mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Make more things private to the style crate.
This commit is contained in:
parent
7e78e54c3f
commit
5f3dc55f72
9 changed files with 103 additions and 84 deletions
|
@ -70,7 +70,7 @@ impl FontFamily {
|
|||
/// Commands that the FontContext sends to the font cache task.
|
||||
pub enum Command {
|
||||
GetFontTemplate(String, FontTemplateDescriptor, Sender<Reply>),
|
||||
AddWebFont(Vec<Url>, String, Sender<()>),
|
||||
AddWebFont(String, Url, Sender<()>),
|
||||
Exit(Sender<()>),
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,7 @@ impl FontCache {
|
|||
|
||||
result.send(GetFontTemplateReply(font_template));
|
||||
}
|
||||
AddWebFont(urls, family_name, result) => {
|
||||
for url in urls.iter() {
|
||||
AddWebFont(family_name, url, result) => {
|
||||
let maybe_resource = load_whole_resource(&self.resource_task, url.clone());
|
||||
match maybe_resource {
|
||||
Ok((_, bytes)) => {
|
||||
|
@ -121,7 +120,6 @@ impl FontCache {
|
|||
fail!("{}: url={}", msg, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.send(());
|
||||
}
|
||||
Exit(result) => {
|
||||
|
@ -264,9 +262,9 @@ impl FontCacheTask {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_web_font(&mut self, urls: Vec<Url>, family: &str) {
|
||||
pub fn add_web_font(&mut self, family: String, url: Url) {
|
||||
let (response_chan, response_port) = channel();
|
||||
self.chan.send(AddWebFont(urls, family.to_string(), response_chan));
|
||||
self.chan.send(AddWebFont(family, url, response_chan));
|
||||
response_port.recv();
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ use std::comm::{channel, Sender, Receiver, Select};
|
|||
use std::mem;
|
||||
use std::ptr;
|
||||
use style::{AuthorOrigin, Stylesheet, Stylist};
|
||||
use style::CSSFontFaceRule;
|
||||
use style::iter_font_face_rules;
|
||||
use sync::{Arc, Mutex};
|
||||
use url::Url;
|
||||
|
||||
|
@ -490,20 +490,9 @@ impl LayoutTask {
|
|||
fn handle_add_stylesheet(&mut self, sheet: Stylesheet) {
|
||||
// Find all font-face rules and notify the font cache of them.
|
||||
// GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!)
|
||||
// GWTODO: Need to handle font-face nested within media rules.
|
||||
for rule in sheet.rules.iter() {
|
||||
match rule {
|
||||
&CSSFontFaceRule(ref font_face_rule) => {
|
||||
let mut font_urls = vec!();
|
||||
for source in font_face_rule.sources.iter() {
|
||||
font_urls.push(source.url.clone());
|
||||
}
|
||||
self.font_cache_task.add_web_font(font_urls, font_face_rule.family.as_slice());
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
iter_font_face_rules(&sheet, |family, url| {
|
||||
self.font_cache_task.add_web_font(family.to_string(), url.clone());
|
||||
});
|
||||
self.stylist.add_stylesheet(sheet, AuthorOrigin);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
//! Element nodes.
|
||||
|
||||
use cssparser::tokenize;
|
||||
use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrHelpersForLayout};
|
||||
use dom::attr::{AttrValue, StringAttrValue, UIntAttrValue, AtomAttrValue};
|
||||
use dom::attrlist::AttrList;
|
||||
|
@ -31,7 +30,7 @@ use dom::nodelist::NodeList;
|
|||
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||
use layout_interface::ContentChangedDocumentDamage;
|
||||
use layout_interface::MatchSelectorsDocumentDamage;
|
||||
use style::{matches_compound_selector, NamespaceMap, parse_selector_list};
|
||||
use style::{matches, parse_selector_list_from_str};
|
||||
use style;
|
||||
use servo_util::atom::Atom;
|
||||
use servo_util::namespace;
|
||||
|
@ -775,22 +774,14 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-element-matches
|
||||
fn Matches(&self, selectors: DOMString) -> Fallible<bool> {
|
||||
let namespace = NamespaceMap::new();
|
||||
match parse_selector_list(tokenize(selectors.as_slice()).map(|(token, _)| token).collect(),
|
||||
&namespace) {
|
||||
Err(()) => return Err(Syntax),
|
||||
match parse_selector_list_from_str(selectors.as_slice()) {
|
||||
Err(()) => Err(Syntax),
|
||||
Ok(ref selectors) => {
|
||||
let root: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
for selector in selectors.iter() {
|
||||
let mut shareable = false;
|
||||
if matches_compound_selector(&*selector.compound_selectors, root, &mut shareable) {
|
||||
return Ok(true);
|
||||
Ok(matches(selectors, root))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_attribute_parts<'a>(name: &'a str) -> (Option<&'a str>, &'a str) {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
//! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements.
|
||||
|
||||
use cssparser::tokenize;
|
||||
use dom::attr::Attr;
|
||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||
|
@ -48,7 +47,7 @@ use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery, C
|
|||
LayoutChan, ReapLayoutDataMsg, TrustedNodeAddress, UntrustedNodeAddress};
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::str::{DOMString, null_str_as_empty};
|
||||
use style::{parse_selector_list, matches_compound_selector, NamespaceMap};
|
||||
use style::{parse_selector_list_from_str, matches};
|
||||
|
||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||
use js::jsfriendapi;
|
||||
|
@ -611,48 +610,35 @@ impl<'m, 'n> NodeHelpers<'m, 'n> for JSRef<'n, Node> {
|
|||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
||||
fn query_selector(&self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
||||
// Step 1.
|
||||
let namespace = NamespaceMap::new();
|
||||
match parse_selector_list(tokenize(selectors.as_slice()).map(|(token, _)| token).collect(), &namespace) {
|
||||
match parse_selector_list_from_str(selectors.as_slice()) {
|
||||
// Step 2.
|
||||
Err(()) => return Err(Syntax),
|
||||
// Step 3.
|
||||
Ok(ref selectors) => {
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
for selector in selectors.iter() {
|
||||
assert!(selector.pseudo_element.is_none());
|
||||
for node in root.traverse_preorder().filter(|node| node.is_element()) {
|
||||
let mut _shareable: bool = false;
|
||||
if matches_compound_selector(selector.compound_selectors.deref(), &node, &mut _shareable) {
|
||||
for node in root.traverse_preorder() {
|
||||
if node.is_element() && matches(selectors, &node) {
|
||||
let elem: &JSRef<Element> = ElementCast::to_ref(&node).unwrap();
|
||||
return Ok(Some(Temporary::from_rooted(elem)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselectorall
|
||||
fn query_selector_all(&self, selectors: DOMString) -> Fallible<Temporary<NodeList>> {
|
||||
// Step 1.
|
||||
let mut nodes = vec!();
|
||||
let nodes;
|
||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||
let namespace = NamespaceMap::new();
|
||||
match parse_selector_list(tokenize(selectors.as_slice()).map(|(token, _)| token).collect(), &namespace) {
|
||||
match parse_selector_list_from_str(selectors.as_slice()) {
|
||||
// Step 2.
|
||||
Err(()) => return Err(Syntax),
|
||||
// Step 3.
|
||||
Ok(ref selectors) => {
|
||||
for selector in selectors.iter() {
|
||||
assert!(selector.pseudo_element.is_none());
|
||||
for node in root.traverse_preorder().filter(|node| node.is_element()) {
|
||||
let mut _shareable: bool = false;
|
||||
if matches_compound_selector(selector.compound_selectors.deref(), &node, &mut _shareable) {
|
||||
nodes.push(node.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
nodes = root.traverse_preorder().filter(
|
||||
|node| node.is_element() && matches(selectors, node)).collect()
|
||||
}
|
||||
}
|
||||
let window = window_from_node(self).root();
|
||||
|
|
|
@ -9,10 +9,35 @@ use std::ascii::StrAsciiExt;
|
|||
use parsing_utils::{BufferedIter, ParserIter, parse_slice_comma_separated};
|
||||
use properties::longhands::font_family::parse_one_family;
|
||||
use properties::computed_values::font_family::FamilyName;
|
||||
use stylesheets::{CSSRule, CSSFontFaceRule};
|
||||
use stylesheets::{CSSRule, CSSFontFaceRule, CSSStyleRule, CSSMediaRule};
|
||||
use media_queries::{Device, Screen};
|
||||
use url::{Url, UrlParser};
|
||||
|
||||
|
||||
static SUPPORTED_FORMATS: &'static [&'static str] = &["truetype", "opentype"];
|
||||
|
||||
|
||||
pub fn iter_font_face_rules_inner(rules: &[CSSRule], callback: |family: &str, source: &Url|) {
|
||||
let device = &Device { media_type: Screen }; // TODO, use Print when printing
|
||||
for rule in rules.iter() {
|
||||
match *rule {
|
||||
CSSStyleRule(_) => {},
|
||||
CSSMediaRule(ref rule) => if rule.media_queries.evaluate(device) {
|
||||
iter_font_face_rules_inner(rule.rules.as_slice(), |f, s| callback(f, s))
|
||||
},
|
||||
CSSFontFaceRule(ref rule) => {
|
||||
for source in rule.sources.iter() {
|
||||
if source.format_hints.is_empty() || source.format_hints.iter().any(
|
||||
|f| SUPPORTED_FORMATS.iter().any(
|
||||
|s| f.as_slice().eq_ignore_ascii_case(*s))) {
|
||||
callback(rule.family.as_slice(), &source.url)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Source {
|
||||
UrlSource(UrlSource),
|
||||
LocalSource(String),
|
||||
|
|
|
@ -18,7 +18,7 @@ use media_queries::{Device, Screen};
|
|||
use node::{TElement, TNode};
|
||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use selectors::*;
|
||||
use stylesheets::{Stylesheet, iter_style_rules};
|
||||
use stylesheets::{Stylesheet, iter_stylesheet_style_rules};
|
||||
|
||||
pub enum StylesheetOrigin {
|
||||
UserAgentOrigin,
|
||||
|
@ -317,7 +317,7 @@ impl Stylist {
|
|||
);
|
||||
|
||||
let device = &Device { media_type: Screen }; // TODO, use Print when printing
|
||||
iter_style_rules(stylesheet.rules.as_slice(), device, |style_rule| {
|
||||
iter_stylesheet_style_rules(&stylesheet, device, |style_rule| {
|
||||
append!(style_rule, normal);
|
||||
append!(style_rule, important);
|
||||
rules_source_order += 1;
|
||||
|
@ -449,6 +449,12 @@ impl DeclarationBlock {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn matches<E:TElement, N:TNode<E>>(selector_list: &SelectorList, element: &N) -> bool {
|
||||
get_selector_list_selectors(selector_list).iter().any(|selector|
|
||||
selector.pseudo_element.is_none() &&
|
||||
matches_compound_selector(&*selector.compound_selectors, element, &mut false))
|
||||
}
|
||||
|
||||
|
||||
/// Determines whether the given element matches the given single or compound selector.
|
||||
///
|
||||
|
@ -456,7 +462,7 @@ impl DeclarationBlock {
|
|||
/// `shareable` to false unless you are willing to update the style sharing logic. Otherwise things
|
||||
/// will almost certainly break as nodes will start mistakenly sharing styles. (See the code in
|
||||
/// `main/css/matching.rs`.)
|
||||
pub fn matches_compound_selector<E:TElement,
|
||||
fn matches_compound_selector<E:TElement,
|
||||
N:TNode<E>>(
|
||||
selector: &CompoundSelector,
|
||||
element: &N,
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::vec;
|
|||
use sync::Arc;
|
||||
|
||||
use cssparser::ast::*;
|
||||
use cssparser::parse_nth;
|
||||
use cssparser::{tokenize, parse_nth};
|
||||
|
||||
use servo_util::atom::Atom;
|
||||
use servo_util::namespace::Namespace;
|
||||
|
@ -116,6 +116,22 @@ pub enum NamespaceConstraint {
|
|||
type Iter = iter::Peekable<ComponentValue, vec::MoveItems<ComponentValue>>;
|
||||
|
||||
|
||||
pub fn parse_selector_list_from_str(input: &str) -> Result<SelectorList, ()> {
|
||||
let namespaces = NamespaceMap::new();
|
||||
let input = tokenize(input).map(|(token, _)| token).collect();
|
||||
parse_selector_list(input, &namespaces).map(|s| SelectorList { selectors: s })
|
||||
}
|
||||
|
||||
/// Re-exported to script, but opaque.
|
||||
pub struct SelectorList {
|
||||
selectors: Vec<Selector>
|
||||
}
|
||||
|
||||
/// Public to the style crate, but not re-exported to script
|
||||
pub fn get_selector_list_selectors<'a>(selector_list: &'a SelectorList) -> &'a [Selector] {
|
||||
selector_list.selectors.as_slice()
|
||||
}
|
||||
|
||||
/// Parse a comma-separated list of Selectors.
|
||||
/// aka Selector Group in http://www.w3.org/TR/css3-selectors/#grouping
|
||||
///
|
||||
|
|
|
@ -30,21 +30,17 @@ extern crate servo_util = "util";
|
|||
|
||||
|
||||
// Public API
|
||||
pub use stylesheets::{Stylesheet, CSSRule, StyleRule, CSSFontFaceRule};
|
||||
pub use stylesheets::{Stylesheet, iter_font_face_rules};
|
||||
pub use selector_matching::{Stylist, StylesheetOrigin, UserAgentOrigin, AuthorOrigin, UserOrigin};
|
||||
pub use selector_matching::{DeclarationBlock, matches_compound_selector};
|
||||
pub use selector_matching::{DeclarationBlock, matches};
|
||||
pub use properties::{cascade, cascade_anonymous};
|
||||
pub use properties::{PropertyDeclaration, ComputedValues, computed_values, style_structs};
|
||||
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
|
||||
pub use properties::{CSSFloat, DeclaredValue, PropertyDeclarationParseResult};
|
||||
pub use properties::longhands;
|
||||
pub use node::{TElement, TNode};
|
||||
pub use selectors::{PseudoElement, Before, After, AttrSelector, SpecificNamespace, AnyNamespace};
|
||||
pub use selectors::{NamespaceConstraint, Selector, CompoundSelector, SimpleSelector, Combinator};
|
||||
pub use selectors::{LocalNameSelector, parse_selector_list};
|
||||
pub use namespaces::NamespaceMap;
|
||||
pub use media_queries::{MediaRule, MediaQueryList, MediaQuery, Device, MediaType, MediaQueryType};
|
||||
pub use font_face::{FontFaceRule};
|
||||
pub use selectors::{PseudoElement, Before, After, SelectorList, parse_selector_list_from_str};
|
||||
pub use selectors::{AttrSelector, NamespaceConstraint, SpecificNamespace, AnyNamespace};
|
||||
|
||||
mod stylesheets;
|
||||
mod errors;
|
||||
|
|
|
@ -16,13 +16,13 @@ use errors::{ErrorLoggerIterator, log_css_error};
|
|||
use namespaces::{NamespaceMap, parse_namespace_rule};
|
||||
use media_queries::{MediaRule, parse_media_rule};
|
||||
use media_queries;
|
||||
use font_face::{FontFaceRule, parse_font_face_rule};
|
||||
use font_face::{FontFaceRule, parse_font_face_rule, iter_font_face_rules_inner};
|
||||
|
||||
|
||||
pub struct Stylesheet {
|
||||
/// List of rules in the order they were found (important for
|
||||
/// cascading order)
|
||||
pub rules: Vec<CSSRule>,
|
||||
rules: Vec<CSSRule>,
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,3 +164,15 @@ pub fn iter_style_rules<'a>(rules: &[CSSRule], device: &media_queries::Device,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn iter_stylesheet_style_rules(stylesheet: &Stylesheet, device: &media_queries::Device,
|
||||
callback: |&StyleRule|) {
|
||||
iter_style_rules(stylesheet.rules.as_slice(), device, callback)
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn iter_font_face_rules(stylesheet: &Stylesheet, callback: |family: &str, sources: &Url|) {
|
||||
iter_font_face_rules_inner(stylesheet.rules.as_slice(), callback)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue