mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
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>
This commit is contained in:
parent
bae77671f8
commit
cb275e086c
15 changed files with 530 additions and 506 deletions
177
components/script/dom/abstractrange.rs
Normal file
177
components/script/dom/abstractrange.rs
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -30,6 +30,14 @@ DOMInterfaces = {
|
|||
'spiderMonkeyInterface': True,
|
||||
},
|
||||
|
||||
'AbstractRange': {
|
||||
'weakReferenceable': True,
|
||||
},
|
||||
|
||||
'StaticRange': {
|
||||
'weakReferenceable': True,
|
||||
},
|
||||
|
||||
'Range': {
|
||||
'weakReferenceable': True,
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn start_offset(&self) -> u32 {
|
||||
self.abstract_range().StartOffset()
|
||||
}
|
||||
|
||||
pub fn end_container(&self) -> DomRoot<Node> {
|
||||
self.abstract_range().EndContainer()
|
||||
}
|
||||
|
||||
pub fn end_offset(&self) -> u32 {
|
||||
self.abstract_range().EndOffset()
|
||||
}
|
||||
|
||||
pub fn collapsed(&self) -> bool {
|
||||
self.abstract_range().Collapsed()
|
||||
}
|
||||
}
|
||||
|
||||
impl RangeMethods for Range {
|
||||
// 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
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-range-commonancestorcontainer
|
||||
/// <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_);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
88
components/script/dom/staticrange.rs
Normal file
88
components/script/dom/staticrange.rs
Normal file
|
@ -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))
|
||||
}
|
||||
}
|
21
components/script/dom/webidls/AbstractRange.webidl
Normal file
21
components/script/dom/webidls/AbstractRange.webidl
Normal file
|
@ -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;
|
||||
};
|
|
@ -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]
|
||||
|
|
19
components/script/dom/webidls/StaticRange.webidl
Normal file
19
components/script/dom/webidls/StaticRange.webidl
Normal file
|
@ -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);
|
||||
};
|
|
@ -11,9 +11,6 @@
|
|||
[Element interface: element must inherit property "assignedSlot" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[AbortController interface object name]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -41,9 +38,6 @@
|
|||
[Element interface: operation append([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: attribute origin]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -59,18 +53,12 @@
|
|||
[EventTarget interface: calling addEventListener(DOMString, EventListener, [object Object\],[object Object\]) on new AbortController().signal with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute startContainer]
|
||||
expected: FAIL
|
||||
|
||||
[AbortSignal interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[Event interface: new CustomEvent("foo") must inherit property "composed" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: operation attachShadow(ShadowRootInit)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -95,18 +83,9 @@
|
|||
[DocumentType interface: operation replaceWith([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[AbortSignal interface: attribute aborted]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute endContainer]
|
||||
expected: FAIL
|
||||
|
||||
[AbortController must be primary interface of new AbortController()]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -116,9 +95,6 @@
|
|||
[CharacterData interface: operation remove()]
|
||||
expected: FAIL
|
||||
|
||||
[Range interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -128,9 +104,6 @@
|
|||
[Element interface: element must inherit property "slot" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[AbortController interface: new AbortController() must inherit property "signal" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -143,12 +116,6 @@
|
|||
[AbortController interface: new AbortController() must inherit property "abort()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute collapsed]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute startOffset]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: operation prepend([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -158,21 +125,12 @@
|
|||
[AbortController interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[Range interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: operation before([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[EventTarget interface: calling dispatchEvent(Event) on new AbortController().signal with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[AbortController interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -182,9 +140,6 @@
|
|||
[Element interface: attribute slot]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[DocumentFragment interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -194,9 +149,6 @@
|
|||
[Element interface: operation prepend([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[DocumentType interface: operation after([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -230,9 +182,6 @@
|
|||
[Element interface: operation remove()]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
[Stringification of new AbortController().signal]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -242,9 +191,6 @@
|
|||
[DocumentFragment interface: operation append([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute endOffset]
|
||||
expected: FAIL
|
||||
|
||||
[CharacterData interface: operation before([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -254,9 +200,6 @@
|
|||
[CharacterData interface: operation after([object Object\],[object Object\])]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
[Event interface: document.createEvent("Event") must inherit property "composed" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
[StaticRange-constructor.html]
|
||||
[Construct static range with endpoints in disconnected trees]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Element startContainer and Text endContainer]
|
||||
expected: FAIL
|
||||
|
||||
[Construct collapsed static range]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Document container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with standalone Node container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with offset greater than length]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Comment container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct inverted static range]
|
||||
expected: FAIL
|
||||
|
||||
[Throw on DocumentType or Attr container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with CDATASection container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Text container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Text startContainer and Element endContainer]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with DocumentFragment container]
|
||||
expected: FAIL
|
||||
|
||||
[Throw on missing or invalid arguments]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Element container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with ProcessingInstruction container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with endpoints in disconnected documents]
|
||||
expected: FAIL
|
||||
|
|
@ -37,9 +37,6 @@
|
|||
[Element interface: element must inherit property "assignedSlot" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[AbortController interface object name]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -70,9 +67,6 @@
|
|||
[Element interface: attribute shadowRoot]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[XPathResult interface: document.evaluate("//*", document.body) must inherit property "ORDERED_NODE_ITERATOR_TYPE" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -85,15 +79,9 @@
|
|||
[EventTarget interface: new AbortController().signal must inherit property "dispatchEvent(Event)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute startContainer]
|
||||
expected: FAIL
|
||||
|
||||
[AbortSignal interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[Event interface: new CustomEvent("foo") must inherit property "composed" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -103,9 +91,6 @@
|
|||
[EventTarget interface: new AbortController().signal must inherit property "removeEventListener(DOMString, EventListener?, optional (EventListenerOptions or boolean))" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: operation attachShadow(ShadowRootInit)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -145,9 +130,6 @@
|
|||
[XPathResult interface: constant ORDERED_NODE_SNAPSHOT_TYPE on interface object]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[XPathResult interface: constant ANY_TYPE on interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -205,9 +187,6 @@
|
|||
[XPathResult interface: calling snapshotItem(unsigned long) on document.evaluate("//*", document.body) with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Range interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
[XPathResult interface: document.evaluate("//*", document.body) must inherit property "snapshotItem(unsigned long)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -220,9 +199,6 @@
|
|||
[Document interface: new Document() must inherit property "evaluate(DOMString, Node, optional XPathNSResolver?, optional unsigned short, optional XPathResult?)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: xmlDoc must inherit property "evaluate(DOMString, Node, optional XPathNSResolver?, optional unsigned short, optional XPathResult?)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -247,12 +223,6 @@
|
|||
[Element interface: attribute slot]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute collapsed]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute startOffset]
|
||||
expected: FAIL
|
||||
|
||||
[XPathResult interface: document.evaluate("//*", document.body) must inherit property "invalidIteratorState" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -265,9 +235,6 @@
|
|||
[AbortController interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[Range interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[XPathExpression interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -289,9 +256,6 @@
|
|||
[XPathResult interface: attribute resultType]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface prototype object's "constructor" property]
|
||||
expected: FAIL
|
||||
|
||||
[Document interface: xmlDoc must inherit property "createExpression(DOMString, optional XPathNSResolver?)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -328,9 +292,6 @@
|
|||
[XPathResult interface: document.evaluate("//*", document.body) must inherit property "UNORDERED_NODE_SNAPSHOT_TYPE" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface object name]
|
||||
expected: FAIL
|
||||
|
||||
[DocumentFragment interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -364,9 +325,6 @@
|
|||
[XPathEvaluator interface: new XPathEvaluator() must inherit property "createNSResolver(Node)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface object length]
|
||||
expected: FAIL
|
||||
|
||||
[XPathResult interface: document.evaluate("//*", document.body) must inherit property "resultType" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -412,9 +370,6 @@
|
|||
[Document interface: operation createExpression(DOMString, optional XPathNSResolver?)]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute endContainer]
|
||||
expected: FAIL
|
||||
|
||||
[AbortSignal interface object length]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -478,9 +433,6 @@
|
|||
[Stringification of new AbortController().signal]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
[XPathResult interface: constant ANY_UNORDERED_NODE_TYPE on interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -493,9 +445,6 @@
|
|||
[CharacterData interface: operation after((Node or DOMString)...)]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: attribute endOffset]
|
||||
expected: FAIL
|
||||
|
||||
[XPathExpression interface object length]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -523,9 +472,6 @@
|
|||
[Stringification of new AbortController()]
|
||||
expected: FAIL
|
||||
|
||||
[AbstractRange interface: existence and properties of interface prototype object]
|
||||
expected: FAIL
|
||||
|
||||
[XPathExpression interface: calling evaluate(Node, optional unsigned short, optional XPathResult?) on document.createExpression("//*") with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -535,9 +481,6 @@
|
|||
[XPathResult interface: operation iterateNext()]
|
||||
expected: FAIL
|
||||
|
||||
[StaticRange interface: existence and properties of interface prototype object's @@unscopables property]
|
||||
expected: FAIL
|
||||
|
||||
[Event interface: document.createEvent("Event") must inherit property "composed" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
[StaticRange-constructor.html]
|
||||
[Construct static range with Element container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Text container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Element startContainer and Text endContainer]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Text startContainer and Element endContainer]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with ProcessingInstruction container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Comment container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with CDATASection container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with Document container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with DocumentFragment container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct collapsed static range]
|
||||
expected: FAIL
|
||||
|
||||
[Construct inverted static range]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with offset greater than length]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with standalone Node container]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with endpoints in disconnected trees]
|
||||
expected: FAIL
|
||||
|
||||
[Construct static range with endpoints in disconnected documents]
|
||||
expected: FAIL
|
||||
|
||||
[Throw on DocumentType or Attr container]
|
||||
expected: FAIL
|
||||
|
||||
[Throw on missing or invalid arguments]
|
||||
expected: FAIL
|
|
@ -13410,7 +13410,7 @@
|
|||
]
|
||||
],
|
||||
"interfaces.html": [
|
||||
"e1a93db2757a85e2baa2ceeaed3d6f24b0feec8d",
|
||||
"5461ff50d836f872fdf09defd98575d08fda0061",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
// IMPORTANT: Do not change the list below without review from a DOM peer!
|
||||
test_interfaces([
|
||||
"AbstractRange",
|
||||
"AnalyserNode",
|
||||
"AnimationEvent",
|
||||
"Attr",
|
||||
|
@ -222,6 +223,7 @@ test_interfaces([
|
|||
"Screen",
|
||||
"Selection",
|
||||
"ShadowRoot",
|
||||
"StaticRange",
|
||||
"StereoPannerNode",
|
||||
"Storage",
|
||||
"StorageEvent",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue