New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stylo: Use atoms as the pseudo-element back-end. #12815
Changes from 1 commit
f9f347e
54b9201
12fcb7a
df44ba4
b1091df
d612d9f
010bce1
6bce4c8
babb2b7
24168f8
2b3c684
09cc240
File filter...
Jump to…
stylo: We have an Atom back-end now.
- Loading branch information
Unverified
| @@ -26,6 +26,9 @@ pub struct GeckoSelectorImpl; | ||
| /// | ||
| /// This should allow us to avoid random FFI overhead when cloning/dropping | ||
| /// pseudos. | ||
| /// | ||
| /// Also, we can further optimize PartialEq and hash comparing/hashing only the | ||
| /// atoms. | ||
| #[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
| pub struct PseudoElement(Atom, bool); | ||
emilio
Author
Member
|
||
|
|
||
| @@ -41,8 +44,9 @@ impl PseudoElement { | ||
| } | ||
|
|
||
| #[inline] | ||
| fn from_atom_unchecked(atom: Atom, is_anon_box: bool) -> Self { | ||
| pub fn from_atom_unchecked(atom: Atom, is_anon_box: bool) -> Self { | ||
| if cfg!(debug_assertions) { | ||
| // Do the check on debug regardless. | ||
| match Self::from_atom(&*atom, true) { | ||
| Some(pseudo) => { | ||
| assert_eq!(pseudo.is_anon_box(), is_anon_box); | ||
| @@ -16,6 +16,7 @@ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; | ||
| use gecko_bindings::structs::ServoElementSnapshot; | ||
| use gecko_bindings::structs::nsRestyleHint; | ||
| use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; | ||
| use gecko_string_cache::Atom; | ||
| use snapshot::GeckoElementSnapshot; | ||
| use std::mem::transmute; | ||
| use std::ptr; | ||
| @@ -39,29 +40,6 @@ use traversal::RecalcStyleOnly; | ||
| use url::Url; | ||
| use wrapper::{DUMMY_BASE_URL, GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData}; | ||
|
|
||
| // TODO: This is ugly and should go away once we get an atom back-end. | ||
| pub fn pseudo_element_from_atom(pseudo: *mut nsIAtom, | ||
| in_ua_stylesheet: bool) -> Result<PseudoElement, String> { | ||
| use gecko_bindings::bindings::Gecko_GetAtomAsUTF16; | ||
| use selectors::parser::{ParserContext, SelectorImpl}; | ||
|
|
||
| let pseudo_string = unsafe { | ||
| let mut length = 0; | ||
| let mut buff = Gecko_GetAtomAsUTF16(pseudo, &mut length); | ||
|
|
||
| // Handle the annoying preceding colon in front of everything in nsCSSAnonBoxList.h. | ||
| debug_assert!(length >= 2 && *buff == ':' as u16 && *buff.offset(1) != ':' as u16); | ||
| buff = buff.offset(1); | ||
| length -= 1; | ||
|
|
||
| String::from_utf16(slice::from_raw_parts(buff, length as usize)).unwrap() | ||
| }; | ||
|
|
||
| let mut context = ParserContext::new(); | ||
| context.in_user_agent_stylesheet = in_ua_stylesheet; | ||
| GeckoSelectorImpl::parse_pseudo_element(&context, &pseudo_string).map_err(|_| pseudo_string) | ||
| } | ||
|
|
||
| /* | ||
| * For Gecko->Servo function calls, we need to redeclare the same signature that was declared in | ||
| * the C header in Gecko. In order to catch accidental mismatches, we run rust-bindgen against | ||
| @@ -286,13 +264,8 @@ pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(parent_style_or_null: * | ||
| let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); | ||
| data.flush_stylesheets(); | ||
|
|
||
| let pseudo = match pseudo_element_from_atom(pseudo_tag, /* ua_stylesheet = */ true) { | ||
| Ok(pseudo) => pseudo, | ||
| Err(pseudo) => { | ||
| warn!("stylo: Unable to parse anonymous-box pseudo-element: {}", pseudo); | ||
| return ptr::null_mut(); | ||
| } | ||
| }; | ||
| let atom = unsafe { Atom::from_static(pseudo_tag) }; | ||
bholley
Contributor
|
||
| let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true); | ||
|
|
||
| type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>; | ||
|
|
||
| @@ -320,14 +293,8 @@ pub extern "C" fn Servo_GetComputedValuesForPseudoElement(parent_style: *mut Ser | ||
| } | ||
| }; | ||
|
|
||
| let pseudo = match pseudo_element_from_atom(pseudo_tag, /* ua_stylesheet = */ true) { | ||
| Ok(pseudo) => pseudo, | ||
| Err(pseudo) => { | ||
| warn!("stylo: Unable to parse anonymous-box pseudo-element: {}", pseudo); | ||
| return parent_or_null(); | ||
| } | ||
| }; | ||
|
|
||
| let atom = unsafe { Atom::from_static(pseudo_tag) }; | ||
| let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false); | ||
|
|
||
| // The stylist consumes stylesheets lazily. | ||
| let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); | ||
Maybe use struct syntax with named fields? I particular to say what this
boolis.