Make argument reading more flexible by introducing options object for readNull and clone, and passing it on to the constructor through this.__options for additional values.

This commit is contained in:
Jürg Lehni 2013-06-28 07:37:03 -07:00
parent 2c578d0558
commit e8765d18d5
8 changed files with 83 additions and 73 deletions

View file

@ -162,7 +162,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
// Do not modify scale, center, since that would arguments of which
// we're reading from!
var scale = Point.read(arguments),
center = Point.read(arguments, 0, 0, true); // readNull
center = Point.read(arguments, 0, 0, { readNull: true });
if (center)
this.translate(center);
this._a *= scale.x;
@ -267,7 +267,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
// Do not modify point, center, since that would arguments of which
// we're reading from!
var point = Point.read(arguments),
center = Point.read(arguments, 0, 0, true); // readNull
center = Point.read(arguments, 0, 0, { readNull: true });
if (center)
this.translate(center);
var a = this._a,

View file

@ -135,12 +135,12 @@ var Point = Base.extend(/** @lends Point# */{
var hasY = typeof arg1 === 'number';
this.x = arg0;
this.y = hasY ? arg1 : arg0;
if (this._read)
this._read = hasY ? 2 : 1;
if (this.__read)
this.__read = hasY ? 2 : 1;
} else if (type === 'undefined' || arg0 === null) {
this.x = this.y = 0;
if (this._read)
this._read = arg0 === null ? 1 : 0;
if (this.__read)
this.__read = arg0 === null ? 1 : 0;
} else {
if (Array.isArray(arg0)) {
this.x = arg0[0];
@ -157,11 +157,11 @@ var Point = Base.extend(/** @lends Point# */{
this.setAngle(arg0.angle);
} else {
this.x = this.y = 0;
if (this._read)
this._read = 0;
if (this.__read)
this.__read = 0;
}
if (this._read)
this._read = 1;
if (this.__read)
this.__read = 1;
}
},

View file

@ -143,8 +143,8 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
}
read = arguments._index;
}
if (this._read)
this._read = read;
if (this.__read)
this.__read = read;
},
/**

View file

@ -98,12 +98,12 @@ var Size = Base.extend(/** @lends Size# */{
var hasHeight = typeof arg1 === 'number';
this.width = arg0;
this.height = hasHeight ? arg1 : arg0;
if (this._read)
this._read = hasHeight ? 2 : 1;
if (this.__read)
this.__read = hasHeight ? 2 : 1;
} else if (type === 'undefined' || arg0 === null) {
this.width = this.height = 0;
if (this._read)
this._read = arg0 === null ? 1 : 0;
if (this.__read)
this.__read = arg0 === null ? 1 : 0;
} else {
if (Array.isArray(arg0)) {
this.width = arg0[0];
@ -116,11 +116,11 @@ var Size = Base.extend(/** @lends Size# */{
this.height = arg0.y;
} else {
this.width = this.height = 0;
if (this._read)
this._read = 0;
if (this.__read)
this.__read = 0;
}
if (this._read)
this._read = 1;
if (this.__read)
this.__read = 1;
}
},

View file

@ -148,16 +148,18 @@ Base.inject(/** @lends Base# */{
* or a normal array.
* @param {Number} start the index at which to start reading in the list
* @param {Number} length the amount of elements that can be read
* @param {Boolean} clone controls wether passed objects should be
* cloned if they are already provided in the required type
* @param {Object} options {@code options.readNull} controls wether null
* is returned or converted. {@code options.clone} controls
* wether passed objects should be cloned if they are already
* provided in the required type
*/
read: function(list, start, length, readNull, clone) {
read: function(list, start, length, options) {
// See if it's called directly on Base, and if so, read value and
// return without object conversion.
if (this === Base) {
var value = this.peek(list, start);
list._index++;
list._read = 1;
list.__read = 1;
return value;
}
var proto = this.prototype,
@ -166,23 +168,29 @@ Base.inject(/** @lends Base# */{
if (!length)
length = list.length - index;
var obj = list[index];
if (obj instanceof this || readNull && obj == null && length <= 1) {
if (obj instanceof this
|| options && options.readNull && obj == null && length <= 1) {
if (readIndex)
list._index = index + 1;
return obj && clone ? obj.clone() : obj;
return obj && options && options.clone ? obj.clone() : obj;
}
obj = Base.create(this);
if (readIndex)
obj._read = true;
obj.__read = true;
// If options were provided, pass them on to the constructed object
if (options)
obj.__options = options;
obj = obj.initialize.apply(obj, index > 0 || length < list.length
? Array.prototype.slice.call(list, index, index + length)
: list) || obj;
if (readIndex) {
list._index = index + obj._read;
// Have arguments._read point to the amount of args read in the
list._index = index + obj.__read;
// Have arguments.__read point to the amount of args read in the
// last read() call
list._read = obj._read;
delete obj._read;
list.__read = obj.__read;
delete obj.__read;
if (options)
delete obj.__options;
}
return obj;
},
@ -204,16 +212,18 @@ Base.inject(/** @lends Base# */{
* @param {Array} list the list to read from, either an arguments object
* or a normal array.
* @param {Number} start the index at which to start reading in the list
* @param {Boolean} clone controls wether passed objects should be
* cloned if they are already provided in the required type
* @param {Object} options {@code options.readNull} controls wether null
* is returned or converted. {@code options.clone} controls
* wether passed objects should be cloned if they are already
* provided in the required type
*/
readAll: function(list, start, readNull, clone) {
readAll: function(list, start, options) {
var res = [], entry;
for (var i = start || 0, l = list.length; i < l; i++) {
res.push(Array.isArray(entry = list[i])
// lenghh = 0 for length = max
? this.read(entry, 0, 0, readNull, clone)
: this.read(list, i, 1, readNull, clone));
? this.read(entry, 0, 0, options)
: this.read(list, i, 1, options));
}
return res;
},
@ -229,10 +239,10 @@ Base.inject(/** @lends Base# */{
* @param {Number} start the index at which to start reading in the list
* @param {String} name the property name to read from.
*/
readNamed: function(list, name, start, length, readNull, clone) {
readNamed: function(list, name, start, length, options) {
var value = this.getNamed(list, name);
return this.read(value != null ? [value] : list, start, length,
readNull, clone);
options);
},
/**

View file

@ -22,7 +22,8 @@ Path.inject({ statics: new function() {
function createRectangle(/* rectangle */) {
var rect = Rectangle.readNamed(arguments, 'rectangle'),
radius = Size.readNamed(arguments, 'radius', 0, 0, true), // readNull
radius = Size.readNamed(arguments, 'radius', 0, 0,
{ readNull: true }),
bl = rect.getBottomLeft(true),
tl = rect.getTopLeft(true),
tr = rect.getTopRight(true),

View file

@ -227,7 +227,7 @@ var Color = Base.extend(new function() {
var current = this._components[0];
value = Gradient.read(
Array.isArray(value) ? value : arguments,
0, 0, true); // readNull
0, 0, { readNull: true });
if (current !== value) {
if (current)
current._removeOwner(this);
@ -244,9 +244,10 @@ var Color = Base.extend(new function() {
}
: type === 'gradient'
? function(/* value */) {
// ..., readNull, clone);
return Point.read(arguments, 0, 0,
name === 'highlight', true);
return Point.read(arguments, 0, 0, {
readNull: name === 'highlight',
clone: true
});
}
: function(value) {
return isNaN(value) ? 0
@ -494,7 +495,7 @@ var Color = Base.extend(new function() {
alpha = args[2];
} else {
// For deserialization, shift out and process normally.
if (this._read)
if (this.__read)
read = 1; // Will be increased below
// Shift type out of the arguments, and process normally.
args = slice.call(args, 1);
@ -522,7 +523,7 @@ var Color = Base.extend(new function() {
: 'gray';
var length = types[type].length;
alpha = values[length];
if (this._read)
if (this.__read)
read += values === arguments
? length + (alpha != null ? 1 : 0)
: 1;
@ -585,7 +586,7 @@ var Color = Base.extend(new function() {
alpha = arg.alpha;
}
}
if (this._read && type)
if (this.__read && type)
read = 1;
}
// Default fallbacks: rgb, black
@ -608,8 +609,8 @@ var Color = Base.extend(new function() {
this._components = components;
this._properties = types[this._type];
this._alpha = alpha;
if (this._read)
this._read = read;
if (this.__read)
this.__read = read;
},
_serialize: function(options, dictionary) {
@ -1084,9 +1085,9 @@ var Color = Base.extend(new function() {
* @return {Color} the addition of the color and the value as a new color
*
* @example
* var color = new Color(0.5, 1.0, 1.0);
* var result = color + 1.0;
* console.log(result); // {red: 1.0, blue: 1.0, green: 1.0}
* var color = new Color(0.5, 1, 1);
* var result = color + 1;
* console.log(result); // { red: 1, blue: 1, green: 1 }
*/
/**
* Returns the addition of the supplied color to the color as a new
@ -1100,10 +1101,10 @@ var Color = Base.extend(new function() {
* @return {Color} the addition of the two colors as a new color
*
* @example
* var color1 = new Color(0.0, 1.0, 1.0);
* var color2 = new Color(1.0, 0.0, 0.0);
* var color1 = new Color(0, 1, 1);
* var color2 = new Color(1, 0, 0);
* var result = color1 + color2;
* console.log(result); // {red: 1.0, blue: 1.0, green: 1.0}
* console.log(result); // { red: 1, blue: 1, green: 1 }
*/
/**
* Returns the subtraction of the supplied value to both coordinates of
@ -1118,9 +1119,9 @@ var Color = Base.extend(new function() {
* color
*
* @example
* var color = new Color(0.5, 1.0, 1.0);
* var result = color - 1.0;
* console.log(result); // {red: 0.0, blue: 0.0, green: 0.0}
* var color = new Color(0.5, 1, 1);
* var result = color - 1;
* console.log(result); // { red: 0, blue: 0, green: 0 }
*/
/**
* Returns the subtraction of the supplied color to the color as a new
@ -1134,10 +1135,10 @@ var Color = Base.extend(new function() {
* @return {Color} the subtraction of the two colors as a new color
*
* @example
* var color1 = new Color(0.0, 1.0, 1.0);
* var color2 = new Color(1.0, 0.0, 0.0);
* var color1 = new Color(0, 1, 1);
* var color2 = new Color(1, 0, 0);
* var result = color1 - color2;
* console.log(result); // {red: 0.0, blue: 1.0, green: 1.0}
* console.log(result); // { red: 0, blue: 1, green: 1 }
*/
/**
* Returns the multiplication of the supplied value to both coordinates
@ -1152,9 +1153,9 @@ var Color = Base.extend(new function() {
* new color
*
* @example
* var color = new Color(0.5, 1.0, 1.0);
* var color = new Color(0.5, 1, 1);
* var result = color * 0.5;
* console.log(result); // {red: 0.20, blue: 0.5, green: 0.5}
* console.log(result); // { red: 0.25, blue: 0.5, green: 0.5 }
*/
/**
* Returns the multiplication of the supplied color to the color as a
@ -1168,10 +1169,10 @@ var Color = Base.extend(new function() {
* @return {Color} the multiplication of the two colors as a new color
*
* @example
* var color1 = new Color(0.0, 1.0, 1.0);
* var color2 = new Color(0.5, 0.0, 0.5);
* var color1 = new Color(0, 1, 1);
* var color2 = new Color(0.5, 0, 0.5);
* var result = color1 * color2;
* console.log(result); // {red: 0.0, blue: 0.0, green: 0.5}
* console.log(result); // { red: 0, blue: 0, green: 0.5 }
*/
/**
* Returns the division of the supplied value to both coordinates of
@ -1186,9 +1187,9 @@ var Color = Base.extend(new function() {
* color
*
* @example
* var color = new Color(0.5, 1.0, 1.0);
* var color = new Color(0.5, 1, 1);
* var result = color / 2;
* console.log(result); // {red: 0.20, blue: 0.5, green: 0.5}
* console.log(result); // { red: 0.25, blue: 0.5, green: 0.5 }
*/
/**
* Returns the division of the supplied color to the color as a new
@ -1202,10 +1203,10 @@ var Color = Base.extend(new function() {
* @return {Color} the division of the two colors as a new color
*
* @example
* var color1 = new Color(0.0, 1.0, 1.0);
* var color2 = new Color(0.5, 0.0, 0.5);
* var color1 = new Color(0, 1, 1);
* var color2 = new Color(0.5, 0, 0.5);
* var result = color1 / color2;
* console.log(result); // {red: 0.0, blue: 0.0, green: 1.0}
* console.log(result); // { red: 0, blue: 0, green: 1 }
*/
/**
* {@grouptitle RGB Components}

View file

@ -125,8 +125,6 @@ var Style = Base.extend(new function() {
// raw value is stored, and conversion only happens in the getter.
fields[set] = function(value) {
var children = this._item && this._item._children;
// Clone color objects since they reference their owner
// value = isColor ? Color.read(arguments, 0, 0, true) : value;
// Only unify styles on children of Groups, excluding CompoundPaths.
if (children && children.length > 0
&& this._item._type !== 'compound-path') {
@ -169,7 +167,7 @@ var Style = Base.extend(new function() {
} else if (isColor && !(value && value.constructor === Color)) {
// Convert to a Color and stored result of conversion.
this._values[key] = value = Color.read(
[value], 0, 0, true, true); // readNull, clone);
[value], 0, 0, { readNull: true, clone: true });
if (value)
value._owner = this._item;
}