blazer 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/blazer.gemspec CHANGED
@@ -21,6 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "rails"
22
22
  spec.add_dependency "chartkick"
23
23
  spec.add_dependency "safely_block", ">= 0.1.1"
24
+ spec.add_dependency "js-routes"
25
+ spec.add_dependency "gon"
24
26
 
25
27
  spec.add_development_dependency "bundler", "~> 1.7"
26
28
  spec.add_development_dependency "rake", "~> 10.0"
data/lib/blazer.rb CHANGED
@@ -2,6 +2,8 @@ require "csv"
2
2
  require "yaml"
3
3
  require "chartkick"
4
4
  require "safely/core"
5
+ require "js-routes"
6
+ require "gon"
5
7
  require "blazer/version"
6
8
  require "blazer/data_source"
7
9
  require "blazer/result"
@@ -34,7 +34,7 @@ module Blazer
34
34
  rescue => e
35
35
  error = e.message.sub(/.+ERROR: /, "")
36
36
  error = Blazer::TIMEOUT_MESSAGE if Blazer::TIMEOUT_ERRORS.any? { |e| error.include?(e) }
37
- reconnect if error.include?("can't get socket descriptor")
37
+ reconnect if error.include?("PG::ConnectionBad")
38
38
  end
39
39
 
40
40
  [columns, rows, error]
@@ -47,7 +47,7 @@ module Blazer
47
47
 
48
48
  def schema
49
49
  result = data_source.run_statement(connection_model.send(:sanitize_sql_array, ["SELECT table_schema, table_name, column_name, data_type, ordinal_position FROM information_schema.columns WHERE table_schema IN (?) ORDER BY 1, 2", schemas]))
50
- result.rows.group_by { |r| [r[0], r[1]] }.map { |k, vs| {schema: k[0], table: k[1], columns: vs.sort_by { |v| v[4].to_i }.map { |v| {name: v[2], data_type: v[3]} }} }
50
+ result.rows.group_by { |r| [r[0], r[1]] }.map { |k, vs| {schema: k[0], table: k[1], columns: vs.sort_by { |v| v[2] }.map { |v| {name: v[2], data_type: v[3]} }} }
51
51
  end
52
52
 
53
53
  def preview_statement
@@ -13,7 +13,7 @@ module Blazer
13
13
  @settings = settings
14
14
 
15
15
  unless settings["url"] || Rails.env.development?
16
- raise Blazer::Error, "Empty url"
16
+ raise Blazer::Error, "Empty url for data source: #{id}"
17
17
  end
18
18
 
19
19
  @adapter_instance =
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "1.7.0"
2
+ VERSION = "1.7.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-08 00:00:00.000000000 Z
11
+ date: 2016-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: js-routes
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: gon
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: bundler
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +128,7 @@ files:
100
128
  - app/assets/fonts/blazer/glyphicons-halflings-regular.woff2
101
129
  - app/assets/javascripts/blazer/Chart.js
102
130
  - app/assets/javascripts/blazer/Sortable.js
131
+ - app/assets/javascripts/blazer/ace.js
103
132
  - app/assets/javascripts/blazer/ace/ace.js
104
133
  - app/assets/javascripts/blazer/ace/ext-language_tools.js
105
134
  - app/assets/javascripts/blazer/ace/mode-sql.js
@@ -114,11 +143,12 @@ files:
114
143
  - app/assets/javascripts/blazer/jquery.js
115
144
  - app/assets/javascripts/blazer/jquery.stickytableheaders.js
116
145
  - app/assets/javascripts/blazer/jquery_ujs.js
117
- - app/assets/javascripts/blazer/list.js
118
146
  - app/assets/javascripts/blazer/moment-timezone.js
119
147
  - app/assets/javascripts/blazer/moment.js
148
+ - app/assets/javascripts/blazer/routes.js.erb
120
149
  - app/assets/javascripts/blazer/selectize.js
121
150
  - app/assets/javascripts/blazer/stupidtable.js
151
+ - app/assets/javascripts/blazer/vue.js
122
152
  - app/assets/stylesheets/blazer/application.css
123
153
  - app/assets/stylesheets/blazer/bootstrap.css.erb
124
154
  - app/assets/stylesheets/blazer/daterangepicker-bs3.css
@@ -137,6 +167,7 @@ files:
137
167
  - app/models/blazer/dashboard_query.rb
138
168
  - app/models/blazer/query.rb
139
169
  - app/views/blazer/_nav.html.erb
170
+ - app/views/blazer/_variables.html.erb
140
171
  - app/views/blazer/check_mailer/failing_checks.html.erb
141
172
  - app/views/blazer/check_mailer/state_change.html.erb
142
173
  - app/views/blazer/checks/_form.html.erb
@@ -1,1258 +0,0 @@
1
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
- /*
3
- List.js 1.1.1
4
- By Jonny Strömberg (www.jonnystromberg.com, www.listjs.com)
5
- */
6
- (function( window, undefined ) {
7
- "use strict";
8
-
9
- var document = window.document,
10
- getByClass = require('./src/utils/get-by-class'),
11
- extend = require('./src/utils/extend'),
12
- indexOf = require('./src/utils/index-of'),
13
- events = require('./src/utils/events'),
14
- toString = require('./src/utils/to-string'),
15
- naturalSort = require('./src/utils/natural-sort'),
16
- classes = require('./src/utils/classes'),
17
- getAttribute = require('./src/utils/get-attribute'),
18
- toArray = require('./src/utils/to-array');
19
-
20
- var List = function(id, options, values) {
21
-
22
- var self = this,
23
- init,
24
- Item = require('./src/item')(self),
25
- addAsync = require('./src/add-async')(self);
26
-
27
- init = {
28
- start: function() {
29
- self.listClass = "list";
30
- self.searchClass = "search";
31
- self.sortClass = "sort";
32
- self.page = 10000;
33
- self.i = 1;
34
- self.items = [];
35
- self.visibleItems = [];
36
- self.matchingItems = [];
37
- self.searched = false;
38
- self.filtered = false;
39
- self.searchColumns = undefined;
40
- self.handlers = { 'updated': [] };
41
- self.plugins = {};
42
- self.valueNames = [];
43
- self.utils = {
44
- getByClass: getByClass,
45
- extend: extend,
46
- indexOf: indexOf,
47
- events: events,
48
- toString: toString,
49
- naturalSort: naturalSort,
50
- classes: classes,
51
- getAttribute: getAttribute,
52
- toArray: toArray
53
- };
54
-
55
- self.utils.extend(self, options);
56
-
57
- self.listContainer = (typeof(id) === 'string') ? document.getElementById(id) : id;
58
- if (!self.listContainer) { return; }
59
- self.list = getByClass(self.listContainer, self.listClass, true);
60
-
61
- self.parse = require('./src/parse')(self);
62
- self.templater = require('./src/templater')(self);
63
- self.search = require('./src/search')(self);
64
- self.filter = require('./src/filter')(self);
65
- self.sort = require('./src/sort')(self);
66
-
67
- this.handlers();
68
- this.items();
69
- self.update();
70
- this.plugins();
71
- },
72
- handlers: function() {
73
- for (var handler in self.handlers) {
74
- if (self[handler]) {
75
- self.on(handler, self[handler]);
76
- }
77
- }
78
- },
79
- items: function() {
80
- self.parse(self.list);
81
- if (values !== undefined) {
82
- self.add(values);
83
- }
84
- },
85
- plugins: function() {
86
- for (var i = 0; i < self.plugins.length; i++) {
87
- var plugin = self.plugins[i];
88
- self[plugin.name] = plugin;
89
- plugin.init(self, List);
90
- }
91
- }
92
- };
93
-
94
- /*
95
- * Re-parse the List, use if html have changed
96
- */
97
- this.reIndex = function() {
98
- self.items = [];
99
- self.visibleItems = [];
100
- self.matchingItems = [];
101
- self.searched = false;
102
- self.filtered = false;
103
- self.parse(self.list);
104
- };
105
-
106
- this.toJSON = function() {
107
- var json = [];
108
- for (var i = 0, il = self.items.length; i < il; i++) {
109
- json.push(self.items[i].values());
110
- }
111
- return json;
112
- };
113
-
114
-
115
- /*
116
- * Add object to list
117
- */
118
- this.add = function(values, callback) {
119
- if (values.length === 0) {
120
- return;
121
- }
122
- if (callback) {
123
- addAsync(values, callback);
124
- return;
125
- }
126
- var added = [],
127
- notCreate = false;
128
- if (values[0] === undefined){
129
- values = [values];
130
- }
131
- for (var i = 0, il = values.length; i < il; i++) {
132
- var item = null;
133
- notCreate = (self.items.length > self.page) ? true : false;
134
- item = new Item(values[i], undefined, notCreate);
135
- self.items.push(item);
136
- added.push(item);
137
- }
138
- self.update();
139
- return added;
140
- };
141
-
142
- this.show = function(i, page) {
143
- this.i = i;
144
- this.page = page;
145
- self.update();
146
- return self;
147
- };
148
-
149
- /* Removes object from list.
150
- * Loops through the list and removes objects where
151
- * property "valuename" === value
152
- */
153
- this.remove = function(valueName, value, options) {
154
- var found = 0;
155
- for (var i = 0, il = self.items.length; i < il; i++) {
156
- if (self.items[i].values()[valueName] == value) {
157
- self.templater.remove(self.items[i], options);
158
- self.items.splice(i,1);
159
- il--;
160
- i--;
161
- found++;
162
- }
163
- }
164
- self.update();
165
- return found;
166
- };
167
-
168
- /* Gets the objects in the list which
169
- * property "valueName" === value
170
- */
171
- this.get = function(valueName, value) {
172
- var matchedItems = [];
173
- for (var i = 0, il = self.items.length; i < il; i++) {
174
- var item = self.items[i];
175
- if (item.values()[valueName] == value) {
176
- matchedItems.push(item);
177
- }
178
- }
179
- return matchedItems;
180
- };
181
-
182
- /*
183
- * Get size of the list
184
- */
185
- this.size = function() {
186
- return self.items.length;
187
- };
188
-
189
- /*
190
- * Removes all items from the list
191
- */
192
- this.clear = function() {
193
- self.templater.clear();
194
- self.items = [];
195
- return self;
196
- };
197
-
198
- this.on = function(event, callback) {
199
- self.handlers[event].push(callback);
200
- return self;
201
- };
202
-
203
- this.off = function(event, callback) {
204
- var e = self.handlers[event];
205
- var index = indexOf(e, callback);
206
- if (index > -1) {
207
- e.splice(index, 1);
208
- }
209
- return self;
210
- };
211
-
212
- this.trigger = function(event) {
213
- var i = self.handlers[event].length;
214
- while(i--) {
215
- self.handlers[event][i](self);
216
- }
217
- return self;
218
- };
219
-
220
- this.reset = {
221
- filter: function() {
222
- var is = self.items,
223
- il = is.length;
224
- while (il--) {
225
- is[il].filtered = false;
226
- }
227
- return self;
228
- },
229
- search: function() {
230
- var is = self.items,
231
- il = is.length;
232
- while (il--) {
233
- is[il].found = false;
234
- }
235
- return self;
236
- }
237
- };
238
-
239
- this.update = function() {
240
- var is = self.items,
241
- il = is.length;
242
-
243
- self.visibleItems = [];
244
- self.matchingItems = [];
245
- self.templater.clear();
246
- for (var i = 0; i < il; i++) {
247
- if (is[i].matching() && ((self.matchingItems.length+1) >= self.i && self.visibleItems.length < self.page)) {
248
- is[i].show();
249
- self.visibleItems.push(is[i]);
250
- self.matchingItems.push(is[i]);
251
- } else if (is[i].matching()) {
252
- self.matchingItems.push(is[i]);
253
- is[i].hide();
254
- } else {
255
- is[i].hide();
256
- }
257
- }
258
- self.trigger('updated');
259
- return self;
260
- };
261
-
262
- init.start();
263
- };
264
-
265
-
266
- // AMD support
267
- if (typeof define === 'function' && define.amd) {
268
- define(function () { return List; });
269
- }
270
- module.exports = List;
271
- window.List = List;
272
-
273
- })(window);
274
-
275
- },{"./src/add-async":2,"./src/filter":3,"./src/item":4,"./src/parse":5,"./src/search":6,"./src/sort":7,"./src/templater":8,"./src/utils/classes":9,"./src/utils/events":10,"./src/utils/extend":11,"./src/utils/get-attribute":12,"./src/utils/get-by-class":13,"./src/utils/index-of":14,"./src/utils/natural-sort":15,"./src/utils/to-array":16,"./src/utils/to-string":17}],2:[function(require,module,exports){
276
- module.exports = function(list) {
277
- var addAsync = function(values, callback, items) {
278
- var valuesToAdd = values.splice(0, 50);
279
- items = items || [];
280
- items = items.concat(list.add(valuesToAdd));
281
- if (values.length > 0) {
282
- setTimeout(function() {
283
- addAsync(values, callback, items);
284
- }, 1);
285
- } else {
286
- list.update();
287
- callback(items);
288
- }
289
- };
290
- return addAsync;
291
- };
292
-
293
- },{}],3:[function(require,module,exports){
294
- module.exports = function(list) {
295
-
296
- // Add handlers
297
- list.handlers.filterStart = list.handlers.filterStart || [];
298
- list.handlers.filterComplete = list.handlers.filterComplete || [];
299
-
300
- return function(filterFunction) {
301
- list.trigger('filterStart');
302
- list.i = 1; // Reset paging
303
- list.reset.filter();
304
- if (filterFunction === undefined) {
305
- list.filtered = false;
306
- } else {
307
- list.filtered = true;
308
- var is = list.items;
309
- for (var i = 0, il = is.length; i < il; i++) {
310
- var item = is[i];
311
- if (filterFunction(item)) {
312
- item.filtered = true;
313
- } else {
314
- item.filtered = false;
315
- }
316
- }
317
- }
318
- list.update();
319
- list.trigger('filterComplete');
320
- return list.visibleItems;
321
- };
322
- };
323
-
324
- },{}],4:[function(require,module,exports){
325
- module.exports = function(list) {
326
- return function(initValues, element, notCreate) {
327
- var item = this;
328
-
329
- this._values = {};
330
-
331
- this.found = false; // Show if list.searched == true and this.found == true
332
- this.filtered = false;// Show if list.filtered == true and this.filtered == true
333
-
334
- var init = function(initValues, element, notCreate) {
335
- if (element === undefined) {
336
- if (notCreate) {
337
- item.values(initValues, notCreate);
338
- } else {
339
- item.values(initValues);
340
- }
341
- } else {
342
- item.elm = element;
343
- var values = list.templater.get(item, initValues);
344
- item.values(values);
345
- }
346
- };
347
-
348
- this.values = function(newValues, notCreate) {
349
- if (newValues !== undefined) {
350
- for(var name in newValues) {
351
- item._values[name] = newValues[name];
352
- }
353
- if (notCreate !== true) {
354
- list.templater.set(item, item.values());
355
- }
356
- } else {
357
- return item._values;
358
- }
359
- };
360
-
361
- this.show = function() {
362
- list.templater.show(item);
363
- };
364
-
365
- this.hide = function() {
366
- list.templater.hide(item);
367
- };
368
-
369
- this.matching = function() {
370
- return (
371
- (list.filtered && list.searched && item.found && item.filtered) ||
372
- (list.filtered && !list.searched && item.filtered) ||
373
- (!list.filtered && list.searched && item.found) ||
374
- (!list.filtered && !list.searched)
375
- );
376
- };
377
-
378
- this.visible = function() {
379
- return (item.elm && (item.elm.parentNode == list.list)) ? true : false;
380
- };
381
-
382
- init(initValues, element, notCreate);
383
- };
384
- };
385
-
386
- },{}],5:[function(require,module,exports){
387
- module.exports = function(list) {
388
-
389
- var Item = require('./item')(list);
390
-
391
- var getChildren = function(parent) {
392
- var nodes = parent.childNodes,
393
- items = [];
394
- for (var i = 0, il = nodes.length; i < il; i++) {
395
- // Only textnodes have a data attribute
396
- if (nodes[i].data === undefined) {
397
- items.push(nodes[i]);
398
- }
399
- }
400
- return items;
401
- };
402
-
403
- var parse = function(itemElements, valueNames) {
404
- for (var i = 0, il = itemElements.length; i < il; i++) {
405
- list.items.push(new Item(valueNames, itemElements[i]));
406
- }
407
- };
408
- var parseAsync = function(itemElements, valueNames) {
409
- var itemsToIndex = itemElements.splice(0, 50); // TODO: If < 100 items, what happens in IE etc?
410
- parse(itemsToIndex, valueNames);
411
- if (itemElements.length > 0) {
412
- setTimeout(function() {
413
- parseAsync(itemElements, valueNames);
414
- }, 1);
415
- } else {
416
- list.update();
417
- list.trigger('parseComplete');
418
- }
419
- };
420
-
421
- list.handlers.parseComplete = list.handlers.parseComplete || [];
422
-
423
- return function() {
424
- var itemsToIndex = getChildren(list.list),
425
- valueNames = list.valueNames;
426
-
427
- if (list.indexAsync) {
428
- parseAsync(itemsToIndex, valueNames);
429
- } else {
430
- parse(itemsToIndex, valueNames);
431
- }
432
- };
433
- };
434
-
435
- },{"./item":4}],6:[function(require,module,exports){
436
- module.exports = function(list) {
437
- var item,
438
- text,
439
- columns,
440
- searchString,
441
- customSearch;
442
-
443
- var prepare = {
444
- resetList: function() {
445
- list.i = 1;
446
- list.templater.clear();
447
- customSearch = undefined;
448
- },
449
- setOptions: function(args) {
450
- if (args.length == 2 && args[1] instanceof Array) {
451
- columns = args[1];
452
- } else if (args.length == 2 && typeof(args[1]) == "function") {
453
- customSearch = args[1];
454
- } else if (args.length == 3) {
455
- columns = args[1];
456
- customSearch = args[2];
457
- }
458
- },
459
- setColumns: function() {
460
- if (list.items.length === 0) return;
461
- if (columns === undefined) {
462
- columns = (list.searchColumns === undefined) ? prepare.toArray(list.items[0].values()) : list.searchColumns;
463
- }
464
- },
465
- setSearchString: function(s) {
466
- s = list.utils.toString(s).toLowerCase();
467
- s = s.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&"); // Escape regular expression characters
468
- searchString = s;
469
- },
470
- toArray: function(values) {
471
- var tmpColumn = [];
472
- for (var name in values) {
473
- tmpColumn.push(name);
474
- }
475
- return tmpColumn;
476
- }
477
- };
478
- var search = {
479
- list: function() {
480
- for (var k = 0, kl = list.items.length; k < kl; k++) {
481
- search.item(list.items[k]);
482
- }
483
- },
484
- item: function(item) {
485
- item.found = false;
486
- for (var j = 0, jl = columns.length; j < jl; j++) {
487
- if (search.values(item.values(), columns[j])) {
488
- item.found = true;
489
- return;
490
- }
491
- }
492
- },
493
- values: function(values, column) {
494
- if (values.hasOwnProperty(column)) {
495
- text = list.utils.toString(values[column]).toLowerCase();
496
- if ((searchString !== "") && (text.search(searchString) > -1)) {
497
- return true;
498
- }
499
- }
500
- return false;
501
- },
502
- reset: function() {
503
- list.reset.search();
504
- list.searched = false;
505
- }
506
- };
507
-
508
- var searchMethod = function(str) {
509
- list.trigger('searchStart');
510
-
511
- prepare.resetList();
512
- prepare.setSearchString(str);
513
- prepare.setOptions(arguments); // str, cols|searchFunction, searchFunction
514
- prepare.setColumns();
515
-
516
- if (searchString === "" ) {
517
- search.reset();
518
- } else {
519
- list.searched = true;
520
- if (customSearch) {
521
- customSearch(searchString, columns);
522
- } else {
523
- search.list();
524
- }
525
- }
526
-
527
- list.update();
528
- list.trigger('searchComplete');
529
- return list.visibleItems;
530
- };
531
-
532
- list.handlers.searchStart = list.handlers.searchStart || [];
533
- list.handlers.searchComplete = list.handlers.searchComplete || [];
534
-
535
- list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'keyup', function(e) {
536
- var target = e.target || e.srcElement, // IE have srcElement
537
- alreadyCleared = (target.value === "" && !list.searched);
538
- if (!alreadyCleared) { // If oninput already have resetted the list, do nothing
539
- searchMethod(target.value);
540
- }
541
- });
542
-
543
- // Used to detect click on HTML5 clear button
544
- list.utils.events.bind(list.utils.getByClass(list.listContainer, list.searchClass), 'input', function(e) {
545
- var target = e.target || e.srcElement;
546
- if (target.value === "") {
547
- searchMethod('');
548
- }
549
- });
550
-
551
- return searchMethod;
552
- };
553
-
554
- },{}],7:[function(require,module,exports){
555
- module.exports = function(list) {
556
- list.sortFunction = list.sortFunction || function(itemA, itemB, options) {
557
- options.desc = options.order == "desc" ? true : false; // Natural sort uses this format
558
- return list.utils.naturalSort(itemA.values()[options.valueName], itemB.values()[options.valueName], options);
559
- };
560
-
561
- var buttons = {
562
- els: undefined,
563
- clear: function() {
564
- for (var i = 0, il = buttons.els.length; i < il; i++) {
565
- list.utils.classes(buttons.els[i]).remove('asc');
566
- list.utils.classes(buttons.els[i]).remove('desc');
567
- }
568
- },
569
- getOrder: function(btn) {
570
- var predefinedOrder = list.utils.getAttribute(btn, 'data-order');
571
- if (predefinedOrder == "asc" || predefinedOrder == "desc") {
572
- return predefinedOrder;
573
- } else if (list.utils.classes(btn).has('desc')) {
574
- return "asc";
575
- } else if (list.utils.classes(btn).has('asc')) {
576
- return "desc";
577
- } else {
578
- return "asc";
579
- }
580
- },
581
- getInSensitive: function(btn, options) {
582
- var insensitive = list.utils.getAttribute(btn, 'data-insensitive');
583
- if (insensitive === "false") {
584
- options.insensitive = false;
585
- } else {
586
- options.insensitive = true;
587
- }
588
- },
589
- setOrder: function(options) {
590
- for (var i = 0, il = buttons.els.length; i < il; i++) {
591
- var btn = buttons.els[i];
592
- if (list.utils.getAttribute(btn, 'data-sort') !== options.valueName) {
593
- continue;
594
- }
595
- var predefinedOrder = list.utils.getAttribute(btn, 'data-order');
596
- if (predefinedOrder == "asc" || predefinedOrder == "desc") {
597
- if (predefinedOrder == options.order) {
598
- list.utils.classes(btn).add(options.order);
599
- }
600
- } else {
601
- list.utils.classes(btn).add(options.order);
602
- }
603
- }
604
- }
605
- };
606
- var sort = function() {
607
- list.trigger('sortStart');
608
- var options = {};
609
-
610
- var target = arguments[0].currentTarget || arguments[0].srcElement || undefined;
611
-
612
- if (target) {
613
- options.valueName = list.utils.getAttribute(target, 'data-sort');
614
- buttons.getInSensitive(target, options);
615
- options.order = buttons.getOrder(target);
616
- } else {
617
- options = arguments[1] || options;
618
- options.valueName = arguments[0];
619
- options.order = options.order || "asc";
620
- options.insensitive = (typeof options.insensitive == "undefined") ? true : options.insensitive;
621
- }
622
- buttons.clear();
623
- buttons.setOrder(options);
624
-
625
- options.sortFunction = options.sortFunction || list.sortFunction;
626
- list.items.sort(function(a, b) {
627
- var mult = (options.order === 'desc') ? -1 : 1;
628
- return (options.sortFunction(a, b, options) * mult);
629
- });
630
- list.update();
631
- list.trigger('sortComplete');
632
- };
633
-
634
- // Add handlers
635
- list.handlers.sortStart = list.handlers.sortStart || [];
636
- list.handlers.sortComplete = list.handlers.sortComplete || [];
637
-
638
- buttons.els = list.utils.getByClass(list.listContainer, list.sortClass);
639
- list.utils.events.bind(buttons.els, 'click', sort);
640
- list.on('searchStart', buttons.clear);
641
- list.on('filterStart', buttons.clear);
642
-
643
- return sort;
644
- };
645
-
646
- },{}],8:[function(require,module,exports){
647
- var Templater = function(list) {
648
- var itemSource,
649
- templater = this;
650
-
651
- var init = function() {
652
- itemSource = templater.getItemSource(list.item);
653
- itemSource = templater.clearSourceItem(itemSource, list.valueNames);
654
- };
655
-
656
- this.clearSourceItem = function(el, valueNames) {
657
- for(var i = 0, il = valueNames.length; i < il; i++) {
658
- var elm;
659
- if (valueNames[i].data) {
660
- for (var j = 0, jl = valueNames[i].data.length; j < jl; j++) {
661
- el.setAttribute('data-'+valueNames[i].data[j], '');
662
- }
663
- } else if (valueNames[i].attr && valueNames[i].name) {
664
- elm = list.utils.getByClass(el, valueNames[i].name, true);
665
- if (elm) {
666
- elm.setAttribute(valueNames[i].attr, "");
667
- }
668
- } else {
669
- elm = list.utils.getByClass(el, valueNames[i], true);
670
- if (elm) {
671
- elm.innerHTML = "";
672
- }
673
- }
674
- elm = undefined;
675
- }
676
- return el;
677
- };
678
-
679
- this.getItemSource = function(item) {
680
- if (item === undefined) {
681
- var nodes = list.list.childNodes,
682
- items = [];
683
-
684
- for (var i = 0, il = nodes.length; i < il; i++) {
685
- // Only textnodes have a data attribute
686
- if (nodes[i].data === undefined) {
687
- return nodes[i].cloneNode(true);
688
- }
689
- }
690
- } else if (/^tr[\s>]/.exec(item)) {
691
- var table = document.createElement('table');
692
- table.innerHTML = item;
693
- return table.firstChild;
694
- } else if (item.indexOf("<") !== -1) {
695
- var div = document.createElement('div');
696
- div.innerHTML = item;
697
- return div.firstChild;
698
- } else {
699
- var source = document.getElementById(list.item);
700
- if (source) {
701
- return source;
702
- }
703
- }
704
- throw new Error("The list need to have at list one item on init otherwise you'll have to add a template.");
705
- };
706
-
707
- this.get = function(item, valueNames) {
708
- templater.create(item);
709
- var values = {};
710
- for(var i = 0, il = valueNames.length; i < il; i++) {
711
- var elm;
712
- if (valueNames[i].data) {
713
- for (var j = 0, jl = valueNames[i].data.length; j < jl; j++) {
714
- values[valueNames[i].data[j]] = list.utils.getAttribute(item.elm, 'data-'+valueNames[i].data[j]);
715
- }
716
- } else if (valueNames[i].attr && valueNames[i].name) {
717
- elm = list.utils.getByClass(item.elm, valueNames[i].name, true);
718
- values[valueNames[i].name] = elm ? list.utils.getAttribute(elm, valueNames[i].attr) : "";
719
- } else {
720
- elm = list.utils.getByClass(item.elm, valueNames[i], true);
721
- values[valueNames[i]] = elm ? elm.innerHTML : "";
722
- }
723
- elm = undefined;
724
- }
725
- return values;
726
- };
727
-
728
- this.set = function(item, values) {
729
- var getValueName = function(name) {
730
- for (var i = 0, il = list.valueNames.length; i < il; i++) {
731
- if (list.valueNames[i].data) {
732
- var data = list.valueNames[i].data;
733
- for (var j = 0, jl = data.length; j < jl; j++) {
734
- if (data[j] === name) {
735
- return { data: name };
736
- }
737
- }
738
- } else if (list.valueNames[i].attr && list.valueNames[i].name && list.valueNames[i].name == name) {
739
- return list.valueNames[i];
740
- } else if (list.valueNames[i] === name) {
741
- return name;
742
- }
743
- }
744
- };
745
- var setValue = function(name, value) {
746
- var elm;
747
- var valueName = getValueName(name);
748
- if (!valueName)
749
- return;
750
- if (valueName.data) {
751
- item.elm.setAttribute('data-'+valueName.data, value);
752
- } else if (valueName.attr && valueName.name) {
753
- elm = list.utils.getByClass(item.elm, valueName.name, true);
754
- if (elm) {
755
- elm.setAttribute(valueName.attr, value);
756
- }
757
- } else {
758
- elm = list.utils.getByClass(item.elm, valueName, true);
759
- if (elm) {
760
- elm.innerHTML = value;
761
- }
762
- }
763
- elm = undefined;
764
- };
765
- if (!templater.create(item)) {
766
- for(var v in values) {
767
- if (values.hasOwnProperty(v)) {
768
- setValue(v, values[v]);
769
- }
770
- }
771
- }
772
- };
773
-
774
- this.create = function(item) {
775
- if (item.elm !== undefined) {
776
- return false;
777
- }
778
- /* If item source does not exists, use the first item in list as
779
- source for new items */
780
- var newItem = itemSource.cloneNode(true);
781
- newItem.removeAttribute('id');
782
- item.elm = newItem;
783
- templater.set(item, item.values());
784
- return true;
785
- };
786
- this.remove = function(item) {
787
- if (item.elm.parentNode === list.list) {
788
- list.list.removeChild(item.elm);
789
- }
790
- };
791
- this.show = function(item) {
792
- templater.create(item);
793
- list.list.appendChild(item.elm);
794
- };
795
- this.hide = function(item) {
796
- if (item.elm !== undefined && item.elm.parentNode === list.list) {
797
- list.list.removeChild(item.elm);
798
- }
799
- };
800
- this.clear = function() {
801
- /* .innerHTML = ''; fucks up IE */
802
- if (list.list.hasChildNodes()) {
803
- while (list.list.childNodes.length >= 1)
804
- {
805
- list.list.removeChild(list.list.firstChild);
806
- }
807
- }
808
- };
809
-
810
- init();
811
- };
812
-
813
- module.exports = function(list) {
814
- return new Templater(list);
815
- };
816
-
817
- },{}],9:[function(require,module,exports){
818
- /**
819
- * Module dependencies.
820
- */
821
-
822
- var index = require('./index-of');
823
-
824
- /**
825
- * Whitespace regexp.
826
- */
827
-
828
- var re = /\s+/;
829
-
830
- /**
831
- * toString reference.
832
- */
833
-
834
- var toString = Object.prototype.toString;
835
-
836
- /**
837
- * Wrap `el` in a `ClassList`.
838
- *
839
- * @param {Element} el
840
- * @return {ClassList}
841
- * @api public
842
- */
843
-
844
- module.exports = function(el){
845
- return new ClassList(el);
846
- };
847
-
848
- /**
849
- * Initialize a new ClassList for `el`.
850
- *
851
- * @param {Element} el
852
- * @api private
853
- */
854
-
855
- function ClassList(el) {
856
- if (!el || !el.nodeType) {
857
- throw new Error('A DOM element reference is required');
858
- }
859
- this.el = el;
860
- this.list = el.classList;
861
- }
862
-
863
- /**
864
- * Add class `name` if not already present.
865
- *
866
- * @param {String} name
867
- * @return {ClassList}
868
- * @api public
869
- */
870
-
871
- ClassList.prototype.add = function(name){
872
- // classList
873
- if (this.list) {
874
- this.list.add(name);
875
- return this;
876
- }
877
-
878
- // fallback
879
- var arr = this.array();
880
- var i = index(arr, name);
881
- if (!~i) arr.push(name);
882
- this.el.className = arr.join(' ');
883
- return this;
884
- };
885
-
886
- /**
887
- * Remove class `name` when present, or
888
- * pass a regular expression to remove
889
- * any which match.
890
- *
891
- * @param {String|RegExp} name
892
- * @return {ClassList}
893
- * @api public
894
- */
895
-
896
- ClassList.prototype.remove = function(name){
897
- if ('[object RegExp]' == toString.call(name)) {
898
- return this.removeMatching(name);
899
- }
900
-
901
- // classList
902
- if (this.list) {
903
- this.list.remove(name);
904
- return this;
905
- }
906
-
907
- // fallback
908
- var arr = this.array();
909
- var i = index(arr, name);
910
- if (~i) arr.splice(i, 1);
911
- this.el.className = arr.join(' ');
912
- return this;
913
- };
914
-
915
- /**
916
- * Remove all classes matching `re`.
917
- *
918
- * @param {RegExp} re
919
- * @return {ClassList}
920
- * @api private
921
- */
922
-
923
- ClassList.prototype.removeMatching = function(re){
924
- var arr = this.array();
925
- for (var i = 0; i < arr.length; i++) {
926
- if (re.test(arr[i])) {
927
- this.remove(arr[i]);
928
- }
929
- }
930
- return this;
931
- };
932
-
933
- /**
934
- * Toggle class `name`, can force state via `force`.
935
- *
936
- * For browsers that support classList, but do not support `force` yet,
937
- * the mistake will be detected and corrected.
938
- *
939
- * @param {String} name
940
- * @param {Boolean} force
941
- * @return {ClassList}
942
- * @api public
943
- */
944
-
945
- ClassList.prototype.toggle = function(name, force){
946
- // classList
947
- if (this.list) {
948
- if ("undefined" !== typeof force) {
949
- if (force !== this.list.toggle(name, force)) {
950
- this.list.toggle(name); // toggle again to correct
951
- }
952
- } else {
953
- this.list.toggle(name);
954
- }
955
- return this;
956
- }
957
-
958
- // fallback
959
- if ("undefined" !== typeof force) {
960
- if (!force) {
961
- this.remove(name);
962
- } else {
963
- this.add(name);
964
- }
965
- } else {
966
- if (this.has(name)) {
967
- this.remove(name);
968
- } else {
969
- this.add(name);
970
- }
971
- }
972
-
973
- return this;
974
- };
975
-
976
- /**
977
- * Return an array of classes.
978
- *
979
- * @return {Array}
980
- * @api public
981
- */
982
-
983
- ClassList.prototype.array = function(){
984
- var className = this.el.getAttribute('class') || '';
985
- var str = className.replace(/^\s+|\s+$/g, '');
986
- var arr = str.split(re);
987
- if ('' === arr[0]) arr.shift();
988
- return arr;
989
- };
990
-
991
- /**
992
- * Check if class `name` is present.
993
- *
994
- * @param {String} name
995
- * @return {ClassList}
996
- * @api public
997
- */
998
-
999
- ClassList.prototype.has =
1000
- ClassList.prototype.contains = function(name){
1001
- return this.list ? this.list.contains(name) : !! ~index(this.array(), name);
1002
- };
1003
-
1004
- },{"./index-of":14}],10:[function(require,module,exports){
1005
- var bind = window.addEventListener ? 'addEventListener' : 'attachEvent',
1006
- unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent',
1007
- prefix = bind !== 'addEventListener' ? 'on' : '',
1008
- toArray = require('./to-array');
1009
-
1010
- /**
1011
- * Bind `el` event `type` to `fn`.
1012
- *
1013
- * @param {Element} el, NodeList, HTMLCollection or Array
1014
- * @param {String} type
1015
- * @param {Function} fn
1016
- * @param {Boolean} capture
1017
- * @api public
1018
- */
1019
-
1020
- exports.bind = function(el, type, fn, capture){
1021
- el = toArray(el);
1022
- for ( var i = 0; i < el.length; i++ ) {
1023
- el[i][bind](prefix + type, fn, capture || false);
1024
- }
1025
- };
1026
-
1027
- /**
1028
- * Unbind `el` event `type`'s callback `fn`.
1029
- *
1030
- * @param {Element} el, NodeList, HTMLCollection or Array
1031
- * @param {String} type
1032
- * @param {Function} fn
1033
- * @param {Boolean} capture
1034
- * @api public
1035
- */
1036
-
1037
- exports.unbind = function(el, type, fn, capture){
1038
- el = toArray(el);
1039
- for ( var i = 0; i < el.length; i++ ) {
1040
- el[i][unbind](prefix + type, fn, capture || false);
1041
- }
1042
- };
1043
-
1044
- },{"./to-array":16}],11:[function(require,module,exports){
1045
- /*
1046
- * Source: https://github.com/segmentio/extend
1047
- */
1048
-
1049
- module.exports = function extend (object) {
1050
- // Takes an unlimited number of extenders.
1051
- var args = Array.prototype.slice.call(arguments, 1);
1052
-
1053
- // For each extender, copy their properties on our object.
1054
- for (var i = 0, source; source = args[i]; i++) {
1055
- if (!source) continue;
1056
- for (var property in source) {
1057
- object[property] = source[property];
1058
- }
1059
- }
1060
-
1061
- return object;
1062
- };
1063
-
1064
- },{}],12:[function(require,module,exports){
1065
- /**
1066
- * A cross-browser implementation of getAttribute.
1067
- * Source found here: http://stackoverflow.com/a/3755343/361337 written by Vivin Paliath
1068
- *
1069
- * Return the value for `attr` at `element`.
1070
- *
1071
- * @param {Element} el
1072
- * @param {String} attr
1073
- * @api public
1074
- */
1075
-
1076
- module.exports = function(el, attr) {
1077
- var result = (el.getAttribute && el.getAttribute(attr)) || null;
1078
- if( !result ) {
1079
- var attrs = el.attributes;
1080
- var length = attrs.length;
1081
- for(var i = 0; i < length; i++) {
1082
- if (attr[i] !== undefined) {
1083
- if(attr[i].nodeName === attr) {
1084
- result = attr[i].nodeValue;
1085
- }
1086
- }
1087
- }
1088
- }
1089
- return result;
1090
- };
1091
-
1092
- },{}],13:[function(require,module,exports){
1093
- /**
1094
- * A cross-browser implementation of getElementsByClass.
1095
- * Heavily based on Dustin Diaz's function: http://dustindiaz.com/getelementsbyclass.
1096
- *
1097
- * Find all elements with class `className` inside `container`.
1098
- * Use `single = true` to increase performance in older browsers
1099
- * when only one element is needed.
1100
- *
1101
- * @param {String} className
1102
- * @param {Element} container
1103
- * @param {Boolean} single
1104
- * @api public
1105
- */
1106
-
1107
- module.exports = (function() {
1108
- if (document.getElementsByClassName) {
1109
- return function(container, className, single) {
1110
- if (single) {
1111
- return container.getElementsByClassName(className)[0];
1112
- } else {
1113
- return container.getElementsByClassName(className);
1114
- }
1115
- };
1116
- } else if (document.querySelector) {
1117
- return function(container, className, single) {
1118
- className = '.' + className;
1119
- if (single) {
1120
- return container.querySelector(className);
1121
- } else {
1122
- return container.querySelectorAll(className);
1123
- }
1124
- };
1125
- } else {
1126
- return function(container, className, single) {
1127
- var classElements = [],
1128
- tag = '*';
1129
- if (container === null) {
1130
- container = document;
1131
- }
1132
- var els = container.getElementsByTagName(tag);
1133
- var elsLen = els.length;
1134
- var pattern = new RegExp("(^|\\s)"+className+"(\\s|$)");
1135
- for (var i = 0, j = 0; i < elsLen; i++) {
1136
- if ( pattern.test(els[i].className) ) {
1137
- if (single) {
1138
- return els[i];
1139
- } else {
1140
- classElements[j] = els[i];
1141
- j++;
1142
- }
1143
- }
1144
- }
1145
- return classElements;
1146
- };
1147
- }
1148
- })();
1149
-
1150
- },{}],14:[function(require,module,exports){
1151
- var indexOf = [].indexOf;
1152
-
1153
- module.exports = function(arr, obj){
1154
- if (indexOf) return arr.indexOf(obj);
1155
- for (var i = 0; i < arr.length; ++i) {
1156
- if (arr[i] === obj) return i;
1157
- }
1158
- return -1;
1159
- };
1160
-
1161
- },{}],15:[function(require,module,exports){
1162
- /*
1163
- * Natural Sort algorithm for Javascript - Version 0.8.1 - Released under MIT license
1164
- * Author: Jim Palmer (based on chunking idea from Dave Koelle)
1165
- */
1166
- module.exports = function(a, b, opts) {
1167
- var re = /(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g,
1168
- sre = /^\s+|\s+$/g, // trim pre-post whitespace
1169
- snre = /\s+/g, // normalize all whitespace to single ' ' character
1170
- dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
1171
- hre = /^0x[0-9a-f]+$/i,
1172
- ore = /^0/,
1173
- options = opts || {},
1174
- i = function(s) {
1175
- return (options.insensitive && ('' + s).toLowerCase() || '' + s).replace(sre, '');
1176
- },
1177
- // convert all to strings strip whitespace
1178
- x = i(a),
1179
- y = i(b),
1180
- // chunk/tokenize
1181
- xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
1182
- yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
1183
- // numeric, hex or date detection
1184
- xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && Date.parse(x)),
1185
- yD = parseInt(y.match(hre), 16) || xD && y.match(dre) && Date.parse(y) || null,
1186
- normChunk = function(s, l) {
1187
- // normalize spaces; find floats not starting with '0', string or 0 if not defined (Clint Priest)
1188
- return (!s.match(ore) || l == 1) && parseFloat(s) || s.replace(snre, ' ').replace(sre, '') || 0;
1189
- },
1190
- oFxNcL, oFyNcL;
1191
- // first try and sort Hex codes or Dates
1192
- if (yD) {
1193
- if (xD < yD) { return -1; }
1194
- else if (xD > yD) { return 1; }
1195
- }
1196
- // natural sorting through split numeric strings and default strings
1197
- for(var cLoc = 0, xNl = xN.length, yNl = yN.length, numS = Math.max(xNl, yNl); cLoc < numS; cLoc++) {
1198
- oFxNcL = normChunk(xN[cLoc] || '', xNl);
1199
- oFyNcL = normChunk(yN[cLoc] || '', yNl);
1200
- // handle numeric vs string comparison - number < string - (Kyle Adams)
1201
- if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
1202
- return isNaN(oFxNcL) ? 1 : -1;
1203
- }
1204
- // if unicode use locale comparison
1205
- if (/[^\x00-\x80]/.test(oFxNcL + oFyNcL) && oFxNcL.localeCompare) {
1206
- var comp = oFxNcL.localeCompare(oFyNcL);
1207
- return comp / Math.abs(comp);
1208
- }
1209
- if (oFxNcL < oFyNcL) { return -1; }
1210
- else if (oFxNcL > oFyNcL) { return 1; }
1211
- }
1212
- return 0;
1213
- };
1214
-
1215
- },{}],16:[function(require,module,exports){
1216
- /**
1217
- * Source: https://github.com/timoxley/to-array
1218
- *
1219
- * Convert an array-like object into an `Array`.
1220
- * If `collection` is already an `Array`, then will return a clone of `collection`.
1221
- *
1222
- * @param {Array | Mixed} collection An `Array` or array-like object to convert e.g. `arguments` or `NodeList`
1223
- * @return {Array} Naive conversion of `collection` to a new `Array`.
1224
- * @api public
1225
- */
1226
-
1227
- module.exports = function toArray(collection) {
1228
- if (typeof collection === 'undefined') return [];
1229
- if (collection === null) return [null];
1230
- if (collection === window) return [window];
1231
- if (typeof collection === 'string') return [collection];
1232
- if (isArray(collection)) return collection;
1233
- if (typeof collection.length != 'number') return [collection];
1234
- if (typeof collection === 'function' && collection instanceof Function) return [collection];
1235
-
1236
- var arr = [];
1237
- for (var i = 0; i < collection.length; i++) {
1238
- if (Object.prototype.hasOwnProperty.call(collection, i) || i in collection) {
1239
- arr.push(collection[i]);
1240
- }
1241
- }
1242
- if (!arr.length) return [];
1243
- return arr;
1244
- };
1245
-
1246
- function isArray(arr) {
1247
- return Object.prototype.toString.call(arr) === "[object Array]";
1248
- }
1249
-
1250
- },{}],17:[function(require,module,exports){
1251
- module.exports = function(s) {
1252
- s = (s === undefined) ? "" : s;
1253
- s = (s === null) ? "" : s;
1254
- s = s.toString();
1255
- return s;
1256
- };
1257
-
1258
- },{}]},{},[1]);