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

📄 renderblock.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    //    // Note also that the previous flow may collapse its margin into the top of    // our block.  If this is the case, then we do not add the margin in to our    // height when computing the position of the float.   This condition can be tested    // for by simply calling canCollapseWithTop.  See    // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for    // an example of this scenario.    int marginOffset = marginInfo.canCollapseWithTop() ? 0 : marginInfo.margin();    setHeight(height() + marginOffset);    positionNewFloats();    setHeight(height() - marginOffset);}RenderBox* RenderBlock::handleSpecialChild(RenderBox* child, const MarginInfo& marginInfo, bool& handled){    // Handle positioned children first.    RenderBox* next = handlePositionedChild(child, marginInfo, handled);    if (handled) return next;        // Handle floating children next.    next = handleFloatingChild(child, marginInfo, handled);    if (handled) return next;    // Finally, see if we have a run-in element.    return handleRunInChild(child, handled);}RenderBox* RenderBlock::handlePositionedChild(RenderBox* child, const MarginInfo& marginInfo, bool& handled){    if (child->isPositioned()) {        handled = true;        child->containingBlock()->insertPositionedObject(child);        adjustPositionedBlock(child, marginInfo);        return child->nextSiblingBox();    }    return 0;}RenderBox* RenderBlock::handleFloatingChild(RenderBox* child, const MarginInfo& marginInfo, bool& handled){    if (child->isFloating()) {        handled = true;        insertFloatingObject(child);        adjustFloatingBlock(marginInfo);        return child->nextSiblingBox();    }        return 0;}RenderBox* RenderBlock::handleRunInChild(RenderBox* child, bool& handled){    // See if we have a run-in element with inline children.  If the    // children aren't inline, then just treat the run-in as a normal    // block.    if (child->isRunIn() && (child->childrenInline() || child->isReplaced())) {        RenderBlock* blockRunIn = toRenderBlock(child);        // Get the next non-positioned/non-floating RenderBlock.        RenderObject* curr = blockRunIn->nextSibling();        while (curr && curr->isFloatingOrPositioned())            curr = curr->nextSibling();        if (curr && (curr->isRenderBlock() && curr->childrenInline() && !curr->isRunIn())) {            RenderBlock* currBlock = toRenderBlock(curr);                    // The block acts like an inline, so just null out its            // position.            handled = true;                        // Remove the old child.            RenderBox* next = blockRunIn->nextSiblingBox();            children()->removeChildNode(this, blockRunIn);            // Create an inline.            RenderInline* inlineRunIn = new (renderArena()) RenderInline(blockRunIn->node());            inlineRunIn->setStyle(blockRunIn->style());            // Move the nodes from the old child to the new child, but skip any :before/:after content.  It has already            // been regenerated by the new inline.            for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild; runInChild = runInChild->nextSibling()) {                if (runInChild->style()->styleType() != BEFORE && runInChild->style()->styleType() != AFTER) {                    blockRunIn->children()->removeChildNode(blockRunIn, runInChild, false);                    inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content.                }            }            // Now insert the new child under |currBlock|.            currBlock->children()->insertChildNode(currBlock, inlineRunIn, currBlock->firstChild());                        // If the run-in had an element, we need to set the new renderer.            if (blockRunIn->node())                blockRunIn->node()->setRenderer(inlineRunIn);                        // Destroy the block run-in.            blockRunIn->destroy();            return next;        }    }    return 0;}int RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo){    // Get our max pos and neg top margins.    int posTop = child->maxTopMargin(true);    int negTop = child->maxTopMargin(false);    // For self-collapsing blocks, collapse our bottom margins into our    // top to get new posTop and negTop values.    if (child->isSelfCollapsingBlock()) {        posTop = max(posTop, child->maxBottomMargin(true));        negTop = max(negTop, child->maxBottomMargin(false));    }        // See if the top margin is quirky. We only care if this child has    // margins that will collapse with us.    bool topQuirk = child->isTopMarginQuirk() || style()->marginTopCollapse() == MDISCARD;    if (marginInfo.canCollapseWithTop()) {        // This child is collapsing with the top of the        // block.  If it has larger margin values, then we need to update        // our own maximal values.        if (!style()->htmlHacks() || !marginInfo.quirkContainer() || !topQuirk)            setMaxTopMargins(max(posTop, maxTopPosMargin()), max(negTop, maxTopNegMargin()));        // The minute any of the margins involved isn't a quirk, don't        // collapse it away, even if the margin is smaller (www.webreference.com        // has an example of this, a <dt> with 0.8em author-specified inside        // a <dl> inside a <td>.        if (!marginInfo.determinedTopQuirk() && !topQuirk && (posTop-negTop)) {            setTopMarginQuirk(false);            marginInfo.setDeterminedTopQuirk(true);        }        if (!marginInfo.determinedTopQuirk() && topQuirk && marginTop() == 0)            // We have no top margin and our top child has a quirky margin.            // We will pick up this quirky margin and pass it through.            // This deals with the <td><div><p> case.            // Don't do this for a block that split two inlines though.  You do            // still apply margins in this case.            setTopMarginQuirk(true);    }    if (marginInfo.quirkContainer() && marginInfo.atTopOfBlock() && (posTop - negTop))        marginInfo.setTopQuirk(topQuirk);    int ypos = height();    if (child->isSelfCollapsingBlock()) {        // This child has no height.  We need to compute our        // position before we collapse the child's margins together,        // so that we can get an accurate position for the zero-height block.        int collapsedTopPos = max(marginInfo.posMargin(), child->maxTopMargin(true));        int collapsedTopNeg = max(marginInfo.negMargin(), child->maxTopMargin(false));        marginInfo.setMargin(collapsedTopPos, collapsedTopNeg);                // Now collapse the child's margins together, which means examining our        // bottom margin values as well.         marginInfo.setPosMarginIfLarger(child->maxBottomMargin(true));        marginInfo.setNegMarginIfLarger(child->maxBottomMargin(false));        if (!marginInfo.canCollapseWithTop())            // We need to make sure that the position of the self-collapsing block            // is correct, since it could have overflowing content            // that needs to be positioned correctly (e.g., a block that            // had a specified height of 0 but that actually had subcontent).            ypos = height() + collapsedTopPos - collapsedTopNeg;    }    else {        if (child->style()->marginTopCollapse() == MSEPARATE) {            setHeight(height() + marginInfo.margin() + child->marginTop());            ypos = height();        }        else if (!marginInfo.atTopOfBlock() ||            (!marginInfo.canCollapseTopWithChildren()             && (!style()->htmlHacks() || !marginInfo.quirkContainer() || !marginInfo.topQuirk()))) {            // We're collapsing with a previous sibling's margins and not            // with the top of the block.            setHeight(height() + max(marginInfo.posMargin(), posTop) - max(marginInfo.negMargin(), negTop));            ypos = height();        }        marginInfo.setPosMargin(child->maxBottomMargin(true));        marginInfo.setNegMargin(child->maxBottomMargin(false));        if (marginInfo.margin())            marginInfo.setBottomQuirk(child->isBottomMarginQuirk() || style()->marginBottomCollapse() == MDISCARD);        marginInfo.setSelfCollapsingBlockClearedFloat(false);    }        return ypos;}int RenderBlock::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, int oldTopPosMargin, int oldTopNegMargin, int yPos){    int heightIncrease = getClearDelta(child, yPos);    if (!heightIncrease)        return yPos;    if (child->isSelfCollapsingBlock()) {        // For self-collapsing blocks that clear, they can still collapse their        // margins with following siblings.  Reset the current margins to represent        // the self-collapsing block's margins only.        marginInfo.setPosMargin(max(child->maxTopMargin(true), child->maxBottomMargin(true)));        marginInfo.setNegMargin(max(child->maxTopMargin(false), child->maxBottomMargin(false)));                // Adjust our height such that we are ready to be collapsed with subsequent siblings.        setHeight(child->y() - max(0, marginInfo.margin()));                // Set a flag that we cleared a float so that we know both to increase the height of the block        // to compensate for the clear and to avoid collapsing our margins with the parent block's        // bottom margin.        marginInfo.setSelfCollapsingBlockClearedFloat(true);    } else        // Increase our height by the amount we had to clear.        setHeight(height() + heightIncrease);        if (marginInfo.canCollapseWithTop()) {        // We can no longer collapse with the top of the block since a clear        // occurred.  The empty blocks collapse into the cleared block.        // FIXME: This isn't quite correct.  Need clarification for what to do        // if the height the cleared block is offset by is smaller than the        // margins involved.        setMaxTopMargins(oldTopPosMargin, oldTopNegMargin);        marginInfo.setAtTopOfBlock(false);    }        return yPos + heightIncrease;}int RenderBlock::estimateVerticalPosition(RenderBox* child, const MarginInfo& marginInfo){    // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological    // relayout if there are intruding floats.    int yPosEstimate = height();    if (!marginInfo.canCollapseWithTop()) {        int childMarginTop = child->selfNeedsLayout() ? child->marginTop() : child->collapsedMarginTop();        yPosEstimate += max(marginInfo.margin(), childMarginTop);    }    yPosEstimate += getClearDelta(child, yPosEstimate);    return yPosEstimate;}void RenderBlock::determineHorizontalPosition(RenderBox* child){    if (style()->direction() == LTR) {        int xPos = borderLeft() + paddingLeft();                // Add in our left margin.        int chPos = xPos + child->marginLeft();                // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need        // to shift over as necessary to dodge any floats that might get in the way.        if (child->avoidsFloats()) {            int leftOff = leftOffset(height(), false);            if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginLeft().type() != Auto) {                if (child->marginLeft() < 0)                    leftOff += child->marginLeft();                chPos = max(chPos, leftOff); // Let the float sit in the child's margin if it can fit.            }            else if (leftOff != xPos) {                // The object is shifting right. The object might be centered, so we need to                // recalculate our horizontal margins. Note that the containing block content                // width computation will take into account the delta between |leftOff| and |xPos|                // so that we can just pass the content width in directly to the |calcHorizontalMargins|                // function.                child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));                chPos = leftOff + child->marginLeft();            }        }        view()->addLayoutDelta(IntSize(child->x() - chPos, 0));        child->setLocation(chPos, child->y());    } else {        int xPos = width() - borderRight() - paddingRight() - verticalScrollbarWidth();        int chPos = xPos - (child->width() + child->marginRight());        if (child->avoidsFloats()) {            int rightOff = rightOffset(height(), false);            if (style()->textAlign() != WEBKIT_CENTER && child->style()->marginRight().type() != Auto) {                if (child->marginRight() < 0)                    rightOff -= child->marginRight();                chPos = min(chPos, rightOff - child->width()); // Let the float sit in the child's margin if it can fit.            } else if (rightOff != xPos) {                // The object is shifting left. The object might be centered, so we need to                // recalculate our horizontal margins. Note that the containing block content                // width computation will take into account the delta between |rightOff| and |xPos|                // so that we can just pass the content width in directly to the |calcHorizontalMargins|                // function.                child->calcHorizontalMargins(child->style()->marginLeft(), child->style()->marginRight(), lineWidth(child->y(), false));                chPos = rightOff - child->marginRight() - child->width();            }        }        view()->addLayoutDelta(IntSize(child->x() - chPos, 0));        child->setLocation(chPos, child->y());    }}void RenderBlock::setCollapsedBottomMargin(const MarginInfo& marginInfo){    if (marginInfo.canCollapseWithBottom() && !marginInfo.canCollapseWithTop()) {        // Update our max pos/neg bottom margins, since we collapsed our bottom margins        // with our children.        setMaxBottomMargins(max(maxBottomPosMargin(), marginInfo.posMargin()), max(maxBottomNegMargin(), marginInfo.negMargin()));        if (!marginInfo.bottomQuirk())            setBottomMarginQuirk(false);

⌨️ 快捷键说明

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