mirror of
https://github.com/servo/servo.git
synced 2025-08-02 04:00:32 +01:00
Add a to_js method to the casting trait code in CodegenRust.py
Replace the manual checks and calls to transmute_copy in /layout/wrapper.rs with calls to to_js Fixes #3616
This commit is contained in:
parent
3eb6b17137
commit
6d91e92c90
2 changed files with 69 additions and 61 deletions
|
@ -21,10 +21,7 @@
|
||||||
//!
|
//!
|
||||||
//! Rules of the road for this file:
|
//! Rules of the road for this file:
|
||||||
//!
|
//!
|
||||||
//! * In general, you must not use the `Cast` functions; use explicit checks and `transmute_copy`
|
//! * You must not use `.get()`; instead, use `.unsafe_get()`.
|
||||||
//! instead.
|
|
||||||
//!
|
|
||||||
//! * You must also not use `.get()`; instead, use `.unsafe_get()`.
|
|
||||||
//!
|
//!
|
||||||
//! * Do not call any methods on DOM nodes without checking to see whether they use borrow flags.
|
//! * Do not call any methods on DOM nodes without checking to see whether they use borrow flags.
|
||||||
//!
|
//!
|
||||||
|
@ -38,17 +35,16 @@ use css::node_style::StyledNode;
|
||||||
use util::{LayoutDataAccess, LayoutDataWrapper, PrivateLayoutData, OpaqueNodeMethods};
|
use util::{LayoutDataAccess, LayoutDataWrapper, PrivateLayoutData, OpaqueNodeMethods};
|
||||||
|
|
||||||
use gfx::display_list::OpaqueNode;
|
use gfx::display_list::OpaqueNode;
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementDerived};
|
use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast, HTMLImageElementCast};
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementDerived};
|
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, TextCast};
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, TextDerived};
|
|
||||||
use script::dom::bindings::js::JS;
|
use script::dom::bindings::js::JS;
|
||||||
use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId};
|
use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId};
|
||||||
use script::dom::element::{HTMLLinkElementTypeId, LayoutElementHelpers, RawLayoutElementHelpers};
|
use script::dom::element::{HTMLLinkElementTypeId, LayoutElementHelpers, RawLayoutElementHelpers};
|
||||||
use script::dom::htmliframeelement::HTMLIFrameElement;
|
use script::dom::htmliframeelement::HTMLIFrameElement;
|
||||||
use script::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
|
use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers;
|
||||||
use script::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
use script::dom::htmlinputelement::LayoutHTMLInputElementHelpers;
|
||||||
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId};
|
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId};
|
||||||
use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers, SharedLayoutData, TextNodeTypeId};
|
use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers, SharedLayoutData};
|
||||||
use script::dom::node::{HasChanged, IsDirty, HasDirtySiblings, HasDirtyDescendants};
|
use script::dom::node::{HasChanged, IsDirty, HasDirtySiblings, HasDirtyDescendants};
|
||||||
use script::dom::text::Text;
|
use script::dom::text::Text;
|
||||||
use script::layout_interface::LayoutChan;
|
use script::layout_interface::LayoutChan;
|
||||||
|
@ -101,11 +97,10 @@ pub trait TLayoutNode {
|
||||||
/// FIXME(pcwalton): Don't copy URLs.
|
/// FIXME(pcwalton): Don't copy URLs.
|
||||||
fn image_url(&self) -> Option<Url> {
|
fn image_url(&self) -> Option<Url> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !self.get().is_htmlimageelement() {
|
match HTMLImageElementCast::to_js(self.get_jsmanaged()) {
|
||||||
fail!("not an image!")
|
Some(elem) => elem.image().as_ref().map(|url| (*url).clone()),
|
||||||
|
None => fail!("not an image!")
|
||||||
}
|
}
|
||||||
let image_element: JS<HTMLImageElement> = self.get_jsmanaged().transmute_copy();
|
|
||||||
image_element.image().as_ref().map(|url| (*url).clone())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,10 +108,11 @@ pub trait TLayoutNode {
|
||||||
/// not an iframe element, fails.
|
/// not an iframe element, fails.
|
||||||
fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) {
|
fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !self.get().is_htmliframeelement() {
|
let iframe_element: JS<HTMLIFrameElement> =
|
||||||
fail!("not an iframe element!")
|
match HTMLIFrameElementCast::to_js(self.get_jsmanaged()) {
|
||||||
}
|
Some(elem) => elem,
|
||||||
let iframe_element: JS<HTMLIFrameElement> = self.get_jsmanaged().transmute_copy();
|
None => fail!("not an iframe element!")
|
||||||
|
};
|
||||||
let size = (*iframe_element.unsafe_get()).size().unwrap();
|
let size = (*iframe_element.unsafe_get()).size().unwrap();
|
||||||
(*size.pipeline_id(), *size.subpage_id())
|
(*size.pipeline_id(), *size.subpage_id())
|
||||||
}
|
}
|
||||||
|
@ -188,14 +184,13 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
|
||||||
|
|
||||||
fn text(&self) -> String {
|
fn text(&self) -> String {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.get().is_text() {
|
let text_opt: Option<JS<Text>> = TextCast::to_js(self.get_jsmanaged());
|
||||||
let text: JS<Text> = self.get_jsmanaged().transmute_copy();
|
match text_opt {
|
||||||
(*text.unsafe_get()).characterdata().data_for_layout().to_string()
|
Some(text) => (*text.unsafe_get()).characterdata().data_for_layout().to_string(),
|
||||||
} else if self.get().is_htmlinputelement() {
|
None => match HTMLInputElementCast::to_js(self.get_jsmanaged()) {
|
||||||
let input: JS<HTMLInputElement> = self.get_jsmanaged().transmute_copy();
|
Some(input) => input.get_value_for_layout(),
|
||||||
input.get_value_for_layout()
|
None => fail!("not text!")
|
||||||
} else {
|
}
|
||||||
fail!("not text!")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,9 +298,13 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_element(self) -> LayoutElement<'ln> {
|
fn as_element(self) -> LayoutElement<'ln> {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(self.node.is_element_for_layout());
|
let elem: JS<Element> = match ElementCast::to_js(&self.node) {
|
||||||
let elem: JS<Element> = self.node.transmute_copy();
|
Some(elem) => elem,
|
||||||
|
None => fail!("not an element")
|
||||||
|
};
|
||||||
|
|
||||||
let element = &*elem.unsafe_get();
|
let element = &*elem.unsafe_get();
|
||||||
|
|
||||||
LayoutElement {
|
LayoutElement {
|
||||||
element: mem::transmute(element),
|
element: mem::transmute(element),
|
||||||
}
|
}
|
||||||
|
@ -341,9 +340,9 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> {
|
||||||
|
|
||||||
fn is_html_element_in_html_document(self) -> bool {
|
fn is_html_element_in_html_document(self) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.is_element() && {
|
match ElementCast::to_js(&self.node) {
|
||||||
let element: JS<Element> = self.node.transmute_copy();
|
Some(elem) => elem.html_element_in_html_document_for_layout(),
|
||||||
element.html_element_in_html_document_for_layout()
|
None => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -714,9 +713,10 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_element(&self) -> ThreadSafeLayoutElement<'ln> {
|
pub fn as_element(&self) -> ThreadSafeLayoutElement<'ln> {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(self.get_jsmanaged().is_element_for_layout());
|
let element = match ElementCast::to_js(self.get_jsmanaged()) {
|
||||||
let elem: JS<Element> = self.get_jsmanaged().transmute_copy();
|
Some(e) => e.unsafe_get(),
|
||||||
let element = elem.unsafe_get();
|
None => fail!("not an element")
|
||||||
|
};
|
||||||
// FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on
|
// FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on
|
||||||
// implementations.
|
// implementations.
|
||||||
ThreadSafeLayoutElement {
|
ThreadSafeLayoutElement {
|
||||||
|
@ -806,47 +806,44 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_ignorable_whitespace(&self) -> bool {
|
pub fn is_ignorable_whitespace(&self) -> bool {
|
||||||
match self.type_id() {
|
unsafe {
|
||||||
Some(TextNodeTypeId) => {
|
let text: JS<Text> = match TextCast::to_js(self.get_jsmanaged()) {
|
||||||
unsafe {
|
Some(text) => text,
|
||||||
let text: JS<Text> = self.get_jsmanaged().transmute_copy();
|
None => return false
|
||||||
if !is_whitespace((*text.unsafe_get()).characterdata().data_for_layout()) {
|
};
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// NB: See the rules for `white-space` here:
|
if !is_whitespace((*text.unsafe_get()).characterdata().data_for_layout()) {
|
||||||
//
|
return false
|
||||||
// http://www.w3.org/TR/CSS21/text.html#propdef-white-space
|
}
|
||||||
//
|
|
||||||
// If you implement other values for this property, you will almost certainly
|
// NB: See the rules for `white-space` here:
|
||||||
// want to update this check.
|
//
|
||||||
match self.style().get_inheritedtext().white_space {
|
// http://www.w3.org/TR/CSS21/text.html#propdef-white-space
|
||||||
white_space::normal => true,
|
//
|
||||||
_ => false,
|
// If you implement other values for this property, you will almost certainly
|
||||||
}
|
// want to update this check.
|
||||||
}
|
match self.style().get_inheritedtext().white_space {
|
||||||
|
white_space::normal => true,
|
||||||
|
_ => false,
|
||||||
}
|
}
|
||||||
_ => false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_input_value(&self) -> String {
|
pub fn get_input_value(&self) -> String {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !self.get().is_htmlinputelement() {
|
match HTMLInputElementCast::to_js(self.get_jsmanaged()) {
|
||||||
fail!("not an input element!")
|
Some(input) => input.get_value_for_layout(),
|
||||||
|
None => fail!("not an input element!")
|
||||||
}
|
}
|
||||||
let input: JS<HTMLInputElement> = self.get_jsmanaged().transmute_copy();
|
|
||||||
input.get_value_for_layout()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_input_size(&self) -> u32 {
|
pub fn get_input_size(&self) -> u32 {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !self.get().is_htmlinputelement() {
|
match HTMLInputElementCast::to_js(self.get_jsmanaged()) {
|
||||||
fail!("not an input element!")
|
Some(input) => input.get_size_for_layout(),
|
||||||
|
None => fail!("not an input element!")
|
||||||
}
|
}
|
||||||
let input: JS<HTMLInputElement> = self.get_jsmanaged().transmute_copy();
|
|
||||||
input.get_size_for_layout()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5480,6 +5480,17 @@ class GlobalGenRoots():
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
#[allow(unrooted_must_root)]
|
||||||
|
fn to_js<T: ${toBound}+Reflectable>(base: &JS<T>) -> Option<JS<Self>> {
|
||||||
|
unsafe {
|
||||||
|
match (*base.unsafe_get()).${checkFn}() {
|
||||||
|
true => Some(base.transmute_copy()),
|
||||||
|
false => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: JSRef<'a, T>) -> JSRef<'a, Self> {
|
fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: JSRef<'a, T>) -> JSRef<'a, Self> {
|
||||||
unsafe { derived.transmute() }
|
unsafe { derived.transmute() }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue