1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 27#ifndef RenderNamedFlowThread_h 28#define RenderNamedFlowThread_h 29 30#include "RenderFlowThread.h" 31#include "SelectionSubtreeRoot.h" 32#include "Timer.h" 33#include <wtf/HashCountedSet.h> 34#include <wtf/ListHashSet.h> 35#include <wtf/text/AtomicString.h> 36 37namespace WebCore { 38 39class Node; 40class RenderNamedFlowThread; 41class WebKitNamedFlow; 42 43typedef ListHashSet<RenderNamedFlowThread*> RenderNamedFlowThreadList; 44typedef HashCountedSet<RenderNamedFlowThread*> RenderNamedFlowThreadCountedSet; 45typedef ListHashSet<Element*> NamedFlowContentElements; 46 47class RenderNamedFlowThread final : public RenderFlowThread, public SelectionSubtreeRoot { 48public: 49 RenderNamedFlowThread(Document&, PassRef<RenderStyle>, PassRef<WebKitNamedFlow>); 50 virtual ~RenderNamedFlowThread(); 51 52 const AtomicString& flowThreadName() const; 53 54 const RenderRegionList& invalidRenderRegionList() const { return m_invalidRegionList; } 55 56 RenderElement* nextRendererForElement(Element&) const; 57 58 void addFlowChild(RenderElement&); 59 void removeFlowChild(RenderElement&); 60 bool hasChildren() const { return !m_flowThreadChildList.isEmpty(); } 61#ifndef NDEBUG 62 bool hasChild(RenderElement& child) const { return m_flowThreadChildList.contains(&child); } 63#endif 64 65 void pushDependencies(RenderNamedFlowThreadList&); 66 67 virtual void addRegionToThread(RenderRegion*) override; 68 virtual void removeRegionFromThread(RenderRegion*) override; 69 70 virtual void regionChangedWritingMode(RenderRegion*) override; 71 72 LayoutRect decorationsClipRectForBoxInNamedFlowFragment(const RenderBox&, RenderNamedFlowFragment&) const; 73 74 RenderNamedFlowFragment* fragmentFromAbsolutePointAndBox(const IntPoint&, const RenderBox& flowedBox); 75 76 void registerNamedFlowContentElement(Element&); 77 void unregisterNamedFlowContentElement(Element&); 78 const NamedFlowContentElements& contentElements() const { return m_contentElements; } 79 bool hasContentElement(Element&) const; 80 81 bool isMarkedForDestruction() const; 82 void getRanges(Vector<RefPtr<Range>>&, const RenderNamedFlowFragment*) const; 83 84 virtual void applyBreakAfterContent(LayoutUnit) override final; 85 86 virtual bool collectsGraphicsLayersUnderRegions() const override; 87 88 // Check if the content is flown into at least a region with region styling rules. 89 bool hasRegionsWithStyling() const { return m_hasRegionsWithStyling; } 90 void checkRegionsWithStyling(); 91 92 void clearRenderObjectCustomStyle(const RenderObject*); 93 94 virtual void removeFlowChildInfo(RenderObject*) override final; 95 96 LayoutUnit flowContentBottom() const { return m_flowContentBottom; } 97 void dispatchNamedFlowEvents(); 98 99 void setDispatchRegionOversetChangeEvent(bool value) { m_dispatchRegionOversetChangeEvent = value; } 100 101 virtual bool absoluteQuadsForBox(Vector<FloatQuad>&, bool*, const RenderBox*, float, float) const override; 102 103protected: 104 void setMarkForDestruction(); 105 void resetMarkForDestruction(); 106 107private: 108 virtual const char* renderName() const override; 109 virtual bool isRenderNamedFlowThread() const override { return true; } 110 virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override; 111 virtual void computeOverflow(LayoutUnit, bool = false) override; 112 virtual void layout() override final; 113 114 void dispatchRegionOversetChangeEventIfNeeded(); 115 116 bool dependsOn(RenderNamedFlowThread* otherRenderFlowThread) const; 117 void addDependencyOnFlowThread(RenderNamedFlowThread*); 118 void removeDependencyOnFlowThread(RenderNamedFlowThread*); 119 120 void addFragmentToNamedFlowThread(RenderNamedFlowFragment*); 121 122 void checkInvalidRegions(); 123 124 bool canBeDestroyed() const { return m_invalidRegionList.isEmpty() && m_regionList.isEmpty() && m_contentElements.isEmpty(); } 125 void regionOversetChangeEventTimerFired(Timer<RenderNamedFlowThread>&); 126 void clearContentElements(); 127 void updateWritingMode(); 128 129 WebKitNamedFlow& namedFlow() { return m_namedFlow.get(); } 130 const WebKitNamedFlow& namedFlow() const { return m_namedFlow.get(); } 131 132 // Observer flow threads have invalid regions that depend on the state of this thread 133 // to re-validate their regions. Keeping a set of observer threads make it easy 134 // to notify them when a region was removed from this flow. 135 RenderNamedFlowThreadCountedSet m_observerThreadsSet; 136 137 // Some threads need to have a complete layout before we layout this flow. 138 // That's because they contain a RenderRegion that should display this thread. The set makes it 139 // easy to sort the order of threads layout. 140 RenderNamedFlowThreadCountedSet m_layoutBeforeThreadsSet; 141 142 // Holds the sorted children of a named flow. This is the only way we can get the ordering right. 143 ListHashSet<RenderElement*> m_flowThreadChildList; 144 145 NamedFlowContentElements m_contentElements; 146 147 RenderRegionList m_invalidRegionList; 148 149 bool m_hasRegionsWithStyling : 1; 150 bool m_dispatchRegionOversetChangeEvent : 1; 151 152 // The DOM Object that represents a named flow. 153 Ref<WebKitNamedFlow> m_namedFlow; 154 155 Timer<RenderNamedFlowThread> m_regionOversetChangeEventTimer; 156 157 LayoutUnit m_flowContentBottom; 158}; 159 160RENDER_OBJECT_TYPE_CASTS(RenderNamedFlowThread, isRenderNamedFlowThread()) 161 162} // namespace WebCore 163 164#endif // RenderNamedFlowThread_h 165