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

📄 renderblock.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (childrenInline() && !newChild->isInline() && !newChild->isFloatingOrPositioned()) {        // This is a block with inline content. Wrap the inline content in anonymous blocks.        makeChildrenNonInline(beforeChild);        madeBoxesNonInline = true;        if (beforeChild && beforeChild->parent() != this) {            beforeChild = beforeChild->parent();            ASSERT(beforeChild->isAnonymousBlock());            ASSERT(beforeChild->parent() == this);        }    } else if (!childrenInline() && (newChild->isFloatingOrPositioned() || newChild->isInline())) {        // If we're inserting an inline child but all of our children are blocks, then we have to make sure        // it is put into an anomyous block box. We try to use an existing anonymous box if possible, otherwise        // a new one is created and inserted into our list of children in the appropriate position.        RenderObject* afterChild = beforeChild ? beforeChild->previousSibling() : lastChild();        if (afterChild && afterChild->isAnonymousBlock()) {            afterChild->addChild(newChild);            return;        }        if (newChild->isInline()) {            // No suitable existing anonymous box - create a new one.            RenderBlock* newBox = createAnonymousBlock();            RenderBox::addChild(newBox, beforeChild);            newBox->addChild(newChild);            return;        }    }    RenderBox::addChild(newChild, beforeChild);    if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock())        toRenderBlock(parent())->removeLeftoverAnonymousBlock(this);    // this object may be dead here}static void getInlineRun(RenderObject* start, RenderObject* boundary,                         RenderObject*& inlineRunStart,                         RenderObject*& inlineRunEnd){    // Beginning at |start| we find the largest contiguous run of inlines that    // we can.  We denote the run with start and end points, |inlineRunStart|    // and |inlineRunEnd|.  Note that these two values may be the same if    // we encounter only one inline.    //    // We skip any non-inlines we encounter as long as we haven't found any    // inlines yet.    //    // |boundary| indicates a non-inclusive boundary point.  Regardless of whether |boundary|    // is inline or not, we will not include it in a run with inlines before it.  It's as though we encountered    // a non-inline.        // Start by skipping as many non-inlines as we can.    RenderObject * curr = start;    bool sawInline;    do {        while (curr && !(curr->isInline() || curr->isFloatingOrPositioned()))            curr = curr->nextSibling();                inlineRunStart = inlineRunEnd = curr;                if (!curr)            return; // No more inline children to be found.                sawInline = curr->isInline();                curr = curr->nextSibling();        while (curr && (curr->isInline() || curr->isFloatingOrPositioned()) && (curr != boundary)) {            inlineRunEnd = curr;            if (curr->isInline())                sawInline = true;            curr = curr->nextSibling();        }    } while (!sawInline);}void RenderBlock::deleteLineBoxTree(){    m_lineBoxes.deleteLineBoxTree(renderArena());}RootInlineBox* RenderBlock::createRootBox(){    return new (renderArena()) RootInlineBox(this);}RootInlineBox* RenderBlock::createRootInlineBox(){    RootInlineBox* rootBox = createRootBox();    m_lineBoxes.appendLineBox(rootBox);    return rootBox;}void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint){        // makeChildrenNonInline takes a block whose children are *all* inline and it    // makes sure that inline children are coalesced under anonymous    // blocks.  If |insertionPoint| is defined, then it represents the insertion point for    // the new block child that is causing us to have to wrap all the inlines.  This    // means that we cannot coalesce inlines before |insertionPoint| with inlines following    // |insertionPoint|, because the new child is going to be inserted in between the inlines,    // splitting them.    ASSERT(isInlineBlockOrInlineTable() || !isInline());    ASSERT(!insertionPoint || insertionPoint->parent() == this);    setChildrenInline(false);    RenderObject *child = firstChild();    if (!child)        return;    deleteLineBoxTree();    while (child) {        RenderObject *inlineRunStart, *inlineRunEnd;        getInlineRun(child, insertionPoint, inlineRunStart, inlineRunEnd);        if (!inlineRunStart)            break;        child = inlineRunEnd->nextSibling();        RenderBlock* block = createAnonymousBlock();        children()->insertChildNode(this, block, inlineRunStart);        RenderObject* o = inlineRunStart;        while (o != inlineRunEnd) {            RenderObject* no = o;            o = no->nextSibling();                        moveChild(block, block->children(), this, children(), no);        }        moveChild(block, block->children(), this, children(), inlineRunEnd);    }#ifndef NDEBUG    for (RenderObject *c = firstChild(); c; c = c->nextSibling())        ASSERT(!c->isInline());#endif    repaint();}void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child){    ASSERT(child->isAnonymousBlock());    ASSERT(!child->childrenInline());        if (child->inlineContinuation())         return;        RenderObject* firstAnChild = child->m_children.firstChild();    RenderObject* lastAnChild = child->m_children.lastChild();    if (firstAnChild) {        RenderObject* o = firstAnChild;        while (o) {            o->setParent(this);            o = o->nextSibling();        }        firstAnChild->setPreviousSibling(child->previousSibling());        lastAnChild->setNextSibling(child->nextSibling());        if (child->previousSibling())            child->previousSibling()->setNextSibling(firstAnChild);        if (child->nextSibling())            child->nextSibling()->setPreviousSibling(lastAnChild);    } else {        if (child->previousSibling())            child->previousSibling()->setNextSibling(child->nextSibling());        if (child->nextSibling())            child->nextSibling()->setPreviousSibling(child->previousSibling());    }    if (child == m_children.firstChild())        m_children.setFirstChild(firstAnChild);    if (child == m_children.lastChild())        m_children.setLastChild(lastAnChild);    child->setParent(0);    child->setPreviousSibling(0);    child->setNextSibling(0);        child->children()->setFirstChild(0);    child->m_next = 0;    child->destroy();}void RenderBlock::removeChild(RenderObject* oldChild){    // If this child is a block, and if our previous and next siblings are    // both anonymous blocks with inline content, then we can go ahead and    // fold the inline content back together.    RenderObject* prev = oldChild->previousSibling();    RenderObject* next = oldChild->nextSibling();    bool canDeleteAnonymousBlocks = !documentBeingDestroyed() && !isInline() && !oldChild->isInline() &&                                     (!oldChild->isRenderBlock() || !toRenderBlock(oldChild)->inlineContinuation()) &&                                     (!prev || (prev->isAnonymousBlock() && prev->childrenInline())) &&                                    (!next || (next->isAnonymousBlock() && next->childrenInline()));    if (canDeleteAnonymousBlocks && prev && next) {        // Take all the children out of the |next| block and put them in        // the |prev| block.        prev->setNeedsLayoutAndPrefWidthsRecalc();        RenderObject* o = next->firstChild();            RenderBlock* nextBlock = toRenderBlock(next);        RenderBlock* prevBlock = toRenderBlock(prev);        while (o) {            RenderObject* no = o;            o = no->nextSibling();            moveChild(prevBlock, prevBlock->children(), nextBlock, nextBlock->children(), no);        }         nextBlock->deleteLineBoxTree();                // Nuke the now-empty block.        next->destroy();    }    RenderBox::removeChild(oldChild);    RenderObject* child = prev ? prev : next;    if (canDeleteAnonymousBlocks && child && !child->previousSibling() && !child->nextSibling() && !isFlexibleBox()) {        // The removal has knocked us down to containing only a single anonymous        // box.  We can go ahead and pull the content right back up into our        // box.        setNeedsLayoutAndPrefWidthsRecalc();        RenderBlock* anonBlock = toRenderBlock(children()->removeChildNode(this, child, false));        setChildrenInline(true);        RenderObject* o = anonBlock->firstChild();        while (o) {            RenderObject* no = o;            o = no->nextSibling();            moveChild(this, children(), anonBlock, anonBlock->children(), no);        }        // Delete the now-empty block's lines and nuke it.        anonBlock->deleteLineBoxTree();        anonBlock->destroy();    }}int RenderBlock::overflowHeight(bool includeInterior) const{    if (!includeInterior && hasOverflowClip()) {        int shadowHeight = 0;        for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next)            shadowHeight = max(boxShadow->y + boxShadow->blur, shadowHeight);        int inflatedHeight = height() + shadowHeight;        if (hasReflection())            inflatedHeight = max(inflatedHeight, reflectionBox().bottom());        return inflatedHeight;    }    return m_overflowHeight;}int RenderBlock::overflowWidth(bool includeInterior) const{    if (!includeInterior && hasOverflowClip()) {        int shadowWidth = 0;        for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next)            shadowWidth = max(boxShadow->x + boxShadow->blur, shadowWidth);        int inflatedWidth = width() + shadowWidth;        if (hasReflection())            inflatedWidth = max(inflatedWidth, reflectionBox().right());        return inflatedWidth;    }    return m_overflowWidth;}int RenderBlock::overflowLeft(bool includeInterior) const{    if (!includeInterior && hasOverflowClip()) {        int shadowLeft = 0;        for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next)            shadowLeft = min(boxShadow->x - boxShadow->blur, shadowLeft);        int left = shadowLeft;        if (hasReflection())            left = min(left, reflectionBox().x());        return left;    }    return m_overflowLeft;}int RenderBlock::overflowTop(bool includeInterior) const{    if (!includeInterior && hasOverflowClip()) {        int shadowTop = 0;        for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next)            shadowTop = min(boxShadow->y - boxShadow->blur, shadowTop);        int top = shadowTop;        if (hasReflection())            top = min(top, reflectionBox().y());        return top;    }    return m_overflowTop;}IntRect RenderBlock::overflowRect(bool includeInterior) const{    if (!includeInterior && hasOverflowClip()) {        IntRect box = borderBoxRect();        int shadowLeft = 0;        int shadowRight = 0;        int shadowTop = 0;        int shadowBottom = 0;        for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) {            shadowLeft = min(boxShadow->x - boxShadow->blur, shadowLeft);            shadowRight = max(boxShadow->x + boxShadow->blur, shadowRight);

⌨️ 快捷键说明

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