Socket
Socket
Sign inDemoInstall

fin-hypergrid

Package Overview
Dependencies
Maintainers
2
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fin-hypergrid - npm Package Compare versions

Comparing version 2.1.2 to 2.1.4

src/renderer/layer-props.js

2

package.json
{
"name": "fin-hypergrid",
"version": "2.1.2",
"version": "2.1.4",
"description": "Canvas-based high-performance grid",

@@ -5,0 +5,0 @@ "repository": {

@@ -19,5 +19,5 @@ [![Build Status](https://travis-ci.org/openfin/fin-hypergrid.svg?branch=develop)](https://travis-ci.org/openfin/fin-hypergrid)

### Current Release (2.1.2 - 29 January 2018)
### Current Release (2.1.4 - 20 February 2018)
**Hypergrid 2.1.2** includes bug fixes as well as some new properties and methods that offer new capabilities.
**Hypergrid 2.1.4** includes bug fixes and new properties and methods that offer new capabilities.

@@ -24,0 +24,0 @@ _For a complete list of changes, see the [release notes](https://github.com/fin-hypergrid/core/releases)._

@@ -15,2 +15,9 @@ /* globals alert */

Object.defineProperty(Base.prototype, 'version', {
enumerable: true,
writable: false, // read-only
configurable: false,
value: require('../package.json').version
});
Base.prototype.deprecated = require('./lib/deprecated');

@@ -17,0 +24,0 @@ Base.prototype.HypergridError = require('./lib/error');

@@ -762,3 +762,3 @@ 'use strict';

var metadata = (dataModel || this.dataModel).getRowMetadata(yOrCellEvent, properties && {});
return metadata && (metadata.__ROW || (metadata.__ROW = properties));
return metadata && (metadata.__ROW || properties && (metadata.__ROW = properties));
},

@@ -1090,3 +1090,3 @@

isColumnReorderable: function() {
return this.grid.properties.columnsReorderable;
return this.deprecated('isColumnReorderable()', 'grid.properties.columnsReorderable', '2.1.3');
},

@@ -1093,0 +1093,0 @@

@@ -148,12 +148,12 @@ /* eslint-env bro wser */

function newCellPropertiesObject(rowIndex, dataModel) {
var rowData = (dataModel || this.dataModel).getRow(rowIndex),
metadata = rowData.__META = rowData.__META || {},
props;
var metadata = (dataModel || this.dataModel).getRowMetadata(rowIndex, {}),
props = this.properties;
if (this._index >= 0) {
props = this.properties;
} else if (this._index === this.behavior.treeColumnIndex) {
props = this.properties.treeHeader;
} else if (this._index === this.behavior.rowColumnIndex) {
props = this.properties.rowHeader;
switch (this._index) {
case this.behavior.treeColumnIndex:
props = this.properties.treeHeader;
break;
case this.behavior.rowColumnIndex:
props = this.properties.rowHeader;
break;
}

@@ -160,0 +160,0 @@

@@ -8,5 +8,7 @@ /* eslint-env browser */

var deprecated = require('../lib/deprecated');
var toFunction = require('../lib/toFunction');
var HypergridError = require('../lib/error');
var images = require('../../images/index');
/** @summary Create a new `Column` object.

@@ -141,2 +143,5 @@ * @see {@link module:Cell} is mixed into Column.prototype.

var schema = this.dataModel.schema;
calculator = resolveCalculator.call(this, calculator);
if (calculator !== schema[this.index].calculator) {

@@ -359,2 +364,58 @@ if (calculator === undefined) {

var REGEX_ARROW_FUNC = /^(\(.*\)|\w+)\s*=>/;
/**
* Calculators are functions. Column calculators are saved in `grid.properties.calculators` using the function name as key. Anonymous functions use the stringified function itself as the key. This may seem pointless, but this achieves the objective here which is to share function instances.
* @throws {HypergridError} Unexpected input.
* @throws {HypergridError} Arrow function not permitted.
* @throws {HypergridError} Unknown function.
* @this {Column}
* @param {function|string} calculator - One of:
* * calculator function
* * stringified calculator function with or without function name
* * function name of a known function (already in `calculators`)
* * falsy value
* @returns {function} Shared calculator instance or `undefined` if input was falsy.
*/
function resolveCalculator(calculator) {
if (!calculator) {
return undefined;
}
if (typeof calculator === 'function') {
calculator = calculator.toString();
} else if (typeof calculator !== 'string') {
throw new HypergridError('Expected function OR string containing function OR function name the "' + this.name + '" column calculator.');
}
var matches, key,
calculators = this.behavior.grid.properties.calculators || (this.behavior.grid.properties.calculators = {});
if (/^\w+$/.test(calculator)) {
key = calculator; // just a function name
if (!calculators[key]) {
throw new HypergridError('Unknown function name "' + key + '" for "' + this.name + '" column calculator.');
}
} else {
matches = calculator.match(/^function\s*(\w+)\(/);
if (matches) {
key = matches[1]; // function name extracted from stringified function
} else {
key = calculator; // anonymous stringified function
}
if (!calculators[key]) { // neither a string nor a function (previoulsy functionified string)?
if (REGEX_ARROW_FUNC.test(calculator)) {
throw new HypergridError('Arrow function not permitted as column calculator (for column "' + this.name + '").');
}
calculators[key] = calculator;
}
}
calculators[key] = toFunction(calculators[key]); // functionifies existing `calculators` entries as well as new entries
return calculators[key];
}
Column.prototype.mixIn(require('./cellProperties'));

@@ -361,0 +422,0 @@ Column.prototype.mixIn(require('./columnProperties'));

'use strict';
var toFunction = require('../lib/toFunction');
var FIELD = 'columnProperties.field is deprecated as of v1.1.0 in favor of columnProperties.name. (Will be removed in a future release.)',

@@ -79,29 +77,3 @@ COLUMN_NAME = 'columnProperties.columnName is deprecated as of v1.1.0 in favor of columnProperties.name. (Will be removed in a future release.)',

}
if (!calculator) {
column.calculator = undefined;
return;
}
if (typeof calculator === 'function') {
calculator = calculator.toString();
} else if (typeof calculator !== 'string') {
throw new this.grid.HypergridError('Expected function or string containing function or function name.');
}
var matches, key = calculator,
calculators = this.grid.properties.calculators = this.grid.properties.calculators || {};
if (/^\w+$/.test(calculator)) { // just a function name?
calculator = calculators[calculator];
} else {
matches = calculator.match(/^function\s*(\w+)\(/);
if (matches) {
key = matches[1];
}
}
column.calculator = calculators[key] = typeof calculators[key] === 'function'
? calculators[key] || key //null calculators use the key itself (anonymous functions)
: toFunction(calculator);
column.calculator = calculator;
}

@@ -108,0 +80,0 @@ },

@@ -48,3 +48,3 @@ 'use strict';

}
return this.super.get.call(this, name);
return this.super.get.call(this, name, true);
}

@@ -51,0 +51,0 @@

@@ -16,2 +16,6 @@ 'use strict';

};
var propClassLayersMap = {
DEFAULT: [propClassEnum.COLUMNS, propClassEnum.STRIPES, propClassEnum.ROWS, propClassEnum.CELLS],
NO_ROWS: [propClassEnum.CELLS]
};

@@ -26,2 +30,10 @@ /**

/**
* @summary The global theme name.
* @default
* @type {string}
* @memberOf module:defaults
*/
themeName: 'default',
set name(x) { throw new HypergridError(COLUMN_ONLY_PROPERTY); },

@@ -56,11 +68,2 @@ set type(x) { throw new HypergridError(COLUMN_ONLY_PROPERTY); },

/**
* @summary The global theme name.
* @desc Note that local themes (applied to grid instances) will have an overriding `themeName` property in their theme layer in the properties hierarchy.
* @default
* @type {string}
* @memberOf module:defaults
*/
themeName: 'default',
/**
* The font for data cells.

@@ -553,3 +556,3 @@ * @default

*/
gridBorderBottom: true,
gridBorderBottom: false,

@@ -1276,9 +1279,2 @@ /**

/** @summary Apply cell properties before `getCell`.
* @type {boolean}
* @default
* @memberOf module:defaults
*/
applyCellProperties: true,
/** @summary Reapply cell properties after `getCell`.

@@ -1289,3 +1285,9 @@ * @type {boolean}

*/
reapplyCellProperties: false,
set reapplyCellProperties(value) {
if (!warned.reapplyCellProperties) {
console.warn('The `.reapplyCellProperties` property has been deprecated as of v2.1.3 in favor of using the new `.propClassLayers` property. (May be removed in a future version.) This property is now a setter which sets `.propClassLayers` to `.propClassLayersMap.DEFAULT` (grid ← columns ← stripes ← rows ← cells) on truthy or `propClassLayersMap.NO_ROWS` (grid ← columns ← cells) on falsy, which is what you will see on properties stringification. This will give the same effect in most cases as the former property implementation, but not in all cases due to it no longer being applied dynamically. Developers should discontinue use of this property and start specifying `.propClassLayers` instead.');
warned.reapplyCellProperties = true;
}
this.propClassLayers = value ? propClassLayersMap.NO_ROWS : propClassLayersMap.DEFAULT;
},

@@ -1340,3 +1342,4 @@ /** @summary Column grab within this number of pixels from top of cell.

propClassEnum: propClassEnum,
propClassLayers: [ propClassEnum.COLUMNS, propClassEnum.STRIPES, propClassEnum.ROWS, propClassEnum.CELLS ],
propClassLayersMap: propClassLayersMap,
propClassLayers: propClassLayersMap.DEFAULT,

@@ -1382,10 +1385,12 @@ /**

Object.defineProperty(defaults, 'rowProperties', {
get: function() {
rowPropertiesDeprecationWarning();
return this.rowStripes;
},
set: function(rowProperties) {
rowPropertiesDeprecationWarning();
this.rowStripes = rowProperties;
Object.defineProperties(defaults, {
rowProperties: {
get: function() {
rowPropertiesDeprecationWarning();
return this.rowStripes;
},
set: function(rowProperties) {
rowPropertiesDeprecationWarning();
this.rowStripes = rowProperties;
}
}

@@ -1392,0 +1397,0 @@ });

@@ -17,7 +17,12 @@ 'use strict';

*/
handleDoubleClick: function(grid, event) {
handleClick: function(grid, event) {
edit.call(this, grid, event);
},
handleClick: function(grid, event) {
/**
* @memberOf CellEditing.prototype
* @param {Hypergrid} grid
* @param {Object} event - the event details
*/
handleDoubleClick: function(grid, event) {
edit.call(this, grid, event, true);

@@ -61,8 +66,6 @@ },

// Note: Keep ! in place to convert both sides to bool for
// accurate equality test because either could be undefined.
function edit(grid, event, onDoubleClick) {
if (
event.isDataCell &&
!event.getCellProperty('editOnDoubleClick') === !onDoubleClick // caution see note
!(event.getCellProperty('editOnDoubleClick') ^ onDoubleClick) // both same (true or falsy)?
) {

@@ -69,0 +72,0 @@ grid.onEditorActivate(event);

@@ -161,3 +161,3 @@ /* eslint-env browser */

if (
grid.behavior.isColumnReorderable() &&
grid.properties.columnsReorderable &&
!event.isColumnFixed

@@ -211,3 +211,3 @@ ) {

if (
grid.behavior.isColumnReorderable() &&
grid.properties.columnsReorderable &&
!event.isColumnFixed &&

@@ -214,0 +214,0 @@ !this.dragging &&

@@ -53,4 +53,2 @@ 'use strict';

// Note: Keep ! in place to convert both sides to bool for
// accurate equality test because either could be undefined.
function sort(grid, event, onDoubleClick) {

@@ -61,3 +59,3 @@ var columnProperties;

!(columnProperties = event.columnProperties).unsortable &&
!columnProperties.sortOnDoubleClick === !onDoubleClick // caution see note
!(columnProperties.sortOnDoubleClick ^ onDoubleClick) // both same (true or falsy)?
) {

@@ -64,0 +62,0 @@ grid.fireSyntheticColumnSortEvent(event.gridCell.x, event.primitiveEvent.detail.keys);

@@ -47,3 +47,4 @@ 'use strict';

* @param {Feature} nextFeature - this is how we build the chain of responsibility
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -80,3 +81,4 @@ setNext: function(nextFeature) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -93,3 +95,4 @@ handleMouseMove: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -106,3 +109,4 @@ handleMouseExit: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -119,3 +123,4 @@ handleMouseEnter: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -132,3 +137,4 @@ handleMouseDown: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -145,3 +151,4 @@ handleMouseUp: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -160,3 +167,4 @@ handleKeyDown: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -173,3 +181,4 @@ handleKeyUp: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -186,3 +195,4 @@ handleWheelMoved: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -199,3 +209,4 @@ handleDoubleClick: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -212,3 +223,4 @@ handleClick: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -225,3 +237,4 @@ handleMouseDrag: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -237,3 +250,4 @@ handleContextMenu: function(grid, event) {

* @desc toggle the column picker
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -298,3 +312,4 @@ moveSingleSelect: function(grid, x, y) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -314,3 +329,4 @@ setCursor: function(grid) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
* @private
* @comment Not really private but was cluttering up all the feature doc pages.
*/

@@ -317,0 +333,0 @@ initializeOn: function(grid) {

@@ -13,2 +13,6 @@ 'use strict';

factory.cellEventProperties = Object.defineProperties({}, {
/**
* The raw value of the cell, unformatted.
* @memberOf CellEvent#
*/
value: {

@@ -19,2 +23,7 @@ get: function() { return this.subgrid.getValue(this.dataCell.x, this.dataCell.y); },

/**
* An object representing the whole data row, including hidden columns.
* @type {object}
* @memberOf CellEvent#
*/
dataRow: {

@@ -24,2 +33,6 @@ get: function() { return this.subgrid.getRow(this.dataCell.y); }

/**
* The formatted value of the cell.
* @memberOf CellEvent#
*/
formattedValue: {

@@ -29,2 +42,10 @@ get: function() { return this.grid.formatValue(this.properties.format, this.value); }

/**
* The bounds of the cell.
* @property {number} left
* @property {number} top
* @property {number} width
* @property {number} height
* @memberOf CellEvent#
*/
bounds: { get: function() {

@@ -65,5 +86,16 @@ return this._bounds || (this._bounds = {

} },
/**
* @returns {string} Cell properties object if it exists, else the column properties object it would have as a prototype if did exist.
* @method
* @memberOf CellEvent#
*/
properties: { get: function() {
return this.cellOwnProperties || this.columnProperties;
} },
/**
* @param {string} key - Property name.
* @returns {string} Property value.
* @method
* @memberOf CellEvent#
*/
getCellProperty: { value: function(key) {

@@ -73,2 +105,8 @@ // included for completeness but `.properties[key]` is preferred

} },
/**
* @param {string} key - Property name.
* @param {string} value - Property value.
* @method
* @memberOf CellEvent#
*/
setCellProperty: { value: function(key, value) {

@@ -105,3 +143,3 @@ // do not use `.cellOwnProperties[key] = value` because object may be null (this method creates new object as needed)

// special methods for use by renderer which reuses cellEvent object for performance reasons
// special method for use by renderer which reuses cellEvent object for performance reasons
reset: { value: function(visibleColumn, visibleRow) {

@@ -138,2 +176,3 @@ // getter caches

* @returns {boolean} Visibility.
* @method
* @memberOf CellEvent#

@@ -156,2 +195,3 @@ */

* @returns {boolean} Visibility.
* @method
* @memberOf CellEvent#

@@ -175,2 +215,3 @@ */

* @returns {boolean} Visibility.
* @method
* @memberOf CellEvent#

@@ -195,2 +236,3 @@ */

* @returns {boolean} Visibility.
* @method
* @memberOf CellEvent#

@@ -232,2 +274,3 @@ */

* @returns {CellEvent}
* @method
* @memberOf CellEvent#

@@ -258,46 +301,161 @@ */

// "Visible" means scrolled into view.
/** "Visible" means scrolled into view.
* @type {boolean}
* @memberOf CellEvent#
*/
isRowVisible: { get: function() { return !!this.visibleRow; } },
/** "Visible" means scrolled into view.
* @type {boolean}
* @memberOf CellEvent#
*/
isColumnVisible: { get: function() { return !!this.visibleColumn; } },
/** "Visible" means scrolled into view.
* @type {boolean}
* @memberOf CellEvent#
*/
isCellVisible: { get: function() { return this.isRowVisible && this.isColumnVisible; } },
/** A data row is any row in the data subgrid; all other rows (headers, footers, _etc._) are not data rows.
* @type {boolean}
* @memberOf CellEvent#
*/
isDataRow: { get: function() { return this.subgrid.isData; } },
/** A data column is any column that is not the row number column or the tree column.
* @type {boolean}
* @memberOf CellEvent#
*/
isDataColumn: { get: function() { return this.gridCell.x >= 0; } },
/** A data cell is a cell in both a data row and a data column.
* @type {boolean}
* @memberOf CellEvent#
*/
isDataCell: { get: function() { return this.isDataRow && this.isDataColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isRowSelected: { get: function() { return this.isDataRow && this.selectionModel.isRowSelected(this.dataCell.y); } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isColumnSelected: { get: function() { return this.isDataColumn && this.selectionModel.isColumnSelected(this.gridCell.x); } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isCellSelected: { get: function() { return this.selectionModel.isCellSelected(this.gridCell.x, this.dataCell.y); } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isRowHovered: { get: function() { return this.grid.canvas.hasMouse && this.isDataRow && this.grid.hoverCell && this.grid.hoverCell.y === this.gridCell.y; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isColumnHovered: { get: function() { return this.grid.canvas.hasMouse && this.isDataColumn && this.grid.hoverCell && this.grid.hoverCell.x === this.gridCell.x; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isCellHovered: { get: function() { return this.isRowHovered && this.isColumnHovered; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isRowFixed: { get: function() { return this.isDataRow && this.dataCell.y < this.grid.properties.fixedRowCount; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isColumnFixed: { get: function() { return this.isDataColumn && this.gridCell.x < this.grid.properties.fixedColumnCount; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isCellFixed: { get: function() { return this.isRowFixed && this.isColumnFixed; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isHandleColumn: { get: function() { return this.gridCell.x === this.behavior.rowColumnIndex && this.grid.properties.showRowNumbers; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isHandleCell: { get: function() { return this.isHandleColumn && this.isDataRow; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isTreeColumn: { get: function() { return this.gridCell.x === this.behavior.treeColumnIndex; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isHeaderRow: { get: function() { return this.subgrid.isHeader; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isHeaderHandle: { get: function() { return this.isHeaderRow && this.isHandleColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isHeaderCell: { get: function() { return this.isHeaderRow && this.isDataColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isFilterRow: { get: function() { return this.subgrid.isFilter; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isFilterHandle: { get: function() { return this.isFilterRow && this.isHandleColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isFilterCell: { get: function() { return this.isFilterRow && this.isDataColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isSummaryRow: { get: function() { return this.subgrid.isSummary; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isSummaryHandle: { get: function() { return this.isSummaryRow && this.isHandleColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isSummaryCell: { get: function() { return this.isSummaryRow && this.isDataColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isTopTotalsRow: { get: function() { return this.subgrid === this.behavior.subgrids.lookup.topTotals; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isTopTotalsHandle: { get: function() { return this.isTopTotalsRow && this.isHandleColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isTopTotalsCell: { get: function() { return this.isTopTotalsRow && this.isDataColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isBottomTotalsRow: { get: function() { return this.subgrid === this.behavior.subgrids.lookup.bottomTotals; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isBottomTotalsHandle: { get: function() { return this.isBottomTotalsRow && this.isHandleColumn; } },
/** @type {boolean}
* @memberOf CellEvent#
*/
isBottomTotalsCell: { get: function() { return this.isBottomTotalsRow && this.isDataColumn; } },

@@ -323,11 +481,4 @@

/**
* @classdesc `CellEvent` is a very low-level object that needs to be super-efficient. JavaScript objects are well known to be light weight in general, but at this level we need to be careful.
* @name cellEventFactory
*
* These objects were originally only being created on mouse events. This was no big deal as mouse events are few and far between. However, as of v1.2.0, the renderer now also creates one for each visible cell on each and every grid paint.
*
* For this reason, to maintain performance, each grid gets a custom definition of `CellEvent`, created by this class factory, with the following optimizations:
*
* * Use of `extend-me` is avoided because its `initialize` chain is a bit too heavy here.
* * Custom versions of `CellEvent` for each grid lightens the load on the constructor.
*
* @summary Create a custom `CellEvent` class.

@@ -339,3 +490,3 @@ *

*
* @returns {CellEvent}
* @returns {function}
*/

@@ -346,2 +497,12 @@ function factory(grid) {

* @summary Create a new CellEvent object.
*
* @classdesc `CellEvent` is a very low-level object that needs to be super-efficient. JavaScript objects are well known to be light weight in general, but at this level we need to be careful.
*
* These objects were originally only being created on mouse events. This was no big deal as mouse events are few and far between. However, as of v1.2.0, the renderer now also creates one for each visible cell on each and every grid paint.
*
* For this reason, to maintain performance, each grid gets a custom definition of `CellEvent`, created by this class factory, with the following optimizations:
*
* * Use of `extend-me` is avoided because its `initialize` chain is a bit too heavy here.
* * Custom versions of `CellEvent` for each grid lightens the load on the constructor.
*
* @desc All own enumerable properties are mixed into cell editor:

@@ -352,8 +513,11 @@ * * Includes `this.column` defined by constructor (as enumerable).

*
* Including params calls {CellEvent#resetGridCY}.
* (See also the alternatives {@link CellEvent#resetGridXY}, {@link CellEvent#resetDataXY}, and {@link CellEvent#resetGridXDataY}.)
* Including the params calls {@link CellEvent#resetGridCY resetGridCY(gridX, gridY)}.
* Alternatively, instantiate without params and/or later call one of these:
* * {@link CellEvent#resetGridXY resetGridXY(...)}
* * {@link CellEvent#resetDataXY resetDataXY(...)}
* * {@link CellEvent#resetGridXDataY resetGridXDataY(...)}
*
* @param {number} [gridX] - grid cell coordinate (adjusted for horizontal scrolling after fixed columns).
* @param {number} [gridY] - grid cell coordinate, adjusted (adjusted for vertical scrolling if data subgrid)
* @constructor
* @constructor CellEvent
*/

@@ -365,3 +529,3 @@ function CellEvent(gridX, gridY) {

* @name visibleColumn
* @type {visibleColumnDescriptor}
* @type {visibleColumnArray}
* @memberOf CellEvent#

@@ -373,3 +537,3 @@ */

* @name visibleRow
* @type {visibleRowDescriptor}
* @type {visibleRowArray}
* @memberOf CellEvent#

@@ -388,2 +552,5 @@ */

* @name gridCell
* @property {number} x - The active column index, adjusted for column scrolling after fixed columns; _i.e.,_
* an index suitable for dereferencing the column object to which the cell belongs via {@link Behavior#getActiveColumn}.
* @property {number} y - The vertical grid coordinate, unaffected by subgrid, row scrolling, and fixed rows.
* @type {WritablePoint}

@@ -398,2 +565,5 @@ * @memberOf CellEvent#

* @name dataCell
* @property {number} x - The data model's column index, unaffected by column scrolling; _i.e.,_
* an index suitable for dereferencing the column object to which the cell belongs via {@link Behavior#getColumn}.
* @property {number} y - The data model's row index, adjusted for data row scrolling after fixed rows.
* @type {WritablePoint}

@@ -406,3 +576,10 @@ * @memberOf CellEvent#

// column is enumerable so it will be copied to cell event on CellEvent.prototype.initialize.
/**
* A reference to the cell's {@link Column} object.
*
* Enumerable so it will be copied to cell event on CellEvent.prototype.initialize.
* @name column
* @type {Column}
* @memberOf CellEvent#
*/
column: eumerableDescriptor,

@@ -409,0 +586,0 @@

@@ -43,3 +43,3 @@ 'use strict';

set: function(subgrids) {
this.var.subgrids = subgrids;
this.var.subgrids = subgrids.slice();

@@ -61,3 +61,3 @@ if (this.grid.behavior) {

set: function(features) {
this.var.features = features;
this.var.features = features.slice();
if (this.grid.behavior) {

@@ -216,4 +216,4 @@ this.grid.behavior.initializeFeatureChain(features);

// The following grid line props are now dynamic (as of v2.1.0).
// They non-enumerable so they will not be output with `grid.saveState()`.
// The new (as of 2.1.0) props they refer to is output instead:
// They're non-enumerable so they will not be output with `grid.saveState()`.
// The new (as of 2.1.0) props they refer to are output instead:
// `gridLinesHColor`, `gridLinesVColor`, `gridLinesHWidth`, and `gridLinesVWidth`

@@ -385,7 +385,4 @@ lineColor: {

function getGridBorderDescriptor(edge) {
edge = edge || '';
var propName = 'gridBorder' + (edge || '');
var propName = 'gridBorder' + edge,
styleName = 'border' + edge;
return {

@@ -398,14 +395,8 @@ enumerable: true,

this.var[propName] = border;
if (!edge) {
this.var.gridBorderLeft = this.var.gridBorderRight = this.var.gridBorderTop = this.var.gridBorderBottom = border;
}
switch (border) {
case true:
border = this.lineWidth + 'px solid ' + this.lineColor;
break;
case false:
border = null;
break;
}
this.grid.canvas.canvas.style[styleName] = border;
this.grid.resetGridBorder(edge);
}

@@ -412,0 +403,0 @@ };

@@ -65,3 +65,7 @@ /* eslint-env browser */

if (info.listener === listener) {
listenerList.splice(index, 1); // remove it from the list
if (listenerList.length === 1) {
delete this.listeners[eventName];
} else {
listenerList.splice(index, 1); // remove it from the list
}
this.canvas.removeEventListener(eventName, info.decorator);

@@ -82,3 +86,3 @@ return true;

_(this.listeners).each(function(listenerList, key) {
listenerList.forEach(function(info) {
listenerList.slice().forEach(function(info) {
if (internal || !info.internal) {

@@ -85,0 +89,0 @@ this.removeEventListener(key, info.listener);

@@ -88,3 +88,3 @@ 'use strict';

if (!noThrow && !result) {
var classDesc = this.$$CLASS_NAME.replace(/[A-Z]/g, ' $1').trim().toLowerCase();
var classDesc = this.BaseClass.$$CLASS_NAME.replace(/([A-Z])/g, ' $1').trim().toLowerCase();
throw new this.HypergridError('Expected "' + name + '" to be a registered ' + classDesc + '.');

@@ -91,0 +91,0 @@ }

'use strict';
var HypergridError = require('./error');
/**

@@ -16,3 +18,3 @@ * @param {function|string} string

default:
throw 'Expected string, function, or undefined.';
throw new HypergridError('Expected string, function, or undefined.');
}

@@ -22,3 +24,3 @@

if (!args) {
throw 'Expected function keyword with formal parameter list.';
throw new HypergridError('Expected function keyword with formal parameter list.');
}

@@ -28,3 +30,3 @@ args = args[1].split(',').map(function(s, i) {

if (!s && i) {
throw 'Expected formal parameter.';
throw new HypergridError('Expected formal parameter.');
}

@@ -34,5 +36,5 @@ return s[1];

var body = string.match(/{\s*([^]*?)\s*}/);
var body = string.match(/{\s*([^]*?)\s*}\s*$/);
if (!body) {
throw 'Expected function body.';
throw new HypergridError('Expected function body.');
}

@@ -39,0 +41,0 @@ body = body[1];

@@ -7,23 +7,6 @@ /* eslint-env browser */

var Base = require('../Base');
var images = require('../../images/index');
var images = require('../../images');
var layerProps = require('./layer-props');
var propClassGet = [
undefined,
function(cellEvent) {
return cellEvent.columnProperties;
},
function(cellEvent) {
var rowStripes = cellEvent.isDataRow && cellEvent.columnProperties.rowStripes;
return rowStripes && rowStripes[cellEvent.dataCell.y % rowStripes.length];
},
function(cellEvent) {
return cellEvent.rowOwnProperties;
},
function(cellEvent) {
return cellEvent.cellOwnProperties;
}
];
var visibleColumnPropertiesDescriptorFn = function(grid) {

@@ -82,3 +65,3 @@ return {

/** @typedef {object} visibleColumnDescriptor
/** @typedef {object} visibleColumnArray
* @property {number} index - A back reference to the element's array index in {@link Renderer#visibleColumns}.

@@ -91,3 +74,3 @@ * @property {number} columnIndex - Dereferences {@link Behavior#columns}, the subset of _active_ columns, specifying which column to show in that position.

/** @typedef {object} visibleRowDescriptor
/** @typedef {object} visibleRowArray
* @property {number} index - A back reference to the element's array index in {@link Renderer#visibleRows}.

@@ -154,3 +137,3 @@ * @property {number} rowIndex - Local vertical row coordinate within the subgrid to which the row belongs, adjusted for scrolling.

* 3. An n-based list of consecutive of integers representing the scrollable columns (where n = number of fixed columns + the number of columns scrolled off to the left).
* @type {visibleColumnDescriptor}
* @type {visibleColumnArray}
*/

@@ -169,3 +152,3 @@ this.visibleColumns = Object.defineProperties([], visibleColumnPropertiesDescriptorFn(this.grid));

* Note that non-scrollable subgrids can come both before _and_ after the scrollable subgrid.
* @type {visibleRowDescriptor}
* @type {visibleRowArray}
*/

@@ -1047,7 +1030,2 @@ this.visibleRows = [];

// Overwrite possibly mutated cell properties, if requested to do so by `getCell` override
if (cellEvent.cellOwnProperties && config.reapplyCellProperties) {
Object.assign(config, cellEvent.cellOwnProperties);
}
behavior.cellPropertiesPrePaintNotification(config);

@@ -1076,23 +1054,7 @@

* Overridable for alternative or faster logic.
* @param cellEvent
* @param CellEvent
* @returns {object} Layered config object.
*/
assignProps: function(cellEvent) {
var i, base, assignments,
propLayers = cellEvent.columnProperties.propClassLayers;
assignProps: layerProps,
if (propLayers[0] !== 1) {
i = 0; // all prop layers
base = this.grid.properties;
} else {
i = 1; // skip column prop layer
base = cellEvent.columnProperties; // because column has grid properties as prototype
}
for (assignments = [Object.create(base)]; i < propLayers.length; ++i) {
assignments.push(propClassGet[propLayers[i]](cellEvent));
}
return Object.assign.apply(Object, assignments);
},
/**

@@ -1099,0 +1061,0 @@ * @param {number|CellEvent} colIndexOrCellEvent - This is the "data" x coordinate.

'use strict';
// This file creates the Hypergrid theme registry, exposed as `Hypergrid.themes` (see).
// This file creates the Hypergrid theme registry, exposed via:
// shared methods `Hypergrid.registerTheme` and `Hypergrid.applyTheme`
// and instance methods `myGrid.applyTheme`.
// The initial registry consists of a single theme ('default').
// Application developers can add additional themes to this registry.
var _ = require('object-iterators'); // fyi: installs the Array.prototype.find polyfill, as needed
var defaults = require('./defaults');
var dynamicPropertyDescriptors = require('./lib/dynamicProperties');
var HypergridError = require('./lib/error');

@@ -15,7 +21,7 @@ var styles = [

var styleWithHalign = styles.concat([
var stylesWithHalign = styles.concat([
'Halign'
]);
var dataCellStyles = styleWithHalign.concat([
var dataCellStyles = stylesWithHalign.concat([
'cellPadding',

@@ -28,3 +34,3 @@ 'iconPadding'

{ prefix: 'foregroundSelection', props: styles },
{ prefix: 'columnHeader', props: styleWithHalign },
{ prefix: 'columnHeader', props: stylesWithHalign },
{ prefix: 'columnHeaderForegroundSelection', props: styles },

@@ -35,14 +41,26 @@ { prefix: 'rowHeader', props: styles },

var defaultTheme = {
themeName: defaults.themeName
var dynamicCosmetics = {
rowHeaderCheckboxes: defaults.rowHeaderCheckboxes,
rowHeaderNumbers: defaults.rowHeaderNumbers,
gridBorder: defaults.gridBorder,
gridBorderTop: defaults.gridBorderTop,
gridBorderRight: defaults.gridBorderRight,
gridBorderBottom: defaults.gridBorderBottom,
gridBorderLeft: defaults.gridBorderLeft,
gridRenderer: defaults.gridRenderer
};
// Here we create the `defaults` theme by copying over the theme props,
// which is a subset of all the props defined in defaults.js. The following
// combines the above prefixes with their styles to get theme prop names; and
// then copies those props from the defaults.js to create the `default` theme.
module.exports.default = stylers.reduce(function(theme, styler) {
// Create the `defaultTheme` theme by copying over the theme props,
// which is a subset of all the props defined in defaults.js, beginning with
// they dynamic cosmetics and `themeName`...
var defaultTheme = Object.assign({}, dynamicCosmetics, {
themeName: defaults.themeName
});
// ...and then adding non-dynamic cosmetics into `defaultTheme`, by combining the above
// prefixes with their styles to get prop names and then copy those props from `defaults`.
stylers.reduce(function(theme, styler) {
return styler.props.reduce(function(theme, prop) {
prop = styler.prefix + prop;
prop = prop.replace('ForegroundSelectionBackground', 'BackgroundSelection');
prop = prop.replace('ForegroundSelectionBackground', 'BackgroundSelection'); // unfortunate!
prop = prop[0].toLowerCase() + prop.substr(1);

@@ -53,1 +71,230 @@ theme[prop] = defaults[prop];

}, defaultTheme);
/**
* @summary The Hypergrid theme registry.
* @desc The standard registry consists of a single theme, `default`, built from values in defaults.js.
*/
var registry = Object.create(null, {
default: { value: defaultTheme }
});
var pseudopropAdvice = {
showRowNumbers: 'rowHeaderCheckboxes and rowHeaderNumbers',
lineColor: 'gridLinesHColor and gridLinesVColor',
lineWidth: 'gridLinesHWidth and gridLinesVWidth',
gridBorder: 'gridBorderLeft, gridBorderRight, gridBorderTop, and gridBorderBottom'
};
function applyTheme(theme) {
var themeLayer, grids, props;
if (theme && typeof theme === 'object' && !Object.getOwnPropertyNames(theme).length) {
theme = null;
}
if (this._theme) {
grids = [this];
themeLayer = this._theme;
props = this.properties;
// If removing theme, reset props to defaults
if (!theme) {
// Delete (non-dynamic) grid props named in this theme, revealing defaults
Object.keys(themeLayer).forEach(function(key) {
if (!(key in dynamicPropertyDescriptors)) {
delete props[key];
}
});
// Reset dynamic cosmetic props to defaults
Object.keys(dynamicCosmetics).forEach(function(key) {
props.var[key] = defaults[key];
});
}
// Delete all own props from this grid instance's theme layer (defined by an eariler call)
Object.keys(themeLayer).forEach(function(key) {
delete themeLayer[key];
});
} else {
grids = this.grids;
themeLayer = defaults; // global theme layer
theme = theme || 'default';
}
if (typeof theme === 'string') {
if (!registry[theme]) {
throw new HypergridError('Unknown theme "' + theme + '"');
}
theme = registry[theme];
}
if (theme) {
// When no theme name, set it to explicit `undefined` (to mask defaults.themeName).
if (!theme.themeName) {
theme.themeName = undefined;
}
Object.keys(theme).forEach(function(key) {
if (!(key in dynamicPropertyDescriptors)) {
grids.forEach(function(grid) {
delete grid.properties[key];
});
} else if (key in dynamicCosmetics) {
grids.forEach(function(grid) {
grid.properties[key] = theme[key];
});
} else {
// Dynamic properties are defined on properties layer; defining these
// r-values on the theme layer is ineffective so let's not allow it.
var message = pseudopropAdvice[key];
message = message
? 'Ignoring unexpected pseudo-prop ' + key + ' in theme object. Use actual props ' + message + ' instead.'
: 'Ignoring invalid property ' + key + ' in theme object.';
console.warn(message);
delete theme[key];
}
});
// No .assign() because themeName is read-only in defaults layer
Object.defineProperties(themeLayer, Object.getOwnPropertyDescriptors(theme));
}
grids.forEach(function(grid) {
grid.repaint();
});
}
/**
* Additions to `Hypergrid.prototype` for setting an instance theme.
* @mixin
*/
var mixin = {
initThemeLayer: function() {
/**
* Descends from {@link module:defaults|defaults}.
* @memberOf Hypergrid#
* @private
*/
this._theme = Object.create(defaults);
return Object.create(this._theme, dynamicPropertyDescriptors);
},
/**
* @summary Apply a grid theme.
* @desc Apply props from the given theme object to the grid instance,
* the instance's `myGrid.themeLayer` layer in the properties hierarchy.
* @this {Hypergrid}
* @param {object|string} [theme] - One of:
* * **string:** A registered theme name.
* * **object:** A unregistered (anonymous) theme object. Empty object removes grid theme, exposing global theme.
* * _falsy value:_ Also removes grid theme.
* @param {string|undefined} [theme.themeName=undefined]
* @memberOf Hypergrid#
*/
applyTheme: applyTheme,
/**
* @summary Get currently active theme.
* @desc May return a theme name or a theme object.
* @returns {string|undefined|object} One of:
* * **string:** Theme name (registered theme).
* * **object:** Theme object (unregistered anonymous theme).
* * **undefined:** No theme (i.e., the default theme).
* @memberOf Hypergrid#
*/
getTheme: function() {
var themeLayer = this._theme,
themeName = themeLayer.themeName;
return themeName === 'default' || !Object.getOwnPropertyNames(themeLayer).length
? undefined // default theme or no theme
: themeName in registry
? themeName // registered theme name
: themeLayer; // unregistered theme object
}
};
Object.defineProperty(mixin, 'theme', {
enumerable: true,
set: mixin.applyTheme,
get: mixin.getTheme
});
/**
* Shared properties of `Hypergrid` for registering themes and setting a global theme.
* @mixin
*/
var sharedMixin = {
/**
* @param {string} [name] - A registry name for the new theme. May be omitted if the theme has an embedded name (in `theme.themeName`).
* _If omitted, the 2nd parameter (`theme`) is promoted to first position._
* @param {HypergridThemeObject} [theme]
* To build a Hypergrid theme object from a loaded {@link https://polymerthemes.com Polymer Theme} CSS stylesheet:
* ```javascript
* var myTheme = require('fin-hypergrid-themes').buildTheme();
* ```
* @this {Hypergrid.constructor}
* @memberOf Hypergrid.
*/
registerTheme: function(name, theme) {
if (arguments.length === 1) {
theme = name;
name = theme.themeName;
}
if (!name) {
throw new HypergridError('Cannot register an anonymous theme.');
}
if (name === 'default') {
throw new HypergridError('Cannot register or unregister the "default" theme.');
}
if (theme) {
theme.themeName = name;
registry[name] = theme;
} else {
delete registry[name];
}
},
/**
* App developers are free to add in additional themes, such as those in {@link https://openfin.github.com/fin-hypergrid-themes/themes}:
* ```javascript
* Hypergrind.registerThemes(require('fin-hypergrid-themes'));
* ```
* @param {object} themeCollection
* @memberOf Hypergrid.
*/
registerThemes: function(themeCollection) {
_(themeCollection).each(function(theme, name) {
this.registerTheme(name, theme);
}, this);
},
/**
* @summary Apply global theme.
* @desc Apply props from the given theme object to the global theme object,
* the `defaults` layer at the bottom of the properties hierarchy.
* @this {Hypergrid.constructor}
* @param {object|string} [theme=registry.default] - One of:
* * **string:** A registered theme name.
* * **object:** A theme object. Empty object removes global them, restoring defaults.
* * _falsy value:_ Also restores defaults.
* @param {string|undefined} [theme.themeName=undefined]
* @memberOf Hypergrid.
*/
applyTheme: applyTheme
};
Object.defineProperty(sharedMixin, 'theme', { // global theme setter/getter
enumerable: true,
set: applyTheme,
get: function() { return defaults; } // the defaults layer *is* the global theme layer
});
module.exports = {
mixin: mixin,
sharedMixin: sharedMixin
};

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc