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 COMPUTER, 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 "core/rendering/RenderFlowThread.h" 31 #include "platform/Timer.h" 32 #include "wtf/HashCountedSet.h" 33 #include "wtf/ListHashSet.h" 34 #include "wtf/text/AtomicString.h" 35 36 namespace WebCore { 37 38 class NamedFlow; 39 class Node; 40 class RenderNamedFlowThread; 41 42 typedef ListHashSet<RenderNamedFlowThread*> RenderNamedFlowThreadList; 43 typedef HashCountedSet<RenderNamedFlowThread*> RenderNamedFlowThreadCountedSet; 44 typedef ListHashSet<Node*> NamedFlowContentNodes; 45 46 class RenderNamedFlowThread FINAL : public RenderFlowThread { 47 public: 48 virtual ~RenderNamedFlowThread(); 49 50 static RenderNamedFlowThread* createAnonymous(Document*, PassRefPtr<NamedFlow>); 51 52 const AtomicString& flowThreadName() const; 53 54 const RenderRegionList& invalidRenderRegionList() const { return m_invalidRegionList; } 55 56 RenderObject* nextRendererForNode(Node*) const; 57 RenderObject* previousRendererForNode(Node*) const; 58 59 void addFlowChild(RenderObject* newChild); 60 void removeFlowChild(RenderObject*); 61 bool hasChildren() const { return !m_flowThreadChildList.isEmpty(); } 62 #ifndef NDEBUG 63 bool hasChild(RenderObject* child) const { return m_flowThreadChildList.contains(child); } 64 #endif 65 66 void pushDependencies(RenderNamedFlowThreadList&); 67 68 virtual void addRegionToThread(RenderRegion*) OVERRIDE; 69 virtual void removeRegionFromThread(RenderRegion*) OVERRIDE; 70 71 virtual void regionChangedWritingMode(RenderRegion*) OVERRIDE; 72 73 bool overset() const { return m_overset; } 74 void computeOversetStateForRegions(LayoutUnit oldClientAfterEdge); 75 76 void registerNamedFlowContentNode(Node*); 77 void unregisterNamedFlowContentNode(Node*); 78 const NamedFlowContentNodes& contentNodes() const { return m_contentNodes; } 79 bool hasContentNode(Node* contentNode) const { ASSERT(contentNode); return m_contentNodes.contains(contentNode); } 80 bool isMarkedForDestruction() const; 81 void getRanges(Vector<RefPtr<Range> >&, const RenderRegion*) const; 82 83 protected: 84 void setMarkForDestruction(); 85 void resetMarkForDestruction(); 86 87 private: 88 RenderNamedFlowThread(PassRefPtr<NamedFlow>); 89 90 virtual const char* renderName() const OVERRIDE; 91 virtual bool isRenderNamedFlowThread() const OVERRIDE { return true; } 92 virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE; 93 94 virtual void dispatchRegionLayoutUpdateEvent() OVERRIDE; 95 virtual void dispatchRegionOversetChangeEvent() OVERRIDE; 96 97 bool dependsOn(RenderNamedFlowThread* otherRenderFlowThread) const; 98 void addDependencyOnFlowThread(RenderNamedFlowThread*); 99 void removeDependencyOnFlowThread(RenderNamedFlowThread*); 100 101 void addRegionToNamedFlowThread(RenderRegion*); 102 103 void checkInvalidRegions(); 104 105 bool canBeDestroyed() const { return m_invalidRegionList.isEmpty() && m_regionList.isEmpty() && m_contentNodes.isEmpty(); } 106 void regionLayoutUpdateEventTimerFired(Timer<RenderNamedFlowThread>*); 107 void regionOversetChangeEventTimerFired(Timer<RenderNamedFlowThread>*); 108 void clearContentNodes(); 109 void updateWritingMode(); 110 111 private: 112 // Observer flow threads have invalid regions that depend on the state of this thread 113 // to re-validate their regions. Keeping a set of observer threads make it easy 114 // to notify them when a region was removed from this flow. 115 RenderNamedFlowThreadCountedSet m_observerThreadsSet; 116 117 // Some threads need to have a complete layout before we layout this flow. 118 // That's because they contain a RenderRegion that should display this thread. The set makes it 119 // easy to sort the order of threads layout. 120 RenderNamedFlowThreadCountedSet m_layoutBeforeThreadsSet; 121 122 // Holds the sorted children of a named flow. This is the only way we can get the ordering right. 123 typedef ListHashSet<RenderObject*> FlowThreadChildList; 124 FlowThreadChildList m_flowThreadChildList; 125 126 NamedFlowContentNodes m_contentNodes; 127 128 RenderRegionList m_invalidRegionList; 129 130 bool m_overset : 1; 131 132 // The DOM Object that represents a named flow. 133 RefPtr<NamedFlow> m_namedFlow; 134 135 Timer<RenderNamedFlowThread> m_regionLayoutUpdateEventTimer; 136 Timer<RenderNamedFlowThread> m_regionOversetChangeEventTimer; 137 }; 138 139 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderNamedFlowThread, isRenderNamedFlowThread()); 140 141 } // namespace WebCore 142 143 #endif // RenderNamedFlowThread_h 144 145