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 3.1.0 to 3.2.0

137

images/index.js

@@ -15,2 +15,3 @@ /* eslint-env browser */

var _ = require('object-iterators');
var svgThemer = require('svg-themer');

@@ -76,16 +77,119 @@ var images = require('./images'); // this is the file generated by gulpfile.js (and ignored by git)

/**
* @name add
* @method
* @param {string} key
* @param {string} name
* @param {HTMLImageElement} img
* @param {boolean} [themeable] - If truthy, the image will be themed by {@link module:images.setTheme images.setTheme}, called by {@link Hypergrid.applyTheme}.
* If falsy, the image won't be themed until `images[name].themeable` is set to `true`.
* In any case the remaining parameters are processed.
* @param {function} [setSvgProps=svgThemer.setSvgProps] - Optional custom theming code for this image and the rules implied by `styles`. _If omitted, `styles` is promoted 2nd parameter position._
* @param {boolean|string[]} [styles] - Optional list style names with which to create CSS rules.
* * If falsy (or omitted), no rules are created.
* * Else if truthy but not an array, create a single rule:
* ```css
* `.hypergrid-background-image-name { background-image: url(...) }`
* where _name_ is the value of the `name` parameter.
* * Else if an array, create a CSS rule for each style named therein.
*
* For each rule thus created:
* * Inserted into `style#injected-stylesheet-grid`.
* * Selector is `.hypergrid-style-name` (where `style` is element value and `name` is image name).
* (If a rule with that selector already exists, it is replaced.)
* * Contains the named style with a value of `url(...)` where `...` is the image data.
* Possible styles must be one of those listed in {*link https://github.com/joneit/svg-themer/blob/master/README.md#cssimagepropertynames svgThemer.cssImagePropertyNames} (which you can extend if needed).
* * Will be automatically themed when the grid is themed (which is the whole point).
*
* @see {@link https://github.com/joneit/svg-themer}
* @memberOf module:images
*/
images.add = function(key, img) {
return images[key] = img;
};
function add(name, img, themeable, setSvgProps, styles) {
if (/^data:image\/svg\+xml|\.svg/.test(img.src)) {
img.themeable = !!themeable;
if (typeof setSvgProps === 'object') {
styles = setSvgProps;
setSvgProps = undefined;
}
if (setSvgProps) {
img.setSvgProps = setSvgProps;
}
if (styles) {
img.themeableRules = createThemeableRules(name, img, setSvgProps, styles);
}
}
return (images[name] = img);
}
function createThemeableRules(key, img, setSvgProps, styles) {
// find or create stylesheet as needed
var styleEl = document.querySelector('style#injected-stylesheet-themeables');
if (!styleEl) {
styleEl = document.createElement('style');
styleEl.id = 'injected-stylesheet-themeables';
document.head.appendChild(styleEl);
}
var sheet = styleEl.sheet;
return (styles.length ? styles : ['background-image']).reduce(function(rules, styleName) {
var selectorText = '.hypergrid-' + styleName + '-' + key;
// find and delete existing rule, if any
var ruleIndex = Array.prototype.findIndex.call(sheet.cssRules, function(rule) {
return rule.selectorText === selectorText;
});
if (ruleIndex !== -1) {
sheet.deleteRule(ruleIndex);
}
// create and insert new rule consisting of selector + style "collection"
var ruleStyles = {};
// add image data style
ruleStyles[styleName] = 'url(' + img.src + ')';
// add dimensions if known
if (img.width) { ruleStyles.width = img.width + 'px'; }
if (img.height) { ruleStyles.height = img.height + 'px'; }
// combine the above styles into a semi-colon-separated "collection"
var styleCollection = Object.keys(ruleStyles).map(function(key) {
return key + ':' + ruleStyles[key];
}).join(';');
var ruleText = '{' + styleCollection + '}';
sheet.insertRule(selectorText + ruleText);
var themeableRule = {
rule: sheet.cssRules[0]
};
if (setSvgProps) {
themeableRule.setSvgProps = setSvgProps;
}
rules.push(themeableRule);
return rules;
}, []);
}
/**
* @param {object} theme
* @memberOf module:images
*/
function setTheme(theme) {
Object.keys(images).forEach(function(name) {
var img = images[name];
if (img.themeable) {
svgThemer.setImgSvgProps.call(img, theme, img.setSvgProps);
}
if (img.themeableRules) {
img.themeableRules.forEach(function(themeable) {
var selectorText = themeable.rule.selectorText;
// extract style name using list of possible names
var regex = new RegExp('^\.hypergrid-(' + svgThemer.cssImagePropertyNames.join('|') + ')-.*$');
var styleName = selectorText.replace(regex, '$1');
svgThemer.setRuleSvgProps.call(themeable.rule, theme, img.setSvgProps, styleName);
});
}
});
}
/**
* Convenience function.
* @name checkbox
* @method
* @param {boolean} state

@@ -95,10 +199,8 @@ * @returns {HTMLImageElement} {@link module:images.checked|checked} when `state` is truthy or {@link module:images.unchecked|unchecked} otherwise.

*/
images.checkbox = function(state) {
function checkbox(state) {
return images[state ? 'checked' : 'unchecked'];
};
}
/**
* Convenience function.
* @name filter
* @method
* @param {boolean} state

@@ -108,6 +210,15 @@ * @returns {HTMLImageElement} {@link module:images.filter-off|filter-off} when `state` is truthy or {@link module:images.filter-on|filter-on} otherwise.

*/
images.filter = function(state) {
function filter(state) {
return images[state ? 'filter-on' : 'filter-off'];
};
}
// add methods as non-enumerable members so member images can be enumerated
Object.defineProperties(images, {
add: { value: add },
setTheme: { value: setTheme },
checkbox: { value: checkbox },
filter: { value: filter }
});
module.exports = images;

5

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

@@ -35,2 +35,3 @@ "main": "src/Hypergrid",

"sparse-boolean-array": "1.0.1",
"svg-themer": "^1.1.2",
"synonomous": "^2.1.2"

@@ -45,3 +46,3 @@ },

"gulp-header": "^1.8.2",
"gulp-imagine-64": "^1.0.1",
"gulp-imagine-64": "^2.0.1",
"gulp-load-plugins": "^1.1.0",

@@ -48,0 +49,0 @@ "gulp-mocha": "^6.0.0",

@@ -18,5 +18,5 @@ **fin-hypergrid** is an ultra-fast HTML5 grid presentation layer, achieving its speed by rendering (in a canvas tag) only the currently visible portion of your (virtual) grid, thus avoiding the latency and life-cycle issues of building, walking, and maintaining a complex DOM structure. Please be sure to checkout our [design overview](OVERVIEW.md)

### Current Release (3.1.0 - 29 September 2018)
### Current Release (3.2.0 - 17 November 2018)
**Hypergrid 3.1 includes 3.0’s revised data model with some breaking changes.**
> **CAUTION:** For those considering upgrading directly from v2, be advised Hypergrid v3 introduced a revised data model _with breaking changes._ The impact of these changes has been intentionally minimized and should not affect the vast majority of users. See the [v3.0.0 release notes](https://github.com/fin-hypergrid/core/releases/tag/v3.0.0) for more information.

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

Published as a CommonJS module to npmjs.org.
Specify a <a href="https://semver.org/">SEMVER</a> of `"fin-hypergrid": "3.1.0"` (or `"^3.1.0"`) in your package.json file,
Specify a <a href="https://semver.org/">SEMVER</a> of `"fin-hypergrid": "3.2.0"` (or `"^3.2.0"`) in your package.json file,
issue the `npm install` command, and let your bundler (<a target="webpack" href="https://webpack.js.org/">wepback</a>,

@@ -32,0 +32,0 @@ <a target="browserify" href="http://browserify.org/">Browserify</a>) create a single file containing both Hypergrid and your application.

@@ -22,10 +22,12 @@ /* globals alert */

Base.prototype.atLeastVersion = function(neededVersion) {
var neededParts = neededVersion.split('.'),
thisParts = this.version.split('.'),
delta;
neededParts.find(function(neededPart, i) {
return (delta = neededPart - thisParts[i]);
});
return delta >= 0;
Base.prototype.versionAtLeast = function(neededVersion) {
var neededParts = neededVersion.split('.').map(Number),
delta = this.version.split('.').map(function(part, i) { return Number(part) - neededParts[i]; });
return (
delta[0] > 0 ||
delta[0] === 0 && (
delta[1] > 0 ||
delta[1] === 0 && delta[2] >= 0
)
);
};

@@ -32,0 +34,0 @@

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

ixoffset = width - Math.round((width - centerIcon.width) / 2) - centerIcon.width;
gc.drawImage(centerIcon, x + ixoffset, y + iyoffset);
gc.drawImage(centerIcon, x + ixoffset, y + iyoffset, centerIcon.width, centerIcon.height); // see [SIZE NOTE]!
valWidth = iconPadding + centerIcon.width + iconPadding;

@@ -156,3 +156,3 @@ if (config.hotIcon === 'center') {

iyoffset = Math.round((height - leftIcon.height) / 2);
gc.drawImage(leftIcon, x + iconPadding, y + iyoffset);
gc.drawImage(leftIcon, x + iconPadding, y + iyoffset, leftIcon.width, leftIcon.height); // see [SIZE NOTE]!
if (config.hotIcon === 'left') {

@@ -176,3 +176,3 @@ config.clickRect = new Rectangle(iconPadding, iyoffset, leftIcon.width, leftIcon.height);

iyoffset = Math.round((height - rightIcon.height) / 2);
gc.drawImage(rightIcon, rightX, y + iyoffset);
gc.drawImage(rightIcon, rightX, y + iyoffset, rightIcon.width, rightIcon.height); // see [SIZE NOTE]!
if (config.hotIcon === 'right') {

@@ -196,2 +196,12 @@ config.clickRect = new Rectangle(ixoffset, iyoffset, rightIcon.width, rightIcon.height);

/* [SIZE NOTE] (11/1/2018): Always call `drawImage` with explicit width and height overload.
* Possible browser bug: Although 3rd and 4th parameters to `drawImage` are optional,
* when image data derived from SVG source, some browsers (e.g., Chrome 70) implementation
* of `drawImage` only respects _implicit_ `width` x `height` specified in the root <svg>
* element `width` & `height` attributes. Otherwise, image is copied into canvas using its
* `naturalWidth` x `naturalHeight`. That is, _explict_ settings of `width` & `height`
* (i.e, via property assignment, calling setAttribute, or in `new Image` call) have no
* effect on `drawImage` in the case of SVGs on these browsers.
*/
/**

@@ -198,0 +208,0 @@ * @summary Renders single line text.

@@ -461,2 +461,19 @@ /* eslint-env browser */

);
// add some interesting mouse offsets
var drilldown;
if ((drilldown = primitiveEvent.primitiveEvent && primitiveEvent.primitiveEvent.detail)) {
decoratedEvent.gridPoint = drilldown.mouse;
if ((drilldown = drilldown.primitiveEvent)) {
decoratedEvent.clientPoint = {
x: drilldown.clientX,
y: drilldown.clientY
};
decoratedEvent.pagePoint = {
x: drilldown.clientX + window.scrollX,
y: drilldown.clientY + window.scrollY
};
}
}
cb.call(grid, decoratedEvent);

@@ -580,3 +597,3 @@ }

this.addInternalEventListener('fin-canvas-context-menu', function(e) {
handleMouseEvent(e, function(mouseEvent){
handleMouseEvent(e, function(mouseEvent) {
grid.delegateContextMenu(mouseEvent);

@@ -583,0 +600,0 @@ grid.fireSyntheticContextMenuEvent(mouseEvent);

@@ -14,2 +14,3 @@ 'use strict';

var HypergridError = require('../lib/error');
var images = require('../../images');

@@ -77,11 +78,5 @@ var styles = [

});
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;
var themeLayer, grids, props, themeObject;

@@ -122,20 +117,21 @@ if (theme && typeof theme === 'object' && !Object.getOwnPropertyNames(theme).length) {

if (typeof theme === 'string') {
if (!registry[theme]) {
throw new HypergridError('Unknown theme "' + theme + '"');
}
theme = registry[theme];
if (typeof theme === 'object') {
themeObject = theme;
} else if (!registry[theme]) {
throw new HypergridError('Unknown theme "' + theme + '"');
} else {
themeObject = registry[theme];
}
if (theme) {
if (themeObject) {
// When no theme name, set it to explicit `undefined` (to mask defaults.themeName).
if (!theme.themeName) {
theme.themeName = undefined;
if (!themeObject.themeName) {
themeObject.themeName = undefined;
}
Object.keys(theme).forEach(function(key) {
Object.keys(themeObject).forEach(function(key) {
if (key in dynamicPropertyDescriptors) {
if (key in dynamicCosmetics) {
grids.forEach(function(grid) {
grid.properties[key] = theme[key];
grid.properties[key] = themeObject[key];
});

@@ -145,8 +141,10 @@ } else {

// 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];
switch (key) {
case 'lineColor':
themeObject.gridLinesHColor = themeObject.gridLinesVColor = themeObject[key];
break;
default:
console.warn('Ignoring unexpected dynamic property ' + key + ' from theme object.');
}
// delete themeObject[key];
}

@@ -157,3 +155,3 @@ }

// No .assign() because themeName is read-only in defaults layer
Object.defineProperties(themeLayer, Object.getOwnPropertyDescriptors(theme));
Object.defineProperties(themeLayer, Object.getOwnPropertyDescriptors(themeObject));
}

@@ -164,2 +162,4 @@

});
return themeObject;
}

@@ -194,4 +194,4 @@

* * **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.
* * **object:** An anonymous (unregistered) theme object. Empty object removes grid theme, exposing global theme.
* * _falsy value:_ Also removes grid theme (like empty object).
* @param {string|undefined} [theme.themeName=undefined]

@@ -223,3 +223,3 @@ * @memberOf Hypergrid#

enumerable: true,
set: mixin.applyTheme,
set: applyTheme,
get: mixin.getTheme

@@ -245,3 +245,4 @@ });

* ```
* If omitted, the theme named in the first parameter is unregistered.
* If omitted, unregister the theme named in the first parameter.
*
* Grid instances that have previously applied the named theme are unaffected by this action (whether re-registering or unregistering).

@@ -296,3 +297,2 @@ * @memberOf Hypergrid.

* the `defaults` layer at the bottom of the properties hierarchy.
* @this {Hypergrid.}
* @param {object|string} [theme=registry.default] - One of:

@@ -305,7 +305,10 @@ * * **string:** A registered theme name.

*/
applyTheme: applyTheme
applyTheme: function(theme) {
var themeObject = applyTheme.call(this, theme);
images.setTheme(themeObject);
}
};
Object.defineProperty(sharedMixin, 'theme', { // global theme setter/getter
enumerable: true,
set: applyTheme,
set: sharedMixin.applyTheme,
get: function() { return defaults; } // the defaults layer *is* the global theme layer

@@ -312,0 +315,0 @@ });

@@ -9,2 +9,5 @@ /* globals CustomEvent */

'mousePoint',
'gridPoint',
'clientPoint',
'pagePoint',
'keys',

@@ -11,0 +14,0 @@ 'row'

@@ -35,2 +35,3 @@ 'use strict';

// getClassName defined if new item derived from extend-me
name = name || item.getClassName && item.getClassName();

@@ -65,2 +66,12 @@

/**
* Create a new item extended from base class. For formal parameters, see {@link Registry#add add}.
* @memberOf Registry#
*/
make: function(name, prototype) {
var last = arguments.length - 1;
arguments[last] = this.BaseClass.extend(arguments[last]);
this.add.apply(this, arguments);
},
/**
* Fetch a registered item.

@@ -67,0 +78,0 @@ * @param {string} [name]

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