Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef EphemeralRange_h | 5 #ifndef EphemeralRange_h |
| 6 #define EphemeralRange_h | 6 #define EphemeralRange_h |
| 7 | 7 |
| 8 #include "core/editing/Position.h" | 8 #include "core/editing/Position.h" |
| 9 | 9 |
| 10 namespace blink { | 10 namespace blink { |
| 11 | 11 |
| 12 class Document; | 12 class Document; |
| 13 class Range; | 13 class Range; |
| 14 | 14 |
| 15 // We should restrict access to the unwanted version of |TraversalRange::end()| function. | |
| 16 template <class Iterator> | |
| 17 class TraversalRangeNodes : private TraversalRange<Iterator> { | |
| 18 STACK_ALLOCATED(); | |
| 19 public: | |
| 20 using StartNodeType = typename TraversalRange<Iterator>::StartNodeType; | |
| 21 TraversalRangeNodes(const StartNodeType* start, const StartNodeType* pastEnd Node) | |
| 22 : TraversalRange<Iterator>(start), m_pastEndNode(pastEndNode) { } | |
| 23 | |
| 24 using TraversalRange<Iterator>::begin; | |
| 25 | |
| 26 Iterator end() { return Iterator(m_pastEndNode); } | |
| 27 | |
| 28 private: | |
| 29 const Member<const StartNodeType> m_pastEndNode; | |
| 30 }; | |
| 31 | |
| 32 // This class acts like |TraversalNextIterator| but in addition | |
| 33 // it allows to set current position and checks |m_current| pointer before | |
| 34 // dereferencing. | |
| 35 template <class TraversalNext> | |
| 36 class CheckedTraversalNextIterator : public TraversalIteratorBase<TraversalNext> { | |
| 37 STACK_ALLOCATED(); | |
| 38 | |
| 39 using TraversalIteratorBase<TraversalNext>::m_current; | |
| 40 public: | |
| 41 using StartNodeType = typename TraversalNext::TraversalNodeType; | |
| 42 explicit CheckedTraversalNextIterator(const StartNodeType* start) : Traversa lIteratorBase<TraversalNext>(const_cast<StartNodeType*>(start)) { } | |
| 43 | |
| 44 void operator++() | |
|
yosin_UTC9
2016/08/18 02:11:09
Interesting, I never know we can implement |operat
Andrey Kraynov
2016/08/18 10:16:33
Yep, |operator++()| is just a regular function =)
| |
| 45 { | |
| 46 DCHECK(m_current); | |
| 47 m_current = TraversalNext::next(*m_current); | |
| 48 } | |
| 49 bool isNull() const { return !m_current; } | |
|
yosin_UTC9
2016/08/18 02:11:09
We may not want to have |isNull()| and |setCurrent
Andrey Kraynov
2016/08/18 10:16:33
Done.
| |
| 50 void setCurrent(Node* current) { m_current = current; } | |
| 51 }; | |
| 52 | |
| 15 // Unlike |Range| objects, |EphemeralRangeTemplate| objects aren't relocated. | 53 // Unlike |Range| objects, |EphemeralRangeTemplate| objects aren't relocated. |
| 16 // You should not use |EphemeralRangeTemplate| objects after DOM modification. | 54 // You should not use |EphemeralRangeTemplate| objects after DOM modification. |
| 17 // | 55 // |
| 18 // EphemeralRangeTemplate is supposed to use returning or passing start and end | 56 // EphemeralRangeTemplate is supposed to use returning or passing start and end |
| 19 // position. | 57 // position. |
| 20 // | 58 // |
| 21 // Example usage: | 59 // Example usage: |
| 22 // Range* range = produceRange(); | 60 // Range* range = produceRange(); |
| 23 // consumeRange(range); | 61 // consumeRange(range); |
| 24 // ... no DOM modification ... | 62 // ... no DOM modification ... |
| 25 // consumeRange2(range); | 63 // consumeRange2(range); |
| 26 // | 64 // |
| 27 // Above code should be: | 65 // Above code should be: |
| 28 // EphemeralRangeTemplate range = produceRange(); | 66 // EphemeralRangeTemplate range = produceRange(); |
| 29 // consumeRange(range); | 67 // consumeRange(range); |
| 30 // ... no DOM modification ... | 68 // ... no DOM modification ... |
| 31 // consumeRange2(range); | 69 // consumeRange2(range); |
| 32 // | 70 // |
| 33 // Because of |Range| objects consume heap memory and inserted into |Range| | 71 // Because of |Range| objects consume heap memory and inserted into |Range| |
| 34 // object list in |Document| for relocation. These operations are redundant | 72 // object list in |Document| for relocation. These operations are redundant |
| 35 // if |Range| objects doesn't live after DOM mutation. | 73 // if |Range| objects doesn't live after DOM mutation. |
| 36 // | 74 // |
| 37 template <typename Strategy> | 75 template <typename Strategy> |
| 38 class CORE_TEMPLATE_CLASS_EXPORT EphemeralRangeTemplate final { | 76 class CORE_TEMPLATE_CLASS_EXPORT EphemeralRangeTemplate final { |
| 39 STACK_ALLOCATED(); | 77 STACK_ALLOCATED(); |
| 40 public: | 78 public: |
| 79 using RangeTraversal = TraversalRangeNodes<CheckedTraversalNextIterator<Stra tegy>>; | |
| 80 | |
| 41 EphemeralRangeTemplate(const PositionTemplate<Strategy>& start, const Positi onTemplate<Strategy>& end); | 81 EphemeralRangeTemplate(const PositionTemplate<Strategy>& start, const Positi onTemplate<Strategy>& end); |
| 42 EphemeralRangeTemplate(const EphemeralRangeTemplate& other); | 82 EphemeralRangeTemplate(const EphemeralRangeTemplate& other); |
| 43 // |position| should be |Position::isNull()| or in-document. | 83 // |position| should be |Position::isNull()| or in-document. |
| 44 explicit EphemeralRangeTemplate(const PositionTemplate<Strategy>& /* positio n */); | 84 explicit EphemeralRangeTemplate(const PositionTemplate<Strategy>& /* positio n */); |
| 45 // When |range| is nullptr, |EphemeralRangeTemplate| is |isNull()|. | 85 // When |range| is nullptr, |EphemeralRangeTemplate| is |isNull()|. |
| 46 explicit EphemeralRangeTemplate(const Range* /* range */); | 86 explicit EphemeralRangeTemplate(const Range* /* range */); |
| 47 EphemeralRangeTemplate(); | 87 EphemeralRangeTemplate(); |
| 48 ~EphemeralRangeTemplate(); | 88 ~EphemeralRangeTemplate(); |
| 49 | 89 |
| 50 EphemeralRangeTemplate<Strategy>& operator=(const EphemeralRangeTemplate<Str ategy>& other); | 90 EphemeralRangeTemplate<Strategy>& operator=(const EphemeralRangeTemplate<Str ategy>& other); |
| 51 | 91 |
| 52 bool operator==(const EphemeralRangeTemplate<Strategy>& other) const; | 92 bool operator==(const EphemeralRangeTemplate<Strategy>& other) const; |
| 53 bool operator!=(const EphemeralRangeTemplate<Strategy>& other) const; | 93 bool operator!=(const EphemeralRangeTemplate<Strategy>& other) const; |
| 54 | 94 |
| 55 Document& document() const; | 95 Document& document() const; |
| 56 PositionTemplate<Strategy> startPosition() const; | 96 PositionTemplate<Strategy> startPosition() const; |
| 57 PositionTemplate<Strategy> endPosition() const; | 97 PositionTemplate<Strategy> endPosition() const; |
| 58 | 98 |
| 59 // Returns true if |m_startPositoin| == |m_endPosition| or |isNull()|. | 99 // Returns true if |m_startPositoin| == |m_endPosition| or |isNull()|. |
| 60 bool isCollapsed() const; | 100 bool isCollapsed() const; |
| 61 bool isNull() const | 101 bool isNull() const |
| 62 { | 102 { |
| 63 DCHECK(isValid()); | 103 DCHECK(isValid()); |
| 64 return m_startPosition.isNull(); | 104 return m_startPosition.isNull(); |
| 65 } | 105 } |
| 66 bool isNotNull() const { return !isNull(); } | 106 bool isNotNull() const { return !isNull(); } |
| 67 | 107 |
| 108 RangeTraversal nodes() const; | |
| 109 | |
| 68 DEFINE_INLINE_TRACE() | 110 DEFINE_INLINE_TRACE() |
| 69 { | 111 { |
| 70 visitor->trace(m_startPosition); | 112 visitor->trace(m_startPosition); |
| 71 visitor->trace(m_endPosition); | 113 visitor->trace(m_endPosition); |
| 72 } | 114 } |
| 73 | 115 |
| 74 // |node| should be in-document and valid for anchor node of | 116 // |node| should be in-document and valid for anchor node of |
| 75 // |PositionTemplate<Strategy>|. | 117 // |PositionTemplate<Strategy>|. |
| 76 static EphemeralRangeTemplate<Strategy> rangeOfContents(const Node& /* node */); | 118 static EphemeralRangeTemplate<Strategy> rangeOfContents(const Node& /* node */); |
| 77 | 119 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 91 extern template class CORE_EXTERN_TEMPLATE_EXPORT EphemeralRangeTemplate<Editing InFlatTreeStrategy>; | 133 extern template class CORE_EXTERN_TEMPLATE_EXPORT EphemeralRangeTemplate<Editing InFlatTreeStrategy>; |
| 92 using EphemeralRangeInFlatTree = EphemeralRangeTemplate<EditingInFlatTreeStrateg y>; | 134 using EphemeralRangeInFlatTree = EphemeralRangeTemplate<EditingInFlatTreeStrateg y>; |
| 93 | 135 |
| 94 // Returns a newly created |Range| object from |range| or |nullptr| if | 136 // Returns a newly created |Range| object from |range| or |nullptr| if |
| 95 // |range.isNull()| returns true. | 137 // |range.isNull()| returns true. |
| 96 CORE_EXPORT Range* createRange(const EphemeralRange& /* range */); | 138 CORE_EXPORT Range* createRange(const EphemeralRange& /* range */); |
| 97 | 139 |
| 98 } // namespace blink | 140 } // namespace blink |
| 99 | 141 |
| 100 #endif | 142 #endif |
| OLD | NEW |