Merge branch 'master' of https://github.com/SVG-Edit/svgedit into issues/544
commit
103c4f590d
|
@ -25,19 +25,20 @@ const svgWhiteList_ = {
|
||||||
a: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'xlink:href', 'xlink:title' ],
|
a: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'xlink:href', 'xlink:title' ],
|
||||||
circle: [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
circle: [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'r', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||||
clipPath: [ 'class', 'clipPathUnits', 'id' ],
|
clipPath: [ 'class', 'clipPathUnits', 'id' ],
|
||||||
defs: [],
|
defs: [ 'id' ],
|
||||||
style: [ 'type' ],
|
style: [ 'id', 'type' ],
|
||||||
desc: [],
|
desc: [],
|
||||||
ellipse: [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
ellipse: [ 'class', 'clip-path', 'clip-rule', 'cx', 'cy', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform' ],
|
||||||
feBlend: [ 'in', 'in2' ],
|
feBlend: [ 'in', 'in2' ],
|
||||||
feComposite: [ 'operator', 'result', 'in2' ],
|
feColorMatrix: [ 'in', 'type', 'value', 'result', 'values', 'id' ],
|
||||||
feFlood: [ 'flood-color', 'in' ],
|
feComposite: [ 'in', 'id', 'operator', 'result', 'in2' ],
|
||||||
feGaussianBlur: [ 'class', 'color-interpolation-filters', 'id', 'requiredFeatures', 'stdDeviation' ],
|
feFlood: [ 'flood-color', 'in', 'id', 'result', 'flood-opacity' ],
|
||||||
|
feGaussianBlur: [ 'class', 'color-interpolation-filters', 'id', 'in', 'requiredFeatures', 'stdDeviation', 'result' ],
|
||||||
feMerge: [],
|
feMerge: [],
|
||||||
feMergeNode: [ 'in' ],
|
feMergeNode: [ 'in' ],
|
||||||
feMorphology: [ 'class', 'in', 'operator', 'radius' ],
|
feMorphology: [ 'class', 'in', 'operator', 'radius' ],
|
||||||
feOffset: [ 'dx', 'in', 'dy', 'result' ],
|
feOffset: [ 'dx', 'id', 'in', 'dy', 'result' ],
|
||||||
filter: [ 'class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'width', 'x', 'xlink:href', 'y' ],
|
filter: [ 'class', 'color-interpolation-filters', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'requiredFeatures', 'style', 'width', 'x', 'xlink:href', 'y' ],
|
||||||
foreignObject: [ 'class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y' ],
|
foreignObject: [ 'class', 'font-size', 'height', 'id', 'opacity', 'requiredFeatures', 'style', 'transform', 'width', 'x', 'y' ],
|
||||||
g: [ 'class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor' ],
|
g: [ 'class', 'clip-path', 'clip-rule', 'id', 'display', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'font-family', 'font-size', 'font-style', 'font-weight', 'text-anchor' ],
|
||||||
image: [ 'class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y' ],
|
image: [ 'class', 'clip-path', 'clip-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:href', 'xlink:title', 'y' ],
|
||||||
|
@ -53,7 +54,7 @@ const svgWhiteList_ = {
|
||||||
radialGradient: [ 'class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href' ],
|
radialGradient: [ 'class', 'cx', 'cy', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'requiredFeatures', 'spreadMethod', 'systemLanguage', 'xlink:href' ],
|
||||||
rect: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y' ],
|
rect: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'height', 'id', 'mask', 'opacity', 'requiredFeatures', 'rx', 'ry', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'width', 'x', 'y' ],
|
||||||
stop: [ 'class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage' ],
|
stop: [ 'class', 'id', 'offset', 'requiredFeatures', 'stop-color', 'stop-opacity', 'style', 'systemLanguage' ],
|
||||||
svg: [ 'class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'xmlns:oi', 'oi:animations', 'y' ],
|
svg: [ 'class', 'clip-path', 'clip-rule', 'filter', 'id', 'height', 'mask', 'preserveAspectRatio', 'requiredFeatures', 'style', 'systemLanguage', 'version', 'viewBox', 'width', 'x', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'xmlns:oi', 'oi:animations', 'y' ],
|
||||||
switch: [ 'class', 'id', 'requiredFeatures', 'systemLanguage' ],
|
switch: [ 'class', 'id', 'requiredFeatures', 'systemLanguage' ],
|
||||||
symbol: [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox' ],
|
symbol: [ 'class', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'opacity', 'preserveAspectRatio', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'transform', 'viewBox' ],
|
||||||
text: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y' ],
|
text: [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'font-family', 'font-size', 'font-style', 'font-weight', 'id', 'mask', 'opacity', 'requiredFeatures', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemLanguage', 'text-anchor', 'transform', 'x', 'xml:space', 'y' ],
|
||||||
|
@ -123,7 +124,7 @@ export const sanitizeSvg = function (node) {
|
||||||
// Cleanup text nodes
|
// Cleanup text nodes
|
||||||
if (node.nodeType === 3) { // 3 === TEXT_NODE
|
if (node.nodeType === 3) { // 3 === TEXT_NODE
|
||||||
// Trim whitespace
|
// Trim whitespace
|
||||||
node.nodeValue = node.nodeValue.replace(/^\s+|\s+$/g, '');
|
node.nodeValue = node.nodeValue.trim();
|
||||||
// Remove if empty
|
// Remove if empty
|
||||||
if (!node.nodeValue.length) {
|
if (!node.nodeValue.length) {
|
||||||
node.remove();
|
node.remove();
|
||||||
|
@ -151,7 +152,6 @@ export const sanitizeSvg = function (node) {
|
||||||
let i = node.attributes.length;
|
let i = node.attributes.length;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
// if the attribute is not in our whitelist, then remove it
|
// if the attribute is not in our whitelist, then remove it
|
||||||
// could use jQuery's inArray(), but I don't know if that's any better
|
|
||||||
const attr = node.attributes.item(i);
|
const attr = node.attributes.item(i);
|
||||||
const attrName = attr.nodeName;
|
const attrName = attr.nodeName;
|
||||||
const attrLocalName = attr.localName;
|
const attrLocalName = attr.localName;
|
||||||
|
@ -162,12 +162,12 @@ export const sanitizeSvg = function (node) {
|
||||||
attrNsURI === allowedAttrsNS[attrLocalName] && attrNsURI !== NS.XMLNS
|
attrNsURI === allowedAttrsNS[attrLocalName] && attrNsURI !== NS.XMLNS
|
||||||
) &&
|
) &&
|
||||||
!(attrNsURI === NS.XMLNS && REVERSE_NS[attr.value])) {
|
!(attrNsURI === NS.XMLNS && REVERSE_NS[attr.value])) {
|
||||||
// TODO(codedread): Programmatically add the se: attributes to the NS-aware whitelist.
|
|
||||||
// Bypassing the whitelist to allow se: prefixes.
|
// Bypassing the whitelist to allow se: prefixes.
|
||||||
// Is there a more appropriate way to do this?
|
// Is there a more appropriate way to do this?
|
||||||
if (attrName.startsWith('se:') || attrName.startsWith('data-')) {
|
if (attrName.startsWith('se:') || attrName.startsWith('data-')) {
|
||||||
seAttrs.push([ attrName, attr.value ]);
|
seAttrs.push([ attrName, attr.value ]);
|
||||||
}
|
}
|
||||||
|
console.warn(`sanitizeSvg: attribute ${attrName} in element ${node.nodeName} not in whitelist is removed`);
|
||||||
node.removeAttributeNS(attrNsURI, attrLocalName);
|
node.removeAttributeNS(attrNsURI, attrLocalName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,11 +214,13 @@ export const sanitizeSvg = function (node) {
|
||||||
'radialGradient', 'textPath', 'use' ].includes(node.nodeName) && href[0] !== '#') {
|
'radialGradient', 'textPath', 'use' ].includes(node.nodeName) && href[0] !== '#') {
|
||||||
// remove the attribute (but keep the element)
|
// remove the attribute (but keep the element)
|
||||||
setHref(node, '');
|
setHref(node, '');
|
||||||
|
console.warn(`sanitizeSvg: attribute href in element ${node.nodeName} pointing to a non-local reference (${href}) is removed`);
|
||||||
node.removeAttributeNS(NS.XLINK, 'href');
|
node.removeAttributeNS(NS.XLINK, 'href');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safari crashes on a <use> without a xlink:href, so we just remove the node here
|
// Safari crashes on a <use> without a xlink:href, so we just remove the node here
|
||||||
if (node.nodeName === 'use' && !getHref(node)) {
|
if (node.nodeName === 'use' && !getHref(node)) {
|
||||||
|
console.warn(`sanitizeSvg: element ${node.nodeName} without a xlink:href is removed`);
|
||||||
node.remove();
|
node.remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -231,6 +233,7 @@ export const sanitizeSvg = function (node) {
|
||||||
// simply check for first character being a '#'
|
// simply check for first character being a '#'
|
||||||
if (val && val[0] !== '#') {
|
if (val && val[0] !== '#') {
|
||||||
node.setAttribute(attr, '');
|
node.setAttribute(attr, '');
|
||||||
|
console.warn(`sanitizeSvg: attribute ${attr} in element ${node.nodeName} pointing to a non-local reference (${val}) is removed`);
|
||||||
node.removeAttribute(attr);
|
node.removeAttribute(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,6 +246,7 @@ export const sanitizeSvg = function (node) {
|
||||||
} else {
|
} else {
|
||||||
// remove all children from this node and insert them before this node
|
// remove all children from this node and insert them before this node
|
||||||
// TODO: in the case of animation elements this will hardly ever be correct
|
// TODO: in the case of animation elements this will hardly ever be correct
|
||||||
|
console.warn(`sanitizeSvg: element ${node.nodeName} not supported is removed`);
|
||||||
const children = [];
|
const children = [];
|
||||||
while (node.hasChildNodes()) {
|
while (node.hasChildNodes()) {
|
||||||
children.push(parent.insertBefore(node.firstChild, node));
|
children.push(parent.insertBefore(node.firstChild, node));
|
||||||
|
|
|
@ -162,21 +162,10 @@ export const getMouseTargetMethod = function (evt) {
|
||||||
return selectionContext_.getCanvas().selectorManager.selectorParentGroup;
|
return selectionContext_.getCanvas().selectorManager.selectorParentGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!mouseTarget.parentNode.isSameNode(selectionContext_.getCurrentGroup() || currentLayer)) {
|
while (!mouseTarget.parentNode?.isSameNode(selectionContext_.getCurrentGroup() || currentLayer)) {
|
||||||
mouseTarget = mouseTarget.parentNode;
|
mouseTarget = mouseTarget.parentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// // go up until we hit a child of a layer
|
|
||||||
// while (mouseTarget.parentNode.parentNode.tagName == 'g') {
|
|
||||||
// mouseTarget = mouseTarget.parentNode;
|
|
||||||
// }
|
|
||||||
// Webkit bubbles the mouse event all the way up to the div, so we
|
|
||||||
// set the mouseTarget to the svgroot like the other browsers
|
|
||||||
// if (mouseTarget.nodeName.toLowerCase() == 'div') {
|
|
||||||
// mouseTarget = svgroot;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return mouseTarget;
|
return mouseTarget;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue