From ba15f5d7098150fcada95199ca030e4a25aeb94c Mon Sep 17 00:00:00 2001 From: Bogdan Tara Date: Sat, 9 Jun 2018 06:34:00 +0300 Subject: [PATCH 1/8] Bug 1465427 - Removed references to WinXp, Ubuntu 12.04 r=jmaher --- .../fractions/frac-1.html.ini | 14 ---- .../operators/mo-axis-height-1.html.ini | 8 --- .../scripts/underover-1.html.ini | 8 --- .../relations/css-styling/color-1.html.ini | 4 -- .../css-styling/displaystyle-1.html.ini | 71 ------------------- 5 files changed, 105 deletions(-) delete mode 100644 testing/web-platform/meta/mathml/presentation-markup/operators/mo-axis-height-1.html.ini delete mode 100644 testing/web-platform/meta/mathml/presentation-markup/scripts/underover-1.html.ini delete mode 100644 testing/web-platform/meta/mathml/relations/css-styling/displaystyle-1.html.ini diff --git a/testing/web-platform/meta/mathml/presentation-markup/fractions/frac-1.html.ini b/testing/web-platform/meta/mathml/presentation-markup/fractions/frac-1.html.ini index 35f0d06d8bfc..1c8688d55b77 100644 --- a/testing/web-platform/meta/mathml/presentation-markup/fractions/frac-1.html.ini +++ b/testing/web-platform/meta/mathml/presentation-markup/fractions/frac-1.html.ini @@ -1,18 +1,4 @@ [frac-1.html] - [Vertical positions of numerator and denominator] - expected: - if not debug and not e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86") and (bits == 32): FAIL - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL - if not debug and e10s and (os == "linux") and (version == "Ubuntu 12.04") and (processor == "x86_64") and (bits == 64): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - [Fraction axis is aligned on the math axis] expected: if (os == "linux") and (version == "Ubuntu 16.04"): FAIL - diff --git a/testing/web-platform/meta/mathml/presentation-markup/operators/mo-axis-height-1.html.ini b/testing/web-platform/meta/mathml/presentation-markup/operators/mo-axis-height-1.html.ini deleted file mode 100644 index eb9595558ab6..000000000000 --- a/testing/web-platform/meta/mathml/presentation-markup/operators/mo-axis-height-1.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[mo-axis-height-1.html] - [AxisHeight (size variant)] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - diff --git a/testing/web-platform/meta/mathml/presentation-markup/scripts/underover-1.html.ini b/testing/web-platform/meta/mathml/presentation-markup/scripts/underover-1.html.ini deleted file mode 100644 index 58ed368af36e..000000000000 --- a/testing/web-platform/meta/mathml/presentation-markup/scripts/underover-1.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[underover-1.html] - [Height of scripted elements] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - diff --git a/testing/web-platform/meta/mathml/relations/css-styling/color-1.html.ini b/testing/web-platform/meta/mathml/relations/css-styling/color-1.html.ini index 1b8e87272724..7a86b9ddc68a 100644 --- a/testing/web-platform/meta/mathml/relations/css-styling/color-1.html.ini +++ b/testing/web-platform/meta/mathml/relations/css-styling/color-1.html.ini @@ -4,8 +4,4 @@ if not debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS if debug and not e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS if debug and e10s and (os == "mac") and (version == "OS X 10.10.5") and (processor == "x86_64") and (bits == 64): PASS - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): PASS - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): PASS - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): PASS - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): PASS FAIL diff --git a/testing/web-platform/meta/mathml/relations/css-styling/displaystyle-1.html.ini b/testing/web-platform/meta/mathml/relations/css-styling/displaystyle-1.html.ini deleted file mode 100644 index 18e3a1ef8573..000000000000 --- a/testing/web-platform/meta/mathml/relations/css-styling/displaystyle-1.html.ini +++ /dev/null @@ -1,71 +0,0 @@ -[displaystyle-1.html] - [math element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [mstyle element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [mtable element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [mroot element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [msub element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [msup element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [msubsup element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [munder element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [mover element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - - [munderover element] - expected: - if not debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if not debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and not e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - if debug and e10s and (os == "win") and (version == "5.1.2600") and (processor == "x86") and (bits == 32): FAIL - From d4d7b3a1baa0a025008891f4971a093b24033f2f Mon Sep 17 00:00:00 2001 From: Jesse Ruderman Date: Sat, 9 Jun 2018 23:03:40 +0200 Subject: [PATCH 2/8] Bug 1250791 - Add a crashtest. r=mats --- layout/style/crashtests/1250791.html | 8 ++++++++ layout/style/crashtests/crashtests.list | 1 + 2 files changed, 9 insertions(+) create mode 100644 layout/style/crashtests/1250791.html diff --git a/layout/style/crashtests/1250791.html b/layout/style/crashtests/1250791.html new file mode 100644 index 000000000000..8fb0a1643136 --- /dev/null +++ b/layout/style/crashtests/1250791.html @@ -0,0 +1,8 @@ + + + +
+
+
+ + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index 6c9fe9bcf791..dfb4d2899317 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -149,6 +149,7 @@ load 1233135-2.html load 1238660-1.html load 1245260-1.html load 1247865-1.html +load 1250791.html load 1264396-1.html load 1264949.html # The following test relies on -webkit-text-fill-color being behind the From 2ed160f32751975bd7530e9e2acce849657f9036 Mon Sep 17 00:00:00 2001 From: Jesse Ruderman Date: Sat, 9 Jun 2018 23:03:41 +0200 Subject: [PATCH 3/8] Bug 612213 - Add a crashtest. r=mats --- layout/style/crashtests/612213.html | 17 +++++++++++++++++ layout/style/crashtests/crashtests.list | 1 + 2 files changed, 18 insertions(+) create mode 100644 layout/style/crashtests/612213.html diff --git a/layout/style/crashtests/612213.html b/layout/style/crashtests/612213.html new file mode 100644 index 000000000000..a97b21bca5f0 --- /dev/null +++ b/layout/style/crashtests/612213.html @@ -0,0 +1,17 @@ + + + + + + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index dfb4d2899317..8ec106d1e676 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -72,6 +72,7 @@ load 601437-1.html load 601439-1.html load 605689-1.html load 611922-1.html +load 612213.html load 621596-1.html load 622314-1.xhtml load 635153.html From 9dbe99473f9b5755cc2f3ecdeeb4cfe8d237d8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 7 Jun 2018 20:27:57 +0200 Subject: [PATCH 4/8] Bug 1467536: Add a Servo API to get the serialized style of a property. r=xidorn This is intended to be used by GetComputedStyle when there's no layout dependency. MozReview-Commit-ID: 3GAbjo1uQ34 --- layout/style/ServoBindingList.h | 5 +- .../style/properties/properties.mako.rs | 93 +++++++++++++------ servo/ports/geckolib/glue.rs | 19 ++++ 3 files changed, 89 insertions(+), 28 deletions(-) diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index 33f20c480ec9..a53c6fe8b2e2 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -825,7 +825,7 @@ SERVO_BINDING_FUNC(Servo_SerializeFontValueForCanvas, void, RawServoDeclarationBlockBorrowed declarations, nsAString* buffer) -// Get custom property value. +// GetComputedStyle APIs. SERVO_BINDING_FUNC(Servo_GetCustomPropertyValue, bool, ComputedStyleBorrowed computed_values, const nsAString* name, nsAString* value) @@ -837,6 +837,9 @@ SERVO_BINDING_FUNC(Servo_GetCustomPropertyNameAt, bool, ComputedStyleBorrowed, uint32_t index, nsAString* name) +SERVO_BINDING_FUNC(Servo_GetPropertyValue, void, + ComputedStyleBorrowed computed_values, + nsCSSPropertyID property, nsAString* value) SERVO_BINDING_FUNC(Servo_ProcessInvalidations, void, RawServoStyleSetBorrowed set, diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs index 4e52412c18d4..cdebe662279c 100644 --- a/servo/components/style/properties/properties.mako.rs +++ b/servo/components/style/properties/properties.mako.rs @@ -22,8 +22,7 @@ use std::cell::RefCell; use std::fmt::{self, Write}; use std::mem::{self, ManuallyDrop}; -#[cfg(feature = "servo")] use cssparser::RGBA; -use cssparser::{Parser, TokenSerializationType}; +use cssparser::{Parser, RGBA, TokenSerializationType}; use cssparser::ParserInput; #[cfg(feature = "servo")] use euclid::SideOffsets2D; use context::QuirksMode; @@ -45,7 +44,6 @@ use shared_lock::StylesheetGuards; use style_traits::{CssWriter, KeywordsCollectFn, ParseError, ParsingMode}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; use stylesheets::{CssRuleType, Origin, UrlExtraData}; -#[cfg(feature = "servo")] use values::Either; use values::generics::text::LineHeight; use values::computed; use values::computed::NonNegativeLength; @@ -834,13 +832,13 @@ bitflags! { const APPLIES_TO_FIRST_LINE = 1 << 4; /// This longhand property applies to ::placeholder. const APPLIES_TO_PLACEHOLDER = 1 << 5; + /// This property's getComputedStyle implementation requires layout + /// to be flushed. + const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 6; /* The following flags are currently not used in Rust code, they * only need to be listed in corresponding properties so that * they can be checked in the C++ side via ServoCSSPropList.h. */ - /// This property's getComputedStyle implementation requires layout - /// to be flushed. - const GETCS_NEEDS_LAYOUT_FLUSH = 0; /// This property can be animated on the compositor. const CAN_ANIMATE_ON_COMPOSITOR = 0; } @@ -2614,6 +2612,59 @@ impl ComputedValues { pub fn custom_properties(&self) -> Option<<&Arc<::custom_properties::CustomPropertiesMap>> { self.custom_properties.as_ref() } + + /// Writes the value of the given longhand as a string in `dest`. + /// + /// Note that the value will usually be the computed value, except for + /// colors, where it's resolved. + pub fn get_longhand_property_value( + &self, + property_id: LonghandId, + dest: &mut CssWriter + ) -> fmt::Result + where + W: Write, + { + // TODO(emilio): Is it worth to merge branches here just like + // PropertyDeclaration::to_css does? + // + // We'd need to get a concept of ~resolved value, which may not be worth + // it. + match property_id { + % for prop in data.longhands: + LonghandId::${prop.camel_case} => { + let style_struct = + self.get_${prop.style_struct.ident.strip("_")}(); + let value = + style_struct + % if prop.logical: + .clone_${prop.ident}(self.writing_mode); + % else: + .clone_${prop.ident}(); + % endif + + % if prop.predefined_type == "Color": + let value = self.resolve_color(value); + % endif + + value.to_css(dest) + } + % endfor + } + } + + /// Resolves the currentColor keyword. + /// + /// Any color value from computed values (except for the 'color' property + /// itself) should go through this method. + /// + /// Usage example: + /// let top_color = + /// style.resolve_color(style.get_border().clone_border_top_color()); + #[inline] + pub fn resolve_color(&self, color: computed::Color) -> RGBA { + color.to_rgba(self.get_color().clone_color()) + } } #[cfg(feature = "servo")] @@ -2726,18 +2777,6 @@ impl ComputedValuesInner { self.get_column().is_multicol() } - /// Resolves the currentColor keyword. - /// - /// Any color value from computed values (except for the 'color' property - /// itself) should go through this method. - /// - /// Usage example: - /// let top_color = style.resolve_color(style.Border.border_top_color); - #[inline] - pub fn resolve_color(&self, color: computed::Color) -> RGBA { - color.to_rgba(self.get_color().color) - } - /// Get the logical computed inline size. #[inline] pub fn content_inline_size(&self) -> computed::LengthOrPercentageOrAuto { @@ -2902,19 +2941,19 @@ impl ComputedValuesInner { /// Serializes the computed value of this property as a string. pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String { match property { - % for style_struct in data.active_style_structs(): - % for longhand in style_struct.longhands: - PropertyDeclarationId::Longhand(LonghandId::${longhand.camel_case}) => { - self.${style_struct.ident}.${longhand.ident}.to_css_string() - } - % endfor - % endfor + PropertyDeclarationId::Longhand(id) => { + let mut s = String::new(); + self.get_longhand_property_value( + property, + &mut CssWriter::new(&mut s) + ).unwrap(); + s + } PropertyDeclarationId::Custom(name) => { self.custom_properties .as_ref() .and_then(|map| map.get(name)) - .map(|value| value.to_css_string()) - .unwrap_or(String::new()) + .map_or(String::new(), |value| value.to_css_string()) } } } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 948286ebd86c..a66866c19c70 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -5132,6 +5132,25 @@ pub extern "C" fn Servo_StyleSet_HasDocumentStateDependency( data.stylist.has_document_state_dependency(state) } +#[no_mangle] +pub unsafe extern "C" fn Servo_GetPropertyValue( + computed_values: ComputedStyleBorrowed, + prop: nsCSSPropertyID, + value: *mut nsAString, +) { + use style::properties::PropertyFlags; + + let longhand = LonghandId::from_nscsspropertyid(prop).expect("Not a longhand?"); + debug_assert!( + !longhand.flags().contains(PropertyFlags::GETCS_NEEDS_LAYOUT_FLUSH), + "We're not supposed to serialize layout-dependent properties" + ); + computed_values.get_longhand_property_value( + longhand, + &mut CssWriter::new(&mut *value), + ).unwrap(); +} + #[no_mangle] pub unsafe extern "C" fn Servo_GetCustomPropertyValue( computed_values: ComputedStyleBorrowed, From 3cf45a2889d5eedb7cc82db8ed55bc37f1b7922f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 7 Jun 2018 21:07:28 +0200 Subject: [PATCH 5/8] Bug 1467536: Add CssPropFlags::SerializedByServo and use it on some simple properties. r=xidorn The idea is to turn the simple properties into a blacklist instead really soon, and fix the offending ones soon after, so that only shorthands and properties with layout dependence (and maybe the scrollbar properties, because the poke at LookAndFeel) are not serialized by Servo. MozReview-Commit-ID: JTLNnmXzny8 --- layout/style/CSSPropFlags.h | 3 +++ layout/style/ServoCSSPropList.mako.py | 31 +++++++++++++++++++++++ servo/components/style/properties/data.py | 12 +++++++++ 3 files changed, 46 insertions(+) diff --git a/layout/style/CSSPropFlags.h b/layout/style/CSSPropFlags.h index 8f72adebe1b8..e5faad425c40 100644 --- a/layout/style/CSSPropFlags.h +++ b/layout/style/CSSPropFlags.h @@ -49,6 +49,9 @@ enum class CSSPropFlags : uint8_t // the DOM. Properties with this flag are defined in an #ifndef // CSS_PROP_LIST_EXCLUDE_INTERNAL section. Internal = 1 << 5, + + // Whether this property should be serialized by Servo in getComputedStyle. + SerializedByServo = 1 << 6, }; MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CSSPropFlags) diff --git a/layout/style/ServoCSSPropList.mako.py b/layout/style/ServoCSSPropList.mako.py index 659f0ffa01a5..26aa18f04ba0 100644 --- a/layout/style/ServoCSSPropList.mako.py +++ b/layout/style/ServoCSSPropList.mako.py @@ -68,6 +68,35 @@ def method(prop): return prop.camel_case[1:] return prop.camel_case +# Colors, integers and lengths are easy as well. +# +# TODO(emilio): This will go away once the rest of the longhands have been +# moved or perhaps using a blacklist for the ones with non-layout-dependence +# but other non-trivial dependence like scrollbar colors. +SERIALIZED_PREDEFINED_TYPES = [ + "Color", + "Integer", + "Length", + "Opacity", +] + +def serialized_by_servo(prop): + # If the property requires layout information, no such luck. + if "GETCS_NEEDS_LAYOUT_FLUSH" in prop.flags: + return False + # No shorthands yet. + if prop.type() == "shorthand": + return False + # Keywords are all fine, except -moz-osx-font-smoothing, which does + # resistfingerprinting stuff. + if prop.keyword and prop.name != "-moz-osx-font-smoothing": + return True + if prop.predefined_type in SERIALIZED_PREDEFINED_TYPES: + return True + # TODO(emilio): Enable the rest of the longhands. + return False + + def flags(prop): result = [] if prop.explicitly_enabled_in_chrome(): @@ -82,6 +111,8 @@ def flags(prop): result.append("GetCSNeedsLayoutFlush") if "CAN_ANIMATE_ON_COMPOSITOR" in prop.flags: result.append("CanAnimateOnCompositor") + if serialized_by_servo(prop): + result.append("SerializedByServo") return ", ".join('"CSSPropFlags::{}"'.format(flag) for flag in result) def pref(prop): diff --git a/servo/components/style/properties/data.py b/servo/components/style/properties/data.py index 0ac42b365eea..fca4b536e013 100644 --- a/servo/components/style/properties/data.py +++ b/servo/components/style/properties/data.py @@ -226,6 +226,10 @@ class Longhand(object): # See compute_damage for the various values this can take self.servo_restyle_damage = servo_restyle_damage + @staticmethod + def type(): + return "longhand" + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) @@ -361,6 +365,10 @@ class Shorthand(object): animatable = property(get_animatable) transitionable = property(get_transitionable) + @staticmethod + def type(): + return "shorthand" + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) @@ -392,6 +400,10 @@ class Alias(object): self.allowed_in_page_rule = original.allowed_in_page_rule self.allowed_in_keyframe_block = original.allowed_in_keyframe_block + @staticmethod + def type(): + return "alias" + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) From 5545421406c9265c4992fd39c95adb6895bce2d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 8 Jun 2018 10:08:44 +0200 Subject: [PATCH 6/8] Bug 1467536: Split GetPropertyValue from GetPropertyCSSValueWithoutWarning. r=xidorn And remove the later. MozReview-Commit-ID: BO3epOMe70w --- layout/style/nsComputedDOMStyle.cpp | 111 ++++++++-------------------- layout/style/nsComputedDOMStyle.h | 7 -- 2 files changed, 31 insertions(+), 87 deletions(-) diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index c165e90d2755..040e15b58820 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -435,20 +435,42 @@ nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName, { aReturn.Truncate(); - ErrorResult error; - RefPtr val = - GetPropertyCSSValueWithoutWarning(aPropertyName, error); - if (error.Failed()) { - return error.StealNSResult(); + nsCSSPropertyID prop = + nsCSSProps::LookupProperty(aPropertyName, CSSEnabledState::eForAllContent); + + const ComputedStyleMap::Entry* entry = nullptr; + if (prop != eCSSPropertyExtra_variable) { + entry = GetComputedStyleMap()->FindEntryForProperty(prop); + if (!entry) { + return NS_OK; + } } - if (val) { + const bool layoutFlushIsNeeded = entry && entry->IsLayoutFlushNeeded(); + UpdateCurrentStyleSources(layoutFlushIsNeeded); + if (!mComputedStyle) { + return NS_ERROR_NOT_AVAILABLE; + } + + auto cleanup = mozilla::MakeScopeExit([&] { + ClearCurrentStyleSources(); + }); + + if (!entry) { + MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName)); + const nsAString& name = + Substring(aPropertyName, CSS_CUSTOM_NAME_PREFIX_LENGTH); + Servo_GetCustomPropertyValue(mComputedStyle, &name, &aReturn); + return NS_OK; + } + + if (RefPtr value = (this->*entry->mGetter)()) { + ErrorResult rv; nsString text; - val->GetCssText(text, error); + value->GetCssText(text, rv); aReturn.Assign(text); - return error.StealNSResult(); + return rv.StealNSResult(); } - return NS_OK; } @@ -987,57 +1009,6 @@ nsComputedDOMStyle::ClearCurrentStyleSources() mPresShell = nullptr; } -already_AddRefed -nsComputedDOMStyle::GetPropertyCSSValueWithoutWarning( - const nsAString& aPropertyName, - ErrorResult& aRv) -{ - nsCSSPropertyID prop = - nsCSSProps::LookupProperty(aPropertyName, CSSEnabledState::eForAllContent); - - bool needsLayoutFlush; - ComputedStyleMap::Entry::ComputeMethod getter; - - if (prop == eCSSPropertyExtra_variable) { - needsLayoutFlush = false; - getter = nullptr; - } else { - const ComputedStyleMap::Entry* propEntry = - GetComputedStyleMap()->FindEntryForProperty(prop); - - if (!propEntry) { -#ifdef DEBUG_ComputedDOMStyle - NS_WARNING(PromiseFlatCString(NS_ConvertUTF16toUTF8(aPropertyName) + - NS_LITERAL_CSTRING(" is not queryable!")).get()); -#endif - - // NOTE: For branches, we should flush here for compatibility! - return nullptr; - } - - needsLayoutFlush = propEntry->IsLayoutFlushNeeded(); - getter = propEntry->mGetter; - } - - UpdateCurrentStyleSources(needsLayoutFlush); - if (!mComputedStyle) { - aRv.Throw(NS_ERROR_NOT_AVAILABLE); - return nullptr; - } - - RefPtr val; - if (prop == eCSSPropertyExtra_variable) { - val = DoGetCustomProperty(aPropertyName); - } else { - // Call our pointer-to-member-function. - val = (this->*getter)(); - } - - ClearCurrentStyleSources(); - - return val.forget(); -} - NS_IMETHODIMP nsComputedDOMStyle::RemoveProperty(const nsAString& aPropertyName, nsAString& aReturn) @@ -7192,26 +7163,6 @@ MarkComputedStyleMapDirty(const char* aPref, void* aData) static_cast(aData)->MarkDirty(); } -already_AddRefed -nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName) -{ - MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName)); - - nsString variableValue; - const nsAString& name = Substring(aPropertyName, - CSS_CUSTOM_NAME_PREFIX_LENGTH); - bool present = - Servo_GetCustomPropertyValue(mComputedStyle, &name, &variableValue); - if (!present) { - return nullptr; - } - - RefPtr val = new nsROCSSPrimitiveValue; - val->SetString(variableValue); - - return val.forget(); -} - void nsComputedDOMStyle::ParentChainChanged(nsIContent* aContent) { diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h index ffd7d790be02..e4ad2af5593e 100644 --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -59,10 +59,6 @@ private: typedef mozilla::dom::CSSValue CSSValue; typedef mozilla::StyleGeometryBox StyleGeometryBox; - already_AddRefed - GetPropertyCSSValueWithoutWarning(const nsAString& aProp, - mozilla::ErrorResult& aRv); - public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle, @@ -617,9 +613,6 @@ private: already_AddRefed DoGetContextProperties(); - /* Custom properties */ - already_AddRefed DoGetCustomProperty(const nsAString& aPropertyName); - /* Helper functions */ void SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor); void SetValueFromComplexColor(nsROCSSPrimitiveValue* aValue, From f5badb6060851b5974dd49e35fbcd94b19ae558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 8 Jun 2018 10:10:45 +0200 Subject: [PATCH 7/8] Bug 1467536: Serialize properties flagged as SerializedByServo from getComputedStyle. r=xidorn MozReview-Commit-ID: 9hnxejljlhG --- layout/style/nsComputedDOMStyle.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 040e15b58820..11c93732b692 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -464,13 +464,18 @@ nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName, return NS_OK; } - if (RefPtr value = (this->*entry->mGetter)()) { - ErrorResult rv; - nsString text; - value->GetCssText(text, rv); - aReturn.Assign(text); - return rv.StealNSResult(); + if (!nsCSSProps::PropHasFlags(prop, CSSPropFlags::SerializedByServo)) { + if (RefPtr value = (this->*entry->mGetter)()) { + ErrorResult rv; + nsString text; + value->GetCssText(text, rv); + aReturn.Assign(text); + return rv.StealNSResult(); + } + return NS_OK; } + + Servo_GetPropertyValue(mComputedStyle, prop, &aReturn); return NS_OK; } From a19c471a9415a00e371196df669a187189fc22ab Mon Sep 17 00:00:00 2001 From: James Willcox Date: Fri, 30 Mar 2018 08:32:43 -0500 Subject: [PATCH 8/8] Bug 1455740 - Make GeckoViewExample more useful r=esawin,jchen,droeh This adds a location bar so you can enter arbitrary URLs, and also adds a menu for toggling various settings such as usage of E10s or tracking protection. MozReview-Commit-ID: FgBPR92dsfm --- mobile/android/geckoview_example/build.gradle | 1 + .../src/main/AndroidManifest.xml | 9 +- .../geckoview_example/GeckoViewActivity.java | 340 ++++++++++++++---- .../geckoview_example/LocationView.java | 61 ++++ .../geckoview_example/SessionActivity.java | 4 + .../main/res/layout/geckoview_activity.xml | 19 +- .../src/main/res/menu/actions.xml | 10 + .../src/main/res/values/strings.xml | 11 + 8 files changed, 380 insertions(+), 75 deletions(-) create mode 100644 mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/LocationView.java create mode 100644 mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/SessionActivity.java create mode 100644 mobile/android/geckoview_example/src/main/res/menu/actions.xml diff --git a/mobile/android/geckoview_example/build.gradle b/mobile/android/geckoview_example/build.gradle index 68654b8be46f..d3a0ad8e127c 100644 --- a/mobile/android/geckoview_example/build.gradle +++ b/mobile/android/geckoview_example/build.gradle @@ -33,6 +33,7 @@ dependencies { testImplementation 'junit:junit:4.12' implementation "com.android.support:support-annotations:$support_library_version" + implementation "com.android.support:appcompat-v7:$support_library_version" androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestImplementation 'com.android.support.test:runner:0.5' diff --git a/mobile/android/geckoview_example/src/main/AndroidManifest.xml b/mobile/android/geckoview_example/src/main/AndroidManifest.xml index 702f7bdc1d3f..7ddd5e702ad7 100644 --- a/mobile/android/geckoview_example/src/main/AndroidManifest.xml +++ b/mobile/android/geckoview_example/src/main/AndroidManifest.xml @@ -15,8 +15,9 @@ @@ -37,6 +38,12 @@ + + + diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java index f9546e91c77d..287dc5f378b4 100644 --- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java +++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java @@ -5,41 +5,76 @@ package org.mozilla.geckoview_example; -import android.app.Activity; +import org.mozilla.geckoview.BasicSelectionActionDelegate; +import org.mozilla.geckoview.GeckoResponse; +import org.mozilla.geckoview.GeckoRuntime; +import org.mozilla.geckoview.GeckoRuntimeSettings; +import org.mozilla.geckoview.GeckoSession; +import org.mozilla.geckoview.GeckoSession.TrackingProtectionDelegate; +import org.mozilla.geckoview.GeckoSessionSettings; +import org.mozilla.geckoview.GeckoView; + +import android.Manifest; +import android.app.DownloadManager; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.os.SystemClock; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.WindowManager; +import java.util.LinkedList; import java.util.Locale; -import org.mozilla.geckoview.GeckoResponse; -import org.mozilla.geckoview.GeckoSession; -import org.mozilla.geckoview.GeckoSessionSettings; -import org.mozilla.geckoview.GeckoSession.TrackingProtectionDelegate; -import org.mozilla.geckoview.GeckoView; -import org.mozilla.geckoview.GeckoRuntime; -import org.mozilla.geckoview.GeckoRuntimeSettings; - -public class GeckoViewActivity extends Activity { +public class GeckoViewActivity extends AppCompatActivity { private static final String LOGTAG = "GeckoViewActivity"; private static final String DEFAULT_URL = "https://mozilla.org"; private static final String USE_MULTIPROCESS_EXTRA = "use_multiprocess"; - private static final String USE_REMOTE_DEBUGGER_EXTRA = "use_remote_debugger"; - private static final String ACTION_SHUTDOWN = - "org.mozilla.geckoview_example.SHUTDOWN"; - private boolean mKillProcessOnDestroy; - - /* package */ static final int REQUEST_FILE_PICKER = 1; + private static final String SEARCH_URI_BASE = "https://www.google.com/search?q="; + private static final String ACTION_SHUTDOWN = "org.mozilla.geckoview_example.SHUTDOWN"; + private static final int REQUEST_FILE_PICKER = 1; private static final int REQUEST_PERMISSIONS = 2; + private static final int REQUEST_WRITE_EXTERNAL_STORAGE = 3; private static GeckoRuntime sGeckoRuntime; private GeckoSession mGeckoSession; private GeckoView mGeckoView; + private boolean mUseMultiprocess; + private boolean mUseTrackingProtection; + private boolean mUsePrivateBrowsing; + private boolean mKillProcessOnDestroy; + + private LocationView mLocationView; + private String mCurrentUri; + private boolean mCanGoBack; + private boolean mCanGoForward; + private boolean mFullScreen; + + private LinkedList mPendingDownloads = new LinkedList<>(); + + private LocationView.CommitListener mCommitListener = new LocationView.CommitListener() { + @Override + public void onCommit(String text) { + if ((text.contains(".") || text.contains(":")) && !text.contains(" ")) { + mGeckoSession.loadUri(text); + } else { + mGeckoSession.loadUri(SEARCH_URI_BASE + text); + } + mGeckoView.requestFocus(); + } + }; @Override protected void onCreate(Bundle savedInstanceState) { @@ -50,8 +85,15 @@ public class GeckoViewActivity extends Activity { setContentView(R.layout.geckoview_activity); mGeckoView = (GeckoView) findViewById(R.id.gecko_view); - final boolean useMultiprocess = - getIntent().getBooleanExtra(USE_MULTIPROCESS_EXTRA, true); + setSupportActionBar((Toolbar)findViewById(R.id.toolbar)); + + mLocationView = new LocationView(this); + getSupportActionBar().setCustomView(mLocationView, + new ActionBar.LayoutParams(ActionBar.LayoutParams.MATCH_PARENT, + ActionBar.LayoutParams.WRAP_CONTENT)); + getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM); + + mUseMultiprocess = getIntent().getBooleanExtra(USE_MULTIPROCESS_EXTRA, true); if (sGeckoRuntime == null) { final GeckoRuntimeSettings.Builder runtimeSettingsBuilder = @@ -68,51 +110,164 @@ public class GeckoViewActivity extends Activity { runtimeSettingsBuilder.extras(extras); } runtimeSettingsBuilder - .useContentProcessHint(useMultiprocess) - .nativeCrashReportingEnabled(true) - .javaCrashReportingEnabled(true) - .trackingProtectionCategories(TrackingProtectionDelegate.CATEGORY_ALL); + .useContentProcessHint(mUseMultiprocess) + .remoteDebuggingEnabled(true) + .nativeCrashReportingEnabled(true) + .javaCrashReportingEnabled(true) + .trackingProtectionCategories(TrackingProtectionDelegate.CATEGORY_ALL); sGeckoRuntime = GeckoRuntime.create(this, runtimeSettingsBuilder.build()); } - final GeckoSessionSettings sessionSettings = new GeckoSessionSettings(); - sessionSettings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, - useMultiprocess); - sessionSettings.setBoolean(GeckoSessionSettings.USE_TRACKING_PROTECTION, - true); - mGeckoSession = new GeckoSession(sessionSettings); + mGeckoSession = (GeckoSession)getIntent().getParcelableExtra("session"); + if (mGeckoSession != null) { + connectSession(mGeckoSession); - mGeckoView.setSession(mGeckoSession, sGeckoRuntime); + if (!mGeckoSession.isOpen()) { + mGeckoSession.open(sGeckoRuntime); + } - mGeckoSession.setContentDelegate(new MyGeckoViewContent()); - final MyTrackingProtection tp = new MyTrackingProtection(); - mGeckoSession.setTrackingProtectionDelegate(tp); - mGeckoSession.setProgressDelegate(new MyGeckoViewProgress(tp)); - mGeckoSession.setNavigationDelegate(new Navigation()); + mUseMultiprocess = mGeckoSession.getSettings().getBoolean(GeckoSessionSettings.USE_MULTIPROCESS); + + mGeckoView.setSession(mGeckoSession); + } else { + mGeckoSession = createSession(); + mGeckoView.setSession(mGeckoSession, sGeckoRuntime); + loadFromIntent(getIntent()); + } + + mLocationView.setCommitListener(mCommitListener); + } + + private GeckoSession createSession() { + GeckoSession session = new GeckoSession(); + session.getSettings().setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, mUseMultiprocess); + session.getSettings().setBoolean(GeckoSessionSettings.USE_PRIVATE_MODE, mUsePrivateBrowsing); + session.getSettings().setBoolean(GeckoSessionSettings.USE_TRACKING_PROTECTION, true); + + connectSession(session); + + return session; + } + + private void connectSession(GeckoSession session) { + session.setContentDelegate(new ExampleContentDelegate()); + final ExampleTrackingProtectionDelegate tp = new ExampleTrackingProtectionDelegate(); + session.setTrackingProtectionDelegate(tp); + session.setProgressDelegate(new ExampleProgressDelegate(tp)); + session.setNavigationDelegate(new ExampleNavigationDelegate()); final BasicGeckoViewPrompt prompt = new BasicGeckoViewPrompt(this); prompt.filePickerRequestCode = REQUEST_FILE_PICKER; - mGeckoSession.setPromptDelegate(prompt); + session.setPromptDelegate(prompt); - final MyGeckoViewPermission permission = new MyGeckoViewPermission(); + final ExamplePermissionDelegate permission = new ExamplePermissionDelegate(); permission.androidPermissionRequestCode = REQUEST_PERMISSIONS; - mGeckoSession.setPermissionDelegate(permission); + session.setPermissionDelegate(permission); - loadSettings(getIntent()); - loadFromIntent(getIntent()); + session.setSelectionActionDelegate(new BasicSelectionActionDelegate(this)); + + updateTrackingProtection(session); + } + + private void recreateSession() { + mGeckoSession.close(); + + mGeckoSession = createSession(); + mGeckoSession.open(sGeckoRuntime); + mGeckoView.setSession(mGeckoSession); + mGeckoSession.loadUri(mCurrentUri != null ? mCurrentUri : DEFAULT_URL); + } + + private void updateTrackingProtection(GeckoSession session) { + int categories = mUseTrackingProtection ? + TrackingProtectionDelegate.CATEGORY_ALL : + TrackingProtectionDelegate.CATEGORY_NONE; + + sGeckoRuntime.getSettings().setTrackingProtectionCategories(categories); + } + + @Override + protected void onPause() { + mGeckoSession.setActive(false); + super.onPause(); + } + + @Override + protected void onResume() { + mGeckoSession.setActive(true); + super.onResume(); + } + + @Override + public void onBackPressed() { + if (mFullScreen) { + mGeckoSession.exitFullScreen(); + return; + } + + if (mCanGoBack && mGeckoSession != null) { + mGeckoSession.goBack(); + return; + } + + super.onBackPressed(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.actions, menu); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + menu.findItem(R.id.action_e10s).setChecked(mUseMultiprocess); + menu.findItem(R.id.action_tp).setChecked(mUseTrackingProtection); + menu.findItem(R.id.action_pb).setChecked(mUsePrivateBrowsing); + menu.findItem(R.id.action_forward).setEnabled(mCanGoForward); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_reload: + mGeckoSession.reload(); + break; + case R.id.action_forward: + mGeckoSession.goForward(); + break; + case R.id.action_e10s: + mUseMultiprocess = !mUseMultiprocess; + recreateSession(); + break; + case R.id.action_tp: + mUseTrackingProtection = !mUseTrackingProtection; + updateTrackingProtection(mGeckoSession); + mGeckoSession.reload(); + break; + case R.id.action_pb: + mUsePrivateBrowsing = !mUsePrivateBrowsing; + recreateSession(); + break; + default: + return super.onOptionsItemSelected(item); + } + + return true; } @Override public void onDestroy() { - super.onDestroy(); - if (mKillProcessOnDestroy) { android.os.Process.killProcess(android.os.Process.myPid()); } + + super.onDestroy(); } - @Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); @@ -127,22 +282,17 @@ public class GeckoViewActivity extends Activity { setIntent(intent); - loadSettings(intent); if (intent.getData() != null) { loadFromIntent(intent); } } - private void loadFromIntent(final Intent intent) { + + private void loadFromIntent(final Intent intent) { final Uri uri = intent.getData(); mGeckoSession.loadUri(uri != null ? uri.toString() : DEFAULT_URL); } - private void loadSettings(final Intent intent) { - sGeckoRuntime.getSettings().setRemoteDebuggingEnabled( - intent.getBooleanExtra(USE_REMOTE_DEBUGGER_EXTRA, false)); - } - @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { @@ -160,15 +310,48 @@ public class GeckoViewActivity extends Activity { final String[] permissions, final int[] grantResults) { if (requestCode == REQUEST_PERMISSIONS) { - final MyGeckoViewPermission permission = (MyGeckoViewPermission) + final ExamplePermissionDelegate permission = (ExamplePermissionDelegate) mGeckoSession.getPermissionDelegate(); permission.onRequestPermissionsResult(permissions, grantResults); + } else if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE && + grantResults[0] == PackageManager.PERMISSION_GRANTED) { + continueDownloads(); } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } - private class MyGeckoViewContent implements GeckoSession.ContentDelegate { + private void continueDownloads() { + LinkedList downloads = mPendingDownloads; + mPendingDownloads = new LinkedList<>(); + + for (GeckoSession.WebResponseInfo response : downloads) { + downloadFile(response); + } + } + + private void downloadFile(GeckoSession.WebResponseInfo response) { + if (ContextCompat.checkSelfPermission(GeckoViewActivity.this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + mPendingDownloads.add(response); + ActivityCompat.requestPermissions(GeckoViewActivity.this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + REQUEST_WRITE_EXTERNAL_STORAGE); + return; + } + + final Uri uri = Uri.parse(response.uri); + final String filename = response.filename != null ? response.filename : uri.getLastPathSegment(); + + DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + DownloadManager.Request req = new DownloadManager.Request(uri); + req.setMimeType(response.contentType); + req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); + req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); + manager.enqueue(req); + } + + private class ExampleContentDelegate implements GeckoSession.ContentDelegate { @Override public void onTitleChange(GeckoSession session, String title) { Log.i(LOGTAG, "Content title changed to " + title); @@ -178,10 +361,11 @@ public class GeckoViewActivity extends Activity { public void onFullScreen(final GeckoSession session, final boolean fullScreen) { getWindow().setFlags(fullScreen ? WindowManager.LayoutParams.FLAG_FULLSCREEN : 0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + mFullScreen = fullScreen; if (fullScreen) { - getActionBar().hide(); + getSupportActionBar().hide(); } else { - getActionBar().show(); + getSupportActionBar().show(); } } @@ -192,8 +376,8 @@ public class GeckoViewActivity extends Activity { @Override public void onCloseRequest(final GeckoSession session) { - if (session != mGeckoSession) { - session.close(); + if (session == mGeckoSession) { + finish(); } } @@ -207,7 +391,14 @@ public class GeckoViewActivity extends Activity { } @Override - public void onExternalResponse(GeckoSession session, GeckoSession.WebResponseInfo request) { + public void onExternalResponse(GeckoSession session, GeckoSession.WebResponseInfo response) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndTypeAndNormalize(Uri.parse(response.uri), response.contentType); + startActivity(intent); + } catch (ActivityNotFoundException e) { + downloadFile(response); + } } @Override @@ -218,10 +409,10 @@ public class GeckoViewActivity extends Activity { } } - private class MyGeckoViewProgress implements GeckoSession.ProgressDelegate { - private MyTrackingProtection mTp; + private class ExampleProgressDelegate implements GeckoSession.ProgressDelegate { + private ExampleTrackingProtectionDelegate mTp; - private MyGeckoViewProgress(final MyTrackingProtection tp) { + private ExampleProgressDelegate(final ExampleTrackingProtectionDelegate tp) { mTp = tp; } @@ -247,7 +438,7 @@ public class GeckoViewActivity extends Activity { } } - private class MyGeckoViewPermission implements GeckoSession.PermissionDelegate { + private class ExamplePermissionDelegate implements GeckoSession.PermissionDelegate { public int androidPermissionRequestCode = 1; private Callback mCallback; @@ -273,13 +464,13 @@ public class GeckoViewActivity extends Activity { @Override public void onAndroidPermissionsRequest(final GeckoSession session, final String[] permissions, final Callback callback) { - if (Build.VERSION.SDK_INT < 23) { + if (Build.VERSION.SDK_INT >= 23) { // requestPermissions was introduced in API 23. + mCallback = callback; + requestPermissions(permissions, androidPermissionRequestCode); + } else { callback.grant(); - return; } - mCallback = callback; - requestPermissions(permissions, androidPermissionRequestCode); } @Override @@ -353,17 +544,21 @@ public class GeckoViewActivity extends Activity { } } - private class Navigation implements GeckoSession.NavigationDelegate { + private class ExampleNavigationDelegate implements GeckoSession.NavigationDelegate { @Override public void onLocationChange(GeckoSession session, final String url) { + mLocationView.setText(url); + mCurrentUri = url; } @Override public void onCanGoBack(GeckoSession session, boolean canGoBack) { + mCanGoBack = canGoBack; } @Override - public void onCanGoForward(GeckoSession session, boolean value) { + public void onCanGoForward(GeckoSession session, boolean canGoForward) { + mCanGoForward = canGoForward; } @Override @@ -377,11 +572,20 @@ public class GeckoViewActivity extends Activity { @Override public void onNewSession(final GeckoSession session, final String uri, GeckoResponse response) { - response.respond(null); + GeckoSession newSession = new GeckoSession(session.getSettings()); + response.respond(newSession); + + Intent intent = new Intent(GeckoViewActivity.this, SessionActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(uri)); + intent.putExtra("session", newSession); + + startActivity(intent); } } - private class MyTrackingProtection implements GeckoSession.TrackingProtectionDelegate { + private class ExampleTrackingProtectionDelegate implements GeckoSession.TrackingProtectionDelegate { private int mBlockedAds = 0; private int mBlockedAnalytics = 0; private int mBlockedSocial = 0; diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/LocationView.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/LocationView.java new file mode 100644 index 000000000000..58df9a334577 --- /dev/null +++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/LocationView.java @@ -0,0 +1,61 @@ +package org.mozilla.geckoview_example; + +import org.mozilla.geckoview.GeckoSession; + +import android.content.Context; +import android.support.v7.widget.AppCompatEditText; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.TextView; + +public class LocationView extends AppCompatEditText { + + private CommitListener mCommitListener; + private FocusAndCommitListener mFocusCommitListener = new FocusAndCommitListener(); + + public interface CommitListener { + void onCommit(String text); + } + + public LocationView(Context context) { + super(context); + + this.setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_URI); + this.setSingleLine(true); + this.setSelectAllOnFocus(true); + this.setHint(R.string.location_hint); + + setOnFocusChangeListener(mFocusCommitListener); + setOnEditorActionListener(mFocusCommitListener); + } + + public void setCommitListener(CommitListener listener) { + mCommitListener = listener; + } + + private class FocusAndCommitListener implements OnFocusChangeListener, OnEditorActionListener { + private String mInitialText; + private boolean mCommitted; + + @Override + public void onFocusChange(View view, boolean focused) { + if (focused) { + mInitialText = ((TextView)view).getText().toString(); + mCommitted = false; + } else if (!mCommitted) { + setText(mInitialText); + } + } + + @Override + public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { + if (mCommitListener != null) { + mCommitListener.onCommit(textView.getText().toString()); + } + + mCommitted = true; + return true; + } + } +} diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/SessionActivity.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/SessionActivity.java new file mode 100644 index 000000000000..c6906bb1c329 --- /dev/null +++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/SessionActivity.java @@ -0,0 +1,4 @@ +package org.mozilla.geckoview_example; + +public class SessionActivity extends GeckoViewActivity { +} diff --git a/mobile/android/geckoview_example/src/main/res/layout/geckoview_activity.xml b/mobile/android/geckoview_example/src/main/res/layout/geckoview_activity.xml index 8f72a2b9a80a..3175c3621a69 100644 --- a/mobile/android/geckoview_example/src/main/res/layout/geckoview_activity.xml +++ b/mobile/android/geckoview_example/src/main/res/layout/geckoview_activity.xml @@ -1,13 +1,20 @@ - + - + + diff --git a/mobile/android/geckoview_example/src/main/res/menu/actions.xml b/mobile/android/geckoview_example/src/main/res/menu/actions.xml new file mode 100644 index 000000000000..4fc65d45e8f1 --- /dev/null +++ b/mobile/android/geckoview_example/src/main/res/menu/actions.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/mobile/android/geckoview_example/src/main/res/values/strings.xml b/mobile/android/geckoview_example/src/main/res/values/strings.xml index 08507b83fe0f..aee99d9c6720 100644 --- a/mobile/android/geckoview_example/src/main/res/values/strings.xml +++ b/mobile/android/geckoview_example/src/main/res/values/strings.xml @@ -1,5 +1,7 @@ geckoview_example + GeckoView Example + Enter URL or search keywords... Username Password Clear @@ -12,4 +14,13 @@ Front camera Microphone Unknown source + + Native + Java + Content (Native) + Multiprocess + Tracking Protection + Private Browsing + Forward + Reload