⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 containernode.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                        // If the child has a parent again, just stop what we're doing, because            // that means someone is doing something with DOM mutation -- can't re-parent            // a child that already has a parent.            if (child->parentNode())                break;        }        // Append child to the end of the list        childCountDelta++;        forbidEventDispatch();        child->setParent(this);        if (m_lastChild) {            child->setPreviousSibling(m_lastChild);            m_lastChild->setNextSibling(child.get());        } else            m_firstChild = child.get();        m_lastChild = child.get();        allowEventDispatch();        // Dispatch the mutation events        dispatchChildInsertionEvents(child.get(), ec);        // Add child to the rendering tree        if (attached() && !child->attached() && child->parent() == this) {            if (shouldLazyAttach)                child->lazyAttach();            else                child->attach();        }                child = nextChild.release();    }    document()->setDocumentChanged(true);    childrenChanged(false, prev.get(), 0, childCountDelta);    dispatchSubtreeModifiedEvent();    return true;}ContainerNode* ContainerNode::addChild(PassRefPtr<Node> newChild){    // This function is only used during parsing.    // It does not send any DOM mutation events.    // Check for consistency with DTD, but only when parsing HTML.    if (document()->isHTMLDocument() && !childAllowed(newChild.get()))        return 0;    forbidEventDispatch();    Node* last = m_lastChild;    appendChildToContainer<Node, ContainerNode>(newChild.get(), this);    allowEventDispatch();    document()->incDOMTreeVersion();    if (inDocument())        newChild->insertedIntoDocument();    childrenChanged(true, last, 0, 1);        if (newChild->isElementNode())        return static_cast<ContainerNode*>(newChild.get());    return this;}void ContainerNode::suspendPostAttachCallbacks(){    if (!s_attachDepth) {        ASSERT(!s_shouldReEnableMemoryCacheCallsAfterAttach);        if (Page* page = document()->page()) {            if (page->areMemoryCacheClientCallsEnabled()) {                page->setMemoryCacheClientCallsEnabled(false);                s_shouldReEnableMemoryCacheCallsAfterAttach = true;            }        }    }    ++s_attachDepth;}void ContainerNode::resumePostAttachCallbacks(){    if (s_attachDepth == 1) {        if (s_postAttachCallbackQueue)            dispatchPostAttachCallbacks();        if (s_shouldReEnableMemoryCacheCallsAfterAttach) {            s_shouldReEnableMemoryCacheCallsAfterAttach = false;            if (Page* page = document()->page())                page->setMemoryCacheClientCallsEnabled(true);        }    }    --s_attachDepth;}void ContainerNode::queuePostAttachCallback(NodeCallback callback, Node* node){    if (!s_postAttachCallbackQueue)        s_postAttachCallbackQueue = new NodeCallbackQueue;        s_postAttachCallbackQueue->append(std::pair<NodeCallback, RefPtr<Node> >(callback, node));}void ContainerNode::dispatchPostAttachCallbacks(){    // We recalculate size() each time through the loop because a callback    // can add more callbacks to the end of the queue.    for (size_t i = 0; i < s_postAttachCallbackQueue->size(); ++i) {        std::pair<NodeCallback, RefPtr<Node> >& pair = (*s_postAttachCallbackQueue)[i];        NodeCallback callback = pair.first;        Node* node = pair.second.get();        callback(node);    }    s_postAttachCallbackQueue->clear();}void ContainerNode::attach(){    suspendPostAttachCallbacks();    for (Node* child = m_firstChild; child; child = child->nextSibling())        child->attach();    Node::attach();    resumePostAttachCallbacks();}void ContainerNode::detach(){    for (Node* child = m_firstChild; child; child = child->nextSibling())        child->detach();    setHasChangedChild(false);    Node::detach();}void ContainerNode::insertedIntoDocument(){    Node::insertedIntoDocument();    insertedIntoTree(false);    for (Node* child = m_firstChild; child; child = child->nextSibling())        child->insertedIntoDocument();}void ContainerNode::removedFromDocument(){    Node::removedFromDocument();    setInDocument(false);    removedFromTree(false);    for (Node* child = m_firstChild; child; child = child->nextSibling())        child->removedFromDocument();}void ContainerNode::insertedIntoTree(bool deep){    if (!deep)        return;    for (Node* child = m_firstChild; child; child = child->nextSibling())        child->insertedIntoTree(true);}void ContainerNode::removedFromTree(bool deep){    if (!deep)        return;    for (Node* child = m_firstChild; child; child = child->nextSibling())        child->removedFromTree(true);}void ContainerNode::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta){    Node::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);    if (!changedByParser && childCountDelta)        document()->nodeChildrenChanged(this);    if (document()->hasNodeListCaches())        notifyNodeListsChildrenChanged();}void ContainerNode::cloneChildNodes(ContainerNode *clone){    // disable the delete button so it's elements are not serialized into the markup    if (document()->frame())        document()->frame()->editor()->deleteButtonController()->disable();    ExceptionCode ec = 0;    for (Node* n = firstChild(); n && !ec; n = n->nextSibling())        clone->appendChild(n->cloneNode(true), ec);    if (document()->frame())        document()->frame()->editor()->deleteButtonController()->enable();}// FIXME: This doesn't work correctly with transforms.bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const{    if (!renderer())        return false;    // What is this code really trying to do?    RenderObject *o = renderer();    RenderObject *p = o;    if (!o->isInline() || o->isReplaced()) {        point = o->localToAbsolute();        return true;    }    // find the next text/image child, to get a position    while (o) {        p = o;        if (o->firstChild())            o = o->firstChild();        else if (o->nextSibling())            o = o->nextSibling();        else {            RenderObject *next = 0;            while (!next && o->parent()) {                o = o->parent();                next = o->nextSibling();            }            o = next;            if (!o)                break;        }        if (!o->isInline() || o->isReplaced()) {            point = o->localToAbsolute();            return true;        }        if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) {                // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor        } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {            point = o->container()->localToAbsolute();            if (o->isText() && toRenderText(o)->firstTextBox()) {                point.move(toRenderText(o)->linesBoundingBox().x(),                           toRenderText(o)->firstTextBox()->root()->topOverflow());            } else if (o->isBox()) {                RenderBox* box = toRenderBox(o);                point.move(box->x(), box->y());            }            return true;        }    }        // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be    // at the end of the document.  Scroll to the bottom. FIXME: who said anything about scrolling?    if (!o && document()->view()) {        point = FloatPoint(0, document()->view()->contentsHeight());        return true;    }    return false;}// FIXME: This doesn't work correctly with transforms.bool ContainerNode::getLowerRightCorner(FloatPoint& point) const{    if (!renderer())        return false;    RenderObject *o = renderer();    if (!o->isInline() || o->isReplaced())    {        RenderBox* box = toRenderBox(o);        point = o->localToAbsolute();        point.move(box->width(), box->height());        return true;    }    // find the last text/image child, to get a position    while (o) {        if (o->lastChild())            o = o->lastChild();        else if (o->previousSibling())            o = o->previousSibling();        else {            RenderObject *prev = 0;            while(!prev) {                o = o->parent();                if (!o)                    return false;                prev = o->previousSibling();            }            o = prev;        }        if (o->isText() || o->isReplaced()) {            point = o->container()->localToAbsolute();            if (o->isText()) {                RenderText* text = toRenderText(o);                IntRect linesBox = text->linesBoundingBox();                point.move(linesBox.x() + linesBox.width(), linesBox.y() + linesBox.height());            } else {                RenderBox* box = toRenderBox(o);                point.move(box->x() + box->width(), box->y() + box->height());            }            return true;        }    }    return true;}IntRect ContainerNode::getRect() const{    FloatPoint  upperLeft, lowerRight;    bool foundUpperLeft = getUpperLeftCorner(upperLeft);    bool foundLowerRight = getLowerRightCorner(lowerRight);        // If we've found one corner, but not the other,    // then we should just return a point at the corner that we did find.    if (foundUpperLeft != foundLowerRight)    {        if (foundUpperLeft)            lowerRight = upperLeft;        else            upperLeft = lowerRight;    }     lowerRight.setX(max(upperLeft.x(), lowerRight.x()));    lowerRight.setY(max(upperLeft.y(), lowerRight.y()));        return enclosingIntRect(FloatRect(upperLeft, lowerRight - upperLeft));}void ContainerNode::setFocus(bool received){    if (focused() == received)        return;    Node::setFocus(received);    // note that we need to recalc the style    setChanged();}void ContainerNode::setActive(bool down, bool pause){    if (down == active()) return;    Node::setActive(down);    // note that we need to recalc the style    // FIXME: Move to Element    if (renderer()) {        bool reactsToPress = renderer()->style()->affectedByActiveRules();        if (reactsToPress)            setChanged();        if (renderer() && renderer()->style()->hasAppearance()) {            if (theme()->stateChanged(renderer(), PressedState))                reactsToPress = true;        }        if (reactsToPress && pause) {            // The delay here is subtle.  It relies on an assumption, namely that the amount of time it takes            // to repaint the "down" state of the control is about the same time as it would take to repaint the            // "up" state.  Once you assume this, you can just delay for 100ms - that time (assuming that after you            // leave this method, it will be about that long before the flush of the up state happens again).#ifdef HAVE_FUNC_USLEEP            double startTime = currentTime();#endif            // Ensure there are no pending changes            Document::updateDocumentsRendering();            // Do an immediate repaint.            if (renderer())                renderer()->repaint(true);                        // FIXME: Find a substitute for usleep for Win32.            // Better yet, come up with a way of doing this that doesn't use this sort of thing at all.            #ifdef HAVE_FUNC_USLEEP            // Now pause for a small amount of time (1/10th of a second from before we repainted in the pressed state)            double remainingTime = 0.1 - (currentTime() - startTime);            if (remainingTime > 0)                usleep(static_cast<useconds_t>(remainingTime * 1000000.0));#endif        }    }}void ContainerNode::setHovered(bool over){    if (over == hovered()) return;    Node::setHovered(over);    // note that we need to recalc the style    // FIXME: Move to Element    if (renderer()) {        if (renderer()->style()->affectedByHoverRules())            setChanged();        if (renderer() && renderer()->style()->hasAppearance())            theme()->stateChanged(renderer(), HoverState);    }}unsigned ContainerNode::childNodeCount() const{    unsigned count = 0;    Node *n;    for (n = firstChild(); n; n = n->nextSibling())        count++;    return count;}Node *ContainerNode::childNode(unsigned index) const{    unsigned i;    Node *n = firstChild();    for (i = 0; n != 0 && i < index; i++)        n = n->nextSibling();    return n;}static void dispatchChildInsertionEvents(Node* child, ExceptionCode& ec){    ASSERT(!eventDispatchForbidden());    RefPtr<Node> c = child;    DocPtr<Document> doc = child->document();    if (c->parentNode() && c->parentNode()->inDocument())        c->insertedIntoDocument();    else        c->insertedIntoTree(true);    if (c->parentNode() && doc->hasListenerType(Document::DOMNODEINSERTED_LISTENER)) {        ec = 0;        c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedEvent, true, false,            c->parentNode(), String(), String(), String(), 0), ec);        if (ec)            return;    }    // dispatch the DOMNodeInsertedIntoDocument event to all descendants    if (c->inDocument() && doc->hasListenerType(Document::DOMNODEINSERTEDINTODOCUMENT_LISTENER))        for (; c; c = c->traverseNextNode(child)) {            ec = 0;            c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeInsertedIntoDocumentEvent, false, false,                0, String(), String(), String(), 0), ec);            if (ec)                return;        }}static void dispatchChildRemovalEvents(Node* child, ExceptionCode& ec){    RefPtr<Node> c = child;    DocPtr<Document> doc = child->document();    // update auxiliary doc info (e.g. iterators) to note that node is being removed    doc->nodeWillBeRemoved(child);    // dispatch pre-removal mutation events    if (c->parentNode() && doc->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {        ec = 0;        c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, false,            c->parentNode(), String(), String(), String(), 0), ec);        if (ec)            return;    }    // dispatch the DOMNodeRemovedFromDocument event to all descendants    if (c->inDocument() && doc->hasListenerType(Document::DOMNODEREMOVEDFROMDOCUMENT_LISTENER))        for (; c; c = c->traverseNextNode(child)) {            ec = 0;            c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedFromDocumentEvent, false, false,                0, String(), String(), String(), 0), ec);            if (ec)                return;        }}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -