Update to straps.js v3.0.1 and make all functions and accessors enumerable.

This commit is contained in:
Jürg Lehni 2017-04-22 18:50:53 +02:00
parent b26b056522
commit 188c006197
12 changed files with 545 additions and 553 deletions

View file

@ -13,7 +13,7 @@
var clones = 30; var clones = 30;
var angle = 360 / clones; var angle = 360 / clones;
for(var i = 0; i < clones; i++) { for (var i = 0; i < clones; i++) {
var clonedPath = circlePath.clone(); var clonedPath = circlePath.clone();
clonedPath.rotate(angle * i, circlePath.bounds.topLeft); clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
}; };

View file

@ -120,7 +120,7 @@
function getEqualizerBands(data) { function getEqualizerBands(data) {
var bands = []; var bands = [];
var amount = Math.sqrt(data.length) / 2; var amount = Math.sqrt(data.length) / 2;
for(var i = 0; i < amount; i++) { for (var i = 0; i < amount; i++) {
var start = Math.pow(2, i) - 1; var start = Math.pow(2, i) - 1;
var end = start * 2 + 1; var end = start * 2 + 1;
var sum = 0; var sum = 0;

View file

@ -55,7 +55,7 @@
function removeSmallBits(path) { function removeSmallBits(path) {
var averageLength = path.length / path.segments.length; var averageLength = path.length / path.segments.length;
var min = path.length / 50; var min = path.length / 50;
for(var i = path.segments.length - 1; i >= 0; i--) { for (var i = path.segments.length - 1; i >= 0; i--) {
var segment = path.segments[i]; var segment = path.segments[i];
var cur = segment.point; var cur = segment.point;
var nextSegment = segment.next; var nextSegment = segment.next;
@ -69,8 +69,8 @@
function generateBeeHivePoints(size, loose) { function generateBeeHivePoints(size, loose) {
var points = []; var points = [];
var col = view.size / size; var col = view.size / size;
for(var i = -1; i < size.width + 1; i++) { for (var i = -1; i < size.width + 1; i++) {
for(var j = -1; j < size.height + 1; j++) { for (var j = -1; j < size.height + 1; j++) {
var point = new Point(i, j) / new Point(size) * view.size + col / 2; var point = new Point(i, j) / new Point(size) * view.size + col / 2;
if (j % 2) if (j % 2)
point += new Point(col.width / 2, 0); point += new Point(col.width / 2, 0);

View file

@ -15,7 +15,7 @@
var clones = 30; var clones = 30;
var angle = 360 / clones; var angle = 360 / clones;
for(var i = 0; i < clones; i++) { for (var i = 0; i < clones; i++) {
var clonedPath = circlePath.clone(); var clonedPath = circlePath.clone();
clonedPath.rotate(angle * i, circlePath.bounds.topLeft); clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
}; };

View file

@ -69,7 +69,7 @@
"run-sequence": "^1.2.2", "run-sequence": "^1.2.2",
"source-map-support": "^0.4.0", "source-map-support": "^0.4.0",
"stats.js": "0.16.0", "stats.js": "0.16.0",
"straps": "^2.1.0" "straps": "^3.0.1"
}, },
"browser": { "browser": {
"canvas": false, "canvas": false,

View file

@ -17,6 +17,8 @@
*/ */
// Extend Base with utility functions used across the library. // Extend Base with utility functions used across the library.
Base.inject(/** @lends Base# */{ Base.inject(/** @lends Base# */{
enumerable: false,
/** /**
* Renders base objects to strings in object literal notation. * Renders base objects to strings in object literal notation.
*/ */
@ -92,14 +94,15 @@ Base.inject(/** @lends Base# */{
if (props) if (props)
Base.filter(this, props, exclude, this._prioritize); Base.filter(this, props, exclude, this._prioritize);
return this; return this;
}, }
}, /** @lends Base# */{
statics: /** @lends Base */{ // Mess with indentation in order to get more line-space for the statics below.
// Explicitly deactivate the creation of beans, as we have functions here
// that look like bean getters but actually read arguments, see getNamed().
beans: false,
statics: /** @lends Base */{
// Keep track of all named classes for serialization and exporting. // Keep track of all named classes for serialization and exporting.
exports: { exports: {},
enumerable: true // For PaperScope.inject() in export.js
},
extend: function extend() { extend: function extend() {
// Override Base.extend() to register named classes in Base.exports, // Override Base.extend() to register named classes in Base.exports,
@ -112,9 +115,9 @@ Base.inject(/** @lends Base# */{
}, },
/** /**
* Checks if two values or objects are equals to each other, by using * Checks if two values or objects are equals to each other, by using their
* their equals() methods if available, and also comparing elements of * equals() methods if available, and also comparing elements of arrays and
* arrays and properties of objects. * properties of objects.
*/ */
equals: function(obj1, obj2) { equals: function(obj1, obj2) {
if (obj1 === obj2) if (obj1 === obj2)
@ -158,26 +161,25 @@ Base.inject(/** @lends Base# */{
}, },
/** /**
* When called on a subclass of Base, it reads arguments of the type of * When called on a subclass of Base, it reads arguments of the type of the
* the subclass from the passed arguments list or array, at the given * subclass from the passed arguments list or array, at the given index, up
* index, up to the specified length. * to the specified length. When called directly on Base, it reads any value
* When called directly on Base, it reads any value without conversion * without conversion from the passed arguments list or array. This is used
* from the passed arguments list or array. * in argument conversion, e.g. by all basic types (Point, Size, Rectangle)
* This is used in argument conversion, e.g. by all basic types (Point, * and also higher classes such as Color and Segment.
* Size, Rectangle) and also higher classes such as Color and Segment.
* *
* @param {Array} list the list to read from, either an arguments object * @param {Array} list the list to read from, either an arguments object or
* or a normal array * a normal array
* @param {Number} start the index at which to start reading in the list * @param {Number} start the index at which to start reading in the list
* @param {Object} options `options.readNull` controls whether null is * @param {Object} options `options.readNull` controls whether null is
* returned or converted. `options.clone` controls whether passed * returned or converted. `options.clone` controls whether passed
* objects should be cloned if they are already provided in the * objects should be cloned if they are already provided in the required
* required type * type
* @param {Number} length the amount of elements that can be read * @param {Number} length the amount of elements that can be read
*/ */
read: function(list, start, options, amount) { read: function(list, start, options, amount) {
// See if it's called directly on Base, and if so, read value and // See if it's called directly on Base, and if so, read value and return
// return without object conversion. // without object conversion.
if (this === Base) { if (this === Base) {
var value = this.peek(list, start); var value = this.peek(list, start);
list.__index++; list.__index++;
@ -189,9 +191,9 @@ Base.inject(/** @lends Base# */{
length = list.length, length = list.length,
obj = list[begin]; obj = list[begin];
amount = amount || length - begin; amount = amount || length - begin;
// When read() is called on a sub-class of which the object is // When read() is called on a sub-class of which the object is already
// already an instance, or when there is only one value in the list // an instance, or when there is only one value in the list and it's
// and it's null or undefined, return the obj. // null or undefined, return the obj.
if (obj instanceof this if (obj instanceof this
|| options && options.readNull && obj == null && amount <= 1) { || options && options.readNull && obj == null && amount <= 1) {
if (readIndex) if (readIndex)
@ -209,7 +211,7 @@ Base.inject(/** @lends Base# */{
if (readIndex) { if (readIndex) {
list.__index = begin + obj.__read; list.__index = begin + obj.__read;
// This is only in use in Rectangle so far: Nested calls to // This is only in use in Rectangle so far: Nested calls to
// Base.readNamed() would loose __filtered if it wasn't returned // `Base.readNamed()` would loose __filtered if it wasn't returned
// on the object. // on the object.
var filtered = obj.__filtered; var filtered = obj.__filtered;
if (filtered) { if (filtered) {
@ -267,20 +269,20 @@ Base.inject(/** @lends Base# */{
}, },
/** /**
* Allows using of Base.read() mechanism in combination with reading * Allows using of Base.read() mechanism in combination with reading named
* named arguments form a passed property object literal. Calling * arguments form a passed property object literal. Calling Base.readNamed()
* Base.readNamed() can read both from such named properties and normal * can read both from such named properties and normal unnamed arguments
* unnamed arguments through Base.read(). In use for example for the * through Base.read(). In use for example for the various
* various Path.Constructors. * Path.Constructors.
* *
* @param {Array} list the list to read from, either an arguments object * @param {Array} list the list to read from, either an arguments object or
* or a normal array * a normal array
* @param {String} name the property name to read from * @param {String} name the property name to read from
* @param {Number} start the index at which to start reading in the list * @param {Number} start the index at which to start reading in the list
* @param {Object} options `options.readNull` controls whether null is * @param {Object} options `options.readNull` controls whether null is
* returned or converted. `options.clone` controls whether passed * returned or converted. `options.clone` controls whether passed
* objects should be cloned if they are already provided in the * objects should be cloned if they are already provided in the required
* required type * type
* @param {Number} amount the amount of elements that can be read * @param {Number} amount the amount of elements that can be read
*/ */
readNamed: function(list, name, start, options, amount) { readNamed: function(list, name, start, options, amount) {
@ -321,9 +323,8 @@ Base.inject(/** @lends Base# */{
}, },
/** /**
* Checks if the argument list has a named argument with the given name. * Checks if the argument list has a named argument with the given name. If
* If name is `null`, it returns `true` if there are any named * name is `null`, it returns `true` if there are any named arguments.
* arguments.
*/ */
hasNamed: function(list, name) { hasNamed: function(list, name) {
return !!this.getNamed(list, name); return !!this.getNamed(list, name);
@ -331,18 +332,17 @@ Base.inject(/** @lends Base# */{
/** /**
* Copies all properties from `source` over to `dest`, supporting * Copies all properties from `source` over to `dest`, supporting
* `_filtered` handling as required by {@link Base.readNamed()} * `_filtered` handling as required by {@link Base.readNamed()} mechanism,
* mechanism, as well as a way to exclude and prioritize properties. * as well as a way to exclude and prioritize properties.
* *
* @param {Object} dest the destination that is to receive the * @param {Object} dest the destination that is to receive the properties
* properties * @param {Object} source the source from where to retrieve the properties
* @param {Object} source the source from where to retrieve the * to be copied
* properties to be copied * @param {Object} [exclude] an object that can define any properties as
* @param {Object} [exclude] an object that can define any properties * `true` that should be excluded when copying
* as `true` that should be excluded when copying * @param {String[]} [prioritize] a list of keys that should be prioritized
* @param {String[]} [prioritize] a list of keys that should be * when copying, if they are defined in `source`, processed in the order
* prioritized when copying, if they are defined in `source`, * of appearance
* processed in the order of appearance
*/ */
filter: function(dest, source, exclude, prioritize) { filter: function(dest, source, exclude, prioritize) {
var processed; var processed;
@ -372,16 +372,16 @@ Base.inject(/** @lends Base# */{
processed = keys; processed = keys;
} }
// If source is a filtered object, we get the keys from the // If source is a filtered object, we get the keys from the the original
// the original object (it's parent / prototype). See _filtered // object (it's parent / prototype). See _filtered inheritance trick in
// inheritance trick in the argument reading code. // the argument reading code.
Object.keys(source.__unfiltered || source).forEach(handleKey); Object.keys(source.__unfiltered || source).forEach(handleKey);
return dest; return dest;
}, },
/** /**
* Returns true if obj is either a plain object or an array, as used by * Returns true if obj is either a plain object or an array, as used by many
* many argument reading methods. * argument reading methods.
*/ */
isPlainValue: function(obj, asString) { isPlainValue: function(obj, asString) {
return Base.isPlainObject(obj) || Array.isArray(obj) return Base.isPlainObject(obj) || Array.isArray(obj)
@ -390,7 +390,7 @@ Base.inject(/** @lends Base# */{
/** /**
* Serializes the passed object into a format that can be passed to * Serializes the passed object into a format that can be passed to
* JSON.stringify() for JSON serialization. * `JSON.stringify()` for JSON serialization.
*/ */
serialize: function(obj, options, compact, dictionary) { serialize: function(obj, options, compact, dictionary) {
options = options || {}; options = options || {};
@ -399,10 +399,10 @@ Base.inject(/** @lends Base# */{
res; res;
if (isRoot) { if (isRoot) {
options.formatter = new Formatter(options.precision); options.formatter = new Formatter(options.precision);
// Create a simple dictionary object that handles all the // Create a simple dictionary object that handles all the storing
// storing and retrieving of dictionary definitions and // and retrieving of dictionary definitions and references, e.g. for
// references, e.g. for symbols and gradients. Items that want // symbols and gradients. Items that want to support this need to
// to support this need to define globally unique _id attribute. // define globally unique _id attribute.
/** /**
* @namespace * @namespace
* @private * @private
@ -412,10 +412,9 @@ Base.inject(/** @lends Base# */{
definitions: {}, definitions: {},
references: {}, references: {},
add: function(item, create) { add: function(item, create) {
// See if we have reference entry with the given id // See if we have reference entry with the given id already.
// already. If not, call create on the item to allow it // If not, call create on the item to allow it to create the
// to create the definition, then store the reference // definition, then store the reference to it and return it.
// to it and return it.
var id = '#' + item._id, var id = '#' + item._id,
ref = this.references[id]; ref = this.references[id];
if (!ref) { if (!ref) {
@ -436,11 +435,11 @@ Base.inject(/** @lends Base# */{
if (obj && obj._serialize) { if (obj && obj._serialize) {
res = obj._serialize(options, dictionary); res = obj._serialize(options, dictionary);
// If we don't serialize to compact form (meaning no type // If we don't serialize to compact form (meaning no type
// identifier), see if _serialize didn't already add the class, // identifier), see if _serialize didn't already add the class, e.g.
// e.g. for classes that do not support compact form. // for classes that do not support compact form.
var name = obj._class; var name = obj._class;
// Enforce class names on root level, except if the class // Enforce class names on root level, except if the class explicitly
// explicitly asks to be serialized in compact form (Project). // asks to be serialized in compact form (Project).
if (name && !obj._compactSerialize && (isRoot || !compact) if (name && !obj._compactSerialize && (isRoot || !compact)
&& res[0] !== name) { && res[0] !== name) {
res.unshift(name); res.unshift(name);
@ -448,8 +447,7 @@ Base.inject(/** @lends Base# */{
} else if (Array.isArray(obj)) { } else if (Array.isArray(obj)) {
res = []; res = [];
for (var i = 0, l = obj.length; i < l; i++) for (var i = 0, l = obj.length; i < l; i++)
res[i] = Base.serialize(obj[i], options, compact, res[i] = Base.serialize(obj[i], options, compact, dictionary);
dictionary);
} else if (Base.isPlainObject(obj)) { } else if (Base.isPlainObject(obj)) {
res = {}; res = {};
var keys = Object.keys(obj); var keys = Object.keys(obj);
@ -471,37 +469,36 @@ Base.inject(/** @lends Base# */{
/** /**
* Deserializes from parsed JSON data. A simple convention is followed: * Deserializes from parsed JSON data. A simple convention is followed:
* Array values with a string at the first position are links to * Array values with a string at the first position are links to
* deserializable types through Base.exports, and the values following * deserializable types through Base.exports, and the values following in
* in the array are the arguments to their initialize function. * the array are the arguments to their initialize function. Any other value
* Any other value is passed on unmodified. * is passed on unmodified. The passed json data is recoursively traversed
* The passed json data is recoursively traversed and converted, leaves * and converted, leaves first.
* first
*/ */
deserialize: function(json, create, _data, _setDictionary, _isRoot) { deserialize: function(json, create, _data, _setDictionary, _isRoot) {
var res = json, var res = json,
isFirst = !_data, isFirst = !_data,
hasDictionary = isFirst && json && json.length hasDictionary = isFirst && json && json.length
&& json[0][0] === 'dictionary'; && json[0][0] === 'dictionary';
// A _data side-car to deserialize that can hold any kind of // A _data side-car to deserialize that can hold any kind of 'global'
// 'global' data across a deserialization. It's currently only used // data across a deserialization. It's currently only used to hold
// to hold dictionary definitions. // dictionary definitions.
_data = _data || {}; _data = _data || {};
if (Array.isArray(json)) { if (Array.isArray(json)) {
// See if it's a serialized type. If so, the rest of the array // See if it's a serialized type. If so, the rest of the array are
// are the arguments to #initialize(). Either way, we simply // the arguments to #initialize(). Either way, we simply deserialize
// deserialize all elements of the array. // all elements of the array.
var type = json[0], var type = json[0],
// Handle stored dictionary specially, since we need to // Handle stored dictionary specially, since we need to keep a
// keep a lookup table to retrieve referenced items from. // lookup table to retrieve referenced items from.
isDictionary = type === 'dictionary'; isDictionary = type === 'dictionary';
// First see if this is perhaps a dictionary reference, and // First see if this is perhaps a dictionary reference, and if so
// if so return its definition instead. // return its definition instead.
if (json.length == 1 && /^#/.test(type)) { if (json.length == 1 && /^#/.test(type)) {
return _data.dictionary[type]; return _data.dictionary[type];
} }
type = Base.exports[type]; type = Base.exports[type];
res = []; res = [];
// Skip first type entry for arguments // Skip first type entry for arguments.
// Pass true for _isRoot in children if we have a dictionary, // Pass true for _isRoot in children if we have a dictionary,
// in which case we need to shift the root level one down. // in which case we need to shift the root level one down.
for (var i = type ? 1 : 0, l = json.length; i < l; i++) { for (var i = type ? 1 : 0, l = json.length; i < l; i++) {
@ -512,9 +509,9 @@ Base.inject(/** @lends Base# */{
// Create serialized type and pass collected arguments to // Create serialized type and pass collected arguments to
// constructor(). // constructor().
var args = res; var args = res;
// If a create method is provided, handle our own // If a create method is provided, handle our own creation. This
// creation. This is used in #importJSON() to pass // is used in #importJSON() to pass on insert = false to all
// on insert = false to all items except layers. // items except layers.
if (create) { if (create) {
res = create(type, args, isFirst || _isRoot); res = create(type, args, isFirst || _isRoot);
} else { } else {
@ -555,10 +552,10 @@ Base.inject(/** @lends Base# */{
&& target.constructor === ctor, && target.constructor === ctor,
obj = useTarget ? target obj = useTarget ? target
: Base.create(ctor.prototype); : Base.create(ctor.prototype);
// NOTE: We don't set insert false for layers since we // NOTE: We don't set insert false for layers since we want
// want these to be created on the fly in the active // these to be created on the fly in the active project into
// project into which we're importing (except for if // which we're importing (except for if it's a preexisting
// it's a preexisting target layer). // target layer).
if (args.length === 1 && obj instanceof Item if (args.length === 1 && obj instanceof Item
&& (useTarget || !(obj instanceof Layer))) { && (useTarget || !(obj instanceof Layer))) {
var arg = args[0]; var arg = args[0];
@ -576,9 +573,9 @@ Base.inject(/** @lends Base# */{
}, },
/** /**
* Utility function for adding and removing items from a list of which * Utility function for adding and removing items from a list of which each
* each entry keeps a reference to its index in the list in the private * entry keeps a reference to its index in the list in the private _index
* _index property. Used for PaperScope#projects and Item#children. * property. Used for PaperScope#projects and Item#children.
*/ */
splice: function(list, items, index, remove) { splice: function(list, items, index, remove) {
var amount = items && items.length, var amount = items && items.length,
@ -634,5 +631,4 @@ Base.inject(/** @lends Base# */{
hyphenate: function(str) { hyphenate: function(str) {
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
} }
} }});
});

View file

@ -17,8 +17,6 @@
// global one in the whole scope. // global one in the whole scope.
paper = new (PaperScope.inject(Base.exports, { paper = new (PaperScope.inject(Base.exports, {
// Mark fields as enumerable so PaperScope.inject can pick them up
enumerable: true,
Base: Base, Base: Base,
Numerical: Numerical, Numerical: Numerical,
Key: Key, Key: Key,

View file

@ -26,11 +26,8 @@ var HitResult = Base.extend(/** @lends HitResult# */{
// Inject passed values, so we can be flexible about the HitResult // Inject passed values, so we can be flexible about the HitResult
// properties. // properties.
// This allows the definition of getters too, e.g. for 'pixel'. // This allows the definition of getters too, e.g. for 'pixel'.
if (values) { if (values)
// Make enumerable so toString() works.
values.enumerable = true;
this.inject(values); this.inject(values);
}
}, },
/** /**

View file

@ -1955,7 +1955,7 @@ new function() { // Scope for bezier intersection using fat-line clipping
// Calculate the curve values of the rotated curve. // Calculate the curve values of the rotated curve.
rv = [], rv = [],
roots = []; roots = [];
for(var i = 0; i < 8; i += 2) { for (var i = 0; i < 8; i += 2) {
var x = v[i] - px, var x = v[i] - px,
y = v[i + 1] - py; y = v[i + 1] - py;
rv.push( rv.push(

View file

@ -115,8 +115,9 @@ new function() {
if (length > 2) { if (length > 2) {
type = item._closed ? 'polygon' : 'polyline'; type = item._closed ? 'polygon' : 'polyline';
var parts = []; var parts = [];
for(var i = 0; i < length; i++) for (var i = 0; i < length; i++) {
parts.push(formatter.point(segments[i]._point)); parts.push(formatter.point(segments[i]._point));
}
attrs.points = parts.join(' '); attrs.points = parts.join(' ');
} else { } else {
type = 'line'; type = 'line';

View file

@ -125,7 +125,7 @@ var Numerical = new function() {
/** /**
* The machine epsilon for a double precision (Javascript Number) is * The machine epsilon for a double precision (Javascript Number) is
* 2.220446049250313e-16. (try this in the js console: * 2.220446049250313e-16. (try this in the js console:
* (function(){for(var e=1;1<1+e/2;)e/=2;return e}()) * (function(){ for (var e = 1; 1 < 1+e/2;) e/=2; return e }())
* *
* The constant MACHINE_EPSILON here refers to the constants δ and ε * The constant MACHINE_EPSILON here refers to the constants δ and ε
* such that, the error introduced by addition, multiplication on a * such that, the error introduced by addition, multiplication on a

View file

@ -154,7 +154,7 @@ test('transform test 1', function() {
var clones = 30; var clones = 30;
var angle = 360 / clones; var angle = 360 / clones;
for(var i = 0; i < clones; i++) { for (var i = 0; i < clones; i++) {
var clonedPath = circlePath.clone(); var clonedPath = circlePath.clone();
clonedPath.rotate(angle * i, circlePath.bounds.topLeft); clonedPath.rotate(angle * i, circlePath.bounds.topLeft);
} }