1 /*
2  * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
3  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20 */
21 
22 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_COUNTER_NODE_H_
23 #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_COUNTER_NODE_H_
24 
25 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
26 #include "third_party/blink/renderer/platform/wtf/forward.h"
27 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
28 
29 // This implements a counter tree that is used for finding parents in counters()
30 // lookup, and for propagating count changes when nodes are added or removed.
31 
32 // Parents represent unique counters and their scope, which are created either
33 // explicitly by "counter-reset" style rules or implicitly by referring to a
34 // counter that is not in scope.
35 // Such nodes are tagged as "reset" nodes, although they are not all due to
36 // "counter-reset".
37 
38 // Not that layout tree children are often counter tree siblings due to counter
39 // scoping rules.
40 
41 namespace blink {
42 
43 class LayoutObject;
44 class LayoutCounter;
45 
46 class CounterNode : public RefCounted<CounterNode> {
47   USING_FAST_MALLOC(CounterNode);
48 
49  public:
50   static scoped_refptr<CounterNode> Create(LayoutObject&,
51                                            bool is_reset,
52                                            int value);
53   ~CounterNode();
ActsAsReset()54   bool ActsAsReset() const { return has_reset_type_ || !parent_; }
HasResetType()55   bool HasResetType() const { return has_reset_type_; }
Value()56   int Value() const { return value_; }
CountInParent()57   int CountInParent() const { return count_in_parent_; }
Owner()58   LayoutObject& Owner() const { return owner_; }
59   void AddLayoutObject(LayoutCounter*);
60   void RemoveLayoutObject(LayoutCounter*);
61 
62   // Invalidates the text in the layoutObjects of this counter, if any.
63   void ResetLayoutObjects();
64 
Parent()65   CounterNode* Parent() const { return parent_; }
PreviousSibling()66   CounterNode* PreviousSibling() const { return previous_sibling_; }
NextSibling()67   CounterNode* NextSibling() const { return next_sibling_; }
FirstChild()68   CounterNode* FirstChild() const { return first_child_; }
LastChild()69   CounterNode* LastChild() const { return last_child_; }
70   CounterNode* LastDescendant() const;
71   CounterNode* PreviousInPreOrder() const;
72   CounterNode* NextInPreOrder(const CounterNode* stay_within = nullptr) const;
73   CounterNode* NextInPreOrderAfterChildren(
74       const CounterNode* stay_within = nullptr) const;
75 
76   void InsertAfter(CounterNode* new_child,
77                    CounterNode* before_child,
78                    const AtomicString& identifier);
79 
80   // identifier must match the identifier of this counter.
81   void RemoveChild(CounterNode*);
82 
83   // Moves all non-reset next siblings of first_node to be children of
84   // new_parent. Used when we insert new reset nodes that requires reparenting
85   // existing nodes.
86   static void MoveNonResetSiblingsToChildOf(CounterNode* first_node,
87                                             CounterNode& new_parent,
88                                             const AtomicString& identifier);
89 
90  private:
91   CounterNode(LayoutObject&, bool is_reset, int value);
92   int ComputeCountInParent() const;
93   // Invalidates the text in the layoutObject of this counter, if any,
94   // and in the layoutObjects of all descendants of this counter, if any.
95   void ResetThisAndDescendantsLayoutObjects();
96   void Recount();
97 
98   bool has_reset_type_;
99   int value_;
100   int count_in_parent_;
101   LayoutObject& owner_;
102   LayoutCounter* root_layout_object_;
103 
104   CounterNode* parent_;
105   CounterNode* previous_sibling_;
106   CounterNode* next_sibling_;
107   CounterNode* first_child_;
108   CounterNode* last_child_;
109 };
110 
111 }  // namespace blink
112 
113 #if DCHECK_IS_ON()
114 // Outside the blink namespace for ease of invocation from gdb.
115 void showCounterTree(const blink::CounterNode*);
116 #endif
117 
118 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_COUNTER_NODE_H_
119