mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
stylo: We have an Atom back-end now.
This commit is contained in:
parent
d612d9f5ef
commit
010bce128b
2 changed files with 10 additions and 39 deletions
|
@ -26,6 +26,9 @@ pub struct GeckoSelectorImpl;
|
||||||
///
|
///
|
||||||
/// This should allow us to avoid random FFI overhead when cloning/dropping
|
/// This should allow us to avoid random FFI overhead when cloning/dropping
|
||||||
/// pseudos.
|
/// pseudos.
|
||||||
|
///
|
||||||
|
/// Also, we can further optimize PartialEq and hash comparing/hashing only the
|
||||||
|
/// atoms.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct PseudoElement(Atom, bool);
|
pub struct PseudoElement(Atom, bool);
|
||||||
|
|
||||||
|
@ -41,8 +44,9 @@ impl PseudoElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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) {
|
if cfg!(debug_assertions) {
|
||||||
|
// Do the check on debug regardless.
|
||||||
match Self::from_atom(&*atom, true) {
|
match Self::from_atom(&*atom, true) {
|
||||||
Some(pseudo) => {
|
Some(pseudo) => {
|
||||||
assert_eq!(pseudo.is_anon_box(), is_anon_box);
|
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::ServoElementSnapshot;
|
||||||
use gecko_bindings::structs::nsRestyleHint;
|
use gecko_bindings::structs::nsRestyleHint;
|
||||||
use gecko_bindings::structs::{SheetParsingMode, nsIAtom};
|
use gecko_bindings::structs::{SheetParsingMode, nsIAtom};
|
||||||
|
use gecko_string_cache::Atom;
|
||||||
use snapshot::GeckoElementSnapshot;
|
use snapshot::GeckoElementSnapshot;
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -39,29 +40,6 @@ use traversal::RecalcStyleOnly;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use wrapper::{DUMMY_BASE_URL, GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData};
|
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
|
* 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
|
* 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);
|
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
|
||||||
data.flush_stylesheets();
|
data.flush_stylesheets();
|
||||||
|
|
||||||
let pseudo = match pseudo_element_from_atom(pseudo_tag, /* ua_stylesheet = */ true) {
|
let atom = unsafe { Atom::from_static(pseudo_tag) };
|
||||||
Ok(pseudo) => pseudo,
|
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ true);
|
||||||
Err(pseudo) => {
|
|
||||||
warn!("stylo: Unable to parse anonymous-box pseudo-element: {}", pseudo);
|
|
||||||
return ptr::null_mut();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
|
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) {
|
let atom = unsafe { Atom::from_static(pseudo_tag) };
|
||||||
Ok(pseudo) => pseudo,
|
let pseudo = PseudoElement::from_atom_unchecked(atom, /* anon_box = */ false);
|
||||||
Err(pseudo) => {
|
|
||||||
warn!("stylo: Unable to parse anonymous-box pseudo-element: {}", pseudo);
|
|
||||||
return parent_or_null();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// The stylist consumes stylesheets lazily.
|
// The stylist consumes stylesheets lazily.
|
||||||
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
|
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue