2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
1998-12-16 21:36:48 +03:00
|
|
|
|
|
|
|
/*
|
2006-03-31 12:41:49 +04:00
|
|
|
* Implementation of the DOM nsIDOMRange object.
|
1998-12-16 21:36:48 +03:00
|
|
|
*/
|
|
|
|
|
2006-03-31 12:00:42 +04:00
|
|
|
#ifndef nsRange_h___
|
|
|
|
#define nsRange_h___
|
|
|
|
|
1998-12-18 05:51:34 +03:00
|
|
|
#include "nsIDOMRange.h"
|
1999-02-14 12:14:50 +03:00
|
|
|
#include "nsCOMPtr.h"
|
2012-07-02 03:45:59 +04:00
|
|
|
#include "nsINode.h"
|
2013-02-07 16:09:41 +04:00
|
|
|
#include "nsIDocument.h"
|
1999-02-15 19:26:04 +03:00
|
|
|
#include "nsIDOMNode.h"
|
2014-06-05 00:54:00 +04:00
|
|
|
#include "nsLayoutUtils.h"
|
1999-07-03 15:14:08 +04:00
|
|
|
#include "prmon.h"
|
2006-11-04 00:51:01 +03:00
|
|
|
#include "nsStubMutationObserver.h"
|
2013-02-07 16:09:41 +04:00
|
|
|
#include "nsWrapperCache.h"
|
|
|
|
#include "mozilla/Attributes.h"
|
2017-03-10 10:55:12 +03:00
|
|
|
#include "mozilla/GuardObjects.h"
|
1998-12-18 05:51:34 +03:00
|
|
|
|
2013-02-07 16:09:41 +04:00
|
|
|
namespace mozilla {
|
|
|
|
class ErrorResult;
|
|
|
|
namespace dom {
|
2016-11-02 23:31:06 +03:00
|
|
|
struct ClientRectsAndTexts;
|
2013-02-07 16:09:41 +04:00
|
|
|
class DocumentFragment;
|
2013-09-20 14:21:03 +04:00
|
|
|
class DOMRect;
|
|
|
|
class DOMRectList;
|
2015-08-12 20:26:01 +03:00
|
|
|
class Selection;
|
2015-07-13 18:25:42 +03:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
2013-02-07 16:09:41 +04:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
class nsRange final : public nsIDOMRange,
|
2015-03-27 21:52:19 +03:00
|
|
|
public nsStubMutationObserver,
|
|
|
|
public nsWrapperCache
|
1998-12-18 05:51:34 +03:00
|
|
|
{
|
2013-02-07 16:09:41 +04:00
|
|
|
typedef mozilla::ErrorResult ErrorResult;
|
2013-09-20 14:21:03 +04:00
|
|
|
typedef mozilla::dom::DOMRect DOMRect;
|
|
|
|
typedef mozilla::dom::DOMRectList DOMRectList;
|
2013-02-07 16:09:41 +04:00
|
|
|
|
2014-06-25 06:09:15 +04:00
|
|
|
virtual ~nsRange();
|
|
|
|
|
1998-12-18 05:51:34 +03:00
|
|
|
public:
|
2015-08-12 20:26:01 +03:00
|
|
|
explicit nsRange(nsINode* aNode);
|
1998-12-18 05:51:34 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
|
|
|
|
nsIDOMNode* aEndParent, int32_t aEndOffset,
|
2012-01-15 12:13:12 +04:00
|
|
|
nsRange** aRange);
|
2012-08-22 19:56:38 +04:00
|
|
|
static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
|
|
|
|
nsIDOMNode* aEndParent, int32_t aEndOffset,
|
2012-01-15 12:13:12 +04:00
|
|
|
nsIDOMRange** aRange);
|
2013-04-17 01:12:03 +04:00
|
|
|
static nsresult CreateRange(nsINode* aStartParent, int32_t aStartOffset,
|
|
|
|
nsINode* aEndParent, int32_t aEndOffset,
|
|
|
|
nsRange** aRange);
|
2012-01-15 12:13:12 +04:00
|
|
|
|
2008-12-03 13:03:10 +03:00
|
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
2013-02-07 16:09:41 +04:00
|
|
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsRange, nsIDOMRange)
|
2006-10-21 05:30:54 +04:00
|
|
|
|
2017-05-25 12:04:55 +03:00
|
|
|
nsrefcnt GetRefCount() const
|
|
|
|
{
|
|
|
|
return mRefCnt;
|
|
|
|
}
|
|
|
|
|
1998-12-18 12:28:55 +03:00
|
|
|
// nsIDOMRange interface
|
2003-01-15 02:05:52 +03:00
|
|
|
NS_DECL_NSIDOMRANGE
|
2013-07-12 07:29:24 +04:00
|
|
|
|
2012-01-10 18:19:54 +04:00
|
|
|
nsINode* GetRoot() const
|
|
|
|
{
|
|
|
|
return mRoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsINode* GetStartParent() const
|
|
|
|
{
|
|
|
|
return mStartParent;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsINode* GetEndParent() const
|
|
|
|
{
|
|
|
|
return mEndParent;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t StartOffset() const
|
2012-01-10 18:19:54 +04:00
|
|
|
{
|
|
|
|
return mStartOffset;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t EndOffset() const
|
2012-01-10 18:19:54 +04:00
|
|
|
{
|
|
|
|
return mEndOffset;
|
|
|
|
}
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2012-01-10 18:19:54 +04:00
|
|
|
bool IsPositioned() const
|
|
|
|
{
|
|
|
|
return mIsPositioned;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetMaySpanAnonymousSubtrees(bool aMaySpanAnonymousSubtrees)
|
|
|
|
{
|
|
|
|
mMaySpanAnonymousSubtrees = aMaySpanAnonymousSubtrees;
|
|
|
|
}
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2012-01-10 18:19:54 +04:00
|
|
|
/**
|
2015-08-12 20:26:01 +03:00
|
|
|
* Return true iff this range is part of a Selection object
|
2012-01-10 18:19:54 +04:00
|
|
|
* and isn't detached.
|
|
|
|
*/
|
|
|
|
bool IsInSelection() const
|
|
|
|
{
|
2015-08-12 20:26:01 +03:00
|
|
|
return !!mSelection;
|
2012-01-10 18:19:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when the range is added/removed from a Selection.
|
|
|
|
*/
|
2015-08-12 20:26:01 +03:00
|
|
|
void SetSelection(mozilla::dom::Selection* aSelection);
|
2012-01-10 18:19:54 +04:00
|
|
|
|
2015-02-21 07:27:59 +03:00
|
|
|
/**
|
|
|
|
* Return true if this range was generated.
|
|
|
|
* @see SetIsGenerated
|
|
|
|
*/
|
|
|
|
bool IsGenerated() const
|
|
|
|
{
|
|
|
|
return mIsGenerated;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mark this range as being generated or not.
|
|
|
|
* Currently it is used for marking ranges that are created when splitting up
|
|
|
|
* a range to exclude a -moz-user-select:none region.
|
|
|
|
* @see Selection::AddItem
|
|
|
|
* @see ExcludeNonSelectableNodes
|
|
|
|
*/
|
|
|
|
void SetIsGenerated(bool aIsGenerated)
|
|
|
|
{
|
|
|
|
mIsGenerated = aIsGenerated;
|
|
|
|
}
|
|
|
|
|
2012-01-10 18:19:54 +04:00
|
|
|
nsINode* GetCommonAncestor() const;
|
|
|
|
void Reset();
|
2017-05-30 07:18:25 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* SetStart() and SetEnd() sets start point or end point separately.
|
|
|
|
* However, this is expensive especially when it's a range of Selection.
|
|
|
|
* When you set both start and end of a range, you should use
|
|
|
|
* SetStartAndEnd() instead.
|
|
|
|
*/
|
2012-08-22 19:56:38 +04:00
|
|
|
nsresult SetStart(nsINode* aParent, int32_t aOffset);
|
|
|
|
nsresult SetEnd(nsINode* aParent, int32_t aOffset);
|
2017-05-30 07:18:25 +03:00
|
|
|
|
2012-06-25 15:44:11 +04:00
|
|
|
already_AddRefed<nsRange> CloneRange() const;
|
2010-07-22 02:05:17 +04:00
|
|
|
|
2017-05-30 07:18:25 +03:00
|
|
|
/**
|
|
|
|
* SetStartAndEnd() works similar to call both SetStart() and SetEnd().
|
|
|
|
* Different from calls them separately, this does nothing if either
|
|
|
|
* the start point or the end point is invalid point.
|
|
|
|
* If the specified start point is after the end point, the range will be
|
|
|
|
* collapsed at the end point. Similarly, if they are in different root,
|
|
|
|
* the range will be collapsed at the end point.
|
|
|
|
*/
|
|
|
|
nsresult SetStartAndEnd(nsINode* aStartParent, int32_t aStartOffset,
|
|
|
|
nsINode* aEndParent, int32_t aEndOffset);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* CollapseTo() works similar to call both SetStart() and SetEnd() with
|
|
|
|
* same node and offset. This just calls SetStartAndParent() to set
|
|
|
|
* collapsed range at aParent and aOffset.
|
|
|
|
*/
|
|
|
|
nsresult CollapseTo(nsINode* aParent, int32_t aOffset)
|
2011-11-04 09:32:09 +04:00
|
|
|
{
|
2017-05-30 07:18:25 +03:00
|
|
|
return SetStartAndEnd(aParent, aOffset, aParent, aOffset);
|
|
|
|
}
|
2011-11-04 09:32:09 +04:00
|
|
|
|
2017-05-30 07:18:25 +03:00
|
|
|
/**
|
|
|
|
* Retrieves node and offset for setting start or end of a range to
|
|
|
|
* before or after aNode.
|
|
|
|
*/
|
|
|
|
static nsINode* GetParentAndOffsetAfter(nsINode* aNode, int32_t* aOffset)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aNode);
|
|
|
|
MOZ_ASSERT(aOffset);
|
|
|
|
nsINode* parentNode = aNode->GetParentNode();
|
|
|
|
*aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
|
|
|
|
if (*aOffset >= 0) {
|
|
|
|
(*aOffset)++;
|
|
|
|
}
|
|
|
|
return parentNode;
|
|
|
|
}
|
|
|
|
static nsINode* GetParentAndOffsetBefore(nsINode* aNode, int32_t* aOffset)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aNode);
|
|
|
|
MOZ_ASSERT(aOffset);
|
|
|
|
nsINode* parentNode = aNode->GetParentNode();
|
|
|
|
*aOffset = parentNode ? parentNode->IndexOf(aNode) : -1;
|
|
|
|
return parentNode;
|
2011-11-04 09:32:09 +04:00
|
|
|
}
|
|
|
|
|
2011-06-16 10:31:36 +04:00
|
|
|
NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult);
|
|
|
|
|
2006-11-04 00:51:01 +03:00
|
|
|
// nsIMutationObserver methods
|
2010-07-22 02:05:17 +04:00
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
|
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
|
2011-12-20 13:15:41 +04:00
|
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
1998-12-18 05:51:34 +03:00
|
|
|
|
2013-02-07 16:09:41 +04:00
|
|
|
// WebIDL
|
2013-05-21 22:33:28 +04:00
|
|
|
static already_AddRefed<nsRange>
|
|
|
|
Constructor(const mozilla::dom::GlobalObject& global,
|
|
|
|
mozilla::ErrorResult& aRv);
|
|
|
|
|
2013-02-07 16:09:41 +04:00
|
|
|
bool Collapsed() const
|
|
|
|
{
|
|
|
|
return mIsPositioned && mStartParent == mEndParent &&
|
|
|
|
mStartOffset == mEndOffset;
|
|
|
|
}
|
|
|
|
already_AddRefed<mozilla::dom::DocumentFragment>
|
|
|
|
CreateContextualFragment(const nsAString& aString, ErrorResult& aError);
|
|
|
|
already_AddRefed<mozilla::dom::DocumentFragment>
|
|
|
|
CloneContents(ErrorResult& aErr);
|
|
|
|
int16_t CompareBoundaryPoints(uint16_t aHow, nsRange& aOther,
|
|
|
|
ErrorResult& aErr);
|
|
|
|
int16_t ComparePoint(nsINode& aParent, uint32_t aOffset, ErrorResult& aErr);
|
|
|
|
void DeleteContents(ErrorResult& aRv);
|
|
|
|
already_AddRefed<mozilla::dom::DocumentFragment>
|
|
|
|
ExtractContents(ErrorResult& aErr);
|
|
|
|
nsINode* GetCommonAncestorContainer(ErrorResult& aRv) const;
|
|
|
|
nsINode* GetStartContainer(ErrorResult& aRv) const;
|
|
|
|
uint32_t GetStartOffset(ErrorResult& aRv) const;
|
|
|
|
nsINode* GetEndContainer(ErrorResult& aRv) const;
|
|
|
|
uint32_t GetEndOffset(ErrorResult& aRv) const;
|
|
|
|
void InsertNode(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
bool IntersectsNode(nsINode& aNode, ErrorResult& aRv);
|
|
|
|
bool IsPointInRange(nsINode& aParent, uint32_t aOffset, ErrorResult& aErr);
|
2017-03-10 10:55:12 +03:00
|
|
|
|
|
|
|
// *JS() methods are mapped to Range.*() of DOM.
|
|
|
|
// They may move focus only when the range represents normal selection.
|
|
|
|
// These methods shouldn't be used from internal.
|
|
|
|
void CollapseJS(bool aToStart);
|
|
|
|
void SelectNodeJS(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SelectNodeContentsJS(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetEndJS(nsINode& aNode, uint32_t aOffset, ErrorResult& aErr);
|
|
|
|
void SetEndAfterJS(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetEndBeforeJS(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetStartJS(nsINode& aNode, uint32_t aOffset, ErrorResult& aErr);
|
|
|
|
void SetStartAfterJS(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetStartBeforeJS(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
|
2013-02-07 16:09:41 +04:00
|
|
|
void SurroundContents(nsINode& aNode, ErrorResult& aErr);
|
2014-07-24 01:06:00 +04:00
|
|
|
already_AddRefed<DOMRect> GetBoundingClientRect(bool aClampToEdge = true,
|
|
|
|
bool aFlushLayout = true);
|
|
|
|
already_AddRefed<DOMRectList> GetClientRects(bool aClampToEdge = true,
|
|
|
|
bool aFlushLayout = true);
|
2016-11-02 23:31:06 +03:00
|
|
|
void GetClientRectsAndTexts(
|
|
|
|
mozilla::dom::ClientRectsAndTexts& aResult,
|
|
|
|
ErrorResult& aErr);
|
2017-03-10 10:55:12 +03:00
|
|
|
|
|
|
|
// Following methods should be used for internal use instead of *JS().
|
|
|
|
void SelectNode(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SelectNodeContents(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetEnd(nsINode& aNode, uint32_t aOffset, ErrorResult& aErr);
|
|
|
|
void SetEndAfter(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetEndBefore(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetStart(nsINode& aNode, uint32_t aOffset, ErrorResult& aErr);
|
|
|
|
void SetStartAfter(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
void SetStartBefore(nsINode& aNode, ErrorResult& aErr);
|
|
|
|
|
2015-10-30 08:37:03 +03:00
|
|
|
static void GetInnerTextNoFlush(mozilla::dom::DOMString& aValue,
|
|
|
|
mozilla::ErrorResult& aError,
|
|
|
|
nsIContent* aStartParent,
|
|
|
|
uint32_t aStartOffset,
|
|
|
|
nsIContent* aEndParent,
|
|
|
|
uint32_t aEndOffset);
|
2013-02-07 16:09:41 +04:00
|
|
|
|
|
|
|
nsINode* GetParentObject() const { return mOwner; }
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override final;
|
2013-02-07 16:09:41 +04:00
|
|
|
|
2006-10-21 05:30:54 +04:00
|
|
|
private:
|
1998-12-18 05:51:34 +03:00
|
|
|
// no copy's or assigns
|
|
|
|
nsRange(const nsRange&);
|
|
|
|
nsRange& operator=(const nsRange&);
|
2007-06-19 07:01:03 +04:00
|
|
|
|
2008-07-25 14:37:37 +04:00
|
|
|
/**
|
|
|
|
* Cut or delete the range's contents.
|
|
|
|
*
|
|
|
|
* @param aFragment nsIDOMDocumentFragment containing the nodes.
|
|
|
|
* May be null to indicate the caller doesn't want a fragment.
|
|
|
|
*/
|
2013-02-07 16:09:41 +04:00
|
|
|
nsresult CutContents(mozilla::dom::DocumentFragment** frag);
|
2008-07-25 14:37:37 +04:00
|
|
|
|
2013-07-12 07:29:24 +04:00
|
|
|
static nsresult CloneParentsBetween(nsINode* aAncestor,
|
|
|
|
nsINode* aNode,
|
|
|
|
nsINode** aClosestAncestor,
|
|
|
|
nsINode** aFarthestAncestor);
|
2008-07-25 14:37:37 +04:00
|
|
|
|
2001-12-15 02:10:42 +03:00
|
|
|
public:
|
2003-01-15 02:05:52 +03:00
|
|
|
/******************************************************************************
|
2013-07-12 07:29:24 +04:00
|
|
|
* Utility routine to detect if a content node starts before a range and/or
|
2003-01-15 02:05:52 +03:00
|
|
|
* ends after a range. If neither it is contained inside the range.
|
2013-07-12 07:29:24 +04:00
|
|
|
*
|
2003-01-15 02:05:52 +03:00
|
|
|
* XXX - callers responsibility to ensure node in same doc as range!
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
2012-01-10 18:19:54 +04:00
|
|
|
static nsresult CompareNodeToRange(nsINode* aNode, nsRange* aRange,
|
2011-09-29 10:19:26 +04:00
|
|
|
bool *outNodeBefore,
|
|
|
|
bool *outNodeAfter);
|
2003-01-15 02:05:52 +03:00
|
|
|
|
2016-02-13 20:40:23 +03:00
|
|
|
/**
|
|
|
|
* Return true if any part of (aNode, aStartOffset) .. (aNode, aEndOffset)
|
|
|
|
* overlaps any nsRange in aNode's GetNextRangeCommonAncestor ranges (i.e.
|
|
|
|
* where aNode is a descendant of a range's common ancestor node).
|
|
|
|
* If a nsRange starts in (aNode, aEndOffset) or if it ends in
|
|
|
|
* (aNode, aStartOffset) then it is non-overlapping and the result is false
|
|
|
|
* for that nsRange. Collapsed ranges always counts as non-overlapping.
|
|
|
|
*/
|
2012-08-22 19:56:38 +04:00
|
|
|
static bool IsNodeSelected(nsINode* aNode, uint32_t aStartOffset,
|
|
|
|
uint32_t aEndOffset);
|
2011-12-20 13:15:41 +04:00
|
|
|
|
2016-11-02 23:49:43 +03:00
|
|
|
/**
|
|
|
|
* This helper function gets rects and correlated text for the given range.
|
|
|
|
* @param aTextList optional where nullptr = don't retrieve text
|
|
|
|
*/
|
|
|
|
static void CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
|
2017-03-03 00:13:12 +03:00
|
|
|
mozilla::dom::Sequence<nsString>* aTextList,
|
2016-11-02 23:49:43 +03:00
|
|
|
nsRange* aRange,
|
|
|
|
nsINode* aStartParent, int32_t aStartOffset,
|
|
|
|
nsINode* aEndParent, int32_t aEndOffset,
|
|
|
|
bool aClampToEdge, bool aFlushLayout);
|
2014-06-05 00:54:00 +04:00
|
|
|
|
2014-09-10 21:07:36 +04:00
|
|
|
/**
|
|
|
|
* Scan this range for -moz-user-select:none nodes and split it up into
|
|
|
|
* multiple ranges to exclude those nodes. The resulting ranges are put
|
|
|
|
* in aOutRanges. If no -moz-user-select:none node is found in the range
|
|
|
|
* then |this| is unmodified and is the only range in aOutRanges.
|
|
|
|
* Otherwise, |this| will be modified so that it ends before the first
|
|
|
|
* -moz-user-select:none node and additional ranges may also be created.
|
|
|
|
* If all nodes in the range are -moz-user-select:none then aOutRanges
|
|
|
|
* will be empty.
|
|
|
|
* @param aOutRanges the resulting set of ranges
|
|
|
|
*/
|
2015-10-18 08:24:48 +03:00
|
|
|
void ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges);
|
2014-09-10 21:07:36 +04:00
|
|
|
|
2012-01-10 18:19:54 +04:00
|
|
|
typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
|
2001-12-15 02:10:42 +03:00
|
|
|
protected:
|
2012-01-10 18:19:54 +04:00
|
|
|
void RegisterCommonAncestor(nsINode* aNode);
|
|
|
|
void UnregisterCommonAncestor(nsINode* aNode);
|
|
|
|
nsINode* IsValidBoundary(nsINode* aNode);
|
2017-05-30 07:18:25 +03:00
|
|
|
static bool IsValidOffset(nsINode* aNode, int32_t aOffset);
|
2012-01-10 18:19:54 +04:00
|
|
|
|
2011-12-20 13:15:41 +04:00
|
|
|
// CharacterDataChanged set aNotInsertedYet to true to disable an assertion
|
|
|
|
// and suppress re-registering a range common ancestor node since
|
|
|
|
// the new text node of a splitText hasn't been inserted yet.
|
|
|
|
// CharacterDataChanged does the re-registering when needed.
|
2012-08-22 19:56:38 +04:00
|
|
|
void DoSetRange(nsINode* aStartN, int32_t aStartOffset,
|
|
|
|
nsINode* aEndN, int32_t aEndOffset,
|
2011-12-20 13:15:41 +04:00
|
|
|
nsINode* aRoot, bool aNotInsertedYet = false);
|
2011-12-24 17:26:03 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* For a range for which IsInSelection() is true, return the common
|
|
|
|
* ancestor for the range. This method uses the selection bits and
|
|
|
|
* nsGkAtoms::range property on the nodes to quickly find the ancestor.
|
|
|
|
* That is, it's a faster version of GetCommonAncestor that only works
|
|
|
|
* for ranges in a Selection. The method will assert and the behavior
|
|
|
|
* is undefined if called on a range where IsInSelection() is false.
|
|
|
|
*/
|
|
|
|
nsINode* GetRegisteredCommonAncestor();
|
|
|
|
|
2016-02-13 20:40:23 +03:00
|
|
|
// Helper to IsNodeSelected.
|
|
|
|
static bool IsNodeInSortedRanges(nsINode* aNode,
|
|
|
|
uint32_t aStartOffset,
|
|
|
|
uint32_t aEndOffset,
|
|
|
|
const nsTArray<const nsRange*>& aRanges,
|
|
|
|
size_t aRangeStart,
|
|
|
|
size_t aRangeEnd);
|
|
|
|
|
2017-03-10 10:55:12 +03:00
|
|
|
// Assume that this is guaranteed that this is held by the caller when
|
|
|
|
// this is used. (Note that we cannot use AutoRestore for mCalledByJS
|
|
|
|
// due to a bit field.)
|
2017-03-17 07:32:51 +03:00
|
|
|
class MOZ_RAII AutoCalledByJSRestore final
|
2017-03-10 10:55:12 +03:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
nsRange& mRange;
|
|
|
|
bool mOldValue;
|
|
|
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
|
|
|
|
|
|
|
public:
|
2017-03-17 07:32:51 +03:00
|
|
|
explicit AutoCalledByJSRestore(nsRange& aRange
|
|
|
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
2017-03-10 10:55:12 +03:00
|
|
|
: mRange(aRange)
|
|
|
|
, mOldValue(aRange.mCalledByJS)
|
|
|
|
{
|
|
|
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
|
|
|
}
|
2017-03-17 07:32:51 +03:00
|
|
|
~AutoCalledByJSRestore()
|
2017-03-10 10:55:12 +03:00
|
|
|
{
|
|
|
|
mRange.mCalledByJS = mOldValue;
|
|
|
|
}
|
2017-03-17 07:32:51 +03:00
|
|
|
bool SavedValue() const { return mOldValue; }
|
2017-03-10 10:55:12 +03:00
|
|
|
};
|
|
|
|
|
2013-04-12 07:20:09 +04:00
|
|
|
struct MOZ_STACK_CLASS AutoInvalidateSelection
|
2011-12-24 17:26:03 +04:00
|
|
|
{
|
2014-08-05 17:19:51 +04:00
|
|
|
explicit AutoInvalidateSelection(nsRange* aRange) : mRange(aRange)
|
2011-12-24 17:26:03 +04:00
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
mWasInSelection = mRange->IsInSelection();
|
|
|
|
#endif
|
|
|
|
if (!mRange->IsInSelection() || mIsNested) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mIsNested = true;
|
|
|
|
mCommonAncestor = mRange->GetRegisteredCommonAncestor();
|
|
|
|
}
|
|
|
|
~AutoInvalidateSelection();
|
|
|
|
nsRange* mRange;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<nsINode> mCommonAncestor;
|
2011-12-24 17:26:03 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
bool mWasInSelection;
|
|
|
|
#endif
|
|
|
|
static bool mIsNested;
|
|
|
|
};
|
2013-02-07 16:09:41 +04:00
|
|
|
|
|
|
|
nsCOMPtr<nsIDocument> mOwner;
|
2012-01-10 18:19:54 +04:00
|
|
|
nsCOMPtr<nsINode> mRoot;
|
|
|
|
nsCOMPtr<nsINode> mStartParent;
|
|
|
|
nsCOMPtr<nsINode> mEndParent;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<mozilla::dom::Selection> mSelection;
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t mStartOffset;
|
|
|
|
int32_t mEndOffset;
|
2012-01-10 18:19:54 +04:00
|
|
|
|
2015-02-24 21:35:30 +03:00
|
|
|
bool mIsPositioned : 1;
|
|
|
|
bool mMaySpanAnonymousSubtrees : 1;
|
|
|
|
bool mIsGenerated : 1;
|
|
|
|
bool mStartOffsetWasIncremented : 1;
|
|
|
|
bool mEndOffsetWasIncremented : 1;
|
2017-03-10 10:55:12 +03:00
|
|
|
bool mCalledByJS : 1;
|
2012-11-21 00:14:15 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
int32_t mAssertNextInsertOrAppendIndex;
|
|
|
|
nsINode* mAssertNextInsertOrAppendNode;
|
|
|
|
#endif
|
1998-12-18 05:51:34 +03:00
|
|
|
};
|
|
|
|
|
2012-12-22 12:27:27 +04:00
|
|
|
inline nsISupports*
|
|
|
|
ToCanonicalSupports(nsRange* aRange)
|
|
|
|
{
|
|
|
|
return static_cast<nsIDOMRange*>(aRange);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline nsISupports*
|
|
|
|
ToSupports(nsRange* aRange)
|
|
|
|
{
|
|
|
|
return static_cast<nsIDOMRange*>(aRange);
|
|
|
|
}
|
|
|
|
|
1999-10-09 00:41:19 +04:00
|
|
|
#endif /* nsRange_h___ */
|