123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- * Copyright (C) 2013 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.
- *
- */
- #ifndef LogicalSelectionOffsetCaches_h
- #define LogicalSelectionOffsetCaches_h
- #include "RenderBlock.h"
- namespace WebCore {
- static inline bool isContainingBlockCandidateForAbsolutelyPositionedObject(RenderObject* object)
- {
- return object->style()->position() != StaticPosition
- || (object->hasTransform() && object->isRenderBlock())
- #if ENABLE(SVG)
- || object->isSVGForeignObject()
- #endif
- || object->isRenderView();
- }
- static inline bool isNonRenderBlockInline(RenderObject* object)
- {
- return (object->isInline() && !object->isReplaced()) || !object->isRenderBlock();
- }
- static inline RenderBlock* containingBlockForFixedPosition(RenderObject* parent)
- {
- RenderObject* object = parent;
- while (object && !object->canContainFixedPositionObjects())
- object = object->parent();
- ASSERT(!object || !object->isAnonymousBlock());
- return toRenderBlock(object);
- }
- static inline RenderBlock* containingBlockForAbsolutePosition(RenderObject* parent)
- {
- RenderObject* object = parent;
- while (object && !isContainingBlockCandidateForAbsolutelyPositionedObject(object))
- object = object->parent();
- // For a relatively positioned inline, return its nearest non-anonymous containing block,
- // not the inline itself, to avoid having a positioned objects list in all RenderInlines
- // and use RenderBlock* as RenderObject::containingBlock's return type.
- // Use RenderBlock::container() to obtain the inline.
- if (object && !object->isRenderBlock())
- object = object->containingBlock();
- while (object && object->isAnonymousBlock())
- object = object->containingBlock();
- return toRenderBlock(object);
- }
- static inline RenderBlock* containingBlockForObjectInFlow(RenderObject* parent)
- {
- RenderObject* object = parent;
- while (object && isNonRenderBlockInline(object))
- object = object->parent();
- return toRenderBlock(object);
- }
- class LogicalSelectionOffsetCaches {
- public:
- class ContainingBlockInfo {
- public:
- ContainingBlockInfo()
- : m_block(0)
- , m_cache(0)
- , m_hasFloatsOrFlowThreads(false)
- , m_cachedLogicalLeftSelectionOffset(false)
- , m_cachedLogicalRightSelectionOffset(false)
- { }
- void setBlock(RenderBlock* block, const LogicalSelectionOffsetCaches* cache)
- {
- m_block = block;
- m_hasFloatsOrFlowThreads = m_hasFloatsOrFlowThreads || m_block->containsFloats() || m_block->flowThreadContainingBlock();
- m_cache = cache;
- m_cachedLogicalLeftSelectionOffset = false;
- m_cachedLogicalRightSelectionOffset = false;
- }
- RenderBlock* block() const { return m_block; }
- const LogicalSelectionOffsetCaches* cache() const { return m_cache; }
- LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) const
- {
- ASSERT(m_cache);
- if (m_hasFloatsOrFlowThreads || !m_cachedLogicalLeftSelectionOffset) {
- m_cachedLogicalLeftSelectionOffset = true;
- m_logicalLeftSelectionOffset = m_block->logicalLeftSelectionOffset(rootBlock, position, *m_cache);
- } else
- ASSERT(m_logicalLeftSelectionOffset == m_block->logicalLeftSelectionOffset(rootBlock, position, *m_cache));
- return m_logicalLeftSelectionOffset;
- }
- LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) const
- {
- ASSERT(m_cache);
- if (m_hasFloatsOrFlowThreads || !m_cachedLogicalRightSelectionOffset) {
- m_cachedLogicalRightSelectionOffset = true;
- m_logicalRightSelectionOffset = m_block->logicalRightSelectionOffset(rootBlock, position, *m_cache);
- } else
- ASSERT(m_logicalRightSelectionOffset == m_block->logicalRightSelectionOffset(rootBlock, position, *m_cache));
- return m_logicalRightSelectionOffset;
- }
- private:
- RenderBlock* m_block;
- const LogicalSelectionOffsetCaches* m_cache;
- bool m_hasFloatsOrFlowThreads : 1;
- mutable bool m_cachedLogicalLeftSelectionOffset : 1;
- mutable bool m_cachedLogicalRightSelectionOffset : 1;
- mutable LayoutUnit m_logicalLeftSelectionOffset;
- mutable LayoutUnit m_logicalRightSelectionOffset;
-
- };
- LogicalSelectionOffsetCaches(RenderBlock* rootBlock)
- {
- ASSERT(rootBlock->isSelectionRoot());
- RenderObject* parent = rootBlock->parent();
- // LogicalSelectionOffsetCaches should not be used on an orphaned tree.
- m_containingBlockForFixedPosition.setBlock(containingBlockForFixedPosition(parent), 0);
- m_containingBlockForAbsolutePosition.setBlock(containingBlockForAbsolutePosition(parent), 0);
- m_containingBlockForInflowPosition.setBlock(containingBlockForObjectInFlow(parent), 0);
- }
- LogicalSelectionOffsetCaches(RenderBlock* block, const LogicalSelectionOffsetCaches& cache)
- : m_containingBlockForFixedPosition(cache.m_containingBlockForFixedPosition)
- , m_containingBlockForAbsolutePosition(cache.m_containingBlockForAbsolutePosition)
- {
- if (block->canContainFixedPositionObjects())
- m_containingBlockForFixedPosition.setBlock(block, &cache);
- if (isContainingBlockCandidateForAbsolutelyPositionedObject(block) && !block->isRenderInline() && !block->isAnonymousBlock())
- m_containingBlockForFixedPosition.setBlock(block, &cache);
- m_containingBlockForInflowPosition.setBlock(block, &cache);
- }
- const ContainingBlockInfo& containingBlockInfo(RenderBlock* block) const
- {
- EPosition position = block->style()->position();
- if (position == FixedPosition) {
- ASSERT(block->containingBlock() == m_containingBlockForFixedPosition.block());
- return m_containingBlockForFixedPosition;
- }
- if (position == AbsolutePosition) {
- ASSERT(block->containingBlock() == m_containingBlockForAbsolutePosition.block());
- return m_containingBlockForAbsolutePosition;
- }
- ASSERT(block->containingBlock() == m_containingBlockForInflowPosition.block());
- return m_containingBlockForInflowPosition;
- }
- private:
- ContainingBlockInfo m_containingBlockForFixedPosition;
- ContainingBlockInfo m_containingBlockForAbsolutePosition;
- ContainingBlockInfo m_containingBlockForInflowPosition;
- };
- } // namespace WebCore
- #endif // LogicalSelectionOffsetCaches_h
|