[Pkg-javascript-commits] [dojo] 30/32: Fixes #16975. Remove leak when calling empty() on SVG elements (all browsers). On IE, use removeChild instead of removeNode on SVG elements since they don't inherit removeNode from HTMLElement and SVG/removeNode is incorrectly implemented. Backport thru 1.6. Add additional strict and quirks automated tests to make sure empty() and destroy() are working correctly with SVG and OBJECT nodes, and since these element's behavior seem dependent on the document's compatMode. !strict

David Prévot taffit at moszumanska.debian.org
Thu Aug 21 17:39:09 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to annotated tag 1.6.2
in repository dojo.

commit 23c1d281e58faa13aa21ac7794fae836e3bd2abd
Author: Douglas Hays <doughays at dojotoolkit.org>
Date:   Wed Apr 10 12:05:48 2013 +0000

    Fixes #16975.  Remove leak when calling empty() on SVG elements (all browsers).  On IE, use removeChild instead of removeNode on SVG elements since they don't inherit removeNode from HTMLElement and SVG/removeNode is incorrectly implemented.  Backport thru 1.6.  Add additional strict and quirks automated tests to make sure empty() and destroy() are working correctly with SVG and OBJECT nodes, and since these element's behavior seem dependent on the document's compatMode. !strict
    
    git-svn-id: http://svn.dojotoolkit.org/src/branches/1.6/dojo@31197 560b804f-0ae3-0310-86f3-f6aa0a117693
---
 _base/html.js                | 29 ++++++++++----------
 tests/_base/html.html        | 65 ++++++++++++++++++++++++++++++++++++++++++--
 tests/_base/html_quirks.html | 64 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 141 insertions(+), 17 deletions(-)

diff --git a/_base/html.js b/_base/html.js
index ae072a7..e546e9b 100644
--- a/_base/html.js
+++ b/_base/html.js
@@ -105,7 +105,7 @@ if(dojo.isIE){
 		if(parent){
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 			// removeNode(false) doesn't leak in IE 6+, but removeChild() and removeNode(true) are known to leak under IE 8- while 9+ is TBD
-			d.isIE && 'removeNode' in node ? node.removeNode(false) :
+			d.isIE && parent.canHaveChildren && 'removeNode' in node ? node.removeNode(false) :
 //>>excludeEnd("webkitMobile");
 				parent.removeChild(node);
 		}
@@ -1572,21 +1572,22 @@ if(dojo.isIE){
 	}
 	=====*/
 
-	var _empty =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE ? function(/*DomNode*/ node){
+	function _empty(/*DomNode*/ node){
+		if(node.canHaveChildren){
 			try{
-				node.innerHTML = ""; // really fast when it works
-			}catch(e){ // IE can generate Unknown Error
-				for(var c; c = node.lastChild;){ // intentional assignment
-					_destroy(c, node); // destroy is better than removeChild so TABLE elements are removed in proper order
-				}
+				// fast path
+				node.innerHTML = "";
+				return;
+			}catch(e){
+				// innerHTML is readOnly (e.g. TABLE (sub)elements in quirks mode)
+				// Fall through (saves bytes)
 			}
-		} :
-		//>>excludeEnd("webkitMobile");
-		function(/*DomNode*/ node){
-			node.innerHTML = "";
-		};
+		}
+		// SVG/strict elements don't support innerHTML/canHaveChildren, and OBJECT/APPLET elements in quirks node have canHaveChildren=false
+		for(var c; c = node.lastChild;){ // intentional assignment
+			_destroy(c, node); // destroy is better than removeChild so TABLE subelements are removed in proper order
+		}
+	}
 
 	d.empty = function(node){
 		_empty(byId(node));
diff --git a/tests/_base/html.html b/tests/_base/html.html
index f96989c..8b55211 100644
--- a/tests/_base/html.html
+++ b/tests/_base/html.html
@@ -624,6 +624,48 @@
 					});
 				});
 
