Merge pull request #1687 from asturur/fix-for-css-and-gradient-overwrite

Fix gradients being overwritten due to async loading
This commit is contained in:
Juriy Zaytsev 2014-09-21 15:46:42 +02:00
commit c6091b6be2
3 changed files with 28 additions and 17 deletions

View file

@ -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));
}
};

View file

@ -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));
},

View file

@ -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);