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

WIP #17808

Closed
wants to merge 5 commits into from
Closed

WIP #17808

Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Some generated files are not rendered by default. Learn more.

@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use app_units::{Au, AU_PER_PX};
use cssparser::{Parser, ParserInput};
use document_loader::{LoadType, LoadBlocker};
use dom::activation::Activatable;
use dom::attr::Attr;
@@ -52,10 +53,17 @@ use script_thread::{Runnable, ScriptThread};
use servo_url::ServoUrl;
use servo_url::origin::ImmutableOrigin;
use std::cell::{Cell, RefMut};
use std::char;
use std::default::Default;
use std::i32;
use std::sync::{Arc, Mutex};
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
use style::context::QuirksMode;
use style::media_queries::MediaQuery;
use style::parser::ParserContext;
use style::values::specified::{Length, ViewportPercentageLength};
use style::values::specified::length::NoCalcLength;
use style_traits::ParsingMode;
use task_source::TaskSource;

#[derive(Clone, Copy, HeapSizeOf, JSTraceable)]
@@ -66,6 +74,13 @@ enum State {
CompletelyAvailable,
Broken,
}

#[derive(PartialEq)]
#[derive(Debug)]
pub struct Size {
pub query: Option<MediaQuery>,
pub length: Length,
}
#[derive(Clone, Copy, HeapSizeOf, JSTraceable)]
enum ImageRequestPhase {
Pending,
@@ -780,6 +795,60 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> {
}
}

//https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute
pub fn parse_a_sizes_attribute(input: DOMString, width: Option<u32>) -> Vec<Size> {
let mut sizes = Vec::<Size>::new();
for unparsed_size in input.split(',') {
let whitespace = unparsed_size.chars().rev().take_while(|c| char::is_whitespace(*c)).count();
let trimmed: String = unparsed_size.chars().take(unparsed_size.chars().count() - whitespace).collect();

if trimmed.is_empty() {
continue;
}
let mut input = ParserInput::new(&trimmed);
let url = ServoUrl::parse("about:blank").unwrap();
let context = ParserContext::new_for_cssom(&url,
None,
ParsingMode::empty(),
QuirksMode::NoQuirks);
let mut parser = Parser::new(&mut input);
let length = parser.try(|i| Length::parse_non_negative(&context, i));
match length {
Ok(len) => sizes.push(Size {
length: len,
query: None
}),
Err(_) => {
let mut media_query_parser = parser;
let media_query = media_query_parser.try(|i| MediaQuery::parse(&context, i));
if let Ok(query) = media_query {
let length = Length::parse_non_negative(&context, &mut media_query_parser);
if let Ok(length) = length {
sizes.push(Size {
length: length,
query: Some(query)
})
}
}
},
}
}
if sizes.is_empty() {
let size = match width {
Some(w) => Size {
length: Length::from_px(w as f32),
query: None
},
None => Size {
length: Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))),
query: None
},
};
sizes.push(size);
}
sizes
}

impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-alt
make_getter!(Alt, "alt");
@@ -791,6 +860,11 @@ impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-src
make_setter!(SetSrc, "src");

// https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute
make_getter!(Sizes, "sizes");
// https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute
make_setter!(SetSizes, "sizes");

This comment has been minimized.

Copy link
@jdm

jdm Aug 31, 2017

Member

nit: remove this extra newline.

// https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin
fn GetCrossOrigin(&self) -> Option<DOMString> {
reflect_cross_origin_attribute(self.upcast::<Element>())
@@ -9,6 +9,8 @@ interface HTMLImageElement : HTMLElement {
attribute DOMString alt;
[CEReactions]
attribute DOMString src;
[CEReactions]
attribute DOMString sizes;
// [CEReactions]
// attribute DOMString srcset;
[CEReactions]
@@ -15,6 +15,10 @@ pub mod area {
pub use dom::htmlareaelement::{Area, Shape};
}

pub mod sizes {
pub use dom::htmlimageelement::{parse_a_sizes_attribute, Size};
}

pub mod size_of {
use dom::characterdata::CharacterData;
use dom::element::Element;
@@ -164,7 +164,7 @@ pub enum ExpressionKind {
/// http://dev.w3.org/csswg/mediaqueries-3/#media1
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Expression(ExpressionKind);
pub struct Expression(pub ExpressionKind);

impl Expression {
/// The kind of expression we're, just for unit testing.
@@ -14,3 +14,4 @@ euclid = "0.15"
msg = {path = "../../../components/msg"}
script = {path = "../../../components/script"}
servo_url = {path = "../../../components/url"}
style = {path = "../../../components/style"}
@@ -0,0 +1,101 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use script::test::DOMString;
use script::test::sizes::{parse_a_sizes_attribute, Size};
use style::media_queries::{MediaQuery, MediaQueryType};
use style::media_queries::Expression;
use style::servo::media_queries::{ExpressionKind, Range};
use style::values::specified::{Length, NoCalcLength, AbsoluteLength, ViewportPercentageLength};


pub fn test_length_for_no_default_provided(len: f32) -> Length {
let length = Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(len)));
return length;
}

#[test]
fn no_default_provided() {
let mut a = vec![];
let length = test_length_for_no_default_provided(100f32);
let size = Size { query: None, length: length };
a.push(size);
assert_eq!(parse_a_sizes_attribute(DOMString::new(), None), a);
}

pub fn test_length_for_default_provided(len: f32) -> Length {
let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len)));
return length;
}

#[test]
fn default_provided() {
let mut a = vec![];
let length = test_length_for_default_provided(2f32);
let size = Size { query: None, length: length };
a.push(size);

This comment has been minimized.

Copy link
@wafflespeanut

wafflespeanut Sep 24, 2017

Member

Nit: If it's just a single size, then let's have let a = vec![size]; (here and everywhere below)

assert_eq!(parse_a_sizes_attribute(DOMString::new(), Some(2)), a);
}

pub fn test_media_query(len: f32) -> MediaQuery {
let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len)));
let expr = Expression(ExpressionKind::Width(Range::Max(length)));
let media_query = MediaQuery {
qualifier: None,
media_type: MediaQueryType::All,
expressions: vec![expr]
};
media_query
}

pub fn test_length(len: f32) -> Length {
let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len)));
return length;
}

#[test]
fn one_value() {
let mut a = vec![];
let media_query = test_media_query(200f32);
let length = test_length(545f32);
let size = Size { query: Some(media_query), length: length };
a.push(size);
assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 200px) 545px"), None), a);
}

#[test]
fn more_then_one_value() {
let media_query = test_media_query(900f32);
let length = test_length(1000f32);
let size = Size { query: Some(media_query), length: length };
let media_query1 = test_media_query(900f32);
let length1 = test_length(50f32);
let size1 = Size { query: Some(media_query1), length: length1 };
let a = &[size, size1];
assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 900px) 1000px, (max-width: 900px) 50px"),
None), a);
}

#[test]
fn no_extra_whitespace() {
let mut a = vec![];
let media_query = test_media_query(200f32);
let length = test_length(545f32);
let size = Size { query: Some(media_query), length: length };
a.push(size);
assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 200px) 545px"), None), a);
}

#[test]
fn extra_whitespace() {
let media_query = test_media_query(900f32);
let length = test_length(1000f32);
let size = Size { query: Some(media_query), length: length };
let media_query1 = test_media_query(900f32);
let length1 = test_length(50f32);
let size1 = Size { query: Some(media_query1), length: length1 };
let a = &[size, size1];
assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 900px) 1000px, (max-width: 900px) 50px"),
None), a);
}
@@ -6,10 +6,12 @@ extern crate euclid;
extern crate msg;
extern crate script;
extern crate servo_url;
extern crate style;

#[cfg(test)] mod origin;
#[cfg(all(test, target_pointer_width = "64"))] mod size_of;
#[cfg(test)] mod textinput;
#[cfg(test)] mod headers;
#[cfg(test)] mod htmlareaelement;
#[cfg(test)] mod htmlimageelement;

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.