Auto merge of #7867 - Ms2ger:layoutjs, r=nox

Move some methods from RawLayoutElementHelpers to LayoutElementHelpers.

This is part of a long-term plan to ensure layout never has access to
unwrapped pointers to DOM objects. The remaining methods on the
RawLayoutElementHelpers trait are harder to move, because of the lifetimes in
their signatures.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7867)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-10-05 08:19:21 -06:00
commit a350b215cc
2 changed files with 80 additions and 70 deletions

View file

@ -516,14 +516,14 @@ impl<'le> ::selectors::Element for LayoutElement<'le> {
#[inline] #[inline]
fn has_class(&self, name: &Atom) -> bool { fn has_class(&self, name: &Atom) -> bool {
unsafe { unsafe {
(*self.element.unsafe_get()).has_class_for_layout(name) self.element.has_class_for_layout(name)
} }
} }
#[inline(always)] #[inline(always)]
fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) {
unsafe { unsafe {
match (*self.element.unsafe_get()).get_classes_for_layout() { match self.element.get_classes_for_layout() {
None => {} None => {}
Some(ref classes) => { Some(ref classes) => {
for class in *classes { for class in *classes {
@ -572,13 +572,13 @@ impl<'le> TElementAttributes for LayoutElement<'le> {
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>> where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
{ {
unsafe { unsafe {
(*self.element.unsafe_get()).synthesize_presentational_hints_for_legacy_attributes(hints); self.element.synthesize_presentational_hints_for_legacy_attributes(hints);
} }
} }
fn get_unsigned_integer_attribute(&self, attribute: UnsignedIntegerAttribute) -> Option<u32> { fn get_unsigned_integer_attribute(&self, attribute: UnsignedIntegerAttribute) -> Option<u32> {
unsafe { unsafe {
(*self.element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute) self.element.get_unsigned_integer_attribute_for_layout(attribute)
} }
} }
@ -840,7 +840,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
let elem: Option<LayoutJS<Element>> = ElementCast::to_layout_js(self.get_jsmanaged()); let elem: Option<LayoutJS<Element>> = ElementCast::to_layout_js(self.get_jsmanaged());
match elem { match elem {
Some(element) => { Some(element) => {
(*element.unsafe_get()).get_unsigned_integer_attribute_for_layout(attribute) element.get_unsigned_integer_attribute_for_layout(attribute)
} }
None => panic!("not an element!") None => panic!("not an element!")
} }

View file

@ -163,14 +163,6 @@ pub trait RawLayoutElementHelpers {
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom) unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom)
-> Option<&'a str>; -> Option<&'a str>;
unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str>; unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str>;
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom) -> Option<Atom>;
unsafe fn has_class_for_layout(&self, name: &Atom) -> bool;
unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]>;
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
unsafe fn get_unsigned_integer_attribute_for_layout(&self, attribute: UnsignedIntegerAttribute)
-> Option<u32>;
} }
#[inline] #[inline]
@ -215,42 +207,74 @@ impl RawLayoutElementHelpers for Element {
} }
}).collect() }).collect()
} }
}
pub trait LayoutElementHelpers {
#[allow(unsafe_code)]
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom) -> Option<Atom>;
#[allow(unsafe_code)]
unsafe fn has_class_for_layout(&self, name: &Atom) -> bool;
#[allow(unsafe_code)]
unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]>;
#[allow(unsafe_code)]
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, &mut V)
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>;
#[allow(unsafe_code)]
unsafe fn get_unsigned_integer_attribute_for_layout(&self, attribute: UnsignedIntegerAttribute)
-> Option<u32>;
#[allow(unsafe_code)]
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
#[allow(unsafe_code)]
unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool;
fn id_attribute(&self) -> *const Option<Atom>;
fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock>;
fn local_name(&self) -> &Atom;
fn namespace(&self) -> &Namespace;
fn get_checked_state_for_layout(&self) -> bool;
fn get_indeterminate_state_for_layout(&self) -> bool;
}
impl LayoutElementHelpers for LayoutJS<Element> {
#[allow(unsafe_code)]
#[inline] #[inline]
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom) unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom)
-> Option<Atom> { -> Option<Atom> {
get_attr_for_layout(self, namespace, name).and_then(|attr| { get_attr_for_layout(&*self.unsafe_get(), namespace, name).and_then(|attr| {
attr.value_atom_forever() attr.value_atom_forever()
}) })
} }
#[allow(unsafe_code)]
#[inline] #[inline]
unsafe fn has_class_for_layout(&self, name: &Atom) -> bool { unsafe fn has_class_for_layout(&self, name: &Atom) -> bool {
get_attr_for_layout(self, &ns!(""), &atom!("class")).map_or(false, |attr| { get_attr_for_layout(&*self.unsafe_get(), &ns!(""), &atom!("class")).map_or(false, |attr| {
attr.value_tokens_forever().unwrap().iter().any(|atom| atom == name) attr.value_tokens_forever().unwrap().iter().any(|atom| atom == name)
}) })
} }
#[allow(unsafe_code)]
#[inline] #[inline]
unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]> { unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]> {
get_attr_for_layout(self, &ns!(""), &atom!("class")).map(|attr| { get_attr_for_layout(&*self.unsafe_get(), &ns!(""), &atom!("class")).map(|attr| {
attr.value_tokens_forever().unwrap() attr.value_tokens_forever().unwrap()
}) })
} }
#[allow(unsafe_code)]
unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V) unsafe fn synthesize_presentational_hints_for_legacy_attributes<V>(&self, hints: &mut V)
where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>> where V: VecLike<DeclarationBlock<Vec<PropertyDeclaration>>>
{ {
let bgcolor = if let Some(this) = HTMLBodyElementCast::to_ref(self) { let bgcolor = if let Some(this) = HTMLBodyElementCast::to_layout_js(self) {
this.get_background_color() (*this.unsafe_get()).get_background_color()
} else if let Some(this) = HTMLTableElementCast::to_ref(self) { } else if let Some(this) = HTMLTableElementCast::to_layout_js(self) {
this.get_background_color() (*this.unsafe_get()).get_background_color()
} else if let Some(this) = HTMLTableCellElementCast::to_ref(self) { } else if let Some(this) = HTMLTableCellElementCast::to_layout_js(self) {
this.get_background_color() (*this.unsafe_get()).get_background_color()
} else if let Some(this) = HTMLTableRowElementCast::to_ref(self) { } else if let Some(this) = HTMLTableRowElementCast::to_layout_js(self) {
this.get_background_color() (*this.unsafe_get()).get_background_color()
} else if let Some(this) = HTMLTableSectionElementCast::to_ref(self) { } else if let Some(this) = HTMLTableSectionElementCast::to_layout_js(self) {
this.get_background_color() (*this.unsafe_get()).get_background_color()
} else { } else {
None None
}; };
@ -261,8 +285,8 @@ impl RawLayoutElementHelpers for Element {
CSSColor { parsed: Color::RGBA(color), authored: None })))); CSSColor { parsed: Color::RGBA(color), authored: None }))));
} }
let background = if let Some(this) = HTMLBodyElementCast::to_ref(self) { let background = if let Some(this) = HTMLBodyElementCast::to_layout_js(self) {
this.get_background() (*this.unsafe_get()).get_background()
} else { } else {
None None
}; };
@ -273,8 +297,8 @@ impl RawLayoutElementHelpers for Element {
background_image::SpecifiedValue(Some(specified::Image::Url(url))))))); background_image::SpecifiedValue(Some(specified::Image::Url(url)))))));
} }
let color = if let Some(this) = HTMLFontElementCast::to_ref(self) { let color = if let Some(this) = HTMLFontElementCast::to_layout_js(self) {
this.get_color() (*this.unsafe_get()).get_color()
} else { } else {
None None
}; };
@ -287,8 +311,8 @@ impl RawLayoutElementHelpers for Element {
})))); }))));
} }
let font_family = if let Some(this) = HTMLFontElementCast::to_ref(self) { let font_family = if let Some(this) = HTMLFontElementCast::to_layout_js(self) {
this.get_face() (*this.unsafe_get()).get_face()
} else { } else {
None None
}; };
@ -302,8 +326,8 @@ impl RawLayoutElementHelpers for Element {
font_family)]))))); font_family)])))));
} }
let font_size = if let Some(this) = HTMLFontElementCast::to_ref(self) { let font_size = if let Some(this) = HTMLFontElementCast::to_layout_js(self) {
this.get_size() (*this.unsafe_get()).get_size()
} else { } else {
None None
}; };
@ -315,8 +339,8 @@ impl RawLayoutElementHelpers for Element {
font_size::SpecifiedValue(font_size))))) font_size::SpecifiedValue(font_size)))))
} }
let cellspacing = if let Some(this) = HTMLTableElementCast::to_ref(self) { let cellspacing = if let Some(this) = HTMLTableElementCast::to_layout_js(self) {
this.get_cellspacing() (*this.unsafe_get()).get_cellspacing()
} else { } else {
None None
}; };
@ -332,13 +356,13 @@ impl RawLayoutElementHelpers for Element {
} }
let size = if let Some(this) = HTMLInputElementCast::to_ref(self) { let size = if let Some(this) = HTMLInputElementCast::to_layout_js(self) {
// FIXME(pcwalton): More use of atoms, please! // FIXME(pcwalton): More use of atoms, please!
// FIXME(Ms2ger): this is nonsense! Invalid values also end up as // FIXME(Ms2ger): this is nonsense! Invalid values also end up as
// a text field // a text field
match self.get_attr_val_for_layout(&ns!(""), &atom!("type")) { match (*self.unsafe_get()).get_attr_val_for_layout(&ns!(""), &atom!("type")) {
Some("text") | Some("password") => { Some("text") | Some("password") => {
match this.get_size_for_layout() { match (*this.unsafe_get()).get_size_for_layout() {
0 => None, 0 => None,
s => Some(s as i32), s => Some(s as i32),
} }
@ -358,12 +382,12 @@ impl RawLayoutElementHelpers for Element {
} }
let width = if let Some(this) = HTMLIFrameElementCast::to_ref(self) { let width = if let Some(this) = HTMLIFrameElementCast::to_layout_js(self) {
this.get_width() (*this.unsafe_get()).get_width()
} else if let Some(this) = HTMLTableElementCast::to_ref(self) { } else if let Some(this) = HTMLTableElementCast::to_layout_js(self) {
this.get_width() (*this.unsafe_get()).get_width()
} else if let Some(this) = HTMLTableCellElementCast::to_ref(self) { } else if let Some(this) = HTMLTableCellElementCast::to_layout_js(self) {
this.get_width() (*this.unsafe_get()).get_width()
} else { } else {
LengthOrPercentageOrAuto::Auto LengthOrPercentageOrAuto::Auto
}; };
@ -385,8 +409,8 @@ impl RawLayoutElementHelpers for Element {
} }
let height = if let Some(this) = HTMLIFrameElementCast::to_ref(self) { let height = if let Some(this) = HTMLIFrameElementCast::to_layout_js(self) {
this.get_height() (*this.unsafe_get()).get_height()
} else { } else {
LengthOrPercentageOrAuto::Auto LengthOrPercentageOrAuto::Auto
}; };
@ -408,8 +432,8 @@ impl RawLayoutElementHelpers for Element {
} }
let cols = if let Some(this) = HTMLTextAreaElementCast::to_ref(self) { let cols = if let Some(this) = HTMLTextAreaElementCast::to_layout_js(self) {
match this.get_cols_for_layout() { match (*this.unsafe_get()).get_cols_for_layout() {
0 => None, 0 => None,
c => Some(c as i32), c => Some(c as i32),
} }
@ -430,8 +454,8 @@ impl RawLayoutElementHelpers for Element {
} }
let rows = if let Some(this) = HTMLTextAreaElementCast::to_ref(self) { let rows = if let Some(this) = HTMLTextAreaElementCast::to_layout_js(self) {
match this.get_rows_for_layout() { match (*this.unsafe_get()).get_rows_for_layout() {
0 => None, 0 => None,
r => Some(r as i32), r => Some(r as i32),
} }
@ -450,8 +474,8 @@ impl RawLayoutElementHelpers for Element {
} }
let border = if let Some(this) = HTMLTableElementCast::to_ref(self) { let border = if let Some(this) = HTMLTableElementCast::to_layout_js(self) {
this.get_border() (*this.unsafe_get()).get_border()
} else { } else {
None None
}; };
@ -473,13 +497,14 @@ impl RawLayoutElementHelpers for Element {
} }
} }
#[allow(unsafe_code)]
unsafe fn get_unsigned_integer_attribute_for_layout(&self, unsafe fn get_unsigned_integer_attribute_for_layout(&self,
attribute: UnsignedIntegerAttribute) attribute: UnsignedIntegerAttribute)
-> Option<u32> { -> Option<u32> {
match attribute { match attribute {
UnsignedIntegerAttribute::ColSpan => { UnsignedIntegerAttribute::ColSpan => {
if let Some(this) = HTMLTableCellElementCast::to_ref(self) { if let Some(this) = HTMLTableCellElementCast::to_layout_js(self) {
this.get_colspan() (*this.unsafe_get()).get_colspan()
} else { } else {
// Don't panic since `display` can cause this to be called on arbitrary // Don't panic since `display` can cause this to be called on arbitrary
// elements. // elements.
@ -488,22 +513,7 @@ impl RawLayoutElementHelpers for Element {
} }
} }
} }
}
pub trait LayoutElementHelpers {
#[allow(unsafe_code)]
unsafe fn html_element_in_html_document_for_layout(&self) -> bool;
#[allow(unsafe_code)]
unsafe fn has_attr_for_layout(&self, namespace: &Namespace, name: &Atom) -> bool;
fn id_attribute(&self) -> *const Option<Atom>;
fn style_attribute(&self) -> *const Option<PropertyDeclarationBlock>;
fn local_name(&self) -> &Atom;
fn namespace(&self) -> &Namespace;
fn get_checked_state_for_layout(&self) -> bool;
fn get_indeterminate_state_for_layout(&self) -> bool;
}
impl LayoutElementHelpers for LayoutJS<Element> {
#[inline] #[inline]
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe fn html_element_in_html_document_for_layout(&self) -> bool { unsafe fn html_element_in_html_document_for_layout(&self) -> bool {