Update layers panel on programatic call to createLayer.
Add class=“layer” to each layer element. This happens when calling createLayer() or any call to identifyLayers(). This happens with new drawings and when opening legacy drawings, so it’s fully backwards compatible. svg-editor.js elementChanged() looks for g.layer as an addition test for calling populateLayers() which updates the layers panel. Addition tests for class=“layer” added to draw_test.html. Fixed Firefox exception in draw_test.html.master
parent
3ef423e30a
commit
ebcf3d9c47
|
@ -20,6 +20,8 @@ if (!svgedit.draw) {
|
||||||
}
|
}
|
||||||
// alias
|
// alias
|
||||||
var NS = svgedit.NS;
|
var NS = svgedit.NS;
|
||||||
|
var LAYER_CLASS = svgedit.LAYER_CLASS;
|
||||||
|
var LAYER_CLASS_REGEX = svgedit.LAYER_CLASS_REGEX;
|
||||||
|
|
||||||
var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'.split(',');
|
var visElems = 'a,circle,ellipse,foreignObject,g,image,line,path,polygon,polyline,rect,svg,text,tspan,use'.split(',');
|
||||||
|
|
||||||
|
@ -30,6 +32,21 @@ var RandomizeModes = {
|
||||||
};
|
};
|
||||||
var randomize_ids = RandomizeModes.LET_DOCUMENT_DECIDE;
|
var randomize_ids = RandomizeModes.LET_DOCUMENT_DECIDE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add class 'layer' to the element
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param {SVGGElement} elem - The SVG element to update
|
||||||
|
*/
|
||||||
|
function addLayerClass(elem) {
|
||||||
|
var classes = elem.getAttribute('class')
|
||||||
|
if (classes === null || classes === undefined || classes.length === 0) {
|
||||||
|
elem.setAttribute('class', LAYER_CLASS);
|
||||||
|
} else if (! LAYER_CLASS_REGEX.test(classes)) {
|
||||||
|
elem.setAttribute('class', classes + ' ' + LAYER_CLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates the concept of a layer in the drawing
|
* This class encapsulates the concept of a layer in the drawing
|
||||||
* @param {String} name - Layer name
|
* @param {String} name - Layer name
|
||||||
|
@ -386,6 +403,7 @@ svgedit.draw.Drawing.prototype.identifyLayers = function() {
|
||||||
a_layer = child;
|
a_layer = child;
|
||||||
svgedit.utilities.walkTree(child, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
svgedit.utilities.walkTree(child, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
||||||
a_layer.setAttribute("style", "pointer-events:none");
|
a_layer.setAttribute("style", "pointer-events:none");
|
||||||
|
addLayerClass(a_layer)
|
||||||
}
|
}
|
||||||
// if group did not have a name, it is an orphan
|
// if group did not have a name, it is an orphan
|
||||||
else {
|
else {
|
||||||
|
@ -407,22 +425,36 @@ svgedit.draw.Drawing.prototype.identifyLayers = function() {
|
||||||
// TODO(codedread): What about internationalization of "Layer"?
|
// TODO(codedread): What about internationalization of "Layer"?
|
||||||
while (layernames.indexOf(("Layer " + i)) >= 0) { i++; }
|
while (layernames.indexOf(("Layer " + i)) >= 0) { i++; }
|
||||||
var newname = "Layer " + i;
|
var newname = "Layer " + i;
|
||||||
a_layer = svgdoc.createElementNS(NS.SVG, "g");
|
a_layer = this._doCreateLayer(newname);
|
||||||
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
|
||||||
layer_title.textContent = newname;
|
|
||||||
a_layer.appendChild(layer_title);
|
|
||||||
var j;
|
var j;
|
||||||
for (j = 0; j < orphans.length; ++j) {
|
for (j = 0; j < orphans.length; ++j) {
|
||||||
a_layer.appendChild(orphans[j]);
|
a_layer.appendChild(orphans[j]);
|
||||||
}
|
}
|
||||||
this.svgElem_.appendChild(a_layer);
|
this.all_layers.push([newname, a_layer] );
|
||||||
this.all_layers.push( [newname, a_layer] );
|
|
||||||
}
|
}
|
||||||
svgedit.utilities.walkTree(a_layer, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
svgedit.utilities.walkTree(a_layer, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
||||||
this.current_layer = a_layer;
|
this.current_layer = a_layer;
|
||||||
this.current_layer.setAttribute("style", "pointer-events:all");
|
this.current_layer.setAttribute("style", "pointer-events:all");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private function that actually creates a new top-level layer in the drawing
|
||||||
|
* with the given name and sets the current layer to it.
|
||||||
|
* @param {string} name - The given name
|
||||||
|
* @returns {SVGGElement} The SVGGElement of the new layer, which is
|
||||||
|
* also the current layer of this drawing.
|
||||||
|
*/
|
||||||
|
svgedit.draw.Drawing.prototype._doCreateLayer = function(name) {
|
||||||
|
var svgdoc = this.svgElem_.ownerDocument;
|
||||||
|
var new_layer = svgdoc.createElementNS(NS.SVG, "g");
|
||||||
|
addLayerClass(new_layer);
|
||||||
|
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
||||||
|
layer_title.textContent = name;
|
||||||
|
new_layer.appendChild(layer_title);
|
||||||
|
this.svgElem_.appendChild(new_layer);
|
||||||
|
return new_layer;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new top-level layer in the drawing with the given name and
|
* Creates a new top-level layer in the drawing with the given name and
|
||||||
* sets the current layer to it.
|
* sets the current layer to it.
|
||||||
|
@ -431,12 +463,7 @@ svgedit.draw.Drawing.prototype.identifyLayers = function() {
|
||||||
* also the current layer of this drawing.
|
* also the current layer of this drawing.
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.createLayer = function(name) {
|
svgedit.draw.Drawing.prototype.createLayer = function(name) {
|
||||||
var svgdoc = this.svgElem_.ownerDocument;
|
var new_layer = this._doCreateLayer(name);
|
||||||
var new_layer = svgdoc.createElementNS(NS.SVG, "g");
|
|
||||||
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
|
||||||
layer_title.textContent = name;
|
|
||||||
new_layer.appendChild(layer_title);
|
|
||||||
this.svgElem_.appendChild(new_layer);
|
|
||||||
this.identifyLayers();
|
this.identifyLayers();
|
||||||
return new_layer;
|
return new_layer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1835,6 +1835,15 @@ TODOS
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether an element is a layer or not.
|
||||||
|
* @param {SVGGElement} elem - The SVGGElement to test.
|
||||||
|
* @returns {boolean} True if the element is a layer
|
||||||
|
*/
|
||||||
|
function isLayer(elem) {
|
||||||
|
return elem && elem.tagName === 'g' && svgedit.LAYER_CLASS_REGEX.test(elem.getAttribute('class'))
|
||||||
|
}
|
||||||
|
|
||||||
// called when any element has changed
|
// called when any element has changed
|
||||||
var elementChanged = function(win, elems) {
|
var elementChanged = function(win, elems) {
|
||||||
var i,
|
var i,
|
||||||
|
@ -1846,10 +1855,13 @@ TODOS
|
||||||
for (i = 0; i < elems.length; ++i) {
|
for (i = 0; i < elems.length; ++i) {
|
||||||
var elem = elems[i];
|
var elem = elems[i];
|
||||||
|
|
||||||
// if the element changed was the svg, then it could be a resolution change
|
var isSvgElem = (elem && elem.tagName === 'svg');
|
||||||
if (elem && elem.tagName === 'svg') {
|
if (isSvgElem || isLayer(elem)) {
|
||||||
populateLayers();
|
populateLayers();
|
||||||
updateCanvas();
|
// if the element changed was the svg, then it could be a resolution change
|
||||||
|
if (isSvgElem) {
|
||||||
|
updateCanvas();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Update selectedElement if element is no longer part of the image.
|
// Update selectedElement if element is no longer part of the image.
|
||||||
// This occurs for the text elements in Firefox
|
// This occurs for the text elements in Firefox
|
||||||
|
|
|
@ -15,8 +15,10 @@ svgedit = {
|
||||||
XLINK: 'http://www.w3.org/1999/xlink',
|
XLINK: 'http://www.w3.org/1999/xlink',
|
||||||
XML: 'http://www.w3.org/XML/1998/namespace',
|
XML: 'http://www.w3.org/XML/1998/namespace',
|
||||||
XMLNS: 'http://www.w3.org/2000/xmlns/' // see http://www.w3.org/TR/REC-xml-names/#xmlReserved
|
XMLNS: 'http://www.w3.org/2000/xmlns/' // see http://www.w3.org/TR/REC-xml-names/#xmlReserved
|
||||||
}
|
},
|
||||||
|
LAYER_CLASS: 'layer'
|
||||||
};
|
};
|
||||||
|
svgedit.LAYER_CLASS_REGEX = new RegExp('(\\s|^)' + svgedit.LAYER_CLASS + '(\\s|$)');
|
||||||
|
|
||||||
// return the svgedit.NS with key values switched and lowercase
|
// return the svgedit.NS with key values switched and lowercase
|
||||||
svgedit.getReverseNS = function() {'use strict';
|
svgedit.getReverseNS = function() {'use strict';
|
||||||
|
|
|
@ -19,12 +19,16 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var NS = svgedit.NS;
|
var NS = svgedit.NS;
|
||||||
|
var LAYER_CLASS = svgedit.LAYER_CLASS;
|
||||||
var NONCE = 'foo';
|
var NONCE = 'foo';
|
||||||
var LAYER1 = 'Layer 1';
|
var LAYER1 = 'Layer 1';
|
||||||
var LAYER2 = 'Layer 2';
|
var LAYER2 = 'Layer 2';
|
||||||
var LAYER3 = 'Layer 3';
|
var LAYER3 = 'Layer 3';
|
||||||
|
|
||||||
var svg = document.createElementNS(NS.SVG, 'svg');
|
var svg = document.createElementNS(NS.SVG, 'svg');
|
||||||
|
var sandbox = document.getElementById('sandbox');
|
||||||
|
// Firefox throws exception in getBBox() when svg is not attached to DOM.
|
||||||
|
sandbox.appendChild(svg);
|
||||||
|
|
||||||
// Set up <svg> with nonce.
|
// Set up <svg> with nonce.
|
||||||
var svg_n = document.createElementNS(NS.SVG, 'svg');
|
var svg_n = document.createElementNS(NS.SVG, 'svg');
|
||||||
|
@ -244,7 +248,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test identifyLayers() with empty document', function() {
|
test('Test identifyLayers() with empty document', function() {
|
||||||
expect(9);
|
expect(10);
|
||||||
|
|
||||||
var drawing = new svgedit.draw.Drawing(svg);
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
// By default, an empty document gets an empty group created.
|
// By default, an empty document gets an empty group created.
|
||||||
|
@ -260,6 +264,7 @@
|
||||||
ok(empty_layer);
|
ok(empty_layer);
|
||||||
equals(empty_layer, drawing.getSvgElem().firstChild);
|
equals(empty_layer, drawing.getSvgElem().firstChild);
|
||||||
equals(empty_layer.tagName, 'g');
|
equals(empty_layer.tagName, 'g');
|
||||||
|
equals(empty_layer.getAttribute('class'), LAYER_CLASS);
|
||||||
ok(empty_layer.hasChildNodes());
|
ok(empty_layer.hasChildNodes());
|
||||||
equals(empty_layer.childNodes.length, 1);
|
equals(empty_layer.childNodes.length, 1);
|
||||||
var firstChild = empty_layer.childNodes.item(0);
|
var firstChild = empty_layer.childNodes.item(0);
|
||||||
|
@ -269,7 +274,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test identifyLayers() with some layers', function() {
|
test('Test identifyLayers() with some layers', function() {
|
||||||
expect(5);
|
expect(8);
|
||||||
|
|
||||||
var drawing = new svgedit.draw.Drawing(svg);
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
setupSvgWith3Layers(svg);
|
setupSvgWith3Layers(svg);
|
||||||
|
@ -283,11 +288,15 @@
|
||||||
equals(drawing.all_layers[1][1], svg.childNodes.item(1));
|
equals(drawing.all_layers[1][1], svg.childNodes.item(1));
|
||||||
equals(drawing.all_layers[2][1], svg.childNodes.item(2));
|
equals(drawing.all_layers[2][1], svg.childNodes.item(2));
|
||||||
|
|
||||||
|
equals(drawing.all_layers[0][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[1][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[2][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
|
||||||
cleanupSvg(svg);
|
cleanupSvg(svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test identifyLayers() with some layers and orphans', function() {
|
test('Test identifyLayers() with some layers and orphans', function() {
|
||||||
expect(10);
|
expect(14);
|
||||||
|
|
||||||
setupSvgWith3Layers(svg);
|
setupSvgWith3Layers(svg);
|
||||||
|
|
||||||
|
@ -307,6 +316,11 @@
|
||||||
equals(drawing.all_layers[2][1], svg.childNodes.item(2));
|
equals(drawing.all_layers[2][1], svg.childNodes.item(2));
|
||||||
equals(drawing.all_layers[3][1], svg.childNodes.item(3));
|
equals(drawing.all_layers[3][1], svg.childNodes.item(3));
|
||||||
|
|
||||||
|
equals(drawing.all_layers[0][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[1][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[2][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[3][1].getAttribute('class'), LAYER_CLASS);
|
||||||
|
|
||||||
var layer4 = drawing.all_layers[3][1];
|
var layer4 = drawing.all_layers[3][1];
|
||||||
equals(layer4.tagName, 'g');
|
equals(layer4.tagName, 'g');
|
||||||
equals(layer4.childNodes.length, 3);
|
equals(layer4.childNodes.length, 3);
|
||||||
|
@ -367,7 +381,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test createLayer()', function() {
|
test('Test createLayer()', function() {
|
||||||
expect(6);
|
expect(7);
|
||||||
|
|
||||||
var drawing = new svgedit.draw.Drawing(svg);
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
setupSvgWith3Layers(svg);
|
setupSvgWith3Layers(svg);
|
||||||
|
@ -380,6 +394,7 @@
|
||||||
var layer_g = drawing.createLayer(NEW_LAYER_NAME);
|
var layer_g = drawing.createLayer(NEW_LAYER_NAME);
|
||||||
equals(4, drawing.getNumLayers());
|
equals(4, drawing.getNumLayers());
|
||||||
equals(layer_g, drawing.getCurrentLayer());
|
equals(layer_g, drawing.getCurrentLayer());
|
||||||
|
equals(layer_g.getAttribute('class'), LAYER_CLASS);
|
||||||
equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
|
equals(NEW_LAYER_NAME, drawing.getCurrentLayerName());
|
||||||
equals(NEW_LAYER_NAME, drawing.getLayerName(3));
|
equals(NEW_LAYER_NAME, drawing.getLayerName(3));
|
||||||
|
|
||||||
|
@ -530,6 +545,6 @@
|
||||||
<h2 id='qunit-banner'></h2>
|
<h2 id='qunit-banner'></h2>
|
||||||
<h2 id='qunit-userAgent'></h2>
|
<h2 id='qunit-userAgent'></h2>
|
||||||
<ol id='qunit-tests'></ol>
|
<ol id='qunit-tests'></ol>
|
||||||
<div id='anchor' style='visibility:hidden'></div>
|
<div id='sandbox' style='visibility:hidden'></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue