From: Kevin Carhart <kevin@carhart.net>
To: Edbrowse-dev@lists.the-brannons.com
Subject: [Edbrowse-dev] [PATCH] nextSibling/previousSibling rev 2
Date: Thu, 29 Dec 2016 01:31:09 -0800 [thread overview]
Message-ID: <20161129013109.kevin@carhart.net > (raw)
>From 29704df5cdedb9aaea60a45b8eab96ecf9f88873 Mon Sep 17 00:00:00 2001
From: Kevin Carhart <kevin@carhart.net>
Date: Thu, 29 Dec 2016 01:09:20 -0800
Subject: [PATCH] common DOM traversal functionality: nextSibling and
previousSibling. Test added to jsrt
---
src/jsrt | 26 +++++++
src/startwindow.js | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 228 insertions(+), 6 deletions(-)
diff --git a/src/jsrt b/src/jsrt
index ac5ebc1..942a6ea 100644
--- a/src/jsrt
+++ b/src/jsrt
@@ -800,6 +800,32 @@ fail(161);
}
}
+test_siblings();
+function test_siblings()
+{
+var x1 = document.createElement("div");
+var x2 = document.createElement("span");
+var x3 = document.createElement("table");
+var x4 = document.createElement("script");
+var x5 = document.createElement("element");
+x5.value = 123;
+
+x1.appendChild(x2);
+x1.appendChild(x3);
+x1.appendChild(x4);
+x1.appendChild(x5);
+
+var child1 = x1.childNodes[0];
+// in the wild it is common to see these sibling calls daisychained
+var testchild = child1.nextSibling.nextSibling.previousSibling.nextSibling.nextSibling;
+if (testchild.value == 123)
+{
+// pass
+} else {
+fail(162);
+}
+}
+
</script>
</body>
diff --git a/src/startwindow.js b/src/startwindow.js
index 2675875..702ff72 100644
--- a/src/startwindow.js
+++ b/src/startwindow.js
@@ -239,7 +239,6 @@ c.className = new String;
c.ownerDocument = document;
c.tagName = t;
-
return c;
}
@@ -602,6 +601,13 @@ get: function() { return document.childNodes[0]; }
Object.defineProperty(document, "lastChild", {
get: function() { return document.childNodes[document.childNodes.length-1]; }
});
+Object.defineProperty(document, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(document, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
document.hasChildNodes = function() { return (this.childNodes.length > 0); }
document.replaceChild = function(newc, oldc) {
var lastentry;
@@ -728,6 +734,35 @@ nodeToReturn[url] = new URL(u.href);
return nodeToReturn;
}
+function get_sibling(obj,direction)
+{
+if (typeof obj.parentNode == 'undefined') {
+// need calling node to have parent and it doesn't, error
+return null;
+}
+var pn = obj.parentNode;
+var j, l;
+l = pn.childNodes.length;
+for (j=0; j<l; ++j)
+if (pn.childNodes[j] == obj) break;
+if (j == l) {
+// child not found under parent, error
+return null;
+}
+switch(direction)
+{
+case "previous":
+return (j > 0 ? pn.childNodes[j-1] : null);
+break;
+case "next":
+return (j < l-1 ? pn.childNodes[j+1] : null);
+break;
+default:
+// the function should always have been called with either 'previous' or 'next' specified
+return null;
+}
+}
+
/* The select element in a form is itself an array, so the above functions have
* to be on array prototype, except appendchild is to have no side effects,
* because select options are maintained by rebuildSelectors(), so appendChild
@@ -764,6 +799,13 @@ get: function() { return this[0]; }
Object.defineProperty(Array.prototype, "lastChild", {
get: function() { return this[this.length-1]; }
});
+Object.defineProperty(Array.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Array.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Array.prototype.hasChildNodes = document.hasChildNodes;
Array.prototype.replaceChild = document.replaceChild;
Array.prototype.getAttribute = document.getAttribute;
@@ -779,6 +821,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Head.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Head.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Head.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Head.prototype.hasChildNodes = document.hasChildNodes;
Head.prototype.removeChild = document.removeChild;
Head.prototype.replaceChild = document.replaceChild;
@@ -796,6 +845,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Body.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Body.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Body.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Body.prototype.hasChildNodes = document.hasChildNodes;
Body.prototype.removeChild = document.removeChild;
Body.prototype.replaceChild = document.replaceChild;
@@ -850,6 +906,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Form.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Form.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Form.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Form.prototype.hasChildNodes = document.hasChildNodes;
Form.prototype.removeChildNative = document.removeChild;
Form.prototype.removeChild = function(item) {
@@ -872,6 +935,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Element.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Element.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Element.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Element.prototype.hasChildNodes = document.hasChildNodes;
Element.prototype.removeChild = document.removeChild;
Element.prototype.replaceChild = document.replaceChild;
@@ -900,6 +970,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Div.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Div.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Div.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Div.prototype.hasChildNodes = document.hasChildNodes;
Div.prototype.removeChild = document.removeChild;
Div.prototype.replaceChild = document.replaceChild;
@@ -917,6 +994,14 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(HtmlObj.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(HtmlObj.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(HtmlObj.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
+
HtmlObj.prototype.hasChildNodes = document.hasChildNodes;
HtmlObj.prototype.removeChild = document.removeChild;
HtmlObj.prototype.replaceChild = document.replaceChild;
@@ -929,11 +1014,56 @@ Script.prototype.getAttribute = document.getAttribute;
Script.prototype.setAttribute = document.setAttribute;
Script.prototype.cloneNode = document.cloneNode;
Script.prototype.hasAttribute = document.hasAttribute;
+Script.prototype.appendChild = document.appendChild;
+Script.prototype.apch$ = document.apch$;
+Script.prototype.insertBefore = document.insertBefore;
+Script.prototype.hasChildNodes = document.hasChildNodes;
+Script.prototype.removeChild = document.removeChild;
+Script.prototype.replaceChild = document.replaceChild;
+
+Object.defineProperty(Script.prototype, "firstChild", {
+get: function() { return this.childNodes[0]; }
+});
+Object.defineProperty(Script.prototype, "lastChild", {
+get: function() { return this.childNodes[this.childNodes.length-1]; }
+});
+Object.defineProperty(Script.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Script.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
+TextNode.prototype.getAttribute = document.getAttribute;
+TextNode.prototype.setAttribute = document.setAttribute;
+TextNode.prototype.cloneNode = document.cloneNode;
+TextNode.prototype.hasAttribute = document.hasAttribute;
+TextNode.prototype.appendChild = document.appendChild;
+TextNode.prototype.apch$ = document.apch$;
+TextNode.prototype.insertBefore = document.insertBefore;
+TextNode.prototype.hasChildNodes = document.hasChildNodes;
+TextNode.prototype.removeChild = document.removeChild;
+TextNode.prototype.replaceChild = document.replaceChild;
+
+Object.defineProperty(TextNode.prototype, "firstChild", {
+get: function() { return this.childNodes[0]; }
+});
+Object.defineProperty(TextNode.prototype, "lastChild", {
+get: function() { return this.childNodes[this.childNodes.length-1]; }
+});
+Object.defineProperty(TextNode.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(TextNode.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
P.prototype.appendChild = document.appendChild;
P.prototype.apch$ = document.apch$;
P.prototype.getAttribute = document.getAttribute;
P.prototype.setAttribute = document.setAttribute;
+P.prototype.hasAttribute = document.hasAttribute;
+
P.prototype.insertBefore = document.insertBefore;
Object.defineProperty(P.prototype, "firstChild", {
get: function() { return this.childNodes[0]; }
@@ -941,11 +1071,17 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(P.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(P.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(P.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
P.prototype.hasChildNodes = document.hasChildNodes;
P.prototype.removeChild = document.removeChild;
P.prototype.replaceChild = document.replaceChild;
P.prototype.cloneNode = document.cloneNode;
-P.prototype.setAttribute = document.hasAttribute;
Lister.prototype.appendChild = document.appendChild;
Lister.prototype.apch$ = document.apch$;
@@ -958,6 +1094,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Lister.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Lister.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Lister.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Lister.prototype.hasChildNodes = document.hasChildNodes;
Lister.prototype.removeChild = document.removeChild;
Lister.prototype.replaceChild = document.replaceChild;
@@ -975,6 +1118,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Listitem.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Listitem.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Listitem.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Listitem.prototype.hasChildNodes = document.hasChildNodes;
Listitem.prototype.removeChild = document.removeChild;
Listitem.prototype.replaceChild = document.replaceChild;
@@ -992,6 +1142,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Table.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Table.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Table.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Table.prototype.hasChildNodes = document.hasChildNodes;
Table.prototype.removeChild = document.removeChild;
Table.prototype.replaceChild = document.replaceChild;
@@ -1009,6 +1166,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Tbody.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Tbody.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Tbody.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Tbody.prototype.hasChildNodes = document.hasChildNodes;
Tbody.prototype.removeChild = document.removeChild;
Tbody.prototype.replaceChild = document.replaceChild;
@@ -1026,6 +1190,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Trow.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Trow.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Trow.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Trow.prototype.hasChildNodes = document.hasChildNodes;
Trow.prototype.removeChild = document.removeChild;
Trow.prototype.replaceChild = document.replaceChild;
@@ -1043,6 +1214,14 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Cell.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Cell.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Cell.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
+
Cell.prototype.hasChildNodes = document.hasChildNodes;
Cell.prototype.removeChild = document.removeChild;
Cell.prototype.replaceChild = document.replaceChild;
@@ -1060,6 +1239,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Span.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Span.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Span.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Span.prototype.hasChildNodes = document.hasChildNodes;
Span.prototype.removeChild = document.removeChild;
Span.prototype.replaceChild = document.replaceChild;
@@ -1077,6 +1263,13 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Image.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Image.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Image.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Image.prototype.hasChildNodes = document.hasChildNodes;
Image.prototype.removeChild = document.removeChild;
Image.prototype.replaceChild = document.replaceChild;
@@ -1094,14 +1287,19 @@ get: function() { return this.childNodes[0]; }
Object.defineProperty(Frame.prototype, "lastChild", {
get: function() { return this.childNodes[this.childNodes.length-1]; }
});
+Object.defineProperty(Frame.prototype, "nextSibling", {
+get: function() { return get_sibling(this,"next"); }
+});
+Object.defineProperty(Frame.prototype, "previousSibling", {
+get: function() { return get_sibling(this,"previous"); }
+});
+
Frame.prototype.hasChildNodes = document.hasChildNodes;
Frame.prototype.removeChild = document.removeChild;
Frame.prototype.replaceChild = document.replaceChild;
Frame.prototype.cloneNode = document.cloneNode;
Frame.prototype.hasAttribute = document.hasAttribute;
-
-
/* navigator; some parameters are filled in by the buildstartwindow script. */
navigator.appName = "edbrowse";
navigator["appCode Name"] = "edbrowse C/mozjs";
@@ -1371,5 +1569,3 @@ getPropertyValue: function (n)
}
}
}
-
-
--
1.8.3.2
next reply other threads:[~2016-12-29 9:31 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-29 9:31 Kevin Carhart [this message]
2016-12-29 14:06 ` Karl Dahlke
2016-12-29 23:50 ` Kevin Carhart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='20161129013109.kevin@carhart.net ' \
--to=kevin@carhart.net \
--cc=Edbrowse-dev@lists.the-brannons.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).