diff --git a/src/elements_parser.js b/src/elements_parser.js index e1bf5f7e..dd33f5b5 100644 --- a/src/elements_parser.js +++ b/src/elements_parser.js @@ -3,6 +3,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver) { this.callback = callback; this.options = options; this.reviver = reviver; + this.svgUid = (options && options.svgUid) || 0; }; fabric.ElementsParser.prototype.parse = function() { @@ -14,6 +15,7 @@ fabric.ElementsParser.prototype.parse = function() { fabric.ElementsParser.prototype.createObjects = function() { for (var i = 0, len = this.elements.length; i < len; i++) { + this.elements[i].setAttribute('svgUid', this.svgUid); (function(_this, i) { setTimeout(function() { _this.createObject(_this.elements[i], i); @@ -69,9 +71,9 @@ fabric.ElementsParser.prototype.resolveGradient = function(obj, property) { return; } var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1); - if (fabric.gradientDefs[gradientId]) { + if (fabric.gradientDefs[this.svgUid][gradientId]) { obj.set(property, - fabric.Gradient.fromElement(fabric.gradientDefs[gradientId], obj)); + fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj)); } }; diff --git a/src/parser.js b/src/parser.js index f2f179c7..7c4e9956 100644 --- a/src/parser.js +++ b/src/parser.js @@ -45,6 +45,9 @@ fill: 'fillOpacity' }; + fabric.cssRules = { }; + fabric.gradientDefs = { }; + function normalizeAttr(attr) { // transform attribute names if (attr in attributesMap) { @@ -349,13 +352,12 @@ /** * @private */ - function getGlobalStylesForElement(element) { + function getGlobalStylesForElement(element, svgUid) { var styles = { }; - - for (var rule in fabric.cssRules) { + for (var rule in fabric.cssRules[svgUid]) { if (elementMatchesRule(element, rule.split(' '))) { - for (var property in fabric.cssRules[rule]) { - styles[property] = fabric.cssRules[rule][property]; + for (var property in fabric.cssRules[svgUid][rule]) { + styles[property] = fabric.cssRules[svgUid][rule][property]; } } } @@ -505,7 +507,8 @@ if (!doc) { return; } - var startTime = new Date(); + var startTime = new Date(), + svgUid = fabric.Object.__uid++; parseUseDirectives(doc); /* http://www.w3.org/TR/SVG/struct.html#SVGElementWidthAttribute @@ -560,11 +563,12 @@ width: widthAttr ? widthAttr : viewBoxWidth, height: heightAttr ? heightAttr : viewBoxHeight, widthAttr: widthAttr, - heightAttr: heightAttr + heightAttr: heightAttr, + svgUid: svgUid }; - fabric.gradientDefs = fabric.getGradientDefs(doc); - fabric.cssRules = fabric.getCSSRules(doc); + fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); + fabric.cssRules[svgUid] = fabric.getCSSRules(doc); // Precedence of rules: style > class > attribute fabric.parseElements(elements, function(instances) { @@ -688,7 +692,7 @@ * @param {Array} attributes Array of attributes to parse * @return {Object} object containing parsed attributes' names/values */ - parseAttributes: function(element, attributes) { + parseAttributes: function(element, attributes, svgUid) { if (!element) { return; @@ -697,9 +701,12 @@ var value, parentAttributes = { }; + if (typeof svgUid === 'undefined') { + svgUid = element.getAttribute('svgUid'); + } // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards if (element.parentNode && /^symbol|[g|a]$/i.test(element.parentNode.nodeName)) { - parentAttributes = fabric.parseAttributes(element.parentNode, attributes); + parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid); } var ownAttributes = attributes.reduce(function(memo, attr) { @@ -716,7 +723,7 @@ // add values parsed from style, which take precedence over attributes // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes) ownAttributes = extend(ownAttributes, - extend(getGlobalStylesForElement(element), fabric.parseStyleAttribute(element))); + extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element))); return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes)); }, diff --git a/test/unit/parser.js b/test/unit/parser.js index aec9f96a..9c62f04e 100644 --- a/test/unit/parser.js +++ b/test/unit/parser.js @@ -364,7 +364,8 @@ styleElement = doc.createElement('style'); styleElement.textContent = 'g polygon.cls, rect {fill:#FF0000; stroke:#000000;stroke-width:0.25px;}\ polygon.cls {fill:none;stroke:#0000FF;}', - doc.body.appendChild(styleElement); + doc.body.appendChild(styleElement), + svgUid = 'uniqueId'; var expectedObject = { 'g polygon.cls': { @@ -383,8 +384,8 @@ } } - fabric.cssRules = fabric.getCSSRules(doc); - deepEqual(fabric.cssRules, expectedObject); + fabric.cssRules[svgUid] = fabric.getCSSRules(doc); + deepEqual(fabric.cssRules[svgUid], expectedObject); var elPolygon = fabric.document.createElement('polygon'), expectedStyle = { @@ -394,6 +395,7 @@ elPolygon.setAttribute('points', '10,12 20,22'); elPolygon.setAttribute('class', 'cls'); + elPolygon.setAttribute('svgUid', svgUid); var style = fabric.parseAttributes(elPolygon, [ ]); deepEqual(style, expectedStyle);