Update SVG-Edit
This commit is contained in:
parent
a12a778c5a
commit
1bef71bbf1
9 changed files with 277 additions and 192 deletions
|
@ -85,6 +85,17 @@ var supportsTextCharPos_ = (function() {
|
|||
return retValue;
|
||||
})();
|
||||
|
||||
var supportsPathBBox_ = (function() {
|
||||
var svgcontent = document.createElementNS(svgns, 'svg');
|
||||
document.documentElement.appendChild(svgcontent);
|
||||
var path = document.createElementNS(svgns, 'path');
|
||||
path.setAttribute('d','M0,0 C0,0 10,10 10,0');
|
||||
svgcontent.appendChild(path);
|
||||
var bbox = path.getBBox();
|
||||
document.documentElement.removeChild(svgcontent);
|
||||
return (bbox.height > 4 && bbox.height < 5);
|
||||
})();
|
||||
|
||||
var supportsEditableText_ = (function() {
|
||||
// TODO: Find better way to check support for this
|
||||
return isOpera_;
|
||||
|
@ -129,6 +140,7 @@ svgedit.browser.supportsXpath = function() { return supportsXpath_; }
|
|||
|
||||
svgedit.browser.supportsPathReplaceItem = function() { return supportsPathReplaceItem_; }
|
||||
svgedit.browser.supportsPathInsertItemBefore = function() { return supportsPathInsertItemBefore_; }
|
||||
svgedit.browser.supportsPathBBox = function() { return supportsPathBBox_; }
|
||||
svgedit.browser.supportsTextCharPos = function() { return supportsTextCharPos_; }
|
||||
svgedit.browser.supportsEditableText = function() { return supportsEditableText_; }
|
||||
svgedit.browser.supportsGoodDecimals = function() { return supportsGoodDecimals_; }
|
||||
|
|
|
@ -23,6 +23,13 @@ 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 RandomizeModes = {
|
||||
LET_DOCUMENT_DECIDE: 0,
|
||||
ALWAYS_RANDOMIZE: 1,
|
||||
NEVER_RANDOMIZE: 2
|
||||
};
|
||||
var randomize_ids = RandomizeModes.LET_DOCUMENT_DECIDE;
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of a layer in the drawing
|
||||
* @param name {String} Layer name
|
||||
|
@ -42,6 +49,23 @@ svgedit.draw.Layer.prototype.getGroup = function() {
|
|||
};
|
||||
|
||||
|
||||
// Called to ensure that drawings will or will not have randomized ids.
|
||||
// The current_drawing will have its nonce set if it doesn't already.
|
||||
//
|
||||
// Params:
|
||||
// enableRandomization - flag indicating if documents should have randomized ids
|
||||
svgedit.draw.randomizeIds = function(enableRandomization, current_drawing) {
|
||||
randomize_ids = enableRandomization == false ?
|
||||
RandomizeModes.NEVER_RANDOMIZE :
|
||||
RandomizeModes.ALWAYS_RANDOMIZE;
|
||||
|
||||
if (randomize_ids == RandomizeModes.ALWAYS_RANDOMIZE && !current_drawing.getNonce()) {
|
||||
current_drawing.setNonce(Math.floor(Math.random() * 100001));
|
||||
} else if (randomize_ids == RandomizeModes.NEVER_RANDOMIZE && current_drawing.getNonce()) {
|
||||
current_drawing.clearNonce();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class encapsulates the concept of a SVG-edit drawing
|
||||
*
|
||||
|
@ -100,7 +124,15 @@ 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 && randomize_ids != RandomizeModes.NEVER_RANDOMIZE) {
|
||||
this.nonce_ = n;
|
||||
} else if (randomize_ids == RandomizeModes.ALWAYS_RANDOMIZE) {
|
||||
this.setNonce(Math.floor(Math.random() * 100001));
|
||||
}
|
||||
};
|
||||
|
||||
svgedit.draw.Drawing.prototype.getElem_ = function(id) {
|
||||
|
@ -121,10 +153,16 @@ svgedit.draw.Drawing.prototype.getNonce = function() {
|
|||
return this.nonce_;
|
||||
};
|
||||
|
||||
svgedit.draw.Drawing.prototype.setNonce = function(nonce) {
|
||||
this.nonce_ = nonce;
|
||||
svgedit.draw.Drawing.prototype.setNonce = function(n) {
|
||||
this.svgElem_.setAttributeNS(xmlns_ns, 'xmlns:se', se_ns);
|
||||
this.svgElem_.setAttributeNS(se_ns, 'se:nonce', nonce);
|
||||
this.svgElem_.setAttributeNS(se_ns, 'se:nonce', n);
|
||||
this.nonce_ = n;
|
||||
};
|
||||
|
||||
svgedit.draw.Drawing.prototype.clearNonce = function() {
|
||||
// We deliberately leave any se:nonce attributes alone,
|
||||
// we just don't use it to randomize ids.
|
||||
this.nonce_ = "";
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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":[
|
||||
|
|
|
@ -36,13 +36,23 @@ var removedElements = {};
|
|||
* An interface that all command objects must implement.
|
||||
*
|
||||
* interface svgedit.history.HistoryCommand {
|
||||
* void apply();
|
||||
* void unapply();
|
||||
* void apply(svgedit.history.HistoryEventHandler);
|
||||
* void unapply(svgedit.history.HistoryEventHandler);
|
||||
* Element[] elements();
|
||||
* String getText();
|
||||
*
|
||||
* static String type();
|
||||
* }
|
||||
*
|
||||
* Interface: svgedit.history.HistoryEventHandler
|
||||
* An interface for objects that will handle history events.
|
||||
*
|
||||
* interface svgedit.history.HistoryEventHandler {
|
||||
* void handleHistoryEvent(eventType, command);
|
||||
* }
|
||||
*
|
||||
* eventType is a string conforming to one of the HistoryEvent types.
|
||||
* command is an object fulfilling the HistoryCommand interface.
|
||||
*/
|
||||
|
||||
// Class: svgedit.history.MoveElementCommand
|
||||
|
@ -213,8 +223,12 @@ svgedit.history.RemoveElementCommand.prototype.unapply = function(handler) {
|
|||
}
|
||||
|
||||
svgedit.transformlist.removeElementFromListMap(this.elem);
|
||||
if(this.nextSibling == null) {
|
||||
console.log('Error: reference element was lost');
|
||||
}
|
||||
this.parent.insertBefore(this.elem, this.nextSibling);
|
||||
|
||||
|
||||
if (handler) {
|
||||
handler.handleHistoryEvent(svgedit.history.HistoryEventTypes.AFTER_UNAPPLY, this);
|
||||
}
|
||||
|
@ -443,18 +457,6 @@ svgedit.history.BatchCommand.prototype.isEmpty = function() {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interface: svgedit.history.HistoryEventHandler
|
||||
* An interface for objects that will handle history events.
|
||||
*
|
||||
* interface svgedit.history.HistoryEventHandler {
|
||||
* void handleHistoryEvent(eventType, command);
|
||||
* }
|
||||
*
|
||||
* eventType is a string conforming to one of the HistoryEvent types (see above).
|
||||
* command is an object fulfilling the HistoryCommand interface (see above).
|
||||
*/
|
||||
|
||||
// Class: svgedit.history.UndoManager
|
||||
// Parameters:
|
||||
// historyEventHandler - an object that conforms to the HistoryEventHandler interface
|
||||
|
|
|
@ -532,7 +532,7 @@
|
|||
position: absolute;
|
||||
top: 77px;
|
||||
left: 40px;
|
||||
right: -2px;
|
||||
right: 0;
|
||||
line-height: 22px;
|
||||
overflow: auto;
|
||||
border: 1px solid #777;
|
||||
|
|
|
@ -1535,8 +1535,8 @@
|
|||
}
|
||||
|
||||
if(unit) {
|
||||
x = svgCanvas.convertUnit(x);
|
||||
y = svgCanvas.convertUnit(y);
|
||||
x = svgedit.units.convertUnit(x);
|
||||
y = svgedit.units.convertUnit(y);
|
||||
}
|
||||
|
||||
$('#selected_x').val(x || 0);
|
||||
|
@ -1560,8 +1560,8 @@
|
|||
if(point) {
|
||||
var seg_type = $('#seg_type');
|
||||
if(unit) {
|
||||
point.x = svgCanvas.convertUnit(point.x);
|
||||
point.y = svgCanvas.convertUnit(point.y);
|
||||
point.x = svgedit.units.convertUnit(point.x);
|
||||
point.y = svgedit.units.convertUnit(point.y);
|
||||
}
|
||||
$('#path_node_x').val(point.x);
|
||||
$('#path_node_y').val(point.y);
|
||||
|
@ -1622,7 +1622,7 @@
|
|||
var attrVal = elem.getAttribute(item);
|
||||
if(curConfig.baseUnit !== 'px' && elem[item]) {
|
||||
var bv = elem[item].baseVal.value;
|
||||
attrVal = svgCanvas.convertUnit(bv);
|
||||
attrVal = svgedit.units.convertUnit(bv);
|
||||
}
|
||||
|
||||
$('#' + el_name + '_' + item).val(attrVal || 0);
|
||||
|
@ -2734,8 +2734,8 @@
|
|||
// update resolution option with actual resolution
|
||||
var res = svgCanvas.getResolution();
|
||||
if(curConfig.baseUnit !== "px") {
|
||||
res.w = svgCanvas.convertUnit(res.w) + curConfig.baseUnit;
|
||||
res.h = svgCanvas.convertUnit(res.h) + curConfig.baseUnit;
|
||||
res.w = svgedit.units.convertUnit(res.w) + curConfig.baseUnit;
|
||||
res.h = svgedit.units.convertUnit(res.h) + curConfig.baseUnit;
|
||||
}
|
||||
|
||||
$('#canvas_width').val(res.w);
|
||||
|
@ -4583,7 +4583,7 @@
|
|||
updateCanvas(true);
|
||||
// });
|
||||
|
||||
// var revnums = "svg-editor.js ($Rev: 1956 $) ";
|
||||
// var revnums = "svg-editor.js ($Rev: 1973 $) ";
|
||||
// revnums += svgCanvas.getVersion();
|
||||
// $('#copyright')[0].setAttribute("title", revnums);
|
||||
|
||||
|
@ -4721,6 +4721,13 @@
|
|||
});
|
||||
};
|
||||
|
||||
Editor.disableUI = function(featList) {
|
||||
// $(function() {
|
||||
// $('#tool_wireframe, #tool_image, #main_button, #tool_source, #sidepanels').remove();
|
||||
// $('#tools_top').css('left', 5);
|
||||
// });
|
||||
};
|
||||
|
||||
Editor.loadFromURL = function(url, opts) {
|
||||
if(!opts) opts = {};
|
||||
|
||||
|
|
|
@ -151,17 +151,29 @@ 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/ ");
|
||||
// Lead to invalid content with Instiki's Sanitizer
|
||||
// svgcontent.appendChild(comment);
|
||||
};
|
||||
clearSvgContentElement();
|
||||
|
||||
// Prefix string for element IDs
|
||||
var idprefix = "svg_";
|
||||
|
@ -177,27 +189,15 @@ canvas.setIdPrefix = function(p) {
|
|||
|
||||
// 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_;
|
||||
};
|
||||
|
||||
// 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
|
||||
// TODO: Remove this? Given randomize_ids is set to false above, it seems useless.
|
||||
if (randomize_ids) {
|
||||
getCurrentDrawing().setNonce(nonce);
|
||||
}
|
||||
|
||||
// Float displaying the current zoom level (1 = 100%, .5 = 50%, etc)
|
||||
var current_zoom = 1;
|
||||
|
||||
|
@ -386,7 +386,8 @@ svgedit.units.init({
|
|||
getBaseUnit: function() { return curConfig.baseUnit; },
|
||||
getElement: getElem,
|
||||
getHeight: function() { return svgcontent.getAttribute("height")/current_zoom; },
|
||||
getWidth: function() { return svgcontent.getAttribute("width")/current_zoom; }
|
||||
getWidth: function() { return svgcontent.getAttribute("width")/current_zoom; },
|
||||
getRoundDigits: function() { return save_options.round_digits; }
|
||||
});
|
||||
// import from units.js
|
||||
var convertToNum = canvas.convertToNum = svgedit.units.convertToNum;
|
||||
|
@ -426,7 +427,7 @@ canvas.undoMgr = new svgedit.history.UndoManager({
|
|||
call("changed", elems);
|
||||
|
||||
var cmdType = cmd.type();
|
||||
var isApply = eventType == EventTypes.AFTER_APPLY;
|
||||
var isApply = (eventType == EventTypes.AFTER_APPLY);
|
||||
if (cmdType == MoveElementCommand.type()) {
|
||||
var parent = isApply ? cmd.newParent : cmd.oldParent;
|
||||
if (parent == svgcontent) {
|
||||
|
@ -442,6 +443,10 @@ canvas.undoMgr = new svgedit.history.UndoManager({
|
|||
} else {
|
||||
if (!isApply) restoreRefElems(cmd.elem);
|
||||
}
|
||||
|
||||
if(cmd.elem.tagName === 'use') {
|
||||
setUseData(cmd.elem);
|
||||
}
|
||||
} else if (cmdType == ChangeElementCommand.type()) {
|
||||
// if we are changing layer names, re-identify all layers
|
||||
if (cmd.elem.tagName == "title" && cmd.elem.parentNode.parentNode == svgcontent) {
|
||||
|
@ -524,14 +529,17 @@ var restoreRefElems = function(elem) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
var childs = elem.getElementsByTagName('*');
|
||||
|
||||
if(childs.length) {
|
||||
for(var i = 0, l = childs.length; i < l; i++) {
|
||||
restoreRefElems(childs[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(function() {
|
||||
// TODO: make this string optional and set by the client
|
||||
var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ ");
|
||||
// Lead to invalid content with Instiki's Sanitizer
|
||||
// svgcontent.appendChild(comment);
|
||||
|
||||
// TODO For Issue 208: this is a start on a thumbnail
|
||||
// var svgthumb = svgdoc.createElementNS(svgns, "use");
|
||||
// svgthumb.setAttribute('width', '100');
|
||||
|
@ -628,7 +636,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 {
|
||||
|
@ -640,32 +648,6 @@ this.addExtension = function(name, ext_func) {
|
|||
console.log('Cannot add extension "' + name + '", an extension by that name already exists"');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Function: shortFloat
|
||||
// Rounds a given value to a float with number of digits defined in save_options
|
||||
//
|
||||
// Parameters:
|
||||
// val - The value as a String, Number or Array of two numbers to be rounded
|
||||
//
|
||||
// Returns:
|
||||
// If a string/number was given, returns a Float. If an array, return a string
|
||||
// with comma-seperated floats
|
||||
var shortFloat = function(val) {
|
||||
var digits = save_options.round_digits;
|
||||
if(!isNaN(val)) {
|
||||
// Note that + converts to Number
|
||||
return +((+val).toFixed(digits));
|
||||
} else if($.isArray(val)) {
|
||||
return shortFloat(val[0]) + ',' + shortFloat(val[1]);
|
||||
} else {
|
||||
return parseFloat(val).toFixed(digits) - 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.convertUnit = function(val, unit) {
|
||||
return shortFloat(svgedit.units.convertUnit(val, unit));
|
||||
};
|
||||
|
||||
// This method rounds the incoming value to the nearest value based on the current_zoom
|
||||
var round = this.round = function(val) {
|
||||
|
@ -1547,6 +1529,23 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
}
|
||||
}
|
||||
|
||||
// If it still has a single [M] or [R][M], return null too (prevents BatchCommand from being returned).
|
||||
switch ( selected.tagName ) {
|
||||
// Ignore these elements, as they can absorb the [M]
|
||||
case 'line':
|
||||
case 'polyline':
|
||||
case 'polygon':
|
||||
case 'path':
|
||||
break;
|
||||
default:
|
||||
if(
|
||||
(tlist.numberOfItems === 1 && tlist.getItem(0).type === 1)
|
||||
|| (tlist.numberOfItems === 2 && tlist.getItem(0).type === 1 && tlist.getItem(0).type === 4)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Grouped SVG element
|
||||
var gsvg = $(selected).data('gsvg');
|
||||
|
||||
|
@ -2184,6 +2183,7 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
if (tlist.numberOfItems == 0) {
|
||||
selected.removeAttribute("transform");
|
||||
}
|
||||
|
||||
batchCmd.addSubCommand(new ChangeElementCommand(selected, initial));
|
||||
|
||||
return batchCmd;
|
||||
|
@ -5832,9 +5832,9 @@ var pathActions = canvas.pathActions = function() {
|
|||
var addToD = function(pnts, more, last) {
|
||||
var str = '';
|
||||
var more = more?' '+more.join(' '):'';
|
||||
var last = last?' '+shortFloat(last):'';
|
||||
var last = last?' '+svgedit.units.shortFloat(last):'';
|
||||
$.each(pnts, function(i, pnt) {
|
||||
pnts[i] = shortFloat(pnt);
|
||||
pnts[i] = svgedit.units.shortFloat(pnt);
|
||||
});
|
||||
d += letter + pnts.join(' ') + more + last;
|
||||
}
|
||||
|
@ -5984,6 +5984,8 @@ var removeUnusedDefElems = this.removeUnusedDefElems = function() {
|
|||
var defs = svgcontent.getElementsByTagNameNS(svgns, "defs");
|
||||
if(!defs || !defs.length) return 0;
|
||||
|
||||
// if(!defs.firstChild) return;
|
||||
|
||||
var defelem_uses = [],
|
||||
numRemoved = 0;
|
||||
var attrs = ['fill', 'stroke', 'filter', 'marker-start', 'marker-mid', 'marker-end'];
|
||||
|
@ -5996,7 +5998,9 @@ var removeUnusedDefElems = this.removeUnusedDefElems = function() {
|
|||
var el = all_els[i];
|
||||
for(var j = 0; j < alen; j++) {
|
||||
var ref = getUrlFromAttr(el.getAttribute(attrs[j]));
|
||||
if(ref) defelem_uses.push(ref.substr(1));
|
||||
if(ref) {
|
||||
defelem_uses.push(ref.substr(1));
|
||||
}
|
||||
}
|
||||
|
||||
// gradients can refer to other gradients
|
||||
|
@ -6019,16 +6023,7 @@ var removeUnusedDefElems = this.removeUnusedDefElems = function() {
|
|||
numRemoved++;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove defs if empty
|
||||
var i = defs.length;
|
||||
while (i--) {
|
||||
var def = defs[i];
|
||||
if(!def.getElementsByTagNameNS(svgns,'*').length) {
|
||||
def.parentNode.removeChild(def);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return numRemoved;
|
||||
}
|
||||
|
||||
|
@ -6119,16 +6114,16 @@ this.svgToString = function(elem, indent) {
|
|||
// if(curConfig.baseUnit !== "px") {
|
||||
// var unit = curConfig.baseUnit;
|
||||
// var unit_m = svgedit.units.getTypeMap()[unit];
|
||||
// res.w = shortFloat(res.w / unit_m)
|
||||
// res.h = shortFloat(res.h / unit_m)
|
||||
// res.w = svgedit.units.shortFloat(res.w / unit_m)
|
||||
// res.h = svgedit.units.shortFloat(res.h / unit_m)
|
||||
// vb = ' viewBox="' + [0, 0, res.w, res.h].join(' ') + '"';
|
||||
// res.w += unit;
|
||||
// res.h += unit;
|
||||
// }
|
||||
|
||||
if(unit !== "px") {
|
||||
res.w = this.convertUnit(res.w, unit) + unit;
|
||||
res.h = this.convertUnit(res.h, unit) + unit;
|
||||
res.w = svgedit.units.convertUnit(res.w, unit) + unit;
|
||||
res.h = svgedit.units.convertUnit(res.h, unit) + unit;
|
||||
}
|
||||
|
||||
out.push(' width="' + res.w + '" height="' + res.h + '"' + vb + ' xmlns="'+svgns+'"');
|
||||
|
@ -6168,6 +6163,9 @@ this.svgToString = function(elem, indent) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// Skip empty defs
|
||||
if(elem.nodeName === 'defs' && !elem.firstChild) return;
|
||||
|
||||
var moz_attrs = ['-moz-math-font-style', '_moz-math-font-style'];
|
||||
for (var i=attrs.length-1; i>=0; i--) {
|
||||
attr = attrs.item(i);
|
||||
|
@ -6180,9 +6178,9 @@ this.svgToString = function(elem, indent) {
|
|||
out.push(" ");
|
||||
if(attr.localName === 'd') attrVal = pathActions.convertPath(elem, true);
|
||||
if(!isNaN(attrVal)) {
|
||||
attrVal = shortFloat(attrVal);
|
||||
attrVal = svgedit.units.shortFloat(attrVal);
|
||||
} else if(unit_re.test(attrVal)) {
|
||||
attrVal = shortFloat(attrVal) + unit;
|
||||
attrVal = svgedit.units.shortFloat(attrVal) + unit;
|
||||
}
|
||||
|
||||
// Embed images when saving
|
||||
|
@ -6350,9 +6348,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
|
||||
|
@ -6363,17 +6361,11 @@ this.getSvgString = function() {
|
|||
//
|
||||
this.randomizeIds = function() {
|
||||
if (arguments.length > 0 && arguments[0] == false) {
|
||||
randomize_ids = false;
|
||||
if (extensions["Arrows"]) call("unsetarrownonce") ;
|
||||
svgedit.draw.randomizeIds(false, getCurrentDrawing());
|
||||
} else {
|
||||
randomize_ids = true;
|
||||
var drawing = getCurrentDrawing();
|
||||
if (!drawing.getSvgElem().getAttributeNS(se_ns, 'nonce')) {
|
||||
drawing.setNonce(nonce);
|
||||
if (extensions["Arrows"]) call("setarrownonce", nonce);
|
||||
}
|
||||
svgedit.draw.randomizeIds(true, getCurrentDrawing());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Function: uniquifyElems
|
||||
// Ensure each element has a unique ID
|
||||
|
@ -6472,9 +6464,16 @@ var uniquifyElems = this.uniquifyElems = function(g) {
|
|||
// Function setUseData
|
||||
// Assigns reference data for each use element
|
||||
var setUseData = this.setUseData = function(parent) {
|
||||
$(parent).find('use').each(function() {
|
||||
var elems = $(parent);
|
||||
|
||||
if(parent.tagName !== 'use') {
|
||||
elems = elems.find('use');
|
||||
}
|
||||
|
||||
elems.each(function() {
|
||||
var id = getHref(this).substr(1);
|
||||
var ref_elem = getElem(id);
|
||||
if(!ref_elem) return;
|
||||
$(this).data('ref', ref_elem);
|
||||
if(ref_elem.tagName == 'symbol' || ref_elem.tagName == 'svg') {
|
||||
$(this).data('symbol', ref_elem);
|
||||
|
@ -6669,8 +6668,11 @@ var convertToGroup = this.convertToGroup = function(elem) {
|
|||
|
||||
selectOnly([g]);
|
||||
|
||||
batchCmd.addSubCommand(pushGroupProperties(g, true));
|
||||
//
|
||||
var cm = pushGroupProperties(g, true);
|
||||
if(cm) {
|
||||
batchCmd.addSubCommand(cm);
|
||||
}
|
||||
|
||||
addCommandToHistory(batchCmd);
|
||||
|
||||
} else {
|
||||
|
@ -6706,19 +6708,16 @@ this.setSvgString = function(xmlString) {
|
|||
|
||||
var content = $(svgcontent);
|
||||
|
||||
current_drawing = new svgedit.draw.Drawing(svgcontent, idprefix);
|
||||
canvas.current_drawing_ = new svgedit.draw.Drawing(svgcontent, idprefix);
|
||||
|
||||
// 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) {
|
||||
current_drawing.setNonce(nonce);
|
||||
if (extensions["Arrows"]) call("setarrownonce", nonce) ;
|
||||
var nonce = getCurrentDrawing().getNonce();
|
||||
if (nonce) {
|
||||
call("setnonce", nonce);
|
||||
} else {
|
||||
call("unsetnonce");
|
||||
}
|
||||
|
||||
|
||||
// change image href vals if possible
|
||||
content.find('image').each(function() {
|
||||
var image = this;
|
||||
|
@ -7042,10 +7041,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
|
||||
|
@ -7086,18 +7085,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;
|
||||
|
@ -7116,7 +7116,7 @@ this.renameCurrentLayer = function(newname) {
|
|||
}
|
||||
}
|
||||
}
|
||||
current_drawing.current_layer = oldLayer;
|
||||
drawing.current_layer = oldLayer;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
@ -7133,31 +7133,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;
|
||||
}
|
||||
|
@ -7207,9 +7208,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;
|
||||
}
|
||||
}
|
||||
|
@ -7237,28 +7239,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();
|
||||
|
@ -7269,13 +7272,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));
|
||||
}
|
||||
|
@ -7342,29 +7346,26 @@ var setContext = this.setContext = function(elem) {
|
|||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
// clear the svgcontent node
|
||||
canvas.clearSvgContentElement();
|
||||
|
||||
// create new document
|
||||
canvas.current_drawing_ = new svgedit.draw.Drawing(svgcontent);
|
||||
|
||||
// create empty first layer
|
||||
current_drawing.all_layers = [];
|
||||
|
||||
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");
|
||||
};
|
||||
|
||||
|
@ -7407,7 +7408,7 @@ this.getZoom = function(){return current_zoom;};
|
|||
// Function: getVersion
|
||||
// Returns a string which describes the revision number of SvgCanvas.
|
||||
this.getVersion = function() {
|
||||
return "svgcanvas.js ($Rev: 1961 $)";
|
||||
return "svgcanvas.js ($Rev: 1972 $)";
|
||||
};
|
||||
|
||||
// Function: setUiStrings
|
||||
|
@ -8730,8 +8731,8 @@ var changeSelectedAttributeNoUndo = function(attr, newValue, elems) {
|
|||
selectedBBoxes[i] = getBBox(elem);
|
||||
// Use the Firefox ffClone hack for text elements with gradients or
|
||||
// where other text attributes are changed.
|
||||
if(elem.nodeName == 'text') {
|
||||
if((newValue+'').indexOf('url') == 0 || ['font-size','font-family','x','y'].indexOf(attr) >= 0 && elem.textContent) {
|
||||
if(svgedit.browser.isGecko() && elem.nodeName === 'text' && /rotate/.test(elem.getAttribute('transform'))) {
|
||||
if((newValue+'').indexOf('url') === 0 || ['font-size','font-family','x','y'].indexOf(attr) >= 0 && elem.textContent) {
|
||||
elem = ffClone(elem);
|
||||
}
|
||||
}
|
||||
|
@ -9015,6 +9016,8 @@ var pushGroupProperties = this.pushGroupProperties = function(g, undoable) {
|
|||
for(var i = 0; i < len; i++) {
|
||||
var elem = children[i];
|
||||
|
||||
if(elem.nodeType !== 1) continue;
|
||||
|
||||
if(gattrs.opacity !== null && gattrs.opacity !== 1) {
|
||||
var c_opac = elem.getAttribute('opacity') || 1;
|
||||
var new_opac = Math.round((elem.getAttribute('opacity') || 1) * gattrs.opacity * 100)/100;
|
||||
|
@ -9149,7 +9152,8 @@ var pushGroupProperties = this.pushGroupProperties = function(g, undoable) {
|
|||
newxform.setMatrix(gm);
|
||||
chtlist.appendItem(newxform);
|
||||
}
|
||||
batchCmd.addSubCommand(recalculateDimensions(elem));
|
||||
var cmd = recalculateDimensions(elem);
|
||||
if(cmd) batchCmd.addSubCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9670,7 +9674,6 @@ this.getPrivateMethods = function() {
|
|||
round: round,
|
||||
runExtensions: runExtensions,
|
||||
sanitizeSvg: sanitizeSvg,
|
||||
shortFloat: shortFloat,
|
||||
SVGEditTransformList: svgedit.transformlist.SVGTransformList,
|
||||
toString: toString,
|
||||
transformBox: svgedit.math.transformBox,
|
||||
|
|
|
@ -186,7 +186,7 @@ svgedit.utilities.convertToXMLReferences = function(input) {
|
|||
return output;
|
||||
};
|
||||
|
||||
// Function: text2xml
|
||||
// Function: svgedit.utilities.text2xml
|
||||
// Cross-browser compatible method of converting a string to an XML tree
|
||||
// found this function here: http://groups.google.com/group/jquery-dev/browse_thread/thread/c6d11387c580a77f
|
||||
svgedit.utilities.text2xml = function(sXML) {
|
||||
|
@ -209,7 +209,7 @@ svgedit.utilities.text2xml = function(sXML) {
|
|||
return out;
|
||||
};
|
||||
|
||||
// Function: bboxToObj
|
||||
// Function: svgedit.utilities.bboxToObj
|
||||
// Converts a SVGRect into an object.
|
||||
//
|
||||
// Parameters:
|
||||
|
@ -226,7 +226,7 @@ svgedit.utilities.bboxToObj = function(bbox) {
|
|||
}
|
||||
};
|
||||
|
||||
// Function: walkTree
|
||||
// Function: svgedit.utilities.walkTree
|
||||
// Walks the tree and executes the callback on each element in a top-down fashion
|
||||
//
|
||||
// Parameters:
|
||||
|
@ -242,7 +242,7 @@ svgedit.utilities.walkTree = function(elem, cbFn){
|
|||
}
|
||||
};
|
||||
|
||||
// Function: walkTreePost
|
||||
// Function: svgedit.utilities.walkTreePost
|
||||
// Walks the tree and executes the callback on each element in a depth-first fashion
|
||||
// TODO: FIXME: Shouldn't this be calling walkTreePost?
|
||||
//
|
||||
|
@ -418,7 +418,7 @@ svgedit.utilities.getBBox = function(elem) {
|
|||
selected.textContent = 'a'; // Some character needed for the selector to use.
|
||||
ret = selected.getBBox();
|
||||
selected.textContent = '';
|
||||
} else if(elname === 'path' && svgedit.browser.isWebkit()) {
|
||||
} else if(elname === 'path' && !svgedit.browser.supportsPathBBox()) {
|
||||
ret = svgedit.utilities.getPathBBox(selected);
|
||||
} else if(elname === 'use' && !svgedit.browser.isWebkit() || elname === 'foreignObject') {
|
||||
ret = selected.getBBox();
|
||||
|
|
|
@ -51,6 +51,7 @@ var typeMap_ = {px: 1};
|
|||
* function getElement() - returns an element in the container given an id
|
||||
* function getHeight() - returns the container's height
|
||||
* function getWidth() - returns the container's width
|
||||
* function getRoundDigits() - returns the number of digits number should be rounded to
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -95,6 +96,26 @@ svgedit.units.getTypeMap = function() {
|
|||
return typeMap_;
|
||||
};
|
||||
|
||||
// Function: svgedit.units.shortFloat
|
||||
// Rounds a given value to a float with number of digits defined in save_options
|
||||
//
|
||||
// Parameters:
|
||||
// val - The value as a String, Number or Array of two numbers to be rounded
|
||||
//
|
||||
// Returns:
|
||||
// If a string/number was given, returns a Float. If an array, return a string
|
||||
// with comma-seperated floats
|
||||
svgedit.units.shortFloat = function(val) {
|
||||
var digits = elementContainer_.getRoundDigits();
|
||||
if(!isNaN(val)) {
|
||||
// Note that + converts to Number
|
||||
return +((+val).toFixed(digits));
|
||||
} else if($.isArray(val)) {
|
||||
return svgedit.units.shortFloat(val[0]) + ',' + svgedit.units.shortFloat(val[1]);
|
||||
}
|
||||
return parseFloat(val).toFixed(digits) - 0;
|
||||
};
|
||||
|
||||
// Function: svgedit.units.convertUnit
|
||||
// Converts the number to given unit or baseUnit
|
||||
svgedit.units.convertUnit = function(val, unit) {
|
||||
|
@ -102,7 +123,7 @@ svgedit.units.convertUnit = function(val, unit) {
|
|||
// baseVal.convertToSpecifiedUnits(unitNumMap[unit]);
|
||||
// var val = baseVal.valueInSpecifiedUnits;
|
||||
// baseVal.convertToSpecifiedUnits(1);
|
||||
return val / typeMap_[unit];
|
||||
return svgedit.unit.shortFloat(val / typeMap_[unit]);
|
||||
};
|
||||
|
||||
// Function: svgedit.units.setUnitAttr
|
||||
|
@ -249,7 +270,9 @@ svgedit.units.isValidUnit = function(attr, val) {
|
|||
result = (elem == null);
|
||||
} catch(e) {}
|
||||
return result;
|
||||
} else valid = true;
|
||||
} else {
|
||||
valid = true;
|
||||
}
|
||||
|
||||
return valid;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue