From 1696a5ccc97a923f65eaf3a554eabce2436bc510 Mon Sep 17 00:00:00 2001
From: wente <329538422@qq.com>
Date: 星期二, 05 十一月 2024 16:20:00 +0800
Subject: [PATCH] 滚轮在页面加载之前报错报错问题
---
web/public/SVGOrigin/Method-Draw-master/method-draw/src/svgcanvas.js | 1718 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 859 insertions(+), 859 deletions(-)
diff --git a/web/public/SVGOrigin/Method-Draw-master/method-draw/src/svgcanvas.js b/web/public/SVGOrigin/Method-Draw-master/method-draw/src/svgcanvas.js
index 093f8ae..f0a4d9c 100644
--- a/web/public/SVGOrigin/Method-Draw-master/method-draw/src/svgcanvas.js
+++ b/web/public/SVGOrigin/Method-Draw-master/method-draw/src/svgcanvas.js
@@ -39,10 +39,10 @@
// This fixes $(...).attr() to work as expected with SVG elements.
// Does not currently use *AttributeNS() since we rarely need that.
-
+
// 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
@@ -72,7 +72,7 @@
obj[aname] = attr;
}
return obj;
-
+
} else if(typeof key === "object") {
// Setting attributes form object
for(var v in key) {
@@ -93,7 +93,7 @@
}
return this;
};
-
+
}());
// Class: SvgCanvas
@@ -117,7 +117,7 @@
var curConfig = {
show_outside_canvas: true,
selectNew: true,
- dimensions: [640, 480]
+ dimensions: [200, 200]
};
// Update config with new one if given
@@ -183,8 +183,8 @@
// Function: setIdPrefix
// Changes the ID prefix to the given value
//
-// Parameters:
-// p - String with the new prefix
+// Parameters:
+// p - String with the new prefix
canvas.setIdPrefix = function(p) {
idprefix = p;
};
@@ -238,7 +238,7 @@
// Function: addSvgElementFromJson
// Create a new SVG element based on the given object keys/values and add it to the current layer
-// The element will be ran through cleanupElement before being returned
+// The element will be ran through cleanupElement before being returned
//
// Parameters:
// data - Object with the following keys/values:
@@ -342,7 +342,7 @@
var elems = cmd.elements();
canvas.pathActions.clear();
call("changed", elems);
-
+
var cmdType = cmd.type();
var isApply = (eventType == EventTypes.AFTER_APPLY);
if (cmdType == MoveElementCommand.type()) {
@@ -360,7 +360,7 @@
} else {
if (!isApply) restoreRefElems(cmd.elem);
}
-
+
if(cmd.elem.tagName === 'use') {
setUseData(cmd.elem);
}
@@ -374,8 +374,8 @@
if (values["stdDeviation"]) {
canvas.setBlurOffsets(cmd.elem.parentNode, values["stdDeviation"]);
}
-
- // Remove & Re-add hack for Webkit (issue 775)
+
+ // Remove & Re-add hack for Webkit (issue 775)
//if(cmd.elem.tagName === 'use' && svgedit.browser.isWebkit()) {
// var elem = cmd.elem;
// if(!elem.getAttribute('x') && !elem.getAttribute('y')) {
@@ -462,9 +462,9 @@
}
}
}
-
+
var childs = elem.getElementsByTagName('*');
-
+
if(childs.length) {
for(var i = 0, l = childs.length; i < l; i++) {
restoreRefElems(childs[i]);
@@ -484,55 +484,55 @@
// Object to contain image data for raster images that were found encodable
var encodableImages = {},
-
+
// String with image URL of last loadable image
last_good_img_url = curConfig.imgPath + 'logo.png',
-
+
// Array with current disabled elements (for in-group editing)
disabled_elems = [],
-
+
// Object with save options
save_options = {round_digits: 5},
-
+
// Boolean indicating whether or not a draw action has been started
started = false,
-
+
// String with an element's initial transform attribute value
start_transform = null,
-
+
// String indicating the current editor mode
current_mode = "select",
-
+
// String with the current direction in which an element is being resized
current_resize_mode = "none",
-
+
// Object with IDs for imported files, to see if one was already added
import_ids = {};
// Current text style properties
var cur_text = all_properties.text,
-
+
// Current general properties
cur_properties = cur_shape,
-
+
// Array with selected elements' Bounding box object
// selectedBBoxes = new Array(1),
-
+
// The DOM element that was just selected
justSelected = null,
-
+
// DOM element for selection rectangle drawn by the user
rubberBox = null,
-
+
// Array of current BBoxes (still needed?)
curBBoxes = [],
-
+
// Object to contain all included extensions
extensions = {},
-
+
// Canvas point for the most recent right click
lastClickPoint = null,
-
+
// Map of deleted reference elements
removedElements = {}
@@ -558,14 +558,14 @@
// Function: addExtension
// Add an extension to the editor
-//
+//
// Parameters:
// name - String with the ID of the extension
// ext_func - Function supplied by the extension with its data
this.addExtension = function(name, ext_func) {
if(!(name in extensions)) {
// Provide private vars/funcs here. Is there a better way to do this?
-
+
if($.isFunction(ext_func)) {
var ext = ext_func($.extend(canvas.getPrivateMethods(), {
svgroot: svgroot,
@@ -582,7 +582,7 @@
console.log('Cannot add extension "' + name + '", an extension by that name already exists"');
}
};
-
+
// This method rounds the incoming value to the nearest value based on the current_zoom
var round = this.round = function(val) {
return parseInt(val*current_zoom)/current_zoom;
@@ -590,10 +590,10 @@
// This method sends back an array or a NodeList full of elements that
// intersect the multi-select rubber-band-box on the current_layer only.
-//
-// Since the only browser that supports the SVG DOM getIntersectionList is Opera,
+//
+// Since the only browser that supports the SVG DOM getIntersectionList is Opera,
// we need to provide an implementation here. We brute-force it for now.
-//
+//
// Reference:
// Firefox does not implement getIntersectionList(), see https://bugzilla.mozilla.org/show_bug.cgi?id=501421
// Webkit does not implement getIntersectionList(), see https://bugs.webkit.org/show_bug.cgi?id=11274
@@ -601,12 +601,12 @@
if (rubberBox == null) { return null; }
var parent = current_group || getCurrentDrawing().getCurrentLayer();
-
+
if(!curBBoxes.length) {
// Cache all bboxes
curBBoxes = getVisibleElementsAndBBoxes(parent);
}
-
+
var resultList = null;
try {
resultList = parent.getIntersectionList(rect, null);
@@ -614,16 +614,16 @@
if (resultList == null || typeof(resultList.item) != "function") {
resultList = [];
-
+
if(!rect) {
var rubberBBox = rubberBox.getBBox();
var bb = {};
-
+
for(var o in rubberBBox) {
bb[o] = rubberBBox[o] / current_zoom;
}
rubberBBox = bb;
-
+
} else {
var rubberBBox = rect;
}
@@ -635,8 +635,8 @@
}
}
}
- // addToSelection expects an array, but it's ok to pass a NodeList
- // because using square-bracket notation is allowed:
+ // addToSelection expects an array, but it's ok to pass a NodeList
+ // because using square-bracket notation is allowed:
// http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html
return resultList;
};
@@ -644,34 +644,34 @@
// TODO(codedread): Migrate this into svgutils.js
// Function: getStrokedBBox
// Get the bounding box for one or more stroked and/or transformed elements
-//
+//
// Parameters:
// elems - Array with DOM elements to check
-//
+//
// Returns:
// A single bounding box object
getStrokedBBox = this.getStrokedBBox = function(elems) {
if(!elems) elems = getVisibleElements();
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);
if ((angle && angle % 90) ||
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) {
@@ -684,10 +684,10 @@
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);
@@ -695,17 +695,17 @@
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
// var angle = angle * Math.PI / 180.0;
-// var rminx = Number.MAX_VALUE, rminy = Number.MAX_VALUE,
+// var rminx = Number.MAX_VALUE, rminy = Number.MAX_VALUE,
// rmaxx = Number.MIN_VALUE, rmaxy = Number.MIN_VALUE;
// var cx = round(bb.x + bb.width/2),
// cy = round(bb.y + bb.height/2);
-// var pts = [ [bb.x - cx, bb.y - cy],
+// var pts = [ [bb.x - cx, bb.y - cy],
// [bb.x + bb.width - cx, bb.y - cy],
// [bb.x + bb.width - cx, bb.y + bb.height - cy],
// [bb.x - cx, bb.y + bb.height - cy] ];
@@ -717,23 +717,23 @@
// var theta = Math.atan2(y,x) + angle;
// x = round(r * Math.cos(theta) + cx);
// y = round(r * Math.sin(theta) + cy);
-//
+//
// // now set the bbox for the shape after it's been rotated
// if (x < rminx) rminx = x;
// if (y < rminy) rminy = y;
// if (x > rmaxx) rmaxx = x;
// if (y > rmaxy) rmaxy = y;
// }
-//
+//
// bb.x = rminx;
// bb.y = rminy;
// bb.width = rmaxx - rminx;
// bb.height = rmaxy - rminy;
}
return bb;
- } catch(e) {
+ } catch(e) {
console.log(elem, e);
- }
+ }
};
var full_bb;
@@ -742,18 +742,18 @@
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");
@@ -773,10 +773,10 @@
bboxes.push(cur_bb);
}
});
-
+
full_bb.x = min_x;
full_bb.y = min_y;
-
+
$.each(elems, function(i, elem) {
var cur_bb = bboxes[i];
// ensure that elem is really an element node
@@ -786,7 +786,7 @@
max_y = Math.max(max_y, cur_bb.y + cur_bb.height + offset);
}
});
-
+
full_bb.width = max_x - min_x;
full_bb.height = max_y - min_y;
return full_bb;
@@ -830,7 +830,7 @@
// * bbox - The element's BBox as retrieved from getStrokedBBox
var getVisibleElementsAndBBoxes = this.getVisibleElementsAndBBoxes = function(parent) {
if(!parent) parent = $(svgcontent).children(); // Prevent layers from being included
-
+
var contentElems = [];
$(parent).children().each(function(i, elem) {
try {
@@ -870,7 +870,7 @@
new_el.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.nodeValue);
}
});
-
+
// Opera's "d" value needs to be reset for Opera/Win/non-EN
// Also needed for webkit (else does not keep curved segments on clone)
if(svgedit.browser.isWebkit() && el.nodeName == 'path') {
@@ -891,7 +891,7 @@
break;
}
});
-
+
if($(el).data('gsvg')) {
$(new_el).data('gsvg', new_el.firstChild);
} else if($(el).data('symbol')) {
@@ -915,7 +915,7 @@
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
//
@@ -927,14 +927,14 @@
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) {
@@ -942,7 +942,7 @@
events[event] = f;
return old;
};
-
+
}(canvas));
// Function: canvas.prepareSvg
@@ -972,13 +972,13 @@
}
// Function: ffClone
-// Hack for Firefox bugs where text element features aren't updated or get
+// Hack for Firefox bugs where text element features aren't updated or get
// messed up. See issue 136 and issue 137.
-// This function clones the element and re-selects it
-// TODO: Test for this bug on load and add it to "support" object instead of
+// This function clones the element and re-selects it
+// TODO: Test for this bug on load and add it to "support" object instead of
// browser sniffing
//
-// Parameters:
+// Parameters:
// elem - The (text) DOM element to clone
var ffClone = function(elem) {
if(!svgedit.browser.isGecko()) return elem;
@@ -1016,7 +1016,7 @@
var bbox = svgedit.utilities.getBBox(elem);
var cx = bbox.x+bbox.width/2, cy = bbox.y+bbox.height/2;
var tlist = getTransformList(elem);
-
+
// only remove the real rotational transform if present (i.e. at index=0)
if (tlist.numberOfItems > 0) {
var xform = tlist.getItem(0);
@@ -1038,7 +1038,7 @@
else if (tlist.numberOfItems == 0) {
elem.removeAttribute("transform");
}
-
+
if (!preventUndo) {
// we need to undo it, then redo it so it can be undo-able! :)
// TODO: figure out how to make changes to transform list undo-able cross-browser?
@@ -1057,7 +1057,7 @@
};
// Function: recalculateAllSelectedDimensions
-// Runs recalculateDimensions on the selected elements,
+// Runs recalculateDimensions on the selected elements,
// adding the changes to a single batch command
var recalculateAllSelectedDimensions = this.recalculateAllSelectedDimensions = function() {
var text = (current_resize_mode == "none" ? "position" : "size");
@@ -1080,9 +1080,9 @@
};
// this is how we map paths to our preferred relative segment types
-var pathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a',
+var pathMap = [0, 'z', 'M', 'm', 'L', 'l', 'C', 'c', 'Q', 'q', 'A', 'a',
'H', 'h', 'V', 'v', 'S', 's', 'T', 't'];
-
+
// Debug tool to easily see the current matrix in the browser's console
var logMatrix = function(m) {
console.log([m.a,m.b,m.c,m.d,m.e,m.f]);
@@ -1106,7 +1106,7 @@
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);
@@ -1114,15 +1114,15 @@
if(m.a < 0 || m.d < 0) {
var grad = 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');
@@ -1134,7 +1134,7 @@
findDefs().appendChild(newgrad);
selected.setAttribute(type, 'url(#' + newgrad.id + ')');
}
-
+
// Not really working :(
// if(selected.tagName === 'path') {
// reorientGrads(selected, m);
@@ -1146,8 +1146,8 @@
var elName = selected.tagName;
if(elName === "g" || elName === "text" || elName === "use") {
// if it was a translate, then just update x,y
- if (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 &&
- (m.e != 0 || m.f != 0) )
+ if (m.a == 1 && m.b == 0 && m.c == 0 && m.d == 1 &&
+ (m.e != 0 || m.f != 0) )
{
// [T][M] = [M][T']
// therefore [T'] = [M_inv][T][M]
@@ -1165,7 +1165,7 @@
chlist.appendItem(mt);
}
}
-
+
// now we have a set of changes and an applied reduced transform list
// we apply the changes directly to the DOM
switch (elName)
@@ -1173,7 +1173,7 @@
case "foreignObject":
case "rect":
case "image":
-
+
// Allow images to be inverted (give them matrix when flipped)
if(elName === 'image' && (m.a < 0 || m.d < 0)) {
// Convert to matrix
@@ -1184,10 +1184,10 @@
chlist.appendItem(mt);
} else {
var pt1 = remap(changes.x,changes.y);
-
+
changes.width = scalew(changes.width);
changes.height = scaleh(changes.height);
-
+
changes.x = pt1.x + Math.min(0,changes.width);
changes.y = pt1.y + Math.min(0,changes.height);
changes.width = Math.abs(changes.width);
@@ -1201,7 +1201,7 @@
changes.cy = c.y;
changes.rx = scalew(changes.rx);
changes.ry = scaleh(changes.ry);
-
+
changes.rx = Math.abs(changes.rx);
changes.ry = Math.abs(changes.ry);
finishUp();
@@ -1225,7 +1225,7 @@
changes.y1 = pt1.y;
changes.x2 = pt2.x;
changes.y2 = pt2.y;
-
+
case "text":
var tspan = selected.querySelectorAll('tspan');
var i = tspan.length
@@ -1272,7 +1272,7 @@
selected.setAttribute("points", pstr);
break;
case "path":
-
+
var segList = selected.pathSegList;
var len = segList.numberOfItems;
changes.d = new Array(len);
@@ -1293,7 +1293,7 @@
sweepFlag: seg.sweepFlag
};
}
-
+
var len = changes.d.length,
firstseg = changes.d[0],
currentpt = remap(firstseg.x,firstseg.y);
@@ -1330,7 +1330,7 @@
seg.r2 = scaleh(seg.r2);
}
} // for each segment
-
+
var dstr = "";
var len = changes.d.length;
for (var i = 0; i < len; ++i) {
@@ -1359,7 +1359,7 @@
dstr += seg.x1 + "," + seg.y1 + " " + seg.x2 + "," + seg.y2 + " " +
seg.x + "," + seg.y + " ";
break;
- case 9: // relative quad (q)
+ case 9: // relative quad (q)
case 8: // absolute quad (Q)
dstr += seg.x1 + "," + seg.y1 + " " + seg.x + "," + seg.y + " ";
break;
@@ -1389,14 +1389,14 @@
// ty - The translation's y value
var updateClipPath = function(attr, tx, ty) {
var path = getRefElem(attr).firstChild;
-
+
var cp_xform = getTransformList(path);
-
+
var newxlate = svgroot.createSVGTransform();
newxlate.setTranslate(tx, ty);
cp_xform.appendItem(newxlate);
-
+
// Update clipPath's dimensions
recalculateDimensions(path);
}
@@ -1407,13 +1407,13 @@
// Parameters:
// selected - The DOM element to recalculate
//
-// Returns:
+// Returns:
// Undo command object with the resulting change
var recalculateDimensions = this.recalculateDimensions = function(selected) {
if (selected == null) return null;
-
+
var tlist = getTransformList(selected);
-
+
// remove any unnecessary transforms
if (tlist && tlist.numberOfItems > 0) {
var k = tlist.numberOfItems;
@@ -1438,13 +1438,13 @@
// End here if all it has is a rotation
if(tlist.numberOfItems === 1 && getRotationAngle(selected)) return null;
}
-
+
// if this element had no transforms, we are done
if (!tlist || tlist.numberOfItems == 0) {
selected.removeAttribute("transform");
return null;
}
-
+
// TODO: Make this work for more than 2
if (tlist) {
var k = tlist.numberOfItems;
@@ -1463,23 +1463,23 @@
tlist.removeItem(mxs[1][1]);
tlist.insertItemBefore(m_new, mxs[1][1]);
}
-
+
// combine matrix + translate
k = tlist.numberOfItems;
if(k >= 2 && tlist.getItem(k-2).type === 1 && tlist.getItem(k-1).type === 2) {
var mt = svgroot.createSVGTransform();
-
+
var m = matrixMultiply(
- tlist.getItem(k-2).matrix,
+ tlist.getItem(k-2).matrix,
tlist.getItem(k-1).matrix
- );
+ );
mt.setMatrix(m);
tlist.removeItem(k-2);
tlist.removeItem(k-2);
tlist.appendItem(mt);
}
}
-
+
// 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]
@@ -1496,13 +1496,13 @@
return null;
}
}
-
- // Grouped SVG element
+
+ // Grouped SVG element
var gsvg = $(selected).data('gsvg');
-
- // we know we have some transforms, so set up return variable
+
+ // we know we have some transforms, so set up return variable
var batchCmd = new BatchCommand("Transform");
-
+
// store initial values that will be affected by reducing the transform list
var changes = {}, initial = null, attrs = [];
switch (selected.tagName)
@@ -1544,7 +1544,7 @@
changes["d"] = selected.getAttribute("d");
break;
} // switch on element type to get initial values
-
+
if(attrs.length) {
changes = $(selected).attr(attrs);
$.each(changes, function(attr, val) {
@@ -1557,8 +1557,8 @@
y: $(gsvg).attr('y') || 0
};
}
-
- // if we haven't created an initial array in polygon/polyline/path, then
+
+ // if we haven't created an initial array in polygon/polyline/path, then
// make a copy of initial values and include the transform
if (initial == null) {
initial = $.extend(true, {}, changes);
@@ -1568,7 +1568,7 @@
}
// save the start transform value too
initial["transform"] = start_transform ? start_transform : "";
-
+
// if it's a regular group, we have special processing to flatten transforms
if ((selected.tagName == "g" && !gsvg) || selected.tagName == "a") {
var box = svgedit.utilities.getBBox(selected),
@@ -1576,8 +1576,8 @@
newcenter = transformPoint(box.x+box.width/2, box.y+box.height/2,
transformListToTransform(tlist).matrix),
m = svgroot.createSVGMatrix();
-
-
+
+
// temporarily strip off the rotate and save the old center
var gangle = getRotationAngle(selected);
if (gangle) {
@@ -1609,17 +1609,17 @@
}
// first, if it was a scale then the second-last transform will be it
- if (N >= 3 && tlist.getItem(N-2).type == 3 &&
- tlist.getItem(N-3).type == 2 && tlist.getItem(N-1).type == 2)
+ if (N >= 3 && tlist.getItem(N-2).type == 3 &&
+ tlist.getItem(N-3).type == 2 && tlist.getItem(N-1).type == 2)
{
operation = 3; // scale
-
+
// if the children are unrotated, pass the scale down directly
// otherwise pass the equivalent matrix() down directly
var tm = tlist.getItem(N-3).matrix,
sm = tlist.getItem(N-2).matrix,
tmn = tlist.getItem(N-1).matrix;
-
+
var children = selected.childNodes;
var c = children.length;
while (c--) {
@@ -1649,7 +1649,7 @@
// childTlist.appendItem(translateOrigin);
// }
// }
-
+
var angle = getRotationAngle(child);
var old_start_transform = start_transform;
var childxforms = [];
@@ -1664,10 +1664,10 @@
// if not rotated or skewed, push the [T][S][-T] down to the child
else {
// update the transform list with translate,scale,translate
-
+
// slide the [T][S][-T] from the front to the back
// [T][S][-T][M] = [M][T2][S2][-T2]
-
+
// (only bringing [-T] to the right of [M])
// [T][S][-T][M] = [T][S][M][-T2]
// [-T2] = [M_inv][-T][M]
@@ -1676,7 +1676,7 @@
var t2 = svgroot.createSVGMatrix();
t2.e = -t2n.e;
t2.f = -t2n.f;
-
+
// [T][S][-T][M] = [M][T2][S2][-T2]
// [S2] = [T2_inv][M_inv][T][S][-T][M][-T2_inv]
var s2 = matrixMultiply(t2.inverse(), m.inverse(), tm, sm, tmn, m, t2n.inverse());
@@ -1697,8 +1697,8 @@
// logMatrix(scale.matrix);
} // not rotated
batchCmd.addSubCommand( recalculateDimensions(child) );
- // TODO: If any <use> have this group as a parent and are
- // referencing this child, then we need to impose a reverse
+ // TODO: If any <use> have this group as a parent and are
+ // referencing this child, then we need to impose a reverse
// scale on it so that when it won't get double-translated
// var uses = selected.getElementsByTagNameNS(svgns, "use");
// var href = "#"+child.id;
@@ -1728,19 +1728,19 @@
e2t.setMatrix(m);
tlist.clear();
tlist.appendItem(e2t);
- }
- // next, check if the first transform was a translate
+ }
+ // next, check if the first transform was a translate
// if we had [ T1 ] [ M ] we want to transform this into [ M ] [ T2 ]
// therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ]
- else if ( (N == 1 || (N > 1 && tlist.getItem(1).type != 3)) &&
- tlist.getItem(0).type == 2)
+ else if ( (N == 1 || (N > 1 && tlist.getItem(1).type != 3)) &&
+ tlist.getItem(0).type == 2)
{
operation = 2; // translate
var T_M = transformListToTransform(tlist).matrix;
tlist.removeItem(0);
var M_inv = transformListToTransform(tlist).matrix.inverse();
var M2 = matrixMultiply( M_inv, T_M );
-
+
tx = M2.e;
ty = M2.f;
@@ -1748,13 +1748,13 @@
// we pass the translates down to the individual children
var children = selected.childNodes;
var c = children.length;
-
+
var clipPaths_done = [];
-
+
while (c--) {
var child = children.item(c);
if (child.nodeType == 1) {
-
+
// Check if child has clip-path
if(child.getAttribute('clip-path')) {
// tx, ty
@@ -1762,12 +1762,12 @@
if(clipPaths_done.indexOf(attr) === -1) {
updateClipPath(attr, tx, ty);
clipPaths_done.push(attr);
- }
+ }
}
var old_start_transform = start_transform;
start_transform = child.getAttribute("transform");
-
+
var childTlist = getTransformList(child);
// some children might not have a transform (<metadata>, <defs>, etc)
if (childTlist) {
@@ -1779,7 +1779,7 @@
childTlist.appendItem(newxlate);
}
batchCmd.addSubCommand( recalculateDimensions(child) );
- // If any <use> have this group as a parent and are
+ // If any <use> have this group as a parent and are
// referencing this child, then impose a reverse translate on it
// so that when it won't get double-translated
var uses = selected.getElementsByTagNameNS(svgns, "use");
@@ -1798,9 +1798,9 @@
}
}
}
-
+
clipPaths_done = [];
-
+
start_transform = old_start_transform;
}
}
@@ -1817,18 +1817,18 @@
var old_start_transform = start_transform;
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);
childTlist.clear();
childTlist.appendItem(e2m,0);
-
+
batchCmd.addSubCommand( recalculateDimensions(child) );
start_transform = old_start_transform;
-
+
// Convert stroke
// TODO: Find out if this should actually happen somewhere else
var sw = child.getAttribute("stroke-width");
@@ -1855,9 +1855,9 @@
if (tlist.numberOfItems == 0) {
selected.removeAttribute("transform");
}
- return null;
+ return null;
}
-
+
// if it was a translate, put back the rotate at the new center
if (operation == 2) {
if (gangle) {
@@ -1865,7 +1865,7 @@
x: oldcenter.x + first_m.e,
y: oldcenter.y + first_m.f
};
-
+
var newRot = svgroot.createSVGTransform();
newRot.setRotate(gangle,newcenter.x,newcenter.y);
if(tlist.numberOfItems) {
@@ -1914,7 +1914,7 @@
}
}
}
-
+
if (gangle) {
if(tlist.numberOfItems) {
tlist.insertItemBefore(rnew, 0);
@@ -1934,9 +1934,9 @@
// but we still may need to recalculate them (see issue 595).
// TODO: Figure out how to get BBox from these elements in case they
// have a rotation transform
-
+
if(!box && selected.tagName != 'path') return null;
-
+
var m = svgroot.createSVGMatrix(),
// temporarily strip off the rotate and save the old center
@@ -1945,7 +1945,7 @@
var oldcenter = {x: box.x+box.width/2, y: box.y+box.height/2},
newcenter = transformPoint(box.x+box.width/2, box.y+box.height/2,
transformListToTransform(tlist).matrix);
-
+
var a = angle * Math.PI / 180;
if ( Math.abs(a) > (1.0e-10) ) {
var s = Math.sin(a)/(1 - Math.cos(a));
@@ -1965,11 +1965,11 @@
}
}
}
-
+
// 2 = translate, 3 = scale, 4 = rotate, 1 = matrix imposition
var operation = 0;
var N = tlist.numberOfItems;
-
+
// Check if it has a gradient with userSpaceOnUse, in which case
// adjust it by recalculating the matrix transform.
// TODO: Make this work in Webkit using svgedit.transformlist.SVGTransformList
@@ -1992,14 +1992,14 @@
}
}
- // first, if it was a scale of a non-skewed element, then the second-last
+ // first, if it was a scale of a non-skewed element, then the second-last
// transform will be the [S]
// 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)
-
- // Removed this so a <use> with a given [T][S][T] would convert to a matrix.
+ if (N >= 3 && tlist.getItem(N-2).type == 3 &&
+ 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"
{
@@ -2019,12 +2019,12 @@
tlist.appendItem(e2t);
// reset the matrix so that the element is not re-mapped
m = svgroot.createSVGMatrix();
- } // if we had [R][T][S][-T][M], then this was a rotated matrix-element
+ } // if we had [R][T][S][-T][M], then this was a rotated matrix-element
// if we had [T1][M] we want to transform this into [M][T2]
- // therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ] and we can push [T2]
+ // therefore [ T2 ] = [ M_inv ] [ T1 ] [ M ] and we can push [T2]
// down to the element
- else if ( (N == 1 || (N > 1 && tlist.getItem(1).type != 3)) &&
- tlist.getItem(0).type == 2)
+ else if ( (N == 1 || (N > 1 && tlist.getItem(1).type != 3)) &&
+ tlist.getItem(0).type == 2)
{
operation = 2; // translate
var oldxlate = tlist.getItem(0).matrix,
@@ -2069,7 +2069,7 @@
if (angle) {
var newRot = svgroot.createSVGTransform();
newRot.setRotate(angle,newcenter.x,newcenter.y);
-
+
if(tlist.numberOfItems) {
tlist.insertItemBefore(newRot, 0);
} else {
@@ -2081,12 +2081,12 @@
}
return null;
}
-
+
// if it was a translate or resize, we need to remap the element and absorb the xform
if (operation == 1 || operation == 2 || operation == 3) {
remapElement(selected,changes,m);
} // if we are remapping
-
+
// if it was a translate, put back the rotate at the new center
if (operation == 2) {
if (angle) {
@@ -2119,7 +2119,7 @@
var rnew_inv = rnew.matrix.inverse();
var m_inv = m.inverse();
var extrat = matrixMultiply(m_inv, rnew_inv, rold, m);
-
+
remapElement(selected,changes,extrat);
if (angle) {
if(tlist.numberOfItems) {
@@ -2135,9 +2135,9 @@
if (tlist.numberOfItems == 0) {
selected.removeAttribute("transform");
}
-
+
batchCmd.addSubCommand(new ChangeElementCommand(selected, initial));
-
+
return batchCmd;
};
@@ -2148,7 +2148,7 @@
// Function: clearSelection
// Clears the selection. The 'selected' handler is then called.
-// Parameters:
+// Parameters:
// noCall - Optional boolean that when true does not call the "selected" handler
var clearSelection = this.clearSelection = function(noCall) {
if (selectedElements[0] != null) {
@@ -2177,9 +2177,9 @@
if (elemsToAdd.length == 0) { return; }
// find the first null in our selectedElements array
var j = 0;
-
+
while (j < selectedElements.length) {
- if (selectedElements[j] == null) {
+ if (selectedElements[j] == null) {
break;
}
++j;
@@ -2192,7 +2192,7 @@
if (!elem || !svgedit.utilities.getBBox(elem)) continue;
if(elem.tagName === 'a' && elem.childNodes.length === 1) {
- // Make "a" element's child be the selected element
+ // Make "a" element's child be the selected element
elem = elem.firstChild;
}
@@ -2205,7 +2205,7 @@
// if (j == 0) selectedBBoxes[0] = svgedit.utilities.getBBox(elem);
j++;
var sel = selectorManager.requestSelector(elem);
-
+
if (selectedElements.length > 1) {
sel.showGrips(false);
}
@@ -2220,12 +2220,12 @@
selectedElements.sort(function(a,b) {
if(a && b && a.compareDocumentPosition) {
- return 3 - (b.compareDocumentPosition(a) & 6);
+ return 3 - (b.compareDocumentPosition(a) & 6);
} else if(a == null) {
return 1;
}
});
-
+
// Make sure first elements are not null
while(selectedElements[0] == null) selectedElements.shift(0);
};
@@ -2285,10 +2285,10 @@
// Function: getMouseTarget
// Gets the desired element from a mouse event
-//
+//
// Parameters:
// evt - Event object from the mouse event
-//
+//
// Returns:
// DOM element we want
var getMouseTarget = this.getMouseTarget = function(evt) {
@@ -2296,33 +2296,33 @@
return null;
}
var mouse_target = evt.target;
-
+
// if it was a <use>, Opera and WebKit return the SVGElementInstance
if (mouse_target.correspondingUseElement) mouse_target = mouse_target.correspondingUseElement;
-
+
// for foreign content, go up until we find the foreignObject
- // WebKit browsers set the mouse target to the svgcanvas div
- if ([mathns, htmlns].indexOf(mouse_target.namespaceURI) >= 0 &&
- mouse_target.id != "svgcanvas")
+ // WebKit browsers set the mouse target to the svgcanvas div
+ if ([mathns, htmlns].indexOf(mouse_target.namespaceURI) >= 0 &&
+ mouse_target.id != "svgcanvas")
{
while (mouse_target.nodeName != "foreignObject") {
mouse_target = mouse_target.parentNode;
if(!mouse_target) return svgroot;
}
}
-
+
// Get the desired mouse_target with jQuery selector-fu
// If it's root-like, select the root
var current_layer = getCurrentDrawing().getCurrentLayer();
if([svgroot, container, svgcontent, current_layer].indexOf(mouse_target) >= 0) {
return svgroot;
}
-
+
var $target = $(mouse_target);
// If it's a selection grip, return the grip parent
if($target.closest('#selectorParentGroup').length) {
- // While we could instead have just returned mouse_target,
+ // While we could instead have just returned mouse_target,
// this makes it easier to indentify as being a selector grip
return selectorManager.selectorParentGroup;
}
@@ -2330,8 +2330,8 @@
while (mouse_target.parentNode && mouse_target.parentNode !== (current_group || current_layer)) {
mouse_target = mouse_target.parentNode;
}
-
-//
+
+//
// // go up until we hit a child of a layer
// while (mouse_target.parentNode.parentNode.tagName == 'g') {
// mouse_target = mouse_target.parentNode;
@@ -2341,7 +2341,7 @@
// if (mouse_target.nodeName.toLowerCase() == "div") {
// mouse_target = svgroot;
// }
-
+
return mouse_target;
};
@@ -2359,7 +2359,7 @@
maxx: null,
maxy: null
};
-
+
// - when we are in a create mode, the element is added to the canvas
// but the action is not recorded until mousing up
// - when we are in select mode, select the element, remember the position
@@ -2374,7 +2374,7 @@
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm ),
mouse_x = pt.x * current_zoom,
mouse_y = pt.y * current_zoom;
-
+
evt.preventDefault();
@@ -2382,15 +2382,15 @@
current_mode = "select";
lastClickPoint = pt;
}
-
+
var x = mouse_x / current_zoom,
y = mouse_y / current_zoom,
mouse_target = getMouseTarget(evt);
-
+
if(mouse_target.tagName === 'a' && mouse_target.childNodes.length === 1) {
mouse_target = mouse_target.firstChild;
}
-
+
// real_x/y ignores grid-snap value
var real_x = r_start_x = start_x = x;
var real_y = r_start_y = start_y = y;
@@ -2402,9 +2402,9 @@
start_y = snapToGrid(start_y);
}
- // if it is a selector grip, then it must be a single element selected,
+ // if it is a selector grip, then it must be a single element selected,
// set the mouse_target to that and update the mode to rotate/resize
-
+
if (mouse_target == selectorManager.selectorParentGroup && selectedElements[0] != null) {
var grip = evt.target;
var griptype = elData(grip, "type");
@@ -2420,7 +2420,7 @@
}
mouse_target = selectedElements[0];
}
-
+
start_transform = mouse_target.getAttribute("transform");
var tlist = getTransformList(mouse_target);
switch (current_mode) {
@@ -2428,11 +2428,11 @@
started = true;
current_resize_mode = "none";
if(right_click) started = false;
-
+
if (mouse_target != svgroot) {
// if this element is not yet selected, clear selection and select it
if (selectedElements.indexOf(mouse_target) == -1) {
- // only clear selection if shift is not pressed (otherwise, add
+ // only clear selection if shift is not pressed (otherwise, add
// element to selection)
if (!evt.shiftKey) {
// No need to do the call here as it will be done on addToSelection
@@ -2443,7 +2443,7 @@
pathActions.clear();
}
// else if it's a path, go into pathedit mode in mouseup
-
+
if(!right_click) {
// insert a dummy transform so if the element(s) are moved it will have
// a transform to use for its translate
@@ -2466,11 +2466,11 @@
}
r_start_x *= current_zoom;
r_start_y *= current_zoom;
-// console.log('p',[evt.pageX, evt.pageY]);
-// console.log('c',[evt.clientX, evt.clientY]);
-// console.log('o',[evt.offsetX, evt.offsetY]);
+// console.log('p',[evt.pageX, evt.pageY]);
+// console.log('c',[evt.clientX, evt.clientY]);
+// console.log('o',[evt.offsetX, evt.offsetY]);
// console.log('s',[start_x, start_y]);
-
+
assignAttributes(rubberBox, {
'x': r_start_x,
'y': r_start_y,
@@ -2480,7 +2480,7 @@
}, 100);
}
break;
- case "zoom":
+ case "zoom":
started = true;
if (rubberBox == null) {
rubberBox = selectorManager.getRubberBandBox();
@@ -2497,7 +2497,7 @@
started = true;
start_x = x;
start_y = y;
-
+
// Getting the BBox from the selection box, since we know we
// want to orient around it
init_bbox = svgedit.utilities.getBBox($('#selectedBox0')[0]);
@@ -2509,7 +2509,7 @@
// append three dummy transforms to the tlist so that
// we can translate,scale,translate in mousemove
var pos = getRotationAngle(mouse_target)?1:0;
-
+
if(hasMatrixTransform(tlist)) {
tlist.insertItemBefore(svgroot.createSVGTransform(), pos);
tlist.insertItemBefore(svgroot.createSVGTransform(), pos);
@@ -2518,7 +2518,7 @@
tlist.appendItem(svgroot.createSVGTransform());
tlist.appendItem(svgroot.createSVGTransform());
tlist.appendItem(svgroot.createSVGTransform());
-
+
if(svgedit.browser.supportsNonScalingStroke()) {
//Handle crash for newer Webkit: https://code.google.com/p/svg-edit/issues/detail?id=904
//Chromium issue: https://code.google.com/p/chromium/issues/detail?id=114625
@@ -2701,27 +2701,27 @@
// This could occur in an extension
break;
}
-
+
var ext_result = runExtensions("mouseDown", {
event: evt,
start_x: start_x,
start_y: start_y,
selectedElements: selectedElements
}, true);
-
+
$.each(ext_result, function(i, r) {
if(r && r.started) {
started = true;
}
});
if (current_mode) {
- document.getElementById("workarea").className =
+ document.getElementById("workarea").className =
(current_mode == "resize")
? evt.target.style.cursor
: current_mode
}
};
-
+
// in this function we do not record any state changes yet (but we do update
// any elements that are still being created, moved or resized on the canvas)
var mouseMove = function(evt) {
@@ -2743,23 +2743,23 @@
}
evt.preventDefault();
-
+
switch (current_mode)
{
case "select":
// we temporarily use a translate on the element(s) being dragged
- // this transform is removed upon mousing up and the element is
+ // this transform is removed upon mousing up and the element is
// relocated to the new location
if (selectedElements[0] !== null) {
var dx = x - start_x;
var dy = y - start_y;
-
+
if(curConfig.gridSnapping){
dx = snapToGrid(dx);
dy = snapToGrid(dy);
}
-
- if(evt.shiftKey) {
+
+ if(evt.shiftKey) {
var xya = snapToAngle(start_x,start_y,x,y); x=xya.x; y=xya.y;
}
if (dx != 0 || dy != 0) {
@@ -2790,13 +2790,13 @@
} else {
tlist.appendItem(xform);
}
-
+
// update our internal bbox that we're tracking while dragging
selectorManager.requestSelector(selected).resize();
}
//duplicate only once
- // alt drag = create a clone and save the reference
+ // alt drag = create a clone and save the reference
if(evt.altKey) {
//clone doesn't exist yet
if (!canvas.addClones) {
@@ -2812,14 +2812,14 @@
window.addEventListener("keyup", canvas.removeClones)
}
}
-
+
call("transition", selectedElements);
}
-
-
-
+
+
+
}
break;
case "multiselect":
@@ -2839,7 +2839,7 @@
var elemsToRemove = [], elemsToAdd = [],
newList = getIntersectionList(),
len = selectedElements.length;
-
+
for (var i = 0; i < len; ++i) {
var ind = newList.indexOf(selectedElements[i]);
if (ind == -1) {
@@ -2849,16 +2849,16 @@
newList[ind] = null;
}
}
-
+
len = newList.length;
for (i = 0; i < len; ++i) { if (newList[i]) elemsToAdd.push(newList[i]); }
-
- if (elemsToRemove.length > 0)
+
+ if (elemsToRemove.length > 0)
canvas.removeFromSelection(elemsToRemove);
-
- if (elemsToAdd.length > 0)
+
+ if (elemsToAdd.length > 0)
addToSelection(elemsToAdd);
-
+
break;
case "resize":
// we track the resize bounding box and translate/scale the selected element
@@ -2866,10 +2866,10 @@
// the shape's coordinates
var tlist = getTransformList(selected),
hasMatrix = hasMatrixTransform(tlist),
- box = hasMatrix ? init_bbox : svgedit.utilities.getBBox(selected),
+ box = hasMatrix ? init_bbox : svgedit.utilities.getBBox(selected),
left=box.x, top=box.y, width=box.width,
height=box.height, dx=(x-start_x), dy=(y-start_y);
-
+
if(curConfig.gridSnapping){
dx = snapToGrid(dx);
dy = snapToGrid(dy);
@@ -2893,24 +2893,24 @@
}
if(current_resize_mode.indexOf("e")==-1 && current_resize_mode.indexOf("w")==-1) {
dx = 0;
- }
-
+ }
+
var ts = null,
tx = 0, ty = 0,
- sy = height ? (height+dy)/height : 1,
+ sy = height ? (height+dy)/height : 1,
sx = width ? (width+dx)/width : 1;
// if we are dragging on the north side, then adjust the scale factor and ty
if(current_resize_mode.indexOf("n") >= 0) {
sy = height ? (height-dy)/height : 1;
ty = height;
}
-
+
// if we dragging on the east side, then adjust the scale factor and tx
if(current_resize_mode.indexOf("w") >= 0) {
sx = width ? (width-dx)/width : 1;
tx = width;
}
-
+
// update the transform list with translate,scale,translate
var translateOrigin = svgroot.createSVGTransform(),
scale = svgroot.createSVGTransform(),
@@ -2929,7 +2929,7 @@
else sy = sx;
}
scale.setScale(sx,sy);
-
+
translateBack.setTranslate(left+tx,top+ty);
if(hasMatrix) {
var diff = angle?1:0;
@@ -2944,9 +2944,9 @@
}
selectorManager.requestSelector(selected).resize();
-
+
call("transition", selectedElements);
-
+
break;
case "zoom":
real_x *= current_zoom;
@@ -2956,7 +2956,7 @@
'y': Math.min(r_start_y*current_zoom, real_y),
'width': Math.abs(real_x - r_start_x*current_zoom),
'height': Math.abs(real_y - r_start_y*current_zoom)
- },100);
+ },100);
break;
case "text":
assignAttributes(shape,{
@@ -2971,10 +2971,10 @@
}
var x2 = x;
- var y2 = y;
+ var y2 = y;
if(evt.shiftKey) { var xya = snapToAngle(start_x,start_y,x2,y2); x2=xya.x; y2=xya.y; }
-
+
shape.setAttributeNS(null, "x2", x2);
shape.setAttributeNS(null, "y2", y2);
break;
@@ -2998,11 +2998,11 @@
}
if (evt.altKey){
w *=2;
- h *=2;
+ h *=2;
new_x = start_x - w/2;
new_y = start_y - h/2;
}
-
+
if(curConfig.gridSnapping){
w = snapToGrid(w);
h = snapToGrid(h);
@@ -3016,7 +3016,7 @@
'x': new_x,
'y': new_y
},1000);
-
+
break;
case "circle":
var c = $(shape).attr(["cx", "cy"]);
@@ -3042,7 +3042,7 @@
if (evt.shiftKey) {
ry = rx
cy = (y > start_y) ? start_y + rx : start_y - rx
-
+
}
if (evt.altKey) {
cx = start_x
@@ -3072,7 +3072,7 @@
case "pathedit":
x *= current_zoom;
y *= current_zoom;
-
+
if(curConfig.gridSnapping){
x = snapToGrid(x);
y = snapToGrid(y);
@@ -3091,7 +3091,7 @@
var xya = snapToAngle(x1,y1,x,y);
x=xya.x; y=xya.y;
}
-
+
if(rubberBox && rubberBox.getAttribute('display') !== 'none') {
real_x *= current_zoom;
real_y *= current_zoom;
@@ -3100,10 +3100,10 @@
'y': Math.min(r_start_y*current_zoom, real_y),
'width': Math.abs(real_x - r_start_x*current_zoom),
'height': Math.abs(real_y - r_start_y*current_zoom)
- },100);
+ },100);
}
pathActions.mouseMove(evt, x, y);
-
+
break;
case "textedit":
x *= current_zoom;
@@ -3116,13 +3116,13 @@
// 'height': Math.abs(y-start_y)
// },100);
// }
-
+
textActions.mouseMove(mouse_x, mouse_y);
-
+
break;
case "rotate":
var box = svgedit.utilities.getBBox(selected),
- cx = box.x + box.width/2,
+ cx = box.x + box.width/2,
cy = box.y + box.height/2,
m = getMatrix(selected),
center = transformPoint(cx,cy,m);
@@ -3150,7 +3150,7 @@
default:
break;
}
-
+
runExtensions("mouseMove", {
event: evt,
mouse_x: mouse_x,
@@ -3159,16 +3159,16 @@
});
}; // mouseMove()
-
-
+
+
/* mouseover mode
var mouseOver = function(evt) {
-
+
if(canvas.spaceKey || evt.button === 1 || current_mode != "select") return;
evt.stopPropagation();
mouse_target = getMouseTarget(evt);
if (svghover.lastChild) svghover.removeChild(svghover.lastChild);
-
+
if (mouse_target.id == "svgroot") return
switch (mouse_target.nodeName) {
case "polyline":
@@ -3176,7 +3176,7 @@
case "path":
case "ellipse":
case "rect":
- var clone = mouse_target.cloneNode(true);
+ var clone = mouse_target.cloneNode(true);
clone.setAttribute("stroke", "#c00")
clone.setAttribute("stroke-width", "1")
clone.setAttribute("stroke-opacity", "1")
@@ -3184,13 +3184,13 @@
clone.setAttribute("fill", "none")
hover_group.appendChild(clone);
break;
-
+
default:
break;
}
}
*/
-
+
// - in create mode, the element's opacity is set properly, we create an InsertElementCommand
// and store it on the Undo stack
// - in move/resize mode, the element's attributes which were affected by the move/resize are
@@ -3256,7 +3256,7 @@
cur_text.font_family = selected.getAttribute("font-family");
}
selectorManager.requestSelector(selected).showGrips(true);
-
+
// This shouldn't be necessary as it was done on mouseDown...
// call("selected", [selected]);
}
@@ -3264,8 +3264,8 @@
recalculateAllSelectedDimensions();
// if it was being dragged/resized
- r_start_x = r_start_x;
- r_start_y = r_start_y;
+ r_start_x = r_start_x;
+ r_start_y = r_start_y;
var difference_x = Math.abs(real_x-r_start_x);
var difference_y = Math.abs(real_y-r_start_y);
@@ -3292,7 +3292,7 @@
}
}
} // no change in mouse position
-
+
// Remove non-scaling stroke
if(svgedit.browser.supportsNonScalingStroke()) {
var elem = selectedElements[0];
@@ -3401,7 +3401,7 @@
element = null;
// continue to be set to true so that mouseMove happens
started = true;
-
+
var res = pathActions.mouseUp(evt, element, mouse_x, mouse_y);
element = res.element;
keep = res.keep;
@@ -3421,7 +3421,7 @@
element = null;
current_mode = "select";
var batchCmd = canvas.undoMgr.finishUndoableChange();
- if (!batchCmd.isEmpty()) {
+ if (!batchCmd.isEmpty()) {
addCommandToHistory(batchCmd);
}
// perform recalculation to weed out any stray identity transforms that might get stuck
@@ -3432,13 +3432,13 @@
// This could occur in an extension
break;
}
-
+
var ext_result = runExtensions("mouseUp", {
event: evt,
mouse_x: mouse_x,
mouse_y: mouse_y
}, true);
-
+
$.each(ext_result, function(i, r) {
if(r) {
keep = r.keep || keep;
@@ -3446,37 +3446,37 @@
started = r.started || started;
}
});
-
+
if (!keep && element != null) {
getCurrentDrawing().releaseId(getId());
element.parentNode.removeChild(element);
element = null;
-
+
var t = evt.target;
-
- // if this element is in a group, go up until we reach the top-level group
+
+ // if this element is in a group, go up until we reach the top-level group
// just below the layer groups
// TODO: once we implement links, we also would have to check for <a> elements
while (t.parentNode.parentNode.tagName == "g") {
t = t.parentNode;
}
- // if we are not in the middle of creating a path, and we've clicked on some shape,
+ // if we are not in the middle of creating a path, and we've clicked on some shape,
// then go to Select mode.
// WebKit returns <div> when the canvas is clicked, Firefox/Opera return <svg>
if ( (current_mode != "path" || !drawn_path) &&
t.parentNode.id != "selectorParentGroup" &&
- t.id != "svgcanvas" && t.id != "svgroot")
+ t.id != "svgcanvas" && t.id != "svgroot")
{
// switch into "select" mode if we've clicked on an element
canvas.setMode("select");
selectOnly([t], true);
}
-
+
} else if (element != null) {
canvas.addedNew = true;
-
+
if(useUnit) svgedit.units.convertAttrs(element);
-
+
var ani_dur = .2, c_ani;
if(opac_ani.beginElement && element.getAttribute('opacity') != cur_shape.opacity) {
c_ani = $(opac_ani).clone().attr({
@@ -3490,7 +3490,7 @@
} else {
ani_dur = 0;
}
-
+
// Ideally this would be done on the endEvent of the animation,
// but that doesn't seem to be supported in Webkit
setTimeout(function() {
@@ -3508,14 +3508,14 @@
// we create the insert command that is stored on the stack
// undo means to call cmd.unapply(), redo means to call cmd.apply()
addCommandToHistory(new InsertElementCommand(element));
-
+
call("changed",[element]);
}, ani_dur * 1000);
}
-
+
start_transform = null;
};
-
+
var dblClick = function(evt) {
var evt_target = evt.target;
var parent = evt_target.parentNode;
@@ -3523,16 +3523,16 @@
var tagName = mouse_target.tagName;
if(parent === current_group) return;
-
+
if(tagName === 'text' && current_mode !== 'textedit') {
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm );
textActions.select(mouse_target, pt.x, pt.y);
}
-
+
if((tagName === "g" || tagName === "a") && getRotationAngle(mouse_target)) {
- // TODO: Allow method of in-group editing without having to do
+ // TODO: Allow method of in-group editing without having to do
// this (similar to editing rotated paths)
-
+
// Ungroup and regroup
pushGroupProperties(mouse_target);
mouse_target = selectedElements[0];
@@ -3542,7 +3542,7 @@
if(current_group) {
leaveContext();
}
-
+
if((parent.tagName !== 'g' && parent.tagName !== 'a') ||
parent === getCurrentDrawing().getCurrentLayer() ||
mouse_target === selectorManager.selectorParentGroup)
@@ -3558,12 +3558,12 @@
e.preventDefault();
return false;
};
-
+
// Added mouseup to the container here.
// TODO(codedread): Figure out why after the Closure compiler, the window mouseup is ignored.
$(container).mousedown(mouseDown).mousemove(mouseMove).click(handleLinkInCanvas).dblclick(dblClick).mouseup(mouseUp);
// $(window).mouseup(mouseUp);
-
+
$(container).bind("mousewheel DOMMouseScroll", function(e){
if(!e.shiftKey) return;
e.preventDefault();
@@ -3589,14 +3589,14 @@
if (e.detail > 0) {
bbox.factor = .5;
} else if (e.detail < 0) {
- bbox.factor = 2;
- }
+ bbox.factor = 2;
+ }
}
-
+
if(!bbox.factor) return;
call("zoomed", bbox);
});
-
+
}());
// Function: preventClickDefault
@@ -3621,11 +3621,11 @@
var matrix;
var last_x, last_y;
var allow_dbl;
-
+
function setCursor(index) {
var empty = (textinput.value === "");
$(textinput).focus();
-
+
if(!arguments.length) {
if(empty) {
index = 0;
@@ -3634,7 +3634,7 @@
index = textinput.selectionEnd;
}
}
-
+
var charbb;
charbb = chardata[index];
if(!empty) {
@@ -3650,7 +3650,7 @@
});
cursor = getElem("selectorParentGroup").appendChild(cursor);
}
-
+
if(!blinker) {
blinker = setInterval(function() {
var show = (cursor.getAttribute('display') === 'none');
@@ -3658,11 +3658,11 @@
}, 600);
}
-
-
+
+
var start_pt = ptToScreen(charbb.x, textbb.y);
var end_pt = ptToScreen(charbb.x, (textbb.y + textbb.height));
-
+
assignAttributes(cursor, {
x1: start_pt.x,
y1: start_pt.y,
@@ -3671,20 +3671,20 @@
visibility: 'visible',
display: 'inline'
});
-
+
if(selblock) selblock.setAttribute('d', 'M 0 0');
}
-
+
function setSelection(start, end, skipInput) {
if(start === end) {
setCursor(end);
return;
}
-
+
if(!skipInput) {
textinput.setSelectionRange(start, end);
}
-
+
selblock = getElem("text_selectblock");
if (!selblock) {
@@ -3698,30 +3698,30 @@
getElem("selectorParentGroup").appendChild(selblock);
}
-
+
var startbb = chardata[start];
-
+
var endbb = chardata[end];
-
+
cursor.setAttribute('visibility', 'hidden');
-
+
var tl = ptToScreen(startbb.x, textbb.y),
tr = ptToScreen(startbb.x + (endbb.x - startbb.x), textbb.y),
bl = ptToScreen(startbb.x, textbb.y + textbb.height),
br = ptToScreen(startbb.x + (endbb.x - startbb.x), textbb.y + textbb.height);
-
-
+
+
var dstr = "M" + tl.x + "," + tl.y
+ " L" + tr.x + "," + tr.y
+ " " + br.x + "," + br.y
+ " " + bl.x + "," + bl.y + "z";
-
+
assignAttributes(selblock, {
d: dstr,
'display': 'inline'
});
}
-
+
function getIndexFromPoint(mouse_x, mouse_y) {
// Position cursor here
var pt = svgroot.createSVGPoint();
@@ -3748,62 +3748,62 @@
}
return charpos;
}
-
+
function setCursorFromPoint(mouse_x, mouse_y) {
setCursor(getIndexFromPoint(mouse_x, mouse_y));
}
-
+
function setEndSelectionFromPoint(x, y, apply) {
var i1 = textinput.selectionStart;
var i2 = getIndexFromPoint(x, y);
-
+
var start = Math.min(i1, i2);
var end = Math.max(i1, i2);
setSelection(start, end, !apply);
}
-
+
function screenToPt(x_in, y_in) {
var out = {
x: x_in,
y: y_in
}
-
+
out.x /= current_zoom;
- out.y /= current_zoom;
+ out.y /= current_zoom;
if(matrix) {
var pt = transformPoint(out.x, out.y, matrix.inverse());
out.x = pt.x;
out.y = pt.y;
}
-
+
return out;
- }
-
+ }
+
function ptToScreen(x_in, y_in) {
var out = {
x: x_in,
y: y_in
}
-
+
if(matrix) {
var pt = transformPoint(out.x, out.y, matrix);
out.x = pt.x;
out.y = pt.y;
}
-
+
out.x *= current_zoom;
out.y *= current_zoom;
-
+
return out;
}
-
+
function hideCursor() {
if(cursor) {
cursor.setAttribute('visibility', 'hidden');
}
}
-
+
function selectAll(evt) {
setSelection(0, curtext.textContent.length);
$(this).unbind(evt);
@@ -3811,25 +3811,25 @@
function selectWord(evt) {
if(!allow_dbl || !curtext) return;
-
+
var ept = transformPoint( evt.pageX, evt.pageY, root_sctm ),
mouse_x = ept.x * current_zoom,
mouse_y = ept.y * current_zoom;
var pt = screenToPt(mouse_x, mouse_y);
-
+
var index = getIndexFromPoint(pt.x, pt.y);
var str = curtext.textContent;
var first = str.substr(0, index).replace(/[a-z0-9]+$/i, '').length;
var m = str.substr(index).match(/^[a-z0-9]+/i);
var last = (m?m[0].length:0) + index;
setSelection(first, last);
-
+
// Set tripleclick
$(evt.target).click(selectAll);
setTimeout(function() {
$(evt.target).unbind('click', selectAll);
}, 300);
-
+
}
return {
@@ -3843,27 +3843,27 @@
},
mouseDown: function(evt, mouse_target, start_x, start_y) {
var pt = screenToPt(start_x, start_y);
-
+
textinput.focus();
setCursorFromPoint(pt.x, pt.y);
last_x = start_x;
last_y = start_y;
-
+
// TODO: Find way to block native selection
},
mouseMove: function(mouse_x, mouse_y) {
var pt = screenToPt(mouse_x, mouse_y);
setEndSelectionFromPoint(pt.x, pt.y);
- },
+ },
mouseUp: function(evt, mouse_x, mouse_y) {
var pt = screenToPt(mouse_x, mouse_y);
-
+
setEndSelectionFromPoint(pt.x, pt.y, true);
-
- // TODO: Find a way to make this work: Use transformed BBox instead of evt.target
+
+ // TODO: Find a way to make this work: Use transformed BBox instead of evt.target
// if(last_x === mouse_x && last_y === mouse_y
// && !svgedit.math.rectsIntersect(transbb, {x: pt.x, y: pt.y, width:0, height:0})) {
-// textActions.toSelectMode(true);
+// textActions.toSelectMode(true);
// }
if(
@@ -3883,21 +3883,21 @@
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');
-
+
if(!arguments.length) {
setCursor();
} else {
var pt = screenToPt(x, y);
setCursorFromPoint(pt.x, pt.y);
}
-
+
setTimeout(function() {
allow_dbl = true;
}, 300);
@@ -3909,11 +3909,11 @@
if(selblock) $(selblock).attr('display','none');
if(cursor) $(cursor).attr('visibility','hidden');
$(curtext).css('cursor', 'move');
-
+
if(selectElem) {
clearSelection();
$(curtext).css('cursor', 'move');
-
+
call("selected", [curtext]);
addToSelection([curtext], true);
}
@@ -3921,11 +3921,11 @@
// No content, so delete
canvas.deleteSelectedElements();
}
-
+
$(textinput).blur();
-
+
curtext = false;
-
+
// if(svgedit.browser.supportsEditableText()) {
// curtext.removeAttribute('editable');
// }
@@ -3946,47 +3946,47 @@
// curtext.select();
// return;
// }
-
+
if(!curtext.parentNode) {
// Result of the ffClone, need to get correct element
curtext = selectedElements[0];
selectorManager.requestSelector(curtext).showGrips(false);
}
-
+
var str = curtext.textContent;
var len = str.length;
-
+
var xform = curtext.getAttribute('transform');
textbb = svgedit.utilities.getBBox(curtext);
-
+
matrix = xform?getMatrix(curtext):null;
chardata = Array(len);
textinput.focus();
-
+
$(curtext).unbind('dblclick', selectWord).dblclick(selectWord);
-
+
if(!len) {
var end = {x: textbb.x + (textbb.width/2), width: 0};
}
-
+
for(var i=0; i<len; i++) {
var start = curtext.getStartPositionOfChar(i);
var end = curtext.getEndPositionOfChar(i);
-
+
if(!svgedit.browser.supportsGoodTextCharPos()) {
var offset = canvas.contentW * current_zoom;
start.x -= offset;
end.x -= offset;
-
+
start.x /= current_zoom;
end.x /= current_zoom;
}
-
+
// Get a "bbox" equivalent for each character. Uses the
// bbox data of the actual text for y, height purposes
-
+
// TODO: Decide if y, width and height are actually necessary
chardata[i] = {
x: start.x,
@@ -3995,7 +3995,7 @@
height: textbb.height
};
}
-
+
// Add a last bbox for cursor at end of text
chardata.push({
x: end.x,
@@ -4010,11 +4010,11 @@
// Group: Path edit functions
// Functions relating to editing path elements
var pathActions = canvas.pathActions = function() {
-
+
var subpath = false;
var current_path;
var newPoint, firstCtrl;
-
+
function resetD(p) {
p.setAttribute("d", pathActions.convertPath(p));
}
@@ -4050,9 +4050,9 @@
}
// TODO: Correct this:
pathActions.canDeleteNodes = true;
-
+
pathActions.closed_subpath = this.subpathIsClosed(this.selected_pts[0]);
-
+
call("selected", grips);
}
@@ -4062,7 +4062,7 @@
stretchy = null;
this.lastCtrlPoint = [0, 0];
-
+
// This function converts a polyline (created by the fh_path tool) into
// a path element and coverts every three line segments into a single bezier
// curve in an attempt to smooth out the free-hand
@@ -4071,13 +4071,13 @@
var N = points.numberOfItems;
if (N >= 4) {
// loop through every 3 points and convert to a cubic bezier curve segment
- //
- // NOTE: this is cheating, it means that every 3 points has the potential to
+ //
+ // NOTE: this is cheating, it means that every 3 points has the potential to
// be a corner instead of treating each point in an equal manner. In general,
// this technique does not look that good.
- //
+ //
// I am open to better ideas!
- //
+ //
// Reading:
// - http://www.efg2.com/Lab/Graphics/Jean-YvesQueinecBezierCurves.htm
// - http://www.codeproject.com/KB/graphics/BezierSpline.aspx?msg=2956963
@@ -4090,7 +4090,7 @@
var ct1 = points.getItem(i);
var ct2 = points.getItem(i+1);
var end = points.getItem(i+2);
-
+
// if the previous segment had a control point, we want to smooth out
// the control points on both sides
if (prevCtlPt) {
@@ -4103,9 +4103,9 @@
ct1 = newpts[1];
}
}
-
+
d.push([ct1.x,ct1.y,ct2.x,ct2.y,end.x,end.y].join(','));
-
+
curpos = end;
prevCtlPt = ct2;
}
@@ -4137,12 +4137,12 @@
if(current_mode === "path") {
mouse_x = start_x;
mouse_y = start_y;
-
+
var x = mouse_x/current_zoom,
y = mouse_y/current_zoom,
stretchy = getElem("path_stretch_line");
- newPoint = [x, y];
-
+ newPoint = [x, y];
+
if(curConfig.gridSnapping){
x = snapToGrid(x);
y = snapToGrid(y);
@@ -4163,9 +4163,9 @@
stretchy.setAttribute("display", "inline");
this.stretchy = stretchy;
-
+
var keep = null;
-
+
// if pts array is empty, create path element with M at current point
if (!drawn_path) {
d_attr = "M" + x + "," + y + " ";
@@ -4200,15 +4200,15 @@
break;
}
}
-
+
// get path element that we are in the process of creating
var id = getId();
-
+
// Remove previous path object if previously created
svgedit.path.removePath_(id);
-
+
var newpath = getElem(id);
-
+
var len = seglist.numberOfItems;
// if we clicked on an existing point, then we are done this path, commit it
// (i,i+1) are the x,y that were clicked on
@@ -4224,7 +4224,7 @@
var abs_y = seglist.getItem(0).y;
var grip_x = svgedit.path.first_grip ? svgedit.path.first_grip[0]/current_zoom : seglist.getItem(0).x;
var grip_y = svgedit.path.first_grip ? svgedit.path.first_grip[1]/current_zoom : seglist.getItem(0).y;
-
+
var s_seg = stretchy.pathSegList.getItem(1);
if(s_seg.pathSegType === 4) {
@@ -4247,7 +4247,7 @@
return keep;
}
$(stretchy).remove();
-
+
// this will signal to commit the path
element = newpath;
drawn_path = null;
@@ -4257,7 +4257,7 @@
if(svgedit.path.path.matrix) {
remapElement(newpath, {}, svgedit.path.path.matrix.inverse());
}
-
+
var new_d = newpath.getAttribute("d");
var orig_d = $(svgedit.path.path.elem).attr("d");
$(svgedit.path.path.elem).attr("d", orig_d + new_d);
@@ -4286,7 +4286,7 @@
var lastx = last.x, lasty = last.y;
if(evt.shiftKey) { var xya = snapToAngle(lastx,lasty,x,y); x=xya.x; y=xya.y; }
-
+
// Use the segment defined by stretchy
var s_seg = stretchy.pathSegList.getItem(1);
if(s_seg.pathSegType === 4) {
@@ -4301,12 +4301,12 @@
s_seg.y2 / current_zoom
);
}
-
+
drawn_path.pathSegList.appendItem(newseg);
-
+
x *= current_zoom;
y *= current_zoom;
-
+
// update everything to the latest point
stretchy.setAttribute('d', ['M', x, y, x, y].join(' '));
var pointGrip1 = svgedit.path.addCtrlGrip('1c1');
@@ -4337,20 +4337,20 @@
}
return;
}
-
+
// TODO: Make sure current_path isn't null at this point
if(!svgedit.path.path) return;
-
+
svgedit.path.path.storeD();
-
+
var id = evt.target.id;
if (id.substr(0,14) == "pathpointgrip_") {
// Select this point
var cur_pt = svgedit.path.path.cur_pt = parseInt(id.substr(14));
svgedit.path.path.dragging = [start_x, start_y];
var seg = svgedit.path.path.segs[cur_pt];
-
- // only clear selection if shift is not pressed (otherwise, add
+
+ // only clear selection if shift is not pressed (otherwise, add
// node to selection)
if (!evt.shiftKey) {
if(svgedit.path.path.selected_pts.length <= 1 || !seg.selected) {
@@ -4364,7 +4364,7 @@
}
} else if(id.indexOf("ctrlpointgrip_") == 0) {
svgedit.path.path.dragging = [start_x, start_y];
-
+
var parts = id.split('_')[1].split('c');
var cur_pt = parts[0]-0;
var ctrl_num = parts[1]-0;
@@ -4467,7 +4467,7 @@
if(!drawn_path) return;
var seglist = drawn_path.pathSegList;
var index = seglist.numberOfItems - 1;
- var pointGrip1 = svgedit.path.addCtrlGrip('1c1');
+ var pointGrip1 = svgedit.path.addCtrlGrip('1c1');
var pointGrip2 = svgedit.path.addCtrlGrip('0c2');
if(newPoint) {
@@ -4484,20 +4484,20 @@
var pt_x = newPoint[0];
var pt_y = newPoint[1];
-
+
// set curve
var seg = seglist.getItem(index);
var cur_x = mouse_x / current_zoom;
var cur_y = mouse_y / current_zoom;
var alt_x = (is_linked) ? (pt_x + (pt_x - cur_x)) : current_pointGrip2_x;
var alt_y = (is_linked) ? (pt_y + (pt_y - cur_y)) : current_pointGrip2_y;
-
-
+
+
pointGrip2.setAttribute('cx', alt_x * current_zoom);
pointGrip2.setAttribute('cy', alt_y * current_zoom);
pointGrip2.setAttribute('display', 'inline');
-
-
+
+
var ctrlLine = svgedit.path.getCtrlLine(1);
var ctrlLine2 = svgedit.path.getCtrlLine(2);
assignAttributes(ctrlLine, {
@@ -4507,7 +4507,7 @@
y2: pt_y * current_zoom,
display: 'inline'
});
-
+
assignAttributes(ctrlLine2, {
x1: alt_x * current_zoom,
@@ -4522,11 +4522,11 @@
firstCtrl = [mouse_x, mouse_y];
} else {
var last_x, last_y;
-
+
var last = seglist.getItem(index - 1);
var last_x = last.x;
var last_y = last.y
-
+
if(last.pathSegType === 6) {
last_x += (last_x - last.x2);
last_y += (last_y - last.y2);
@@ -4552,7 +4552,7 @@
if(prev.pathSegType === 6) {
var prev_x = this.lastCtrlPoint[0]/current_zoom || prev.x + (prev.x - prev.x2);
var prev_y = this.lastCtrlPoint[1]/current_zoom || prev.y + (prev.y - prev.y2);
- svgedit.path.replacePathSeg(6, 1, [mouse_x, mouse_y, prev_x * current_zoom, prev_y * current_zoom, lastgripx, lastgripy], stretchy);
+ svgedit.path.replacePathSeg(6, 1, [mouse_x, mouse_y, prev_x * current_zoom, prev_y * current_zoom, lastgripx, lastgripy], stretchy);
} else if(firstCtrl) {
svgedit.path.replacePathSeg(6, 1, [mouse_x, mouse_y, firstCtrl[0], firstCtrl[1], mouse_x, mouse_y], stretchy);
} else {
@@ -4592,7 +4592,7 @@
if(!seg.next && !seg.prev) return;
var item = seg.item;
var rbb = rubberBox.getBBox();
-
+
var pt = svgedit.path.getGripPt(seg);
var pt_bb = {
x: pt.x,
@@ -4600,7 +4600,7 @@
width: 0,
height: 0
};
-
+
var sel = svgedit.math.rectsIntersect(rbb, pt_bb);
this.select(sel);
@@ -4609,7 +4609,7 @@
});
}
- },
+ },
mouseUp: function(evt, element, mouse_x, mouse_y) {
var lastpointgrip = getElem('ctrlpointgrip_1c1');
var firstpointgrip = getElem('ctrlpointgrip_0c2');
@@ -4639,34 +4639,34 @@
element: element
}
}
-
+
// Edit mode
-
+
if (svgedit.path.path.dragging) {
var last_pt = svgedit.path.path.cur_pt;
svgedit.path.path.dragging = false;
svgedit.path.path.dragctrl = false;
svgedit.path.path.update();
-
-
+
+
if(hasMoved) {
svgedit.path.path.endChanges("Move path point(s)");
- }
-
+ }
+
if(!evt.shiftKey && !hasMoved) {
svgedit.path.path.selectPt(last_pt);
- }
+ }
}
else if(rubberBox && rubberBox.getAttribute('display') != 'none') {
// Done with multi-node-select
rubberBox.setAttribute("display", "none");
-
+
if(rubberBox.getAttribute('width') <= 2 && rubberBox.getAttribute('height') <= 2) {
pathActions.toSelectMode(evt.target);
}
-
- // else, move back to select mode
+
+ // else, move back to select mode
} else {
pathActions.toSelectMode(evt.target);
}
@@ -4686,12 +4686,12 @@
svgedit.path.path.show(false);
current_path = false;
clearSelection();
-
+
if(svgedit.path.path.matrix) {
// Rotated, so may need to re-calculate the center
svgedit.path.recalcRotatedPath();
}
-
+
if(selPath) {
call("selected", [elem]);
addToSelection([elem], true);
@@ -4715,14 +4715,14 @@
} // going into pathedit mode
else {
current_path = target;
- }
+ }
},
reorient: function() {
var elem = selectedElements[0];
if(!elem) return;
var angle = getRotationAngle(elem);
if(angle == 0) return;
-
+
var batchCmd = new BatchCommand("Reorient path");
var changes = {
d: elem.getAttribute('d'),
@@ -4731,18 +4731,18 @@
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes));
clearSelection();
this.resetOrientation(elem);
-
+
addCommandToHistory(batchCmd);
// Set matrix to null
- svgedit.path.getPath_(elem).show(false).matrix = null;
+ svgedit.path.getPath_(elem).show(false).matrix = null;
this.clear();
-
+
addToSelection([elem], true);
call("changed", selectedElements);
},
-
+
clear: function(remove) {
current_path = null;
if (drawn_path) {
@@ -4764,11 +4764,11 @@
tlist.clear();
path.removeAttribute("transform");
var segList = path.pathSegList;
-
+
// Opera/win/non-EN throws an error here.
// TODO: Find out why!
// Presumed fixed in Opera 10.5, so commented out for now
-
+
// try {
var len = segList.numberOfItems;
// } catch(err) {
@@ -4794,7 +4794,7 @@
});
svgedit.path.replacePathSeg(type, i, pts, path);
}
-
+
reorientGrads(path, m);
@@ -4814,16 +4814,16 @@
y: seg.item.y,
type: seg.type
};
- },
+ },
linkControlPoints: function(linkPoints) {
svgedit.path.setLinkControlPoints(linkPoints);
},
clonePathNode: function() {
svgedit.path.path.storeD();
-
+
var sel_pts = svgedit.path.path.selected_pts;
var segs = svgedit.path.path.segs;
-
+
var i = sel_pts.length;
var nums = [];
@@ -4833,7 +4833,7 @@
nums.push(pt + i);
nums.push(pt + i + 1);
}
-
+
svgedit.path.path.init().addPtsToSelection(nums);
svgedit.path.path.endChanges("Clone path node(s)");
@@ -4842,14 +4842,14 @@
var sel_pts = svgedit.path.path.selected_pts;
// Only allow one selected node for now
if(sel_pts.length !== 1) return;
-
+
var elem = svgedit.path.path.elem;
var list = elem.pathSegList;
var len = list.numberOfItems;
var index = sel_pts[0];
-
+
var open_pt = null;
var start_item = null;
@@ -4869,7 +4869,7 @@
return false;
}
});
-
+
if(open_pt == null) {
// Single path, so close last seg
open_pt = svgedit.path.path.segs.length - 1;
@@ -4877,10 +4877,10 @@
if(open_pt !== false) {
// Close this path
-
+
// Create a line going to the previous "M"
var newseg = elem.createSVGPathSegLinetoAbs(start_item.x, start_item.y);
-
+
var closer = elem.createSVGPathSegClosePath();
if(open_pt == svgedit.path.path.segs.length) {
list.appendItem(newseg);
@@ -4889,30 +4889,30 @@
svgedit.path.insertItemBefore(elem, closer, open_pt);
svgedit.path.insertItemBefore(elem, newseg, open_pt);
}
-
+
svgedit.path.path.init().selectPt(open_pt+1);
return;
}
-
-
+
+
// M 1,1 L 2,2 L 3,3 L 1,1 z // open at 2,2
// M 2,2 L 3,3 L 1,1
-
- // M 1,1 L 2,2 L 1,1 z M 4,4 L 5,5 L6,6 L 5,5 z
- // M 1,1 L 2,2 L 1,1 z [M 4,4] L 5,5 L(M)6,6 L 5,5 z
-
+
+ // M 1,1 L 2,2 L 1,1 z M 4,4 L 5,5 L6,6 L 5,5 z
+ // M 1,1 L 2,2 L 1,1 z [M 4,4] L 5,5 L(M)6,6 L 5,5 z
+
var seg = svgedit.path.path.segs[index];
-
+
if(seg.mate) {
list.removeItem(index); // Removes last "L"
list.removeItem(index); // Removes the "Z"
svgedit.path.path.init().selectPt(index - 1);
return;
}
-
+
var last_m, z_seg;
-
+
// Find this sub-path's closing point and remove
for(var i=0; i<list.numberOfItems; i++) {
var item = list.getItem(i);
@@ -4931,26 +4931,26 @@
break;
}
}
-
+
var num = (index - last_m) - 1;
-
+
while(num--) {
svgedit.path.insertItemBefore(elem, list.getItem(last_m), z_seg);
}
-
+
var pt = list.getItem(last_m);
-
+
// Make this point the new "M"
svgedit.path.replacePathSeg(2, last_m, [pt.x, pt.y]);
-
+
var i = index
-
+
svgedit.path.path.init().selectPt(0);
},
deletePathNode: function() {
if(!pathActions.canDeleteNodes) return;
svgedit.path.path.storeD();
-
+
var sel_pts = svgedit.path.path.selected_pts;
var i = sel_pts.length;
@@ -4958,12 +4958,12 @@
var pt = sel_pts[i];
svgedit.path.path.deleteSeg(pt);
}
-
+
// Cleanup
var cleanup = function() {
var segList = svgedit.path.path.elem.pathSegList;
var len = segList.numberOfItems;
-
+
var remItems = function(pos, count) {
while(count--) {
segList.removeItem(pos);
@@ -4971,7 +4971,7 @@
}
if(len <= 1) return true;
-
+
while(len--) {
var item = segList.getItem(len);
if(item.pathSegType === 1) {
@@ -4990,12 +4990,12 @@
} else if(item.pathSegType === 2) {
if(len > 0) {
var prev_type = segList.getItem(len-1).pathSegType;
- // Path has M M
+ // Path has M M
if(prev_type === 2) {
remItems(len-1, 1);
cleanup();
break;
- // Entire path ends with Z M
+ // Entire path ends with Z M
} else if(prev_type === 1 && segList.numberOfItems-1 === len) {
remItems(len, 1);
cleanup();
@@ -5003,23 +5003,23 @@
}
}
}
- }
+ }
return false;
}
-
+
cleanup();
-
+
// Completely delete a path with 1 or 0 segments
if(svgedit.path.path.elem.pathSegList.numberOfItems <= 1) {
canvas.setMode("select")
canvas.deleteSelectedElements();
return;
}
-
+
svgedit.path.path.init();
-
+
svgedit.path.path.clearSelection();
-
+
// TODO: Find right way to select point now
// path.selectPt(sel_pt);
if(window.opera) { // Opera repaints incorrectly
@@ -5034,14 +5034,14 @@
moveNode: function(attr, newValue) {
var sel_pts = svgedit.path.path.selected_pts;
if(!sel_pts.length) return;
-
+
svgedit.path.path.storeD();
-
+
// Get first selected point
var seg = svgedit.path.path.segs[sel_pts[0]];
var diff = {x:0, y:0};
diff[attr] = newValue - seg.item[attr];
-
+
seg.move(diff.x, diff.y);
svgedit.path.path.endChanges("Move path point");
},
@@ -5057,7 +5057,7 @@
if(item.pathSegType === 2) {
last_m = item;
}
-
+
if(item.pathSegType === 1) {
var prev = segList.getItem(i-1);
if(prev.x != last_m.x || prev.y != last_m.y) {
@@ -5068,7 +5068,7 @@
pathActions.fixEnd(elem);
break;
}
-
+
}
}
if(svgedit.browser.isWebkit()) resetD(elem);
@@ -5080,7 +5080,7 @@
var curx = 0, cury = 0;
var d = "";
var last_m = null;
-
+
for (var i = 0; i < len; ++i) {
var seg = segList.getItem(i);
// if these properties are not in the segment, set them to zero
@@ -5090,10 +5090,10 @@
y1 = seg.y1 || 0,
x2 = seg.x2 || 0,
y2 = seg.y2 || 0;
-
+
var type = seg.pathSegType;
var letter = pathMap[type]['to'+(toRel?'Lower':'Upper')+'Case']();
-
+
var addToD = function(pnts, more, last) {
var str = '';
var more = more?' '+more.join(' '):'';
@@ -5103,7 +5103,7 @@
});
d += letter + pnts.join(' ') + more + last;
}
-
+
switch (type) {
case 1: // z,Z closepath (Z/z)
d += "z";
@@ -5143,12 +5143,12 @@
y -= cury;
case 5: // relative line (l)
case 3: // relative move (m)
- // If the last segment was a "z", this must be relative to
+ // If the last segment was a "z", this must be relative to
if(last_m && segList.getItem(i-1).pathSegType === 1 && !toRel) {
curx = last_m[0];
cury = last_m[1];
}
-
+
case 19: // relative smooth quad (t)
if(toRel) {
curx += x;
@@ -5160,7 +5160,7 @@
cury = y;
}
if(type === 3) last_m = [curx, cury];
-
+
addToD([[x,y]]);
break;
case 6: // absolute cubic (C)
@@ -5181,7 +5181,7 @@
case 8: // absolute quad (Q)
x -= curx; x1 -= curx;
y -= cury; y1 -= cury;
- case 9: // relative quad (q)
+ case 9: // relative quad (q)
if(toRel) {
curx += x;
cury += y;
@@ -5241,23 +5241,23 @@
// Function: removeUnusedDefElems
// Looks at DOM elements inside the <defs> to see if they are referred to,
// removes them from the DOM if they are not.
-//
+//
// Returns:
// The amount of elements that were removed
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'];
var alen = attrs.length;
-
+
var all_els = svgcontent.getElementsByTagNameNS(svgns, '*');
var all_len = all_els.length;
-
+
for(var i=0; i<all_len; i++) {
var el = all_els[i];
for(var j = 0; j < alen; j++) {
@@ -5268,14 +5268,14 @@
}
}
}
-
+
// gradients can refer to other gradients
var href = getHref(el);
if (href && href.indexOf('#') === 0) {
defelem_uses.push(href.substr(1));
}
};
-
+
var defelems = $(defs).find("linearGradient, radialGradient, filter, marker, svg, symbol");
defelem_ids = [],
i = defelems.length;
@@ -5294,34 +5294,34 @@
}
// Function: svgCanvasToString
-// Main function to set up the SVG content for output
+// Main function to set up the SVG content for output
//
-// Returns:
+// Returns:
// String containing the SVG image for output
this.svgCanvasToString = function() {
// keep calling it until there are none to remove
while (removeUnusedDefElems() > 0) {};
-
+
pathActions.clear(true);
-
+
// Keep SVG-Edit comment on top
$.each(svgcontent.childNodes, function(i, node) {
if(i && node.nodeType === 8 && node.data.indexOf('Created with') >= 0) {
svgcontent.insertBefore(node, svgcontent.firstChild);
}
});
-
+
// Move out of in-group editing mode
if(current_group) {
leaveContext();
selectOnly([current_group]);
}
-
+
//hide grid, otherwise shows a black canvas
$('#canvasGrid').attr('display', 'none');
-
+
var naked_svgs = [];
-
+
// Unwrap gsvg if it has no special attributes (only id and style)
$(svgcontent).find('g:data(gsvg)').each(function() {
var attrs = this.attributes;
@@ -5339,25 +5339,25 @@
}
});
var output = this.svgToString(svgcontent, 0);
-
+
// Rewrap gsvg
if(naked_svgs.length) {
$(naked_svgs).each(function() {
groupSvgElem(this);
});
}
-
+
return output;
};
// Function: svgToString
// Sub function ran on each SVG element to convert it to a string as desired
-//
-// Parameters:
+//
+// Parameters:
// elem - The SVG element to convert
// indent - Integer with the amount of spaces to indent this tag
//
-// Returns:
+// Returns:
// String with the given element as an SVG tag
this.svgToString = function(elem, indent) {
var out = new Array(), toXml = svgedit.utilities.toXml;
@@ -5370,13 +5370,13 @@
attr,
i,
childs = elem.childNodes;
-
+
for (var i=0; i<indent; i++) out.push(" ");
out.push("<"); out.push(elem.nodeName);
if(elem.id === 'svgcontent') {
// Process root element separately
var res = getResolution();
-
+
var vb = "";
// TODO: Allow this by dividing all values by current baseVal
// Note that this also means we should properly deal with this on import
@@ -5385,20 +5385,20 @@
// var unit_m = svgedit.units.getTypeMap()[unit];
// 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(' ') + '"';
+// vb = ' viewBox="' + [0, 0, res.w, res.h].join(' ') + '"';
// res.w += unit;
// res.h += unit;
// }
-
+
if(unit !== "px") {
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+'"');
-
+
var nsuris = {};
-
+
// Check elements for namespaces, add if found
$(elem).find('*').andSelf().each(function() {
var el = this;
@@ -5410,22 +5410,22 @@
}
});
});
-
+
var i = attrs.length;
var attr_names = ['width','height','xmlns','x','y','viewBox','id','overflow'];
while (i--) {
attr = attrs.item(i);
var attrVal = toXml(attr.nodeValue);
-
+
// Namespaces have already been dealt with, so skip
if(attr.nodeName.indexOf('xmlns:') === 0) continue;
// only serialize attributes we don't use internally
- if (attrVal != "" && attr_names.indexOf(attr.localName) == -1)
+ if (attrVal != "" && attr_names.indexOf(attr.localName) == -1)
{
if(!attr.namespaceURI || nsMap[attr.namespaceURI]) {
- out.push(' ');
+ out.push(' ');
out.push(attr.nodeName); out.push("=\"");
out.push(attrVal); out.push("\"");
}
@@ -5434,7 +5434,7 @@
} 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);
@@ -5444,25 +5444,25 @@
if (attrVal != "") {
if(attrVal.indexOf('pointer-events') === 0) continue;
if(attr.localName === "class" && attrVal.indexOf('se_') === 0) continue;
- out.push(" ");
+ out.push(" ");
if(attr.localName === 'd') attrVal = pathActions.convertPath(elem, true);
if(!isNaN(attrVal)) {
attrVal = svgedit.units.shortFloat(attrVal);
} else if(unit_re.test(attrVal)) {
attrVal = svgedit.units.shortFloat(attrVal) + unit;
}
-
- // Embed images when saving
+
+ // Embed images when saving
if(save_options.apply
- && elem.nodeName === 'image'
+ && elem.nodeName === 'image'
&& attr.localName === 'href'
&& save_options.images
- && save_options.images === 'embed')
+ && save_options.images === 'embed')
{
var img = encodableImages[attrVal];
if(img) attrVal = img;
}
-
+
// map various namespaces to our fixed namespace prefixes
// (the default xmlns attribute itself does not get a prefix)
if(!attr.namespaceURI || attr.namespaceURI == svgns || nsMap[attr.namespaceURI]) {
@@ -5477,7 +5477,7 @@
out.push(">");
indent++;
var bOneLine = false;
-
+
for (var i=0; i<childs.length; i++)
{
var child = childs.item(i);
@@ -5525,7 +5525,7 @@
// Function: embedImage
// Converts a given image file to a data URL when possible, then runs a given callback
//
-// Parameters:
+// Parameters:
// val - String with the path/URL of the image
// callback - Optional function to run when image data is found, supplies the
// result (data URL or false) as first parameter.
@@ -5567,7 +5567,7 @@
// This function also includes the XML prolog. Clients of the SvgCanvas bind their save
// function to the 'saved' event.
//
-// Returns:
+// Returns:
// Nothing
this.save = function(opts) {
// remove the selected outline before serializing
@@ -5575,7 +5575,7 @@
// Update save options if provided
if(opts) $.extend(save_options, opts);
save_options.apply = true;
-
+
// no need for doctype, see http://jwatt.org/svg/authoring/#doctype-declaration
var str = this.svgCanvasToString();
if (svgedit.browser.supportsBlobs()) {
@@ -5589,15 +5589,15 @@
};
// Function: rasterExport
-// Generates a PNG Data URL based on the current image, then calls "exported"
+// Generates a PNG Data URL based on the current image, then calls "exported"
// with an object including the string and any issues found
this.rasterExport = function() {
// remove the selected outline before serializing
clearSelection();
-
- // Check for known CanVG issues
+
+ // Check for known CanVG issues
var issues = [];
-
+
// Selector and notice
var issue_list = {
'feGaussianBlur': uiStrings.exportNoBlur,
@@ -5605,12 +5605,12 @@
'[stroke-dasharray]': uiStrings.exportNoDashArray
};
var content = $(svgcontent);
-
+
// Add font/text check if Canvas Text API is not implemented
if(!("font" in $('<canvas>')[0].getContext('2d'))) {
issue_list['text'] = uiStrings.exportNoText;
}
-
+
$.each(issue_list, function(sel, descr) {
if(content.find(sel).length) {
issues.push(descr);
@@ -5634,7 +5634,7 @@
// 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
// svgCanvas.randomizeIds() <==> svgCanvas.randomizeIds(true)
@@ -5662,11 +5662,11 @@
//
// <marker id='se_marker_end_svg_7'/>
// <polyline id='svg_7' se:connector='svg_1 svg_6' marker-end='url(#se_marker_end_svg_7)'/>
- //
+ //
// Problem #1: if svg_1 gets renamed, we do not update the polyline's se:connector attribute
// Problem #2: if the polyline svg_7 gets renamed, we do not update the marker id nor the polyline's marker-end attribute
var ref_elems = ["filter", "linearGradient", "pattern", "radialGradient", "symbol", "textPath", "use"];
-
+
svgedit.utilities.walkTree(g, function(n) {
// if it's an element node
if (n.nodeType == 1) {
@@ -5679,7 +5679,7 @@
}
ids[n.id]["elem"] = n;
}
-
+
// now search for all attributes on this element that might refer
// to other elements
$.each(ref_attrs,function(i,attr) {
@@ -5697,7 +5697,7 @@
}
}
});
-
+
// check xlink:href now
var href = svgedit.utilities.getHref(n);
// TODO: what if an <image> or <a> element refers to an element internally?
@@ -5711,20 +5711,20 @@
}
ids[refid]["hrefs"].push(n);
}
- }
+ }
}
});
-
+
// in ids, we now have a map of ids, elements and attributes, let's re-identify
for (var oldid in ids) {
if (!oldid) continue;
var elem = ids[oldid]["elem"];
if (elem) {
var newid = getNextId();
-
+
// assign element its new id
elem.id = newid;
-
+
// remap all url() attributes
var attrs = ids[oldid]["attrs"];
var j = attrs.length;
@@ -5732,7 +5732,7 @@
var attr = attrs[j];
attr.ownerElement.setAttribute(attr.name, "url(#" + newid + ")");
}
-
+
// remap all href attributes
var hreffers = ids[oldid]["hrefs"];
var k = hreffers.length;
@@ -5748,11 +5748,11 @@
// Assigns reference data for each use element
var setUseData = this.setUseData = function(parent) {
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);
@@ -5774,38 +5774,38 @@
return (this.tagName.indexOf('Gradient') >= 0);
});
}
-
+
elems.each(function() {
var grad = this;
if($(grad).attr('gradientUnits') === 'userSpaceOnUse') {
// TODO: Support more than one element with this ref by duplicating parent grad
var elems = $(svgcontent).find('[fill="url(#' + grad.id + ')"],[stroke="url(#' + grad.id + ')"]');
if(!elems.length) return;
-
+
// get object's bounding box
var bb = svgedit.utilities.getBBox(elems[0]);
-
+
// This will occur if the element is inside a <defs> or a <symbol>,
// in which we shouldn't need to convert anyway.
if(!bb) return;
-
+
if(grad.tagName === 'linearGradient') {
var g_coords = $(grad).attr(['x1', 'y1', 'x2', 'y2']);
-
+
// If has transform, convert
var tlist = grad.gradientTransform.baseVal;
if(tlist && tlist.numberOfItems > 0) {
var m = transformListToTransform(tlist).matrix;
var pt1 = transformPoint(g_coords.x1, g_coords.y1, m);
var pt2 = transformPoint(g_coords.x2, g_coords.y2, m);
-
+
g_coords.x1 = pt1.x;
g_coords.y1 = pt1.y;
g_coords.x2 = pt2.x;
g_coords.y2 = pt2.y;
grad.removeAttribute('gradientTransform');
}
-
+
$(grad).attr({
x1: (g_coords.x1 - bb.x) / bb.width,
y1: (g_coords.y1 - bb.y) / bb.height,
@@ -5814,26 +5814,26 @@
});
grad.removeAttribute('gradientUnits');
} else {
- // Note: radialGradient elements cannot be easily converted
+ // Note: radialGradient elements cannot be easily converted
// because userSpaceOnUse will keep circular gradients, while
// objectBoundingBox will x/y scale the gradient according to
- // its bbox.
-
+ // its bbox.
+
// For now we'll do nothing, though we should probably have
- // the gradient be updated as the element is moved, as
+ // the gradient be updated as the element is moved, as
// inkscape/illustrator do.
-
+
// var g_coords = $(grad).attr(['cx', 'cy', 'r']);
-//
+//
// $(grad).attr({
// cx: (g_coords.cx - bb.x) / bb.width,
// cy: (g_coords.cy - bb.y) / bb.height,
// r: g_coords.r
// });
-//
+//
// grad.removeAttribute('gradientUnits');
}
-
+
}
});
@@ -5846,19 +5846,19 @@
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);
@@ -5867,61 +5867,61 @@
call("selected", [elem]);
} else if($elem.data('symbol')) {
elem = $elem.data('symbol');
-
+
ts = $elem.attr('transform');
var pos = $elem.attr(['x','y']);
var vb = elem.getAttribute('viewBox');
-
+
if(vb) {
var nums = vb.split(' ');
pos.x -= +nums[0];
pos.y -= +nums[1];
}
-
+
// Not ideal, but works
ts += " translate(" + (pos.x || 0) + "," + (pos.y || 0) + ")";
-
+
var prev = $elem.prev();
-
+
// Remove <use> element
batchCmd.addSubCommand(new RemoveElementCommand($elem[0], $elem[0].nextSibling, $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));
}
-
+
// Duplicate the gradients for Gecko, since they weren't included in the <symbol>
if(svgedit.browser.isGecko()) {
var dupeGrads = $(findDefs()).children('linearGradient,radialGradient,pattern').clone();
$(g).append(dupeGrads);
}
-
+
if (ts) {
g.setAttribute("transform", ts);
}
-
+
var parent = elem.parentNode;
-
+
uniquifyElems(g);
-
+
// Put the dupe gradients back into <defs> (after uniquifying them)
if(svgedit.browser.isGecko()) {
$(findDefs()).append( $(g).find('linearGradient,radialGradient,pattern') );
}
-
+
// now give the g itself a new id
g.id = getNextId();
-
+
prev.after(g);
-
+
if(parent) {
if(!has_more) {
// remove symbol/svg element
@@ -5931,39 +5931,39 @@
}
batchCmd.addSubCommand(new InsertElementCommand(g));
}
-
+
setUseData(g);
-
+
if(svgedit.browser.isGecko()) {
convertGradients(findDefs());
} else {
convertGradients(g);
}
-
+
// recalculate dimensions on the top-level children so that unnecessary transforms
// are removed
svgedit.utilities.walkTreePost(g, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
-
+
// Give ID for any visible element missing one
$(g).find(visElems).each(function() {
if(!this.id) this.id = getNextId();
});
-
+
selectOnly([g]);
-
+
var cm = pushGroupProperties(g, true);
if(cm) {
batchCmd.addSubCommand(cm);
}
addCommandToHistory(batchCmd);
-
+
} else {
console.log('Unexpected element to ungroup:', elem);
}
}
-//
+//
// Function: setSvgString
// This function sets the current drawing as the input SVG XML.
//
@@ -5985,7 +5985,7 @@
var nextSibling = svgcontent.nextSibling;
var oldzoom = svgroot.removeChild(svgcontent);
batchCmd.addSubCommand(new RemoveElementCommand(oldzoom, nextSibling, svgroot));
-
+
// set new svg document
// If DOM3 adoptNode() available, use it. Otherwise fall back to DOM2 importNode()
if(svgdoc.adoptNode) {
@@ -5994,12 +5994,12 @@
else {
svgcontent = svgdoc.importNode(newDoc.documentElement, true);
}
-
+
svgroot.appendChild(svgcontent);
var content = $(svgcontent);
-
+
canvas.current_drawing_ = new svgedit.draw.Drawing(svgcontent, idprefix);
-
+
// retrieve or set the nonce
var nonce = getCurrentDrawing().getNonce();
if (nonce) {
@@ -6007,7 +6007,7 @@
} else {
call("unsetnonce");
}
-
+
// change image href vals if possible
content.find('image').each(function() {
var image = this;
@@ -6026,14 +6026,14 @@
// Add to encodableImages if it loads
canvas.embedImage(val);
});
-
+
// Wrap child SVGs in group elements
content.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.childNodes.length === 1 && pa.nodeName === 'g') {
@@ -6043,29 +6043,29 @@
groupSvgElem(this);
}
});
-
+
// Put all paint elems in defs
-
+
content.find('linearGradient, radialGradient, pattern').appendTo(findDefs());
-
+
// Set ref element for <use> elements
-
+
// TODO: This should also be done if the object is re-added through "redo"
setUseData(content);
-
+
convertGradients(content[0]);
-
+
// recalculate dimensions on the top-level children so that unnecessary transforms
// are removed
svgedit.utilities.walkTreePost(svgcontent, function(n){try{recalculateDimensions(n)}catch(e){console.log(e)}});
-
+
var attrs = {
id: 'svgcontent',
overflow: curConfig.show_outside_canvas?'visible':'hidden'
};
-
+
var percs = false;
-
+
// determine proper size
if (content.attr("viewBox")) {
var vb = content.attr("viewBox").split(' ');
@@ -6077,9 +6077,9 @@
$.each(['width', 'height'], function(i, dim) {
// Set to 100 if not given
var val = content.attr(dim);
-
+
if(!val) val = '100%';
-
+
if((val+'').substr(-1) === "%") {
// Use user units if percentage given
percs = true;
@@ -6088,31 +6088,31 @@
}
});
}
-
+
// identify layers
identifyLayers();
-
+
// Give ID for any visible layer children missing one
content.children().find(visElems).each(function() {
if(!this.id) this.id = getNextId();
});
-
+
// Percentage width/height, so let's base it on visible elements
if(percs) {
var bb = getStrokedBBox();
attrs.width = bb.width + bb.x;
attrs.height = bb.height + bb.y;
}
-
- // Just in case negative numbers are given or
+
+ // Just in case negative numbers are given or
// result from the percs calculation
if(attrs.width <= 0) attrs.width = 200;
if(attrs.height <= 0) attrs.height = 200;
-
+
content.attr(attrs);
this.contentW = attrs['width'];
this.contentH = attrs['height'];
-
+
$("#canvas_width").val(this.contentW)
$("#canvas_height").val(this.contentH)
var background = $("#canvas_background")
@@ -6131,16 +6131,16 @@
// update root to the correct size
var changes = content.attr(["width", "height"]);
batchCmd.addSubCommand(new ChangeElementCommand(svgroot, changes));
-
+
// reset zoom
current_zoom = 1;
-
+
// reset transform lists
svgedit.transformlist.resetListMap();
clearSelection();
svgedit.path.clearData();
svgroot.appendChild(selectorManager.selectorParentGroup);
-
+
addCommandToHistory(batchCmd);
call("changed", [svgcontent]);
} catch(e) {
@@ -6165,7 +6165,7 @@
opts = { alpha: opac };
opts[refElem.tagName] = refElem;
- }
+ }
else if (color.indexOf("#") === 0) {
opts = {
alpha: opac,
@@ -6190,19 +6190,19 @@
//
// Returns:
// This function returns false if the import was unsuccessful, true otherwise.
-// TODO:
+// TODO:
// * properly handle if namespace is introduced by imported content (must add to svgcontent
// and update all prefixes in the imported node)
// * properly handle recalculating dimensions, recalculateDimensions() doesn't handle
-// arbitrary transform lists, but makes some assumptions about how the transform list
+// arbitrary transform lists, but makes some assumptions about how the transform list
// was obtained
-// * import should happen in top-left of current zoomed viewport
+// * import should happen in top-left of current zoomed viewport
this.importSvgString = function(xmlString) {
try {
// Get unique ID
var uid = svgedit.utilities.encode64(xmlString.length + xmlString).substr(0,32);
-
+
var useExisting = false;
// Look for symbol and make sure symbol exists in image
@@ -6211,18 +6211,18 @@
useExisting = true;
}
}
-
+
var batchCmd = new BatchCommand("Import SVG");
-
+
if(useExisting) {
var symbol = import_ids[uid].symbol;
var ts = import_ids[uid].xform;
} else {
// convert string into XML document
var newDoc = svgedit.utilities.text2xml(xmlString);
-
+
this.prepareSvg(newDoc);
-
+
// import new svg document into our document
var svg;
// If DOM3 adoptNode() available, use it. Otherwise fall back to DOM2 importNode()
@@ -6232,9 +6232,9 @@
else {
svg = svgdoc.importNode(newDoc.documentElement, true);
}
-
+
uniquifyElems(svg);
-
+
var innerw = convertToNum('width', svg.getAttribute("width")),
innerh = convertToNum('height', svg.getAttribute("height")),
innervb = svg.getAttribute("viewBox"),
@@ -6242,32 +6242,32 @@
vb = innervb ? innervb.split(" ") : [0,0,innerw,innerh];
for (var j = 0; j < 4; ++j)
vb[j] = +(vb[j]);
-
+
// TODO: properly handle preserveAspectRatio
var canvasw = +svgcontent.getAttribute("width"),
canvash = +svgcontent.getAttribute("height");
// imported content should be 1/3 of the canvas on its largest dimension
-
+
if (innerh > innerw) {
var ts = "scale(" + (canvash/3)/vb[3] + ")";
}
else {
var ts = "scale(" + (canvash/3)/vb[2] + ")";
}
-
+
// Hack to make recalculateDimensions understand how to scale
ts = "translate(0) " + ts + " translate(0)";
-
+
var symbol = svgdoc.createElementNS(svgns, "symbol");
var defs = findDefs();
-
+
if(svgedit.browser.isGecko()) {
// Move all gradients into root for Firefox, workaround for this bug:
// https://bugzilla.mozilla.org/show_bug.cgi?id=353575
// TODO: Make this properly undo-able.
$(svg).find('linearGradient, radialGradient, pattern').appendTo(defs);
}
-
+
while (svg.firstChild) {
var first = svg.firstChild;
symbol.appendChild(first);
@@ -6278,31 +6278,31 @@
symbol.setAttribute(attr.nodeName, attr.nodeValue);
}
symbol.id = getNextId();
-
+
// Store data
import_ids[uid] = {
symbol: symbol,
xform: ts
}
-
+
findDefs().appendChild(symbol);
batchCmd.addSubCommand(new InsertElementCommand(symbol));
}
-
-
+
+
var use_el = svgdoc.createElementNS(svgns, "use");
use_el.id = getNextId();
setHref(use_el, "#" + symbol.id);
-
+
(current_group || getCurrentDrawing().getCurrentLayer()).appendChild(use_el);
batchCmd.addSubCommand(new InsertElementCommand(use_el));
clearSelection();
-
+
use_el.setAttribute("transform", ts);
recalculateDimensions(use_el);
$(use_el).data('symbol', symbol).data('ref', symbol);
addToSelection([use_el]);
-
+
// 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;
@@ -6330,7 +6330,7 @@
};
// Function: createLayer
-// Creates a new top-level layer in the drawing with the given name, sets the current layer
+// Creates a new top-level layer in the drawing with the given name, sets the current layer
// to it, and then clears the selection This function then calls the 'changed' handler.
// This is an undoable action.
//
@@ -6366,7 +6366,7 @@
if(ch.localName == 'title') continue;
new_layer.appendChild(copyElem(ch));
}
-
+
clearSelection();
identifyLayers();
@@ -6377,7 +6377,7 @@
};
// Function: deleteCurrentLayer
-// Deletes the current layer from the drawing and then clears the selection. This function
+// 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 = getCurrentDrawing().getCurrentLayer();
@@ -6414,11 +6414,11 @@
};
// Function: renameCurrentLayer
-// Renames the current layer. If the layer name is not valid (i.e. unique), then this function
+// Renames the current layer. If the layer name is not valid (i.e. unique), then this function
// does nothing and returns false, otherwise it returns true. This is an undo-able action.
-//
+//
// Parameters:
-// newname - the new name you want to give the current layer. This name must be unique
+// newname - the new name you want to give the current layer. This name must be unique
// among all layer names.
//
// Returns:
@@ -6437,14 +6437,14 @@
}
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;
for (var i = 0; i < len; ++i) {
var child = oldLayer.childNodes.item(i);
// found the <title> element, now append all the
if (child && child.tagName == "title") {
- // wipe out old name
+ // wipe out old name
while (child.firstChild) { child.removeChild(child.firstChild); }
child.textContent = newname;
@@ -6461,14 +6461,14 @@
};
// Function: setCurrentLayerPosition
-// Changes the position of the current layer to the new value. If the new index is not valid,
+// Changes the position of the current layer to the new value. If the new index is not valid,
// this function does nothing and returns false, otherwise it returns true. This is an
// undo-able action.
//
// Parameters:
// newpos - The zero-based index of the new position of the layer. This should be between
// 0 and (number of layers - 1)
-//
+//
// Returns:
// true if the current layer position was changed, false otherwise.
this.setCurrentLayerPosition = function(newpos) {
@@ -6479,7 +6479,7 @@
}
// some unknown error condition (current_layer not in all_layers)
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;
@@ -6495,19 +6495,19 @@
}
svgcontent.insertBefore(drawing.current_layer, refLayer);
addCommandToHistory(new MoveElementCommand(drawing.current_layer, oldNextSibling, svgcontent));
-
+
identifyLayers();
canvas.setCurrentLayer(drawing.getLayerName(newpos));
-
+
return true;
}
}
-
+
return false;
};
// Function: setLayerVisibility
-// Sets the visibility of the layer. If the layer name is not valid, this function return
+// Sets the visibility of the layer. If the layer name is not valid, this function return
// false, otherwise it returns true. This is an undo-able action.
//
// Parameters:
@@ -6526,17 +6526,17 @@
} else {
return false;
}
-
+
if (layer == drawing.getCurrentLayer()) {
clearSelection();
pathActions.clear();
}
-// call("changed", [selected]);
+// call("changed", [selected]);
return true;
};
// Function: moveSelectedToLayer
-// Moves the selected elements to layername. If the name is not a valid layer name, then false
+// Moves the selected elements to layername. If the name is not a valid layer name, then false
// is returned. Otherwise it returns true. This is an undo-able action.
//
// Parameters:
@@ -6555,9 +6555,9 @@
}
}
if (!layer) return false;
-
+
var batchCmd = new BatchCommand("Move Elements to Layer");
-
+
// loop for each selected element and move it
var selElems = selectedElements;
var i = selElems.length;
@@ -6570,9 +6570,9 @@
layer.appendChild(elem);
batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldLayer));
}
-
+
addCommandToHistory(batchCmd);
-
+
return true;
};
@@ -6598,19 +6598,19 @@
prev.appendChild(ch);
batchCmd.addSubCommand(new MoveElementCommand(ch, oldNextSibling, drawing.current_layer));
}
-
+
// Remove current layer
svgcontent.removeChild(drawing.current_layer);
-
+
if(!skipHistory) {
clearSelection();
identifyLayers();
call("changed", [svgcontent]);
-
+
addCommandToHistory(batchCmd);
}
-
+
drawing.current_layer = prev;
return batchCmd;
}
@@ -6622,7 +6622,7 @@
while($(svgcontent).children('g').length > 1) {
batchCmd.addSubCommand(canvas.mergeLayer(true));
}
-
+
clearSelection();
identifyLayers();
call("changed", [svgcontent]);
@@ -6637,7 +6637,7 @@
if(len) {
for(var i = 0; i < len; i++) {
var elem = disabled_elems[i];
-
+
var orig = elData(elem, 'orig_opac');
if(orig !== 1) {
elem.setAttribute('opacity', orig);
@@ -6663,7 +6663,7 @@
// Edit inside this group
current_group = elem;
-
+
// Disable other elements
$(elem).parentsUntil('#svgcontent').andSelf().siblings().each(function() {
var opac = this.getAttribute('opacity') || 1;
@@ -6695,7 +6695,7 @@
// create empty first layer
canvas.createLayer("Layer 1");
-
+
// clear the undo stack
canvas.undoMgr.resetUndoStack();
@@ -6729,10 +6729,10 @@
var getResolution = this.getResolution = function() {
// var vb = svgcontent.getAttribute("viewBox").split(' ');
// return {'w':vb[2], 'h':vb[3], 'zoom': current_zoom};
-
+
var width = svgcontent.getAttribute("width")/current_zoom;
var height = svgcontent.getAttribute("height")/current_zoom;
-
+
return {
'w': width,
'h': height,
@@ -6789,11 +6789,11 @@
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
var tsNextSibling = ts.nextSibling;
@@ -6829,9 +6829,9 @@
// newtitle - String with the new title
this.setDocumentTitle = function(newtitle) {
var childs = svgcontent.childNodes, doc_title = false, old_title = '';
-
+
var batchCmd = new BatchCommand("Change Image Title");
-
+
for (var i=0; i<childs.length; i++) {
if(childs[i].nodeName == 'title') {
doc_title = childs[i];
@@ -6842,8 +6842,8 @@
if(!doc_title) {
doc_title = svgdoc.createElementNS(svgns, "title");
svgcontent.insertBefore(doc_title, svgcontent.firstChild);
- }
-
+ }
+
if(newtitle.length) {
doc_title.textContent = newtitle;
} else {
@@ -6869,13 +6869,13 @@
// Function: setResolution
// Changes the document's dimensions to the given size
//
-// Parameters:
-// x - Number with the width of the new dimensions in user units.
+// Parameters:
+// x - Number with the width of the new dimensions in user units.
// Can also be the string "fit" to indicate "fit to content"
-// y - Number with the height of the new dimensions in user units.
+// y - Number with the height of the new dimensions in user units.
//
// Returns:
-// Boolean to indicate if resolution change was succesful.
+// Boolean to indicate if resolution change was succesful.
// It will fail on "fit to content" option with no content to fit to.
this.setResolution = function(x, y) {
var res = getResolution();
@@ -6885,7 +6885,7 @@
if(x == 'fit') {
// Get bounding box
var bbox = getStrokedBBox();
-
+
if(bbox) {
batchCmd = new BatchCommand("Fit Canvas to Content");
var visEls = getVisibleElements();
@@ -6895,11 +6895,11 @@
dx.push(bbox.x*-1);
dy.push(bbox.y*-1);
});
-
+
var cmd = canvas.moveSelectedElements(dx, dy, true);
batchCmd.addSubCommand(cmd);
clearSelection();
-
+
x = Math.round(bbox.width);
y = Math.round(bbox.height);
} else {
@@ -6913,17 +6913,17 @@
x = convertToNum('width', x);
y = convertToNum('height', y);
-
+
svgcontent.setAttribute('width', x);
svgcontent.setAttribute('height', y);
-
+
this.contentW = x;
this.contentH = y;
batchCmd.addSubCommand(new ChangeElementCommand(svgcontent, {"width":w, "height":h}));
svgcontent.setAttribute("viewBox", [0, 0, x/current_zoom, y/current_zoom].join(' '));
batchCmd.addSubCommand(new ChangeElementCommand(svgcontent, {"viewBox": ["0 0", w, h].join(' ')}));
-
+
addCommandToHistory(batchCmd);
background = document.getElementById("canvas_background");
if (background) {
@@ -6946,9 +6946,9 @@
// Function: setBBoxZoom
// Sets the zoom level on the canvas-side based on the given value
-//
+//
// Parameters:
-// val - Bounding box object to zoom to or string indicating zoom option
+// val - Bounding box object to zoom to or string indicating zoom option
// editor_w - Integer with the editor's workarea box's width
// editor_h - Integer with the editor's workarea box's height
this.setBBoxZoom = function(val, editor_w, editor_h) {
@@ -6957,12 +6957,12 @@
var calcZoom = function(bb) {
if(!bb) return false;
var w_zoom = Math.round((editor_w / bb.width)*100 * spacer)/100;
- var h_zoom = Math.round((editor_h / bb.height)*100 * spacer)/100;
+ var h_zoom = Math.round((editor_h / bb.height)*100 * spacer)/100;
var zoomlevel = Math.min(w_zoom,h_zoom);
canvas.setZoom(zoomlevel);
return {'zoom': zoomlevel, 'bbox': bb};
}
-
+
if(typeof val == 'object') {
bb = val;
if(bb.width == 0 || bb.height == 0) {
@@ -7025,7 +7025,7 @@
// Parameters:
// name - String with the new mode to change to
this.setMode = function(name) {
-
+
pathActions.clear();
textActions.clear();
$("#workarea").attr("class", name);
@@ -7043,7 +7043,7 @@
// Function: setColor
// Change the current stroke/fill color/gradient value
-//
+//
// Parameters:
// type - String indicating fill or stroke
// val - The value to set the stroke attribute to
@@ -7073,7 +7073,7 @@
if (!preventUndo) {
changeSelectedAttribute(type, val, elems);
call("changed", elems);
- } else
+ } else
changeSelectedAttributeNoUndo(type, val, elems);
}
}
@@ -7147,22 +7147,22 @@
if (grad.getAttribute('x1') != og.getAttribute('x1') ||
grad.getAttribute('y1') != og.getAttribute('y1') ||
grad.getAttribute('x2') != og.getAttribute('x2') ||
- grad.getAttribute('y2') != og.getAttribute('y2'))
+ grad.getAttribute('y2') != og.getAttribute('y2'))
{
continue;
}
} else {
var grad_attrs = $(grad).attr(rad_attrs);
var og_attrs = $(og).attr(rad_attrs);
-
+
var diff = false;
$.each(rad_attrs, function(i, attr) {
if(grad_attrs[attr] != og_attrs[attr]) diff = true;
});
-
+
if(diff) continue;
}
-
+
// else could be a duplicate, iterate through stops
var stops = grad.getElementsByTagNameNS(svgns, "stop");
var ostops = og.getElementsByTagNameNS(svgns, "stop");
@@ -7178,7 +7178,7 @@
if (stop.getAttribute('offset') != ostop.getAttribute('offset') ||
stop.getAttribute('stop-opacity') != ostop.getAttribute('stop-opacity') ||
- stop.getAttribute('stop-color') != ostop.getAttribute('stop-color'))
+ stop.getAttribute('stop-color') != ostop.getAttribute('stop-color'))
{
break;
}
@@ -7204,28 +7204,28 @@
var y1 = grad.getAttribute('y1') || 0;
var x2 = grad.getAttribute('x2') || 1;
var y2 = grad.getAttribute('y2') || 0;
-
+
// Convert to USOU points
x1 = (bb.width * x1) + bb.x;
y1 = (bb.height * y1) + bb.y;
x2 = (bb.width * x2) + bb.x;
y2 = (bb.height * y2) + bb.y;
-
+
// Transform those points
var pt1 = transformPoint(x1, y1, m);
var pt2 = transformPoint(x2, y2, m);
-
+
// Convert back to BB points
var g_coords = {};
-
+
g_coords.x1 = (pt1.x - bb.x) / bb.width;
g_coords.y1 = (pt1.y - bb.y) / bb.height;
g_coords.x2 = (pt2.x - bb.x) / bb.width;
g_coords.y2 = (pt2.y - bb.y) / bb.height;
-
+
var newgrad = grad.cloneNode(true);
$(newgrad).attr(g_coords);
-
+
newgrad.id = getNextId();
findDefs().appendChild(newgrad);
elem.setAttribute(type, 'url(#' + newgrad.id + ')');
@@ -7237,7 +7237,7 @@
// Function: setPaint
// Set a color/gradient to a fill/stroke
//
-// Parameters:
+// Parameters:
// type - String with "fill" or "stroke"
// paint - The jGraduate paint object to apply
this.setPaint = function(type, paint) {
@@ -7248,13 +7248,13 @@
cur_properties[type + '_paint'] = p;
switch ( p.type ) {
case "solidColor":
-
+
if (p.solidColor != "none" && p.solidColor != "#none") {
this.setColor(type, "#"+p.solidColor)
}
else {
this.setColor(type, "none");
- var selector = (type == "fill") ? "#fill_color rect" : "#stroke_color rect"
+ var selector = (type == "fill") ? "#fill_color rect" : "#stroke_color rect"
document.querySelector(selector).setAttribute('fill', 'none');
}
break;
@@ -7273,7 +7273,7 @@
// // make a copy
// var p = new $.jGraduate.Paint(p);
// this.setStrokeOpacity(p.alpha/100);
-//
+//
// // now set the current paint object
// cur_properties.stroke_paint = p;
// switch ( p.type ) {
@@ -7283,17 +7283,17 @@
// case "linearGradient"
// case "radialGradient"
// canvas.strokeGrad = p[p.type];
-// setGradient(type);
+// setGradient(type);
// default:
// // console.log("none!");
// }
// };
-//
+//
// this.setFillPaint = function(p, addGrad) {
// // make a copy
// var p = new $.jGraduate.Paint(p);
// this.setFillOpacity(p.alpha/100, true);
-//
+//
// // now set the current paint object
// cur_properties.fill_paint = p;
// if (p.type == "solidColor") {
@@ -7301,11 +7301,11 @@
// }
// else if(p.type == "linearGradient") {
// canvas.fillGrad = p.linearGradient;
-// if(addGrad) setGradient();
+// if(addGrad) setGradient();
// }
// else if(p.type == "radialGradient") {
// canvas.fillGrad = p.radialGradient;
-// if(addGrad) setGradient();
+// if(addGrad) setGradient();
// }
// else {
// // console.log("none!");
@@ -7330,7 +7330,7 @@
return;
}
cur_properties.stroke_width = val;
-
+
var elems = [];
var i = selectedElements.length;
while (i--) {
@@ -7338,10 +7338,10 @@
if (elem) {
if (elem.tagName == "g")
svgedit.utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);});
- else
+ else
elems.push(elem);
}
- }
+ }
if (elems.length > 0) {
changeSelectedAttribute("stroke-width", val, elems);
call("changed", selectedElements);
@@ -7363,10 +7363,10 @@
if (elem) {
if (elem.tagName == "g")
svgedit.utilities.walkTree(elem, function(e){if(e.nodeName!="g") elems.push(e);});
- else
+ else
elems.push(elem);
}
- }
+ }
if (elems.length > 0) {
changeSelectedAttribute(attr, val, elems);
call("changed", selectedElements);
@@ -7427,7 +7427,7 @@
this.getBlur = function(elem) {
var val = 0;
// var elem = selectedElements[0];
-
+
if(elem) {
var filter_url = elem.getAttribute('filter');
if(filter_url) {
@@ -7444,7 +7444,7 @@
var cur_command = null;
var filter = null;
var filterHidden = false;
-
+
// Function: setBlurNoUndo
// Sets the stdDeviation blur value on the selected element without being undoable
//
@@ -7473,12 +7473,12 @@
canvas.setBlurOffsets(filter, val);
}
}
-
+
function finishChange() {
var bCmd = canvas.undoMgr.finishUndoableChange();
cur_command.addSubCommand(bCmd);
addCommandToHistory(cur_command);
- cur_command = null;
+ cur_command = null;
filter = null;
}
@@ -7509,7 +7509,7 @@
}
}
- // Function: setBlur
+ // Function: setBlur
// Adds/updates the blur filter to the selected element
//
// Parameters:
@@ -7520,16 +7520,16 @@
finishChange();
return;
}
-
+
// Looks for associated blur, creates one if not found
var elem = selectedElements[0];
var elem_id = elem.id;
filter = getElem(elem_id + '_blur');
-
+
val -= 0;
-
+
var batchCmd = new BatchCommand();
-
+
// Blur found!
if(filter) {
if(val === 0) {
@@ -7543,33 +7543,33 @@
"stdDeviation": val
}
});
-
+
filter = addSvgElementFromJson({ "element": "filter",
"attr": {
"id": elem_id + '_blur'
}
});
-
+
filter.appendChild(newblur);
findDefs().appendChild(filter);
-
+
batchCmd.addSubCommand(new InsertElementCommand(filter));
}
var changes = {filter: elem.getAttribute('filter')};
-
+
if(val === 0) {
elem.removeAttribute("filter");
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes));
return;
} else {
changeSelectedAttribute("filter", 'url(#' + elem_id + '_blur)');
-
+
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes));
-
+
canvas.setBlurOffsets(filter, val);
}
-
+
cur_command = batchCmd;
canvas.undoMgr.beginUndoableChange("stdDeviation", [filter?filter.firstChild:null]);
if(complete) {
@@ -7710,18 +7710,18 @@
// Function: setImageURL
// Sets the new image URL for the selected image element. Updates its size if
// a new URL is given
-//
+//
// Parameters:
// val - String with the image URL/path
this.setImageURL = function(val) {
var elem = selectedElements[0];
if(!elem) return;
-
+
var attrs = $(elem).attr(['width', 'height']);
var setsize = (!attrs.width || !attrs.height);
var cur_href = getHref(elem);
-
+
// Do nothing if no URL change or size change
if(cur_href !== val) {
setsize = true;
@@ -7737,14 +7737,14 @@
if(setsize) {
$(new Image()).load(function() {
var changes = $(elem).attr(['width', 'height']);
-
+
$(elem).attr({
width: this.width,
height: this.height
});
-
+
selectorManager.requestSelector(elem).resize();
-
+
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes));
addCommandToHistory(batchCmd);
call("changed", [elem]);
@@ -7756,7 +7756,7 @@
// Function: setLinkURL
// Sets the new link URL for the selected anchor element.
-//
+//
// Parameters:
// val - String with the link URL/path
this.setLinkURL = function(val) {
@@ -7771,11 +7771,11 @@
return;
}
}
-
+
var cur_href = getHref(elem);
-
+
if(cur_href === val) return;
-
+
var batchCmd = new BatchCommand("Change Link URL");
setHref(elem, val);
@@ -7789,14 +7789,14 @@
// Function elementAreSame
// Checks if all the selected Elements are the same type
-//
+//
// Parameters:
// None
this.elementsAreSame = function(elements) {
if (!elements.length || elements[0] == null) return null
else {
- var isSameElement = function(el) {
+ var isSameElement = function(el) {
if (el && selectedElements[0])
return (el.nodeName == selectedElements[0].nodeName);
else return null;
@@ -7808,7 +7808,7 @@
// Function: setRectRadius
// Sets the rx & ry values to the selected rect element to change its corner radius
-//
+//
// Parameters:
// val - The new radius
this.setRectRadius = function(val) {
@@ -7830,7 +7830,7 @@
// Wraps the selected element(s) in an anchor element or converts group to one
this.makeHyperlink = function(url) {
canvas.groupSelectedElements('a', url);
-
+
// TODO: If element is a single "g", convert to "a"
// if(selectedElements.length > 1 && selectedElements[1]) {
@@ -7844,7 +7844,7 @@
// Group: Element manipulation
// Function: setSegType
-// Sets the new segment type to the selected segment(s).
+// Sets the new segment type to the selected segment(s).
//
// Parameters:
// new_type - Integer with the new segment type
@@ -7857,7 +7857,7 @@
// Function: convertToPath
// Convert selected element to a path, or get the BBox of an element-as-path
//
-// Parameters:
+// Parameters:
// elem - The DOM element to be converted
// getBBox - Boolean on whether or not to only return the path's BBox
//
@@ -7872,11 +7872,11 @@
});
return;
}
-
+
if(!getBBox) {
var batchCmd = new BatchCommand("Convert element to Path");
}
-
+
var attrs = getBBox?{}:{
"fill": cur_shape.fill,
"fill-opacity": cur_shape.fill_opacity,
@@ -7889,7 +7889,7 @@
"opacity": cur_shape.opacity,
"visibility":"hidden"
};
-
+
// any attribute on the element not covered by the above
// TODO: make this list global so that we can properly maintain it
// TODO: what about @transform, @clip-rule, @fill-rule, etc?
@@ -7898,17 +7898,17 @@
attrs[this] = elem.getAttribute(this);
}
});
-
+
var path = addSvgElementFromJson({
"element": "path",
"attr": attrs
});
-
+
var eltrans = elem.getAttribute("transform");
if(eltrans) {
path.setAttribute("transform",eltrans);
}
-
+
var id = elem.id;
var parent = elem.parentNode;
if(elem.nextSibling) {
@@ -7916,9 +7916,9 @@
} else {
parent.appendChild(path);
}
-
+
var d = '';
-
+
var joinSegs = function(segs) {
$.each(segs, function(j, seg) {
var l = seg[0], pts = seg[1];
@@ -7940,7 +7940,7 @@
if(elem.tagName == 'circle') {
rx = ry = $(elem).attr('r');
}
-
+
joinSegs([
['M',[(cx-rx),(cy)]],
['C',[(cx-rx),(cy-ry/num), (cx-rx/num),(cy-ry), (cx),(cy-ry)]],
@@ -7997,14 +7997,14 @@
path.parentNode.removeChild(path);
break;
}
-
+
if(d) {
path.setAttribute('d',d);
}
-
+
if(!getBBox) {
// Replace the current element with the converted one
-
+
// Reorient if it has a matrix
if(eltrans) {
var tlist = getTransformList(path);
@@ -8012,7 +8012,7 @@
pathActions.resetOrientation(path);
}
}
-
+
var nextSibling = elem.nextSibling;
batchCmd.addSubCommand(new RemoveElementCommand(elem, nextSibling, parent));
batchCmd.addSubCommand(new InsertElementCommand(path));
@@ -8022,9 +8022,9 @@
path.setAttribute('id', id);
path.removeAttribute("visibility");
addToSelection([path], true);
-
+
addCommandToHistory(batchCmd);
-
+
} else {
// Get the correct BBox of the new path, then discard it
pathActions.resetOrientation(path);
@@ -8042,8 +8042,8 @@
// Function: changeSelectedAttributeNoUndo
// This function makes the changes to the elements. It does not add the change
-// to the history stack.
-//
+// to the history stack.
+//
// Parameters:
// attr - String with the attribute name
// newValue - String or number with the new attribute value
@@ -8099,7 +8099,7 @@
},0);
}
// if this element was rotated, and we changed the position of this element
- // we need to update the rotational transform attribute
+ // we need to update the rotational transform attribute
var angle = getRotationAngle(elem);
if (angle != 0 && attr != "transform") {
var tlist = getTransformList(elem);
@@ -8130,7 +8130,7 @@
// If you want to change all selectedElements, ignore the elems argument.
// If you want to change only a subset of selectedElements, then send the
// subset to this function in the elems argument.
-//
+//
// Parameters:
// attr - String with the attribute name
// newValue - String or number with the new attribute value
@@ -8143,13 +8143,13 @@
changeSelectedAttributeNoUndo(attr, val, elems);
var batchCmd = canvas.undoMgr.finishUndoableChange();
- if (!batchCmd.isEmpty()) {
+ if (!batchCmd.isEmpty()) {
addCommandToHistory(batchCmd);
}
};
// Function: deleteSelectedElements
-// Removes all selected elements from the DOM and adds the change to the
+// Removes all selected elements from the DOM and adds the change to the
// history stack
this.deleteSelectedElements = function() {
var batchCmd = new BatchCommand("Delete Elements");
@@ -8161,19 +8161,19 @@
var parent = selected.parentNode;
var t = selected;
-
+
// this will unselect the element and remove the selectedOutline
selectorManager.releaseSelector(t);
-
+
// Remove the path if present.
svgedit.path.removePath_(t.id);
-
+
// Get the parent if it's a single-child anchor
if(parent.tagName === 'a' && parent.childNodes.length === 1) {
t = parent;
parent = parent.parentNode;
}
-
+
var nextSibling = t.nextSibling;
var elem = parent.removeChild(t);
selectedCopy.push(selected); //for the copy
@@ -8186,7 +8186,7 @@
};
// Function: cutSelectedElements
-// Removes all selected elements from the DOM and adds the change to the
+// Removes all selected elements from the DOM and adds the change to the
// history stack. Remembers removed elements on the clipboard
// TODO: Combine similar code with deleteSelectedElements
@@ -8216,7 +8216,7 @@
if (!batchCmd.isEmpty()) addCommandToHistory(batchCmd);
call("changed", selectedCopy);
clearSelection();
-
+
canvas.clipBoard = selectedCopy;
};
@@ -8230,10 +8230,10 @@
var cb = canvas.clipBoard;
var len = cb.length;
if(!len) return;
-
+
var pasted = [];
var batchCmd = new BatchCommand('Paste elements');
-
+
// Move elements to lastClickPoint
while (len--) {
@@ -8249,9 +8249,9 @@
}
svgCanvas.clearSelection();
setTimeout(function(){selectOnly(pasted)},100);
-
-
+
+
addCommandToHistory(batchCmd);
call("changed", pasted);
}
@@ -8259,12 +8259,12 @@
// Function: groupSelectedElements
// Wraps all the selected elements in a group (g) element
-// Parameters:
+// Parameters:
// type - type of element to group into, defaults to <g>
this.groupSelectedElements = function(type) {
if(!type) type = 'g';
var cmd_str = '';
-
+
switch ( type ) {
case "a":
cmd_str = "Make hyperlink";
@@ -8278,9 +8278,9 @@
cmd_str = "Group Elements";
break;
}
-
+
var batchCmd = new BatchCommand(cmd_str);
-
+
// create and insert the group element
var g = addSvgElementFromJson({
"element": type,
@@ -8292,24 +8292,24 @@
setHref(g, url);
}
batchCmd.addSubCommand(new InsertElementCommand(g));
-
+
// now move all children into the group
var i = selectedElements.length;
while (i--) {
var elem = selectedElements[i];
if (elem == null) continue;
-
+
if (elem.parentNode.tagName === 'a' && elem.parentNode.childNodes.length === 1) {
elem = elem.parentNode;
}
-
+
var oldNextSibling = elem.nextSibling;
var oldParent = elem.parentNode;
g.appendChild(elem);
- batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldParent));
+ batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldParent));
}
if (!batchCmd.isEmpty()) addCommandToHistory(batchCmd);
-
+
// update selection
selectOnly([g], true);
};
@@ -8326,27 +8326,27 @@
var glist = getTransformList(g);
var m = transformListToTransform(glist).matrix;
-
+
var batchCmd = new BatchCommand("Push group properties");
// TODO: get all fill/stroke properties from the group that we are about to destroy
- // "fill", "fill-opacity", "fill-rule", "stroke", "stroke-dasharray", "stroke-dashoffset",
- // "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity",
+ // "fill", "fill-opacity", "fill-rule", "stroke", "stroke-dasharray", "stroke-dashoffset",
+ // "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity",
// "stroke-width"
// and then for each child, if they do not have the attribute (or the value is 'inherit')
// then set the child's attribute
-
+
var i = 0;
var gangle = getRotationAngle(g);
-
+
var gattrs = $(g).attr(['filter', 'opacity']);
var gfilter, gblur;
-
+
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;
@@ -8363,7 +8363,7 @@
} else if(cblur === 0) {
cblur = gblur;
}
-
+
// If child has no current filter, get group's filter or clone it.
if(!orig_cblur) {
// Set group's filter to use first child's ID
@@ -8379,28 +8379,28 @@
}
// Change this in future for different filters
- var suffix = (gfilter.firstChild.tagName === 'feGaussianBlur')?'blur':'filter';
+ var suffix = (gfilter.firstChild.tagName === 'feGaussianBlur')?'blur':'filter';
gfilter.id = elem.id + '_' + suffix;
changeSelectedAttribute('filter', 'url(#' + gfilter.id + ')', [elem]);
-
- // Update blur value
+
+ // Update blur value
if(cblur) {
changeSelectedAttribute('stdDeviation', cblur, [gfilter.firstChild]);
canvas.setBlurOffsets(gfilter, cblur);
}
}
-
+
var chtlist = getTransformList(elem);
// Don't process gradient transforms
if(~elem.tagName.indexOf('Gradient')) chtlist = null;
-
+
// Hopefully not a problem to add this. Necessary for elements like <desc/>
if(!chtlist) continue;
-
+
// Apparently <defs> can get get a transformlist, but we don't want it to have one!
if(elem.tagName === 'defs') 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
@@ -8408,43 +8408,43 @@
if (gangle && glist.numberOfItems == 1) {
// [Rg] [Rc] [Mc]
// we want [Tr] [Rc2] [Mc] where:
- // - [Rc2] is at the child's current center but has the
+ // - [Rc2] is at the child's current center but has the
// sum of the group and child's rotation angles
- // - [Tr] is the equivalent translation that this child
+ // - [Tr] is the equivalent translation that this child
// undergoes if the group wasn't there
-
+
// [Tr] = [Rg] [Rc] [Rc2_inv]
-
+
// get group's rotation matrix (Rg)
var rgm = glist.getItem(0).matrix;
-
+
// get child's rotation matrix (Rc)
var rcm = svgroot.createSVGMatrix();
var cangle = getRotationAngle(elem);
if (cangle) {
rcm = chtlist.getItem(0).matrix;
}
-
+
// get child's old center of rotation
var cbox = svgedit.utilities.getBBox(elem);
var ceqm = transformListToTransform(chtlist).matrix;
var coldc = transformPoint(cbox.x+cbox.width/2, cbox.y+cbox.height/2,ceqm);
-
+
// sum group and child's angles
var sangle = gangle + cangle;
-
+
// get child's rotation at the old center (Rc2_inv)
var r2 = svgroot.createSVGTransform();
r2.setRotate(sangle, coldc.x, coldc.y);
-
+
// calculate equivalent translate
var trm = matrixMultiply(rgm, rcm, r2.matrix.inverse());
-
+
// set up tlist
if (cangle) {
chtlist.removeItem(0);
}
-
+
if (sangle) {
if(chtlist.numberOfItems) {
chtlist.insertItemBefore(r2, 0);
@@ -8464,9 +8464,9 @@
}
}
else { // more complicated than just a rotate
-
+
// transfer the group's transform down to each child and then
- // call recalculateDimensions()
+ // call recalculateDimensions()
var oldxform = elem.getAttribute("transform");
var changes = {};
changes["transform"] = oldxform ? oldxform : "";
@@ -8486,16 +8486,16 @@
}
}
-
+
// remove transform and make it undo-able
if (xform) {
var changes = {};
changes["transform"] = xform;
g.setAttribute("transform", "");
- g.removeAttribute("transform");
+ g.removeAttribute("transform");
batchCmd.addSubCommand(new ChangeElementCommand(g, changes));
}
-
+
if (undoable && !batchCmd.isEmpty()) {
return batchCmd;
}
@@ -8523,25 +8523,25 @@
if(parents_a.length) {
g = parents_a[0];
}
-
+
// Look for parent "a"
if (g.tagName === "g" || g.tagName === "a") {
-
+
var batchCmd = new BatchCommand("Ungroup Elements");
var cmd = pushGroupProperties(g, true);
if(cmd) batchCmd.addSubCommand(cmd);
-
+
var parent = g.parentNode;
var anchor = g.nextSibling;
var children = new Array(g.childNodes.length);
-
+
var i = 0;
-
+
while (g.firstChild) {
var elem = g.firstChild;
var oldNextSibling = elem.nextSibling;
var oldParent = elem.parentNode;
-
+
// Remove child title elements
if(elem.tagName === 'title') {
var nextSibling = elem.nextSibling;
@@ -8549,21 +8549,21 @@
oldParent.removeChild(elem);
continue;
}
-
+
children[i++] = elem = parent.insertBefore(elem, anchor);
batchCmd.addSubCommand(new MoveElementCommand(elem, oldNextSibling, oldParent));
}
- // remove the group from the selection
+ // remove the group from the selection
clearSelection();
-
+
// delete the group element (but make undo-able)
var gNextSibling = g.nextSibling;
g = parent.removeChild(g);
batchCmd.addSubCommand(new RemoveElementCommand(g, gNextSibling, parent));
if (!batchCmd.isEmpty()) addCommandToHistory(batchCmd);
-
+
// update selection
addToSelection(children);
}
@@ -8591,7 +8591,7 @@
};
// Function: moveToBottomSelectedElement
-// Repositions the selected element to the top in the DOM to appear under
+// Repositions the selected element to the top in the DOM to appear under
// other elements
this.moveToBottomSelectedElement = function() {
var selected = selectedElements.filter(Boolean).reverse();
@@ -8624,7 +8624,7 @@
// Moves the select element up or down the stack, based on the visibly
// intersecting elements
//
-// Parameters:
+// Parameters:
// dir - String that's either 'Up' or 'Down'
this.moveUpDownSelected = function(dir) {
var selected = selectedElements.filter(Boolean);
@@ -8648,7 +8648,7 @@
return false;
});
if(!closest) return;
-
+
var t = selected;
var oldParent = t.parentNode;
var oldNextSibling = t.nextSibling;
@@ -8664,7 +8664,7 @@
};
// Function: moveSelectedElements
-// Moves selected elements on the X/Y axis
+// Moves selected elements on the X/Y axis
//
// Parameters:
// dx - Float with the distance to move on the x-axis
@@ -8688,14 +8688,14 @@
if (selected != null) {
// if (i==0)
// selectedBBoxes[0] = svgedit.utilities.getBBox(selected);
-
+
// var b = {};
// for(var j in selectedBBoxes[i]) b[j] = selectedBBoxes[i][j];
// selectedBBoxes[i] = b;
-
+
var xform = svgroot.createSVGTransform();
var tlist = getTransformList(selected);
-
+
// dx and dy could be arrays
if (dx.constructor == Array) {
// if (i==0) {
@@ -8716,12 +8716,12 @@
} else {
tlist.appendItem(xform);
}
-
+
var cmd = recalculateDimensions(selected);
if (cmd) {
batchCmd.addSubCommand(cmd);
}
-
+
selectorManager.requestSelector(selected).resize();
}
}
@@ -8734,7 +8734,7 @@
};
// Function: cloneSelectedElements
-// Create deep DOM copies (clones) of all selected elements and move them slightly
+// Create deep DOM copies (clones) of all selected elements and move them slightly
// from their originals
this.cloneSelectedElements = function(x,y, drag) {
var batchCmd = new BatchCommand("Clone Elements");
@@ -8753,7 +8753,7 @@
clones = []
while (i--) {
// clone each element and replace it within copiedElements
- var elem = copiedElements[i]
+ var elem = copiedElements[i]
var clone = copyElem(copiedElements[i]);
var parent = (current_group || getCurrentDrawing().getCurrentLayer())
if (drag) {
@@ -8769,7 +8769,7 @@
clones.push(clone)
batchCmd.addSubCommand(new InsertElementCommand(clone));
}
-
+
if (!batchCmd.isEmpty()) {
addToSelection(copiedElements.reverse()); // Need to reverse for correct selection-adding
if (!drag) this.moveSelectedElements(x,y,false);
@@ -8783,7 +8783,7 @@
//
// Parameters:
// type - String with single character indicating the alignment type
-// relative_to - String that must be one of the following:
+// relative_to - String that must be one of the following:
// "selected", "largest", "smallest", "page"
this.alignSelectedElements = function(type, relative_to) {
var bboxes = [], angles = [];
@@ -8795,7 +8795,7 @@
if (selectedElements[i] == null) break;
var elem = selectedElements[i];
bboxes[i] = getStrokedBBox([elem]);
-
+
// now bbox is axis-aligned and handles rotation
switch (relative_to) {
case 'smallest':
@@ -8874,13 +8874,13 @@
this.contentH = getResolution().h;
// Function: updateCanvas
-// Updates the editor canvas width/height/position after a zoom has occurred
+// Updates the editor canvas width/height/position after a zoom has occurred
//
// Parameters:
// w - Float with the new width
// h - Float with the new height
//
-// Returns:
+// Returns:
// Object with the following values:
// * x - The canvas' new x coordinate
// * y - The canvas' new y coordinate
@@ -8904,7 +8904,7 @@
'y': y,
"viewBox" : "0 0 " + this.contentW + " " + this.contentH
});
-
+
assignAttributes(bg, {
width: svgcontent.getAttribute('width'),
height: svgcontent.getAttribute('height'),
@@ -8919,9 +8919,9 @@
'height': '100%'
});
}
-
+
selectorManager.selectorParentGroup.setAttribute("transform","translate(" + x + "," + y + ")");
-
+
return {x:x, y:y, old_x:old_x, old_y:old_y, d_x:x - old_x, d_y:y - old_y};
}
@@ -8976,12 +8976,12 @@
num = 0;
} else if(num < 0) {
num = all_elems.length-1;
- }
+ }
elem = all_elems[num];
break;
- }
+ }
}
- }
+ }
selectOnly([elem], true);
call("selected", selectedElements);
}
@@ -8989,7 +8989,7 @@
this.clear();
-// DEPRECATED: getPrivateMethods
+// DEPRECATED: getPrivateMethods
// Since all methods are/should be public somehow, this function should be removed
// Being able to access private methods publicly seems wrong somehow,
--
Gitblit v1.9.1