From 145bd3b03f1c05a0b2d0944964285857a099381e Mon Sep 17 00:00:00 2001 From: Andrea Bogazzi Date: Sun, 11 Jun 2017 21:36:51 +0200 Subject: [PATCH] Force async (#3996) * removed forced async * tests * fixed lint --- src/elements_parser.js | 13 +--- src/shapes/circle.class.js | 11 ++-- src/shapes/ellipse.class.js | 10 +-- src/shapes/group.class.js | 9 --- src/shapes/image.class.js | 18 +----- src/shapes/itext.class.js | 6 +- src/shapes/line.class.js | 16 ++--- src/shapes/object.class.js | 36 +++++------ src/shapes/path.class.js | 17 ++---- src/shapes/polygon.class.js | 14 ++--- src/shapes/polyline.class.js | 16 +++-- src/shapes/rect.class.js | 14 ++--- src/shapes/text.class.js | 14 ++--- src/shapes/textbox.class.js | 6 +- src/shapes/triangle.class.js | 6 +- src/util/misc.js | 5 +- test/unit/circle.js | 114 +++++++++++++++++------------------ test/unit/ellipse.js | 56 +++++++++-------- test/unit/image.js | 1 - test/unit/itext.js | 12 ++-- test/unit/line.js | 61 ++++++++++--------- test/unit/object.js | 20 +++--- test/unit/parser.js | 94 +++++++++++++---------------- test/unit/path.js | 5 +- test/unit/polygon.js | 108 ++++++++++++++++++--------------- test/unit/polyline.js | 91 ++++++++++++++++------------ test/unit/rect.js | 86 ++++++++++++++------------ test/unit/text.js | 96 ++++++++++++++--------------- test/unit/util.js | 11 +--- 29 files changed, 453 insertions(+), 513 deletions(-) diff --git a/src/elements_parser.js b/src/elements_parser.js index 47b8fd189d8..c2d782c2088 100644 --- a/src/elements_parser.js +++ b/src/elements_parser.js @@ -41,18 +41,7 @@ fabric.ElementsParser.prototype.createObject = function(el, index) { }; fabric.ElementsParser.prototype._createObject = function(klass, el, index) { - if (klass.async) { - klass.fromElement(el, this.createCallback(index, el), this.options); - } - else { - var obj = klass.fromElement(el, this.options); - this.resolveGradient(obj, 'fill'); - this.resolveGradient(obj, 'stroke'); - obj._removeTransformMatrix(); - this.reviver && this.reviver(el, obj); - this.instances[index] = obj; - this.checkIfDone(); - } + klass.fromElement(el, this.createCallback(index, el), this.options); }; fabric.ElementsParser.prototype.createCallback = function(index, el) { diff --git a/src/shapes/circle.class.js b/src/shapes/circle.class.js index 58f05a7ac74..88cdbfe26d2 100644 --- a/src/shapes/circle.class.js +++ b/src/shapes/circle.class.js @@ -188,10 +188,10 @@ * @memberOf fabric.Circle * @param {SVGElement} element Element to parse * @param {Object} [options] Options object + * @param {Function} [callback] Options callback invoked after parsing is finished * @throws {Error} If value of `r` attribute is missing or invalid - * @return {fabric.Circle} Instance of fabric.Circle */ - fabric.Circle.fromElement = function(element, options) { + fabric.Circle.fromElement = function(element, callback, options) { options || (options = { }); var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); @@ -204,7 +204,7 @@ parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius; parsedAttributes.originX = 'left'; parsedAttributes.originY = 'top'; - return new fabric.Circle(extend(parsedAttributes, options)); + callback(new fabric.Circle(extend(parsedAttributes, options))); }; /** @@ -221,11 +221,10 @@ * @memberOf fabric.Circle * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first * @return {Object} Instance of fabric.Circle */ - fabric.Circle.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Circle', object, callback, forceAsync); + fabric.Circle.fromObject = function(object, callback) { + return fabric.Object._fromObject('Circle', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/ellipse.class.js b/src/shapes/ellipse.class.js index 0f48deeda69..526f1bb3753 100644 --- a/src/shapes/ellipse.class.js +++ b/src/shapes/ellipse.class.js @@ -168,9 +168,10 @@ * @memberOf fabric.Ellipse * @param {SVGElement} element Element to parse * @param {Object} [options] Options object + * @param {Function} [callback] Options callback invoked after parsing is finished * @return {fabric.Ellipse} */ - fabric.Ellipse.fromElement = function(element, options) { + fabric.Ellipse.fromElement = function(element, callback, options) { options || (options = { }); var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); @@ -179,7 +180,7 @@ parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; parsedAttributes.originX = 'left'; parsedAttributes.originY = 'top'; - return new fabric.Ellipse(extend(parsedAttributes, options)); + callback(new fabric.Ellipse(extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -189,11 +190,10 @@ * @memberOf fabric.Ellipse * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first * @return {fabric.Ellipse} */ - fabric.Ellipse.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Ellipse', object, callback, forceAsync); + fabric.Ellipse.fromObject = function(object, callback) { + return fabric.Object._fromObject('Ellipse', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/group.class.js b/src/shapes/group.class.js index 344b54a80e2..61697540e38 100644 --- a/src/shapes/group.class.js +++ b/src/shapes/group.class.js @@ -612,13 +612,4 @@ }); }; - /** - * Indicates that instances of this type are async - * @static - * @memberOf fabric.Group - * @type Boolean - * @default - */ - fabric.Group.async = true; - })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/image.class.js b/src/shapes/image.class.js index dbeb77f1ca2..38c36f710a1 100644 --- a/src/shapes/image.class.js +++ b/src/shapes/image.class.js @@ -664,8 +664,8 @@ * Returns {@link fabric.Image} instance from an SVG element * @static * @param {SVGElement} element Element to parse - * @param {Function} callback Callback to execute when fabric.Image object is created * @param {Object} [options] Options object + * @param {Function} callback Callback to execute when fabric.Image object is created * @return {fabric.Image} Instance of fabric.Image */ fabric.Image.fromElement = function(element, callback, options) { @@ -682,20 +682,4 @@ }; /* _FROM_SVG_END_ */ - /** - * Indicates that instances of this type are async - * @static - * @type Boolean - * @default - */ - fabric.Image.async = true; - - /** - * Indicates compression level used when generating PNG under Node (in applyFilters). Any of 0-9 - * @static - * @type Number - * @default - */ - fabric.Image.pngCompression = 1; - })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/itext.class.js b/src/shapes/itext.class.js index d033f385e51..dc2808dbf11 100644 --- a/src/shapes/itext.class.js +++ b/src/shapes/itext.class.js @@ -564,10 +564,8 @@ * @memberOf fabric.IText * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.IText} instance of fabric.IText */ - fabric.IText.fromObject = function(object, callback, forceAsync) { + fabric.IText.fromObject = function(object, callback) { parseDecoration(object); if (object.styles) { for (var i in object.styles) { @@ -576,6 +574,6 @@ } } } - return fabric.Object._fromObject('IText', object, callback, forceAsync, 'text'); + fabric.Object._fromObject('IText', object, callback, 'text'); }; })(); diff --git a/src/shapes/line.class.js b/src/shapes/line.class.js index 8d0bd3ec4a1..5e7d0102b69 100644 --- a/src/shapes/line.class.js +++ b/src/shapes/line.class.js @@ -294,9 +294,9 @@ * @memberOf fabric.Line * @param {SVGElement} element Element to parse * @param {Object} [options] Options object - * @return {fabric.Line} instance of fabric.Line + * @param {Function} [callback] callback function invoked after parsing */ - fabric.Line.fromElement = function(element, options) { + fabric.Line.fromElement = function(element, callback, options) { options = options || { }; var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), points = [ @@ -307,7 +307,7 @@ ]; options.originX = 'left'; options.originY = 'top'; - return new fabric.Line(points, extend(parsedAttributes, options)); + callback(new fabric.Line(points, extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -317,21 +317,15 @@ * @memberOf fabric.Line * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Line} instance of fabric.Line */ - fabric.Line.fromObject = function(object, callback, forceAsync) { + fabric.Line.fromObject = function(object, callback) { function _callback(instance) { delete instance.points; callback && callback(instance); }; var options = clone(object, true); options.points = [object.x1, object.y1, object.x2, object.y2]; - var line = fabric.Object._fromObject('Line', options, _callback, forceAsync, 'points'); - if (line) { - delete line.points; - } - return line; + fabric.Object._fromObject('Line', options, _callback, 'points'); }; /** diff --git a/src/shapes/object.class.js b/src/shapes/object.class.js index 834f3294d26..166db79825c 100644 --- a/src/shapes/object.class.js +++ b/src/shapes/object.class.js @@ -1473,17 +1473,18 @@ }, /** - * Clones an instance, some objects are async, so using callback method will work for every object. - * Using the direct return does not work for images and groups. + * Clones an instance, using a callback method will work for every object. * @param {Function} callback Callback is invoked with a clone as a first argument * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output - * @return {fabric.Object} clone of an instance */ clone: function(callback, propertiesToInclude) { + var objectForm = this.toObject(propertiesToInclude); if (this.constructor.fromObject) { - return this.constructor.fromObject(this.toObject(propertiesToInclude), callback); + this.constructor.fromObject(objectForm, callback); + } + else { + fabric.Object._fromObject('Object', objectForm, callback); } - return new fabric.Object(this.toObject(propertiesToInclude)); }, /** @@ -1867,26 +1868,19 @@ */ fabric.Object.NUM_FRACTION_DIGITS = 2; - fabric.Object._fromObject = function(className, object, callback, forceAsync, extraParam) { + fabric.Object._fromObject = function(className, object, callback, extraParam) { var klass = fabric[className]; object = clone(object, true); - if (forceAsync) { - fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { - if (typeof patterns[0] !== 'undefined') { - object.fill = patterns[0]; - } - if (typeof patterns[1] !== 'undefined') { - object.stroke = patterns[1]; - } - var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); - callback && callback(instance); - }); - } - else { + fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) { + if (typeof patterns[0] !== 'undefined') { + object.fill = patterns[0]; + } + if (typeof patterns[1] !== 'undefined') { + object.stroke = patterns[1]; + } var instance = extraParam ? new klass(object[extraParam], object) : new klass(object); callback && callback(instance); - return instance; - } + }); }; /** diff --git a/src/shapes/path.class.js b/src/shapes/path.class.js index c71c46af629..d54d67796f2 100644 --- a/src/shapes/path.class.js +++ b/src/shapes/path.class.js @@ -909,9 +909,8 @@ * @memberOf fabric.Path * @param {Object} object * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first */ - fabric.Path.fromObject = function(object, callback, forceAsync) { + fabric.Path.fromObject = function(object, callback) { if (typeof object.path === 'string') { var pathUrl = object.path; fabric.loadSVGFromURL(pathUrl, function (elements) { @@ -925,7 +924,7 @@ }); } else { - return fabric.Object._fromObject('Path', object, callback, forceAsync, 'path'); + fabric.Object._fromObject('Path', object, callback, 'path'); } }; @@ -945,22 +944,14 @@ * @param {SVGElement} element to parse * @param {Function} callback Callback to invoke when an fabric.Path instance is created * @param {Object} [options] Options object + * @param {Function} [callback] Options callback invoked after parsing is finished */ fabric.Path.fromElement = function(element, callback, options) { var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); parsedAttributes.originX = 'left'; parsedAttributes.originY = 'top'; - callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); + callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ - /** - * Indicates that instances of this type are async - * @static - * @memberOf fabric.Path - * @type Boolean - * @default - */ - fabric.Path.async = true; - })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/polygon.class.js b/src/shapes/polygon.class.js index 848015579a5..f1b43afe05b 100644 --- a/src/shapes/polygon.class.js +++ b/src/shapes/polygon.class.js @@ -62,12 +62,12 @@ * @static * @memberOf fabric.Polygon * @param {SVGElement} element Element to parse + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Polygon} Instance of fabric.Polygon */ - fabric.Polygon.fromElement = function(element, options) { + fabric.Polygon.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options || (options = { }); @@ -75,7 +75,7 @@ var points = fabric.parsePointsAttribute(element.getAttribute('points')), parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES); - return new fabric.Polygon(points, extend(parsedAttributes, options)); + callback(new fabric.Polygon(points, extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -85,11 +85,9 @@ * @memberOf fabric.Polygon * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Polygon} Instance of fabric.Polygon */ - fabric.Polygon.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Polygon', object, callback, forceAsync, 'points'); + fabric.Polygon.fromObject = function(object, callback) { + return fabric.Object._fromObject('Polygon', object, callback, 'points'); }; })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/polyline.class.js b/src/shapes/polyline.class.js index 40753226a64..365321b21a5 100644 --- a/src/shapes/polyline.class.js +++ b/src/shapes/polyline.class.js @@ -221,20 +221,20 @@ * Returns fabric.Polyline instance from an SVG element * @static * @memberOf fabric.Polyline - * @param {SVGElement} element Element to parse + * @param {SVGElement} element Element to parser + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Polyline} Instance of fabric.Polyline */ - fabric.Polyline.fromElement = function(element, options) { + fabric.Polyline.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options || (options = { }); var points = fabric.parsePointsAttribute(element.getAttribute('points')), parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); - return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)); + callback(new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options))); }; /* _FROM_SVG_END_ */ @@ -244,11 +244,9 @@ * @memberOf fabric.Polyline * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Path instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Polyline} Instance of fabric.Polyline */ - fabric.Polyline.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Polyline', object, callback, forceAsync, 'points'); + fabric.Polyline.fromObject = function(object, callback) { + return fabric.Object._fromObject('Polyline', object, callback, 'points'); }; })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/rect.class.js b/src/shapes/rect.class.js index 05320366f59..0267fe9186e 100644 --- a/src/shapes/rect.class.js +++ b/src/shapes/rect.class.js @@ -185,12 +185,12 @@ * @static * @memberOf fabric.Rect * @param {SVGElement} element Element to parse + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Rect} Instance of fabric.Rect */ - fabric.Rect.fromElement = function(element, options) { + fabric.Rect.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } options = options || { }; @@ -202,7 +202,7 @@ parsedAttributes.originY = 'top'; var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); rect.visible = rect.visible && rect.width > 0 && rect.height > 0; - return rect; + callback(rect); }; /* _FROM_SVG_END_ */ @@ -212,11 +212,9 @@ * @memberOf fabric.Rect * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Rect instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {Object} instance of fabric.Rect */ - fabric.Rect.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Rect', object, callback, forceAsync); + fabric.Rect.fromObject = function(object, callback) { + return fabric.Object._fromObject('Rect', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/shapes/text.class.js b/src/shapes/text.class.js index 7a295971162..ddb5c0dbcd2 100644 --- a/src/shapes/text.class.js +++ b/src/shapes/text.class.js @@ -1476,12 +1476,12 @@ * @static * @memberOf fabric.Text * @param {SVGElement} element Element to parse + * @param {Function} callback callback function invoked after parsing * @param {Object} [options] Options object - * @return {fabric.Text} Instance of fabric.Text */ - fabric.Text.fromElement = function(element, options) { + fabric.Text.fromElement = function(element, callback, options) { if (!element) { - return null; + return callback(null); } var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES); @@ -1557,7 +1557,7 @@ }); text.originX = 'left'; text.originY = 'top'; - return text; + callback(text); }; /* _FROM_SVG_END_ */ @@ -1567,11 +1567,9 @@ * @memberOf fabric.Text * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Text instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Text} Instance of fabric.Text */ - fabric.Text.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Text', object, callback, forceAsync, 'text'); + fabric.Text.fromObject = function(object, callback) { + return fabric.Object._fromObject('Text', object, callback, 'text'); }; fabric.util.createAccessors(fabric.Text); diff --git a/src/shapes/textbox.class.js b/src/shapes/textbox.class.js index 3d8850865b7..bcd52350bf4 100644 --- a/src/shapes/textbox.class.js +++ b/src/shapes/textbox.class.js @@ -394,11 +394,9 @@ * @memberOf fabric.Textbox * @param {Object} object Object to create an instance from * @param {Function} [callback] Callback to invoke when an fabric.Textbox instance is created - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Textbox} instance of fabric.Textbox */ - fabric.Textbox.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Textbox', object, callback, forceAsync, 'text'); + fabric.Textbox.fromObject = function(object, callback) { + return fabric.Object._fromObject('Textbox', object, callback, 'text'); }; /** diff --git a/src/shapes/triangle.class.js b/src/shapes/triangle.class.js index 0b5fb45bc59..2d58e16ad6c 100644 --- a/src/shapes/triangle.class.js +++ b/src/shapes/triangle.class.js @@ -105,11 +105,9 @@ * @memberOf fabric.Triangle * @param {Object} object Object to create an instance from * @param {function} [callback] invoked with new instance as first argument - * @param {Boolean} [forceAsync] Force an async behaviour trying to create pattern first - * @return {fabric.Triangle} */ - fabric.Triangle.fromObject = function(object, callback, forceAsync) { - return fabric.Object._fromObject('Triangle', object, callback, forceAsync); + fabric.Triangle.fromObject = function(object, callback) { + return fabric.Object._fromObject('Triangle', object, callback); }; })(typeof exports !== 'undefined' ? exports : this); diff --git a/src/util/misc.js b/src/util/misc.js index b879952a0cd..b1c2f423473 100644 --- a/src/util/misc.js +++ b/src/util/misc.js @@ -312,8 +312,7 @@ var enlivenedObjects = [], numLoadedObjects = 0, - numTotalObjects = objects.length, - forceAsync = true; + numTotalObjects = objects.length; if (!numTotalObjects) { callback && callback(enlivenedObjects); @@ -331,7 +330,7 @@ error || (enlivenedObjects[index] = obj); reviver && reviver(o, obj, error); onLoaded(); - }, forceAsync); + }); }); }, diff --git a/test/unit/circle.js b/test/unit/circle.js index fd63bedf4c8..ab90b5fd8fe 100644 --- a/test/unit/circle.js +++ b/test/unit/circle.js @@ -155,46 +155,46 @@ elCircle.setAttribute('stroke-linejoin', strokeLineJoin); elCircle.setAttribute('stroke-miterlimit', strokeMiterLimit); - var oCircle = fabric.Circle.fromElement(elCircle); - ok(oCircle instanceof fabric.Circle); - - equal(oCircle.get('radius'), radius); - equal(oCircle.get('left'), left - radius); - equal(oCircle.get('top'), top - radius); - equal(oCircle.get('fill'), fill); - equal(oCircle.get('opacity'), opacity); - equal(oCircle.get('strokeWidth'), strokeWidth); - deepEqual(oCircle.get('strokeDashArray'), strokeDashArray); - equal(oCircle.get('strokeLineCap'), strokeLineCap); - equal(oCircle.get('strokeLineJoin'), strokeLineJoin); - equal(oCircle.get('strokeMiterLimit'), strokeMiterLimit); - - var elFaultyCircle = fabric.document.createElement('circle'); - elFaultyCircle.setAttribute('r', '-10'); - - var error; - try { - fabric.Circle.fromElement(elFaultyCircle); - } - catch (err) { - error = err; - } - ok(error, 'negative attribute should throw'); - - elFaultyCircle.removeAttribute('r'); - - error = void 0; - try { - fabric.Circle.fromElement(elFaultyCircle); - } - catch (err) { - error = err; - } - - ok(error, 'inexstent attribute should throw'); + fabric.Circle.fromElement(elCircle, function(oCircle) { + ok(oCircle instanceof fabric.Circle); + equal(oCircle.get('radius'), radius); + equal(oCircle.get('left'), left - radius); + equal(oCircle.get('top'), top - radius); + equal(oCircle.get('fill'), fill); + equal(oCircle.get('opacity'), opacity); + equal(oCircle.get('strokeWidth'), strokeWidth); + deepEqual(oCircle.get('strokeDashArray'), strokeDashArray); + equal(oCircle.get('strokeLineCap'), strokeLineCap); + equal(oCircle.get('strokeLineJoin'), strokeLineJoin); + equal(oCircle.get('strokeMiterLimit'), strokeMiterLimit); + + var elFaultyCircle = fabric.document.createElement('circle'); + elFaultyCircle.setAttribute('r', '-10'); + + var error; + try { + fabric.Circle.fromElement(elFaultyCircle); + } + catch (err) { + error = err; + } + ok(error, 'negative attribute should throw'); + + elFaultyCircle.removeAttribute('r'); + + error = void 0; + try { + fabric.Circle.fromElement(elFaultyCircle); + } + catch (err) { + error = err; + } + + ok(error, 'inexstent attribute should throw'); + }); }); - test('fromObject', function() { + asyncTest('fromObject', function() { ok(typeof fabric.Circle.fromObject == 'function'); var left = 112, @@ -202,32 +202,32 @@ radius = 13.45, fill = 'ff5555'; - var circle = fabric.Circle.fromObject({ + fabric.Circle.fromObject({ left: left, top: top, radius: radius, fill: fill + }, function(circle) { + ok(circle instanceof fabric.Circle); + + equal(circle.get('left'), left); + equal(circle.get('top'), top); + equal(circle.get('radius'), radius); + equal(circle.get('fill'), fill); + + var expected = circle.toObject(); + fabric.Circle.fromObject(expected, function(actual) { + deepEqual(actual.toObject(), expected); + start(); + }); }); - - ok(circle instanceof fabric.Circle); - - equal(circle.get('left'), left); - equal(circle.get('top'), top); - equal(circle.get('radius'), radius); - equal(circle.get('fill'), fill); - - var expected = circle.toObject(); - var actual = fabric.Circle.fromObject(expected).toObject(); - - deepEqual(actual, expected); }); test('cloning and radius, width, height', function() { var circle = new fabric.Circle({ radius: 10, strokeWidth: 0}); circle.scale(2); - var clone = circle.clone(); - - equal(clone.getWidth(), 40); - equal(clone.getHeight(), 40); - - equal(clone.radius, 10); + circle.clone(function(clone) { + equal(clone.getWidth(), 40); + equal(clone.getHeight(), 40); + equal(clone.radius, 10); + }); }); })(); diff --git a/test/unit/ellipse.js b/test/unit/ellipse.js index 098f38de3ee..bdf3e451bf4 100644 --- a/test/unit/ellipse.js +++ b/test/unit/ellipse.js @@ -119,23 +119,23 @@ elEllipse.setAttribute('stroke-linejoin', strokeLineJoin); elEllipse.setAttribute('stroke-miterlimit', strokeMiterLimit); - var oEllipse = fabric.Ellipse.fromElement(elEllipse); - ok(oEllipse instanceof fabric.Ellipse); - - equal(oEllipse.get('rx'), rx); - equal(oEllipse.get('ry'), ry); - equal(oEllipse.get('left'), left - rx); - equal(oEllipse.get('top'), top - ry); - equal(oEllipse.get('fill'), fill); - equal(oEllipse.get('opacity'), opacity); - equal(oEllipse.get('strokeWidth'), strokeWidth); - deepEqual(oEllipse.get('strokeDashArray'), strokeDashArray); - equal(oEllipse.get('strokeLineCap'), strokeLineCap); - equal(oEllipse.get('strokeLineJoin'), strokeLineJoin); - equal(oEllipse.get('strokeMiterLimit'), strokeMiterLimit); + fabric.Ellipse.fromElement(elEllipse, function(oEllipse) { + ok(oEllipse instanceof fabric.Ellipse); + equal(oEllipse.get('rx'), rx); + equal(oEllipse.get('ry'), ry); + equal(oEllipse.get('left'), left - rx); + equal(oEllipse.get('top'), top - ry); + equal(oEllipse.get('fill'), fill); + equal(oEllipse.get('opacity'), opacity); + equal(oEllipse.get('strokeWidth'), strokeWidth); + deepEqual(oEllipse.get('strokeDashArray'), strokeDashArray); + equal(oEllipse.get('strokeLineCap'), strokeLineCap); + equal(oEllipse.get('strokeLineJoin'), strokeLineJoin); + equal(oEllipse.get('strokeMiterLimit'), strokeMiterLimit); + }); }); - test('fromObject', function() { + asyncTest('fromObject', function() { ok(typeof fabric.Ellipse == 'function'); var left = 112, @@ -144,20 +144,24 @@ ry = 14.78, fill = 'ff5555'; - var ellipse = fabric.Ellipse.fromObject({ + fabric.Ellipse.fromObject({ left: left, top: top, rx: rx, ry: ry, fill: fill + }, function(ellipse) { + ok(ellipse instanceof fabric.Ellipse); + + equal(ellipse.get('left'), left); + equal(ellipse.get('top'), top); + equal(ellipse.get('rx'), rx); + equal(ellipse.get('ry'), ry); + equal(ellipse.get('fill'), fill); + + var expected = ellipse.toObject(); + fabric.Ellipse.fromObject(expected, function(actual) { + deepEqual(actual.toObject(), expected); + start(); + }); }); - ok(ellipse instanceof fabric.Ellipse); - - equal(ellipse.get('left'), left); - equal(ellipse.get('top'), top); - equal(ellipse.get('rx'), rx); - equal(ellipse.get('ry'), ry); - equal(ellipse.get('fill'), fill); - var expected = ellipse.toObject(); - var actual = fabric.Ellipse.fromObject(expected).toObject(); - deepEqual(actual, expected); }); })(); diff --git a/test/unit/image.js b/test/unit/image.js index 8ae38ac9a66..081bea8508e 100644 --- a/test/unit/image.js +++ b/test/unit/image.js @@ -266,7 +266,6 @@ asyncTest('clone', function() { createImageObject(function(image) { ok(typeof image.clone == 'function'); - image.clone(function(clone) { ok(clone instanceof fabric.Image); deepEqual(clone.toObject(), image.toObject()); diff --git a/test/unit/itext.js b/test/unit/itext.js index eb40496f3ad..a9a2490a415 100644 --- a/test/unit/itext.js +++ b/test/unit/itext.js @@ -92,13 +92,13 @@ equal(lastInstance, iText); }); - test('fromObject', function() { + asyncTest('fromObject', function() { ok(typeof fabric.IText.fromObject == 'function'); - - var iText = fabric.IText.fromObject(ITEXT_OBJECT); - - ok(iText instanceof fabric.IText); - deepEqual(ITEXT_OBJECT, iText.toObject()); + fabric.IText.fromObject(ITEXT_OBJECT, function(iText) { + ok(iText instanceof fabric.IText); + deepEqual(ITEXT_OBJECT, iText.toObject()); + start(); + }); }); test('lineHeight with single line', function() { diff --git a/test/unit/line.js b/test/unit/line.js index 66378ad7079..606786b15b4 100644 --- a/test/unit/line.js +++ b/test/unit/line.js @@ -71,11 +71,13 @@ deepEqual(LINE_OBJECT, line.toObject()); }); - test('fromObject', function() { + asyncTest('fromObject', function() { ok(typeof fabric.Line.fromObject == 'function'); - var line = fabric.Line.fromObject(LINE_OBJECT); - ok(line instanceof fabric.Line); - deepEqual(LINE_OBJECT, line.toObject()); + fabric.Line.fromObject(LINE_OBJECT, function(line) { + ok(line instanceof fabric.Line); + deepEqual(LINE_OBJECT, line.toObject()); + start(); + }); }); test('fromElement', function() { @@ -104,28 +106,29 @@ lineEl.setAttribute('stroke-linejoin', strokeLineJoin); lineEl.setAttribute('stroke-miterlimit', strokeMiterLimit); - var oLine = fabric.Line.fromElement(lineEl); - ok(oLine instanceof fabric.Line); - - equal(oLine.get('x1'), x1); - equal(oLine.get('y1'), y1); - equal(oLine.get('x2'), x2); - equal(oLine.get('y2'), y2); - equal(oLine.get('stroke'), stroke); - equal(oLine.get('strokeWidth'), strokeWidth); - deepEqual(oLine.get('strokeDashArray'), strokeDashArray); - equal(oLine.get('strokeLineCap'), strokeLineCap); - equal(oLine.get('strokeLineJoin'), strokeLineJoin); - equal(oLine.get('strokeMiterLimit'), strokeMiterLimit); - - var lineElWithMissingAttributes = fabric.document.createElement('line'); - lineElWithMissingAttributes.setAttribute('x1', 10); - lineElWithMissingAttributes.setAttribute('y1', 20); - - oLine = fabric.Line.fromElement(lineElWithMissingAttributes); - - equal(oLine.get('x2'), 0, 'missing attributes count as 0 values'); - equal(oLine.get('y2'), 0, 'missing attributes count as 0 values'); + fabric.Line.fromElement(lineEl, function(oLine) { + ok(oLine instanceof fabric.Line); + + equal(oLine.get('x1'), x1); + equal(oLine.get('y1'), y1); + equal(oLine.get('x2'), x2); + equal(oLine.get('y2'), y2); + equal(oLine.get('stroke'), stroke); + equal(oLine.get('strokeWidth'), strokeWidth); + deepEqual(oLine.get('strokeDashArray'), strokeDashArray); + equal(oLine.get('strokeLineCap'), strokeLineCap); + equal(oLine.get('strokeLineJoin'), strokeLineJoin); + equal(oLine.get('strokeMiterLimit'), strokeMiterLimit); + + var lineElWithMissingAttributes = fabric.document.createElement('line'); + lineElWithMissingAttributes.setAttribute('x1', 10); + lineElWithMissingAttributes.setAttribute('y1', 20); + + fabric.Line.fromElement(lineElWithMissingAttributes, function(oLine2) { + equal(oLine2.get('x2'), 0, 'missing attributes count as 0 values'); + equal(oLine2.get('y2'), 0, 'missing attributes count as 0 values'); + }); + }); }); test('straight lines may have 0 width or heigth', function() { @@ -150,9 +153,9 @@ test('stroke-width in a style', function() { var lineEl = fabric.document.createElement('line'); lineEl.setAttribute('style', 'stroke-width:4'); - - var oLine = fabric.Line.fromElement(lineEl); - ok(4, oLine.strokeWidth); + fabric.Line.fromElement(lineEl, function(oLine) { + ok(4, oLine.strokeWidth); + }); }); // this isn't implemented yet, so disabling for now diff --git a/test/unit/object.js b/test/unit/object.js index d8903606bf5..3537c5ee5f8 100644 --- a/test/unit/object.js +++ b/test/unit/object.js @@ -534,18 +534,18 @@ test('clone', function() { var cObj = new fabric.Object({ left: 123, top: 456, opacity: 0.66 }); ok(typeof cObj.clone == 'function'); - var clone = cObj.clone(); + cObj.clone(function(clone) { + equal(clone.get('left'), 123); + equal(clone.get('top'), 456); + equal(clone.get('opacity'), 0.66); - equal(clone.get('left'), 123); - equal(clone.get('top'), 456); - equal(clone.get('opacity'), 0.66); + // augmenting clone properties should not affect original instance + clone.set('left', 12).set('scaleX', 2.5).setAngle(33); - // augmenting clone properties should not affect original instance - clone.set('left', 12).set('scaleX', 2.5).setAngle(33); - - equal(cObj.get('left'), 123); - equal(cObj.get('scaleX'), 1); - equal(cObj.getAngle(), 0); + equal(cObj.get('left'), 123); + equal(cObj.get('scaleX'), 1); + equal(cObj.getAngle(), 0); + }); }); asyncTest('cloneAsImage', function() { diff --git a/test/unit/parser.js b/test/unit/parser.js index 49a739e46a6..70a475509bc 100644 --- a/test/unit/parser.js +++ b/test/unit/parser.js @@ -101,7 +101,7 @@ }); asyncTest('parseElements', function() { - ok(fabric.parseElements); + ok(typeof fabric.parseElements === 'function'); function getOptions(options) { return fabric.util.object.extend(fabric.util.object.clone({ @@ -115,26 +115,13 @@ fabric.util.makeElement('path', getOptions({ d: 'M 100 100 L 300 100 L 200 300 z' })), fabric.util.makeElement('inexistent', getOptions()) ]; + fabric.parseElements(elements, function(parsedElements) { + ok(parsedElements[0] instanceof fabric.Rect); + ok(parsedElements[1] instanceof fabric.Circle); + ok(parsedElements[2] instanceof fabric.Path); + setTimeout(start, 1000); + }); - var parsedElements, error; - try { - fabric.parseElements(elements, function(instances) { - parsedElements = instances; - }); - } - catch (err) { - error = err; - } - ok(error === undefined, 'No error is raised'); - - setTimeout(function() { - if (parsedElements) { - ok(parsedElements[0] instanceof fabric.Rect); - ok(parsedElements[1] instanceof fabric.Circle); - ok(parsedElements[2] instanceof fabric.Path); - } - start(); - }, 1000); }); test('parseStyleAttribute', function() { @@ -420,7 +407,7 @@ // asyncTest('parseSVGDocument', function() { // ok(fabric.parseSVGDocument); - + // // var data; // fabric.util.request('../fixtures/path.svg', { // method: 'get', @@ -438,15 +425,15 @@ // }); // } // }); - + // // setTimeout(function() { // equal(typeof data, 'object'); - + // // if (data) { // equal(data.length, 1); - + // // var path = data[0]; - + // // ok(path instanceof fabric.Path); // equal(JSON.stringify(path), EXPECTED_PATH_JSON); // } @@ -456,7 +443,7 @@ // https://github.com/kangax/fabric.js/issues/25 // asyncTest('parsing one element should not "leak" its "fill" value onto parsing of following element', function() { - + // // var objects; // fabric.util.request('../fixtures/svg_with_rect.svg', { // method: 'get', @@ -468,12 +455,12 @@ // }); // } // }); - + // // setTimeout(function() { // if (objects) { // equal(objects[1].fill, 'green'); // } - + // // start(); // }, 1500); // }); @@ -486,10 +473,11 @@ var opacityValue = Math.random().toFixed(2); el.setAttribute('opacity', opacityValue); - var obj = fabric.Rect.fromElement(el); - - equal(obj.opacity, parseFloat(opacityValue), - 'opacity should be parsed correctly from "opacity" attribute of ' + tagNames[i] + ' element'); + // eslint-disable-next-line + fabric.Rect.fromElement(el, function(obj) { + equal(obj.opacity, parseFloat(opacityValue), + 'opacity should be parsed correctly from "opacity" attribute of ' + tagNames[i] + ' element'); + }); } }); @@ -499,10 +487,10 @@ el.setAttribute('fill-opacity', opacityValue); el.setAttribute('fill', '#FF0000'); - var obj = fabric.Rect.fromElement(el); - - equal(obj.fill, 'rgba(255,0,0,' + parseFloat(opacityValue) + ')', - 'opacity should be parsed correctly from "opacity" attribute of rect element'); + fabric.Rect.fromElement(el, function(obj) { + equal(obj.fill, 'rgba(255,0,0,' + parseFloat(opacityValue) + ')', + 'opacity should be parsed correctly from "opacity" attribute of rect element'); + }); }); test('fill-opacity attribute without fill attribute', function() { @@ -510,10 +498,10 @@ var opacityValue = Math.random().toFixed(2); el.setAttribute('fill-opacity', opacityValue); - var obj = fabric.Rect.fromElement(el); - - equal(obj.fill, 'rgba(0,0,0,' + parseFloat(opacityValue) + ')', - 'opacity should be parsed correctly from "opacity" attribute of rect element'); + fabric.Rect.fromElement(el, function(obj) { + equal(obj.fill, 'rgba(0,0,0,' + parseFloat(opacityValue) + ')', + 'opacity should be parsed correctly from "opacity" attribute of rect element'); + }); }); test('fill-opacity attribute with fill none', function() { @@ -522,9 +510,9 @@ el.setAttribute('fill-opacity', opacityValue); el.setAttribute('fill', 'none'); - var obj = fabric.Rect.fromElement(el); - - equal(obj.fill, '', 'fill should stay empty'); + fabric.Rect.fromElement(el, function(obj) { + equal(obj.fill, '', 'fill should stay empty'); + }); }); test('stroke-opacity attribute with stroke attribute', function() { @@ -533,10 +521,10 @@ el.setAttribute('stroke-opacity', opacityValue); el.setAttribute('stroke', '#FF0000'); - var obj = fabric.Rect.fromElement(el); - - equal(obj.stroke, 'rgba(255,0,0,' + parseFloat(opacityValue) + ')', - 'opacity should be parsed correctly from "opacity" attribute of rect element'); + fabric.Rect.fromElement(el, function(obj) { + equal(obj.stroke, 'rgba(255,0,0,' + parseFloat(opacityValue) + ')', + 'opacity should be parsed correctly from "opacity" attribute of rect element'); + }); }); test('stroke-opacity attribute without stroke attribute', function() { @@ -544,9 +532,9 @@ var opacityValue = Math.random().toFixed(2); el.setAttribute('stroke-opacity', opacityValue); - var obj = fabric.Rect.fromElement(el); - - equal(obj.stroke, null, 'Default stroke is null'); + fabric.Rect.fromElement(el, function(obj) { + equal(obj.stroke, null, 'Default stroke is null'); + }); }); test('stroke-opacity attribute with stroke none', function() { @@ -555,9 +543,9 @@ el.setAttribute('stroke-opacity', opacityValue); el.setAttribute('stroke', 'none'); - var obj = fabric.Rect.fromElement(el); - - equal(obj.stroke, '', 'stroke should stay empty'); + fabric.Rect.fromElement(el, function(obj) { + equal(obj.stroke, '', 'stroke should stay empty'); + }); }); test('getCssRule', function() { diff --git a/test/unit/path.js b/test/unit/path.js index 63cac0ac9e3..96b650e8a7e 100644 --- a/test/unit/path.js +++ b/test/unit/path.js @@ -122,14 +122,11 @@ }); }); - asyncTest('path array not shared when cloned', function() { + test('path array not shared when cloned', function() { makePathObject(function(originalPath) { originalPath.clone(function(clonedPath) { - clonedPath.path[0][1] = 200; equal(originalPath.path[0][1], 100); - - start(); }); }); }); diff --git a/test/unit/polygon.js b/test/unit/polygon.js index 78ec606c942..9cac72977f1 100644 --- a/test/unit/polygon.js +++ b/test/unit/polygon.js @@ -78,14 +78,16 @@ deepEqual(objectWithOriginalPoints, REFERENCE_OBJECT); }); - test('fromObject', function() { + asyncTest('fromObject', function() { ok(typeof fabric.Polygon.fromObject == 'function'); - var polygon = fabric.Polygon.fromObject(REFERENCE_OBJECT); - ok(polygon instanceof fabric.Polygon); - deepEqual(polygon.toObject(), REFERENCE_OBJECT); + fabric.Polygon.fromObject(REFERENCE_OBJECT, function(polygon) { + ok(polygon instanceof fabric.Polygon); + deepEqual(polygon.toObject(), REFERENCE_OBJECT); + start(); + }); }); - test('fromElement', function() { + test('fromElement without points', function() { ok(typeof fabric.Polygon.fromElement == 'function'); var empty_object = fabric.util.object.extend({}, REFERENCE_OBJECT); @@ -93,28 +95,35 @@ var elPolygonWithoutPoints = fabric.document.createElement('polygon'); - deepEqual(fabric.Polygon.fromElement(elPolygonWithoutPoints).toObject(), empty_object); + fabric.Polygon.fromElement(elPolygonWithoutPoints, function(polygon) { + deepEqual(polygon.toObject(), empty_object); + }); + }); + test('fromElement with empty points', function() { var elPolygonWithEmptyPoints = fabric.document.createElement('polygon'); elPolygonWithEmptyPoints.setAttribute('points', ''); + var empty_object = fabric.util.object.extend({}, REFERENCE_OBJECT); + empty_object = fabric.util.object.extend(empty_object, REFERENCE_EMPTY_OBJECT); + fabric.Polygon.fromElement(elPolygonWithEmptyPoints, function(polygon) { + deepEqual(polygon.toObject(), empty_object); + }); + }); - deepEqual(fabric.Polygon.fromElement(elPolygonWithEmptyPoints).toObject(), empty_object); - + test('fromElement with empty points', function() { var elPolygon = fabric.document.createElement('polygon'); - elPolygon.setAttribute('points', '10,12 20,22'); + fabric.Polygon.fromElement(elPolygon, function(polygon) { + ok(polygon instanceof fabric.Polygon); + var expected = fabric.util.object.extend( + fabric.util.object.clone(REFERENCE_OBJECT), { + points: [{ x: 10, y: 12 }, { x: 20, y: 22 }] + }); + deepEqual(polygon.toObject(), expected); + }); + }); - var polygon = fabric.Polygon.fromElement(elPolygon); - - ok(polygon instanceof fabric.Polygon); - - var expected = fabric.util.object.extend( - fabric.util.object.clone(REFERENCE_OBJECT), { - points: [{ x: 10, y: 12 }, { x: 20, y: 22 }] - }); - - deepEqual(polygon.toObject(), expected); - + test('fromElement with empty points', function() { var elPolygonWithAttrs = fabric.document.createElement('polygon'); elPolygonWithAttrs.setAttribute('points', '10,10 20,20 30,30 10,10'); elPolygonWithAttrs.setAttribute('fill', 'rgb(255,255,255)'); @@ -126,34 +135,35 @@ elPolygonWithAttrs.setAttribute('stroke-linecap', 'round'); elPolygonWithAttrs.setAttribute('stroke-linejoin', 'bevil'); elPolygonWithAttrs.setAttribute('stroke-miterlimit', '5'); - - var polygonWithAttrs = fabric.Polygon.fromElement(elPolygonWithAttrs); - var expectedPoints = [ - { x: 10, y: 10 }, - { x: 20, y: 20 }, - { x: 30, y: 30 }, - { x: 10, y: 10 } - ]; - - deepEqual(polygonWithAttrs.toObject(), fabric.util.object.extend(REFERENCE_OBJECT, { - 'width': 20, - 'height': 20, - 'fill': 'rgb(255,255,255)', - 'stroke': 'blue', - 'strokeWidth': 3, - 'strokeDashArray': [5, 2], - 'strokeLineCap': 'round', - 'strokeLineJoin': 'bevil', - 'strokeMiterLimit': 5, - 'opacity': 0.34, - 'points': expectedPoints, - 'top': 10, - 'left': 10, - 'transformMatrix': [2, 0, 0, 2, -10, -20] - })); - - deepEqual(polygonWithAttrs.get('transformMatrix'), [2, 0, 0, 2, -10, -20]); - - equal(fabric.Polygon.fromElement(), null); + fabric.Polygon.fromElement(elPolygonWithAttrs, function(polygonWithAttrs) { + var expectedPoints = [ + { x: 10, y: 10 }, + { x: 20, y: 20 }, + { x: 30, y: 30 }, + { x: 10, y: 10 } + ]; + deepEqual(polygonWithAttrs.toObject(), fabric.util.object.extend(REFERENCE_OBJECT, { + 'width': 20, + 'height': 20, + 'fill': 'rgb(255,255,255)', + 'stroke': 'blue', + 'strokeWidth': 3, + 'strokeDashArray': [5, 2], + 'strokeLineCap': 'round', + 'strokeLineJoin': 'bevil', + 'strokeMiterLimit': 5, + 'opacity': 0.34, + 'points': expectedPoints, + 'top': 10, + 'left': 10, + 'transformMatrix': [2, 0, 0, 2, -10, -20] + })); + deepEqual(polygonWithAttrs.get('transformMatrix'), [2, 0, 0, 2, -10, -20]); + }); + }); + test('fromElement with null', function() { + fabric.Polygon.fromElement(null, function(polygon) { + equal(polygon, null); + }); }); })(); diff --git a/test/unit/polyline.js b/test/unit/polyline.js index 64a06da3f46..722cf2257e2 100644 --- a/test/unit/polyline.js +++ b/test/unit/polyline.js @@ -77,36 +77,45 @@ deepEqual(objectWithOriginalPoints, REFERENCE_OBJECT); }); - test('fromObject', function() { + asyncTest('fromObject', function() { ok(typeof fabric.Polyline.fromObject == 'function'); - var polyline = fabric.Polyline.fromObject(REFERENCE_OBJECT); - ok(polyline instanceof fabric.Polyline); - deepEqual(polyline.toObject(), REFERENCE_OBJECT); + fabric.Polyline.fromObject(REFERENCE_OBJECT, function(polyline) { + ok(polyline instanceof fabric.Polyline); + deepEqual(polyline.toObject(), REFERENCE_OBJECT); + start(); + }); }); - test('fromElement', function() { + test('fromElement without points', function() { ok(typeof fabric.Polyline.fromElement == 'function'); - var elPolylineWithoutPoints = fabric.document.createElement('polyline'); var empty_object = fabric.util.object.extend({}, REFERENCE_OBJECT); empty_object = fabric.util.object.extend(empty_object, REFERENCE_EMPTY_OBJECT); + fabric.Polyline.fromElement(elPolylineWithoutPoints, function(polyline) { + deepEqual(polyline.toObject(), empty_object); + }); + }); - deepEqual(fabric.Polyline.fromElement(elPolylineWithoutPoints).toObject(), empty_object); - + test('fromElement with empty points', function() { var elPolylineWithEmptyPoints = fabric.document.createElement('polyline'); elPolylineWithEmptyPoints.setAttribute('points', ''); + fabric.Polyline.fromElement(elPolylineWithEmptyPoints, function(polyline) { + var empty_object = fabric.util.object.extend({}, REFERENCE_OBJECT); + empty_object = fabric.util.object.extend(empty_object, REFERENCE_EMPTY_OBJECT); + deepEqual(polyline.toObject(), empty_object); + }); + }); - deepEqual(fabric.Polyline.fromElement(elPolylineWithEmptyPoints).toObject(), empty_object); - + test('fromElement', function() { var elPolyline = fabric.document.createElement('polyline'); - elPolyline.setAttribute('points', '10,12 20,22'); + fabric.Polyline.fromElement(elPolyline, function(polyline) { + ok(polyline instanceof fabric.Polyline); + deepEqual(polyline.toObject(), REFERENCE_OBJECT); + }); + }); - var polyline = fabric.Polyline.fromElement(elPolyline); - ok(polyline instanceof fabric.Polyline); - - deepEqual(polyline.toObject(), REFERENCE_OBJECT); - + test('fromElement with custom attr', function() { var elPolylineWithAttrs = fabric.document.createElement('polyline'); elPolylineWithAttrs.setAttribute('points', '10,10 20,20 30,30 10,10'); elPolylineWithAttrs.setAttribute('fill', 'rgb(255,255,255)'); @@ -119,29 +128,31 @@ elPolylineWithAttrs.setAttribute('stroke-linejoin', 'bevil'); elPolylineWithAttrs.setAttribute('stroke-miterlimit', '5'); - var polylineWithAttrs = fabric.Polyline.fromElement(elPolylineWithAttrs); - - var expectedPoints = [{x: 10, y: 10}, {x: 20, y: 20}, {x: 30, y: 30}, {x: 10, y: 10}]; - - deepEqual(polylineWithAttrs.toObject(), fabric.util.object.extend(REFERENCE_OBJECT, { - 'width': 20, - 'height': 20, - 'fill': 'rgb(255,255,255)', - 'stroke': 'blue', - 'strokeWidth': 3, - 'strokeDashArray': [5, 2], - 'strokeLineCap': 'round', - 'strokeLineJoin': 'bevil', - 'strokeMiterLimit': 5, - 'opacity': 0.34, - 'points': expectedPoints, - 'left': 10, - 'top': 10, - 'transformMatrix': [2, 0, 0, 2, -10, -20] - })); - - deepEqual(polylineWithAttrs.get('transformMatrix'), [2, 0, 0, 2, -10, -20]); - - equal(fabric.Polyline.fromElement(), null); + fabric.Polyline.fromElement(elPolylineWithAttrs, function(polylineWithAttrs) { + var expectedPoints = [{x: 10, y: 10}, {x: 20, y: 20}, {x: 30, y: 30}, {x: 10, y: 10}]; + deepEqual(polylineWithAttrs.toObject(), fabric.util.object.extend(REFERENCE_OBJECT, { + 'width': 20, + 'height': 20, + 'fill': 'rgb(255,255,255)', + 'stroke': 'blue', + 'strokeWidth': 3, + 'strokeDashArray': [5, 2], + 'strokeLineCap': 'round', + 'strokeLineJoin': 'bevil', + 'strokeMiterLimit': 5, + 'opacity': 0.34, + 'points': expectedPoints, + 'left': 10, + 'top': 10, + 'transformMatrix': [2, 0, 0, 2, -10, -20] + })); + deepEqual(polylineWithAttrs.get('transformMatrix'), [2, 0, 0, 2, -10, -20]); + }); + }); + + test('fromElement with nothing', function() { + fabric.Polyline.fromElement(null, function(polyline) { + equal(polyline, null); + }); }); })(); diff --git a/test/unit/rect.js b/test/unit/rect.js index 4d93e3cf2f8..19564eb27f3 100644 --- a/test/unit/rect.js +++ b/test/unit/rect.js @@ -68,30 +68,34 @@ deepEqual(object, REFERENCE_RECT); }); - test('fabric.Rect.fromObject', function() { + asyncTest('fabric.Rect.fromObject', function() { ok(typeof fabric.Rect.fromObject == 'function'); - var rect = fabric.Rect.fromObject(REFERENCE_RECT); - ok(rect instanceof fabric.Rect); - deepEqual(rect.toObject(), REFERENCE_RECT); - - var expectedObject = fabric.util.object.extend({ }, REFERENCE_RECT); - expectedObject.fill = {'type': 'linear','coords': {'x1': 0,'y1': 0,'x2': 200,'y2': 0},'colorStops': [{'offset': '0','color': 'rgb(255,0,0)','opacity': 1},{'offset': '1','color': 'rgb(0,0,255)','opacity': 1}],'offsetX': 0,'offsetY': 0}; - expectedObject.stroke = {'type': 'linear','coords': {'x1': 0,'y1': 0,'x2': 200,'y2': 0},'colorStops': [{'offset': '0','color': 'rgb(255,0,0)','opacity': 1},{'offset': '1','color': 'rgb(0,0,255)','opacity': 1}],'offsetX': 0,'offsetY': 0}; - rect = fabric.Rect.fromObject(expectedObject); - ok(rect.fill instanceof fabric.Gradient); - ok(rect.stroke instanceof fabric.Gradient); + fabric.Rect.fromObject(REFERENCE_RECT, function(rect) { + ok(rect instanceof fabric.Rect); + deepEqual(rect.toObject(), REFERENCE_RECT); + + var expectedObject = fabric.util.object.extend({ }, REFERENCE_RECT); + expectedObject.fill = {'type': 'linear','coords': {'x1': 0,'y1': 0,'x2': 200,'y2': 0},'colorStops': [{'offset': '0','color': 'rgb(255,0,0)','opacity': 1},{'offset': '1','color': 'rgb(0,0,255)','opacity': 1}],'offsetX': 0,'offsetY': 0}; + expectedObject.stroke = {'type': 'linear','coords': {'x1': 0,'y1': 0,'x2': 200,'y2': 0},'colorStops': [{'offset': '0','color': 'rgb(255,0,0)','opacity': 1},{'offset': '1','color': 'rgb(0,0,255)','opacity': 1}],'offsetX': 0,'offsetY': 0}; + fabric.Rect.fromObject(expectedObject, function(rect2) { + ok(rect2.fill instanceof fabric.Gradient); + ok(rect2.stroke instanceof fabric.Gradient); + start(); + }); + }); }); test('fabric.Rect.fromElement', function() { ok(typeof fabric.Rect.fromElement == 'function'); var elRect = fabric.document.createElement('rect'); - var rect = fabric.Rect.fromElement(elRect); - var expectedObject = fabric.util.object.extend({ }, REFERENCE_RECT); - expectedObject.visible = false; - ok(rect instanceof fabric.Rect); - deepEqual(rect.toObject(), expectedObject); + fabric.Rect.fromElement(elRect, function(rect) { + var expectedObject = fabric.util.object.extend({ }, REFERENCE_RECT); + expectedObject.visible = false; + ok(rect instanceof fabric.Rect); + deepEqual(rect.toObject(), expectedObject); + }); }); test('fabric.Rect.fromElement with custom attributes', function() { @@ -113,38 +117,40 @@ elRectWithAttrs.setAttribute('stroke-miterlimit', 5); //elRectWithAttrs.setAttribute('transform', 'translate(-10,-20) scale(2) rotate(45) translate(5,10)'); - var rectWithAttrs = fabric.Rect.fromElement(elRectWithAttrs); - ok(rectWithAttrs instanceof fabric.Rect); - - var expectedObject = fabric.util.object.extend(REFERENCE_RECT, { - left: 10, - top: 20, - width: 222, - height: 333, - fill: 'rgb(255,255,255)', - opacity: 0.45, - stroke: 'blue', - strokeWidth: 3, - strokeDashArray: [5, 2], - strokeLineCap: 'round', - strokeLineJoin: 'bevil', - strokeMiterLimit: 5, - rx: 11, - ry: 12 + fabric.Rect.fromElement(elRectWithAttrs, function(rectWithAttrs) { + ok(rectWithAttrs instanceof fabric.Rect); + var expectedObject = fabric.util.object.extend(REFERENCE_RECT, { + left: 10, + top: 20, + width: 222, + height: 333, + fill: 'rgb(255,255,255)', + opacity: 0.45, + stroke: 'blue', + strokeWidth: 3, + strokeDashArray: [5, 2], + strokeLineCap: 'round', + strokeLineJoin: 'bevil', + strokeMiterLimit: 5, + rx: 11, + ry: 12 + }); + deepEqual(rectWithAttrs.toObject(), expectedObject); }); - deepEqual(rectWithAttrs.toObject(), expectedObject); }); test('empty fromElement', function() { - ok(fabric.Rect.fromElement() === null); + fabric.Rect.fromElement(null, function(rect) { + equal(rect, null); + }); }); test('clone with rounded corners', function() { var rect = new fabric.Rect({ width: 100, height: 100, rx: 20, ry: 30 }); - var clone = rect.clone(); - - equal(clone.get('rx'), rect.get('rx')); - equal(clone.get('ry'), rect.get('ry')); + rect.clone(function(clone) { + equal(clone.get('rx'), rect.get('rx')); + equal(clone.get('ry'), rect.get('ry')); + }); }); test('toSVG with rounded corners', function() { diff --git a/test/unit/text.js b/test/unit/text.js index 20ece402e91..a600f29d459 100644 --- a/test/unit/text.js +++ b/test/unit/text.js @@ -198,10 +198,12 @@ equal(text.getText(), 'bar'); }); - test('fabric.Text.fromObject', function(){ + asyncTest('fabric.Text.fromObject', function(){ ok(typeof fabric.Text.fromObject == 'function'); - var text = fabric.Text.fromObject(REFERENCE_TEXT_OBJECT); - deepEqual(text.toObject(), REFERENCE_TEXT_OBJECT); + fabric.Text.fromObject(REFERENCE_TEXT_OBJECT, function(text) { + deepEqual(text.toObject(), REFERENCE_TEXT_OBJECT); + start(); + }); }); test('fabric.Text.fromElement', function() { @@ -210,23 +212,18 @@ var elText = fabric.document.createElement('text'); elText.textContent = 'x'; - var text = fabric.Text.fromElement(elText); - - ok(text instanceof fabric.Text); - - // temp workaround for text objects not obtaining width under node - // text.width = CHAR_WIDTH; - - var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), { - left: 0, - top: -14.59, - width: 8, - height: 18.08, - fontSize: 16, - originX: 'left' + fabric.Text.fromElement(elText, function(text) { + ok(text instanceof fabric.Text); + var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), { + left: 0, + top: -14.59, + width: 8, + height: 18.08, + fontSize: 16, + originX: 'left' + }); + deepEqual(text.toObject(), expectedObject, 'parsed object is what expected'); }); - - deepEqual(text.toObject(), expectedObject, 'parsed object is what expected'); }); test('fabric.Text.fromElement with custom attributes', function() { @@ -251,39 +248,42 @@ elTextWithAttrs.setAttribute('text-decoration', 'underline'); elTextWithAttrs.setAttribute('text-anchor', 'middle'); - var textWithAttrs = fabric.Text.fromElement(elTextWithAttrs); - // temp workaround for text objects not obtaining width under node - textWithAttrs.width = CHAR_WIDTH; - - ok(textWithAttrs instanceof fabric.Text); - - var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), { - /* left varies slightly due to node-canvas rendering */ - left: fabric.util.toFixed(textWithAttrs.left + '', 2), - top: -82.43, - width: CHAR_WIDTH, - height: 138.99, - fill: 'rgb(255,255,255)', - opacity: 0.45, - stroke: 'blue', - strokeWidth: 3, - strokeDashArray: [5, 2], - strokeLineCap: 'round', - strokeLineJoin: 'bevil', - strokeMiterLimit: 5, - fontFamily: 'Monaco', - fontStyle: 'italic', - fontWeight: 'bold', - fontSize: 123, - underline: true, - originX: 'left' + fabric.Text.fromElement(elTextWithAttrs, function(textWithAttrs) { + // temp workaround for text objects not obtaining width under node + textWithAttrs.width = CHAR_WIDTH; + + ok(textWithAttrs instanceof fabric.Text); + + var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), { + /* left varies slightly due to node-canvas rendering */ + left: fabric.util.toFixed(textWithAttrs.left + '', 2), + top: -82.43, + width: CHAR_WIDTH, + height: 138.99, + fill: 'rgb(255,255,255)', + opacity: 0.45, + stroke: 'blue', + strokeWidth: 3, + strokeDashArray: [5, 2], + strokeLineCap: 'round', + strokeLineJoin: 'bevil', + strokeMiterLimit: 5, + fontFamily: 'Monaco', + fontStyle: 'italic', + fontWeight: 'bold', + fontSize: 123, + underline: true, + originX: 'left' + }); + + deepEqual(textWithAttrs.toObject(), expectedObject); }); - - deepEqual(textWithAttrs.toObject(), expectedObject); }); test('empty fromElement', function() { - ok(fabric.Text.fromElement() === null); + fabric.Text.fromElement(null, function(text) { + equal(text, null); + }); }); test('dimensions after text change', function() { diff --git a/test/unit/util.js b/test/unit/util.js index 3a2e2efba81..bd1fe3dafb0 100644 --- a/test/unit/util.js +++ b/test/unit/util.js @@ -401,16 +401,11 @@ asyncTest('fabric.loadSVGFromString', function() { equal('function', typeof fabric.loadSVGFromString); - var loadedObjects = []; - fabric.loadSVGFromString(SVG_DOC_AS_STRING, function(objects) { - loadedObjects = objects; - }); - - setTimeout(function() { + fabric.loadSVGFromString(SVG_DOC_AS_STRING, function(loadedObjects) { ok(loadedObjects[0] instanceof fabric.Polygon); equal('red', loadedObjects[0].fill); - start(); - }, 1000); + setTimeout(start, 1000); + }); }); asyncTest('fabric.loadSVGFromString with surrounding whitespace', function() {