aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorcathiechen <cathiechen@igalia.com>2024-03-22 16:02:01 +0100
committerGitHub <noreply@github.com>2024-03-22 15:02:01 +0000
commitcb275e086c215b6da741c7918cd9683a134eb24f (patch)
tree173f32008068d06f27b3d1a8af1a855dfa6174da /components/script
parentbae77671f85481503ab563c20ed488cf883436fa (diff)
downloadservo-cb275e086c215b6da741c7918cd9683a134eb24f.tar.gz
servo-cb275e086c215b6da741c7918cd9683a134eb24f.zip
Implement StaticRange (#31809)
* Add DOM interface for AbstractRange * Add DOM interface for StaticRange * Update WPT tests for StaticRange-constructor.html * Fix formatting * Add AbstractRange & StaticRange in interfaces.html * rebased the code and fixed the failures Signed-off-by: Cathie Chen <cathiechen@igalia.com> * update the expected result in idlharness.window.js.ini file * Addressed the code review comments * updae the test result of legacy layout --------- Signed-off-by: Cathie Chen <cathiechen@igalia.com> Co-authored-by: Nipun Garg <nipung271@gmail.com>
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/abstractrange.rs177
-rw-r--r--components/script/dom/bindings/codegen/Bindings.conf8
-rw-r--r--components/script/dom/mod.rs2
-rw-r--r--components/script/dom/range.rs430
-rw-r--r--components/script/dom/selection.rs42
-rw-r--r--components/script/dom/staticrange.rs88
-rw-r--r--components/script/dom/webidls/AbstractRange.webidl21
-rw-r--r--components/script/dom/webidls/Range.webidl12
-rw-r--r--components/script/dom/webidls/StaticRange.webidl19
9 files changed, 519 insertions, 280 deletions
diff --git a/components/script/dom/abstractrange.rs b/components/script/dom/abstractrange.rs
new file mode 100644
index 00000000000..a39b67b1807
--- /dev/null
+++ b/components/script/dom/abstractrange.rs
@@ -0,0 +1,177 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use std::cell::Cell;
+use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
+
+use deny_public_fields::DenyPublicFields;
+use dom_struct::dom_struct;
+
+use crate::dom::bindings::codegen::Bindings::AbstractRangeBinding::AbstractRangeMethods;
+use crate::dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
+use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
+use crate::dom::bindings::root::{DomRoot, MutDom};
+use crate::dom::document::Document;
+use crate::dom::node::{Node, ShadowIncluding};
+
+#[dom_struct]
+pub struct AbstractRange {
+ reflector_: Reflector,
+ start: BoundaryPoint,
+ end: BoundaryPoint,
+}
+
+impl AbstractRange {
+ pub fn new_inherited(
+ start_container: &Node,
+ start_offset: u32,
+ end_container: &Node,
+ end_offset: u32,
+ ) -> AbstractRange {
+ AbstractRange {
+ reflector_: Reflector::new(),
+ start: BoundaryPoint::new(start_container, start_offset),
+ end: BoundaryPoint::new(end_container, end_offset),
+ }
+ }
+
+ pub fn new(
+ document: &Document,
+ start_container: &Node,
+ start_offset: u32,
+ end_container: &Node,
+ end_offset: u32,
+ ) -> DomRoot<AbstractRange> {
+ let abstractrange = reflect_dom_object(
+ Box::new(AbstractRange::new_inherited(
+ start_container,
+ start_offset,
+ end_container,
+ end_offset,
+ )),
+ document.window(),
+ );
+ abstractrange
+ }
+
+ pub fn start(&self) -> &BoundaryPoint {
+ &self.start
+ }
+
+ pub fn end(&self) -> &BoundaryPoint {
+ &self.end
+ }
+}
+
+impl AbstractRangeMethods for AbstractRange {
+ /// <https://dom.spec.whatwg.org/#dom-range-startcontainer>
+ fn StartContainer(&self) -> DomRoot<Node> {
+ self.start.node.get()
+ }
+
+ /// <https://dom.spec.whatwg.org/#dom-range-startoffset>
+ fn StartOffset(&self) -> u32 {
+ self.start.offset.get()
+ }
+
+ /// <https://dom.spec.whatwg.org/#dom-range-endcontainer>
+ fn EndContainer(&self) -> DomRoot<Node> {
+ self.end.node.get()
+ }
+
+ /// <https://dom.spec.whatwg.org/#dom-range-endoffset>
+ fn EndOffset(&self) -> u32 {
+ self.end.offset.get()
+ }
+
+ /// <https://dom.spec.whatwg.org/#dom-range-collapsed>
+ fn Collapsed(&self) -> bool {
+ self.start == self.end
+ }
+}
+
+#[derive(DenyPublicFields, JSTraceable, MallocSizeOf)]
+#[crown::unrooted_must_root_lint::must_root]
+pub struct BoundaryPoint {
+ node: MutDom<Node>,
+ offset: Cell<u32>,
+}
+
+impl BoundaryPoint {
+ fn new(node: &Node, offset: u32) -> BoundaryPoint {
+ debug_assert!(!node.is_doctype());
+ BoundaryPoint {
+ node: MutDom::new(node),
+ offset: Cell::new(offset),
+ }
+ }
+
+ pub fn set(&self, node: &Node, offset: u32) {
+ self.node.set(node);
+ self.set_offset(offset);
+ }
+
+ pub fn set_offset(&self, offset: u32) {
+ self.offset.set(offset);
+ }
+
+ pub fn node(&self) -> &MutDom<Node> {
+ &self.node
+ }
+}
+
+#[allow(crown::unrooted_must_root)]
+impl PartialOrd for BoundaryPoint {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ bp_position(
+ &self.node.get(),
+ self.offset.get(),
+ &other.node.get(),
+ other.offset.get(),
+ )
+ }
+}
+
+#[allow(crown::unrooted_must_root)]
+impl PartialEq for BoundaryPoint {
+ fn eq(&self, other: &Self) -> bool {
+ self.node.get() == other.node.get() && self.offset.get() == other.offset.get()
+ }
+}
+
+/// <https://dom.spec.whatwg.org/#concept-range-bp-position>
+pub fn bp_position(a_node: &Node, a_offset: u32, b_node: &Node, b_offset: u32) -> Option<Ordering> {
+ if a_node as *const Node == b_node as *const Node {
+ // Step 1.
+ return Some(a_offset.cmp(&b_offset));
+ }
+ let position = b_node.CompareDocumentPosition(a_node);
+ if position & NodeConstants::DOCUMENT_POSITION_DISCONNECTED != 0 {
+ // No order is defined for nodes not in the same tree.
+ None
+ } else if position & NodeConstants::DOCUMENT_POSITION_FOLLOWING != 0 {
+ // Step 2.
+ match bp_position(b_node, b_offset, a_node, a_offset).unwrap() {
+ Ordering::Less => Some(Ordering::Greater),
+ Ordering::Greater => Some(Ordering::Less),
+ Ordering::Equal => unreachable!(),
+ }
+ } else if position & NodeConstants::DOCUMENT_POSITION_CONTAINS != 0 {
+ // Step 3-1, 3-2.
+ let mut b_ancestors = b_node.inclusive_ancestors(ShadowIncluding::No);
+ let child = b_ancestors
+ .find(|child| &*child.GetParentNode().unwrap() == a_node)
+ .unwrap();
+ // Step 3-3.
+ if child.index() < a_offset {
+ Some(Ordering::Greater)
+ } else {
+ // Step 4.
+ Some(Ordering::Less)
+ }
+ } else {
+ // Step 4.
+ Some(Ordering::Less)
+ }
+}
diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf
index 4f8986dea48..b4c5c96b8ff 100644
--- a/components/script/dom/bindings/codegen/Bindings.conf
+++ b/components/script/dom/bindings/codegen/Bindings.conf
@@ -30,6 +30,14 @@ DOMInterfaces = {
'spiderMonkeyInterface': True,
},
+'AbstractRange': {
+ 'weakReferenceable': True,
+},
+
+'StaticRange': {
+ 'weakReferenceable': True,
+},
+
'Range': {
'weakReferenceable': True,
},
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 2b1e72d0bb7..4df2c0188e6 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -209,6 +209,7 @@ pub mod types {
include!(concat!(env!("OUT_DIR"), "/InterfaceTypes.rs"));
}
+pub mod abstractrange;
pub mod abstractworker;
pub mod abstractworkerglobalscope;
pub mod activation;
@@ -524,6 +525,7 @@ pub mod serviceworkerglobalscope;
pub mod serviceworkerregistration;
pub mod servoparser;
pub mod shadowroot;
+pub mod staticrange;
pub mod stereopannernode;
pub mod storage;
pub mod storageevent;
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index 227a346ffbd..09f0d8454d0 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -2,26 +2,27 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-use std::cell::{Cell, UnsafeCell};
-use std::cmp::{Ord, Ordering, PartialEq, PartialOrd};
+use std::cell::UnsafeCell;
+use std::cmp::{Ordering, PartialOrd};
-use deny_public_fields::DenyPublicFields;
use dom_struct::dom_struct;
use js::jsapi::JSTracer;
use js::rust::HandleObject;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
+use crate::dom::abstractrange::{bp_position, AbstractRange, BoundaryPoint};
use crate::dom::bindings::cell::DomRefCell;
+use crate::dom::bindings::codegen::Bindings::AbstractRangeBinding::AbstractRangeMethods;
use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
-use crate::dom::bindings::codegen::Bindings::NodeBinding::{NodeConstants, NodeMethods};
+use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use crate::dom::bindings::codegen::Bindings::RangeBinding::{RangeConstants, RangeMethods};
use crate::dom::bindings::codegen::Bindings::TextBinding::TextMethods;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId};
-use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
-use crate::dom::bindings::root::{Dom, DomRoot, MutDom};
+use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
+use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::trace::JSTraceable;
use crate::dom::bindings::weakref::{WeakRef, WeakRefVec};
@@ -37,9 +38,7 @@ use crate::dom::window::Window;
#[dom_struct]
pub struct Range {
- reflector_: Reflector,
- start: BoundaryPoint,
- end: BoundaryPoint,
+ abstract_range: AbstractRange,
// A range that belongs to a Selection needs to know about it
// so selectionchange can fire when the range changes.
// A range shouldn't belong to more than one Selection at a time,
@@ -59,10 +58,15 @@ impl Range {
end_container: &Node,
end_offset: u32,
) -> Range {
+ debug_assert!(start_offset <= start_container.len());
+ debug_assert!(end_offset <= end_container.len());
Range {
- reflector_: Reflector::new(),
- start: BoundaryPoint::new(start_container, start_offset),
- end: BoundaryPoint::new(end_container, end_offset),
+ abstract_range: AbstractRange::new_inherited(
+ start_container,
+ start_offset,
+ end_container,
+ end_offset,
+ ),
associated_selections: DomRefCell::new(vec![]),
}
}
@@ -114,35 +118,35 @@ impl Range {
range
}
- // https://dom.spec.whatwg.org/#dom-range
+ /// <https://dom.spec.whatwg.org/#dom-range>
#[allow(non_snake_case)]
pub fn Constructor(window: &Window, proto: Option<HandleObject>) -> Fallible<DomRoot<Range>> {
let document = window.Document();
Ok(Range::new_with_doc(&document, proto))
}
- // https://dom.spec.whatwg.org/#contained
+ /// <https://dom.spec.whatwg.org/#contained>
fn contains(&self, node: &Node) -> bool {
match (
- bp_position(node, 0, &self.StartContainer(), self.StartOffset()),
- bp_position(node, node.len(), &self.EndContainer(), self.EndOffset()),
+ bp_position(node, 0, &self.start_container(), self.start_offset()),
+ bp_position(node, node.len(), &self.end_container(), self.end_offset()),
) {
(Some(Ordering::Greater), Some(Ordering::Less)) => true,
_ => false,
}
}
- // https://dom.spec.whatwg.org/#partially-contained
+ /// <https://dom.spec.whatwg.org/#partially-contained>
fn partially_contains(&self, node: &Node) -> bool {
- self.StartContainer()
+ self.start_container()
.inclusive_ancestors(ShadowIncluding::No)
.any(|n| &*n == node) !=
- self.EndContainer()
+ self.end_container()
.inclusive_ancestors(ShadowIncluding::No)
.any(|n| &*n == node)
}
- // https://dom.spec.whatwg.org/#concept-range-clone
+ /// <https://dom.spec.whatwg.org/#concept-range-clone>
fn contained_children(
&self,
) -> Fallible<(
@@ -150,8 +154,8 @@ impl Range {
Option<DomRoot<Node>>,
Vec<DomRoot<Node>>,
)> {
- let start_node = self.StartContainer();
- let end_node = self.EndContainer();
+ let start_node = self.start_container();
+ let end_node = self.end_container();
// Steps 5-6.
let common_ancestor = self.CommonAncestorContainer();
@@ -193,45 +197,45 @@ impl Range {
))
}
- // https://dom.spec.whatwg.org/#concept-range-bp-set
+ /// <https://dom.spec.whatwg.org/#concept-range-bp-set>
fn set_start(&self, node: &Node, offset: u32) {
- if &self.start.node != node || self.start.offset.get() != offset {
+ if self.start().node() != node || self.start_offset() != offset {
self.report_change();
}
- if &self.start.node != node {
- if self.start.node == self.end.node {
+ if self.start().node() != node {
+ if self.start().node() == self.end().node() {
node.ranges().push(WeakRef::new(self));
- } else if &self.end.node == node {
- self.StartContainer().ranges().remove(self);
+ } else if self.end().node() == node {
+ self.start_container().ranges().remove(self);
} else {
node.ranges()
- .push(self.StartContainer().ranges().remove(self));
+ .push(self.start_container().ranges().remove(self));
}
}
- self.start.set(node, offset);
+ self.start().set(node, offset);
}
- // https://dom.spec.whatwg.org/#concept-range-bp-set
+ /// <https://dom.spec.whatwg.org/#concept-range-bp-set>
fn set_end(&self, node: &Node, offset: u32) {
- if &self.end.node != node || self.end.offset.get() != offset {
+ if self.end().node() != node || self.end_offset() != offset {
self.report_change();
}
- if &self.end.node != node {
- if self.end.node == self.start.node {
+ if self.end().node() != node {
+ if self.end().node() == self.start().node() {
node.ranges().push(WeakRef::new(self));
- } else if &self.start.node == node {
- self.EndContainer().ranges().remove(self);
+ } else if self.start().node() == node {
+ self.end_container().ranges().remove(self);
} else {
node.ranges()
- .push(self.EndContainer().ranges().remove(self));
+ .push(self.end_container().ranges().remove(self));
}
}
- self.end.set(node, offset);
+ self.end().set(node, offset);
}
- // https://dom.spec.whatwg.org/#dom-range-comparepointnode-offset
+ /// <https://dom.spec.whatwg.org/#dom-range-comparepointnode-offset>
fn compare_point(&self, node: &Node, offset: u32) -> Fallible<Ordering> {
- let start_node = self.StartContainer();
+ let start_node = self.start_container();
let start_node_root = start_node
.inclusive_ancestors(ShadowIncluding::No)
.last()
@@ -252,13 +256,13 @@ impl Range {
// Step 3.
return Err(Error::IndexSize);
}
- if let Ordering::Less = bp_position(node, offset, &start_node, self.StartOffset()).unwrap()
+ if let Ordering::Less = bp_position(node, offset, &start_node, self.start_offset()).unwrap()
{
// Step 4.
return Ok(Ordering::Less);
}
if let Ordering::Greater =
- bp_position(node, offset, &self.EndContainer(), self.EndOffset()).unwrap()
+ bp_position(node, offset, &self.end_container(), self.end_offset()).unwrap()
{
// Step 5.
return Ok(Ordering::Greater);
@@ -286,42 +290,49 @@ impl Range {
.iter()
.for_each(|s| s.queue_selectionchange_task());
}
-}
-impl RangeMethods for Range {
- // https://dom.spec.whatwg.org/#dom-range-startcontainer
- fn StartContainer(&self) -> DomRoot<Node> {
- self.start.node.get()
+ fn abstract_range(&self) -> &AbstractRange {
+ &self.abstract_range
+ }
+
+ fn start(&self) -> &BoundaryPoint {
+ &self.abstract_range().start()
+ }
+
+ fn end(&self) -> &BoundaryPoint {
+ &self.abstract_range().end()
+ }
+
+ pub fn start_container(&self) -> DomRoot<Node> {
+ self.abstract_range().StartContainer()
}
- // https://dom.spec.whatwg.org/#dom-range-startoffset
- fn StartOffset(&self) -> u32 {
- self.start.offset.get()
+ pub fn start_offset(&self) -> u32 {
+ self.abstract_range().StartOffset()
}
- // https://dom.spec.whatwg.org/#dom-range-endcontainer
- fn EndContainer(&self) -> DomRoot<Node> {
- self.end.node.get()
+ pub fn end_container(&self) -> DomRoot<Node> {
+ self.abstract_range().EndContainer()
}
- // https://dom.spec.whatwg.org/#dom-range-endoffset
- fn EndOffset(&self) -> u32 {
- self.end.offset.get()
+ pub fn end_offset(&self) -> u32 {
+ self.abstract_range().EndOffset()
}
- // https://dom.spec.whatwg.org/#dom-range-collapsed
- fn Collapsed(&self) -> bool {
- self.start == self.end
+ pub fn collapsed(&self) -> bool {
+ self.abstract_range().Collapsed()
}
+}
- // https://dom.spec.whatwg.org/#dom-range-commonancestorcontainer
+impl RangeMethods for Range {
+ /// <https://dom.spec.whatwg.org/#dom-range-commonancestorcontainer>
fn CommonAncestorContainer(&self) -> DomRoot<Node> {
- self.EndContainer()
- .common_ancestor(&self.StartContainer(), ShadowIncluding::No)
+ self.end_container()
+ .common_ancestor(&self.start_container(), ShadowIncluding::No)
.expect("Couldn't find common ancestor container")
}
- // https://dom.spec.whatwg.org/#dom-range-setstart
+ /// <https://dom.spec.whatwg.org/#dom-range-setstart>
fn SetStart(&self, node: &Node, offset: u32) -> ErrorResult {
if node.is_doctype() {
// Step 1.
@@ -332,7 +343,7 @@ impl RangeMethods for Range {
} else {
// Step 3.
self.set_start(node, offset);
- if !(self.start <= self.end) {
+ if !(self.start() <= self.end()) {
// Step 4.
self.set_end(node, offset);
}
@@ -340,7 +351,7 @@ impl RangeMethods for Range {
}
}
- // https://dom.spec.whatwg.org/#dom-range-setend
+ /// <https://dom.spec.whatwg.org/#dom-range-setend>
fn SetEnd(&self, node: &Node, offset: u32) -> ErrorResult {
if node.is_doctype() {
// Step 1.
@@ -351,7 +362,7 @@ impl RangeMethods for Range {
} else {
// Step 3.
self.set_end(node, offset);
- if !(self.end >= self.start) {
+ if !(self.end() >= self.start()) {
// Step 4.
self.set_start(node, offset);
}
@@ -359,40 +370,40 @@ impl RangeMethods for Range {
}
}
- // https://dom.spec.whatwg.org/#dom-range-setstartbefore
+ /// <https://dom.spec.whatwg.org/#dom-range-setstartbefore>
fn SetStartBefore(&self, node: &Node) -> ErrorResult {
let parent = node.GetParentNode().ok_or(Error::InvalidNodeType)?;
self.SetStart(&parent, node.index())
}
- // https://dom.spec.whatwg.org/#dom-range-setstartafter
+ /// <https://dom.spec.whatwg.org/#dom-range-setstartafter>
fn SetStartAfter(&self, node: &Node) -> ErrorResult {
let parent = node.GetParentNode().ok_or(Error::InvalidNodeType)?;
self.SetStart(&parent, node.index() + 1)
}
- // https://dom.spec.whatwg.org/#dom-range-setendbefore
+ /// <https://dom.spec.whatwg.org/#dom-range-setendbefore>
fn SetEndBefore(&self, node: &Node) -> ErrorResult {
let parent = node.GetParentNode().ok_or(Error::InvalidNodeType)?;
self.SetEnd(&parent, node.index())
}
- // https://dom.spec.whatwg.org/#dom-range-setendafter
+ /// <https://dom.spec.whatwg.org/#dom-range-setendafter>
fn SetEndAfter(&self, node: &Node) -> ErrorResult {
let parent = node.GetParentNode().ok_or(Error::InvalidNodeType)?;
self.SetEnd(&parent, node.index() + 1)
}
- // https://dom.spec.whatwg.org/#dom-range-collapse
+ /// <https://dom.spec.whatwg.org/#dom-range-collapse>
fn Collapse(&self, to_start: bool) {
if to_start {
- self.set_end(&self.StartContainer(), self.StartOffset());
+ self.set_end(&self.start_container(), self.start_offset());
} else {
- self.set_start(&self.EndContainer(), self.EndOffset());
+ self.set_start(&self.end_container(), self.end_offset());
}
}
- // https://dom.spec.whatwg.org/#dom-range-selectnode
+ /// <https://dom.spec.whatwg.org/#dom-range-selectnode>
fn SelectNode(&self, node: &Node) -> ErrorResult {
// Steps 1, 2.
let parent = node.GetParentNode().ok_or(Error::InvalidNodeType)?;
@@ -405,7 +416,7 @@ impl RangeMethods for Range {
Ok(())
}
- // https://dom.spec.whatwg.org/#dom-range-selectnodecontents
+ /// <https://dom.spec.whatwg.org/#dom-range-selectnodecontents>
fn SelectNodeContents(&self, node: &Node) -> ErrorResult {
if node.is_doctype() {
// Step 1.
@@ -420,19 +431,19 @@ impl RangeMethods for Range {
Ok(())
}
- // https://dom.spec.whatwg.org/#dom-range-compareboundarypoints
+ /// <https://dom.spec.whatwg.org/#dom-range-compareboundarypoints>
fn CompareBoundaryPoints(&self, how: u16, other: &Range) -> Fallible<i16> {
if how > RangeConstants::END_TO_START {
// Step 1.
return Err(Error::NotSupported);
}
let this_root = self
- .StartContainer()
+ .start_container()
.inclusive_ancestors(ShadowIncluding::No)
.last()
.unwrap();
let other_root = other
- .StartContainer()
+ .start_container()
.inclusive_ancestors(ShadowIncluding::No)
.last()
.unwrap();
@@ -442,10 +453,10 @@ impl RangeMethods for Range {
}
// Step 3.
let (this_point, other_point) = match how {
- RangeConstants::START_TO_START => (&self.start, &other.start),
- RangeConstants::START_TO_END => (&self.end, &other.start),
- RangeConstants::END_TO_END => (&self.end, &other.end),
- RangeConstants::END_TO_START => (&self.start, &other.end),
+ RangeConstants::START_TO_START => (self.start(), other.start()),
+ RangeConstants::START_TO_END => (self.end(), other.start()),
+ RangeConstants::END_TO_END => (self.end(), other.end()),
+ RangeConstants::END_TO_START => (self.start(), other.end()),
_ => unreachable!(),
};
// step 4.
@@ -456,20 +467,20 @@ impl RangeMethods for Range {
}
}
- // https://dom.spec.whatwg.org/#dom-range-clonerange
+ /// <https://dom.spec.whatwg.org/#dom-range-clonerange>
fn CloneRange(&self) -> DomRoot<Range> {
- let start_node = self.StartContainer();
+ let start_node = self.start_container();
let owner_doc = start_node.owner_doc();
Range::new(
&owner_doc,
&start_node,
- self.StartOffset(),
- &self.EndContainer(),
- self.EndOffset(),
+ self.start_offset(),
+ &self.end_container(),
+ self.end_offset(),
)
}
- // https://dom.spec.whatwg.org/#dom-range-ispointinrange
+ /// <https://dom.spec.whatwg.org/#dom-range-ispointinrange>
fn IsPointInRange(&self, node: &Node, offset: u32) -> Fallible<bool> {
match self.compare_point(node, offset) {
Ok(Ordering::Less) => Ok(false),
@@ -483,7 +494,7 @@ impl RangeMethods for Range {
}
}
- // https://dom.spec.whatwg.org/#dom-range-comparepoint
+ /// <https://dom.spec.whatwg.org/#dom-range-comparepoint>
fn ComparePoint(&self, node: &Node, offset: u32) -> Fallible<i16> {
self.compare_point(node, offset).map(|order| match order {
Ordering::Less => -1,
@@ -492,11 +503,11 @@ impl RangeMethods for Range {
})
}
- // https://dom.spec.whatwg.org/#dom-range-intersectsnode
+ /// <https://dom.spec.whatwg.org/#dom-range-intersectsnode>
fn IntersectsNode(&self, node: &Node) -> bool {
- let start_node = self.StartContainer();
+ let start_node = self.start_container();
let start_node_root = self
- .StartContainer()
+ .start_container()
.inclusive_ancestors(ShadowIncluding::No)
.last()
.unwrap();
@@ -519,25 +530,26 @@ impl RangeMethods for Range {
let offset = node.index();
// Step 5.
Ordering::Greater ==
- bp_position(&parent, offset + 1, &start_node, self.StartOffset()).unwrap() &&
+ bp_position(&parent, offset + 1, &start_node, self.start_offset()).unwrap() &&
Ordering::Less ==
- bp_position(&parent, offset, &self.EndContainer(), self.EndOffset()).unwrap()
+ bp_position(&parent, offset, &self.end_container(), self.end_offset())
+ .unwrap()
}
- // https://dom.spec.whatwg.org/#dom-range-clonecontents
- // https://dom.spec.whatwg.org/#concept-range-clone
+ /// <https://dom.spec.whatwg.org/#dom-range-clonecontents>
+ /// <https://dom.spec.whatwg.org/#concept-range-clone>
fn CloneContents(&self) -> Fallible<DomRoot<DocumentFragment>> {
// Step 3.
- let start_node = self.StartContainer();
- let start_offset = self.StartOffset();
- let end_node = self.EndContainer();
- let end_offset = self.EndOffset();
+ let start_node = self.start_container();
+ let start_offset = self.start_offset();
+ let end_node = self.end_container();
+ let end_offset = self.end_offset();
// Step 1.
let fragment = DocumentFragment::new(&start_node.owner_doc());
// Step 2.
- if self.start == self.end {
+ if self.start() == self.end() {
return Ok(fragment);
}
@@ -625,20 +637,20 @@ impl RangeMethods for Range {
Ok(fragment)
}
- // https://dom.spec.whatwg.org/#dom-range-extractcontents
- // https://dom.spec.whatwg.org/#concept-range-extract
+ /// <https://dom.spec.whatwg.org/#dom-range-extractcontents>
+ /// <https://dom.spec.whatwg.org/#concept-range-extract>
fn ExtractContents(&self) -> Fallible<DomRoot<DocumentFragment>> {
// Step 3.
- let start_node = self.StartContainer();
- let start_offset = self.StartOffset();
- let end_node = self.EndContainer();
- let end_offset = self.EndOffset();
+ let start_node = self.start_container();
+ let start_offset = self.start_offset();
+ let end_node = self.end_container();
+ let end_offset = self.end_offset();
// Step 1.
let fragment = DocumentFragment::new(&start_node.owner_doc());
// Step 2.
- if self.Collapsed() {
+ if self.collapsed() {
return Ok(fragment);
}
@@ -763,16 +775,16 @@ impl RangeMethods for Range {
Ok(fragment)
}
- // https://dom.spec.whatwg.org/#dom-range-detach
+ /// <https://dom.spec.whatwg.org/#dom-range-detach>
fn Detach(&self) {
// This method intentionally left blank.
}
- // https://dom.spec.whatwg.org/#dom-range-insertnode
- // https://dom.spec.whatwg.org/#concept-range-insert
+ /// <https://dom.spec.whatwg.org/#dom-range-insertnode>
+ /// <https://dom.spec.whatwg.org/#concept-range-insert>
fn InsertNode(&self, node: &Node) -> ErrorResult {
- let start_node = self.StartContainer();
- let start_offset = self.StartOffset();
+ let start_node = self.start_container();
+ let start_offset = self.start_offset();
// Step 1.
if &*start_node == node {
@@ -846,25 +858,25 @@ impl RangeMethods for Range {
Node::pre_insert(node, &parent, reference_node.as_deref())?;
// Step 13.
- if self.Collapsed() {
+ if self.collapsed() {
self.set_end(&parent, new_offset);
}
Ok(())
}
- // https://dom.spec.whatwg.org/#dom-range-deletecontents
+ /// <https://dom.spec.whatwg.org/#dom-range-deletecontents>
fn DeleteContents(&self) -> ErrorResult {
// Step 1.
- if self.Collapsed() {
+ if self.collapsed() {
return Ok(());
}
// Step 2.
- let start_node = self.StartContainer();
- let end_node = self.EndContainer();
- let start_offset = self.StartOffset();
- let end_offset = self.EndOffset();
+ let start_node = self.start_container();
+ let end_node = self.end_container();
+ let start_offset = self.start_offset();
+ let end_offset = self.end_offset();
// Step 3.
if start_node == end_node {
@@ -937,11 +949,11 @@ impl RangeMethods for Range {
Ok(())
}
- // https://dom.spec.whatwg.org/#dom-range-surroundcontents
+ /// <https://dom.spec.whatwg.org/#dom-range-surroundcontents>
fn SurroundContents(&self, new_parent: &Node) -> ErrorResult {
// Step 1.
- let start = self.StartContainer();
- let end = self.EndContainer();
+ let start = self.start_container();
+ let end = self.end_container();
if start
.inclusive_ancestors(ShadowIncluding::No)
@@ -978,10 +990,10 @@ impl RangeMethods for Range {
self.SelectNode(new_parent)
}
- // https://dom.spec.whatwg.org/#dom-range-stringifier
+ /// <https://dom.spec.whatwg.org/#dom-range-stringifier>
fn Stringifier(&self) -> DOMString {
- let start_node = self.StartContainer();
- let end_node = self.EndContainer();
+ let start_node = self.start_container();
+ let end_node = self.end_container();
// Step 1.
let mut s = DOMString::new();
@@ -992,14 +1004,17 @@ impl RangeMethods for Range {
// Step 2.
if start_node == end_node {
return char_data
- .SubstringData(self.StartOffset(), self.EndOffset() - self.StartOffset())
+ .SubstringData(self.start_offset(), self.end_offset() - self.start_offset())
.unwrap();
}
// Step 3.
s.push_str(
&*char_data
- .SubstringData(self.StartOffset(), char_data.Length() - self.StartOffset())
+ .SubstringData(
+ self.start_offset(),
+ char_data.Length() - self.start_offset(),
+ )
.unwrap(),
);
}
@@ -1019,17 +1034,17 @@ impl RangeMethods for Range {
// Step 5.
if let Some(text_node) = end_node.downcast::<Text>() {
let char_data = text_node.upcast::<CharacterData>();
- s.push_str(&*char_data.SubstringData(0, self.EndOffset()).unwrap());
+ s.push_str(&*char_data.SubstringData(0, self.end_offset()).unwrap());
}
// Step 6.
s
}
- // https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#extensions-to-the-range-interface
+ /// <https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#extensions-to-the-range-interface>
fn CreateContextualFragment(&self, fragment: DOMString) -> Fallible<DomRoot<DocumentFragment>> {
// Step 1.
- let node = self.StartContainer();
+ let node = self.start_container();
let owner_doc = node.owner_doc();
let element = match node.type_id() {
NodeTypeId::Document(_) | NodeTypeId::DocumentFragment(_) => None,
@@ -1063,88 +1078,6 @@ impl RangeMethods for Range {
}
}
-#[derive(DenyPublicFields, JSTraceable, MallocSizeOf)]
-#[crown::unrooted_must_root_lint::must_root]
-pub struct BoundaryPoint {
- node: MutDom<Node>,
- offset: Cell<u32>,
-}
-
-impl BoundaryPoint {
- fn new(node: &Node, offset: u32) -> BoundaryPoint {
- debug_assert!(!node.is_doctype());
- debug_assert!(offset <= node.len());
- BoundaryPoint {
- node: MutDom::new(node),
- offset: Cell::new(offset),
- }
- }
-
- pub fn set(&self, node: &Node, offset: u32) {
- self.node.set(node);
- self.set_offset(offset);
- }
-
- pub fn set_offset(&self, offset: u32) {
- self.offset.set(offset);
- }
-}
-
-#[allow(crown::unrooted_must_root)]
-impl PartialOrd for BoundaryPoint {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- bp_position(
- &self.node.get(),
- self.offset.get(),
- &other.node.get(),
- other.offset.get(),
- )
- }
-}
-
-#[allow(crown::unrooted_must_root)]
-impl PartialEq for BoundaryPoint {
- fn eq(&self, other: &Self) -> bool {
- self.node.get() == other.node.get() && self.offset.get() == other.offset.get()
- }
-}
-
-// https://dom.spec.whatwg.org/#concept-range-bp-position
-fn bp_position(a_node: &Node, a_offset: u32, b_node: &Node, b_offset: u32) -> Option<Ordering> {
- if a_node as *const Node == b_node as *const Node {
- // Step 1.
- return Some(a_offset.cmp(&b_offset));
- }
- let position = b_node.CompareDocumentPosition(a_node);
- if position & NodeConstants::DOCUMENT_POSITION_DISCONNECTED != 0 {
- // No order is defined for nodes not in the same tree.
- None
- } else if position & NodeConstants::DOCUMENT_POSITION_FOLLOWING != 0 {
- // Step 2.
- match bp_position(b_node, b_offset, a_node, a_offset).unwrap() {
- Ordering::Less => Some(Ordering::Greater),
- Ordering::Greater => Some(Ordering::Less),
- Ordering::Equal => unreachable!(),
- }
- } else if position & NodeConstants::DOCUMENT_POSITION_CONTAINS != 0 {
- // Step 3-1, 3-2.
- let mut b_ancestors = b_node.inclusive_ancestors(ShadowIncluding::No);
- let child = b_ancestors
- .find(|child| &*child.GetParentNode().unwrap() == a_node)
- .unwrap();
- // Step 3-3.
- if child.index() < a_offset {
- Some(Ordering::Greater)
- } else {
- // Step 4.
- Some(Ordering::Less)
- }
- } else {
- // Step 4.
- Some(Ordering::Less)
- }
-}
-
pub struct WeakRangeVec {
cell: UnsafeCell<WeakRefVec<Range>>,
}
@@ -1189,16 +1122,16 @@ impl WeakRangeVec {
ranges.update(|entry| {
let range = entry.root().unwrap();
- if &range.start.node == parent || &range.end.node == parent {
+ if range.start().node() == parent || range.end().node() == parent {
entry.remove();
}
- if &range.start.node == child {
+ if range.start().node() == child {
range.report_change();
- range.start.set(context.parent, offset);
+ range.start().set(context.parent, offset);
}
- if &range.end.node == child {
+ if range.end().node() == child {
range.report_change();
- range.end.set(context.parent, offset);
+ range.end().set(context.parent, offset);
}
});
@@ -1218,16 +1151,16 @@ impl WeakRangeVec {
ranges.update(|entry| {
let range = entry.root().unwrap();
- if &range.start.node == sibling || &range.end.node == sibling {
+ if range.start().node() == sibling || range.end().node() == sibling {
entry.remove();
}
- if &range.start.node == node {
+ if range.start().node() == node {
range.report_change();
- range.start.set(sibling, range.StartOffset() + length);
+ range.start().set(sibling, range.start_offset() + length);
}
- if &range.end.node == node {
+ if range.end().node() == node {
range.report_change();
- range.end.set(sibling, range.EndOffset() + length);
+ range.end().set(sibling, range.end_offset() + length);
}
});
@@ -1244,17 +1177,17 @@ impl WeakRangeVec {
(*self.cell.get()).update(|entry| {
let range = entry.root().unwrap();
- let node_is_start = &range.start.node == node;
- let node_is_end = &range.end.node == node;
+ let node_is_start = range.start().node() == node;
+ let node_is_end = range.end().node() == node;
- let move_start = node_is_start && range.StartOffset() == offset;
- let move_end = node_is_end && range.EndOffset() == offset;
+ let move_start = node_is_start && range.start_offset() == offset;
+ let move_end = node_is_end && range.end_offset() == offset;
let remove_from_node = move_start && move_end ||
move_start && !node_is_end ||
move_end && !node_is_start;
- let already_in_child = &range.start.node == child || &range.end.node == child;
+ let already_in_child = range.start().node() == child || range.end().node() == child;
let push_to_child = !already_in_child && (move_start || move_end);
if remove_from_node {
@@ -1268,11 +1201,11 @@ impl WeakRangeVec {
if move_start {
range.report_change();
- range.start.set(child, new_offset);
+ range.start().set(child, new_offset);
}
if move_end {
range.report_change();
- range.end.set(child, new_offset);
+ range.end().set(child, new_offset);
}
});
}
@@ -1304,11 +1237,11 @@ impl WeakRangeVec {
(*self.cell.get()).update(|entry| {
let range = entry.root().unwrap();
- let start_offset = range.StartOffset();
- let end_offset = range.EndOffset();
+ let start_offset = range.start_offset();
+ let end_offset = range.end_offset();
- let node_is_start = &range.start.node == node;
- let node_is_end = &range.end.node == node;
+ let node_is_start = range.start().node() == node;
+ let node_is_end = range.end().node() == node;
let move_start = node_is_start && start_offset > offset;
let move_end = node_is_end && end_offset > offset;
@@ -1317,7 +1250,8 @@ impl WeakRangeVec {
move_start && !node_is_end ||
move_end && !node_is_start;
- let already_in_sibling = &range.start.node == sibling || &range.end.node == sibling;
+ let already_in_sibling =
+ range.start().node() == sibling || range.end().node() == sibling;
let push_to_sibling = !already_in_sibling && (move_start || move_end);
if remove_from_node {
@@ -1331,11 +1265,11 @@ impl WeakRangeVec {
if move_start {
range.report_change();
- range.start.set(sibling, start_offset - offset);
+ range.start().set(sibling, start_offset - offset);
}
if move_end {
range.report_change();
- range.end.set(sibling, end_offset - offset);
+ range.end().set(sibling, end_offset - offset);
}
});
}
@@ -1347,13 +1281,13 @@ impl WeakRangeVec {
unsafe {
(*self.cell.get()).update(|entry| {
let range = entry.root().unwrap();
- if &range.start.node == node && offset == range.StartOffset() {
+ if range.start().node() == node && offset == range.start_offset() {
range.report_change();
- range.start.set_offset(offset + 1);
+ range.start().set_offset(offset + 1);
}
- if &range.end.node == node && offset == range.EndOffset() {
+ if range.end().node() == node && offset == range.end_offset() {
range.report_change();
- range.end.set_offset(offset + 1);
+ range.end().set_offset(offset + 1);
}
});
}
@@ -1363,21 +1297,21 @@ impl WeakRangeVec {
unsafe {
(*self.cell.get()).update(|entry| {
let range = entry.root().unwrap();
- let start_offset = range.StartOffset();
- if &range.start.node == node && start_offset > offset {
+ let start_offset = range.start_offset();
+ if range.start().node() == node && start_offset > offset {
range.report_change();
- range.start.set_offset(f(start_offset));
+ range.start().set_offset(f(start_offset));
}
- let end_offset = range.EndOffset();
- if &range.end.node == node && end_offset > offset {
+ let end_offset = range.end_offset();
+ if range.end().node() == node && end_offset > offset {
range.report_change();
- range.end.set_offset(f(end_offset));
+ range.end().set_offset(f(end_offset));
}
});
}
}
- fn push(&self, ref_: WeakRef<Range>) {
+ pub fn push(&self, ref_: WeakRef<Range>) {
unsafe {
(*self.cell.get()).push(ref_);
}
diff --git a/components/script/dom/selection.rs b/components/script/dom/selection.rs
index 2d5b3cb0474..8d16372e46c 100644
--- a/components/script/dom/selection.rs
+++ b/components/script/dom/selection.rs
@@ -113,8 +113,8 @@ impl SelectionMethods for Selection {
fn GetAnchorNode(&self) -> Option<DomRoot<Node>> {
if let Some(range) = self.range.get() {
match self.direction.get() {
- Direction::Forwards => Some(range.StartContainer()),
- _ => Some(range.EndContainer()),
+ Direction::Forwards => Some(range.start_container()),
+ _ => Some(range.end_container()),
}
} else {
None
@@ -125,8 +125,8 @@ impl SelectionMethods for Selection {
fn AnchorOffset(&self) -> u32 {
if let Some(range) = self.range.get() {
match self.direction.get() {
- Direction::Forwards => range.StartOffset(),
- _ => range.EndOffset(),
+ Direction::Forwards => range.start_offset(),
+ _ => range.end_offset(),
}
} else {
0
@@ -137,8 +137,8 @@ impl SelectionMethods for Selection {
fn GetFocusNode(&self) -> Option<DomRoot<Node>> {
if let Some(range) = self.range.get() {
match self.direction.get() {
- Direction::Forwards => Some(range.EndContainer()),
- _ => Some(range.StartContainer()),
+ Direction::Forwards => Some(range.end_container()),
+ _ => Some(range.start_container()),
}
} else {
None
@@ -149,8 +149,8 @@ impl SelectionMethods for Selection {
fn FocusOffset(&self) -> u32 {
if let Some(range) = self.range.get() {
match self.direction.get() {
- Direction::Forwards => range.EndOffset(),
- _ => range.StartOffset(),
+ Direction::Forwards => range.end_offset(),
+ _ => range.start_offset(),
}
} else {
0
@@ -160,7 +160,7 @@ impl SelectionMethods for Selection {
// https://w3c.github.io/selection-api/#dom-selection-iscollapsed
fn IsCollapsed(&self) -> bool {
if let Some(range) = self.range.get() {
- range.Collapsed()
+ range.collapsed()
} else {
true
}
@@ -178,7 +178,7 @@ impl SelectionMethods for Selection {
// https://w3c.github.io/selection-api/#dom-selection-type
fn Type(&self) -> DOMString {
if let Some(range) = self.range.get() {
- if range.Collapsed() {
+ if range.collapsed() {
DOMString::from("Caret")
} else {
DOMString::from("Range")
@@ -202,7 +202,7 @@ impl SelectionMethods for Selection {
// https://w3c.github.io/selection-api/#dom-selection-addrange
fn AddRange(&self, range: &Range) {
// Step 1
- if !self.is_same_root(&*range.StartContainer()) {
+ if !self.is_same_root(&*range.start_container()) {
return;
}
@@ -283,7 +283,7 @@ impl SelectionMethods for Selection {
// https://w3c.github.io/selection-api/#dom-selection-collapsetostart
fn CollapseToStart(&self) -> ErrorResult {
if let Some(range) = self.range.get() {
- self.Collapse(Some(&*range.StartContainer()), range.StartOffset())
+ self.Collapse(Some(&*range.start_container()), range.start_offset())
} else {
Err(Error::InvalidState)
}
@@ -292,7 +292,7 @@ impl SelectionMethods for Selection {
// https://w3c.github.io/selection-api/#dom-selection-collapsetoend
fn CollapseToEnd(&self) -> ErrorResult {
if let Some(range) = self.range.get() {
- self.Collapse(Some(&*range.EndContainer()), range.EndOffset())
+ self.Collapse(Some(&*range.end_container()), range.end_offset())
} else {
Err(Error::InvalidState)
}
@@ -319,7 +319,7 @@ impl SelectionMethods for Selection {
}
// Step 4
- if !self.is_same_root(&*range.StartContainer()) {
+ if !self.is_same_root(&*range.start_container()) {
// Step 5, and its following 8 and 9
self.set_range(&*Range::new(&self.document, node, offset, node, offset));
self.direction.set(Direction::Forwards);
@@ -458,7 +458,7 @@ impl SelectionMethods for Selection {
return false;
}
if let Some(range) = self.range.get() {
- let start_node = &*range.StartContainer();
+ let start_node = &*range.start_container();
if !self.is_same_root(start_node) {
// node can't be contained in a range with a different root
return false;
@@ -468,30 +468,30 @@ impl SelectionMethods for Selection {
if node.is_before(start_node) {
return false;
}
- let end_node = &*range.EndContainer();
+ let end_node = &*range.end_container();
if end_node.is_before(node) {
return false;
}
if node == start_node {
- return range.StartOffset() < node.len();
+ return range.start_offset() < node.len();
}
if node == end_node {
- return range.EndOffset() > 0;
+ return range.end_offset() > 0;
}
true
} else {
if node.is_before(start_node) {
return false;
}
- let end_node = &*range.EndContainer();
+ let end_node = &*range.end_container();
if end_node.is_before(node) {
return false;
}
if node == start_node {
- return range.StartOffset() == 0;
+ return range.start_offset() == 0;
}
if node == end_node {
- return range.EndOffset() == node.len();
+ return range.end_offset() == node.len();
}
true
}
diff --git a/components/script/dom/staticrange.rs b/components/script/dom/staticrange.rs
new file mode 100644
index 00000000000..84c25e12f47
--- /dev/null
+++ b/components/script/dom/staticrange.rs
@@ -0,0 +1,88 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use dom_struct::dom_struct;
+use js::rust::HandleObject;
+
+use crate::dom::abstractrange::AbstractRange;
+use crate::dom::bindings::codegen::Bindings::StaticRangeBinding::StaticRangeInit;
+use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
+use crate::dom::bindings::error::{Error, Fallible};
+use crate::dom::bindings::inheritance::NodeTypeId;
+use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::document::Document;
+use crate::dom::node::Node;
+use crate::dom::window::Window;
+
+#[dom_struct]
+pub struct StaticRange {
+ abstract_range: AbstractRange,
+}
+
+impl StaticRange {
+ fn new_inherited(
+ start_container: &Node,
+ start_offset: u32,
+ end_container: &Node,
+ end_offset: u32,
+ ) -> StaticRange {
+ StaticRange {
+ abstract_range: AbstractRange::new_inherited(
+ start_container,
+ start_offset,
+ end_container,
+ end_offset,
+ ),
+ }
+ }
+ pub fn new_with_doc(
+ document: &Document,
+ proto: Option<HandleObject>,
+ init: &StaticRangeInit,
+ ) -> DomRoot<StaticRange> {
+ StaticRange::new_with_proto(document, proto, init)
+ }
+
+ pub fn new_with_proto(
+ document: &Document,
+ proto: Option<HandleObject>,
+ init: &StaticRangeInit,
+ ) -> DomRoot<StaticRange> {
+ let staticrange = reflect_dom_object_with_proto(
+ Box::new(StaticRange::new_inherited(
+ &init.startContainer,
+ init.startOffset,
+ &init.endContainer,
+ init.endOffset,
+ )),
+ document.window(),
+ proto,
+ );
+ staticrange
+ }
+
+ /// <https://dom.spec.whatwg.org/#dom-staticrange-staticrange>
+ #[allow(non_snake_case)]
+ pub fn Constructor(
+ window: &Window,
+ proto: Option<HandleObject>,
+ init: &StaticRangeInit,
+ ) -> Fallible<DomRoot<StaticRange>> {
+ match init.startContainer.type_id() {
+ NodeTypeId::DocumentType | NodeTypeId::Attr => {
+ return Err(Error::InvalidNodeType);
+ },
+ _ => (),
+ }
+ match init.endContainer.type_id() {
+ NodeTypeId::DocumentType | NodeTypeId::Attr => {
+ return Err(Error::InvalidNodeType);
+ },
+ _ => (),
+ }
+ let document = window.Document();
+ Ok(StaticRange::new_with_doc(&document, proto, init))
+ }
+}
diff --git a/components/script/dom/webidls/AbstractRange.webidl b/components/script/dom/webidls/AbstractRange.webidl
new file mode 100644
index 00000000000..4472d27fc20
--- /dev/null
+++ b/components/script/dom/webidls/AbstractRange.webidl
@@ -0,0 +1,21 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+/*
+ * The origin of this IDL file is
+ * https://dom.spec.whatwg.org/#interface-abstractrange
+ */
+
+[Exposed=Window]
+interface AbstractRange {
+ [Pure]
+ readonly attribute Node startContainer;
+ [Pure]
+ readonly attribute unsigned long startOffset;
+ [Pure]
+ readonly attribute Node endContainer;
+ [Pure]
+ readonly attribute unsigned long endOffset;
+ [Pure]
+ readonly attribute boolean collapsed;
+};
diff --git a/components/script/dom/webidls/Range.webidl b/components/script/dom/webidls/Range.webidl
index 037093a0762..7ba168ddb05 100644
--- a/components/script/dom/webidls/Range.webidl
+++ b/components/script/dom/webidls/Range.webidl
@@ -9,19 +9,9 @@
*/
[Exposed=Window]
-interface Range {
+interface Range : AbstractRange {
[Throws] constructor();
[Pure]
- readonly attribute Node startContainer;
- [Pure]
- readonly attribute unsigned long startOffset;
- [Pure]
- readonly attribute Node endContainer;
- [Pure]
- readonly attribute unsigned long endOffset;
- [Pure]
- readonly attribute boolean collapsed;
- [Pure]
readonly attribute Node commonAncestorContainer;
[Throws]
diff --git a/components/script/dom/webidls/StaticRange.webidl b/components/script/dom/webidls/StaticRange.webidl
new file mode 100644
index 00000000000..a582afe3d7a
--- /dev/null
+++ b/components/script/dom/webidls/StaticRange.webidl
@@ -0,0 +1,19 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+/*
+ * The origin of this IDL file is
+ * https://dom.spec.whatwg.org/#interface-staticrange
+ */
+
+dictionary StaticRangeInit {
+ required Node startContainer;
+ required unsigned long startOffset;
+ required Node endContainer;
+ required unsigned long endOffset;
+};
+
+[Exposed=Window]
+interface StaticRange : AbstractRange {
+ [Throws] constructor(StaticRangeInit init);
+};