Fix Issue 770: Trouncing the nonce. Restructured how random ids are produced. Updated how new documents are created.
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1962 eee81c28-f429-11dd-99c0-75d572ba1dddmaster
parent
846ee8eca1
commit
9c8ba2361f
|
@ -21,6 +21,9 @@ if (!svgedit.draw) {
|
|||
|
||||
var svg_ns = "http://www.w3.org/2000/svg";
|
||||
var se_ns = "http://svg-edit.googlecode.com";
|
||||
var xmlns_ns = "http://www.w3.org/2000/xmlns/";
|
||||
|
||||
var randomize_ids = false;
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of a layer in the drawing
|
||||
|
@ -41,6 +44,12 @@ svgedit.draw.Layer.prototype.getGroup = function() {
|
|||
};
|
||||
|
||||
|
||||
// Called to ensure that drawings will or will not have
|
||||
// randomized ids.
|
||||
svgedit.draw.randomizeIds = function(enableRandomization) {
|
||||
randomize_ids = enableRandomization;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of a SVG-edit drawing
|
||||
*
|
||||
|
@ -99,7 +108,17 @@ svgedit.draw.Drawing = function(svgElem, opt_idPrefix) {
|
|||
* The nonce to use to uniquely identify elements across drawings.
|
||||
* @type {!String}
|
||||
*/
|
||||
this.nonce_ = this.svgElem_.getAttributeNS(se_ns, 'nonce') || "";
|
||||
this.nonce_ = "";
|
||||
var n = this.svgElem_.getAttributeNS(se_ns, 'nonce');
|
||||
// If already set in the DOM, use the nonce throughout the document
|
||||
// else, if randomizeIds(true) has been called, create and set the nonce.
|
||||
if (!!n) {
|
||||
this.nonce_ = n;
|
||||
} else if (randomize_ids) {
|
||||
this.nonce_ = Math.floor(Math.random() * 100001);
|
||||
this.svgElem_.setAttributeNS(xmlns_ns, 'xmlns:se', se_ns);
|
||||
this.svgElem_.setAttributeNS(se_ns, 'se:nonce', this.nonce_);
|
||||
}
|
||||
};
|
||||
|
||||
svgedit.draw.Drawing.prototype.getElem_ = function(id) {
|
||||
|
|
|
@ -15,8 +15,8 @@ svgEditor.addExtension("Arrows", function(S) {
|
|||
randomize_ids = S.randomize_ids,
|
||||
selElems;
|
||||
|
||||
svgCanvas.bind('setarrownonce', setArrowNonce);
|
||||
svgCanvas.bind('unsetsetarrownonce', unsetArrowNonce);
|
||||
svgCanvas.bind('setnonce', setArrowNonce);
|
||||
svgCanvas.bind('unsetnonce', unsetArrowNonce);
|
||||
|
||||
var lang_list = {
|
||||
"en":[
|
||||
|
|
|
@ -151,17 +151,28 @@ container.appendChild(svgroot);
|
|||
// The actual element that represents the final output SVG element
|
||||
var svgcontent = svgdoc.createElementNS(svgns, "svg");
|
||||
|
||||
$(svgcontent).attr({
|
||||
id: 'svgcontent',
|
||||
width: dimensions[0],
|
||||
height: dimensions[1],
|
||||
x: dimensions[0],
|
||||
y: dimensions[1],
|
||||
overflow: curConfig.show_outside_canvas ? 'visible' : 'hidden',
|
||||
xmlns: svgns,
|
||||
"xmlns:se": se_ns,
|
||||
"xmlns:xlink": xlinkns
|
||||
}).appendTo(svgroot);
|
||||
// This function resets the svgcontent element while keeping it in the DOM.
|
||||
var clearSvgContentElement = canvas.clearSvgContentElement = function() {
|
||||
while (svgcontent.firstChild) { svgcontent.removeChild(svgcontent.firstChild); }
|
||||
|
||||
// TODO: Clear out all other attributes first?
|
||||
$(svgcontent).attr({
|
||||
id: 'svgcontent',
|
||||
width: dimensions[0],
|
||||
height: dimensions[1],
|
||||
x: dimensions[0],
|
||||
y: dimensions[1],
|
||||
overflow: curConfig.show_outside_canvas ? 'visible' : 'hidden',
|
||||
xmlns: svgns,
|
||||
"xmlns:se": se_ns,
|
||||
"xmlns:xlink": xlinkns
|
||||
}).appendTo(svgroot);
|
||||
|
||||
// TODO: make this string optional and set by the client
|
||||
var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ ");
|
||||
svgcontent.appendChild(comment);
|
||||
};
|
||||
clearSvgContentElement();
|
||||
|
||||
// Prefix string for element IDs
|
||||
var idprefix = "svg_";
|
||||
|
@ -175,24 +186,15 @@ canvas.setIdPrefix = function(p) {
|
|||
idprefix = p;
|
||||
};
|
||||
|
||||
// nonce to uniquify id's
|
||||
var nonce = Math.floor(Math.random() * 100001);
|
||||
|
||||
// Boolean to indicate whether or not IDs given to elements should be random
|
||||
var randomize_ids = false;
|
||||
|
||||
// Set nonce if randomize_ids = true
|
||||
if (randomize_ids) svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce);
|
||||
|
||||
// Current svgedit.draw.Drawing object
|
||||
// @type {svgedit.draw.Drawing}
|
||||
var current_drawing = new svgedit.draw.Drawing(svgcontent, idprefix);
|
||||
canvas.current_drawing_ = new svgedit.draw.Drawing(svgcontent, idprefix);
|
||||
|
||||
// Function: getCurrentDrawing
|
||||
// Returns the current Drawing.
|
||||
// @return {svgedit.draw.Drawing}
|
||||
var getCurrentDrawing = canvas.getCurrentDrawing = function() {
|
||||
return current_drawing;
|
||||
return canvas.current_drawing_;
|
||||
};
|
||||
|
||||
// Float displaying the current zoom level (1 = 100%, .5 = 50%, etc)
|
||||
|
@ -524,10 +526,6 @@ var restoreRefElems = function(elem) {
|
|||
};
|
||||
|
||||
(function() {
|
||||
// TODO: make this string optional and set by the client
|
||||
var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ ");
|
||||
svgcontent.appendChild(comment);
|
||||
|
||||
// TODO For Issue 208: this is a start on a thumbnail
|
||||
// var svgthumb = svgdoc.createElementNS(svgns, "use");
|
||||
// svgthumb.setAttribute('width', '100');
|
||||
|
@ -624,7 +622,7 @@ this.addExtension = function(name, ext_func) {
|
|||
var ext = ext_func($.extend(canvas.getPrivateMethods(), {
|
||||
svgroot: svgroot,
|
||||
svgcontent: svgcontent,
|
||||
nonce: nonce,
|
||||
nonce: getCurrentDrawing().getNonce(),
|
||||
selectorManager: selectorManager
|
||||
}));
|
||||
} else {
|
||||
|
@ -6346,9 +6344,9 @@ this.getSvgString = function() {
|
|||
return this.svgCanvasToString();
|
||||
};
|
||||
|
||||
//function randomizeIds
|
||||
// This function determines whether to add a nonce to the prefix, when
|
||||
// generating IDs in SVG-Edit
|
||||
// Function: randomizeIds
|
||||
// This function determines whether to use a nonce in the prefix, when
|
||||
// generating IDs for future documents in SVG-Edit.
|
||||
//
|
||||
// Parameters:
|
||||
// an opional boolean, which, if true, adds a nonce to the prefix. Thus
|
||||
|
@ -6358,17 +6356,12 @@ this.getSvgString = function() {
|
|||
// this BEFORE calling svgCanvas.setSvgString
|
||||
//
|
||||
this.randomizeIds = function() {
|
||||
if (arguments.length > 0 && arguments[0] == false) {
|
||||
randomize_ids = false;
|
||||
if (extensions["Arrows"]) call("unsetarrownonce") ;
|
||||
} else {
|
||||
randomize_ids = true;
|
||||
if (!svgcontent.getAttributeNS(se_ns, 'nonce')) {
|
||||
svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce);
|
||||
if (extensions["Arrows"]) call("setarrownonce", nonce) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arguments.length > 0 && arguments[0] == false) {
|
||||
svgedit.draw.randomizeIds(false);
|
||||
} else {
|
||||
svgedit.draw.randomizeIds(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Function: uniquifyElems
|
||||
// Ensure each element has a unique ID
|
||||
|
@ -6701,19 +6694,15 @@ this.setSvgString = function(xmlString) {
|
|||
|
||||
var content = $(svgcontent);
|
||||
|
||||
// retrieve or set the nonce
|
||||
n = svgcontent.getAttributeNS(se_ns, 'nonce');
|
||||
if (n) {
|
||||
randomize_ids = true;
|
||||
nonce = n;
|
||||
if (extensions["Arrows"]) call("setarrownonce", n) ;
|
||||
} else if (randomize_ids) {
|
||||
svgcontent.setAttributeNS(xmlnsns, 'xmlns:se', se_ns);
|
||||
svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce);
|
||||
if (extensions["Arrows"]) call("setarrownonce", nonce) ;
|
||||
}
|
||||
canvas.current_drawing_ = new svgedit.draw.Drawing(svgcontent, idprefix);
|
||||
|
||||
current_drawing = new svgedit.draw.Drawing(svgcontent, idprefix);
|
||||
// retrieve or set the nonce
|
||||
var nonce = getCurrentDrawing().getNonce();
|
||||
if (nonce) {
|
||||
call("setnonce", nonce);
|
||||
} else {
|
||||
call("unsetnonce");
|
||||
}
|
||||
|
||||
// change image href vals if possible
|
||||
content.find('image').each(function() {
|
||||
|
@ -7038,10 +7027,10 @@ this.cloneLayer = function(name) {
|
|||
// Deletes the current layer from the drawing and then clears the selection. This function
|
||||
// then calls the 'changed' handler. This is an undoable action.
|
||||
this.deleteCurrentLayer = function() {
|
||||
var current_layer = current_drawing.getCurrentLayer();
|
||||
var current_layer = getCurrentDrawing().getCurrentLayer();
|
||||
var nextSibling = current_layer.nextSibling;
|
||||
var parent = current_layer.parentNode;
|
||||
current_layer = current_drawing.deleteCurrentLayer();
|
||||
current_layer = getCurrentDrawing().deleteCurrentLayer();
|
||||
if (current_layer) {
|
||||
var batchCmd = new BatchCommand("Delete Layer");
|
||||
// store in our Undo History
|
||||
|
@ -7082,18 +7071,19 @@ this.setCurrentLayer = function(name) {
|
|||
// Returns:
|
||||
// true if the rename succeeded, false otherwise.
|
||||
this.renameCurrentLayer = function(newname) {
|
||||
if (current_drawing.current_layer) {
|
||||
var oldLayer = current_drawing.current_layer;
|
||||
var drawing = getCurrentDrawing();
|
||||
if (drawing.current_layer) {
|
||||
var oldLayer = drawing.current_layer;
|
||||
// setCurrentLayer will return false if the name doesn't already exist
|
||||
// this means we are free to rename our oldLayer
|
||||
if (!canvas.setCurrentLayer(newname)) {
|
||||
var batchCmd = new BatchCommand("Rename Layer");
|
||||
// find the index of the layer
|
||||
for (var i = 0; i < current_drawing.getNumLayers(); ++i) {
|
||||
if (current_drawing.all_layers[i][1] == oldLayer) break;
|
||||
for (var i = 0; i < drawing.getNumLayers(); ++i) {
|
||||
if (drawing.all_layers[i][1] == oldLayer) break;
|
||||
}
|
||||
var oldname = current_drawing.getLayerName(i);
|
||||
current_drawing.all_layers[i][0] = svgedit.utilities.toXml(newname);
|
||||
var oldname = drawing.getLayerName(i);
|
||||
drawing.all_layers[i][0] = svgedit.utilities.toXml(newname);
|
||||
|
||||
// now change the underlying title element contents
|
||||
var len = oldLayer.childNodes.length;
|
||||
|
@ -7112,7 +7102,7 @@ this.renameCurrentLayer = function(newname) {
|
|||
}
|
||||
}
|
||||
}
|
||||
current_drawing.current_layer = oldLayer;
|
||||
drawing.current_layer = oldLayer;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
@ -7129,31 +7119,32 @@ this.renameCurrentLayer = function(newname) {
|
|||
// Returns:
|
||||
// true if the current layer position was changed, false otherwise.
|
||||
this.setCurrentLayerPosition = function(newpos) {
|
||||
if (current_drawing.current_layer && newpos >= 0 && newpos < current_drawing.getNumLayers()) {
|
||||
for (var oldpos = 0; oldpos < current_drawing.getNumLayers(); ++oldpos) {
|
||||
if (current_drawing.all_layers[oldpos][1] == current_drawing.current_layer) break;
|
||||
var drawing = getCurrentDrawing();
|
||||
if (drawing.current_layer && newpos >= 0 && newpos < drawing.getNumLayers()) {
|
||||
for (var oldpos = 0; oldpos < drawing.getNumLayers(); ++oldpos) {
|
||||
if (drawing.all_layers[oldpos][1] == drawing.current_layer) break;
|
||||
}
|
||||
// some unknown error condition (current_layer not in all_layers)
|
||||
if (oldpos == current_drawing.getNumLayers()) { return false; }
|
||||
if (oldpos == drawing.getNumLayers()) { return false; }
|
||||
|
||||
if (oldpos != newpos) {
|
||||
// if our new position is below us, we need to insert before the node after newpos
|
||||
var refLayer = null;
|
||||
var oldNextSibling = current_drawing.current_layer.nextSibling;
|
||||
var oldNextSibling = drawing.current_layer.nextSibling;
|
||||
if (newpos > oldpos ) {
|
||||
if (newpos < current_drawing.getNumLayers()-1) {
|
||||
refLayer = current_drawing.all_layers[newpos+1][1];
|
||||
if (newpos < drawing.getNumLayers()-1) {
|
||||
refLayer = drawing.all_layers[newpos+1][1];
|
||||
}
|
||||
}
|
||||
// if our new position is above us, we need to insert before the node at newpos
|
||||
else {
|
||||
refLayer = current_drawing.all_layers[newpos][1];
|
||||
refLayer = drawing.all_layers[newpos][1];
|
||||
}
|
||||
svgcontent.insertBefore(current_drawing.current_layer, refLayer);
|
||||
addCommandToHistory(new MoveElementCommand(current_drawing.current_layer, oldNextSibling, svgcontent));
|
||||
svgcontent.insertBefore(drawing.current_layer, refLayer);
|
||||
addCommandToHistory(new MoveElementCommand(drawing.current_layer, oldNextSibling, svgcontent));
|
||||
|
||||
identifyLayers();
|
||||
canvas.setCurrentLayer(current_drawing.getLayerName(newpos));
|
||||
canvas.setCurrentLayer(drawing.getLayerName(newpos));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -7203,9 +7194,10 @@ this.setLayerVisibility = function(layername, bVisible) {
|
|||
this.moveSelectedToLayer = function(layername) {
|
||||
// find the layer
|
||||
var layer = null;
|
||||
for (var i = 0; i < current_drawing.getNumLayers(); ++i) {
|
||||
if (current_drawing.getLayerName(i) == layername) {
|
||||
layer = current_drawing.all_layers[i][1];
|
||||
var drawing = getCurrentDrawing();
|
||||
for (var i = 0; i < drawing.getNumLayers(); ++i) {
|
||||
if (drawing.getLayerName(i) == layername) {
|
||||
layer = drawing.all_layers[i][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7233,28 +7225,29 @@ this.moveSelectedToLayer = function(layername) {
|
|||
|
||||
this.mergeLayer = function(skipHistory) {
|
||||
var batchCmd = new BatchCommand("Merge Layer");
|
||||
var prev = $(current_drawing.current_layer).prev()[0];
|
||||
var drawing = getCurrentDrawing();
|
||||
var prev = $(drawing.current_layer).prev()[0];
|
||||
if(!prev) return;
|
||||
var childs = current_drawing.current_layer.childNodes;
|
||||
var childs = drawing.current_layer.childNodes;
|
||||
var len = childs.length;
|
||||
var layerNextSibling = current_drawing.current_layer.nextSibling;
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(current_drawing.current_layer, layerNextSibling, svgcontent));
|
||||
var layerNextSibling = drawing.current_layer.nextSibling;
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(drawing.current_layer, layerNextSibling, svgcontent));
|
||||
|
||||
while(current_drawing.current_layer.firstChild) {
|
||||
var ch = current_drawing.current_layer.firstChild;
|
||||
while(drawing.current_layer.firstChild) {
|
||||
var ch = drawing.current_layer.firstChild;
|
||||
if(ch.localName == 'title') {
|
||||
var chNextSibling = ch.nextSibling;
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(ch, chNextSibling, current_drawing.current_layer));
|
||||
current_drawing.current_layer.removeChild(ch);
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(ch, chNextSibling, drawing.current_layer));
|
||||
drawing.current_layer.removeChild(ch);
|
||||
continue;
|
||||
}
|
||||
var oldNextSibling = ch.nextSibling;
|
||||
prev.appendChild(ch);
|
||||
batchCmd.addSubCommand(new MoveElementCommand(ch, oldNextSibling, current_drawing.current_layer));
|
||||
batchCmd.addSubCommand(new MoveElementCommand(ch, oldNextSibling, drawing.current_layer));
|
||||
}
|
||||
|
||||
// Remove current layer
|
||||
svgcontent.removeChild(current_drawing.current_layer);
|
||||
svgcontent.removeChild(drawing.current_layer);
|
||||
|
||||
if(!skipHistory) {
|
||||
clearSelection();
|
||||
|
@ -7265,13 +7258,14 @@ this.mergeLayer = function(skipHistory) {
|
|||
addCommandToHistory(batchCmd);
|
||||
}
|
||||
|
||||
current_drawing.current_layer = prev;
|
||||
drawing.current_layer = prev;
|
||||
return batchCmd;
|
||||
}
|
||||
|
||||
this.mergeAllLayers = function() {
|
||||
var batchCmd = new BatchCommand("Merge all Layers");
|
||||
current_drawing.current_layer = current_drawing.all_layers[current_drawing.getNumLayers()-1][1];
|
||||
var drawing = getCurrentDrawing();
|
||||
drawing.current_layer = drawing.all_layers[drawing.getNumLayers()-1][1];
|
||||
while($(svgcontent).children('g').length > 1) {
|
||||
batchCmd.addSubCommand(canvas.mergeLayer(true));
|
||||
}
|
||||
|
@ -7339,28 +7333,23 @@ this.clear = function() {
|
|||
pathActions.clear();
|
||||
|
||||
// clear the svgcontent node
|
||||
var nodes = svgcontent.childNodes;
|
||||
var len = svgcontent.childNodes.length;
|
||||
var i = 0;
|
||||
clearSelection();
|
||||
for(var rep = 0; rep < len; rep++){
|
||||
if (nodes[i].nodeType == 1) { // element node
|
||||
svgcontent.removeChild(nodes[i]);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// create empty first layer
|
||||
current_drawing.all_layers = [];
|
||||
canvas.clearSvgContentElement();
|
||||
|
||||
// create new document
|
||||
canvas.current_drawing_ = new svgedit.draw.Drawing(svgcontent);
|
||||
|
||||
// create empty first layer
|
||||
canvas.createLayer("Layer 1");
|
||||
|
||||
// clear the undo stack
|
||||
canvas.undoMgr.resetUndoStack();
|
||||
|
||||
// reset the selector manager
|
||||
selectorManager.initGroup();
|
||||
|
||||
// reset the rubber band box
|
||||
rubberBox = selectorManager.getRubberBandBox();
|
||||
|
||||
call("cleared");
|
||||
};
|
||||
|
||||
|
|
|
@ -480,6 +480,18 @@
|
|||
equals(drawing.getCurrentLayer(), drawing.all_layers[1][1]);
|
||||
});
|
||||
|
||||
test('Test svgedit.draw.randomizeIds()', function() {
|
||||
expect(2);
|
||||
|
||||
svgedit.draw.randomizeIds(true);
|
||||
var drawing = new svgedit.draw.Drawing(svg.cloneNode(true));
|
||||
ok(!!drawing.getNonce());
|
||||
|
||||
svgedit.draw.randomizeIds(false);
|
||||
var drawing = new svgedit.draw.Drawing(svg);
|
||||
ok(!drawing.getNonce());
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
|
Loading…
Reference in New Issue