Auto merge of #14190 - Manishearth:cssom, r=SimonSapin

Immutable CSSOM

This PR is intended to add basic support for all CSSOM interfaces, with the ability to index `document.styleSheets` and css rule lists, and serializing individual css rules. Handling individual interface methods for CSSRule subclasses can probably be done with easy/medium bugs.

Mutation safety isn't dealt with here; if the css rule list is mutated the CSSOM will be in an inconsistent state. I intend to deal with this via zero sized tokens, see https://groups.google.com/forum/#!topic/mozilla.dev.servo/AnxJoVmtMXQ .  I'll handle that when I start making the CSSOM mutable. (Getting the immutable bit landed first opens this up for easy bugs)

This doesn't really change style aside from adding an extra arc in the CSS rule list as discussed in the linked thread. So far this same design can be used by stylo as well when the time comes.

f? @SimonSapin @emilio

cc @upsuper

part of #11420
Todo:

 - [x] Stubs for rest of the CSSRule subclasses
 - [x] <s>ToCSS impls for CSSRules.</s> May make into easy bugs and stub out in this PR https://github.com/servo/servo/issues/14195
 - [x] Cache CSSStyleSheet on the relevant node

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14190)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-11-16 15:05:59 -06:00 committed by GitHub
commit afc60bee28
57 changed files with 915 additions and 209 deletions

View file

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSFontFaceRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::cssrule::{CSSRule, SpecificCSSRule};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::font_face::FontFaceRule;
#[dom_struct]
pub struct CSSFontFaceRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
fontfacerule: Arc<RwLock<FontFaceRule>>,
}
impl CSSFontFaceRule {
fn new_inherited(parent: &CSSStyleSheet, fontfacerule: Arc<RwLock<FontFaceRule>>) -> CSSFontFaceRule {
CSSFontFaceRule {
cssrule: CSSRule::new_inherited(parent),
fontfacerule: fontfacerule,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet,
fontfacerule: Arc<RwLock<FontFaceRule>>) -> Root<CSSFontFaceRule> {
reflect_dom_object(box CSSFontFaceRule::new_inherited(parent, fontfacerule),
window,
CSSFontFaceRuleBinding::Wrap)
}
}
impl SpecificCSSRule for CSSFontFaceRule {
fn ty(&self) -> u16 {
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
CSSRuleConstants::FONT_FACE_RULE
}
fn get_css(&self) -> DOMString {
// self.fontfacerule.read().to_css_string().into()
"".into()
}
}

View file

@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::cssrule::CSSRule;
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
#[dom_struct]
pub struct CSSGroupingRule {
cssrule: CSSRule,
}
impl CSSGroupingRule {
pub fn new_inherited(parent: &CSSStyleSheet) -> CSSGroupingRule {
CSSGroupingRule {
cssrule: CSSRule::new_inherited(parent),
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet) -> Root<CSSGroupingRule> {
reflect_dom_object(box CSSGroupingRule::new_inherited(parent),
window,
CSSGroupingRuleBinding::Wrap)
}
}

View file

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::cssrule::{CSSRule, SpecificCSSRule};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::stylesheets::KeyframesRule;
#[dom_struct]
pub struct CSSKeyframesRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
keyframesrule: Arc<RwLock<KeyframesRule>>,
}
impl CSSKeyframesRule {
fn new_inherited(parent: &CSSStyleSheet, keyframesrule: Arc<RwLock<KeyframesRule>>) -> CSSKeyframesRule {
CSSKeyframesRule {
cssrule: CSSRule::new_inherited(parent),
keyframesrule: keyframesrule,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet,
keyframesrule: Arc<RwLock<KeyframesRule>>) -> Root<CSSKeyframesRule> {
reflect_dom_object(box CSSKeyframesRule::new_inherited(parent, keyframesrule),
window,
CSSKeyframesRuleBinding::Wrap)
}
}
impl SpecificCSSRule for CSSKeyframesRule {
fn ty(&self) -> u16 {
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
CSSRuleConstants::KEYFRAMES_RULE
}
fn get_css(&self) -> DOMString {
// self.keyframesrule.read().to_css_string().into()
"".into()
}
}

View file

@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSMediaRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::cssgroupingrule::CSSGroupingRule;
use dom::cssrule::SpecificCSSRule;
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::stylesheets::MediaRule;
#[dom_struct]
pub struct CSSMediaRule {
cssrule: CSSGroupingRule,
#[ignore_heap_size_of = "Arc"]
mediarule: Arc<RwLock<MediaRule>>,
}
impl CSSMediaRule {
fn new_inherited(parent: &CSSStyleSheet, mediarule: Arc<RwLock<MediaRule>>) -> CSSMediaRule {
CSSMediaRule {
cssrule: CSSGroupingRule::new_inherited(parent),
mediarule: mediarule,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet,
mediarule: Arc<RwLock<MediaRule>>) -> Root<CSSMediaRule> {
reflect_dom_object(box CSSMediaRule::new_inherited(parent, mediarule),
window,
CSSMediaRuleBinding::Wrap)
}
}
impl SpecificCSSRule for CSSMediaRule {
fn ty(&self) -> u16 {
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
CSSRuleConstants::MEDIA_RULE
}
fn get_css(&self) -> DOMString {
// self.mediarule.read().to_css_string().into()
"".into()
}
}

View file

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSNamespaceRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::cssrule::{CSSRule, SpecificCSSRule};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::stylesheets::NamespaceRule;
#[dom_struct]
pub struct CSSNamespaceRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
namespacerule: Arc<RwLock<NamespaceRule>>,
}
impl CSSNamespaceRule {
fn new_inherited(parent: &CSSStyleSheet, namespacerule: Arc<RwLock<NamespaceRule>>) -> CSSNamespaceRule {
CSSNamespaceRule {
cssrule: CSSRule::new_inherited(parent),
namespacerule: namespacerule,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet,
namespacerule: Arc<RwLock<NamespaceRule>>) -> Root<CSSNamespaceRule> {
reflect_dom_object(box CSSNamespaceRule::new_inherited(parent, namespacerule),
window,
CSSNamespaceRuleBinding::Wrap)
}
}
impl SpecificCSSRule for CSSNamespaceRule {
fn ty(&self) -> u16 {
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
CSSRuleConstants::NAMESPACE_RULE
}
fn get_css(&self) -> DOMString {
// self.namespacerule.read().to_css_string().into()
"".into()
}
}

View file

@ -0,0 +1,103 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSRuleBinding;
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::cssfontfacerule::CSSFontFaceRule;
use dom::csskeyframesrule::CSSKeyframesRule;
use dom::cssmediarule::CSSMediaRule;
use dom::cssnamespacerule::CSSNamespaceRule;
use dom::cssstylerule::CSSStyleRule;
use dom::cssstylesheet::CSSStyleSheet;
use dom::cssviewportrule::CSSViewportRule;
use dom::window::Window;
use style::stylesheets::CssRule as StyleCssRule;
#[dom_struct]
pub struct CSSRule {
reflector_: Reflector,
parent: MutNullableHeap<JS<CSSStyleSheet>>,
}
impl CSSRule {
#[allow(unrooted_must_root)]
pub fn new_inherited(parent: &CSSStyleSheet) -> CSSRule {
CSSRule {
reflector_: Reflector::new(),
parent: MutNullableHeap::new(Some(parent)),
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet) -> Root<CSSRule> {
reflect_dom_object(box CSSRule::new_inherited(parent),
window,
CSSRuleBinding::Wrap)
}
pub fn as_specific(&self) -> &SpecificCSSRule {
if let Some(rule) = self.downcast::<CSSStyleRule>() {
rule as &SpecificCSSRule
} else if let Some(rule) = self.downcast::<CSSFontFaceRule>() {
rule as &SpecificCSSRule
} else if let Some(rule) = self.downcast::<CSSKeyframesRule>() {
rule as &SpecificCSSRule
} else if let Some(rule) = self.downcast::<CSSMediaRule>() {
rule as &SpecificCSSRule
} else if let Some(rule) = self.downcast::<CSSNamespaceRule>() {
rule as &SpecificCSSRule
} else if let Some(rule) = self.downcast::<CSSViewportRule>() {
rule as &SpecificCSSRule
} else {
unreachable!()
}
}
// Given a StyleCssRule, create a new instance of a derived class of
// CSSRule based on which rule it is
pub fn new_specific(window: &Window, parent: &CSSStyleSheet,
rule: StyleCssRule) -> Root<CSSRule> {
// be sure to update the match in as_specific when this is updated
match rule {
StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent, s)),
StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent, s)),
StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent, s)),
StyleCssRule::Media(s) => Root::upcast(CSSMediaRule::new(window, parent, s)),
StyleCssRule::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent, s)),
StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent, s)),
}
}
}
impl CSSRuleMethods for CSSRule {
// https://drafts.csswg.org/cssom/#dom-cssrule-type
fn Type(&self) -> u16 {
self.as_specific().ty()
}
// https://drafts.csswg.org/cssom/#dom-cssrule-parentstylesheet
fn GetParentStyleSheet(&self) -> Option<Root<CSSStyleSheet>> {
self.parent.get()
}
// https://drafts.csswg.org/cssom/#dom-cssrule-csstext
fn CssText(&self) -> DOMString {
self.as_specific().get_css()
}
// https://drafts.csswg.org/cssom/#dom-cssrule-csstext
fn SetCssText(&self, _: DOMString) {
// do nothing
}
}
pub trait SpecificCSSRule {
fn ty(&self) -> u16;
fn get_css(&self) -> DOMString;
}

View file

@ -0,0 +1,67 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSRuleListBinding;
use dom::bindings::codegen::Bindings::CSSRuleListBinding::CSSRuleListMethods;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
use dom::cssrule::CSSRule;
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use style::stylesheets::CssRules;
no_jsmanaged_fields!(CssRules);
#[dom_struct]
pub struct CSSRuleList {
reflector_: Reflector,
sheet: JS<CSSStyleSheet>,
#[ignore_heap_size_of = "Arc"]
rules: CssRules,
dom_rules: Vec<MutNullableHeap<JS<CSSRule>>>
}
impl CSSRuleList {
#[allow(unrooted_must_root)]
pub fn new_inherited(sheet: &CSSStyleSheet, rules: CssRules) -> CSSRuleList {
let dom_rules = rules.0.read().iter().map(|_| MutNullableHeap::new(None)).collect();
CSSRuleList {
reflector_: Reflector::new(),
sheet: JS::from_ref(sheet),
rules: rules,
dom_rules: dom_rules,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, sheet: &CSSStyleSheet, rules: CssRules) -> Root<CSSRuleList> {
reflect_dom_object(box CSSRuleList::new_inherited(sheet, rules),
window,
CSSRuleListBinding::Wrap)
}
}
impl CSSRuleListMethods for CSSRuleList {
// https://drafts.csswg.org/cssom/#ref-for-dom-cssrulelist-item-1
fn Item(&self, idx: u32) -> Option<Root<CSSRule>> {
self.dom_rules.get(idx as usize).map(|rule| {
rule.or_init(|| {
CSSRule::new_specific(self.global().as_window(),
&self.sheet,
self.rules.0.read()[idx as usize].clone())
})
})
}
// https://drafts.csswg.org/cssom/#dom-cssrulelist-length
fn Length(&self) -> u32 {
self.dom_rules.len() as u32
}
// check-tidy: no specs after this line
fn IndexedGetter(&self, index: u32) -> Option<Root<CSSRule>> {
self.Item(index)
}
}

View file

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSStyleRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::cssrule::{CSSRule, SpecificCSSRule};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::stylesheets::StyleRule;
use style_traits::ToCss;
#[dom_struct]
pub struct CSSStyleRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
stylerule: Arc<RwLock<StyleRule>>,
}
impl CSSStyleRule {
fn new_inherited(parent: &CSSStyleSheet, stylerule: Arc<RwLock<StyleRule>>) -> CSSStyleRule {
CSSStyleRule {
cssrule: CSSRule::new_inherited(parent),
stylerule: stylerule,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet,
stylerule: Arc<RwLock<StyleRule>>) -> Root<CSSStyleRule> {
reflect_dom_object(box CSSStyleRule::new_inherited(parent, stylerule),
window,
CSSStyleRuleBinding::Wrap)
}
}
impl SpecificCSSRule for CSSStyleRule {
fn ty(&self) -> u16 {
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
CSSRuleConstants::STYLE_RULE
}
fn get_css(&self) -> DOMString {
self.stylerule.read().to_css_string().into()
}
}

View file

@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding;
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding::CSSStyleSheetMethods;
use dom::bindings::js::{JS, Root, MutNullableHeap};
use dom::bindings::reflector::{reflect_dom_object, Reflectable};
use dom::bindings::str::DOMString;
use dom::cssrulelist::CSSRuleList;
use dom::stylesheet::StyleSheet;
use dom::window::Window;
use std::sync::Arc;
use style::stylesheets::Stylesheet as StyleStyleSheet;
#[dom_struct]
pub struct CSSStyleSheet {
stylesheet: StyleSheet,
rulelist: MutNullableHeap<JS<CSSRuleList>>,
#[ignore_heap_size_of = "Arc"]
style_stylesheet: Arc<StyleStyleSheet>,
}
impl CSSStyleSheet {
fn new_inherited(type_: DOMString, href: Option<DOMString>,
title: Option<DOMString>, stylesheet: Arc<StyleStyleSheet>) -> CSSStyleSheet {
CSSStyleSheet {
stylesheet: StyleSheet::new_inherited(type_, href, title),
rulelist: MutNullableHeap::new(None),
style_stylesheet: stylesheet,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, type_: DOMString,
href: Option<DOMString>,
title: Option<DOMString>,
stylesheet: Arc<StyleStyleSheet>) -> Root<CSSStyleSheet> {
reflect_dom_object(box CSSStyleSheet::new_inherited(type_, href, title, stylesheet),
window,
CSSStyleSheetBinding::Wrap)
}
}
impl CSSStyleSheetMethods for CSSStyleSheet {
// https://drafts.csswg.org/cssom/#dom-cssstylesheet-cssrules
fn CssRules(&self) -> Root<CSSRuleList> {
self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), self, self.style_stylesheet.rules.clone()))
}
}

View file

@ -0,0 +1,50 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::codegen::Bindings::CSSViewportRuleBinding;
use dom::bindings::js::Root;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::str::DOMString;
use dom::cssrule::{CSSRule, SpecificCSSRule};
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
use parking_lot::RwLock;
use std::sync::Arc;
use style::viewport::ViewportRule;
#[dom_struct]
pub struct CSSViewportRule {
cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"]
viewportrule: Arc<RwLock<ViewportRule>>,
}
impl CSSViewportRule {
fn new_inherited(parent: &CSSStyleSheet, viewportrule: Arc<RwLock<ViewportRule>>) -> CSSViewportRule {
CSSViewportRule {
cssrule: CSSRule::new_inherited(parent),
viewportrule: viewportrule,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, parent: &CSSStyleSheet,
viewportrule: Arc<RwLock<ViewportRule>>) -> Root<CSSViewportRule> {
reflect_dom_object(box CSSViewportRule::new_inherited(parent, viewportrule),
window,
CSSViewportRuleBinding::Wrap)
}
}
impl SpecificCSSRule for CSSViewportRule {
fn ty(&self) -> u16 {
use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants;
CSSRuleConstants::VIEWPORT_RULE
}
fn get_css(&self) -> DOMString {
// self.viewportrule.read().to_css_string().into()
"".into()
}
}

View file

@ -59,10 +59,7 @@ use dom::htmlheadelement::HTMLHeadElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmliframeelement::HTMLIFrameElement;
use dom::htmlimageelement::HTMLImageElement;
use dom::htmllinkelement::HTMLLinkElement;
use dom::htmlmetaelement::HTMLMetaElement;
use dom::htmlscriptelement::HTMLScriptElement;
use dom::htmlstyleelement::HTMLStyleElement;
use dom::htmltitleelement::HTMLTitleElement;
use dom::keyboardevent::KeyboardEvent;
use dom::location::Location;
@ -152,10 +149,10 @@ enum ParserBlockedByScript {
#[derive(JSTraceable, HeapSizeOf)]
#[must_root]
struct StylesheetInDocument {
node: JS<Node>,
pub struct StylesheetInDocument {
pub node: JS<Node>,
#[ignore_heap_size_of = "Arc"]
stylesheet: Arc<Stylesheet>,
pub stylesheet: Arc<Stylesheet>,
}
// https://dom.spec.whatwg.org/#document
@ -189,6 +186,7 @@ pub struct Document {
stylesheets: DOMRefCell<Option<Vec<StylesheetInDocument>>>,
/// Whether the list of stylesheets has changed since the last reflow was triggered.
stylesheets_changed_since_reflow: Cell<bool>,
stylesheet_list: MutNullableHeap<JS<StyleSheetList>>,
ready_state: Cell<DocumentReadyState>,
/// Whether the DOMContentLoaded event has already been dispatched.
domcontentloaded_dispatched: Cell<bool>,
@ -1811,6 +1809,7 @@ impl Document {
applets: Default::default(),
stylesheets: DOMRefCell::new(None),
stylesheets_changed_since_reflow: Cell::new(false),
stylesheet_list: MutNullableHeap::new(None),
ready_state: Cell::new(ready_state),
domcontentloaded_dispatched: Cell::new(domcontentloaded_dispatched),
possibly_focused: Default::default(),
@ -1910,35 +1909,37 @@ impl Document {
self.GetDocumentElement().and_then(Root::downcast)
}
/// Returns the list of stylesheets associated with nodes in the document.
pub fn stylesheets(&self) -> Vec<Arc<Stylesheet>> {
{
// Ensure that the stylesheets vector is populated
fn ensure_stylesheets(&self) {
let mut stylesheets = self.stylesheets.borrow_mut();
if stylesheets.is_none() {
*stylesheets = Some(self.upcast::<Node>()
.traverse_preorder()
.filter_map(|node| {
if let Some(node) = node.downcast::<HTMLStyleElement>() {
node.get_stylesheet()
} else if let Some(node) = node.downcast::<HTMLLinkElement>() {
node.get_stylesheet()
} else if let Some(node) = node.downcast::<HTMLMetaElement>() {
node.get_stylesheet()
} else {
None
}.map(|stylesheet| StylesheetInDocument {
.map(|stylesheet| StylesheetInDocument {
node: JS::from_ref(&*node),
stylesheet: stylesheet
stylesheet: stylesheet,
})
})
.collect());
};
}
/// Returns the list of stylesheets associated with nodes in the document.
pub fn stylesheets(&self) -> Vec<Arc<Stylesheet>> {
self.ensure_stylesheets();
self.stylesheets.borrow().as_ref().unwrap().iter()
.map(|s| s.stylesheet.clone())
.collect()
}
pub fn with_style_sheets_in_document<F, T>(&self, mut f: F) -> T
where F: FnMut(&[StylesheetInDocument]) -> T {
self.ensure_stylesheets();
f(&self.stylesheets.borrow().as_ref().unwrap())
}
/// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document
pub fn appropriate_template_contents_owner_document(&self) -> Root<Document> {
self.appropriate_template_contents_owner_document.or_init(|| {
@ -2038,7 +2039,7 @@ impl Element {
impl DocumentMethods for Document {
// https://drafts.csswg.org/cssom/#dom-document-stylesheets
fn StyleSheets(&self) -> Root<StyleSheetList> {
StyleSheetList::new(&self.window, JS::from_ref(&self))
self.stylesheet_list.or_init(|| StyleSheetList::new(&self.window, JS::from_ref(&self)))
}
// https://dom.spec.whatwg.org/#dom-document-implementation

View file

@ -14,6 +14,7 @@ use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::bindings::refcounted::Trusted;
use dom::bindings::reflector::Reflectable;
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
use dom::domtokenlist::DOMTokenList;
use dom::element::{AttributeMutation, Element, ElementCreator};
@ -56,6 +57,7 @@ pub struct HTMLLinkElement {
rel_list: MutNullableHeap<JS<DOMTokenList>>,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
parser_inserted: Cell<bool>,
@ -69,6 +71,7 @@ impl HTMLLinkElement {
rel_list: Default::default(),
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
stylesheet: DOMRefCell::new(None),
cssom_stylesheet: MutNullableHeap::new(None),
}
}
@ -85,6 +88,18 @@ impl HTMLLinkElement {
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
self.stylesheet.borrow().clone()
}
pub fn get_cssom_stylesheet(&self) -> Option<Root<CSSStyleSheet>> {
self.get_stylesheet().map(|sheet| {
self.cssom_stylesheet.or_init(|| {
CSSStyleSheet::new(&window_from_node(self),
"text/css".into(),
None, // todo handle location
None, // todo handle title
sheet)
})
})
}
}
fn get_attr(element: &Element, local_name: &LocalName) -> Option<String> {

View file

@ -8,13 +8,14 @@ use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{Root, RootedReference};
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
use dom::element::{AttributeMutation, Element};
use dom::htmlelement::HTMLElement;
use dom::htmlheadelement::HTMLHeadElement;
use dom::node::{Node, UnbindContext, document_from_node};
use dom::node::{Node, UnbindContext, document_from_node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use html5ever_atoms::LocalName;
use parking_lot::RwLock;
@ -30,6 +31,7 @@ pub struct HTMLMetaElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
}
impl HTMLMetaElement {
@ -39,6 +41,7 @@ impl HTMLMetaElement {
HTMLMetaElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
stylesheet: DOMRefCell::new(None),
cssom_stylesheet: MutNullableHeap::new(None),
}
}
@ -55,6 +58,18 @@ impl HTMLMetaElement {
self.stylesheet.borrow().clone()
}
pub fn get_cssom_stylesheet(&self) -> Option<Root<CSSStyleSheet>> {
self.get_stylesheet().map(|sheet| {
self.cssom_stylesheet.or_init(|| {
CSSStyleSheet::new(&window_from_node(self),
"text/css".into(),
None, // todo handle location
None, // todo handle title
sheet)
})
})
}
fn process_attributes(&self) {
let element = self.upcast::<Element>();
if let Some(name) = element.get_attribute(&ns!(), &local_name!("name")).r() {
@ -81,7 +96,7 @@ impl HTMLMetaElement {
if !content.is_empty() {
if let Some(translated_rule) = ViewportRule::from_meta(&**content) {
*self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
rules: vec![CssRule::Viewport(Arc::new(RwLock::new(translated_rule)))],
rules: vec![CssRule::Viewport(Arc::new(RwLock::new(translated_rule)))].into(),
origin: Origin::Author,
media: Default::default(),
// Viewport constraints are always recomputed on resize; they don't need to

View file

@ -7,8 +7,9 @@ use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HTMLStyleElementBinding;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::Document;
use dom::element::Element;
use dom::htmlelement::HTMLElement;
@ -26,6 +27,7 @@ pub struct HTMLStyleElement {
htmlelement: HTMLElement,
#[ignore_heap_size_of = "Arc"]
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
}
impl HTMLStyleElement {
@ -35,6 +37,7 @@ impl HTMLStyleElement {
HTMLStyleElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
stylesheet: DOMRefCell::new(None),
cssom_stylesheet: MutNullableHeap::new(None),
}
}
@ -77,6 +80,18 @@ impl HTMLStyleElement {
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
self.stylesheet.borrow().clone()
}
pub fn get_cssom_stylesheet(&self) -> Option<Root<CSSStyleSheet>> {
self.get_stylesheet().map(|sheet| {
self.cssom_stylesheet.or_init(|| {
CSSStyleSheet::new(&window_from_node(self),
"text/css".into(),
None, // todo handle location
None, // todo handle title
sheet)
})
})
}
}
impl VirtualMethods for HTMLStyleElement {

View file

@ -242,7 +242,17 @@ pub mod comment;
pub mod console;
pub mod crypto;
pub mod css;
pub mod cssfontfacerule;
pub mod cssgroupingrule;
pub mod csskeyframesrule;
pub mod cssmediarule;
pub mod cssnamespacerule;
pub mod cssrule;
pub mod cssrulelist;
pub mod cssstyledeclaration;
pub mod cssstylerule;
pub mod cssstylesheet;
pub mod cssviewportrule;
pub mod customevent;
pub mod dedicatedworkerglobalscope;
pub mod document;

View file

@ -30,6 +30,7 @@ use dom::bindings::reflector::{Reflectable, reflect_dom_object};
use dom::bindings::str::{DOMString, USVString};
use dom::bindings::xmlname::namespace_from_domstring;
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
use dom::cssstylesheet::CSSStyleSheet;
use dom::document::{Document, DocumentSource, IsHTMLDocument};
use dom::documentfragment::DocumentFragment;
use dom::documenttype::DocumentType;
@ -43,6 +44,9 @@ use dom::htmlelement::HTMLElement;
use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
use dom::htmllinkelement::HTMLLinkElement;
use dom::htmlmetaelement::HTMLMetaElement;
use dom::htmlstyleelement::HTMLStyleElement;
use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers};
use dom::nodelist::NodeList;
use dom::processinginstruction::ProcessingInstruction;
@ -76,8 +80,10 @@ use std::default::Default;
use std::iter;
use std::mem;
use std::ops::Range;
use std::sync::Arc;
use style::dom::OpaqueNode;
use style::selector_impl::ServoSelectorImpl;
use style::stylesheets::Stylesheet;
use style::thread_state;
use url::Url;
use uuid::Uuid;
@ -901,6 +907,30 @@ impl Node {
element.upcast::<Node>().remove_self();
Ok(())
}
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
if let Some(node) = self.downcast::<HTMLStyleElement>() {
node.get_stylesheet()
} else if let Some(node) = self.downcast::<HTMLLinkElement>() {
node.get_stylesheet()
} else if let Some(node) = self.downcast::<HTMLMetaElement>() {
node.get_stylesheet()
} else {
None
}
}
pub fn get_cssom_stylesheet(&self) -> Option<Root<CSSStyleSheet>> {
if let Some(node) = self.downcast::<HTMLStyleElement>() {
node.get_cssom_stylesheet()
} else if let Some(node) = self.downcast::<HTMLLinkElement>() {
node.get_cssom_stylesheet()
} else if let Some(node) = self.downcast::<HTMLMetaElement>() {
node.get_cssom_stylesheet()
} else {
None
}
}
}

View file

@ -20,7 +20,7 @@ pub struct StyleSheet {
impl StyleSheet {
#[allow(unrooted_must_root)]
fn new_inherited(type_: DOMString, href: Option<DOMString>, title: Option<DOMString>) -> StyleSheet {
pub fn new_inherited(type_: DOMString, href: Option<DOMString>, title: Option<DOMString>) -> StyleSheet {
StyleSheet {
reflector_: Reflector::new(),
type_: type_,

View file

@ -35,13 +35,18 @@ impl StyleSheetList {
impl StyleSheetListMethods for StyleSheetList {
// https://drafts.csswg.org/cssom/#dom-stylesheetlist-length
fn Length(&self) -> u32 {
self.document.stylesheets().len() as u32
self.document.with_style_sheets_in_document(|s| s.len() as u32)
}
// https://drafts.csswg.org/cssom/#dom-stylesheetlist-item
fn Item(&self, _index: u32) -> Option<Root<StyleSheet>> {
None
//TODO Create a new StyleSheet object and return it
fn Item(&self, index: u32) -> Option<Root<StyleSheet>> {
// XXXManishearth this doesn't handle the origin clean flag
// and is a cors vulnerability
self.document.with_style_sheets_in_document(|sheets| {
sheets.get(index as usize)
.and_then(|sheet| sheet.node.get_cssom_stylesheet())
.map(Root::upcast)
})
}
// check-tidy: no specs after this line

View file

@ -6,7 +6,7 @@
* http://dev.w3.org/csswg/cssom/#the-css-interface
*/
[Abstract, Exposed=(Window,Worker)]
[Abstract, Exposed=Window]
interface CSS {
[Throws]
static DOMString escape(DOMString ident);

View file

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/css-fonts/#cssfontfacerule
[Exposed=Window]
interface CSSFontFaceRule : CSSRule {
// attribute DOMString family;
// attribute DOMString src;
// attribute DOMString style;
// attribute DOMString weight;
// attribute DOMString stretch;
// attribute DOMString unicodeRange;
// attribute DOMString variant;
// attribute DOMString featureSettings;
};

View file

@ -0,0 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssgroupingrule-interface
[Exposed=Window]
interface CSSGroupingRule : CSSRule {
// [SameObject] readonly attribute CSSRuleList cssRules;
// unsigned long insertRule(DOMString rule, unsigned long index);
// void deleteRule(unsigned long index);
};

View file

@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/css-animations/#interface-csskeyframesrule
[Exposed=Window]
interface CSSKeyframesRule : CSSRule {
// attribute DOMString name;
// readonly attribute CSSRuleList cssRules;
// void appendRule(DOMString rule);
// void deleteRule(DOMString select);
// CSSKeyframeRule? findRule(DOMString select);
};

View file

@ -0,0 +1,9 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssmediarule-interface
[Exposed=Window]
interface CSSMediaRule : CSSGroupingRule {
// [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
};

View file

@ -0,0 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssnamespacerule-interface
[Exposed=Window]
interface CSSNamespaceRule : CSSRule {
// readonly attribute DOMString namespaceURI;
// readonly attribute DOMString prefix;
};

View file

@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssrule-interface
[Exposed=Window]
interface CSSRule {
const unsigned short STYLE_RULE = 1;
const unsigned short CHARSET_RULE = 2; // historical
const unsigned short IMPORT_RULE = 3;
const unsigned short MEDIA_RULE = 4;
const unsigned short FONT_FACE_RULE = 5;
const unsigned short PAGE_RULE = 6;
const unsigned short MARGIN_RULE = 9;
const unsigned short NAMESPACE_RULE = 10;
readonly attribute unsigned short type;
attribute DOMString cssText;
// readonly attribute CSSRule? parentRule;
readonly attribute CSSStyleSheet? parentStyleSheet;
};
// https://drafts.csswg.org/css-animations/#interface-cssrule-idl
partial interface CSSRule {
const unsigned short KEYFRAMES_RULE = 7;
const unsigned short KEYFRAME_RULE = 8;
};
// https://drafts.csswg.org/css-device-adapt/#css-rule-interface
partial interface CSSRule {
const unsigned short VIEWPORT_RULE = 15;
};

View file

@ -0,0 +1,11 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#cssrulelist
// [LegacyArrayClass]
[Exposed=Window]
interface CSSRuleList {
getter CSSRule? item(unsigned long index);
readonly attribute unsigned long length;
};

View file

@ -8,7 +8,7 @@
* Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
*/
[Exposed=(Window,Worker)]
[Exposed=(Window, Worker)]
interface CSSStyleDeclaration {
[SetterThrows]
attribute DOMString cssText;

View file

@ -0,0 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssstylerule-interface
[Exposed=Window]
interface CSSStyleRule : CSSRule {
// attribute DOMString selectorText;
// [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
};

View file

@ -0,0 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-cssstylesheet-interface
[Exposed=Window]
interface CSSStyleSheet : StyleSheet {
// readonly attribute CSSRule? ownerRule;
[SameObject] readonly attribute CSSRuleList cssRules;
// unsigned long insertRule(DOMString rule, unsigned long index);
// void deleteRule(unsigned long index);
};

View file

@ -0,0 +1,9 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/css-device-adapt/#css-viewport-rule-interface
[Exposed=Window]
interface CSSViewportRule : CSSRule {
// readonly attribute CSSStyleDeclaration style;
};

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// https://drafts.csswg.org/cssom/#the-stylesheet-interface
[Exposed=(Window,Worker)]
[Exposed=Window]
interface StyleSheet {
readonly attribute DOMString type_;
readonly attribute DOMString? href;

View file

@ -4,7 +4,7 @@
// https://drafts.csswg.org/cssom/#the-stylesheetlist-interface
// [ArrayClass]
[Exposed=(Window,Worker)]
[Exposed=Window]
interface StyleSheetList {
getter StyleSheet? item(unsigned long index);
readonly attribute unsigned long length;

View file

@ -388,7 +388,7 @@ impl Stylist {
false
}
self.is_device_dirty |= stylesheets.iter().any(|stylesheet| {
mq_eval_changed(&stylesheet.rules, &self.device, &device)
mq_eval_changed(&stylesheet.rules.0.read(), &self.device, &device)
});
self.device = device;

View file

@ -7,6 +7,7 @@
use {Atom, Prefix, Namespace};
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes};
use cssparser::{AtRuleType, RuleListParser, Token};
use cssparser::ToCss as ParserToCss;
use encoding::EncodingRef;
use error_reporting::ParseErrorReporter;
use font_face::{FontFaceRule, parse_font_face_block};
@ -18,7 +19,9 @@ use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selector_impl::TheSelectorImpl;
use selectors::parser::{Selector, parse_selector_list};
use std::cell::Cell;
use std::fmt;
use std::sync::Arc;
use style_traits::ToCss;
use url::Url;
use viewport::ViewportRule;
@ -39,12 +42,20 @@ pub enum Origin {
User,
}
#[derive(Debug, Clone)]
pub struct CssRules(pub Arc<RwLock<Vec<CssRule>>>);
impl From<Vec<CssRule>> for CssRules {
fn from(other: Vec<CssRule>) -> Self {
CssRules(Arc::new(RwLock::new(other)))
}
}
#[derive(Debug)]
pub struct Stylesheet {
/// List of rules in the order they were found (important for
/// cascading order)
pub rules: Vec<CssRule>,
pub rules: CssRules,
/// List of media associated with the Stylesheet.
pub media: MediaList,
pub origin: Origin,
@ -59,7 +70,7 @@ pub struct UserAgentStylesheets {
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum CssRule {
// No Charset here, CSSCharsetRule has been removed from CSSOM
// https://drafts.csswg.org/cssom/#changes-from-5-december-2013
@ -89,7 +100,8 @@ impl CssRule {
CssRule::Media(ref lock) => {
let media_rule = lock.read();
let mq = media_rule.media_queries.read();
f(&media_rule.rules, Some(&mq))
let rules = media_rule.rules.0.read();
f(&rules, Some(&mq))
}
}
}
@ -112,7 +124,7 @@ pub struct KeyframesRule {
#[derive(Debug)]
pub struct MediaRule {
pub media_queries: Arc<RwLock<MediaList>>,
pub rules: Vec<CssRule>,
pub rules: CssRules,
}
#[derive(Debug)]
@ -121,6 +133,41 @@ pub struct StyleRule {
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
}
impl StyleRule {
/// Serialize the group of selectors for this rule.
///
/// https://drafts.csswg.org/cssom/#serialize-a-group-of-selectors
pub fn selectors_to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
let mut iter = self.selectors.iter();
try!(iter.next().unwrap().to_css(dest));
for selector in iter {
try!(write!(dest, ", "));
try!(selector.to_css(dest));
}
Ok(())
}
}
impl ToCss for StyleRule {
// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
// Step 1
try!(self.selectors_to_css(dest));
// Step 2
try!(dest.write_str(" { "));
// Step 3
let declaration_block = self.block.read();
try!(declaration_block.to_css(dest));
// Step 4
if declaration_block.declarations.len() > 0 {
try!(write!(dest, " "));
}
// Step 5
try!(dest.write_str("}"));
Ok(())
}
}
impl Stylesheet {
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
@ -180,7 +227,7 @@ impl Stylesheet {
Stylesheet {
origin: origin,
rules: rules,
rules: rules.into(),
media: Default::default(),
dirty_on_viewport_size_change:
input.seen_viewport_percentages(),
@ -208,7 +255,7 @@ impl Stylesheet {
/// examined.
#[inline]
pub fn effective_rules<F>(&self, device: &Device, mut f: F) where F: FnMut(&CssRule) {
effective_rules(&self.rules, device, &mut f);
effective_rules(&self.rules.0.read(), device, &mut f);
}
}
@ -251,7 +298,7 @@ rule_filter! {
effective_keyframes_rules(Keyframes => KeyframesRule),
}
fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CssRule> {
fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> CssRules {
let mut iter = RuleListParser::new_for_nested_rule(input,
NestedRuleParser { context: context });
let mut rules = Vec::new();
@ -265,7 +312,7 @@ fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CssRul
}
}
}
rules
rules.into()
}

View file

@ -255,7 +255,7 @@ pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorr
#[no_mangle]
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
!Stylesheet::as_arc(&raw_sheet).rules.is_empty()
!Stylesheet::as_arc(&raw_sheet).rules.0.read().is_empty()
}
#[no_mangle]

View file

@ -63,7 +63,7 @@ WEBIDL_STANDARDS = [
"//dvcs.w3.org/hg",
"//dom.spec.whatwg.org",
"//domparsing.spec.whatwg.org",
"//drafts.csswg.org/cssom",
"//drafts.csswg.org",
"//drafts.fxtf.org",
"//encoding.spec.whatwg.org",
"//fetch.spec.whatwg.org",

View file

@ -29,7 +29,7 @@ fn test_media_rule<F>(css: &str, callback: F) where F: Fn(&MediaList, &str) {
let stylesheet = Stylesheet::from_str(css, url, Origin::Author, Box::new(CSSErrorReporterTest),
ParserContextExtraData::default());
let mut rule_count = 0;
media_queries(&stylesheet.rules, &mut |mq| {
media_queries(&stylesheet.rules.0.read(), &mut |mq| {
rule_count += 1;
callback(mq, css);
});

View file

@ -256,7 +256,7 @@ fn test_parse_stylesheet() {
]
})))
],
].into(),
};
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));

View file

@ -1,2 +1,3 @@
[test_pref_reset.html]
type: testharness
prefs: [@Reset]

View file

@ -1,3 +1,4 @@
[test_pref_set.html]
type: testharness
prefs: ["browser.display.foreground_color:#00FF00",
"browser.display.background_color:#000000"]

View file

@ -1,2 +1,3 @@
[testharness_1.html]
type: testharness
disabled: @False

View file

@ -1,4 +1,5 @@
tags: [file-tag]
[testharness_0.html]
type: testharness
tags: [test-tag]

View file

@ -1,2 +1,3 @@
[testharness_0.html]
type: testharness
tags: [test-1-tag]

View file

@ -1,4 +1,5 @@
tags: [file-tag]
[testharness_2.html]
type: testharness
tags: [test-2-tag, @Reset]

View file

@ -2,6 +2,7 @@
type: testharness
[changing transition-property / values]
expected: FAIL
[changing transition-duration / values]
expected: FAIL

View file

@ -1,2 +1,3 @@
[color-applies-to-014.htm]
disabled: https://github.com/servo/servo/pull/13870#issuecomment-255507790
type: reftest
disabled: https://github.com/servo/servo/pull/13870

View file

@ -1,3 +1,8 @@
[index-003.htm]
type: testharness
expected: ERROR
[@import rule is expected to be @import url("main.css")]
expected: FAIL
[page rule is expected to be @page :first]
expected: FAIL

View file

@ -117,24 +117,9 @@
[StyleSheet interface: attribute disabled]
expected: FAIL
[CSSStyleSheet interface: existence and properties of interface object]
expected: FAIL
[CSSStyleSheet interface object length]
expected: FAIL
[CSSStyleSheet interface: existence and properties of interface prototype object]
expected: FAIL
[CSSStyleSheet interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSStyleSheet interface: attribute ownerRule]
expected: FAIL
[CSSStyleSheet interface: attribute cssRules]
expected: FAIL
[CSSStyleSheet interface: operation insertRule(DOMString,unsigned long)]
expected: FAIL
@ -189,24 +174,9 @@
[StyleSheetList interface: existence and properties of interface prototype object]
expected: FAIL
[CSSRuleList interface: existence and properties of interface object]
expected: FAIL
[CSSRuleList interface object length]
expected: FAIL
[CSSRuleList interface: existence and properties of interface prototype object]
expected: FAIL
[CSSRuleList interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSRuleList interface: operation item(unsigned long)]
expected: FAIL
[CSSRuleList interface: attribute length]
expected: FAIL
[CSSRuleList must be primary interface of style_element.sheet.cssRules]
expected: FAIL
@ -222,90 +192,9 @@
[CSSRuleList interface: style_element.sheet.cssRules must inherit property "length" with the proper type (1)]
expected: FAIL
[CSSRule interface: existence and properties of interface object]
expected: FAIL
[CSSRule interface object length]
expected: FAIL
[CSSRule interface: existence and properties of interface prototype object]
expected: FAIL
[CSSRule interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSRule interface: constant STYLE_RULE on interface object]
expected: FAIL
[CSSRule interface: constant STYLE_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant CHARSET_RULE on interface object]
expected: FAIL
[CSSRule interface: constant CHARSET_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant IMPORT_RULE on interface object]
expected: FAIL
[CSSRule interface: constant IMPORT_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant MEDIA_RULE on interface object]
expected: FAIL
[CSSRule interface: constant MEDIA_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant FONT_FACE_RULE on interface object]
expected: FAIL
[CSSRule interface: constant FONT_FACE_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant PAGE_RULE on interface object]
expected: FAIL
[CSSRule interface: constant PAGE_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant MARGIN_RULE on interface object]
expected: FAIL
[CSSRule interface: constant MARGIN_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: constant NAMESPACE_RULE on interface object]
expected: FAIL
[CSSRule interface: constant NAMESPACE_RULE on interface prototype object]
expected: FAIL
[CSSRule interface: attribute type]
expected: FAIL
[CSSRule interface: attribute cssText]
expected: FAIL
[CSSRule interface: attribute parentRule]
expected: FAIL
[CSSRule interface: attribute parentStyleSheet]
expected: FAIL
[CSSStyleRule interface: existence and properties of interface object]
expected: FAIL
[CSSStyleRule interface object length]
expected: FAIL
[CSSStyleRule interface: existence and properties of interface prototype object]
expected: FAIL
[CSSStyleRule interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSStyleRule interface: attribute selectorText]
expected: FAIL
@ -381,18 +270,6 @@
[CSSImportRule interface: attribute styleSheet]
expected: FAIL
[CSSGroupingRule interface: existence and properties of interface object]
expected: FAIL
[CSSGroupingRule interface object length]
expected: FAIL
[CSSGroupingRule interface: existence and properties of interface prototype object]
expected: FAIL
[CSSGroupingRule interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSGroupingRule interface: attribute cssRules]
expected: FAIL
@ -402,18 +279,6 @@
[CSSGroupingRule interface: operation deleteRule(unsigned long)]
expected: FAIL
[CSSMediaRule interface: existence and properties of interface object]
expected: FAIL
[CSSMediaRule interface object length]
expected: FAIL
[CSSMediaRule interface: existence and properties of interface prototype object]
expected: FAIL
[CSSMediaRule interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSMediaRule interface: attribute media]
expected: FAIL
@ -453,18 +318,6 @@
[CSSMarginRule interface: attribute style]
expected: FAIL
[CSSNamespaceRule interface: existence and properties of interface object]
expected: FAIL
[CSSNamespaceRule interface object length]
expected: FAIL
[CSSNamespaceRule interface: existence and properties of interface prototype object]
expected: FAIL
[CSSNamespaceRule interface: existence and properties of interface prototype object's "constructor" property]
expected: FAIL
[CSSNamespaceRule interface: attribute namespaceURI]
expected: FAIL

View file

@ -17,3 +17,4 @@
[test skewY()]
expected: FAIL

View file

@ -1,6 +1,5 @@
[DOMMatrix-001.xht]
type: testharness
[testConstructor1]
expected: FAIL

View file

@ -17,3 +17,4 @@
[test skewY()]
expected: FAIL

View file

@ -1,6 +1,5 @@
[DOMMatrix-001.xht]
type: testharness
[testConstructor1]
expected: FAIL

View file

@ -17,3 +17,4 @@
[test skewY()]
expected: FAIL

View file

@ -1,2 +1,3 @@
[basic-transition.html]
type: reftest
disabled: https://github.com/servo/servo/issues/13865

View file

@ -0,0 +1,4 @@
[inline_block_opacity_change.html]
type: reftest
expected: PASS
disabled: https://github.com/servo/servo/issues/13360

View file

@ -20,7 +20,17 @@ test_interfaces([
"CharacterData",
"CloseEvent",
"CSS",
"CSSFontFaceRule",
"CSSGroupingRule",
"CSSKeyframesRule",
"CSSMediaRule",
"CSSNamespaceRule",
"CSSRule",
"CSSRuleList",
"CSSStyleDeclaration",
"CSSStyleRule",
"CSSStyleSheet",
"CSSViewportRule",
"DOMMatrix",
"DOMMatrixReadOnly",
"DOMPoint",

View file

@ -10,7 +10,6 @@ test_interfaces([
"BeforeUnloadEvent",
"Blob",
"CloseEvent",
"CSS",
"CSSStyleDeclaration",
"DOMPoint",
"DOMPointReadOnly",
@ -50,8 +49,6 @@ test_interfaces([
"Screen",
"Storage",
"StorageEvent",
"StyleSheet",
"StyleSheetList",
"TextDecoder",
"TextEncoder",
"URL",