From e557f346e9f501ee264435fb4d8860bbf734d649 Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Thu, 13 Jan 2011 06:57:26 +0000 Subject: [PATCH] Add unused document JS module and test. Change svgcanvas to always increment object ids for every call to getNextId(). git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1908 eee81c28-f429-11dd-99c0-75d572ba1ddd --- Makefile | 1 + editor/document.js | 104 +++++++++++++++++++++++++ editor/svg-editor.html | 1 + editor/svgcanvas.js | 35 ++++----- test/all_tests.html | 1 + test/document_test.html | 168 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 290 insertions(+), 20 deletions(-) create mode 100644 editor/document.js create mode 100644 test/document_test.html diff --git a/Makefile b/Makefile index ade3ed2a..08b7ec19 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ build/$(PACKAGE): --js sanitize.js \ --js history.js \ --js select.js \ + --js document.js \ --js svgcanvas.js \ --js svg-editor.js \ --js locale/locale.js \ diff --git a/editor/document.js b/editor/document.js new file mode 100644 index 00000000..ce6d779a --- /dev/null +++ b/editor/document.js @@ -0,0 +1,104 @@ +/** + * Package: svgedit.document + * + * Licensed under the Apache License, Version 2 + * + * Copyright(c) 2010 Jeff Schiller + */ + +/* + TODOs: + + Phase 1: + - migrate svgcanvas to using a Document object for its calls to getNextId() and getId() + - migrate usages of randomizeIds() to proxy into the Document + + Phase 2: + - migrate uniquifyElems into this module + - migrate as many usages of svgcontent in svgcanvas to using a Document instance as possible + + */ +// Dependencies: +// 1) jQuery + +(function() { +if (!window.svgedit) { + window.svgedit = {}; +} + +if (!svgedit.document) { + svgedit.document = {}; +} + +var svg_ns = "http://www.w3.org/2000/svg"; +var se_ns = "http://svg-edit.googlecode.com"; + +/** + * This class encapsulates the concept of a SVG-edit document. + * + * @param svgElem {SVGSVGElement} The SVG DOM Element that this JS object + * encapsulates. If the svgElem has a se:nonce attribute on it, then + * IDs will use the nonce as they are generated. + * @param opt_idPrefix {String} The ID prefix to use. Defaults to "svg_" + * if not specified. + */ +svgedit.document.Document = function(svgElem, opt_idPrefix) { + if (!svgElem || !svgElem.tagName || !svgElem.namespaceURI || + svgElem.tagName != 'svg' || svgElem.namespaceURI != svg_ns) { + throw "Error: svgedit.document.Document instance initialized without a element"; + } + + this.svgElem_ = svgElem; + this.obj_num = 0; + this.idPrefix = opt_idPrefix || "svg_"; + + // Determine if the element has a nonce on it + this.nonce_ = this.svgElem_.getAttributeNS(se_ns, 'nonce') || ""; +}; + +svgedit.document.Document.prototype.getElem_ = function(id) { + if(this.svgElem_.querySelector) { + // querySelector lookup + return this.svgElem_.querySelector('#'+id); + } else { + // jQuery lookup: twice as slow as xpath in FF + return $(this.svgElem_).find('[id=' + id + ']')[0]; + } +}; + +svgedit.document.Document.prototype.getSvgElem = function() { + return this.svgElem_; +} + +svgedit.document.Document.prototype.getNonce = function() { + return this.nonce_; +}; + +/** + * Returns the latest object id as a string. + * @return {String} The latest object Id. + */ +svgedit.document.Document.prototype.getId = function() { + return this.nonce_ ? + this.idPrefix + this.nonce_ +'_' + this.obj_num : + this.idPrefix + this.obj_num; +}; + +/** + * Returns the next object Id as a string. + * @return {String} The next object Id to use. + */ +svgedit.document.Document.prototype.getNextId = function() { + // always increment the obj_num every time we call getNextId() + this.obj_num++; + + // ensure the ID does not exist + var id = this.getId(); + while (this.getElem_(id)) { + this.obj_num++; + id = this.getId(); + } + return id; +}; + +})(); diff --git a/editor/svg-editor.html b/editor/svg-editor.html index dca8b294..26b55190 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -26,6 +26,7 @@ + diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 01c279b8..40c5f25f 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -18,6 +18,7 @@ // 6) svgutils.js // 7) sanitize.js // 8) history.js +// 9) select.js if(!window.console) { window.console = {}; @@ -125,6 +126,7 @@ var dimensions = curConfig.dimensions; var canvas = this; // "document" element associated with the container (same as window.document using default svg-editor.js) +// NOTE: This is not actually a SVG document, but a HTML document. var svgdoc = container.ownerDocument; // This is a container for the document being edited, not the document itself. @@ -159,6 +161,15 @@ $(svgcontent).attr({ "xmlns:xlink": xlinkns }).appendTo(svgroot); +// nonce to uniquify id's +var nonce = Math.floor(Math.random() * 100001); + +// Boolean to indicate whether or not IDs given to elements should be random +var randomize_ids = false; + +// Set nonce if randomize_ids = true +if (randomize_ids) svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce); + // Float displaying the current zoom level (1 = 100%, .5 = 50%, etc) var current_zoom = 1; @@ -461,15 +472,6 @@ var ref_attrs = ["clip-path", "fill", "filter", "marker-end", "marker-mid", "mar var elData = $.data; -// nonce to uniquify id's -var nonce = Math.floor(Math.random() * 100001); - -// Boolean to indicate whether or not IDs given to elements should be random -var randomize_ids = false; - -// Set nonce if randomize_ids = true -if (randomize_ids) svgcontent.setAttributeNS(se_ns, 'se:nonce', nonce); - // Animation element to change the opacity of any newly created element var opac_ani = document.createElementNS(svgns, 'animate'); $(opac_ani).attr({ @@ -529,7 +531,7 @@ var all_layers = [], started = false, // Integer with internal ID number for the latest element - obj_num = 1, + obj_num = 0, // String with an element's initial transform attribute value start_transform = null, @@ -930,8 +932,6 @@ var copyElem = function(el) { // set the copied element's new id new_el.removeAttribute("id"); new_el.id = getNextId(); - // manually increment obj_num because our cloned elements are not in the DOM yet - obj_num++; // 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) @@ -981,7 +981,6 @@ var getId, getNextId, call; // Function: getId // Returns the last created DOM element ID string getId = c.getId = function() { - if (events["getid"]) return call("getid", obj_num); if (randomize_ids) { return idprefix + nonce +'_' + obj_num; } else { @@ -992,9 +991,11 @@ var getId, getNextId, call; // Function: getNextId // Creates and returns a unique ID string for a DOM element getNextId = c.getNextId = function() { + // always increment the obj_num every time we call getNextId() + obj_num++; + // ensure the ID does not exist var id = getId(); - while (getElem(id)) { obj_num++; id = getId(); @@ -3326,7 +3327,6 @@ var getMouseTarget = this.getMouseTarget = function(evt) { } } - // we return immediately from select so that the obj_num is not incremented return; break; case "zoom": @@ -6439,8 +6439,6 @@ var uniquifyElems = this.uniquifyElems = function(g) { var elem = ids[oldid]["elem"]; if (elem) { var newid = getNextId(); - // manually increment obj_num because our cloned elements are not in the DOM yet - obj_num++; // assign element its new id elem.id = newid; @@ -6462,9 +6460,6 @@ var uniquifyElems = this.uniquifyElems = function(g) { } } } - - // manually increment obj_num because our cloned elements are not in the DOM yet - obj_num++; } // Function convertGradients diff --git a/test/all_tests.html b/test/all_tests.html index e929ccda..99528c26 100644 --- a/test/all_tests.html +++ b/test/all_tests.html @@ -11,6 +11,7 @@ + + + + + + + + +

Unit Tests for document.js

+

+

+
    +
+ + +