mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-04 20:04:45 +00:00
Parser RegEx update (#4003)
* better regex and attribute validation as well as public accesss to the regex * lint
This commit is contained in:
parent
b7d9047c9c
commit
b114d8d0ee
3 changed files with 51 additions and 10 deletions
|
|
@ -48,7 +48,8 @@ fabric.SHARED_ATTRIBUTES = [
|
|||
"stroke", "stroke-dasharray", "stroke-linecap",
|
||||
"stroke-linejoin", "stroke-miterlimit",
|
||||
"stroke-opacity", "stroke-width",
|
||||
"id"
|
||||
"id",
|
||||
"instantiated_by_use"
|
||||
];
|
||||
/* _FROM_SVG_END_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@
|
|||
parseUnit = fabric.util.parseUnit,
|
||||
multiplyTransformMatrices = fabric.util.multiplyTransformMatrices,
|
||||
|
||||
reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/i,
|
||||
reViewBoxTagNames = /^(symbol|image|marker|pattern|view|svg)$/i,
|
||||
reNotAllowedAncestors = /^(?:pattern|defs|symbol|metadata|clipPath|mask)$/i,
|
||||
reAllowedParents = /^(symbol|g|a|svg)$/i,
|
||||
svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line',
|
||||
'image', 'text', 'linearGradient', 'radialGradient', 'stop'],
|
||||
svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
|
||||
svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'],
|
||||
svgValidParents = ['symbol', 'g', 'a', 'svg'],
|
||||
|
||||
attributesMap = {
|
||||
cx: 'left',
|
||||
|
|
@ -50,6 +51,11 @@
|
|||
fill: 'fillOpacity'
|
||||
};
|
||||
|
||||
fabric.svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);
|
||||
fabric.svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);
|
||||
fabric.svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);
|
||||
fabric.svgValidParentsRegEx = getSvgRegex(svgValidParents);
|
||||
|
||||
fabric.cssRules = { };
|
||||
fabric.gradientDefs = { };
|
||||
|
||||
|
|
@ -110,6 +116,13 @@
|
|||
return (!isArray && isNaN(parsed) ? value : parsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function getSvgRegex(arr) {
|
||||
return new RegExp('^(' + arr.join('|') + ')\\b', 'i');
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} attributes Array of attributes to parse
|
||||
|
|
@ -508,7 +521,7 @@
|
|||
x = element.getAttribute('x') || 0,
|
||||
y = element.getAttribute('y') || 0,
|
||||
preserveAspectRatio = element.getAttribute('preserveAspectRatio') || '',
|
||||
missingViewBox = (!viewBoxAttr || !reViewBoxTagNames.test(element.nodeName)
|
||||
missingViewBox = (!viewBoxAttr || !fabric.svgViewBoxElementsRegEx.test(element.nodeName)
|
||||
|| !(viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))),
|
||||
missingDimAttr = (!widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'),
|
||||
toBeParsed = missingViewBox && missingDimAttr,
|
||||
|
|
@ -631,8 +644,8 @@
|
|||
|
||||
var elements = descendants.filter(function(el) {
|
||||
applyViewboxTransform(el);
|
||||
return reAllowedSVGTagNames.test(el.nodeName.replace('svg:', '')) &&
|
||||
!hasAncestorWithNodeName(el, reNotAllowedAncestors); // http://www.w3.org/TR/SVG/struct.html#DefsElement
|
||||
return fabric.svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) &&
|
||||
!hasAncestorWithNodeName(el, fabric.svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement
|
||||
});
|
||||
|
||||
if (!elements || (elements && !elements.length)) {
|
||||
|
|
@ -759,7 +772,7 @@
|
|||
svgUid = element.getAttribute('svgUid');
|
||||
}
|
||||
// if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards
|
||||
if (element.parentNode && reAllowedParents.test(element.parentNode.nodeName)) {
|
||||
if (element.parentNode && fabric.svgValidParentsRegEx.test(element.parentNode.nodeName)) {
|
||||
parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid);
|
||||
}
|
||||
fontSize = (parentAttributes && parentAttributes.fontSize ) ||
|
||||
|
|
@ -787,7 +800,7 @@
|
|||
fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);
|
||||
}
|
||||
var mergedAttrs = extend(parentAttributes, normalizedStyle);
|
||||
return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
|
||||
return fabric.svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -229,6 +229,33 @@
|
|||
return fabric.util.resolveNamespace(namespace)[type];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns array of attributes for given svg that fabric parses
|
||||
* @memberOf fabric.util
|
||||
* @param {String} type Type of svg element (eg. 'circle')
|
||||
* @return {Array} string names of supported attributes
|
||||
*/
|
||||
getSvgAttributes: function(type) {
|
||||
var attributes = [
|
||||
'instantiated_by_use',
|
||||
'style',
|
||||
'id',
|
||||
'class'
|
||||
];
|
||||
switch (type) {
|
||||
case 'linearGradient':
|
||||
attributes = attributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']);
|
||||
break;
|
||||
case 'radialGradient':
|
||||
attributes = attributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']);
|
||||
break;
|
||||
case 'stop':
|
||||
attributes = attributes.concat(['offset', 'stop-color', 'stop-opacity']);
|
||||
break;
|
||||
}
|
||||
return attributes;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns object of given namespace
|
||||
* @memberOf fabric.util
|
||||
|
|
|
|||
Loading…
Reference in a new issue