Merge branch 'bzr/golem' of /Users/distler/Sites/code/instiki
This commit is contained in:
commit
1654316557
|
@ -74,70 +74,44 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function findConnectors() {
|
function findConnectors() {
|
||||||
// Check if selected elements have connections
|
|
||||||
var elems = selElems;
|
var elems = selElems;
|
||||||
var i = elems.length;
|
|
||||||
var connectors = $(svgcontent).find(conn_sel);
|
var connectors = $(svgcontent).find(conn_sel);
|
||||||
if(!connectors.length) return;
|
|
||||||
connections = [];
|
connections = [];
|
||||||
|
|
||||||
var sel = ':not(a,g,svg,'+conn_sel+')';
|
|
||||||
var all_els = [];
|
|
||||||
// Get children from groups
|
|
||||||
|
|
||||||
while(i--) {
|
|
||||||
var elem = elems[i];
|
|
||||||
if(!elem) continue;
|
|
||||||
// Get all children that cannot contain children
|
|
||||||
var solid_elems = $(elem).find(sel);
|
|
||||||
// Include self if okay
|
|
||||||
if($(elem).filter(sel).length) {
|
|
||||||
solid_elems.push(elem);
|
|
||||||
}
|
|
||||||
$.merge(all_els, solid_elems);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = all_els.length;
|
|
||||||
|
|
||||||
if(i > 1) {
|
|
||||||
// Multiselected, so unselect connector
|
|
||||||
svgCanvas.removeFromSelection($(conn_sel).toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through selected elements
|
|
||||||
while(i--) {
|
|
||||||
var elem = all_els[i];
|
|
||||||
if(!elem) continue;
|
|
||||||
|
|
||||||
// Element was deleted, so delete connector
|
|
||||||
var was_deleted = !elem.parentNode;
|
|
||||||
|
|
||||||
// Skip connector
|
|
||||||
if($(elem).data('c_start')) continue;
|
|
||||||
|
|
||||||
// Loop through connectors to see if one is connected to the element
|
// Loop through connectors to see if one is connected to the element
|
||||||
connectors.each(function() {
|
connectors.each(function() {
|
||||||
var start = $(this).data("c_start");
|
var start = $(this).data("c_start");
|
||||||
var end = $(this).data("c_end");
|
var end = $(this).data("c_end");
|
||||||
|
|
||||||
// Connector found for this element
|
var parts = [getElem(start), getElem(end)];
|
||||||
if(start == elem.id || end == elem.id) {
|
for(var i=0; i<2; i++) {
|
||||||
|
var c_elem = parts[i];
|
||||||
if(was_deleted) {
|
var add_this = false;
|
||||||
$(this).remove();
|
// The connected element might be part of a selected group
|
||||||
return;
|
$(c_elem).parents().each(function() {
|
||||||
|
if($.inArray(this, elems) !== -1) {
|
||||||
|
// Pretend this element is selected
|
||||||
|
add_this = true;
|
||||||
}
|
}
|
||||||
var bb = svgCanvas.getStrokedBBox([elem]);
|
});
|
||||||
|
|
||||||
|
if(!c_elem || !c_elem.parentNode) {
|
||||||
|
$(this).remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($.inArray(c_elem, elems) !== -1 || add_this) {
|
||||||
|
var bb = svgCanvas.getStrokedBBox([c_elem]);
|
||||||
connections.push({
|
connections.push({
|
||||||
elem: elem,
|
elem: c_elem,
|
||||||
connector: this,
|
connector: this,
|
||||||
is_start: start == elem.id,
|
is_start: (i === 0),
|
||||||
start_x: bb.x,
|
start_x: bb.x,
|
||||||
start_y: bb.y
|
start_y: bb.y
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateConnectors() {
|
function updateConnectors() {
|
||||||
|
@ -300,7 +274,6 @@ $(function() {
|
||||||
},
|
},
|
||||||
mouseDown: function(opts) {
|
mouseDown: function(opts) {
|
||||||
var e = opts.event;
|
var e = opts.event;
|
||||||
|
|
||||||
start_x = opts.start_x,
|
start_x = opts.start_x,
|
||||||
start_y = opts.start_y;
|
start_y = opts.start_y;
|
||||||
var mode = svgCanvas.getMode();
|
var mode = svgCanvas.getMode();
|
||||||
|
@ -316,7 +289,9 @@ $(function() {
|
||||||
if($.inArray(svgcontent, parents) != -1) {
|
if($.inArray(svgcontent, parents) != -1) {
|
||||||
// Connectable element
|
// Connectable element
|
||||||
|
|
||||||
start_elem = mouse_target;
|
// If child of foreignObject, use parent
|
||||||
|
var fo = $(mouse_target).closest("foreignObject");
|
||||||
|
start_elem = fo.length ? fo[0] : mouse_target;
|
||||||
|
|
||||||
// Get center of source element
|
// Get center of source element
|
||||||
var bb = svgCanvas.getStrokedBBox([start_elem]);
|
var bb = svgCanvas.getStrokedBBox([start_elem]);
|
||||||
|
@ -422,10 +397,13 @@ $(function() {
|
||||||
var zoom = svgCanvas.getZoom();
|
var zoom = svgCanvas.getZoom();
|
||||||
var e = opts.event,
|
var e = opts.event,
|
||||||
x = opts.mouse_x/zoom,
|
x = opts.mouse_x/zoom,
|
||||||
y = opts.mouse_y/zoom;
|
y = opts.mouse_y/zoom,
|
||||||
|
mouse_target = e.target;
|
||||||
|
|
||||||
if(svgCanvas.getMode() == "connector") {
|
if(svgCanvas.getMode() == "connector") {
|
||||||
if(e.target.parentNode.parentNode != svgcontent) {
|
var fo = $(mouse_target).closest("foreignObject");
|
||||||
|
if(fo.length) mouse_target = fo[0];
|
||||||
|
if(mouse_target.parentNode.parentNode != svgcontent) {
|
||||||
// Not a valid target element, so remove line
|
// Not a valid target element, so remove line
|
||||||
$(cur_line).remove();
|
$(cur_line).remove();
|
||||||
started = false;
|
started = false;
|
||||||
|
@ -434,7 +412,7 @@ $(function() {
|
||||||
element: null,
|
element: null,
|
||||||
started: started
|
started: started
|
||||||
}
|
}
|
||||||
} else if(e.target == start_elem) {
|
} else if(mouse_target == start_elem) {
|
||||||
// Start line through click
|
// Start line through click
|
||||||
started = true;
|
started = true;
|
||||||
return {
|
return {
|
||||||
|
@ -444,7 +422,8 @@ $(function() {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Valid end element
|
// Valid end element
|
||||||
end_elem = e.target;
|
end_elem = mouse_target;
|
||||||
|
|
||||||
var start_id = start_elem.id, end_id = end_elem.id;
|
var start_id = start_elem.id, end_id = end_elem.id;
|
||||||
var conn_str = start_id + " " + end_id;
|
var conn_str = start_id + " " + end_id;
|
||||||
var alt_str = end_id + " " + start_id;
|
var alt_str = end_id + " " + start_id;
|
||||||
|
|
|
@ -63,7 +63,6 @@ $(function() {
|
||||||
var newDoc = Utils.text2xml('<svg xmlns="'+svgns+'" xmlns:xlink="'+xlinkns+'">'+xmlString+'</svg>');
|
var newDoc = Utils.text2xml('<svg xmlns="'+svgns+'" xmlns:xlink="'+xlinkns+'">'+xmlString+'</svg>');
|
||||||
// run it through our sanitizer to remove anything we do not support
|
// run it through our sanitizer to remove anything we do not support
|
||||||
S.sanitizeSvg(newDoc.documentElement);
|
S.sanitizeSvg(newDoc.documentElement);
|
||||||
|
|
||||||
elt.parentNode.replaceChild(svgdoc.importNode(newDoc.documentElement.firstChild, true), elt);
|
elt.parentNode.replaceChild(svgdoc.importNode(newDoc.documentElement.firstChild, true), elt);
|
||||||
S.call("changed", [elt]);
|
S.call("changed", [elt]);
|
||||||
svgCanvas.clearSelection();
|
svgCanvas.clearSelection();
|
||||||
|
|
|
@ -45,7 +45,6 @@ script type="text/javascript" src="locale/locale.min.js"></script-->
|
||||||
<title>SVG-edit</title>
|
<title>SVG-edit</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="svg_editor">
|
<div id="svg_editor">
|
||||||
|
|
||||||
<div id="workarea">
|
<div id="workarea">
|
||||||
|
|
|
@ -1385,6 +1385,11 @@ function BatchCommand(text) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Safari crashes on a <use> without a xlink:href, so we just remove the node here
|
||||||
|
if (node.nodeName == "use" && !node.getAttributeNS(xlinkns,"href")) {
|
||||||
|
parent.removeChild(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// if the element has attributes pointing to a non-local reference,
|
// if the element has attributes pointing to a non-local reference,
|
||||||
// need to remove the attribute
|
// need to remove the attribute
|
||||||
$.each(["clip-path", "fill", "marker-end", "marker-mid", "marker-start", "mask", "stroke"],function(i,attr) {
|
$.each(["clip-path", "fill", "marker-end", "marker-mid", "marker-start", "mask", "stroke"],function(i,attr) {
|
||||||
|
@ -2647,6 +2652,7 @@ function BatchCommand(text) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var hasMatrixTransform = function(tlist) {
|
var hasMatrixTransform = function(tlist) {
|
||||||
|
if(!tlist) return false;
|
||||||
var num = tlist.numberOfItems;
|
var num = tlist.numberOfItems;
|
||||||
while (num--) {
|
while (num--) {
|
||||||
var xform = tlist.getItem(num);
|
var xform = tlist.getItem(num);
|
||||||
|
@ -3083,11 +3089,13 @@ function BatchCommand(text) {
|
||||||
start_x: start_x,
|
start_x: start_x,
|
||||||
start_y: start_y,
|
start_y: start_y,
|
||||||
selectedElements: selectedElements
|
selectedElements: selectedElements
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
if(ext_result) {
|
$.each(ext_result, function(i, r) {
|
||||||
started = ext_result.started;
|
if(r && r.started) {
|
||||||
|
started = true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// in this function we do not record any state changes yet (but we do update
|
// in this function we do not record any state changes yet (but we do update
|
||||||
|
@ -3604,13 +3612,15 @@ function BatchCommand(text) {
|
||||||
event: evt,
|
event: evt,
|
||||||
mouse_x: mouse_x,
|
mouse_x: mouse_x,
|
||||||
mouse_y: mouse_y
|
mouse_y: mouse_y
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
if(ext_result) {
|
$.each(ext_result, function(i, r) {
|
||||||
keep = ext_result.keep;
|
if(r) {
|
||||||
element = ext_result.element;
|
keep = r.keep || keep;
|
||||||
started = ext_result.started;
|
element = r.element;
|
||||||
|
started = r.started || started;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!keep && element != null) {
|
if (!keep && element != null) {
|
||||||
element.parentNode.removeChild(element);
|
element.parentNode.removeChild(element);
|
||||||
|
@ -5618,28 +5628,33 @@ function BatchCommand(text) {
|
||||||
|
|
||||||
var content = $(svgcontent);
|
var content = $(svgcontent);
|
||||||
|
|
||||||
|
var attrs = {
|
||||||
|
id: 'svgcontent',
|
||||||
|
overflow: 'visible'
|
||||||
|
};
|
||||||
|
|
||||||
// determine proper size
|
// determine proper size
|
||||||
var w, h;
|
|
||||||
if (content.attr("viewBox")) {
|
if (content.attr("viewBox")) {
|
||||||
var vb = content.attr("viewBox").split(' ');
|
var vb = content.attr("viewBox").split(' ');
|
||||||
w = vb[2];
|
attrs.width = vb[2];
|
||||||
h = vb[3];
|
attrs.height = vb[3];
|
||||||
}
|
}
|
||||||
// handle content that doesn't have a viewBox
|
// handle content that doesn't have a viewBox
|
||||||
else {
|
else {
|
||||||
var dims = content.attr(["width", "height"]);
|
$.each(['width', 'height'], function(i, dim) {
|
||||||
w = convertToNum('width', dims.width);
|
// Set to 100 if not given
|
||||||
h = convertToNum('height', dims.height);
|
var val = content.attr(dim) || 100;
|
||||||
// svgcontent.setAttribute("viewBox", ["0", "0", w, h].join(" "));
|
|
||||||
|
if((val+'').substr(-1) === "%") {
|
||||||
|
// Use user units if percentage given
|
||||||
|
attrs[dim] = parseInt(val);
|
||||||
|
} else {
|
||||||
|
attrs[dim] = convertToNum(dim, val);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
content.attr({
|
content.attr(attrs);
|
||||||
id: 'svgcontent',
|
|
||||||
width: w,
|
|
||||||
height: h,
|
|
||||||
overflow: 'visible'
|
|
||||||
});
|
|
||||||
|
|
||||||
batchCmd.addSubCommand(new InsertElementCommand(svgcontent));
|
batchCmd.addSubCommand(new InsertElementCommand(svgcontent));
|
||||||
// update root to the correct size
|
// update root to the correct size
|
||||||
var changes = content.attr(["width", "height"]);
|
var changes = content.attr(["width", "height"]);
|
||||||
|
@ -6602,7 +6617,19 @@ function BatchCommand(text) {
|
||||||
ret.y += parseFloat(selected.getAttribute('y'));
|
ret.y += parseFloat(selected.getAttribute('y'));
|
||||||
} else {
|
} else {
|
||||||
try { ret = selected.getBBox(); }
|
try { ret = selected.getBBox(); }
|
||||||
catch(e) { ret = null; }
|
catch(e) {
|
||||||
|
// Check if element is child of a foreignObject
|
||||||
|
var fo = $(selected).closest("foreignObject");
|
||||||
|
if(fo.length) {
|
||||||
|
try {
|
||||||
|
ret = fo[0].getBBox();
|
||||||
|
} catch(e) {
|
||||||
|
ret = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the bounding box from the DOM (which is in that element's coordinate system)
|
// get the bounding box from the DOM (which is in that element's coordinate system)
|
||||||
|
@ -7326,6 +7353,7 @@ function BatchCommand(text) {
|
||||||
// re-creating the getCheckedBBox() function? shouldn't we make this a function
|
// re-creating the getCheckedBBox() function? shouldn't we make this a function
|
||||||
// at the 'canvas' level
|
// at the 'canvas' level
|
||||||
var getCheckedBBox = function(elem) {
|
var getCheckedBBox = function(elem) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// TODO: Fix issue with rotated groups. Currently they work
|
// TODO: Fix issue with rotated groups. Currently they work
|
||||||
// fine in FF, but not in other browsers (same problem mentioned
|
// fine in FF, but not in other browsers (same problem mentioned
|
||||||
|
@ -7399,7 +7427,10 @@ function BatchCommand(text) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return bb;
|
return bb;
|
||||||
} catch(e) { return null; }
|
} catch(e) {
|
||||||
|
console.log(elem, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
var full_bb;
|
var full_bb;
|
||||||
|
@ -7565,7 +7596,7 @@ function BatchCommand(text) {
|
||||||
new_el.appendChild(copyElem(child));
|
new_el.appendChild(copyElem(child));
|
||||||
break;
|
break;
|
||||||
case 3: // text node
|
case 3: // text node
|
||||||
new_el.appendChild(child.cloneNode(false));
|
new_el.textContent = child.nodeValue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -7723,7 +7754,7 @@ function BatchCommand(text) {
|
||||||
// Function: getVersion
|
// Function: getVersion
|
||||||
// Returns a string which describes the revision number of SvgCanvas.
|
// Returns a string which describes the revision number of SvgCanvas.
|
||||||
this.getVersion = function() {
|
this.getVersion = function() {
|
||||||
return "svgcanvas.js ($Rev: 1404 $)";
|
return "svgcanvas.js ($Rev: 1409 $)";
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setUiStrings = function(strs) {
|
this.setUiStrings = function(strs) {
|
||||||
|
|
|
@ -124,19 +124,22 @@
|
||||||
module("Import Module");
|
module("Import Module");
|
||||||
|
|
||||||
test("Test import use", function() {
|
test("Test import use", function() {
|
||||||
expect(2);
|
expect(3);
|
||||||
|
|
||||||
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='400' x='300'>" +
|
svgCanvas.setSvgString("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='400' x='300'>" +
|
||||||
"<rect id='the-rect' width='200' height='200'/>" +
|
"<rect id='the-rect' width='200' height='200'/>" +
|
||||||
"<use id='the-use' xlink:href='#the-rect'/>" +
|
"<use id='the-use' xlink:href='#the-rect'/>" +
|
||||||
"<use id='foreign-use' xlink:href='somefile.svg#the-rect'/>" +
|
"<use id='foreign-use' xlink:href='somefile.svg#the-rect'/>" +
|
||||||
|
"<use id='no-use'/>" +
|
||||||
"</svg>");
|
"</svg>");
|
||||||
|
|
||||||
var u = document.getElementById("the-use"),
|
var u = document.getElementById("the-use"),
|
||||||
fu = document.getElementById("foreign-use");
|
fu = document.getElementById("foreign-use"),
|
||||||
|
nfu = document.getElementById("no-use");
|
||||||
|
|
||||||
equals((u && u.nodeName == "use"), true, "Did not import <use> element");
|
equals((u && u.nodeName == "use"), true, "Did not import <use> element");
|
||||||
equals((fu && !fu.getAttributeNS(xlinkns,"href")), true, "Did not remove reference to foreign element in <use>");
|
equals(fu, null, "Removed <use> element that had a foreign href");
|
||||||
|
equals(nfu, null, "Removed <use> element that had no href");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Test getUrlFromAttr", function() {
|
test("Test getUrlFromAttr", function() {
|
||||||
|
|
Loading…
Reference in a new issue