mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Support basic immutable CSSOM
This commit is contained in:
parent
2220fcdc0b
commit
177d6fa4ee
33 changed files with 861 additions and 43 deletions
50
components/script/dom/cssfontfacerule.rs
Normal file
50
components/script/dom/cssfontfacerule.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
30
components/script/dom/cssgroupingrule.rs
Normal file
30
components/script/dom/cssgroupingrule.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
50
components/script/dom/csskeyframesrule.rs
Normal file
50
components/script/dom/csskeyframesrule.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
51
components/script/dom/cssmediarule.rs
Normal file
51
components/script/dom/cssmediarule.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
50
components/script/dom/cssnamespacerule.rs
Normal file
50
components/script/dom/cssnamespacerule.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
103
components/script/dom/cssrule.rs
Normal file
103
components/script/dom/cssrule.rs
Normal 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;
|
||||||
|
}
|
67
components/script/dom/cssrulelist.rs
Normal file
67
components/script/dom/cssrulelist.rs
Normal 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.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[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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
50
components/script/dom/cssstylerule.rs
Normal file
50
components/script/dom/cssstylerule.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
51
components/script/dom/cssstylesheet.rs
Normal file
51
components/script/dom/cssstylesheet.rs
Normal 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()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
50
components/script/dom/cssviewportrule.rs
Normal file
50
components/script/dom/cssviewportrule.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,10 +59,7 @@ use dom::htmlheadelement::HTMLHeadElement;
|
||||||
use dom::htmlhtmlelement::HTMLHtmlElement;
|
use dom::htmlhtmlelement::HTMLHtmlElement;
|
||||||
use dom::htmliframeelement::HTMLIFrameElement;
|
use dom::htmliframeelement::HTMLIFrameElement;
|
||||||
use dom::htmlimageelement::HTMLImageElement;
|
use dom::htmlimageelement::HTMLImageElement;
|
||||||
use dom::htmllinkelement::HTMLLinkElement;
|
|
||||||
use dom::htmlmetaelement::HTMLMetaElement;
|
|
||||||
use dom::htmlscriptelement::HTMLScriptElement;
|
use dom::htmlscriptelement::HTMLScriptElement;
|
||||||
use dom::htmlstyleelement::HTMLStyleElement;
|
|
||||||
use dom::htmltitleelement::HTMLTitleElement;
|
use dom::htmltitleelement::HTMLTitleElement;
|
||||||
use dom::keyboardevent::KeyboardEvent;
|
use dom::keyboardevent::KeyboardEvent;
|
||||||
use dom::location::Location;
|
use dom::location::Location;
|
||||||
|
@ -152,10 +149,10 @@ enum ParserBlockedByScript {
|
||||||
|
|
||||||
#[derive(JSTraceable, HeapSizeOf)]
|
#[derive(JSTraceable, HeapSizeOf)]
|
||||||
#[must_root]
|
#[must_root]
|
||||||
struct StylesheetInDocument {
|
pub struct StylesheetInDocument {
|
||||||
node: JS<Node>,
|
pub node: JS<Node>,
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
stylesheet: Arc<Stylesheet>,
|
pub stylesheet: Arc<Stylesheet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#document
|
// https://dom.spec.whatwg.org/#document
|
||||||
|
@ -189,6 +186,7 @@ pub struct Document {
|
||||||
stylesheets: DOMRefCell<Option<Vec<StylesheetInDocument>>>,
|
stylesheets: DOMRefCell<Option<Vec<StylesheetInDocument>>>,
|
||||||
/// Whether the list of stylesheets has changed since the last reflow was triggered.
|
/// Whether the list of stylesheets has changed since the last reflow was triggered.
|
||||||
stylesheets_changed_since_reflow: Cell<bool>,
|
stylesheets_changed_since_reflow: Cell<bool>,
|
||||||
|
stylesheet_list: MutNullableHeap<JS<StyleSheetList>>,
|
||||||
ready_state: Cell<DocumentReadyState>,
|
ready_state: Cell<DocumentReadyState>,
|
||||||
/// Whether the DOMContentLoaded event has already been dispatched.
|
/// Whether the DOMContentLoaded event has already been dispatched.
|
||||||
domcontentloaded_dispatched: Cell<bool>,
|
domcontentloaded_dispatched: Cell<bool>,
|
||||||
|
@ -1811,6 +1809,7 @@ impl Document {
|
||||||
applets: Default::default(),
|
applets: Default::default(),
|
||||||
stylesheets: DOMRefCell::new(None),
|
stylesheets: DOMRefCell::new(None),
|
||||||
stylesheets_changed_since_reflow: Cell::new(false),
|
stylesheets_changed_since_reflow: Cell::new(false),
|
||||||
|
stylesheet_list: MutNullableHeap::new(None),
|
||||||
ready_state: Cell::new(ready_state),
|
ready_state: Cell::new(ready_state),
|
||||||
domcontentloaded_dispatched: Cell::new(domcontentloaded_dispatched),
|
domcontentloaded_dispatched: Cell::new(domcontentloaded_dispatched),
|
||||||
possibly_focused: Default::default(),
|
possibly_focused: Default::default(),
|
||||||
|
@ -1910,35 +1909,37 @@ impl Document {
|
||||||
self.GetDocumentElement().and_then(Root::downcast)
|
self.GetDocumentElement().and_then(Root::downcast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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| {
|
||||||
|
node.get_stylesheet()
|
||||||
|
.map(|stylesheet| StylesheetInDocument {
|
||||||
|
node: JS::from_ref(&*node),
|
||||||
|
stylesheet: stylesheet,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect());
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the list of stylesheets associated with nodes in the document.
|
/// Returns the list of stylesheets associated with nodes in the document.
|
||||||
pub fn stylesheets(&self) -> Vec<Arc<Stylesheet>> {
|
pub fn stylesheets(&self) -> Vec<Arc<Stylesheet>> {
|
||||||
{
|
self.ensure_stylesheets();
|
||||||
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 {
|
|
||||||
node: JS::from_ref(&*node),
|
|
||||||
stylesheet: stylesheet
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
self.stylesheets.borrow().as_ref().unwrap().iter()
|
self.stylesheets.borrow().as_ref().unwrap().iter()
|
||||||
.map(|s| s.stylesheet.clone())
|
.map(|s| s.stylesheet.clone())
|
||||||
.collect()
|
.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
|
/// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document
|
||||||
pub fn appropriate_template_contents_owner_document(&self) -> Root<Document> {
|
pub fn appropriate_template_contents_owner_document(&self) -> Root<Document> {
|
||||||
self.appropriate_template_contents_owner_document.or_init(|| {
|
self.appropriate_template_contents_owner_document.or_init(|| {
|
||||||
|
@ -2038,7 +2039,7 @@ impl Element {
|
||||||
impl DocumentMethods for Document {
|
impl DocumentMethods for Document {
|
||||||
// https://drafts.csswg.org/cssom/#dom-document-stylesheets
|
// https://drafts.csswg.org/cssom/#dom-document-stylesheets
|
||||||
fn StyleSheets(&self) -> Root<StyleSheetList> {
|
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
|
// https://dom.spec.whatwg.org/#dom-document-implementation
|
||||||
|
|
|
@ -14,6 +14,7 @@ use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
||||||
use dom::bindings::refcounted::Trusted;
|
use dom::bindings::refcounted::Trusted;
|
||||||
use dom::bindings::reflector::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
|
use dom::cssstylesheet::CSSStyleSheet;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::domtokenlist::DOMTokenList;
|
use dom::domtokenlist::DOMTokenList;
|
||||||
use dom::element::{AttributeMutation, Element, ElementCreator};
|
use dom::element::{AttributeMutation, Element, ElementCreator};
|
||||||
|
@ -56,6 +57,7 @@ pub struct HTMLLinkElement {
|
||||||
rel_list: MutNullableHeap<JS<DOMTokenList>>,
|
rel_list: MutNullableHeap<JS<DOMTokenList>>,
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
||||||
|
cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
|
||||||
|
|
||||||
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
|
/// https://html.spec.whatwg.org/multipage/#a-style-sheet-that-is-blocking-scripts
|
||||||
parser_inserted: Cell<bool>,
|
parser_inserted: Cell<bool>,
|
||||||
|
@ -69,6 +71,7 @@ impl HTMLLinkElement {
|
||||||
rel_list: Default::default(),
|
rel_list: Default::default(),
|
||||||
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
|
parser_inserted: Cell::new(creator == ElementCreator::ParserCreated),
|
||||||
stylesheet: DOMRefCell::new(None),
|
stylesheet: DOMRefCell::new(None),
|
||||||
|
cssom_stylesheet: MutNullableHeap::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +88,18 @@ impl HTMLLinkElement {
|
||||||
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
|
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
|
||||||
self.stylesheet.borrow().clone()
|
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> {
|
fn get_attr(element: &Element, local_name: &LocalName) -> Option<String> {
|
||||||
|
|
|
@ -8,13 +8,14 @@ use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
|
||||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
use dom::bindings::inheritance::Castable;
|
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::bindings::str::DOMString;
|
||||||
|
use dom::cssstylesheet::CSSStyleSheet;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeMutation, Element};
|
use dom::element::{AttributeMutation, Element};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmlheadelement::HTMLHeadElement;
|
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 dom::virtualmethods::VirtualMethods;
|
||||||
use html5ever_atoms::LocalName;
|
use html5ever_atoms::LocalName;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -30,6 +31,7 @@ pub struct HTMLMetaElement {
|
||||||
htmlelement: HTMLElement,
|
htmlelement: HTMLElement,
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
||||||
|
cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLMetaElement {
|
impl HTMLMetaElement {
|
||||||
|
@ -39,6 +41,7 @@ impl HTMLMetaElement {
|
||||||
HTMLMetaElement {
|
HTMLMetaElement {
|
||||||
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
||||||
stylesheet: DOMRefCell::new(None),
|
stylesheet: DOMRefCell::new(None),
|
||||||
|
cssom_stylesheet: MutNullableHeap::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +58,18 @@ impl HTMLMetaElement {
|
||||||
self.stylesheet.borrow().clone()
|
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) {
|
fn process_attributes(&self) {
|
||||||
let element = self.upcast::<Element>();
|
let element = self.upcast::<Element>();
|
||||||
if let Some(name) = element.get_attribute(&ns!(), &local_name!("name")).r() {
|
if let Some(name) = element.get_attribute(&ns!(), &local_name!("name")).r() {
|
||||||
|
|
|
@ -7,8 +7,9 @@ use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::HTMLStyleElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLStyleElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||||
use dom::bindings::inheritance::Castable;
|
use dom::bindings::inheritance::Castable;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
|
use dom::cssstylesheet::CSSStyleSheet;
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::Element;
|
use dom::element::Element;
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
|
@ -26,6 +27,7 @@ pub struct HTMLStyleElement {
|
||||||
htmlelement: HTMLElement,
|
htmlelement: HTMLElement,
|
||||||
#[ignore_heap_size_of = "Arc"]
|
#[ignore_heap_size_of = "Arc"]
|
||||||
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
|
||||||
|
cssom_stylesheet: MutNullableHeap<JS<CSSStyleSheet>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLStyleElement {
|
impl HTMLStyleElement {
|
||||||
|
@ -35,6 +37,7 @@ impl HTMLStyleElement {
|
||||||
HTMLStyleElement {
|
HTMLStyleElement {
|
||||||
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
|
||||||
stylesheet: DOMRefCell::new(None),
|
stylesheet: DOMRefCell::new(None),
|
||||||
|
cssom_stylesheet: MutNullableHeap::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +80,18 @@ impl HTMLStyleElement {
|
||||||
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
|
pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
|
||||||
self.stylesheet.borrow().clone()
|
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 {
|
impl VirtualMethods for HTMLStyleElement {
|
||||||
|
|
|
@ -242,7 +242,17 @@ pub mod comment;
|
||||||
pub mod console;
|
pub mod console;
|
||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
pub mod css;
|
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 cssstyledeclaration;
|
||||||
|
pub mod cssstylerule;
|
||||||
|
pub mod cssstylesheet;
|
||||||
|
pub mod cssviewportrule;
|
||||||
pub mod customevent;
|
pub mod customevent;
|
||||||
pub mod dedicatedworkerglobalscope;
|
pub mod dedicatedworkerglobalscope;
|
||||||
pub mod document;
|
pub mod document;
|
||||||
|
|
|
@ -30,6 +30,7 @@ use dom::bindings::reflector::{Reflectable, reflect_dom_object};
|
||||||
use dom::bindings::str::{DOMString, USVString};
|
use dom::bindings::str::{DOMString, USVString};
|
||||||
use dom::bindings::xmlname::namespace_from_domstring;
|
use dom::bindings::xmlname::namespace_from_domstring;
|
||||||
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
|
use dom::characterdata::{CharacterData, LayoutCharacterDataHelpers};
|
||||||
|
use dom::cssstylesheet::CSSStyleSheet;
|
||||||
use dom::document::{Document, DocumentSource, IsHTMLDocument};
|
use dom::document::{Document, DocumentSource, IsHTMLDocument};
|
||||||
use dom::documentfragment::DocumentFragment;
|
use dom::documentfragment::DocumentFragment;
|
||||||
use dom::documenttype::DocumentType;
|
use dom::documenttype::DocumentType;
|
||||||
|
@ -43,6 +44,9 @@ use dom::htmlelement::HTMLElement;
|
||||||
use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
|
use dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
|
||||||
use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
|
use dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
|
||||||
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
use dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
|
||||||
|
use dom::htmllinkelement::HTMLLinkElement;
|
||||||
|
use dom::htmlmetaelement::HTMLMetaElement;
|
||||||
|
use dom::htmlstyleelement::HTMLStyleElement;
|
||||||
use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers};
|
use dom::htmltextareaelement::{HTMLTextAreaElement, LayoutHTMLTextAreaElementHelpers};
|
||||||
use dom::nodelist::NodeList;
|
use dom::nodelist::NodeList;
|
||||||
use dom::processinginstruction::ProcessingInstruction;
|
use dom::processinginstruction::ProcessingInstruction;
|
||||||
|
@ -76,8 +80,10 @@ use std::default::Default;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
use std::sync::Arc;
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
use style::selector_impl::ServoSelectorImpl;
|
use style::selector_impl::ServoSelectorImpl;
|
||||||
|
use style::stylesheets::Stylesheet;
|
||||||
use style::thread_state;
|
use style::thread_state;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -901,6 +907,30 @@ impl Node {
|
||||||
element.upcast::<Node>().remove_self();
|
element.upcast::<Node>().remove_self();
|
||||||
Ok(())
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub struct StyleSheet {
|
||||||
|
|
||||||
impl StyleSheet {
|
impl StyleSheet {
|
||||||
#[allow(unrooted_must_root)]
|
#[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 {
|
StyleSheet {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
type_: type_,
|
type_: type_,
|
||||||
|
|
|
@ -35,13 +35,18 @@ impl StyleSheetList {
|
||||||
impl StyleSheetListMethods for StyleSheetList {
|
impl StyleSheetListMethods for StyleSheetList {
|
||||||
// https://drafts.csswg.org/cssom/#dom-stylesheetlist-length
|
// https://drafts.csswg.org/cssom/#dom-stylesheetlist-length
|
||||||
fn Length(&self) -> u32 {
|
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
|
// https://drafts.csswg.org/cssom/#dom-stylesheetlist-item
|
||||||
fn Item(&self, _index: u32) -> Option<Root<StyleSheet>> {
|
fn Item(&self, index: u32) -> Option<Root<StyleSheet>> {
|
||||||
None
|
// XXXManishearth this doesn't handle the origin clean flag
|
||||||
//TODO Create a new StyleSheet object and return it
|
// 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
|
// check-tidy: no specs after this line
|
||||||
|
|
17
components/script/dom/webidls/CSSFontFaceRule.webidl
Normal file
17
components/script/dom/webidls/CSSFontFaceRule.webidl
Normal 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,Worker)]
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
12
components/script/dom/webidls/CSSGroupingRule.webidl
Normal file
12
components/script/dom/webidls/CSSGroupingRule.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSGroupingRule : CSSRule {
|
||||||
|
// [SameObject] readonly attribute CSSRuleList cssRules;
|
||||||
|
// unsigned long insertRule(DOMString rule, unsigned long index);
|
||||||
|
// void deleteRule(unsigned long index);
|
||||||
|
};
|
||||||
|
|
14
components/script/dom/webidls/CSSKeyframesRule.webidl
Normal file
14
components/script/dom/webidls/CSSKeyframesRule.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSKeyframesRule : CSSRule {
|
||||||
|
// attribute DOMString name;
|
||||||
|
// readonly attribute CSSRuleList cssRules;
|
||||||
|
|
||||||
|
// void appendRule(DOMString rule);
|
||||||
|
// void deleteRule(DOMString select);
|
||||||
|
// CSSKeyframeRule? findRule(DOMString select);
|
||||||
|
};
|
9
components/script/dom/webidls/CSSMediaRule.webidl
Normal file
9
components/script/dom/webidls/CSSMediaRule.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSMediaRule : CSSGroupingRule {
|
||||||
|
// [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
|
||||||
|
};
|
10
components/script/dom/webidls/CSSNamespaceRule.webidl
Normal file
10
components/script/dom/webidls/CSSNamespaceRule.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSNamespaceRule : CSSRule {
|
||||||
|
// readonly attribute DOMString namespaceURI;
|
||||||
|
// readonly attribute DOMString prefix;
|
||||||
|
};
|
33
components/script/dom/webidls/CSSRule.webidl
Normal file
33
components/script/dom/webidls/CSSRule.webidl
Normal 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,Worker)]
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
11
components/script/dom/webidls/CSSRuleList.webidl
Normal file
11
components/script/dom/webidls/CSSRuleList.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSRuleList {
|
||||||
|
getter CSSRule? item(unsigned long index);
|
||||||
|
readonly attribute unsigned long length;
|
||||||
|
};
|
10
components/script/dom/webidls/CSSStyleRule.webidl
Normal file
10
components/script/dom/webidls/CSSStyleRule.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSStyleRule : CSSRule {
|
||||||
|
// attribute DOMString selectorText;
|
||||||
|
// [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
|
||||||
|
};
|
12
components/script/dom/webidls/CSSStyleSheet.webidl
Normal file
12
components/script/dom/webidls/CSSStyleSheet.webidl
Normal 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,Worker)]
|
||||||
|
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);
|
||||||
|
};
|
9
components/script/dom/webidls/CSSViewportRule.webidl
Normal file
9
components/script/dom/webidls/CSSViewportRule.webidl
Normal 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,Worker)]
|
||||||
|
interface CSSViewportRule : CSSRule {
|
||||||
|
// readonly attribute CSSStyleDeclaration style;
|
||||||
|
};
|
|
@ -7,6 +7,7 @@
|
||||||
use {Atom, Prefix, Namespace};
|
use {Atom, Prefix, Namespace};
|
||||||
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes};
|
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes};
|
||||||
use cssparser::{AtRuleType, RuleListParser, Token};
|
use cssparser::{AtRuleType, RuleListParser, Token};
|
||||||
|
use cssparser::ToCss as ParserToCss;
|
||||||
use encoding::EncodingRef;
|
use encoding::EncodingRef;
|
||||||
use error_reporting::ParseErrorReporter;
|
use error_reporting::ParseErrorReporter;
|
||||||
use font_face::{FontFaceRule, parse_font_face_block};
|
use font_face::{FontFaceRule, parse_font_face_block};
|
||||||
|
@ -18,7 +19,9 @@ use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
||||||
use selector_impl::TheSelectorImpl;
|
use selector_impl::TheSelectorImpl;
|
||||||
use selectors::parser::{Selector, parse_selector_list};
|
use selectors::parser::{Selector, parse_selector_list};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use style_traits::ToCss;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use viewport::ViewportRule;
|
use viewport::ViewportRule;
|
||||||
|
|
||||||
|
@ -39,7 +42,7 @@ pub enum Origin {
|
||||||
User,
|
User,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CssRules(pub Arc<Vec<CssRule>>);
|
pub struct CssRules(pub Arc<Vec<CssRule>>);
|
||||||
|
|
||||||
impl From<Vec<CssRule>> for CssRules {
|
impl From<Vec<CssRule>> for CssRules {
|
||||||
|
@ -67,7 +70,7 @@ pub struct UserAgentStylesheets {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum CssRule {
|
pub enum CssRule {
|
||||||
// No Charset here, CSSCharsetRule has been removed from CSSOM
|
// No Charset here, CSSCharsetRule has been removed from CSSOM
|
||||||
// https://drafts.csswg.org/cssom/#changes-from-5-december-2013
|
// https://drafts.csswg.org/cssom/#changes-from-5-december-2013
|
||||||
|
@ -129,6 +132,41 @@ pub struct StyleRule {
|
||||||
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
|
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 {
|
impl Stylesheet {
|
||||||
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
|
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
|
||||||
|
|
|
@ -255,7 +255,7 @@ pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorr
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
|
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.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -63,7 +63,7 @@ WEBIDL_STANDARDS = [
|
||||||
"//dvcs.w3.org/hg",
|
"//dvcs.w3.org/hg",
|
||||||
"//dom.spec.whatwg.org",
|
"//dom.spec.whatwg.org",
|
||||||
"//domparsing.spec.whatwg.org",
|
"//domparsing.spec.whatwg.org",
|
||||||
"//drafts.csswg.org/cssom",
|
"//drafts.csswg.org",
|
||||||
"//drafts.fxtf.org",
|
"//drafts.fxtf.org",
|
||||||
"//encoding.spec.whatwg.org",
|
"//encoding.spec.whatwg.org",
|
||||||
"//fetch.spec.whatwg.org",
|
"//fetch.spec.whatwg.org",
|
||||||
|
|
|
@ -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),
|
let stylesheet = Stylesheet::from_str(css, url, Origin::Author, Box::new(CSSErrorReporterTest),
|
||||||
ParserContextExtraData::default());
|
ParserContextExtraData::default());
|
||||||
let mut rule_count = 0;
|
let mut rule_count = 0;
|
||||||
media_queries(&stylesheet.rules, &mut |mq| {
|
media_queries(&stylesheet.rules.0, &mut |mq| {
|
||||||
rule_count += 1;
|
rule_count += 1;
|
||||||
callback(mq, css);
|
callback(mq, css);
|
||||||
});
|
});
|
||||||
|
|
|
@ -256,7 +256,7 @@ fn test_parse_stylesheet() {
|
||||||
]
|
]
|
||||||
})))
|
})))
|
||||||
|
|
||||||
],
|
].into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));
|
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue