diff options
Diffstat (limited to 'dom/base/nsRange.h')
-rw-r--r-- | dom/base/nsRange.h | 116 |
1 files changed, 93 insertions, 23 deletions
diff --git a/dom/base/nsRange.h b/dom/base/nsRange.h index 4b35c749ab..2c0c19edc6 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; |