From 7405858f32d9ea7e2d07d9c08df6389051e78faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Lehni?= Date: Fri, 1 Mar 2013 14:06:04 -0800 Subject: [PATCH] Simplify code for reading of named arguments, removing the need for filtering arguments by using 'in' checks instead for the presence of properties / setters. --- src/core/Base.js | 43 ++++++++++------------------------- src/item/Item.js | 11 +++++++++ src/path/Path.Constructors.js | 35 ++++++++++++++-------------- 3 files changed, 41 insertions(+), 48 deletions(-) diff --git a/src/core/Base.js b/src/core/Base.js index 1ecbd9d6..c4bd7c18 100644 --- a/src/core/Base.js +++ b/src/core/Base.js @@ -60,27 +60,17 @@ this.Base = Base.inject(/** @lends Base# */{ }, /** - * Sets all the properties of the passed object literal to their values on - * the item it is called on, if the item has property of the given name (or - * a setter defined for it), annd returns the item itself. + * #_set() is part of the mechanism for constructors which take one object + * literal describing all the properties to be set on the created instance. + * @return {Boolean} {@true if the object is a plain object} */ - set: function(props) { - if (props) { + _set: function(props) { + if (Base.isPlainObject(props)) { for (var key in props) if (props.hasOwnProperty(key) && key in this) this[key] = props[key]; + return true; } - return this; - }, - - /** - * #_set() is part of the mechanism for constructors which take one object - * literal describing all the properties to be set on the created instance. - * It behaves the same as #set(), but only if the provided object is a plain - * object. It returns undefined otherwise. - */ - _set: function(props) { - return Base.isPlainObject(props) && this.set(props); }, statics: /** @lends Base */{ @@ -238,21 +228,12 @@ this.Base = Base.inject(/** @lends Base# */{ * or a normal array. * @param {Number} start the index at which to start reading in the list * @param {String} name the property name to read from. - * @param {Boolean} [filter=true] controls wether a clone of the passed - * object should be kept in list._filtered, of which the consumed - * properties are removed. This can be passed on e.g. to Item#set(). */ - readNamed: function(list, name, filter) { - var value = this.getNamed(list, name), - // value is undefined if there is no arguments object, and null - // if there is one, but no value is defined. - hasObject = value !== undefined; - if (hasObject && filter !== false) { - if (!list._filtered) - list._filtered = Base.merge(list[0]); - delete list._filtered[name]; - } - return this.read(hasObject ? [value] : list); + readNamed: function(list, name) { + var value = this.getNamed(list, name); + // value is undefined if there is no arguments object, and null + // if there is one, but no value is defined. + return this.read(value !== undefined ? [value] : list); }, /** @@ -280,7 +261,7 @@ this.Base = Base.inject(/** @lends Base# */{ * named arguments. */ hasNamed: function(list, name) { - return !name && list._hasObject || !!this.getNamed(list, name); + return !!this.getNamed(list, name); }, /** diff --git a/src/item/Item.js b/src/item/Item.js index 187f8384..5af7d9ab 100644 --- a/src/item/Item.js +++ b/src/item/Item.js @@ -207,6 +207,17 @@ var Item = this.Item = Base.extend(Callback, { } }, + /** + * Sets those properties of the passed object literal on this item to + * the values defined in the object literal, if the item has property of the + * given name (or a setter defined for it). + * @return {Item} the item itself. + */ + set: function(props) { + this._set(props); + return this; + }, + /** * The unique id of the item. * diff --git a/src/path/Path.Constructors.js b/src/path/Path.Constructors.js index fedd635f..a79c45fd 100644 --- a/src/path/Path.Constructors.js +++ b/src/path/Path.Constructors.js @@ -13,15 +13,16 @@ Path.inject({ statics: new function() { function readRectangle(list) { - var rect; - if (Base.hasNamed(list, 'from')) { - rect = new Rectangle(Point.readNamed(list, 'from'), - Point.readNamed(list, 'to')); - } else if (Base.hasNamed(list)) { - rect = Base.each(Base.getNamed(list), function(value, key) { - if (key in this) - this[key] = Base.readNamed(list, key); - }, new Rectangle()); + var props = Base.getNamed(list), + rect; + if (props) { + if ('from' in props) { + rect = new Rectangle(Point.readNamed(list, 'from'), + Point.readNamed(list, 'to')); + } else { + rect = new Rectangle(); + rect._set(Base.getNamed(list)); + } } else { rect = Rectangle.read(list); } @@ -34,7 +35,7 @@ Path.inject({ statics: new function() { top = rect.getTop(), right = rect.getRight(), bottom = rect.getBottom(), - path = new Path(arguments._filtered); + path = new Path(Base.getNamed(arguments)); path._add([ new Segment(Point.create(left, bottom)), new Segment(Point.create(left, top)), @@ -57,7 +58,7 @@ Path.inject({ statics: new function() { function createEllipse(/* rect */) { var rect = readRectangle(arguments), - path = new Path(arguments._filtered), + path = new Path(Base.getNamed(arguments)), point = rect.getPoint(true), size = rect.getSize(true), segments = new Array(4); @@ -94,7 +95,7 @@ Path.inject({ statics: new function() { return new Path( Point.readNamed(arguments, 'from'), Point.readNamed(arguments, 'to') - ).set(arguments._filtered); + ).set(Base.getNamed(arguments)); }, /** @@ -169,7 +170,7 @@ Path.inject({ statics: new function() { tr = rect.getTopRight(true), br = rect.getBottomRight(true), h = radius.multiply(kappa * 2), // handle vector - path = new Path(arguments._filtered); + path = new Path(Base.getNamed(arguments)); path._add([ new Segment(bl.add(radius.width, 0), null, [-h.width, 0]), new Segment(bl.subtract(0, radius.height), [0, h.height], null), @@ -226,7 +227,7 @@ Path.inject({ statics: new function() { radius = Base.readNamed(arguments, 'radius'); return createEllipse(new Rectangle(center.subtract(radius), Size.create(radius * 2, radius * 2))) - .set(arguments._filtered); + .set(Base.getNamed(arguments)); }, /** @@ -248,7 +249,7 @@ Path.inject({ statics: new function() { var from = Point.readNamed(arguments, 'from'), through = Point.readNamed(arguments, 'through'), to = Point.readNamed(arguments, 'to'), - path = new Path(arguments._filtered); + path = new Path(Base.getNamed(arguments)); path.moveTo(from); path.arcTo(through, to); return path; @@ -282,7 +283,7 @@ Path.inject({ statics: new function() { var center = Point.readNamed(arguments, 'center'), numSides = Base.readNamed(arguments, 'numSides'), radius = Base.readNamed(arguments, 'radius'), - path = new Path(arguments._filtered), + path = new Path(Base.getNamed(arguments)), step = 360 / numSides, three = !(numSides % 3), vector = new Point(0, three ? -radius : radius), @@ -323,7 +324,7 @@ Path.inject({ statics: new function() { numPoints = Base.readNamed(arguments, 'numPoints') * 2, radius1 = Base.readNamed(arguments, 'radius1'), radius2 = Base.readNamed(arguments, 'radius2'), - path = new Path(arguments._filtered), + path = new Path(Base.getNamed(arguments)), step = 360 / numPoints, vector = new Point(0, -1), segments = new Array(numPoints);