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/. */
7 #include "mozilla/dom/StaticRange.h"
8 #include "mozilla/dom/StaticRangeBinding.h"
11 namespace mozilla::dom
{
13 template already_AddRefed
<StaticRange
> StaticRange::Create(
14 const RangeBoundary
& aStartBoundary
, const RangeBoundary
& aEndBoundary
,
16 template already_AddRefed
<StaticRange
> StaticRange::Create(
17 const RangeBoundary
& aStartBoundary
, const RawRangeBoundary
& aEndBoundary
,
19 template already_AddRefed
<StaticRange
> StaticRange::Create(
20 const RawRangeBoundary
& aStartBoundary
, const RangeBoundary
& aEndBoundary
,
22 template already_AddRefed
<StaticRange
> StaticRange::Create(
23 const RawRangeBoundary
& aStartBoundary
,
24 const RawRangeBoundary
& aEndBoundary
, ErrorResult
& aRv
);
25 template nsresult
StaticRange::SetStartAndEnd(
26 const RangeBoundary
& aStartBoundary
, const RangeBoundary
& aEndBoundary
);
27 template nsresult
StaticRange::SetStartAndEnd(
28 const RangeBoundary
& aStartBoundary
, const RawRangeBoundary
& aEndBoundary
);
29 template nsresult
StaticRange::SetStartAndEnd(
30 const RawRangeBoundary
& aStartBoundary
, const RangeBoundary
& aEndBoundary
);
31 template nsresult
StaticRange::SetStartAndEnd(
32 const RawRangeBoundary
& aStartBoundary
,
33 const RawRangeBoundary
& aEndBoundary
);
34 template void StaticRange::DoSetRange(const RangeBoundary
& aStartBoundary
,
35 const RangeBoundary
& aEndBoundary
,
37 template void StaticRange::DoSetRange(const RangeBoundary
& aStartBoundary
,
38 const RawRangeBoundary
& aEndBoundary
,
40 template void StaticRange::DoSetRange(const RawRangeBoundary
& aStartBoundary
,
41 const RangeBoundary
& aEndBoundary
,
43 template void StaticRange::DoSetRange(const RawRangeBoundary
& aStartBoundary
,
44 const RawRangeBoundary
& aEndBoundary
,
47 nsTArray
<RefPtr
<StaticRange
>>* StaticRange::sCachedRanges
= nullptr;
49 NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_ADDREF(StaticRange
)
50 NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_INTERRUPTABLE_LAST_RELEASE(
51 StaticRange
, DoSetRange(RawRangeBoundary(), RawRangeBoundary(), nullptr),
52 AbstractRange::MaybeCacheToReuse(*this))
54 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StaticRange
)
55 NS_INTERFACE_MAP_END_INHERITING(AbstractRange
)
57 NS_IMPL_CYCLE_COLLECTION_CLASS(StaticRange
)
59 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(StaticRange
, AbstractRange
)
60 NS_IMPL_CYCLE_COLLECTION_UNLINK(mStart
)
61 NS_IMPL_CYCLE_COLLECTION_UNLINK(mEnd
)
62 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
64 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(StaticRange
, AbstractRange
)
65 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
67 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(StaticRange
, AbstractRange
)
68 NS_IMPL_CYCLE_COLLECTION_TRACE_END
71 already_AddRefed
<StaticRange
> StaticRange::Create(nsINode
* aNode
) {
73 if (!sCachedRanges
|| sCachedRanges
->IsEmpty()) {
74 return do_AddRef(new StaticRange(aNode
));
76 RefPtr
<StaticRange
> staticRange
= sCachedRanges
->PopLastElement().forget();
77 staticRange
->Init(aNode
);
78 return staticRange
.forget();
82 template <typename SPT
, typename SRT
, typename EPT
, typename ERT
>
83 already_AddRefed
<StaticRange
> StaticRange::Create(
84 const RangeBoundaryBase
<SPT
, SRT
>& aStartBoundary
,
85 const RangeBoundaryBase
<EPT
, ERT
>& aEndBoundary
, ErrorResult
& aRv
) {
86 RefPtr
<StaticRange
> staticRange
=
87 StaticRange::Create(aStartBoundary
.Container());
88 staticRange
->DoSetRange(aStartBoundary
, aEndBoundary
, nullptr);
90 return staticRange
.forget();
93 template <typename SPT
, typename SRT
, typename EPT
, typename ERT
>
94 void StaticRange::DoSetRange(const RangeBoundaryBase
<SPT
, SRT
>& aStartBoundary
,
95 const RangeBoundaryBase
<EPT
, ERT
>& aEndBoundary
,
97 mStart
= aStartBoundary
;
99 MOZ_ASSERT(mStart
.IsSet() == mEnd
.IsSet());
100 mIsPositioned
= mStart
.IsSet() && mEnd
.IsSet();
104 already_AddRefed
<StaticRange
> StaticRange::Constructor(
105 const GlobalObject
& global
, const StaticRangeInit
& init
, ErrorResult
& aRv
) {
106 if (init
.mStartContainer
->NodeType() == nsINode::DOCUMENT_TYPE_NODE
||
107 init
.mStartContainer
->NodeType() == nsINode::ATTRIBUTE_NODE
||
108 init
.mEndContainer
->NodeType() == nsINode::DOCUMENT_TYPE_NODE
||
109 init
.mEndContainer
->NodeType() == nsINode::ATTRIBUTE_NODE
) {
110 aRv
.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR
);
114 return Create(init
.mStartContainer
, init
.mStartOffset
, init
.mEndContainer
,
115 init
.mEndOffset
, aRv
);
118 JSObject
* StaticRange::WrapObject(JSContext
* aCx
,
119 JS::Handle
<JSObject
*> aGivenProto
) {
120 return StaticRange_Binding::Wrap(aCx
, this, aGivenProto
);
123 } // namespace mozilla::dom