Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/EphemeralRange.h |
| diff --git a/third_party/WebKit/Source/core/editing/EphemeralRange.h b/third_party/WebKit/Source/core/editing/EphemeralRange.h |
| index 5512100955b9ffc4b3645580a3fe62002ab97e87..fd76e4779a20eeedf8a6d85fea6f93060d026ddd 100644 |
| --- a/third_party/WebKit/Source/core/editing/EphemeralRange.h |
| +++ b/third_party/WebKit/Source/core/editing/EphemeralRange.h |
| @@ -12,6 +12,44 @@ namespace blink { |
| class Document; |
| class Range; |
| +// We should restrict access to the unwanted version of |TraversalRange::end()| function. |
| +template <class Iterator> |
| +class TraversalRangeNodes : private TraversalRange<Iterator> { |
| + STACK_ALLOCATED(); |
| +public: |
| + using StartNodeType = typename TraversalRange<Iterator>::StartNodeType; |
| + TraversalRangeNodes(const StartNodeType* start, const StartNodeType* pastEndNode) |
| + : TraversalRange<Iterator>(start), m_pastEndNode(pastEndNode) { } |
| + |
| + using TraversalRange<Iterator>::begin; |
| + |
| + Iterator end() { return Iterator(m_pastEndNode); } |
| + |
| +private: |
| + const Member<const StartNodeType> m_pastEndNode; |
| +}; |
| + |
| +// This class acts like |TraversalNextIterator| but in addition |
| +// it allows to set current position and checks |m_current| pointer before |
| +// dereferencing. |
| +template <class TraversalNext> |
| +class CheckedTraversalNextIterator : public TraversalIteratorBase<TraversalNext> { |
| + STACK_ALLOCATED(); |
| + |
| + using TraversalIteratorBase<TraversalNext>::m_current; |
| +public: |
| + using StartNodeType = typename TraversalNext::TraversalNodeType; |
| + explicit CheckedTraversalNextIterator(const StartNodeType* start) : TraversalIteratorBase<TraversalNext>(const_cast<StartNodeType*>(start)) { } |
| + |
| + 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 =)
|
| + { |
| + DCHECK(m_current); |
| + m_current = TraversalNext::next(*m_current); |
| + } |
| + 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.
|
| + void setCurrent(Node* current) { m_current = current; } |
| +}; |
| + |
| // Unlike |Range| objects, |EphemeralRangeTemplate| objects aren't relocated. |
| // You should not use |EphemeralRangeTemplate| objects after DOM modification. |
| // |
| @@ -38,6 +76,8 @@ template <typename Strategy> |
| class CORE_TEMPLATE_CLASS_EXPORT EphemeralRangeTemplate final { |
| STACK_ALLOCATED(); |
| public: |
| + using RangeTraversal = TraversalRangeNodes<CheckedTraversalNextIterator<Strategy>>; |
| + |
| EphemeralRangeTemplate(const PositionTemplate<Strategy>& start, const PositionTemplate<Strategy>& end); |
| EphemeralRangeTemplate(const EphemeralRangeTemplate& other); |
| // |position| should be |Position::isNull()| or in-document. |
| @@ -65,6 +105,8 @@ public: |
| } |
| bool isNotNull() const { return !isNull(); } |
| + RangeTraversal nodes() const; |
| + |
| DEFINE_INLINE_TRACE() |
| { |
| visitor->trace(m_startPosition); |