Use SVGElement.getIntersectionList() for multiselect. Remove some try-catch statements

master
Jeff Schiller 2015-11-30 19:08:13 -08:00
parent 59303eb6cc
commit 3f0db99c6c
2 changed files with 84 additions and 99 deletions

View File

@ -175,7 +175,7 @@ var cur_shape = all_properties.shape;
// Array with all the currently selected elements // Array with all the currently selected elements
// default size of 1 until it needs to grow bigger // default size of 1 until it needs to grow bigger
var selectedElements = new Array(1); var selectedElements = [];
// Function: addSvgElementFromJson // Function: addSvgElementFromJson
// Create a new SVG element based on the given object keys/values and add it to the current layer // Create a new SVG element based on the given object keys/values and add it to the current layer
@ -472,7 +472,7 @@ var encodableImages = {},
// DOM element for selection rectangle drawn by the user // DOM element for selection rectangle drawn by the user
rubberBox = null, rubberBox = null,
// Array of current BBoxes (still needed?) // Array of current BBoxes, used in getIntersectionList().
curBBoxes = [], curBBoxes = [],
// Object to contain all included extensions // Object to contain all included extensions
@ -537,42 +537,37 @@ var round = this.round = function(val) {
// This method sends back an array or a NodeList full of elements that // 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. // intersect the multi-select rubber-band-box on the current_layer only.
// //
// Since the only browser that supports the SVG DOM getIntersectionList is Opera, // We brute-force getIntersectionList for browsers that do not support it (Firefox).
// we need to provide an implementation here. We brute-force it for now.
// //
// Reference: // Reference:
// Firefox does not implement getIntersectionList(), see https://bugzilla.mozilla.org/show_bug.cgi?id=501421 // 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
var getIntersectionList = this.getIntersectionList = function(rect) { var getIntersectionList = this.getIntersectionList = function(rect) {
if (rubberBox == null) { return null; } if (rubberBox == null) { return null; }
var parent = current_group || getCurrentDrawing().getCurrentLayer(); var parent = current_group || getCurrentDrawing().getCurrentLayer();
if (!curBBoxes.length) {
// Cache all bboxes
curBBoxes = getVisibleElementsAndBBoxes(parent);
}
var resultList = null;
try {
resultList = parent.getIntersectionList(rect, null);
} catch(e) { }
if (resultList == null || typeof(resultList.item) != 'function') {
resultList = [];
var rubberBBox; var rubberBBox;
if (!rect) { if (!rect) {
rubberBBox = rubberBox.getBBox(); rubberBBox = rubberBox.getBBox();
var o,
bb = {};
for (o in rubberBBox) {
bb[o] = rubberBBox[o] / current_zoom;
}
rubberBBox = bb;
} else { } else {
rubberBBox = rect; rubberBBox = svgcontent.createSVGRect(rect.x, rect.y, rect.width, rect.height);
}
var resultList = null;
if (typeof(svgroot.getIntersectionList) == 'function') {
// Offset the bbox of the rubber box by the offset of the svgcontent element.
rubberBBox.x += parseInt(svgcontent.getAttribute('x'), 10);
rubberBBox.y += parseInt(svgcontent.getAttribute('y'), 10);
resultList = svgroot.getIntersectionList(rubberBBox, parent);
}
if (resultList == null || typeof(resultList.item) != 'function') {
resultList = [];
if (!curBBoxes.length) {
// Cache all bboxes
curBBoxes = getVisibleElementsAndBBoxes(parent);
} }
var i = curBBoxes.length; var i = curBBoxes.length;
while (i--) { while (i--) {
@ -582,6 +577,7 @@ var getIntersectionList = this.getIntersectionList = function(rect) {
} }
} }
} }
// addToSelection expects an array, but it's ok to pass a NodeList // addToSelection expects an array, but it's ok to pass a NodeList
// because using square-bracket notation is allowed: // because using square-bracket notation is allowed:
// http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html // http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html
@ -602,13 +598,14 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
if (!elems.length) {return false;} if (!elems.length) {return false;}
// Make sure the expected BBox is returned if the element is a group // Make sure the expected BBox is returned if the element is a group
var getCheckedBBox = function(elem) { var getCheckedBBox = function(elem) {
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
// in Issue 339 comment #2). // in Issue 339 comment #2).
var bb = svgedit.utilities.getBBox(elem); var bb = svgedit.utilities.getBBox(elem);
if (!bb) {
return null;
}
var angle = svgedit.utilities.getRotationAngle(elem); var angle = svgedit.utilities.getRotationAngle(elem);
if ((angle && angle % 90) || if ((angle && angle % 90) ||
@ -674,10 +671,6 @@ getStrokedBBox = this.getStrokedBBox = function(elems) {
// bb.height = rmaxy - rminy; // bb.height = rmaxy - rminy;
} }
return bb; return bb;
} catch(e) {
console.log(elem, e);
return null;
}
}; };
var full_bb; var full_bb;
@ -753,11 +746,9 @@ var getVisibleElements = this.getVisibleElements = function(parent) {
var contentElems = []; var contentElems = [];
$(parent).children().each(function(i, elem) { $(parent).children().each(function(i, elem) {
try { if (elem.getBBox) {
if (elem.getBBox()) {
contentElems.push(elem); contentElems.push(elem);
} }
} catch(e) {}
}); });
return contentElems.reverse(); return contentElems.reverse();
}; };
@ -780,11 +771,9 @@ var getVisibleElementsAndBBoxes = this.getVisibleElementsAndBBoxes = function(pa
} }
var contentElems = []; var contentElems = [];
$(parent).children().each(function(i, elem) { $(parent).children().each(function(i, elem) {
try { if (elem.getBBox) {
if (elem.getBBox()) {
contentElems.push({'elem':elem, 'bbox':getStrokedBBox([elem])}); contentElems.push({'elem':elem, 'bbox':getStrokedBBox([elem])});
} }
} catch(e) {}
}); });
return contentElems.reverse(); return contentElems.reverse();
}; };
@ -1762,22 +1751,22 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
// - if newList contains selected, do nothing // - if newList contains selected, do nothing
// - if newList doesn't contain selected, remove it from selected // - if newList doesn't contain selected, remove it from selected
// - for any newList that was not in selectedElements, add it to selected // - for any newList that was not in selectedElements, add it to selected
var elemsToRemove = [], elemsToAdd = [], var elemsToRemove = selectedElements.slice(), elemsToAdd = [],
newList = getIntersectionList(); newList = getIntersectionList();
len = selectedElements.length;
for (i = 0; i < len; ++i) {
var ind = newList.indexOf(selectedElements[i]);
if (ind == -1) {
elemsToRemove.push(selectedElements[i]);
} else {
newList[ind] = null;
}
}
// For every element in the intersection, add if not present in selectedElements.
len = newList.length; len = newList.length;
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
if (newList[i]) {elemsToAdd.push(newList[i]);} var intElem = newList[i];
// Found an element that was not selected before, so we should add it.
if (selectedElements.indexOf(intElem) == -1) {
elemsToAdd.push(intElem);
}
// Found an element that was already selected, so we shouldn't remove it.
var foundInd = elemsToRemove.indexOf(intElem);
if (foundInd != -1) {
elemsToRemove.splice(foundInd, 1)
}
} }
if (elemsToRemove.length > 0) { if (elemsToRemove.length > 0) {
@ -1785,7 +1774,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} }
if (elemsToAdd.length > 0) { if (elemsToAdd.length > 0) {
addToSelection(elemsToAdd); canvas.addToSelection(elemsToAdd);
} }
break; break;

