From a5b4b90e84adf4ef13ac7a0739b83a46df7dea4e Mon Sep 17 00:00:00 2001 From: ggarand Date: Fri, 5 Sep 2008 00:41:38 +0000 Subject: [PATCH] implementation of ElementTraversal interface http://www.w3.org/TR/ElementTraversal/ derived from patch by Vincent Ricard git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/KDE/kdelibs@857216 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- khtml/dom/dom_element.cpp | 30 +++++++++++++++++++++++++++ khtml/dom/dom_element.h | 47 +++++++++++++++++++++++++++++++++++++++++++ khtml/ecma/kjs_dom.cpp | 22 +++++++++++++++++--- khtml/ecma/kjs_dom.h | 3 ++- khtml/xml/dom_elementimpl.cpp | 46 +++++++++++++++++++++++++++++++++++++++++- khtml/xml/dom_elementimpl.h | 7 +++++++ 6 files changed, 150 insertions(+), 5 deletions(-) diff --git a/khtml/dom/dom_element.cpp b/khtml/dom/dom_element.cpp index 48939c90b..25a66f745 100644 --- a/khtml/dom/dom_element.cpp +++ b/khtml/dom/dom_element.cpp @@ -324,6 +324,36 @@ CSSStyleDeclaration Element::style() return 0; } +Element Element::firstElementChild() const +{ + if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR); + return static_cast(impl)->firstElementChild(); +} + +Element Element::lastElementChild() const +{ + if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR); + return static_cast(impl)->lastElementChild(); +} + +Element Element::previousElementSibling() const +{ + if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR); + return static_cast(impl)->previousElementSibling(); +} + +Element Element::nextElementSibling() const +{ + if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR); + return static_cast(impl)->nextElementSibling(); +} + +unsigned long Element::childElementCount() const +{ + if (!impl) throw DOMException(DOMException::NOT_FOUND_ERR); + return static_cast(impl)->childElementCount(); +} + bool Element::khtmlValidAttrName(const DOMString &name) { // Check if name is valid diff --git a/khtml/dom/dom_element.h b/khtml/dom/dom_element.h index 66c0bcd69..4986c7405 100644 --- a/khtml/dom/dom_element.h +++ b/khtml/dom/dom_element.h @@ -557,6 +557,53 @@ public: * The style attribute */ CSSStyleDeclaration style ( ); + + /** + * Introduced in DOM level 3 + * This method is part of the ElementTraversal interface + * + * The first child node which is of nodeType ELEMENT_NODE. + * + */ + Element firstElementChild ( ) const; + + /** + * Introduced in DOM level 3 + * This method is part of the ElementTraversal interface + * + * @return The last child node of that element which is of nodeType ELEMENT_NODE. + * + */ + Element lastElementChild ( ) const; + + /** + * Introduced in DOM level 3 + * This method is part of the ElementTraversal interface + * + * @return The sibling node of that element which most immediately precedes that element in document order, + * and which is of nodeType ELEMENT_NODE + * + */ + Element previousElementSibling ( ) const; + + /** + * Introduced in DOM level 3 + * This method is part of the ElementTraversal interface + * + * @return The sibling node of that element which most immediately follows that element in document order, + * and which is of nodeType ELEMENT_NODE + * + */ + Element nextElementSibling ( ) const; + + /** + * Introduced in DOM level 3 + * This method is part of the ElementTraversal interface + * + * @return The current number of child nodes of that element which are of nodeType ELEMENT_NODE + * + */ + unsigned long childElementCount ( ) const; /** * not part of the official DOM diff --git a/khtml/ecma/kjs_dom.cpp b/khtml/ecma/kjs_dom.cpp index e7e00e3e0..30fe4a499 100644 --- a/khtml/ecma/kjs_dom.cpp +++ b/khtml/ecma/kjs_dom.cpp @@ -1186,9 +1186,15 @@ IMPLEMENT_PSEUDO_CONSTRUCTOR(ElementPseudoCtor, "Element", DOMElementProto) const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 }; /* Source for DOMElementTable. -@begin DOMElementTable 3 - tagName DOMElement::TagName DontDelete|ReadOnly - style DOMElement::Style DontDelete|ReadOnly +@begin DOMElementTable 7 + tagName DOMElement::TagName DontDelete|ReadOnly + style DOMElement::Style DontDelete|ReadOnly +# DOM 3 - ElementTraversal interface + firstElementChild DOMElement::FirstElementChild DontDelete|ReadOnly + lastElementChild DOMElement::LastElementChild DontDelete|ReadOnly + previousElementSibling DOMElement::PreviousElementSibling DontDelete|ReadOnly + nextElementSibling DOMElement::NextElementSibling DontDelete|ReadOnly + childElementCount DOMElement::ChildElementCount DontDelete|ReadOnly @end */ DOMElement::DOMElement(ExecState *exec, DOM::ElementImpl* e) @@ -1209,6 +1215,16 @@ JSValue* DOMElement::getValueProperty(ExecState *exec, int token) const return jsString(element.tagName()); case Style: return getDOMCSSStyleDeclaration(exec,element.getInlineStyleDecls()); + case FirstElementChild: + return getDOMNode(exec,element.firstElementChild()); + case LastElementChild: + return getDOMNode(exec,element.lastElementChild()); + case PreviousElementSibling: + return getDOMNode(exec,element.previousElementSibling()); + case NextElementSibling: + return getDOMNode(exec,element.nextElementSibling()); + case ChildElementCount: + return jsNumber((unsigned int)element.childElementCount()); default: kDebug(6070) << "WARNING: Unhandled token in DOMElement::getValueProperty : " << token; return jsUndefined(); diff --git a/khtml/ecma/kjs_dom.h b/khtml/ecma/kjs_dom.h index d23b23df5..32bea2dd6 100644 --- a/khtml/ecma/kjs_dom.h +++ b/khtml/ecma/kjs_dom.h @@ -165,7 +165,8 @@ namespace KJS { // no put - all read-only virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; - enum { TagName, Style, + enum { TagName, Style, FirstElementChild, LastElementChild, + PreviousElementSibling, NextElementSibling, ChildElementCount, GetAttribute, SetAttribute, RemoveAttribute, GetAttributeNode, SetAttributeNode, RemoveAttributeNode, GetElementsByTagName, GetAttributeNS, SetAttributeNS, RemoveAttributeNS, GetAttributeNodeNS, diff --git a/khtml/xml/dom_elementimpl.cpp b/khtml/xml/dom_elementimpl.cpp index c3fb2cd27..c5b4f223c 100644 --- a/khtml/xml/dom_elementimpl.cpp +++ b/khtml/xml/dom_elementimpl.cpp @@ -1269,6 +1269,50 @@ RenderStyle* ElementImpl::computedStyle() return rd->m_computedStyle; } +// ElementTraversal API +ElementImpl* ElementImpl::firstElementChild() const +{ + NodeImpl* n = firstChild(); + while (n && !n->isElementNode()) + n = n->nextSibling(); + return static_cast(n); +} + +ElementImpl* ElementImpl::lastElementChild() const +{ + NodeImpl* n = lastChild(); + while (n && !n->isElementNode()) + n = n->previousSibling(); + return static_cast(n); +} + +ElementImpl* ElementImpl::previousElementSibling() const +{ + NodeImpl* n = previousSibling(); + while (n && !n->isElementNode()) + n = n->previousSibling(); + return static_cast(n); +} + +ElementImpl* ElementImpl::nextElementSibling() const +{ + NodeImpl* n = nextSibling(); + while (n && !n->isElementNode()) + n = n->nextSibling(); + return static_cast(n); +} + +unsigned ElementImpl::childElementCount() const +{ + unsigned count = 0; + NodeImpl* n = firstChild(); + while (n) { + count += n->isElementNode(); + n = n->nextSibling(); + } + return count; +} + // ------------------------------------------------------------------------- XMLElementImpl::XMLElementImpl(DocumentImpl *doc, NodeImpl::Id id) @@ -1668,4 +1712,4 @@ void NamedAttrMapImpl::detachFromElement() m_attrCount = 0; } -} \ No newline at end of file +} diff --git a/khtml/xml/dom_elementimpl.h b/khtml/xml/dom_elementimpl.h index 7d00ad290..2f1107e08 100644 --- a/khtml/xml/dom_elementimpl.h +++ b/khtml/xml/dom_elementimpl.h @@ -200,6 +200,13 @@ public: virtual void insertedIntoDocument(); virtual void removedFromDocument(); + // ElementTraversal API + ElementImpl* firstElementChild() const; + ElementImpl* lastElementChild() const; + ElementImpl* previousElementSibling() const; + ElementImpl* nextElementSibling() const; + unsigned childElementCount() const; + // convenience methods which ignore exceptions void setAttribute (NodeImpl::Id id, const DOMString &value); -- 2.11.4.GIT