HTRACE-77. htraced gui: add pagination to the search page. (abe via cmccabe)
Project: http://git-wip-us.apache.org/repos/asf/incubator-htrace/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-htrace/commit/83053c8b Tree: http://git-wip-us.apache.org/repos/asf/incubator-htrace/tree/83053c8b Diff: http://git-wip-us.apache.org/repos/asf/incubator-htrace/diff/83053c8b Branch: refs/heads/master Commit: 83053c8be166290dfa6639ee12417aa602c14e81 Parents: 94b9b53 Author: Colin P. Mccabe <[email protected]> Authored: Mon Feb 9 13:55:16 2015 -0800 Committer: Colin P. Mccabe <[email protected]> Committed: Mon Feb 9 13:56:15 2015 -0800 ---------------------------------------------------------------------- LICENSE.txt | 8 + htrace-core/src/web/app/mock.js | 23 - htrace-core/src/web/app/models/span.js | 34 +- htrace-core/src/web/app/setup.js | 2 +- htrace-core/src/web/app/views/search.js | 5 +- htrace-core/src/web/app/views/span.js | 11 +- htrace-core/src/web/index.html | 9 +- .../src/web/lib/css/backgrid-0.3.5.min.css | 1 + .../lib/css/backgrid-paginator-0.3.5.min.css | 1 + htrace-core/src/web/lib/css/backgrid.min.css | 1 - .../web/lib/js/backbone.paginator-2.0.2.min.js | 8 + .../src/web/lib/js/backgrid-0.3.5.min.js | 8 + .../src/web/lib/js/backgrid-paginator.js | 433 +++++++++++++++++++ .../src/web/lib/js/backgrid-paginator.min.js | 9 + htrace-core/src/web/lib/js/backgrid.min.js | 8 - 15 files changed, 500 insertions(+), 61 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/LICENSE.txt ---------------------------------------------------------------------- diff --git a/LICENSE.txt b/LICENSE.txt index 1d80bc4..78b178a 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -244,10 +244,18 @@ backbone, is a javascript library, that is Copyright (c) 2010-2014 Jeremy Ashkenas, DocumentCloud. It is MIT licensed: https://github.com/jashkenas/backbone/blob/master/LICENSE +backbone-paginator, is a javascript library, that is Copyright (c) 2012-2014 +Jimmy Yuen Ho Wong and contributors. It is MIT licensed: +https://github.com/backbone-paginator/backbone.paginator/blob/master/LICENSE-MIT + backgrid, is a javascript library, that is Copyright (c) 2013 Jimmy Yuen Ho Wong. It is MIT licensed: https://github.com/wyuenho/backgrid/blob/master/LICENSE-MIT +backgrid-paginator, is a javascript library, that is Copyright (c) 2013 +Jimmy Yuen Ho Wong. It is MIT licensed: +https://github.com/wyuenho/backgrid-paginator/blob/master/LICENSE-MIT + moment.js is a front end time conversion project. It is (c) 2011-2014 Tim Wood, Iskren Chernev, Moment.js contributors and shared under the MIT license: http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/app/mock.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/app/mock.js b/htrace-core/src/web/app/mock.js deleted file mode 100644 index e4277e5..0000000 --- a/htrace-core/src/web/app/mock.js +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var spans = new App.Spans([ - {"beginTime": 1419977682, "stopTime": 1419977689, "description": "test1()", "spanId": 1, "traceId": 1, "parentSpanId": null, "processId": "namenode:1"}, - {"beginTime": 1419977685, "stopTime": 1419977690, "description": "test2()", "spanId": 2, "traceId": 2, "parentSpanId": 1, "processId": "datanode:1"} -]); http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/app/models/span.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/app/models/span.js b/htrace-core/src/web/app/models/span.js index e292970..85c7c72 100644 --- a/htrace-core/src/web/app/models/span.js +++ b/htrace-core/src/web/app/models/span.js @@ -53,33 +53,27 @@ App.Span = Backbone.Model.extend({ } }); -App.Spans = Backbone.Collection.extend({ +App.Spans = Backbone.PageableCollection.extend({ model: App.Span, - url: "/query", - - initialize: function(models, options) { - this.predicates = []; - return Backbone.Collection.prototype.initialize.apply(this, arguments); + mode: "client", + state: { + pageSize: 2 }, + url: "/query", - fetch: function(options) { - options = options ? _.clone(options) : {}; - options.data = { - "query": { - "lim": 100000 - } + query: function(options, predicates) { + var query = { + "lim": 100000 }; - if (this.predicates.length > 0) { - options.data.query.pred = this.predicates; + if (predicates && predicates.length > 0) { + query.pred = predicates; } - options.data.query = JSON.stringify(options.data.query); - - return Backbone.Collection.prototype.fetch.apply(this, [options]); - }, + options = options ? _.clone(options) : {}; + options.data = options.data ? _.clone(options.data) : {}; + options.data.query = JSON.stringify(query); - setPredicates: function(predicates) { - this.predicates = predicates; + return this.fetch(options); } }); http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/app/setup.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/app/setup.js b/htrace-core/src/web/app/setup.js index bb41ad8..9b78ba3 100644 --- a/htrace-core/src/web/app/setup.js +++ b/htrace-core/src/web/app/setup.js @@ -26,7 +26,7 @@ var Router = Backbone.Router.extend({ initialize: function() { this.spansCollection = new App.Spans(); - this.spansCollection.fetch(); + this.spansCollection.query(); this.spanViews = {}; http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/app/views/search.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/app/views/search.js b/htrace-core/src/web/app/views/search.js index bcdd980..4e221ed 100644 --- a/htrace-core/src/web/app/views/search.js +++ b/htrace-core/src/web/app/views/search.js @@ -34,7 +34,7 @@ App.SearchView = Backbone.View.extend({ var endtime = $(this.el).find("#stoptime").val() || now.format("H:mm A"); var duration = $(this.el).find("#duration").val(); - var newSpans = spans.clone(); + var newSpans = spans.fullCollection; if (begindate) { begin = new moment(begindate + " " + begintime).unix(); @@ -78,8 +78,7 @@ App.SearchView = Backbone.View.extend({ }); } - this.collection.setPredicates(predicates); - this.collection.fetch(); + this.collection.query(null, predicates); return false; } http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/app/views/span.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/app/views/span.js b/htrace-core/src/web/app/views/span.js index dd50bc6..764b797 100644 --- a/htrace-core/src/web/app/views/span.js +++ b/htrace-core/src/web/app/views/span.js @@ -46,7 +46,6 @@ App.SpanView = Backbone.View.extend({ } }); - App.ListSpansView = Backbone.View.extend({ "tagName": "div", @@ -75,15 +74,23 @@ App.ListSpansView = Backbone.View.extend({ } }) }); + + this.listSpansPaginator = new Backgrid.Extension.Paginator({ + collection: this.collection + }); }, "render": function() { $(this.listSpansView.$el).detach(); + $(this.listSpansPaginator.$el).detach(); this.listSpansView.render(); + this.listSpansPaginator.render(); $(this.$el).append(this.listSpansView.$el); + $(this.$el).append(this.listSpansPaginator.$el); return this; } -}); \ No newline at end of file +}); + http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/index.html ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/index.html b/htrace-core/src/web/index.html index 181762f..7f0773c 100644 --- a/htrace-core/src/web/index.html +++ b/htrace-core/src/web/index.html @@ -25,7 +25,8 @@ <!-- TODO: Add Favicon --> <link rel="icon" href="//favicon.ico" type="image/x-icon" sizes="16x16"> <link href="lib/bootstrap-3.3.1/css/bootstrap.css" rel="stylesheet"> - <link href="lib/css/backgrid.min.css" rel="stylesheet"> + <link href="lib/css/backgrid-0.3.5.min.css" rel="stylesheet"> + <link href="lib/css/backgrid-paginator-0.3.5.min.css" rel="stylesheet"> <link href="lib/pickadate-3.5.2/themes/classic.css" rel="stylesheet"> <link href="lib/pickadate-3.5.2/themes/classic.date.css" rel="stylesheet"> <link href="lib/pickadate-3.5.2/themes/classic.time.css" rel="stylesheet"> @@ -159,10 +160,12 @@ </script> <script src="lib/js/jquery-2.1.3.min.js" type="text/javascript"></script> + <script src="lib/bootstrap-3.3.1/js/bootstrap.min.js" type="text/javascript"></script> <script src="lib/js/underscore-1.7.0.min.js" type="text/javascript"></script> <script src="lib/js/backbone-1.1.2.min.js" type="text/javascript"></script> - <script src="lib/bootstrap-3.3.1/js/bootstrap.min.js" type="text/javascript"></script> - <script src="lib/js/backgrid.min.js" type="text/javascript"></script> + <script src="lib/js/backbone.paginator-2.0.2.min.js" type="text/javascript"></script> + <script src="lib/js/backgrid-0.3.5.min.js" type="text/javascript"></script> + <script src="lib/js/backgrid-paginator.js" type="text/javascript"></script> <script src="lib/js/moment-2.9.0.min.js" type="text/javascript"></script> <script src="lib/pickadate-3.5.2/picker.js" type="text/javascript"></script> <script src="lib/pickadate-3.5.2/picker.date.js" type="text/javascript"></script> http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/css/backgrid-0.3.5.min.css ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/css/backgrid-0.3.5.min.css b/htrace-core/src/web/lib/css/backgrid-0.3.5.min.css new file mode 100644 index 0000000..764e799 --- /dev/null +++ b/htrace-core/src/web/lib/css/backgrid-0.3.5.min.css @@ -0,0 +1 @@ +.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{display:none;height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;border-bottom:1px solid #DDD}.backgrid th.renderable,.backgrid td.renderable{display:table-cell}.backgrid th{font-weight:bold;text-align:center}.backgrid th.sortable a{text-decoration:none;white-space:nowrap;cursor:pointer}.backgrid thead th{vertical-align:bottom;background-color:#f9f9f9}.backgrid thead th a{display:block}.backgrid.backgrid-striped tbody tr:nth-child(even){background-color:#f9f9f9}.backgrid tbody tr.empty{font-style:italic;color:gray}.backgrid tbody tr.empty td{display:inherit;text-align:center}.backgrid td.edito r{padding:0}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0 5px;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-b ox;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.editor input[type=text]::-ms-clear{display:none}.backgrid td.error,.backgrid tbody tr:nth-child(odd) td.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}. backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .percent-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text],.backgrid .percent-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor select[multiple]{height:auto}.backgr id .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/css/backgrid-paginator-0.3.5.min.css ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/css/backgrid-paginator-0.3.5.min.css b/htrace-core/src/web/lib/css/backgrid-paginator-0.3.5.min.css new file mode 100644 index 0000000..285fe81 --- /dev/null +++ b/htrace-core/src/web/lib/css/backgrid-paginator-0.3.5.min.css @@ -0,0 +1 @@ +.backgrid-paginator{text-align:center;border-top:0;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid-paginator ul{display:inline-block;*display:inline;margin:5px 0;*zoom:1}.backgrid-paginator ul>li{display:inline}.backgrid-paginator ul>li>a,.backgrid-paginator ul>li>span{float:left;width:30px;height:30px;padding:0;line-height:30px;text-decoration:none}.backgrid-paginator ul>li>a:hover,.backgrid-paginator ul>.active>a,.backgrid-paginator ul>.active>span{background-color:#f5f5f5}.backgrid-paginator ul>.active>a,.backgrid-paginator ul>.active>span{color:#999;cursor:default}.backgrid-paginator ul>.disabled>span,.backgrid-paginator ul>.disabled>a,.backgrid-paginator ul>.disabled>a:hover{color:#999;cursor:default} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/css/backgrid.min.css ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/css/backgrid.min.css b/htrace-core/src/web/lib/css/backgrid.min.css deleted file mode 100644 index 764e799..0000000 --- a/htrace-core/src/web/lib/css/backgrid.min.css +++ /dev/null @@ -1 +0,0 @@ -.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{display:none;height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;border-bottom:1px solid #DDD}.backgrid th.renderable,.backgrid td.renderable{display:table-cell}.backgrid th{font-weight:bold;text-align:center}.backgrid th.sortable a{text-decoration:none;white-space:nowrap;cursor:pointer}.backgrid thead th{vertical-align:bottom;background-color:#f9f9f9}.backgrid thead th a{display:block}.backgrid.backgrid-striped tbody tr:nth-child(even){background-color:#f9f9f9}.backgrid tbody tr.empty{font-style:italic;color:gray}.backgrid tbody tr.empty td{display:inherit;text-align:center}.backgrid td.edito r{padding:0}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0 5px;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-b ox;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.editor input[type=text]::-ms-clear{display:none}.backgrid td.error,.backgrid tbody tr:nth-child(odd) td.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}. backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .percent-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text],.backgrid .percent-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor select[multiple]{height:auto}.backgr id .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/js/backbone.paginator-2.0.2.min.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/js/backbone.paginator-2.0.2.min.js b/htrace-core/src/web/lib/js/backbone.paginator-2.0.2.min.js new file mode 100644 index 0000000..687349c --- /dev/null +++ b/htrace-core/src/web/lib/js/backbone.paginator-2.0.2.min.js @@ -0,0 +1,8 @@ +/* + backbone.paginator 2.0.0 + http://github.com/backbone-paginator/backbone.paginator + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT @license. +*/ +!function(a){if("object"==typeof exports)module.exports=a(require("underscore"),require("backbone"));else if("function"==typeof define&&define.amd)define(["underscore","backbone"],a);else if("undefined"!=typeof _&&"undefined"!=typeof Backbone){var b=Backbone.PageableCollection,c=a(_,Backbone);Backbone.PageableCollection.noConflict=function(){return Backbone.PageableCollection=b,c}}}(function(a,b){"use strict";function c(b,c){if(!a.isNumber(b)||a.isNaN(b)||!a.isFinite(b)||~~b!==b)throw new TypeError("`"+c+"` must be a finite integer");return b}function d(a){for(var b,c,d,e,f={},g=decodeURIComponent,h=a.split("&"),i=0,j=h.length;j>i;i++){var k=h[i];b=k.split("="),c=b[0],d=b[1]||!0,c=g(c),d=g(d),e=f[c],o(e)?e.push(d):f[c]=e?[e,d]:d}return f}function e(a,b,c){var d=a._events[b];if(d&&d.length){var e=d[d.length-1],f=e.callback;e.callback=function(){try{f.apply(this,arguments),c()}catch(a){throw a}finally{e.callback=f}}}else c()}var f=a.extend,g=a.omit,h=a.clone,i=a.each,j=a.pick,k=a.cont ains,l=a.isEmpty,m=a.pairs,n=a.invert,o=a.isArray,p=a.isFunction,q=a.isObject,r=a.keys,s=a.isUndefined,t=Math.ceil,u=Math.floor,v=Math.max,w=b.Collection.prototype,x=/[\s'"]/g,y=/[<>\s'"]/g,z=b.PageableCollection=b.Collection.extend({state:{firstPage:1,lastPage:null,currentPage:null,pageSize:25,totalPages:null,totalRecords:null,sortKey:null,order:-1},mode:"server",queryParams:{currentPage:"page",pageSize:"per_page",totalPages:"total_pages",totalRecords:"total_entries",sortKey:"sort_by",order:"order",directions:{"-1":"asc",1:"desc"}},constructor:function(a,b){w.constructor.apply(this,arguments),b=b||{};var c=this.mode=b.mode||this.mode||A.mode,d=f({},A.queryParams,this.queryParams,b.queryParams||{});d.directions=f({},A.queryParams.directions,this.queryParams.directions,d.directions||{}),this.queryParams=d;var e=this.state=f({},A.state,this.state,b.state||{});e.currentPage=null==e.currentPage?e.firstPage:e.currentPage,o(a)||(a=a?[a]:[]),a=a.slice(),"server"==c||null!=e.totalRecords||l (a)||(e.totalRecords=a.length),this.switchMode(c,f({fetch:!1,resetState:!1,models:a},b));var g=b.comparator;if(e.sortKey&&!g&&this.setSorting(e.sortKey,e.order,b),"server"!=c){var i=this.fullCollection;g&&b.full&&(this.comparator=null,i.comparator=g),b.full&&i.sort(),a&&!l(a)&&(this.reset(a,f({silent:!0},b)),this.getPage(e.currentPage),a.splice.apply(a,[0,a.length].concat(this.models)))}this._initState=h(this.state)},_makeFullCollection:function(a,c){var d,e,f,g=["url","model","sync","comparator"],h=this.constructor.prototype,i={};for(d=0,e=g.length;e>d;d++)f=g[d],s(h[f])||(i[f]=h[f]);var j=new(b.Collection.extend(i))(a,c);for(d=0,e=g.length;e>d;d++)f=g[d],this[f]!==h[f]&&(j[f]=this[f]);return j},_makeCollectionEventHandler:function(a,b){return function(c,d,g,j){var k=a._handlers;i(r(k),function(c){var d=k[c];a.off(c,d),b.off(c,d)});var l=h(a.state),m=l.firstPage,n=0===m?l.currentPage:l.currentPage-1,o=l.pageSize,p=n*o,q=p+o;if("add"==c){var u,v,w,x,j=j||{};if(g==b)v=b.indexOf(d),v> =p&&q>v&&(x=a,u=w=v-p);else{u=a.indexOf(d),v=p+u,x=b;var w=s(j.at)?v:j.at+p}if(j.onRemove||(++l.totalRecords,delete j.onRemove),a.state=a._checkState(l),x){x.add(d,f({},j||{},{at:w}));var y=u>=o?d:!s(j.at)&&q>w&&a.length>o?a.at(o):null;y&&e(g,c,function(){a.remove(y,{onAdd:!0})})}}if("remove"==c)if(j.onAdd)delete j.onAdd;else{if(--l.totalRecords){var z=l.totalPages=t(l.totalRecords/o);l.lastPage=0===m?z-1:z||m,l.currentPage>z&&(l.currentPage=l.lastPage)}else l.totalRecords=null,l.totalPages=null;a.state=a._checkState(l);var A,B=j.index;g==a?((A=b.at(q))?e(a,c,function(){a.push(A,{onRemove:!0})}):!a.length&&l.totalRecords&&a.reset(b.models.slice(p-o,q-o),f({},j,{parse:!1})),b.remove(d)):B>=p&&q>B&&((A=b.at(q-1))&&e(a,c,function(){a.push(A,{onRemove:!0})}),a.remove(d),!a.length&&l.totalRecords&&a.reset(b.models.slice(p-o,q-o),f({},j,{parse:!1})))}if("reset"==c)if(j=g,g=d,g==a&&null==j.from&&null==j.to){var C=b.models.slice(0,p),D=b.models.slice(p+a.models.length);b.reset(C.concat(a.mo dels).concat(D),j)}else g==b&&((l.totalRecords=b.models.length)||(l.totalRecords=null,l.totalPages=null),"client"==a.mode&&(l.lastPage=l.currentPage=l.firstPage),a.state=a._checkState(l),a.reset(b.models.slice(p,q),f({},j,{parse:!1})));"sort"==c&&(j=g,g=d,g===b&&a.reset(b.models.slice(p,q),f({},j,{parse:!1}))),i(r(k),function(c){var d=k[c];i([a,b],function(a){a.on(c,d);var b=a._events[c]||[];b.unshift(b.pop())})})}},_checkState:function(a){var b=this.mode,d=this.links,e=a.totalRecords,f=a.pageSize,g=a.currentPage,h=a.firstPage,i=a.totalPages;if(null!=e&&null!=f&&null!=g&&null!=h&&("infinite"==b?d:!0)){if(e=c(e,"totalRecords"),f=c(f,"pageSize"),g=c(g,"currentPage"),h=c(h,"firstPage"),1>f)throw new RangeError("`pageSize` must be >= 1");if(i=a.totalPages=t(e/f),0>h||h>1)throw new RangeError("`firstPage must be 0 or 1`");if(a.lastPage=0===h?v(0,i-1):i||h,"infinite"==b){if(!d[g+""])throw new RangeError("No link found for page "+g)}else if(h>g||i>0&&(h?g>i:g>=i))throw new RangeError("`cur rentPage` must be firstPage <= currentPage "+(h?">":">=")+" totalPages if "+h+"-based. Got "+g+".")}return a},setPageSize:function(a,b){a=c(a,"pageSize"),b=b||{first:!1};var d=this.state,e=t(d.totalRecords/a),h=e?v(d.firstPage,u(e*d.currentPage/d.totalPages)):d.firstPage;return d=this.state=this._checkState(f({},d,{pageSize:a,currentPage:b.first?d.firstPage:h,totalPages:e})),this.getPage(d.currentPage,g(b,["first"]))},switchMode:function(b,c){if(!k(["server","client","infinite"],b))throw new TypeError('`mode` must be one of "server", "client" or "infinite"');c=c||{fetch:!0,resetState:!0};var d=this.state=c.resetState?h(this._initState):this._checkState(f({},this.state));this.mode=b;var e,j=this,l=this.fullCollection,m=this._handlers=this._handlers||{};if("server"==b||l)"server"==b&&l&&(i(r(m),function(a){e=m[a],j.off(a,e),l.off(a,e)}),delete this._handlers,this._fullComparator=l.comparator,delete this.fullCollection);else{l=this._makeFullCollection(c.models||[],c),l.pageableCollecti on=this,this.fullCollection=l;var n=this._makeCollectionEventHandler(this,l);i(["add","remove","reset","sort"],function(b){m[b]=e=a.bind(n,{},b),j.on(b,e),l.on(b,e)}),l.comparator=this._fullComparator}if("infinite"==b)for(var o=this.links={},p=d.firstPage,q=t(d.totalRecords/d.pageSize),s=0===p?v(0,q-1):q||p,u=d.firstPage;s>=u;u++)o[u]=this.url;else this.links&&delete this.links;return c.fetch?this.fetch(g(c,"fetch","resetState")):this},hasPreviousPage:function(){var a=this.state,b=a.currentPage;return"infinite"!=this.mode?b>a.firstPage:!!this.links[b-1]},hasNextPage:function(){var a=this.state,b=this.state.currentPage;return"infinite"!=this.mode?b<a.lastPage:!!this.links[b+1]},getFirstPage:function(a){return this.getPage("first",a)},getPreviousPage:function(a){return this.getPage("prev",a)},getNextPage:function(a){return this.getPage("next",a)},getLastPage:function(a){return this.getPage("last",a)},getPage:function(a,b){var d=this.mode,e=this.fullCollection;b=b||{fetch:!1};var h=thi s.state,i=h.firstPage,j=h.currentPage,k=h.lastPage,m=h.pageSize,n=a;switch(a){case"first":n=i;break;case"prev":n=j-1;break;case"next":n=j+1;break;case"last":n=k;break;default:n=c(a,"index")}this.state=this._checkState(f({},h,{currentPage:n})),b.from=j,b.to=n;var o=(0===i?n:n-1)*m,p=e&&e.length?e.models.slice(o,o+m):[];return"client"!=d&&("infinite"!=d||l(p))||b.fetch?("infinite"==d&&(b.url=this.links[n]),this.fetch(g(b,"fetch"))):(this.reset(p,g(b,"fetch")),this)},getPageByOffset:function(a,b){if(0>a)throw new RangeError("`offset must be > 0`");a=c(a);var d=u(a/this.state.pageSize);return 0!==this.state.firstPage&&d++,d>this.state.lastPage&&(d=this.state.lastPage),this.getPage(d,b)},sync:function(a,c,d){var e=this;if("infinite"==e.mode){var g=d.success,h=e.state.currentPage;d.success=function(a,b,c){var i=e.links,j=e.parseLinks(a,f({xhr:c},d));j.first&&(i[e.state.firstPage]=j.first),j.prev&&(i[h-1]=j.prev),j.next&&(i[h+1]=j.next),g&&g(a,b,c)}}return(w.sync||b.sync).call(e,a,c,d)},pa rseLinks:function(a,b){var c={},d=b.xhr.getResponseHeader("Link");if(d){var e=["first","prev","next"];i(d.split(","),function(a){var b=a.split(";"),d=b[0].replace(y,""),f=b.slice(1);i(f,function(a){var b=a.split("="),f=b[0].replace(x,""),g=b[1].replace(x,"");"rel"==f&&k(e,g)&&(c[g]=d)})})}return c},parse:function(a,b){var c=this.parseState(a,h(this.queryParams),h(this.state),b);return c&&(this.state=this._checkState(f({},this.state,c))),this.parseRecords(a,b)},parseState:function(b,c,d){if(b&&2===b.length&&q(b[0])&&o(b[1])){var e=h(d),f=b[0];return i(m(g(c,"directions")),function(b){var c=b[0],d=b[1],g=f[d];s(g)||a.isNull(g)||(e[c]=f[d])}),f.order&&(e.order=1*n(c.directions)[f.order]),e}},parseRecords:function(a){return a&&2===a.length&&q(a[0])&&o(a[1])?a[1]:a},fetch:function(a){a=a||{};var b=this._checkState(this.state),c=this.mode;"infinite"!=c||a.url||(a.url=this.links[b.currentPage]);var e=a.data||{},i=a.url||this.url||"";p(i)&&(i=i.call(this));var k=i.indexOf("?");-1!=k&&(f(e,d (i.slice(k+1))),i=i.slice(0,k)),a.url=i,a.data=e;var l,n,o,q,t="client"==this.mode?j(this.queryParams,"sortKey","order"):g(j(this.queryParams,r(A.queryParams)),"directions"),u=m(t),v=h(this);for(l=0;l<u.length;l++)n=u[l],o=n[0],q=n[1],q=p(q)?q.call(v):q,null!=b[o]&&null!=q&&(e[q]=b[o]);if(b.sortKey&&b.order){var x=p(t.order)?t.order.call(v):t.order;e[x]=this.queryParams.directions[b.order+""]}else b.sortKey||delete e[t.order];var y=m(g(this.queryParams,r(A.queryParams)));for(l=0;l<y.length;l++)n=y[l],q=n[1],q=p(q)?q.call(v):q,null!=q&&(e[n[0]]=q);if("server"!=c){var z=this,B=this.fullCollection,C=a.success;return a.success=function(b,d,e){e=e||{},s(a.silent)?delete e.silent:e.silent=a.silent;var g=b.models;"client"==c?B.reset(g,e):(B.add(g,f({at:B.length},f(e,{parse:!1}))),z.trigger("reset",z,e)),C&&C(b,d,e)},w.fetch.call(this,f({},a,{silent:!0}))}return w.fetch.call(this,a)},_makeComparator:function(a,b,c){var d=this.state;return a=a||d.sortKey,b=b||d.order,a&&b?(c||(c=function(a,b ){return a.get(b)}),function(d,e){var f,g=c(d,a),h=c(e,a);return 1===b&&(f=g,g=h,h=f),g===h?0:h>g?-1:1}):void 0},setSorting:function(a,b,c){var d=this.state;d.sortKey=a,d.order=b=b||d.order;var e=this.fullCollection,g=!1,h=!1;a||(g=h=!0);var i=this.mode;c=f({side:"client"==i?i:"server",full:!0},c);var j=this._makeComparator(a,b,c.sortValue),k=c.full,l=c.side;return"client"==l?k?(e&&(e.comparator=j),g=!0):(this.comparator=j,h=!0):"server"!=l||k||(this.comparator=j),g&&(this.comparator=null),h&&e&&(e.comparator=null),this}}),A=z.prototype;return z}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/js/backgrid-0.3.5.min.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/js/backgrid-0.3.5.min.js b/htrace-core/src/web/lib/js/backgrid-0.3.5.min.js new file mode 100644 index 0000000..4938964 --- /dev/null +++ b/htrace-core/src/web/lib/js/backgrid-0.3.5.min.js @@ -0,0 +1,8 @@ +/*! + backgrid + http://github.com/wyuenho/backgrid + + Copyright (c) 2014 Jimmy Yuen Ho Wong and contributors <[email protected]> + Licensed under the MIT license. +*/ +!function(a){"object"==typeof exports?module.exports=a(module.exports,require("underscore"),require("backbone")):a(this,this._,this.Backbone)}(function(a,b,c){"use strict";function d(a,b,c){var d=b-(a+"").length;d=0>d?0:d;for(var e="",f=0;d>f;f++)e+=c;return e+a}var e=" \n\f\r  áá ââââââ ââââââ¯âã\u2028\u2029";if(!String.prototype.trim||e.trim()){e="["+e+"]";var f=new RegExp("^"+e+e+"*"),g=new RegExp(e+e+"*$");String.prototype.trim=function(){if(void 0===this||null===this)throw new TypeError("can't convert "+this+" to object");return String(this).replace(f,"").replace(g,"")}}var h=c.$,i=a.Backgrid={Extension:{},resolveNameToClass:function(a,c){if(b.isString(a)){var d=b.map(a.split("-"),function(a){return a.slice(0,1).toUpperCase()+a.slice(1)}).join("")+c,e=i[d]||i.Extension[d];if(b.isUndefined(e))throw new ReferenceError("Class '"+d+"' not found");return e}return a},callByNeed:function(){var a=arguments[0];if(!b.isFunction(a))return a;var c=argument s[1],d=[].slice.call(arguments,2);return a.apply(c,d+""?d:[])}};b.extend(i,c.Events);var j=i.Command=function(a){b.extend(this,{altKey:!!a.altKey,"char":a["char"],charCode:a.charCode,ctrlKey:!!a.ctrlKey,key:a.key,keyCode:a.keyCode,locale:a.locale,location:a.location,metaKey:!!a.metaKey,repeat:!!a.repeat,shiftKey:!!a.shiftKey,which:a.which})};b.extend(j.prototype,{moveUp:function(){return 38==this.keyCode},moveDown:function(){return 40===this.keyCode},moveLeft:function(){return this.shiftKey&&9===this.keyCode},moveRight:function(){return!this.shiftKey&&9===this.keyCode},save:function(){return 13===this.keyCode},cancel:function(){return 27===this.keyCode},passThru:function(){return!(this.moveUp()||this.moveDown()||this.moveLeft()||this.moveRight()||this.save()||this.cancel())}});var k=i.CellFormatter=function(){};b.extend(k.prototype,{fromRaw:function(a){return a},toRaw:function(a){return a}});var l=i.NumberFormatter=function(a){if(b.extend(this,this.defaults,a||{}),this.decimals<0||t his.decimals>20)throw new RangeError("decimals must be between 0 and 20")};l.prototype=new k,b.extend(l.prototype,{defaults:{decimals:2,decimalSeparator:".",orderSeparator:","},HUMANIZED_NUM_RE:/(\d)(?=(?:\d{3})+$)/g,fromRaw:function(a){if(b.isNull(a)||b.isUndefined(a))return"";a=a.toFixed(~~this.decimals);var c=a.split("."),d=c[0],e=c[1]?(this.decimalSeparator||".")+c[1]:"";return d.replace(this.HUMANIZED_NUM_RE,"$1"+this.orderSeparator)+e},toRaw:function(a){if(a=a.trim(),""===a)return null;for(var c="",d=a.split(this.orderSeparator),e=0;e<d.length;e++)c+=d[e];var f=c.split(this.decimalSeparator);c="";for(var e=0;e<f.length;e++)c=c+f[e]+".";"."===c[c.length-1]&&(c=c.slice(0,c.length-1));var g=1*(1*c).toFixed(~~this.decimals);return b.isNumber(g)&&!b.isNaN(g)?g:void 0}});var m=i.PercentFormatter=function(){i.NumberFormatter.apply(this,arguments)};m.prototype=new i.NumberFormatter,b.extend(m.prototype,{defaults:b.extend({},l.prototype.defaults,{multiplier:1,symbol:"%"}),fromRaw:funct ion(a){var b=[].slice.call(arguments,1);return b.unshift(a*this.multiplier),(l.prototype.fromRaw.apply(this,b)||"0")+this.symbol},toRaw:function(a){var c=a.split(this.symbol);if(c&&c[0]&&""===c[1]||null==c[1]){var d=l.prototype.toRaw.call(this,c[0]);return b.isUndefined(d)?d:d/this.multiplier}}});var n=i.DatetimeFormatter=function(a){if(b.extend(this,this.defaults,a||{}),!this.includeDate&&!this.includeTime)throw new Error("Either includeDate or includeTime must be true")};n.prototype=new k,b.extend(n.prototype,{defaults:{includeDate:!0,includeTime:!0,includeMilli:!1},DATE_RE:/^([+\-]?\d{4})-(\d{2})-(\d{2})$/,TIME_RE:/^(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?$/,ISO_SPLITTER_RE:/T|Z| +/,_convert:function(a,c){if(""===(a+"").trim())return null;var e,f=null;if(b.isNumber(a)){var g=new Date(a);e=d(g.getUTCFullYear(),4,0)+"-"+d(g.getUTCMonth()+1,2,0)+"-"+d(g.getUTCDate(),2,0),f=d(g.getUTCHours(),2,0)+":"+d(g.getUTCMinutes(),2,0)+":"+d(g.getUTCSeconds(),2,0)}else{a=a.trim();var h=a.split(this. ISO_SPLITTER_RE)||[];e=this.DATE_RE.test(h[0])?h[0]:"",f=e&&h[1]?h[1]:this.TIME_RE.test(h[0])?h[0]:""}var i=this.DATE_RE.exec(e)||[],j=this.TIME_RE.exec(f)||[];if(c){if(this.includeDate&&b.isUndefined(i[0]))return;if(this.includeTime&&b.isUndefined(j[0]))return;if(!this.includeDate&&e)return;if(!this.includeTime&&f)return}var g=new Date(Date.UTC(1*i[1]||0,1*i[2]-1||0,1*i[3]||0,1*j[1]||null,1*j[2]||null,1*j[3]||null,1*j[5]||null)),k="";return this.includeDate&&(k=d(g.getUTCFullYear(),4,0)+"-"+d(g.getUTCMonth()+1,2,0)+"-"+d(g.getUTCDate(),2,0)),this.includeTime&&(k=k+(this.includeDate?"T":"")+d(g.getUTCHours(),2,0)+":"+d(g.getUTCMinutes(),2,0)+":"+d(g.getUTCSeconds(),2,0),this.includeMilli&&(k=k+"."+d(g.getUTCMilliseconds(),3,0))),this.includeDate&&this.includeTime&&(k+="Z"),k},fromRaw:function(a){return b.isNull(a)||b.isUndefined(a)?"":this._convert(a)},toRaw:function(a){return this._convert(a,!0)}});var o=i.StringFormatter=function(){};o.prototype=new k,b.extend(o.prototype,{fromRaw :function(a){return b.isUndefined(a)||b.isNull(a)?"":a+""}});var p=i.EmailFormatter=function(){};p.prototype=new k,b.extend(p.prototype,{toRaw:function(a){var c=a.trim().split("@");return 2===c.length&&b.all(c)?a:void 0}});var q=i.SelectFormatter=function(){};q.prototype=new k,b.extend(q.prototype,{fromRaw:function(a){return b.isArray(a)?a:null!=a?[a]:[]}});var r=i.CellEditor=c.View.extend({initialize:function(a){this.formatter=a.formatter,this.column=a.column,this.column instanceof C||(this.column=new C(this.column)),this.listenTo(this.model,"backgrid:editing",this.postRender)},postRender:function(a,b){return(null==b||b.get("name")==this.column.get("name"))&&this.$el.focus(),this}}),s=i.InputCellEditor=r.extend({tagName:"input",attributes:{type:"text"},events:{blur:"saveOrCancel",keydown:"saveOrCancel"},initialize:function(a){s.__super__.initialize.apply(this,arguments),a.placeholder&&this.$el.attr("placeholder",a.placeholder)},render:function(){var a=this.model;return this.$el.val (this.formatter.fromRaw(a.get(this.column.get("name")),a)),this},saveOrCancel:function(a){var c=this.formatter,d=this.model,e=this.column,f=new j(a),g="blur"===a.type;if(f.moveUp()||f.moveDown()||f.moveLeft()||f.moveRight()||f.save()||g){a.preventDefault(),a.stopPropagation();var h=this.$el.val(),i=c.toRaw(h,d);b.isUndefined(i)?d.trigger("backgrid:error",d,e,h):(d.set(e.get("name"),i),d.trigger("backgrid:edited",d,e,f))}else f.cancel()&&(a.stopPropagation(),d.trigger("backgrid:edited",d,e,f))},postRender:function(a,b){if(null==b||b.get("name")==this.column.get("name"))if("right"===this.$el.css("text-align")){var c=this.$el.val();this.$el.focus().val(null).val(c)}else this.$el.focus();return this}}),t=i.Cell=c.View.extend({tagName:"td",formatter:k,editor:s,events:{click:"enterEditMode"},initialize:function(a){this.column=a.column,this.column instanceof C||(this.column=new C(this.column));var c=this.column,d=this.model,e=this.$el,f=i.resolveNameToClass(c.get("formatter")||this.formatt er,"Formatter");b.isFunction(f.fromRaw)||b.isFunction(f.toRaw)||(f=new f),this.formatter=f,this.editor=i.resolveNameToClass(this.editor,"CellEditor"),this.listenTo(d,"change:"+c.get("name"),function(){e.hasClass("editor")||this.render()}),this.listenTo(d,"backgrid:error",this.renderError),this.listenTo(c,"change:editable change:sortable change:renderable",function(a){var b=a.changedAttributes();for(var c in b)b.hasOwnProperty(c)&&e.toggleClass(c,b[c])}),i.callByNeed(c.editable(),c,d)&&e.addClass("editable"),i.callByNeed(c.sortable(),c,d)&&e.addClass("sortable"),i.callByNeed(c.renderable(),c,d)&&e.addClass("renderable")},render:function(){this.$el.empty();var a=this.model;return this.$el.text(this.formatter.fromRaw(a.get(this.column.get("name")),a)),this.delegateEvents(),this},enterEditMode:function(){var a=this.model,b=this.column,c=i.callByNeed(b.editable(),b,a);c&&(this.currentEditor=new this.editor({column:this.column,model:this.model,formatter:this.formatter}),a.trigger("backgri d:edit",a,b,this,this.currentEditor),this.undelegateEvents(),this.$el.empty(),this.$el.append(this.currentEditor.$el),this.currentEditor.render(),this.$el.addClass("editor"),a.trigger("backgrid:editing",a,b,this,this.currentEditor))},renderError:function(a,b){(null==b||b.get("name")==this.column.get("name"))&&this.$el.addClass("error")},exitEditMode:function(){this.$el.removeClass("error"),this.currentEditor.remove(),this.stopListening(this.currentEditor),delete this.currentEditor,this.$el.removeClass("editor"),this.render()},remove:function(){return this.currentEditor&&(this.currentEditor.remove.apply(this.currentEditor,arguments),delete this.currentEditor),t.__super__.remove.apply(this,arguments)}}),u=i.StringCell=t.extend({className:"string-cell",formatter:o}),v=i.UriCell=t.extend({className:"uri-cell",title:null,target:"_blank",initialize:function(a){v.__super__.initialize.apply(this,arguments),this.title=a.title||this.title,this.target=a.target||this.target},render:function(){t his.$el.empty();var a=this.model.get(this.column.get("name")),b=this.formatter.fromRaw(a,this.model);return this.$el.append(h("<a>",{tabIndex:-1,href:a,title:this.title||b,target:this.target}).text(b)),this.delegateEvents(),this}}),w=(i.EmailCell=u.extend({className:"email-cell",formatter:p,render:function(){this.$el.empty();var a=this.model,b=this.formatter.fromRaw(a.get(this.column.get("name")),a);return this.$el.append(h("<a>",{tabIndex:-1,href:"mailto:"+b,title:b}).text(b)),this.delegateEvents(),this}}),i.NumberCell=t.extend({className:"number-cell",decimals:l.prototype.defaults.decimals,decimalSeparator:l.prototype.defaults.decimalSeparator,orderSeparator:l.prototype.defaults.orderSeparator,formatter:l,initialize:function(){w.__super__.initialize.apply(this,arguments);var a=this.formatter;a.decimals=this.decimals,a.decimalSeparator=this.decimalSeparator,a.orderSeparator=this.orderSeparator}})),x=(i.IntegerCell=w.extend({className:"integer-cell",decimals:0}),i.PercentCell=w.exte nd({className:"percent-cell",multiplier:m.prototype.defaults.multiplier,symbol:m.prototype.defaults.symbol,formatter:m,initialize:function(){x.__super__.initialize.apply(this,arguments);var a=this.formatter;a.multiplier=this.multiplier,a.symbol=this.symbol}})),y=i.DatetimeCell=t.extend({className:"datetime-cell",includeDate:n.prototype.defaults.includeDate,includeTime:n.prototype.defaults.includeTime,includeMilli:n.prototype.defaults.includeMilli,formatter:n,initialize:function(){y.__super__.initialize.apply(this,arguments);var a=this.formatter;a.includeDate=this.includeDate,a.includeTime=this.includeTime,a.includeMilli=this.includeMilli;var c=this.includeDate?"YYYY-MM-DD":"";c+=this.includeDate&&this.includeTime?"T":"",c+=this.includeTime?"HH:mm:ss":"",c+=this.includeTime&&this.includeMilli?".SSS":"",this.editor=this.editor.extend({attributes:b.extend({},this.editor.prototype.attributes,this.editor.attributes,{placeholder:c})})}}),z=(i.DateCell=y.extend({className:"date-cell",inclu deTime:!1}),i.TimeCell=y.extend({className:"time-cell",includeDate:!1}),i.BooleanCellEditor=r.extend({tagName:"input",attributes:{tabIndex:-1,type:"checkbox"},events:{mousedown:function(){this.mouseDown=!0},blur:"enterOrExitEditMode",mouseup:function(){this.mouseDown=!1},change:"saveOrCancel",keydown:"saveOrCancel"},render:function(){var a=this.model,b=this.formatter.fromRaw(a.get(this.column.get("name")),a);return this.$el.prop("checked",b),this},enterOrExitEditMode:function(a){if(!this.mouseDown){var b=this.model;b.trigger("backgrid:edited",b,this.column,new j(a))}},saveOrCancel:function(a){var b=this.model,c=this.column,d=this.formatter,e=new j(a);if(e.passThru()&&"change"!=a.type)return!0;e.cancel()&&(a.stopPropagation(),b.trigger("backgrid:edited",b,c,e));var f=this.$el;if(e.save()||e.moveLeft()||e.moveRight()||e.moveUp()||e.moveDown()){a.preventDefault(),a.stopPropagation();var g=d.toRaw(f.prop("checked"),b);b.set(c.get("name"),g),b.trigger("backgrid:edited",b,c,e)}else if("ch ange"==a.type){var g=d.toRaw(f.prop("checked"),b);b.set(c.get("name"),g),f.focus()}}})),A=(i.BooleanCell=t.extend({className:"boolean-cell",editor:z,events:{click:"enterEditMode"},render:function(){this.$el.empty();var a=this.model,b=this.column,c=i.callByNeed(b.editable(),b,a);return this.$el.append(h("<input>",{tabIndex:-1,type:"checkbox",checked:this.formatter.fromRaw(a.get(b.get("name")),a),disabled:!c})),this.delegateEvents(),this}}),i.SelectCellEditor=r.extend({tagName:"select",events:{change:"save",blur:"close",keydown:"close"},template:b.template('<option value="<%- value %>" <%= selected ? \'selected="selected"\' : "" %>><%- text %></option>',null,{variable:null}),setOptionValues:function(a){this.optionValues=a,this.optionValues=b.result(this,"optionValues")},setMultiple:function(a){this.multiple=a,this.$el.prop("multiple",a)},_renderOptions:function(a,c){for(var d="",e=0;e<a.length;e++)d+=this.template({text:a[e][0],value:a[e][1],selected:b.indexOf(c,a[e][1])>-1});return d },render:function(){this.$el.empty();var a=b.result(this,"optionValues"),c=this.model,d=this.formatter.fromRaw(c.get(this.column.get("name")),c);if(!b.isArray(a))throw new TypeError("optionValues must be an array");for(var e=null,f=null,e=null,g=null,i=null,j=0;j<a.length;j++){var e=a[j];if(b.isArray(e))f=e[0],e=e[1],this.$el.append(this.template({text:f,value:e,selected:b.indexOf(d,e)>-1}));else{if(!b.isObject(e))throw new TypeError("optionValues elements must be a name-value pair or an object hash of { name: 'optgroup label', value: [option name-value pairs] }");g=e.name,i=h("<optgroup></optgroup>",{label:g}),i.append(this._renderOptions.call(this,e.values,d)),this.$el.append(i)}}return this.delegateEvents(),this},save:function(){var a=this.model,b=this.column;a.set(b.get("name"),this.formatter.toRaw(this.$el.val(),a))},close:function(a){var b=this.model,c=this.column,d=new j(a);d.cancel()?(a.stopPropagation(),b.trigger("backgrid:edited",b,c,new j(a))):(d.save()||d.moveLeft()||d.m oveRight()||d.moveUp()||d.moveDown()||"blur"==a.type)&&(a.preventDefault(),a.stopPropagation(),this.save(a),b.trigger("backgrid:edited",b,c,new j(a)))}})),B=i.SelectCell=t.extend({className:"select-cell",editor:A,multiple:!1,formatter:q,optionValues:void 0,delimiter:", ",initialize:function(){B.__super__.initialize.apply(this,arguments),this.listenTo(this.model,"backgrid:edit",function(a,b,c,d){b.get("name")==this.column.get("name")&&(d.setOptionValues(this.optionValues),d.setMultiple(this.multiple))})},render:function(){this.$el.empty();var a=b.result(this,"optionValues"),c=this.model,d=this.formatter.fromRaw(c.get(this.column.get("name")),c),e=[];try{if(!b.isArray(a)||b.isEmpty(a))throw new TypeError;for(var f=0;f<d.length;f++)for(var g=d[f],h=0;h<a.length;h++){var i=a[h];if(b.isArray(i)){var j=i[0],i=i[1];i==g&&e.push(j)}else{if(!b.isObject(i))throw new TypeError;for(var k=i.values,l=0;l<k.length;l++){var m=k[l];m[1]==g&&e.push(m[0])}}}this.$el.append(e.join(this.delimiter))}catc h(n){if(n instanceof TypeError)throw new TypeError("'optionValues' must be of type {Array.<Array>|Array.<{name: string, values: Array.<Array>}>}");throw n}return this.delegateEvents(),this}}),C=i.Column=c.Model.extend({defaults:{name:void 0,label:void 0,sortable:!0,editable:!0,renderable:!0,formatter:void 0,sortType:"cycle",sortValue:void 0,direction:null,cell:void 0,headerCell:void 0},initialize:function(){this.has("label")||this.set({label:this.get("name")},{silent:!0});var a=i.resolveNameToClass(this.get("headerCell"),"HeaderCell"),b=i.resolveNameToClass(this.get("cell"),"Cell");this.set({cell:b,headerCell:a},{silent:!0})},sortValue:function(){var a=this.get("sortValue");return b.isString(a)?this[a]:b.isFunction(a)?a:function(a,b){return a.get(b)}}});b.each(["sortable","renderable","editable"],function(a){C.prototype[a]=function(){var c=this.get(a);return b.isString(c)?this[c]:b.isFunction(c)?c:!!c}});{var D=i.Columns=c.Collection.extend({model:C}),E=i.Row=c.View.extend({tagName: "tr",initialize:function(a){var b=this.columns=a.columns;b instanceof c.Collection||(b=this.columns=new D(b));for(var d=this.cells=[],e=0;e<b.length;e++)d.push(this.makeCell(b.at(e),a));this.listenTo(b,"add",function(b,c){var e=c.indexOf(b),f=this.makeCell(b,a);d.splice(e,0,f);var g=this.$el;0===e?g.prepend(f.render().$el):e===c.length-1?g.append(f.render().$el):g.children().eq(e).before(f.render().$el)}),this.listenTo(b,"remove",function(a,b,c){d[c.index].remove(),d.splice(c.index,1)})},makeCell:function(a){return new(a.get("cell"))({column:a,model:this.model})},render:function(){this.$el.empty();for(var a=document.createDocumentFragment(),b=0;b<this.cells.length;b++)a.appendChild(this.cells[b].render().el);return this.el.appendChild(a),this.delegateEvents(),this},remove:function(){for(var a=0;a<this.cells.length;a++){var b=this.cells[a];b.remove.apply(b,arguments)}return c.View.prototype.remove.apply(this,arguments)}}),F=i.EmptyRow=c.View.extend({tagName:"tr",emptyText:null,initia lize:function(a){this.emptyText=a.emptyText,this.columns=a.columns},render:function(){this.$el.empty();var a=document.createElement("td");return a.setAttribute("colspan",this.columns.length),a.appendChild(document.createTextNode(b.result(this,"emptyText"))),this.el.className="empty",this.el.appendChild(a),this}}),G=i.HeaderCell=c.View.extend({tagName:"th",events:{"click a":"onClick"},initialize:function(a){this.column=a.column,this.column instanceof C||(this.column=new C(this.column));var b=this.column,c=this.collection,d=this.$el;this.listenTo(b,"change:editable change:sortable change:renderable",function(a){var b=a.changedAttributes();for(var c in b)b.hasOwnProperty(c)&&d.toggleClass(c,b[c])}),this.listenTo(b,"change:direction",this.setCellDirection),this.listenTo(b,"change:name change:label",this.render),i.callByNeed(b.editable(),b,c)&&d.addClass("editable"),i.callByNeed(b.sortable(),b,c)&&d.addClass("sortable"),i.callByNeed(b.renderable(),b,c)&&d.addClass("renderable"),this.list enTo(c.fullCollection||c,"sort",this.removeCellDirection)},removeCellDirection:function(){this.$el.removeClass("ascending").removeClass("descending"),this.column.set("direction",null)},setCellDirection:function(a,b){this.$el.removeClass("ascending").removeClass("descending"),a.cid==this.column.cid&&this.$el.addClass(b)},onClick:function(a){function b(a,b){"ascending"===d.get("direction")?e.trigger(f,b,"descending"):"descending"===d.get("direction")?e.trigger(f,b,null):e.trigger(f,b,"ascending")}function c(a,b){"ascending"===d.get("direction")?e.trigger(f,b,"descending"):e.trigger(f,b,"ascending")}a.preventDefault();var d=this.column,e=this.collection,f="backgrid:sort",g=i.callByNeed(d.sortable(),d,this.collection);if(g){var h=d.get("sortType");"toggle"===h?c(this,d):b(this,d)}},render:function(){this.$el.empty();var a,b=this.column,c=i.callByNeed(b.sortable(),b,this.collection);return a=c?h("<a>").text(b.get("label")).append("<b class='sort-caret'></b>"):document.createTextNode(b.ge t("label")),this.$el.append(a),this.$el.addClass(b.get("name")),this.$el.addClass(b.get("direction")),this.delegateEvents(),this}}),H=(i.HeaderRow=i.Row.extend({requiredOptions:["columns","collection"],initialize:function(){i.Row.prototype.initialize.apply(this,arguments)},makeCell:function(a,b){var c=a.get("headerCell")||b.headerCell||G;return c=new c({column:a,collection:this.collection})}}),i.Header=c.View.extend({tagName:"thead",initialize:function(a){this.columns=a.columns,this.columns instanceof c.Collection||(this.columns=new D(this.columns)),this.row=new i.HeaderRow({columns:this.columns,collection:this.collection})},render:function(){return this.$el.append(this.row.render().$el),this.delegateEvents(),this},remove:function(){return this.row.remove.apply(this.row,arguments),c.View.prototype.remove.apply(this,arguments)}})),I=i.Body=c.View.extend({tagName:"tbody",initialize:function(a){this.columns=a.columns,this.columns instanceof c.Collection||(this.columns=new D(this.column s)),this.row=a.row||E,this.rows=this.collection.map(function(a){var b=new this.row({columns:this.columns,model:a});return b},this),this.emptyText=a.emptyText,this._unshiftEmptyRowMayBe();var b=this.collection;this.listenTo(b,"add",this.insertRow),this.listenTo(b,"remove",this.removeRow),this.listenTo(b,"sort",this.refresh),this.listenTo(b,"reset",this.refresh),this.listenTo(b,"backgrid:sort",this.sort),this.listenTo(b,"backgrid:edited",this.moveToNextCell)},_unshiftEmptyRowMayBe:function(){0===this.rows.length&&null!=this.emptyText&&this.rows.unshift(new F({emptyText:this.emptyText,columns:this.columns}))},insertRow:function(a,b,d){if(this.rows[0]instanceof F&&this.rows.pop().remove(),!(b instanceof c.Collection||d))return void this.collection.add(a,d=b);var e=new this.row({columns:this.columns,model:a}),f=b.indexOf(a);this.rows.splice(f,0,e);var g=this.$el,h=g.children(),i=e.render().$el;return f>=h.length?g.append(i):h.eq(f).before(i),this},removeRow:function(a,c,d){return d?((b.i sUndefined(d.render)||d.render)&&this.rows[d.index].remove(),this.rows.splice(d.index,1),this._unshiftEmptyRowMayBe(),this):(this.collection.remove(a,d=c),void this._unshiftEmptyRowMayBe())},refresh:function(){for(var a=0;a<this.rows.length;a++)this.rows[a].remove();return this.rows=this.collection.map(function(a){var b=new this.row({columns:this.columns,model:a});return b},this),this._unshiftEmptyRowMayBe(),this.render(),this.collection.trigger("backgrid:refresh",this),this},render:function(){this.$el.empty();for(var a=document.createDocumentFragment(),b=0;b<this.rows.length;b++){var c=this.rows[b];a.appendChild(c.render().el)}return this.el.appendChild(a),this.delegateEvents(),this},remove:function(){for(var a=0;a<this.rows.length;a++){var b=this.rows[a];b.remove.apply(b,arguments)}return c.View.prototype.remove.apply(this,arguments)},sort:function(a,d){if(!b.contains(["ascending","descending",null],d))throw new RangeError('direction must be one of "ascending", "descending" or `nu ll`');b.isString(a)&&(a=this.columns.findWhere({name:a}));var e,f=this.collection;e="ascending"===d?-1:"descending"===d?1:null;var g=this.makeComparator(a.get("name"),e,e?a.sortValue():function(a){return 1*a.cid.replace("c","")});return c.PageableCollection&&f instanceof c.PageableCollection?(f.setSorting(e&&a.get("name"),e,{sortValue:a.sortValue()}),f.fullCollection?(null==f.fullCollection.comparator&&(f.fullCollection.comparator=g),f.fullCollection.sort(),f.trigger("backgrid:sorted",a,d,f)):f.fetch({reset:!0,success:function(){f.trigger("backgrid:sorted",a,d,f)}})):(f.comparator=g,f.sort(),f.trigger("backgrid:sorted",a,d,f)),a.set("direction",d),this},makeComparator:function(a,b,c){return function(d,e){var f,g=c(d,a),h=c(e,a);return 1===b&&(f=g,g=h,h=f),g===h?0:h>g?-1:1}},moveToNextCell:function(a,b,c){var d,e,f,g,h,j=this.collection.indexOf(a),k=this.columns.indexOf(b);if(this.rows[j].cells[k].exitEditMode(),c.moveUp()||c.moveDown()||c.moveLeft()||c.moveRight()||c.save()){var l=t his.columns.length,m=l*this.collection.length;if(c.moveUp()||c.moveDown()){g=j+(c.moveUp()?-1:1);var n=this.rows[g];n?(d=n.cells[k],i.callByNeed(d.column.editable(),d.column,a)&&(d.enterEditMode(),a.trigger("backgrid:next",g,k,!1))):a.trigger("backgrid:next",g,k,!0)}else if(c.moveLeft()||c.moveRight()){for(var o=c.moveRight(),p=j*l+k+(o?1:-1);p>=0&&m>p;o?p++:p--)if(g=~~(p/l),h=p-g*l,d=this.rows[g].cells[h],e=i.callByNeed(d.column.renderable(),d.column,d.model),f=i.callByNeed(d.column.editable(),d.column,a),e&&f){d.enterEditMode(),a.trigger("backgrid:next",g,h,!1);break}p==m&&a.trigger("backgrid:next",~~(p/l),p-g*l,!0)}}return this}});i.Footer=c.View.extend({tagName:"tfoot",initialize:function(a){this.columns=a.columns,this.columns instanceof c.Collection||(this.columns=new i.Columns(this.columns))}}),i.Grid=c.View.extend({tagName:"table",className:"backgrid",header:H,body:I,footer:null,initialize:function(a){a.columns instanceof c.Collection||(a.columns=new D(a.columns)),this.column s=a.columns;var d=b.omit(a,["el","id","attributes","className","tagName","events"]);this.body=a.body||this.body,this.body=new this.body(d),this.header=a.header||this.header,this.header&&(this.header=new this.header(d)),this.footer=a.footer||this.footer,this.footer&&(this.footer=new this.footer(d)),this.listenTo(this.columns,"reset",function(){this.header&&(this.header=new(this.header.remove().constructor)(d)),this.body=new(this.body.remove().constructor)(d),this.footer&&(this.footer=new(this.footer.remove().constructor)(d)),this.render()})},insertRow:function(){return this.body.insertRow.apply(this.body,arguments),this},removeRow:function(){return this.body.removeRow.apply(this.body,arguments),this},insertColumn:function(){return this.columns.add.apply(this.columns,arguments),this},removeColumn:function(){return this.columns.remove.apply(this.columns,arguments),this},sort:function(){return this.body.sort.apply(this.body,arguments),this},render:function(){return this.$el.empty(),this .header&&this.$el.append(this.header.render().$el),this.footer&&this.$el.append(this.footer.render().$el),this.$el.append(this.body.render().$el),this.delegateEvents(),this.trigger("backgrid:rendered",this),this},remove:function(){return this.header&&this.header.remove.apply(this.header,arguments),this.body.remove.apply(this.body,arguments),this.footer&&this.footer.remove.apply(this.footer,arguments),c.View.prototype.remove.apply(this,arguments)}})}return i}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/js/backgrid-paginator.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/js/backgrid-paginator.js b/htrace-core/src/web/lib/js/backgrid-paginator.js new file mode 100644 index 0000000..64dd434 --- /dev/null +++ b/htrace-core/src/web/lib/js/backgrid-paginator.js @@ -0,0 +1,433 @@ +/* + backgrid-paginator + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT @license. +*/ +(function (root, factory) { + + // CommonJS + if (typeof exports == "object") { + module.exports = factory(require("underscore"), + require("backbone"), + require("backgrid"), + require("backbone.paginator")); + } + // AMD. Register as an anonymous module. + else if (typeof define === 'function' && define.amd) { + define(['underscore', 'backbone', 'backgrid', 'backbone.paginator'], factory); + } + // Browser + else { + factory(root._, root.Backbone, root.Backgrid); + } + +}(this, function (_, Backbone, Backgrid) { + + "use strict"; + + /** + PageHandle is a class that renders the actual page handles and reacts to + click events for pagination. + + This class acts in two modes - control or discrete page handle modes. If + one of the `is*` flags is `true`, an instance of this class is under + control page handle mode. Setting a `pageIndex` to an instance of this + class under control mode has no effect and the correct page index will + always be inferred from the `is*` flag. Only one of the `is*` flags should + be set to `true` at a time. For example, an instance of this class cannot + simultaneously be a rewind control and a fast forward control. A `label` + and a `title` function or a string are required to be passed to the + constuctor under this mode. If a `title` function is provided, it __MUST__ + accept a hash parameter `data`, which contains a key `label`. Its result + will be used to render the generated anchor's title attribute. + + If all of the `is*` flags is set to `false`, which is the default, an + instance of this class will be in discrete page handle mode. An instance + under this mode requires the `pageIndex` to be passed from the constructor + as an option and it __MUST__ be a 0-based index of the list of page numbers + to render. The constuctor will normalize the base to the same base the + underlying PageableCollection collection instance uses. A `label` is not + required under this mode, which will default to the equivalent 1-based page + index calculated from `pageIndex` and the underlying PageableCollection + instance. A provided `label` will still be honored however. The `title` + parameter is also not required under this mode, in which case the default + `title` function will be used. You are encouraged to provide your own + `title` function however if you wish to localize the title strings. + + If this page handle represents the current page, an `active` class will be + placed on the root list element. + + If this page handle is at the border of the list of pages, a `disabled` + class will be placed on the root list element. + + Only page handles that are neither `active` nor `disabled` will respond to + click events and triggers pagination. + + @class Backgrid.Extension.PageHandle + */ + var PageHandle = Backgrid.Extension.PageHandle = Backbone.View.extend({ + + /** @property */ + tagName: "li", + + /** @property */ + events: { + "click a": "changePage" + }, + + /** + @property {string|function(Object.<string, string>): string} title + The title to use for the `title` attribute of the generated page handle + anchor elements. It can be a string or a function that takes a `data` + parameter, which contains a mandatory `label` key which provides the + label value to be displayed. + */ + title: function (data) { + return 'Page ' + data.label; + }, + + /** + @property {boolean} isRewind Whether this handle represents a rewind + control + */ + isRewind: false, + + /** + @property {boolean} isBack Whether this handle represents a back + control + */ + isBack: false, + + /** + @property {boolean} isForward Whether this handle represents a forward + control + */ + isForward: false, + + /** + @property {boolean} isFastForward Whether this handle represents a fast + forward control + */ + isFastForward: false, + + /** + Initializer. + + @param {Object} options + @param {Backbone.Collection} options.collection + @param {number} pageIndex 0-based index of the page number this handle + handles. This parameter will be normalized to the base the underlying + PageableCollection uses. + @param {string} [options.label] If provided it is used to render the + anchor text, otherwise the normalized pageIndex will be used + instead. Required if any of the `is*` flags is set to `true`. + @param {string} [options.title] + @param {boolean} [options.isRewind=false] + @param {boolean} [options.isBack=false] + @param {boolean} [options.isForward=false] + @param {boolean} [options.isFastForward=false] + */ + initialize: function (options) { + var collection = this.collection; + var state = collection.state; + var currentPage = state.currentPage; + var firstPage = state.firstPage; + var lastPage = state.lastPage; + + _.extend(this, _.pick(options, + ["isRewind", "isBack", "isForward", "isFastForward"])); + + var pageIndex; + if (this.isRewind) pageIndex = firstPage; + else if (this.isBack) pageIndex = Math.max(firstPage, currentPage - 1); + else if (this.isForward) pageIndex = Math.min(lastPage, currentPage + 1); + else if (this.isFastForward) pageIndex = lastPage; + else { + pageIndex = +options.pageIndex; + pageIndex = (firstPage ? pageIndex + 1 : pageIndex); + } + this.pageIndex = pageIndex; + + this.label = (options.label || (firstPage ? pageIndex : pageIndex + 1)) + ''; + var title = options.title || this.title; + this.title = _.isFunction(title) ? title({label: this.label}) : title; + }, + + /** + Renders a clickable anchor element under a list item. + */ + render: function () { + this.$el.empty(); + var anchor = document.createElement("a"); + anchor.href = '#'; + if (this.title) anchor.title = this.title; + anchor.innerHTML = this.label; + this.el.appendChild(anchor); + + var collection = this.collection; + var state = collection.state; + var currentPage = state.currentPage; + var pageIndex = this.pageIndex; + + if (this.isRewind && currentPage == state.firstPage || + this.isBack && !collection.hasPreviousPage() || + this.isForward && !collection.hasNextPage() || + this.isFastForward && (currentPage == state.lastPage || state.totalPages < 1)) { + this.$el.addClass("disabled"); + } + else if (!(this.isRewind || + this.isBack || + this.isForward || + this.isFastForward) && + state.currentPage == pageIndex) { + this.$el.addClass("active"); + } + + this.delegateEvents(); + return this; + }, + + /** + jQuery click event handler. Goes to the page this PageHandle instance + represents. No-op if this page handle is currently active or disabled. + */ + changePage: function (e) { + e.preventDefault(); + var $el = this.$el, col = this.collection; + if (!$el.hasClass("active") && !$el.hasClass("disabled")) { + if (this.isRewind) col.getFirstPage(); + else if (this.isBack) col.getPreviousPage(); + else if (this.isForward) col.getNextPage(); + else if (this.isFastForward) col.getLastPage(); + else col.getPage(this.pageIndex, {reset: true}); + } + return this; + } + + }); + + /** + Paginator is a Backgrid extension that renders a series of configurable + pagination handles. This extension is best used for splitting a large data + set across multiple pages. If the number of pages is larger then a + threshold, which is set to 10 by default, the page handles are rendered + within a sliding window, plus the rewind, back, forward and fast forward + control handles. The individual control handles can be turned off. + + @class Backgrid.Extension.Paginator + */ + var Paginator = Backgrid.Extension.Paginator = Backbone.View.extend({ + + /** @property */ + className: "backgrid-paginator", + + /** @property */ + windowSize: 10, + + /** + @property {number} slideScale the number used by #slideHowMuch to scale + `windowSize` to yield the number of pages to slide. For example, the + default windowSize(10) * slideScale(0.5) yields 5, which means the window + will slide forward 5 pages as soon as you've reached page 6. The smaller + the scale factor the less pages to slide, and vice versa. + + Also See: + + - #slideMaybe + - #slideHowMuch + */ + slideScale: 0.5, + + /** + @property {Object.<string, Object.<string, string>>} controls You can + disable specific control handles by setting the keys in question to + null. The defaults will be merged with your controls object, with your + changes taking precedent. + */ + controls: { + rewind: { + label: "ã", + title: "First" + }, + back: { + label: "ã", + title: "Previous" + }, + forward: { + label: "ã", + title: "Next" + }, + fastForward: { + label: "ã", + title: "Last" + } + }, + + /** @property */ + renderIndexedPageHandles: true, + + /** + @property {Backgrid.Extension.PageHandle} pageHandle. The PageHandle + class to use for rendering individual handles + */ + pageHandle: PageHandle, + + /** @property */ + goBackFirstOnSort: true, + + /** + Initializer. + + @param {Object} options + @param {Backbone.Collection} options.collection + @param {boolean} [options.controls] + @param {boolean} [options.pageHandle=Backgrid.Extension.PageHandle] + @param {boolean} [options.goBackFirstOnSort=true] + */ + initialize: function (options) { + var self = this; + self.controls = _.defaults(options.controls || {}, self.controls, + Paginator.prototype.controls); + + _.extend(self, _.pick(options || {}, "windowSize", "pageHandle", + "slideScale", "goBackFirstOnSort", + "renderIndexedPageHandles")); + + var col = self.collection; + self.listenTo(col, "add", self.render); + self.listenTo(col, "remove", self.render); + self.listenTo(col, "reset", self.render); + self.listenTo(col, "backgrid:sorted", function () { + if (self.goBackFirstOnSort) col.getFirstPage({reset: true}); + }); + }, + + /** + Decides whether the window should slide. This method should return 1 if + sliding should occur and 0 otherwise. The default is sliding should occur + if half of the pages in a window has been reached. + + __Note__: All the parameters have been normalized to be 0-based. + + @param {number} firstPage + @param {number} lastPage + @param {number} currentPage + @param {number} windowSize + @param {number} slideScale + + @return {0|1} + */ + slideMaybe: function (firstPage, lastPage, currentPage, windowSize, slideScale) { + return Math.round(currentPage % windowSize / windowSize); + }, + + /** + Decides how many pages to slide when sliding should occur. The default + simply scales the `windowSize` to arrive at a fraction of the `windowSize` + to increment. + + __Note__: All the parameters have been normalized to be 0-based. + + @param {number} firstPage + @param {number} lastPage + @param {number} currentPage + @param {number} windowSize + @param {number} slideScale + + @return {number} + */ + slideThisMuch: function (firstPage, lastPage, currentPage, windowSize, slideScale) { + return ~~(windowSize * slideScale); + }, + + _calculateWindow: function () { + var collection = this.collection; + var state = collection.state; + + // convert all indices to 0-based here + var firstPage = state.firstPage; + var lastPage = +state.lastPage; + lastPage = Math.max(0, firstPage ? lastPage - 1 : lastPage); + var currentPage = Math.max(state.currentPage, state.firstPage); + currentPage = firstPage ? currentPage - 1 : currentPage; + var windowSize = this.windowSize; + var slideScale = this.slideScale; + var windowStart = Math.floor(currentPage / windowSize) * windowSize; + if (currentPage <= lastPage - this.slideThisMuch()) { + windowStart += (this.slideMaybe(firstPage, lastPage, currentPage, windowSize, slideScale) * + this.slideThisMuch(firstPage, lastPage, currentPage, windowSize, slideScale)); + } + var windowEnd = Math.min(lastPage + 1, windowStart + windowSize); + return [windowStart, windowEnd]; + }, + + /** + Creates a list of page handle objects for rendering. + + @return {Array.<Object>} an array of page handle objects hashes + */ + makeHandles: function () { + + var handles = []; + var collection = this.collection; + + var window = this._calculateWindow(); + var winStart = window[0], winEnd = window[1]; + + if (this.renderIndexedPageHandles) { + for (var i = winStart; i < winEnd; i++) { + handles.push(new this.pageHandle({ + collection: collection, + pageIndex: i + })); + } + } + + var controls = this.controls; + _.each(["back", "rewind", "forward", "fastForward"], function (key) { + var value = controls[key]; + if (value) { + var handleCtorOpts = { + collection: collection, + title: value.title, + label: value.label + }; + handleCtorOpts["is" + key.slice(0, 1).toUpperCase() + key.slice(1)] = true; + var handle = new this.pageHandle(handleCtorOpts); + if (key == "rewind" || key == "back") handles.unshift(handle); + else handles.push(handle); + } + }, this); + + return handles; + }, + + /** + Render the paginator handles inside an unordered list. + */ + render: function () { + this.$el.empty(); + + if (this.handles) { + for (var i = 0, l = this.handles.length; i < l; i++) { + this.handles[i].remove(); + } + } + + var handles = this.handles = this.makeHandles(); + + var ul = document.createElement("ul"); + for (var i = 0; i < handles.length; i++) { + ul.appendChild(handles[i].render().el); + } + + this.el.appendChild(ul); + + return this; + } + + }); + +})); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-htrace/blob/83053c8b/htrace-core/src/web/lib/js/backgrid-paginator.min.js ---------------------------------------------------------------------- diff --git a/htrace-core/src/web/lib/js/backgrid-paginator.min.js b/htrace-core/src/web/lib/js/backgrid-paginator.min.js new file mode 100644 index 0000000..5d3bc0b --- /dev/null +++ b/htrace-core/src/web/lib/js/backgrid-paginator.min.js @@ -0,0 +1,9 @@ +/* + backgrid-paginator + http://github.com/wyuenho/backgrid + + Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors + Licensed under the MIT @license. + */ +// Trunk from Commit ID: 669bca9383f1cafa53dc0efefe96a83c5315684d. +!function(a,b){"object"==typeof exports&&(module.exports=b(require("underscore"),require("backbone"),require("backgrid"),require("backbone.paginator"))),"function"==typeof define&&define.amd?define(["underscore","backbone","backgrid","backbone.paginator"],b):b(a._,a.Backbone,a.Backgrid)}(this,function(a,b,c){"use strict";var d=c.Extension.PageHandle=b.View.extend({tagName:"li",events:{"click a":"changePage"},title:function(a){return"Page "+a.label},isRewind:!1,isBack:!1,isForward:!1,isFastForward:!1,initialize:function(b){var c=this.collection,d=c.state,e=d.currentPage,f=d.firstPage,g=d.lastPage;a.extend(this,a.pick(b,["isRewind","isBack","isForward","isFastForward"]));var h;this.isRewind?h=f:this.isBack?h=Math.max(f,e-1):this.isForward?h=Math.min(g,e+1):this.isFastForward?h=g:(h=+b.pageIndex,h=f?h+1:h),this.pageIndex=h,this.label=(b.label||(f?h:h+1))+"";var i=b.title||this.title;this.title=a.isFunction(i)?i({label:this.label}):i},render:function(){this.$el.empty();var a=document.cr eateElement("a");a.href="#",this.title&&(a.title=this.title),a.innerHTML=this.label,this.el.appendChild(a);var b=this.collection,c=b.state,d=c.currentPage,e=this.pageIndex;return this.isRewind&&d==c.firstPage||this.isBack&&!b.hasPreviousPage()||this.isForward&&!b.hasNextPage()||this.isFastForward&&(d==c.lastPage||c.totalPages<1)?this.$el.addClass("disabled"):this.isRewind||this.isBack||this.isForward||this.isFastForward||c.currentPage!=e||this.$el.addClass("active"),this.delegateEvents(),this},changePage:function(a){a.preventDefault();var b=this.$el,c=this.collection;return b.hasClass("active")||b.hasClass("disabled")||(this.isRewind?c.getFirstPage():this.isBack?c.getPreviousPage():this.isForward?c.getNextPage():this.isFastForward?c.getLastPage():c.getPage(this.pageIndex,{reset:!0})),this}}),e=c.Extension.Paginator=b.View.extend({className:"backgrid-paginator",windowSize:10,slideScale:.5,controls:{rewind:{label:"ã",title:"First"},back:{label:"ã",title:"Previous"},forward:{label: "ã",title:"Next"},fastForward:{label:"ã",title:"Last"}},renderIndexedPageHandles:!0,pageHandle:d,goBackFirstOnSort:!0,initialize:function(b){var c=this;c.controls=a.defaults(b.controls||{},c.controls,e.prototype.controls),a.extend(c,a.pick(b||{},"windowSize","pageHandle","slideScale","goBackFirstOnSort","renderIndexedPageHandles"));var d=c.collection;c.listenTo(d,"add",c.render),c.listenTo(d,"remove",c.render),c.listenTo(d,"reset",c.render),c.listenTo(d,"backgrid:sorted",function(){c.goBackFirstOnSort&&d.getFirstPage({reset:!0})})},slideMaybe:function(a,b,c,d){return Math.round(c%d/d)},slideThisMuch:function(a,b,c,d,e){return~~(d*e)},_calculateWindow:function(){var a=this.collection,b=a.state,c=b.firstPage,d=+b.lastPage;d=Math.max(0,c?d-1:d);var e=Math.max(b.currentPage,b.firstPage);e=c?e-1:e;var f=this.windowSize,g=this.slideScale,h=Math.floor(e/f)*f;e<=d-this.slideThisMuch()&&(h+=this.slideMaybe(c,d,e,f,g)*this.slideThisMuch(c,d,e,f,g));var i=Math.min(d+1,h+f);return[h,i]},mak eHandles:function(){var b=[],c=this.collection,d=this._calculateWindow(),e=d[0],f=d[1];if(this.renderIndexedPageHandles)for(var g=e;f>g;g++)b.push(new this.pageHandle({collection:c,pageIndex:g}));var h=this.controls;return a.each(["back","rewind","forward","fastForward"],function(a){var d=h[a];if(d){var e={collection:c,title:d.title,label:d.label};e["is"+a.slice(0,1).toUpperCase()+a.slice(1)]=!0;var f=new this.pageHandle(e);"rewind"==a||"back"==a?b.unshift(f):b.push(f)}},this),b},render:function(){if(this.$el.empty(),this.handles)for(var a=0,b=this.handles.length;b>a;a++)this.handles[a].remove();for(var c=this.handles=this.makeHandles(),d=document.createElement("ul"),a=0;a<c.length;a++)d.appendChild(c[a].render().el);return this.el.appendChild(d),this}})}); \ No newline at end of file
