Avoid getDescendants(document)
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Mon, 01 Aug 2011 13:20:22 -0600
changeset 479 1580a1b1f19d
parent 478 1fc389b77696
child 480 40ce917d1ee7
Avoid getDescendants(document)

It's unlikely to be fast . . .
implementation.js
--- a/implementation.js	Mon Aug 01 13:05:45 2011 -0600
+++ b/implementation.js	Mon Aug 01 13:20:22 2011 -0600
@@ -5275,18 +5275,33 @@
 
 	// "Let items be a list of all lis that are ancestor containers of the
 	// range's start and/or end node."
-	var items = getDescendants(document).filter(function(node) {
-		return isHtmlElement(node, "li")
-			&& (isAncestor(node, range.startContainer)
-			|| node == range.startContainer
-			|| isAncestor(node, range.endContainer)
-			|| node == range.endContainer);
-	});
+	//
+	// It's annoying to get this in tree order using functional stuff without
+	// doing getDescendants(document), which is slow, so I do it imperatively.
+	var items = [];
+	(function(){
+		for (
+			var ancestorContainer = range.endContainer;
+			ancestorContainer != range.commonAncestorContainer;
+			ancestorContainer = ancestorContainer.parentNode
+		) {
+			if (isHtmlElement(ancestorContainer, "li")) {
+				items.unshift(ancestorContainer);
+			}
+		}
+		for (
+			var ancestorContainer = range.startContainer;
+			ancestorContainer;
+			ancestorContainer = ancestorContainer.parentNode
+		) {
+			if (isHtmlElement(ancestorContainer, "li")) {
+				items.unshift(ancestorContainer);
+			}
+		}
+	})();
 
 	// "For each item in items, normalize sublists of item."
-	for (var i = 0; i < items.length; i++) {
-		normalizeSublists(items[i]);
-	}
+	items.forEach(normalizeSublists);
 
 	// "Block-extend the range, and let new range be the result."
 	var newRange = blockExtend(range);
@@ -7371,19 +7386,35 @@
 commands.outdent = {
 	action: function() {
 		// "Let items be a list of all lis that are ancestor containers of the
-		// active range's start and/or end node."
-		var items = getDescendants(document).filter(function(node) {
-			return isHtmlElement(node, "li")
-				&& (isAncestor(node, getActiveRange().startContainer)
-				|| node == getActiveRange().startContainer
-				|| isAncestor(node, getActiveRange().endContainer)
-				|| node == getActiveRange().endContainer);
-		});
+		// range's start and/or end node."
+		//
+		// It's annoying to get this in tree order using functional stuff
+		// without doing getDescendants(document), which is slow, so I do it
+		// imperatively.
+		var items = [];
+		(function(){
+			for (
+				var ancestorContainer = getActiveRange().endContainer;
+				ancestorContainer != getActiveRange().commonAncestorContainer;
+				ancestorContainer = ancestorContainer.parentNode
+			) {
+				if (isHtmlElement(ancestorContainer, "li")) {
+					items.unshift(ancestorContainer);
+				}
+			}
+			for (
+				var ancestorContainer = getActiveRange().startContainer;
+				ancestorContainer;
+				ancestorContainer = ancestorContainer.parentNode
+			) {
+				if (isHtmlElement(ancestorContainer, "li")) {
+					items.unshift(ancestorContainer);
+				}
+			}
+		})();
 
 		// "For each item in items, normalize sublists of item."
-		for (var i = 0; i < items.length; i++) {
-			normalizeSublists(items[i]);
-		}
+		items.forEach(normalizeSublists);
 
 		// "Block-extend the active range, and let new range be the result."
 		var newRange = blockExtend(getActiveRange());