diff --git a/Makefile b/Makefile index cdb39f7a..ce84398a 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ ZIP=zip JS_FILES=\ svgedit.js \ + jquery-svg.js \ contextmenu/jquery.contextmenu.js \ browser.js \ svgtransformlist.js \ diff --git a/editor/jquery-svg.js b/editor/jquery-svg.js new file mode 100644 index 00000000..200ad76e --- /dev/null +++ b/editor/jquery-svg.js @@ -0,0 +1,69 @@ +/** + * jQuery module to work with SVG. + * + * Licensed under the MIT License + * + */ + +// Dependencies: +// 1) jquery + +(function() { + + // 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: + // - 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 + + var proxied = jQuery.fn.attr, + // TODO use NS.SVG instead + svgns = "http://www.w3.org/2000/svg"; + jQuery.fn.attr = function(key, value) { + var len = this.length; + if (!len) return proxied.apply(this, arguments); + for (var i = 0; i < len; ++i) { + var elem = this[i]; + // set/get SVG attribute + if (elem.namespaceURI === svgns) { + // Setting attribute + if (value !== undefined) { + elem.setAttribute(key, value); + } else if ($.isArray(key)) { + // Getting attributes from array + var j = key.length, obj = {}; + + while (j--) { + var aname = key[j]; + var attr = elem.getAttribute(aname); + // This returns a number when appropriate + if (attr || attr === "0") { + attr = isNaN(attr) ? attr : (attr - 0); + } + obj[aname] = attr; + } + return obj; + } else if (typeof key === "object") { + // Setting attributes form object + for (var v in key) { + elem.setAttribute(v, key[v]); + } + // Getting attribute + } else { + var attr = elem.getAttribute(key); + if (attr || attr === "0") { + attr = isNaN(attr) ? attr : (attr - 0); + } + return attr; + } + } else { + return proxied.apply(this, arguments); + } + } + return this; + }; +}()); diff --git a/editor/recalculate.js b/editor/recalculate.js index 2e0dd572..7c5c0b65 100644 --- a/editor/recalculate.js +++ b/editor/recalculate.js @@ -6,14 +6,16 @@ */ // Dependencies: -// 1) svgedit.js -// 2) browser.js -// 3) math.js -// 4) history.js -// 5) units.js -// 6) svgtransformlist.js -// 7) svgutils.js -// 8) coords.js +// 1) jquery +// 2) jquery-svg.js +// 3) svgedit.js +// 4) browser.js +// 5) math.js +// 6) history.js +// 7) units.js +// 8) svgtransformlist.js +// 9) svgutils.js +// 10) coords.js var svgedit = svgedit || {}; @@ -52,7 +54,6 @@ svgedit.recalculate.updateClipPath = function(attr, tx, ty) { }; - // Function: svgedit.recalculate.recalculateDimensions // Decides the course of action based on the element's transform list // @@ -95,7 +96,9 @@ svgedit.recalculate.recalculateDimensions = function(selected) { // if this element had no transforms, we are done if (!tlist || tlist.numberOfItems == 0) { - selected.removeAttribute("transform"); + // Chrome has a bug that requires clearing the attribute first. + selected.setAttribute('transform', ''); + selected.removeAttribute('transform'); return null; } diff --git a/editor/svg-editor.html b/editor/svg-editor.html index d720717c..063f74c7 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -29,6 +29,7 @@ + diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 2f29ac1e..0853a751 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -36,64 +36,6 @@ if (window.opera) { } (function() { - // 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: - // - 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 - - var proxied = jQuery.fn.attr, - // TODO use NS.SVG instead - svgns = "http://www.w3.org/2000/svg"; - jQuery.fn.attr = function(key, value) { - var len = this.length; - if (!len) return proxied.apply(this, arguments); - for (var i=0; i

All SVG-edit Tests

This file frames all SVG-edit test pages. This should only include tests known to work. These tests are known to pass 100% in the following: Firefox 3.6, Chrome 7, IE9 Preview 6 (1.9.8006.6000), Opera 10.63. If a test is broken in this page, it is possible that YOU broke it. Please do not submit code that breaks any of these tests.

+ diff --git a/test/jquery-svg_test.html b/test/jquery-svg_test.html new file mode 100644 index 00000000..dfc987e9 --- /dev/null +++ b/test/jquery-svg_test.html @@ -0,0 +1,27 @@ + + + + Unit Tests for jquery-svg.js + + + + + + +

Unit Tests for jquery-svg

+

+

+
    +
    + + diff --git a/test/recalculate_test.html b/test/recalculate_test.html index 864a9e7a..de5bd67a 100644 --- a/test/recalculate_test.html +++ b/test/recalculate_test.html @@ -3,6 +3,8 @@ Unit Tests for recalculate.js + + @@ -22,6 +24,84 @@ } }; + var root = document.getElementById('root'); + var svgroot = document.createElementNS(svgedit.NS.SVG, 'svg'); + svgroot.id = 'svgroot'; + root.appendChild(svgroot); + var svg = document.createElementNS(svgedit.NS.SVG, 'svg'); + svgroot.appendChild(svg); + var elemId = 1; + var elem; + + function setUp() { + svgedit.utilities.init({ + getSVGRoot: function() { return svg }, + getDOMDocument: function() { return null }, + getDOMContainer: function() { return null } + }); + svgedit.coords.init({ + getGridSnapping: function() { return false; }, + getDrawing: function() { + return { + getNextId: function() { return '' + elemId++; } + }; + } + }); + svgedit.recalculate.init({ + getSVGRoot: function() { return svg }, + getStartTransform: function() { return ''}, + setStartTransform: function() { } + }); + } + + function setUpRect() { + setUp(); + elem = document.createElementNS(svgedit.NS.SVG, 'rect'); + elem.setAttribute('x', '200'); + elem.setAttribute('y', '150'); + elem.setAttribute('width', '250'); + elem.setAttribute('height', '120'); + svg.appendChild(elem); + } + + function tearDown() { + while(svg.hasChildNodes()) { + svg.removeChild(svg.firstChild); + } + } + + test('Test recalculateDimensions() for identity matrix', function() { + expect(1); + + setUpRect(); + elem.setAttribute('transform', 'matrix(1,0,0,1,0,0)'); + + svgedit.recalculate.recalculateDimensions(elem); + + // Ensure that the identity matrix is swallowed and the element has no + // transform on it. + equal(false, elem.hasAttribute('transform')); + + tearDown(); + }); + + test('Test recalculateDimensions() for simple translate', function() { + expect(1); + + setUpRect(); + elem.setAttribute('transform', 'translate(100,50)'); + + // TODO: Need the hack to jquery's attr() at the top of svgcanvas.js + // to make this work. + svgedit.recalculate.recalculateDimensions(elem); + + // Ensure that the identity matrix is swallowed and the element has no + // transform on it. + equal(false, elem.hasAttribute('transform')); + + tearDown(); + }); + // TODO: Since recalculateDimensions() and surrounding code is // probably the largest, most complicated and strange piece of // code in SVG-edit, we need to write a whole lot of unit tests