Merge pull request #106 from gec/createLayerFix
Update layers panel on programatic call to createLayer.master
commit
b985a062c0
358
editor/draw.js
358
editor/draw.js
|
@ -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(',');
|
||||||
|
|
||||||
|
@ -31,31 +33,150 @@ var RandomizeModes = {
|
||||||
var randomize_ids = RandomizeModes.LET_DOCUMENT_DECIDE;
|
var randomize_ids = RandomizeModes.LET_DOCUMENT_DECIDE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates the concept of a layer in the drawing
|
* Add class 'layer' to the element
|
||||||
* @param {String} name - Layer name
|
*
|
||||||
* @param {SVGGElement} child - Layer SVG group.
|
* Parameters:
|
||||||
|
* @param {SVGGElement} elem - The SVG element to update
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Layer = function(name, group) {
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createLayer(name, svgElem) {
|
||||||
|
if (!svgElem) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
var svgdoc = svgElem.ownerDocument;
|
||||||
|
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);
|
||||||
|
svgElem.appendChild(new_layer);
|
||||||
|
return new_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class encapsulates the concept of a layer in the drawing. It can be constructed with
|
||||||
|
* an existing group element or, with three parameters, will create a new layer group element.
|
||||||
|
* @param {string} name - Layer name
|
||||||
|
* @param {SVGGElement} group - SVG group element that constitutes the layer or null if a group should be created and added to the DOM..
|
||||||
|
* @param {SVGGElement} svgElem - The SVG DOM element. If defined, use this to add
|
||||||
|
* a new layer to the document.
|
||||||
|
*/
|
||||||
|
var Layer = svgedit.draw.Layer = function(name, group, svgElem) {
|
||||||
this.name_ = name;
|
this.name_ = name;
|
||||||
this.group_ = group;
|
this.group_ = group || createLayer(name, svgElem);
|
||||||
|
|
||||||
|
addLayerClass(this.group_);
|
||||||
|
svgedit.utilities.walkTree(this.group_, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
||||||
|
|
||||||
|
this.group_.setAttribute("style", svgElem ? "pointer-events:all" : "pointer-events:none");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the layer's name.
|
||||||
* @returns {string} The layer name
|
* @returns {string} The layer name
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Layer.prototype.getName = function() {
|
Layer.prototype.getName = function() {
|
||||||
return this.name_;
|
return this.name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get the group element for this layer.
|
||||||
* @returns {SVGGElement} The layer SVG group
|
* @returns {SVGGElement} The layer SVG group
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Layer.prototype.getGroup = function() {
|
Layer.prototype.getGroup = function() {
|
||||||
return this.group_;
|
return this.group_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Active this layer so it takes pointer events.
|
||||||
|
*/
|
||||||
|
Layer.prototype.activate = function() {
|
||||||
|
this.group_.setAttribute("style", "pointer-events:all");
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Deactive this layer so it does NOT take pointer events.
|
||||||
|
*/
|
||||||
|
Layer.prototype.deactivate = function() {
|
||||||
|
this.group_.setAttribute("style", "pointer-events:none");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this layer visible or hidden based on 'visible' parameter.
|
||||||
|
* @param {boolean} visible - If true, make visible; otherwise, hide it.
|
||||||
|
*/
|
||||||
|
Layer.prototype.setVisible = function(visible) {
|
||||||
|
var expected = visible === undefined || visible ? "inline" : "none";
|
||||||
|
var oldDisplay = this.group_.getAttribute("display");
|
||||||
|
if (oldDisplay !== expected) {
|
||||||
|
this.group_.setAttribute("display", expected);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this layer visible?
|
||||||
|
* @returns {boolean} True if visible.
|
||||||
|
*/
|
||||||
|
Layer.prototype.isVisible = function() {
|
||||||
|
return this.group_.getAttribute('display') !== 'none';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get layer opacity.
|
||||||
|
* @returns {number} Opacity value.
|
||||||
|
*/
|
||||||
|
Layer.prototype.getOpacity = function() {
|
||||||
|
var opacity = this.group_.getAttribute('opacity');
|
||||||
|
if (opacity === null || opacity === undefined) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return parseFloat(opacity);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the opacity of this layer. If opacity is not a value between 0.0 and 1.0,
|
||||||
|
* nothing happens.
|
||||||
|
* @param {number} opacity - A float value in the range 0.0-1.0
|
||||||
|
*/
|
||||||
|
Layer.prototype.setOpacity = function(opacity) {
|
||||||
|
if (typeof opacity === 'number' && opacity >= 0.0 && opacity <= 1.0) {
|
||||||
|
this.group_.setAttribute('opacity', opacity);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append children to this layer.
|
||||||
|
* @param {SVGGElement} children - The children to append to this layer.
|
||||||
|
*/
|
||||||
|
Layer.prototype.appendChildren = function(children) {
|
||||||
|
for (var i = 0; i < children.length; ++i) {
|
||||||
|
this.group_.appendChild(children[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove this layer's group from the DOM. No more functions on group can be called after this.
|
||||||
|
* @param {SVGGElement} children - The children to append to this layer.
|
||||||
|
* @returns {SVGGElement} The layer SVG group that was just removed.
|
||||||
|
*/
|
||||||
|
Layer.prototype.removeGroup = function() {
|
||||||
|
var parent = this.group_.parentNode;
|
||||||
|
var group = parent.removeChild(this.group_);
|
||||||
|
this.group_ = undefined;
|
||||||
|
return group;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
* Called to ensure that drawings will or will not have randomized ids.
|
* Called to ensure that drawings will or will not have randomized ids.
|
||||||
* The currentDrawing will have its nonce set if it doesn't already.
|
* The currentDrawing will have its nonce set if it doesn't already.
|
||||||
* @param {boolean} enableRandomization - flag indicating if documents should have randomized ids
|
* @param {boolean} enableRandomization - flag indicating if documents should have randomized ids
|
||||||
|
@ -111,17 +232,22 @@ svgedit.draw.Drawing = function(svgElem, opt_idPrefix) {
|
||||||
this.releasedNums = [];
|
this.releasedNums = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The z-ordered array of tuples containing layer names and <g> elements.
|
* The z-ordered array of Layer objects. Each layer has a name
|
||||||
|
* and group element.
|
||||||
* The first layer is the one at the bottom of the rendering.
|
* The first layer is the one at the bottom of the rendering.
|
||||||
* TODO: Turn this into an Array.<Layer>
|
* @type {Layer[]}
|
||||||
* @type {Array.<Array.<String, SVGGElement>>}
|
|
||||||
*/
|
*/
|
||||||
this.all_layers = [];
|
this.all_layers = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of all_layers by name.
|
||||||
|
* @type {Object.<string,Layer>}
|
||||||
|
*/
|
||||||
|
this.layer_map = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current layer being used.
|
* The current layer being used.
|
||||||
* TODO: Make this a {Layer}.
|
* @type {Layer}
|
||||||
* @type {SVGGElement}
|
|
||||||
*/
|
*/
|
||||||
this.current_layer = null;
|
this.current_layer = null;
|
||||||
|
|
||||||
|
@ -272,11 +398,7 @@ svgedit.draw.Drawing.prototype.getNumLayers = function() {
|
||||||
* @param {string} name - The layer name to check
|
* @param {string} name - The layer name to check
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.hasLayer = function (name) {
|
svgedit.draw.Drawing.prototype.hasLayer = function (name) {
|
||||||
var i;
|
return this.layer_map[name] !== undefined;
|
||||||
for (i = 0; i < this.getNumLayers(); i++) {
|
|
||||||
if(this.all_layers[i][0] == name) {return true;}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -286,32 +408,23 @@ svgedit.draw.Drawing.prototype.hasLayer = function (name) {
|
||||||
* @returns {string} The name of the ith layer (or the empty string if none found)
|
* @returns {string} The name of the ith layer (or the empty string if none found)
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.getLayerName = function (i) {
|
svgedit.draw.Drawing.prototype.getLayerName = function (i) {
|
||||||
if (i >= 0 && i < this.getNumLayers()) {
|
return i >= 0 && i < this.getNumLayers() ? this.all_layers[i].getName() : '';
|
||||||
return this.all_layers[i][0];
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {SVGGElement} The SVGGElement representing the current layer.
|
* @returns {SVGGElement} The SVGGElement representing the current layer.
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.getCurrentLayer = function() {
|
svgedit.draw.Drawing.prototype.getCurrentLayer = function() {
|
||||||
return this.current_layer;
|
return this.current_layer ? this.current_layer.getGroup() : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the currently selected layer. If an error occurs, an empty string
|
* Returns the name of the currently selected layer. If an error occurs, an empty string
|
||||||
* is returned.
|
* is returned.
|
||||||
* @returns The name of the currently active layer (or the empty string if none found).
|
* @returns {string} The name of the currently active layer (or the empty string if none found).
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.getCurrentLayerName = function () {
|
svgedit.draw.Drawing.prototype.getCurrentLayerName = function () {
|
||||||
var i;
|
return this.current_layer ? this.current_layer.getName() : '';
|
||||||
for (i = 0; i < this.getNumLayers(); ++i) {
|
|
||||||
if (this.all_layers[i][1] == this.current_layer) {
|
|
||||||
return this.getLayerName(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,16 +435,14 @@ svgedit.draw.Drawing.prototype.getCurrentLayerName = function () {
|
||||||
* @returns {boolean} true if the current layer was switched, otherwise false
|
* @returns {boolean} true if the current layer was switched, otherwise false
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.setCurrentLayer = function(name) {
|
svgedit.draw.Drawing.prototype.setCurrentLayer = function(name) {
|
||||||
var i;
|
var layer = this.layer_map[name];
|
||||||
for (i = 0; i < this.getNumLayers(); ++i) {
|
if (layer) {
|
||||||
if (name == this.getLayerName(i)) {
|
if (this.current_layer) {
|
||||||
if (this.current_layer != this.all_layers[i][1]) {
|
this.current_layer.deactivate();
|
||||||
this.current_layer.setAttribute("style", "pointer-events:none");
|
|
||||||
this.current_layer = this.all_layers[i][1];
|
|
||||||
this.current_layer.setAttribute("style", "pointer-events:all");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
this.current_layer = layer;
|
||||||
|
this.current_layer.activate();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -344,101 +455,107 @@ svgedit.draw.Drawing.prototype.setCurrentLayer = function(name) {
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.deleteCurrentLayer = function() {
|
svgedit.draw.Drawing.prototype.deleteCurrentLayer = function() {
|
||||||
if (this.current_layer && this.getNumLayers() > 1) {
|
if (this.current_layer && this.getNumLayers() > 1) {
|
||||||
// actually delete from the DOM and return it
|
var oldLayerGroup = this.current_layer.removeGroup();
|
||||||
var parent = this.current_layer.parentNode;
|
|
||||||
var nextSibling = this.current_layer.nextSibling;
|
|
||||||
var oldLayerGroup = parent.removeChild(this.current_layer);
|
|
||||||
this.identifyLayers();
|
this.identifyLayers();
|
||||||
return oldLayerGroup;
|
return oldLayerGroup;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the layer name in a group element.
|
||||||
|
* @param group The group element to search in.
|
||||||
|
* @returns {string} The layer name or empty string.
|
||||||
|
*/
|
||||||
|
function findLayerNameInGroup(group) {
|
||||||
|
var name = $("title", group).text();
|
||||||
|
|
||||||
|
// Hack for Opera 10.60
|
||||||
|
if (!name && svgedit.browser.isOpera() && group.querySelectorAll) {
|
||||||
|
name = $(group.querySelectorAll('title')).text();
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a set of names, return a new unique name.
|
||||||
|
* @param {string[]} existingLayerNames - Existing layer names.
|
||||||
|
* @returns {string} - The new name.
|
||||||
|
*/
|
||||||
|
function getNewLayerName(existingLayerNames) {
|
||||||
|
var i = 1;
|
||||||
|
// TODO(codedread): What about internationalization of "Layer"?
|
||||||
|
while (existingLayerNames.indexOf(("Layer " + i)) >= 0) { i++; }
|
||||||
|
return "Layer " + i;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates layer system and sets the current layer to the
|
* Updates layer system and sets the current layer to the
|
||||||
* top-most layer (last <g> child of this drawing).
|
* top-most layer (last <g> child of this drawing).
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.identifyLayers = function() {
|
svgedit.draw.Drawing.prototype.identifyLayers = function() {
|
||||||
this.all_layers = [];
|
this.all_layers = [];
|
||||||
|
this.layer_map = {};
|
||||||
var numchildren = this.svgElem_.childNodes.length;
|
var numchildren = this.svgElem_.childNodes.length;
|
||||||
// loop through all children of SVG element
|
// loop through all children of SVG element
|
||||||
var orphans = [], layernames = [];
|
var orphans = [], layernames = [];
|
||||||
var a_layer = null;
|
var layer = null;
|
||||||
var childgroups = false;
|
var childgroups = false;
|
||||||
var i;
|
for (var i = 0; i < numchildren; ++i) {
|
||||||
for (i = 0; i < numchildren; ++i) {
|
|
||||||
var child = this.svgElem_.childNodes.item(i);
|
var child = this.svgElem_.childNodes.item(i);
|
||||||
// for each g, find its layer name
|
// for each g, find its layer name
|
||||||
if (child && child.nodeType == 1) {
|
if (child && child.nodeType == 1) {
|
||||||
if (child.tagName == "g") {
|
if (child.tagName == "g") {
|
||||||
childgroups = true;
|
childgroups = true;
|
||||||
var name = $("title", child).text();
|
var name = findLayerNameInGroup(child);
|
||||||
|
|
||||||
// Hack for Opera 10.60
|
|
||||||
if(!name && svgedit.browser.isOpera() && child.querySelectorAll) {
|
|
||||||
name = $(child.querySelectorAll('title')).text();
|
|
||||||
}
|
|
||||||
|
|
||||||
// store layer and name in global variable
|
|
||||||
if (name) {
|
if (name) {
|
||||||
layernames.push(name);
|
layernames.push(name);
|
||||||
this.all_layers.push( [name, child] );
|
layer = new Layer(name, child);
|
||||||
a_layer = child;
|
this.all_layers.push(layer);
|
||||||
svgedit.utilities.walkTree(child, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
this.layer_map[ name] = layer;
|
||||||
a_layer.setAttribute("style", "pointer-events:none");
|
} else {
|
||||||
}
|
// if group did not have a name, it is an orphan
|
||||||
// if group did not have a name, it is an orphan
|
|
||||||
else {
|
|
||||||
orphans.push(child);
|
orphans.push(child);
|
||||||
}
|
}
|
||||||
}
|
} else if (~visElems.indexOf(child.nodeName)) {
|
||||||
// if child has is "visible" (i.e. not a <title> or <defs> element), then it is an orphan
|
// Child is "visible" (i.e. not a <title> or <defs> element), so it is an orphan
|
||||||
else if(~visElems.indexOf(child.nodeName)) {
|
|
||||||
var bb = svgedit.utilities.getBBox(child);
|
|
||||||
orphans.push(child);
|
orphans.push(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new layer and add all the orphans to it
|
// If orphans or no layers found, create a new layer and add all the orphans to it
|
||||||
var svgdoc = this.svgElem_.ownerDocument;
|
|
||||||
if (orphans.length > 0 || !childgroups) {
|
if (orphans.length > 0 || !childgroups) {
|
||||||
i = 1;
|
layer = new Layer(getNewLayerName(layernames), null, this.svgElem_);
|
||||||
// TODO(codedread): What about internationalization of "Layer"?
|
layer.appendChildren(orphans);
|
||||||
while (layernames.indexOf(("Layer " + i)) >= 0) { i++; }
|
this.all_layers.push(layer);
|
||||||
var newname = "Layer " + i;
|
this.layer_map[ name] = layer;
|
||||||
a_layer = svgdoc.createElementNS(NS.SVG, "g");
|
} else {
|
||||||
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
layer.activate();
|
||||||
layer_title.textContent = newname;
|
|
||||||
a_layer.appendChild(layer_title);
|
|
||||||
var j;
|
|
||||||
for (j = 0; j < orphans.length; ++j) {
|
|
||||||
a_layer.appendChild(orphans[j]);
|
|
||||||
}
|
|
||||||
this.svgElem_.appendChild(a_layer);
|
|
||||||
this.all_layers.push( [newname, a_layer] );
|
|
||||||
}
|
}
|
||||||
svgedit.utilities.walkTree(a_layer, function(e){e.setAttribute("style", "pointer-events:inherit");});
|
this.current_layer = layer;
|
||||||
this.current_layer = a_layer;
|
|
||||||
this.current_layer.setAttribute("style", "pointer-events:all");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
* @param {string} name - The given name
|
* @param {string} name - The given name. If the layer name exists, a new name will be generated.
|
||||||
* @returns {SVGGElement} The SVGGElement of the new layer, which is
|
* @returns {SVGGElement} The SVGGElement of the new layer, which is
|
||||||
* 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;
|
if (this.current_layer) {
|
||||||
var new_layer = svgdoc.createElementNS(NS.SVG, "g");
|
this.current_layer.deactivate();
|
||||||
var layer_title = svgdoc.createElementNS(NS.SVG, "title");
|
}
|
||||||
layer_title.textContent = name;
|
// Check for duplicate name.
|
||||||
new_layer.appendChild(layer_title);
|
if (name === undefined || name === null || name === '' || this.layer_map[name]) {
|
||||||
this.svgElem_.appendChild(new_layer);
|
name = getNewLayerName(Object.keys(this.layer_map));
|
||||||
this.identifyLayers();
|
}
|
||||||
return new_layer;
|
var layer = new Layer(name, null, this.svgElem_);
|
||||||
|
this.all_layers.push(layer);
|
||||||
|
this.layer_map[ name] = layer;
|
||||||
|
this.current_layer = layer;
|
||||||
|
return layer.getGroup();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -448,17 +565,8 @@ svgedit.draw.Drawing.prototype.createLayer = function(name) {
|
||||||
* @returns {boolean} The visibility state of the layer, or false if the layer name was invalid.
|
* @returns {boolean} The visibility state of the layer, or false if the layer name was invalid.
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.getLayerVisibility = function(layername) {
|
svgedit.draw.Drawing.prototype.getLayerVisibility = function(layername) {
|
||||||
// find the layer
|
var layer = this.layer_map[layername];
|
||||||
var layer = null;
|
return layer ? layer.isVisible() : false;
|
||||||
var i;
|
|
||||||
for (i = 0; i < this.getNumLayers(); ++i) {
|
|
||||||
if (this.getLayerName(i) == layername) {
|
|
||||||
layer = this.all_layers[i][1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!layer) {return false;}
|
|
||||||
return (layer.getAttribute('display') !== 'none');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -474,21 +582,10 @@ svgedit.draw.Drawing.prototype.setLayerVisibility = function(layername, bVisible
|
||||||
if (typeof bVisible !== 'boolean') {
|
if (typeof bVisible !== 'boolean') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// find the layer
|
var layer = this.layer_map[layername];
|
||||||
var layer = null;
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < this.getNumLayers(); ++i) {
|
|
||||||
if (this.getLayerName(i) == layername) {
|
|
||||||
layer = this.all_layers[i][1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!layer) {return null;}
|
if (!layer) {return null;}
|
||||||
|
layer.setVisible(bVisible);
|
||||||
var oldDisplay = layer.getAttribute("display");
|
return layer.getGroup();
|
||||||
if (!oldDisplay) {oldDisplay = "inline";}
|
|
||||||
layer.setAttribute("display", bVisible ? "inline" : "none");
|
|
||||||
return layer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -499,18 +596,9 @@ svgedit.draw.Drawing.prototype.setLayerVisibility = function(layername, bVisible
|
||||||
* if layername is not a valid layer
|
* if layername is not a valid layer
|
||||||
*/
|
*/
|
||||||
svgedit.draw.Drawing.prototype.getLayerOpacity = function(layername) {
|
svgedit.draw.Drawing.prototype.getLayerOpacity = function(layername) {
|
||||||
var i;
|
var layer = this.layer_map[layername];
|
||||||
for (i = 0; i < this.getNumLayers(); ++i) {
|
if (!layer) {return null;}
|
||||||
if (this.getLayerName(i) == layername) {
|
return layer.getOpacity();
|
||||||
var g = this.all_layers[i][1];
|
|
||||||
var opacity = g.getAttribute('opacity');
|
|
||||||
if (!opacity) {
|
|
||||||
opacity = '1.0';
|
|
||||||
}
|
|
||||||
return parseFloat(opacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -524,13 +612,9 @@ svgedit.draw.Drawing.prototype.setLayerOpacity = function(layername, opacity) {
|
||||||
if (typeof opacity !== 'number' || opacity < 0.0 || opacity > 1.0) {
|
if (typeof opacity !== 'number' || opacity < 0.0 || opacity > 1.0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var i;
|
var layer = this.layer_map[layername];
|
||||||
for (i = 0; i < this.getNumLayers(); ++i) {
|
if (layer) {
|
||||||
if (this.getLayerName(i) == layername) {
|
layer.setOpacity(opacity);
|
||||||
var g = this.all_layers[i][1];
|
|
||||||
g.setAttribute("opacity", opacity);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,9 +248,10 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test identifyLayers() with empty document', function() {
|
test('Test identifyLayers() with empty document', function() {
|
||||||
expect(9);
|
expect(11);
|
||||||
|
|
||||||
var drawing = new svgedit.draw.Drawing(svg);
|
var drawing = new svgedit.draw.Drawing(svg);
|
||||||
|
equals(drawing.getCurrentLayer(), null);
|
||||||
// By default, an empty document gets an empty group created.
|
// By default, an empty document gets an empty group created.
|
||||||
drawing.identifyLayers();
|
drawing.identifyLayers();
|
||||||
|
|
||||||
|
@ -254,22 +259,24 @@
|
||||||
ok(drawing.getSvgElem().hasChildNodes());
|
ok(drawing.getSvgElem().hasChildNodes());
|
||||||
equals(drawing.getSvgElem().childNodes.length, 1);
|
equals(drawing.getSvgElem().childNodes.length, 1);
|
||||||
|
|
||||||
// Check that all_layers is correctly set up.
|
// Check that all_layers are correctly set up.
|
||||||
equals(drawing.getNumLayers(), 1);
|
equals(drawing.getNumLayers(), 1);
|
||||||
var empty_layer = drawing.all_layers[0][1];
|
var empty_layer = drawing.all_layers[0];
|
||||||
ok(empty_layer);
|
ok(empty_layer);
|
||||||
equals(empty_layer, drawing.getSvgElem().firstChild);
|
var layerGroup = empty_layer.getGroup();
|
||||||
equals(empty_layer.tagName, 'g');
|
equals(layerGroup, drawing.getSvgElem().firstChild);
|
||||||
ok(empty_layer.hasChildNodes());
|
equals(layerGroup.tagName, 'g');
|
||||||
equals(empty_layer.childNodes.length, 1);
|
equals(layerGroup.getAttribute('class'), LAYER_CLASS);
|
||||||
var firstChild = empty_layer.childNodes.item(0);
|
ok(layerGroup.hasChildNodes());
|
||||||
|
equals(layerGroup.childNodes.length, 1);
|
||||||
|
var firstChild = layerGroup.childNodes.item(0);
|
||||||
equals(firstChild.tagName, 'title');
|
equals(firstChild.tagName, 'title');
|
||||||
|
|
||||||
cleanupSvg(svg);
|
cleanupSvg(svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
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);
|
||||||
|
@ -279,15 +286,19 @@
|
||||||
drawing.identifyLayers();
|
drawing.identifyLayers();
|
||||||
|
|
||||||
equals(drawing.getNumLayers(), 3);
|
equals(drawing.getNumLayers(), 3);
|
||||||
equals(drawing.all_layers[0][1], svg.childNodes.item(0));
|
equals(drawing.all_layers[0].getGroup(), svg.childNodes.item(0));
|
||||||
equals(drawing.all_layers[1][1], svg.childNodes.item(1));
|
equals(drawing.all_layers[1].getGroup(), svg.childNodes.item(1));
|
||||||
equals(drawing.all_layers[2][1], svg.childNodes.item(2));
|
equals(drawing.all_layers[2].getGroup(), svg.childNodes.item(2));
|
||||||
|
|
||||||
|
equals(drawing.all_layers[0].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[1].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[2].getGroup().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);
|
||||||
|
|
||||||
|
@ -302,12 +313,17 @@
|
||||||
drawing.identifyLayers();
|
drawing.identifyLayers();
|
||||||
|
|
||||||
equals(drawing.getNumLayers(), 4);
|
equals(drawing.getNumLayers(), 4);
|
||||||
equals(drawing.all_layers[0][1], svg.childNodes.item(0));
|
equals(drawing.all_layers[0].getGroup(), svg.childNodes.item(0));
|
||||||
equals(drawing.all_layers[1][1], svg.childNodes.item(1));
|
equals(drawing.all_layers[1].getGroup(), svg.childNodes.item(1));
|
||||||
equals(drawing.all_layers[2][1], svg.childNodes.item(2));
|
equals(drawing.all_layers[2].getGroup(), svg.childNodes.item(2));
|
||||||
equals(drawing.all_layers[3][1], svg.childNodes.item(3));
|
equals(drawing.all_layers[3].getGroup(), svg.childNodes.item(3));
|
||||||
|
|
||||||
var layer4 = drawing.all_layers[3][1];
|
equals(drawing.all_layers[0].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[1].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[2].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||||
|
equals(drawing.all_layers[3].getGroup().getAttribute('class'), LAYER_CLASS);
|
||||||
|
|
||||||
|
var layer4 = drawing.all_layers[3].getGroup();
|
||||||
equals(layer4.tagName, 'g');
|
equals(layer4.tagName, 'g');
|
||||||
equals(layer4.childNodes.length, 3);
|
equals(layer4.childNodes.length, 3);
|
||||||
equals(layer4.childNodes.item(1), orphan1);
|
equals(layer4.childNodes.item(1), orphan1);
|
||||||
|
@ -342,7 +358,9 @@
|
||||||
ok(drawing.getCurrentLayer);
|
ok(drawing.getCurrentLayer);
|
||||||
equals(typeof drawing.getCurrentLayer, typeof function(){});
|
equals(typeof drawing.getCurrentLayer, typeof function(){});
|
||||||
ok(drawing.getCurrentLayer());
|
ok(drawing.getCurrentLayer());
|
||||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2][1]);
|
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||||
|
|
||||||
|
cleanupSvg(svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test setCurrentLayer() and getCurrentLayerName()', function() {
|
test('Test setCurrentLayer() and getCurrentLayerName()', function() {
|
||||||
|
@ -357,17 +375,17 @@
|
||||||
|
|
||||||
drawing.setCurrentLayer(LAYER2);
|
drawing.setCurrentLayer(LAYER2);
|
||||||
equals(drawing.getCurrentLayerName(LAYER2), LAYER2);
|
equals(drawing.getCurrentLayerName(LAYER2), LAYER2);
|
||||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1][1]);
|
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||||
|
|
||||||
drawing.setCurrentLayer(LAYER3);
|
drawing.setCurrentLayer(LAYER3);
|
||||||
equals(drawing.getCurrentLayerName(LAYER3), LAYER3);
|
equals(drawing.getCurrentLayerName(LAYER3), LAYER3);
|
||||||
equals(drawing.getCurrentLayer(), drawing.all_layers[2][1]);
|
equals(drawing.getCurrentLayer(), drawing.all_layers[2].getGroup());
|
||||||
|
|
||||||
cleanupSvg(svg);
|
cleanupSvg(svg);
|
||||||
});
|
});
|
||||||
|
|
||||||
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);
|
||||||
|
@ -378,8 +396,9 @@
|
||||||
|
|
||||||
var NEW_LAYER_NAME = 'Layer A';
|
var NEW_LAYER_NAME = 'Layer A';
|
||||||
var layer_g = drawing.createLayer(NEW_LAYER_NAME);
|
var layer_g = drawing.createLayer(NEW_LAYER_NAME);
|
||||||
equals(4, drawing.getNumLayers());
|
equals(drawing.getNumLayers(), 4);
|
||||||
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));
|
||||||
|
|
||||||
|
@ -477,14 +496,14 @@
|
||||||
drawing.setCurrentLayer(LAYER2);
|
drawing.setCurrentLayer(LAYER2);
|
||||||
|
|
||||||
var curLayer = drawing.getCurrentLayer();
|
var curLayer = drawing.getCurrentLayer();
|
||||||
equals(curLayer, drawing.all_layers[1][1]);
|
equals(curLayer, drawing.all_layers[1].getGroup());
|
||||||
var deletedLayer = drawing.deleteCurrentLayer();
|
var deletedLayer = drawing.deleteCurrentLayer();
|
||||||
|
|
||||||
equals(curLayer, deletedLayer);
|
equals(curLayer, deletedLayer);
|
||||||
equals(2, drawing.getNumLayers());
|
equals(2, drawing.getNumLayers());
|
||||||
equals(LAYER1, drawing.all_layers[0][0]);
|
equals(LAYER1, drawing.all_layers[0].getName());
|
||||||
equals(LAYER3, drawing.all_layers[1][0]);
|
equals(LAYER3, drawing.all_layers[1].getName());
|
||||||
equals(drawing.getCurrentLayer(), drawing.all_layers[1][1]);
|
equals(drawing.getCurrentLayer(), drawing.all_layers[1].getGroup());
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test svgedit.draw.randomizeIds()', function() {
|
test('Test svgedit.draw.randomizeIds()', function() {
|
||||||
|
@ -530,6 +549,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