View File

@ -476,14 +476,14 @@ svgedit.utilities.getBBox = function(elem) {
ret = selected.getBBox(); ret = selected.getBBox();
selected.textContent = ''; selected.textContent = '';
} else { } else {
try { ret = selected.getBBox();} catch(e){} if (selected.getBBox) { ret = selected.getBBox(); }
} }
break; break;
case 'path': case 'path':
if(!svgedit.browser.supportsPathBBox()) { if(!svgedit.browser.supportsPathBBox()) {
ret = svgedit.utilities.getPathBBox(selected); ret = svgedit.utilities.getPathBBox(selected);
} else { } else {
try { ret = selected.getBBox();} catch(e2){} if (selected.getBBox) { ret = selected.getBBox(); }
} }
break; break;
case 'g': case 'g':
@ -509,18 +509,14 @@ svgedit.utilities.getBBox = function(elem) {
ret = bb; ret = bb;
//} //}
} else if(~visElems_arr.indexOf(elname)) { } else if(~visElems_arr.indexOf(elname)) {
try { ret = selected.getBBox();} if (selected) { ret = selected.getBBox(); }
catch(e3) { else {
// Check if element is child of a foreignObject // Check if element is child of a foreignObject
var fo = $(selected).closest('foreignObject'); var fo = $(selected).closest('foreignObject');
if (fo.length) { if (fo.length) {
try { if (fo[0].getBBox) {
ret = fo[0].getBBox(); ret = fo[0].getBBox();
} catch(e4) {
ret = null;
} }
} else {
ret = null;
} }
} }
} }