aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout_thread/lib.rs13
-rw-r--r--components/script/dom/css.rs7
-rw-r--r--components/script/dom/cssmediarule.rs5
-rw-r--r--components/script/dom/cssstyledeclaration.rs9
-rw-r--r--components/script/dom/csssupportsrule.rs4
-rw-r--r--components/script/dom/document.rs2
-rw-r--r--components/script/dom/element.rs3
-rw-r--r--components/script/dom/htmllinkelement.rs3
-rw-r--r--components/script/dom/htmlmetaelement.rs1
-rw-r--r--components/script/dom/htmlstyleelement.rs6
-rw-r--r--components/script/dom/medialist.rs13
-rw-r--r--components/script/dom/mediaquerylist.rs2
-rw-r--r--components/script/dom/window.rs4
-rw-r--r--components/script/stylesheet_loader.rs3
-rw-r--r--components/script_layout_interface/message.rs6
-rw-r--r--components/style/animation.rs3
-rw-r--r--components/style/encoding_support.rs5
-rw-r--r--components/style/gecko/media_queries.rs10
-rw-r--r--components/style/gecko/wrapper.rs4
-rw-r--r--components/style/keyframes.rs3
-rw-r--r--components/style/matching.rs3
-rw-r--r--components/style/media_queries.rs5
-rw-r--r--components/style/parser.rs17
-rw-r--r--components/style/properties/data.py3
-rw-r--r--components/style/properties/declaration_block.rs13
-rw-r--r--components/style/properties/helpers.mako.rs24
-rw-r--r--components/style/properties/helpers/animated_properties.mako.rs4
-rw-r--r--components/style/properties/longhand/border.mako.rs4
-rw-r--r--components/style/properties/longhand/box.mako.rs3
-rw-r--r--components/style/properties/longhand/font.mako.rs16
-rw-r--r--components/style/properties/longhand/inherited_table.mako.rs9
-rw-r--r--components/style/properties/longhand/inherited_text.mako.rs9
-rw-r--r--components/style/properties/longhand/margin.mako.rs1
-rw-r--r--components/style/properties/longhand/padding.mako.rs3
-rw-r--r--components/style/properties/longhand/position.mako.rs18
-rw-r--r--components/style/properties/properties.mako.rs23
-rw-r--r--components/style/properties/shorthand/background.mako.rs4
-rw-r--r--components/style/properties/shorthand/border.mako.rs7
-rw-r--r--components/style/properties/shorthand/margin.mako.rs3
-rw-r--r--components/style/properties/shorthand/padding.mako.rs3
-rw-r--r--components/style/servo/media_queries.rs8
-rw-r--r--components/style/stylesheets.rs37
-rw-r--r--components/style/stylist.rs34
-rw-r--r--components/style/values/computed/mod.rs4
-rw-r--r--components/style/values/specified/length.rs159
-rw-r--r--components/style/values/specified/mod.rs33
-rw-r--r--components/style/values/specified/position.rs31
-rw-r--r--components/style/viewport.rs8
-rw-r--r--ports/geckolib/glue.rs37
-rw-r--r--tests/unit/style/media_queries.rs5
-rw-r--r--tests/unit/style/parsing/image.rs2
-rw-r--r--tests/unit/style/parsing/length.rs4
-rw-r--r--tests/unit/style/parsing/mod.rs4
-rw-r--r--tests/unit/style/properties/mod.rs4
-rw-r--r--tests/unit/style/rule_tree/bench.rs2
-rw-r--r--tests/unit/style/stylesheets.rs6
-rw-r--r--tests/unit/style/viewport.rs23
-rw-r--r--tests/wpt/include.ini2
-rw-r--r--tests/wpt/metadata/MANIFEST.json2
-rw-r--r--tests/wpt/metadata/quirks-mode/blocks-ignore-line-height.html.ini11
-rw-r--r--tests/wpt/metadata/quirks-mode/hashless-hex-color.html.ini233
-rw-r--r--tests/wpt/metadata/quirks-mode/line-height-calculation.html.ini50
-rw-r--r--tests/wpt/metadata/quirks-mode/percentage-height-calculation.html.ini122
-rw-r--r--tests/wpt/metadata/quirks-mode/supports.html.ini8
-rw-r--r--tests/wpt/metadata/quirks-mode/table-cell-nowrap-minimum-width-calculation.html.ini5
-rw-r--r--tests/wpt/metadata/quirks-mode/table-cell-width-calculation.html.ini26
-rw-r--r--tests/wpt/metadata/quirks-mode/unitless-length.html.ini1129
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json10
-rw-r--r--tests/wpt/mozilla/tests/mozilla/unitless-length.html219
-rw-r--r--tests/wpt/web-platform-tests/quirks-mode/unitless-length.html19
70 files changed, 2321 insertions, 194 deletions
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index c17d3bd9b48..30d59180a3c 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -601,7 +601,7 @@ impl LayoutThread {
Msg::AddStylesheet(style_info) => {
self.handle_add_stylesheet(style_info, possibly_locked_rw_data)
}
- Msg::SetQuirksMode => self.handle_set_quirks_mode(possibly_locked_rw_data),
+ Msg::SetQuirksMode(mode) => self.handle_set_quirks_mode(possibly_locked_rw_data, mode),
Msg::GetRPC(response_chan) => {
response_chan.send(box LayoutRPCImpl(self.rw_data.clone()) as
Box<LayoutRPC + Send>).unwrap();
@@ -772,9 +772,11 @@ impl LayoutThread {
}
/// Sets quirks mode for the document, causing the quirks mode stylesheet to be used.
- fn handle_set_quirks_mode<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
+ fn handle_set_quirks_mode<'a, 'b>(&self,
+ possibly_locked_rw_data: &mut RwData<'a, 'b>,
+ quirks_mode: QuirksMode) {
let mut rw_data = possibly_locked_rw_data.lock();
- Arc::get_mut(&mut rw_data.stylist).unwrap().set_quirks_mode(true);
+ Arc::get_mut(&mut rw_data.stylist).unwrap().set_quirks_mode(quirks_mode);
possibly_locked_rw_data.block(rw_data);
}
@@ -1587,7 +1589,8 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
MediaList::empty(),
shared_lock.clone(),
None,
- &NullReporter))
+ &NullReporter,
+ QuirksMode::NoQuirks))
}
let shared_lock = SharedRwLock::new();
@@ -1600,7 +1603,7 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
for &(ref contents, ref url) in &opts::get().user_stylesheets {
user_or_user_agent_stylesheets.push(Stylesheet::from_bytes(
&contents, url.clone(), None, None, Origin::User, MediaList::empty(),
- shared_lock.clone(), None, &RustLogReporter));
+ shared_lock.clone(), None, &RustLogReporter, QuirksMode::NoQuirks));
}
let quirks_mode_stylesheet = try!(parse_ua_stylesheet(&shared_lock, "quirks-mode.css"));
diff --git a/components/script/dom/css.rs b/components/script/dom/css.rs
index 0e4a7f85065..72cdbfa5be6 100644
--- a/components/script/dom/css.rs
+++ b/components/script/dom/css.rs
@@ -9,6 +9,7 @@ use dom::bindings::reflector::Reflector;
use dom::bindings::str::DOMString;
use dom::window::Window;
use dom_struct::dom_struct;
+use style::context::QuirksMode;
use style::parser::{LengthParsingMode, ParserContext};
use style::stylesheets::CssRuleType;
use style::supports::{Declaration, parse_condition_or_declaration};
@@ -31,7 +32,8 @@ impl CSS {
let decl = Declaration { prop: property.into(), val: value.into() };
let url = win.Document().url();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Supports),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
decl.eval(&context)
}
@@ -42,7 +44,8 @@ impl CSS {
if let Ok(cond) = cond {
let url = win.Document().url();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Supports),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
cond.eval(&context)
} else {
false
diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs
index aff12e2e2ad..45bf65b1adf 100644
--- a/components/script/dom/cssmediarule.rs
+++ b/components/script/dom/cssmediarule.rs
@@ -5,6 +5,7 @@
use cssparser::Parser;
use dom::bindings::codegen::Bindings::CSSMediaRuleBinding;
use dom::bindings::codegen::Bindings::CSSMediaRuleBinding::CSSMediaRuleMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::js::{MutNullableJS, Root};
use dom::bindings::reflector::{DomObject, reflect_dom_object};
use dom::bindings::str::DOMString;
@@ -72,8 +73,10 @@ impl CSSMediaRule {
let global = self.global();
let win = global.as_window();
let url = win.get_url();
+ let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
let new_medialist = parse_media_query_list(&context, &mut input);
let mut guard = self.cssconditionrule.shared_lock().write();
diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs
index 22fd1194034..d0996f04567 100644
--- a/components/script/dom/cssstyledeclaration.rs
+++ b/components/script/dom/cssstyledeclaration.rs
@@ -256,9 +256,12 @@ impl CSSStyleDeclaration {
// Step 6
let window = self.owner.window();
+ let quirks_mode = window.Document().quirks_mode();
let result =
parse_one_declaration(id, &value, &self.owner.base_url(),
- window.css_error_reporter(), LengthParsingMode::Default);
+ window.css_error_reporter(),
+ LengthParsingMode::Default,
+ quirks_mode);
// Step 7
let parsed = match result {
@@ -434,11 +437,13 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration {
return Err(Error::NoModificationAllowed);
}
+ let quirks_mode = window.Document().quirks_mode();
self.owner.mutate_associated_block(|mut pdb, mut _changed| {
// Step 3
*pdb = parse_style_attribute(&value,
&self.owner.base_url(),
- window.css_error_reporter());
+ window.css_error_reporter(),
+ quirks_mode);
});
Ok(())
diff --git a/components/script/dom/csssupportsrule.rs b/components/script/dom/csssupportsrule.rs
index 3ac60a00e06..86aedf10864 100644
--- a/components/script/dom/csssupportsrule.rs
+++ b/components/script/dom/csssupportsrule.rs
@@ -61,8 +61,10 @@ impl CSSSupportsRule {
let global = self.global();
let win = global.as_window();
let url = win.Document().url();
+ let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Supports),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
let enabled = cond.eval(&context);
let mut guard = self.cssconditionrule.shared_lock().write();
let rule = self.supportsrule.write_with(&mut guard);
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index ab124ba1734..06b8f7596cf 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -542,7 +542,7 @@ impl Document {
self.quirks_mode.set(mode);
if mode == QuirksMode::Quirks {
- self.window.layout_chan().send(Msg::SetQuirksMode).unwrap();
+ self.window.layout_chan().send(Msg::SetQuirksMode(mode)).unwrap();
}
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 7b56b6c6e81..d6974fb9075 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -2196,7 +2196,8 @@ impl VirtualMethods for Element {
Arc::new(doc.style_shared_lock().wrap(parse_style_attribute(
&attr.value(),
&doc.base_url(),
- win.css_error_reporter())))
+ win.css_error_reporter(),
+ doc.quirks_mode())))
};
Some(block)
diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs
index c0d0d12a775..bf36d28b29d 100644
--- a/components/script/dom/htmllinkelement.rs
+++ b/components/script/dom/htmllinkelement.rs
@@ -282,7 +282,8 @@ impl HTMLLinkElement {
let win = document.window();
let doc_url = document.url();
let context = CssParserContext::new_for_cssom(&doc_url, win.css_error_reporter(), Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ document.quirks_mode());
let media = parse_media_query_list(&context, &mut css_parser);
let im_attribute = element.get_attribute(&ns!(), &local_name!("integrity"));
diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs
index 3c4e817a132..62d7215e3df 100644
--- a/components/script/dom/htmlmetaelement.rs
+++ b/components/script/dom/htmlmetaelement.rs
@@ -113,6 +113,7 @@ impl HTMLMetaElement {
// force all styles to be recomputed.
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
+ quirks_mode: document.quirks_mode(),
}));
let doc = document_from_node(self);
doc.invalidate_stylesheets();
diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs
index 0c026fcfe9a..8905c3baa65 100644
--- a/components/script/dom/htmlstyleelement.rs
+++ b/components/script/dom/htmlstyleelement.rs
@@ -76,6 +76,7 @@ impl HTMLStyleElement {
assert!(node.is_in_doc());
let win = window_from_node(node);
+ let doc = document_from_node(self);
let mq_attribute = element.get_attribute(&ns!(), &local_name!("media"));
let mq_str = match mq_attribute {
@@ -88,7 +89,8 @@ impl HTMLStyleElement {
let context = CssParserContext::new_for_cssom(&url,
win.css_error_reporter(),
Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ doc.quirks_mode());
let shared_lock = node.owner_doc().style_shared_lock().clone();
let mq = Arc::new(shared_lock.wrap(
parse_media_query_list(&context, &mut CssParser::new(&mq_str))));
@@ -96,6 +98,7 @@ impl HTMLStyleElement {
let sheet = Stylesheet::from_str(&data, win.get_url(), Origin::Author, mq,
shared_lock, Some(&loader),
win.css_error_reporter(),
+ doc.quirks_mode(),
self.line_number);
let sheet = Arc::new(sheet);
@@ -107,7 +110,6 @@ impl HTMLStyleElement {
win.layout_chan().send(Msg::AddStylesheet(sheet.clone())).unwrap();
*self.stylesheet.borrow_mut() = Some(sheet);
- let doc = document_from_node(self);
doc.invalidate_stylesheets();
}
diff --git a/components/script/dom/medialist.rs b/components/script/dom/medialist.rs
index 881c17966da..f2a2299d169 100644
--- a/components/script/dom/medialist.rs
+++ b/components/script/dom/medialist.rs
@@ -5,6 +5,7 @@
use cssparser::Parser;
use dom::bindings::codegen::Bindings::MediaListBinding;
use dom::bindings::codegen::Bindings::MediaListBinding::MediaListMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods;
use dom::bindings::js::{JS, Root};
use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object};
use dom::bindings::str::DOMString;
@@ -74,8 +75,10 @@ impl MediaListMethods for MediaList {
let global = self.global();
let win = global.as_window();
let url = win.get_url();
+ let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
*media_queries = parse_media_query_list(&context, &mut parser);
}
@@ -108,8 +111,10 @@ impl MediaListMethods for MediaList {
let global = self.global();
let win = global.as_window();
let url = win.get_url();
+ let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
let m = MediaQuery::parse(&context, &mut parser);
// Step 2
if let Err(_) = m {
@@ -134,8 +139,10 @@ impl MediaListMethods for MediaList {
let global = self.global();
let win = global.as_window();
let url = win.get_url();
+ let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, win.css_error_reporter(), Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
let m = MediaQuery::parse(&context, &mut parser);
// Step 2
if let Err(_) = m {
diff --git a/components/script/dom/mediaquerylist.rs b/components/script/dom/mediaquerylist.rs
index dafc7602794..b25e041f4ef 100644
--- a/components/script/dom/mediaquerylist.rs
+++ b/components/script/dom/mediaquerylist.rs
@@ -77,7 +77,7 @@ impl MediaQueryList {
if let Some(window_size) = self.document.window().window_size() {
let viewport_size = window_size.initial_viewport;
let device = Device::new(MediaType::Screen, viewport_size);
- self.media_query_list.evaluate(&device)
+ self.media_query_list.evaluate(&device, self.document.quirks_mode())
} else {
false
}
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index eaba1ded928..6b8857b81b1 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -976,8 +976,10 @@ impl WindowMethods for Window {
fn MatchMedia(&self, query: DOMString) -> Root<MediaQueryList> {
let mut parser = Parser::new(&query);
let url = self.get_url();
+ let quirks_mode = self.Document().quirks_mode();
let context = CssParserContext::new_for_cssom(&url, self.css_error_reporter(), Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
let media_query_list = media_queries::parse_media_query_list(&context, &mut parser);
let document = self.Document();
let mql = MediaQueryList::new(&document, media_query_list);
diff --git a/components/script/stylesheet_loader.rs b/components/script/stylesheet_loader.rs
index a859e798818..14b8c385e39 100644
--- a/components/script/stylesheet_loader.rs
+++ b/components/script/stylesheet_loader.rs
@@ -144,7 +144,8 @@ impl FetchResponseListener for StylesheetContext {
media.take().unwrap(),
shared_lock,
Some(&loader),
- win.css_error_reporter()));
+ win.css_error_reporter(),
+ document.quirks_mode()));
if link.is_alternate() {
sheet.set_disabled(true);
diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs
index 69dfd125e12..b94b6cd8d14 100644
--- a/components/script_layout_interface/message.rs
+++ b/components/script_layout_interface/message.rs
@@ -17,7 +17,7 @@ use script_traits::{LayoutMsg as ConstellationMsg, StackingContextScrollState, W
use servo_url::ServoUrl;
use std::sync::Arc;
use std::sync::mpsc::{Receiver, Sender};
-use style::context::ReflowGoal;
+use style::context::{QuirksMode, ReflowGoal};
use style::properties::PropertyId;
use style::selector_parser::PseudoElement;
use style::stylesheets::Stylesheet;
@@ -27,8 +27,8 @@ pub enum Msg {
/// Adds the given stylesheet to the document.
AddStylesheet(Arc<Stylesheet>),
- /// Puts a document into quirks mode, causing the quirks mode stylesheet to be loaded.
- SetQuirksMode,
+ /// Change the quirks mode.
+ SetQuirksMode(QuirksMode),
/// Requests a reflow.
Reflow(ScriptReflow),
diff --git a/components/style/animation.rs b/components/style/animation.rs
index 0a5a9921d2e..ed5a5c602f8 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -468,7 +468,8 @@ fn compute_style_for_animation_step(context: &SharedStyleContext,
/* cascade_info = */ None,
&*context.error_reporter,
font_metrics_provider,
- CascadeFlags::empty());
+ CascadeFlags::empty(),
+ context.quirks_mode);
computed
}
}
diff --git a/components/style/encoding_support.rs b/components/style/encoding_support.rs
index b61c743051f..2775de54893 100644
--- a/components/style/encoding_support.rs
+++ b/components/style/encoding_support.rs
@@ -6,6 +6,7 @@
extern crate encoding;
+use context::QuirksMode;
use cssparser::{stylesheet_encoding, EncodingSupport};
use error_reporting::ParseErrorReporter;
use media_queries::MediaList;
@@ -56,7 +57,8 @@ impl Stylesheet {
media: MediaList,
shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
- error_reporter: &ParseErrorReporter)
+ error_reporter: &ParseErrorReporter,
+ quirks_mode: QuirksMode)
-> Stylesheet {
let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding);
@@ -67,6 +69,7 @@ impl Stylesheet {
shared_lock,
stylesheet_loader,
error_reporter,
+ quirks_mode,
0u64)
}
diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs
index 4aff56ee8d5..8aa3b2da396 100644
--- a/components/style/gecko/media_queries.rs
+++ b/components/style/gecko/media_queries.rs
@@ -5,6 +5,7 @@
//! Gecko's media-query device and expression representation.
use app_units::Au;
+use context::QuirksMode;
use cssparser::{CssStringWriter, Parser, Token};
use euclid::Size2D;
use font_metrics::get_metrics_provider_for_product;
@@ -521,7 +522,7 @@ impl Expression {
}
/// Returns whether this media query evaluates to true for the given device.
- pub fn matches(&self, device: &Device) -> bool {
+ pub fn matches(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
let mut css_value = nsCSSValue::null();
unsafe {
(self.feature.mGetter.unwrap())(device.pres_context,
@@ -534,12 +535,13 @@ impl Expression {
None => return false,
};
- self.evaluate_against(device, &value)
+ self.evaluate_against(device, &value, quirks_mode)
}
fn evaluate_against(&self,
device: &Device,
- actual_value: &MediaExpressionValue)
+ actual_value: &MediaExpressionValue,
+ quirks_mode: QuirksMode)
-> bool {
use self::MediaExpressionValue::*;
use std::cmp::Ordering;
@@ -564,6 +566,8 @@ impl Expression {
style: default_values.clone(),
font_metrics_provider: &provider,
in_media_query: true,
+ // TODO: pass the correct value here.
+ quirks_mode: quirks_mode,
};
let required_value = match self.value {
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 62a2d835d1a..177aa5987b6 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -16,7 +16,7 @@
use app_units::Au;
use atomic_refcell::AtomicRefCell;
-use context::{SharedStyleContext, UpdateAnimationsTasks};
+use context::{QuirksMode, SharedStyleContext, UpdateAnimationsTasks};
use data::ElementData;
use dom::{self, AnimationRules, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
use dom::{OpaqueNode, PresentationalHintsSynthetizer};
@@ -325,7 +325,7 @@ impl<'le> GeckoElement<'le> {
/// Parse the style attribute of an element.
pub fn parse_style_attribute(value: &str,
url_data: &UrlExtraData) -> PropertyDeclarationBlock {
- parse_style_attribute(value, url_data, &RustLogReporter)
+ parse_style_attribute(value, url_data, &RustLogReporter, QuirksMode::NoQuirks)
}
fn flags(&self) -> u32 {
diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs
index fb8290fedf4..8113c06bb6c 100644
--- a/components/style/keyframes.rs
+++ b/components/style/keyframes.rs
@@ -131,7 +131,8 @@ impl Keyframe {
&parent_stylesheet.url_data,
&error_reporter,
Some(CssRuleType::Keyframe),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ parent_stylesheet.quirks_mode);
let mut input = Parser::new(css);
let mut rule_parser = KeyframeListParser {
diff --git a/components/style/matching.rs b/components/style/matching.rs
index b3696a0b7b7..2ac1e4d2e18 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -483,7 +483,8 @@ trait PrivateMatchMethods: TElement {
Some(&mut cascade_info),
&*shared_context.error_reporter,
font_metrics_provider,
- cascade_flags));
+ cascade_flags,
+ shared_context.quirks_mode));
cascade_info.finish(&self.as_node());
values
diff --git a/components/style/media_queries.rs b/components/style/media_queries.rs
index 10a29509bd1..4f1b3d68a12 100644
--- a/components/style/media_queries.rs
+++ b/components/style/media_queries.rs
@@ -7,6 +7,7 @@
//! [mq]: https://drafts.csswg.org/mediaqueries/
use Atom;
+use context::QuirksMode;
use cssparser::{Delimiter, Parser, Token};
use parser::ParserContext;
use serialize_comma_separated_list;
@@ -280,7 +281,7 @@ pub fn parse_media_query_list(context: &ParserContext, input: &mut Parser) -> Me
impl MediaList {
/// Evaluate a whole `MediaList` against `Device`.
- pub fn evaluate(&self, device: &Device) -> bool {
+ pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
// Check if it is an empty media query list or any queries match (OR condition)
// https://drafts.csswg.org/mediaqueries-4/#mq-list
self.media_queries.is_empty() || self.media_queries.iter().any(|mq| {
@@ -290,7 +291,7 @@ impl MediaList {
let query_match =
media_match &&
mq.expressions.iter()
- .all(|expression| expression.matches(&device));
+ .all(|expression| expression.matches(&device, quirks_mode));
// Apply the logical NOT qualifier to the result
match mq.qualifier {
diff --git a/components/style/parser.rs b/components/style/parser.rs
index b82d21ace4f..bac1252228a 100644
--- a/components/style/parser.rs
+++ b/components/style/parser.rs
@@ -6,6 +6,7 @@
#![deny(missing_docs)]
+use context::QuirksMode;
use cssparser::{Parser, SourcePosition, UnicodeRange};
use error_reporting::ParseErrorReporter;
use style_traits::OneOrMoreCommaSeparated;
@@ -44,6 +45,8 @@ pub struct ParserContext<'a> {
pub line_number_offset: u64,
/// The mode to use when parsing lengths.
pub length_parsing_mode: LengthParsingMode,
+ /// The quirks mode of this stylesheet.
+ pub quirks_mode: QuirksMode,
}
impl<'a> ParserContext<'a> {
@@ -52,7 +55,8 @@ impl<'a> ParserContext<'a> {
url_data: &'a UrlExtraData,
error_reporter: &'a ParseErrorReporter,
rule_type: Option<CssRuleType>,
- length_parsing_mode: LengthParsingMode)
+ length_parsing_mode: LengthParsingMode,
+ quirks_mode: QuirksMode)
-> ParserContext<'a> {
ParserContext {
stylesheet_origin: stylesheet_origin,
@@ -61,6 +65,7 @@ impl<'a> ParserContext<'a> {
rule_type: rule_type,
line_number_offset: 0u64,
length_parsing_mode: length_parsing_mode,
+ quirks_mode: quirks_mode,
}
}
@@ -68,9 +73,10 @@ impl<'a> ParserContext<'a> {
pub fn new_for_cssom(url_data: &'a UrlExtraData,
error_reporter: &'a ParseErrorReporter,
rule_type: Option<CssRuleType>,
- length_parsing_mode: LengthParsingMode)
+ length_parsing_mode: LengthParsingMode,
+ quirks_mode: QuirksMode)
-> ParserContext<'a> {
- Self::new(Origin::Author, url_data, error_reporter, rule_type, length_parsing_mode)
+ Self::new(Origin::Author, url_data, error_reporter, rule_type, length_parsing_mode, quirks_mode)
}
/// Create a parser context based on a previous context, but with a modified rule type.
@@ -84,6 +90,7 @@ impl<'a> ParserContext<'a> {
rule_type: rule_type,
line_number_offset: context.line_number_offset,
length_parsing_mode: context.length_parsing_mode,
+ quirks_mode: context.quirks_mode,
}
}
@@ -92,7 +99,8 @@ impl<'a> ParserContext<'a> {
url_data: &'a UrlExtraData,
error_reporter: &'a ParseErrorReporter,
line_number_offset: u64,
- length_parsing_mode: LengthParsingMode)
+ length_parsing_mode: LengthParsingMode,
+ quirks_mode: QuirksMode)
-> ParserContext<'a> {
ParserContext {
stylesheet_origin: stylesheet_origin,
@@ -101,6 +109,7 @@ impl<'a> ParserContext<'a> {
rule_type: None,
line_number_offset: line_number_offset,
length_parsing_mode: length_parsing_mode,
+ quirks_mode: quirks_mode,
}
}
diff --git a/components/style/properties/data.py b/components/style/properties/data.py
index c935e00a79f..8db09e6fe81 100644
--- a/components/style/properties/data.py
+++ b/components/style/properties/data.py
@@ -140,7 +140,7 @@ class Longhand(object):
need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False,
allowed_in_keyframe_block=True, complex_color=False, cast_type='u8',
has_uncacheable_values=False, logical=False, alias=None, extra_prefixes=None, boxed=False,
- flags=None, allowed_in_page_rule=False):
+ flags=None, allowed_in_page_rule=False, allow_quirks=False):
self.name = name
if not spec:
raise TypeError("Spec should be specified for %s" % name)
@@ -166,6 +166,7 @@ class Longhand(object):
self.boxed = arg_to_bool(boxed)
self.flags = flags.split() if flags else []
self.allowed_in_page_rule = arg_to_bool(allowed_in_page_rule)
+ self.allow_quirks = allow_quirks
# https://drafts.csswg.org/css-animations/#keyframes
# > The <declaration-list> inside of <keyframe-block> accepts any CSS property
diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs
index d652ab21c96..7b53a49626a 100644
--- a/components/style/properties/declaration_block.rs
+++ b/components/style/properties/declaration_block.rs
@@ -6,6 +6,7 @@
#![deny(missing_docs)]
+use context::QuirksMode;
use cssparser::{DeclarationListParser, parse_important};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter;
@@ -641,13 +642,15 @@ pub fn append_serialization<'a, W, I, N>(dest: &mut W,
/// shared between Servo and Gecko.
pub fn parse_style_attribute(input: &str,
url_data: &UrlExtraData,
- error_reporter: &ParseErrorReporter)
+ error_reporter: &ParseErrorReporter,
+ quirks_mode: QuirksMode)
-> PropertyDeclarationBlock {
let context = ParserContext::new(Origin::Author,
url_data,
error_reporter,
Some(CssRuleType::Style),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
parse_property_declaration_list(&context, &mut Parser::new(input))
}
@@ -660,13 +663,15 @@ pub fn parse_one_declaration(id: PropertyId,
input: &str,
url_data: &UrlExtraData,
error_reporter: &ParseErrorReporter,
- length_parsing_mode: LengthParsingMode)
+ length_parsing_mode: LengthParsingMode,
+ quirks_mode: QuirksMode)
-> Result<ParsedDeclaration, ()> {
let context = ParserContext::new(Origin::Author,
url_data,
error_reporter,
Some(CssRuleType::Style),
- length_parsing_mode);
+ length_parsing_mode,
+ quirks_mode);
Parser::new(input).parse_entirely(|parser| {
ParsedDeclaration::parse(id, &context, parser)
.map_err(|_| ())
diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs
index 5d13f91e282..478e1be659b 100644
--- a/components/style/properties/helpers.mako.rs
+++ b/components/style/properties/helpers.mako.rs
@@ -8,11 +8,13 @@
%>
<%def name="predefined_type(name, type, initial_value, parse_method='parse',
- needs_context=True, vector=False, computed_type=None, initial_specified_value=None, **kwargs)">
+ needs_context=True, vector=False, computed_type=None, initial_specified_value=None,
+ allow_quirks=False, **kwargs)">
<%def name="predefined_type_inner(name, type, initial_value, parse_method)">
#[allow(unused_imports)]
use app_units::Au;
use cssparser::{Color as CSSParserColor, RGBA};
+ use values::specified::AllowQuirks;
pub use values::specified::${type} as SpecifiedValue;
pub mod computed_value {
% if computed_type:
@@ -30,7 +32,9 @@
pub fn parse(context: &ParserContext,
input: &mut Parser)
-> Result<SpecifiedValue, ()> {
- % if needs_context:
+ % if allow_quirks:
+ specified::${type}::${parse_method}_quirky(context, input, AllowQuirks::Yes)
+ % elif needs_context:
specified::${type}::${parse_method}(context, input)
% else:
specified::${type}::${parse_method}(input)
@@ -277,6 +281,7 @@
% if not property.derived_from:
{
let custom_props = context.style().custom_properties();
+ let quirks_mode = context.quirks_mode;
::properties::substitute_variables_${property.ident}(
&declared_value, &custom_props,
|value| {
@@ -349,7 +354,7 @@
}
}
}
- }, error_reporter);
+ }, error_reporter, quirks_mode);
}
% if property.custom_cascade:
@@ -370,7 +375,11 @@
parse(context, input).map(|result| Box::new(result))
% else:
-> Result<SpecifiedValue, ()> {
- parse(context, input)
+ % if property.allow_quirks:
+ parse_quirky(context, input, specified::AllowQuirks::Yes)
+ % else:
+ parse(context, input)
+ % endif
% endif
}
pub fn parse_declared(context: &ParserContext, input: &mut Parser)
@@ -800,7 +809,8 @@
% endif
</%def>
-<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function, needs_context=True, **kwargs)">
+<%def name="four_sides_shorthand(name, sub_property_pattern, parser_function,
+ needs_context=True, allow_quirks=False, **kwargs)">
<% sub_properties=' '.join(sub_property_pattern % side for side in ['top', 'right', 'bottom', 'left']) %>
<%call expr="self.shorthand(name, sub_properties=sub_properties, **kwargs)">
#[allow(unused_imports)]
@@ -810,7 +820,9 @@
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let (top, right, bottom, left) =
- % if needs_context:
+ % if allow_quirks:
+ try!(parse_four_sides(input, |i| ${parser_function}_quirky(context, i, specified::AllowQuirks::Yes)));
+ % elif needs_context:
try!(parse_four_sides(input, |i| ${parser_function}(context, i)));
% else:
try!(parse_four_sides(input, ${parser_function}));
diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs
index cd384da294a..6e8cefc74c5 100644
--- a/components/style/properties/helpers/animated_properties.mako.rs
+++ b/components/style/properties/helpers/animated_properties.mako.rs
@@ -515,6 +515,7 @@ impl AnimationValue {
% if prop.animatable:
LonghandId::${prop.camel_case} => {
let mut result = None;
+ let quirks_mode = context.quirks_mode;
::properties::substitute_variables_${prop.ident}_slow(
&variables.css,
variables.first_token_type,
@@ -533,7 +534,8 @@ impl AnimationValue {
};
result = AnimationValue::from_declaration(&declaration, context, initial);
},
- &reporter);
+ &reporter,
+ quirks_mode);
result
},
% else:
diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs
index df5cb06f1cc..a540b515a82 100644
--- a/components/style/properties/longhand/border.mako.rs
+++ b/components/style/properties/longhand/border.mako.rs
@@ -33,7 +33,9 @@
computed_type="::app_units::Au",
alias=maybe_moz_logical_alias(product, side, "-moz-border-%s-width"),
spec=maybe_logical_spec(side, "width"),
- animation_value_type="ComputedValue", logical=side[1])}
+ animation_value_type="ComputedValue",
+ logical=side[1],
+ allow_quirks=not side[1])}
% endfor
${helpers.gecko_keyword_conversion(Keyword('border-style',
diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs
index 9afcae44701..9c445436d0f 100644
--- a/components/style/properties/longhand/box.mako.rs
+++ b/components/style/properties/longhand/box.mako.rs
@@ -264,6 +264,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
+ use values::specified::AllowQuirks;
<% vertical_align = data.longhands_by_name["vertical-align"] %>
<% vertical_align.keyword = Keyword("vertical-align",
@@ -306,7 +307,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
/// baseline | sub | super | top | text-top | middle | bottom | text-bottom
/// | <percentage> | <length>
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- input.try(|i| specified::LengthOrPercentage::parse(context, i))
+ input.try(|i| specified::LengthOrPercentage::parse_quirky(context, i, AllowQuirks::Yes))
.map(SpecifiedValue::LengthOrPercentage)
.or_else(|_| {
match_ignore_ascii_case! { &try!(input.expect_ident()),
diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs
index 6bdc67037d3..02df590ee9d 100644
--- a/components/style/properties/longhand/font.mako.rs
+++ b/components/style/properties/longhand/font.mako.rs
@@ -550,14 +550,14 @@ ${helpers.single_keyword_system("font-variant-caps",
</%helpers:longhand>
<%helpers:longhand name="font-size" need_clone="True" animation_value_type="ComputedValue"
- spec="https://drafts.csswg.org/css-fonts/#propdef-font-size">
+ allow_quirks="True" spec="https://drafts.csswg.org/css-fonts/#propdef-font-size">
use app_units::Au;
use properties::longhands::system_font::SystemFont;
use properties::style_structs::Font;
use std::fmt;
use style_traits::ToCss;
use values::{FONT_MEDIUM_PX, HasViewportPercentage};
- use values::specified::{FontRelativeLength, LengthOrPercentage, Length};
+ use values::specified::{AllowQuirks, FontRelativeLength, LengthOrPercentage, Length};
use values::specified::{NoCalcLength, Percentage};
use values::specified::length::FontBaseSize;
@@ -843,9 +843,19 @@ ${helpers.single_keyword_system("font-variant-caps",
))
}
}
+
/// <length> | <percentage> | <absolute-size> | <relative-size>
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- if let Ok(lop) = input.try(|i| specified::LengthOrPercentage::parse_non_negative(context, i)) {
+ parse_quirky(context, input, AllowQuirks::No)
+ }
+
+ /// Parses a font-size, with quirks.
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<SpecifiedValue, ()> {
+ use self::specified::LengthOrPercentage;
+ if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative_quirky(context, i, allow_quirks)) {
return Ok(SpecifiedValue::Length(lop))
}
diff --git a/components/style/properties/longhand/inherited_table.mako.rs b/components/style/properties/longhand/inherited_table.mako.rs
index a66de2691db..5caaa17195d 100644
--- a/components/style/properties/longhand/inherited_table.mako.rs
+++ b/components/style/properties/longhand/inherited_table.mako.rs
@@ -26,6 +26,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
+ use values::specified::{AllowQuirks, Length};
pub mod computed_value {
use app_units::Au;
@@ -73,8 +74,8 @@ ${helpers.single_keyword("caption-side", "top bottom",
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SpecifiedValue {
- pub horizontal: specified::Length,
- pub vertical: Option<specified::Length>,
+ pub horizontal: Length,
+ pub vertical: Option<Length>,
}
#[inline]
@@ -130,11 +131,11 @@ ${helpers.single_keyword("caption-side", "top bottom",
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
let mut first = None;
let mut second = None;
- match specified::Length::parse_non_negative(context, input) {
+ match Length::parse_non_negative_quirky(context, input, AllowQuirks::Yes) {
Err(()) => (),
Ok(length) => {
first = Some(length);
- if let Ok(len) = input.try(|input| specified::Length::parse_non_negative(context, input)) {
+ if let Ok(len) = input.try(|i| Length::parse_non_negative_quirky(context, i, AllowQuirks::Yes)) {
second = Some(len);
}
}
diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs
index bbd2f51964d..c2e85e43b4b 100644
--- a/components/style/properties/longhand/inherited_text.mako.rs
+++ b/components/style/properties/longhand/inherited_text.mako.rs
@@ -184,7 +184,8 @@ ${helpers.predefined_type("text-indent",
"LengthOrPercentage",
"computed::LengthOrPercentage::Length(Au(0))",
animation_value_type="ComputedValue",
- spec="https://drafts.csswg.org/css-text/#propdef-text-indent")}
+ spec="https://drafts.csswg.org/css-text/#propdef-text-indent",
+ allow_quirks=True)}
// Also known as "word-wrap" (which is more popular because of IE), but this is the preferred
// name per CSS-TEXT 6.2.
@@ -411,6 +412,7 @@ ${helpers.single_keyword("text-align-last",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
+ use values::specified::AllowQuirks;
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
@@ -487,7 +489,7 @@ ${helpers.single_keyword("text-align-last",
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
Ok(SpecifiedValue::Normal)
} else {
- specified::Length::parse(context, input).map(SpecifiedValue::Specified)
+ specified::Length::parse_quirky(context, input, AllowQuirks::Yes).map(SpecifiedValue::Specified)
}
}
</%helpers:longhand>
@@ -497,6 +499,7 @@ ${helpers.single_keyword("text-align-last",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
+ use values::specified::AllowQuirks;
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
@@ -572,7 +575,7 @@ ${helpers.single_keyword("text-align-last",
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
Ok(SpecifiedValue::Normal)
} else {
- specified::LengthOrPercentage::parse(context, input)
+ specified::LengthOrPercentage::parse_quirky(context, input, AllowQuirks::Yes)
.map(SpecifiedValue::Specified)
}
}
diff --git a/components/style/properties/longhand/margin.mako.rs b/components/style/properties/longhand/margin.mako.rs
index 1fe4e7cca61..5c8a62aa01f 100644
--- a/components/style/properties/longhand/margin.mako.rs
+++ b/components/style/properties/longhand/margin.mako.rs
@@ -15,6 +15,7 @@
${helpers.predefined_type("margin-%s" % side[0], "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Length(Au(0))",
alias=maybe_moz_logical_alias(product, side, "-moz-margin-%s"),
+ allow_quirks=not side[1],
animation_value_type="ComputedValue", logical = side[1], spec = spec,
allowed_in_page_rule=True)}
% endfor
diff --git a/components/style/properties/longhand/padding.mako.rs b/components/style/properties/longhand/padding.mako.rs
index 593deb769ac..ce74320f220 100644
--- a/components/style/properties/longhand/padding.mako.rs
+++ b/components/style/properties/longhand/padding.mako.rs
@@ -18,5 +18,6 @@
alias=maybe_moz_logical_alias(product, side, "-moz-padding-%s"),
animation_value_type="ComputedValue",
logical = side[1],
- spec = spec)}
+ spec = spec,
+ allow_quirks=not side[1])}
% endfor
diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs
index 3f995b10873..757c270bb49 100644
--- a/components/style/properties/longhand/position.mako.rs
+++ b/components/style/properties/longhand/position.mako.rs
@@ -13,7 +13,8 @@
${helpers.predefined_type(side, "LengthOrPercentageOrAuto",
"computed::LengthOrPercentageOrAuto::Auto",
spec="https://www.w3.org/TR/CSS2/visuren.html#propdef-%s" % side,
- animation_value_type="ComputedValue")}
+ animation_value_type="ComputedValue",
+ allow_quirks=True)}
% endfor
// offset-* logical properties, map to "top" / "left" / "bottom" / "right"
% for side in LOGICAL_SIDES:
@@ -157,6 +158,7 @@ ${helpers.predefined_type("flex-basis",
"computed::LengthOrPercentageOrAuto::Auto",
"parse_non_negative",
spec=spec % size,
+ allow_quirks=not logical,
animation_value_type="ComputedValue", logical = logical)}
% if product == "gecko":
% for min_max in ["min", "max"]:
@@ -177,7 +179,7 @@ ${helpers.predefined_type("flex-basis",
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
- use values::specified::${MinMax}Length;
+ use values::specified::{AllowQuirks, ${MinMax}Length};
impl HasViewportPercentage for SpecifiedValue {
fn has_viewport_percentage(&self) -> bool {
@@ -199,7 +201,11 @@ ${helpers.predefined_type("flex-basis",
${MinMax}Length::${initial}
}
fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
+ % if logical:
let ret = ${MinMax}Length::parse(context, input);
+ % else:
+ let ret = ${MinMax}Length::parse_quirky(context, input, AllowQuirks::Yes);
+ % endif
// Keyword values don't make sense in the block direction; don't parse them
% if "block" in size:
if let Ok(${MinMax}Length::ExtremumLength(..)) = ret {
@@ -254,13 +260,17 @@ ${helpers.predefined_type("flex-basis",
"computed::LengthOrPercentage::Length(Au(0))",
"parse_non_negative",
spec=spec % ("min-%s" % size),
- animation_value_type="ComputedValue", logical = logical)}
+ animation_value_type="ComputedValue",
+ logical=logical,
+ allow_quirks=not logical)}
${helpers.predefined_type("max-%s" % size,
"LengthOrPercentageOrNone",
"computed::LengthOrPercentageOrNone::None",
"parse_non_negative",
spec=spec % ("min-%s" % size),
- animation_value_type="ComputedValue", logical = logical)}
+ animation_value_type="ComputedValue",
+ logical=logical,
+ allow_quirks=not logical)}
% endif
% endfor
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index 60da6d89704..4a736c38e36 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -21,6 +21,7 @@ use cssparser::{Parser, TokenSerializationType};
use error_reporting::ParseErrorReporter;
#[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
use computed_values;
+use context::QuirksMode;
use font_metrics::FontMetricsProvider;
#[cfg(feature = "gecko")] use gecko_bindings::bindings;
#[cfg(feature = "gecko")] use gecko_bindings::structs::{self, nsCSSPropertyID};
@@ -328,7 +329,8 @@ impl PropertyDeclarationIdSet {
% endif
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
- error_reporter: &ParseErrorReporter)
+ error_reporter: &ParseErrorReporter,
+ quirks_mode: QuirksMode)
% if property.boxed:
where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>)
% else:
@@ -342,7 +344,8 @@ impl PropertyDeclarationIdSet {
with_variables.from_shorthand,
custom_properties,
f,
- error_reporter);
+ error_reporter,
+ quirks_mode);
} else {
f(value);
}
@@ -357,7 +360,8 @@ impl PropertyDeclarationIdSet {
from_shorthand: Option<ShorthandId>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
- error_reporter: &ParseErrorReporter)
+ error_reporter: &ParseErrorReporter,
+ quirks_mode: QuirksMode)
% if property.boxed:
where F: FnOnce(&DeclaredValue<Box<longhands::${property.ident}::SpecifiedValue>>)
% else:
@@ -375,7 +379,8 @@ impl PropertyDeclarationIdSet {
url_data,
error_reporter,
None,
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ quirks_mode);
Parser::new(&css).parse_entirely(|input| {
match from_shorthand {
None => {
@@ -2116,7 +2121,8 @@ pub fn cascade(device: &Device,
cascade_info: Option<<&mut CascadeInfo>,
error_reporter: &ParseErrorReporter,
font_metrics_provider: &FontMetricsProvider,
- flags: CascadeFlags)
+ flags: CascadeFlags,
+ quirks_mode: QuirksMode)
-> ComputedValues {
debug_assert_eq!(parent_style.is_some(), layout_parent_style.is_some());
let (is_root_element, inherited_style, layout_parent_style) = match parent_style {
@@ -2162,7 +2168,8 @@ pub fn cascade(device: &Device,
cascade_info,
error_reporter,
font_metrics_provider,
- flags)
+ flags,
+ quirks_mode)
}
/// NOTE: This function expects the declaration with more priority to appear
@@ -2177,7 +2184,8 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
mut cascade_info: Option<<&mut CascadeInfo>,
error_reporter: &ParseErrorReporter,
font_metrics_provider: &FontMetricsProvider,
- flags: CascadeFlags)
+ flags: CascadeFlags,
+ quirks_mode: QuirksMode)
-> ComputedValues
where F: Fn() -> I,
I: Iterator<Item = &'a PropertyDeclaration>,
@@ -2230,6 +2238,7 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
style: starting_style,
font_metrics_provider: font_metrics_provider,
in_media_query: false,
+ quirks_mode: quirks_mode,
};
// Set computed values, overwriting earlier declarations for the same
diff --git a/components/style/properties/shorthand/background.mako.rs b/components/style/properties/shorthand/background.mako.rs
index 8eaa94772f1..ab19507702f 100644
--- a/components/style/properties/shorthand/background.mako.rs
+++ b/components/style/properties/shorthand/background.mako.rs
@@ -194,8 +194,8 @@
sub_properties="background-position-x background-position-y"
spec="https://drafts.csswg.org/css-backgrounds-4/#the-background-position">
use properties::longhands::{background_position_x,background_position_y};
+ use values::specified::AllowQuirks;
use values::specified::position::Position;
- use parser::Parse;
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
let mut position_x = background_position_x::SpecifiedValue(Vec::new());
@@ -204,7 +204,7 @@
try!(input.parse_comma_separated(|input| {
loop {
- if let Ok(value) = input.try(|input| Position::parse(context, input)) {
+ if let Ok(value) = input.try(|input| Position::parse_quirky(context, input, AllowQuirks::Yes)) {
position_x.0.push(value.horizontal);
position_y.0.push(value.vertical);
any = true;
diff --git a/components/style/properties/shorthand/border.mako.rs b/components/style/properties/shorthand/border.mako.rs
index 00fc89b0cec..223e5069d59 100644
--- a/components/style/properties/shorthand/border.mako.rs
+++ b/components/style/properties/shorthand/border.mako.rs
@@ -17,11 +17,12 @@ ${helpers.four_sides_shorthand("border-style", "border-%s-style",
for side in PHYSICAL_SIDES)}"
spec="https://drafts.csswg.org/css-backgrounds/#border-width">
use super::parse_four_sides;
- use parser::Parse;
- use values::specified;
+ use values::specified::{AllowQuirks, BorderWidth};
pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
- let (top, right, bottom, left) = try!(parse_four_sides(input, |i| specified::BorderWidth::parse(context, i)));
+ let (top, right, bottom, left) = try!(parse_four_sides(input, |i| {
+ BorderWidth::parse_quirky(context, i, AllowQuirks::Yes)
+ }));
Ok(Longhands {
% for side in PHYSICAL_SIDES:
${to_rust_ident('border-%s-width' % side)}: ${side},
diff --git a/components/style/properties/shorthand/margin.mako.rs b/components/style/properties/shorthand/margin.mako.rs
index 4dcaa71e626..07b6ba6bbed 100644
--- a/components/style/properties/shorthand/margin.mako.rs
+++ b/components/style/properties/shorthand/margin.mako.rs
@@ -6,4 +6,5 @@
${helpers.four_sides_shorthand("margin", "margin-%s", "specified::LengthOrPercentageOrAuto::parse",
spec="https://drafts.csswg.org/css-box/#propdef-margin",
- allowed_in_page_rule=True)}
+ allowed_in_page_rule=True,
+ allow_quirks=True)}
diff --git a/components/style/properties/shorthand/padding.mako.rs b/components/style/properties/shorthand/padding.mako.rs
index a0e94f8bdcb..c07a80b1e04 100644
--- a/components/style/properties/shorthand/padding.mako.rs
+++ b/components/style/properties/shorthand/padding.mako.rs
@@ -5,4 +5,5 @@
<%namespace name="helpers" file="/helpers.mako.rs" />
${helpers.four_sides_shorthand("padding", "padding-%s", "specified::LengthOrPercentage::parse",
- spec="https://drafts.csswg.org/css-box-3/#propdef-padding")}
+ spec="https://drafts.csswg.org/css-box-3/#propdef-padding",
+ allow_quirks=True)}
diff --git a/components/style/servo/media_queries.rs b/components/style/servo/media_queries.rs
index c2ff1cb828d..4756d5bb705 100644
--- a/components/style/servo/media_queries.rs
+++ b/components/style/servo/media_queries.rs
@@ -5,6 +5,7 @@
//! Servo's media-query device and expression representation.
use app_units::Au;
+use context::QuirksMode;
use cssparser::Parser;
use euclid::{Size2D, TypedSize2D};
use font_metrics::ServoMetricsProvider;
@@ -128,12 +129,12 @@ impl Expression {
/// Evaluate this expression and return whether it matches the current
/// device.
- pub fn matches(&self, device: &Device) -> bool {
+ pub fn matches(&self, device: &Device, quirks_mode: QuirksMode) -> bool {
let viewport_size = device.au_viewport_size();
let value = viewport_size.width;
match self.0 {
ExpressionKind::Width(ref range) => {
- match range.to_computed_range(device) {
+ match range.to_computed_range(device, quirks_mode) {
Range::Min(ref width) => { value >= *width },
Range::Max(ref width) => { value <= *width },
Range::Eq(ref width) => { value == *width },
@@ -175,7 +176,7 @@ pub enum Range<T> {
}
impl Range<specified::Length> {
- fn to_computed_range(&self, device: &Device) -> Range<Au> {
+ fn to_computed_range(&self, device: &Device, quirks_mode: QuirksMode) -> Range<Au> {
let default_values = device.default_computed_values();
// http://dev.w3.org/csswg/mediaqueries3/#units
// em units are relative to the initial font-size.
@@ -192,6 +193,7 @@ impl Range<specified::Length> {
// ch units can exist in media queries.
font_metrics_provider: &ServoMetricsProvider,
in_media_query: true,
+ quirks_mode: quirks_mode,
};
match *self {
diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs
index 9986328cb00..97dfce4c51f 100644
--- a/components/style/stylesheets.rs
+++ b/components/style/stylesheets.rs
@@ -7,6 +7,7 @@
#![deny(missing_docs)]
use {Atom, Prefix, Namespace};
+use context::QuirksMode;
use counter_style::{CounterStyleRule, parse_counter_style_name, parse_counter_style_body};
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser};
use cssparser::{AtRuleType, RuleListParser, parse_one_rule};
@@ -263,6 +264,8 @@ pub struct Stylesheet {
pub dirty_on_viewport_size_change: AtomicBool,
/// Whether this stylesheet should be disabled.
pub disabled: AtomicBool,
+ /// The quirks mode of this stylesheet.
+ pub quirks_mode: QuirksMode,
}
@@ -415,7 +418,8 @@ impl CssRule {
&parent_stylesheet.url_data,
&error_reporter,
None,
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ parent_stylesheet.quirks_mode);
let mut input = Parser::new(css);
// nested rules are in the body state
@@ -663,7 +667,7 @@ impl Stylesheet {
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, url_data, existing.origin, &mut namespaces,
&existing.shared_lock, stylesheet_loader, error_reporter,
- 0u64);
+ existing.quirks_mode, 0u64);
*existing.namespaces.write() = namespaces;
existing.dirty_on_viewport_size_change
@@ -681,6 +685,7 @@ impl Stylesheet {
shared_lock: &SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
+ quirks_mode: QuirksMode,
line_number_offset: u64)
-> (Vec<CssRule>, bool) {
let mut rules = Vec::new();
@@ -691,7 +696,8 @@ impl Stylesheet {
shared_lock: shared_lock,
loader: stylesheet_loader,
context: ParserContext::new_with_line_number_offset(origin, url_data, error_reporter,
- line_number_offset, LengthParsingMode::Default),
+ line_number_offset, LengthParsingMode::Default,
+ quirks_mode),
state: Cell::new(State::Start),
};
@@ -726,11 +732,13 @@ impl Stylesheet {
shared_lock: SharedRwLock,
stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter,
- line_number_offset: u64) -> Stylesheet {
+ quirks_mode: QuirksMode,
+ line_number_offset: u64)
+ -> Stylesheet {
let mut namespaces = Namespaces::default();
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
css, &url_data, origin, &mut namespaces,
- &shared_lock, stylesheet_loader, error_reporter, line_number_offset
+ &shared_lock, stylesheet_loader, error_reporter, quirks_mode, line_number_offset,
);
Stylesheet {
origin: origin,
@@ -741,6 +749,7 @@ impl Stylesheet {
shared_lock: shared_lock,
dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
disabled: AtomicBool::new(false),
+ quirks_mode: quirks_mode,
}
}
@@ -769,7 +778,7 @@ impl Stylesheet {
///
/// Always true if no associated MediaList exists.
pub fn is_effective_for_device(&self, device: &Device, guard: &SharedRwLockReadGuard) -> bool {
- self.media.read_with(guard).evaluate(device)
+ self.media.read_with(guard).evaluate(device, self.quirks_mode)
}
/// Return an iterator over the effective rules within the style-sheet, as
@@ -781,7 +790,7 @@ impl Stylesheet {
#[inline]
pub fn effective_rules<F>(&self, device: &Device, guard: &SharedRwLockReadGuard, mut f: F)
where F: FnMut(&CssRule) {
- effective_rules(&self.rules.read_with(guard).0, device, guard, &mut f);
+ effective_rules(&self.rules.read_with(guard).0, device, self.quirks_mode, guard, &mut f);
}
/// Returns whether the stylesheet has been explicitly disabled through the
@@ -802,17 +811,22 @@ impl Stylesheet {
}
}
-fn effective_rules<F>(rules: &[CssRule], device: &Device, guard: &SharedRwLockReadGuard, f: &mut F)
-where F: FnMut(&CssRule) {
+fn effective_rules<F>(rules: &[CssRule],
+ device: &Device,
+ quirks_mode: QuirksMode,
+ guard: &SharedRwLockReadGuard,
+ f: &mut F)
+ where F: FnMut(&CssRule)
+{
for rule in rules {
f(rule);
rule.with_nested_rules_and_mq(guard, |rules, mq| {
if let Some(media_queries) = mq {
- if !media_queries.evaluate(device) {
+ if !media_queries.evaluate(device, quirks_mode) {
return
}
}
- effective_rules(rules, device, guard, f)
+ effective_rules(rules, device, quirks_mode, guard, f)
})
}
}
@@ -973,6 +987,7 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
namespaces: RwLock::new(Namespaces::default()),
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
+ quirks_mode: self.context.quirks_mode,
})
}
}, &mut |import_rule| {
diff --git a/components/style/stylist.rs b/components/style/stylist.rs
index 8791498f687..cb4848f3b98 100644
--- a/components/style/stylist.rs
+++ b/components/style/stylist.rs
@@ -8,6 +8,7 @@
use {Atom, LocalName};
use bit_vec::BitVec;
+use context::QuirksMode;
use data::ComputedStyle;
use dom::{AnimationRules, PresentationalHintsSynthetizer, TElement};
use error_reporting::RustLogReporter;
@@ -76,7 +77,7 @@ pub struct Stylist {
viewport_constraints: Option<ViewportConstraints>,
/// If true, the quirks-mode stylesheet is applied.
- quirks_mode: bool,
+ quirks_mode: QuirksMode,
/// If true, the device has changed, and the stylist needs to be updated.
is_device_dirty: bool,
@@ -166,7 +167,7 @@ impl Stylist {
viewport_constraints: None,
device: Arc::new(device),
is_device_dirty: true,
- quirks_mode: false,
+ quirks_mode: QuirksMode::NoQuirks,
element_map: PerPseudoElementSelectorMap::new(),
pseudos_map: Default::default(),
@@ -240,7 +241,7 @@ impl Stylist {
};
self.viewport_constraints =
- ViewportConstraints::maybe_new(&self.device, &cascaded_rule);
+ ViewportConstraints::maybe_new(&self.device, &cascaded_rule, self.quirks_mode);
if let Some(ref constraints) = self.viewport_constraints {
Arc::get_mut(&mut self.device).unwrap()
@@ -269,7 +270,7 @@ impl Stylist {
self.add_stylesheet(&stylesheet, guards.ua_or_user, extra_data);
}
- if self.quirks_mode {
+ if self.quirks_mode != QuirksMode::NoQuirks {
self.add_stylesheet(&ua_stylesheets.quirks_mode_stylesheet,
guards.ua_or_user, extra_data);
}
@@ -424,7 +425,8 @@ impl Stylist {
None,
&RustLogReporter,
font_metrics,
- cascade_flags);
+ cascade_flags,
+ self.quirks_mode);
ComputedStyle::new(rule_node, Arc::new(computed))
}
@@ -548,7 +550,8 @@ impl Stylist {
None,
&RustLogReporter,
font_metrics,
- CascadeFlags::empty());
+ CascadeFlags::empty(),
+ self.quirks_mode);
Some(ComputedStyle::new(rule_node, Arc::new(computed)))
}
@@ -581,22 +584,22 @@ impl Stylist {
};
self.viewport_constraints =
- ViewportConstraints::maybe_new(&device, &cascaded_rule);
+ ViewportConstraints::maybe_new(&device, &cascaded_rule, self.quirks_mode);
if let Some(ref constraints) = self.viewport_constraints {
device.account_for_viewport_rule(constraints);
}
fn mq_eval_changed(guard: &SharedRwLockReadGuard, rules: &[CssRule],
- before: &Device, after: &Device) -> bool {
+ before: &Device, after: &Device, quirks_mode: QuirksMode) -> bool {
for rule in rules {
let changed = rule.with_nested_rules_and_mq(guard, |rules, mq| {
if let Some(mq) = mq {
- if mq.evaluate(before) != mq.evaluate(after) {
+ if mq.evaluate(before, quirks_mode) != mq.evaluate(after, quirks_mode) {
return true
}
}
- mq_eval_changed(guard, rules, before, after)
+ mq_eval_changed(guard, rules, before, after, quirks_mode)
});
if changed {
return true
@@ -606,11 +609,11 @@ impl Stylist {
}
self.is_device_dirty |= stylesheets.iter().any(|stylesheet| {
let mq = stylesheet.media.read_with(guard);
- if mq.evaluate(&self.device) != mq.evaluate(&device) {
+ if mq.evaluate(&self.device, self.quirks_mode) != mq.evaluate(&device, self.quirks_mode) {
return true
}
- mq_eval_changed(guard, &stylesheet.rules.read_with(guard).0, &self.device, &device)
+ mq_eval_changed(guard, &stylesheet.rules.read_with(guard).0, &self.device, &device, self.quirks_mode)
});
self.device = Arc::new(device);
@@ -623,14 +626,14 @@ impl Stylist {
}
/// Sets the quirks mode of the document.
- pub fn set_quirks_mode(&mut self, enabled: bool) {
+ pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
// FIXME(emilio): We don't seem to change the quirks mode dynamically
// during multiple layout passes, but this is totally bogus, in the
// sense that it's updated asynchronously.
//
// This should probably be an argument to `update`, and use the quirks
// mode info in the `SharedLayoutContext`.
- self.quirks_mode = enabled;
+ self.quirks_mode = quirks_mode;
}
/// Returns the applicable CSS declarations for the given element.
@@ -893,7 +896,8 @@ impl Stylist {
None,
&RustLogReporter,
&metrics,
- CascadeFlags::empty()))
+ CascadeFlags::empty(),
+ self.quirks_mode))
}
}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index 4b4588fbe4f..9f739660877 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -4,6 +4,7 @@
//! Computed values.
+use context::QuirksMode;
use euclid::size::Size2D;
use font_metrics::FontMetricsProvider;
use media_queries::Device;
@@ -63,6 +64,9 @@ pub struct Context<'a> {
/// Whether or not we are computing the media list in a media query
pub in_media_query: bool,
+
+ /// The quirks mode of this context.
+ pub quirks_mode: QuirksMode,
}
impl<'a> Context<'a> {
diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs
index ff8bdaa548e..d3ebba44726 100644
--- a/components/style/values/specified/length.rs
+++ b/components/style/values/specified/length.rs
@@ -17,7 +17,7 @@ use std::ops::Mul;
use style_traits::ToCss;
use style_traits::values::specified::AllowedLengthType;
use stylesheets::CssRuleType;
-use super::{Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time, ToComputedValue};
+use super::{AllowQuirks, Angle, Number, SimplifiedValueNode, SimplifiedSumNode, Time, ToComputedValue};
use values::{Auto, CSSFloat, Either, FONT_MEDIUM_PX, HasViewportPercentage, None_, Normal};
use values::ExtremumLength;
use values::computed::{ComputedValueAsSpecified, Context};
@@ -563,13 +563,17 @@ impl Length {
}
#[inline]
- fn parse_internal(context: &ParserContext, input: &mut Parser, num_context: AllowedLengthType)
+ fn parse_internal(context: &ParserContext,
+ input: &mut Parser,
+ num_context: AllowedLengthType,
+ allow_quirks: AllowQuirks)
-> Result<Length, ()> {
match try!(input.next()) {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) =>
Length::parse_dimension(context, value.value, unit),
- Token::Number(ref value) => {
- if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() {
+ Token::Number(ref value) if num_context.is_ok(value.value) => {
+ if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() &&
+ !allow_quirks.allowed(context.quirks_mode) {
return Err(())
}
Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(value.value))))
@@ -585,7 +589,16 @@ impl Length {
/// Parse a non-negative length
#[inline]
pub fn parse_non_negative(context: &ParserContext, input: &mut Parser) -> Result<Length, ()> {
- Self::parse_internal(context, input, AllowedLengthType::NonNegative)
+ Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
+ }
+
+ /// Parse a non-negative length, allowing quirks.
+ #[inline]
+ pub fn parse_non_negative_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<Length, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::NonNegative, allow_quirks)
}
/// Get an absolute length from a px value.
@@ -605,7 +618,17 @@ impl Length {
impl Parse for Length {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- Self::parse_internal(context, input, AllowedLengthType::All)
+ Self::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl Length {
+ /// Parses a length, with quirks.
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<Self, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::All, allow_quirks)
}
}
@@ -616,7 +639,7 @@ impl<T: Parse> Either<Length, T> {
if let Ok(v) = input.try(|input| T::parse(context, input)) {
return Ok(Either::Second(v));
}
- Length::parse_internal(context, input, AllowedLengthType::NonNegative).map(Either::First)
+ Length::parse_internal(context, input, AllowedLengthType::NonNegative, AllowQuirks::No).map(Either::First)
}
}
@@ -1154,7 +1177,10 @@ impl LengthOrPercentage {
LengthOrPercentage::Length(NoCalcLength::zero())
}
- fn parse_internal(context: &ParserContext, input: &mut Parser, num_context: AllowedLengthType)
+ fn parse_internal(context: &ParserContext,
+ input: &mut Parser,
+ num_context: AllowedLengthType,
+ allow_quirks: AllowQuirks)
-> Result<LengthOrPercentage, ()>
{
match try!(input.next()) {
@@ -1162,12 +1188,9 @@ impl LengthOrPercentage {
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentage::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) =>
Ok(LengthOrPercentage::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) => {
- if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() {
- return Err(())
- }
- Ok(LengthOrPercentage::Length(NoCalcLength::Absolute(AbsoluteLength::Px(value.value))))
- }
+ Token::Number(value) if value.value == 0. ||
+ (num_context.is_ok(value.value) && allow_quirks.allowed(context.quirks_mode)) =>
+ Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value.value))),
Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {
let calc = try!(input.parse_nested_block(|i| {
CalcLengthOrPercentage::parse_length_or_percentage(context, i)
@@ -1181,14 +1204,23 @@ impl LengthOrPercentage {
/// Parse a non-negative length.
#[inline]
pub fn parse_non_negative(context: &ParserContext, input: &mut Parser) -> Result<LengthOrPercentage, ()> {
- Self::parse_internal(context, input, AllowedLengthType::NonNegative)
+ Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
+ }
+
+ /// Parse a non-negative length, with quirks.
+ #[inline]
+ pub fn parse_non_negative_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<LengthOrPercentage, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::NonNegative, allow_quirks)
}
/// Parse a length, treating dimensionless numbers as pixels
///
/// https://www.w3.org/TR/SVG2/types.html#presentation-attribute-css-value
pub fn parse_numbers_are_pixels(context: &ParserContext, input: &mut Parser) -> Result<LengthOrPercentage, ()> {
- if let Ok(lop) = input.try(|i| Self::parse_internal(context, i, AllowedLengthType::All)) {
+ if let Ok(lop) = input.try(|i| Self::parse(context, i)) {
return Ok(lop)
}
@@ -1204,7 +1236,7 @@ impl LengthOrPercentage {
pub fn parse_numbers_are_pixels_non_negative(context: &ParserContext,
input: &mut Parser)
-> Result<LengthOrPercentage, ()> {
- if let Ok(lop) = input.try(|i| Self::parse_internal(context, i, AllowedLengthType::NonNegative)) {
+ if let Ok(lop) = input.try(|i| Self::parse_non_negative(context, i)) {
return Ok(lop)
}
@@ -1230,7 +1262,18 @@ impl LengthOrPercentage {
impl Parse for LengthOrPercentage {
#[inline]
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- Self::parse_internal(context, input, AllowedLengthType::All)
+ Self::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl LengthOrPercentage {
+ /// Parses a length or a percentage, allowing the unitless length quirk.
+ /// https://quirks.spec.whatwg.org/#the-unitless-length-quirk
+ #[inline]
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks) -> Result<Self, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::All, allow_quirks)
}
}
@@ -1283,15 +1326,19 @@ impl ToCss for LengthOrPercentageOrAuto {
}
impl LengthOrPercentageOrAuto {
- fn parse_internal(context: &ParserContext, input: &mut Parser, num_context: AllowedLengthType)
+ fn parse_internal(context: &ParserContext,
+ input: &mut Parser,
+ num_context: AllowedLengthType,
+ allow_quirks: AllowQuirks)
-> Result<Self, ()> {
match try!(input.next()) {
Token::Dimension(ref value, ref unit) if num_context.is_ok(value.value) =>
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrAuto::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) =>
Ok(LengthOrPercentageOrAuto::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) if value.value == 0. => {
- if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() {
+ Token::Number(ref value) if num_context.is_ok(value.value) => {
+ if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() &&
+ !allow_quirks.allowed(context.quirks_mode) {
return Err(())
}
Ok(LengthOrPercentageOrAuto::Length(
@@ -1313,7 +1360,16 @@ impl LengthOrPercentageOrAuto {
/// Parse a non-negative length, percentage, or auto.
#[inline]
pub fn parse_non_negative(context: &ParserContext, input: &mut Parser) -> Result<LengthOrPercentageOrAuto, ()> {
- Self::parse_internal(context, input, AllowedLengthType::NonNegative)
+ Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
+ }
+
+ /// Parse a non-negative length, percentage, or auto.
+ #[inline]
+ pub fn parse_non_negative_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<Self, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::NonNegative, allow_quirks)
}
/// Returns the `auto` value.
@@ -1330,7 +1386,18 @@ impl LengthOrPercentageOrAuto {
impl Parse for LengthOrPercentageOrAuto {
#[inline]
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- Self::parse_internal(context, input, AllowedLengthType::All)
+ Self::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl LengthOrPercentageOrAuto {
+ /// Parses, with quirks.
+ #[inline]
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<Self, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::All, allow_quirks)
}
}
@@ -1367,7 +1434,10 @@ impl ToCss for LengthOrPercentageOrNone {
}
}
impl LengthOrPercentageOrNone {
- fn parse_internal(context: &ParserContext, input: &mut Parser, num_context: AllowedLengthType)
+ fn parse_internal(context: &ParserContext,
+ input: &mut Parser,
+ num_context: AllowedLengthType,
+ allow_quirks: AllowQuirks)
-> Result<LengthOrPercentageOrNone, ()>
{
match try!(input.next()) {
@@ -1375,8 +1445,9 @@ impl LengthOrPercentageOrNone {
NoCalcLength::parse_dimension(context, value.value, unit).map(LengthOrPercentageOrNone::Length),
Token::Percentage(ref value) if num_context.is_ok(value.unit_value) =>
Ok(LengthOrPercentageOrNone::Percentage(Percentage(value.unit_value))),
- Token::Number(ref value) if value.value == 0. => {
- if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() {
+ Token::Number(value) if num_context.is_ok(value.value) => {
+ if value.value != 0. && !context.length_parsing_mode.allows_unitless_lengths() &&
+ !allow_quirks.allowed(context.quirks_mode) {
return Err(())
}
Ok(LengthOrPercentageOrNone::Length(
@@ -1394,17 +1465,27 @@ impl LengthOrPercentageOrNone {
_ => Err(())
}
}
+
/// Parse a non-negative LengthOrPercentageOrNone.
#[inline]
pub fn parse_non_negative(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- Self::parse_internal(context, input, AllowedLengthType::NonNegative)
+ Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
+ }
+
+ /// Parse a non-negative LengthOrPercentageOrNone, with quirks.
+ #[inline]
+ pub fn parse_non_negative_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<Self, ()> {
+ Self::parse_internal(context, input, AllowedLengthType::NonNegative, allow_quirks)
}
}
impl Parse for LengthOrPercentageOrNone {
#[inline]
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- Self::parse_internal(context, input, AllowedLengthType::All)
+ Self::parse_internal(context, input, AllowedLengthType::All, AllowQuirks::No)
}
}
@@ -1548,8 +1629,17 @@ impl ToCss for MinLength {
impl Parse for MinLength {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
+ MinLength::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl MinLength {
+ /// Parses, with quirks.
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks) -> Result<Self, ()> {
input.try(ExtremumLength::parse).map(MinLength::ExtremumLength)
- .or_else(|()| input.try(|i| LengthOrPercentage::parse_non_negative(context, i))
+ .or_else(|()| input.try(|i| LengthOrPercentage::parse_non_negative_quirky(context, i, allow_quirks))
.map(MinLength::LengthOrPercentage))
.or_else(|()| input.expect_ident_matching("auto").map(|()| MinLength::Auto))
}
@@ -1589,8 +1679,17 @@ impl ToCss for MaxLength {
impl Parse for MaxLength {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
+ MaxLength::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl MaxLength {
+ /// Parses, with quirks.
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks) -> Result<Self, ()> {
input.try(ExtremumLength::parse).map(MaxLength::ExtremumLength)
- .or_else(|()| input.try(|i| LengthOrPercentage::parse_non_negative(context, i))
+ .or_else(|()| input.try(|i| LengthOrPercentage::parse_non_negative_quirky(context, i, allow_quirks))
.map(MaxLength::LengthOrPercentage))
.or_else(|()| {
match_ignore_ascii_case! { &try!(input.expect_ident()),
diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs
index 040728d8e77..c51027b864a 100644
--- a/components/style/values/specified/mod.rs
+++ b/components/style/values/specified/mod.rs
@@ -7,6 +7,7 @@
//! TODO(emilio): Enhance docs.
use app_units::Au;
+use context::QuirksMode;
use cssparser::{self, Parser, Token};
use euclid::size::Size2D;
use parser::{ParserContext, Parse};
@@ -490,7 +491,17 @@ pub enum BorderWidth {
impl Parse for BorderWidth {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<BorderWidth, ()> {
- match input.try(|i| Length::parse_non_negative(context, i)) {
+ Self::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl BorderWidth {
+ /// Parses a border width, allowing quirks.
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<BorderWidth, ()> {
+ match input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) {
Ok(length) => Ok(BorderWidth::Width(length)),
Err(_) => match_ignore_ascii_case! { &try!(input.expect_ident()),
"thin" => Ok(BorderWidth::Thin),
@@ -1281,13 +1292,13 @@ impl ToComputedValue for ClipRect {
impl Parse for ClipRect {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- use values::specified::Length;
+ use values::specified::{AllowQuirks, Length};
fn parse_argument(context: &ParserContext, input: &mut Parser) -> Result<Option<Length>, ()> {
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
Ok(None)
} else {
- Length::parse(context, input).map(Some)
+ Length::parse_quirky(context, input, AllowQuirks::Yes).map(Some)
}
}
@@ -1327,3 +1338,19 @@ pub type ClipRectOrAuto = Either<ClipRect, Auto>;
/// <color> | auto
pub type ColorOrAuto = Either<CSSColor, Auto>;
+
+/// Whether quirks are allowed in this context.
+#[derive(Clone, Copy, PartialEq)]
+pub enum AllowQuirks {
+ /// Quirks are allowed.
+ Yes,
+ /// Quirks are not allowed.
+ No,
+}
+
+impl AllowQuirks {
+ /// Returns `true` if quirks are allowed in this context.
+ pub fn allowed(self, quirks_mode: QuirksMode) -> bool {
+ self == AllowQuirks::Yes && quirks_mode == QuirksMode::Quirks
+ }
+}
diff --git a/components/style/values/specified/position.rs b/components/style/values/specified/position.rs
index f8501e870c2..dfa05b36609 100644
--- a/components/style/values/specified/position.rs
+++ b/components/style/values/specified/position.rs
@@ -19,7 +19,7 @@ use values::computed::position as computed_position;
use values::generics::position::{Position as GenericPosition, PositionValue, PositionWithKeyword};
use values::generics::position::HorizontalPosition as GenericHorizontalPosition;
use values::generics::position::VerticalPosition as GenericVerticalPosition;
-use values::specified::{LengthOrPercentage, Percentage};
+use values::specified::{AllowQuirks, LengthOrPercentage, Percentage};
pub use values::generics::position::Keyword;
@@ -132,13 +132,23 @@ impl Position {
impl Parse for Position {
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
- let first = input.try(|i| PositionComponent::parse(context, i))?;
- let second = input.try(|i| PositionComponent::parse(context, i))
+ Position::parse_quirky(context, input, AllowQuirks::No)
+ }
+}
+
+impl Position {
+ /// Parses, with quirks.
+ pub fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks)
+ -> Result<Self, ()> {
+ let first = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))?;
+ let second = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
.unwrap_or(Either::Second(Keyword::Center));
- if let Ok(third) = input.try(|i| PositionComponent::parse(context, i)) {
+ if let Ok(third) = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
// There's a 3rd value.
- if let Ok(fourth) = input.try(|i| PositionComponent::parse(context, i)) {
+ if let Ok(fourth) = input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
// There's a 4th value.
Position::from_components(Some(second), Some(fourth), Some(first), Some(third))
} else {
@@ -173,6 +183,17 @@ impl Parse for Position {
}
}
+impl PositionComponent {
+ /// Parses, with quirks.
+ fn parse_quirky(context: &ParserContext,
+ input: &mut Parser,
+ allow_quirks: AllowQuirks) -> Result<Self, ()> {
+ input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks))
+ .map(Either::First)
+ .or_else(|()| input.try(Keyword::parse).map(Either::Second))
+ }
+}
+
impl PositionValue<LengthOrPercentage> {
/// Generic function for the computed value of a position.
fn computed_value(&self, context: &Context) -> ComputedLengthOrPercentage {
diff --git a/components/style/viewport.rs b/components/style/viewport.rs
index 4c05ff52107..90811fa8549 100644
--- a/components/style/viewport.rs
+++ b/components/style/viewport.rs
@@ -10,6 +10,7 @@
#![deny(missing_docs)]
use app_units::Au;
+use context::QuirksMode;
use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser, parse_important};
use cssparser::ToCss as ParserToCss;
use euclid::size::TypedSize2D;
@@ -588,13 +589,15 @@ pub trait MaybeNew {
/// Create a ViewportConstraints from a viewport size and a `@viewport`
/// rule.
fn maybe_new(device: &Device,
- rule: &ViewportRule)
+ rule: &ViewportRule,
+ quirks_mode: QuirksMode)
-> Option<ViewportConstraints>;
}
impl MaybeNew for ViewportConstraints {
fn maybe_new(device: &Device,
- rule: &ViewportRule)
+ rule: &ViewportRule,
+ quirks_mode: QuirksMode)
-> Option<ViewportConstraints>
{
use std::cmp;
@@ -684,6 +687,7 @@ impl MaybeNew for ViewportConstraints {
style: device.default_computed_values().clone(),
font_metrics_provider: &provider,
in_media_query: false,
+ quirks_mode: quirks_mode,
};
// DEVICE-ADAPT § 9.3 Resolving 'extend-to-zoom'
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index 492b19eb9cc..f090a9f31dc 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -513,7 +513,7 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl
Arc::new(Stylesheet::from_str(
"", unsafe { dummy_url_data() }.clone(), origin,
Arc::new(shared_lock.wrap(MediaList::empty())),
- shared_lock, None, &RustLogReporter, 0u64)
+ shared_lock, None, &RustLogReporter, QuirksMode::NoQuirks, 0u64)
).into_strong()
}
@@ -556,7 +556,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
Arc::new(Stylesheet::from_str(
input, url_data.clone(), origin, media,
- shared_lock, loader, &RustLogReporter, 0u64)
+ shared_lock, loader, &RustLogReporter, QuirksMode::NoQuirks, 0u64)
).into_strong()
}
@@ -1012,7 +1012,8 @@ pub extern "C" fn Servo_ParseProperty(property: nsCSSPropertyID, value: *const n
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let reporter = RustLogReporter;
let context = ParserContext::new(Origin::Author, url_data, &reporter,
- Some(CssRuleType::Style), LengthParsingMode::Default);
+ Some(CssRuleType::Style), LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
match ParsedDeclaration::parse(id, &context, &mut Parser::new(value)) {
Ok(parsed) => {
@@ -1035,7 +1036,8 @@ pub extern "C" fn Servo_ParseEasing(easing: *const nsAString,
let url_data = unsafe { RefPtr::from_ptr_ref(&data) };
let reporter = RustLogReporter;
let context = ParserContext::new(Origin::Author, url_data, &reporter,
- Some(CssRuleType::Style), LengthParsingMode::Default);
+ Some(CssRuleType::Style), LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
let easing = unsafe { (*easing).to_string() };
match transition_timing_function::single_value::parse(&context, &mut Parser::new(&easing)) {
Ok(parsed_easing) => {
@@ -1176,7 +1178,7 @@ fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: Pro
structs::LengthParsingMode::SVG => LengthParsingMode::SVG,
};
if let Ok(parsed) = parse_one_declaration(property_id, value, url_data, &RustLogReporter,
- length_parsing_mode) {
+ length_parsing_mode, QuirksMode::NoQuirks) {
let importance = if is_important { Importance::Important } else { Importance::Normal };
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
parsed.expand_set_into(decls, importance)
@@ -1243,7 +1245,7 @@ pub extern "C" fn Servo_MediaList_Matches(list: RawServoMediaListBorrowed,
-> bool {
let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
read_locked_arc(list, |list: &MediaList| {
- list.evaluate(&per_doc_data.stylist.device)
+ list.evaluate(&per_doc_data.stylist.device, QuirksMode::NoQuirks)
})
}
@@ -1270,7 +1272,8 @@ pub extern "C" fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed, text:
let url_data = unsafe { dummy_url_data() };
let reporter = RustLogReporter;
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
write_locked_arc(list, |list: &mut MediaList| {
*list = parse_media_query_list(&context, &mut parser);
})
@@ -1301,7 +1304,8 @@ pub extern "C" fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed,
let url_data = unsafe { dummy_url_data() };
let reporter = RustLogReporter;
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
write_locked_arc(list, |list: &mut MediaList| {
list.append_medium(&context, new_medium);
})
@@ -1314,7 +1318,8 @@ pub extern "C" fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed,
let url_data = unsafe { dummy_url_data() };
let reporter = RustLogReporter;
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Media),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
write_locked_arc(list, |list: &mut MediaList| list.delete_medium(&context, old_medium))
}
@@ -1667,7 +1672,8 @@ pub extern "C" fn Servo_DeclarationBlock_SetBackgroundImage(declarations:
let string = unsafe { (*value).to_string() };
let error_reporter = RustLogReporter;
let context = ParserContext::new(Origin::Author, url_data, &error_reporter,
- Some(CssRuleType::Style), LengthParsingMode::Default);
+ Some(CssRuleType::Style), LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
if let Ok(url) = SpecifiedUrl::parse_from_string(string.into(), &context) {
let decl = PropertyDeclaration::BackgroundImage(BackgroundImage(
vec![SingleBackgroundImage(
@@ -1705,7 +1711,12 @@ pub extern "C" fn Servo_CSSSupports2(property: *const nsACString, value: *const
let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
let url_data = unsafe { dummy_url_data() };
- parse_one_declaration(id, &value, url_data, &RustLogReporter, LengthParsingMode::Default).is_ok()
+ parse_one_declaration(id,
+ &value,
+ url_data,
+ &RustLogReporter,
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks).is_ok()
}
#[no_mangle]
@@ -1717,7 +1728,8 @@ pub extern "C" fn Servo_CSSSupports(cond: *const nsACString) -> bool {
let url_data = unsafe { dummy_url_data() };
let reporter = RustLogReporter;
let context = ParserContext::new_for_cssom(url_data, &reporter, Some(CssRuleType::Style),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
cond.eval(&context)
} else {
false
@@ -1947,6 +1959,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
style: (**style).clone(),
font_metrics_provider: &metrics,
in_media_query: false,
+ quirks_mode: QuirksMode::NoQuirks,
};
for (index, keyframe) in keyframes.iter().enumerate() {
diff --git a/tests/unit/style/media_queries.rs b/tests/unit/style/media_queries.rs
index f256d296c9f..10634a6f134 100644
--- a/tests/unit/style/media_queries.rs
+++ b/tests/unit/style/media_queries.rs
@@ -8,6 +8,7 @@ use servo_url::ServoUrl;
use std::borrow::ToOwned;
use std::sync::Arc;
use style::Atom;
+use style::context::QuirksMode;
use style::error_reporting::ParseErrorReporter;
use style::media_queries::*;
use style::servo::media_queries::*;
@@ -37,7 +38,7 @@ fn test_media_rule<F>(css: &str, callback: F)
let media_list = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock,
- None, &CSSErrorReporterTest, 0u64);
+ None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0u64);
let mut rule_count = 0;
let guard = stylesheet.shared_lock.read();
media_queries(&guard, &stylesheet.rules.read_with(&guard).0, &mut |mq| {
@@ -66,7 +67,7 @@ fn media_query_test(device: &Device, css: &str, expected_rule_count: usize) {
let media_list = Arc::new(lock.wrap(MediaList::empty()));
let ss = Stylesheet::from_str(
css, url, Origin::Author, media_list, lock,
- None, &CSSErrorReporterTest, 0u64);
+ None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0u64);
let mut rule_count = 0;
ss.effective_style_rules(device, &ss.shared_lock.read(), |_| rule_count += 1);
assert!(rule_count == expected_rule_count, css.to_owned());
diff --git a/tests/unit/style/parsing/image.rs b/tests/unit/style/parsing/image.rs
index 78a6b04eed9..158f99aaa4e 100644
--- a/tests/unit/style/parsing/image.rs
+++ b/tests/unit/style/parsing/image.rs
@@ -5,6 +5,7 @@
use euclid::size::TypedSize2D;
use parsing::parse;
use std::f32::consts::PI;
+use style::context::QuirksMode;
use style::font_metrics::ServoMetricsProvider;
use style::media_queries::{Device, MediaType};
use style::properties::ComputedValues;
@@ -51,6 +52,7 @@ fn test_linear_gradient() {
style: initial_style.clone(),
font_metrics_provider: &ServoMetricsProvider,
in_media_query: false,
+ quirks_mode: QuirksMode::NoQuirks,
};
assert_eq!(specified::AngleOrCorner::None.to_computed_value(&specified_context),
computed::AngleOrCorner::Angle(Angle::from_radians(PI)));
diff --git a/tests/unit/style/parsing/length.rs b/tests/unit/style/parsing/length.rs
index ad0b77d2e01..b6d9a30b42c 100644
--- a/tests/unit/style/parsing/length.rs
+++ b/tests/unit/style/parsing/length.rs
@@ -5,6 +5,7 @@
use cssparser::Parser;
use media_queries::CSSErrorReporterTest;
use parsing::parse;
+use style::context::QuirksMode;
use style::parser::{LengthParsingMode, Parse, ParserContext};
use style::stylesheets::{CssRuleType, Origin};
use style::values::specified::length::{AbsoluteLength, Length, NoCalcLength};
@@ -38,7 +39,8 @@ fn test_length_parsing_modes() {
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let reporter = CSSErrorReporterTest;
let context = ParserContext::new(Origin::Author, &url, &reporter,
- Some(CssRuleType::Style), LengthParsingMode::SVG);
+ Some(CssRuleType::Style), LengthParsingMode::SVG,
+ QuirksMode::NoQuirks);
let mut parser = Parser::new("1");
let result = Length::parse(&context, &mut parser);
assert!(result.is_ok());
diff --git a/tests/unit/style/parsing/mod.rs b/tests/unit/style/parsing/mod.rs
index 79efb4a3484..6ba2043bd95 100644
--- a/tests/unit/style/parsing/mod.rs
+++ b/tests/unit/style/parsing/mod.rs
@@ -6,6 +6,7 @@
use cssparser::Parser;
use media_queries::CSSErrorReporterTest;
+use style::context::QuirksMode;
use style::parser::{LengthParsingMode, ParserContext};
use style::stylesheets::{CssRuleType, Origin};
@@ -13,7 +14,8 @@ fn parse<T, F: Fn(&ParserContext, &mut Parser) -> Result<T, ()>>(f: F, s: &str)
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let reporter = CSSErrorReporterTest;
let context = ParserContext::new(Origin::Author, &url, &reporter, Some(CssRuleType::Style),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
let mut parser = Parser::new(s);
f(&context, &mut parser)
}
diff --git a/tests/unit/style/properties/mod.rs b/tests/unit/style/properties/mod.rs
index 68aae4dacca..747b0bd6571 100644
--- a/tests/unit/style/properties/mod.rs
+++ b/tests/unit/style/properties/mod.rs
@@ -4,6 +4,7 @@
use cssparser::Parser;
use media_queries::CSSErrorReporterTest;
+use style::context::QuirksMode;
use style::parser::{LengthParsingMode, ParserContext};
use style::stylesheets::{CssRuleType, Origin};
@@ -11,7 +12,8 @@ fn parse<T, F: Fn(&ParserContext, &mut Parser) -> Result<T, ()>>(f: F, s: &str)
let url = ::servo_url::ServoUrl::parse("http://localhost").unwrap();
let reporter = CSSErrorReporterTest;
let context = ParserContext::new(Origin::Author, &url, &reporter, Some(CssRuleType::Style),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
let mut parser = Parser::new(s);
f(&context, &mut parser)
}
diff --git a/tests/unit/style/rule_tree/bench.rs b/tests/unit/style/rule_tree/bench.rs
index 96b63cfe2fb..ed73bd11d6f 100644
--- a/tests/unit/style/rule_tree/bench.rs
+++ b/tests/unit/style/rule_tree/bench.rs
@@ -6,6 +6,7 @@ use cssparser::{Parser, SourcePosition};
use rayon;
use servo_url::ServoUrl;
use std::sync::Arc;
+use style::context::QuirksMode;
use style::error_reporting::ParseErrorReporter;
use style::media_queries::MediaList;
use style::properties::{longhands, Importance, PropertyDeclaration, PropertyDeclarationBlock};
@@ -58,6 +59,7 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
lock,
None,
&ErrorringErrorReporter,
+ QuirksMode::NoQuirks,
0u64);
let guard = s.shared_lock.read();
let rules = s.rules.read_with(&guard);
diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs
index dd1762ee686..47aa1ea9730 100644
--- a/tests/unit/style/stylesheets.rs
+++ b/tests/unit/style/stylesheets.rs
@@ -13,6 +13,7 @@ use std::borrow::ToOwned;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::atomic::AtomicBool;
+use style::context::QuirksMode;
use style::error_reporting::ParseErrorReporter;
use style::keyframes::{Keyframe, KeyframeSelector, KeyframePercentage};
use style::media_queries::MediaList;
@@ -66,7 +67,7 @@ fn test_parse_stylesheet() {
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
- None, &CSSErrorReporterTest, 0u64);
+ None, &CSSErrorReporterTest, QuirksMode::NoQuirks, 0u64);
let mut namespaces = Namespaces::default();
namespaces.default = Some(ns!(html));
let expected = Stylesheet {
@@ -77,6 +78,7 @@ fn test_parse_stylesheet() {
url_data: url,
dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false),
+ quirks_mode: QuirksMode::NoQuirks,
rules: CssRules::new(vec![
CssRule::Namespace(Arc::new(stylesheet.shared_lock.wrap(NamespaceRule {
prefix: None,
@@ -316,7 +318,7 @@ fn test_report_error_stylesheet() {
let lock = SharedRwLock::new();
let media = Arc::new(lock.wrap(MediaList::empty()));
Stylesheet::from_str(css, url.clone(), Origin::UserAgent, media, lock,
- None, &error_reporter, 5u64);
+ None, &error_reporter, QuirksMode::NoQuirks, 5u64);
let mut errors = errors.lock().unwrap();
diff --git a/tests/unit/style/viewport.rs b/tests/unit/style/viewport.rs
index 150546ee588..fb29e87debf 100644
--- a/tests/unit/style/viewport.rs
+++ b/tests/unit/style/viewport.rs
@@ -8,6 +8,7 @@ use media_queries::CSSErrorReporterTest;
use servo_config::prefs::{PREFS, PrefValue};
use servo_url::ServoUrl;
use std::sync::Arc;
+use style::context::QuirksMode;
use style::media_queries::{Device, MediaList, MediaType};
use style::parser::{LengthParsingMode, Parse, ParserContext};
use style::shared_lock::SharedRwLock;
@@ -32,6 +33,7 @@ macro_rules! stylesheet {
$shared_lock,
None,
&$error_reporter,
+ QuirksMode::NoQuirks,
0u64
))
}
@@ -293,7 +295,8 @@ fn constrain_viewport() {
let url = ServoUrl::parse("http://localhost").unwrap();
let reporter = CSSErrorReporterTest;
let context = ParserContext::new(Origin::Author, &url, &reporter, Some(CssRuleType::Viewport),
- LengthParsingMode::Default);
+ LengthParsingMode::Default,
+ QuirksMode::NoQuirks);
macro_rules! from_css {
($css:expr) => {
@@ -303,9 +306,9 @@ fn constrain_viewport() {
let initial_viewport = TypedSize2D::new(800., 600.);
let device = Device::new(MediaType::Screen, initial_viewport);
- assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("")), None);
+ assert_eq!(ViewportConstraints::maybe_new(&device, from_css!(""), QuirksMode::NoQuirks), None);
- assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 320px auto")),
+ assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 320px auto"), QuirksMode::NoQuirks),
Some(ViewportConstraints {
size: initial_viewport,
@@ -317,7 +320,7 @@ fn constrain_viewport() {
orientation: Orientation::Auto
}));
- assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 320px auto")),
+ assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 320px auto"), QuirksMode::NoQuirks),
Some(ViewportConstraints {
size: initial_viewport,
@@ -329,10 +332,12 @@ fn constrain_viewport() {
orientation: Orientation::Auto
}));
- assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 800px; height: 600px;\
- zoom: 1;\
- user-zoom: zoom;\
- orientation: auto;")),
+ assert_eq!(ViewportConstraints::maybe_new(&device,
+ from_css!("width: 800px; height: 600px;\
+ zoom: 1;\
+ user-zoom: zoom;\
+ orientation: auto;"),
+ QuirksMode::NoQuirks),
Some(ViewportConstraints {
size: initial_viewport,
@@ -346,7 +351,7 @@ fn constrain_viewport() {
let initial_viewport = TypedSize2D::new(200., 150.);
let device = Device::new(MediaType::Screen, initial_viewport);
- assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 320px auto")),
+ assert_eq!(ViewportConstraints::maybe_new(&device, from_css!("width: 320px auto"), QuirksMode::NoQuirks),
Some(ViewportConstraints {
size: TypedSize2D::new(320., 240.),
diff --git a/tests/wpt/include.ini b/tests/wpt/include.ini
index 201a69c5b98..795d3bbe2f5 100644
--- a/tests/wpt/include.ini
+++ b/tests/wpt/include.ini
@@ -43,6 +43,8 @@ skip: true
skip: true
[script_scheduling]
skip: false
+[quirks-mode]
+ skip: false
[referrer-policy]
skip: false
[subresource-integrity]
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index fc43eb22216..90d74745236 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -586960,7 +586960,7 @@
"testharness"
],
"quirks-mode/unitless-length.html": [
- "1e896cad5c89bfe1756af5db60b61bc9fa93f61b",
+ "578d2aed4afa7cd6739610d353aebc591d832418",
"testharness"
],
"referrer-policy/OWNERS": [
diff --git a/tests/wpt/metadata/quirks-mode/blocks-ignore-line-height.html.ini b/tests/wpt/metadata/quirks-mode/blocks-ignore-line-height.html.ini
new file mode 100644
index 00000000000..3979d3098e2
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/blocks-ignore-line-height.html.ini
@@ -0,0 +1,11 @@
+[blocks-ignore-line-height.html]
+ type: testharness
+ [The blocks ignore line-height quirk, #ref { display:block }<div id=test><font size=1>x</font></div><font id=ref size=1>x</font><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The blocks ignore line-height quirk, #ref { display:block }<div id=test><font size=1>x</font><br><font size=1>x</font></div><font id=ref size=1>x<br>x</font><div id=s_ref>x<br>x</div>]
+ expected: FAIL
+
+ [The blocks ignore line-height quirk, #ref { display:block } div, #ref { line-height:2 } span { font-size:50% }<div id=test><span>x</span></div><span id=ref>x</span><div id=s_ref>x</div>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/hashless-hex-color.html.ini b/tests/wpt/metadata/quirks-mode/hashless-hex-color.html.ini
new file mode 100644
index 00000000000..0834442c891
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/hashless-hex-color.html.ini
@@ -0,0 +1,233 @@
+[hashless-hex-color.html]
+ type: testharness
+ [123 (quirks)]
+ expected: FAIL
+
+ [023 (quirks)]
+ expected: FAIL
+
+ [003 (quirks)]
+ expected: FAIL
+
+ [000 (quirks)]
+ expected: FAIL
+
+ [abc (quirks)]
+ expected: FAIL
+
+ [ABC (quirks)]
+ expected: FAIL
+
+ [1ab (quirks)]
+ expected: FAIL
+
+ [1AB (quirks)]
+ expected: FAIL
+
+ [112233 (quirks)]
+ expected: FAIL
+
+ [012233 (quirks)]
+ expected: FAIL
+
+ [002233 (quirks)]
+ expected: FAIL
+
+ [000233 (quirks)]
+ expected: FAIL
+
+ [000033 (quirks)]
+ expected: FAIL
+
+ [000003 (quirks)]
+ expected: FAIL
+
+ [000000 (quirks)]
+ expected: FAIL
+
+ [aabbcc (quirks)]
+ expected: FAIL
+
+ [AABBCC (quirks)]
+ expected: FAIL
+
+ [11aabb (quirks)]
+ expected: FAIL
+
+ [11AABB (quirks)]
+ expected: FAIL
+
+ [\\31 23 (quirks)]
+ expected: FAIL
+
+ [\\61 bc (quirks)]
+ expected: FAIL
+
+ [\\41 BC (quirks)]
+ expected: FAIL
+
+ [\\31 ab (quirks)]
+ expected: FAIL
+
+ [\\31 AB (quirks)]
+ expected: FAIL
+
+ [\\31 12233 (quirks)]
+ expected: FAIL
+
+ [\\61 abbcc (quirks)]
+ expected: FAIL
+
+ [\\41 ABBCC (quirks)]
+ expected: FAIL
+
+ [\\31 1aabb (quirks)]
+ expected: FAIL
+
+ [\\31 1AABB (quirks)]
+ expected: FAIL
+
+ [12\\33 (quirks)]
+ expected: FAIL
+
+ [1 (quirks)]
+ expected: FAIL
+
+ [12 (quirks)]
+ expected: FAIL
+
+ [1234 (quirks)]
+ expected: FAIL
+
+ [12345 (quirks)]
+ expected: FAIL
+
+ [1a (quirks)]
+ expected: FAIL
+
+ [1abc (quirks)]
+ expected: FAIL
+
+ [1abcd (quirks)]
+ expected: FAIL
+
+ [+1 (quirks)]
+ expected: FAIL
+
+ [+12 (quirks)]
+ expected: FAIL
+
+ [+123 (quirks)]
+ expected: FAIL
+
+ [+1234 (quirks)]
+ expected: FAIL
+
+ [+12345 (quirks)]
+ expected: FAIL
+
+ [+123456 (quirks)]
+ expected: FAIL
+
+ [+1a (quirks)]
+ expected: FAIL
+
+ [+12a (quirks)]
+ expected: FAIL
+
+ [+123a (quirks)]
+ expected: FAIL
+
+ [+1234a (quirks)]
+ expected: FAIL
+
+ [+12345a (quirks)]
+ expected: FAIL
+
+ [+1A (quirks)]
+ expected: FAIL
+
+ [+12A (quirks)]
+ expected: FAIL
+
+ [+123A (quirks)]
+ expected: FAIL
+
+ [+1234A (quirks)]
+ expected: FAIL
+
+ [+12345A (quirks)]
+ expected: FAIL
+
+ [rgb(calc(100 + 155), 255, 255) (quirks)]
+ expected: FAIL
+
+ [rgb(calc(100 + 155), 255, 255) (almost standards)]
+ expected: FAIL
+
+ [rgb(calc(100 + 155), 255, 255) (standards)]
+ expected: FAIL
+
+ [rgba(calc(100 + 155), 255, 255, 001) (quirks)]
+ expected: FAIL
+
+ [rgba(calc(100 + 155), 255, 255, 001) (almost standards)]
+ expected: FAIL
+
+ [rgba(calc(100 + 155), 255, 255, 001) (standards)]
+ expected: FAIL
+
+ [hsl(calc(050 + 050), 100%, 100%) (quirks)]
+ expected: FAIL
+
+ [hsl(calc(050 + 050), 100%, 100%) (almost standards)]
+ expected: FAIL
+
+ [hsl(calc(050 + 050), 100%, 100%) (standards)]
+ expected: FAIL
+
+ [hsla(calc(050 + 050), 100%, 100%, 001) (quirks)]
+ expected: FAIL
+
+ [hsla(calc(050 + 050), 100%, 100%, 001) (almost standards)]
+ expected: FAIL
+
+ [hsla(calc(050 + 050), 100%, 100%, 001) (standards)]
+ expected: FAIL
+
+ [rgb(calc(/**/100/**/ + /**/155/**/), 255, 255) (quirks)]
+ expected: FAIL
+
+ [rgb(calc(/**/100/**/ + /**/155/**/), 255, 255) (almost standards)]
+ expected: FAIL
+
+ [rgb(calc(/**/100/**/ + /**/155/**/), 255, 255) (standards)]
+ expected: FAIL
+
+ [#123 123 abc 12a (quirks)]
+ expected: FAIL
+
+ [#123 123 abc 12a (almost standards)]
+ expected: FAIL
+
+ [#123 123 abc 12a (standards)]
+ expected: FAIL
+
+ [rgb(119, 255, 255) 123 (quirks)]
+ expected: FAIL
+
+ [rgb(119, 255, 255) 123 (almost standards)]
+ expected: FAIL
+
+ [rgb(119, 255, 255) 123 (standards)]
+ expected: FAIL
+
+ [123 rgb(119, 255, 255) (quirks)]
+ expected: FAIL
+
+ [123 rgb(119, 255, 255) (almost standards)]
+ expected: FAIL
+
+ [123 rgb(119, 255, 255) (standards)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/line-height-calculation.html.ini b/tests/wpt/metadata/quirks-mode/line-height-calculation.html.ini
new file mode 100644
index 00000000000..59aa0a298ce
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/line-height-calculation.html.ini
@@ -0,0 +1,50 @@
+[line-height-calculation.html]
+ type: testharness
+ [The line height calculation quirk, <div id=test><img src="{png}"></div><img id=ref src="{png}"><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, <table><tr><td id=test><img src="{png}"><tr><td><img id=ref src="{png}"><tr><td id=s_ref>x</table>]
+ expected: FAIL
+
+ [The line height calculation quirk, <pre id=test><img src="{png}"></pre><img id=ref src="{png}"><pre id=s_ref>x</pre>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { margin:1px }<div id=test><span></span></div><div id=ref></div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { margin:0 1px }<div id=test><span></span></div><div id=ref></div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { margin:0 1px; padding:1px 0 }<div id=test><span></span></div><div id=ref></div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { border-right:1px solid }<div id=test><span></span></div><div id=ref>x</div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { border-left:1px solid }<div id=test><span></span></div><div id=ref>x</div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { padding-right:1px }<div id=test><span></span></div><div id=ref>x</div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { padding-left:1px }<div id=test><span></span></div><div id=ref>x</div><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, span { display:inline-block; height:1px }<div id=test><i><span></span> </i></div><span id=ref></span><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, <div id=test><img src="{png}" border=1></div><img id=ref src="{png}" height=3><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, #test img { padding:1px }<div id=test><img src="{png}"></div><img id=ref src="{png}" height=3><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, iframe { height:1px }<div id=test><iframe></iframe></div><img id=ref src="{png}" height=5><div id=s_ref>x</div>]
+ expected: FAIL
+
+ [The line height calculation quirk, #test::before { content:"" } #test::before, span { border:solid }<div id=test></div><div id=ref><span>x</span></div><div id=s_ref><span>x</span></div>]
+ expected: FAIL
+
+ [The line height calculation quirk, div { line-height: 0;} span { margin:0 1px; line-height: normal; }<div id=test>x<span></span></div><div id=ref>x</div><div id=s_ref>x<span>x</span></div>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/percentage-height-calculation.html.ini b/tests/wpt/metadata/quirks-mode/percentage-height-calculation.html.ini
new file mode 100644
index 00000000000..5837be3bd93
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/percentage-height-calculation.html.ini
@@ -0,0 +1,122 @@
+[percentage-height-calculation.html]
+ type: testharness
+ [The percentage height calculation quirk, #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #test { height:50% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #test { height:25% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #test { height:12.5% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #test { height:100% }<div><div id=test></div></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <img id=test src="{png}" height=100%>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <img id=test src="{png}" height=100% border=10>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <table id=test height=100%><tr><td></table>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #foo { height:100px } #test { height:100% }<div id=foo><div><div id=test></div></div></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #foo { position:relative } #test { height:100% }<div id=foo><div><div id=test></div></div></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, #foo { height:100px } #test { height:100%; position:relative }<div id=foo><div><div id=test></div></div></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { display:inline } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { margin:10px } body { display:inline } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { margin:0 } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { margin:0; padding:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { margin:0; border:10px solid } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { margin:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { padding:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { border:10px solid } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { height:100%; margin:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { height:100%; padding:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { height:100%; border:10px solid } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { height:100%; margin:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { height:100%; padding:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { height:100%; border:10px solid } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { position:absolute; height:100%; margin:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { position:absolute; height:100%; padding:10px } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html { position:absolute; height:100%; border:10px solid } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, body { margin:99px 0 } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html, body { border:10px none } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, html, body { border:10px hidden } #test { height:100% }<div id=test></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html xmlns="{html}"><head><style>#test { height:100% }</style></head><body><div id="test"/></body></html>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html xmlns="{html}"><head><style>#test { height:100% }</style></head><body/><div id="test"/></html>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html xmlns="{html}"><head><style>#test { height:100% }</style></head><span><body><div id="test"/></body></span></html>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html xmlns="{html}"><head><style>#test { height:100% }</style></head><body><body><div id="test"/></body></body></html>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html><head xmlns="{html}"><style>#test { height:100% }</style></head><body xmlns="{html}"><div id="test"/></body></html>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <div xmlns="{html}"><head><style>#test { height:100% }</style></head><body><div id="test"/></body></div>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html xmlns="{html}"><head><style>#test { height:100% }</style></head><body xmlns=""><div xmlns="{html}" id="test"/></body></html>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <HTML xmlns="{html}"><head><style>#test { height:100% }</style></head><body><div id="test"/></body></HTML>]
+ expected: FAIL
+
+ [The percentage height calculation quirk, <html xmlns="{html}"><head><style>#test { height:100% }</style></head><BODY><div id="test"/></BODY></html>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/supports.html.ini b/tests/wpt/metadata/quirks-mode/supports.html.ini
new file mode 100644
index 00000000000..d3fb177270f
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/supports.html.ini
@@ -0,0 +1,8 @@
+[supports.html]
+ type: testharness
+ [@supports quirky color]
+ expected: FAIL
+
+ [Sanity check @supports length]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/table-cell-nowrap-minimum-width-calculation.html.ini b/tests/wpt/metadata/quirks-mode/table-cell-nowrap-minimum-width-calculation.html.ini
new file mode 100644
index 00000000000..8ef6f809d1a
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/table-cell-nowrap-minimum-width-calculation.html.ini
@@ -0,0 +1,5 @@
+[table-cell-nowrap-minimum-width-calculation.html]
+ type: testharness
+ [The table cell nowrap minimum width calculation quirk, basic]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/table-cell-width-calculation.html.ini b/tests/wpt/metadata/quirks-mode/table-cell-width-calculation.html.ini
new file mode 100644
index 00000000000..2ad0708c604
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/table-cell-width-calculation.html.ini
@@ -0,0 +1,26 @@
+[table-cell-width-calculation.html]
+ type: testharness
+ [The table cell width calculation quirk, basic]
+ expected: FAIL
+
+ [The table cell width calculation quirk, inline-block]
+ expected: FAIL
+
+ [The table cell width calculation quirk, img in span]
+ expected: FAIL
+
+ [The table cell width calculation quirk, the don't-wrap rule is only for the purpose of calculating the width of the cell]
+ expected: FAIL
+
+ [The table cell width calculation quirk, the quirk shouldn't apply for <input>]
+ expected: FAIL
+
+ [The table cell width calculation quirk, non-auto width on cell]
+ expected: FAIL
+
+ [The table cell width calculation quirk, display:table-cell on span]
+ expected: FAIL
+
+ [The table cell width calculation quirk, display:table-cell on span, wbr]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/quirks-mode/unitless-length.html.ini b/tests/wpt/metadata/quirks-mode/unitless-length.html.ini
new file mode 100644
index 00000000000..307046ccfdf
--- /dev/null
+++ b/tests/wpt/metadata/quirks-mode/unitless-length.html.ini
@@ -0,0 +1,1129 @@
+[unitless-length.html]
+ type: testharness
+ [bottom: 1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1.5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1.5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1.5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1.5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1.5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1.5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1.5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1.5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1.5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1.5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1.5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1.5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1.5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1.5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1.5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1.5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1.5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1.5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: \\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: \\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: \\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: \\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: \\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: \\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: \\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: \\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: \\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: \\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: \\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: \\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1\\31 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1\\31 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1\\31 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1\\31 .5 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1\\31 .5 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1\\31 .5 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: 1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: 1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +1A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +1A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -1A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -1A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -A (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -A (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -A (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: @1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @1a (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @1a (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: @1a (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "a" (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "a" (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "a" (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "a" (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "a" (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "a" (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "1" (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "1" (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "1" (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "1" (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "1" (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "1" (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "1a" (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "1a" (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: "1a" (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "1a" (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "1a" (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: "1a" (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: url(1) (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: url(1) (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: url(1) (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: url(1) (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: url(1) (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: url(1) (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: url('1') (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: url('1') (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: url('1') (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: url('1') (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: url('1') (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: url('1') (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #01 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #01 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #01 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #01 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #01 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #01 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #0001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #0001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #0001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #0001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #0001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #0001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #00001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #00001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #00001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #00001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #00001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #00001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #000001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #000001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: #000001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #000001 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #000001 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: #000001 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +/**/1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +/**/1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: +/**/1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +/**/1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +/**/1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: +/**/1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -/**/1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -/**/1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: -/**/1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -/**/1 (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -/**/1 (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: -/**/1 (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: calc(1) (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: calc(1) (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: calc(1) (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: calc(1) (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: calc(1) (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: calc(1) (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: calc(2 * 2px) (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: calc(2 * 2px) (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [bottom: calc(2 * 2px) (standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: calc(2 * 2px) (quirks)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: calc(2 * 2px) (almost standards)]
+ expected:
+ if os == "mac": FAIL
+
+ [top: calc(2 * 2px) (standards)]
+ expected:
+ if os == "mac": FAIL
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 391b2f83b8b..5f70f04ee64 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -19874,6 +19874,12 @@
{}
]
],
+ "mozilla/unitless-length.html": [
+ [
+ "/_mozilla/mozilla/unitless-length.html",
+ {}
+ ]
+ ],
"mozilla/variadic-interface.html": [
[
"/_mozilla/mozilla/variadic-interface.html",
@@ -31497,6 +31503,10 @@
"47ee847e660eb907a7bd916cf37cf3ceba68ea7d",
"testharness"
],
+ "mozilla/unitless-length.html": [
+ "dfb31d3f9c4f24913055924c375f08b990b63e49",
+ "testharness"
+ ],
"mozilla/variadic-interface.html": [
"9edd5150d36fabae42077a034655a8457eb75bff",
"testharness"
diff --git a/tests/wpt/mozilla/tests/mozilla/unitless-length.html b/tests/wpt/mozilla/tests/mozilla/unitless-length.html
new file mode 100644
index 00000000000..a79520844db
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/unitless-length.html
@@ -0,0 +1,219 @@
+<!doctype html>
+<html>
+ <head>
+ <title>The unitless length quirk</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style> iframe { width:20px; height:20px; } </style>
+ </head>
+ <body>
+ <div id=log></div>
+ <iframe id=quirks></iframe>
+ <iframe id=almost></iframe>
+ <iframe id=standards></iframe>
+ <script>
+ setup({explicit_done:true});
+ onload = function() {
+ var html = "<style id=style></style><div id=test></div><div id=ref></div>";
+ var a_doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
+ var s_doctype = '<!DOCTYPE HTML>';
+ var q = document.getElementById('quirks').contentWindow;
+ var a = document.getElementById('almost').contentWindow;
+ var s = document.getElementById('standards').contentWindow;
+ q.document.open();
+ q.document.write(html);
+ q.document.close();
+ a.document.open();
+ a.document.write(a_doctype + html);
+ a.document.close();
+ s.document.open();
+ s.document.write(s_doctype + html);
+ s.document.close();
+ [q, a, s].forEach(function(win) {
+ ['style', 'test', 'ref'].forEach(function(id) {
+ win[id] = win.document.getElementById(id);
+ });
+ });
+
+ var tests = [
+ {input:"1", q:"1px"},
+ {input:"+1", q:"1px"},
+ {input:"-1", q:"-1px"},
+ {input:"1.5", q:"1.5px"},
+ {input:"+1.5", q:"1.5px"},
+ {input:"-1.5", q:"-1.5px"},
+ {input:"\\31 "},
+ {input:"+\\31 "},
+ {input:"-\\31 "},
+ {input:"\\31 .5"},
+ {input:"+\\31 .5"},
+ {input:"-\\31 .5"},
+ {input:"1\\31 "},
+ {input:"+1\\31 "},
+ {input:"-1\\31 "},
+ {input:"1\\31 .5"},
+ {input:"+1\\31 .5"},
+ {input:"-1\\31 .5"},
+ {input:"a"},
+ {input:"A"},
+ {input:"1a"},
+ {input:"+1a"},
+ {input:"-1a"},
+ {input:"+1A"},
+ {input:"-1A"},
+ {input:"+a"},
+ {input:"-a"},
+ {input:"+A"},
+ {input:"-A"},
+ {input:"@a"},
+ {input:"@1"},
+ {input:"@1a"},
+ {input:'"a"'},
+ {input:'"1"'},
+ {input:'"1a"'},
+ {input:"url(1)"},
+ {input:"url('1')"},
+ {input:"#1"},
+ {input:"#01"},
+ {input:"#001"},
+ {input:"#0001"},
+ {input:"#00001"},
+ {input:"#000001"},
+ {input:"+/**/1"},
+ {input:"-/**/1"},
+ {input:"calc(1)"},
+ {input:"calc(2 * 2px)", q:"4px", s:"4px"},
+ {input:"1px 2", q:"1px 2px", shorthand:true},
+ {input:"1 2px", q:"1px 2px", shorthand:true},
+ {input:"1px calc(2)", shorthand:true},
+ {input:"calc(1) 2px", shorthand:true},
+ {input:"1 +2", q:"1px 2px", shorthand:true},
+ {input:"1 -2", q:"1px -2px", shorthand:true},
+ ];
+
+ var props = [
+ {prop:'background-position', check:'background-position', check_also:[]},
+ {prop:'border-spacing', check:'border-spacing', check_also:[]},
+ {prop:'border-top-width', check:'border-top-width'},
+ {prop:'border-right-width', check:'border-right-width'},
+ {prop:'border-bottom-width', check:'border-bottom-width'},
+ {prop:'border-left-width', check:'border-left-width'},
+ {prop:'border-width', check:'border-top-width', check_also:['border-right-width', 'border-bottom-width', 'border-left-width']},
+ // {prop:'bottom', check:'bottom'},
+ {prop:'clip', check:'clip'},
+ {prop:'font-size', check:'font-size'},
+ {prop:'height', check:'height'},
+ {prop:'left', check:'left'},
+ {prop:'letter-spacing', check:'letter-spacing'},
+ {prop:'margin-right', check:'margin-right'},
+ {prop:'margin-left', check:'margin-left'},
+ {prop:'margin-top', check:'margin-top'},
+ {prop:'margin-bottom', check:'margin-bottom'},
+ {prop:'margin', check:'margin-top', check_also:['margin-right', 'margin-bottom', 'margin-left']},
+ {prop:'max-height', check:'max-height'},
+ {prop:'max-width', check:'max-width'},
+ {prop:'min-height', check:'min-height'},
+ {prop:'min-width', check:'min-width'},
+ {prop:'padding-top', check:'padding-top'},
+ {prop:'padding-right', check:'padding-right'},
+ {prop:'padding-bottom', check:'padding-bottom'},
+ {prop:'padding-left', check:'padding-left'},
+ {prop:'padding', check:'padding-top', check_also:['padding-right', 'padding-bottom', 'padding-left']},
+ {prop:'right', check:'right'},
+ {prop:'text-indent', check:'text-indent'},
+ // {prop:'top', check:'top'},
+ {prop:'vertical-align', check:'vertical-align'},
+ {prop:'width', check:'width'},
+ {prop:'word-spacing', check:'word-spacing'},
+ ];
+ var style_template = '#test{border-style:solid;position:relative;{prop}:{test};}' +
+ '#ref{border-style:solid;position:relative;{prop}:{ref};}';
+
+ tests.forEach(function(t) {
+ for (var i in props) {
+ if (t.shorthand && !(props[i].check_also)) {
+ continue;
+ }
+ test(function() {
+ q.style.textContent = style_template.replace('{test}', t.input)
+ .replace('{ref}', t.q).replace(/\{prop\}/g, props[i].prop)
+ .replace(/clip:[^;]+/g, function(match) {
+ return 'clip:rect(auto, auto, auto, ' + match.substr(5) + ')';
+ });
+ assert_equals(q.getComputedStyle(q.test).getPropertyValue(props[i].check),
+ q.getComputedStyle(q.ref).getPropertyValue(props[i].check),
+ props[i].prop);
+ if (t.shorthand && props[i].check_also) {
+ for (var j in props[i].check_also) {
+ assert_equals(q.getComputedStyle(q.test).getPropertyValue(props[i].check_also[j]),
+ q.getComputedStyle(q.ref).getPropertyValue(props[i].check_also[j]),
+ props[i].prop + ', checking ' + props[i].check_also[j]);
+ }
+ }
+ }, props[i].prop + ": " + t.input + ' (quirks)');
+ test(function() {
+ a.style.textContent = style_template.replace('{test}', t.input)
+ .replace('{ref}', t.s).replace(/\{prop\}/g, props[i].prop)
+ .replace(/clip:[^;]+/g, function(match) {
+ return 'clip:rect(auto, auto, auto, ' + match.substr(5) + ')';
+ });
+ assert_equals(a.getComputedStyle(a.test).getPropertyValue(props[i].check),
+ a.getComputedStyle(a.ref).getPropertyValue(props[i].check),
+ props[i].prop + ' in almost standards mode');
+ if (t.shorthand && props[i].check_also) {
+ for (var j in props[i].check_also) {
+ assert_equals(a.getComputedStyle(a.test).getPropertyValue(props[i].check_also[j]),
+ a.getComputedStyle(a.ref).getPropertyValue(props[i].check_also[j]),
+ props[i].prop + ', checking ' + props[i].check_also[j]);
+ }
+ }
+ }, props[i].prop + ": " + t.input + ' (almost standards)');
+ test(function() {
+ s.style.textContent = style_template.replace('{test}', t.input)
+ .replace('{ref}', t.s).replace(/\{prop\}/g, props[i].prop)
+ .replace(/clip:[^;]+/g, function(match) {
+ return 'clip:rect(auto, auto, auto, ' + match.substr(5) + ')';
+ });
+ assert_equals(s.getComputedStyle(s.test).getPropertyValue(props[i].check),
+ s.getComputedStyle(s.ref).getPropertyValue(props[i].check),
+ props[i].prop + ' in standards mode');
+ if (t.shorthand && props[i].check_also) {
+ for (var j in props[i].check_also) {
+ assert_equals(s.getComputedStyle(s.test).getPropertyValue(props[i].check_also[j]),
+ s.getComputedStyle(s.ref).getPropertyValue(props[i].check_also[j]),
+ props[i].prop + ', checking ' + props[i].check_also[j]);
+ }
+ }
+ }, props[i].prop + ": " + t.input + ' (standards)');
+ }
+ });
+
+ var other_tests = [
+ {input:'background:1 1', prop:'background-position'},
+ {input:'border-top:red solid 1', prop:'border-top-width'},
+ {input:'border-right:red solid 1', prop:'border-right-width'},
+ {input:'border-bottom:red solid 1', prop:'border-bottom-width'},
+ {input:'border-left:red solid 1', prop:'border-left-width'},
+ {input:'border:red solid 1', prop:'border-top-width'},
+ {input:'font:normal normal normal 40 sans-serif', prop:'font-size'},
+ {input:'outline:red solid 1', prop:'outline-width'},
+ {input:'outline-width:1', prop:'outline-width'},
+ ];
+
+ var other_template = "#test{position:relative;outline-style:solid;{test}}" +
+ "#ref{outline-style:solid}";
+
+ other_tests.forEach(function(t) {
+ test(function() {
+ q.style.textContent = other_template.replace('{test}', t.input);
+ assert_equals(q.getComputedStyle(q.test).getPropertyValue(t.prop),
+ q.getComputedStyle(q.ref).getPropertyValue(t.prop),
+ 'quirk was supported');
+ }, 'Excluded property '+t.input);
+ });
+
+ done();
+ }
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/quirks-mode/unitless-length.html b/tests/wpt/web-platform-tests/quirks-mode/unitless-length.html
index b2f05c01049..944c91fe395 100644
--- a/tests/wpt/web-platform-tests/quirks-mode/unitless-length.html
+++ b/tests/wpt/web-platform-tests/quirks-mode/unitless-length.html
@@ -130,14 +130,11 @@
'#ref{border-style:solid;position:relative;{prop}:{ref};}';
tests.forEach(function(t) {
- var test_q = async_test(t.input + ' (quirks)');
- var test_a = async_test(t.input + ' (almost standards)');
- var test_s = async_test(t.input + ' (standards)');
for (var i in props) {
if (t.shorthand && !(props[i].check_also)) {
continue;
}
- test_q.step(function() {
+ test(function() {
q.style.textContent = style_template.replace('{test}', t.input)
.replace('{ref}', t.q).replace(/\{prop\}/g, props[i].prop)
.replace(/clip:[^;]+/g, function(match) {
@@ -153,8 +150,8 @@
props[i].prop + ', checking ' + props[i].check_also[j]);
}
}
- });
- test_a.step(function() {
+ }, props[i].prop + ": " + t.input + ' (quirks)');
+ test(function() {
a.style.textContent = style_template.replace('{test}', t.input)
.replace('{ref}', t.s).replace(/\{prop\}/g, props[i].prop)
.replace(/clip:[^;]+/g, function(match) {
@@ -170,8 +167,8 @@
props[i].prop + ', checking ' + props[i].check_also[j]);
}
}
- });
- test_s.step(function() {
+ }, props[i].prop + ": " + t.input + ' (almost standards)');
+ test(function() {
s.style.textContent = style_template.replace('{test}', t.input)
.replace('{ref}', t.s).replace(/\{prop\}/g, props[i].prop)
.replace(/clip:[^;]+/g, function(match) {
@@ -187,12 +184,8 @@
props[i].prop + ', checking ' + props[i].check_also[j]);
}
}
- });
+ }, props[i].prop + ": " + t.input + ' (standards)');
}
- test_q.done();
- test_a.done();
- test_s.done();
-
});
var other_tests = [