From 039a6830f3044fdaa0891aa59036501c614b87c5 Mon Sep 17 00:00:00 2001 From: nupurbaghel Date: Thu, 26 Jul 2018 01:02:21 +0530 Subject: [PATCH 1/2] add react to env --- components/script/dom/htmlimageelement.rs | 225 ++++++++++++++++++++-- 1 file changed, 211 insertions(+), 14 deletions(-) diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 7aead67ed79aa..d16d2a15704ad 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -303,7 +303,7 @@ impl HTMLImageElement { document.loader().fetch_async_background(request, action_sender); } - /// Step 14 of https://html.spec.whatwg.org/multipage/#update-the-image-data + /// Step 24 of https://html.spec.whatwg.org/multipage/#update-the-image-data fn process_image_response(&self, image: ImageResponse) { // TODO: Handle multipart/x-mixed-replace let (trigger_image_load, trigger_image_error) = match (image, self.image_request.get()) { @@ -579,7 +579,7 @@ impl HTMLImageElement { } /// - fn select_image_source(&self) -> Option<(DOMString, f32)> { + fn select_image_source(&self) -> Option<(DOMString, f64)> { // Step 1, 3 self.update_source_set(); let source_set = &*self.source_set.borrow_mut(); @@ -632,7 +632,7 @@ impl HTMLImageElement { } } let selected_source = img_sources.remove(best_candidate.1).clone(); - Some((DOMString::from_string(selected_source.url), selected_source.descriptor.den.unwrap() as f32)) + Some((DOMString::from_string(selected_source.url), selected_source.descriptor.den.unwrap() as f64)) } fn init_image_request(&self, @@ -648,12 +648,12 @@ impl HTMLImageElement { request.blocker = Some(LoadBlocker::new(&*document, LoadType::Image(url.clone()))); } - /// Step 12 of html.spec.whatwg.org/multipage/#update-the-image-data + /// Step 13-17 of html.spec.whatwg.org/multipage/#update-the-image-data fn prepare_image_request(&self, url: &ServoUrl, src: &DOMString) { match self.image_request.get() { ImageRequestPhase::Pending => { if let Some(pending_url) = self.pending_request.borrow().parsed_url.clone() { - // Step 12.1 + // Step 13 if pending_url == *url { return } @@ -662,12 +662,12 @@ impl HTMLImageElement { ImageRequestPhase::Current => { let mut current_request = self.current_request.borrow_mut(); let mut pending_request = self.pending_request.borrow_mut(); - // step 12.4, create a new "image_request" + // step 16, create a new "image_request" match (current_request.parsed_url.clone(), current_request.state) { (Some(parsed_url), State::PartiallyAvailable) => { - // Step 12.2 + // Step 14 if parsed_url == *url { - // 12.3 abort pending request + // 15 abort pending request pending_request.image = None; pending_request.parsed_url = None; LoadBlocker::terminate(&mut pending_request.blocker); @@ -678,11 +678,11 @@ impl HTMLImageElement { self.init_image_request(&mut pending_request, &url, &src); }, (_, State::Broken) | (_, State::Unavailable) => { - // Step 12.5 + // Step 17 self.init_image_request(&mut current_request, &url, &src); }, (_, _) => { - // step 12.6 + // step 17 self.image_request.set(ImageRequestPhase::Pending); self.init_image_request(&mut pending_request, &url, &src); }, @@ -700,7 +700,7 @@ impl HTMLImageElement { let this = Trusted::new(self); let src = match self.select_image_source() { Some(src) => { - // Step 8. + // Step 8 // TODO: Handle pixel density. src.0 }, @@ -755,11 +755,11 @@ impl HTMLImageElement { let parsed_url = base_url.join(&src); match parsed_url { Ok(url) => { - // Step 12 + // Step 13 self.prepare_image_request(&url, &src); }, Err(_) => { - // Step 11.1-11.5. + // Step 12.1-12.5. let src = String::from(src); // FIXME(nox): Why are errors silenced here? let _ = task_source.queue( @@ -871,6 +871,185 @@ impl HTMLImageElement { ScriptThread::await_stable_state(Microtask::ImageElement(task)); } + /// + fn react_to_environment_changes(&self){ + // Step 1 + let task = ImageElementMicrotask::EnvironmentChangesTask { + elem: DomRoot::from_ref(self), + }; + ScriptThread::await_stable_state(Microtask::ImageElement(task)); + + let elem = self.upcast::(); + let document = document_from_node(elem); + + } + + /// Step 3-12 of https://html.spec.whatwg.org/multipage/#img-environment-changes + fn react_to_environment_changes_sync_steps(&self){ + let mut selected_source = None; + let mut selected_pixel_density = None; + let elem = self.upcast::(); + let document = document_from_node(elem); + let base_url = document.base_url(); + match self.select_image_source() { + Some(src) => { + // Step 3 + selected_source = Some(src.0); + selected_pixel_density = Some(src.1); + }, + _ => () + } + + // Step 4 + let src = match selected_source { + Some(src) => src, + _ => return, + }; + + // Step 5 + let same_source = match *self.last_selected_source.borrow() { + Some(ref last_src) => *last_src == src, + _ => false, + }; + + let same_selected_pixel_density = match selected_pixel_density { + Some(den) => self.current_request.borrow().current_pixel_density.map_or(false,|density| density==den), + _ => self.current_request.borrow().current_pixel_density.map_or(true, |den| false), + }; + + if same_source && same_selected_pixel_density { + return; + } + + // Step 6 + if let Ok(img_url) = base_url.join(&String::from(src)) { + + // Step 7 + let corsAttributeState = self.GetCrossOrigin(); + + // Step 8 + let origin = document.origin().immutable().clone(); + + // Step 10 + // TODO Handle No CORS here + let key = (img_url.clone(), corsAttributeState); + + // Step 12 + *self.pending_request.borrow_mut() = ImageRequest { + state: State::Unavailable, + parsed_url: Some(img_url), + source_url: None, + image: None, + metadata: None, + blocker: None, + final_url: None, + current_pixel_density: None, + }; + + // Step 13 ?? + let window = window_from_node(self); + let image_cache = window.image_cache(); + // Step 14 + let response = + image_cache.find_image_or_metadata(img_url.clone().into(), + UsePlaceholder::No, + CanRequestImages::No); + + if let Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) = response { + + } else { + let window = window_from_node(self); + let image_cache = window.image_cache(); + // Step 14.1 + let response = + image_cache.find_image_or_metadata(img_url.clone().into(), + UsePlaceholder::Yes, + CanRequestImages::Yes); + match response { + // TODO Handle multipart/x-mixtape + Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) => { + + } + + Err(ImageState::LoadError) => { + *self.pending_request.borrow_mut() = ImageRequest { + state: State::Unavailable, + parsed_url: None, + source_url: None, + image: None, + metadata: None, + blocker: None, + final_url: None, + current_pixel_density: None, + }; + } + + } + } + + let this = Trusted::new(self); + let new_selected_source = selected_source.unwrap().to_string(); + // Step 15 + let _ = window.dom_manipulation_task_source().queue( + task!(image_load_event: move || { + let this = this.root(); + // Step 15.1 + if this.has_relevant_mutations() { + let mut pending_request = + *this.pending_request.borrow_mut(); + pending_request = ImageRequest { + state: State::Unavailable, + parsed_url: None, + source_url: None, + image: None, + metadata: None, + blocker: None, + final_url: None, + current_pixel_density: None, + }; + return; + } + + // Step 15.2 + *this.last_selected_source.borrow_mut() = Some(DOMString::from_string(new_selected_source)); + let mut current_request = this.current_request.borrow_mut(); + current_request.current_pixel_density = selected_pixel_density; + + // Step 15.3 + this.current_request.borrow_mut().state = State::CompletelyAvailable; + + // Step 15.4 ? + + // Step 15.5 + *this.current_request.borrow_mut() = *this.pending_request.borrow(); + *this.pending_request.borrow_mut() = ImageRequest { + state: State::Unavailable, + parsed_url: None, + source_url: None, + image: None, + metadata: None, + blocker: None, + final_url: None, + current_pixel_density: None, + }; + + // Step 15.6 ? + + // Step 15.7 + this.upcast::().fire_event(atom!("load")); + + }), + window.upcast(), + ); + + } + return; + } + + fn has_relevant_mutations(&self) -> bool { + return false; + } + fn new_inherited(local_name: LocalName, prefix: Option, document: &Document) -> HTMLImageElement { HTMLImageElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), @@ -962,7 +1141,10 @@ impl HTMLImageElement { pub enum ImageElementMicrotask { StableStateUpdateImageDataTask { elem: DomRoot, - generation: u32, + generation: u32, + }, + EnvironmentChangesTask { + elem: DomRoot, } } @@ -976,6 +1158,21 @@ impl MicrotaskRunnable for ImageElementMicrotask { elem.update_the_image_data_sync_steps(); } }, + &ImageElementMicrotask::EnvironmentChangesTask { ref elem } => { + // TODO: Handle multipart/x-mixed-replace + // Step 2 of https://html.spec.whatwg.org/multipage/#img-environment-changes, + let element = elem.upcast::(); + let has_src = element.has_attribute(&local_name!("srcset")); + let document = document_from_node(element); + let has_pending_request = match elem.image_request.get() { + ImageRequestPhase::Pending => true, + _ => false + }; + + if document.is_active() && has_src && !has_pending_request { + elem.react_to_environment_changes_sync_steps(); + } + }, } } } From 1b777966897183e3ecb6c2f4fcd796fc93f5ad3c Mon Sep 17 00:00:00 2001 From: nupurbaghel Date: Thu, 26 Jul 2018 02:06:40 +0530 Subject: [PATCH 2/2] add non-exhaustive cases --- components/script/dom/htmlimageelement.rs | 27 +++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index d16d2a15704ad..69a4d6faaf486 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -922,7 +922,7 @@ impl HTMLImageElement { } // Step 6 - if let Ok(img_url) = base_url.join(&String::from(src)) { + if let Ok(img_url) = base_url.join(&String::from(src.clone())) { // Step 7 let corsAttributeState = self.GetCrossOrigin(); @@ -937,7 +937,7 @@ impl HTMLImageElement { // Step 12 *self.pending_request.borrow_mut() = ImageRequest { state: State::Unavailable, - parsed_url: Some(img_url), + parsed_url: Some(img_url.clone()), source_url: None, image: None, metadata: None, @@ -955,7 +955,7 @@ impl HTMLImageElement { UsePlaceholder::No, CanRequestImages::No); - if let Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) = response { + if let Ok(ImageOrMetadataAvailable::ImageAvailable(_image, _url)) = response { } else { let window = window_from_node(self); @@ -967,9 +967,22 @@ impl HTMLImageElement { CanRequestImages::Yes); match response { // TODO Handle multipart/x-mixtape - Ok(ImageOrMetadataAvailable::ImageAvailable(image, url)) => { + Ok(ImageOrMetadataAvailable::ImageAvailable(_image, _url)) => { } + // TODO required for making response exhaustive, but what should it return ?? + Ok(ImageOrMetadataAvailable::MetadataAvailable(_m)) => { + + } + // TODO what here? + Err(ImageState::Pending(_id)) => { + //add_cache_listener_for_element(image_cache.clone(), id, self); + } + // TODO what here? + Err(ImageState::NotRequested(_id)) => { + //add_cache_listener_for_element(image_cache, id, self); + //self.fetch_request(img_url, id); + } Err(ImageState::LoadError) => { *self.pending_request.borrow_mut() = ImageRequest { @@ -988,7 +1001,7 @@ impl HTMLImageElement { } let this = Trusted::new(self); - let new_selected_source = selected_source.unwrap().to_string(); + let new_selected_source = src.to_string(); // Step 15 let _ = window.dom_manipulation_task_source().queue( task!(image_load_event: move || { @@ -996,8 +1009,8 @@ impl HTMLImageElement { // Step 15.1 if this.has_relevant_mutations() { let mut pending_request = - *this.pending_request.borrow_mut(); - pending_request = ImageRequest { + &*this.pending_request.borrow_mut(); + pending_request = &ImageRequest { state: State::Unavailable, parsed_url: None, source_url: None,