diff options
Diffstat (limited to 'components/script/dom/htmlmetaelement.rs')
-rw-r--r-- | components/script/dom/htmlmetaelement.rs | 164 |
1 files changed, 86 insertions, 78 deletions
diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 3c4e817a132..f91e4339f1d 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -1,83 +1,90 @@ /* 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::attr::Attr; -use dom::bindings::cell::DOMRefCell; -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::{MutNullableJS, 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, window_from_node}; -use dom::virtualmethods::VirtualMethods; + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::attr::Attr; +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods; +use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::bindings::str::DOMString; +use crate::dom::cssstylesheet::CSSStyleSheet; +use crate::dom::document::Document; +use crate::dom::element::{AttributeMutation, Element}; +use crate::dom::htmlelement::HTMLElement; +use crate::dom::htmlheadelement::HTMLHeadElement; +use crate::dom::node::{ + document_from_node, stylesheets_owner_from_node, window_from_node, BindContext, Node, + UnbindContext, +}; +use crate::dom::virtualmethods::VirtualMethods; use dom_struct::dom_struct; -use html5ever_atoms::LocalName; -use servo_config::prefs::PREFS; -use std::ascii::AsciiExt; -use std::sync::Arc; +use html5ever::{LocalName, Prefix}; +use parking_lot::RwLock; +use servo_arc::Arc; +use servo_config::pref; use std::sync::atomic::AtomicBool; -use style::attr::AttrValue; use style::media_queries::MediaList; use style::str::HTML_SPACE_CHARACTERS; -use style::stylesheets::{Stylesheet, CssRule, CssRules, Origin}; -use style::viewport::ViewportRule; +use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StylesheetContents, ViewportRule}; #[dom_struct] pub struct HTMLMetaElement { htmlelement: HTMLElement, - #[ignore_heap_size_of = "Arc"] - stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>, - cssom_stylesheet: MutNullableJS<CSSStyleSheet>, + #[ignore_malloc_size_of = "Arc"] + stylesheet: DomRefCell<Option<Arc<Stylesheet>>>, + cssom_stylesheet: MutNullableDom<CSSStyleSheet>, } impl HTMLMetaElement { - fn new_inherited(local_name: LocalName, - prefix: Option<DOMString>, - document: &Document) -> HTMLMetaElement { + fn new_inherited( + local_name: LocalName, + prefix: Option<Prefix>, + document: &Document, + ) -> HTMLMetaElement { HTMLMetaElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), - stylesheet: DOMRefCell::new(None), - cssom_stylesheet: MutNullableJS::new(None), + stylesheet: DomRefCell::new(None), + cssom_stylesheet: MutNullableDom::new(None), } } #[allow(unrooted_must_root)] - pub fn new(local_name: LocalName, - prefix: Option<DOMString>, - document: &Document) -> Root<HTMLMetaElement> { - Node::reflect_node(box HTMLMetaElement::new_inherited(local_name, prefix, document), - document, - HTMLMetaElementBinding::Wrap) + pub fn new( + local_name: LocalName, + prefix: Option<Prefix>, + document: &Document, + ) -> DomRoot<HTMLMetaElement> { + Node::reflect_node( + Box::new(HTMLMetaElement::new_inherited(local_name, prefix, document)), + document, + ) } pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> { self.stylesheet.borrow().clone() } - pub fn get_cssom_stylesheet(&self) -> Option<Root<CSSStyleSheet>> { + pub fn get_cssom_stylesheet(&self) -> Option<DomRoot<CSSStyleSheet>> { 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 - sheet) + CSSStyleSheet::new( + &window_from_node(self), + self.upcast::<Element>(), + "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() { - let name = name.value().to_ascii_lowercase(); + if let Some(ref name) = element.get_name() { + let name = name.to_ascii_lowercase(); let name = name.trim_matches(HTML_SPACE_CHARACTERS); if name == "viewport" { @@ -90,32 +97,36 @@ impl HTMLMetaElement { } } + #[allow(unrooted_must_root)] fn apply_viewport(&self) { - if !PREFS.get("layout.viewport.enabled").as_boolean().unwrap_or(false) { + if !pref!(layout.viewport.enabled) { return; } let element = self.upcast::<Element>(); - if let Some(content) = element.get_attribute(&ns!(), &local_name!("content")).r() { + if let Some(ref content) = element.get_attribute(&ns!(), &local_name!("content")) { let content = content.value(); if !content.is_empty() { if let Some(translated_rule) = ViewportRule::from_meta(&**content) { - let document = self.upcast::<Node>().owner_doc(); + let stylesheets_owner = stylesheets_owner_from_node(self); + let document = document_from_node(self); let shared_lock = document.style_shared_lock(); let rule = CssRule::Viewport(Arc::new(shared_lock.wrap(translated_rule))); - *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet { - rules: CssRules::new(vec![rule], shared_lock), - origin: Origin::Author, - shared_lock: shared_lock.clone(), - url_data: window_from_node(self).get_url(), - namespaces: Default::default(), + let sheet = Arc::new(Stylesheet { + contents: StylesheetContents { + rules: CssRules::new(vec![rule], shared_lock), + origin: Origin::Author, + namespaces: Default::default(), + quirks_mode: document.quirks_mode(), + url_data: RwLock::new(window_from_node(self).get_url()), + source_map_url: RwLock::new(None), + source_url: RwLock::new(None), + }, media: Arc::new(shared_lock.wrap(MediaList::empty())), - // 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), + shared_lock: shared_lock.clone(), disabled: AtomicBool::new(false), - })); - let doc = document_from_node(self); - doc.invalidate_stylesheets(); + }); + *self.stylesheet.borrow_mut() = Some(sheet.clone()); + stylesheets_owner.add_stylesheet(self.upcast(), sheet); } } } @@ -123,8 +134,8 @@ impl HTMLMetaElement { fn process_referrer_attribute(&self) { let element = self.upcast::<Element>(); - if let Some(name) = element.get_attribute(&ns!(), &local_name!("name")).r() { - let name = name.value().to_ascii_lowercase(); + if let Some(ref name) = element.get_name() { + let name = name.to_ascii_lowercase(); let name = name.trim_matches(HTML_SPACE_CHARACTERS); if name == "referrer" { @@ -133,7 +144,7 @@ impl HTMLMetaElement { } } - /// https://html.spec.whatwg.org/multipage/#meta-referrer + /// <https://html.spec.whatwg.org/multipage/#meta-referrer> fn apply_referrer(&self) { if let Some(parent) = self.upcast::<Node>().GetParentElement() { if let Some(head) = parent.downcast::<HTMLHeadElement>() { @@ -158,27 +169,20 @@ impl HTMLMetaElementMethods for HTMLMetaElement { } impl VirtualMethods for HTMLMetaElement { - fn super_type(&self) -> Option<&VirtualMethods> { - Some(self.upcast::<HTMLElement>() as &VirtualMethods) + fn super_type(&self) -> Option<&dyn VirtualMethods> { + Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods) } - fn bind_to_tree(&self, tree_in_doc: bool) { + fn bind_to_tree(&self, context: &BindContext) { if let Some(ref s) = self.super_type() { - s.bind_to_tree(tree_in_doc); + s.bind_to_tree(context); } - if tree_in_doc { + if context.tree_connected { self.process_attributes(); } } - fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { - match name { - &local_name!("name") => AttrValue::from_atomic(value.into()), - _ => self.super_type().unwrap().parse_plain_attribute(name, value), - } - } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { if let Some(s) = self.super_type() { s.attribute_mutated(attr, mutation); @@ -192,8 +196,12 @@ impl VirtualMethods for HTMLMetaElement { s.unbind_from_tree(context); } - if context.tree_in_doc { + if context.tree_connected { self.process_referrer_attribute(); + + if let Some(s) = self.stylesheet.borrow_mut().take() { + stylesheets_owner_from_node(self).remove_stylesheet(self.upcast(), &s); + } } } } |