From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out.smtp-auth.no-ip.com (out.smtp-auth.no-ip.com [8.23.224.60]) by hurricane.the-brannons.com (Postfix) with ESMTPS id 71C0379DCD for ; Thu, 29 Dec 2016 01:31:10 -0800 (PST) X-No-IP: carhart.net@noip-smtp X-Report-Spam-To: abuse@no-ip.com Received: from carhart.net (unknown [99.52.200.227]) (Authenticated sender: carhart.net@noip-smtp) by smtp-auth.no-ip.com (Postfix) with ESMTPA id 896D92C8 for ; Thu, 29 Dec 2016 01:31:10 -0800 (PST) Received: from kevc (carhart.net [192.168.1.179]) by carhart.net (8.13.8/8.13.8) with ESMTP id uBT9V9vw005356; Thu, 29 Dec 2016 01:31:09 -0800 To: Edbrowse-dev@lists.the-brannons.com From: Kevin Carhart Reply-to: Kevin Carhart User-Agent: edbrowse/3.5.4.2 Date: Thu, 29 Dec 2016 01:31:09 -0800 Message-ID: <20161129013109.kevin@carhart.net > Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 7bit Subject: [Edbrowse-dev] [PATCH] nextSibling/previousSibling rev 2 X-BeenThere: edbrowse-dev@lists.the-brannons.com X-Mailman-Version: 2.1.23 Precedence: list List-Id: Edbrowse Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 29 Dec 2016 09:31:10 -0000 >>From 29704df5cdedb9aaea60a45b8eab96ecf9f88873 Mon Sep 17 00:00:00 2001 From: Kevin Carhart 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); +} +} + 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 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