servo: Merge #14340 - implement StyleSheet.disabled (from heycam:sheet-disabled); r=Manishearth

<!-- Please describe your changes on the following line: -->

This implements the [CSSOM StyleSheet.disabled](https://drafts.csswg.org/cssom/#dom-stylesheet-disabled) IDL attribute.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: c1c3974fb2d8ca60f2837ccd7d2d3b345e440af8
This commit is contained in:
Cameron McCormack 2016-11-24 20:40:24 -08:00
Родитель 43830e4013
Коммит 7b5d5ddcea
9 изменённых файлов: 62 добавлений и 10 удалений

Просмотреть файл

@ -4,11 +4,13 @@
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding;
use dom::bindings::codegen::Bindings::CSSStyleSheetBinding::CSSStyleSheetMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::js::{JS, Root, MutNullableHeap};
use dom::bindings::reflector::{reflect_dom_object, Reflectable};
use dom::bindings::str::DOMString;
use dom::cssrulelist::{CSSRuleList, RulesSource};
use dom::element::Element;
use dom::stylesheet::StyleSheet;
use dom::window::Window;
use std::sync::Arc;
@ -17,27 +19,34 @@ use style::stylesheets::Stylesheet as StyleStyleSheet;
#[dom_struct]
pub struct CSSStyleSheet {
stylesheet: StyleSheet,
owner: JS<Element>,
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 {
fn new_inherited(owner: &Element,
type_: DOMString,
href: Option<DOMString>,
title: Option<DOMString>,
stylesheet: Arc<StyleStyleSheet>) -> CSSStyleSheet {
CSSStyleSheet {
stylesheet: StyleSheet::new_inherited(type_, href, title),
owner: JS::from_ref(owner),
rulelist: MutNullableHeap::new(None),
style_stylesheet: stylesheet,
}
}
#[allow(unrooted_must_root)]
pub fn new(window: &Window, type_: DOMString,
pub fn new(window: &Window,
owner: &Element,
type_: DOMString,
href: Option<DOMString>,
title: Option<DOMString>,
stylesheet: Arc<StyleStyleSheet>) -> Root<CSSStyleSheet> {
reflect_dom_object(box CSSStyleSheet::new_inherited(type_, href, title, stylesheet),
reflect_dom_object(box CSSStyleSheet::new_inherited(owner, type_, href, title, stylesheet),
window,
CSSStyleSheetBinding::Wrap)
}
@ -48,6 +57,16 @@ impl CSSStyleSheet {
RulesSource::Rules(self.style_stylesheet
.rules.clone())))
}
pub fn disabled(&self) -> bool {
self.style_stylesheet.disabled()
}
pub fn set_disabled(&self, disabled: bool) {
if self.style_stylesheet.set_disabled(disabled) {
self.global().as_window().Document().invalidate_stylesheets();
}
}
}
impl CSSStyleSheetMethods for CSSStyleSheet {

Просмотреть файл

@ -94,6 +94,7 @@ impl HTMLLinkElement {
self.get_stylesheet().map(|sheet| {
self.cssom_stylesheet.or_init(|| {
CSSStyleSheet::new(&window_from_node(self),
self.upcast::<Element>(),
"text/css".into(),
None, // todo handle location
None, // todo handle title

Просмотреть файл

@ -63,6 +63,7 @@ impl HTMLMetaElement {
self.get_stylesheet().map(|sheet| {
self.cssom_stylesheet.or_init(|| {
CSSStyleSheet::new(&window_from_node(self),
self.upcast::<Element>(),
"text/css".into(),
None, // todo handle location
None, // todo handle title
@ -103,6 +104,7 @@ impl HTMLMetaElement {
// Viewport constraints are always recomputed on resize; they don't need to
// force all styles to be recomputed.
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
}));
let doc = document_from_node(self);
doc.invalidate_stylesheets();

Просмотреть файл

@ -86,6 +86,7 @@ impl HTMLStyleElement {
self.get_stylesheet().map(|sheet| {
self.cssom_stylesheet.or_init(|| {
CSSStyleSheet::new(&window_from_node(self),
self.upcast::<Element>(),
"text/css".into(),
None, // todo handle location
None, // todo handle title

Просмотреть файл

@ -4,12 +4,13 @@
use dom::bindings::codegen::Bindings::StyleSheetBinding;
use dom::bindings::codegen::Bindings::StyleSheetBinding::StyleSheetMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
use dom::cssstylesheet::CSSStyleSheet;
use dom::window::Window;
#[dom_struct]
pub struct StyleSheet {
reflector_: Reflector,
@ -20,12 +21,14 @@ pub struct StyleSheet {
impl StyleSheet {
#[allow(unrooted_must_root)]
pub 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_,
href: href,
title: title
title: title,
}
}
@ -55,5 +58,14 @@ impl StyleSheetMethods for StyleSheet {
fn GetTitle(&self) -> Option<DOMString> {
self.title.clone()
}
}
// https://drafts.csswg.org/cssom/#dom-stylesheet-disabled
fn Disabled(&self) -> bool {
self.downcast::<CSSStyleSheet>().unwrap().disabled()
}
// https://drafts.csswg.org/cssom/#dom-stylesheet-disabled
fn SetDisabled(&self, disabled: bool) {
self.downcast::<CSSStyleSheet>().unwrap().set_disabled(disabled)
}
}

Просмотреть файл

@ -13,7 +13,7 @@ interface StyleSheet {
readonly attribute DOMString? title;
// [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
// attribute boolean disabled;
attribute boolean disabled;
};
// https://drafts.csswg.org/cssom/#the-linkstyle-interface

Просмотреть файл

@ -113,6 +113,7 @@ pub struct Stylesheet {
pub media: Arc<RwLock<MediaList>>,
pub origin: Origin,
pub dirty_on_viewport_size_change: AtomicBool,
pub disabled: AtomicBool,
}
@ -402,6 +403,7 @@ impl Stylesheet {
rules: rules.into(),
media: Arc::new(RwLock::new(media)),
dirty_on_viewport_size_change: AtomicBool::new(input.seen_viewport_percentages()),
disabled: AtomicBool::new(false),
}
}
@ -442,6 +444,20 @@ impl Stylesheet {
pub fn effective_rules<F>(&self, device: &Device, mut f: F) where F: FnMut(&CssRule) {
effective_rules(&self.rules.0.read(), device, &mut f);
}
/// Returns whether the stylesheet has been explicitly disabled through the CSSOM.
pub fn disabled(&self) -> bool {
self.disabled.load(Ordering::SeqCst)
}
/// Records that the stylesheet has been explicitly disabled through the CSSOM.
/// Returns whether the the call resulted in a change in disabled state.
///
/// Disabled stylesheets remain in the document, but their rules are not added to
/// the Stylist.
pub fn set_disabled(&self, disabled: bool) -> bool {
self.disabled.swap(disabled, Ordering::SeqCst) != disabled
}
}
fn effective_rules<F>(rules: &[CssRule], device: &Device, f: &mut F) where F: FnMut(&CssRule) {

Просмотреть файл

@ -169,7 +169,7 @@ impl Stylist {
}
fn add_stylesheet(&mut self, stylesheet: &Stylesheet) {
if !stylesheet.is_effective_for_device(&self.device) {
if stylesheet.disabled() || !stylesheet.is_effective_for_device(&self.device) {
return;
}

Просмотреть файл

@ -57,6 +57,7 @@ fn test_parse_stylesheet() {
origin: Origin::UserAgent,
media: Default::default(),
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
rules: vec![
CssRule::Namespace(Arc::new(RwLock::new(NamespaceRule {
prefix: None,