Auto merge of #26083 - servo:layout-2020-more-cleanups, r=jdm

More layout cleanups from the introduction of a lifetime in LayoutDom<T>

What can I say, the follow-up fixes just kept coming to my door one by one, I couldn't just tell them to go away.
This commit is contained in:
bors-servo 2020-04-01 12:05:16 -04:00 committed by GitHub
commit af1ebe79ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 602 additions and 696 deletions

View file

@ -48,7 +48,6 @@ use script::layout_exports::{Document, Element, Node, Text};
use script::layout_exports::{LayoutCharacterDataHelpers, LayoutDocumentHelpers};
use script::layout_exports::{
LayoutDom, LayoutElementHelpers, LayoutNodeHelpers, LayoutShadowRootHelpers,
RawLayoutElementHelpers,
};
use script_layout_interface::wrapper_traits::{
DangerousThreadSafeLayoutNode, GetLayoutData, LayoutNode,
@ -136,13 +135,13 @@ impl<'ln> ServoLayoutNode<'ln> {
}
fn script_type_id(&self) -> NodeTypeId {
unsafe { self.node.type_id_for_layout() }
self.node.type_id_for_layout()
}
}
impl<'ln> NodeInfo for ServoLayoutNode<'ln> {
fn is_element(&self) -> bool {
unsafe { self.node.is_element_for_layout() }
self.node.is_element_for_layout()
}
fn is_text_node(&self) -> bool {
@ -171,14 +170,14 @@ impl<'lr> TShadowRoot for ServoShadowRoot<'lr> {
}
fn host(&self) -> ServoLayoutElement<'lr> {
ServoLayoutElement::from_layout_js(unsafe { self.shadow_root.get_host_for_layout() })
ServoLayoutElement::from_layout_js(self.shadow_root.get_host_for_layout())
}
fn style_data<'a>(&self) -> Option<&'a CascadeData>
where
Self: 'a,
{
Some(unsafe { &self.shadow_root.get_style_data_for_layout().data })
Some(&self.shadow_root.get_style_data_for_layout())
}
}
@ -204,31 +203,29 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
type ConcreteShadowRoot = ServoShadowRoot<'ln>;
fn parent_node(&self) -> Option<Self> {
unsafe {
self.node
.composed_parent_node_ref()
.map(Self::from_layout_js)
}
self.node
.composed_parent_node_ref()
.map(Self::from_layout_js)
}
fn first_child(&self) -> Option<Self> {
unsafe { self.node.first_child_ref().map(Self::from_layout_js) }
self.node.first_child_ref().map(Self::from_layout_js)
}
fn last_child(&self) -> Option<Self> {
unsafe { self.node.last_child_ref().map(Self::from_layout_js) }
self.node.last_child_ref().map(Self::from_layout_js)
}
fn prev_sibling(&self) -> Option<Self> {
unsafe { self.node.prev_sibling_ref().map(Self::from_layout_js) }
self.node.prev_sibling_ref().map(Self::from_layout_js)
}
fn next_sibling(&self) -> Option<Self> {
unsafe { self.node.next_sibling_ref().map(Self::from_layout_js) }
self.node.next_sibling_ref().map(Self::from_layout_js)
}
fn owner_doc(&self) -> Self::ConcreteDocument {
ServoLayoutDocument::from_layout_js(unsafe { self.node.owner_doc_for_layout() })
ServoLayoutDocument::from_layout_js(self.node.owner_doc_for_layout())
}
fn traversal_parent(&self) -> Option<ServoLayoutElement<'ln>> {
@ -346,11 +343,11 @@ impl<'ld> TDocument for ServoLayoutDocument<'ld> {
}
fn quirks_mode(&self) -> QuirksMode {
unsafe { self.document.quirks_mode() }
self.document.quirks_mode()
}
fn is_html_document(&self) -> bool {
unsafe { self.document.is_html_document_for_layout() }
self.document.is_html_document_for_layout()
}
}
@ -371,7 +368,7 @@ impl<'ld> ServoLayoutDocument<'ld> {
}
pub fn style_shared_lock(&self) -> &StyleSharedRwLock {
unsafe { self.document.style_shared_lock() }
self.document.style_shared_lock()
}
pub fn shadow_roots(&self) -> Vec<ServoShadowRoot> {
@ -444,7 +441,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
}
fn is_html_element(&self) -> bool {
unsafe { self.element.is_html_element() }
self.element.is_html_element()
}
fn is_mathml_element(&self) -> bool {
@ -490,11 +487,9 @@ impl<'le> TElement for ServoLayoutElement<'le> {
where
F: FnMut(&Atom),
{
unsafe {
if let Some(ref classes) = self.element.get_classes_for_layout() {
for class in *classes {
callback(class)
}
if let Some(ref classes) = self.element.get_classes_for_layout() {
for class in *classes {
callback(class)
}
}
}
@ -644,29 +639,23 @@ impl<'le> TElement for ServoLayoutElement<'le> {
) where
V: Push<ApplicableDeclarationBlock>,
{
unsafe {
self.element
.synthesize_presentational_hints_for_legacy_attributes(hints);
}
self.element
.synthesize_presentational_hints_for_legacy_attributes(hints);
}
/// The shadow root this element is a host of.
fn shadow_root(&self) -> Option<ServoShadowRoot<'le>> {
unsafe {
self.element
.get_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
self.element
.get_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
/// The shadow root which roots the subtree this element is contained in.
fn containing_shadow(&self) -> Option<ServoShadowRoot<'le>> {
unsafe {
self.element
.upcast()
.containing_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
self.element
.upcast()
.containing_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
fn local_name(&self) -> &LocalName {
@ -699,12 +688,12 @@ impl<'le> ServoLayoutElement<'le> {
#[inline]
fn get_attr_enum(&self, namespace: &Namespace, name: &LocalName) -> Option<&AttrValue> {
unsafe { (*self.element.unsafe_get()).get_attr_for_layout(namespace, name) }
self.element.get_attr_for_layout(namespace, name)
}
#[inline]
fn get_attr(&self, namespace: &Namespace, name: &LocalName) -> Option<&str> {
unsafe { (*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name) }
self.element.get_attr_val_for_layout(namespace, name)
}
fn get_style_data(&self) -> Option<&StyleData> {
@ -752,12 +741,10 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
}
fn parent_element(&self) -> Option<ServoLayoutElement<'le>> {
unsafe {
self.element
.upcast()
.composed_parent_node_ref()
.and_then(as_element)
}
self.element
.upcast()
.composed_parent_node_ref()
.and_then(as_element)
}
fn parent_node_is_shadow_root(&self) -> bool {
@ -806,11 +793,11 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
NamespaceConstraint::Specific(ref ns) => self
.get_attr_enum(ns, local_name)
.map_or(false, |value| value.eval_selector(operation)),
NamespaceConstraint::Any => {
let values =
unsafe { (*self.element.unsafe_get()).get_attr_vals_for_layout(local_name) };
values.iter().any(|value| value.eval_selector(operation))
},
NamespaceConstraint::Any => self
.element
.get_attr_vals_for_layout(local_name)
.iter()
.any(|value| value.eval_selector(operation)),
}
}
@ -880,8 +867,9 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
NonTSPseudoClass::Lang(ref lang) => self.match_element_lang(None, &*lang),
NonTSPseudoClass::ServoNonZeroBorder => unsafe {
match (*self.element.unsafe_get())
NonTSPseudoClass::ServoNonZeroBorder => {
match self
.element
.get_attr_for_layout(&ns!(), &local_name!("border"))
{
None | Some(&AttrValue::UInt(_, 0)) => false,
@ -913,22 +901,18 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
#[inline]
fn is_link(&self) -> bool {
unsafe {
match self.as_node().script_type_id() {
// https://html.spec.whatwg.org/multipage/#selector-link
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLAnchorElement,
)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLAreaElement,
)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLLinkElement,
)) => (*self.element.unsafe_get())
match self.as_node().script_type_id() {
// https://html.spec.whatwg.org/multipage/#selector-link
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLAnchorElement,
)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
self.element
.get_attr_val_for_layout(&ns!(), &local_name!("href"))
.is_some(),
_ => false,
}
.is_some()
},
_ => false,
}
}
@ -956,18 +940,16 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
#[inline]
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
unsafe { self.element.has_class_for_layout(name, case_sensitivity) }
self.element.has_class_for_layout(name, case_sensitivity)
}
fn is_html_slot_element(&self) -> bool {
unsafe { self.element.is_html_element() && self.local_name() == &local_name!("slot") }
self.element.is_html_element() && self.local_name() == &local_name!("slot")
}
fn is_html_element_in_html_document(&self) -> bool {
unsafe {
if !self.element.is_html_element() {
return false;
}
if !self.element.is_html_element() {
return false;
}
self.as_node().owner_doc().is_html_document()
@ -1439,12 +1421,12 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
NamespaceConstraint::Specific(ref ns) => self
.get_attr_enum(ns, local_name)
.map_or(false, |value| value.eval_selector(operation)),
NamespaceConstraint::Any => {
let values = unsafe {
(*self.element.element.unsafe_get()).get_attr_vals_for_layout(local_name)
};
values.iter().any(|v| v.eval_selector(operation))
},
NamespaceConstraint::Any => self
.element
.element
.get_attr_vals_for_layout(local_name)
.iter()
.any(|v| v.eval_selector(operation)),
}
}

View file

@ -48,7 +48,6 @@ use script::layout_exports::{Document, Element, Node, Text};
use script::layout_exports::{LayoutCharacterDataHelpers, LayoutDocumentHelpers};
use script::layout_exports::{
LayoutDom, LayoutElementHelpers, LayoutNodeHelpers, LayoutShadowRootHelpers,
RawLayoutElementHelpers,
};
use script_layout_interface::wrapper_traits::{
DangerousThreadSafeLayoutNode, GetLayoutData, LayoutNode,
@ -143,13 +142,13 @@ impl<'ln> ServoLayoutNode<'ln> {
}
fn script_type_id(&self) -> NodeTypeId {
unsafe { self.node.type_id_for_layout() }
self.node.type_id_for_layout()
}
}
impl<'ln> NodeInfo for ServoLayoutNode<'ln> {
fn is_element(&self) -> bool {
unsafe { self.node.is_element_for_layout() }
self.node.is_element_for_layout()
}
fn is_text_node(&self) -> bool {
@ -178,14 +177,14 @@ impl<'lr> TShadowRoot for ServoShadowRoot<'lr> {
}
fn host(&self) -> ServoLayoutElement<'lr> {
ServoLayoutElement::from_layout_js(unsafe { self.shadow_root.get_host_for_layout() })
ServoLayoutElement::from_layout_js(self.shadow_root.get_host_for_layout())
}
fn style_data<'a>(&self) -> Option<&'a CascadeData>
where
Self: 'a,
{
Some(unsafe { &self.shadow_root.get_style_data_for_layout().data })
Some(&self.shadow_root.get_style_data_for_layout())
}
}
@ -211,31 +210,29 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
type ConcreteShadowRoot = ServoShadowRoot<'ln>;
fn parent_node(&self) -> Option<Self> {
unsafe {
self.node
.composed_parent_node_ref()
.map(Self::from_layout_js)
}
self.node
.composed_parent_node_ref()
.map(Self::from_layout_js)
}
fn first_child(&self) -> Option<Self> {
unsafe { self.node.first_child_ref().map(Self::from_layout_js) }
self.node.first_child_ref().map(Self::from_layout_js)
}
fn last_child(&self) -> Option<Self> {
unsafe { self.node.last_child_ref().map(Self::from_layout_js) }
self.node.last_child_ref().map(Self::from_layout_js)
}
fn prev_sibling(&self) -> Option<Self> {
unsafe { self.node.prev_sibling_ref().map(Self::from_layout_js) }
self.node.prev_sibling_ref().map(Self::from_layout_js)
}
fn next_sibling(&self) -> Option<Self> {
unsafe { self.node.next_sibling_ref().map(Self::from_layout_js) }
self.node.next_sibling_ref().map(Self::from_layout_js)
}
fn owner_doc(&self) -> Self::ConcreteDocument {
ServoLayoutDocument::from_layout_js(unsafe { self.node.owner_doc_for_layout() })
ServoLayoutDocument::from_layout_js(self.node.owner_doc_for_layout())
}
fn traversal_parent(&self) -> Option<ServoLayoutElement<'ln>> {
@ -353,11 +350,11 @@ impl<'ld> TDocument for ServoLayoutDocument<'ld> {
}
fn quirks_mode(&self) -> QuirksMode {
unsafe { self.document.quirks_mode() }
self.document.quirks_mode()
}
fn is_html_document(&self) -> bool {
unsafe { self.document.is_html_document_for_layout() }
self.document.is_html_document_for_layout()
}
}
@ -378,7 +375,7 @@ impl<'ld> ServoLayoutDocument<'ld> {
}
pub fn style_shared_lock(&self) -> &StyleSharedRwLock {
unsafe { self.document.style_shared_lock() }
self.document.style_shared_lock()
}
pub fn shadow_roots(&self) -> Vec<ServoShadowRoot> {
@ -451,7 +448,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
}
fn is_html_element(&self) -> bool {
unsafe { self.element.is_html_element() }
self.element.is_html_element()
}
fn is_mathml_element(&self) -> bool {
@ -497,11 +494,9 @@ impl<'le> TElement for ServoLayoutElement<'le> {
where
F: FnMut(&Atom),
{
unsafe {
if let Some(ref classes) = self.element.get_classes_for_layout() {
for class in *classes {
callback(class)
}
if let Some(ref classes) = self.element.get_classes_for_layout() {
for class in *classes {
callback(class)
}
}
}
@ -651,29 +646,23 @@ impl<'le> TElement for ServoLayoutElement<'le> {
) where
V: Push<ApplicableDeclarationBlock>,
{
unsafe {
self.element
.synthesize_presentational_hints_for_legacy_attributes(hints);
}
self.element
.synthesize_presentational_hints_for_legacy_attributes(hints);
}
/// The shadow root this element is a host of.
fn shadow_root(&self) -> Option<ServoShadowRoot<'le>> {
unsafe {
self.element
.get_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
self.element
.get_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
/// The shadow root which roots the subtree this element is contained in.
fn containing_shadow(&self) -> Option<ServoShadowRoot<'le>> {
unsafe {
self.element
.upcast()
.containing_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
self.element
.upcast()
.containing_shadow_root_for_layout()
.map(ServoShadowRoot::from_layout_js)
}
fn local_name(&self) -> &LocalName {
@ -706,12 +695,12 @@ impl<'le> ServoLayoutElement<'le> {
#[inline]
fn get_attr_enum(&self, namespace: &Namespace, name: &LocalName) -> Option<&AttrValue> {
unsafe { (*self.element.unsafe_get()).get_attr_for_layout(namespace, name) }
self.element.get_attr_for_layout(namespace, name)
}
#[inline]
fn get_attr(&self, namespace: &Namespace, name: &LocalName) -> Option<&str> {
unsafe { (*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name) }
self.element.get_attr_val_for_layout(namespace, name)
}
fn get_style_data(&self) -> Option<&StyleData> {
@ -759,12 +748,10 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
}
fn parent_element(&self) -> Option<ServoLayoutElement<'le>> {
unsafe {
self.element
.upcast()
.composed_parent_node_ref()
.and_then(as_element)
}
self.element
.upcast()
.composed_parent_node_ref()
.and_then(as_element)
}
fn parent_node_is_shadow_root(&self) -> bool {
@ -813,11 +800,11 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
NamespaceConstraint::Specific(ref ns) => self
.get_attr_enum(ns, local_name)
.map_or(false, |value| value.eval_selector(operation)),
NamespaceConstraint::Any => {
let values =
unsafe { (*self.element.unsafe_get()).get_attr_vals_for_layout(local_name) };
values.iter().any(|value| value.eval_selector(operation))
},
NamespaceConstraint::Any => self
.element
.get_attr_vals_for_layout(local_name)
.iter()
.any(|value| value.eval_selector(operation)),
}
}
@ -887,8 +874,9 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
NonTSPseudoClass::Lang(ref lang) => self.match_element_lang(None, &*lang),
NonTSPseudoClass::ServoNonZeroBorder => unsafe {
match (*self.element.unsafe_get())
NonTSPseudoClass::ServoNonZeroBorder => {
match self
.element
.get_attr_for_layout(&ns!(), &local_name!("border"))
{
None | Some(&AttrValue::UInt(_, 0)) => false,
@ -920,22 +908,18 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
#[inline]
fn is_link(&self) -> bool {
unsafe {
match self.as_node().script_type_id() {
// https://html.spec.whatwg.org/multipage/#selector-link
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLAnchorElement,
)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLAreaElement,
)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLLinkElement,
)) => (*self.element.unsafe_get())
match self.as_node().script_type_id() {
// https://html.spec.whatwg.org/multipage/#selector-link
NodeTypeId::Element(ElementTypeId::HTMLElement(
HTMLElementTypeId::HTMLAnchorElement,
)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) |
NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLinkElement)) => {
self.element
.get_attr_val_for_layout(&ns!(), &local_name!("href"))
.is_some(),
_ => false,
}
.is_some()
},
_ => false,
}
}
@ -963,18 +947,16 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
#[inline]
fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
unsafe { self.element.has_class_for_layout(name, case_sensitivity) }
self.element.has_class_for_layout(name, case_sensitivity)
}
fn is_html_slot_element(&self) -> bool {
unsafe { self.element.is_html_element() && self.local_name() == &local_name!("slot") }
self.element.is_html_element() && self.local_name() == &local_name!("slot")
}
fn is_html_element_in_html_document(&self) -> bool {
unsafe {
if !self.element.is_html_element() {
return false;
}
if !self.element.is_html_element() {
return false;
}
self.as_node().owner_doc().is_html_document()
@ -1447,9 +1429,7 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
.get_attr_enum(ns, local_name)
.map_or(false, |value| value.eval_selector(operation)),
NamespaceConstraint::Any => {
let values = unsafe {
(*self.element.element.unsafe_get()).get_attr_vals_for_layout(local_name)
};
let values = self.element.element.get_attr_vals_for_layout(local_name);
values.iter().any(|v| v.eval_selector(operation))
},
}

View file

@ -441,6 +441,15 @@ where
debug_assert!(thread_state::get().is_layout());
self.value.downcast::<U>().map(|value| LayoutDom { value })
}
/// Returns whether this inner object is a U.
pub fn is<U>(&self) -> bool
where
U: DerivedFrom<T>,
{
debug_assert!(thread_state::get().is_layout());
self.value.is::<U>()
}
}
impl<T> LayoutDom<'_, T>
@ -736,6 +745,15 @@ where
debug_assert!(thread_state::get().is_layout());
self.value
}
/// Transforms a slice of Dom<T> into a slice of LayoutDom<T>.
// FIXME(nox): This should probably be done through a ToLayout trait.
pub unsafe fn to_layout_slice(slice: &'dom [Dom<T>]) -> &'dom [LayoutDom<'dom, T>] {
// This doesn't compile if Dom and LayoutDom don't have the same
// representation.
let _ = mem::transmute::<Dom<T>, LayoutDom<T>>;
&*(slice as *const [Dom<T>] as *const [LayoutDom<T>])
}
}
/// Helper trait for safer manipulations of `Option<Heap<T>>` values.

View file

@ -153,8 +153,7 @@ impl CanvasRenderingContext2D {
pub trait LayoutCanvasRenderingContext2DHelpers {
#[allow(unsafe_code)]
unsafe fn get_ipc_renderer(self) -> IpcSender<CanvasMsg>;
#[allow(unsafe_code)]
unsafe fn get_canvas_id(self) -> CanvasId;
fn get_canvas_id(self) -> CanvasId;
}
impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<'_, CanvasRenderingContext2D> {
@ -168,11 +167,16 @@ impl LayoutCanvasRenderingContext2DHelpers for LayoutDom<'_, CanvasRenderingCont
}
#[allow(unsafe_code)]
unsafe fn get_canvas_id(self) -> CanvasId {
(*self.unsafe_get())
.canvas_state
.borrow_for_layout()
.get_canvas_id()
fn get_canvas_id(self) -> CanvasId {
// FIXME(nox): This relies on the fact that CanvasState::get_canvas_id
// does nothing fancy but it would be easier to trust a
// LayoutDom<_>-like type that would wrap the &CanvasState.
unsafe {
self.unsafe_get()
.canvas_state
.borrow_for_layout()
.get_canvas_id()
}
}
}

View file

@ -2618,21 +2618,21 @@ pub enum DocumentSource {
#[allow(unsafe_code)]
pub trait LayoutDocumentHelpers<'dom> {
unsafe fn is_html_document_for_layout(self) -> bool;
fn is_html_document_for_layout(self) -> bool;
unsafe fn needs_paint_from_layout(self);
unsafe fn will_paint(self);
unsafe fn quirks_mode(self) -> QuirksMode;
unsafe fn style_shared_lock(self) -> &'dom StyleSharedRwLock;
unsafe fn shadow_roots(self) -> Vec<LayoutDom<'dom, ShadowRoot>>;
unsafe fn shadow_roots_styles_changed(self) -> bool;
fn quirks_mode(self) -> QuirksMode;
fn style_shared_lock(self) -> &'dom StyleSharedRwLock;
fn shadow_roots(self) -> Vec<LayoutDom<'dom, ShadowRoot>>;
fn shadow_roots_styles_changed(self) -> bool;
unsafe fn flush_shadow_roots_stylesheets(self);
}
#[allow(unsafe_code)]
impl<'dom> LayoutDocumentHelpers<'dom> for LayoutDom<'dom, Document> {
#[inline]
unsafe fn is_html_document_for_layout(self) -> bool {
(*self.unsafe_get()).is_html_document
fn is_html_document_for_layout(self) -> bool {
unsafe { self.unsafe_get().is_html_document }
}
#[inline]
@ -2646,28 +2646,34 @@ impl<'dom> LayoutDocumentHelpers<'dom> for LayoutDom<'dom, Document> {
}
#[inline]
unsafe fn quirks_mode(self) -> QuirksMode {
(*self.unsafe_get()).quirks_mode()
fn quirks_mode(self) -> QuirksMode {
unsafe { self.unsafe_get().quirks_mode.get() }
}
#[inline]
unsafe fn style_shared_lock(self) -> &'dom StyleSharedRwLock {
(*self.unsafe_get()).style_shared_lock()
fn style_shared_lock(self) -> &'dom StyleSharedRwLock {
unsafe { self.unsafe_get().style_shared_lock() }
}
#[inline]
unsafe fn shadow_roots(self) -> Vec<LayoutDom<'dom, ShadowRoot>> {
(*self.unsafe_get())
.shadow_roots
.borrow_for_layout()
.iter()
.map(|sr| sr.to_layout())
.collect()
fn shadow_roots(self) -> Vec<LayoutDom<'dom, ShadowRoot>> {
// FIXME(nox): We should just return a
// &'dom HashSet<LayoutDom<'dom, ShadowRoot>> here but not until
// I rework the ToLayout trait as mentioned in
// LayoutDom::to_layout_slice.
unsafe {
self.unsafe_get()
.shadow_roots
.borrow_for_layout()
.iter()
.map(|sr| sr.to_layout())
.collect()
}
}
#[inline]
unsafe fn shadow_roots_styles_changed(self) -> bool {
(*self.unsafe_get()).shadow_roots_styles_changed()
fn shadow_roots_styles_changed(self) -> bool {
unsafe { self.unsafe_get().shadow_roots_styles_changed.get() }
}
#[inline]

View file

@ -551,92 +551,29 @@ impl Element {
}
}
#[allow(unsafe_code)]
pub trait RawLayoutElementHelpers {
unsafe fn get_attr_for_layout<'a>(
&'a self,
namespace: &Namespace,
name: &LocalName,
) -> Option<&'a AttrValue>;
unsafe fn get_attr_val_for_layout<'a>(
&'a self,
namespace: &Namespace,
name: &LocalName,
) -> Option<&'a str>;
unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &LocalName) -> Vec<&'a AttrValue>;
}
#[inline]
#[allow(unsafe_code)]
pub unsafe fn get_attr_for_layout<'dom>(
elem: &'dom Element,
pub fn get_attr_for_layout<'dom>(
elem: LayoutDom<'dom, Element>,
namespace: &Namespace,
name: &LocalName,
) -> Option<LayoutDom<'dom, Attr>> {
// cast to point to T in RefCell<T> directly
let attrs = elem.attrs.borrow_for_layout();
attrs
elem.attrs()
.iter()
.find(|attr| {
let attr = attr.to_layout();
name == attr.local_name() && namespace == attr.namespace()
})
.map(|attr| attr.to_layout())
}
#[allow(unsafe_code)]
impl RawLayoutElementHelpers for Element {
#[inline]
unsafe fn get_attr_for_layout<'a>(
&'a self,
namespace: &Namespace,
name: &LocalName,
) -> Option<&'a AttrValue> {
get_attr_for_layout(self, namespace, name).map(|attr| attr.value())
}
#[inline]
unsafe fn get_attr_val_for_layout<'a>(
&'a self,
namespace: &Namespace,
name: &LocalName,
) -> Option<&'a str> {
get_attr_for_layout(self, namespace, name).map(|attr| attr.as_str())
}
#[inline]
unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &LocalName) -> Vec<&'a AttrValue> {
let attrs = self.attrs.borrow_for_layout();
attrs
.iter()
.filter_map(|attr| {
let attr = attr.to_layout();
if name == attr.local_name() {
Some(attr.value())
} else {
None
}
})
.collect()
}
.find(|attr| name == attr.local_name() && namespace == attr.namespace())
.cloned()
}
pub trait LayoutElementHelpers<'dom> {
#[allow(unsafe_code)]
unsafe fn has_class_for_layout(self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool;
#[allow(unsafe_code)]
unsafe fn get_classes_for_layout(self) -> Option<&'dom [Atom]>;
fn attrs(self) -> &'dom [LayoutDom<'dom, Attr>];
fn has_class_for_layout(self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool;
fn get_classes_for_layout(self) -> Option<&'dom [Atom]>;
#[allow(unsafe_code)]
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(self, _: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(self, hints: &mut V)
where
V: Push<ApplicableDeclarationBlock>;
#[allow(unsafe_code)]
unsafe fn get_colspan(self) -> u32;
#[allow(unsafe_code)]
unsafe fn get_rowspan(self) -> u32;
#[allow(unsafe_code)]
unsafe fn is_html_element(self) -> bool;
fn get_colspan(self) -> u32;
fn get_rowspan(self) -> u32;
fn is_html_element(self) -> bool;
fn id_attribute(self) -> *const Option<Atom>;
fn style_attribute(self) -> *const Option<Arc<Locked<PropertyDeclarationBlock>>>;
fn local_name(self) -> &'dom LocalName;
@ -646,34 +583,52 @@ pub trait LayoutElementHelpers<'dom> {
fn insert_selector_flags(self, flags: ElementSelectorFlags);
fn has_selector_flags(self, flags: ElementSelectorFlags) -> bool;
/// The shadow root this element is a host of.
fn get_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>>;
fn get_attr_for_layout(
self,
namespace: &Namespace,
name: &LocalName,
) -> Option<&'dom AttrValue>;
fn get_attr_val_for_layout(self, namespace: &Namespace, name: &LocalName) -> Option<&'dom str>;
fn get_attr_vals_for_layout(self, name: &LocalName) -> Vec<&'dom AttrValue>;
}
impl<'dom> LayoutDom<'dom, Element> {
#[allow(unsafe_code)]
unsafe fn get_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>>;
pub(super) fn focus_state(self) -> bool {
unsafe {
self.unsafe_get()
.state
.get()
.contains(ElementState::IN_FOCUS_STATE)
}
}
}
impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
#[allow(unsafe_code)]
#[inline]
unsafe fn has_class_for_layout(self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
get_attr_for_layout(&*self.unsafe_get(), &ns!(), &local_name!("class")).map_or(
false,
|attr| {
attr.as_tokens()
.unwrap()
.iter()
.any(|atom| case_sensitivity.eq_atom(atom, name))
},
)
fn attrs(self) -> &'dom [LayoutDom<'dom, Attr>] {
unsafe { LayoutDom::to_layout_slice(self.unsafe_get().attrs.borrow_for_layout()) }
}
#[allow(unsafe_code)]
#[inline]
unsafe fn get_classes_for_layout(self) -> Option<&'dom [Atom]> {
get_attr_for_layout(&*self.unsafe_get(), &ns!(), &local_name!("class"))
fn has_class_for_layout(self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool {
get_attr_for_layout(self, &ns!(), &local_name!("class")).map_or(false, |attr| {
attr.as_tokens()
.unwrap()
.iter()
.any(|atom| case_sensitivity.eq_atom(atom, name))
})
}
#[inline]
fn get_classes_for_layout(self) -> Option<&'dom [Atom]> {
get_attr_for_layout(self, &ns!(), &local_name!("class"))
.map(|attr| attr.as_tokens().unwrap())
}
#[allow(unsafe_code)]
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(self, hints: &mut V)
fn synthesize_presentational_hints_for_legacy_attributes<V>(self, hints: &mut V)
where
V: Push<ApplicableDeclarationBlock>,
{
@ -803,7 +758,7 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
let size = if let Some(this) = self.downcast::<HTMLInputElement>() {
// FIXME(pcwalton): More use of atoms, please!
match (*self.unsafe_get()).get_attr_val_for_layout(&ns!(), &local_name!("type")) {
match self.get_attr_val_for_layout(&ns!(), &local_name!("type")) {
// Not text entry widget
Some("hidden") |
Some("date") |
@ -996,8 +951,7 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
}
}
#[allow(unsafe_code)]
unsafe fn get_colspan(self) -> u32 {
fn get_colspan(self) -> u32 {
if let Some(this) = self.downcast::<HTMLTableCellElement>() {
this.get_colspan().unwrap_or(1)
} else {
@ -1007,8 +961,7 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
}
}
#[allow(unsafe_code)]
unsafe fn get_rowspan(self) -> u32 {
fn get_rowspan(self) -> u32 {
if let Some(this) = self.downcast::<HTMLTableCellElement>() {
this.get_rowspan().unwrap_or(1)
} else {
@ -1019,9 +972,8 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
}
#[inline]
#[allow(unsafe_code)]
unsafe fn is_html_element(self) -> bool {
(*self.unsafe_get()).namespace == ns!(html)
fn is_html_element(self) -> bool {
*self.namespace() == ns!(html)
}
#[allow(unsafe_code)]
@ -1044,32 +996,27 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
unsafe { &(*self.unsafe_get()).namespace }
}
#[allow(unsafe_code)]
fn get_lang_for_layout(self) -> String {
unsafe {
let mut current_node = Some(self.upcast::<Node>());
while let Some(node) = current_node {
current_node = node.composed_parent_node_ref();
match node.downcast::<Element>().map(|el| el.unsafe_get()) {
Some(elem) => {
if let Some(attr) =
(*elem).get_attr_val_for_layout(&ns!(xml), &local_name!("lang"))
{
return attr.to_owned();
}
if let Some(attr) =
(*elem).get_attr_val_for_layout(&ns!(), &local_name!("lang"))
{
return attr.to_owned();
}
},
None => continue,
}
let mut current_node = Some(self.upcast::<Node>());
while let Some(node) = current_node {
current_node = node.composed_parent_node_ref();
match node.downcast::<Element>() {
Some(elem) => {
if let Some(attr) =
elem.get_attr_val_for_layout(&ns!(xml), &local_name!("lang"))
{
return attr.to_owned();
}
if let Some(attr) = elem.get_attr_val_for_layout(&ns!(), &local_name!("lang")) {
return attr.to_owned();
}
},
None => continue,
}
// TODO: Check meta tags for a pragma-set default language
// TODO: Check HTTP Content-Language header
String::new()
}
// TODO: Check meta tags for a pragma-set default language
// TODO: Check HTTP Content-Language header
String::new()
}
#[inline]
@ -1096,13 +1043,44 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
#[inline]
#[allow(unsafe_code)]
unsafe fn get_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>> {
(*self.unsafe_get())
.rare_data_for_layout()
.as_ref()?
.shadow_root
.as_ref()
.map(|sr| sr.to_layout())
fn get_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>> {
unsafe {
self.unsafe_get()
.rare_data
.borrow_for_layout()
.as_ref()?
.shadow_root
.as_ref()
.map(|sr| sr.to_layout())
}
}
#[inline]
fn get_attr_for_layout(
self,
namespace: &Namespace,
name: &LocalName,
) -> Option<&'dom AttrValue> {
get_attr_for_layout(self, namespace, name).map(|attr| attr.value())
}
#[inline]
fn get_attr_val_for_layout(self, namespace: &Namespace, name: &LocalName) -> Option<&'dom str> {
get_attr_for_layout(self, namespace, name).map(|attr| attr.as_str())
}
#[inline]
fn get_attr_vals_for_layout(self, name: &LocalName) -> Vec<&'dom AttrValue> {
self.attrs()
.iter()
.filter_map(|attr| {
if name == attr.local_name() {
Some(attr.value())
} else {
None
}
})
.collect()
}
}

View file

@ -9,7 +9,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::eventtarget::EventTarget;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{document_from_node, window_from_node, BindContext, Node};
@ -100,34 +100,25 @@ pub trait HTMLBodyElementLayoutHelpers {
}
impl HTMLBodyElementLayoutHelpers for LayoutDom<'_, HTMLBodyElement> {
#[allow(unsafe_code)]
fn get_background_color(self) -> Option<RGBA> {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
#[allow(unsafe_code)]
fn get_color(self) -> Option<RGBA> {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("text"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("text"))
.and_then(AttrValue::as_color)
.cloned()
}
#[allow(unsafe_code)]
fn get_background(self) -> Option<ServoUrl> {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("background"))
.and_then(AttrValue::as_resolved_url)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("background"))
.and_then(AttrValue::as_resolved_url)
.cloned()
}
}

View file

@ -18,7 +18,7 @@ use crate::dom::canvasrenderingcontext2d::{
CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers,
};
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{window_from_node, Node};
@ -123,9 +123,8 @@ pub trait LayoutHTMLCanvasElementHelpers {
impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> {
#[allow(unsafe_code)]
fn data(self) -> HTMLCanvasData {
unsafe {
let canvas = &*self.unsafe_get();
let source = match canvas.context.borrow_for_layout().as_ref() {
let source = unsafe {
match self.unsafe_get().context.borrow_for_layout().as_ref() {
Some(&CanvasContext::Context2d(ref context)) => {
HTMLCanvasDataSource::Image(Some(context.to_layout().get_ipc_renderer()))
},
@ -136,41 +135,35 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> {
context.to_layout().canvas_data_source()
},
None => HTMLCanvasDataSource::Image(None),
};
let width_attr = canvas
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"));
let height_attr = canvas
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"));
HTMLCanvasData {
source: source,
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
canvas_id: self.get_canvas_id_for_layout(),
}
};
let width_attr = self
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"));
let height_attr = self
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"));
HTMLCanvasData {
source: source,
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
canvas_id: self.get_canvas_id_for_layout(),
}
}
#[allow(unsafe_code)]
fn get_width(self) -> LengthOrPercentageOrAuto {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_uint_px_dimension)
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_uint_px_dimension)
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
#[allow(unsafe_code)]
fn get_height(self) -> LengthOrPercentageOrAuto {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("height"))
.map(AttrValue::as_uint_px_dimension)
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"))
.map(AttrValue::as_uint_px_dimension)
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
#[allow(unsafe_code)]

View file

@ -8,7 +8,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{Element, RawLayoutElementHelpers};
use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods;
@ -107,32 +107,24 @@ pub trait HTMLFontElementLayoutHelpers {
}
impl HTMLFontElementLayoutHelpers for LayoutDom<'_, HTMLFontElement> {
#[allow(unsafe_code)]
fn get_color(self) -> Option<RGBA> {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("color"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("color"))
.and_then(AttrValue::as_color)
.cloned()
}
#[allow(unsafe_code)]
fn get_face(self) -> Option<Atom> {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("face"))
.map(AttrValue::as_atom)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("face"))
.map(AttrValue::as_atom)
.cloned()
}
#[allow(unsafe_code)]
fn get_size(self) -> Option<u32> {
let size = unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("size"))
};
let size = self
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("size"));
match size {
Some(&AttrValue::UInt(_, s)) => Some(s),
_ => None,

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{Element, RawLayoutElementHelpers};
use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::dom::virtualmethods::VirtualMethods;
@ -71,25 +71,19 @@ pub trait HTMLHRLayoutHelpers {
}
impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> {
#[allow(unsafe_code)]
fn get_color(self) -> Option<RGBA> {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("color"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("color"))
.and_then(AttrValue::as_color)
.cloned()
}
#[allow(unsafe_code)]
fn get_width(self) -> LengthOrPercentageOrAuto {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}

View file

@ -14,7 +14,7 @@ use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::document::Document;
use crate::dom::domtokenlist::DOMTokenList;
use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlelement::HTMLElement;
@ -499,26 +499,20 @@ impl HTMLIFrameElementLayoutMethods for LayoutDom<'_, HTMLIFrameElement> {
unsafe { (*self.unsafe_get()).browsing_context_id.get() }
}
#[allow(unsafe_code)]
fn get_width(self) -> LengthOrPercentageOrAuto {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
#[allow(unsafe_code)]
fn get_height(self) -> LengthOrPercentageOrAuto {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("height"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}

View file

@ -22,7 +22,7 @@ use crate::dom::document::Document;
use crate::dom::element::{cors_setting_for_element, referrer_policy_for_element};
use crate::dom::element::{reflect_cross_origin_attribute, set_cross_origin_attribute};
use crate::dom::element::{
AttributeMutation, CustomElementCreationMode, Element, ElementCreator, RawLayoutElementHelpers,
AttributeMutation, CustomElementCreationMode, Element, ElementCreator, LayoutElementHelpers,
};
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
@ -1366,75 +1366,56 @@ impl MicrotaskRunnable for ImageElementMicrotask {
}
pub trait LayoutHTMLImageElementHelpers {
#[allow(unsafe_code)]
unsafe fn image(self) -> Option<Arc<Image>>;
#[allow(unsafe_code)]
unsafe fn image_url(self) -> Option<ServoUrl>;
#[allow(unsafe_code)]
unsafe fn image_density(self) -> Option<f64>;
#[allow(unsafe_code)]
unsafe fn image_data(self) -> (Option<Arc<Image>>, Option<ImageMetadata>);
fn image(self) -> Option<Arc<Image>>;
fn image_url(self) -> Option<ServoUrl>;
fn image_density(self) -> Option<f64>;
fn image_data(self) -> (Option<Arc<Image>>, Option<ImageMetadata>);
fn get_width(self) -> LengthOrPercentageOrAuto;
fn get_height(self) -> LengthOrPercentageOrAuto;
}
impl<'dom> LayoutDom<'dom, HTMLImageElement> {
#[allow(unsafe_code)]
fn current_request(self) -> &'dom ImageRequest {
unsafe { self.unsafe_get().current_request.borrow_for_layout() }
}
}
impl LayoutHTMLImageElementHelpers for LayoutDom<'_, HTMLImageElement> {
#[allow(unsafe_code)]
unsafe fn image(self) -> Option<Arc<Image>> {
(*self.unsafe_get())
.current_request
.borrow_for_layout()
.image
.clone()
fn image(self) -> Option<Arc<Image>> {
self.current_request().image.clone()
}
#[allow(unsafe_code)]
unsafe fn image_url(self) -> Option<ServoUrl> {
(*self.unsafe_get())
.current_request
.borrow_for_layout()
.parsed_url
.clone()
fn image_url(self) -> Option<ServoUrl> {
self.current_request().parsed_url.clone()
}
#[allow(unsafe_code)]
unsafe fn image_data(self) -> (Option<Arc<Image>>, Option<ImageMetadata>) {
let current_request = (*self.unsafe_get()).current_request.borrow_for_layout();
fn image_data(self) -> (Option<Arc<Image>>, Option<ImageMetadata>) {
let current_request = self.current_request();
(
current_request.image.clone(),
current_request.metadata.clone(),
)
}
#[allow(unsafe_code)]
unsafe fn image_density(self) -> Option<f64> {
(*self.unsafe_get())
.current_request
.borrow_for_layout()
.current_pixel_density
.clone()
fn image_density(self) -> Option<f64> {
self.current_request().current_pixel_density.clone()
}
#[allow(unsafe_code)]
fn get_width(self) -> LengthOrPercentageOrAuto {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
#[allow(unsafe_code)]
fn get_height(self) -> LengthOrPercentageOrAuto {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("height"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}

View file

@ -18,9 +18,7 @@ use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::{DOMString, USVString};
use crate::dom::compositionevent::CompositionEvent;
use crate::dom::document::Document;
use crate::dom::element::{
AttributeMutation, Element, LayoutElementHelpers, RawLayoutElementHelpers,
};
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
use crate::dom::file::File;
@ -707,89 +705,98 @@ impl HTMLInputElement {
pub trait LayoutHTMLInputElementHelpers<'dom> {
fn value_for_layout(self) -> Cow<'dom, str>;
#[allow(unsafe_code)]
unsafe fn size_for_layout(self) -> u32;
#[allow(unsafe_code)]
unsafe fn selection_for_layout(self) -> Option<Range<usize>>;
#[allow(unsafe_code)]
unsafe fn checked_state_for_layout(self) -> bool;
#[allow(unsafe_code)]
unsafe fn indeterminate_state_for_layout(self) -> bool;
fn size_for_layout(self) -> u32;
fn selection_for_layout(self) -> Option<Range<usize>>;
fn checked_state_for_layout(self) -> bool;
fn indeterminate_state_for_layout(self) -> bool;
}
#[allow(unsafe_code)]
unsafe fn get_raw_textinput_value(input: LayoutDom<HTMLInputElement>) -> DOMString {
(*input.unsafe_get())
.textinput
.borrow_for_layout()
.get_content()
impl<'dom> LayoutDom<'dom, HTMLInputElement> {
fn get_raw_textinput_value(self) -> DOMString {
unsafe {
self.unsafe_get()
.textinput
.borrow_for_layout()
.get_content()
}
}
fn placeholder(self) -> &'dom str {
unsafe { self.unsafe_get().placeholder.borrow_for_layout() }
}
fn input_type(self) -> InputType {
unsafe { self.unsafe_get().input_type.get() }
}
fn textinput_sorted_selection_offsets_range(self) -> Range<UTF8Bytes> {
unsafe {
self.unsafe_get()
.textinput
.borrow_for_layout()
.sorted_selection_offsets_range()
}
}
}
impl<'dom> LayoutHTMLInputElementHelpers<'dom> for LayoutDom<'dom, HTMLInputElement> {
#[allow(unsafe_code)]
fn value_for_layout(self) -> Cow<'dom, str> {
fn get_raw_attr_value<'dom>(
input: LayoutDom<'dom, HTMLInputElement>,
default: &'static str,
) -> Cow<'dom, str> {
unsafe {
input
.upcast::<Element>()
.unsafe_get()
.get_attr_val_for_layout(&ns!(), &local_name!("value"))
.unwrap_or(default)
.into()
}
input
.upcast::<Element>()
.get_attr_val_for_layout(&ns!(), &local_name!("value"))
.unwrap_or(default)
.into()
}
let placeholder = unsafe { &**self.unsafe_get().placeholder.borrow_for_layout() };
match unsafe { self.unsafe_get().input_type() } {
match self.input_type() {
InputType::Checkbox | InputType::Radio => "".into(),
InputType::File | InputType::Image => "".into(),
InputType::Button => get_raw_attr_value(self, ""),
InputType::Submit => get_raw_attr_value(self, DEFAULT_SUBMIT_VALUE),
InputType::Reset => get_raw_attr_value(self, DEFAULT_RESET_VALUE),
InputType::Password => {
let text = unsafe { get_raw_textinput_value(self) };
let text = self.get_raw_textinput_value();
if !text.is_empty() {
text.chars()
.map(|_| PASSWORD_REPLACEMENT_CHAR)
.collect::<String>()
.into()
} else {
placeholder.into()
self.placeholder().into()
}
},
_ => {
let text = unsafe { get_raw_textinput_value(self) };
let text = self.get_raw_textinput_value();
if !text.is_empty() {
text.into()
} else {
placeholder.into()
self.placeholder().into()
}
},
}
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn size_for_layout(self) -> u32 {
(*self.unsafe_get()).size.get()
fn size_for_layout(self) -> u32 {
unsafe { self.unsafe_get().size.get() }
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn selection_for_layout(self) -> Option<Range<usize>> {
if !(*self.unsafe_get()).upcast::<Element>().focus_state() {
fn selection_for_layout(self) -> Option<Range<usize>> {
if !self.upcast::<Element>().focus_state() {
return None;
}
let textinput = (*self.unsafe_get()).textinput.borrow_for_layout();
let sorted_selection_offsets_range = self.textinput_sorted_selection_offsets_range();
match (*self.unsafe_get()).input_type() {
match self.input_type() {
InputType::Password => {
let text = get_raw_textinput_value(self);
let sel = UTF8Bytes::unwrap_range(textinput.sorted_selection_offsets_range());
let text = self.get_raw_textinput_value();
let sel = UTF8Bytes::unwrap_range(sorted_selection_offsets_range);
// Translate indices from the raw value to indices in the replacement value.
let char_start = text[..sel.start].chars().count();
@ -798,24 +805,20 @@ impl<'dom> LayoutHTMLInputElementHelpers<'dom> for LayoutDom<'dom, HTMLInputElem
let bytes_per_char = PASSWORD_REPLACEMENT_CHAR.len_utf8();
Some(char_start * bytes_per_char..char_end * bytes_per_char)
},
input_type if input_type.is_textual() => Some(UTF8Bytes::unwrap_range(
textinput.sorted_selection_offsets_range(),
)),
input_type if input_type.is_textual() => {
Some(UTF8Bytes::unwrap_range(sorted_selection_offsets_range))
},
_ => None,
}
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn checked_state_for_layout(self) -> bool {
fn checked_state_for_layout(self) -> bool {
self.upcast::<Element>()
.get_state_for_layout()
.contains(ElementState::IN_CHECKED_STATE)
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn indeterminate_state_for_layout(self) -> bool {
fn indeterminate_state_for_layout(self) -> bool {
self.upcast::<Element>()
.get_state_for_layout()
.contains(ElementState::IN_INDETERMINATE_STATE)

View file

@ -9,7 +9,7 @@ use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::root::LayoutDom;
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{Element, RawLayoutElementHelpers};
use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmltablerowelement::HTMLTableRowElement;
use crate::dom::node::Node;
@ -104,41 +104,32 @@ pub trait HTMLTableCellElementLayoutHelpers {
fn get_width(self) -> LengthOrPercentageOrAuto;
}
#[allow(unsafe_code)]
impl HTMLTableCellElementLayoutHelpers for LayoutDom<'_, HTMLTableCellElement> {
fn get_background_color(self) -> Option<RGBA> {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
fn get_colspan(self) -> Option<u32> {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("colspan"))
.map(AttrValue::as_uint)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("colspan"))
.map(AttrValue::as_uint)
}
fn get_rowspan(self) -> Option<u32> {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("rowspan"))
.map(AttrValue::as_uint)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("rowspan"))
.map(AttrValue::as_uint)
}
fn get_width(self) -> LengthOrPercentageOrAuto {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}

View file

@ -11,7 +11,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmltablecaptionelement::HTMLTableCaptionElement;
@ -413,14 +413,11 @@ pub trait HTMLTableElementLayoutHelpers {
}
impl HTMLTableElementLayoutHelpers for LayoutDom<'_, HTMLTableElement> {
#[allow(unsafe_code)]
fn get_background_color(self) -> Option<RGBA> {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
#[allow(unsafe_code)]
@ -433,15 +430,12 @@ impl HTMLTableElementLayoutHelpers for LayoutDom<'_, HTMLTableElement> {
unsafe { (*self.unsafe_get()).cellspacing.get() }
}
#[allow(unsafe_code)]
fn get_width(self) -> LengthOrPercentageOrAuto {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"))
.map(AttrValue::as_dimension)
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
}

View file

@ -11,7 +11,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{Element, RawLayoutElementHelpers};
use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmltablecellelement::HTMLTableCellElement;
@ -149,15 +149,12 @@ pub trait HTMLTableRowElementLayoutHelpers {
fn get_background_color(self) -> Option<RGBA>;
}
#[allow(unsafe_code)]
impl HTMLTableRowElementLayoutHelpers for LayoutDom<'_, HTMLTableRowElement> {
fn get_background_color(self) -> Option<RGBA> {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
}

View file

@ -9,7 +9,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{Element, RawLayoutElementHelpers};
use crate::dom::element::{Element, LayoutElementHelpers};
use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection};
use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmltablerowelement::HTMLTableRowElement;
@ -87,15 +87,12 @@ pub trait HTMLTableSectionElementLayoutHelpers {
fn get_background_color(self) -> Option<RGBA>;
}
#[allow(unsafe_code)]
impl HTMLTableSectionElementLayoutHelpers for LayoutDom<'_, HTMLTableSectionElement> {
fn get_background_color(self) -> Option<RGBA> {
unsafe {
(&*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("bgcolor"))
.and_then(AttrValue::as_color)
.cloned()
}
}

View file

@ -14,7 +14,7 @@ use crate::dom::bindings::root::{DomRoot, LayoutDom, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::compositionevent::CompositionEvent;
use crate::dom::document::Document;
use crate::dom::element::RawLayoutElementHelpers;
use crate::dom::element::LayoutElementHelpers;
use crate::dom::element::{AttributeMutation, Element};
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::globalscope::GlobalScope;
@ -57,61 +57,70 @@ pub struct HTMLTextAreaElement {
pub trait LayoutHTMLTextAreaElementHelpers {
fn value_for_layout(self) -> String;
#[allow(unsafe_code)]
unsafe fn selection_for_layout(self) -> Option<Range<usize>>;
#[allow(unsafe_code)]
fn selection_for_layout(self) -> Option<Range<usize>>;
fn get_cols(self) -> u32;
#[allow(unsafe_code)]
fn get_rows(self) -> u32;
}
impl LayoutHTMLTextAreaElementHelpers for LayoutDom<'_, HTMLTextAreaElement> {
#[allow(unsafe_code)]
fn value_for_layout(self) -> String {
let text = unsafe {
#[allow(unsafe_code)]
impl<'dom> LayoutDom<'dom, HTMLTextAreaElement> {
fn textinput_content(self) -> DOMString {
unsafe {
self.unsafe_get()
.textinput
.borrow_for_layout()
.get_content()
};
}
}
fn textinput_sorted_selection_offsets_range(self) -> Range<UTF8Bytes> {
unsafe {
self.unsafe_get()
.textinput
.borrow_for_layout()
.sorted_selection_offsets_range()
}
}
fn placeholder(self) -> &'dom str {
unsafe { self.unsafe_get().placeholder.borrow_for_layout() }
}
}
impl LayoutHTMLTextAreaElementHelpers for LayoutDom<'_, HTMLTextAreaElement> {
fn value_for_layout(self) -> String {
let text = self.textinput_content();
if text.is_empty() {
let placeholder = unsafe { self.unsafe_get().placeholder.borrow_for_layout() };
// FIXME(nox): Would be cool to not allocate a new string if the
// placeholder is single line, but that's an unimportant detail.
placeholder.replace("\r\n", "\n").replace("\r", "\n").into()
self.placeholder()
.replace("\r\n", "\n")
.replace("\r", "\n")
.into()
} else {
text.into()
}
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
unsafe fn selection_for_layout(self) -> Option<Range<usize>> {
if !(*self.unsafe_get()).upcast::<Element>().focus_state() {
fn selection_for_layout(self) -> Option<Range<usize>> {
if !self.upcast::<Element>().focus_state() {
return None;
}
let textinput = (*self.unsafe_get()).textinput.borrow_for_layout();
Some(UTF8Bytes::unwrap_range(
textinput.sorted_selection_offsets_range(),
self.textinput_sorted_selection_offsets_range(),
))
}
#[allow(unsafe_code)]
fn get_cols(self) -> u32 {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("cols"))
.map_or(DEFAULT_COLS, AttrValue::as_uint)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("cols"))
.map_or(DEFAULT_COLS, AttrValue::as_uint)
}
#[allow(unsafe_code)]
fn get_rows(self) -> u32 {
unsafe {
(*self.upcast::<Element>().unsafe_get())
.get_attr_for_layout(&ns!(), &local_name!("rows"))
.map_or(DEFAULT_ROWS, AttrValue::as_uint)
}
self.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("rows"))
.map_or(DEFAULT_ROWS, AttrValue::as_uint)
}
}

View file

@ -671,11 +671,6 @@ macro_rules! impl_rare_data (
rare_data.as_mut().unwrap()
})
}
#[allow(unsafe_code)]
fn rare_data_for_layout(&self) -> &Option<Box<$type>> {
unsafe { self.rare_data.borrow_for_layout() }
}
);
);

View file

@ -1305,22 +1305,22 @@ pub unsafe fn from_untrusted_node_address(
#[allow(unsafe_code)]
pub trait LayoutNodeHelpers<'dom> {
unsafe fn type_id_for_layout(self) -> NodeTypeId;
fn type_id_for_layout(self) -> NodeTypeId;
unsafe fn composed_parent_node_ref(self) -> Option<LayoutDom<'dom, Node>>;
unsafe fn first_child_ref(self) -> Option<LayoutDom<'dom, Node>>;
unsafe fn last_child_ref(self) -> Option<LayoutDom<'dom, Node>>;
unsafe fn prev_sibling_ref(self) -> Option<LayoutDom<'dom, Node>>;
unsafe fn next_sibling_ref(self) -> Option<LayoutDom<'dom, Node>>;
fn composed_parent_node_ref(self) -> Option<LayoutDom<'dom, Node>>;
fn first_child_ref(self) -> Option<LayoutDom<'dom, Node>>;
fn last_child_ref(self) -> Option<LayoutDom<'dom, Node>>;
fn prev_sibling_ref(self) -> Option<LayoutDom<'dom, Node>>;
fn next_sibling_ref(self) -> Option<LayoutDom<'dom, Node>>;
unsafe fn owner_doc_for_layout(self) -> LayoutDom<'dom, Document>;
unsafe fn containing_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>>;
fn owner_doc_for_layout(self) -> LayoutDom<'dom, Document>;
fn containing_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>>;
unsafe fn is_element_for_layout(self) -> bool;
fn is_element_for_layout(self) -> bool;
unsafe fn get_flag(self, flag: NodeFlags) -> bool;
unsafe fn set_flag(self, flag: NodeFlags, value: bool);
unsafe fn children_count(self) -> u32;
fn children_count(self) -> u32;
unsafe fn get_style_and_layout_data(self) -> Option<OpaqueStyleAndLayoutData>;
unsafe fn init_style_and_layout_data(self, _: OpaqueStyleAndLayoutData);
@ -1339,24 +1339,30 @@ pub trait LayoutNodeHelpers<'dom> {
fn opaque(self) -> OpaqueNode;
}
impl<'dom> LayoutDom<'dom, Node> {
#[inline]
#[allow(unsafe_code)]
fn parent_node_ref(self) -> Option<LayoutDom<'dom, Node>> {
unsafe { self.unsafe_get().parent_node.get_inner_as_layout() }
}
}
impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> {
#[inline]
#[allow(unsafe_code)]
unsafe fn type_id_for_layout(self) -> NodeTypeId {
(*self.unsafe_get()).type_id()
fn type_id_for_layout(self) -> NodeTypeId {
unsafe { self.unsafe_get().type_id() }
}
#[inline]
#[allow(unsafe_code)]
unsafe fn is_element_for_layout(self) -> bool {
(*self.unsafe_get()).is::<Element>()
fn is_element_for_layout(self) -> bool {
self.is::<Element>()
}
#[inline]
#[allow(unsafe_code)]
unsafe fn composed_parent_node_ref(self) -> Option<LayoutDom<'dom, Node>> {
let parent = (*self.unsafe_get()).parent_node.get_inner_as_layout();
if let Some(ref parent) = parent {
fn composed_parent_node_ref(self) -> Option<LayoutDom<'dom, Node>> {
let parent = self.parent_node_ref();
if let Some(parent) = parent {
if let Some(shadow_root) = parent.downcast::<ShadowRoot>() {
return Some(shadow_root.get_host_for_layout().upcast());
}
@ -1366,48 +1372,52 @@ impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> {
#[inline]
#[allow(unsafe_code)]
unsafe fn first_child_ref(self) -> Option<LayoutDom<'dom, Node>> {
(*self.unsafe_get()).first_child.get_inner_as_layout()
fn first_child_ref(self) -> Option<LayoutDom<'dom, Node>> {
unsafe { self.unsafe_get().first_child.get_inner_as_layout() }
}
#[inline]
#[allow(unsafe_code)]
unsafe fn last_child_ref(self) -> Option<LayoutDom<'dom, Node>> {
(*self.unsafe_get()).last_child.get_inner_as_layout()
fn last_child_ref(self) -> Option<LayoutDom<'dom, Node>> {
unsafe { self.unsafe_get().last_child.get_inner_as_layout() }
}
#[inline]
#[allow(unsafe_code)]
unsafe fn prev_sibling_ref(self) -> Option<LayoutDom<'dom, Node>> {
(*self.unsafe_get()).prev_sibling.get_inner_as_layout()
fn prev_sibling_ref(self) -> Option<LayoutDom<'dom, Node>> {
unsafe { self.unsafe_get().prev_sibling.get_inner_as_layout() }
}
#[inline]
#[allow(unsafe_code)]
unsafe fn next_sibling_ref(self) -> Option<LayoutDom<'dom, Node>> {
(*self.unsafe_get()).next_sibling.get_inner_as_layout()
fn next_sibling_ref(self) -> Option<LayoutDom<'dom, Node>> {
unsafe { self.unsafe_get().next_sibling.get_inner_as_layout() }
}
#[inline]
#[allow(unsafe_code)]
unsafe fn owner_doc_for_layout(self) -> LayoutDom<'dom, Document> {
(*self.unsafe_get())
.owner_doc
.get_inner_as_layout()
.unwrap()
fn owner_doc_for_layout(self) -> LayoutDom<'dom, Document> {
unsafe { self.unsafe_get().owner_doc.get_inner_as_layout().unwrap() }
}
#[inline]
#[allow(unsafe_code)]
unsafe fn containing_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>> {
(*self.unsafe_get())
.rare_data_for_layout()
.as_ref()?
.containing_shadow_root
.as_ref()
.map(|sr| sr.to_layout())
fn containing_shadow_root_for_layout(self) -> Option<LayoutDom<'dom, ShadowRoot>> {
unsafe {
self.unsafe_get()
.rare_data
.borrow_for_layout()
.as_ref()?
.containing_shadow_root
.as_ref()
.map(|sr| sr.to_layout())
}
}
// FIXME(nox): get_flag/set_flag (especially the latter) are not safe because
// they mutate stuff while values of this type can be used from multiple
// threads at once, this should be revisited.
#[inline]
#[allow(unsafe_code)]
unsafe fn get_flag(self, flag: NodeFlags) -> bool {
@ -1431,10 +1441,13 @@ impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> {
#[inline]
#[allow(unsafe_code)]
unsafe fn children_count(self) -> u32 {
(*self.unsafe_get()).children_count.get()
fn children_count(self) -> u32 {
unsafe { self.unsafe_get().children_count.get() }
}
// FIXME(nox): How we handle style and layout data needs to be completely
// revisited so we can do that more cleanly and safely in layout 2020.
#[inline]
#[allow(unsafe_code)]
unsafe fn get_style_and_layout_data(self) -> Option<OpaqueStyleAndLayoutData> {
@ -1472,40 +1485,32 @@ impl<'dom> LayoutNodeHelpers<'dom> for LayoutDom<'dom, Node> {
panic!("not text!")
}
#[allow(unsafe_code)]
fn selection(self) -> Option<Range<usize>> {
if let Some(area) = self.downcast::<HTMLTextAreaElement>() {
return unsafe { area.selection_for_layout() };
return area.selection_for_layout();
}
if let Some(input) = self.downcast::<HTMLInputElement>() {
return unsafe { input.selection_for_layout() };
return input.selection_for_layout();
}
None
}
#[allow(unsafe_code)]
fn image_url(self) -> Option<ServoUrl> {
unsafe {
self.downcast::<HTMLImageElement>()
.expect("not an image!")
.image_url()
}
self.downcast::<HTMLImageElement>()
.expect("not an image!")
.image_url()
}
#[allow(unsafe_code)]
fn image_data(self) -> Option<(Option<StdArc<Image>>, Option<ImageMetadata>)> {
unsafe { self.downcast::<HTMLImageElement>().map(|e| e.image_data()) }
self.downcast::<HTMLImageElement>().map(|e| e.image_data())
}
#[allow(unsafe_code)]
fn image_density(self) -> Option<f64> {
unsafe {
self.downcast::<HTMLImageElement>()
.expect("not an image!")
.image_density()
}
self.downcast::<HTMLImageElement>()
.expect("not an image!")
.image_density()
}
fn canvas_data(self) -> Option<HTMLCanvasData> {

View file

@ -27,6 +27,7 @@ use style::dom::TElement;
use style::media_queries::Device;
use style::shared_lock::SharedRwLockReadGuard;
use style::stylesheets::Stylesheet;
use style::stylist::CascadeData;
/// Whether a shadow root hosts an User Agent widget.
#[derive(JSTraceable, MallocSizeOf, PartialEq)]
@ -240,8 +241,8 @@ impl ShadowRootMethods for ShadowRoot {
#[allow(unsafe_code)]
pub trait LayoutShadowRootHelpers<'dom> {
unsafe fn get_host_for_layout(self) -> LayoutDom<'dom, Element>;
unsafe fn get_style_data_for_layout(self) -> &'dom AuthorStyles<StyleSheetInDocument>;
fn get_host_for_layout(self) -> LayoutDom<'dom, Element>;
fn get_style_data_for_layout(self) -> &'dom CascadeData;
unsafe fn flush_stylesheets<E: TElement>(
self,
device: &Device,
@ -253,19 +254,25 @@ pub trait LayoutShadowRootHelpers<'dom> {
impl<'dom> LayoutShadowRootHelpers<'dom> for LayoutDom<'dom, ShadowRoot> {
#[inline]
#[allow(unsafe_code)]
unsafe fn get_host_for_layout(self) -> LayoutDom<'dom, Element> {
(*self.unsafe_get())
.host
.get_inner_as_layout()
.expect("We should never do layout on a detached shadow root")
fn get_host_for_layout(self) -> LayoutDom<'dom, Element> {
unsafe {
self.unsafe_get()
.host
.get_inner_as_layout()
.expect("We should never do layout on a detached shadow root")
}
}
#[inline]
#[allow(unsafe_code)]
unsafe fn get_style_data_for_layout(self) -> &'dom AuthorStyles<StyleSheetInDocument> {
(*self.unsafe_get()).author_styles.borrow_for_layout()
fn get_style_data_for_layout(self) -> &'dom CascadeData {
fn is_sync<T: Sync>() {}
let _ = is_sync::<CascadeData>;
unsafe { &self.unsafe_get().author_styles.borrow_for_layout().data }
}
// FIXME(nox): This uses the dreaded borrow_mut_for_layout so this should
// probably be revisited.
#[inline]
#[allow(unsafe_code)]
unsafe fn flush_stylesheets<E: TElement>(

View file

@ -7,7 +7,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::document::Document;
use crate::dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
use crate::dom::node::Node;
use crate::dom::svggraphicselement::SVGGraphicsElement;
use crate::dom::virtualmethods::VirtualMethods;
@ -53,21 +53,16 @@ pub trait LayoutSVGSVGElementHelpers {
}
impl LayoutSVGSVGElementHelpers for LayoutDom<'_, SVGSVGElement> {
#[allow(unsafe_code, non_snake_case)]
fn data(self) -> SVGSVGData {
unsafe {
let SVG = &*self.unsafe_get();
let width_attr = SVG
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"));
let height_attr = SVG
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"));
SVGSVGData {
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
}
let width_attr = self
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("width"));
let height_attr = self
.upcast::<Element>()
.get_attr_for_layout(&ns!(), &local_name!("height"));
SVGSVGData {
width: width_attr.map_or(DEFAULT_WIDTH, |val| val.as_uint()),
height: height_attr.map_or(DEFAULT_HEIGHT, |val| val.as_uint()),
}
}
}

View file

@ -131,7 +131,7 @@ pub mod layout_exports {
pub use crate::dom::bindings::root::LayoutDom;
pub use crate::dom::characterdata::LayoutCharacterDataHelpers;
pub use crate::dom::document::{Document, LayoutDocumentHelpers};
pub use crate::dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers};
pub use crate::dom::element::{Element, LayoutElementHelpers};
pub use crate::dom::node::NodeFlags;
pub use crate::dom::node::{LayoutNodeHelpers, Node};
pub use crate::dom::shadowroot::{LayoutShadowRootHelpers, ShadowRoot};