fixed getRefElem and smoothControlPoints leaking variables

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@2402 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Bruno Heridet 2013-02-15 23:05:23 +00:00
parent d5dca6b4a3
commit 7a36f90eb6
5 changed files with 65 additions and 81 deletions

View File

@ -356,7 +356,7 @@ svgedit.path.getSegSelector = function(seg, update) {
//
// Returns:
// Array of two "smoothed" point objects
svgedit.path.smoothControlPoints = this.smoothControlPoints = function(ct1, ct2, pt) {
svgedit.path.smoothControlPoints = function(ct1, ct2, pt) {
// each point must not be the origin
var x1 = ct1.x - pt.x,
y1 = ct1.y - pt.y,

View File

@ -723,7 +723,7 @@
// Call when part of element is in process of changing, generally
// on mousemove actions like rotate, move, etc.
var elementTransition = function(window,elems) {
var elementTransition = function(window, elems) {
var mode = svgCanvas.getMode();
var elem = elems[0];
@ -970,7 +970,7 @@
flyout_funcs[opt]();
}
});
// $('#tools_rect').mouseleave(function(){$('#tools_rect').fadeOut();});
// $('#tools_rect').mouseleave(function(){$('#tools_rect').fadeOut();});
});
setFlyoutTitles();
};
@ -1728,7 +1728,7 @@
// Set up editor background functionality
// TODO add checkerboard as "pattern"
var color_blocks = ['#FFF','#888','#000']; // ,'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP%2F%2F%2F9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG%2Bgq4jM3IFLJgpswNly%2FXkcBpIiVaInlLJr9FZWAQA7)'];
var color_blocks = ['#FFF', '#888', '#000']; // ,'url(data:image/gif;base64,R0lGODlhEAAQAIAAAP%2F%2F%2F9bW1iH5BAAAAAAALAAAAAAQABAAAAIfjG%2Bgq4jM3IFLJgpswNly%2FXkcBpIiVaInlLJr9FZWAQA7)'];
var str = '';
$.each(color_blocks, function() {
str += '<div class="color_block" style="background-color:' + this + ';"></div>';
@ -1842,7 +1842,7 @@
var promptMoveLayerOnce = false;
$('#selLayerNames').change(function(){
var destLayer = this.options[this.selectedIndex].value;
var confirm_str = uiStrings.notification.QmoveElemsToLayer.replace('%s',destLayer);
var confirmStr = uiStrings.notification.QmoveElemsToLayer.replace('%s', destLayer);
var moveToLayer = function(ok) {
if (!ok) return;
promptMoveLayerOnce = true;
@ -1854,7 +1854,7 @@
if (promptMoveLayerOnce) {
moveToLayer(true);
} else {
$.confirm(confirm_str, moveToLayer);
$.confirm(confirmStr, moveToLayer);
}
}
});

View File

@ -39,7 +39,7 @@ if (window.opera) {
// See http://api.jquery.com/attr/ for basic documentation of .attr()
// Additional functionality:
// Additional functionality:
// - When getting attributes, a string that's a number is return as type number.
// - If an array is supplied as first parameter, multiple values are returned
// as an object with values for each given attributes
@ -71,7 +71,6 @@ if (window.opera) {
obj[aname] = attr;
}
return obj;
} else if (typeof key === "object") {
// Setting attributes form object
for (var v in key) {
@ -91,7 +90,6 @@ if (window.opera) {
}
return this;
};
}());
// Class: SvgCanvas
@ -345,7 +343,6 @@ canvas.undoMgr = new svgedit.history.UndoManager({
var elems = cmd.elements();
canvas.pathActions.clear();
call("changed", elems);
var cmdType = cmd.type();
var isApply = (eventType == EventTypes.AFTER_APPLY);
if (cmdType == MoveElementCommand.type()) {
@ -363,7 +360,6 @@ canvas.undoMgr = new svgedit.history.UndoManager({
} else {
if (!isApply) restoreRefElems(cmd.elem);
}
if (cmd.elem.tagName === 'use') {
setUseData(cmd.elem);
}
@ -655,12 +651,12 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
if (!elems.length) return false;
// Make sure the expected BBox is returned if the element is a group
var getCheckedBBox = function(elem) {
try {
// TODO: Fix issue with rotated groups. Currently they work
// fine in FF, but not in other browsers (same problem mentioned
// in Issue 339 comment #2).
var bb = svgedit.utilities.getBBox(elem);
var angle = svgedit.utilities.getRotationAngle(elem);
@ -668,9 +664,7 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
svgedit.math.hasMatrixTransform(svgedit.transformlist.getTransformList(elem))) {
// Accurate way to get BBox of rotated element in Firefox:
// Put element in group and get its BBox
var good_bb = false;
// Get the BBox from the raw path for these elements
var elemNames = ['ellipse', 'path', 'line', 'polyline', 'polygon'];
if (elemNames.indexOf(elem.tagName) >= 0) {
@ -683,10 +677,10 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
bb = good_bb = canvas.convertToPath(elem, true);
}
}
if (!good_bb) {
// Must use clone else FF freaks out
var clone = elem.cloneNode(true);
var clone = elem.cloneNode(true);
var g = document.createElementNS(svgns, "g");
var parent = elem.parentNode;
parent.appendChild(g);
@ -694,7 +688,7 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
bb = svgedit.utilities.bboxToObj(g.getBBox());
parent.removeChild(g);
}
// Old method: Works by giving the rotated BBox,
// this is (unfortunately) what Opera and Safari do
// natively when getting the BBox of the parent group
@ -729,10 +723,10 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
// bb.height = rmaxy - rminy;
}
return bb;
} catch(e) {
} catch(e) {
console.log(elem, e);
return null;
}
}
};
var full_bb;
@ -741,18 +735,18 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
if (!this.parentNode) return;
full_bb = getCheckedBBox(this);
});
// This shouldn't ever happen...
if (full_bb == null) return null;
// full_bb doesn't include the stoke, so this does no good!
// if (elems.length == 1) return full_bb;
var max_x = full_bb.x + full_bb.width;
var max_y = full_bb.y + full_bb.height;
var min_x = full_bb.x;
var min_y = full_bb.y;
// FIXME: same re-creation problem with this function as getCheckedBBox() above
var getOffset = function(elem) {
var sw = elem.getAttribute("stroke-width");
@ -913,7 +907,7 @@ var getId, getNextId, call;
getId = c.getId = function() { return getCurrentDrawing().getId(); };
getNextId = c.getNextId = function() { return getCurrentDrawing().getNextId(); };
// Function: call
// Run the callback function associated with the given event
//
@ -925,14 +919,14 @@ var getId, getNextId, call;
return events[event](this, arg);
}
};
// Function: bind
// Attaches a callback function to an event
//
// Parameters:
// event - String indicating the name of the event
// f - The callback function to bind to the event
//
//
// Return:
// The previous event
c.bind = function(event, f) {
@ -940,7 +934,7 @@ var getId, getNextId, call;
events[event] = f;
return old;
};
}(canvas));
// Function: canvas.prepareSvg
@ -1093,7 +1087,7 @@ var remapElement = this.remapElement = function(selected, changes, m) {
assignAttributes(selected, changes, 1000, true);
}
box = svgedit.utilities.getBBox(selected);
for (var i = 0; i < 2; i++) {
var type = i === 0 ? 'fill' : 'stroke';
var attrVal = selected.getAttribute(type);
@ -1101,15 +1095,15 @@ var remapElement = this.remapElement = function(selected, changes, m) {
if (m.a < 0 || m.d < 0) {
var grad = svgedit.utilities.getRefElem(attrVal);
var newgrad = grad.cloneNode(true);
if (m.a < 0) {
//flip x
var x1 = newgrad.getAttribute('x1');
var x2 = newgrad.getAttribute('x2');
newgrad.setAttribute('x1', -(x1 - 1));
newgrad.setAttribute('x2', -(x2 - 1));
}
}
if (m.d < 0) {
//flip y
var y1 = newgrad.getAttribute('y1');
@ -1369,14 +1363,12 @@ var remapElement = this.remapElement = function(selected, changes, m) {
// ty - The translation's y value
var updateClipPath = function(attr, tx, ty) {
var path = getRefElem(attr).firstChild;
var cp_xform = svgedit.transformlist.getTransformList(path);
var newxlate = svgroot.createSVGTransform();
newxlate.setTranslate(tx, ty);
cp_xform.appendItem(newxlate);
// Update clipPath's dimensions
recalculateDimensions(path);
};

View File

@ -58,15 +58,15 @@ svgedit.utilities.init = function(editorContext) {
svgedit.utilities.toXml = function(str) {
return $('<p/>').text(str).html();
};
// Function: svgedit.utilities.fromXml
// Converts XML entities in a string to single characters.
// Converts XML entities in a string to single characters.
// Example: '&amp;' becomes '&'
//
// Parameters:
// str - The string to be converted
//
// Returns:
// Returns:
// The converted string
svgedit.utilities.fromXml = function(str) {
return $('<p/>').html(str).text();
@ -168,7 +168,7 @@ svgedit.utilities.decode64 = function(input) {
// else if (c > 127) {
// if (c < 2048){
// output += String.fromCharCode((c >> 6) | 192);
// }
// }
// else {
// output += String.fromCharCode((c >> 12) | 224) + String.fromCharCode((c >> 6) & 63 | 128);
// }
@ -178,7 +178,7 @@ svgedit.utilities.decode64 = function(input) {
// return output;
// },
// Function: svgedit.utilities.convertToXMLReferences
// Function: svgedit.utilities.convertToXMLReferences
// Converts a string to use XML references
svgedit.utilities.convertToXMLReferences = function(input) {
var output = '';
@ -205,8 +205,8 @@ svgedit.utilities.text2xml = function(sXML) {
try{
var dXML = (window.DOMParser)?new DOMParser():new ActiveXObject('Microsoft.XMLDOM');
dXML.async = false;
} catch(e){
throw new Error('XML Parser could not be instantiated');
} catch(e){
throw new Error('XML Parser could not be instantiated');
};
try{
if(dXML.loadXML) out = (dXML.loadXML(sXML))?dXML:false;
@ -267,7 +267,7 @@ svgedit.utilities.walkTreePost = function(elem, cbFn) {
};
// Function: svgedit.utilities.getUrlFromAttr
// Extracts the URL from the url(...) syntax of some attributes.
// Extracts the URL from the url(...) syntax of some attributes.
// Three variants:
// * <circle fill="url(someFile.svg#foo)" />
// * <circle fill="url('someFile.svg#foo')" />
@ -275,11 +275,11 @@ svgedit.utilities.walkTreePost = function(elem, cbFn) {
//
// Parameters:
// attrVal - The attribute value as a string
//
//
// Returns:
// String with just the URL, like someFile.svg#foo
svgedit.utilities.getUrlFromAttr = function(attrVal) {
if (attrVal) {
if (attrVal) {
// url("#somegrad")
if (attrVal.indexOf('url("') === 0) {
return attrVal.substring(5, attrVal.indexOf('"',6));
@ -316,8 +316,7 @@ svgedit.utilities.findDefs = function() {
var defs = svgElement.getElementsByTagNameNS(SVGNS, 'defs');
if (defs.length > 0) {
defs = defs[0];
}
else {
} else {
defs = svgElement.ownerDocument.createElementNS(SVGNS, 'defs');
if (svgElement.firstChild) {
// first child is a comment, so call nextSibling
@ -335,7 +334,7 @@ svgedit.utilities.findDefs = function() {
// Get correct BBox for a path in Webkit
// Converted from code found here:
// http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
//
//
// Parameters:
// path - The path DOM element to get the BBox for
//
@ -344,7 +343,7 @@ svgedit.utilities.findDefs = function() {
svgedit.utilities.getPathBBox = function(path) {
var seglist = path.pathSegList;
var tot = seglist.numberOfItems;
var bounds = [[], []];
var start = seglist.getItem(0);
var P0 = [start.x, start.y];
@ -357,7 +356,7 @@ svgedit.utilities.getPathBBox = function(path) {
// Add actual points to limits
bounds[0].push(P0[0]);
bounds[1].push(P0[1]);
if(seg.x1) {
var P1 = [seg.x1, seg.y1],
P2 = [seg.x2, seg.y2],
@ -366,7 +365,7 @@ svgedit.utilities.getPathBBox = function(path) {
for(var j=0; j < 2; j++) {
var calc = function(t) {
return Math.pow(1-t,3) * P0[j]
return Math.pow(1-t,3) * P0[j]
+ 3 * Math.pow(1-t,2) * t * P1[j]
+ 3 * (1-t) * Math.pow(t, 2) * P2[j]
+ Math.pow(t,3) * P3[j];
@ -375,7 +374,7 @@ svgedit.utilities.getPathBBox = function(path) {
var b = 6 * P0[j] - 12 * P1[j] + 6 * P2[j];
var a = -3 * P0[j] + 9 * P1[j] - 9 * P2[j] + 3 * P3[j];
var c = 3 * P1[j] - 3 * P0[j];
if(a == 0) {
if(b == 0) {
continue;
@ -386,7 +385,6 @@ svgedit.utilities.getPathBBox = function(path) {
}
continue;
}
var b2ac = Math.pow(b,2) - 4 * c * a;
if(b2ac < 0) continue;
var t1 = (-b + Math.sqrt(b2ac))/(2 * a);
@ -400,7 +398,7 @@ svgedit.utilities.getPathBBox = function(path) {
bounds[1].push(seg.y);
}
}
var x = Math.min.apply(null, bounds[0]);
var w = Math.max.apply(null, bounds[0]) - x;
var y = Math.min.apply(null, bounds[1]);
@ -419,15 +417,15 @@ svgedit.utilities.getPathBBox = function(path) {
// Note that performance is currently terrible, so some way to improve would
// be great.
//
// Parameters:
// Parameters:
// selected - Container or <use> DOM element
function groupBBFix(selected) {
if(svgedit.browser.supportsHVLineContainerBBox()) {
try { return selected.getBBox();} catch(e){}
try { return selected.getBBox();} catch(e){}
}
var ref = $.data(selected, 'ref');
var matched = null;
if(ref) {
var copy = $(ref).children().clone().attr('visibility', 'hidden');
$(svgroot_).append(copy);
@ -435,7 +433,7 @@ function groupBBFix(selected) {
} else {
matched = $(selected).find('line, path');
}
var issue = false;
if(matched.length) {
matched.each(function() {
@ -470,7 +468,7 @@ svgedit.utilities.getBBox = function(elem) {
if (elem.nodeType != 1) return null;
var ret = null;
var elname = selected.nodeName;
switch ( elname ) {
case 'text':
if(selected.textContent === '') {
@ -497,7 +495,6 @@ svgedit.utilities.getBBox = function(elem) {
if(elname === 'use') {
ret = groupBBFix(selected, true);
}
if(elname === 'use' || ( elname === 'foreignObject' && svgedit.browser.isWebkit() ) ) {
if(!ret) ret = selected.getBBox();
// This is resolved in later versions of webkit, perhaps we should
@ -512,8 +509,8 @@ svgedit.utilities.getBBox = function(elem) {
ret = bb;
//}
} else if(~visElems_arr.indexOf(elname)) {
try { ret = selected.getBBox();}
catch(e) {
try { ret = selected.getBBox();}
catch(e) {
// Check if element is child of a foreignObject
var fo = $(selected).closest('foreignObject');
if(fo.length) {
@ -528,7 +525,6 @@ svgedit.utilities.getBBox = function(elem) {
}
}
}
if(ret) {
ret = svgedit.utilities.bboxToObj(ret);
}
@ -566,7 +562,7 @@ svgedit.utilities.getRotationAngle = function(elem, to_rad) {
//
// Parameters:
// attrVal - The attribute value as a string
svgedit.utilities.getRefElem = this.getRefElem = function(attrVal) {
svgedit.utilities.getRefElem = function(attrVal) {
return svgedit.utilities.getElem(svgedit.utilities.getUrlFromAttr(attrVal).substr(1));
};
@ -585,7 +581,7 @@ if (svgedit.browser.supportsSelectors()) {
// xpath lookup
return domdoc_.evaluate(
'svg:svg[@id="svgroot"]//svg:*[@id="'+id+'"]',
domcontainer_,
domcontainer_,
function() { return 'http://www.w3.org/2000/svg'; },
9,
null).singleNodeValue;
@ -612,9 +608,9 @@ svgedit.utilities.assignAttributes = function(node, attrs, suspendLength, unitCh
if (!svgedit.browser.isOpera()) svgroot_.suspendRedraw(suspendLength);
for (var i in attrs) {
var ns = (i.substr(0,4) === 'xml:' ? XMLNS :
var ns = (i.substr(0,4) === 'xml:' ? XMLNS :
i.substr(0,6) === 'xlink:' ? XLINKNS : null);
if(ns) {
node.setAttributeNS(ns, i, attrs[i]);
} else if(!unitCheck) {
@ -622,9 +618,7 @@ svgedit.utilities.assignAttributes = function(node, attrs, suspendLength, unitCh
} else {
svgedit.units.setUnitAttr(node, i, attrs[i]);
}
}
if (!svgedit.browser.isOpera()) svgroot_.unsuspendRedraw(handle);
};
@ -648,16 +642,15 @@ svgedit.utilities.cleanupElement = function(element) {
'rx':0,
'ry':0
}
for(var attr in defaults) {
var val = defaults[attr];
if(element.getAttribute(attr) == val) {
element.removeAttribute(attr);
}
}
svgroot_.unsuspendRedraw(handle);
};
})();

View File

@ -225,17 +225,16 @@ svgedit.units.convertToNum = function(attr, val) {
if (wAttrs.indexOf(attr) >= 0) {
return num * width;
} else if (hAttrs.indexOf(attr) >= 0) {
return num * height;
} else {
return num * Math.sqrt((width*width) + (height*height))/Math.sqrt(2);
}
} else {
var unit = val.substr(-2);
var num = val.substr(0, val.length-2);
// Note that this multiplication turns the string into a number
return num * typeMap_[unit];
if (hAttrs.indexOf(attr) >= 0) {
return num * height;
}
return num * Math.sqrt((width*width) + (height*height))/Math.sqrt(2);
}
var unit = val.substr(-2);
var num = val.substr(0, val.length-2);
// Note that this multiplication turns the string into a number
return num * typeMap_[unit];
};
// Function: svgedit.units.isValidUnit