[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    branches/KDE/4.0/kdelibs/khtml
From:       Harri Porten <porten () kde ! org>
Date:       2008-04-20 22:19:40
Message-ID: 1208729980.834468.3097.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 799256 by porten:

Merged revision 799254:
Merged WebCore's r30088 to implement wholeText property and
replaceWholeText() function from DOM Level 3.

 M  +26 -4     ecma/kjs_dom.cpp  
 M  +3 -1      ecma/kjs_dom.h  
 M  +92 -0     xml/dom_textimpl.cpp  
 M  +4 -0      xml/dom_textimpl.h  


--- branches/KDE/4.0/kdelibs/khtml/ecma/kjs_dom.cpp #799255:799256
@@ -1884,12 +1884,17 @@
 
 // -------------------------------------------------------------------------
 
-const ClassInfo DOMText::info = { "Text",
-				 &DOMCharacterData::info, 0, 0 };
+const ClassInfo DOMText::info = { "Text", &DOMCharacterData::info,
+                                  &DOMTextTable , 0 };
+
 /*
-@begin DOMTextProtoTable 1
-  splitText	DOMText::SplitText	DontDelete|Function 1
+@begin DOMTextTable 2
+  wholeText        DOMText::WholeText        DontDelete|ReadOnly
 @end
+@begin DOMTextProtoTable 2
+  splitText	   DOMText::SplitText	     DontDelete|Function 1
+  replaceWholeText DOMText::ReplaceWholeText DontDelete|Function 1
+@end
 */
 KJS_DEFINE_PROTOTYPE_WITH_PROTOTYPE(DOMTextProto, DOMCharacterDataProto)
 KJS_IMPLEMENT_PROTOFUNC(DOMTextProtoFunc)
@@ -1901,7 +1906,22 @@
   setPrototype(DOMTextProto::self(exec));
 }
 
+bool DOMText::getOwnPropertySlot(ExecState* exec,
+                                 const Identifier& propertyName,
+                                 PropertySlot& slot)
+{
+    return getStaticValueSlot<DOMText, DOMCharacterData>(exec, &DOMTextTable, this, \
propertyName, slot); +}
 
+JSValue* DOMText::getValueProperty(ExecState*, int token) const
+{
+    TextImpl* text = static_cast<TextImpl*>(impl());
+    switch (token) {
+    case WholeText:
+        return jsString(text->wholeText());
+    }
+    return jsNull(); // not reached
+}
 
 JSValue* DOMTextProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const \
List &args)  {
@@ -1911,6 +1931,8 @@
   switch(id) {
     case DOMText::SplitText:
       return getDOMNode(exec,text.splitText(args[0]->toInteger(exec), exception));
+    case DOMText::ReplaceWholeText:
+      return getDOMNode(exec, \
text.replaceWholeText(args[0]->toString(exec).domString(), exception));  default:
       break;
   }
--- branches/KDE/4.0/kdelibs/khtml/ecma/kjs_dom.h #799255:799256
@@ -317,10 +317,12 @@
   class DOMText : public DOMCharacterData {
   public:
     DOMText(ExecState *exec, DOM::TextImpl* t);
+    virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, \
PropertySlot& slot); +    JSValue* getValueProperty(ExecState* exec, int token) \
const;  virtual const ClassInfo* classInfo() const { return &info; }
     static const ClassInfo info;
     DOM::TextImpl* impl() const { return static_cast<DOM::TextImpl*>(m_impl.get()); \
                }
-    enum { SplitText };
+    enum { SplitText, WholeText, ReplaceWholeText, };
   };
 
 } // namespace
--- branches/KDE/4.0/kdelibs/khtml/xml/dom_textimpl.cpp #799255:799256
@@ -31,6 +31,7 @@
 #include <misc/htmlhashes.h>
 #include <rendering/render_text.h>
 #include <rendering/render_flow.h>
+#include <wtf/RefPtr.h>
 
 #include <kdebug.h>
 
@@ -342,6 +343,97 @@
     return newText;
 }
 
+static const TextImpl* earliestLogicallyAdjacentTextNode(const TextImpl* t)
+{
+    const NodeImpl* n = t;
+    while ((n = n->previousSibling())) {
+        unsigned short type = n->nodeType();
+        if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
+            t = static_cast<const TextImpl*>(n);
+            continue;
+        }
+
+        // We would need to visit EntityReference child text nodes if they existed
+        assert(type != Node::ENTITY_REFERENCE_NODE || !n->hasChildNodes());
+        break;
+    }
+    return t;
+}
+
+static const TextImpl* latestLogicallyAdjacentTextNode(const TextImpl* t)
+{
+    const NodeImpl* n = t;
+    while ((n = n->nextSibling())) {
+        unsigned short type = n->nodeType();
+        if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
+            t = static_cast<const TextImpl*>(n);
+            continue;
+        }
+
+        // We would need to visit EntityReference child text nodes if they existed
+        assert(type != Node::ENTITY_REFERENCE_NODE || !n->hasChildNodes());
+        break;
+    }
+    return t;
+}
+
+DOMString TextImpl::wholeText() const
+{
+    const TextImpl* startText = earliestLogicallyAdjacentTextNode(this);
+    const TextImpl* endText = latestLogicallyAdjacentTextNode(this);
+
+    DOMString result;
+    NodeImpl* onePastEndText = endText->nextSibling();
+    for (const NodeImpl* n = startText; n != onePastEndText; n = n->nextSibling()) {
+        if (!n->isTextNode())
+            continue;
+        const TextImpl* t = static_cast<const TextImpl*>(n);
+        const DOMString& data = t->data();
+        result += data;
+    }
+
+    return result;
+}
+
+TextImpl* TextImpl::replaceWholeText(const DOMString& newText, int &ec)
+{
+    // We don't support "read-only" text nodes (no Entity node support)
+    // Thus, we remove all adjacent text nodes, and replace the contents of this \
one. +    assert(!isReadOnly());
+    // This method only raises exceptions when dealing with Entity nodes (which we \
don't support) +
+    // Protect startText and endText against mutation event handlers removing the \
last ref +    RefPtr<TextImpl> startText = \
const_cast<TextImpl*>(earliestLogicallyAdjacentTextNode(this)); +    RefPtr<TextImpl> \
endText = const_cast<TextImpl*>(latestLogicallyAdjacentTextNode(this)); +
+    RefPtr<TextImpl> protectedThis(this); // Mutation event handlers could cause our \
last ref to go away +    NodeImpl* parent = parentNode(); // Protect against mutation \
handlers moving this node during traversal +    int ignored = 0;
+    for (RefPtr<NodeImpl> n = startText; n && n != this && n->isTextNode() && \
n->parentNode() == parent;) { +        RefPtr<NodeImpl> nodeToRemove(n.release());
+        n = nodeToRemove->nextSibling();
+        parent->removeChild(nodeToRemove.get(), ignored);
+    }
+
+    if (this != endText) {
+        NodeImpl* onePastEndText = endText->nextSibling();
+        for (RefPtr<NodeImpl> n = nextSibling(); n && n != onePastEndText && \
n->isTextNode() && n->parentNode() == parent;) { +            RefPtr<NodeImpl> \
nodeToRemove(n.release()); +            n = nodeToRemove->nextSibling();
+            parent->removeChild(nodeToRemove.get(), ignored);
+        }
+    }
+
+    if (newText.isEmpty()) {
+        if (parent && parentNode() == parent)
+            parent->removeChild(this, ignored);
+        return 0;
+    }
+
+    setData(newText, ignored);
+    return protectedThis.release().get();
+}
+
 DOMString TextImpl::nodeName() const
 {
   return "#text";
--- branches/KDE/4.0/kdelibs/khtml/xml/dom_textimpl.h #799255:799256
@@ -117,6 +117,10 @@
 
     TextImpl *splitText ( const unsigned long offset, int &exceptioncode );
 
+    // DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1312295772
+    DOMString wholeText() const;
+    TextImpl* replaceWholeText(const DOMString& newText, int &ec);
+
     // DOM methods overridden from  parent classes
     virtual DOMString nodeName() const;
     virtual unsigned short nodeType() const;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic