diff options
author | jaymodi98 <jaymodi98@gmail.com> | 2019-10-28 17:21:45 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2019-11-12 13:57:54 -0500 |
commit | bf69b6fea7c7eed2ba3b96e5c77573f25b7929ed (patch) | |
tree | fb0632e7edc62d80dcd133ef9adeb1b093c923ce /components | |
parent | 944c1e9f976a4daf5ba640d889f0b00a06d15a17 (diff) | |
download | servo-bf69b6fea7c7eed2ba3b96e5c77573f25b7929ed.tar.gz servo-bf69b6fea7c7eed2ba3b96e5c77573f25b7929ed.zip |
Implement srcdoc support for iframes.
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 49 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLIFrameElement.webidl | 4 | ||||
-rw-r--r-- | components/script/script_thread.rs | 24 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 4 |
4 files changed, 76 insertions, 5 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index e58e65ea5bb..df94aeb361c 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -229,7 +229,30 @@ impl HTMLIFrameElement { /// <https://html.spec.whatwg.org/multipage/#process-the-iframe-attributes> fn process_the_iframe_attributes(&self, mode: ProcessingMode) { - // TODO: srcdoc + if self + .upcast::<Element>() + .has_attribute(&local_name!("srcdoc")) + { + let url = ServoUrl::parse("about:srcdoc").unwrap(); + let document = document_from_node(self); + let window = window_from_node(self); + let pipeline_id = Some(window.upcast::<GlobalScope>().pipeline_id()); + let mut load_data = LoadData::new( + LoadOrigin::Script(document.origin().immutable().clone()), + url, + pipeline_id, + Some(Referrer::ReferrerUrl(document.url())), + document.get_referrer_policy(), + ); + let element = self.upcast::<Element>(); + load_data.srcdoc = String::from(element.get_string_attribute(&local_name!("srcdoc"))); + self.navigate_or_reload_child_browsing_context( + load_data, + NavigationType::InitialAboutBlank, + HistoryEntryReplacement::Disabled, + ); + return; + } let window = window_from_node(self); @@ -480,6 +503,12 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { // https://html.spec.whatwg.org/multipage/#dom-iframe-src make_url_setter!(SetSrc, "src"); + // https://html.spec.whatwg.org/multipage/#dom-iframe-srcdoc + make_getter!(Srcdoc, "srcdoc"); + + // https://html.spec.whatwg.org/multipage/#dom-iframe-srcdoc + make_setter!(SetSrcdoc, "srcdoc"); + // https://html.spec.whatwg.org/multipage/#dom-iframe-sandbox fn Sandbox(&self) -> DomRoot<DOMTokenList> { self.sandbox @@ -580,13 +609,29 @@ impl VirtualMethods for HTMLIFrameElement { modes })); }, + &local_name!("srcdoc") => { + // https://html.spec.whatwg.org/multipage/#the-iframe-element:the-iframe-element-9 + // "Whenever an iframe element with a non-null nested browsing context has its + // srcdoc attribute set, changed, or removed, the user agent must process the + // iframe attributes." + // but we can't check that directly, since the child browsing context + // may be in a different script thread. Instead, we check to see if the parent + // is in a document tree and has a browsing context, which is what causes + // the child browsing context to be created. + + // trigger the processing of iframe attributes whenever "srcdoc" attribute is set, changed or removed + if self.upcast::<Node>().is_connected_with_browsing_context() { + debug!("iframe srcdoc modified while in browsing context."); + self.process_the_iframe_attributes(ProcessingMode::NotFirstTime); + } + }, &local_name!("src") => { // https://html.spec.whatwg.org/multipage/#the-iframe-element // "Similarly, whenever an iframe element with a non-null nested browsing context // but with no srcdoc attribute specified has its src attribute set, changed, or removed, // the user agent must process the iframe attributes," // but we can't check that directly, since the child browsing context - // may be in a different script thread. Instread, we check to see if the parent + // may be in a different script thread. Instead, we check to see if the parent // is in a document tree and has a browsing context, which is what causes // the child browsing context to be created. if self.upcast::<Node>().is_connected_with_browsing_context() { diff --git a/components/script/dom/webidls/HTMLIFrameElement.webidl b/components/script/dom/webidls/HTMLIFrameElement.webidl index acc4f0f201d..b9dd97bdea6 100644 --- a/components/script/dom/webidls/HTMLIFrameElement.webidl +++ b/components/script/dom/webidls/HTMLIFrameElement.webidl @@ -9,8 +9,8 @@ interface HTMLIFrameElement : HTMLElement { [CEReactions] attribute USVString src; - // [CEReactions] - // attribute DOMString srcdoc; + [CEReactions] + attribute DOMString srcdoc; [CEReactions] attribute DOMString name; diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 191df335ec5..20ac88b7bc1 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2430,6 +2430,8 @@ impl ScriptThread { ); if load_data.url.as_str() == "about:blank" { self.start_page_load_about_blank(new_load, load_data.js_eval_result); + } else if load_data.url.as_str() == "about:srcdoc" { + self.page_load_about_srcdoc(new_load, load_data.srcdoc); } else { self.pre_page_load(new_load, load_data); } @@ -3177,7 +3179,8 @@ impl ScriptThread { self.timer_event_chan.clone(), ); - let origin = if final_url.as_str() == "about:blank" { + let origin = if final_url.as_str() == "about:blank" || final_url.as_str() == "about:srcdoc" + { incomplete.origin.clone() } else { MutableOrigin::new(final_url.origin()) @@ -3838,6 +3841,25 @@ impl ScriptThread { context.process_response_eof(Ok(ResourceFetchTiming::new(ResourceTimingType::None))); } + /// Synchronously parse a srcdoc document from a giving HTML string. + fn page_load_about_srcdoc(&self, incomplete: InProgressLoad, src_doc: String) { + let id = incomplete.pipeline_id; + + self.incomplete_loads.borrow_mut().push(incomplete); + + let url = ServoUrl::parse("about:srcdoc").unwrap(); + let mut context = ParserContext::new(id, url.clone()); + + let mut meta = Metadata::default(url); + meta.set_content_type(Some(&mime::TEXT_HTML)); + + let chunk = src_doc.into_bytes(); + + context.process_response(Ok(FetchMetadata::Unfiltered(meta))); + context.process_response_chunk(chunk); + context.process_response_eof(Ok(ResourceFetchTiming::new(ResourceTimingType::None))); + } + fn handle_css_error_reporting( &self, pipeline_id: PipelineId, diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 468cfb19fb3..1b1a0e80e65 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -163,6 +163,9 @@ pub struct LoadData { pub referrer: Option<Referrer>, /// The referrer policy. pub referrer_policy: Option<ReferrerPolicy>, + + /// The source to use instead of a network response for a srcdoc document. + pub srcdoc: String, } /// The result of evaluating a javascript scheme url. @@ -194,6 +197,7 @@ impl LoadData { js_eval_result: None, referrer: referrer, referrer_policy: referrer_policy, + srcdoc: "".to_string(), } } } |