| 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++() |
| 45 { |
| 46 DCHECK(m_current); |
| 47 m_current = TraversalNext::next(*m_current); |
| 48 } |
| 49 }; |
| 50 |
| 15 // Unlike |Range| objects, |EphemeralRangeTemplate| objects aren't relocated. | 51 // Unlike |Range| objects, |EphemeralRangeTemplate| objects aren't relocated. |
| 16 // You should not use |EphemeralRangeTemplate| objects after DOM modification. | 52 // You should not use |EphemeralRangeTemplate| objects after DOM modification. |
| 17 // | 53 // |
| 18 // EphemeralRangeTemplate is supposed to use returning or passing start and end | 54 // EphemeralRangeTemplate is supposed to use returning or passing start and end |
| 19 // position. | 55 // position. |
| 20 // | 56 // |
| 21 // Example usage: | 57 // Example usage: |
| 22 // Range* range = produceRange(); | 58 // Range* range = produceRange(); |
| 23 // consumeRange(range); | 59 // consumeRange(range); |
| 24 // ... no DOM modification ... | 60 // ... no DOM modification ... |
| 25 // consumeRange2(range); | 61 // consumeRange2(range); |
| 26 // | 62 // |
| 27 // Above code should be: | 63 // Above code should be: |
| 28 // EphemeralRangeTemplate range = produceRange(); | 64 // EphemeralRangeTemplate range = produceRange(); |
| 29 // consumeRange(range); | 65 // consumeRange(range); |
| 30 // ... no DOM modification ... | 66 // ... no DOM modification ... |
| 31 // consumeRange2(range); | 67 // consumeRange2(range); |
| 32 // | 68 // |
| 33 // Because of |Range| objects consume heap memory and inserted into |Range| | 69 // Because of |Range| objects consume heap memory and inserted into |Range| |
| 34 // object list in |Document| for relocation. These operations are redundant | 70 // object list in |Document| for relocation. These operations are redundant |
| 35 // if |Range| objects doesn't live after DOM mutation. | 71 // if |Range| objects doesn't live after DOM mutation. |
| 36 // | 72 // |
| 37 template <typename Strategy> | 73 template <typename Strategy> |
| 38 class CORE_TEMPLATE_CLASS_EXPORT EphemeralRangeTemplate final { | 74 class CORE_TEMPLATE_CLASS_EXPORT EphemeralRangeTemplate final { |
| 39 STACK_ALLOCATED(); | 75 STACK_ALLOCATED(); |
| 40 public: | 76 public: |
| 77 using RangeTraversal = TraversalRangeNodes<CheckedTraversalNextIterator<Stra
tegy>>; |
| 78 |
| 41 EphemeralRangeTemplate(const PositionTemplate<Strategy>& start, const Positi
onTemplate<Strategy>& end); | 79 EphemeralRangeTemplate(const PositionTemplate<Strategy>& start, const Positi
onTemplate<Strategy>& end); |
| 42 EphemeralRangeTemplate(const EphemeralRangeTemplate& other); | 80 EphemeralRangeTemplate(const EphemeralRangeTemplate& other); |
| 43 // |position| should be |Position::isNull()| or in-document. | 81 // |position| should be |Position::isNull()| or in-document. |
| 44 explicit EphemeralRangeTemplate(const PositionTemplate<Strategy>& /* positio
n */); | 82 explicit EphemeralRangeTemplate(const PositionTemplate<Strategy>& /* positio
n */); |
| 45 // When |range| is nullptr, |EphemeralRangeTemplate| is |isNull()|. | 83 // When |range| is nullptr, |EphemeralRangeTemplate| is |isNull()|. |
| 46 explicit EphemeralRangeTemplate(const Range* /* range */); | 84 explicit EphemeralRangeTemplate(const Range* /* range */); |
| 47 EphemeralRangeTemplate(); | 85 EphemeralRangeTemplate(); |
| 48 ~EphemeralRangeTemplate(); | 86 ~EphemeralRangeTemplate(); |
| 49 | 87 |
| 50 EphemeralRangeTemplate<Strategy>& operator=(const EphemeralRangeTemplate<Str
ategy>& other); | 88 EphemeralRangeTemplate<Strategy>& operator=(const EphemeralRangeTemplate<Str
ategy>& other); |
| 51 | 89 |
| 52 bool operator==(const EphemeralRangeTemplate<Strategy>& other) const; | 90 bool operator==(const EphemeralRangeTemplate<Strategy>& other) const; |
| 53 bool operator!=(const EphemeralRangeTemplate<Strategy>& other) const; | 91 bool operator!=(const EphemeralRangeTemplate<Strategy>& other) const; |
| 54 | 92 |
| 55 Document& document() const; | 93 Document& document() const; |
| 56 PositionTemplate<Strategy> startPosition() const; | 94 PositionTemplate<Strategy> startPosition() const; |
| 57 PositionTemplate<Strategy> endPosition() const; | 95 PositionTemplate<Strategy> endPosition() const; |
| 58 | 96 |
| 59 // Returns true if |m_startPositoin| == |m_endPosition| or |isNull()|. | 97 // Returns true if |m_startPositoin| == |m_endPosition| or |isNull()|. |
| 60 bool isCollapsed() const; | 98 bool isCollapsed() const; |
| 61 bool isNull() const | 99 bool isNull() const |
| 62 { | 100 { |
| 63 DCHECK(isValid()); | 101 DCHECK(isValid()); |
| 64 return m_startPosition.isNull(); | 102 return m_startPosition.isNull(); |
| 65 } | 103 } |
| 66 bool isNotNull() const { return !isNull(); } | 104 bool isNotNull() const { return !isNull(); } |
| 67 | 105 |
| 106 RangeTraversal nodes() const; |
| 107 |
| 68 DEFINE_INLINE_TRACE() | 108 DEFINE_INLINE_TRACE() |
| 69 { | 109 { |
| 70 visitor->trace(m_startPosition); | 110 visitor->trace(m_startPosition); |
| 71 visitor->trace(m_endPosition); | 111 visitor->trace(m_endPosition); |
| 72 } | 112 } |
| 73 | 113 |
| 74 // |node| should be in-document and valid for anchor node of | 114 // |node| should be in-document and valid for anchor node of |
| 75 // |PositionTemplate<Strategy>|. | 115 // |PositionTemplate<Strategy>|. |
| 76 static EphemeralRangeTemplate<Strategy> rangeOfContents(const Node& /* node
*/); | 116 static EphemeralRangeTemplate<Strategy> rangeOfContents(const Node& /* node
*/); |
| 77 | 117 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 91 extern template class CORE_EXTERN_TEMPLATE_EXPORT EphemeralRangeTemplate<Editing
InFlatTreeStrategy>; | 131 extern template class CORE_EXTERN_TEMPLATE_EXPORT EphemeralRangeTemplate<Editing
InFlatTreeStrategy>; |
| 92 using EphemeralRangeInFlatTree = EphemeralRangeTemplate<EditingInFlatTreeStrateg
y>; | 132 using EphemeralRangeInFlatTree = EphemeralRangeTemplate<EditingInFlatTreeStrateg
y>; |
| 93 | 133 |
| 94 // Returns a newly created |Range| object from |range| or |nullptr| if | 134 // Returns a newly created |Range| object from |range| or |nullptr| if |
| 95 // |range.isNull()| returns true. | 135 // |range.isNull()| returns true. |
| 96 CORE_EXPORT Range* createRange(const EphemeralRange& /* range */); | 136 CORE_EXPORT Range* createRange(const EphemeralRange& /* range */); |
| 97 | 137 |
| 98 } // namespace blink | 138 } // namespace blink |
| 99 | 139 |
| 100 #endif | 140 #endif |
| OLD | NEW |