diff options
author | mrnayak <rmuddur@gmail.com> | 2017-01-13 23:35:00 +0530 |
---|---|---|
committer | mrnayak <rmuddur@gmail.com> | 2017-01-13 23:35:00 +0530 |
commit | 3d9e44a8c497acd52b428dd02062a9c55a2efafc (patch) | |
tree | e62450e7f88ea8152da2d0f0276c25ad5402ed66 /components/script | |
parent | dc93a72997aefaeb04cdc058b01fdd2eb14cef8f (diff) | |
download | servo-3d9e44a8c497acd52b428dd02062a9c55a2efafc.tar.gz servo-3d9e44a8c497acd52b428dd02062a9c55a2efafc.zip |
Handle crossorigin in link and refactor crossorigin handling
Implemented Step three and handled step four of obtain the resource part
of 4.2.4 The link element.
Link to spec : https://html.spec.whatwg.org/multipage/semantics.html#concept-link-obtain
Refactored crossOrigin handling in HTMLScriptElement, HTMLImageElement
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/element.rs | 33 | ||||
-rw-r--r-- | components/script/dom/htmlimageelement.rs | 10 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 16 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 29 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLImageElement.webidl | 2 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLLinkElement.webidl | 2 | ||||
-rw-r--r-- | components/script/stylesheet_loader.rs | 23 |
7 files changed, 80 insertions, 35 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index be1e0eca42e..bd3925c04f9 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -79,6 +79,7 @@ use html5ever::serialize::TraversalScope; use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; use js::jsapi::{HandleValue, JSAutoCompartment}; +use net_traits::request::CorsSettings; use parking_lot::RwLock; use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowQueryType; @@ -2897,3 +2898,35 @@ impl Runnable for ElementPerformFullscreenExit { promise.resolve(promise.global().get_cx(), HandleValue::undefined()); } } + +pub fn reflect_cross_origin_attribute(element: &Element) -> Option<DOMString> { + let attr = element.get_attribute(&ns!(), &local_name!("crossorigin")); + + if let Some(mut val) = attr.map(|v| v.Value()) { + val.make_ascii_lowercase(); + if val == "anonymous" || val == "use-credentials" { + return Some(val); + } + return Some(DOMString::from("anonymous")); + } + None +} + +pub fn set_cross_origin_attribute(element: &Element, value: Option<DOMString>) { + match value { + Some(val) => element.set_string_attribute(&local_name!("crossorigin"), val), + None => { + element.remove_attribute(&ns!(), &local_name!("crossorigin")); + } + } +} + +pub fn cors_setting_for_element(element: &Element) -> Option<CorsSettings> { + reflect_cross_origin_attribute(element).map_or(None, |attr| { + match &*attr { + "anonymous" => Some(CorsSettings::Anonymous), + "use-credentials" => Some(CorsSettings::UseCredentials), + _ => unreachable!() + } + }) +} diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 29ddcd0a7c4..629d5d50fb6 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -19,6 +19,7 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; +use dom::element::{reflect_cross_origin_attribute, set_cross_origin_attribute}; use dom::event::Event; use dom::eventtarget::EventTarget; use dom::htmlareaelement::HTMLAreaElement; @@ -335,9 +336,14 @@ impl HTMLImageElementMethods for HTMLImageElement { make_setter!(SetSrc, "src"); // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin - make_enumerated_getter!(CrossOrigin, "crossorigin", "anonymous", "use-credentials"); + fn GetCrossOrigin(&self) -> Option<DOMString> { + reflect_cross_origin_attribute(self.upcast::<Element>()) + } + // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin - make_setter!(SetCrossOrigin, "crossorigin"); + fn SetCrossOrigin(&self, value: Option<DOMString>) { + set_cross_origin_attribute(self.upcast::<Element>(), value); + } // https://html.spec.whatwg.org/multipage/#dom-img-usemap make_getter!(UseMap, "usemap"); diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 8f5d530769a..674db5c8a0c 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -15,6 +15,7 @@ use dom::cssstylesheet::CSSStyleSheet; use dom::document::Document; use dom::domtokenlist::DOMTokenList; use dom::element::{AttributeMutation, Element, ElementCreator}; +use dom::element::{cors_setting_for_element, reflect_cross_origin_attribute, set_cross_origin_attribute}; use dom::globalscope::GlobalScope; use dom::htmlelement::HTMLElement; use dom::node::{Node, document_from_node, window_from_node}; @@ -239,6 +240,9 @@ impl HTMLLinkElement { let element = self.upcast::<Element>(); + // Step 3 + let cors_setting = cors_setting_for_element(element); + let mq_attribute = element.get_attribute(&ns!(), &local_name!("media")); let value = mq_attribute.r().map(|a| a.value()); let mq_str = match value { @@ -262,7 +266,7 @@ impl HTMLLinkElement { loader.load(StylesheetContextSource::LinkElement { url: url, media: Some(media), - }, integrity_metadata.to_owned()); + }, cors_setting, integrity_metadata.to_owned()); } fn handle_favicon_url(&self, rel: &str, href: &str, sizes: &Option<String>) { @@ -379,6 +383,16 @@ impl HTMLLinkElementMethods for HTMLLinkElement { // https://html.spec.whatwg.org/multipage/#dom-link-target make_setter!(SetTarget, "target"); + // https://html.spec.whatwg.org/multipage/#dom-link-crossorigin + fn GetCrossOrigin(&self) -> Option<DOMString> { + reflect_cross_origin_attribute(self.upcast::<Element>()) + } + + // https://html.spec.whatwg.org/multipage/#dom-link-crossorigin + fn SetCrossOrigin(&self, value: Option<DOMString>) { + set_cross_origin_attribute(self.upcast::<Element>(), value); + } + // https://drafts.csswg.org/cssom/#dom-linkstyle-sheet fn GetSheet(&self) -> Option<Root<DOMStyleSheet>> { self.get_cssom_stylesheet().map(Root::upcast) diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index cf0d3c6cf94..1a946871f32 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -4,7 +4,6 @@ use document_loader::LoadType; use dom::attr::Attr; -use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::HTMLScriptElementBinding; use dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods; @@ -17,6 +16,7 @@ use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element, ElementCreator}; +use dom::element::{cors_setting_for_element, reflect_cross_origin_attribute, set_cross_origin_attribute}; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventdispatcher::EventStatus; use dom::globalscope::GlobalScope; @@ -369,12 +369,7 @@ impl HTMLScriptElement { .unwrap_or_else(|| doc.encoding()); // Step 14. - let cors_setting = match self.GetCrossOrigin() { - Some(ref s) if *s == "anonymous" => Some(CorsSettings::Anonymous), - Some(ref s) if *s == "use-credentials" => Some(CorsSettings::UseCredentials), - None => None, - _ => unreachable!() - }; + let cors_setting = cors_setting_for_element(element); // TODO: Step 15: Module script credentials mode. @@ -707,28 +702,12 @@ impl HTMLScriptElementMethods for HTMLScriptElement { // https://html.spec.whatwg.org/multipage/#dom-script-crossorigin fn GetCrossOrigin(&self) -> Option<DOMString> { - let element = self.upcast::<Element>(); - let attr = element.get_attribute(&ns!(), &local_name!("crossorigin")); - - if let Some(mut val) = attr.map(|v| v.Value()) { - val.make_ascii_lowercase(); - if val == "anonymous" || val == "use-credentials" { - return Some(val); - } - return Some(DOMString::from("anonymous")); - } - None + reflect_cross_origin_attribute(self.upcast::<Element>()) } // https://html.spec.whatwg.org/multipage/#dom-script-crossorigin fn SetCrossOrigin(&self, value: Option<DOMString>) { - let element = self.upcast::<Element>(); - match value { - Some(val) => element.set_string_attribute(&local_name!("crossorigin"), val), - None => { - element.remove_attribute(&ns!(), &local_name!("crossorigin")); - } - } + set_cross_origin_attribute(self.upcast::<Element>(), value); } // https://html.spec.whatwg.org/multipage/#dom-script-text diff --git a/components/script/dom/webidls/HTMLImageElement.webidl b/components/script/dom/webidls/HTMLImageElement.webidl index 88e0dae8d3b..7bd69124d87 100644 --- a/components/script/dom/webidls/HTMLImageElement.webidl +++ b/components/script/dom/webidls/HTMLImageElement.webidl @@ -8,7 +8,7 @@ interface HTMLImageElement : HTMLElement { attribute DOMString alt; attribute DOMString src; // attribute DOMString srcset; - attribute DOMString crossOrigin; + attribute DOMString? crossOrigin; attribute DOMString useMap; attribute boolean isMap; attribute unsigned long width; diff --git a/components/script/dom/webidls/HTMLLinkElement.webidl b/components/script/dom/webidls/HTMLLinkElement.webidl index 46b611d3548..bfab6270092 100644 --- a/components/script/dom/webidls/HTMLLinkElement.webidl +++ b/components/script/dom/webidls/HTMLLinkElement.webidl @@ -5,7 +5,7 @@ // https://html.spec.whatwg.org/multipage/#htmllinkelement interface HTMLLinkElement : HTMLElement { attribute DOMString href; - // attribute DOMString crossOrigin; + attribute DOMString? crossOrigin; attribute DOMString rel; readonly attribute DOMTokenList relList; attribute DOMString media; diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs index 637f0619fc5..25b06e31de9 100644 --- a/components/script/stylesheet_loader.rs +++ b/components/script/stylesheet_loader.rs @@ -20,7 +20,7 @@ use hyper_serde::Serde; use ipc_channel::ipc; use ipc_channel::router::ROUTER; use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError, ReferrerPolicy}; -use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType}; +use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use parking_lot::RwLock; use script_layout_interface::message::Msg; @@ -196,7 +196,8 @@ impl<'a> StylesheetLoader<'a> { } impl<'a> StylesheetLoader<'a> { - pub fn load(&self, source: StylesheetContextSource, integrity_metadata: String) { + pub fn load(&self, source: StylesheetContextSource, cors_setting: Option<CorsSettings>, + integrity_metadata: String) { let url = source.url(); let document = document_from_node(self.elem); let context = Arc::new(Mutex::new(StylesheetContext { @@ -231,8 +232,18 @@ impl<'a> StylesheetLoader<'a> { url: url.clone(), type_: RequestType::Style, destination: Destination::Style, - credentials_mode: CredentialsMode::Include, - use_url_credentials: true, + // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request + // Step 1 + mode: match cors_setting { + Some(_) => RequestMode::CorsMode, + None => RequestMode::NoCors, + }, + // https://html.spec.whatwg.org/multipage/#create-a-potential-cors-request + // Step 3-4 + credentials_mode: match cors_setting { + Some(CorsSettings::Anonymous) => CredentialsMode::CredentialsSameOrigin, + _ => CredentialsMode::Include, + }, origin: document.url(), pipeline_id: Some(self.elem.global().pipeline_id()), referrer_url: Some(document.url()), @@ -247,6 +258,8 @@ impl<'a> StylesheetLoader<'a> { impl<'a> StyleStylesheetLoader for StylesheetLoader<'a> { fn request_stylesheet(&self, import: &Arc<RwLock<ImportRule>>) { - self.load(StylesheetContextSource::Import(import.clone()), "".to_owned()) + //TODO (mrnayak) : Whether we should use the original loader's CORS setting? + //Fix this when spec has more details. + self.load(StylesheetContextSource::Import(import.clone()), None, "".to_owned()) } } |