Update SVG-Edit
Version 2.5.1
This commit is contained in:
parent
8e57e97869
commit
113e0af736
10 changed files with 723 additions and 335 deletions
|
@ -1253,9 +1253,11 @@ var SelectorManager;
|
|||
// The bbox for a group does not include stroke vals, so we
|
||||
// get the bbox based on its children.
|
||||
var stroked_bbox = getStrokedBBox(selected.childNodes);
|
||||
$.each(bbox, function(key, val) {
|
||||
bbox[key] = stroked_bbox[key];
|
||||
});
|
||||
if(stroked_bbox) {
|
||||
$.each(bbox, function(key, val) {
|
||||
bbox[key] = stroked_bbox[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// loop and transform our bounding box until we reach our first rotation
|
||||
|
@ -1834,8 +1836,8 @@ var addSvgElementFromJson = this.addSvgElementFromJson = function(data) {
|
|||
(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);
|
||||
// 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");
|
||||
|
@ -2280,7 +2282,12 @@ var copyElem = function(el) {
|
|||
|
||||
if($(el).data('gsvg')) {
|
||||
$(new_el).data('gsvg', new_el.firstChild);
|
||||
} else if(new_el.tagName == 'image') {
|
||||
} else if($(el).data('symbol')) {
|
||||
var ref = $(el).data('symbol');
|
||||
$(new_el).data('ref', ref).data('symbol', ref);
|
||||
}
|
||||
|
||||
else if(new_el.tagName == 'image') {
|
||||
preventClickDefault(new_el);
|
||||
}
|
||||
return new_el;
|
||||
|
@ -2885,10 +2892,10 @@ var remapElement = this.remapElement = function(selected,changes,m) {
|
|||
changes["height"] = scaleh(changes["height"]);
|
||||
break;
|
||||
case "use":
|
||||
var pt1 = remap(changes["x"],changes["y"]);
|
||||
changes["x"] = pt1.x;
|
||||
changes["y"] = pt1.y;
|
||||
break;
|
||||
// var pt1 = remap(changes["x"],changes["y"]);
|
||||
// changes["x"] = pt1.x;
|
||||
// changes["y"] = pt1.y;
|
||||
// break;
|
||||
case "g":
|
||||
case "text":
|
||||
// if it was a translate, then just update x,y
|
||||
|
@ -2999,9 +3006,6 @@ var remapElement = this.remapElement = function(selected,changes,m) {
|
|||
changes.height = Math.abs(changes.height);
|
||||
assignAttributes(selected, changes, 1000, true);
|
||||
break;
|
||||
case "use":
|
||||
assignAttributes(selected, changes, 1000, true);
|
||||
break;
|
||||
case "ellipse":
|
||||
changes.rx = Math.abs(changes.rx);
|
||||
changes.ry = Math.abs(changes.ry);
|
||||
|
@ -3009,6 +3013,7 @@ var remapElement = this.remapElement = function(selected,changes,m) {
|
|||
if(changes.r) changes.r = Math.abs(changes.r);
|
||||
case "line":
|
||||
case "text":
|
||||
case "use":
|
||||
assignAttributes(selected, changes, 1000, true);
|
||||
break;
|
||||
case "g":
|
||||
|
@ -3168,8 +3173,6 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
attrs = ["width", "height", "x", "y"];
|
||||
break;
|
||||
case "use":
|
||||
attrs = ["x", "y"];
|
||||
break;
|
||||
case "text":
|
||||
attrs = ["x", "y"];
|
||||
break;
|
||||
|
@ -3280,6 +3283,22 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
if (!childTlist) continue;
|
||||
|
||||
var m = transformListToTransform(childTlist).matrix;
|
||||
|
||||
// Convert a matrix to a scale if applicable
|
||||
// if(hasMatrixTransform(childTlist) && childTlist.numberOfItems == 1) {
|
||||
// if(m.b==0 && m.c==0 && m.e==0 && m.f==0) {
|
||||
// childTlist.removeItem(0);
|
||||
// var translateOrigin = svgroot.createSVGTransform(),
|
||||
// scale = svgroot.createSVGTransform(),
|
||||
// translateBack = svgroot.createSVGTransform();
|
||||
// translateOrigin.setTranslate(0, 0);
|
||||
// scale.setScale(m.a, m.d);
|
||||
// translateBack.setTranslate(0, 0);
|
||||
// childTlist.appendItem(translateBack);
|
||||
// childTlist.appendItem(scale);
|
||||
// childTlist.appendItem(translateOrigin);
|
||||
// }
|
||||
// }
|
||||
|
||||
var angle = getRotationAngle(child);
|
||||
var old_start_transform = start_transform;
|
||||
|
@ -3445,6 +3464,8 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
start_transform = child.getAttribute("transform");
|
||||
var childTlist = getTransformList(child);
|
||||
|
||||
if (!childTlist) continue;
|
||||
|
||||
var em = matrixMultiply(m, transformListToTransform(childTlist).matrix);
|
||||
var e2m = svgroot.createSVGTransform();
|
||||
e2m.setMatrix(em);
|
||||
|
@ -3595,8 +3616,11 @@ var recalculateDimensions = this.recalculateDimensions = function(selected) {
|
|||
// if we had [M][T][S][T] we want to extract the matrix equivalent of
|
||||
// [T][S][T] and push it down to the element
|
||||
if (N >= 3 && tlist.getItem(N-2).type == 3 &&
|
||||
tlist.getItem(N-3).type == 2 && tlist.getItem(N-1).type == 2 &&
|
||||
selected.nodeName != "use")
|
||||
tlist.getItem(N-3).type == 2 && tlist.getItem(N-1).type == 2)
|
||||
|
||||
// Removed this so a <use> with a given [T][S][T] would convert to a matrix.
|
||||
// Is that bad?
|
||||
// && selected.nodeName != "use"
|
||||
{
|
||||
operation = 3; // scale
|
||||
m = transformListToTransform(tlist,N-3,N-1).matrix;
|
||||
|
@ -4522,12 +4546,13 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
|||
// to be a translate
|
||||
var xform = svgroot.createSVGTransform();
|
||||
var tlist = getTransformList(selected);
|
||||
// Note that if Webkit and there's no ID for this
|
||||
// element, the dummy transform may have gotten lost.
|
||||
// This results in unexpected behaviour
|
||||
|
||||
xform.setTranslate(dx,dy);
|
||||
if(tlist.numberOfItems) {
|
||||
tlist.replaceItem(xform, 0);
|
||||
// TODO: Webkit returns null here, find out why
|
||||
// console.log(selected.getAttribute("transform"))
|
||||
|
||||
} else {
|
||||
tlist.appendItem(xform);
|
||||
}
|
||||
|
@ -5077,7 +5102,10 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
|
|||
to: cur_shape.opacity,
|
||||
dur: ani_dur
|
||||
}).appendTo(element);
|
||||
c_ani[0].beginElement();
|
||||
try {
|
||||
// Fails in FF4 on foreignObject
|
||||
c_ani[0].beginElement();
|
||||
} catch(e){}
|
||||
} else {
|
||||
ani_dur = 0;
|
||||
}
|
||||
|
@ -5174,6 +5202,7 @@ var textActions = canvas.textActions = function() {
|
|||
|
||||
function setCursor(index) {
|
||||
var empty = (textinput.value === "");
|
||||
$(textinput).focus();
|
||||
|
||||
if(!arguments.length) {
|
||||
if(empty) {
|
||||
|
@ -5430,6 +5459,8 @@ var textActions = canvas.textActions = function() {
|
|||
allow_dbl = false;
|
||||
current_mode = "textedit";
|
||||
selectorManager.requestSelector(curtext).showGrips(false);
|
||||
// Make selector group accept clicks
|
||||
var sel = selectorManager.requestSelector(curtext).selectorRect;
|
||||
|
||||
textActions.init();
|
||||
$(curtext).css('cursor', 'text');
|
||||
|
@ -5480,7 +5511,7 @@ var textActions = canvas.textActions = function() {
|
|||
},
|
||||
setInputElem: function(elem) {
|
||||
textinput = elem;
|
||||
$(textinput).blur(hideCursor);
|
||||
// $(textinput).blur(hideCursor);
|
||||
},
|
||||
clear: function() {
|
||||
current_text = null;
|
||||
|
@ -5562,7 +5593,9 @@ var pathActions = this.pathActions = function() {
|
|||
8: ['x','y','x1','y1'],
|
||||
10: ['x','y','r1','r2','angle','largeArcFlag','sweepFlag'],
|
||||
12: ['x'],
|
||||
14: ['y']
|
||||
14: ['y'],
|
||||
16: ['x','y','x2','y2'],
|
||||
18: ['x','y']
|
||||
};
|
||||
|
||||
function retPath() {
|
||||
|
@ -7823,6 +7856,94 @@ var uniquifyElems = this.uniquifyElems = function(g) {
|
|||
obj_num++;
|
||||
}
|
||||
|
||||
// Function: convertToGroup
|
||||
// Converts selected/given <use> or child SVG element to a group
|
||||
var convertToGroup = this.convertToGroup = function(elem) {
|
||||
if(!elem) {
|
||||
elem = selectedElements[0];
|
||||
}
|
||||
var $elem = $(elem);
|
||||
|
||||
var batchCmd = new BatchCommand();
|
||||
|
||||
var ts;
|
||||
|
||||
if($elem.data('gsvg')) {
|
||||
// Use the gsvg as the new group
|
||||
var svg = elem.firstChild;
|
||||
var pt = $(svg).attr(['x', 'y']);
|
||||
|
||||
$(elem.firstChild.firstChild).unwrap();
|
||||
$(elem).removeData('gsvg');
|
||||
|
||||
var tlist = getTransformList(elem);
|
||||
var xform = svgroot.createSVGTransform();
|
||||
xform.setTranslate(pt.x, pt.y);
|
||||
tlist.appendItem(xform);
|
||||
recalculateDimensions(elem);
|
||||
call("selected", [elem]);
|
||||
} else if($elem.data('symbol')) {
|
||||
elem = $elem.data('symbol');
|
||||
|
||||
ts = $elem.attr('transform');
|
||||
var pos = $elem.attr(['x','y']);
|
||||
|
||||
// Not ideal, but works
|
||||
ts += "translate(" + pos.x + "," + pos.y + ")";
|
||||
|
||||
var prev = $elem.prev();
|
||||
|
||||
// Remove <use> element
|
||||
batchCmd.addSubCommand(new RemoveElementCommand($elem[0], $elem[0].parentNode));
|
||||
$elem.remove();
|
||||
|
||||
// See if other elements reference this symbol
|
||||
var has_more = $(svgcontent).find('use:data(symbol)').length;
|
||||
|
||||
var g = svgdoc.createElementNS(svgns, "g");
|
||||
var childs = elem.childNodes;
|
||||
|
||||
for(var i = 0; i < childs.length; i++) {
|
||||
g.appendChild(childs[i].cloneNode(true));
|
||||
}
|
||||
|
||||
// while (elem.hasChildNodes())
|
||||
// g.appendChild(elem.firstChild.cloneNode(true));
|
||||
if (ts)
|
||||
g.setAttribute("transform", ts);
|
||||
|
||||
var parent = elem.parentNode;
|
||||
|
||||
uniquifyElems(g);
|
||||
|
||||
// now give the g itself a new id
|
||||
g.id = getNextId();
|
||||
|
||||
prev.after(g);
|
||||
|
||||
if(parent) {
|
||||
if(!has_more) {
|
||||
// remove symbol/svg element
|
||||
parent.removeChild(elem);
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(elem, parent));
|
||||
}
|
||||
batchCmd.addSubCommand(new InsertElementCommand(g));
|
||||
}
|
||||
|
||||
// recalculate dimensions on the top-level children so that unnecessary transforms
|
||||
// are removed
|
||||
walkTreePost(g, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
|
||||
|
||||
clearSelection();
|
||||
addToSelection([g]);
|
||||
|
||||
addCommandToHistory(batchCmd);
|
||||
|
||||
} else {
|
||||
console.log('Unexpected element to ungroup:', elem);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Function: setSvgString
|
||||
// This function sets the current drawing as the input SVG XML.
|
||||
|
@ -7879,11 +8000,14 @@ this.setSvgString = function(xmlString) {
|
|||
|
||||
// Wrap child SVGs in group elements
|
||||
$(svgcontent).find('svg').each(function() {
|
||||
// Skip if it's in a <defs>
|
||||
if($(this).closest('defs').length) return;
|
||||
|
||||
uniquifyElems(this);
|
||||
|
||||
// Check if it already has a gsvg group
|
||||
var pa = this.parentNode;
|
||||
if(pa.children.length === 1 && pa.nodeName === 'g') {
|
||||
if(pa.childNodes.length === 1 && pa.nodeName === 'g') {
|
||||
$(pa).data('gsvg', this);
|
||||
pa.id = pa.id || getNextId();
|
||||
} else {
|
||||
|
@ -7891,6 +8015,16 @@ this.setSvgString = function(xmlString) {
|
|||
}
|
||||
});
|
||||
|
||||
// Set ref element for <use> elements
|
||||
$(svgcontent).find('use').each(function() {
|
||||
var id = this.getAttributeNS(xlinkns,"href").substr(1);
|
||||
var ref_elem = getElem(id);
|
||||
$(this).data('ref', ref_elem);
|
||||
if(ref_elem.tagName == 'symbol' || ref_elem.tagName == 'svg') {
|
||||
$(this).data('symbol', ref_elem);
|
||||
}
|
||||
});
|
||||
|
||||
// convert gradients with userSpaceOnUse to objectBoundingBox
|
||||
$(svgcontent).find('linearGradient, radialGradient').each(function() {
|
||||
var grad = this;
|
||||
|
@ -8013,12 +8147,11 @@ this.setSvgString = function(xmlString) {
|
|||
};
|
||||
|
||||
// Function: importSvgString
|
||||
// This function imports the input SVG XML into the current layer in the drawing
|
||||
// This function imports the input SVG XML as a <symbol> in the <defs>, then adds a
|
||||
// <use> to the current layer.
|
||||
//
|
||||
// Parameters:
|
||||
// xmlString - The SVG as XML text.
|
||||
// toElements - Boolean indicating whether or not to convert the SVG to a group
|
||||
// with children
|
||||
//
|
||||
// Returns:
|
||||
// This function returns false if the import was unsuccessful, true otherwise.
|
||||
|
@ -8029,8 +8162,7 @@ this.setSvgString = function(xmlString) {
|
|||
// arbitrary transform lists, but makes some assumptions about how the transform list
|
||||
// was obtained
|
||||
// * import should happen in top-left of current zoomed viewport
|
||||
// * create a new layer for the imported SVG
|
||||
this.importSvgString = function(xmlString, toElements) {
|
||||
this.importSvgString = function(xmlString) {
|
||||
try {
|
||||
// convert string into XML document
|
||||
var newDoc = Utils.text2xml(xmlString);
|
||||
|
@ -8040,11 +8172,11 @@ this.importSvgString = function(xmlString, toElements) {
|
|||
var batchCmd = new BatchCommand("Change Source");
|
||||
|
||||
// import new svg document into our document
|
||||
var importedNode = svgdoc.importNode(newDoc.documentElement, true);
|
||||
var svg = svgdoc.importNode(newDoc.documentElement, true);
|
||||
|
||||
var innerw = convertToNum('width', importedNode.getAttribute("width")),
|
||||
innerh = convertToNum('height', importedNode.getAttribute("height")),
|
||||
innervb = importedNode.getAttribute("viewBox"),
|
||||
var innerw = convertToNum('width', svg.getAttribute("width")),
|
||||
innerh = convertToNum('height', svg.getAttribute("height")),
|
||||
innervb = svg.getAttribute("viewBox"),
|
||||
// if no explicit viewbox, create one out of the width and height
|
||||
vb = innervb ? innervb.split(" ") : [0,0,innerw,innerh];
|
||||
for (var j = 0; j < 4; ++j)
|
||||
|
@ -8064,79 +8196,40 @@ this.importSvgString = function(xmlString, toElements) {
|
|||
|
||||
// Hack to make recalculateDimensions understand how to scale
|
||||
ts = "translate(0) " + ts + " translate(0)";
|
||||
|
||||
if(!toElements) {
|
||||
var elem = $(importedNode).appendTo(current_layer)[0];
|
||||
groupSvgElem(elem);
|
||||
clearSelection();
|
||||
|
||||
var g = elem.parentNode;
|
||||
|
||||
g.setAttribute("transform", ts);
|
||||
recalculateDimensions(g);
|
||||
|
||||
addToSelection([g]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Uncomment this once Firefox has fixed their symbol bug:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=353575
|
||||
// var symbol = svgdoc.createElementNS(svgns, "symbol");
|
||||
// while (svg.firstChild) {
|
||||
// symbol.appendChild(svg.firstChild);
|
||||
// }
|
||||
// var attrs = svg.attributes;
|
||||
// for(var i=0; i < attrs.length; i++) {
|
||||
// var attr = attrs[i];
|
||||
// symbol.setAttribute(attr.nodeName, attr.nodeValue);
|
||||
// }
|
||||
var symbol = svg;
|
||||
symbol.id = getNextId();
|
||||
|
||||
var use_el = svgdoc.createElementNS(svgns, "use");
|
||||
use_el.id = getNextId();
|
||||
use_el.setAttributeNS(xlinkns, "xlink:href", "#" + symbol.id);
|
||||
findDefs().appendChild(symbol);
|
||||
current_layer.appendChild(use_el);
|
||||
clearSelection();
|
||||
|
||||
use_el.setAttribute("transform", ts);
|
||||
recalculateDimensions(use_el);
|
||||
$(use_el).data('symbol', symbol);
|
||||
addToSelection([use_el]);
|
||||
return true;
|
||||
|
||||
|
||||
// TODO: Find way to add this in a recalculateDimensions-parsable way
|
||||
// if (vb[0] != 0 || vb[1] != 0)
|
||||
// ts = "translate(" + (-vb[0]) + "," + (-vb[1]) + ") " + ts;
|
||||
|
||||
// add all children of the imported <svg> to the <g> we create
|
||||
var g = svgdoc.createElementNS(svgns, "g");
|
||||
while (importedNode.hasChildNodes())
|
||||
g.appendChild(importedNode.firstChild);
|
||||
if (ts)
|
||||
g.setAttribute("transform", ts);
|
||||
|
||||
uniquifyElems(g);
|
||||
|
||||
// now give the g itself a new id
|
||||
g.id = getNextId();
|
||||
|
||||
current_layer.appendChild(g);
|
||||
|
||||
// change image href vals if possible
|
||||
// $(svgcontent).find('image').each(function() {
|
||||
// var image = this;
|
||||
// preventClickDefault(image);
|
||||
// var val = this.getAttributeNS(xlinkns, "href");
|
||||
// if(val.indexOf('data:') === 0) {
|
||||
// // Check if an SVG-edit data URI
|
||||
// var m = val.match(/svgedit_url=(.*?);/);
|
||||
// if(m) {
|
||||
// var url = decodeURIComponent(m[1]);
|
||||
// $(new Image()).load(function() {
|
||||
// image.setAttributeNS(xlinkns,'xlink:href',url);
|
||||
// }).attr('src',url);
|
||||
// }
|
||||
// }
|
||||
// // Add to encodableImages if it loads
|
||||
// canvas.embedImage(val);
|
||||
// });
|
||||
|
||||
|
||||
// recalculate dimensions on the top-level children so that unnecessary transforms
|
||||
// are removed
|
||||
walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
|
||||
|
||||
|
||||
batchCmd.addSubCommand(new InsertElementCommand(svgcontent));
|
||||
|
||||
// reset zoom - TODO: why?
|
||||
// current_zoom = 1;
|
||||
|
||||
// identify layers
|
||||
// identifyLayers();
|
||||
|
||||
// reset transform lists
|
||||
svgTransformLists = {};
|
||||
clearSelection();
|
||||
|
||||
addCommandToHistory(batchCmd);
|
||||
call("changed", [svgcontent]);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return false;
|
||||
|
@ -8614,7 +8707,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: 1636 $)";
|
||||
return "svgcanvas.js ($Rev: 1653 $)";
|
||||
};
|
||||
|
||||
// Function: setUiStrings
|
||||
|
@ -8636,9 +8729,12 @@ this.setConfig = function(opts) {
|
|||
}
|
||||
|
||||
// Function: getDocumentTitle
|
||||
// Returns the current document title or an empty string if not found
|
||||
this.getDocumentTitle = function() {
|
||||
var childs = svgcontent.childNodes;
|
||||
// Returns the current group/SVG's title contents
|
||||
this.getTitle = function(elem) {
|
||||
elem = elem || selectedElements[0];
|
||||
if(!elem) return;
|
||||
elem = $(elem).data('gsvg') || $(elem).data('symbol') || elem;
|
||||
var childs = elem.childNodes;
|
||||
for (var i=0; i<childs.length; i++) {
|
||||
if(childs[i].nodeName == 'title') {
|
||||
return childs[i].textContent;
|
||||
|
@ -8647,6 +8743,43 @@ this.getDocumentTitle = function() {
|
|||
return '';
|
||||
}
|
||||
|
||||
// Function: setGroupTitle
|
||||
// Sets the group/SVG's title content
|
||||
// TODO: Combine this with setDocumentTitle
|
||||
this.setGroupTitle = function(val) {
|
||||
var elem = selectedElements[0];
|
||||
elem = $(elem).data('gsvg') || elem;
|
||||
|
||||
var ts = $(elem).children('title');
|
||||
|
||||
var batchCmd = new BatchCommand("Set Label");
|
||||
|
||||
if(!val.length) {
|
||||
// Remove title element
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(ts[0], elem));
|
||||
ts.remove();
|
||||
} else if(ts.length) {
|
||||
// Change title contents
|
||||
var title = ts[0];
|
||||
batchCmd.addSubCommand(new ChangeElementCommand(title, {'#text': title.textContent}));
|
||||
title.textContent = val;
|
||||
} else {
|
||||
// Add title element
|
||||
title = svgdoc.createElementNS(svgns, "title");
|
||||
title.textContent = val;
|
||||
$(elem).prepend(title);
|
||||
batchCmd.addSubCommand(new InsertElementCommand(title));
|
||||
}
|
||||
|
||||
addCommandToHistory(batchCmd);
|
||||
}
|
||||
|
||||
// Function: getDocumentTitle
|
||||
// Returns the current document title or an empty string if not found
|
||||
this.getDocumentTitle = function() {
|
||||
return canvas.getTitle(svgcontent);
|
||||
}
|
||||
|
||||
// Function: setDocumentTitle
|
||||
// Adds/updates a title element for the document with the given name.
|
||||
// This is an undoable action
|
||||
|
@ -9357,6 +9490,9 @@ this.setBold = function(b) {
|
|||
{
|
||||
changeSelectedAttribute("font-weight", b ? "bold" : "normal");
|
||||
}
|
||||
if(!selectedElements[0].textContent) {
|
||||
textActions.setCursor();
|
||||
}
|
||||
};
|
||||
|
||||
// Function: getItalic
|
||||
|
@ -9386,6 +9522,9 @@ this.setItalic = function(i) {
|
|||
{
|
||||
changeSelectedAttribute("font-style", i ? "italic" : "normal");
|
||||
}
|
||||
if(!selectedElements[0].textContent) {
|
||||
textActions.setCursor();
|
||||
}
|
||||
};
|
||||
|
||||
// Function: getFontFamily
|
||||
|
@ -9402,6 +9541,9 @@ this.getFontFamily = function() {
|
|||
this.setFontFamily = function(val) {
|
||||
cur_text.font_family = val;
|
||||
changeSelectedAttribute("font-family", val);
|
||||
if(selectedElements[0] && !selectedElements[0].textContent) {
|
||||
textActions.setCursor();
|
||||
}
|
||||
};
|
||||
|
||||
// Function: getFontSize
|
||||
|
@ -9417,8 +9559,10 @@ this.getFontSize = function() {
|
|||
// val - Float with the new font size
|
||||
this.setFontSize = function(val) {
|
||||
cur_text.font_size = val;
|
||||
textActions.toSelectMode();
|
||||
changeSelectedAttribute("font-size", val);
|
||||
if(!selectedElements[0].textContent) {
|
||||
textActions.setCursor();
|
||||
}
|
||||
};
|
||||
|
||||
// Function: getText
|
||||
|
@ -9723,7 +9867,7 @@ var changeSelectedAttributeNoUndo = function(attr, newValue, elems) {
|
|||
if (elem == null) continue;
|
||||
|
||||
// Go into "select" mode for text changes
|
||||
if(current_mode === "textedit" && attr !== "#text") {
|
||||
if(current_mode === "textedit" && attr !== "#text" && elem.textContent.length) {
|
||||
textActions.toSelectMode(elem);
|
||||
}
|
||||
|
||||
|
@ -9771,7 +9915,7 @@ var changeSelectedAttributeNoUndo = function(attr, newValue, elems) {
|
|||
// 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 || $.inArray(attr, ['font-size','font-family','x','y']) != -1) {
|
||||
if((newValue+'').indexOf('url') == 0 || $.inArray(attr, ['font-size','font-family','x','y']) != -1 && elem.textContent) {
|
||||
elem = ffClone(elem);
|
||||
}
|
||||
}
|
||||
|
@ -9899,10 +10043,17 @@ this.groupSelectedElements = function() {
|
|||
// significant recalculations to apply group's transforms, etc to its children
|
||||
this.ungroupSelectedElement = function() {
|
||||
var g = selectedElements[0];
|
||||
if($(g).data('gsvg') || $(g).data('symbol')) {
|
||||
// Is svg, so actually convert to group
|
||||
|
||||
convertToGroup(g);
|
||||
return;
|
||||
}
|
||||
if (g.tagName == "g") {
|
||||
|
||||
var batchCmd = new BatchCommand("Ungroup Elements");
|
||||
var parent = g.parentNode;
|
||||
var anchor = g.previousSibling;
|
||||
var anchor = g.nextSibling;
|
||||
var children = new Array(g.childNodes.length);
|
||||
var xform = g.getAttribute("transform");
|
||||
// get consolidated matrix
|
||||
|
@ -9926,6 +10077,14 @@ this.ungroupSelectedElement = function() {
|
|||
var elem = g.firstChild;
|
||||
var oldNextSibling = elem.nextSibling;
|
||||
var oldParent = elem.parentNode;
|
||||
|
||||
// Remove child title elements
|
||||
if(elem.tagName == 'title') {
|
||||
batchCmd.addSubCommand(new RemoveElementCommand(elem, oldParent));
|
||||
oldParent.removeChild(elem);
|
||||
continue;
|
||||
}
|
||||
|
||||
children[i++] = elem = parent.insertBefore(elem, anchor);
|
||||
batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldParent));
|
||||
|
||||
|
@ -9974,6 +10133,9 @@ this.ungroupSelectedElement = function() {
|
|||
|
||||
var chtlist = getTransformList(elem);
|
||||
|
||||
// Hopefully not a problem to add this. Necessary for elements like <desc/>
|
||||
if(!chtlist) continue;
|
||||
|
||||
if (glist.numberOfItems) {
|
||||
// TODO: if the group's transform is just a rotate, we can always transfer the
|
||||
// rotate() down to the children (collapsing consecutive rotates and factoring
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue