mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
commit
462940fc2a
14 changed files with 162 additions and 87 deletions
|
@ -33,8 +33,9 @@ In the `_finalize()` function the pointer of the Rusty DOM object that is contai
|
|||
For supporting SpiderMonkey’s exact GC rooting, we introduce [some types](https://github.com/mozilla/servo/wiki/Using-DOM-types):
|
||||
|
||||
- `JS<T>` is used for the DOM typed field in a DOM type structure. The GC can trace them recursively while the enclosing DOM object (maybe root) is alive.
|
||||
- `LayoutJS<T>` is specialized `JS<T>` to use in layout. `Layout*Helper` must be implemented on this type to prevent calling methods from non layout code.
|
||||
- `Temporary<T>` is used as a return value for functions returning a DOM type. They are rooted for the duration of their lifetime. But a retun value gets moved around which can break the LIFO ordering constraint. Thus we need to introduce `Root<T>`.
|
||||
- `Root<T>` contains the pointer to `JSObject` which the represented DOM type has. SpiderMonkey's conservative stack scanner scans it's pointers and marks a pointed `JSObject` as GC root.
|
||||
- `JSRef` is just a reference to the value rooted by `Root<T>`.
|
||||
- `RootCollection` is used to dynamically check if rooting satisfies LIFO ordering, because SpiderMonkey's GC requires LIFO order (See also: [Exact Stack Rooting - Storing a GCPointer on the CStack](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting)).
|
||||
- `MutHeap<T>` is a version of `Cell<T>` that is safe to use for internal mutability of Spidermonkey heap objects like `JSVal` and `JS<T>`
|
||||
- `MutHeap<T>` is a version of `Cell<T>` that is safe to use for internal mutability of Spidermonkey heap objects like `JSVal` and `JS<T>`
|
||||
|
|
|
@ -5220,7 +5220,7 @@ class GlobalGenRoots():
|
|||
descriptors = config.getDescriptors(register=True, isCallback=False)
|
||||
allprotos = [CGGeneric("#![allow(unused_imports)]\n"),
|
||||
CGGeneric("use dom::types::*;\n"),
|
||||
CGGeneric("use dom::bindings::js::{JS, JSRef, Temporary};\n"),
|
||||
CGGeneric("use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};\n"),
|
||||
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
|
||||
CGGeneric("use dom::bindings::utils::Reflectable;\n"),
|
||||
CGGeneric("use js::jsapi::JSTracer;\n\n"),
|
||||
|
@ -5279,6 +5279,17 @@ pub trait ${castTraitName} : Sized {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[allow(unrooted_must_root)]
|
||||
fn to_layout_js<T: ${toBound}+Reflectable>(base: &LayoutJS<T>) -> Option<LayoutJS<Self>> {
|
||||
unsafe {
|
||||
match (*base.unsafe_get()).${checkFn}() {
|
||||
true => Some(base.transmute_copy()),
|
||||
false => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: JSRef<'a, T>) -> JSRef<'a, Self> {
|
||||
unsafe { derived.transmute() }
|
||||
|
|
|
@ -129,8 +129,32 @@ pub struct JS<T> {
|
|||
ptr: NonZero<*const T>
|
||||
}
|
||||
|
||||
impl<T> JS<T> {
|
||||
/// Returns `LayoutJS<T>` containing the same pointer.
|
||||
fn to_layout(self) -> LayoutJS<T> {
|
||||
LayoutJS {
|
||||
ptr: self.ptr.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This is specialized `JS<T>` to use in under `layout` crate.
|
||||
/// `Layout*Helpers` traits must be implemented on this.
|
||||
pub struct LayoutJS<T> {
|
||||
ptr: NonZero<*const T>
|
||||
}
|
||||
|
||||
impl<T: Reflectable> LayoutJS<T> {
|
||||
/// Get the reflector.
|
||||
pub unsafe fn get_jsobject(&self) -> *mut JSObject {
|
||||
(**self.ptr).reflector().get_jsobject()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for JS<T> {}
|
||||
|
||||
impl<T> Copy for LayoutJS<T> {}
|
||||
|
||||
impl<T> PartialEq for JS<T> {
|
||||
#[allow(unrooted_must_root)]
|
||||
fn eq(&self, other: &JS<T>) -> bool {
|
||||
|
@ -138,6 +162,13 @@ impl<T> PartialEq for JS<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for LayoutJS<T> {
|
||||
#[allow(unrooted_must_root)]
|
||||
fn eq(&self, other: &LayoutJS<T>) -> bool {
|
||||
self.ptr == other.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl <T> Clone for JS<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> JS<T> {
|
||||
|
@ -147,6 +178,15 @@ impl <T> Clone for JS<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl <T> Clone for LayoutJS<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> LayoutJS<T> {
|
||||
LayoutJS {
|
||||
ptr: self.ptr.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl JS<Node> {
|
||||
/// Create a new JS-owned value wrapped from an address known to be a `Node` pointer.
|
||||
pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<Node> {
|
||||
|
@ -158,6 +198,16 @@ impl JS<Node> {
|
|||
}
|
||||
}
|
||||
|
||||
impl LayoutJS<Node> {
|
||||
/// Create a new JS-owned value wrapped from an address known to be a `Node` pointer.
|
||||
pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> LayoutJS<Node> {
|
||||
let TrustedNodeAddress(addr) = inner;
|
||||
LayoutJS {
|
||||
ptr: NonZero::new(addr as *const Node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> JS<T> {
|
||||
/// Create a new JS-owned value wrapped from a raw Rust pointer.
|
||||
pub unsafe fn from_raw(raw: *const T) -> JS<T> {
|
||||
|
@ -296,6 +346,12 @@ impl<T: Reflectable> MutNullableJS<T> {
|
|||
self.ptr.get()
|
||||
}
|
||||
|
||||
/// Retrieve a copy of the inner optional `JS<T>` as `LayoutJS<T>`.
|
||||
/// For use by layout, which can't use safe types like Temporary.
|
||||
pub unsafe fn get_inner_as_layout(&self) -> Option<LayoutJS<T>> {
|
||||
self.get_inner().map(|js| js.to_layout())
|
||||
}
|
||||
|
||||
/// Retrieve a copy of the current inner value. If it is `None`, it is
|
||||
/// initialized with the result of `cb` first.
|
||||
pub fn or_init<F>(&self, cb: F) -> Temporary<T>
|
||||
|
@ -313,9 +369,8 @@ impl<T: Reflectable> MutNullableJS<T> {
|
|||
}
|
||||
|
||||
impl<T: Reflectable> JS<T> {
|
||||
/// Returns an unsafe pointer to the interior of this object. This is the
|
||||
/// only method that be safely accessed from layout. (The fact that this is
|
||||
/// unsafe is what necessitates the layout wrappers.)
|
||||
/// Returns an unsafe pointer to the interior of this object.
|
||||
/// This should only be used by the DOM bindings.
|
||||
pub unsafe fn unsafe_get(&self) -> *const T {
|
||||
*self.ptr
|
||||
}
|
||||
|
@ -328,19 +383,28 @@ impl<T: Reflectable> JS<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<From> JS<From> {
|
||||
/// Return `self` as a `JS` of another type.
|
||||
//XXXjdm It would be lovely if this could be private.
|
||||
pub unsafe fn transmute<To>(self) -> JS<To> {
|
||||
mem::transmute(self)
|
||||
impl<T: Reflectable> LayoutJS<T> {
|
||||
/// Returns an unsafe pointer to the interior of this JS object without touching the borrow
|
||||
/// flags. This is the only method that be safely accessed from layout. (The fact that this
|
||||
/// is unsafe is what necessitates the layout wrappers.)
|
||||
pub unsafe fn unsafe_get(&self) -> *const T {
|
||||
*self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<From> JS<From> {
|
||||
/// Return `self` as a `JS` of another type.
|
||||
pub unsafe fn transmute_copy<To>(&self) -> JS<To> {
|
||||
mem::transmute_copy(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<From> LayoutJS<From> {
|
||||
/// Return `self` as a `LayoutJS` of another type.
|
||||
pub unsafe fn transmute_copy<To>(&self) -> LayoutJS<To> {
|
||||
mem::transmute_copy(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get an `Option<JSRef<T>>` out of an `Option<Root<T>>`
|
||||
pub trait RootedReference<T> {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding;
|
||||
use dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DMethods;
|
||||
use dom::bindings::global::{GlobalRef, GlobalField};
|
||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
use dom::htmlcanvaselement::HTMLCanvasElement;
|
||||
|
||||
|
@ -50,7 +50,7 @@ pub trait LayoutCanvasRenderingContext2DHelpers {
|
|||
unsafe fn get_renderer(&self) -> Sender<CanvasMsg>;
|
||||
}
|
||||
|
||||
impl LayoutCanvasRenderingContext2DHelpers for JS<CanvasRenderingContext2D> {
|
||||
impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D> {
|
||||
unsafe fn get_renderer(&self) -> Sender<CanvasMsg> {
|
||||
(*self.unsafe_get()).renderer.clone()
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use dom::bindings::error::{ErrorResult, Fallible};
|
|||
use dom::bindings::error::Error::{NotSupported, InvalidCharacter};
|
||||
use dom::bindings::error::Error::{HierarchyRequest, NamespaceError};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{OptionalRootable, RootedReference};
|
||||
use dom::bindings::utils::reflect_dom_object;
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
|
@ -395,7 +395,7 @@ pub trait LayoutDocumentHelpers {
|
|||
unsafe fn is_html_document_for_layout(&self) -> bool;
|
||||
}
|
||||
|
||||
impl LayoutDocumentHelpers for JS<Document> {
|
||||
impl LayoutDocumentHelpers for LayoutJS<Document> {
|
||||
#[allow(unrooted_must_root)]
|
||||
#[inline]
|
||||
unsafe fn is_html_document_for_layout(&self) -> bool {
|
||||
|
|
|
@ -23,7 +23,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLTableRowElementDerived, HTMLTextA
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLTableSectionElementDerived, NodeCast};
|
||||
use dom::bindings::error::{ErrorResult, Fallible};
|
||||
use dom::bindings::error::Error::{NamespaceError, InvalidCharacter, Syntax};
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, LayoutJS, Temporary, TemporaryPushable};
|
||||
use dom::bindings::js::{OptionalRootable, Root};
|
||||
use dom::bindings::utils::xml_name_type;
|
||||
use dom::bindings::utils::XMLName::{QName, Name, InvalidXMLName};
|
||||
|
@ -376,13 +376,13 @@ pub trait LayoutElementHelpers {
|
|||
unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool;
|
||||
}
|
||||
|
||||
impl LayoutElementHelpers for JS<Element> {
|
||||
impl LayoutElementHelpers for LayoutJS<Element> {
|
||||
#[inline]
|
||||
unsafe fn html_element_in_html_document_for_layout(&self) -> bool {
|
||||
if (*self.unsafe_get()).namespace != ns!(HTML) {
|
||||
return false
|
||||
}
|
||||
let node: JS<Node> = self.transmute_copy();
|
||||
let node: LayoutJS<Node> = self.transmute_copy();
|
||||
node.owner_doc_for_layout().is_html_document_for_layout()
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElemen
|
|||
use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived;
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{MutNullableJS, JS, JSRef, Temporary};
|
||||
use dom::bindings::js::{MutNullableJS, JSRef, LayoutJS, Temporary};
|
||||
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||
use dom::document::Document;
|
||||
use dom::element::{Element, AttributeHandlers};
|
||||
|
@ -68,9 +68,9 @@ pub trait LayoutHTMLCanvasElementHelpers {
|
|||
unsafe fn get_canvas_height(&self) -> u32;
|
||||
}
|
||||
|
||||
impl LayoutHTMLCanvasElementHelpers for JS<HTMLCanvasElement> {
|
||||
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
||||
unsafe fn get_renderer(&self) -> Option<Sender<CanvasMsg>> {
|
||||
let context = (*self.unsafe_get()).context.get_inner();
|
||||
let context = (*self.unsafe_get()).context.get_inner_as_layout();
|
||||
context.map(|cx| cx.get_renderer())
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use dom::bindings::cell::DOMRefCell;
|
|||
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
|
||||
use dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived};
|
||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
use dom::bindings::js::{JSRef, LayoutJS, Temporary};
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::element::Element;
|
||||
use dom::element::AttributeHandlers;
|
||||
|
@ -88,7 +88,7 @@ pub trait LayoutHTMLImageElementHelpers {
|
|||
unsafe fn image(&self) -> Option<Url>;
|
||||
}
|
||||
|
||||
impl LayoutHTMLImageElementHelpers for JS<HTMLImageElement> {
|
||||
impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> {
|
||||
unsafe fn image(&self) -> Option<Url> {
|
||||
(*self.unsafe_get()).image.borrow_for_layout().clone()
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLInp
|
|||
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{Comparable, JS, JSRef, Root, Temporary, OptionalRootable};
|
||||
use dom::bindings::js::{Comparable, JSRef, LayoutJS, Root, Temporary, OptionalRootable};
|
||||
use dom::bindings::js::{ResultRootable, RootedReference, MutNullableJS};
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::element::{AttributeHandlers, Element};
|
||||
|
@ -140,15 +140,15 @@ pub trait RawLayoutHTMLInputElementHelpers {
|
|||
unsafe fn get_size_for_layout(&self) -> u32;
|
||||
}
|
||||
|
||||
impl LayoutHTMLInputElementHelpers for JS<HTMLInputElement> {
|
||||
impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
|
||||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_value_for_layout(self) -> String {
|
||||
unsafe fn get_raw_textinput_value(input: JS<HTMLInputElement>) -> String {
|
||||
unsafe fn get_raw_textinput_value(input: LayoutJS<HTMLInputElement>) -> String {
|
||||
(*input.unsafe_get()).textinput.borrow_for_layout().get_content()
|
||||
}
|
||||
|
||||
unsafe fn get_raw_attr_value(input: JS<HTMLInputElement>) -> Option<String> {
|
||||
let elem: JS<Element> = input.transmute_copy();
|
||||
unsafe fn get_raw_attr_value(input: LayoutJS<HTMLInputElement>) -> Option<String> {
|
||||
let elem: LayoutJS<Element> = input.transmute_copy();
|
||||
(*elem.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("value"))
|
||||
.map(|s| s.to_owned())
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
|||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived};
|
||||
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
|
||||
use dom::bindings::js::{JSRef, LayoutJS, Temporary, OptionalRootable};
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::element::{Element, AttributeHandlers};
|
||||
use dom::event::Event;
|
||||
|
@ -58,7 +58,7 @@ pub trait RawLayoutHTMLTextAreaElementHelpers {
|
|||
unsafe fn get_rows_for_layout(&self) -> u32;
|
||||
}
|
||||
|
||||
impl LayoutHTMLTextAreaElementHelpers for JS<HTMLTextAreaElement> {
|
||||
impl LayoutHTMLTextAreaElementHelpers for LayoutJS<HTMLTextAreaElement> {
|
||||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_value_for_layout(self) -> String {
|
||||
(*self.unsafe_get()).textinput.borrow_for_layout().get_content()
|
||||
|
|
|
@ -23,7 +23,7 @@ use dom::bindings::conversions;
|
|||
use dom::bindings::error::Fallible;
|
||||
use dom::bindings::error::Error::{NotFound, HierarchyRequest, Syntax};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JS, JSRef, RootedReference, Temporary, Root};
|
||||
use dom::bindings::js::{JS, JSRef, LayoutJS, RootedReference, Temporary, Root};
|
||||
use dom::bindings::js::{TemporaryPushable, OptionalRootedRootable};
|
||||
use dom::bindings::js::{ResultRootable, OptionalRootable, MutNullableJS};
|
||||
use dom::bindings::trace::JSTraceable;
|
||||
|
@ -914,20 +914,20 @@ pub fn from_untrusted_node_address(runtime: *mut JSRuntime, candidate: Untrusted
|
|||
pub trait LayoutNodeHelpers {
|
||||
unsafe fn type_id_for_layout(&self) -> NodeTypeId;
|
||||
|
||||
unsafe fn parent_node_ref(&self) -> Option<JS<Node>>;
|
||||
unsafe fn first_child_ref(&self) -> Option<JS<Node>>;
|
||||
unsafe fn last_child_ref(&self) -> Option<JS<Node>>;
|
||||
unsafe fn prev_sibling_ref(&self) -> Option<JS<Node>>;
|
||||
unsafe fn next_sibling_ref(&self) -> Option<JS<Node>>;
|
||||
unsafe fn parent_node_ref(&self) -> Option<LayoutJS<Node>>;
|
||||
unsafe fn first_child_ref(&self) -> Option<LayoutJS<Node>>;
|
||||
unsafe fn last_child_ref(&self) -> Option<LayoutJS<Node>>;
|
||||
unsafe fn prev_sibling_ref(&self) -> Option<LayoutJS<Node>>;
|
||||
unsafe fn next_sibling_ref(&self) -> Option<LayoutJS<Node>>;
|
||||
|
||||
unsafe fn owner_doc_for_layout(&self) -> JS<Document>;
|
||||
unsafe fn owner_doc_for_layout(&self) -> LayoutJS<Document>;
|
||||
|
||||
unsafe fn is_element_for_layout(&self) -> bool;
|
||||
unsafe fn get_flag(self, flag: NodeFlags) -> bool;
|
||||
unsafe fn set_flag(self, flag: NodeFlags, value: bool);
|
||||
}
|
||||
|
||||
impl LayoutNodeHelpers for JS<Node> {
|
||||
impl LayoutNodeHelpers for LayoutJS<Node> {
|
||||
#[inline]
|
||||
unsafe fn type_id_for_layout(&self) -> NodeTypeId {
|
||||
(*self.unsafe_get()).type_id
|
||||
|
@ -939,33 +939,33 @@ impl LayoutNodeHelpers for JS<Node> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn parent_node_ref(&self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).parent_node.get_inner()
|
||||
unsafe fn parent_node_ref(&self) -> Option<LayoutJS<Node>> {
|
||||
(*self.unsafe_get()).parent_node.get_inner_as_layout()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn first_child_ref(&self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).first_child.get_inner()
|
||||
unsafe fn first_child_ref(&self) -> Option<LayoutJS<Node>> {
|
||||
(*self.unsafe_get()).first_child.get_inner_as_layout()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn last_child_ref(&self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).last_child.get_inner()
|
||||
unsafe fn last_child_ref(&self) -> Option<LayoutJS<Node>> {
|
||||
(*self.unsafe_get()).last_child.get_inner_as_layout()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn prev_sibling_ref(&self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).prev_sibling.get_inner()
|
||||
unsafe fn prev_sibling_ref(&self) -> Option<LayoutJS<Node>> {
|
||||
(*self.unsafe_get()).prev_sibling.get_inner_as_layout()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn next_sibling_ref(&self) -> Option<JS<Node>> {
|
||||
(*self.unsafe_get()).next_sibling.get_inner()
|
||||
unsafe fn next_sibling_ref(&self) -> Option<LayoutJS<Node>> {
|
||||
(*self.unsafe_get()).next_sibling.get_inner_as_layout()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn owner_doc_for_layout(&self) -> JS<Document> {
|
||||
(*self.unsafe_get()).owner_doc.get_inner().unwrap()
|
||||
unsafe fn owner_doc_for_layout(&self) -> LayoutJS<Document> {
|
||||
(*self.unsafe_get()).owner_doc.get_inner_as_layout().unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue