Skip to content

Commit

Permalink
Fix opacity parsing from classes and from fill-opacity (#3747)
Browse files Browse the repository at this point in the history
* fix to parser

* fix opacity parsing

* fix opacity parsing

* added tests

* fix for parsing attributes equalt to 0

* added test

* fixed better

* removed fix
  • Loading branch information
asturur authored Feb 27, 2017
1 parent c3a6447 commit 211edec
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 29 deletions.
41 changes: 26 additions & 15 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
'stroke-opacity': 'strokeOpacity',
'stroke-width': 'strokeWidth',
'text-decoration': 'textDecoration',
'text-anchor': 'originX'
'text-anchor': 'originX',
opacity: 'opacity'
},

colorAttributes = {
Expand Down Expand Up @@ -93,6 +94,12 @@
value = false;
}
}
else if (attr === 'opacity') {
value = parseFloat(value);
if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {
value *= parentAttributes.opacity;
}
}
else if (attr === 'originX' /* text-anchor */) {
value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';
}
Expand Down Expand Up @@ -311,8 +318,8 @@
style.replace(/;\s*$/, '').split(';').forEach(function (chunk) {
var pair = chunk.split(':');

attr = normalizeAttr(pair[0].trim().toLowerCase());
value = normalizeValue(attr, pair[1].trim());
attr = pair[0].trim().toLowerCase();
value = pair[1].trim();

oStyle[attr] = value;
});
Expand All @@ -328,8 +335,8 @@
continue;
}

attr = normalizeAttr(prop.toLowerCase());
value = normalizeValue(attr, style[prop]);
attr = prop.toLowerCase();
value = style[prop];

oStyle[attr] = value;
}
Expand Down Expand Up @@ -758,23 +765,27 @@

var ownAttributes = attributes.reduce(function(memo, attr) {
value = element.getAttribute(attr);
if (value) {
attr = normalizeAttr(attr);
value = normalizeValue(attr, value, parentAttributes, fontSize);

if (value) { // eslint-disable-line
memo[attr] = value;
}
return memo;
}, { });

// 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, svgUid), fabric.parseStyleAttribute(element)));
if (ownAttributes.font) {
fabric.parseFontDeclaration(ownAttributes.font, ownAttributes);

var normalizedAttr, normalizedValue, normalizedStyle = {};
for (var attr in ownAttributes) {
normalizedAttr = normalizeAttr(attr);
normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);
normalizedStyle[normalizedAttr] = normalizedValue;
}
if (normalizedStyle && normalizedStyle.font) {
fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);
}
return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes));
var mergedAttrs = extend(parentAttributes, normalizedStyle);
return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
},

/**
Expand Down Expand Up @@ -884,8 +895,8 @@

for (var i = 0, len = propertyValuePairs.length; i < len; i++) {
var pair = propertyValuePairs[i].split(/\s*:\s*/),
property = normalizeAttr(pair[0]),
value = normalizeValue(property, pair[1], pair[0]);
property = pair[0],
value = pair[1];
ruleObj[property] = value;
}
rule = match[1];
Expand Down
82 changes: 68 additions & 14 deletions test/unit/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@
var styleObj = fabric.parseStyleAttribute(element);
// TODO: looks like this still fails with % values
var expectedObject = {
'left': 10,
'top': 356.8,
'width': 137.93333333333334,
'height': 20
left: '10px',
top: '22.3em',
width: '103.45pt',
height: '20%'
};
deepEqual(styleObj, expectedObject);
});
Expand All @@ -158,7 +158,7 @@
element.setAttribute('style', 'left:10px');

var expectedObject = {
'left': 10
left: '10px'
};
deepEqual(fabric.parseStyleAttribute(element), expectedObject);
});
Expand All @@ -168,8 +168,8 @@
element.setAttribute('style', 'left:10px; top:5px; ');

var expectedObject = {
'left': 10,
'top': 5
left: '10px',
top: '5px'
};
deepEqual(fabric.parseStyleAttribute(element), expectedObject);
});
Expand All @@ -179,8 +179,8 @@
element.setAttribute('style', 'fill:none; stroke-dasharray: 2 0.4;');

var expectedObject = {
'fill': '',
'strokeDashArray': [2, 0.4]
fill: 'none',
'stroke-dasharray': '2 0.4'
};
deepEqual(fabric.parseStyleAttribute(element), expectedObject);
});
Expand Down Expand Up @@ -244,6 +244,16 @@
deepEqual(fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES), expectedObject);
});

