summaryrefslogtreecommitdiffstats
path: root/dom/base/nsRange.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/nsRange.h')
-rw-r--r--dom/base/nsRange.h116
1 files changed, 93 insertions, 23 deletions
diff --git a/dom/base/nsRange.h b/dom/base/nsRange.h
index 4b35c749a..2c0c19edc 100644
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -26,6 +26,7 @@ namespace mozilla {
class ErrorResult;
namespace dom {
struct ClientRectsAndTexts;
+class DocGroup;
class DocumentFragment;
class DOMRect;
class DOMRectList;
@@ -38,6 +39,7 @@ class nsRange final : public nsIDOMRange,
public nsWrapperCache
{
typedef mozilla::ErrorResult ErrorResult;
+ typedef mozilla::dom::DocGroup DocGroup;
typedef mozilla::dom::DOMRect DOMRect;
typedef mozilla::dom::DOMRectList DOMRectList;
@@ -46,14 +48,14 @@ class nsRange final : public nsIDOMRange,
public:
explicit nsRange(nsINode* aNode);
- static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
- nsIDOMNode* aEndParent, int32_t aEndOffset,
+ static nsresult CreateRange(nsIDOMNode* aStartParent, uint32_t aStartOffset,
+ nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsRange** aRange);
- static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
- nsIDOMNode* aEndParent, int32_t aEndOffset,
+ static nsresult CreateRange(nsIDOMNode* aStartParent, uint32_t aStartOffset,
+ nsIDOMNode* aEndParent, uint32_t aEndOffset,
nsIDOMRange** aRange);
- static nsresult CreateRange(nsINode* aStartParent, int32_t aStartOffset,
- nsINode* aEndParent, int32_t aEndOffset,
+ static nsresult CreateRange(nsINode* aStartParent, uint32_t aStartOffset,
+ nsINode* aEndParent, uint32_t aEndOffset,
nsRange** aRange);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -91,12 +93,12 @@ public:
return mEndParent;
}
- int32_t StartOffset() const
+ uint32_t StartOffset() const
{
return mStartOffset;
}
- int32_t EndOffset() const
+ uint32_t EndOffset() const
{
return mEndOffset;
}
@@ -148,19 +150,74 @@ public:
nsINode* GetCommonAncestor() const;
void Reset();
- nsresult SetStart(nsINode* aParent, int32_t aOffset);
- nsresult SetEnd(nsINode* aParent, int32_t aOffset);
+
+ /**
+ * 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.
+ */
+ nsresult SetStart(nsINode* aParent, uint32_t aOffset);
+ nsresult SetEnd(nsINode* aParent, uint32_t aOffset);
+
already_AddRefed<nsRange> CloneRange() const;
- nsresult Set(nsINode* aStartParent, int32_t aStartOffset,
- nsINode* aEndParent, int32_t aEndOffset)
+ /**
+ * 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, uint32_t aStartOffset,
+ nsINode* aEndParent, uint32_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, uint32_t aOffset)
{
- // If this starts being hot, we may be able to optimize this a bit,
- // but for now just set start and end separately.
- nsresult rv = SetStart(aStartParent, aStartOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ return SetStartAndEnd(aParent, aOffset, aParent, aOffset);
+ }
- return SetEnd(aEndParent, aEndOffset);
+ /**
+ * Retrieves node and offset for setting start or end of a range to
+ * before or after aNode.
+ */
+ static nsINode* GetParentAndOffsetAfter(nsINode* aNode, uint32_t* aOffset)
+ {
+ MOZ_ASSERT(aNode);
+ MOZ_ASSERT(aOffset);
+ *aOffset = 0;
+ nsINode* parentNode = aNode->GetParentNode();
+ if (!parentNode) {
+ return nullptr;
+ }
+ int32_t indexInParent = parentNode->IndexOf(aNode);
+ if (NS_WARN_IF(indexInParent < 0)) {
+ return nullptr;
+ }
+ *aOffset = static_cast<uint32_t>(indexInParent) + 1;
+ return parentNode;
+ }
+ static nsINode* GetParentAndOffsetBefore(nsINode* aNode, uint32_t* aOffset)
+ {
+ MOZ_ASSERT(aNode);
+ MOZ_ASSERT(aOffset);
+ *aOffset = 0;
+ nsINode* parentNode = aNode->GetParentNode();
+ if (!parentNode) {
+ return nullptr;
+ }
+ int32_t indexInParent = parentNode->IndexOf(aNode);
+ if (NS_WARN_IF(indexInParent < 0)) {
+ return nullptr;
+ }
+ *aOffset = static_cast<uint32_t>(indexInParent);
+ return parentNode;
}
NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult);
@@ -225,6 +282,7 @@ public:
nsINode* GetParentObject() const { return mOwner; }
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override final;
+ DocGroup* GetDocGroup() const;
private:
// no copy's or assigns
@@ -274,8 +332,8 @@ public:
static void CollectClientRectsAndText(nsLayoutUtils::RectCallback* aCollector,
mozilla::dom::DOMStringList* aTextList,
nsRange* aRange,
- nsINode* aStartParent, int32_t aStartOffset,
- nsINode* aEndParent, int32_t aEndOffset,
+ nsINode* aStartParent, uint32_t aStartOffset,
+ nsINode* aEndParent, uint32_t aEndOffset,
bool aClampToEdge, bool aFlushLayout);
/**
@@ -297,12 +355,24 @@ protected:
void UnregisterCommonAncestor(nsINode* aNode);
nsINode* IsValidBoundary(nsINode* aNode);
+ /**
+ * XXX nsRange should accept 0 - UINT32_MAX as offset. However, users of
+ * nsRange treat offset as int32_t. Additionally, some other internal
+ * APIs like nsINode::IndexOf() use int32_t. Therefore, nsRange should
+ * accept only 0 - INT32_MAX as valid offset for now.
+ */
+ static bool IsValidOffset(uint32_t aOffset)
+ {
+ return aOffset <= INT32_MAX;
+ }
+ static bool IsValidOffset(nsINode* aNode, uint32_t aOffset);
+
// 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.
- void DoSetRange(nsINode* aStartN, int32_t aStartOffset,
- nsINode* aEndN, int32_t aEndOffset,
+ void DoSetRange(nsINode* aStartN, uint32_t aStartOffset,
+ nsINode* aEndN, uint32_t aEndOffset,
nsINode* aRoot, bool aNotInsertedYet = false);
/**
@@ -350,8 +420,8 @@ protected:
nsCOMPtr<nsINode> mStartParent;
nsCOMPtr<nsINode> mEndParent;
RefPtr<mozilla::dom::Selection> mSelection;
- int32_t mStartOffset;
- int32_t mEndOffset;
+ uint32_t mStartOffset;
+ uint32_t mEndOffset;
bool mIsPositioned : 1;
bool mMaySpanAnonymousSubtrees : 1;