diff --git a/editor/browsersupport.js b/editor/browsersupport.js index 34dbc467..90cd94bf 100644 --- a/editor/browsersupport.js +++ b/editor/browsersupport.js @@ -22,6 +22,7 @@ if (!svgedit.browsersupport) { var svgns = 'http://www.w3.org/2000/svg'; var userAgent = navigator.userAgent; +var svg = document.createElementNS(svgns, 'svg'); // Note: Browser sniffing should only be used if no other detection method is possible var isOpera_ = !!window.opera; @@ -34,7 +35,7 @@ svgedit.browsersupport.isGecko = function() { return isGecko_; } // segList functions (for FF1.5 and 2.0) function supportPathReplaceItem() { - var path = document.createElementNS(svgns,'path'); + var path = document.createElementNS(svgns, 'path'); path.setAttribute('d','M0,0 10,10'); var seglist = path.pathSegList; var seg = path.createSVGPathSegLinetoAbs(5,5); @@ -80,7 +81,7 @@ function supportEditableText() { function supportGoodDecimals() { // Correct decimals on clone attributes (Opera < 10.5/win/non-en) - var rect = document.createElementNS(svgns,'rect'); + var rect = document.createElementNS(svgns, 'rect'); rect.setAttribute('x',.1); var crect = rect.cloneNode(false); var retValue = (crect.getAttribute('x').indexOf(',') == -1); @@ -92,16 +93,26 @@ function supportGoodDecimals() { } function supportNonScalingStroke() { - var rect = document.createElementNS(svgns,'rect'); + var rect = document.createElementNS(svgns, 'rect'); rect.setAttribute('style','vector-effect:non-scaling-stroke'); return rect.style.vectorEffect === 'non-scaling-stroke'; } +function supportNativeSVGTransformLists() { + var rect = document.createElementNS(svgns, 'rect'); + var rxform = rect.transform.baseVal; + + var t1 = svg.createSVGTransform(); + rxform.appendItem(t1); + return rxform.getItem(0) == t1; +} + svgedit.browsersupport.pathReplaceItem = supportPathReplaceItem(); svgedit.browsersupport.pathInsertItemBefore = supportPathInsertItemBefore(); svgedit.browsersupport.textCharPos = supportTextCharPos(); svgedit.browsersupport.editableText = supportEditableText(); svgedit.browsersupport.goodDecimals = supportGoodDecimals(); svgedit.browsersupport.nonScalingStroke = supportNonScalingStroke(); +svgedit.browsersupport.nativeTransformLists = supportNativeSVGTransformLists(); })(); \ No newline at end of file diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 8ac74151..5fbd0ff7 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -10,8 +10,8 @@ - - + + diff --git a/editor/svgtransformlist.js b/editor/svgtransformlist.js index 69d19bb5..958ae9b2 100644 --- a/editor/svgtransformlist.js +++ b/editor/svgtransformlist.js @@ -135,21 +135,23 @@ svgedit.transformlist.SVGTransformList = function(elem) { } }; this._removeFromOtherLists = function(item) { - // Check if this transform is already in a transformlist, and - // remove it if so. - var found = false; - for (var id in listMap_) { - var tl = listMap_[id]; - for (var i = 0, len = tl._xforms.length; i < len; ++i) { - if(tl._xforms[i] == item) { - found = true; - tl.removeItem(i); + if (item) { + // Check if this transform is already in a transformlist, and + // remove it if so. + var found = false; + for (var id in listMap_) { + var tl = listMap_[id]; + for (var i = 0, len = tl._xforms.length; i < len; ++i) { + if(tl._xforms[i] == item) { + found = true; + tl.removeItem(i); + break; + } + } + if (found) { break; } } - if (found) { - break; - } } }; @@ -169,7 +171,7 @@ svgedit.transformlist.SVGTransformList = function(elem) { if (index < this.numberOfItems && index >= 0) { return this._xforms[index]; } - return null; + throw {code: 1}; // DOMException with code=INDEX_SIZE_ERR }; this.insertItemBefore = function(newItem, index) { @@ -210,7 +212,6 @@ svgedit.transformlist.SVGTransformList = function(elem) { }; this.removeItem = function(index) { - var retValue = null; if (index < this.numberOfItems && index >= 0) { var retValue = this._xforms[index]; var newxforms = new Array(this.numberOfItems - 1); @@ -223,8 +224,10 @@ svgedit.transformlist.SVGTransformList = function(elem) { this.numberOfItems--; this._xforms = newxforms; this._list._update(); + return retValue; + } else { + throw {code: 1}; // DOMException with code=INDEX_SIZE_ERR } - return retValue; }; this.appendItem = function(newItem) { @@ -258,7 +261,7 @@ svgedit.transformlist.removeElementFromListMap = function(elem) { // Parameters: // elem - DOM element to get a transformlist from svgedit.transformlist.getTransformList = function(elem) { - if (svgedit.browsersupport.isWebkit()) { + if (!svgedit.browsersupport.nativeTransformLists) { var id = elem.id; if(!id) { // Get unique ID for temporary element diff --git a/test/svgtransformlist_test.html b/test/svgtransformlist_test.html index 3696f294..f76293a3 100644 --- a/test/svgtransformlist_test.html +++ b/test/svgtransformlist_test.html @@ -6,8 +6,7 @@ // Mock for browsersupport window.svgedit = {}; svgedit.browsersupport = {}; - svgedit.browsersupport.isWebkit_ = true; - svgedit.browsersupport.isWebkit = function() { return svgedit.browsersupport.isWebkit_; } + svgedit.browsersupport.nativeTransformLists = false; @@ -29,6 +28,19 @@ msg = msg || (a + ' did not equal ' + b); ok(Math.abs(a - b) < NEAR_ZERO, msg); } + + function checkOutOfBoundsException(obj, fn, arg1) { + var caughtException = false; + try { + obj[fn](arg1); + } + catch(e) { + if (e.code == 1) { + caughtException = true; + } + } + ok(caughtException, 'Caugh an INDEX_SIZE_ERR exception'); + } function setUp() { svgcontent = svgroot.appendChild(document.createElementNS(svgns, 'svg')); @@ -82,7 +94,7 @@ }); test('Test SVGTransformList.initialize()', function() { - expect(7); + expect(6); setUp(); var rxform = svgedit.transformlist.getTransformList(rect); @@ -99,14 +111,15 @@ // If a transform was already in a transform list, this should // remove it from its old list and add it to this list. cxform.initialize(t); - equals(rxform.numberOfItems, 0); + // This also fails in Firefox native. +// equals(rxform.numberOfItems, 0, 'Did not remove transform from list before initializing another transformlist'); equals(cxform.numberOfItems, 1); tearDown(); }); test('Test SVGTransformList.appendItem() and getItem()', function() { - expect(15); + expect(12); setUp(); var rxform = svgedit.transformlist.getTransformList(rect); @@ -126,17 +139,19 @@ rxform.appendItem(t3); equals(rxform.numberOfItems, 3); - equals(rxform.getItem(0), t1); + var rxf = rxform.getItem(0); + equals(rxf, t1); equals(rxform.getItem(1), t2); equals(rxform.getItem(2), t3); - ok(!rxform.getItem(-1)); - ok(!rxform.getItem(3)); + checkOutOfBoundsException(rxform, 'getItem', -1); + checkOutOfBoundsException(rxform, 'getItem', 3); cxform.appendItem(t1); - equals(rxform.numberOfItems, 2); - equals(rxform.getItem(0), t2); - equals(rxform.getItem(1), t3); + // These also fail in Firefox native. +// equals(rxform.numberOfItems, 2, 'Did not remove a transform from a list before appending it to a new transformlist'); +// equals(rxform.getItem(0), t2, 'Found the wrong transform in a transformlist'); +// equals(rxform.getItem(1), t3, 'Found the wrong transform in a transformlist'); equals(cxform.numberOfItems, 1); equals(cxform.getItem(0), t1); @@ -162,14 +177,14 @@ equals(removedTransform, t1); equals(rxform.getItem(0), t2); - ok(!rxform.removeItem(-1)); - ok(!rxform.removeItem(1)); + checkOutOfBoundsException(rxform, 'removeItem', -1); + checkOutOfBoundsException(rxform, 'removeItem', 1); tearDown(); }); test('Test SVGTransformList.replaceItem()', function() { - expect(10); + expect(8); setUp(); var rxform = svgedit.transformlist.getTransformList(rect); @@ -191,12 +206,14 @@ equals(newItem, t3); equals(rxform.getItem(0), t3); equals(rxform.getItem(1), t2); - equals(cxform.numberOfItems, 0); + // Fails in Firefox native +// equals(cxform.numberOfItems, 0); // test replaceItem within a list rxform.appendItem(t1); rxform.replaceItem(t1, 0); - equals(rxform.numberOfItems, 2); + // Fails in Firefox native +// equals(rxform.numberOfItems, 2); equals(rxform.getItem(0), t1); equals(rxform.getItem(1), t2); @@ -204,7 +221,7 @@ }); test('Test SVGTransformList.insertItemBefore()', function() { - expect(12); + expect(10); setUp(); var rxform = svgedit.transformlist.getTransformList(rect); @@ -227,10 +244,12 @@ equals(rxform.getItem(0), t3); equals(rxform.getItem(1), t1); equals(rxform.getItem(2), t2); - equals(cxform.numberOfItems, 0); + // Fails in Firefox native +// equals(cxform.numberOfItems, 0); rxform.insertItemBefore(t2, 1); - equals(rxform.numberOfItems, 3); + // Fails in Firefox native (they make copies of the transforms) +// equals(rxform.numberOfItems, 3); equals(rxform.getItem(0), t3); equals(rxform.getItem(1), t2); equals(rxform.getItem(2), t1); @@ -343,7 +362,6 @@ almostEquals(m.b, 1/Math.sqrt(2)); almostEquals(m.c, -1/Math.sqrt(2)); almostEquals(m.d, 1/Math.sqrt(2)); - // TODO(codedread): calculation var r = svgcontent.createSVGMatrix(); r.a = 1/Math.sqrt(2); r.b = 1/Math.sqrt(2); @@ -362,6 +380,28 @@ tearDown(); }); + + test('Test SVGTransformList.init() for matrix(1, 2, 3, 4, 5, 6)', function() { + expect(8); + setUp(); + rect.setAttribute('transform', 'matrix(1,2,3,4,5,6)'); + + var rxform = svgedit.transformlist.getTransformList(rect); + equals(1, rxform.numberOfItems); + + var mt = rxform.getItem(0); + equals(1, mt.type); + + var m = mt.matrix; + equals(m.a, 1); + equals(m.b, 2); + equals(m.c, 3); + equals(m.d, 4); + equals(m.e, 5); + equals(m.f, 6); + + tearDown(); + }); });