1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_StaticRange_h 8 #define mozilla_dom_StaticRange_h 9 10 #include "mozilla/ErrorResult.h" 11 #include "mozilla/RangeBoundary.h" 12 #include "mozilla/dom/AbstractRange.h" 13 #include "mozilla/dom/StaticRangeBinding.h" 14 #include "nsTArray.h" 15 #include "nsWrapperCache.h" 16 17 namespace mozilla { 18 namespace dom { 19 20 class StaticRange final : public AbstractRange { 21 public: 22 StaticRange() = delete; 23 explicit StaticRange(const StaticRange& aOther) = delete; 24 25 static already_AddRefed<StaticRange> Constructor(const GlobalObject& global, 26 const StaticRangeInit& init, 27 ErrorResult& aRv); 28 29 /** 30 * The following Create() returns `nsRange` instance which is initialized 31 * only with aNode. The result is never positioned. 32 */ 33 static already_AddRefed<StaticRange> Create(nsINode* aNode); 34 35 /** 36 * Create() may return `StaticRange` instance which is initialized with 37 * given range or points. If it fails initializing new range with the 38 * arguments, returns `nullptr`. `ErrorResult` is set to an error only 39 * when this returns `nullptr`. The error code indicates the reason why 40 * it couldn't initialize the instance. 41 */ Create(const AbstractRange * aAbstractRange,ErrorResult & aRv)42 static already_AddRefed<StaticRange> Create( 43 const AbstractRange* aAbstractRange, ErrorResult& aRv) { 44 MOZ_ASSERT(aAbstractRange); 45 return StaticRange::Create(aAbstractRange->StartRef(), 46 aAbstractRange->EndRef(), aRv); 47 } Create(nsINode * aStartContainer,uint32_t aStartOffset,nsINode * aEndContainer,uint32_t aEndOffset,ErrorResult & aRv)48 static already_AddRefed<StaticRange> Create(nsINode* aStartContainer, 49 uint32_t aStartOffset, 50 nsINode* aEndContainer, 51 uint32_t aEndOffset, 52 ErrorResult& aRv) { 53 return StaticRange::Create(RawRangeBoundary(aStartContainer, aStartOffset), 54 RawRangeBoundary(aEndContainer, aEndOffset), 55 aRv); 56 } 57 template <typename SPT, typename SRT, typename EPT, typename ERT> 58 static already_AddRefed<StaticRange> Create( 59 const RangeBoundaryBase<SPT, SRT>& aStartBoundary, 60 const RangeBoundaryBase<EPT, ERT>& aEndBoundary, ErrorResult& aRv); 61 62 protected: StaticRange(nsINode * aNode)63 explicit StaticRange(nsINode* aNode) : AbstractRange(aNode) {} 64 virtual ~StaticRange() = default; 65 66 public: 67 NS_DECL_ISUPPORTS_INHERITED 68 NS_IMETHODIMP_(void) DeleteCycleCollectable(void) override; 69 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(StaticRange, 70 AbstractRange) 71 72 JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final; 73 74 /** 75 * SetStartAndEnd() works similar to call both SetStart() and SetEnd(). 76 * Different from calls them separately, this does nothing if either 77 * the start point or the end point is invalid point. 78 * If the specified start point is after the end point, the range will be 79 * collapsed at the end point. Similarly, if they are in different root, 80 * the range will be collapsed at the end point. 81 */ SetStartAndEnd(nsINode * aStartContainer,uint32_t aStartOffset,nsINode * aEndContainer,uint32_t aEndOffset)82 nsresult SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset, 83 nsINode* aEndContainer, uint32_t aEndOffset) { 84 return SetStartAndEnd(RawRangeBoundary(aStartContainer, aStartOffset), 85 RawRangeBoundary(aEndContainer, aEndOffset)); 86 } 87 template <typename SPT, typename SRT, typename EPT, typename ERT> SetStartAndEnd(const RangeBoundaryBase<SPT,SRT> & aStartBoundary,const RangeBoundaryBase<EPT,ERT> & aEndBoundary)88 nsresult SetStartAndEnd(const RangeBoundaryBase<SPT, SRT>& aStartBoundary, 89 const RangeBoundaryBase<EPT, ERT>& aEndBoundary) { 90 return AbstractRange::SetStartAndEndInternal(aStartBoundary, aEndBoundary, 91 this); 92 } 93 94 protected: 95 /** 96 * DoSetRange() is called when `AbstractRange::SetStartAndEndInternal()` sets 97 * mStart and mEnd. 98 * 99 * @param aStartBoundary Computed start point. This must equals or be before 100 * aEndBoundary in the DOM tree order. 101 * @param aEndBoundary Computed end point. 102 * @param aRootNode The root node. 103 */ 104 template <typename SPT, typename SRT, typename EPT, typename ERT> 105 void DoSetRange(const RangeBoundaryBase<SPT, SRT>& aStartBoundary, 106 const RangeBoundaryBase<EPT, ERT>& aEndBoundary, 107 nsINode* aRootNode); 108 109 static nsTArray<RefPtr<StaticRange>>* sCachedRanges; 110 111 friend class AbstractRange; 112 }; 113 114 } // namespace dom 115 } // namespace mozilla 116 117 #endif // #ifndef mozilla_dom_StaticRange_h 118