2010-10-18 Darin Adler <darin@apple.com>
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Oct 2010 19:52:27 +0000 (19:52 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 18 Oct 2010 19:52:27 +0000 (19:52 +0000)
        Reviewed by Alexey Proskuryakov.

        Remove some functions from class Node and make a few others non-virtual
        https://bugs.webkit.org/show_bug.cgi?id=47735

        Refactoring. No new tests.

        * bindings/js/JSNodeCustom.cpp:
        (WebCore::JSNode::markChildren): Added a FIXME about the use of the virtual
        ownerDocument function.

        * dom/ContainerNode.cpp:
        (WebCore::ContainerNode::removeChildren): Removed the unused return value.

        * dom/ContainerNode.h: Made insertBefore, replaceChild, removeChild, and
        appendChild non-virtual for clarity and performance. Made removeChildren
        non-virtual and removed its return value. Moved the inline Node functions
        that call through to ContainerNode into this file since the old way involved
        an extra level of inline function but otherwise had no advantages.

        * dom/Element.h: Moved isMathMLElement here because there is no call site
        that needs to call it on a Node*. We can always move it back if we need to,
        but it's better to have less in the Node class.

        * dom/Node.cpp:
        (WebCore::Node::insertBefore): Added an isContainerNode check so this can
        be non-virtual. There are very few callers who call this function on Node.
        If we want to optimize them further we can make the isContainerNode check
        inline in the future.
        (WebCore::Node::replaceChild): Ditto.
        (WebCore::Node::removeChild): Ditto.
        (WebCore::Node::appendChild): Ditto.
        (WebCore::Node::remove): Removed unneeded ref/unref because
        ContainerNode::removeChild already does this.
        (WebCore::Node::createRendererIfNeeded): Removed #if around call to
        childShouldCreateRenderer since it's needed even without SVG and XHTMLMP.

        * dom/Node.h: Moved definitions of inline functions that depend on
        ContainerNode to the ContainerNode.h header. They already required inclusion
        of that header, so there is no functional change. Made insertBefore,
        replaceChild, removeChild, and appendChild non-virtual. There are very few
        callers of these functions on this class. Moved isMathMLElement to Element.
        Added a FIXME about the name of eventAncestors. Fixed comment formatting.
        Eliminated unused isEditableBlock function. Moved the body of the
        enclosingInlineElement function to the editing file that was the only
        call site. Removed the previousEditable and nextEditable functions,
        incorporating their bodies into the one place they were called.
        Took the childShouldCreateRenderer function out of #if since it's
        now used by the implementation of the <noscript> element.

        * dom/Position.cpp:
        (WebCore::nextRenderedEditable): Rewrote the function to use nextLeafNode
        instead of nextEditable.
        (WebCore::previousRenderedEditable): Rewrote the function to use
        previousLeafNode instead of previousEditable.

        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::enclosingInline): Moved function here from the Node class. Also
        fixed an incorrect cast this function did, which assumed the function
        result was always an element, which the function does not guarantee.
        (WebCore::ReplaceSelectionCommand::doApply): Call the function above.

        * history/HistoryItem.cpp: Added include of MathExtras.h.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69987 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/bindings/js/JSNodeCustom.cpp
WebCore/dom/ContainerNode.cpp
WebCore/dom/ContainerNode.h
WebCore/dom/Element.h
WebCore/dom/Node.cpp
WebCore/dom/Node.h
WebCore/dom/Position.cpp
WebCore/editing/ReplaceSelectionCommand.cpp
WebCore/history/HistoryItem.cpp

