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

📄 renderblock.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2007 David Smith (catfish.man@gmail.com) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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 * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */#include "config.h"#include "RenderBlock.h"#include "Document.h"#include "Element.h"#include "FloatQuad.h"#include "Frame.h"#include "FrameView.h"#include "GraphicsContext.h"#include "HTMLNames.h"#include "HitTestResult.h"#include "InlineTextBox.h"#include "RenderImage.h"#include "RenderInline.h"#include "RenderMarquee.h"#include "RenderReplica.h"#include "RenderTableCell.h"#include "RenderTextFragment.h"#include "RenderTheme.h"#include "RenderView.h"#include "SelectionController.h"#include <wtf/StdLibExtras.h>using namespace std;using namespace WTF;using namespace Unicode;namespace WebCore {// Number of pixels to allow as a fudge factor when clicking above or below a line.// clicking up to verticalLineClickFudgeFactor pixels above a line will correspond to the closest point on the line.   const int verticalLineClickFudgeFactor= 3;using namespace HTMLNames;static void moveChild(RenderObject* to, RenderObjectChildList* toChildList, RenderObject* from, RenderObjectChildList* fromChildList, RenderObject* child){    ASSERT(from == child->parent());    toChildList->appendChildNode(to, fromChildList->removeChildNode(from, child, false), false);}struct ColumnInfo {    ColumnInfo()        : m_desiredColumnWidth(0)        , m_desiredColumnCount(1)        { }    int m_desiredColumnWidth;    unsigned m_desiredColumnCount;    Vector<IntRect> m_columnRects;};typedef WTF::HashMap<const RenderBox*, ColumnInfo*> ColumnInfoMap;static ColumnInfoMap* gColumnInfoMap = 0;typedef WTF::HashMap<const RenderBlock*, HashSet<RenderBox*>*> PercentHeightDescendantsMap;static PercentHeightDescendantsMap* gPercentHeightDescendantsMap = 0;typedef WTF::HashMap<const RenderBox*, HashSet<RenderBlock*>*> PercentHeightContainerMap;static PercentHeightContainerMap* gPercentHeightContainerMap = 0;    typedef WTF::HashMap<RenderBlock*, ListHashSet<RenderInline*>*> ContinuationOutlineTableMap;// Our MarginInfo state used when laying out block children.RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, int top, int bottom){    // Whether or not we can collapse our own margins with our children.  We don't do this    // if we had any border/padding (obviously), if we're the root or HTML elements, or if    // we're positioned, floating, a table cell.    m_canCollapseWithChildren = !block->isRenderView() && !block->isRoot() && !block->isPositioned() &&        !block->isFloating() && !block->isTableCell() && !block->hasOverflowClip() && !block->isInlineBlockOrInlineTable();    m_canCollapseTopWithChildren = m_canCollapseWithChildren && (top == 0) && block->style()->marginTopCollapse() != MSEPARATE;    // If any height other than auto is specified in CSS, then we don't collapse our bottom    // margins with our children's margins.  To do otherwise would be to risk odd visual    // effects when the children overflow out of the parent block and yet still collapse    // with it.  We also don't collapse if we have any bottom border/padding.    m_canCollapseBottomWithChildren = m_canCollapseWithChildren && (bottom == 0) &&        (block->style()->height().isAuto() && block->style()->height().value() == 0) && block->style()->marginBottomCollapse() != MSEPARATE;        m_quirkContainer = block->isTableCell() || block->isBody() || block->style()->marginTopCollapse() == MDISCARD ||         block->style()->marginBottomCollapse() == MDISCARD;    m_atTopOfBlock = true;    m_atBottomOfBlock = false;    m_posMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(true) : 0;    m_negMargin = m_canCollapseTopWithChildren ? block->maxTopMargin(false) : 0;    m_selfCollapsingBlockClearedFloat = false;        m_topQuirk = m_bottomQuirk = m_determinedTopQuirk = false;}// -------------------------------------------------------------------------------------------------------RenderBlock::RenderBlock(Node* node)      : RenderBox(node)      , m_floatingObjects(0)      , m_positionedObjects(0)      , m_inlineContinuation(0)      , m_maxMargin(0)      , m_overflowHeight(0)      , m_overflowWidth(0)      , m_overflowLeft(0)      , m_overflowTop(0)      , m_lineHeight(-1){    setChildrenInline(true);}RenderBlock::~RenderBlock(){    delete m_floatingObjects;    delete m_positionedObjects;    delete m_maxMargin;        if (hasColumns())        delete gColumnInfoMap->take(this);    if (gPercentHeightDescendantsMap) {        if (HashSet<RenderBox*>* descendantSet = gPercentHeightDescendantsMap->take(this)) {            HashSet<RenderBox*>::iterator end = descendantSet->end();            for (HashSet<RenderBox*>::iterator descendant = descendantSet->begin(); descendant != end; ++descendant) {                HashSet<RenderBlock*>* containerSet = gPercentHeightContainerMap->get(*descendant);                ASSERT(containerSet);                if (!containerSet)                    continue;                ASSERT(containerSet->contains(this));                containerSet->remove(this);                if (containerSet->isEmpty()) {                    gPercentHeightContainerMap->remove(*descendant);                    delete containerSet;                }            }            delete descendantSet;        }    }}void RenderBlock::destroy(){    // Detach our continuation first.    if (m_inlineContinuation)        m_inlineContinuation->destroy();    m_inlineContinuation = 0;        // Make sure to destroy anonymous children first while they are still connected to the rest of the tree, so that they will    // properly dirty line boxes that they are removed from.  Effects that do :before/:after only on hover could crash otherwise.    children()->destroyLeftoverChildren();    if (!documentBeingDestroyed()) {        if (firstLineBox()) {            // We can't wait for RenderBox::destroy to clear the selection,            // because by then we will have nuked the line boxes.            // FIXME: The SelectionController should be responsible for this when it            // is notified of DOM mutations.            if (isSelectionBorder())                view()->clearSelection();            // If we are an anonymous block, then our line boxes might have children            // that will outlast this block. In the non-anonymous block case those            // children will be destroyed by the time we return from this function.            if (isAnonymousBlock()) {                for (InlineFlowBox* box = firstLineBox(); box; box = box->nextFlowBox()) {                    while (InlineBox* childBox = box->firstChild())                        childBox->remove();                }            }        } else if (isInline() && parent())            parent()->dirtyLinesFromChangedChild(this);    }    m_lineBoxes.deleteLineBoxes(renderArena());    RenderBox::destroy();}void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle){    setReplaced(newStyle->isDisplayReplacedType());        if (style() && parent() && diff == StyleDifferenceLayout && style()->position() != newStyle->position()) {        if (newStyle->position() == StaticPosition)            // Clear our positioned objects list. Our absolutely positioned descendants will be            // inserted into our containing block's positioned objects list during layout.            removePositionedObjects(0);        else if (style()->position() == StaticPosition) {            // Remove our absolutely positioned descendants from their current containing block.            // They will be inserted into our positioned objects list during layout.            RenderObject* cb = parent();            while (cb && (cb->style()->position() == StaticPosition || (cb->isInline() && !cb->isReplaced())) && !cb->isRenderView()) {                if (cb->style()->position() == RelativePosition && cb->isInline() && !cb->isReplaced()) {                    cb = cb->containingBlock();                    break;                }                cb = cb->parent();            }                        if (cb->isRenderBlock())                toRenderBlock(cb)->removePositionedObjects(this);        }    }    RenderBox::styleWillChange(diff, newStyle);}void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle){    RenderBox::styleDidChange(diff, oldStyle);    // FIXME: We could save this call when the change only affected non-inherited properties    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {        if (child->isAnonymousBlock()) {            RefPtr<RenderStyle> newStyle = RenderStyle::create();            newStyle->inheritFrom(style());            newStyle->setDisplay(BLOCK);            child->setStyle(newStyle.release());        }    }    m_lineHeight = -1;    // Update pseudos for :before and :after now.    if (!isAnonymous() && document()->usesBeforeAfterRules() && canHaveChildren()) {        updateBeforeAfterContent(BEFORE);        updateBeforeAfterContent(AFTER);    }    updateFirstLetter();}void RenderBlock::updateBeforeAfterContent(PseudoId pseudoId){    // If this is an anonymous wrapper, then the parent applies its own pseudo-element style to it.    if (parent() && parent()->createsAnonymousWrapper())        return;    return children()->updateBeforeAfterContent(this, pseudoId);}    void RenderBlock::addChild(RenderObject* newChild, RenderObject* beforeChild){    // Make sure we don't append things after :after-generated content if we have it.    if (!beforeChild && isAfterContent(lastChild()))        beforeChild = lastChild();    bool madeBoxesNonInline = false;    // If the requested beforeChild is not one of our children, then this is because    // there is an anonymous container within this object that contains the beforeChild.    if (beforeChild && beforeChild->parent() != this) {        RenderObject* anonymousChild = beforeChild->parent();        ASSERT(anonymousChild);        while (anonymousChild->parent() != this)            anonymousChild = anonymousChild->parent();        ASSERT(anonymousChild->isAnonymous());        if (anonymousChild->isAnonymousBlock()) {            // Insert the child into the anonymous block box instead of here.            if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)                beforeChild->parent()->addChild(newChild, beforeChild);            else                addChild(newChild, beforeChild->parent());            return;        }        ASSERT(anonymousChild->isTable());        if (newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP                || newChild->isRenderBlock() && newChild->style()->display() == TABLE_CAPTION                || newChild->isTableSection()                || newChild->isTableRow()                || newChild->isTableCell()) {            // Insert into the anonymous table.            anonymousChild->addChild(newChild, beforeChild);            return;        }        // Go on to insert before the anonymous table.        beforeChild = anonymousChild;    }    // A block has to either have all of its children inline, or all of its children as blocks.    // So, if our children are currently inline and a block child has to be inserted, we move all our    // inline children into anonymous block boxes.

⌨️ 快捷键说明

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