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

📄 render_block.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        int oldTopNegMargin = m_maxTopNegMargin;        if (legend == child) {            child = child->nextSibling();            continue; // Skip the legend, since it has already been positioned up in the fieldset's border.        }                // make sure we relayout children if we need it.        if (relayoutChildren || floatBottom() > m_y ||            (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())) ||            (child->isRenderBlock() && child->style()->height().isPercent()))            child->setChildNeedsLayout(true);        //         kdDebug( 6040 ) << "   " << child->renderName() << " loop " << child << ", " << child->isInline() << ", " << child->needsLayout() << endl;        //         kdDebug( 6040 ) << t.elapsed() << endl;        // ### might be some layouts are done two times... FIX that.        if (child->isPositioned())        {            child->containingBlock()->insertPositionedObject(child);            if (child->hasStaticX()) {                if (style()->direction() == LTR)                    child->setStaticX(xPos);                else                    child->setStaticX(borderRight()+paddingRight());            }            if (child->hasStaticY()) {                int marginOffset = 0;                bool shouldSynthesizeCollapse = (!topMarginContributor || !canCollapseTopWithChildren);                if (shouldSynthesizeCollapse) {                    int collapsedTopPos = prevPosMargin;                    int collapsedTopNeg = prevNegMargin;                    bool posMargin = child->marginTop() >= 0;                    if (posMargin && child->marginTop() > collapsedTopPos)                        collapsedTopPos = child->marginTop();                    else if (!posMargin && child->marginTop() > collapsedTopNeg)                        collapsedTopNeg = child->marginTop();                    marginOffset += (collapsedTopPos - collapsedTopNeg) - child->marginTop();                }                                int yPosEstimate = m_height + marginOffset;                child->setStaticY(yPosEstimate);            }            child = child->nextSibling();            continue;        } else if (child->isReplaced())            child->layoutIfNeeded();                if ( child->isFloating() ) {            insertFloatingObject( child );            // The float should be positioned taking into account the bottom margin            // of the previous flow.  We add that margin into the height, get the            // float positioned properly, and then subtract the margin out of the            // height again.  In the case of self-collapsing blocks, we always just            // use the top margins, since the self-collapsing block collapsed its            // own bottom margin into its top margin.            //            // 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 checking the boolean |topMarginContributor| variable.  See            // http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for            // an example of this scenario.            int marginOffset = (!topMarginContributor || !canCollapseTopWithChildren) ? (prevPosMargin - prevNegMargin) : 0;                        m_height += marginOffset;            positionNewFloats();            m_height -= marginOffset;            //kdDebug() << "RenderBlock::layoutBlockChildren inserting float at "<< m_height <<" prevMargin="<<prevMargin << endl;            child = child->nextSibling();            continue;        }        // See if we have a compact element.  If we do, then try to tuck the compact        // element into the margin space of the next block.        // FIXME: We only deal with one compact at a time.  It is unclear what should be        // done if multiple contiguous compacts are encountered.  For now we assume that        // compact A followed by another compact B should simply be treated as block A.        if (child->isCompact() && !compactChild && (child->childrenInline() || child->isReplaced())) {            // Get the next non-positioned/non-floating RenderBlock.            RenderObject* next = child->nextSibling();            RenderObject* curr = next;            while (curr && curr->isFloatingOrPositioned())                curr = curr->nextSibling();            if (curr && curr->isRenderBlock() && !curr->isCompact() && !curr->isRunIn()) {                curr->calcWidth(); // So that horizontal margins are correct.                // Need to compute margins for the child as though it is a block.                child->style()->setDisplay(BLOCK);                child->calcWidth();                child->style()->setDisplay(COMPACT);                int childMargins = child->marginLeft() + child->marginRight();                int margin = style()->direction() == LTR ? curr->marginLeft() : curr->marginRight();                if (margin < (childMargins + child->maxWidth())) {                    // It won't fit. Kill the "compact" boolean and just treat                    // the child like a normal block. This is only temporary.                    child->style()->setDisplay(BLOCK);                    treatCompactAsBlock = true;                }                else {                    blockForCompactChild = curr;                    compactChild = child;                    child->setInline(true);                    child->setPos(0,0); // This position will be updated to reflect the compact's                                        // desired position and the line box for the compact will                                        // pick that position up.                    // Remove the child.                    RenderObject* next = child->nextSibling();                    removeChildNode(child);                    // Now insert the child under |curr|.                    curr->insertChildNode(child, curr->firstChild());                    child = next;                    continue;                }            }        }        // 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())) {            // Get the next non-positioned/non-floating RenderBlock.            RenderObject* curr = child->nextSibling();            while (curr && curr->isFloatingOrPositioned())                curr = curr->nextSibling();            if (curr && (curr->isRenderBlock() && curr->childrenInline() && !curr->isCompact() && !curr->isRunIn())) {                // The block acts like an inline, so just null out its                // position.                child->setInline(true);                child->setPos(0,0);                // Remove the child.                RenderObject* next = child->nextSibling();                removeChildNode(child);                // Now insert the child under |curr|.                curr->insertChildNode(child, curr->firstChild());                child = next;                continue;            }        }                child->calcVerticalMargins();        // Try to guess our correct y position.  In most cases this guess will        // be correct.  Only if we're wrong (when we compute the real y position)        // will we have to relayout.        int yPosEstimate = m_height;        if (prevBlock) {            yPosEstimate += kMax(prevBlock->collapsedMarginBottom(), child->marginTop());            if (prevFlow) {                if (prevFlow->yPos() + prevFlow->floatBottom() > yPosEstimate)                    child->setChildNeedsLayout(true);                else                    prevFlow = 0;            }        }        else if (!canCollapseTopWithChildren || !topMarginContributor)            yPosEstimate += child->marginTop();                // Note this occurs after the test for positioning and floating above, sincep        // we want to ensure that we don't artificially increase our height because of        // a positioned or floating child.        int fb = floatBottom();        if (child->avoidsFloats() && style()->width().isFixed() && child->minWidth() > lineWidth(m_height)) {            if (fb > m_height) {                m_height = yPosEstimate = fb;                shouldCollapseChild = false;                clearOccurred = true;                prevFlow = 0;                prevBlock = 0;            }        }        // take care in case we inherited floats        if (fb > m_height)            child->setChildNeedsLayout(true);        //kdDebug(0) << "margin = " << margin << " yPos = " << m_height << endl;        int oldChildX = child->xPos();        int oldChildY = child->yPos();                // Go ahead and position the child as though it didn't collapse with the top.        child->setPos(child->xPos(), yPosEstimate);        child->layoutIfNeeded();        // Now determine the correct ypos based off examination of collapsing margin        // values.        if (shouldCollapseChild) {            // 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()) {                if (child->maxBottomMargin(true) > posTop)                    posTop = child->maxBottomMargin(true);                if (child->maxBottomMargin(false) > negTop)                    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();            if (canCollapseTopWithChildren && topMarginContributor && !clearOccurred) {                // 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 (strictMode || !quirkContainer || !topQuirk) {                    if (posTop > m_maxTopPosMargin)                        m_maxTopPosMargin = posTop;                    if (negTop > m_maxTopNegMargin)                        m_maxTopNegMargin = negTop;                }                // 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 (!determinedTopQuirk && !topQuirk && (posTop-negTop)) {                    m_topMarginQuirk = false;                    determinedTopQuirk = true;                }                if (!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.                    m_topMarginQuirk = true;            }            if (quirkContainer && topMarginContributor && (posTop-negTop))                topChildQuirk = topQuirk;            int ypos = m_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 = prevPosMargin;                int collapsedTopNeg = prevNegMargin;                if (child->maxTopMargin(true) > prevPosMargin)                    collapsedTopPos = prevPosMargin = child->maxTopMargin(true);                if (child->maxTopMargin(false) > prevNegMargin)                    collapsedTopNeg = prevNegMargin = child->maxTopMargin(false);                // Now collapse the child's margins together, which means examining our                // bottom margin values as well.                 if (child->maxBottomMargin(true) > prevPosMargin)                    prevPosMargin = child->maxBottomMargin(true);                if (child->maxBottomMargin(false) > prevNegMargin)                    prevNegMargin = child->maxBottomMargin(false);                if (!canCollapseTopWithChildren || !topMarginContributor)                    // 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 = m_height + collapsedTopPos - collapsedTopNeg;            }            else {                if (!topMarginContributor ||                    (!canCollapseTopWithChildren                     && (strictMode || !quirkContainer || !topChildQuirk)                     )) {                    // We're collapsing with a previous sibling's margins and not                    // with the top of the block.                    int absPos = prevPosMargin > posTop ? prevPosMargin : posTop;                    int absNeg = prevNegMargin > negTop ? prevNegMargin : negTop;                    int collapsedMargin = absPos - absNeg;                    m_height += collapsedMargin;                    ypos = m_height;                }                prevPosMargin = child->maxBottomMargin(true);                prevNegMargin = child->maxBottomMargin(false);                if (prevPosMargin-prevNegMargin) {                    bottomChildQuirk = child->isBottomMarginQuirk();                }                selfCollapsingBlockClearedFloat = false;            }            child->setPos(child->xPos(), ypos);            if (ypos != yPosEstimate) {                if (child->style()->width().isPercent() && child->usesLineWidth())                    // The child's width is a percentage of the line width.                    // When the child shifts to clear an item, its width can                    // change (because it has more available line width).                    // So go ahead and mark the item as dirty.                    child->setChildNeedsLayout(true);                if (child->containsFloats() || containsFloats())                    child->markAllDescendantsWithFloatsForLayout();                // Our guess was wrong. Make the child lay itself out again.                child->layoutIfNeeded();            }        }        else            selfCollapsingBlockClearedFloat = false;

⌨️ 快捷键说明

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