index f3b8cc1..193f18d 100644 (file)
@@ -1,3 +1,69 @@
+2010-10-18  Darin Adler  <darin@apple.com>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Remove some functions from class Node and make a few others non-virtual
+        https://bugs.webkit.org/show_bug.cgi?id=47735
+
+        Refactoring. No new tests.
+
+        * bindings/js/JSNodeCustom.cpp:
+        (WebCore::JSNode::markChildren): Added a FIXME about the use of the virtual
+        ownerDocument function.
+
+        * dom/ContainerNode.cpp:
+        (WebCore::ContainerNode::removeChildren): Removed the unused return value.
+
+        * dom/ContainerNode.h: Made insertBefore, replaceChild, removeChild, and
+        appendChild non-virtual for clarity and performance. Made removeChildren
+        non-virtual and removed its return value. Moved the inline Node functions
+        that call through to ContainerNode into this file since the old way involved
+        an extra level of inline function but otherwise had no advantages.
+
+        * dom/Element.h: Moved isMathMLElement here because there is no call site
+        that needs to call it on a Node*. We can always move it back if we need to,
+        but it's better to have less in the Node class.
+
+        * dom/Node.cpp:
+        (WebCore::Node::insertBefore): Added an isContainerNode check so this can
+        be non-virtual. There are very few callers who call this function on Node.
+        If we want to optimize them further we can make the isContainerNode check
+        inline in the future.
+        (WebCore::Node::replaceChild): Ditto.
+        (WebCore::Node::removeChild): Ditto.
+        (WebCore::Node::appendChild): Ditto.
+        (WebCore::Node::remove): Removed unneeded ref/unref because
+        ContainerNode::removeChild already does this.
+        (WebCore::Node::createRendererIfNeeded): Removed #if around call to
+        childShouldCreateRenderer since it's needed even without SVG and XHTMLMP.
+
+        * dom/Node.h: Moved definitions of inline functions that depend on
+        ContainerNode to the ContainerNode.h header. They already required inclusion
+        of that header, so there is no functional change. Made insertBefore,
+        replaceChild, removeChild, and appendChild non-virtual. There are very few
+        callers of these functions on this class. Moved isMathMLElement to Element.
+        Added a FIXME about the name of eventAncestors. Fixed comment formatting.
+        Eliminated unused isEditableBlock function. Moved the body of the
+        enclosingInlineElement function to the editing file that was the only
+        call site. Removed the previousEditable and nextEditable functions,
+        incorporating their bodies into the one place they were called.
+        Took the childShouldCreateRenderer function out of #if since it's
+        now used by the implementation of the <noscript> element.
+
+        * dom/Position.cpp:
+        (WebCore::nextRenderedEditable): Rewrote the function to use nextLeafNode
+        instead of nextEditable.
+        (WebCore::previousRenderedEditable): Rewrote the function to use
+        previousLeafNode instead of previousEditable.
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::enclosingInline): Moved function here from the Node class. Also
+        fixed an incorrect cast this function did, which assumed the function
+        result was always an element, which the function does not guarantee.
+        (WebCore::ReplaceSelectionCommand::doApply): Call the function above.
+
+        * history/HistoryItem.cpp: Added include of MathExtras.h.
+
 2010-10-18  Yongjun Zhang  <yongjun_zhang@apple.com>
 
         Reviewed by Darin Adler.
index b7c50f2..a0963b8 100644 (file)
@@ -127,6 +127,8 @@ void JSNode::markChildren(MarkStack& markStack)
     // the document, we need to mark the document, but we don't need to explicitly
     // mark any other nodes.
     if (node->inDocument()) {
+        // FIXME: Do we really want to call a virtual function, ownerDocument here,
+        // when the non-virtual inline function, document, is so much faster?!
         if (Document* doc = node->ownerDocument())
             markDOMNodeWrapper(markStack, doc, doc);
         return;
index 092ce74..fc33519 100644 (file)
@@ -489,10 +489,10 @@ void ContainerNode::parserRemoveChild(Node* oldChild)
 
 // this differs from other remove functions because it forcibly removes all the children,
 // regardless of read-only status or event exceptions, e.g.
-bool ContainerNode::removeChildren()
+void ContainerNode::removeChildren()
 {
     if (!m_firstChild)
-        return false;
+        return;
 
     // The container node can be removed from event handlers.
     RefPtr<ContainerNode> protect(this);
@@ -541,8 +541,6 @@ bool ContainerNode::removeChildren()
         // document. There is no explanation for this discrepancy between removeChild()
         // and its optimized version removeChildren().
     }
-
-    return true;
 }
 
 bool ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
