diff --git a/examples/bclys/fin-hypergrid.dev.html b/examples/bclys/fin-hypergrid.dev.html
deleted file mode 100644
index 8eab4605b..000000000
--- a/examples/bclys/fin-hypergrid.dev.html
+++ /dev/null
@@ -1,37964 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- ⬤
-
- {{labelAdapter(item)}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/examples/bclys/fin-hypergrid.min.html b/examples/bclys/fin-hypergrid.min.html
deleted file mode 100644
index a513aa7bf..000000000
--- a/examples/bclys/fin-hypergrid.min.html
+++ /dev/null
@@ -1,32 +0,0 @@
--
- ⬤
-
- {{labelAdapter(item)}}
-
\ No newline at end of file
diff --git a/examples/bclys/index.html b/examples/bclys/index.html
index 7184f34de..f94a64c56 100644
--- a/examples/bclys/index.html
+++ b/examples/bclys/index.html
@@ -7,7 +7,7 @@
-
+
@@ -89,11 +89,10 @@
var div = document.querySelector('div#json-example'),
bodyStyle = window.getComputedStyle(document.body);
- var getContainer = function(grid) {
+ jsonGrid = new fin.Hypergrid(div, function(grid) {
return new fin.Hypergrid.behaviors.JSON(grid, window.people1);
- };
+ });
- jsonGrid = new fin.Hypergrid(div, getContainer);
var jsonModel = jsonGrid.getBehavior();
//functions for showing the grouping/rollup capbilities
@@ -541,7 +540,7 @@
var state = {
columnIndexes: [
fieldsMap.last_name,
- fieldsMap.pets,
+ fieldsMap.total_number_of_pets_owned,
fieldsMap.birthDate,
fieldsMap.birthState,
// fieldsMap.residenceState,
diff --git a/examples/bclys/index.js b/examples/bclys/index.js
index fa9edcbd8..16f9403c0 100644
--- a/examples/bclys/index.js
+++ b/examples/bclys/index.js
@@ -1,5 +1,5 @@
(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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o CAUTION: Mutates `this` array!
- * @param {Array} appendix
- * @returns {Array} Reference to `this` (for convenience)
- */
-function append(appendix) {
- this.splice.bind(this, this.length, 0).apply(this, appendix);
- return this;
-}
-
-module.exports = DataNodeGroup;
-},{"./DataNodeBase":5,"./util/Mappy":17}],7:[function(require,module,exports){
-'use strict';
-
-var DataNodeBase = require('./DataNodeBase');
-
-var DataNodeLeaf = DataNodeBase.extend('DataNodeLeaf', {
-
- prune: function(depth) {
- this.depth = depth;
- this.data[0] = this.computeDepthString();
+ var elapsed = now - this.lastRepaintTime;
+ if (elapsed > interval && this.dirty) {
+ this.lastRepaintTime = now - (elapsed % interval);
+ this.paintNow();
+ }
},
- getIndex: function() {
- return this.index;
+ beginPainting: function() {
+ var self = this;
+ this.dirty = true;
+ this.tickPainter = function(now) {
+ self.tickPaint(now);
+ };
+ paintables.push(this);
},
- buildView: function(aggregator) {
- aggregator.addView(this);
+ stopPainting: function() {
+ paintables.splice(paintables.indexOf(this), 1);
},
- computeHeight: function() {
- return 1;
- }
-
-});
-
-module.exports = DataNodeLeaf;
-},{"./DataNodeBase":5}],8:[function(require,module,exports){
-'use strict';
-
-var DataNodeGroup = require('./DataNodeGroup');
-
-var DataNodeTree = DataNodeGroup.extend('DataNodeTree', {
-
- initialize: function(key) {
- this.height = 0;
- this.expanded = true;
+ beginResizing: function() {
+ var self = this;
+ this.tickResizer = function() {
+ self.checksize();
+ };
+ resizables.push(this);
},
- prune: function() {
- this.children = this.children.values;
- this.children.forEach(function(child) {
- child.prune(0);
- });
+ stopResizing: function() {
+ resizables.splice(resizables.indexOf(this), 1);
},
- buildView: function(aggregator) {
- this.children.forEach(function(child) {
- child.buildView(aggregator);
- });
+ start: function() {
+ this.beginPainting();
+ this.beginResizing();
},
- computeHeight: function() {
- var height = 1;
-
- this.children.forEach(function(child) {
- height = height + child.computeHeight();
- });
-
- return (this.height = height);
- }
+ stop: function() {
+ this.stopPainting();
+ this.stopResizing();
+ },
-});
+ checksize: function() {
+ //this is expensive lets do it at some modulo
+ var sizeNow = this.div.getBoundingClientRect();
+ if (sizeNow.width !== this.size.width || sizeNow.height !== this.size.height) {
+ this.sizeChangedNotification();
+ }
+ },
-module.exports = DataNodeTree;
-},{"./DataNodeGroup":6}],9:[function(require,module,exports){
-'use strict';
+ sizeChangedNotification: function() {
+ this.resize();
+ },
-var headerify = require('./util/headerify');
+ resize: function() {
+ var box = this.size = this.div.getBoundingClientRect();
-function DataSource(data, fields) {
- this.fields = fields || computeFieldNames(data[0]);
- this.data = data;
-}
+ this.canvas.width = this.buffer.width = box.width;
+ this.canvas.height = this.buffer.height = box.height;
-DataSource.prototype = {
- constructor: DataSource.prototype.constructor, // preserve constructor
+ //fix ala sir spinka, see
+ //http://www.html5rocks.com/en/tutorials/canvas/hidpi/
+ //just add 'hdpi' as an attribute to the fin-canvas tag
+ var ratio = 1;
+ var useBitBlit = this.useBitBlit();
+ var isHIDPI = window.devicePixelRatio && this.useHiDPI();
+ if (isHIDPI) {
+ var devicePixelRatio = window.devicePixelRatio || 1;
+ var backingStoreRatio = this.canvasCTX.webkitBackingStorePixelRatio ||
+ this.canvasCTX.mozBackingStorePixelRatio ||
+ this.canvasCTX.msBackingStorePixelRatio ||
+ this.canvasCTX.oBackingStorePixelRatio ||
+ this.canvasCTX.backingStorePixelRatio || 1;
- isNullObject: false,
+ ratio = devicePixelRatio / backingStoreRatio;
+ //this.canvasCTX.scale(ratio, ratio);
+ }
+ var width = this.canvas.getAttribute('width');
+ var height = this.canvas.getAttribute('height');
+ this.canvas.width = width * ratio;
+ this.canvas.height = height * ratio;
+ this.buffer.width = width * ratio;
+ this.buffer.height = height * ratio;
- getRow: function(y) {
- return this.data[y];
- },
+ this.canvas.style.width = width + 'px';
+ this.canvas.style.height = height + 'px';
+ this.buffer.style.width = width + 'px';
+ this.buffer.style.height = height + 'px';
- getValue: function(x, y) {
- var row = this.getRow(y);
- if (!row) {
- return null;
+ this.bufferCTX.scale(ratio, ratio);
+ if (isHIDPI && !useBitBlit) {
+ this.canvasCTX.scale(ratio, ratio);
}
- return row[this.fields[x]];
- },
- setValue: function(x, y, value) {
- this.getRow(y)[this.fields[x]] = value;
+ //this.origin = new rectangular.Point(Math.round(this.size.left), Math.round(this.size.top));
+ this.bounds = new rectangular.Rectangle(0, 0, box.width, box.height);
+ //setTimeout(function() {
+ var comp = this._component;
+ if (comp) {
+ comp.setBounds(this.bounds);
+ }
+ this.resizeNotification();
+ this.paintNow();
+ //});
},
- getRowCount: function() {
- return this.data.length;
+ resizeNotification: function() {
+ //to be overridden
},
- getColumnCount: function() {
- return this.getFields().length;
+ getBounds: function() {
+ return this.bounds;
},
- getFields: function() {
- return this.fields;
- },
+ paintNow: function() {
+ var self = this;
+ this.safePaintImmediately(function(gc) {
+ gc.clearRect(0, 0, self.canvas.width, self.canvas.height);
- getHeaders: function() {
- return (
- this.headers = this.headers ||
- this.getDefaultHeaders().map(function(each) {
- return headerify(each);
- })
- );
- },
+ var comp = self._component;
+ if (comp) {
+ comp._paint(gc);
+ }
- getDefaultHeaders: function() {
- return this.getFields();
+ self.dirty = false;
+ });
},
- setFields: function(fields) {
- this.fields = fields;
+ safePaintImmediately: function(paintFunction) {
+ var useBitBlit = this.useBitBlit(),
+ gc = useBitBlit ? this.bufferGC : this.gc;
+ try {
+ gc.save();
+ paintFunction(gc);
+ } catch (e) {
+ console.error(e);
+ } finally {
+ gc.restore();
+ }
+ if (useBitBlit) {
+ this.flushBuffer();
+ }
},
- setHeaders: function(headers) {
- if (!(headers instanceof Array)) {
- error('setHeaders', 'param #1 `headers` not array');
+ flushBuffer: function() {
+ if (this.buffer.width > 0 && this.buffer.height > 0) {
+ this.canvasCTX.drawImage(this.buffer, 0, 0);
}
- this.headers = headers;
},
- getGrandTotals: function() {
- //nothing here
- return;
+ dispatchNewEvent: function(event, name, detail) {
+ detail = {
+ detail: detail || {}
+ };
+ detail.detail.primitiveEvent = event;
+ return this.canvas.dispatchEvent(new CustomEvent(name, detail));
},
- setData: function(arrayOfUniformObjects) {
- this.data = arrayOfUniformObjects;
- }
-};
-
-function error(methodName, message) {
- throw new Error('DataSource.' + methodName + ': ' + message);
-}
-
-function computeFieldNames(object) {
- if (!object) {
- return [];
- }
- var fields = [].concat(Object.getOwnPropertyNames(object).filter(function(e) {
- return e.substr(0, 2) !== '__';
- }));
- return fields;
-}
-
-module.exports = DataSource;
-},{"./util/headerify":19}],10:[function(require,module,exports){
-'use strict';
-
-var _ = require('object-iterators');
-
-var DataSourceSorter = require('./DataSourceSorter');
-var DataNodeTree = require('./DataNodeTree');
-var DataNodeGroup = require('./DataNodeGroup');
-var DataNodeLeaf = require('./DataNodeLeaf');
-var headerify = require('./util/headerify');
-
-//?[t,c,b,a]
-// t is a dataSource,
-// a is a dictionary of aggregates, columnName:function
-// b is a dictionary of groupbys, columnName:sourceColumnName
-// c is a list of constraints,
-
-function DataSourceAggregator(dataSource) {
- this.dataSource = dataSource;
- this.tree = new DataNodeTree('Totals');
- this.index = [];
- this.aggregates = [];
- this.headers = [];
- this.groupBys = [];
- this.view = [];
- this.sorterInstance = {};
- this.presortGroups = true;
- this.lastAggregate = {};
- this.setAggregates({});
-}
-
-DataSourceAggregator.prototype = {
- constructor: DataSourceAggregator.prototype.constructor, // preserve constructor
-
- isNullObject: false,
-
- setAggregates: function(aggregations) {
- this.lastAggregate = aggregations;
- this.clearAggregations();
- this.headers.length = 0;
+ dispatchNewMouseKeysEvent: function(event, name, detail) {
+ detail = detail || {};
+ detail.mouse = this.mouseLocation;
+ detail.keys = this.currentKeys;
+ return this.dispatchNewEvent(event, name, detail);
+ },
- if (this.hasGroups()) {
- this.headers.push('Tree');
+ finmousemove: function(e) {
+ if (!this.isDragging() && this.mousedown) {
+ this.beDragging();
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-dragstart', {
+ isRightClick: this.isRightClick(e)
+ });
+ this.dragstart = new rectangular.Point(this.mouseLocation.x, this.mouseLocation.y);
+ }
+ this.mouseLocation = this.getLocal(e);
+ //console.log(this.mouseLocation);
+ if (this.isDragging()) {
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-drag', {
+ dragstart: this.dragstart,
+ isRightClick: this.isRightClick(e)
+ });
+ }
+ if (this.bounds.contains(this.mouseLocation)) {
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-mousemove');
}
-
- var self = this;
- _(aggregations).each(function(aggregation, key) {
- self.addAggregate(key, aggregation);
- });
},
- addAggregate: function(label, func) {
- this.headers.push(headerify(label));
- this.aggregates.push(func);
- },
+ finmousedown: function(e) {
+ this.mouseLocation = this.getLocal(e);
+ this.mousedown = true;
- setGroupBys: function(columnIndexArray) {
- var groupBys = this.groupBys;
- groupBys.length = 0;
- columnIndexArray.forEach(function(columnIndex) {
- groupBys.push(columnIndex);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-mousedown', {
+ isRightClick: this.isRightClick(e)
});
- this.setAggregates(this.lastAggregate);
+ this.takeFocus();
},
- addGroupBy: function(index) {
- this.groupBys.push(index);
+ finmouseup: function(e) {
+ if (this.isDragging()) {
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-dragend', {
+ dragstart: this.dragstart,
+ isRightClick: this.isRightClick(e)
+ });
+ this.beNotDragging();
+ this.dragEndtime = Date.now();
+ }
+ this.mousedown = false;
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-mouseup', {
+ isRightClick: this.isRightClick(e)
+ });
+ //this.mouseLocation = new rectangular.Point(-1, -1);
},
- hasGroups: function() {
- return !!this.groupBys.length;
+ finmouseout: function(e) {
+ if (!this.mousedown) {
+ this.mouseLocation = new rectangular.Point(-1, -1);
+ }
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-mouseout');
},
- hasAggregates: function() {
- return !!this.aggregates.length;
+ finwheelmoved: function(e) {
+ if (this.isDragging() || !this.hasFocus()) {
+ return;
+ }
+ e.preventDefault();
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-wheelmoved', {
+ isRightClick: this.isRightClick(e)
+ });
},
- apply: function() {
- this.buildGroupTree();
+ finclick: function(e) {
+ if (Date.now() - this.lastClickTime < 250) {
+ //this is a double click...
+ this.findblclick(e);
+ return;
+ }
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-click', {
+ isRightClick: this.isRightClick(e)
+ });
+ this.lastClickTime = Date.now();
},
- clearGroups: function() {
- this.groupBys.length = 0;
+ finrelease: function(e) {
+ this.holdPulseCount = 0;
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-release');
},
- clearAggregations: function() {
- this.aggregates.length = 0;
- this.headers.length = 0;
+ finflick: function(e) {
+ if (!this.hasFocus()) {
+ return;
+ }
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-flick', {
+ isRightClick: this.isRightClick(e)
+ });
},
- buildGroupTree: function() {
- var groupBys = this.groupBys,
- leafDepth = groupBys.length - 1,
- source = this.dataSource,
- rowCount = source.getRowCount(),
- tree = this.tree = new DataNodeTree('Totals');
-
- // first sort data
- if (this.presortGroups) {
- groupBys.reverse().forEach(function(groupBy) {
- source = new DataSourceSorter(source);
- source.sortOn(groupBy);
- });
+ fintrackstart: function(e) {
+ if (!this.hasFocus()) {
+ return;
}
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-trackstart');
+ },
- for (var r = 0; r < rowCount; r++) {
- var path = tree;
-
- groupBys.forEach(function(g, c) { // eslint-disable-line no-loop-func
- var key = source.getValue(g, r),
- terminalNode = (c === leafDepth),
- Constructor = terminalNode ? DataNodeLeaf : DataNodeGroup,
- ifAbsentFunc = createNode.bind(this, Constructor);
- path = path.children.getIfAbsent(key, ifAbsentFunc);
- });
-
- path.index.push(r);
+ fintrack: function(e) {
+ if (!this.hasFocus()) {
+ return;
}
-
- this.sorterInstance = new DataSourceSorter(source);
- tree.prune();
- tree.computeAggregates(this);
- this.buildView();
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-track');
},
- addView: function(dataNode) {
- this.view.push(dataNode);
+ fintrackend: function(e) {
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-trackend');
},
- buildView: function() {
- this.view.length = 0;
- this.tree.computeHeight();
- this.tree.buildView(this);
+ finhold: function(e) {
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-hold', {
+ isRightClick: this.isRightClick(e)
+ });
},
- viewMakesSense: function() {
- return this.hasAggregates();
+ finholdpulse: function(e) {
+ this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-holdpulse', {
+ count: this.holdPulseCount++
+ });
},
- getValue: function(x, y) {
- if (!this.viewMakesSense()) {
- return this.dataSource.getValue(x, y);
- }
- var row = this.view[y];
- if (!row) {
- return null;
+ fintap: function(e) {
+ //this nonsense is to hold a tap if it's really a double click
+ var self = this;
+ var now = Date.now();
+ var dif = now - this.lastDoubleClickTime;
+ if (dif < 300) {
+ return;
}
- return row.getValue(x); // TODO: what kind of object is row... ? should it be unfiltred?
- },
-
- setValue: function(x, y, value) {
- if (!this.viewMakesSense()) {
- return this.dataSource.setValue(x, y, value);
+ //dragend is also causing a tap
+ //lets fix this here
+ if (now - this.dragEndtime < 100) {
+ return;
}
+ setTimeout(function() {
+ self._fintap(e);
+ }, 180);
},
- getColumnCount: function() {
- if (!this.viewMakesSense()) {
- return this.dataSource.getColumnCount();
+ _fintap: function(e) {
+ //this nonsense is to hold a tap if it's really a double click
+ var now = Date.now();
+ var dif = now - this.lastDoubleClickTime;
+ if (dif < 300) {
+ return;
}
- return this.getHeaders().length;
+ //this.mouseLocation = this.getLocal(e);
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-tap', {
+ isRightClick: this.isRightClick(e)
+ });
},
- getRowCount: function() {
- if (!this.viewMakesSense()) {
- return this.dataSource.getRowCount();
- }
- return this.view.length; //header column
+ findblclick: function(e) {
+ this.mouseLocation = this.getLocal(e);
+ this.lastDoubleClickTime = Date.now();
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-dblclick', {
+ isRightClick: this.isRightClick(e)
+ });
+ //console.log('dblclick', this.currentKeys);
},
- click: function(y) {
- var group = this.view[y];
- group.toggleExpansionState(this);
- this.buildView();
+ getCharMap: function() { //TODO: This is static. Make it a property of the constructor.
+ return charMap;
},
- getHeaders: function() {
- if (!this.viewMakesSense()) {
- return this.dataSource.getHeaders();
+ finkeydown: function(e) {
+ if (!this.hasFocus()) {
+ return;
}
- return this.headers; // TODO: Views override dataSource headers with their own headers?
+
+ //e.preventDefault();
+ var keyChar = e.shiftKey ? charMap[e.keyCode][1] : charMap[e.keyCode][0];
+ if (e.repeat) {
+ if (this.repeatKey === keyChar) {
+ this.repeatKeyCount++;
+ } else {
+ this.repeatKey = keyChar;
+ this.repeatKeyStartTime = Date.now();
+ }
+ } else {
+ this.repeatKey = null;
+ this.repeatKeyCount = 0;
+ this.repeatKeyStartTime = 0;
+ }
+ if (this.currentKeys.indexOf(keyChar) === -1) {
+ this.currentKeys.push(keyChar);
+ }
+ //console.log(keyChar, e.keyCode);
+ this.dispatchNewEvent(e, 'fin-canvas-keydown', {
+ alt: e.altKey,
+ ctrl: e.ctrlKey,
+ char: keyChar,
+ code: e.charCode,
+ key: e.keyCode,
+ meta: e.metaKey,
+ repeatCount: this.repeatKeyCount,
+ repeatStartTime: this.repeatKeyStartTime,
+ shift: e.shiftKey,
+ identifier: e.keyIdentifier,
+ currentKeys: this.currentKeys.slice(0)
+ });
},
- setHeaders: function(headers) {
- this.dataSource.setHeaders(headers);
+ finkeyup: function(e) {
+ var keyChar = e.shiftKey ? charMap[e.keyCode][1] : charMap[e.keyCode][0];
+ this.currentKeys.splice(this.currentKeys.indexOf(keyChar), 1);
+ if (!this.hasFocus()) {
+ return;
+ }
+ this.repeatKeyCount = 0;
+ this.repeatKey = null;
+ this.repeatKeyStartTime = 0;
+ this.dispatchNewEvent(e, 'fin-canvas-keyup', {
+ alt: e.altKey,
+ ctrl: e.ctrlKey,
+ char: keyChar,
+ code: e.charCode,
+ key: e.keyCode,
+ meta: e.metaKey,
+ repeat: e.repeat,
+ shift: e.shiftKey,
+ identifier: e.keyIdentifier,
+ currentKeys: this.currentKeys.slice(0)
+ });
},
- getFields: function() {
- return this.dataSource.getFields();
+ finfocusgained: function(e) {
+ this.dispatchNewEvent(e, 'fin-canvas-focus-gained');
},
- setFields: function(fields) {
- return this.dataSource.setFields(fields);
+ finfocuslost: function(e) {
+ this.dispatchNewEvent(e, 'fin-canvas-focus-lost');
},
- getGrandTotals: function() {
- var view = this.tree;
- return [view.data];
+ fincontextmenu: function(e) {
+ if (e.ctrlKey && this.currentKeys.indexOf('CTRL') === -1) {
+ this.currentKeys.push('CTRL');
+ }
+ if (Date.now() - this.lastClickTime < 250) {
+ //this is a double click...
+ this.findblclick(e);
+ return;
+ }
+ this.dispatchNewMouseKeysEvent(e, 'fin-canvas-context-menu', {
+ isRightClick: this.isRightClick(e)
+ });
+ this.lastClickTime = Date.now();
},
- getRow: function(y) {
- if (!this.viewMakesSense()) {
- return this.dataSource.getRow(y);
+ repaint: function() {
+ var fps = this.getFPS();
+ this.dirty = true;
+ if (!paintLoopRunning || fps === 0) {
+ this.paintNow();
}
+ },
- var rollups = this.view[y];
+ getMouseLocation: function() {
+ return this.mouseLocation;
+ },
- return rollups ? rollups : this.tree;
+ getOrigin: function() {
+ var rect = this.canvas.getBoundingClientRect();
+ var p = new rectangular.Point(rect.left, rect.top);
+ return p;
},
- setData: function(arrayOfUniformObjects) {
- this.dataSource.setData(arrayOfUniformObjects);
- this.apply();
- }
-};
+ getLocal: function(e) {
+ var rect = this.canvas.getBoundingClientRect();
+ var p = new rectangular.Point(e.clientX - rect.left, e.clientY - rect.top);
+ return p;
+ },
-function createNode(DataNodeConstructor, key, map) {
- var value = new DataNodeConstructor(key);
- map.set(key, value);
- return value;
-}
+ hasFocus: function() {
+ return document.activeElement === this.canvas;
+ },
-module.exports = DataSourceAggregator;
-},{"./DataNodeGroup":6,"./DataNodeLeaf":7,"./DataNodeTree":8,"./DataSourceSorter":14,"./util/headerify":19,"object-iterators":24}],11:[function(require,module,exports){
-'use strict';
+ takeFocus: function() {
+ var self = this;
+ if (!this.hasFocus()) {
+ setTimeout(function() {
+ self.canvas.focus();
+ }, 10);
+ }
+ },
-var DataSourceIndexed = require('./DataSourceIndexed');
+ beDragging: function() {
+ this.dragging = true;
+ this.disableDocumentElementSelection();
+ },
-var DataSourceFilter = DataSourceIndexed.extend('DataSourceFilter', {
+ beNotDragging: function() {
+ this.dragging = false;
+ this.enableDocumentElementSelection();
+ },
- initialize: function() {
- this.filters = [];
+ isDragging: function() {
+ return this.dragging;
},
- add: function(columnIndex, filter) {
- filter.columnIndex = columnIndex;
- this.filters.push(filter);
+ disableDocumentElementSelection: function() {
+ var style = document.body.style;
+ style.cssText = style.cssText + '-webkit-user-select: none';
},
- clearAll: function() {
- this.filters.length = 0;
- this.clearIndex();
+ enableDocumentElementSelection: function() {
+ var style = document.body.style;
+ style.cssText = style.cssText.replace('-webkit-user-select: none', '');
},
- applyAll: function() {
- if (!this.filters.length) {
- this.clearIndex();
- } else {
- this.buildIndex(applyFilters);
- }
+ setFocusable: function(truthy) {
+ this.focuser.style.display = truthy ? '' : 'none';
},
- getRowCount: function() {
- return this.filters.length ? this.index.length : this.dataSource.getRowCount();
+ isRightClick: function(e) {
+ var isRightMB;
+ e = e || window.event;
+
+ if ('which' in e) { // Gecko (Firefox), WebKit (Safari/Chrome) & Opera
+ isRightMB = e.which === 3;
+ } else if ('button' in e) { // IE, Opera
+ isRightMB = e.button === 2;
+ }
+ return isRightMB;
},
- aliases: {
- set: 'add'
+ dispatchEvent: function(e) {
+ return this.canvas.dispatchEvent(e);
}
-});
+};
-function applyFilters(r, rowObject) { // called in context from .buildIndex()
- var self = this;
+function paintLoopFunction(now) {
+ if (!paintLoopRunning) {
+ return;
+ }
+ for (var i = 0; i < paintables.length; i++) {
+ try {
+ paintables[i].tickPainter(now);
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ requestAnimationFrame(paintLoopFunction);
+}
+requestAnimationFrame(paintLoopFunction);
- if (Array.prototype.find) {
- // double negative here means "no filter fails" (i.e., row passes all filters)
- return !this.filters.find(function(filter) {
- return !filter(self.dataSource.getValue(filter.columnIndex, r), rowObject, r);
- });
- } else {
- return this.filters.reduce(function(isFiltered, filter) {
- return isFiltered && filter(self.dataSource.getValue(filter.columnIndex, r), rowObject, r);
- }, true);
+function resizablesLoopFunction(now) {
+ if (!resizeLoopRunning) {
+ return;
+ }
+ for (var i = 0; i < resizables.length; i++) {
+ try {
+ resizables[i].tickResizer(now);
+ } catch (e) {
+ console.error(e);
+ }
}
}
+setInterval(resizablesLoopFunction, RESIZE_POLLING_INTERVAL);
-module.exports = DataSourceFilter;
+function makeCharMap() {
+ var map = [];
-},{"./DataSourceIndexed":13}],12:[function(require,module,exports){
-'use strict';
+ var empty = ['', ''];
-var DataSourceIndexed = require('./DataSourceIndexed');
-
-var DataSourceGlobalFilter = DataSourceIndexed.extend('DataSourceGlobalFilter', {
-
- set: function(filter) {
- this.filter = filter;
- },
-
- clear: function() {
- delete this.filter;
- this.clearIndex();
- },
+ for (var i = 0; i < 256; i++) {
+ map[i] = empty;
+ }
- apply: function() {
- if (!this.filter) {
- this.clearIndex();
- } else {
- this.buildIndex(applyFilter);
- }
- },
+ map[27] = ['ESC', 'ESCSHIFT'];
+ map[192] = ['`', '~'];
+ map[49] = ['1', '!'];
+ map[50] = ['2', '@'];
+ map[51] = ['3', '#'];
+ map[52] = ['4', '$'];
+ map[53] = ['5', '%'];
+ map[54] = ['6', '^'];
+ map[55] = ['7', '&'];
+ map[56] = ['8', '*'];
+ map[57] = ['9', '('];
+ map[48] = ['0', ')'];
+ map[189] = ['-', '_'];
+ map[187] = ['=', '+'];
+ map[8] = ['DELETE', 'DELETESHIFT'];
+ map[9] = ['TAB', 'TABSHIFT'];
+ map[81] = ['q', 'Q'];
+ map[87] = ['w', 'W'];
+ map[69] = ['e', 'E'];
+ map[82] = ['r', 'R'];
+ map[84] = ['t', 'T'];
+ map[89] = ['y', 'Y'];
+ map[85] = ['u', 'U'];
+ map[73] = ['i', 'I'];
+ map[79] = ['o', 'O'];
+ map[80] = ['p', 'P'];
+ map[219] = ['[', '{'];
+ map[221] = [']', '}'];
+ map[220] = ['\\', '|'];
+ map[220] = ['CAPSLOCK', 'CAPSLOCKSHIFT'];
+ map[65] = ['a', 'A'];
+ map[83] = ['s', 'S'];
+ map[68] = ['d', 'D'];
+ map[70] = ['f', 'F'];
+ map[71] = ['g', 'G'];
+ map[72] = ['h', 'H'];
+ map[74] = ['j', 'J'];
+ map[75] = ['k', 'K'];
+ map[76] = ['l', 'L'];
+ map[186] = [';', ':'];
+ map[222] = ['\'', '|'];
+ map[13] = ['RETURN', 'RETURNSHIFT'];
+ map[16] = ['SHIFT', 'SHIFT'];
+ map[90] = ['z', 'Z'];
+ map[88] = ['x', 'X'];
+ map[67] = ['c', 'C'];
+ map[86] = ['v', 'V'];
+ map[66] = ['b', 'B'];
+ map[78] = ['n', 'N'];
+ map[77] = ['m', 'M'];
+ map[188] = [',', '<'];
+ map[190] = ['.', '>'];
+ map[191] = ['/', '?'];
+ map[16] = ['SHIFT', 'SHIFT'];
+ map[17] = ['CTRL', 'CTRLSHIFT'];
+ map[18] = ['ALT', 'ALTSHIFT'];
+ map[91] = ['COMMANDLEFT', 'COMMANDLEFTSHIFT'];
+ map[32] = ['SPACE', 'SPACESHIFT'];
+ map[93] = ['COMMANDRIGHT', 'COMMANDRIGHTSHIFT'];
+ map[18] = ['ALT', 'ALTSHIFT'];
+ map[38] = ['UP', 'UPSHIFT'];
+ map[37] = ['LEFT', 'LEFTSHIFT'];
+ map[40] = ['DOWN', 'DOWNSHIFT'];
+ map[39] = ['RIGHT', 'RIGHTSHIFT'];
- getRowCount: function() {
- return this.filter ? this.index.length : this.dataSource.getRowCount();
- }
-});
+ map[33] = ['PAGEUP', 'PAGEUPSHIFT'];
+ map[34] = ['PAGEDOWN', 'PAGEDOWNSHIFT'];
+ map[35] = ['PAGERIGHT', 'PAGERIGHTSHIFT'];
+ map[36] = ['PAGELEFT', 'PAGELEFTSHIFT'];
-function applyFilter(r, rowObject) { // called in context from .buildIndex()
- var self = this;
- return this.getFields().find(function(columnIndex) {
- var cellValue = self.dataSource.getValue(columnIndex, r);
- return self.filter(cellValue, rowObject, r);
- });
+ return map;
}
-module.exports = DataSourceGlobalFilter;
-},{"./DataSourceIndexed":13}],13:[function(require,module,exports){
-'use strict';
+module.exports = Canvas;
-var Base = require('extend-me').Base;
+},{"./js/GraphicsContext.js":6,"./js/polymergestures.dev.js":8,"rectangular":29}],6:[function(require,module,exports){
+'use strict';
-var DataSourceIndexed = Base.extend('DataSourceIndexed', {
+var consoleLogger = require('./gc-console-logger');
- isNullObject: false,
+/**
+ * @constructor
+ * @param gc - The 2-D graphics context from your canvas
+ * @param {boolean|apiLogger} [logger=true]
+ * * `true` uses `gc-console-logger` function bound to 'gc.' as prefix
+ * * string uses `gc-console-logger` function bound to string
+ * * function used as is
+ */
+function GraphicsContext(gc, logger) {
+ this.gc = gc;
- initialize: function(dataSource) {
- this.dataSource = dataSource;
- this.index = [];
- },
+ var self = this;
+ var reWEBKIT = /^webkit/;
- transposeY: function(y) {
- return this.index.length ? this.index[y] : y;
- },
+ switch (typeof logger) {
- getRow: function(y) {
- return this.dataSource.getRow(this.transposeY(y));
- },
+ case 'string':
+ logger = consoleLogger.bind(undefined, logger + '.');
+ break;
- getValue: function(x, y) {
- return this.dataSource.getValue(x, this.transposeY(y));
- },
+ case 'boolean':
+ if (logger === true) {
+ logger = consoleLogger.bind(undefined, 'gc.');
+ }
+ break;
- setValue: function(x, y, value) {
- this.dataSource.setValue(x, this.transposeY(y), value);
- },
+ case 'function':
+ if (logger.length !== 3) {
+ throw 'GraphicsContext: User-supplied API logger function does not accept three parameters.';
+ }
+ break;
- getRowCount: function() {
- return this.index.length || this.dataSource.getRowCount();
- },
+ default:
+ logger = false;
+ }
- getColumnCount: function() {
- return this.dataSource.getColumnCount();
- },
+ // Stub out all the prototype members of the canvas 2D graphics context:
+ Object.keys(Object.getPrototypeOf(gc)).forEach(MakeStub);
- getFields: function() {
- return this.dataSource.getFields();
- },
+ // Some older browsers (e.g., Chrome 40) did not have all members of canvas
+ // 2D graphics context in the prototype so we make this additional call:
+ Object.keys(gc).forEach(MakeStub);
- setFields: function(fields) {
- return this.dataSource.setFields(fields);
- },
+ function MakeStub(key) {
+ if (key in GraphicsContext.prototype || reWEBKIT.test(key)) {
+ return;
+ }
+ if (typeof gc[key] === 'function') {
+ self[key] = !logger ? gc[key].bind(gc) : function() {
+ return logger(key, arguments, gc[key].apply(gc, arguments));
+ };
+ } else {
+ Object.defineProperty(self, key, {
+ get: function() {
+ var result = gc[key];
+ return logger ? logger(key, 'getter', result) : result;
+ },
+ set: function(value) {
+ gc[key] = logger ? logger(key, 'setter', value) : value;
+ }
+ });
+ }
+ }
+}
- getDefaultHeaders: function() {
- return this.dataSource.getFields();
- },
+module.exports = GraphicsContext;
- setHeaders: function(headers) {
- return this.dataSource.setHeaders(headers);
- },
+},{"./gc-console-logger":7}],7:[function(require,module,exports){
+'use strict';
- getHeaders: function() {
- return this.dataSource.getHeaders();
- },
+var YIELDS = '\u27F9'; // LONG RIGHTWARDS DOUBLE ARROW
- getGrandTotals: function() {
- return this.dataSource.getGrandTotals();
- },
+function consoleLogger(prefix, name, args, value) {
+ var result = value;
- setData: function(arrayOfUniformObjects) {
- return this.dataSource.setData(arrayOfUniformObjects);
- },
+ if (typeof value === 'string') {
+ result = '"' + result + '"';
+ }
- clearIndex: function() {
- this.index.length = 0;
- },
+ name = prefix + name;
- buildIndex: function(predicate) {
- var rowCount = this.dataSource.getRowCount(),
- index = this.index;
+ switch (args) {
+ case 'getter':
+ console.log(name, '=', result);
+ break;
- index.length = 0;
+ case 'setter':
+ console.log(name, YIELDS, result);
+ break;
- for (var r = 0; r < rowCount; r++) {
- if (!predicate || predicate.call(this, r, this.dataSource.getRow(r))) {
- index.push(r);
+ default: // method call
+ name += '(' + Array.prototype.slice.call(args).join(', ') + ')';
+ if (result === undefined) {
+ console.log(name);
+ } else {
+ console.log(name, YIELDS, result);
}
- }
-
- return index;
}
-});
-
-module.exports = DataSourceIndexed;
+ return value;
+}
-},{"extend-me":3}],14:[function(require,module,exports){
-'use strict';
+module.exports = consoleLogger;
-var DataSourceIndexed = require('./DataSourceIndexed');
-var stableSort = require('./util/stableSort');
+},{}],8:[function(require,module,exports){
+/* eslint-disable */
-var DataSourceSorter = DataSourceIndexed.extend('DataSourceSorter', {
- initialize: function() {
- this.descendingSort = false; // TODO: this does not seem to be in use
- },
+/**
+ * @license
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+//module.exports = {};
- sortOn: function(colIdx, direction) {
- switch (direction) {
- case 0:
- this.clearIndex();
- break;
+(function(scope) {
+ var hasFullPath = false;
- case undefined:
- case 1:
- case -1:
- var self = this; // for use in getValue
- stableSort.sort(this.buildIndex(), getValue, direction);
- break;
- }
+ // test for full event path support
+ var pathTest = document.createElement('meta');
+ if (pathTest.createShadowRoot) {
+ var sr = pathTest.createShadowRoot();
+ var s = document.createElement('span');
+ sr.appendChild(s);
+ pathTest.addEventListener('testpath', function(ev) {
+ if (ev.path) {
+ // if the span is in the event path, then path[0] is the real source for all events
+ hasFullPath = ev.path[0] === s;
+ }
+ ev.stopPropagation();
+ });
+ var ev = new CustomEvent('testpath', {
+ bubbles: true
+ });
+ // must add node to DOM to trigger event listener
+ document.head.appendChild(pathTest);
+ s.dispatchEvent(ev);
+ pathTest.parentNode.removeChild(pathTest);
+ sr = s = null;
+ }
+ pathTest = null;
- function getValue(rowIdx) {
- return valOrFuncCall(self.dataSource.getValue(colIdx, rowIdx));
+ var target = {
+ shadow: function(inEl) {
+ if (inEl) {
+ return inEl.shadowRoot || inEl.webkitShadowRoot;
+ }
+ },
+ canTarget: function(shadow) {
+ return shadow && Boolean(shadow.elementFromPoint);
+ },
+ targetingShadow: function(inEl) {
+ var s = this.shadow(inEl);
+ if (this.canTarget(s)) {
+ return s;
+ }
+ },
+ olderShadow: function(shadow) {
+ var os = shadow.olderShadowRoot;
+ if (!os) {
+ var se = shadow.querySelector('shadow');
+ if (se) {
+ os = se.olderShadowRoot;
+ }
+ }
+ return os;
+ },
+ allShadows: function(element) {
+ var shadows = [],
+ s = this.shadow(element);
+ while (s) {
+ shadows.push(s);
+ s = this.olderShadow(s);
+ }
+ return shadows;
+ },
+ searchRoot: function(inRoot, x, y) {
+ var t, st, sr, os;
+ if (inRoot) {
+ t = inRoot.elementFromPoint(x, y);
+ if (t) {
+ // found element, check if it has a ShadowRoot
+ sr = this.targetingShadow(t);
+ } else if (inRoot !== document) {
+ // check for sibling roots
+ sr = this.olderShadow(inRoot);
+ }
+ // search other roots, fall back to light dom element
+ return this.searchRoot(sr, x, y) || t;
+ }
+ },
+ owner: function(element) {
+ if (!element) {
+ return document;
+ }
+ var s = element;
+ // walk up until you hit the shadow root or document
+ while (s.parentNode) {
+ s = s.parentNode;
+ }
+ // the owner element is expected to be a Document or ShadowRoot
+ if (s.nodeType != Node.DOCUMENT_NODE && s.nodeType != Node.DOCUMENT_FRAGMENT_NODE) {
+ s = document;
+ }
+ return s;
+ },
+ findTarget: function(inEvent) {
+ if (hasFullPath && inEvent.path && inEvent.path.length) {
+ return inEvent.path[0];
+ }
+ var x = inEvent.clientX,
+ y = inEvent.clientY;
+ // if the listener is in the shadow root, it is much faster to start there
+ var s = this.owner(inEvent.target);
+ // if x, y is not in this root, fall back to document search
+ if (!s.elementFromPoint(x, y)) {
+ s = document;
+ }
+ return this.searchRoot(s, x, y);
+ },
+ findTouchAction: function(inEvent) {
+ var n;
+ if (hasFullPath && inEvent.path && inEvent.path.length) {
+ var path = inEvent.path;
+ for (var i = 0; i < path.length; i++) {
+ n = path[i];
+ if (n.nodeType === Node.ELEMENT_NODE && n.hasAttribute('touch-action')) {
+ return n.getAttribute('touch-action');
+ }
+ }
+ } else {
+ n = inEvent.target;
+ while (n) {
+ if (n.nodeType === Node.ELEMENT_NODE && n.hasAttribute('touch-action')) {
+ return n.getAttribute('touch-action');
+ }
+ n = n.parentNode || n.host;
+ }
+ }
+ // auto is default
+ return "auto";
+ },
+ LCA: function(a, b) {
+ if (a === b) {
+ return a;
+ }
+ if (a && !b) {
+ return a;
+ }
+ if (b && !a) {
+ return b;
+ }
+ if (!b && !a) {
+ return document;
+ }
+ // fast case, a is a direct descendant of b or vice versa
+ if (a.contains && a.contains(b)) {
+ return a;
+ }
+ if (b.contains && b.contains(a)) {
+ return b;
+ }
+ var adepth = this.depth(a);
+ var bdepth = this.depth(b);
+ var d = adepth - bdepth;
+ if (d >= 0) {
+ a = this.walk(a, d);
+ } else {
+ b = this.walk(b, -d);
+ }
+ while (a && b && a !== b) {
+ a = a.parentNode || a.host;
+ b = b.parentNode || b.host;
+ }
+ return a;
+ },
+ walk: function(n, u) {
+ for (var i = 0; n && (i < u); i++) {
+ n = n.parentNode || n.host;
+ }
+ return n;
+ },
+ depth: function(n) {
+ var d = 0;
+ while (n) {
+ d++;
+ n = n.parentNode || n.host;
+ }
+ return d;
+ },
+ deepContains: function(a, b) {
+ var common = this.LCA(a, b);
+ // if a is the common ancestor, it must "deeply" contain b
+ return common === a;
+ },
+ insideNode: function(node, x, y) {
+ var rect = node.getBoundingClientRect();
+ return (rect.left <= x) && (x <= rect.right) && (rect.top <= y) && (y <= rect.bottom);
+ },
+ path: function(event) {
+ var p;
+ if (hasFullPath && event.path && event.path.length) {
+ p = event.path;
+ } else {
+ p = [];
+ var n = this.findTarget(event);
+ while (n) {
+ p.push(n);
+ n = n.parentNode || n.host;
+ }
+ }
+ return p;
}
- }
-});
-
-function valOrFuncCall(valOrFunc) {
- return typeof valOrFunc === 'function' ? valOrFunc() : valOrFunc;
-}
-
-module.exports = DataSourceSorter;
-},{"./DataSourceIndexed":13,"./util/stableSort":20}],15:[function(require,module,exports){
-'use strict';
-
-var DataSourceIndexed = require('./DataSourceIndexed');
-var DataSourceSorter = require('./DataSourceSorter');
-
-var DataSourceSorterComposite = DataSourceIndexed.extend('DataSourceSorterComposite', {
- initialize: function() {
- this.sorts = [];
- this.last = this.dataSource;
- },
-
- // Caveats regarding this.sorts:
- // 1. Columns should be uniquely represented (i.e., no repeats with same columnIndex)
- // 2. Columns should be added low- to high-order (i.e., most grouped columns come last)
- sortOn: function(columnIndex, direction) {
- this.sorts.push([columnIndex, direction]);
- },
+ };
+ scope.targetFinding = target;
+ /**
+ * Given an event, finds the "deepest" node that could have been the original target before ShadowDOM retargetting
+ *
+ * @param {Event} Event An event object with clientX and clientY properties
+ * @return {Element} The probable event origninator
+ */
+ scope.findTarget = target.findTarget.bind(target);
+ /**
+ * Determines if the "container" node deeply contains the "containee" node, including situations where the "containee" is contained by one or more ShadowDOM
+ * roots.
+ *
+ * @param {Node} container
+ * @param {Node} containee
+ * @return {Boolean}
+ */
+ scope.deepContains = target.deepContains.bind(target);
- applySorts: function() {
- var each = this.dataSource;
+ /**
+ * Determines if the x/y position is inside the given node.
+ *
+ * Example:
+ *
+ * function upHandler(event) {
+ * var innode = PolymerGestures.insideNode(event.target, event.clientX, event.clientY);
+ * if (innode) {
+ * // wait for tap?
+ * } else {
+ * // tap will never happen
+ * }
+ * }
+ *
+ * @param {Node} node
+ * @param {Number} x Screen X position
+ * @param {Number} y screen Y position
+ * @return {Boolean}
+ */
+ scope.insideNode = target.insideNode;
- this.sorts.forEach(function(sort) {
- each = new DataSourceSorter(each);
- each.sortOn.apply(each, sort);
- });
+})(exports);
- this.last = each;
- },
+(function() {
+ function shadowSelector(v) {
+ return 'html /deep/ ' + selector(v);
+ }
- clearSorts: function() {
- this.sorts.length = 0;
- this.last = this.dataSource;
- },
+ function selector(v) {
+ return '[touch-action="' + v + '"]';
+ }
- getValue: function(x, y) {
- return this.last.getValue(x, y);
- },
-
- setValue: function(x, y, value) {
- this.last.setValue(x, y, value);
+ function rule(v) {
+ return '{ -ms-touch-action: ' + v + '; touch-action: ' + v + ';}';
}
-});
+ var attrib2css = [
+ 'none',
+ 'auto',
+ 'pan-x',
+ 'pan-y', {
+ rule: 'pan-x pan-y',
+ selectors: [
+ 'pan-x pan-y',
+ 'pan-y pan-x'
+ ]
+ },
+ 'manipulation'
+ ];
+ var styles = '';
+ // only install stylesheet if the browser has touch action support
+ var hasTouchAction = typeof document.head.style.touchAction === 'string';
+ // only add shadow selectors if shadowdom is supported
+ var hasShadowRoot = !window.ShadowDOMPolyfill && document.head.createShadowRoot;
-module.exports = DataSourceSorterComposite;
-},{"./DataSourceIndexed":13,"./DataSourceSorter":14}],16:[function(require,module,exports){
-'use strict';
+ if (hasTouchAction) {
+ attrib2css.forEach(function(r) {
+ if (String(r) === r) {
+ styles += selector(r) + rule(r) + '\n';
+ if (hasShadowRoot) {
+ styles += shadowSelector(r) + rule(r) + '\n';
+ }
+ } else {
+ styles += r.selectors.map(selector) + rule(r.rule) + '\n';
+ if (hasShadowRoot) {
+ styles += r.selectors.map(shadowSelector) + rule(r.rule) + '\n';
+ }
+ }
+ });
-module.exports = {
- JSDataSource: require('./DataSource'),
- DataSourceSorter: require('./DataSourceSorter'),
- DataSourceSorterComposite: require('./DataSourceSorterComposite'),
- DataSourceFilter: require('./DataSourceFilter'),
- DataSourceGlobalFilter: require('./DataSourceGlobalFilter'),
- DataSourceAggregator: require('./DataSourceAggregator'),
- util: {
- aggregations: require('./util/aggregations')
+ var el = document.createElement('style');
+ el.textContent = styles;
+ document.head.appendChild(el);
}
-};
-},{"./DataSource":9,"./DataSourceAggregator":10,"./DataSourceFilter":11,"./DataSourceGlobalFilter":12,"./DataSourceSorter":14,"./DataSourceSorterComposite":15,"./util/aggregations":18}],17:[function(require,module,exports){
-'use strict';
+})();
-function Mappy() {
- this.keys = [];
- this.data = {};
- this.values = [];
-}
+/**
+ * This is the constructor for new PointerEvents.
+ *
+ * New Pointer Events must be given a type, and an optional dictionary of
+ * initialization properties.
+ *
+ * Due to certain platform requirements, events returned from the constructor
+ * identify as MouseEvents.
+ *
+ * @constructor
+ * @param {String} inType The type of the event to create.
+ * @param {Object} [inDict] An optional dictionary of initial event properties.
+ * @return {Event} A new PointerEvent of type `inType` and initialized with properties from `inDict`.
+ */
+(function(scope) {
-Mappy.prototype = {
+ var MOUSE_PROPS = [
+ 'bubbles',
+ 'cancelable',
+ 'view',
+ 'detail',
+ 'screenX',
+ 'screenY',
+ 'clientX',
+ 'clientY',
+ 'ctrlKey',
+ 'altKey',
+ 'shiftKey',
+ 'metaKey',
+ 'button',
+ 'relatedTarget',
+ 'pageX',
+ 'pageY'
+ ];
- constructor: Mappy.prototype.constructor, // preserve constructor
+ var MOUSE_DEFAULTS = [
+ false,
+ false,
+ null,
+ null,
+ 0,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ 0,
+ 0
+ ];
- set: function(key, value) {
- var hashCode = hash(key);
- if (!(hashCode in this.data)) {
- this.keys.push(key);
- this.values.push(value);
- }
- this.data[hashCode] = value;
- },
+ var NOP_FACTORY = function() {
+ return function() {};
+ };
- get: function(key) {
- var hashCode = hash(key);
- return this.data[hashCode];
- },
+ var eventFactory = {
+ // TODO(dfreedm): this is overridden by tap recognizer, needs review
+ preventTap: NOP_FACTORY,
+ makeBaseEvent: function(inType, inDict) {
+ var e = document.createEvent('Event');
+ e.initEvent(inType, inDict.bubbles || false, inDict.cancelable || false);
+ e.preventTap = eventFactory.preventTap(e);
+ return e;
+ },
+ makeGestureEvent: function(inType, inDict) {
+ inDict = inDict || Object.create(null);
- getIfAbsent: function(key, ifAbsentFunc) {
- var value = this.get(key);
- if (value === undefined) {
- value = ifAbsentFunc(key, this);
- }
- return value;
- },
+ var e = this.makeBaseEvent(inType, inDict);
+ for (var i = 0, keys = Object.keys(inDict), k; i < keys.length; i++) {
+ k = keys[i];
+ if (k !== 'bubbles' && k !== 'cancelable') {
+ e[k] = inDict[k];
+ }
+ }
+ return e;
+ },
+ makePointerEvent: function(inType, inDict) {
+ inDict = inDict || Object.create(null);
- size: function() {
- return this.keys.length;
- },
+ var e = this.makeBaseEvent(inType, inDict);
+ // define inherited MouseEvent properties
+ for (var i = 2, p; i < MOUSE_PROPS.length; i++) {
+ p = MOUSE_PROPS[i];
+ e[p] = inDict[p] || MOUSE_DEFAULTS[i];
+ }
+ e.buttons = inDict.buttons || 0;
- clear: function() {
- this.keys.length = 0;
- // TODO: Is there a reason why this.values is not being truncated here as well?
- this.data = {};
- },
+ // Spec requires that pointers without pressure specified use 0.5 for down
+ // state and 0 for up state.
+ var pressure = 0;
+ if (inDict.pressure) {
+ pressure = inDict.pressure;
+ } else {
+ pressure = e.buttons ? 0.5 : 0;
+ }
- delete: function(key) {
- var hashCode = hash(key);
- if (this.data[hashCode] !== undefined) {
- var index = betterIndexOf(this.keys, key);
- this.keys.splice(index, 1);
- this.values.splice(index, 1);
- delete this.data[hashCode];
+ // add x/y properties aliased to clientX/Y
+ e.x = e.clientX;
+ e.y = e.clientY;
+
+ // define the properties of the PointerEvent interface
+ e.pointerId = inDict.pointerId || 0;
+ e.width = inDict.width || 0;
+ e.height = inDict.height || 0;
+ e.pressure = pressure;
+ e.tiltX = inDict.tiltX || 0;
+ e.tiltY = inDict.tiltY || 0;
+ e.pointerType = inDict.pointerType || '';
+ e.hwTimestamp = inDict.hwTimestamp || 0;
+ e.isPrimary = inDict.isPrimary || false;
+ e._source = inDict._source || '';
+ return e;
}
- },
+ };
- forEach: function(func) {
- var keys = this.keys,
- self = this;
- keys.forEach(function(key) {
- var value = self.get(key);
- func(value, key, self);
- });
- },
+ scope.eventFactory = eventFactory;
+})(exports);
- map: function(func) {
- var keys = this.keys,
- newMap = new Mappy(),
- self = this;
- keys.forEach(function(key) {
- var value = self.get(key),
- transformed = func(value, key, self);
- newMap.set(key, transformed);
- });
- return newMap;
- },
+/**
+ * This module implements an map of pointer states
+ */
+(function(scope) {
+ var USE_MAP = window.Map && window.Map.prototype.forEach;
+ var POINTERS_FN = function() {
+ return this.size;
+ };
- copy: function() {
- var keys = this.keys,
- newMap = new Mappy(),
- self = this;
- keys.forEach(function(key) {
- var value = self.get(key);
- newMap.set(key, value);
- });
- return newMap;
+ function PointerMap() {
+ if (USE_MAP) {
+ var m = new Map();
+ m.pointers = POINTERS_FN;
+ return m;
+ } else {
+ this.keys = [];
+ this.values = [];
+ }
}
-};
-
-var OID_PREFIX = '.~.#%_'; //this should be something we never will see at the beginning of a string
-var counter = 0;
-
-function hash(key) {
- var typeOf = typeof key;
-
- switch (typeOf) {
- case 'number':
- case 'string':
- case 'boolean':
- case 'symbol':
- return OID_PREFIX + typeOf + '_' + key;
-
- case 'undefined':
- return OID_PREFIX + 'undefined';
-
- case 'object':
- // TODO: what about handling null (special case of object)?
- case 'function':
- return (key.___finhash = key.___finhash || OID_PREFIX + counter++); // eslint-disable-line
- }
-}
-
-// Object.is polyfill, courtesy of @WebReflection
-var is = Object.is || function(a, b) {
- return a === b ? a !== 0 || 1 / a == 1 / b : a != a && b != b; // eslint-disable-line
-};
-
-// More reliable indexOf, courtesy of @WebReflection
-function betterIndexOf(arr, value) {
- if (value != value || value === 0) { // eslint-disable-line
- for (var i = arr.length; i-- && !is(arr[i], value);) { // eslint-disable-line
+ PointerMap.prototype = {
+ set: function(inId, inEvent) {
+ var i = this.keys.indexOf(inId);
+ if (i > -1) {
+ this.values[i] = inEvent;
+ } else {
+ this.keys.push(inId);
+ this.values.push(inEvent);
+ }
+ },
+ has: function(inId) {
+ return this.keys.indexOf(inId) > -1;
+ },
+ 'delete': function(inId) {
+ var i = this.keys.indexOf(inId);
+ if (i > -1) {
+ this.keys.splice(i, 1);
+ this.values.splice(i, 1);
+ }
+ },
+ get: function(inId) {
+ var i = this.keys.indexOf(inId);
+ return this.values[i];
+ },
+ clear: function() {
+ this.keys.length = 0;
+ this.values.length = 0;
+ },
+ // return value, key, map
+ forEach: function(callback, thisArg) {
+ this.values.forEach(function(v, i) {
+ callback.call(thisArg, v, this.keys[i], this);
+ }, this);
+ },
+ pointers: function() {
+ return this.keys.length;
}
- } else {
- i = [].indexOf.call(arr, value);
- }
- return i;
-}
-
-module.exports = Mappy;
-},{}],18:[function(require,module,exports){
-'use strict';
-
-function count(group) {
- return group.getRowCount();
-}
-
-function sum(columnIndex, group) {
- var r = group.getRowCount(),
- n = 0;
-
- while (r--) {
- n += group.getValue(columnIndex, r);
- }
-
- return n;
-}
-
-function minmax(columnIndex, method, n, group) {
- var r = group.getRowCount();
-
- while (r--) {
- n = method(n, group.getValue(columnIndex, r));
- }
-
- return n;
-}
-
-function avg(columnIndex, group) {
- return sum(columnIndex, group) / group.getRowCount();
-}
-
-function first(columnIndex, group) {
- return group.getValue(columnIndex, 0);
-}
-
-function last(columnIndex, group) {
- return group.getValue(columnIndex, group.getRowCount() - 1);
-}
-
-function stddev(columnIndex, group) {
- var rows = group.getRowCount(),
- mean = avg(columnIndex, group);
-
- for (var dev, r = rows, variance = 0; r--; variance += dev * dev) {
- dev = group.getValue(columnIndex, r) - mean;
- }
+ };
- return Math.sqrt(variance / rows);
-}
+ scope.PointerMap = PointerMap;
+})(exports);
-module.exports = {
- count: function(columnIndex) {
- return count;
- },
- sum: function(columnIndex) {
- return sum.bind(this, columnIndex);
- },
- min: function(columnIndex) {
- return minmax.bind(this, columnIndex, Math.min, Infinity);
- },
- max: function(columnIndex) {
- return minmax.bind(this, columnIndex, Math.max, -Infinity);
- },
- avg: function(columnIndex) {
- return avg.bind(this, columnIndex);
- },
- first: function(columnIndex) {
- return first.bind(this, columnIndex);
- },
- last: function(columnIndex) {
- return last.bind(this, columnIndex);
- },
- stddev: function(columnIndex) {
- return stddev.bind(this, columnIndex);
- }
-};
-},{}],19:[function(require,module,exports){
-'use strict';
+(function(scope) {
+ var CLONE_PROPS = [
+ // MouseEvent
+ 'bubbles',
+ 'cancelable',
+ 'view',
+ 'detail',
+ 'screenX',
+ 'screenY',
+ 'clientX',
+ 'clientY',
+ 'ctrlKey',
+ 'altKey',
+ 'shiftKey',
+ 'metaKey',
+ 'button',
+ 'relatedTarget',
+ // DOM Level 3
+ 'buttons',
+ // PointerEvent
+ 'pointerId',
+ 'width',
+ 'height',
+ 'pressure',
+ 'tiltX',
+ 'tiltY',
+ 'pointerType',
+ 'hwTimestamp',
+ 'isPrimary',
+ // event instance
+ 'type',
+ 'target',
+ 'currentTarget',
+ 'which',
+ 'pageX',
+ 'pageY',
+ 'timeStamp',
+ // gesture addons
+ 'preventTap',
+ 'tapPrevented',
+ '_source'
+ ];
-function headerify(string) {
- return (/[a-z]/.test(string) ? string : string.toLowerCase())
- .replace(/[\s\-_]*([^\s\-_])([^\s\-_]+)/g, replacer)
- .replace(/[A-Z]/g, ' $&')
- .trim();
-}
+ var CLONE_DEFAULTS = [
+ // MouseEvent
+ false,
+ false,
+ null,
+ null,
+ 0,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ // DOM Level 3
+ 0,
+ // PointerEvent
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ '',
+ 0,
+ false,
+ // event instance
+ '',
+ null,
+ null,
+ 0,
+ 0,
+ 0,
+ 0,
+ function() {},
+ false
+ ];
-function replacer(a, b, c) {
- return b.toUpperCase() + c;
-}
+ var HAS_SVG_INSTANCE = (typeof SVGElementInstance !== 'undefined');
-module.exports = headerify;
-},{}],20:[function(require,module,exports){
-'use strict';
+ var eventFactory = scope.eventFactory;
-function stabilize(comparator, descending, arr1, arr2) { // eslint-disable-line no-shadow
- var x = arr1[0];
- var y = arr2[0];
-
- if (x === y) {
- x = descending ? arr2[1] : arr1[1];
- y = descending ? arr1[1] : arr2[1];
- } else {
- if (y === null) {
- return -1;
- }
- if (x === null) {
- return 1;
- }
- }
-
- return comparator(x, y);
-}
-
-function ascendingNumbers(x, y) {
- return x - y;
-}
-
-function descendingNumbers(x, y) {
- return y - x;
-}
-
-function ascendingAllOthers(x, y) {
- return x < y ? -1 : 1;
-}
-
-function descendingAllOthers(x, y) {
- return y < x ? -1 : 1;
-}
-
-function ascending(typeOfData) {
- return stabilize.bind(this, typeOfData === 'number' ? ascendingNumbers : ascendingAllOthers, false);
-}
-
-function descending(typeOfData) {
- return stabilize.bind(this, typeOfData === 'number' ? descendingNumbers : descendingAllOthers, true);
-}
-
-function sort(index, getValue, direction) {
-
- var compare, i;
-
- // apply defaults
- if (direction === undefined) {
- direction = 1;
- }
-
- if (index.length) { // something to do
- switch (direction) {
- case 0:
- return; // bail: nothing to sort
-
- case undefined: // eslint-disable-line no-fallthrough
- direction = 1;
- case 1:
- compare = ascending(typeof getValue(0));
- break;
-
- case -1:
- compare = descending(typeof getValue(0));
- break;
- }
-
- // set up the sort.....
- var tmp = new Array(index.length);
-
- // add the index for "stability"
- for (i = 0; i < index.length; i++) {
- tmp[i] = [getValue(i), i];
- }
-
- // do the actual sort
- tmp.sort(compare);
-
- // copy the sorted values into our index vector
- for (i = 0; i < index.length; i++) {
- index[i] = tmp[i][1];
- }
- }
-
-}
-
-exports.sort = sort;
-},{}],21:[function(require,module,exports){
-// list-dragon node module
-// https://github.com/openfin/list-dragon
-
-'use strict';
-
-/* eslint-env node, browser */
-
-(function (module) { // eslint-disable-line no-unused-expressions
-
- // This closure supports NodeJS-less client side includes with `.
- * For custom namespace, such as `window.namespace.rectangular`:
- * ```html
- *
- *
- *
- * ```
- * 2. File was reorganized to use prototypal inheritance so:
- * a. Change `finrectangle.point.create(...)` to `new rectangular.Point(...)`
- * b. Change `finrectangle.rectangle.create(...)` to `new rectangular.Rectangle(...)`
- * 3. Change all invocations of `Rectangle.top`, `.left`, `.bottom`, `.right`, `.width`,
- * `.height`, and `.area` to getter references by removing the invocation operator
- * (i.e., the parentheses).
- * 4. Change all invocations of `.isContainedWithinRectangle()` to `.within()`.
- * 5. Change all invocations of `.equal()` to `.equals()`.
- * 6. Change all invocations of `.lessThanEqualTo()` to `.lessThanOrEqualTo()`.
- * 7. Change all invocations of `.greaterThanEqualTo()` to `.greaterThanOrEqualTo()`.
- */
+ //var behavior = grid.getBehavior();
+ var y = gridCell.y;
+ // var previousDragExtent = grid.getDragExtent();
+ var mouseDown = grid.getMouseDown();
-(function(module, exports) { // eslint-disable-line no-unused-expressions
+ var newY = y - mouseDown.y;
+ //var newY = y - mouseDown.y;
- // This closure supports NodeJS-less client side includes with