Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse srcset algo #10829

Closed
wants to merge 10 commits into from
@@ -394,6 +394,9 @@ impl ImageCache {
let result = self.get_image_or_meta_if_available(url, use_placeholder);
consumer.send(result).unwrap();
}
ImageCacheCommand::StoreDecodeImage(url, image_vector) => {
self.store_decode_image(url, image_vector);
}
};

None
@@ -588,6 +591,18 @@ impl ImageCache {
}
}
}

fn store_decode_image(&mut self,
ref_url: Url,
loaded_bytes: Vec<u8>) {
let (cache_result, load_key, pending_load) = self.pending_loads.get_cached(Arc::new(ref_url));
assert!(cache_result == CacheResult::Miss);
let action: ResponseAction = ResponseAction::ResponseComplete(Ok(()));
self.progress_sender.send(ResourceLoadInfo {
action: action,
key: load_key,
});
}
}

/// Create a new image cache.
@@ -92,6 +92,10 @@ pub enum ImageCacheCommand {
/// state and but its metadata has been made available, it will be sent as a response.
GetImageOrMetadataIfAvailable(Url, UsePlaceholder, IpcSender<Result<ImageOrMetadataAvailable, ImageState>>),

/// Instruct the cache to store this data as a newly-complete network request and continue
/// decoding the result into pixel data
StoreDecodeImage(Url, Vec<u8>),

/// Clients must wait for a response before shutting down the ResourceThread
Exit(IpcSender<()>),
}
@@ -157,6 +161,14 @@ impl ImageCacheThread {
receiver.recv().unwrap()
}

/// Decode the given image bytes and cache the result for the given URL.
pub fn store_complete_image_bytes(&self,
url: Url,
image_data: Vec<u8>) {
let msg = ImageCacheCommand::StoreDecodeImage(url, image_data);
self.chan.send(msg).unwrap();
}

/// Shutdown the image cache thread.
pub fn exit(&self) {
let (response_chan, response_port) = ipc::channel().unwrap();
@@ -29,9 +29,12 @@ use net_traits::image_cache_thread::{ImageResponder, ImageResponse};
use script_runtime::ScriptThreadEventCategory::UpdateReplacedElement;
use script_runtime::{CommonScriptMsg, ScriptChan};
use script_thread::Runnable;
use std::collections::LinkedList;
use std::sync::Arc;
use string_cache::Atom;
use style::values::specified::Length;
use url::Url;
use util;
use util::str::{DOMString, LengthOrPercentageOrAuto};

#[derive(JSTraceable, HeapSizeOf)]
@@ -43,6 +46,13 @@ enum State {
Broken,
}
#[derive(JSTraceable, HeapSizeOf)]
#[allow(dead_code)]
enum ParseState {
InDescriptor,
InParens,
AfterDescriptor,
}
#[derive(JSTraceable, HeapSizeOf)]
struct ImageRequest {
state: State,
url: Option<Url>,
@@ -247,6 +257,11 @@ impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-src
make_setter!(SetSrc, "src");

// https://html.spec.whatwg.org/multipage/#dom-img-srcset
//make_getter!(Srcset, "srcset");
// https://html.spec.whatwg.org/multipage/#dom-img-srcset
//make_setter!(SetsrcSet, "srcset");

// https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin
make_enumerated_getter!(CrossOrigin, "crossorigin", "anonymous", ("use-credentials"));
// https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin
@@ -398,3 +413,119 @@ fn image_dimension_setter(element: &Element, attr: Atom, value: u32) {
let value = AttrValue::Dimension(DOMString::from(value.to_string()), dim);
element.set_attribute(&attr, value);
}


struct ImageSource {
candidate: String,
length: Length,
}

fn collect_sequence_characters<'a, P>(s: &'a str, predicate: P)
-> (&'a str, &'a str)
where P: Fn(char) -> bool {
for (i, c) in s.chars().enumerate() {
if !predicate(c) {
return (&s[0..i], &s[i..]);
}
}
return (s, "");
}

fn parse_a_srcset_attribute(input: String) -> Vec<ImageSource> {
let position = &input;
let candidate: Vec<ImageSource> = Vec::new();
let(spaces, position) = collect_sequence_characters(position, |c| c ==',' || util::str::char_is_whitespace(c));
println!("{} {}", spaces, position);
let x = spaces.find(',');
match x {
Some(val) => println!("Parse Error"),
None => println!("No commas"),
}
if position == "" {
//Does something need to be asserted here? The algorithm says abort the steps is this condition exists
return candidate;
}
let (url, spaces) = collect_sequence_characters(position, |c| !util::str::char_is_whitespace(c));
let comma_count = url.chars().rev().take_while(|c| *c == ',').count();
let url: String = url.chars().take(url.chars().count() - comma_count).collect();
if comma_count > 1 {
println!("Parse Error (trailing commas)")
}

let mut descriptor = LinkedList::<String>::new();
// Descriptor Tokeniser: whitespace
let (space, position) = collect_sequence_characters(position, |c| util::str::char_is_whitespace(c));
let mut current_descriptor = String::new();
let mut state = ParseState::InDescriptor;
for (i, c) in position.chars().enumerate() {
match state {
ParseState::InDescriptor => {
match c {
' ' => {
if current_descriptor != "" {
descriptor.push_back(current_descriptor.clone());
state = ParseState::AfterDescriptor;
}
},
',' => { position.chars().enumerate();
if current_descriptor != "" {
descriptor.push_back(current_descriptor.clone());
state = ParseState::AfterDescriptor;
}
}
'(' => {
current_descriptor.push(c);
state = ParseState::InParens;
}
//Matching EOF
/*'' => { if current_descriptor != "" {
descriptor.push_back(current_descriptor.clone());
state = ParseState::AfterDescriptor;
}
}
*/
_ => {
current_descriptor.push(c);
}
}
}
ParseState::InParens =>{
match c {
'(' => {
current_descriptor.push(c);
state = ParseState::InDescriptor;
}
//Matching EOF
/*'' => { if current_descriptor != "" {
descriptor.push_back(current_descriptor.clone());
state = ParseState::AfterDescriptor;
}
}
*/
_ => {
current_descriptor.push(c);
}
}
}
ParseState::AfterDescriptor => {
match c {
' ' => {
state = ParseState::AfterDescriptor;
}
//Matching EOF
/*'' => { if current_descriptor != "" {
descriptor.push_back(current_descriptor.clone());
state = ParseState::AfterDescriptor;
}
}
*/
_ => {
state = ParseState::InDescriptor;
}
}
}
}
}
return candidate;
}

@@ -8,7 +8,7 @@
interface HTMLImageElement : HTMLElement {
attribute DOMString alt;
attribute DOMString src;
// attribute DOMString srcset;
// attribute DOMString srcset;
attribute DOMString crossOrigin;
attribute DOMString useMap;
attribute boolean isMap;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.