mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-18 02:21:07 +00:00
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:
commit
c6091b6be2
3 changed files with 28 additions and 17 deletions
|
|
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue