From 63677fa65f5e75a076f1964b2339ebe20ddcb3f2 Mon Sep 17 00:00:00 2001 From: Pyfisch Date: Sat, 29 Apr 2017 09:40:32 -0500 Subject: [PATCH 01/11] servo: Merge #16385 - Implement radial gradients (from pyfisch:radial-gradient); r=emilio This PR passes the `radial-gradient` function down from CSS parsed properties to webrender. It currently lacks tests but the examples from MDN and some other tests work fine. Probably there are some wpt tests I can enable? - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #11779 (github issue number if applicable). - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ Source-Repo: https://github.com/servo/servo Source-Revision: 53c62e890acd05475d94b19d760272c6b658d83a --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 1b8dd637f2ccee556a9edd14c2ef6fc2de8cc7d4 --- servo/components/gfx/display_list/mod.rs | 31 ++ .../components/layout/display_list_builder.rs | 442 ++++++++++++------ servo/components/layout/webrender_helpers.rs | 27 +- .../components/style/values/computed/image.rs | 3 +- 4 files changed, 353 insertions(+), 150 deletions(-) diff --git a/servo/components/gfx/display_list/mod.rs b/servo/components/gfx/display_list/mod.rs index 205b4071589c..77a64553c29f 100644 --- a/servo/components/gfx/display_list/mod.rs +++ b/servo/components/gfx/display_list/mod.rs @@ -528,6 +528,7 @@ pub enum DisplayItem { WebGL(Box), Border(Box), Gradient(Box), + RadialGradient(Box), Line(Box), BoxShadow(Box), Iframe(Box), @@ -889,6 +890,9 @@ pub struct Gradient { /// A list of color stops. pub stops: Vec, + + /// True if gradient repeats infinitly. + pub repeating: bool, } #[derive(Clone, Deserialize, HeapSizeOf, Serialize)] @@ -900,6 +904,31 @@ pub struct GradientDisplayItem { pub gradient: Gradient, } +/// Paints a radial gradient. +#[derive(Clone, Deserialize, HeapSizeOf, Serialize)] +pub struct RadialGradient { + /// The center point of the gradient. + pub center: Point2D, + + /// The radius of the gradient with an x and an y component. + pub radius: Size2D, + + /// A list of color stops. + pub stops: Vec, + + /// True if gradient repeats infinitly. + pub repeating: bool, +} + +#[derive(Clone, Deserialize, HeapSizeOf, Serialize)] +pub struct RadialGradientDisplayItem { + /// Fields common to all display item. + pub base: BaseDisplayItem, + + /// Contains all gradient data. + pub gradient: RadialGradient, +} + /// A normal border, supporting CSS border styles. #[derive(Clone, HeapSizeOf, Deserialize, Serialize)] pub struct NormalBorder { @@ -1124,6 +1153,7 @@ impl DisplayItem { DisplayItem::WebGL(ref webgl_item) => &webgl_item.base, DisplayItem::Border(ref border) => &border.base, DisplayItem::Gradient(ref gradient) => &gradient.base, + DisplayItem::RadialGradient(ref gradient) => &gradient.base, DisplayItem::Line(ref line) => &line.base, DisplayItem::BoxShadow(ref box_shadow) => &box_shadow.base, DisplayItem::Iframe(ref iframe) => &iframe.base, @@ -1241,6 +1271,7 @@ impl fmt::Debug for DisplayItem { DisplayItem::WebGL(_) => "WebGL".to_owned(), DisplayItem::Border(_) => "Border".to_owned(), DisplayItem::Gradient(_) => "Gradient".to_owned(), + DisplayItem::RadialGradient(_) => "RadialGradient".to_owned(), DisplayItem::Line(_) => "Line".to_owned(), DisplayItem::BoxShadow(_) => "BoxShadow".to_owned(), DisplayItem::Iframe(_) => "Iframe".to_owned(), diff --git a/servo/components/layout/display_list_builder.rs b/servo/components/layout/display_list_builder.rs index 2e065572615d..a2453067e1f5 100644 --- a/servo/components/layout/display_list_builder.rs +++ b/servo/components/layout/display_list_builder.rs @@ -25,7 +25,7 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDetails}; use gfx::display_list::{BorderDisplayItem, ImageBorder, NormalBorder}; use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion}; use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayList, DisplayListSection}; -use gfx::display_list::{GradientDisplayItem, IframeDisplayItem, ImageDisplayItem}; +use gfx::display_list::{GradientDisplayItem, RadialGradientDisplayItem, IframeDisplayItem, ImageDisplayItem}; use gfx::display_list::{LineDisplayItem, OpaqueNode}; use gfx::display_list::{SolidColorDisplayItem, ScrollRoot, StackingContext, StackingContextType}; use gfx::display_list::{TextDisplayItem, TextOrientation, WebGLDisplayItem, WebRenderImageInfo}; @@ -33,7 +33,7 @@ use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId} use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT}; use ipc_channel::ipc; use list_item::ListItemFlow; -use model::{self, MaybeAuto}; +use model::{self, MaybeAuto, specified}; use msg::constellation_msg::PipelineId; use net_traits::image::base::PixelFormat; use net_traits::image_cache::UsePlaceholder; @@ -58,8 +58,10 @@ use style::properties::longhands::border_image_repeat::computed_value::RepeatKey use style::properties::style_structs; use style::servo::restyle_damage::REPAINT; use style::values::{Either, RGBA, computed}; -use style::values::computed::{AngleOrCorner, Gradient, GradientItem, GradientKind}; -use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, NumberOrPercentage}; +use style::values::computed::{AngleOrCorner, Gradient, GradientItem, GradientKind, LengthOrPercentage}; +use style::values::computed::{LengthOrPercentageOrAuto, LengthOrKeyword, LengthOrPercentageOrKeyword}; +use style::values::computed::{NumberOrPercentage, Position}; +use style::values::computed::image::{EndingShape, SizeKeyword}; use style::values::specified::{HorizontalDirection, VerticalDirection}; use style_traits::CSSPixel; use style_traits::cursor::Cursor; @@ -385,11 +387,22 @@ pub trait FragmentDisplayListBuilding { image_url: &ServoUrl, background_index: usize); - fn convert_gradient(&self, - absolute_bounds: &Rect, - gradient: &Gradient, - style: &ServoComputedValues) - -> Option; + fn convert_linear_gradient(&self, + bounds: &Rect, + stops: &[GradientItem], + angle_or_corner: &AngleOrCorner, + repeating: bool, + style: &ServoComputedValues) + -> display_list::Gradient; + + fn convert_radial_gradient(&self, + bounds: &Rect, + stops: &[GradientItem], + shape: &EndingShape, + center: &Position, + repeating: bool, + style: &ServoComputedValues) + -> display_list::RadialGradient; /// Adds the display items necessary to paint the background linear gradient of this fragment /// to the appropriate section of the display list. @@ -397,6 +410,7 @@ pub trait FragmentDisplayListBuilding { state: &mut DisplayListBuildState, display_list_section: DisplayListSection, absolute_bounds: &Rect, + clip_bounds: &Rect, clip: &ClippingRegion, gradient: &Gradient, style: &ServoComputedValues); @@ -588,6 +602,152 @@ fn build_border_radius_for_inner_rect(outer_rect: &Rect, radii } +fn convert_gradient_stops(gradient_items: &[GradientItem], + length: Au, + style: &ServoComputedValues) -> Vec { + // Determine the position of each stop per CSS-IMAGES § 3.4. + // + // FIXME(#3908, pcwalton): Make sure later stops can't be behind earlier stops. + let stop_items = gradient_items.iter().filter_map(|item| { + match *item { + GradientItem::ColorStop(ref stop) => Some(stop), + _ => None, + } + }).collect::>(); + let mut stops = Vec::with_capacity(stop_items.len()); + let mut stop_run = None; + for (i, stop) in stop_items.iter().enumerate() { + let offset = match stop.position { + None => { + if stop_run.is_none() { + // Initialize a new stop run. + let start_offset = if i == 0 { + 0.0 + } else { + // `unwrap()` here should never fail because this is the beginning of + // a stop run, which is always bounded by a length or percentage. + position_to_offset(stop_items[i - 1].position.unwrap(), length) + }; + let (end_index, end_offset) = + match stop_items[i..] + .iter() + .enumerate() + .find(|&(_, ref stop)| stop.position.is_some()) { + None => (stop_items.len() - 1, 1.0), + Some((end_index, end_stop)) => { + // `unwrap()` here should never fail because this is the end of + // a stop run, which is always bounded by a length or + // percentage. + (end_index, + position_to_offset(end_stop.position.unwrap(), length)) + } + }; + stop_run = Some(StopRun { + start_offset: start_offset, + end_offset: end_offset, + start_index: i, + stop_count: end_index - i, + }) + } + + let stop_run = stop_run.unwrap(); + let stop_run_length = stop_run.end_offset - stop_run.start_offset; + if stop_run.stop_count == 0 { + stop_run.end_offset + } else { + stop_run.start_offset + + stop_run_length * (i - stop_run.start_index) as f32 / + (stop_run.stop_count as f32) + } + } + Some(position) => { + stop_run = None; + position_to_offset(position, length) + } + }; + stops.push(GradientStop { + offset: offset, + color: style.resolve_color(stop.color).to_gfx_color() + }) + } + stops +} + +/// Returns the the distance to the nearest or farthest corner depending on the comperator. +fn get_distance_to_corner(size: &Size2D, center: &Point2D, cmp: F) -> Au + where F: Fn(Au, Au) -> Au +{ + let dist = get_distance_to_sides(size, center, cmp); + Au::from_f32_px(dist.width.to_f32_px().hypot(dist.height.to_f32_px())) +} + +/// Returns the distance to the nearest or farthest sides depending on the comparator. +/// +/// The first return value is horizontal distance the second vertical distance. +fn get_distance_to_sides(size: &Size2D, center: &Point2D, cmp: F) -> Size2D + where F: Fn(Au, Au) -> Au +{ + let top_side = center.y; + let right_side = size.width - center.x; + let bottom_side = size.height - center.y; + let left_side = center.x; + Size2D::new(cmp(left_side, right_side), cmp(top_side, bottom_side)) +} + +/// Returns the radius for an ellipse with the same ratio as if it was matched to the sides. +fn get_ellipse_radius(size: &Size2D, center: &Point2D, cmp: F) -> Size2D + where F: Fn(Au, Au) -> Au +{ + let dist = get_distance_to_sides(size, center, cmp); + Size2D::new(dist.width.scale_by(::std::f32::consts::FRAC_1_SQRT_2 * 2.0), + dist.height.scale_by(::std::f32::consts::FRAC_1_SQRT_2 * 2.0)) +} + +/// Determines the radius of a circle if it was not explictly provided. +/// https://drafts.csswg.org/css-images-3/#typedef-size +fn convert_circle_size_keyword(keyword: SizeKeyword, + size: &Size2D, + center: &Point2D) -> Size2D { + use style::values::computed::image::SizeKeyword::*; + let radius = match keyword { + ClosestSide => { + let dist = get_distance_to_sides(size, center, ::std::cmp::min); + ::std::cmp::min(dist.width, dist.height) + } + FarthestSide => { + let dist = get_distance_to_sides(size, center, ::std::cmp::max); + ::std::cmp::max(dist.width, dist.height) + } + ClosestCorner => get_distance_to_corner(size, center, ::std::cmp::min), + FarthestCorner => get_distance_to_corner(size, center, ::std::cmp::max), + _ => { + // TODO(#16542) + println!("TODO: implement size keyword {:?} for circles", keyword); + Au::new(0) + } + }; + Size2D::new(radius, radius) +} + +/// Determines the radius of an ellipse if it was not explictly provided. +/// https://drafts.csswg.org/css-images-3/#typedef-size +fn convert_ellipse_size_keyword(keyword: SizeKeyword, + size: &Size2D, + center: &Point2D) -> Size2D { + use style::values::computed::image::SizeKeyword::*; + match keyword { + ClosestSide => get_distance_to_sides(size, center, ::std::cmp::min), + FarthestSide => get_distance_to_sides(size, center, ::std::cmp::max), + ClosestCorner => get_ellipse_radius(size, center, ::std::cmp::min), + FarthestCorner => get_ellipse_radius(size, center, ::std::cmp::max), + _ => { + // TODO(#16542) + println!("TODO: implement size keyword {:?} for ellipses", keyword); + Size2D::new(Au::new(0), Au::new(0)) + } + } +} + impl FragmentDisplayListBuilding for Fragment { fn build_display_list_for_background_if_applicable(&self, state: &mut DisplayListBuildState, @@ -653,15 +813,13 @@ impl FragmentDisplayListBuilding for Fragment { match background_image.0 { None => {} Some(computed::Image::Gradient(ref gradient)) => { - // FIXME: Radial gradients aren't implemented yet. - if let GradientKind::Linear(_) = gradient.gradient_kind { - self.build_display_list_for_background_gradient(state, - display_list_section, - &bounds, - &clip, - gradient, - style); - } + self.build_display_list_for_background_gradient(state, + display_list_section, + &absolute_bounds, + &bounds, + &clip, + gradient, + style); } Some(computed::Image::Url(ref image_url)) => { if let Some(url) = image_url.url() { @@ -893,46 +1051,40 @@ impl FragmentDisplayListBuilding for Fragment { } } - fn convert_gradient(&self, - absolute_bounds: &Rect, - gradient: &Gradient, - style: &ServoComputedValues) -> Option { - // FIXME: Repeating gradients aren't implemented yet. - if gradient.repeating { - return None; - } - let angle = if let GradientKind::Linear(angle_or_corner) = gradient.gradient_kind { - match angle_or_corner { - AngleOrCorner::Angle(angle) => angle.radians(), - AngleOrCorner::Corner(horizontal, vertical) => { - // This the angle for one of the diagonals of the box. Our angle - // will either be this one, this one + PI, or one of the other - // two perpendicular angles. - let atan = (absolute_bounds.size.height.to_f32_px() / - absolute_bounds.size.width.to_f32_px()).atan(); - match (horizontal, vertical) { - (HorizontalDirection::Right, VerticalDirection::Bottom) - => f32::consts::PI - atan, - (HorizontalDirection::Left, VerticalDirection::Bottom) - => f32::consts::PI + atan, - (HorizontalDirection::Right, VerticalDirection::Top) - => atan, - (HorizontalDirection::Left, VerticalDirection::Top) - => -atan, - } + fn convert_linear_gradient(&self, + bounds: &Rect, + stops: &[GradientItem], + angle_or_corner: &AngleOrCorner, + repeating: bool, + style: &ServoComputedValues) + -> display_list::Gradient { + let angle = match *angle_or_corner { + AngleOrCorner::Angle(angle) => angle.radians(), + AngleOrCorner::Corner(horizontal, vertical) => { + // This the angle for one of the diagonals of the box. Our angle + // will either be this one, this one + PI, or one of the other + // two perpendicular angles. + let atan = (bounds.size.height.to_f32_px() / + bounds.size.width.to_f32_px()).atan(); + match (horizontal, vertical) { + (HorizontalDirection::Right, VerticalDirection::Bottom) + => f32::consts::PI - atan, + (HorizontalDirection::Left, VerticalDirection::Bottom) + => f32::consts::PI + atan, + (HorizontalDirection::Right, VerticalDirection::Top) + => atan, + (HorizontalDirection::Left, VerticalDirection::Top) + => -atan, } } - } else { - // FIXME: Radial gradients aren't implemented yet. - return None; }; // Get correct gradient line length, based on: // https://drafts.csswg.org/css-images-3/#linear-gradients let dir = Point2D::new(angle.sin(), -angle.cos()); - let line_length = (dir.x * absolute_bounds.size.width.to_f32_px()).abs() + - (dir.y * absolute_bounds.size.height.to_f32_px()).abs(); + let line_length = (dir.x * bounds.size.width.to_f32_px()).abs() + + (dir.y * bounds.size.height.to_f32_px()).abs(); let inv_dir_length = 1.0 / (dir.x * dir.x + dir.y * dir.y).sqrt(); @@ -945,108 +1097,100 @@ impl FragmentDisplayListBuilding for Fragment { let length = Au::from_f32_px( (delta.x.to_f32_px() * 2.0).hypot(delta.y.to_f32_px() * 2.0)); - // Determine the position of each stop per CSS-IMAGES § 3.4. - // - // FIXME(#3908, pcwalton): Make sure later stops can't be behind earlier stops. - let stop_items = gradient.items.iter().filter_map(|item| { - match *item { - GradientItem::ColorStop(ref stop) => Some(stop), - _ => None, - } - }).collect::>(); - let mut stops = Vec::with_capacity(stop_items.len()); - let mut stop_run = None; - for (i, stop) in stop_items.iter().enumerate() { - let offset = match stop.position { - None => { - if stop_run.is_none() { - // Initialize a new stop run. - let start_offset = if i == 0 { - 0.0 - } else { - // `unwrap()` here should never fail because this is the beginning of - // a stop run, which is always bounded by a length or percentage. - position_to_offset(stop_items[i - 1].position.unwrap(), length) - }; - let (end_index, end_offset) = - match stop_items[i..] - .iter() - .enumerate() - .find(|&(_, ref stop)| stop.position.is_some()) { - None => (stop_items.len() - 1, 1.0), - Some((end_index, end_stop)) => { - // `unwrap()` here should never fail because this is the end of - // a stop run, which is always bounded by a length or - // percentage. - (end_index, - position_to_offset(end_stop.position.unwrap(), length)) - } - }; - stop_run = Some(StopRun { - start_offset: start_offset, - end_offset: end_offset, - start_index: i, - stop_count: end_index - i, - }) - } + let stops = convert_gradient_stops(stops, length, style); - let stop_run = stop_run.unwrap(); - let stop_run_length = stop_run.end_offset - stop_run.start_offset; - if stop_run.stop_count == 0 { - stop_run.end_offset - } else { - stop_run.start_offset + - stop_run_length * (i - stop_run.start_index) as f32 / - (stop_run.stop_count as f32) - } - } - Some(position) => { - stop_run = None; - position_to_offset(position, length) - } - }; - stops.push(GradientStop { - offset: offset, - color: style.resolve_color(stop.color).to_gfx_color() - }) - } + let center = Point2D::new(bounds.size.width / 2, bounds.size.height / 2); - let center = Point2D::new(absolute_bounds.size.width / 2, - absolute_bounds.size.height / 2); - - Some(display_list::Gradient { + display_list::Gradient { start_point: center - delta, end_point: center + delta, stops: stops, - }) + repeating: repeating, + } + } + + fn convert_radial_gradient(&self, + bounds: &Rect, + stops: &[GradientItem], + shape: &EndingShape, + center: &Position, + repeating: bool, + style: &ServoComputedValues) + -> display_list::RadialGradient { + let center = Point2D::new(specified(center.horizontal.0, bounds.size.width), + specified(center.vertical.0, bounds.size.height)); + let radius = match *shape { + EndingShape::Circle(LengthOrKeyword::Length(length)) + => Size2D::new(length, length), + EndingShape::Circle(LengthOrKeyword::Keyword(word)) + => convert_circle_size_keyword(word, &bounds.size, ¢er), + EndingShape::Ellipse(LengthOrPercentageOrKeyword::LengthOrPercentage(horizontal, + vertical)) + => Size2D::new(specified(horizontal, bounds.size.width), + specified(vertical, bounds.size.height)), + EndingShape::Ellipse(LengthOrPercentageOrKeyword::Keyword(word)) + => convert_ellipse_size_keyword(word, &bounds.size, ¢er), + }; + let length = Au::from_f32_px(radius.width.to_f32_px().hypot(radius.height.to_f32_px())); + let stops = convert_gradient_stops(stops, length, style); + display_list::RadialGradient { + center: center, + radius: radius, + stops: stops, + repeating: repeating, + } } fn build_display_list_for_background_gradient(&self, state: &mut DisplayListBuildState, display_list_section: DisplayListSection, absolute_bounds: &Rect, + clip_bounds: &Rect, clip: &ClippingRegion, gradient: &Gradient, style: &ServoComputedValues) { let mut clip = clip.clone(); - clip.intersect_rect(absolute_bounds); + clip.intersect_rect(clip_bounds); - let grad = self.convert_gradient(absolute_bounds, gradient, style); + let border_padding = self.border_padding.to_physical(style.writing_mode); + let mut bounds = *absolute_bounds; + bounds.origin.x = bounds.origin.x + border_padding.left; + bounds.origin.y = bounds.origin.y + border_padding.top; + bounds.size.width = bounds.size.width - border_padding.horizontal(); + bounds.size.height = bounds.size.height - border_padding.vertical(); - if let Some(x) = grad { - let base = state.create_base_display_item(absolute_bounds, - &clip, - self.node, - style.get_cursor(Cursor::Default), - display_list_section); + let base = state.create_base_display_item(&bounds, + &clip, + self.node, + style.get_cursor(Cursor::Default), + display_list_section); - let gradient_display_item = DisplayItem::Gradient(box GradientDisplayItem { - base: base, - gradient: x, - }); - - state.add_display_item(gradient_display_item); - } + let display_item = match gradient.gradient_kind { + GradientKind::Linear(ref angle_or_corner) => { + let gradient = self.convert_linear_gradient(&bounds, + &gradient.items[..], + angle_or_corner, + gradient.repeating, + style); + DisplayItem::Gradient(box GradientDisplayItem { + base: base, + gradient: gradient, + }) + } + GradientKind::Radial(ref shape, ref center) => { + let gradient = self.convert_radial_gradient(&bounds, + &gradient.items[..], + shape, + center, + gradient.repeating, + style); + DisplayItem::RadialGradient(box RadialGradientDisplayItem { + base: base, + gradient: gradient, + }) + } + }; + state.add_display_item(display_item); } fn build_display_list_for_box_shadow_if_applicable(&self, @@ -1159,24 +1303,26 @@ impl FragmentDisplayListBuilding for Fragment { } Some(computed::Image::Gradient(ref gradient)) => { match gradient.gradient_kind { - GradientKind::Linear(_) => { - let grad = self.convert_gradient(&bounds, gradient, style); + GradientKind::Linear(angle_or_corner) => { + let grad = self.convert_linear_gradient(&bounds, + &gradient.items[..], + &angle_or_corner, + gradient.repeating, + style); - if let Some(x) = grad { - state.add_display_item(DisplayItem::Border(box BorderDisplayItem { - base: base, - border_widths: border.to_physical(style.writing_mode), - details: BorderDetails::Gradient(display_list::GradientBorder { - gradient: x, + state.add_display_item(DisplayItem::Border(box BorderDisplayItem { + base: base, + border_widths: border.to_physical(style.writing_mode), + details: BorderDetails::Gradient(display_list::GradientBorder { + gradient: grad, - // TODO(gw): Support border-image-outset - outset: SideOffsets2D::zero(), - }), - })); - } + // TODO(gw): Support border-image-outset + outset: SideOffsets2D::zero(), + }), + })); } GradientKind::Radial(_, _) => { - // TODO(gw): Handle border-image with radial gradient. + // TODO(#16638): Handle border-image with radial gradient. } } } diff --git a/servo/components/layout/webrender_helpers.rs b/servo/components/layout/webrender_helpers.rs index 723e33287024..70479d438379 100644 --- a/servo/components/layout/webrender_helpers.rs +++ b/servo/components/layout/webrender_helpers.rs @@ -370,16 +370,41 @@ impl WebRenderDisplayItemConverter for DisplayItem { let start_point = item.gradient.start_point.to_pointf(); let end_point = item.gradient.end_point.to_pointf(); let clip = item.base.clip.to_clip_region(builder); + let extend_mode = if item.gradient.repeating { + ExtendMode::Repeat + } else { + ExtendMode::Clamp + }; let gradient = builder.create_gradient(start_point, end_point, item.gradient.stops.clone(), - ExtendMode::Clamp); + extend_mode); builder.push_gradient(rect, clip, gradient, rect.size, webrender_traits::LayoutSize::zero()); } + DisplayItem::RadialGradient(ref item) => { + let rect = item.base.bounds.to_rectf(); + let center = item.gradient.center.to_pointf(); + let radius = item.gradient.radius.to_sizef(); + let clip = item.base.clip.to_clip_region(builder); + let extend_mode = if item.gradient.repeating { + ExtendMode::Repeat + } else { + ExtendMode::Clamp + }; + let gradient = builder.create_radial_gradient(center, + radius, + item.gradient.stops.clone(), + extend_mode); + builder.push_radial_gradient(rect, + clip, + gradient, + rect.size, + webrender_traits::LayoutSize::zero()); + } DisplayItem::Line(..) => { println!("TODO DisplayItem::Line"); } diff --git a/servo/components/style/values/computed/image.rs b/servo/components/style/values/computed/image.rs index 4ccce1e1f8f9..607cc8f20257 100644 --- a/servo/components/style/values/computed/image.rs +++ b/servo/components/style/values/computed/image.rs @@ -14,10 +14,11 @@ use std::fmt; use style_traits::ToCss; use values::computed::{Angle, Context, Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; use values::computed::position::Position; -use values::specified::{self, HorizontalDirection, SizeKeyword, VerticalDirection}; +use values::specified::{self, HorizontalDirection, VerticalDirection}; use values::specified::image::CompatMode; use values::specified::url::SpecifiedUrl; +pub use values::specified::SizeKeyword; impl ToComputedValue for specified::Image { type ComputedValue = Image; From 3a4a71d13634b18c95350842551b0c319de18b78 Mon Sep 17 00:00:00 2001 From: Sean Lee Date: Fri, 21 Apr 2017 15:15:35 +0800 Subject: [PATCH 02/11] Bug 1349489 - Part 1: Move the codes from FormAutofillHandler.collectFormFields to FormAutofillHeuristics.getFormInfo.; r=MattN MozReview-Commit-ID: BQTpopSyBUe --HG-- extra : rebase_source : 18852259ad76ec23c33fdcc29f7e461df2e0599f --- .../formautofill/FormAutofillHandler.jsm | 32 ++---------------- .../formautofill/FormAutofillHeuristics.jsm | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/browser/extensions/formautofill/FormAutofillHandler.jsm b/browser/extensions/formautofill/FormAutofillHandler.jsm index 4d78584799d9..cb36eeb4c3e8 100644 --- a/browser/extensions/formautofill/FormAutofillHandler.jsm +++ b/browser/extensions/formautofill/FormAutofillHandler.jsm @@ -61,36 +61,8 @@ FormAutofillHandler.prototype = { * Set fieldDetails from the form about fields that can be autofilled. */ collectFormFields() { - this.fieldDetails = []; - - for (let element of this.form.elements) { - // Exclude elements to which no autocomplete field has been assigned. - let info = FormAutofillHeuristics.getInfo(element); - if (!info) { - continue; - } - - // Store the association between the field metadata and the element. - if (this.fieldDetails.some(f => f.section == info.section && - f.addressType == info.addressType && - f.contactType == info.contactType && - f.fieldName == info.fieldName)) { - // A field with the same identifier already exists. - log.debug("Not collecting a field matching another with the same info:", info); - continue; - } - - let formatWithElement = { - section: info.section, - addressType: info.addressType, - contactType: info.contactType, - fieldName: info.fieldName, - elementWeakRef: Cu.getWeakReference(element), - }; - - this.fieldDetails.push(formatWithElement); - } - + let fieldDetails = FormAutofillHeuristics.getFormInfo(this.form); + this.fieldDetails = fieldDetails ? fieldDetails : []; log.debug("Collected details on", this.fieldDetails.length, "fields"); }, diff --git a/browser/extensions/formautofill/FormAutofillHeuristics.jsm b/browser/extensions/formautofill/FormAutofillHeuristics.jsm index b188f44119c8..bfa9272b71e8 100644 --- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm +++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm @@ -34,6 +34,39 @@ this.FormAutofillHeuristics = { "email", ], + getFormInfo(form) { + let fieldDetails = []; + for (let element of form.elements) { + // Exclude elements to which no autocomplete field has been assigned. + let info = this.getInfo(element); + if (!info) { + continue; + } + + // Store the association between the field metadata and the element. + if (fieldDetails.some(f => f.section == info.section && + f.addressType == info.addressType && + f.contactType == info.contactType && + f.fieldName == info.fieldName)) { + // A field with the same identifier already exists. + log.debug("Not collecting a field matching another with the same info:", info); + continue; + } + + let formatWithElement = { + section: info.section, + addressType: info.addressType, + contactType: info.contactType, + fieldName: info.fieldName, + elementWeakRef: Cu.getWeakReference(element), + }; + + fieldDetails.push(formatWithElement); + } + + return fieldDetails; + }, + getInfo(element) { if (!(element instanceof Ci.nsIDOMHTMLInputElement)) { return null; From becccc738515aacd4d477885f576005710b07974 Mon Sep 17 00:00:00 2001 From: Sean Lee Date: Fri, 21 Apr 2017 15:20:26 +0800 Subject: [PATCH 03/11] Bug 1349489 - Part 2: Add test fixtures for autofill field name heuristics.; r=MattN MozReview-Commit-ID: IuvSEpSHVtK --HG-- extra : rebase_source : b763eba5ea36744f9b05149d42b6d5680e0843e8 --- .../formautofill/FormAutofillHeuristics.jsm | 5 + .../test/fixtures/autocomplete_basic.html | 23 + .../third_party/BestBuy/Checkout_Payment.html | 283 +++++ .../BestBuy/Checkout_ShippingAddress.html | 326 +++++ .../fixtures/third_party/BestBuy/SignIn.html | 21 + .../CDW/Checkout_BillingPaymentInfo.html | 515 ++++++++ .../third_party/CDW/Checkout_Logon.html | 118 ++ .../CDW/Checkout_ShippingInfo.html | 376 ++++++ .../fixtures/third_party/CostCo/Payment.html | 892 ++++++++++++++ .../third_party/CostCo/ShippingAddress.html | 527 ++++++++ .../fixtures/third_party/CostCo/SignIn.html | 374 ++++++ .../HomeDepot/Checkout_ShippingPayment.html | 381 ++++++ .../third_party/HomeDepot/SignIn.html | 83 ++ .../third_party/Macys/Checkout_Payment.html | 478 ++++++++ .../Macys/Checkout_ShippingAddress.html | 439 +++++++ .../fixtures/third_party/Macys/SignIn.html | 208 ++++ .../third_party/NewEgg/BillingInfo.html | 1083 +++++++++++++++++ .../fixtures/third_party/NewEgg/Login.html | 156 +++ .../third_party/NewEgg/ShippingInfo.html | 270 ++++ .../third_party/OfficeDepot/Payment.html | 672 ++++++++++ .../OfficeDepot/ShippingAddress.html | 347 ++++++ .../third_party/OfficeDepot/SignIn.html | 44 + .../third_party/QVC/PaymentMethod.html | 527 ++++++++ .../test/fixtures/third_party/QVC/SignIn.html | 80 ++ .../third_party/QVC/YourInformation.html | 522 ++++++++ .../test/fixtures/third_party/README | 4 + .../third_party/Sears/PaymentOptions.html | 566 +++++++++ .../third_party/Sears/ShippingAddress.html | 447 +++++++ .../fixtures/third_party/Staples/Basic.html | 117 ++ .../third_party/Staples/Basic_ac_on.html | 117 ++ .../third_party/Staples/PaymentBilling.html | 99 ++ .../Staples/PaymentBilling_ac_on.html | 98 ++ .../third_party/Walmart/Checkout.html | 243 ++++ .../fixtures/third_party/Walmart/Payment.html | 235 ++++ .../third_party/Walmart/Shipping.html | 234 ++++ .../extensions/formautofill/test/unit/head.js | 41 +- .../test/unit/heuristics/test_basic.js | 22 + .../heuristics/third_party/test_BestBuy.js | 56 + .../unit/heuristics/third_party/test_CDW.js | 55 + .../heuristics/third_party/test_CostCo.js | 124 ++ .../heuristics/third_party/test_HomeDepot.js | 34 + .../unit/heuristics/third_party/test_Macys.js | 67 + .../heuristics/third_party/test_NewEgg.js | 66 + .../third_party/test_OfficeDepot.js | 64 + .../unit/heuristics/third_party/test_QVC.js | 54 + .../unit/heuristics/third_party/test_Sears.js | 87 ++ .../heuristics/third_party/test_Staples.js | 48 + .../heuristics/third_party/test_Walmart.js | 62 + .../formautofill/test/unit/xpcshell.ini | 13 + .../modules/tests/modules/MockDocument.jsm | 12 + 50 files changed, 11714 insertions(+), 1 deletion(-) create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/BestBuy/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_BillingPaymentInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_Logon.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_ShippingInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CostCo/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CostCo/ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CostCo/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/Checkout_ShippingPayment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Macys/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/NewEgg/BillingInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/NewEgg/Login.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/NewEgg/ShippingInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/QVC/PaymentMethod.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/QVC/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/QVC/YourInformation.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/README create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Sears/PaymentOptions.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Sears/ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic_ac_on.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling_ac_on.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Walmart/Checkout.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Walmart/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Walmart/Shipping.html create mode 100644 browser/extensions/formautofill/test/unit/heuristics/test_basic.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_BestBuy.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_CDW.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_CostCo.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_HomeDepot.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_Macys.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_NewEgg.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_OfficeDepot.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_QVC.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_Sears.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_Staples.js create mode 100644 browser/extensions/formautofill/test/unit/heuristics/third_party/test_Walmart.js diff --git a/browser/extensions/formautofill/FormAutofillHeuristics.jsm b/browser/extensions/formautofill/FormAutofillHeuristics.jsm index bfa9272b71e8..0ce5138a7f03 100644 --- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm +++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm @@ -12,6 +12,11 @@ this.EXPORTED_SYMBOLS = ["FormAutofillHeuristics"]; const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; +Cu.import("resource://formautofill/FormAutofillUtils.jsm"); + +this.log = null; +FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]); + /** * Returns the autocomplete information of fields according to heuristics. */ diff --git a/browser/extensions/formautofill/test/fixtures/autocomplete_basic.html b/browser/extensions/formautofill/test/fixtures/autocomplete_basic.html new file mode 100644 index 000000000000..bb74c9da920c --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/autocomplete_basic.html @@ -0,0 +1,23 @@ + + + + + Form Autofill Demo Page + + +

Form Autofill Demo Page

+
+

+

+

+

+

+

+

+

+

+

+
+ + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_Payment.html b/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_Payment.html new file mode 100644 index 000000000000..e987ef59cac1 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_Payment.html @@ -0,0 +1,283 @@ + + + + Checkout – Best Buy + + +
+ + + + + + + + + + + + + + + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
  • +
+
+
+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_ShippingAddress.html b/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_ShippingAddress.html new file mode 100644 index 000000000000..36760a26108e --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_ShippingAddress.html @@ -0,0 +1,326 @@ + + + + Checkout – Best Buy + + +
+ + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
  • +
+
+
+
    +
  • + +
  • +
  • + +
  • +
+
+
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/SignIn.html b/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/SignIn.html new file mode 100644 index 000000000000..8111d49c3725 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/BestBuy/SignIn.html @@ -0,0 +1,21 @@ + + + + Sign In to BestBuy.com + + +
+
+ + +
+
+ +
+ +
+
+ +
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_BillingPaymentInfo.html b/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_BillingPaymentInfo.html new file mode 100644 index 000000000000..3258417b78cd --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_BillingPaymentInfo.html @@ -0,0 +1,515 @@ + + + + + + Checkout + + + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+ Tester + Mo +
+
+ Mozilla +
+
331 E. Evelyn Avenue
+
+ Mountain View, + CA + 94041 +
+
+
+ + +
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+
The billing address above must match what appears on this credit card's statement.
+
+
+ + +
+
+ + + +
+
+ + + + + +
+
+ + +
+ + +
+
+
+ What is a CVV? +
+ For Visa, MasterCard & Discover, the three digits on the back of your card. +
+ For American Express, the 4 digits on the front of your card. +
+
+
+
+
+
+
+
+
+ +
+ + Verisign Secured + +
+
+ + BBB Accredited Busines + +
+
+
+
+
    +
  • + Edit +
    +
    + Address: +
    +
    +
    + Tester + Mo +
    +
    + Mozilla +
    +
    331 E. Evelyn Avenue
    +
    + Mountain View, + CA + 94041 +
    +
    +
    +
    + Contact Info: +
    +
    +
    + formautofilltester@gmail.com +
    +
    + 650-903-0800 650 +
    +
    +
    +
    +
  • +
  • + Edit +
    +
    Shipping Method
    +
    +
    UPS Ground (2-3 days)
    +
    2-3 business days
    +
    $19.99
    +
    +
    +
  • +
  • + Edit +
    +
    + Billing Address +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +, + + + + +
    +
    +
    Payment Method
    +
    +
    +
    +
  • +
  • +
  • +
+
+ +
+ +
+
+ + +
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_Logon.html b/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_Logon.html new file mode 100644 index 000000000000..6ee46c88731b --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_Logon.html @@ -0,0 +1,118 @@ + + + + + + Logon Checkout + + + +
+
+ + + +
+
+ + +
+

You don't need an account to place an order but you will have the option to create one after completing your purchase.

+
+
+
+

Click or touch the House +

+
+
+ +
+
+
+ + +
+
+ + + +
+ +! The validation code entered is incorrect +
+
+ +
+
+ + +
+
+
+
+
+ User Name + Forgot user name? +
+ +
+
+
+ + +
+ + + + +
+
+
+ Password + Forgot password? +
+ +
+
+
+
+
+ ! You have entered an invalid username and/or password. Please re-enter your information. +
+
+ ! + + +
+ +
+
+ + + + + +
+
+ +
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_ShippingInfo.html b/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_ShippingInfo.html new file mode 100644 index 000000000000..d461a0050b86 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_ShippingInfo.html @@ -0,0 +1,376 @@ + + + + + + Checkout + + + +
+
+ + + +
+
+ + +
+
+
+
+
+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
We will only contact you about your order and shipping.
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ + +
+
+
    +
  • + Edit +
    +
    + Address: +
    +
    +
    + + + + +
    +
    + + +
    +
    +
    +
    +
    +
    + +, + + + + +
    +
    +
    +
    + Contact Info: +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
  • +
  • + Edit +
    +
    Shipping Method
    +
    +
    -
    +
    -
    +
    -
    +
    +
    +
  • +
  • + Edit +
    +
    + Billing Address +
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +, + + + + +
    +
    +
    Payment Method
    +
    +
    +
    +
  • +
  • +
  • +
+
+
+ +
+
+ +
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/CostCo/Payment.html b/browser/extensions/formautofill/test/fixtures/third_party/CostCo/Payment.html new file mode 100644 index 000000000000..e45176cabc26 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/CostCo/Payment.html @@ -0,0 +1,892 @@ + + + + + + Costco - Payment + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + +
+
+ + +
+
+
+
+ + + +
+
+ + +  ? + +
+
+
+ + +
+
+ + +
+
+
+
+ + + + + + + + + + + + + + + + +
+
+ + +
+
+ + +  ? + +
+         More Info - Costco Cash Card + + Costco Cash Card Number + This image highlights the unique number + cashcard-us.gif + used to identify your Costco Cash card. + Pin Number + This number is used to access your + + Costco Cash card. The image shows + where this number is located. + @ 1998-2016 Costco Wholesale Corporation. All rights reserved. +
+
+
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+
+ +

+* Required fields

+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + + +
+ +
+
+ +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +

+* Required fields

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + + +
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + +
+
+ + +
+
+
+
[rx-DefaultAddrConfirm]
+
+
    +
  • + You are changing your Costco Default Shipping Address.  All future orders from Costco.com, including Pharmacy Prescription Orders, will be sent to this Address. +
  • +
+
+
+
+
+
+
+ +
+
+
+
+
+ + + + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/CostCo/ShippingAddress.html b/browser/extensions/formautofill/test/fixtures/third_party/CostCo/ShippingAddress.html new file mode 100644 index 000000000000..b9b72eb3385c --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/CostCo/ShippingAddress.html @@ -0,0 +1,527 @@ + + + + + + + Shipping + + + + + + +
+ + + + + + +
+
+ + + + + + +
+
+
+ +

+ * Required fields

+
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + + +
+ +
+
+ +
+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +

+* Required fields

+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + + +
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ + +
+
+ + +
+
+
+
+ [rx-DefaultAddrConfirm] +
+
+
    +
  • You are changing your Costco Default Shipping Address.  All future orders from Costco.com, including Pharmacy Prescription Orders, will be sent to this Address. +
  • +
+
+
+
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
+
+ + +
+ + +
+
+ + + + + + +
+ + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/CostCo/SignIn.html b/browser/extensions/formautofill/test/fixtures/third_party/CostCo/SignIn.html new file mode 100644 index 000000000000..afcd5fe6f09b --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/CostCo/SignIn.html @@ -0,0 +1,374 @@ + + + + + + Sign In + + + + + + +
+ + +
+ + + + + +
+
+
+
+
+ +
+ +
+ + +
+
+ + + + +
+
+
+
+
  • + +
  • +
    +
    +
    + + +
    +
    +
    + + + + + + + +

    Please provide your email address and password to access your account.† +

    +
    + + +
    +
    +
    + + +

    Passwords are case sensitive.

    +
    +
    +
    + + +
    + +
    + +
    +
    +
    + + + + + + + + + + +

    To reset your password, enter the email address associated with your Costco.com account. Instructions to create a new password will be sent to your address. +

    +
    + + +
    + +
    + +
    +
    +
    + + + + + + + + + + + + + + + + + + +

    Enter your email address and create a password below to register.† +

    +
    +* Required fields +
    +
    + + +
    +
    + + +
    + +
    +

    Password must meet the following:

    +
    +
      +
    • Use between 8 and 20 characters
    • +
    • Include at least one letter
    • +
    • Does not contain blank spaces or the following special characters: < > " \ . +
    • +
    • Passwords match
    • +
    +
    +

    Password Strength : + +

    +
      +
    • Too Short
    • +
    • Weak
    • +
    • Fair
    • +
    • Good
    • +
    • Strong
    • +
    +

    +

    +

    To improve strength, increase password length and use capital letters, numbers, and special characters + (except < > " \ .) +

    +
    +
    +
    +
    + + +
    +
    + + +
    +

    +Non-members may be assessed an additional surcharge. The surcharge does not apply to prescription items. Executive Members need to provide a membership number to receive credit for their 2% rebate. +

    +
    + + +
    + +
    + +
    +
    + +
    +
    + ???LANGUAGE_REGION_MODAL_TITLE??? +
    +
    +
    +

    ???LANGUAGE_REGION_MODAL_CHOOSE_LANGUAGE???

    + +
    +
    +
    +

    ???LANGUAGE_REGION_MODAL_CHOOSE_REGION???

    +
    + + + + + + + +
    +
    + + + + + + +
    +
    +
    + +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/Checkout_ShippingPayment.html b/browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/Checkout_ShippingPayment.html new file mode 100644 index 000000000000..182535065101 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/Checkout_ShippingPayment.html @@ -0,0 +1,381 @@ + + + + + + + The Home Depot - Checkout + + + + +
    + + +
    +
    +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    + + + + + + +
    +
    +
    + +
    +
    +
    +Create an account to track your order history and check out faster - all we need is a password.
    +
    +

    Check out faster, access past orders, and organize products into lists.

    +
    +
    +
    +
    + + + + + + + + +
    +
    + + + + + + + + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    + Passwords are case sensitive and must be at least 8 characters. +
    + Create a strong password by: +
      +
    • Including numbers or symbols
    • +
    • Mixing upper/lowercase
    • +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    +
    +
    +
    +
    +
    +Add an apartment, suite, building, etc. +
    +
    +
    + + + + +
    +
    + + + +MOUNTAIN VIEW, CA + +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    + Payment +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + Expiration + + + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + + + + +
    +
    +
    + Apply a Gift Card +  |  + Have a PO/Job Code for this order? +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    + + + + +
    +
    +
    + +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +Have a promo code? +
    +
    +
    + + + + +
    +
    +
    + + + + + +Apply + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/SignIn.html b/browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/SignIn.html new file mode 100644 index 000000000000..b741ce5f0c20 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/SignIn.html @@ -0,0 +1,83 @@ + + + + + The Home Depot - SignIn + + + + + + + +
    + + + + + + + + + + + +
    + + + + +
    +
    +

    You will have the opportunity to create an account and track your order once you complete your checkout. +

    +

    +

    +
    +
    + +
    +
    +
    + + +

    I'm a Returning Customer +

    +
    + Your sign in is incorrect. Please enter your email address or password. Note: One more invalid attempt will lock your account. +
    +
    + We periodically require password updates. Please reset your password or continue as a guest. +
    +
    + + + + +
    +
    + + + + + +
    +
    +
    + +
    + +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_Payment.html b/browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_Payment.html new file mode 100644 index 000000000000..4ec11c2b857f --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_Payment.html @@ -0,0 +1,478 @@ + + + + + Macy's Checkout + + + + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + +
    +
    +
    +
    + Note: PayPal can't be used with Gift Cards, Reward Cards and Credit Cards. + Plenti points can be earned but not used with PayPal. +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    Secure payment + more info +

    +
    +
    +
    +
    + + +
    Your Shipping, Plenti, and Gift Card information can be found and verified at the top of this page"
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    Please enter the 4 digit security code on the front of your credit card
    +
    Please enter the 3 digit security code on the back of your credit card
    +
    +
    + + + + +
    +
    +
    +
    +
    +
    +
    + Note: PayPal can't be used with Gift Cards, Reward Cards and Credit Cards. + Plenti points can be earned but not used with PayPal. +
    +
    +
    +
    + You will login on PayPal's site on the next page and review your order, then you will finish the transaction at macy's.com +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +

    Vance Chen

    +

    1099 Maiden Lane

    +

    102

    +

    Ann Arbor, MI 48105

    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + We'll only contact you if we have questions about this order. +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + + + + + + + + + + + + + + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_ShippingAddress.html b/browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_ShippingAddress.html new file mode 100644 index 000000000000..7ed68344fa90 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_ShippingAddress.html @@ -0,0 +1,439 @@ + + + + + Macy's Checkout + + + + + + +
    +
    +
    +
    +
    + + +Please enter a first name. +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + Shipping method +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    $10.95 +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    $19.95 +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    $29.95 +
    +
    +
    +
    +

    +Note: We'll send you an email to schedule your delivery. +

    +

    +Note: Some items in your order may ship separately. Transit time is the time between leaving our fulfillment center & delivery to you. +

    +
    +
    +
    +
    +
    +
    + + Gift Options + +
    +
    +
    +
    + +
    + "Selecting this checkbox will expand additional gift options" +
    + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + Write a personal message. We'll print it on a card & send it along with the order. +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Macys/SignIn.html b/browser/extensions/formautofill/test/fixtures/third_party/Macys/SignIn.html new file mode 100644 index 000000000000..51dff05d0464 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Macys/SignIn.html @@ -0,0 +1,208 @@ + + + + + Sign In - Macy's Checkout + + + + + + +
    +
    +
      +
    • +
      + +
      +
      + +
      +
       
      +
    • +
    • +
      + +
      +
      + +
      +
       
      +
    • +
    +
    +
    +Password is case sensitive +
    + +
    + +
    +
    +
    +
    +
    +
    +
      +
    • + + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +
      +
    • + + + + + +
    • +
    • + enter the letters in the below field +
      + +new_image + +
      +
    • +
    • + + + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +
      +
    • + + + +
    • +
    • +
      +
      +
    • +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +
      +
    • +
      +
      + +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
    • +
    • +
      +
      + +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
    • +
    • + +
    • +
    +
    +
    + + + + + + + + + + + + + + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/BillingInfo.html b/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/BillingInfo.html new file mode 100644 index 000000000000..c614660e1093 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/BillingInfo.html @@ -0,0 +1,1083 @@ + + + + + Newegg.com - Billing Info + + + + + + + + + +
    +
    + Redeem Newegg gift cards + +
    +
    +
    +
    +
    + + + +
    +
    + + + +
    +
    + + + + +
    +
    + EggPoints +
    +
    +
      +
    • +
      +
      +
      +
      +
      +
      +
      +Missing Information Card Number and Security Code fields cannot be empty. Please enter valid information and try again.
      +
      +
      +
      +
      +
    • +
    +
    + Payment Methods + + +
    +

    Some payment methods may not be eligible for your order. Please review the full list by clicking here for payment restrictions.

    +
    + + +
    +
    +
      +
    • + + +
      +
      +
      + Newegg Store Credit Card +

      +

      +
      +
      + Newegg Store Credit Card +
      +
      +
      +
      +
      + + +
      +
      + + +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      Do not have a Newegg Store Credit Card? Learn More +
      +
      +
    • +
    • + + +
      +
      +
      + Amex Express Checkout Button +

      +

      +
      +
      + Checkout faster with American Express +
      +
      +
      +
    • +
    • + + +
      +
      +
      + Bitcoin accepted here +

      +

      +
      +
      + Bitcoin is the safest and most secure way to pay online. +
        +
      • No identity theft risk; no payment information is ever stored.
      • +
      • Your payment completes immediately.
      • +
      • +Learn more + +
      • +
      +
      +
      +
      +
      +
      +
      +
      +NOTE: Please note that when using Bitcoin as your payment method, once you have clicked the "bitcoin checkout now" button, you will have only 15 minutes to complete your payment. If you are unable to complete your payment, you will have two options: You can try again later to place a new order or you can change your payment method later from Order History in My Account.
      +
      + All orders fully paid by Bitcoin are final and cannot be returned for Bitcoin or hard currency. All returns will be made in the form of a Newegg Gift Card. All returns follow our return policy. +
      +
      +
      +
      +
      +
      +
    • + +
    • + + +
      +
      +
      + MasterPass +

      +

      +
      +
      + MasterPass is a free service that is a fast, simple and safe way to check out online. It cuts down on the time and effort it takes to buy the things you want and need. And because it's from MasterCard, you can trust that it's secure. + +
        +
      • + When you are ready to check out online, click on the "Buy with MasterPass" button. +
      • +
      • + Next, unlock your MasterPass account to choose your payment method and shipping address. +
      • +
      • + Then simply confirm your purchase, and you are done! +
      • +
      • + Use it with all major credit, debit, and prepaid cards. +
      • +
      • + Use it to easily store all your cards and addresses in one place. +
      • +
      • + Use it on all your connected devices. +
      • +
      +
      +
      +
      +
    • +
    • + + +
      +
      +
      + +Visa Checkout + + Visa Checkout + +

      +

      +
      +
      +
      +
    • +
    • + + +
      +
      +
      + newegg +
        +
      • + Speed through checkout. +
      • +
      • + PayPal is the safer, easier way to pay. +
      • +
      • + + What is PayPal? + +
      • +
      +

      +

      +
      +
      + + PayPal is the safer, easier way to pay + +
        +
      • + Never expose your credit card number. +
      • +
      • + Speed through checkout all over the web. One account, one password - no need to retype your shipping or financial information. +
      • +
      +
      +
      +
      +
    • +
    • + + +
      +
      +
      +
      + +
      +
      +
      + +
      + +
      +
      +
      +
      +
      +

      + All major credit cards accepted: + + Major Cards Accepted + Major Cards Accepted + Major Cards Accepted + Major Cards Accepted + +

      +
      +
      + + +
      +
      + + + Major Cards Accepted +
      +
      + + + +
      +
      + + + + cvv2 + +
      +
      +
      + +
      +
      + +
      +
      + +
      +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + +
      +
      +
      +
    • +
    + +
    +
    + Billing Address + + +
    +
      +
    • + + +
    • +
    • +
        +
      • 331 E. Evelyn Avenue
      • +
      • Mountain View,CA 94041
      • +
      • United States
      • +
      • 650-903-0800
      • +
      • + formautofilltester@gmail.com +
      • +
      +
    • +
    • +
      + + + +
        +
      • + + +
      • +
      • + + +
      • +
      • + + +
      • +
      • +
          +
        • +
          + + +
          +
        • +
        • +
          + +
          + +
          +
          +
          + + +
          +
        • +
        • + + +
        • +
        • + + +
        • + + +
        +
      • +
      +
      +
    • + + + + + + + + + + + + +
    + + + + + + + + + + + +
    +
    +
    +
    +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • + + + Major Cards Accepted +
    • +
    • + + + +
    • +
    • + +
    • +
    • +
    • +
    +
    + + + + + + + +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
      +
    • + + +
    • +
    • + + +
    • +
    • +
    • + + +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/Login.html b/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/Login.html new file mode 100644 index 000000000000..a5f149b68362 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/Login.html @@ -0,0 +1,156 @@ + + + + + Newegg.com - Login + + + + + + + + + +
    + + + + + + + + + + + + + + + +
    +
    + + CONTINUE AS A GUEST + +
    +
    + + + + + + +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • +
    • +
    • + + +
    • +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/ShippingInfo.html b/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/ShippingInfo.html new file mode 100644 index 000000000000..14bd9502afe4 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/NewEgg/ShippingInfo.html @@ -0,0 +1,270 @@ + + + + + Newegg.com - Shipping Info + + + + + + + + + +
    + + + + +
      +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • + + +
    • +
    • +
        +
      • +
        + + +
        +
      • +
      • +
        + +
        + +
        +
        +
        + + +
        +
      • +
      • + + +
      • +
      • + + +
      • +
      • + +
      • + +
      +
    • +
    + +
    + + + +
      +
    • + + +
      +
      +
    • +
    +
    + + +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/Payment.html b/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/Payment.html new file mode 100644 index 000000000000..06b9f8e7632b --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/Payment.html @@ -0,0 +1,672 @@ + + + + + + + + + + + + + + + + + Office Supplies, Furniture, Technology at Offic Depot + + + +
    + + + + + + + + + + + + + +
    +
    +
    +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +Need Help? +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + +
    +
    +
    +
    +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +

    + +

    + + 87 +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + + + + + +
    + + + + + + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/ShippingAddress.html b/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/ShippingAddress.html new file mode 100644 index 000000000000..849e3be49559 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/ShippingAddress.html @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + Office Supplies, Furniture, Technology at Office Depot + + + +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + + + +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + +
    + + + + + + +
    +
    +
    +
    +
    +
    + + + + + + + + + + +
    +
    + + +
    +
    +
    +
    + + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/SignIn.html b/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/SignIn.html new file mode 100644 index 000000000000..70b55fedddb3 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/SignIn.html @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + Office Supplies, Furniture, Technology at Office Depot + + + +
    + + + + + +
    + + + +
    +
    + + + +Forgot login name/password? + +
    +
    + Keep me logged in +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/QVC/PaymentMethod.html b/browser/extensions/formautofill/test/fixtures/third_party/QVC/PaymentMethod.html new file mode 100644 index 000000000000..9d51db7c5d8c --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/QVC/PaymentMethod.html @@ -0,0 +1,527 @@ + + + + + + + + + Payment Method + + +
    + + + + + + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
      +
    • + + +
    • +
    • + + +
    • +
    + + +
    +
    +
    + + + + + + + + + + + + + + + + +
    + + + (formerly Bill Me Later®) +
    +
    +
    + + +
    +
    + + +
    +
    + XXX-XX- +
    +
    + + + + + + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + +      +
    +
    +
    + + + + + +
    + + +
    +
    +
    +
    +   +
    +
    +
    + + + + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + Enter Another Card + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + Continue Checkout + + + Continue Checkout + + + + + Edit Shopping cart + +
    +
    +
    +
    + + * + + + + *You're signing up to receive QVC promotional email. +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/QVC/SignIn.html b/browser/extensions/formautofill/test/fixtures/third_party/QVC/SignIn.html new file mode 100644 index 000000000000..a056ccfc5cc5 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/QVC/SignIn.html @@ -0,0 +1,80 @@ + + + + + + + + QVC.com Sign In + + +
    +
    + + + + + + +
    +
    +
    + +
    + + + + + + + + +
    +
    + + +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +
    + + Create Password + + + + Continue + + +
    +
    + + Sign In + + +
    +
    +
    + +
    +
    +
    + +
    + + Continue + + +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/QVC/YourInformation.html b/browser/extensions/formautofill/test/fixtures/third_party/QVC/YourInformation.html new file mode 100644 index 000000000000..7af160e354cc --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/QVC/YourInformation.html @@ -0,0 +1,522 @@ + + + + + + + + + Payment Method + + +
    + + + + + + + + + + + + + + + + + + + +
    +
    +
      +
    • + + +
    • +
    • + + +
    • +
    + + +
    +
    +
    + + + + + + + + + + + + + + + + +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + XXX-XX- +
    +
    + + + + + + +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + +      +
    +
    +
    + + + + + +
    + + +
    +
    +
    +
    +   +
    +
    +
    + + + Add My QCard + + + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + Enter Another Card + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    +
    + + + Continue Checkout + + + Continue Checkout + + + + + Edit Shopping cart + +
    +
    +
    +
    + + * + + + + *You're signing up to receive QVC promotional email. +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/README b/browser/extensions/formautofill/test/fixtures/third_party/README new file mode 100644 index 000000000000..ca4750ec08cf --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/README @@ -0,0 +1,4 @@ +This directory contains pages downloaded from the web for the purpose of testing +Form Autofill against pages from the real world. These files are not made +available under an open source license. + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Sears/PaymentOptions.html b/browser/extensions/formautofill/test/fixtures/third_party/Sears/PaymentOptions.html new file mode 100644 index 000000000000..5f6ecd24d9d7 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Sears/PaymentOptions.html @@ -0,0 +1,566 @@ + + + + + + + + + + + Payment Options | Sears PartsDirect + + + + +
    +
    + + + + + + +
    +
    +
    + + + + + + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + + + + + + +
    + + +
    +
    + + +
    + +
    + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    + + + + +
    +
    +
    +
    +
    + + +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Sears/ShippingAddress.html b/browser/extensions/formautofill/test/fixtures/third_party/Sears/ShippingAddress.html new file mode 100644 index 000000000000..a9d1f5cd0f3f --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Sears/ShippingAddress.html @@ -0,0 +1,447 @@ + + + + + + + + + + + Shipping address | Sears PartsDirect + + + + +
    +
    + + + + + + +
    +
    +
    + +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    +
    +

    +

    +
    + + + +
    +
    + +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    24 character limit
    +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + +
    + +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    + + + +
    +
    +
      +
    • + +
    • +
    +
    +
    +
    + + +
    +
    +
    + + +
    +
    +
    + + + + + +
    + + +
    +
    + + +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic.html b/browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic.html new file mode 100644 index 000000000000..cf9e892cb2b2 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic.html @@ -0,0 +1,117 @@ + + + + + It's easy to find the Office Supplies, Copy Paper, + Furniture, Ink, Toner, Cleaning Products, Electronics and the + Technology you need | Staples® + + + + + + + + + + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic_ac_on.html b/browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic_ac_on.html new file mode 100644 index 000000000000..d3ba1116aabf --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic_ac_on.html @@ -0,0 +1,117 @@ + + + + + It's easy to find the Office Supplies, Copy Paper, + Furniture, Ink, Toner, Cleaning Products, Electronics and the + Technology you need | Staples® + + + + + + + + + + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling.html b/browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling.html new file mode 100644 index 000000000000..37dadeb514a9 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling.html @@ -0,0 +1,99 @@ + + + + + It's easy to find the Office Supplies, Copy Paper, + Furniture, Ink, Toner, Cleaning Products, Electronics and the + Technology you need | Staples® + + + + + + + + + + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +

    Purchase Order # (optional) Add +

    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    +By placing your order, you agree to + Staples + +Terms & + Conditions. + +

    +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling_ac_on.html b/browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling_ac_on.html new file mode 100644 index 000000000000..98c9fb85555b --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling_ac_on.html @@ -0,0 +1,98 @@ + + + + + It's easy to find the Office Supplies, Copy Paper, + Furniture, Ink, Toner, Cleaning Products, Electronics and the + Technology you need | Staples® + + + + + + + + + + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +

    Purchase Order # (optional) Add +

    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    +By placing your order, you agree to + Staples + +Terms & + Conditions. + +

    +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Checkout.html b/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Checkout.html new file mode 100644 index 000000000000..0d59eec17280 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Checkout.html @@ -0,0 +1,243 @@ + + + + + + + + + + + + +
    +

    Enter new zip code:

    + +
    +

    + +

    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    *required field
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +By clicking Create Account, you acknowledge you + have read and agreed to our +Terms of + Use +and +Privacy + Policy +. + +
    + +
    +
    + + +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Payment.html b/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Payment.html new file mode 100644 index 000000000000..26936843291a --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Payment.html @@ -0,0 +1,235 @@ + + + + + + + + + Checkout + + + + + + + + + + + +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    * required field
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + +
    + + + +
    +  /  +
    + + + +
    +
    +
    +
    + + +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +

    +22F., No.55, Haiiu 1st Rd., Bafu Dist., +
    + +San Bruno +, + + +CA + +94066 +

    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Shipping.html b/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Shipping.html new file mode 100644 index 000000000000..908453b7f1e0 --- /dev/null +++ b/browser/extensions/formautofill/test/fixtures/third_party/Walmart/Shipping.html @@ -0,0 +1,234 @@ + + + + + + + + + Checkout + + + + + + + + + + + +
    +

    Enter new zip code:

    + +
    +

    + +

    + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +
    +
    *required field
    + +
    + +
    + +
    + +
    + +
    + +
    +
    +
    + +
    + +
    + +
    + +
    + +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + diff --git a/browser/extensions/formautofill/test/unit/head.js b/browser/extensions/formautofill/test/unit/head.js index a49757a340ba..0bf3608ba4e4 100644 --- a/browser/extensions/formautofill/test/unit/head.js +++ b/browser/extensions/formautofill/test/unit/head.js @@ -2,7 +2,7 @@ * Provides infrastructure for automated formautofill components tests. */ -/* exported loadFormAutofillContent, getTempFile, sinon */ +/* exported getTempFile, loadFormAutofillContent, runHeuristicsTest, sinon */ "use strict"; @@ -79,6 +79,45 @@ function getTempFile(leafName) { return file; } +function runHeuristicsTest(patterns, fixturePathPrefix) { + Cu.import("resource://gre/modules/FormLikeFactory.jsm"); + Cu.import("resource://formautofill/FormAutofillHeuristics.jsm"); + + // TODO: "select" and "textarea" will be included eventually. + const QUERY_STRING = ["input"]; + patterns.forEach(testPattern => { + add_task(function* () { + do_print("Starting test fixture: " + testPattern.fixturePath); + let file = do_get_file(fixturePathPrefix + testPattern.fixturePath); + let doc = MockDocument.createTestDocumentFromFile("http://localhost:8080/test/", file); + + let forms = []; + + for (let query of QUERY_STRING) { + for (let field of doc.querySelectorAll(query)) { + let formLike = FormLikeFactory.createFromField(field); + if (!forms.some(form => form.rootElement === formLike.rootElement)) { + forms.push(formLike); + } + } + } + + Assert.equal(forms.length, testPattern.expectedResult.length, "Expected form count."); + + forms.forEach((form, formIndex) => { + let formInfo = FormAutofillHeuristics.getFormInfo(form); + // TODO: This line should be uncommented to make sure every field are verified. + // Assert.equal(formInfo.length, testPattern.expectedResult[formIndex].length, "Expected field count."); + formInfo.forEach((field, fieldIndex) => { + let expectedField = testPattern.expectedResult[formIndex][fieldIndex]; + expectedField.elementWeakRef = field.elementWeakRef; + Assert.deepEqual(field, expectedField); + }); + }); + }); + }); +} + add_task(function* head_initialize() { Services.prefs.setBoolPref("browser.formautofill.experimental", true); Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", true); diff --git a/browser/extensions/formautofill/test/unit/heuristics/test_basic.js b/browser/extensions/formautofill/test/unit/heuristics/test_basic.js new file mode 100644 index 000000000000..5f3c7759c85e --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/test_basic.js @@ -0,0 +1,22 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "autocomplete_basic.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, +], "../../fixtures/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_BestBuy.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_BestBuy.js new file mode 100644 index 000000000000..60df0f661a29 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_BestBuy.js @@ -0,0 +1,56 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "Checkout_ShippingAddress.html", + expectedResult: [ + [], // Search form + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO:select,state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + ], + [ // Sign up + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ // unknown + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + ], + ], + }, { + fixturePath: "Checkout_Payment.html", + expectedResult: [ + [], // Search form + [ // Sign up + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO:select,state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + ], + [ + // unknown + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + ], + ], + }, { + fixturePath: "SignIn.html", + expectedResult: [ + [ // Sign in + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, +], "../../../fixtures/third_party/BestBuy/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CDW.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CDW.js new file mode 100644 index 000000000000..6c7a5fe0d2b8 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CDW.js @@ -0,0 +1,55 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "Checkout_ShippingInfo.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select,state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + ], + [], + ], + }, { + fixturePath: "Checkout_BillingPaymentInfo.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select,state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + ], + [ + /* TODO: Credit Card + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, +*/ + ], + ], + }, { + fixturePath: "Checkout_Logon.html", + expectedResult: [ + [], + [], + [], + ], + }, +], "../../../fixtures/third_party/CDW/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CostCo.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CostCo.js new file mode 100644 index 000000000000..f5e77d42fe77 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_CostCo.js @@ -0,0 +1,124 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "ShippingAddress.html", + expectedResult: [ + [], + [], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "additional-name"}, // middle-name initial + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, // TODO: select,country + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, // TODO: fix the regexp + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select,state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "additional-name"}, // middle-name initial + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, // TODO: select,country + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, // TODO: fix the regexp + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select,state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, { + fixturePath: "Payment.html", + expectedResult: [ + [ +/* TODO: credit card + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"}, // ac-off +*/ + ], + [], + [], + [], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "additional-name"}, // middle-name initial + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, // TODO: select, country + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, // TODO: fix the regexp + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "additional-name"}, // middle-name initial + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, // TODO: select, country + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, // TODO: fix the regexp + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, { + fixturePath: "SignIn.html", + expectedResult: [ + [], + [], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + [ // Forgot password + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "password"}, + ], + [ // Sign up + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, +], "../../../fixtures/third_party/CostCo/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_HomeDepot.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_HomeDepot.js new file mode 100644 index 000000000000..77993b6c66a9 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_HomeDepot.js @@ -0,0 +1,34 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "Checkout_ShippingPayment.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, + ], + ], + }, { + fixturePath: "SignIn.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, +], "../../../fixtures/third_party/HomeDepot/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Macys.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Macys.js new file mode 100644 index 000000000000..6a957ae5e6ad --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Macys.js @@ -0,0 +1,67 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "Checkout_ShippingAddress.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // select + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + ], + [ +/* +*/ + ], + ], + }, { + fixturePath: "Checkout_Payment.html", + expectedResult: [ + [ + /* + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, // ac-off +*/ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // select + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, { + fixturePath: "SignIn.html", + expectedResult: [ + [ // Sign in + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "password"}, + ], + [ // Forgot password + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + [], + [], + ], + }, +], "../../../fixtures/third_party/Macys/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_NewEgg.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_NewEgg.js new file mode 100644 index 000000000000..d5479f364d52 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_NewEgg.js @@ -0,0 +1,66 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "ShippingInfo.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, // TODO: select, country + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, { + fixturePath: "BillingInfo.html", + expectedResult: [ + [ +/* TODO: Should match the following fields. + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, +*/ +// {"section": "", "addressType": "", "contactType": "", "fieldName": "country"}, // TODO: select, country + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, country + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"}, // TODO +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, // TODO +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, // TODO +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, // TODO + ], + [], + [], + [], + ], + }, { + fixturePath: "Login.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, +], "../../../fixtures/third_party/NewEgg/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_OfficeDepot.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_OfficeDepot.js new file mode 100644 index 000000000000..c553615c765f --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_OfficeDepot.js @@ -0,0 +1,64 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "ShippingAddress.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + + // TODO: telphone relative fields should be fixed: + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, + + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, { + fixturePath: "Payment.html", + expectedResult: [ + [ +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + + // TODO: telphone relative fields should be fixed: + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-area-code"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-prefix"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-local-suffix"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, + + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, { + fixturePath: "SignIn.html", + expectedResult: [ + [ // ac-off +// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, +], "../../../fixtures/third_party/OfficeDepot/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_QVC.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_QVC.js new file mode 100644 index 000000000000..d2b088ca9d49 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_QVC.js @@ -0,0 +1,54 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "YourInformation.html", + expectedResult: [ + [ +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, { + fixturePath: "PaymentMethod.html", + expectedResult: [ + [ +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, // ac-off + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"}, // select +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, // select +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"}, // select +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-type"}, // select +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"}, // select +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, { + fixturePath: "SignIn.html", + expectedResult: [ + [ + // Unknown + ], + [ // Sign in + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [], + ], + }, +], "../../../fixtures/third_party/QVC/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Sears.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Sears.js new file mode 100644 index 000000000000..60fe39e55ad2 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Sears.js @@ -0,0 +1,87 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "ShippingAddress.html", + expectedResult: [ + [], + [], // search form, ac-off + [ // ac-off +// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ // check-out, ac-off +/* + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +*/ + ], + [ // ac-off +/* + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "new-password"}, +*/ + ], + [ // ac-off +// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + [ // ac-off +// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, { + fixturePath: "PaymentOptions.html", + expectedResult: [ + [], + [], // search + [ // credit card +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, + ], + [ // Another billing address + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, + ], + [ // check out + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: Wrong. This is for Driver's license. +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-month"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-day"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "bday-year"}, + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + ], + ], + }, +], "../../../fixtures/third_party/Sears/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Staples.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Staples.js new file mode 100644 index 000000000000..240aa0fbbea3 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Staples.js @@ -0,0 +1,48 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "Basic.html", + expectedResult: [ + [ // ac-off +// {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + ], + ], + }, { + fixturePath: "Basic_ac_on.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "tel-extension"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"}, + ], + ], + }, { + fixturePath: "PaymentBilling.html", + expectedResult: [ + [], + ], + }, { + fixturePath: "PaymentBilling_ac_on.html", + expectedResult: [ + [ +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, + ], + ], + }, +], "../../../fixtures/third_party/Staples/"); + diff --git a/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Walmart.js b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Walmart.js new file mode 100644 index 000000000000..4d8d67953a63 --- /dev/null +++ b/browser/extensions/formautofill/test/unit/heuristics/third_party/test_Walmart.js @@ -0,0 +1,62 @@ +/* global runHeuristicsTest */ + +"use strict"; + +runHeuristicsTest([ + { + fixturePath: "Checkout.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + ], + [ + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "password"}, // ac-off + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "email"}, // ac-off +// {"section": "", "addressType": "", "contactType": "", "fieldName": "password"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "password"}, // ac-off + ], + ], + }, { + fixturePath: "Payment.html", + expectedResult: [ + [ + ], + [ + {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "family-name"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-csc"}, + {"section": "section-payment", "addressType": "", "contactType": "", "fieldName": "tel"}, + ], + ], + }, { + fixturePath: "Shipping.html", + expectedResult: [ + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + ], + [ + ], + [ + {"section": "", "addressType": "", "contactType": "", "fieldName": "given-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "family-name"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"}, + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"}, +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"}, // TODO: fix the regexp + {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"}, // city +// {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level1"}, // TODO: select, state + {"section": "", "addressType": "", "contactType": "", "fieldName": "postal-code"}, + ], + ], + }, +], "../../../fixtures/third_party/Walmart/"); + diff --git a/browser/extensions/formautofill/test/unit/xpcshell.ini b/browser/extensions/formautofill/test/unit/xpcshell.ini index 78c472186503..724e799c2e71 100644 --- a/browser/extensions/formautofill/test/unit/xpcshell.ini +++ b/browser/extensions/formautofill/test/unit/xpcshell.ini @@ -2,7 +2,20 @@ firefox-appdir = browser head = head.js support-files = + ../fixtures/** +[heuristics/test_basic.js] +[heuristics/third_party/test_BestBuy.js] +[heuristics/third_party/test_CDW.js] +[heuristics/third_party/test_CostCo.js] +[heuristics/third_party/test_HomeDepot.js] +[heuristics/third_party/test_Macys.js] +[heuristics/third_party/test_NewEgg.js] +[heuristics/third_party/test_OfficeDepot.js] +[heuristics/third_party/test_QVC.js] +[heuristics/third_party/test_Sears.js] +[heuristics/third_party/test_Staples.js] +[heuristics/third_party/test_Walmart.js] [test_autofillFormFields.js] [test_collectFormFields.js] [test_enabledStatus.js] diff --git a/toolkit/modules/tests/modules/MockDocument.jsm b/toolkit/modules/tests/modules/MockDocument.jsm index 3cae9bb910e0..a4048dac9a01 100644 --- a/toolkit/modules/tests/modules/MockDocument.jsm +++ b/toolkit/modules/tests/modules/MockDocument.jsm @@ -10,6 +10,8 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; Cu.importGlobalProperties(["URL"]); +const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {}); + const MockDocument = { /** * Create a document for the given URL containing the given HTML with the ownerDocument of all
    s having a mocked location. @@ -46,5 +48,15 @@ const MockDocument = { }); }, + createTestDocumentFromFile(aDocumentURL, aFile) { + let fileStream = Cc["@mozilla.org/network/file-input-stream;1"]. + createInstance(Ci.nsIFileInputStream); + fileStream.init(aFile, -1, -1, 0); + + let data = NetUtil.readInputStreamToString(fileStream, fileStream.available()); + + return this.createTestDocument(aDocumentURL, data); + }, + }; From 527fb3fff577a9767f24bbb0696f9cfd71628afb Mon Sep 17 00:00:00 2001 From: Aryeh Gregor Date: Thu, 20 Apr 2017 17:37:07 +0300 Subject: [PATCH 04/11] Bug 1358104 - Only throw InvalidCharacterError for bad XML id's, not NamespaceError r=baku Discussion at . In short, the specification used to say to throw sometimes InvalidCharacterError and sometimes NamespaceError, but browsers disagreed on which to throw in corner cases, and everyone agreed it wasn't worth the effort to spec the distinction, so we just changed it to InvalidCharacterError across the board. The test changes are already upstream. MozReview-Commit-ID: AWSZBznQprG --HG-- extra : rebase_source : 2f0051f48124380f17300a38ceb8c2ab23015ca1 --- dom/base/nsContentUtils.cpp | 7 +-- .../test_createAttributeNS01.html | 4 +- .../test_createDocument01.html | 4 +- .../test_createDocumentType01.html | 4 +- .../test_createElementNS01.html | 4 +- .../test_documentcreateattributeNS04.html | 2 +- ...est_domimplementationcreatedocument07.html | 2 +- .../test_setAttributeNS02.html | 4 +- .../DOMImplementation-createDocumentType.html | 6 +-- .../dom/nodes/Document-createElementNS.js | 48 +++++++++---------- .../tests/dom/nodes/attributes.html | 4 +- 11 files changed, 42 insertions(+), 47 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index a35f546208d6..69d675ff80ac 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3094,12 +3094,7 @@ nsContentUtils::CheckQName(const nsAString& aQualifiedName, return NS_OK; } - // MOZ_EXPAT_EMPTY_QNAME || MOZ_EXPAT_INVALID_CHARACTER - if (result == (1 << 0) || result == (1 << 1)) { - return NS_ERROR_DOM_INVALID_CHARACTER_ERR; - } - - return NS_ERROR_DOM_NAMESPACE_ERR; + return NS_ERROR_DOM_INVALID_CHARACTER_ERR; } //static diff --git a/dom/tests/mochitest/dom-level2-core/test_createAttributeNS01.html b/dom/tests/mochitest/dom-level2-core/test_createAttributeNS01.html index aea5a3a6e0cf..727ee15f8caf 100644 --- a/dom/tests/mochitest/dom-level2-core/test_createAttributeNS01.html +++ b/dom/tests/mochitest/dom-level2-core/test_createAttributeNS01.html @@ -108,9 +108,9 @@ function createAttributeNS01() { newAttr = doc.createAttributeNS(namespaceURI,malformedName); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } - assertTrue("throw_NAMESPACE_ERR",success); + assertTrue("throw INVALID_CHARACTER_ERR",success); } } diff --git a/dom/tests/mochitest/dom-level2-core/test_createDocument01.html b/dom/tests/mochitest/dom-level2-core/test_createDocument01.html index ffc032082893..173c2bdb824b 100644 --- a/dom/tests/mochitest/dom-level2-core/test_createDocument01.html +++ b/dom/tests/mochitest/dom-level2-core/test_createDocument01.html @@ -114,9 +114,9 @@ function createDocument01() { aNewDoc = domImpl.createDocument(namespaceURI,malformedName,docType); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } - assertTrue("throw_NAMESPACE_ERR",success); + assertTrue("throw INVALID_CHARACTER_ERR",success); } } diff --git a/dom/tests/mochitest/dom-level2-core/test_createDocumentType01.html b/dom/tests/mochitest/dom-level2-core/test_createDocumentType01.html index d52ce64e1c44..d6d460d00969 100644 --- a/dom/tests/mochitest/dom-level2-core/test_createDocumentType01.html +++ b/dom/tests/mochitest/dom-level2-core/test_createDocumentType01.html @@ -112,9 +112,9 @@ function createDocumentType01() { newType = domImpl.createDocumentType(malformedName,publicId,systemId); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } - assertTrue("throw_NAMESPACE_ERR",success); + assertTrue("throw INVALID_CHARACTER_ERR", success); } } diff --git a/dom/tests/mochitest/dom-level2-core/test_createElementNS01.html b/dom/tests/mochitest/dom-level2-core/test_createElementNS01.html index e15464d3b42a..e592d096fbd6 100644 --- a/dom/tests/mochitest/dom-level2-core/test_createElementNS01.html +++ b/dom/tests/mochitest/dom-level2-core/test_createElementNS01.html @@ -108,9 +108,9 @@ function createElementNS01() { newElement = doc.createElementNS(namespaceURI,malformedName); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } - assertTrue("throw_NAMESPACE_ERR",success); + assertTrue("throw INVALID_CHARACTER_ERR", success); } } diff --git a/dom/tests/mochitest/dom-level2-core/test_documentcreateattributeNS04.html b/dom/tests/mochitest/dom-level2-core/test_documentcreateattributeNS04.html index 89e34b874d30..1485f75a07bf 100644 --- a/dom/tests/mochitest/dom-level2-core/test_documentcreateattributeNS04.html +++ b/dom/tests/mochitest/dom-level2-core/test_documentcreateattributeNS04.html @@ -113,7 +113,7 @@ function documentcreateattributeNS04() { attribute = doc.createAttributeNS(namespaceURI,qualifiedName); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } assertTrue("documentcreateattributeNS04",success); } diff --git a/dom/tests/mochitest/dom-level2-core/test_domimplementationcreatedocument07.html b/dom/tests/mochitest/dom-level2-core/test_domimplementationcreatedocument07.html index b87b2150cb87..056fa2d256ec 100644 --- a/dom/tests/mochitest/dom-level2-core/test_domimplementationcreatedocument07.html +++ b/dom/tests/mochitest/dom-level2-core/test_domimplementationcreatedocument07.html @@ -106,7 +106,7 @@ function domimplementationcreatedocument07() { newDoc = domImpl.createDocument(namespaceURI,":",docType); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } assertTrue("domimplementationcreatedocument07",success); } diff --git a/dom/tests/mochitest/dom-level2-core/test_setAttributeNS02.html b/dom/tests/mochitest/dom-level2-core/test_setAttributeNS02.html index 6f58738f6cf6..de73321e66b9 100644 --- a/dom/tests/mochitest/dom-level2-core/test_setAttributeNS02.html +++ b/dom/tests/mochitest/dom-level2-core/test_setAttributeNS02.html @@ -109,9 +109,9 @@ function setAttributeNS02() { testAddr.setAttributeNS(namespaceURI,qualifiedName,"newValue"); } catch(ex) { - success = (typeof(ex.code) != 'undefined' && ex.code == 14); + success = ex.code === DOMException.INVALID_CHARACTER_ERR; } - assertTrue("throw_NAMESPACE_ERR",success); + assertTrue("throw INVALID_CHARACTER_ERR",success); } } diff --git a/testing/web-platform/tests/dom/nodes/DOMImplementation-createDocumentType.html b/testing/web-platform/tests/dom/nodes/DOMImplementation-createDocumentType.html index ac79ddd7340a..f7e6e18b8442 100644 --- a/testing/web-platform/tests/dom/nodes/DOMImplementation-createDocumentType.html +++ b/testing/web-platform/tests/dom/nodes/DOMImplementation-createDocumentType.html @@ -80,9 +80,9 @@ test(function() { ["(", "", "", "INVALID_CHARACTER_ERR"], [")", "", "", "INVALID_CHARACTER_ERR"], ["f:oo", "", "", null], - [":foo", "", "", "NAMESPACE_ERR"], - ["foo:", "", "", "NAMESPACE_ERR"], - ["prefix::local", "", "", "NAMESPACE_ERR"], + [":foo", "", "", "INVALID_CHARACTER_ERR"], + ["foo:", "", "", "INVALID_CHARACTER_ERR"], + ["prefix::local", "", "", "INVALID_CHARACTER_ERR"], ["foo", "foo", "", null], ["foo", "", "foo", null], ["foo", "f'oo", "", null], diff --git a/testing/web-platform/tests/dom/nodes/Document-createElementNS.js b/testing/web-platform/tests/dom/nodes/Document-createElementNS.js index 1abd3330183c..bf5e12cf9518 100644 --- a/testing/web-platform/tests/dom/nodes/Document-createElementNS.js +++ b/testing/web-platform/tests/dom/nodes/Document-createElementNS.js @@ -25,11 +25,11 @@ var createElementNS_tests = [ [null, "fo o", "INVALID_CHARACTER_ERR"], [null, "-foo", "INVALID_CHARACTER_ERR"], [null, ".foo", "INVALID_CHARACTER_ERR"], - [null, ":foo", "NAMESPACE_ERR"], + [null, ":foo", "INVALID_CHARACTER_ERR"], [null, "f:oo", "NAMESPACE_ERR"], - [null, "foo:", "NAMESPACE_ERR"], - [null, "f:o:o", "NAMESPACE_ERR"], - [null, ":", "NAMESPACE_ERR"], + [null, "foo:", "INVALID_CHARACTER_ERR"], + [null, "f:o:o", "INVALID_CHARACTER_ERR"], + [null, ":", "INVALID_CHARACTER_ERR"], [null, "xml", null], [null, "xmlns", "NAMESPACE_ERR"], [null, "xmlfoo", null], @@ -38,19 +38,19 @@ var createElementNS_tests = [ [null, "xmlfoo:bar", "NAMESPACE_ERR"], [null, "null:xml", "NAMESPACE_ERR"], ["", null, null], - ["", ":foo", "NAMESPACE_ERR"], + ["", ":foo", "INVALID_CHARACTER_ERR"], ["", "f:oo", "NAMESPACE_ERR"], - ["", "foo:", "NAMESPACE_ERR"], + ["", "foo:", "INVALID_CHARACTER_ERR"], [undefined, null, null], [undefined, undefined, null], [undefined, "foo", null], [undefined, "1foo", "INVALID_CHARACTER_ERR"], [undefined, "f1oo", null], [undefined, "foo1", null], - [undefined, ":foo", "NAMESPACE_ERR"], + [undefined, ":foo", "INVALID_CHARACTER_ERR"], [undefined, "f:oo", "NAMESPACE_ERR"], - [undefined, "foo:", "NAMESPACE_ERR"], - [undefined, "f::oo", "NAMESPACE_ERR"], + [undefined, "foo:", "INVALID_CHARACTER_ERR"], + [undefined, "f::oo", "INVALID_CHARACTER_ERR"], [undefined, "xml", null], [undefined, "xmlns", "NAMESPACE_ERR"], [undefined, "xmlfoo", null], @@ -65,15 +65,15 @@ var createElementNS_tests = [ ["http://example.com/", ".foo", "INVALID_CHARACTER_ERR"], ["http://example.com/", "f1oo", null], ["http://example.com/", "foo1", null], - ["http://example.com/", ":foo", "NAMESPACE_ERR"], + ["http://example.com/", ":foo", "INVALID_CHARACTER_ERR"], ["http://example.com/", "f:oo", null], - ["http://example.com/", "f:o:o", "NAMESPACE_ERR"], - ["http://example.com/", "foo:", "NAMESPACE_ERR"], - ["http://example.com/", "f::oo", "NAMESPACE_ERR"], - ["http://example.com/", "a:0", "NAMESPACE_ERR"], + ["http://example.com/", "f:o:o", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "foo:", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "f::oo", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "a:0", "INVALID_CHARACTER_ERR"], ["http://example.com/", "0:a", "INVALID_CHARACTER_ERR"], ["http://example.com/", "a:_", null], - ["http://example.com/", "a:\u0BC6", "NAMESPACE_ERR"], + ["http://example.com/", "a:\u0BC6", "INVALID_CHARACTER_ERR"], ["http://example.com/", "\u0BC6:a", "INVALID_CHARACTER_ERR"], ["http://example.com/", "a:a\u0BC6", null], ["http://example.com/", "a\u0BC6:a", null], @@ -98,7 +98,7 @@ var createElementNS_tests = [ ["http://example.com/", "xmlns:foo", "NAMESPACE_ERR"], ["http://example.com/", "XMLNS:foo", null], ["http://example.com/", "xmlfoo:bar", null], - ["http://example.com/", "prefix::local", "NAMESPACE_ERR"], + ["http://example.com/", "prefix::local", "INVALID_CHARACTER_ERR"], ["http://example.com/", "namespaceURI:{", "INVALID_CHARACTER_ERR"], ["http://example.com/", "namespaceURI:}", "INVALID_CHARACTER_ERR"], ["http://example.com/", "namespaceURI:~", "INVALID_CHARACTER_ERR"], @@ -130,9 +130,9 @@ var createElementNS_tests = [ ["/", "1foo", "INVALID_CHARACTER_ERR"], ["/", "f1oo", null], ["/", "foo1", null], - ["/", ":foo", "NAMESPACE_ERR"], + ["/", ":foo", "INVALID_CHARACTER_ERR"], ["/", "f:oo", null], - ["/", "foo:", "NAMESPACE_ERR"], + ["/", "foo:", "INVALID_CHARACTER_ERR"], ["/", "xml", null], ["/", "xmlns", "NAMESPACE_ERR"], ["/", "xmlfoo", null], @@ -143,9 +143,9 @@ var createElementNS_tests = [ ["http://www.w3.org/XML/1998/namespace", "1foo", "INVALID_CHARACTER_ERR"], ["http://www.w3.org/XML/1998/namespace", "f1oo", null], ["http://www.w3.org/XML/1998/namespace", "foo1", null], - ["http://www.w3.org/XML/1998/namespace", ":foo", "NAMESPACE_ERR"], + ["http://www.w3.org/XML/1998/namespace", ":foo", "INVALID_CHARACTER_ERR"], ["http://www.w3.org/XML/1998/namespace", "f:oo", null], - ["http://www.w3.org/XML/1998/namespace", "foo:", "NAMESPACE_ERR"], + ["http://www.w3.org/XML/1998/namespace", "foo:", "INVALID_CHARACTER_ERR"], ["http://www.w3.org/XML/1998/namespace", "xml", null], ["http://www.w3.org/XML/1998/namespace", "xmlns", "NAMESPACE_ERR"], ["http://www.w3.org/XML/1998/namespace", "xmlfoo", null], @@ -158,9 +158,9 @@ var createElementNS_tests = [ ["http://www.w3.org/2000/xmlns/", "1foo", "INVALID_CHARACTER_ERR"], ["http://www.w3.org/2000/xmlns/", "f1oo", "NAMESPACE_ERR"], ["http://www.w3.org/2000/xmlns/", "foo1", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", ":foo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", ":foo", "INVALID_CHARACTER_ERR"], ["http://www.w3.org/2000/xmlns/", "f:oo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "foo:", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "foo:", "INVALID_CHARACTER_ERR"], ["http://www.w3.org/2000/xmlns/", "xml", "NAMESPACE_ERR"], ["http://www.w3.org/2000/xmlns/", "xmlns", null], ["http://www.w3.org/2000/xmlns/", "xmlfoo", "NAMESPACE_ERR"], @@ -172,9 +172,9 @@ var createElementNS_tests = [ ["foo:", "1foo", "INVALID_CHARACTER_ERR"], ["foo:", "f1oo", null], ["foo:", "foo1", null], - ["foo:", ":foo", "NAMESPACE_ERR"], + ["foo:", ":foo", "INVALID_CHARACTER_ERR"], ["foo:", "f:oo", null], - ["foo:", "foo:", "NAMESPACE_ERR"], + ["foo:", "foo:", "INVALID_CHARACTER_ERR"], ["foo:", "xml", null], ["foo:", "xmlns", "NAMESPACE_ERR"], ["foo:", "xmlfoo", null], diff --git a/testing/web-platform/tests/dom/nodes/attributes.html b/testing/web-platform/tests/dom/nodes/attributes.html index 8d983350df9d..d1f2aeea571f 100644 --- a/testing/web-platform/tests/dom/nodes/attributes.html +++ b/testing/web-platform/tests/dom/nodes/attributes.html @@ -130,12 +130,12 @@ test(function() { test(function() { var el = document.createElement("foo") for (var i = 0, il = invalid_qnames.length; i < il; ++i) { - assert_throws("NAMESPACE_ERR", + assert_throws("INVALID_CHARACTER_ERR", function() { el.setAttributeNS("a", invalid_qnames[i], "fail") }, "Expected exception for " + invalid_qnames[i] + ".") } }, "When qualifiedName does not match the QName production, an " + - "NAMESPACE_ERR exception is to be thrown.") + "INVALID_CHARACTER_ERR exception is to be thrown.") // Step 3 test(function() { From c4d4ebe05cc022c9a229b9e79a11a910d8bcc52e Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Sat, 29 Apr 2017 02:12:43 +0000 Subject: [PATCH 05/11] Bug 1360771 - llvm-config is N/A on FreeBSD try llvm-config39 as well. r=rillian llvm39 package on FreeBSD installs llvm-config under non-default prefix with llvm-config39 wrapper under PATH. No package currently provides default/unsuffixed llvm-config. So, adjust lookup to avoid having to add "export LLVM_CONFIG=llvm-config39" in .mozconfig for the common case when Stylo bindgen is known to work. MozReview-Commit-ID: 9PmnpTPoBcR --HG-- extra : rebase_source : 6c252e9e0e8da1f02fa74107597f69066b024f55 --- toolkit/moz.configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/moz.configure b/toolkit/moz.configure index 8cf76085728d..c27bb34be9cc 100644 --- a/toolkit/moz.configure +++ b/toolkit/moz.configure @@ -587,7 +587,7 @@ option('--enable-stylo', env='STYLO_ENABLED', nargs=0, # configure options. The Windows installer of LLVM/Clang doesn't provide # llvm-config, so we need both methods to support all of our tier-1 # platforms. -llvm_config = check_prog('LLVM_CONFIG', ('llvm-config-3.9', 'llvm-config',), +llvm_config = check_prog('LLVM_CONFIG', ('llvm-config-3.9', 'llvm-config39', 'llvm-config',), what='llvm-config', allow_missing=True) option('--disable-stylo-build-bindgen', From ab6f4b520c5acbd848ef79acdccbe4fdd54d77cd Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Sat, 29 Apr 2017 12:11:51 -0500 Subject: [PATCH 06/11] servo: Merge #16646 - Reverse Number and LengthOrPercentage in LengthOrPercentageOrNumber (from nox:loponu); r=emilio "0" must be parsed as the number 0, not the unitless 0px length. Source-Repo: https://github.com/servo/servo Source-Revision: 5dac4fbd2d23009fd9ee55b61371bbfb4d1fcc06 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : b1f749192c173b065e9e9ff56ad75db14b3634f5 --- servo/components/style/properties/gecko.mako.rs | 4 ++-- servo/components/style/properties/longhand/box.mako.rs | 8 ++++---- .../style/properties/longhand/inherited_svg.mako.rs | 2 +- servo/components/style/values/computed/mod.rs | 2 +- servo/components/style/values/specified/mod.rs | 6 +++--- servo/tests/unit/style/parsing/length.rs | 7 +++++++ 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index b468a76009d1..b8f4d4ed5418 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -3784,8 +3784,8 @@ clip-path for (mut gecko, servo) in self.gecko.mStrokeDasharray.iter_mut().zip(v.0.into_iter()) { match servo { - Either::First(lop) => gecko.set(lop), - Either::Second(number) => gecko.set_value(CoordDataValue::Factor(number)), + Either::First(number) => gecko.set_value(CoordDataValue::Factor(number)), + Either::Second(lop) => gecko.set(lop), } } } diff --git a/servo/components/style/properties/longhand/box.mako.rs b/servo/components/style/properties/longhand/box.mako.rs index 85350c76ddf3..bd53e8c716db 100644 --- a/servo/components/style/properties/longhand/box.mako.rs +++ b/servo/components/style/properties/longhand/box.mako.rs @@ -2008,8 +2008,8 @@ ${helpers.predefined_type("scroll-snap-coordinate", m32: Number::from_computed_value(&computed.m32), m33: Number::from_computed_value(&computed.m33), m34: Number::from_computed_value(&computed.m34), - m41: Either::First(LengthOrPercentage::from_computed_value(&computed.m41)), - m42: Either::First(LengthOrPercentage::from_computed_value(&computed.m42)), + m41: Either::Second(LengthOrPercentage::from_computed_value(&computed.m41)), + m42: Either::Second(LengthOrPercentage::from_computed_value(&computed.m42)), m43: LengthOrNumber::from_computed_value(&Either::First(computed.m43)), m44: Number::from_computed_value(&computed.m44), }); @@ -2056,8 +2056,8 @@ ${helpers.predefined_type("scroll-snap-coordinate", // LengthOrPercentage. Number maps into Length fn lopon_to_lop(value: &ComputedLoPoNumber) -> ComputedLoP { match *value { - Either::First(length_or_percentage) => length_or_percentage, - Either::Second(number) => ComputedLoP::Length(Au::from_f32_px(number)), + Either::First(number) => ComputedLoP::Length(Au::from_f32_px(number)), + Either::Second(length_or_percentage) => length_or_percentage, } } diff --git a/servo/components/style/properties/longhand/inherited_svg.mako.rs b/servo/components/style/properties/longhand/inherited_svg.mako.rs index 480f4a7adfb1..068c3d127f61 100644 --- a/servo/components/style/properties/longhand/inherited_svg.mako.rs +++ b/servo/components/style/properties/longhand/inherited_svg.mako.rs @@ -92,7 +92,7 @@ ${helpers.predefined_type("stroke-opacity", "Opacity", "1.0", ${helpers.predefined_type("stroke-dasharray", "LengthOrPercentageOrNumber", - "Either::Second(0.0)", + "Either::First(0.0)", "parse_non_negative", vector="True", allow_empty="True", diff --git a/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs index 9f7396608779..7cfdfa777163 100644 --- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -468,7 +468,7 @@ impl ToCss for SVGPaint { } /// | | -pub type LengthOrPercentageOrNumber = Either; +pub type LengthOrPercentageOrNumber = Either; #[derive(Clone, PartialEq, Eq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/servo/components/style/values/specified/mod.rs b/servo/components/style/values/specified/mod.rs index c51027b864ae..84c25c81119b 100644 --- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -1191,7 +1191,7 @@ impl ToComputedValue for SVGPaintKind { } /// | | -pub type LengthOrPercentageOrNumber = Either; +pub type LengthOrPercentageOrNumber = Either; impl LengthOrPercentageOrNumber { /// parse a | enforcing that the contents aren't negative @@ -1199,10 +1199,10 @@ impl LengthOrPercentageOrNumber { // NB: Parse numbers before Lengths so we are consistent about how to // recognize and serialize "0". if let Ok(num) = input.try(|i| Number::parse_non_negative(context, i)) { - return Ok(Either::Second(num)) + return Ok(Either::First(num)) } - LengthOrPercentage::parse_non_negative(context, input).map(Either::First) + LengthOrPercentage::parse_non_negative(context, input).map(Either::Second) } } diff --git a/servo/tests/unit/style/parsing/length.rs b/servo/tests/unit/style/parsing/length.rs index b6d9a30b42c5..6b2464849349 100644 --- a/servo/tests/unit/style/parsing/length.rs +++ b/servo/tests/unit/style/parsing/length.rs @@ -8,6 +8,8 @@ use parsing::parse; use style::context::QuirksMode; use style::parser::{LengthParsingMode, Parse, ParserContext}; use style::stylesheets::{CssRuleType, Origin}; +use style::values::Either; +use style::values::specified::{LengthOrPercentageOrNumber, Number}; use style::values::specified::length::{AbsoluteLength, Length, NoCalcLength}; use style_traits::ToCss; @@ -46,3 +48,8 @@ fn test_length_parsing_modes() { assert!(result.is_ok()); assert_eq!(result.unwrap(), Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(1.)))); } + +#[test] +fn test_zero_percentage_length_or_number() { + assert_eq!(parse(LengthOrPercentageOrNumber::parse, "0"), Ok(Either::First(Number::new(0.)))); +} From fbe7ebdbc82a22cc1aa862e8a22fb25097a8dcbe Mon Sep 17 00:00:00 2001 From: n0max Date: Sat, 29 Apr 2017 13:42:11 -0500 Subject: [PATCH 07/11] servo: Merge #16658 - Remove IndexSizeError in CanvasRenderingContext2D::drawImage (from n0max:remove-index-size-error); r=emilio The current spec don't expect the IndexSizeError if the rectangle is empty. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #10600 (github issue number if applicable). - [X] There are tests for these changes Source-Repo: https://github.com/servo/servo Source-Revision: 0c4e13cbc5ea4d80a8a4ac8a876777d53289a6da --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : eada56a8ea13d67a48010336eef799b60d2a5b52 --- servo/components/script/dom/canvasrenderingcontext2d.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servo/components/script/dom/canvasrenderingcontext2d.rs b/servo/components/script/dom/canvasrenderingcontext2d.rs index 432dbe800aa8..a5ec8d233b65 100644 --- a/servo/components/script/dom/canvasrenderingcontext2d.rs +++ b/servo/components/script/dom/canvasrenderingcontext2d.rs @@ -350,7 +350,7 @@ impl CanvasRenderingContext2D { dh); if !is_rect_valid(source_rect) || !is_rect_valid(dest_rect) { - return Err(Error::IndexSize); + return Ok(()); } let smoothing_enabled = self.state.borrow().image_smoothing_enabled; @@ -407,7 +407,7 @@ impl CanvasRenderingContext2D { dh); if !is_rect_valid(source_rect) || !is_rect_valid(dest_rect) { - return Err(Error::IndexSize); + return Ok(()); } let smoothing_enabled = self.state.borrow().image_smoothing_enabled; From 768009cfceed1a326e174876171e20eaaec2485e Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Sat, 29 Apr 2017 20:23:58 +0900 Subject: [PATCH 08/11] Bug 1360656 - Remove fails-if(stylo) for box-decoration-break-first-letter.html. r=jmaher MozReview-Commit-ID: 7tU2AdQAH57 --HG-- extra : rebase_source : c18eb144e98e639e48f8dc9f126f6c7be88f8500 --- layout/reftests/css-break/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/css-break/reftest.list b/layout/reftests/css-break/reftest.list index c85d4238cbd0..28f60935b9c0 100644 --- a/layout/reftests/css-break/reftest.list +++ b/layout/reftests/css-break/reftest.list @@ -6,7 +6,7 @@ fuzzy(16,460) fuzzy-if(Android,10,3673) fuzzy-if(skiaContent,32,254) == box-deco random-if(!gtkWidget) HTTP(..) == box-decoration-break-border-image.html box-decoration-break-border-image-ref.html == box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding-ref.html == box-decoration-break-block-margin.html box-decoration-break-block-margin-ref.html -fuzzy-if(!Android,1,62) fuzzy-if(Android,8,6627) fails-if(stylo) == box-decoration-break-first-letter.html box-decoration-break-first-letter-ref.html #Bug 1313773 +fuzzy-if(!Android,1,62) fuzzy-if(Android,8,6627) == box-decoration-break-first-letter.html box-decoration-break-first-letter-ref.html #Bug 1313773 == box-decoration-break-with-bidi.html box-decoration-break-with-bidi-ref.html == box-decoration-break-bug-1235152.html box-decoration-break-bug-1235152-ref.html == box-decoration-break-bug-1249913.html box-decoration-break-bug-1249913-ref.html From 0300d9228d4e4df9df03ebfbb66cb9152ebac190 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Sat, 29 Apr 2017 18:08:19 -0500 Subject: [PATCH 09/11] servo: Merge #16659 - Speed up stylist rebuilds (from bholley:faster_stylist_rebuild); r=emilio Reviewed in https://bugzilla.mozilla.org/show_bug.cgi?id=1360767 Source-Repo: https://github.com/servo/servo Source-Revision: caa66a880a89b4a8052959eb403dd7f1de4dfb54 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 77d86a5eb090c2b787ed025a7b9527962a474173 --- servo/components/selectors/parser.rs | 2 +- servo/components/style/restyle_hints.rs | 101 +++++++++++------------- servo/components/style/stylist.rs | 92 +++++++++++---------- 3 files changed, 100 insertions(+), 95 deletions(-) diff --git a/servo/components/selectors/parser.rs b/servo/components/selectors/parser.rs index f53380c2b220..66867000fda0 100644 --- a/servo/components/selectors/parser.rs +++ b/servo/components/selectors/parser.rs @@ -1457,7 +1457,7 @@ pub mod tests { where V: SelectorVisitor { true } } - #[derive(PartialEq, Debug)] + #[derive(Clone, PartialEq, Debug)] pub struct DummySelectorImpl; #[derive(Default)] diff --git a/servo/components/style/restyle_hints.rs b/servo/components/style/restyle_hints.rs index 9d3d8814ac76..193b7e82a9da 100644 --- a/servo/components/style/restyle_hints.rs +++ b/servo/components/style/restyle_hints.rs @@ -18,7 +18,7 @@ use selectors::{Element, MatchAttr}; use selectors::matching::{ElementSelectorFlags, StyleRelations}; use selectors::matching::matches_selector; use selectors::parser::{AttrSelector, Combinator, Component, Selector}; -use selectors::parser::{SelectorInner, SelectorIter, SelectorMethods}; +use selectors::parser::{SelectorInner, SelectorMethods}; use selectors::visitor::SelectorVisitor; use std::clone::Clone; @@ -482,27 +482,13 @@ struct Dependency { /// of them is sensitive to attribute or state changes. struct SensitivitiesVisitor { sensitivities: Sensitivities, - hint: RestyleHint, } impl SelectorVisitor for SensitivitiesVisitor { type Impl = SelectorImpl; - - fn visit_complex_selector(&mut self, - _: SelectorIter, - combinator: Option) -> bool { - self.hint |= combinator_to_restyle_hint(combinator); - - true - } - fn visit_simple_selector(&mut self, s: &Component) -> bool { self.sensitivities.states.insert(selector_to_state(s)); - - if !self.sensitivities.attrs { - self.sensitivities.attrs = is_attr_selector(s); - } - + self.sensitivities.attrs |= is_attr_selector(s); true } } @@ -539,56 +525,63 @@ impl DependencySet { /// Adds a selector to this `DependencySet`. pub fn note_selector(&mut self, selector: &Selector) { - let mut is_pseudo_element = selector.pseudo_element.is_some(); - - let mut next = Some(selector.inner.complex.clone()); let mut combinator = None; + let mut iter = selector.inner.complex.iter(); + let mut index = 0; - while let Some(current) = next.take() { - // Set up our visitor. + loop { + let sequence_start = index; let mut visitor = SensitivitiesVisitor { - sensitivities: Sensitivities::new(), - hint: combinator_to_restyle_hint(combinator), + sensitivities: Sensitivities::new() }; - if is_pseudo_element { - // TODO(emilio): use more fancy restyle hints to avoid restyling - // the whole subtree when pseudos change. - // - // We currently need is_pseudo_element to handle eager pseudos - // (so the style the parent stores doesn't become stale), and - // restyle_descendants to handle all of them (::before and - // ::after, because we find them in the subtree, and other lazy - // pseudos for the same reason). - visitor.hint |= RESTYLE_SELF | RESTYLE_DESCENDANTS; - is_pseudo_element = false; + // Visit all the simple selectors in this sequence. + // + // Note that this works because we can't have combinators nested + // inside simple selectors (i.e. in :not() or :-moz-any()). If we + // ever support that we'll need to visit complex selectors as well. + for ss in &mut iter { + ss.visit(&mut visitor); + index += 1; // Account for the simple selector. } - { - // Visit all the simple selectors. - let mut iter = current.iter(); - let mut index = 0usize; - for ss in &mut iter { - ss.visit(&mut visitor); - index += 1; - } - - // Prepare the next sequence of simple selectors. - if let Some(next_combinator) = iter.next_sequence() { - next = Some(current.slice_from(index + 1)); - combinator = Some(next_combinator); - } - } - - // Note what we found. + // If we found a sensitivity, add an entry in the dependency set. if !visitor.sensitivities.is_empty() { + let mut hint = combinator_to_restyle_hint(combinator); + let dep_selector; + if sequence_start == 0 { + if selector.pseudo_element.is_some() { + // TODO(emilio): use more fancy restyle hints to avoid + // restyling the whole subtree when pseudos change. + // + // We currently need is_pseudo_element to handle eager + // pseudos (so the style the parent stores doesn't + // become stale), and restyle_descendants to handle all + // of them (::before and ::after, because we find them + // in the subtree, and other lazy pseudos for the same + // reason). + hint |= RESTYLE_SELF | RESTYLE_DESCENDANTS; + } + + // Reuse the bloom hashes if this is the base selector. + dep_selector = selector.inner.clone(); + } else { + dep_selector = SelectorInner::new(selector.inner.complex.slice_from(sequence_start)); + } + self.add_dependency(Dependency { sensitivities: visitor.sensitivities, - hint: visitor.hint, - selector: SelectorInner::new(current), - }) + hint: hint, + selector: dep_selector, + }); } + combinator = iter.next_sequence(); + if combinator.is_none() { + break; + } + + index += 1; // Account for the combinator. } } diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs index cde51a8f3fbe..65d04630fd35 100644 --- a/servo/components/style/stylist.rs +++ b/servo/components/style/stylist.rs @@ -313,38 +313,13 @@ impl Stylist { CssRule::Style(ref locked) => { let style_rule = locked.read_with(&guard); self.num_declarations += style_rule.block.read_with(&guard).len(); - for selector in &style_rule.selectors.0 { self.num_selectors += 1; - let map = if let Some(ref pseudo) = selector.pseudo_element { - self.pseudos_map - .entry(pseudo.clone()) - .or_insert_with(PerPseudoElementSelectorMap::new) - .borrow_for_origin(&stylesheet.origin) - } else { - self.element_map.borrow_for_origin(&stylesheet.origin) - }; - - map.insert(Rule::new(guard, - selector.inner.clone(), - locked.clone(), - self.rules_source_order, - selector.specificity)); + self.add_rule_to_map(guard, selector, locked, stylesheet); + self.dependencies.note_selector(selector); + self.note_for_revalidation(selector); } self.rules_source_order += 1; - - for selector in &style_rule.selectors.0 { - self.dependencies.note_selector(selector); - - if needs_revalidation(selector) { - // For revalidation, we can skip everything left of - // the first ancestor combinator. - let revalidation_sel = - selector.inner.slice_to_first_ancestor_combinator(); - - self.selectors_for_cache_revalidation.push(revalidation_sel); - } - } } CssRule::Import(ref import) => { let import = import.read_with(guard); @@ -374,6 +349,38 @@ impl Stylist { }); } + #[inline] + fn add_rule_to_map(&mut self, + guard: &SharedRwLockReadGuard, + selector: &Selector, + rule: &Arc>, + stylesheet: &Stylesheet) + { + let map = if let Some(ref pseudo) = selector.pseudo_element { + self.pseudos_map + .entry(pseudo.clone()) + .or_insert_with(PerPseudoElementSelectorMap::new) + .borrow_for_origin(&stylesheet.origin) + } else { + self.element_map.borrow_for_origin(&stylesheet.origin) + }; + + map.insert(Rule::new(guard, + selector.inner.clone(), + rule.clone(), + self.rules_source_order, + selector.specificity)); + } + + #[inline] + fn note_for_revalidation(&mut self, selector: &Selector) { + if needs_revalidation(selector) { + // For revalidation, we can skip everything left of the first ancestor + // combinator. + let revalidation_sel = selector.inner.slice_to_first_ancestor_combinator(); + self.selectors_for_cache_revalidation.push(revalidation_sel); + } + } /// Computes the style for a given "precomputed" pseudo-element, taking the /// universal rules and applying them. @@ -1043,9 +1050,6 @@ pub struct SelectorMap { pub class_hash: FnvHashMap>, /// A hash from local name to rules which contain that local name selector. pub local_name_hash: FnvHashMap>, - /// Same as local_name_hash, but keys are lower-cased. - /// For HTML elements in HTML documents. - pub lower_local_name_hash: FnvHashMap>, /// Rules that don't have ID, class, or element selectors. pub other_rules: Vec, /// Whether this hash is empty. @@ -1064,7 +1068,6 @@ impl SelectorMap { id_hash: HashMap::default(), class_hash: HashMap::default(), local_name_hash: HashMap::default(), - lower_local_name_hash: HashMap::default(), other_rules: Vec::new(), empty: true, } @@ -1113,14 +1116,9 @@ impl SelectorMap { cascade_level); }); - let local_name_hash = if element.is_html_element_in_html_document() { - &self.lower_local_name_hash - } else { - &self.local_name_hash - }; SelectorMap::get_matching_rules_from_hash(element, parent_bf, - local_name_hash, + &self.local_name_hash, element.get_local_name(), matching_rules_list, relations, @@ -1253,8 +1251,22 @@ impl SelectorMap { } if let Some(LocalNameSelector { name, lower_name }) = SelectorMap::get_local_name(&rule) { - find_push(&mut self.local_name_hash, name, rule.clone()); - find_push(&mut self.lower_local_name_hash, lower_name, rule); + // If the local name in the selector isn't lowercase, insert it into + // the rule hash twice. This means that, during lookup, we can always + // find the rules based on the local name of the element, regardless + // of whether it's an html element in an html document (in which case + // we match against lower_name) or not (in which case we match against + // name). + // + // In the case of a non-html-element-in-html-document with a + // lowercase localname and a non-lowercase selector, the rulehash + // lookup may produce superfluous selectors, but the subsequent + // selector matching work will filter them out. + if name != lower_name { + find_push(&mut self.local_name_hash, lower_name, rule.clone()); + } + find_push(&mut self.local_name_hash, name, rule); + return; } From 14642896885795aa601b85e0b63a629a4007fb32 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Sun, 30 Apr 2017 10:24:03 +0900 Subject: [PATCH 10/11] Bug 1341102 Update mochitest expectations for -moz-transform. r=me Two test cases have been passed since https://hg.mozilla.org/integration/autoland/rev/237a8d3c6be37e58b606da4a65df617a0d17dd6a MozReview-Commit-ID: CznLJSmqOLQ --- layout/style/test/stylo-failures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/style/test/stylo-failures.md b/layout/style/test/stylo-failures.md index 67f2f2bfca9e..01cf0e8f81a6 100644 --- a/layout/style/test/stylo-failures.md +++ b/layout/style/test/stylo-failures.md @@ -128,7 +128,7 @@ to mochitest command. * test_initial_storage.html `-moz-force-broken-image-icon` [4] * test_value_storage.html `-moz-force-broken-image-icon` [4] * -moz-transform: need different parsing rules servo/servo#16003 - * test_value_storage.html `-moz-transform`: need different parsing rules bug 1357906 [72] + * test_value_storage.html `-moz-transform`: need different parsing rules bug 1357906 [70] * test_variables.html `var(--var6)`: -x-system-font [1] * Unimplemented CSS properties: * place-{content,items,self} shorthands servo/servo#16391 From 71f396bd14964d04f95cbbf674fe1e6ba7f5e88b Mon Sep 17 00:00:00 2001 From: Vangelis Katsikaros Date: Sun, 30 Apr 2017 12:49:33 +0300 Subject: [PATCH 11/11] Bug 1360902 - Improve localization of netmonitor waterfall tooltip. r=flod MozReview-Commit-ID: INXp80HJjUK --HG-- extra : rebase_source : 7558d5d964fdd8b7f069dfca57bf67351ca8a347 --- devtools/client/locales/en-US/netmonitor.properties | 6 ++++++ .../src/components/request-list-column-waterfall.js | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/devtools/client/locales/en-US/netmonitor.properties b/devtools/client/locales/en-US/netmonitor.properties index 75f0e0b62e57..e6f6b57dc43a 100644 --- a/devtools/client/locales/en-US/netmonitor.properties +++ b/devtools/client/locales/en-US/netmonitor.properties @@ -219,6 +219,12 @@ networkMenu.sizeServiceWorker=service worker # in the network menu specifying the time for a request to finish (in milliseconds). networkMenu.totalMS=→ %S ms +# This string is used to concatenate tooltips (netmonitor.waterfall.tooltip.*) +# in the requests waterfall for total time (in milliseconds). \\u0020 represents +# a whitespace. You can replace this with a different character, e.g. an hyphen +# or a period, if a comma doesn't work for your language. +netmonitor.waterfall.tooltip.separator=,\u0020 + # LOCALIZATION NOTE (netmonitor.waterfall.tooltip.total): This is part of the tooltip # displayed in the requests waterfall for total time (in milliseconds). netmonitor.waterfall.tooltip.total=Total %S ms diff --git a/devtools/client/netmonitor/src/components/request-list-column-waterfall.js b/devtools/client/netmonitor/src/components/request-list-column-waterfall.js index a6277655c146..1fdf07b7eeb0 100644 --- a/devtools/client/netmonitor/src/components/request-list-column-waterfall.js +++ b/devtools/client/netmonitor/src/components/request-list-column-waterfall.js @@ -96,7 +96,10 @@ function timingBoxes(item) { tooltip.push(L10N.getFormatStr("netmonitor.waterfall.tooltip.total", totalTime)); } - return { boxes, tooltip: tooltip.join(", ") }; + return { + boxes, + tooltip: tooltip.join(L10N.getStr("netmonitor.waterfall.tooltip.separator")) + }; } module.exports = RequestListColumnWaterfall;