Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/editor/libeditor/WSRunObject.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef WSRunObject_h
7
#define WSRunObject_h
8
9
#include "nsCOMPtr.h"
10
#include "nsIEditor.h" // for EDirection
11
#include "nsINode.h"
12
#include "nscore.h"
13
#include "mozilla/Attributes.h"
14
#include "mozilla/dom/Text.h"
15
#include "mozilla/EditorDOMPoint.h" // for EditorDOMPoint
16
17
namespace mozilla {
18
19
class HTMLEditor;
20
class HTMLEditRules;
21
22
// class WSRunObject represents the entire whitespace situation
23
// around a given point.  It collects up a list of nodes that contain
24
// whitespace and categorizes in up to 3 different WSFragments (detailed
25
// below).  Each WSFragment is a collection of whitespace that is
26
// either all insignificant, or that is significant.  A WSFragment could
27
// consist of insignificant whitespace because it is after a block
28
// boundary or after a break.  Or it could be insignificant because it
29
// is before a block.  Or it could be significant because it is
30
// surrounded by text, or starts and ends with nbsps, etc.
31
32
// Throughout I refer to LeadingWS, NormalWS, TrailingWS.  LeadingWS & TrailingWS
33
// are runs of ascii ws that are insignificant (do not render) because they
34
// are adjacent to block boundaries, or after a break.  NormalWS is ws that
35
// does cause soem rendering.  Note that not all the ws in a NormalWS run need
36
// render.  For example, two ascii spaces surrounded by text on both sides
37
// will only render as one space (in non-preformatted stlye html), yet both
38
// spaces count as NormalWS.  Together, they render as the one visible space.
39
40
/**
41
 * A type-safe bitfield indicating various types of whitespace or other things.
42
 * Used as a member variable in WSRunObject and WSFragment.
43
 *
44
 * XXX: If this idea is useful in other places, we should generalize it using a
45
 * template.
46
 */
47
class WSType
48
{
49
public:
50
  enum Enum
51
  {
52
    none       = 0,
53
    leadingWS  = 1,      // leading insignificant ws, ie, after block or br
54
    trailingWS = 1 << 1, // trailing insignificant ws, ie, before block
55
    normalWS   = 1 << 2, // normal significant ws, ie, after text, image, ...
56
    text       = 1 << 3, // indicates regular (non-ws) text
57
    special    = 1 << 4, // indicates an inline non-container, like image
58
    br         = 1 << 5, // indicates a br node
59
    otherBlock = 1 << 6, // indicates a block other than one ws run is in
60
    thisBlock  = 1 << 7, // indicates the block ws run is in
61
    block      = otherBlock | thisBlock // block found
62
  };
63
64
  /**
65
   * Implicit constructor, because the enums are logically just WSTypes
66
   * themselves, and are only a separate type because there's no other obvious
67
   * way to name specific WSType values.
68
   */
69
  MOZ_IMPLICIT WSType(const Enum& aEnum = none)
70
    : mEnum(aEnum)
71
0
  {}
72
73
  // operator==, &, and | need to access mEnum
74
  friend bool operator==(const WSType& aLeft, const WSType& aRight);
75
  friend const WSType operator&(const WSType& aLeft, const WSType& aRight);
76
  friend const WSType operator|(const WSType& aLeft, const WSType& aRight);
77
  WSType& operator=(const WSType& aOther)
78
0
  {
79
0
    // This handles self-assignment fine
80
0
    mEnum = aOther.mEnum;
81
0
    return *this;
82
0
  }
83
  WSType& operator&=(const WSType& aOther)
84
0
  {
85
0
    mEnum &= aOther.mEnum;
86
0
    return *this;
87
0
  }
88
  WSType& operator|=(const WSType& aOther)
89
0
  {
90
0
    mEnum |= aOther.mEnum;
91
0
    return *this;
92
0
  }
93
94
private:
95
  uint16_t mEnum;
96
0
  void bool_conversion_helper() {}
97
98
public:
99
  // Allow boolean conversion with no numeric conversion
100
  typedef void (WSType::*bool_type)();
101
  operator bool_type() const
102
0
  {
103
0
    return mEnum ? &WSType::bool_conversion_helper : nullptr;
104
0
  }
105
};
106
107
/**
108
 * These are declared as global functions so "WSType::Enum == WSType" et al.
109
 * will work using the implicit constructor.
110
 */
111
inline bool operator==(const WSType& aLeft, const WSType& aRight)
112
0
{
113
0
  return aLeft.mEnum == aRight.mEnum;
114
0
}
115
116
inline bool operator!=(const WSType& aLeft, const WSType& aRight)
117
0
{
118
0
  return !(aLeft == aRight);
119
0
}
120
121
inline const WSType operator&(const WSType& aLeft, const WSType& aRight)
122
0
{
123
0
  WSType ret;
124
0
  ret.mEnum = aLeft.mEnum & aRight.mEnum;
125
0
  return ret;
126
0
}
127
128
inline const WSType operator|(const WSType& aLeft, const WSType& aRight)
129
0
{
130
0
  WSType ret;
131
0
  ret.mEnum = aLeft.mEnum | aRight.mEnum;
132
0
  return ret;
133
0
}
134
135
/**
136
 * Make sure that & and | of WSType::Enum creates a WSType instead of an int,
137
 * because operators between WSType and int shouldn't work
138
 */
139
inline const WSType operator&(const WSType::Enum& aLeft,
140
                              const WSType::Enum& aRight)
141
0
{
142
0
  return WSType(aLeft) & WSType(aRight);
143
0
}
144
145
inline const WSType operator|(const WSType::Enum& aLeft,
146
                              const WSType::Enum& aRight)
147
0
{
148
0
  return WSType(aLeft) | WSType(aRight);
149
0
}
150
151
class MOZ_STACK_CLASS WSRunObject final
152
{
153
public:
154
  enum BlockBoundary
155
  {
156
    kBeforeBlock,
157
    kBlockStart,
158
    kBlockEnd,
159
    kAfterBlock
160
  };
161
162
  enum {eBefore = 1};
163
  enum {eAfter  = 1 << 1};
164
  enum {eBoth   = eBefore | eAfter};
165
166
  template<typename PT, typename CT>
167
  WSRunObject(HTMLEditor* aHTMLEditor,
168
              const EditorDOMPointBase<PT, CT>& aPoint);
169
  WSRunObject(HTMLEditor* aHTMLEditor, nsINode* aNode, int32_t aOffset);
170
  ~WSRunObject();
171
172
  // ScrubBlockBoundary removes any non-visible whitespace at the specified
173
  // location relative to a block node.
174
  static nsresult ScrubBlockBoundary(HTMLEditor* aHTMLEditor,
175
                                     BlockBoundary aBoundary,
176
                                     nsINode* aBlock,
177
                                     int32_t aOffset = -1);
178
179
  // PrepareToJoinBlocks fixes up ws at the end of aLeftBlock and the
180
  // beginning of aRightBlock in preperation for them to be joined.  Example
181
  // of fixup: trailingws in aLeftBlock needs to be removed.
182
  static nsresult PrepareToJoinBlocks(HTMLEditor* aHTMLEditor,
183
                                      dom::Element* aLeftBlock,
184
                                      dom::Element* aRightBlock);
185
186
  // PrepareToDeleteRange fixes up ws before {aStartNode,aStartOffset}
187
  // and after {aEndNode,aEndOffset} in preperation for content
188
  // in that range to be deleted.  Note that the nodes and offsets
189
  // are adjusted in response to any dom changes we make while
190
  // adjusting ws.
191
  // example of fixup: trailingws before {aStartNode,aStartOffset}
192
  //                   needs to be removed.
193
  static nsresult PrepareToDeleteRange(HTMLEditor* aHTMLEditor,
194
                                       nsCOMPtr<nsINode>* aStartNode,
195
                                       int32_t* aStartOffset,
196
                                       nsCOMPtr<nsINode>* aEndNode,
197
                                       int32_t* aEndOffset);
198
199
  // PrepareToDeleteNode fixes up ws before and after aContent in preparation
200
  // for aContent to be deleted.  Example of fixup: trailingws before
201
  // aContent needs to be removed.
202
  static nsresult PrepareToDeleteNode(HTMLEditor* aHTMLEditor,
203
                                      nsIContent* aContent);
204
205
  // PrepareToSplitAcrossBlocks fixes up ws before and after
206
  // {aSplitNode,aSplitOffset} in preparation for a block parent to be split.
207
  // Note that the aSplitNode and aSplitOffset are adjusted in response to
208
  // any DOM changes we make while adjusting ws.  Example of fixup: normalws
209
  // before {aSplitNode,aSplitOffset} needs to end with nbsp.
210
  static nsresult PrepareToSplitAcrossBlocks(HTMLEditor* aHTMLEditor,
211
                                             nsCOMPtr<nsINode>* aSplitNode,
212
                                             int32_t* aSplitOffset);
213
214
  /**
215
   * InsertBreak() inserts a <br> node at (before) aPointToInsert and delete
216
   * unnecessary whitespaces around there and/or replaces whitespaces with
217
   * non-breaking spaces.  Note that if the point is in a text node, the
218
   * text node will be split and insert new <br> node between the left node
219
   * and the right node.
220
   *
221
   * @param aSelection      The selection for the editor.
222
   * @param aPointToInsert  The point to insert new <br> element.  Note that
223
   *                        it'll be inserted before this point.  I.e., the
224
   *                        point will be the point of new <br>.
225
   * @param aSelect         If eNone, this won't change selection.
226
   *                        If eNext, selection will be collapsed after the
227
   *                        <br> element.
228
   *                        If ePrevious, selection will be collapsed at the
229
   *                        <br> element.
230
   * @return                The new <br> node.  If failed to create new <br>
231
   *                        node, returns nullptr.
232
   */
233
  template<typename PT, typename CT>
234
  already_AddRefed<dom::Element>
235
  InsertBreak(Selection& aSelection,
236
              const EditorDOMPointBase<PT, CT>& aPointToInsert,
237
              nsIEditor::EDirection aSelect);
238
239
  /**
240
   * InsertText() inserts aStringToInsert to aPointToInsert and makes any
241
   * needed adjustments to white spaces around that point. E.g., trailing white
242
   * spaces before aPointToInsert needs to be removed.
243
   * This calls EditorBase::InsertTextWithTransaction() after adjusting white
244
   * spaces.  So, please refer the method's explanation to know what this
245
   * method exactly does.
246
   *
247
   * @param aDocument       The document of this editor.
248
   * @param aStringToInsert The string to insert.
249
   * @param aPointToInser   The point to insert aStringToInsert.
250
   *                        Must be valid DOM point.
251
   * @param aPointAfterInsertedString
252
   *                        The point after inserted aStringToInsert.
253
   *                        So, when this method actually inserts string,
254
   *                        this is set to a point in the text node.
255
   *                        Otherwise, this may be set to aPointToInsert.
256
   * @return                When this succeeds to insert the string or
257
   *                        does nothing during composition, returns NS_OK.
258
   *                        Otherwise, an error code.
259
   */
260
  template<typename PT, typename CT>
261
  nsresult InsertText(nsIDocument& aDocument,
262
                      const nsAString& aStringToInsert,
263
                      const EditorDOMPointBase<PT, CT>& aPointToInsert,
264
                      EditorRawDOMPoint* aPointAfterInsertedString = nullptr);
265
266
  // DeleteWSBackward deletes a single visible piece of ws before the ws
267
  // point (the point to create the wsRunObject, passed to its constructor).
268
  // It makes any needed conversion to adjacent ws to retain its
269
  // significance.
270
  nsresult DeleteWSBackward();
271
272
  // DeleteWSForward deletes a single visible piece of ws after the ws point
273
  // (the point to create the wsRunObject, passed to its constructor).  It
274
  // makes any needed conversion to adjacent ws to retain its significance.
275
  nsresult DeleteWSForward();
276
277
  // PriorVisibleNode() returns the first piece of visible thing before aPoint.
278
  // If there is no visible ws qualifying it returns what is before the ws run.
279
  // If outVisNode and/or outvisOffset is unused, callers can use nullptr.
280
  // Note that {outVisNode,outVisOffset} is set to just AFTER the visible
281
  // object. Also outVisOffset might be invalid offset unless outVisNode is
282
  // start reason node.
283
  template<typename PT, typename CT>
284
  void PriorVisibleNode(const EditorDOMPointBase<PT, CT>& aPoint,
285
                        nsCOMPtr<nsINode>* outVisNode,
286
                        int32_t* outVisOffset,
287
                        WSType* outType) const;
288
289
  template<typename PT, typename CT>
290
  void PriorVisibleNode(const EditorDOMPointBase<PT, CT>& aPoint,
291
                        WSType* outType) const
292
0
  {
293
0
    PriorVisibleNode(aPoint, nullptr, nullptr, outType);
294
0
  }
Unexecuted instantiation: void mozilla::WSRunObject::PriorVisibleNode<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> >(mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&, mozilla::WSType*) const
Unexecuted instantiation: void mozilla::WSRunObject::PriorVisibleNode<nsINode*, nsIContent*>(mozilla::EditorDOMPointBase<nsINode*, nsIContent*> const&, mozilla::WSType*) const
295
296
297
  // NextVisibleNode() returns the first piece of visible thing after aPoint.
298
  // If there is no visible ws qualifying it returns what is after the ws run.
299
  // If outVisNode and/or outvisOffset is unused, callers can use nullptr.
300
  // Note that {outVisNode,outVisOffset} is set to just BEFORE the visible
301
  // object. Also outVisOffset might be invalid offset unless outVisNode is
302
  // end reason node.
303
  template<typename PT, typename CT>
304
  void NextVisibleNode(const EditorDOMPointBase<PT, CT>& aPoint,
305
                       nsCOMPtr<nsINode>* outVisNode,
306
                       int32_t* outVisOffset,
307
                       WSType* outType) const;
308
309
  template<typename PT, typename CT>
310
  void NextVisibleNode(const EditorDOMPointBase<PT, CT>& aPoint,
311
                       WSType* outType) const
312
0
  {
313
0
    NextVisibleNode(aPoint, nullptr, nullptr, outType);
314
0
  }
Unexecuted instantiation: void mozilla::WSRunObject::NextVisibleNode<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> >(mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&, mozilla::WSType*) const
Unexecuted instantiation: void mozilla::WSRunObject::NextVisibleNode<nsINode*, nsIContent*>(mozilla::EditorDOMPointBase<nsINode*, nsIContent*> const&, mozilla::WSType*) const
315
316
  // AdjustWhitespace examines the ws object for nbsp's that can
317
  // be safely converted to regular ascii space and converts them.
318
  nsresult AdjustWhitespace();
319
320
protected:
321
  // WSFragment represents a single run of ws (all leadingws, or all normalws,
322
  // or all trailingws, or all leading+trailingws).  Note that this single run
323
  // may still span multiple nodes.
324
  struct WSFragment final
325
  {
326
    nsCOMPtr<nsINode> mStartNode;  // node where ws run starts
327
    nsCOMPtr<nsINode> mEndNode;    // node where ws run ends
328
    int32_t mStartOffset;          // offset where ws run starts
329
    int32_t mEndOffset;            // offset where ws run ends
330
    // type of ws, and what is to left and right of it
331
    WSType mType, mLeftType, mRightType;
332
    // other ws runs to left or right.  may be null.
333
    WSFragment *mLeft, *mRight;
334
335
    WSFragment()
336
      : mStartOffset(0)
337
      , mEndOffset(0)
338
      , mLeft(nullptr)
339
      , mRight(nullptr)
340
0
    {}
341
342
    EditorRawDOMPoint StartPoint() const
343
0
    {
344
0
      return EditorRawDOMPoint(mStartNode, mStartOffset);
345
0
    }
346
    EditorRawDOMPoint EndPoint() const
347
0
    {
348
0
      return EditorRawDOMPoint(mEndNode, mEndOffset);
349
0
    }
350
  };
351
352
  // A WSPoint struct represents a unique location within the ws run.  It is
353
  // always within a textnode that is one of the nodes stored in the list
354
  // in the wsRunObject.  For convenience, the character at that point is also
355
  // stored in the struct.
356
  struct MOZ_STACK_CLASS WSPoint final
357
  {
358
    RefPtr<dom::Text> mTextNode;
359
    uint32_t mOffset;
360
    char16_t mChar;
361
362
    WSPoint()
363
      : mTextNode(nullptr)
364
      , mOffset(0)
365
      , mChar(0)
366
0
    {}
367
368
    WSPoint(dom::Text* aTextNode, int32_t aOffset, char16_t aChar)
369
      : mTextNode(aTextNode)
370
      , mOffset(aOffset)
371
      , mChar(aChar)
372
0
    {}
373
  };
374
375
  /**
376
   * Return the node which we will handle white-space under. This is the
377
   * closest block within the DOM subtree we're editing, or if none is
378
   * found, the (inline) root of the editable subtree.
379
   */
380
  nsINode* GetWSBoundingParent();
381
382
  nsresult GetWSNodes();
383
  void GetRuns();
384
  void ClearRuns();
385
  void MakeSingleWSRun(WSType aType);
386
  nsIContent* GetPreviousWSNodeInner(nsINode* aStartNode,
387
                                     nsINode* aBlockParent);
388
  nsIContent* GetPreviousWSNode(const EditorDOMPoint& aPoint,
389
                                nsINode* aBlockParent);
390
  nsIContent* GetNextWSNodeInner(nsINode* aStartNode, nsINode* aBlockParent);
391
  nsIContent* GetNextWSNode(const EditorDOMPoint& aPoint,
392
                            nsINode* aBlockParent);
393
  nsresult PrepareToDeleteRangePriv(WSRunObject* aEndObject);
394
  nsresult PrepareToSplitAcrossBlocksPriv();
395
396
  /**
397
   * DeleteRange() removes the range between aStartPoint and aEndPoint.
398
   * When aStartPoint and aEndPoint are same point, does nothing.
399
   * When aStartPoint and aEndPoint are in same text node, removes characters
400
   * between them.
401
   * When aStartPoint is in a text node, removes the text data after the point.
402
   * When aEndPoint is in a text node, removes the text data before the point.
403
   * Removes any nodes between them.
404
   */
405
  template<typename PT1, typename CT1, typename PT2, typename CT2>
406
  nsresult DeleteRange(const EditorDOMPointBase<PT1, CT1>& aStartPoint,
407
                       const EditorDOMPointBase<PT2, CT2>& aEndPoint);
408
409
  /**
410
   * GetNextCharPoint() returns next character's point of aPoint.  If there is
411
   * no character after aPoint, mTextNode is set to nullptr.
412
   */
413
  template<typename PT, typename CT>
414
  WSPoint GetNextCharPoint(const EditorDOMPointBase<PT, CT>& aPoint) const;
415
  WSPoint GetNextCharPoint(const WSPoint& aPoint) const;
416
417
  /**
418
   * GetPreviousCharPoint() returns previous character's point of of aPoint.
419
   * If there is no character before aPoint, mTextNode is set to nullptr.
420
   */
421
  template<typename PT, typename CT>
422
  WSPoint GetPreviousCharPoint(const EditorDOMPointBase<PT, CT>& aPoint) const;
423
  WSPoint GetPreviousCharPoint(const WSPoint& aPoint) const;
424
425
  /**
426
   * GetNextCharPointInternal() and GetPreviousCharPointInternal() are
427
   * helper methods of GetNextCharPoint(const EditorRawDOMPoint&) and
428
   * GetPreviousCharPoint(const EditorRawDOMPoint&).  When the container
429
   * isn't in mNodeArray, they call one of these methods.  Then, these
430
   * methods look for nearest text node in mNodeArray from aPoint.
431
   * Then, will call GetNextCharPoint(const WSPoint&) or
432
   * GetPreviousCharPoint(const WSPoint&) and returns its result.
433
   */
434
  template<typename PT, typename CT>
435
  WSPoint
436
  GetNextCharPointInternal(const EditorDOMPointBase<PT, CT>& aPoint) const;
437
  template<typename PT, typename CT>
438
  WSPoint
439
  GetPreviousCharPointInternal(const EditorDOMPointBase<PT, CT>& aPoint) const;
440
441
  /**
442
   * InsertNBSPAndRemoveFollowingASCIIWhitespaces() inserts an NBSP first.
443
   * Then, if following characters are ASCII whitespaces, will remove them.
444
   */
445
  nsresult InsertNBSPAndRemoveFollowingASCIIWhitespaces(WSPoint aPoint);
446
447
  /**
448
   * GetASCIIWhitespacesBounds() retrieves whitespaces before and/or after the
449
   * point specified by aNode and aOffset.
450
   *
451
   * @param aDir            Specify eBefore if you want to scan text backward.
452
   *                        Specify eAfter if you want to scan text forward.
453
   *                        Specify eBoth if you want to scan text to both
454
   *                        direction.
455
   * @param aNode           The container node where you want to start to scan
456
   *                        whitespaces from.
457
   * @param aOffset         The offset in aNode where you want to start to scan
458
   *                        whitespaces from.
459
   * @param outStartNode    [out] The container of first ASCII whitespace.
460
   *                              If there is no whitespaces, returns nullptr.
461
   * @param outStartOffset  [out] The offset of first ASCII whitespace in
462
   *                              outStartNode.
463
   * @param outEndNode      [out] The container of last ASCII whitespace.
464
   *                              If there is no whitespaces, returns nullptr.
465
   * @param outEndOffset    [out] The offset of last ASCII whitespace in
466
   *                              outEndNode.
467
   */
468
  void GetASCIIWhitespacesBounds(int16_t aDir,
469
                                 nsINode* aNode,
470
                                 int32_t aOffset,
471
                                 dom::Text** outStartNode,
472
                                 int32_t* outStartOffset,
473
                                 dom::Text** outEndNode,
474
                                 int32_t* outEndOffset);
475
476
  /**
477
   * FindNearestRun() looks for a WSFragment which is closest to specified
478
   * direction from aPoint.
479
   *
480
   * @param aPoint      The point to start to look for.
481
   * @param aForward    true if caller needs to look for a WSFragment after the
482
   *                    point in the DOM tree.  Otherwise, i.e., before the
483
   *                    point, false.
484
   * @return            Found WSFragment instance.
485
   *                    If aForward is true and:
486
   *                      if aPoint is end of a run, returns next run.
487
   *                      if aPoint is start of a run, returns the run.
488
   *                      if aPoint is before the first run, returns the first
489
   *                      run.
490
   *                      If aPoint is after the last run, returns nullptr.
491
   *                    If aForward is false and:
492
   *                      if aPoint is end of a run, returns the run.
493
   *                      if aPoint is start of a run, returns its next run.
494
   *                      if aPoint is before the first run, returns nullptr.
495
   *                      if aPoint is after the last run, returns the last run.
496
   */
497
  template<typename PT, typename CT>
498
  WSFragment* FindNearestRun(const EditorDOMPointBase<PT, CT>& aPoint,
499
                             bool aForward) const;
500
501
  char16_t GetCharAt(dom::Text* aTextNode, int32_t aOffset) const;
502
  nsresult CheckTrailingNBSPOfRun(WSFragment *aRun);
503
504
  /**
505
   * ReplacePreviousNBSPIfUnncessary() replaces previous character of aPoint
506
   * if it's a NBSP and it's unnecessary.
507
   *
508
   * @param aRun        Current text run.  aPoint must be in this run.
509
   * @param aPoint      Current insertion point.  Its previous character is
510
   *                    unnecessary NBSP will be checked.
511
   */
512
  template<typename PT, typename CT>
513
  nsresult
514
  ReplacePreviousNBSPIfUnncessary(WSFragment* aRun,
515
                                  const EditorDOMPointBase<PT, CT>& aPoint);
516
517
  nsresult CheckLeadingNBSP(WSFragment* aRun, nsINode* aNode,
518
                            int32_t aOffset);
519
520
  nsresult Scrub();
521
  bool IsBlockNode(nsINode* aNode);
522
523
  EditorRawDOMPoint Point() const
524
0
  {
525
0
    return EditorRawDOMPoint(mNode, mOffset);
526
0
  }
527
  EditorRawDOMPoint StartPoint() const
528
0
  {
529
0
    return EditorRawDOMPoint(mStartNode, mStartOffset);
530
0
  }
531
  EditorRawDOMPoint EndPoint() const
532
0
  {
533
0
    return EditorRawDOMPoint(mEndNode, mEndOffset);
534
0
  }
535
536
  // The node passed to our constructor.
537
  nsCOMPtr<nsINode> mNode;
538
  // The offset passed to our contructor.
539
  int32_t mOffset;
540
  // Together, the above represent the point at which we are building up ws info.
541
542
  // true if we are in preformatted whitespace context.
543
  bool mPRE;
544
  // Node/offset where ws starts.
545
  nsCOMPtr<nsINode> mStartNode;
546
  int32_t mStartOffset;
547
  // Reason why ws starts (eText, eOtherBlock, etc.).
548
  WSType mStartReason;
549
  // The node that implicated by start reason.
550
  nsCOMPtr<nsINode> mStartReasonNode;
551
552
  // Node/offset where ws ends.
553
  nsCOMPtr<nsINode> mEndNode;
554
  int32_t mEndOffset;
555
  // Reason why ws ends (eText, eOtherBlock, etc.).
556
  WSType mEndReason;
557
  // The node that implicated by end reason.
558
  nsCOMPtr<nsINode> mEndReasonNode;
559
560
  // Location of first nbsp in ws run, if any.
561
  RefPtr<dom::Text> mFirstNBSPNode;
562
  int32_t mFirstNBSPOffset;
563
564
  // Location of last nbsp in ws run, if any.
565
  RefPtr<dom::Text> mLastNBSPNode;
566
  int32_t mLastNBSPOffset;
567
568
  // The list of nodes containing ws in this run.
569
  nsTArray<RefPtr<dom::Text>> mNodeArray;
570
571
  // The first WSFragment in the run.
572
  WSFragment* mStartRun;
573
  // The last WSFragment in the run, may be same as first.
574
  WSFragment* mEndRun;
575
576
  // Non-owning.
577
  HTMLEditor* mHTMLEditor;
578
579
  // Opening this class up for pillaging.
580
  friend class HTMLEditRules;
581
  // Opening this class up for more pillaging.
582
  friend class HTMLEditor;
583
};
584
585
} // namespace mozilla
586
587
#endif // #ifndef WSRunObject_h