test('parse 0 attribute', function() {
var element = fabric.document.createElement('path');
element.setAttribute('opacity', 0);

var expectedObject = {
opacity: 0,
};
deepEqual(fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES), expectedObject);
});

test('parsePointsAttribute', function() {
ok(fabric.parsePointsAttribute);

Expand Down Expand Up @@ -348,6 +358,50 @@
});
});

asyncTest('parseSVGFromString nested opacity', function() {
var string = '<?xml version="1.0" encoding="UTF-8"?>' +
'<svg version="1.2" baseProfile="tiny" xml:id="svg-root" width="300" height="400" ' +
'viewBox="0 0 300 400" xmlns="http://www.w3.org/2000/svg" ' +
'xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xe="http://www.w3.org/2001/xml-events">' +
'<defs>' +
'<style>' +
'.cls-3{opacity:0.5;}' +
'.cls-4{opacity:0.5;}' +
'</style>' +
'</defs>' +
'<g fill="red" stroke="#000000" fill-opacity="0.5">' +
'<circle cx="50" cy="50" r="50" fill-opacity="1" fill="rgba(255,0,0,0.3)" />' +
'<circle cx="150" cy="50" r="50" fill="rgba(0,255,0,0.5)" />' +
'<circle cx="50" cy="150" r="50" />' +
'<circle cx="150" cy="150" r="50" fill-opacity="0.5" fill="rgb(0,0,255)" />' +
'<circle cx="250" cy="50" r="50" fill-opacity="0.5" fill="rgba(0,0,255,0.5)" />' +
'<circle cx="250" cy="150" r="50" fill-opacity="1" fill="rgb(0,0,255)" />' +
'</g>' +
'<g class="cls-3" transform="translate(0,200)">' +
'<circle cx="50" cy="50" r="50" class="cls-4" fill="red" />' +
'<circle cx="150" cy="50" r="50" fill="red" />' +
'</g>' +
'</svg>';

fabric.loadSVGFromString(string, function(objects) {
equal(objects[0].fill, 'rgba(255,0,0,0.3)', 'first circle has opacity 0.3 from rgba');
equal(objects[0].fillOpacity, 1,'first circle has fill-opacity 1');
equal(objects[1].fill, 'rgba(0,255,0,0.25)', 'first circle has opacity 0.5 from rgba and 0.5 from gtoup fill opacity');
equal(objects[1].fillOpacity, 0.5,'first circle has fill-opacity 0.5');
equal(objects[2].fill, 'rgba(255,0,0,0.5)', 'first circle has opacity 0.5 from group fill opacity');
equal(objects[2].fillOpacity, 0.5,'first circle has fill-opacity 0.5');
equal(objects[3].fill, 'rgba(0,0,255,0.5)', 'first circle has opacity 0.5 from fill opacity');
equal(objects[3].fillOpacity, 0.5,'first circle has fill-opacity 1');
equal(objects[4].fill, 'rgba(0,0,255,0.25)', 'first circle has opacity 0.5 from rgba and 0.5 from fill opacity');
equal(objects[4].fillOpacity, 0.5,'first circle has fill-opacity 0.5');
equal(objects[5].fill, 'rgba(0,0,255,1)', 'first circle has opacity 1 from rgba');
equal(objects[5].fillOpacity, 1,'first circle has fill-opacity 1');
equal(objects[6].opacity, 0.25, 'opacity is 0.25 for cls-3 * cls-4');
equal(objects[7].opacity, 0.5,'opacity is 0.5 from cls-3');
start();
});
});

asyncTest('parseSVGFromString with svg:namespace', function() {
var string = '<?xml version="1.0" standalone="no"?><svg width="100%" height="100%" version="1.1" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' +
'<svg:defs><svg:rect id="myrect" width="300" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)"/></svg:defs>' +
Expand Down Expand Up @@ -523,15 +577,15 @@
'g polygon.cls': {
'fill': '#FF0000',
'stroke': '#000000',
'strokeWidth': 0.25
'stroke-width': '0.25px'
},
'rect': {
'fill': '#FF0000',
'stroke': '#000000',
'strokeWidth': 0.25
'stroke-width': '0.25px'
},
'polygon.cls': {
'fill': '',
'fill': 'none',
'stroke': '#0000FF'
}
};
Expand Down Expand Up @@ -575,13 +629,13 @@
'.cls1': {
'fill': '#FF0000',
'stroke': '#00FF00',
'strokeWidth': 3
'stroke-width': '3'
},
'.cls2': {
'fill': '#FF0000'
},
'.cls3': {
'strokeWidth': 3
'stroke-width': '3'
}
};

Expand Down

0 comments on commit 211edec

Please sign in to comment.