+				doh.register("t",
+					[
+						function emptySvg(t){
+							dojo.empty(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface").firstChild, "svg firstChild");
+						},
+						function destroySvg(t){
+							dojo.destroy(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface"), "svg byId");
+						},
+						function emptyObject(t){
+							dojo.empty(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty").firstChild, "object firstChild");
+						},
+						function destroyObject(t){
+							dojo.destroy(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty"), "object byId");
+						},
+						function destroyIframe(t){
+							dojo.destroy(dojo.byId("iframeToDestroy"));
+							doh.f(!!dojo.byId("iframeToDestroy"), "iframe byId");
+						},
+						function destroyDivNotInDOM(t){
+							var p = dojo.byId("divToRemoveFromDOM");
+							var n = dojo.byId("divToDestroy");
+							p = p.parentNode.removeChild(p);
+							doh.f(!!dojo.byId("divToRemoveFromDOM"), "div byId");
+							doh.t(!!p.firstChild, "div child 1");
+							doh.is(p.firstChild, n, "div 1st child");
+							doh.isNot(p.firstChild, p.lastChild, "div 1st child");
+							dojo.destroy(n);
+							doh.t(!!p.firstChild, "div child 2");
+							doh.isNot(p.firstChild, n, "div 2nd child");
+							doh.is(p.firstChild, p.lastChild, "div 2nd child");
+							dojo.empty(p);
+							doh.f(!!p.firstChild, "div child 3");
+							dojo.destroy(p);
+							doh.t(true, "no exception thrown");
+						}
+					]
+				);
+
 				doh.run();
 			});
 		</script>
@@ -859,8 +901,25 @@
 		<div id="iframeContainer"></div>
 
 		<!-- SVG element to test dojo.getComputedStyle on IE9 (#14103) -->
-		<svg id="surface" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
-			<rect id="rect1" fill="rgb(255, 0, 0)" x="0" y="0" width="80" height="60" ry="0" rx="0" fill-rule="evenodd"/>
-		</svg>
+		<!-- SVG element to test empty -->
+		<svg id="surface" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"
+			><rect id="rect1" fill="rgb(255, 0, 0)" x="0" y="0" width="80" height="60" ry="0" rx="0" fill-rule="evenodd"
+		/></svg>
+
+		<!-- OBJECT element to test empty -->
+		<object width="500" height="500" id="objectToEmpty" data="data:application/x-silverlight," type="application/x-silverlight"
+			><param name="background" value="transparent"
+		/></object>
+
+		<!-- IFRAME element to test destroy -->
+		<iframe id="iframeToDestroy" src="about:blank"
+			><span></span
+		></iframe>
+
+		<!-- DIV element to test destroy of element not in the DOM -->
+		<div id="divToRemoveFromDOM"
+			><div id="divToDestroy"></div
+			><div></div
+		></div>
 	</body>
 </html>
diff --git a/tests/_base/html_quirks.html b/tests/_base/html_quirks.html
index 128122f..d3da0cb 100644
--- a/tests/_base/html_quirks.html
+++ b/tests/_base/html_quirks.html
@@ -138,6 +138,48 @@
 					);
 				}
 
+				doh.register("t",
+					[
+						function emptySvg(t){
+							dojo.empty(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface").firstChild, "svg firstChild");
+						},
+						function destroySvg(t){
+							dojo.destroy(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface"), "svg byId");
+						},
+						function emptyObject(t){
+							dojo.empty(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty").firstChild, "object firstChild");
+						},
+						function destroyObject(t){
+							dojo.destroy(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty"), "object byId");
+						},
+						function destroyIframe(t){
+							dojo.destroy(dojo.byId("iframeToDestroy"));
+							doh.f(!!dojo.byId("iframeToDestroy"), "iframe byId");
+						},
+						function destroyDivNotInDOM(t){
+							var p = dojo.byId("divToRemoveFromDOM");
+							var n = dojo.byId("divToDestroy");
+							p = p.parentNode.removeChild(p);
+							doh.f(!!dojo.byId("divToRemoveFromDOM"), "div byId");
+							doh.t(!!p.firstChild, "div child 1");
+							doh.is(p.firstChild, n, "div 1st child");
+							doh.isNot(p.firstChild, p.lastChild, "div 1st child");
+							dojo.destroy(n);
+							doh.t(!!p.firstChild, "div child 2");
+							doh.isNot(p.firstChild, n, "div 2nd child");
+							doh.is(p.firstChild, p.lastChild, "div 2nd child");
+							dojo.empty(p);
+							doh.f(!!p.firstChild, "div child 3");
+							dojo.destroy(p);
+							doh.t(true, "no exception thrown");
+						}
+					]
+				);
+
 				doh.run();
 			});
 		</script>
@@ -326,6 +368,28 @@
 		<div id="sq100nopos">
 			100px square, no positioning
 		</div>
+
+		<!-- SVG element to test dojo.getComputedStyle on IE9 (#14103) -->
+		<!-- SVG element to test empty -->
+		<svg id="surface" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"
+			><rect id="rect1" fill="rgb(255, 0, 0)" x="0" y="0" width="80" height="60" ry="0" rx="0" fill-rule="evenodd"
+		/></svg>
+
+		<!-- OBJECT element to test empty -->
+		<object width="500" height="500" id="objectToEmpty" data="data:application/x-silverlight," type="application/x-silverlight"
+			><param name="background" value="transparent"
+		/></object>
+
+		<!-- IFRAME element to test destroy -->
+		<iframe id="iframeToDestroy" src="about:blank"
+			><span></span
+		></iframe>
+
+		<!-- DIV element to test destroy of element not in the DOM -->
+		<div id="divToRemoveFromDOM"
+			><div id="divToDestroy"></div
+			><div></div
+		></div>
 	</body>
 </html>
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dojo.git



More information about the Pkg-javascript-commits mailing list