-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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>
- Loading branch information
1 parent
bae7767
commit cb275e0
Showing
15 changed files
with
522 additions
and
498 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.