index c8583d2..76eb1bd 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 #define ContainerNode_h
 
 #include "Node.h"
-#include "FloatPoint.h"
 
 namespace WebCore {
+
+class FloatPoint;
     
 typedef void (*NodeCallback)(Node*);
 
@@ -43,10 +44,10 @@ public:
     Node* firstChild() const { return m_firstChild; }
     Node* lastChild() const { return m_lastChild; }
 
-    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
-    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
-    virtual bool removeChild(Node* child, ExceptionCode&);
-    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
+    bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+    bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
+    bool removeChild(Node* child, ExceptionCode&);
+    bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
 
     // These methods are only used during parsing.
     // They don't send DOM mutation events or handle reparenting.
@@ -72,8 +73,9 @@ public:
     virtual void removedFromTree(bool deep);
     virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
 
-    virtual bool removeChildren();
-
+    // FIXME: It's not good to have two functions with such similar names, especially public functions.
+    // How do removeChildren and removeAllChildren differ?
+    void removeChildren();
     void removeAllChildren();
     void takeAllChildrenFrom(ContainerNode*);
 
@@ -140,23 +142,31 @@ inline ContainerNode::ContainerNode(Document* document, ConstructionType type)
 {
 }
 
-inline unsigned Node::containerChildNodeCount() const
+inline unsigned Node::childNodeCount() const
 {
+    if (!isContainerNode())
+        return 0;
     return toContainerNode(this)->childNodeCount();
 }
 
-inline Node* Node::containerChildNode(unsigned index) const
+inline Node* Node::childNode(unsigned index) const
 {
+    if (!isContainerNode())
+        return 0;
     return toContainerNode(this)->childNode(index);
 }
 
-inline Node* Node::containerFirstChild() const
+inline Node* Node::firstChild() const
 {
+    if (!isContainerNode())
+        return 0;
     return toContainerNode(this)->firstChild();
 }
 
-inline Node* Node::containerLastChild() const
+inline Node* Node::lastChild() const
 {
+    if (!isContainerNode())
+        return 0;
     return toContainerNode(this)->lastChild();
 }
 
index 6362b02..b890ecd 100644 (file)
@@ -276,6 +276,12 @@ public:
     DOMStringMap* dataset();
     DOMStringMap* optionalDataset() const;
 
+#if ENABLE(MATHML)
+    virtual bool isMathMLElement() const { return false; }
+#else
+    static bool isMathMLElement() { return false; }
+#endif
+
     virtual bool isFormControlElement() const { return false; }
     virtual bool isEnabledFormControl() const { return true; }
     virtual bool isReadOnlyFormControl() const { return false; }
index ac0afc9..0907820 100644 (file)
@@ -530,38 +530,48 @@ Node* Node::firstDescendant() const
     return n;
 }
 
-bool Node::insertBefore(PassRefPtr<Node>, Node*, ExceptionCode& ec, bool)
+bool Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    ec = HIERARCHY_REQUEST_ERR;
-    return false;
+    if (!isContainerNode()) {
+        ec = HIERARCHY_REQUEST_ERR;
+        return false;
+    }
+    return toContainerNode(this)->insertBefore(newChild, refChild, ec, shouldLazyAttach);
 }
 
-bool Node::replaceChild(PassRefPtr<Node>, Node*, ExceptionCode& ec, bool)
+bool Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    ec = HIERARCHY_REQUEST_ERR;
-    return false;
+    if (!isContainerNode()) {
+        ec = HIERARCHY_REQUEST_ERR;
+        return false;
+    }
+    return toContainerNode(this)->replaceChild(newChild, oldChild, ec, shouldLazyAttach);
 }
 
-bool Node::removeChild(Node*, ExceptionCode& ec)
+bool Node::removeChild(Node* oldChild, ExceptionCode& ec)
 {
-    ec = NOT_FOUND_ERR;
-    return false;
+    if (!isContainerNode()) {
+        ec = NOT_FOUND_ERR;
+        return false;
+    }
+    return toContainerNode(this)->removeChild(oldChild, ec);
 }
 
-bool Node::appendChild(PassRefPtr<Node>, ExceptionCode& ec, bool)
+bool Node::appendChild(PassRefPtr<Node> newChild, ExceptionCode& ec, bool shouldLazyAttach)
 {
-    ec = HIERARCHY_REQUEST_ERR;
-    return false;
+    if (!isContainerNode()) {
+        ec = HIERARCHY_REQUEST_ERR;
+        return false;
+    }
+    return toContainerNode(this)->appendChild(newChild, ec, shouldLazyAttach);
 }
 
 void Node::remove(ExceptionCode& ec)
 {
-    ref();
-    if (Node *p = parentNode())
-        p->removeChild(this, ec);
+    if (ContainerNode* parent = parentNode())
+        parent->removeChild(this, ec);
     else
         ec = HIERARCHY_REQUEST_ERR;
-    deref();
 }
 
 void Node::normalize()
@@ -1228,28 +1238,6 @@ void Node::detach()
     clearFlag(InDetachFlag);
 }
 
-Node *Node::previousEditable() const
-{
-    Node *node = previousLeafNode();
-    while (node) {
-        if (node->isContentEditable())
-            return node;
-        node = node->previousLeafNode();
-    }
-    return 0;
-}
-
-Node *Node::nextEditable() const
-{
-    Node *node = nextLeafNode();
-    while (node) {
-        if (node->isContentEditable())
-            return node;
-        node = node->nextLeafNode();
-    }
-    return 0;
-}
-
 RenderObject * Node::previousRenderer()
 {
     for (Node *n = previousSibling(); n; n = n->previousSibling()) {
@@ -1337,11 +1325,7 @@ void Node::createRendererIfNeeded()
     ASSERT(parent);
     
     RenderObject* parentRenderer = parent->renderer();
-    if (parentRenderer && parentRenderer->canHaveChildren()
-#if ENABLE(SVG) || ENABLE(XHTMLMP)
-        && parent->childShouldCreateRenderer(this)
-#endif
-        ) {
+    if (parentRenderer && parentRenderer->canHaveChildren() && parent->childShouldCreateRenderer(this)) {
         RefPtr<RenderStyle> style = styleForRenderer();
         if (rendererIsNeeded(style.get())) {
             if (RenderObject* r = createRenderer(document()->renderArena(), style.get())) {
@@ -1466,11 +1450,6 @@ bool Node::isBlockFlowOrBlockTable() const
     return renderer() && (renderer()->isBlockFlow() || (renderer()->isTable() && !renderer()->isInline()));
 }
 
-bool Node::isEditableBlock() const
-{
-    return isContentEditable() && isBlockFlow();
-}
-
 Element *Node::enclosingBlockFlowElement() const
 {
     Node *n = const_cast<Node *>(this);
@@ -1487,26 +1466,6 @@ Element *Node::enclosingBlockFlowElement() const
     return 0;
 }
 
-Element *Node::enclosingInlineElement() const
-{
-    Node *n = const_cast<Node *>(this);
-    Node *p;
-
-    while (1) {
-        p = n->parentNode();
-        if (!p || p->isBlockFlow() || p->hasTagName(bodyTag))
-            return static_cast<Element *>(n);
-        // Also stop if any previous sibling is a block
-        for (Node *sibling = n->previousSibling(); sibling; sibling = sibling->previousSibling()) {
-            if (sibling->isBlockFlow())
-                return static_cast<Element *>(n);
-        }
-        n = p;
-    }
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
 Element* Node::rootEditableElement() const
 {
     Element* result = 0;
index 33a222b..20e7b50 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  *
  * This library is free software; you can redistribute it and/or
@@ -35,8 +35,8 @@
 
 #if USE(JSC)
 namespace JSC {
-class JSGlobalData;
-class MarkStack;
+    class JSGlobalData;
+    class MarkStack;
 }
 #endif
 
@@ -137,8 +137,8 @@ public:
     Node* previousSibling() const { return m_previous; }
     Node* nextSibling() const { return m_next; }
     PassRefPtr<NodeList> childNodes();
-    Node* firstChild() const { return isContainerNode() ? containerFirstChild() : 0; }
-    Node* lastChild() const { return isContainerNode() ? containerLastChild() : 0; }
+    Node* firstChild() const;
+    Node* lastChild() const;
     bool hasAttributes() const;
     NamedNodeMap* attributes() const;
 
@@ -149,10 +149,10 @@ public:
     // These should all actually return a node, but this is only important for language bindings,
     // which will already know and hold a ref on the right node to return. Returning bool allows
     // these methods to be more efficient since they don't need to return a ref
-    virtual bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
-    virtual bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
-    virtual bool removeChild(Node* child, ExceptionCode&);
-    virtual bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
+    bool insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionCode&, bool shouldLazyAttach = false);
+    bool replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionCode&, bool shouldLazyAttach = false);
+    bool removeChild(Node* child, ExceptionCode&);
+    bool appendChild(PassRefPtr<Node> newChild, ExceptionCode&, bool shouldLazyAttach = false);
 
     void remove(ExceptionCode&);
     bool hasChildNodes() const { return firstChild(); }
@@ -192,13 +192,6 @@ public:
     static bool isWMLElement() { return false; }
 #endif
 
-#if ENABLE(MATHML)
-    virtual bool isMathMLElement() const { return false; }
-#else
-    static bool isMathMLElement() { return false; }
-#endif
-
-
     virtual bool isMediaControlElement() const { return false; }
     bool isStyledElement() const { return getFlag(IsStyledElementFlag); }
     virtual bool isFrameOwnerElement() const { return false; }
@@ -218,7 +211,8 @@ public:
     // Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation.
     Node* enclosingLinkEventParentOrSelf();
 
-    // Node ancestors when concerned about event flow
+    // Node ancestors when concerned about event flow.
+    // FIXME: Should be named getEventAncestors.
     void eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors);
 
     bool isBlockFlow() const;
@@ -232,28 +226,21 @@ public:
     Node* previousNodeConsideringAtomicNodes() const;
     Node* nextNodeConsideringAtomicNodes() const;
     
-    /** (Not part of the official DOM)
-     * Returns the next leaf node.
-     *
-     * Using this function delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
-     * @return next leaf node or 0 if there are no more.
-     */
+    // Returns the next leaf node or 0 if there are no more.
+    // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
+    // Uses an editing-specific concept of what a leaf node is, and should probably be moved
+    // out of the Node class into an editing-specific source file.
     Node* nextLeafNode() const;
 
-    /** (Not part of the official DOM)
-     * Returns the previous leaf node.
-     *
-     * Using this function delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
-     * @return previous leaf node or 0 if there are no more.
-     */
+    // Returns the previous leaf node or 0 if there are no more.
+    // Delivers leaf nodes as if the whole DOM tree were a linear chain of its leaf nodes.
+    // Uses an editing-specific concept of what a leaf node is, and should probably be moved
+    // out of the Node class into an editing-specific source file.
     Node* previousLeafNode() const;
 
-    bool isEditableBlock() const;
-    
-    // enclosingBlockFlowElement() is deprecated.  Use enclosingBlock instead.
+    // enclosingBlockFlowElement() is deprecated. Use enclosingBlock instead.
     Element* enclosingBlockFlowElement() const;
     
-    Element* enclosingInlineElement() const;
     Element* rootEditableElement() const;
     
     bool inSameContainingBlockFlowElement(Node*);
@@ -270,9 +257,7 @@ public:
     virtual void finishParsingChildren() { }
     virtual void beginParsingChildren() { }
 
-    // Called by the frame right before dispatching an unloadEvent. [Radar 4532113]
-    // This is needed for HTMLInputElements to tell the frame that it is done editing 
-    // (sends textFieldDidEndEditing notification)
+    // Called on the focused node right before dispatching an unload event.
     virtual void aboutToUnload() { }
 
     // For <link> and <style> elements.
@@ -315,14 +300,14 @@ public:
     };
     void lazyAttach(ShouldSetAttached = SetAttached);
 
-    virtual void setFocus(bool = true);
+    virtual void setFocus(bool = true);
     virtual void setActive(bool f = true, bool /*pause*/ = false) { setFlag(f, IsActiveFlag); }
     virtual void setHovered(bool f = true) { setFlag(f, IsHoveredFlag); }
 
     virtual short tabIndex() const;
 
     // Whether this kind of node can receive focus by default. Most nodes are
-    // not focusable but some elements, such as form controls and links are.
+    // not focusable but some elements, such as form controls and links, are.
     virtual bool supportsFocus() const;
     // Whether the node can actually be focused.
     virtual bool isFocusable() const;
@@ -371,53 +356,27 @@ public:
 
     bool isReadOnlyNode() const { return nodeType() == ENTITY_REFERENCE_NODE; }
     virtual bool childTypeAllowed(NodeType) { return false; }
-    unsigned childNodeCount() const { return isContainerNode() ? containerChildNodeCount() : 0; }
-    Node* childNode(unsigned index) const { return isContainerNode() ? containerChildNode(index) : 0; }
-
-    /**
-     * Does a pre-order traversal of the tree to find the node next node after this one. This uses the same order that
-     * the tags appear in the source file.
-     *
-     * @param stayWithin If not null, the traversal will stop once the specified node is reached. This can be used to
-     * restrict traversal to a particular sub-tree.
-     *
-     * @return The next node, in document order
-     *
-     * see @ref traversePreviousNode()
-     */
+    unsigned childNodeCount() const;
+    Node* childNode(unsigned index) const;
+
+    // Does a pre-order traversal of the tree to find the node next node after this one.
+    // This uses the same order that tags appear in the source file. If the stayWithin
+    // argument is non-null, the traversal will stop once the specified node is reached.
+    // This can be used to restrict traversal to a particular sub-tree.
     Node* traverseNextNode(const Node* stayWithin = 0) const;
     
     // Like traverseNextNode, but skips children and starts with the next sibling.
     Node* traverseNextSibling(const Node* stayWithin = 0) const;
 
-    /**
-     * Does a reverse pre-order traversal to find the node that comes before the current one in document order
-     *
-     * see @ref traverseNextNode()
-     */
-    Node* traversePreviousNode(const Node * stayWithin = 0) const;
+    // Does a reverse pre-order traversal to find the node that comes before the current one in document order
+    Node* traversePreviousNode(const Node* stayWithin = 0) const;
 
     // Like traverseNextNode, but visits parents after their children.
     Node* traverseNextNodePostOrder() const;
 
     // Like traversePreviousNode, but visits parents before their children.
-    Node* traversePreviousNodePostOrder(const Node *stayWithin = 0) const;
-    Node* traversePreviousSiblingPostOrder(const Node *stayWithin = 0) const;
-
-    /**
-     * Finds previous or next editable leaf node.
-     */
-    Node* previousEditable() const;
-    Node* nextEditable() const;
-
-    RenderObject* renderer() const { return m_renderer; }
-    RenderObject* nextRenderer();
-    RenderObject* previousRenderer();
-    void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
-    
-    // Use these two methods with caution.
-    RenderBox* renderBox() const;
-    RenderBoxModelObject* renderBoxModelObject() const;
+    Node* traversePreviousNodePostOrder(const Node* stayWithin = 0) const;
+    Node* traversePreviousSiblingPostOrder(const Node* stayWithin = 0) const;
 
     void checkSetPrefix(const AtomicString& prefix, ExceptionCode&);
     bool isDescendantOf(const Node*) const;
@@ -444,32 +403,35 @@ public:
     virtual bool canStartSelection() const;
 
     // Getting points into and out of screen space
-    FloatPoint convertToPage(const FloatPoint& p) const;
-    FloatPoint convertFromPage(const FloatPoint& p) const;
+    FloatPoint convertToPage(const FloatPoint&) const;
+    FloatPoint convertFromPage(const FloatPoint&) const;
 
     // -----------------------------------------------------------------------------
     // Integration with rendering tree
 
-    /**
-     * Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
-     * appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
-     * makes the node visible in the FrameView.
-     */
+    RenderObject* renderer() const { return m_renderer; }
+    RenderObject* nextRenderer();
+    RenderObject* previousRenderer();
+    void setRenderer(RenderObject* renderer) { m_renderer = renderer; }
+    
+    // Use these two methods with caution.
+    RenderBox* renderBox() const;
+    RenderBoxModelObject* renderBoxModelObject() const;
+
+    // Attaches this node to the rendering tree. This calculates the style to be applied to the node and creates an
+    // appropriate RenderObject which will be inserted into the tree (except when the style has display: none). This
+    // makes the node visible in the FrameView.
     virtual void attach();
 
-    /**
-     * Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
-     * the node's rendering object from the rendering tree and delete it.
-     */
+    // Detaches the node from the rendering tree, making it invisible in the rendered view. This method will remove
+    // the node's rendering object from the rendering tree and delete it.
     virtual void detach();
 
     virtual void willRemove();
     void createRendererIfNeeded();
     PassRefPtr<RenderStyle> styleForRenderer();
     virtual bool rendererIsNeeded(RenderStyle*);
-#if ENABLE(SVG) || ENABLE(XHTMLMP)
     virtual bool childShouldCreateRenderer(Node*) const { return true; }
-#endif
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
     
     // Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
@@ -481,24 +443,20 @@ public:
     // -----------------------------------------------------------------------------
     // Notification of document structure changes
 
-    /**
-     * Notifies the node that it has been inserted into the document. This is called during document parsing, and also
-     * when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
-     * happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
-     * the node. The call happens _after_ the node has been added to the tree.
-     *
-     * This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
-     * dispatching.
-     */
+    // Notifies the node that it has been inserted into the document. This is called during document parsing, and also
+    // when a node is added through the DOM methods insertBefore(), appendChild() or replaceChild(). Note that this only
+    // happens when the node becomes part of the document tree, i.e. only when the document is actually an ancestor of
+    // the node. The call happens _after_ the node has been added to the tree.
+    //
+    // This is similar to the DOMNodeInsertedIntoDocument DOM event, but does not require the overhead of event
+    // dispatching.
     virtual void insertedIntoDocument();
 
-    /**
-     * Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
-     * node.
-     *
-     * This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
-     * dispatching, and is called _after_ the node is removed from the tree.
-     */
+    // Notifies the node that it is no longer part of the document tree, i.e. when the document is no longer an ancestor
+    // node.
+    //
+    // This is similar to the DOMNodeRemovedFromDocument DOM event, but does not require the overhead of event
+    // dispatching, and is called _after_ the node is removed from the tree.
     virtual void removedFromDocument();
 
     // These functions are called whenever you are connected or disconnected from a tree.  That tree may be the main
@@ -507,10 +465,8 @@ public:
     virtual void insertedIntoTree(bool /*deep*/) { }
     virtual void removedFromTree(bool /*deep*/) { }
 
-    /**
-     * Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
-     * node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
-     */
+    // Notifies the node that it's list of children have changed (either by adding or removing child nodes), or a child
+    // node that is of the type CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
     virtual void childrenChanged(bool /*changedByParser*/ = false, Node* /*beforeChange*/ = 0, Node* /*afterChange*/ = 0, int /*childCountDelta*/ = 0) { }
 
 #ifndef NDEBUG
@@ -565,8 +521,7 @@ public:
     void dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent);
     bool dispatchKeyEvent(const PlatformKeyboardEvent&);
     void dispatchWheelEvent(PlatformWheelEvent&);
-    bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
-        int clickCount = 0, Node* relatedTarget = 0);
+    bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
     bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
         int pageX, int pageY, int screenX, int screenY,
         bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
@@ -577,15 +532,11 @@ public:
     virtual void dispatchFocusEvent();
     virtual void dispatchBlurEvent();
 
-    /**
-     * Perform the default action for an event e.g. submitting a form
-     */
+    // Perform the default action for an event.
     virtual void defaultEventHandler(Event*);
 
-    /**
-     * Used for disabled form elements; if true, prevents mouse events from being dispatched
-     * to event listeners, and prevents DOMActivate events from being sent at all.
-     */
+    // Used for disabled form elements; if true, prevents mouse events from being dispatched
+    // to event listeners, and prevents DOMActivate events from being sent at all.
     virtual bool disabled() const;
 
     using TreeShared<ContainerNode>::ref;
@@ -690,10 +641,6 @@ private:
     virtual void derefEventTarget();
 
     virtual NodeRareData* createRareData();
-    Node* containerChildNode(unsigned index) const;
-    unsigned containerChildNodeCount() const;
-    Node* containerFirstChild() const;
-    Node* containerLastChild() const;
     bool rareDataFocused() const;
 
     virtual RenderStyle* nonRendererRenderStyle() const;
@@ -713,7 +660,7 @@ private:
     RenderObject* m_renderer;
     mutable uint32_t m_nodeFlags;
 
- protected:
+protected:
     bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
     void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
     void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
index f1834d8..8c03224 100644 (file)
@@ -45,10 +45,9 @@ using namespace HTMLNames;
 
 static Node* nextRenderedEditable(Node* node)
 {
-    while (1) {
-        node = node->nextEditable();
-        if (!node)
-            return 0;
+    while ((node = node->nextLeafNode())) {
+        if (!node->isContentEditable())
+            continue;
         RenderObject* renderer = node->renderer();
         if (!renderer)
             continue;
@@ -60,10 +59,9 @@ static Node* nextRenderedEditable(Node* node)
 
 static Node* previousRenderedEditable(Node* node)
 {
-    while (1) {
-        node = node->previousEditable();
-        if (!node)
-            return 0;
+    while ((node = node->previousLeafNode())) {
+        if (!node->isContentEditable())
+            continue;
         RenderObject* renderer = node->renderer();
         if (!renderer)
             continue;
index 51234e3..056ab70 100644 (file)
@@ -779,6 +779,21 @@ void ReplaceSelectionCommand::mergeEndIfNeeded()
     }
 }
 
+static Node* enclosingInline(Node* node)
+{
+    while (ContainerNode* parent = node->parentNode()) {
+        if (parent->isBlockFlow() || parent->hasTagName(bodyTag))
+            return node;
+        // Stop if any previous sibling is a block.
+        for (Node* sibling = node->previousSibling(); sibling; sibling = sibling->previousSibling()) {
+            if (sibling->isBlockFlow())
+                return node;
+        }
+        node = parent;
+    }
+    return node;
+}
+
 void ReplaceSelectionCommand::doApply()
 {
     VisibleSelection selection = endingSelection();
@@ -998,7 +1013,7 @@ void ReplaceSelectionCommand::doApply()
         // but our destination node is inside an inline that is the last in the block.
         // We insert a placeholder before the newly inserted content to avoid being merged into the inline.
         Node* destinationNode = destination.deepEquivalent().node();
-        if (m_shouldMergeEnd && destinationNode != destinationNode->enclosingInlineElement() && destinationNode->enclosingInlineElement()->nextSibling())
+        if (m_shouldMergeEnd && destinationNode != enclosingInline(destinationNode) && enclosingInline(destinationNode)->nextSibling())
             insertNodeBefore(createBreakElement(document()), refNode.get());
         
         // Merging the the first paragraph of inserted content with the content that came
index 2d6ca58..34b54a1 100644 (file)
@@ -32,8 +32,9 @@
 #include "PageCache.h"
 #include "ResourceRequest.h"
 #include <stdio.h>
-#include <wtf/text/CString.h>
 #include <wtf/CurrentTime.h>
+#include <wtf/MathExtras.h>
+#include <wtf/text/CString.h>
 
 namespace WebCore {