Uniquify IDs in SVG-Edit

Since we can have several SVG-Edit graphics
on a page, SVG-Edit should assign unique IDs
to elements, and do so in a fashion that survives
re-editing.

To do this, we use a nonce, and record its value in
a custom se:nonce attribute on the <svg> element.
(Is there a better way?). 

Also, preserve the custom se:connector attribute for
later editing purposes.
This commit is contained in:
Jacques Distler 2010-02-25 02:25:16 -06:00
parent c4003f79b3
commit aa0a151ba4
4 changed files with 34 additions and 8 deletions

View file

@ -60,7 +60,7 @@ module Sanitizer
patternContentUnits patternTransform patternUnits points patternContentUnits patternTransform patternUnits points
preserveAspectRatio primitiveUnits r refX refY repeatCount repeatDur preserveAspectRatio primitiveUnits r refX refY repeatCount repeatDur
requiredExtensions requiredFeatures restart rotate rx ry se:connector requiredExtensions requiredFeatures restart rotate rx ry se:connector
slope spacing se:nonce slope spacing
startOffset stdDeviation stemh stemv stop-color stop-opacity startOffset stdDeviation stemh stemv stop-color stop-opacity
strikethrough-position strikethrough-thickness stroke stroke-dasharray strikethrough-position strikethrough-thickness stroke stroke-dasharray
stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit

View file

@ -12,8 +12,11 @@ $(function() {
svgCanvas.addExtension("Arrows", function(S) { svgCanvas.addExtension("Arrows", function(S) {
var svgcontent = S.svgcontent, var svgcontent = S.svgcontent,
addElem = S.addSvgElementFromJson, addElem = S.addSvgElementFromJson,
nonce = S.nonce,
selElems; selElems;
svgCanvas.bind('setarrownonce', setArrowNonce);
var lang_list = { var lang_list = {
"en":[ "en":[
{"id": "arrow_none", "textContent": "No arrow" } {"id": "arrow_none", "textContent": "No arrow" }
@ -23,10 +26,20 @@ $(function() {
] ]
}; };
var prefix = 'se_arrow_';
var arrowprefix = prefix + nonce + '_';
var pathdata = { var pathdata = {
fw: {d:"m0,0l10,5l-10,5l5,-5l-5,-5z", refx:8, id:"se_arrow_fw"}, fw: {d:"m0,0l10,5l-10,5l5,-5l-5,-5z", refx:8, id: arrowprefix + 'fw'},
bk: {d:"m10,0l-10,5l10,5l-5,-5l5,-5z", refx:2, id:"se_arrow_bk"} bk: {d:"m10,0l-10,5l10,5l-5,-5l5,-5z", refx:2, id: arrowprefix + 'bk'}
} }
function setArrowNonce(window, n) {
arrowprefix = prefix + n + '_';
pathdata.fw.id = arrowprefix + 'fw';
pathdata.bk.id = arrowprefix + 'bk';
}
function getLinked(elem, attr) { function getLinked(elem, attr) {
var str = elem.getAttribute(attr); var str = elem.getAttribute(attr);
if(!str) return null; if(!str) return null;
@ -77,7 +90,7 @@ $(function() {
function addMarker(dir, type, id) { function addMarker(dir, type, id) {
// TODO: Make marker (or use?) per arrow type, since refX can be different // TODO: Make marker (or use?) per arrow type, since refX can be different
id = id || 'se_arrow_' + dir; id = id || arrowprefix + dir;
var marker = S.getElem(id); var marker = S.getElem(id);
@ -174,7 +187,7 @@ $(function() {
var last_id = marker.id; var last_id = marker.id;
var dir = last_id.indexOf('_fw') !== -1?'fw':'bk'; var dir = last_id.indexOf('_fw') !== -1?'fw':'bk';
new_marker = addMarker(dir, type, 'se_arrow_' + dir + all_markers.length); new_marker = addMarker(dir, type, arrowprefix + dir + all_markers.length);
$(new_marker).children().attr('fill', color); $(new_marker).children().attr('fill', color);
} }

View file

@ -78,8 +78,6 @@ $(function() {
mrow.appendChild(children[0]); mrow.appendChild(children[0]);
} }
S.sanitizeSvg(math); S.sanitizeSvg(math);
//elt.setAttribute('width', math.clientWidth+5);
//elt.setAttribute('height', math.clientHeight+5);
S.call("changed", [elt]); S.call("changed", [elt]);
}); });
elt.replaceChild(math, elt.firstChild); elt.replaceChild(math, elt.firstChild);

View file

@ -943,6 +943,9 @@ function BatchCommand(text) {
$(svgroot).appendTo(container); $(svgroot).appendTo(container);
//nonce to uniquify id's
var nonce = Math.floor(Math.random()*100001);
// map namespace URIs to prefixes // map namespace URIs to prefixes
var nsMap = {}; var nsMap = {};
nsMap[xlinkns] = 'xlink'; nsMap[xlinkns] = 'xlink';
@ -982,6 +985,8 @@ function BatchCommand(text) {
y: 480, y: 480,
overflow: 'visible', overflow: 'visible',
xmlns: svgns, xmlns: svgns,
"xmlns:se": se_ns,
"se:nonce": nonce,
"xmlns:xlink": xlinkns "xmlns:xlink": xlinkns
}).appendTo(svgroot); }).appendTo(svgroot);
@ -1284,7 +1289,7 @@ function BatchCommand(text) {
// private functions // private functions
var getId = function() { var getId = function() {
if (events["getid"]) return call("getid", obj_num); if (events["getid"]) return call("getid", obj_num);
return idprefix + obj_num; return idprefix + nonce +'_' + obj_num;
}; };
var getNextId = function() { var getNextId = function() {
@ -5602,6 +5607,15 @@ function BatchCommand(text) {
// set new svg document // set new svg document
svgcontent = svgroot.appendChild(svgdoc.importNode(newDoc.documentElement, true)); svgcontent = svgroot.appendChild(svgdoc.importNode(newDoc.documentElement, true));
// retrieve or set the nonce
n = svgcontent.getAttributeNS(se_ns, 'nonce');
if (n) {
nonce = n;
if (extensions["Arrows"]) call("setarrownonce", n) ;
} else {
svgcontent.setAttributeNS(xmlnsns, 'xml:se', se_ns);
svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce);
}
// change image href vals if possible // change image href vals if possible
$(svgcontent).find('image').each(function() { $(svgcontent).find('image').each(function() {
var image = this; var image = this;
@ -8049,6 +8063,7 @@ function BatchCommand(text) {
var ext = ext_func($.extend(canvas.getPrivateMethods(), { var ext = ext_func($.extend(canvas.getPrivateMethods(), {
svgroot: svgroot, svgroot: svgroot,
svgcontent: svgcontent, svgcontent: svgcontent,
nonce: nonce,
selectorManager: selectorManager selectorManager: selectorManager
})); }));
extensions[name] = ext; extensions[name] = ext;