diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs index b06e3253989..3abe8de8edb 100644 --- a/src/components/script/dom/element.rs +++ b/src/components/script/dom/element.rs @@ -12,17 +12,17 @@ use dom::bindings::js::JS; use dom::bindings::utils::{Reflectable, Reflector}; use dom::bindings::error::{ErrorResult, Fallible, NamespaceError, InvalidCharacter}; use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type}; -use dom::htmlcollection::HTMLCollection; use dom::clientrect::ClientRect; use dom::clientrectlist::ClientRectList; use dom::document::Document; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; -use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node}; +use dom::htmlcollection::HTMLCollection; use dom::htmlserializer::serialize; +use dom::node::{ElementNodeTypeId, Node, NodeHelpers, NodeIterator, document_from_node}; use dom::virtualmethods::{VirtualMethods, vtable_for}; use layout_interface::{ContentBoxQuery, ContentBoxResponse, ContentBoxesQuery}; use layout_interface::{ContentBoxesResponse, ContentChangedDocumentDamage}; -use layout_interface::{MatchSelectorsDocumentDamage}; +use layout_interface::MatchSelectorsDocumentDamage; use style; use servo_util::namespace; use servo_util::namespace::{Namespace, Null}; diff --git a/src/components/script/dom/htmlstyleelement.rs b/src/components/script/dom/htmlstyleelement.rs index 8c09d6336c0..6596eaec932 100644 --- a/src/components/script/dom/htmlstyleelement.rs +++ b/src/components/script/dom/htmlstyleelement.rs @@ -3,14 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::HTMLStyleElementBinding; -use dom::bindings::codegen::InheritTypes::HTMLStyleElementDerived; +use dom::bindings::codegen::InheritTypes::{HTMLStyleElementDerived, NodeCast}; use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; use dom::document::Document; use dom::element::HTMLStyleElementTypeId; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; -use dom::node::{Node, ElementNodeTypeId}; +use dom::node::{Node, ElementNodeTypeId, window_from_node}; +use html::cssparse::parse_inline_css; +use layout_interface::{AddStylesheetMsg, LayoutChan}; use servo_util::str::DOMString; #[deriving(Encodable)] @@ -72,3 +74,20 @@ impl HTMLStyleElement { Ok(()) } } + +pub trait StyleElementHelpers { + fn parse_own_css(&self); +} + +impl StyleElementHelpers for JS { + fn parse_own_css(&self) { + let node: JS = NodeCast::from(self); + let win = window_from_node(&node); + let url = win.get().page().get_url(); + + let data = node.get().GetTextContent(&node).expect("Element.textContent must be a string"); + let sheet = parse_inline_css(url, data); + let LayoutChan(ref layout_chan) = win.get().page().layout_chan; + layout_chan.send(AddStylesheetMsg(sheet)); + } +} diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 733d1ad7f86..a8c7dbfe961 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -6,7 +6,7 @@ use dom::attr::Attr; use dom::bindings::codegen::InheritTypes::{CommentCast, DocumentCast, DocumentTypeCast}; -use dom::bindings::codegen::InheritTypes::{ElementCast, TextCast, NodeCast}; +use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLStyleElementCast, TextCast, NodeCast}; use dom::bindings::codegen::InheritTypes::{CharacterDataCast, NodeBase, NodeDerived}; use dom::bindings::codegen::InheritTypes::{ProcessingInstructionCast, EventTargetCast}; use dom::bindings::codegen::NodeBinding::NodeConstants; @@ -21,6 +21,7 @@ use dom::documentfragment::DocumentFragment; use dom::documenttype::DocumentType; use dom::element::{Element, ElementTypeId, HTMLAnchorElementTypeId}; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; +use dom::htmlstyleelement::StyleElementHelpers; use dom::nodelist::{NodeList}; use dom::processinginstruction::ProcessingInstruction; use dom::text::Text; @@ -269,6 +270,8 @@ pub trait NodeHelpers { fn add_child(&mut self, new_child: &mut JS, before: Option>); fn remove_child(&mut self, child: &mut JS); + fn child_inserted(&self); + fn get_hover_state(&self) -> bool; fn set_hover_state(&mut self, state: bool); @@ -408,6 +411,7 @@ impl NodeHelpers for JS { } } + self.parent_node().map(|parent| parent.child_inserted()); document.get().content_changed(); } @@ -499,6 +503,15 @@ impl NodeHelpers for JS { child_node.set_parent_node(None); } + fn child_inserted(&self) { + // Parse text content added to an inline stylesheet. + match HTMLStyleElementCast::to(self) { + Some(elem) => elem.parse_own_css(), + None => () + } + } + + fn get_hover_state(&self) -> bool { self.get().flags.get_in_hover_state() } diff --git a/src/components/script/html/cssparse.rs b/src/components/script/html/cssparse.rs index c5cad0849de..b538676edac 100644 --- a/src/components/script/html/cssparse.rs +++ b/src/components/script/html/cssparse.rs @@ -18,34 +18,45 @@ pub enum StylesheetProvenance { InlineProvenance(Url, ~str), } +// Parses the style data and returns the stylesheet +pub fn parse_inline_css(url: Url, data: ~str) -> Stylesheet { + let resource_task = ResourceTask(); // Resource task is not used for inline parsing + parse_css(InlineProvenance(url, data), resource_task) +} + +fn parse_css(provenance: StylesheetProvenance, + resource_task: ResourceTask) -> Stylesheet { + // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding + let environment_encoding = UTF_8 as EncodingRef; + + match provenance { + UrlProvenance(url) => { + debug!("cssparse: loading style sheet at {:s}", url.to_str()); + let (input_chan, input_port) = channel(); + resource_task.send(Load(url, input_chan)); + let LoadResponse { metadata: metadata, progress_port: progress_port } + = input_port.recv(); + let final_url = &metadata.final_url; + let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); + let iter = ProgressMsgPortIterator { progress_port: progress_port }; + Stylesheet::from_bytes_iter( + iter, final_url.clone(), + protocol_encoding_label, Some(environment_encoding)) + } + InlineProvenance(base_url, data) => { + debug!("cssparse: loading inline stylesheet {:s}", data); + Stylesheet::from_str(data, base_url, environment_encoding) + } + } +} + pub fn spawn_css_parser(provenance: StylesheetProvenance, resource_task: ResourceTask) -> Receiver { let (result_chan, result_port) = channel(); - // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding - let environment_encoding = UTF_8 as EncodingRef; - spawn_named("cssparser", proc() { - let sheet = match provenance { - UrlProvenance(url) => { - debug!("cssparse: loading style sheet at {:s}", url.to_str()); - let (input_chan, input_port) = channel(); - resource_task.send(Load(url, input_chan)); - let LoadResponse { metadata: metadata, progress_port: progress_port } - = input_port.recv(); - let final_url = &metadata.final_url; - let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); - let iter = ProgressMsgPortIterator { progress_port: progress_port }; - Stylesheet::from_bytes_iter( - iter, final_url.clone(), - protocol_encoding_label, Some(environment_encoding)) - } - InlineProvenance(base_url, data) => { - Stylesheet::from_str(data, base_url, environment_encoding) - } - }; - result_chan.send(sheet); + result_chan.send(parse_css(provenance, resource_task)); }); return result_port; diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs index c9d57ba0e16..21d285632f8 100644 --- a/src/components/script/html/hubbub_html_parser.rs +++ b/src/components/script/html/hubbub_html_parser.rs @@ -14,7 +14,7 @@ use dom::htmliframeelement::IFrameSize; use dom::htmlformelement::HTMLFormElement; use dom::node::{ElementNodeTypeId, INode, NodeHelpers}; use dom::types::*; -use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser}; +use html::cssparse::{StylesheetProvenance, UrlProvenance, spawn_css_parser}; use script_task::Page; use hubbub::hubbub; @@ -298,7 +298,7 @@ pub fn parse_html(page: &Page, parser.enable_scripting(true); parser.enable_styling(true); - let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone()); + let (css_chan2, js_chan2) = (css_chan.clone(), js_chan.clone()); let next_subpage_id = RefCell::new(next_subpage_id); @@ -483,22 +483,8 @@ pub fn parse_html(page: &Page, } debug!("complete script"); }, - complete_style: |style| { - // We've reached the end of a