File: ephemeral_range.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (165 lines) | stat: -rw-r--r-- 5,429 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_EPHEMERAL_RANGE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_EPHEMERAL_RANGE_H_

#include "base/dcheck_is_on.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/editing/position.h"

namespace blink {

class Document;
class AbstractRange;
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* past_end_node)
      : TraversalRange<Iterator>(start), past_end_node_(past_end_node) {}

  using TraversalRange<Iterator>::begin;

  Iterator end() { return Iterator(past_end_node_); }

 private:
  const StartNodeType* const past_end_node_;
};

// This class acts like |TraversalNextIterator| but in addition
// it allows to set current position and checks |current_| pointer before
// dereferencing.
template <class TraversalNext>
class CheckedTraversalNextIterator
    : public TraversalIteratorBase<TraversalNext> {
  STACK_ALLOCATED();

  using TraversalIteratorBase<TraversalNext>::current_;

 public:
  using StartNodeType = typename TraversalNext::TraversalNodeType;
  explicit CheckedTraversalNextIterator(const StartNodeType* start)
      : TraversalIteratorBase<TraversalNext>(
            const_cast<StartNodeType*>(start)) {}

  void operator++() {
    DCHECK(current_);
    current_ = TraversalNext::Next(*current_);
  }
};

// Unlike |Range| objects, |EphemeralRangeTemplate| objects aren't relocated.
// You should not use |EphemeralRangeTemplate| objects after DOM modification.
//
// EphemeralRangeTemplate is supposed to use returning or passing start and end
// position.
//
//  Example usage:
//    Range* range = produceRange();
//    consumeRange(range);
//    ... no DOM modification ...
//    consumeRange2(range);
//
//  Above code should be:
//    EphemeralRangeTemplate range = produceRange();
//    consumeRange(range);
//    ... no DOM modification ...
//    consumeRange2(range);
//
//  Because of |Range| objects consume heap memory and inserted into |Range|
//  object list in |Document| for relocation. These operations are redundant
//  if |Range| objects doesn't live after DOM mutation.
//
template <typename Strategy>
class 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.
  explicit EphemeralRangeTemplate(
      const PositionTemplate<Strategy>& /* position */);
  explicit EphemeralRangeTemplate(const AbstractRange*);
  // When |range| is nullptr, |EphemeralRangeTemplate| is |isNull()|.
  explicit EphemeralRangeTemplate(const Range* /* range */);
  EphemeralRangeTemplate();
  ~EphemeralRangeTemplate();

  EphemeralRangeTemplate<Strategy>& operator=(
      const EphemeralRangeTemplate<Strategy>& other);

  bool operator==(const EphemeralRangeTemplate<Strategy>& other) const;
  bool operator!=(const EphemeralRangeTemplate<Strategy>& other) const;

  Document& GetDocument() const;
  PositionTemplate<Strategy> StartPosition() const;
  PositionTemplate<Strategy> EndPosition() const;

  Node* CommonAncestorContainer() const;

  // Returns true if |start_position_| == |end_position_| or |isNull()|.
  bool IsCollapsed() const;
  bool IsNull() const {
    DCHECK(IsValid());
    return start_position_.IsNull();
  }
  bool IsNotNull() const { return !IsNull(); }

  RangeTraversal Nodes() const;

  // |node| should be in-document and valid for anchor node of
  // |PositionTemplate<Strategy>|.
  static EphemeralRangeTemplate<Strategy> RangeOfContents(
      const Node& /* node */);

#if DCHECK_IS_ON()
  void ShowTreeForThis() const;
#endif

 private:
  bool IsValid() const;

  PositionTemplate<Strategy> start_position_;
  PositionTemplate<Strategy> end_position_;
#if DCHECK_IS_ON()
  uint64_t dom_tree_version_;
#endif
};

extern template class CORE_EXTERN_TEMPLATE_EXPORT
    EphemeralRangeTemplate<EditingStrategy>;
using EphemeralRange = EphemeralRangeTemplate<EditingStrategy>;

extern template class CORE_EXTERN_TEMPLATE_EXPORT
    EphemeralRangeTemplate<EditingInFlatTreeStrategy>;
using EphemeralRangeInFlatTree =
    EphemeralRangeTemplate<EditingInFlatTreeStrategy>;

// Returns a newly created |Range| object from |range| or |nullptr| if
// |range.isNull()| returns true.
CORE_EXPORT Range* CreateRange(const EphemeralRange& /* range */);

CORE_EXPORT std::ostream& operator<<(std::ostream&, const EphemeralRange&);
CORE_EXPORT std::ostream& operator<<(std::ostream&,
                                     const EphemeralRangeInFlatTree&);

CORE_EXPORT EphemeralRangeInFlatTree
ToEphemeralRangeInFlatTree(const EphemeralRange&);

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_EPHEMERAL_RANGE_H_