From 0aa342687dafe9c14f98de9f88a33ed2cff77eb9 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 9 Oct 2017 23:04:15 -0500 Subject: [PATCH 01/68] servo: Merge #18790 - Support :scope pseudo-class (from upsuper:scope); r=emilio This fixes [bug 1406817](https://bugzilla.mozilla.org/show_bug.cgi?id=1406817). Source-Repo: https://github.com/servo/servo Source-Revision: bbb2a3cde9f4c7fc9debd5784fce2b07966101ff --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : d4d2b23cd7a27ea3fc053d5062673ff19f6c2a11 --- servo/components/script/dom/element.rs | 9 +++++++-- servo/components/selectors/builder.rs | 2 +- servo/components/selectors/context.rs | 15 +++++++++++++++ servo/components/selectors/matching.rs | 6 ++++++ servo/components/selectors/parser.rs | 3 +++ servo/ports/geckolib/glue.rs | 1 + 6 files changed, 33 insertions(+), 3 deletions(-) diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index 6c69b09d1f73..438d01f4d0ac 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -87,6 +87,7 @@ use net_traits::request::CorsSettings; use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowGoal; use script_thread::ScriptThread; +use selectors::Element as SelectorsElement; use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode}; use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS}; @@ -2191,10 +2192,12 @@ impl ElementMethods for Element { Err(_) => Err(Error::Syntax), Ok(selectors) => { let quirks_mode = document_from_node(self).quirks_mode(); + let root = DomRoot::from_ref(self); // FIXME(bholley): Consider an nth-index cache here. let mut ctx = MatchingContext::new(MatchingMode::Normal, None, None, quirks_mode); - Ok(matches_selector_list(&selectors, &DomRoot::from_ref(self), &mut ctx)) + ctx.scope_element = Some(root.opaque()); + Ok(matches_selector_list(&selectors, &root, &mut ctx)) } } } @@ -2209,6 +2212,7 @@ impl ElementMethods for Element { match SelectorParser::parse_author_origin_no_namespace(&selectors) { Err(_) => Err(Error::Syntax), Ok(selectors) => { + let self_root = DomRoot::from_ref(self); let root = self.upcast::(); for element in root.inclusive_ancestors() { if let Some(element) = DomRoot::downcast::(element) { @@ -2216,6 +2220,7 @@ impl ElementMethods for Element { // FIXME(bholley): Consider an nth-index cache here. let mut ctx = MatchingContext::new(MatchingMode::Normal, None, None, quirks_mode); + ctx.scope_element = Some(self_root.opaque()); if matches_selector_list(&selectors, &element, &mut ctx) { return Ok(Some(element)); } @@ -2500,7 +2505,7 @@ impl VirtualMethods for Element { } } -impl<'a> ::selectors::Element for DomRoot { +impl<'a> SelectorsElement for DomRoot { type Impl = SelectorImpl; fn opaque(&self) -> ::selectors::OpaqueElement { diff --git a/servo/components/selectors/builder.rs b/servo/components/selectors/builder.rs index 99a8f0869156..c996a6a6491a 100644 --- a/servo/components/selectors/builder.rs +++ b/servo/components/selectors/builder.rs @@ -284,7 +284,7 @@ fn complex_selector_specificity(mut iter: slice::Iter>) Component::FirstChild | Component::LastChild | Component::OnlyChild | Component::Root | - Component::Empty | + Component::Empty | Component::Scope | Component::NthChild(..) | Component::NthLastChild(..) | Component::NthOfType(..) | diff --git a/servo/components/selectors/context.rs b/servo/components/selectors/context.rs index c67ef6638cc6..894cc31b15db 100644 --- a/servo/components/selectors/context.rs +++ b/servo/components/selectors/context.rs @@ -5,6 +5,7 @@ use attr::CaseSensitivity; use bloom::BloomFilter; use nth_index_cache::NthIndexCache; +use tree::OpaqueElement; /// What kind of selector matching mode we should use. /// @@ -88,6 +89,19 @@ pub struct MatchingContext<'a> { /// only.) pub relevant_link_found: bool, + /// The element which is going to match :scope pseudo-class. It can be + /// either one :scope element, or the scoping element. + /// + /// Note that, although in theory there can be multiple :scope elements, + /// in current specs, at most one is specified, and when there is one, + /// scoping element is not relevant anymore, so we use a single field for + /// them. + /// + /// When this is None, :scope will match the root element. + /// + /// See https://drafts.csswg.org/selectors-4/#scope-pseudo + pub scope_element: Option, + quirks_mode: QuirksMode, classes_and_ids_case_sensitivity: CaseSensitivity, } @@ -125,6 +139,7 @@ impl<'a> MatchingContext<'a> { quirks_mode, relevant_link_found: false, classes_and_ids_case_sensitivity: quirks_mode.classes_and_ids_case_sensitivity(), + scope_element: None, } } diff --git a/servo/components/selectors/matching.rs b/servo/components/selectors/matching.rs index ff0dd40b484c..875ac2862e66 100644 --- a/servo/components/selectors/matching.rs +++ b/servo/components/selectors/matching.rs @@ -724,6 +724,12 @@ fn matches_simple_selector( flags_setter(element, HAS_EMPTY_SELECTOR); element.is_empty() } + Component::Scope => { + match context.shared.scope_element { + Some(ref scope_element) => element.opaque() == *scope_element, + None => element.is_root(), + } + } Component::NthChild(a, b) => { matches_generic_nth_child(element, context, a, b, false, false, flags_setter) } diff --git a/servo/components/selectors/parser.rs b/servo/components/selectors/parser.rs index b020a04fd032..44ff450aa3e0 100644 --- a/servo/components/selectors/parser.rs +++ b/servo/components/selectors/parser.rs @@ -673,6 +673,7 @@ pub enum Component { FirstChild, LastChild, OnlyChild, Root, Empty, + Scope, NthChild(i32, i32), NthLastChild(i32, i32), NthOfType(i32, i32), @@ -969,6 +970,7 @@ impl ToCss for Component { OnlyChild => dest.write_str(":only-child"), Root => dest.write_str(":root"), Empty => dest.write_str(":empty"), + Scope => dest.write_str(":scope"), FirstOfType => dest.write_str(":first-of-type"), LastOfType => dest.write_str(":last-of-type"), OnlyOfType => dest.write_str(":only-of-type"), @@ -1699,6 +1701,7 @@ fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>) "only-child" => Ok(Component::OnlyChild), "root" => Ok(Component::Root), "empty" => Ok(Component::Empty), + "scope" => Ok(Component::Scope), "first-of-type" => Ok(Component::FirstOfType), "last-of-type" => Ok(Component::LastOfType), "only-of-type" => Ok(Component::OnlyOfType), diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 06c7b794a962..1c975c5767b0 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -1530,6 +1530,7 @@ pub unsafe extern "C" fn Servo_SelectorList_Matches( None, element.owner_document_quirks_mode(), ); + context.scope_element = Some(element.opaque()); selectors::matching::matches_selector_list(selectors, &element, &mut context) } From bda66ac6dad9b2462f29b96d3f442df36593834e Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Tue, 10 Oct 2017 01:20:38 -0500 Subject: [PATCH 02/68] servo: Merge #18800 - Fix mismatched arguments for servo selector list (from hiikezoe:fix-mismatched-arguments-for-servo-selector-list); r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1406811 This needs to be fixed to update binding files. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors Source-Repo: https://github.com/servo/servo Source-Revision: 2cd9dcebeefd22a265b3fe4e424fbf231392f594 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 9c6eac62aa67a5c30ce91ecb64cccb5cf97df5e0 --- .../style/gecko/generated/atom_macro.rs | 8 + .../style/gecko/generated/bindings.rs | 48 +- .../style/gecko/generated/structs.rs | 1115 +++++++++-------- .../components/style/gecko/selector_parser.rs | 9 + servo/ports/geckolib/glue.rs | 17 +- 5 files changed, 677 insertions(+), 520 deletions(-) diff --git a/servo/components/style/gecko/generated/atom_macro.rs b/servo/components/style/gecko/generated/atom_macro.rs index 425cd5fcfd1a..db43667f6b1b 100644 --- a/servo/components/style/gecko/generated/atom_macro.rs +++ b/servo/components/style/gecko/generated/atom_macro.rs @@ -1122,6 +1122,8 @@ cfg_if! { pub static nsGkAtoms_integrity: *mut nsAtom; #[link_name = "_ZN9nsGkAtoms12intersectionE"] pub static nsGkAtoms_intersection: *mut nsAtom; + #[link_name = "_ZN9nsGkAtoms24intersectionobserverlistE"] + pub static nsGkAtoms_intersectionobserverlist: *mut nsAtom; #[link_name = "_ZN9nsGkAtoms2isE"] pub static nsGkAtoms_is: *mut nsAtom; #[link_name = "_ZN9nsGkAtoms11iscontainerE"] @@ -6291,6 +6293,8 @@ cfg_if! { pub static nsGkAtoms_integrity: *mut nsAtom; #[link_name = "?intersection@nsGkAtoms@@2PEAVnsAtom@@EA"] pub static nsGkAtoms_intersection: *mut nsAtom; + #[link_name = "?intersectionobserverlist@nsGkAtoms@@2PEAVnsAtom@@EA"] + pub static nsGkAtoms_intersectionobserverlist: *mut nsAtom; #[link_name = "?is@nsGkAtoms@@2PEAVnsAtom@@EA"] pub static nsGkAtoms_is: *mut nsAtom; #[link_name = "?iscontainer@nsGkAtoms@@2PEAVnsAtom@@EA"] @@ -11460,6 +11464,8 @@ cfg_if! { pub static nsGkAtoms_integrity: *mut nsAtom; #[link_name = "\x01?intersection@nsGkAtoms@@2PAVnsAtom@@A"] pub static nsGkAtoms_intersection: *mut nsAtom; + #[link_name = "\x01?intersectionobserverlist@nsGkAtoms@@2PAVnsAtom@@A"] + pub static nsGkAtoms_intersectionobserverlist: *mut nsAtom; #[link_name = "\x01?is@nsGkAtoms@@2PAVnsAtom@@A"] pub static nsGkAtoms_is: *mut nsAtom; #[link_name = "\x01?iscontainer@nsGkAtoms@@2PAVnsAtom@@A"] @@ -16632,6 +16638,8 @@ macro_rules! atom { { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_integrity as *mut _) } }; ("intersection") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_intersection as *mut _) } }; +("intersectionobserverlist") => + { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_intersectionobserverlist as *mut _) } }; ("is") => { unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_is as *mut _) } }; ("iscontainer") => diff --git a/servo/components/style/gecko/generated/bindings.rs b/servo/components/style/gecko/generated/bindings.rs index 80a7989c9578..57f08684e8f5 100644 --- a/servo/components/style/gecko/generated/bindings.rs +++ b/servo/components/style/gecko/generated/bindings.rs @@ -45,6 +45,7 @@ use gecko_bindings::structs::RawGeckoStyleChildrenIterator; use gecko_bindings::structs::RawGeckoServoStyleRuleList; use gecko_bindings::structs::RawGeckoURLExtraData; use gecko_bindings::structs::RawGeckoXBLBinding; +use gecko_bindings::structs::RawServoSelectorList; use gecko_bindings::structs::RefPtr; use gecko_bindings::structs::RustString; use gecko_bindings::structs::CSSPseudoClassType; @@ -250,6 +251,12 @@ pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>; enum RawServoStyleSetVoid { } pub struct RawServoStyleSet(RawServoStyleSetVoid); +pub type RawServoSelectorListOwned = ::gecko_bindings::sugar::ownership::Owned; +pub type RawServoSelectorListOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull; +pub type RawServoSelectorListBorrowed<'a> = &'a RawServoSelectorList; +pub type RawServoSelectorListBorrowedOrNull<'a> = Option<&'a RawServoSelectorList>; +pub type RawServoSelectorListBorrowedMut<'a> = &'a mut RawServoSelectorList; +pub type RawServoSelectorListBorrowedMutOrNull<'a> = Option<&'a mut RawServoSelectorList>; pub type ServoElementSnapshotOwned = ::gecko_bindings::sugar::ownership::Owned; pub type ServoElementSnapshotOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull; pub type ServoElementSnapshotBorrowed<'a> = &'a ServoElementSnapshot; @@ -514,6 +521,9 @@ extern "C" { extern "C" { pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned); } +extern "C" { + pub fn Servo_SelectorList_Drop(ptr: RawServoSelectorListOwned); +} extern "C" { pub fn Gecko_IsInDocument(node: RawGeckoNodeBorrowed) -> bool; } @@ -628,9 +638,9 @@ extern "C" { name: *mut nsAtom) -> bool; } extern "C" { - pub fn Gecko_AttrEquals(element: RawGeckoElementBorrowed, - ns: *mut nsAtom, name: *mut nsAtom, - str: *mut nsAtom, ignoreCase: bool) -> bool; + pub fn Gecko_AttrEquals(element: RawGeckoElementBorrowed, ns: *mut nsAtom, + name: *mut nsAtom, str: *mut nsAtom, + ignoreCase: bool) -> bool; } extern "C" { pub fn Gecko_AttrDashEquals(element: RawGeckoElementBorrowed, @@ -665,8 +675,7 @@ extern "C" { } extern "C" { pub fn Gecko_SnapshotAtomAttrValue(element: *const ServoElementSnapshot, - attribute: *mut nsAtom) - -> *mut nsAtom; + attribute: *mut nsAtom) -> *mut nsAtom; } extern "C" { pub fn Gecko_SnapshotLangValue(element: *const ServoElementSnapshot) @@ -674,8 +683,7 @@ extern "C" { } extern "C" { pub fn Gecko_SnapshotHasAttr(element: *const ServoElementSnapshot, - ns: *mut nsAtom, name: *mut nsAtom) - -> bool; + ns: *mut nsAtom, name: *mut nsAtom) -> bool; } extern "C" { pub fn Gecko_SnapshotAttrEquals(element: *const ServoElementSnapshot, @@ -698,10 +706,9 @@ extern "C" { extern "C" { pub fn Gecko_SnapshotAttrHasSubstring(element: *const ServoElementSnapshot, - ns: *mut nsAtom, - name: *mut nsAtom, - str: *mut nsAtom, - ignore_case: bool) -> bool; + ns: *mut nsAtom, name: *mut nsAtom, + str: *mut nsAtom, ignore_case: bool) + -> bool; } extern "C" { pub fn Gecko_SnapshotAttrHasPrefix(element: *const ServoElementSnapshot, @@ -1015,8 +1022,7 @@ extern "C" { aImageValue: *mut ImageValue); } extern "C" { - pub fn Gecko_SetImageElement(image: *mut nsStyleImage, - atom: *mut nsAtom); + pub fn Gecko_SetImageElement(image: *mut nsStyleImage, atom: *mut nsAtom); } extern "C" { pub fn Gecko_CopyImageValueFrom(image: *mut nsStyleImage, @@ -1580,9 +1586,6 @@ extern "C" { extern "C" { pub fn Gecko_ShouldCreateStyleThreadPool() -> bool; } -extern "C" { - pub fn Gecko_GetSystemPageSize() -> usize; -} extern "C" { pub fn Gecko_Construct_Default_nsStyleFont(ptr: *mut nsStyleFont, pres_context: @@ -1902,6 +1905,10 @@ extern "C" { extern "C" { pub fn Gecko_SetJemallocThreadLocalArena(enabled: bool); } +extern "C" { + pub fn Gecko_AddBufferToCrashReport(addr: *const ::std::os::raw::c_void, + len: usize); +} extern "C" { pub fn Servo_Element_ClearData(node: RawGeckoElementBorrowed); } @@ -2090,6 +2097,15 @@ extern "C" { RawServoDeclarationBlockBorrowed) -> ServoStyleContextStrong; } +extern "C" { + pub fn Servo_SelectorList_Parse(selector_list: *const nsACString) + -> *mut RawServoSelectorList; +} +extern "C" { + pub fn Servo_SelectorList_Matches(arg1: RawGeckoElementBorrowed, + arg2: RawServoSelectorListBorrowed) + -> bool; +} extern "C" { pub fn Servo_StyleSet_AddSizeOfExcludingThis(malloc_size_of: MallocSizeOf, malloc_enclosing_size_of: diff --git a/servo/components/style/gecko/generated/structs.rs b/servo/components/style/gecko/generated/structs.rs index 48e7d132636b..69253f300a61 100644 --- a/servo/components/style/gecko/generated/structs.rs +++ b/servo/components/style/gecko/generated/structs.rs @@ -1001,8 +1001,6 @@ pub mod root { } pub type pair_first_type<_T1> = _T1; pub type pair_second_type<_T2> = _T2; - pub type pair__PCCP = u8; - pub type pair__PCCFP = u8; #[repr(C)] #[derive(Debug, Copy)] pub struct input_iterator_tag { @@ -2316,7 +2314,7 @@ pub mod root { #[repr(C)] #[derive(Debug)] pub struct SRIMetadata { - pub mHashes: root::nsTArray, + pub mHashes: root::nsTArray>, pub mIntegrityString: ::nsstring::nsStringRepr, pub mAlgorithm: root::nsCString, pub mAlgorithmType: i8, @@ -2974,65 +2972,6 @@ pub mod root { ( "Alignment of " , stringify ! ( Attr ) )); } #[repr(C)] - #[derive(Debug)] - pub struct DOMIntersectionObserver { - pub _base: root::nsISupports, - pub _base_1: root::nsWrapperCache, - pub mRefCnt: root::nsCycleCollectingAutoRefCnt, - pub mOwner: root::nsCOMPtr, - pub mDocument: root::RefPtr, - pub mCallback: root::RefPtr, - pub mRoot: root::RefPtr, - pub mRootMargin: root::nsCSSRect, - pub mThresholds: root::nsTArray, - pub mObservationTargets: root::nsTArray<*mut root::mozilla::dom::Element>, - pub mQueuedEntries: root::nsTArray>, - pub mConnected: bool, - } - pub type DOMIntersectionObserver_HasThreadSafeRefCnt = - root::mozilla::FalseType; - #[repr(C)] - #[derive(Debug, Copy)] - pub struct DOMIntersectionObserver_cycleCollection { - pub _base: root::nsXPCOMCycleCollectionParticipant, - } - #[test] - fn bindgen_test_layout_DOMIntersectionObserver_cycleCollection() { - assert_eq!(::std::mem::size_of::() - , 16usize , concat ! ( - "Size of: " , stringify ! ( - DOMIntersectionObserver_cycleCollection ) )); - assert_eq! (::std::mem::align_of::() - , 8usize , concat ! ( - "Alignment of " , stringify ! ( - DOMIntersectionObserver_cycleCollection ) )); - } - impl Clone for DOMIntersectionObserver_cycleCollection { - fn clone(&self) -> Self { *self } - } - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct DOMIntersectionObserver_COMTypeInfo { - pub _address: u8, - } - extern "C" { - #[link_name = - "_ZN7mozilla3dom23DOMIntersectionObserver21_cycleCollectorGlobalE"] - pub static mut DOMIntersectionObserver__cycleCollectorGlobal: - root::mozilla::dom::DOMIntersectionObserver_cycleCollection; - } - #[test] - fn bindgen_test_layout_DOMIntersectionObserver() { - assert_eq!(::std::mem::size_of::() , - 168usize , concat ! ( - "Size of: " , stringify ! ( DOMIntersectionObserver - ) )); - assert_eq! (::std::mem::align_of::() - , 8usize , concat ! ( - "Alignment of " , stringify ! ( - DOMIntersectionObserver ) )); - } - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct FontFaceSet { _unused: [u8; 0], @@ -3240,15 +3179,13 @@ pub mod root { pub mXBLInsertionParent: root::nsCOMPtr, /// Web components custom element data. pub mCustomElementData: root::RefPtr, - /// Registered Intersection Observers on the element. - pub mRegisteredIntersectionObservers: [u64; 4usize], /// For XUL to hold either frameloader or opener. pub mFrameLoaderOrOpener: root::nsCOMPtr, } #[test] fn bindgen_test_layout_FragmentOrElement_nsExtendedDOMSlots() { assert_eq!(::std::mem::size_of::() - , 128usize , concat ! ( + , 96usize , concat ! ( "Size of: " , stringify ! ( FragmentOrElement_nsExtendedDOMSlots ) )); assert_eq! (::std::mem::align_of::() @@ -3354,22 +3291,12 @@ pub mod root { "Alignment of field: " , stringify ! ( FragmentOrElement_nsExtendedDOMSlots ) , "::" , stringify ! ( mCustomElementData ) )); - assert_eq! (unsafe { - & ( - * ( - 0 as * const FragmentOrElement_nsExtendedDOMSlots - ) ) . mRegisteredIntersectionObservers as * const - _ as usize } , 88usize , concat ! ( - "Alignment of field: " , stringify ! ( - FragmentOrElement_nsExtendedDOMSlots ) , "::" , - stringify ! ( mRegisteredIntersectionObservers ) - )); assert_eq! (unsafe { & ( * ( 0 as * const FragmentOrElement_nsExtendedDOMSlots ) ) . mFrameLoaderOrOpener as * const _ as usize } - , 120usize , concat ! ( + , 88usize , concat ! ( "Alignment of field: " , stringify ! ( FragmentOrElement_nsExtendedDOMSlots ) , "::" , stringify ! ( mFrameLoaderOrOpener ) )); @@ -3556,25 +3483,6 @@ pub mod root { DOMIntersectionObserverEntry ) )); } #[repr(C)] - #[derive(Debug, Copy)] - pub struct IntersectionCallback { - pub _bindgen_opaque_blob: [u64; 6usize], - } - #[test] - fn bindgen_test_layout_IntersectionCallback() { - assert_eq!(::std::mem::size_of::() , - 48usize , concat ! ( - "Size of: " , stringify ! ( IntersectionCallback ) - )); - assert_eq! (::std::mem::align_of::() , - 8usize , concat ! ( - "Alignment of " , stringify ! ( - IntersectionCallback ) )); - } - impl Clone for IntersectionCallback { - fn clone(&self) -> Self { *self } - } - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct Grid { _unused: [u8; 0], @@ -5755,7 +5663,6 @@ pub mod root { assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( Runnable ) )); } - pub type Preferences_PrefSetting = root::mozilla::dom::PrefSetting; #[repr(C)] #[derive(Debug)] pub struct CycleCollectedJSContext_RunInMetastableStateData { @@ -5906,9 +5813,8 @@ pub mod root { eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap = 92, eUseCounter_URLCreateObjectURL_MediaStream = 93, eUseCounter_XMLBaseAttribute = 94, - eUseCounter_XMLBaseAttributeForStyleAttr = 95, - eUseCounter_WindowContentUntrusted = 96, - eUseCounter_Count = 97, + eUseCounter_WindowContentUntrusted = 95, + eUseCounter_Count = 96, } /// This class holds all non-tree-structural state of an element that might be /// used for selector matching eventually. @@ -6710,8 +6616,6 @@ pub mod root { #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct OriginFlags(pub u8); - pub type ComputedKeyframeValues = - root::nsTArray; #[test] fn __bindgen_test_layout_DefaultDelete_open0_RawServoStyleSet_close0_instantiation() { assert_eq!(::std::mem::size_of::() , @@ -11586,7 +11490,7 @@ pub mod root { #[derive(Debug)] pub struct gfxFontFeatureValueSet_ValueList { pub name: ::nsstring::nsStringRepr, - pub featureSelectors: root::nsTArray, + pub featureSelectors: root::nsTArray<::std::os::raw::c_uint>, } #[test] fn bindgen_test_layout_gfxFontFeatureValueSet_ValueList() { @@ -11691,7 +11595,7 @@ pub mod root { pub struct gfxFontFeatureValueSet_FeatureValueHashEntry { pub _base: root::PLDHashEntryHdr, pub mKey: root::gfxFontFeatureValueSet_FeatureValueHashKey, - pub mValues: root::nsTArray, + pub mValues: root::nsTArray<::std::os::raw::c_uint>, } pub type gfxFontFeatureValueSet_FeatureValueHashEntry_KeyType = *const root::gfxFontFeatureValueSet_FeatureValueHashKey; @@ -11789,7 +11693,7 @@ pub mod root { pub alternateValues: root::nsTArray, pub featureValueLookup: root::RefPtr, pub fontFeatureSettings: root::nsTArray, - pub fontVariationSettings: root::nsTArray, + pub fontVariationSettings: root::nsTArray, pub languageOverride: u32, } #[test] @@ -16079,7 +15983,7 @@ pub mod root { pub mUpgradeInsecurePreloads: bool, pub mHSTSPrimingURIList: [u64; 4usize], pub mDocumentContainer: u64, - pub mCharacterSet: root::mozilla::NotNull<*const root::nsIDocument_Encoding>, + pub mCharacterSet: root::mozilla::NotNull<*const root::mozilla::Encoding>, pub mCharacterSetSource: i32, pub mParentDocument: *mut root::nsIDocument, pub mCachedRootElement: *mut root::mozilla::dom::Element, @@ -16128,7 +16032,7 @@ pub mod root { /// The current frame request callback handle pub mFrameRequestCallbackCounter: i32, pub mStaticCloneCount: u32, - pub mBlockedTrackingNodes: root::nsTArray, + pub mBlockedTrackingNodes: root::nsTArray, pub mWindow: *mut root::nsPIDOMWindowInner, pub mCachedEncoder: root::nsCOMPtr, pub mFrameRequestCallbacks: root::nsTArray, @@ -16451,9 +16355,8 @@ pub mod root { eImageBitmapRenderingContext_TransferImageBitmap = 36, eURLCreateObjectURL_MediaStream = 37, eXMLBaseAttribute = 38, - eXMLBaseAttributeForStyleAttr = 39, - eWindowContentUntrusted = 40, - eDeprecatedOperationCount = 41, + eWindowContentUntrusted = 39, + eDeprecatedOperationCount = 40, } #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -19142,7 +19045,7 @@ pub mod root { pub _base: root::nsStubMutationObserver, pub mRefCnt: root::nsCycleCollectingAutoRefCnt, pub mBoundContentSet: u64, - pub mWrapperTable: root::nsAutoPtr, + pub mWrapperTable: u64, pub mDocumentTable: u64, pub mLoadingDocTable: u64, pub mAttachedStack: root::nsBindingList, @@ -22838,7 +22741,7 @@ pub mod root { pub struct nsIGlobalObject { pub _base: root::nsISupports, pub _base_1: root::mozilla::dom::DispatcherTrait, - pub mHostObjectURIs: root::nsTArray, + pub mHostObjectURIs: root::nsTArray>, pub mIsDying: bool, } #[repr(C)] @@ -24245,57 +24148,57 @@ pub mod root { pub struct RawServoSelectorList { _unused: [u8; 0], } - pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_LISTENERMANAGER; - pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_PROPERTIES; - pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_ANONYMOUS_ROOT; - pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; - pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_NATIVE_ANONYMOUS_ROOT; - pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_FORCE_XBL_BINDINGS; - pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_MAY_BE_IN_BINDING_MNGR; - pub const NODE_IS_EDITABLE: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_EDITABLE; - pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_NATIVE_ANONYMOUS; - pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_IN_SHADOW_TREE; - pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_EMPTY_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_SLOW_SELECTOR; - pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_EDGE_CHILD_SELECTOR; - pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; - pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_ALL_SELECTOR_FLAGS; - pub const NODE_NEEDS_FRAME: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_NEEDS_FRAME; - pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_DESCENDANTS_NEED_FRAMES; - pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_ACCESSKEY; - pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_DIRECTION_RTL; - pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_HAS_DIRECTION_LTR; - pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_ALL_DIRECTION_FLAGS; - pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_CHROME_ONLY_ACCESS; - pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; - pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_77 = - _bindgen_ty_77::NODE_TYPE_SPECIFIC_BITS_OFFSET; + pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_LISTENERMANAGER; + pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_PROPERTIES; + pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_ANONYMOUS_ROOT; + pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE; + pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_NATIVE_ANONYMOUS_ROOT; + pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_FORCE_XBL_BINDINGS; + pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_MAY_BE_IN_BINDING_MNGR; + pub const NODE_IS_EDITABLE: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_EDITABLE; + pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_NATIVE_ANONYMOUS; + pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_IN_SHADOW_TREE; + pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_EMPTY_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_SLOW_SELECTOR; + pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_EDGE_CHILD_SELECTOR; + pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS; + pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_ALL_SELECTOR_FLAGS; + pub const NODE_NEEDS_FRAME: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_NEEDS_FRAME; + pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_DESCENDANTS_NEED_FRAMES; + pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_ACCESSKEY; + pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_DIRECTION_RTL; + pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_HAS_DIRECTION_LTR; + pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_ALL_DIRECTION_FLAGS; + pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_CHROME_ONLY_ACCESS; + pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS; + pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_83 = + _bindgen_ty_83::NODE_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_77 { + pub enum _bindgen_ty_83 { NODE_HAS_LISTENERMANAGER = 4, NODE_HAS_PROPERTIES = 8, NODE_IS_ANONYMOUS_ROOT = 16, @@ -26332,7 +26235,7 @@ pub mod root { pub type RawGeckoPropertyValuePairList = root::nsTArray; pub type RawGeckoComputedKeyframeValuesList = - root::nsTArray; + root::nsTArray>; pub type RawGeckoStyleAnimationList = root::nsStyleAutoArray; pub type RawGeckoFontFaceRuleList = @@ -28440,7 +28343,7 @@ pub mod root { pub _base_4: root::nsITimedChannel, pub mRefCnt: root::nsAutoRefCnt, pub mBehaviour: root::mozilla::UniquePtr, - pub mURI: root::RefPtr, + pub mURI: root::RefPtr, pub mListener: *mut root::imgINotificationObserver, pub mLoadGroup: root::nsCOMPtr, pub mTabGroup: root::RefPtr, @@ -30293,7 +30196,7 @@ pub mod root { #[repr(C)] #[derive(Debug)] pub struct nsBorderColors { - pub mColors: [root::nsTArray; 4usize], + pub mColors: [root::nsTArray<::std::os::raw::c_uint>; 4usize], } #[test] fn bindgen_test_layout_nsBorderColors() { @@ -30317,7 +30220,8 @@ pub mod root { pub mQuotePairs: root::nsStyleQuoteValues_QuotePairArray, } pub type nsStyleQuoteValues_QuotePairArray = - root::nsTArray>; + root::nsTArray>; pub type nsStyleQuoteValues_HasThreadSafeRefCnt = root::mozilla::TrueType; #[test] fn bindgen_test_layout_nsStyleQuoteValues() { @@ -31734,51 +31638,51 @@ pub mod root { assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISMILAttr ) )); } - pub const ELEMENT_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; - pub const ELEMENT_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_SHARED_RESTYLE_BIT_3: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; - pub const ELEMENT_SHARED_RESTYLE_BIT_4: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_SHARED_RESTYLE_BITS: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BITS; - pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_SHARED_RESTYLE_BIT_3: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_3; + pub const ELEMENT_SHARED_RESTYLE_BIT_4: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_SHARED_RESTYLE_BITS: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BITS; + pub const ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_1; pub const ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO: - root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_HAS_SNAPSHOT: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; - pub const ELEMENT_HANDLED_SNAPSHOT: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_HAS_PENDING_RESTYLE: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_1; - pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_2; - pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE: root::_bindgen_ty_79 + root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_HAS_SNAPSHOT: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_3; + pub const ELEMENT_HANDLED_SNAPSHOT: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_HAS_PENDING_RESTYLE: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_1; + pub const ELEMENT_IS_POTENTIAL_RESTYLE_ROOT: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_2; + pub const ELEMENT_HAS_PENDING_ANIMATION_ONLY_RESTYLE: root::_bindgen_ty_85 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_3; + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_3; pub const ELEMENT_IS_POTENTIAL_ANIMATION_ONLY_RESTYLE_ROOT: - root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_SHARED_RESTYLE_BIT_4; - pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR; - pub const ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT: root::_bindgen_ty_79 + root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_SHARED_RESTYLE_BIT_4; + pub const ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_IS_CONDITIONAL_RESTYLE_ANCESTOR; + pub const ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT: root::_bindgen_ty_85 = - _bindgen_ty_79::ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT; - pub const ELEMENT_PENDING_RESTYLE_FLAGS: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_PENDING_RESTYLE_FLAGS; - pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS; - pub const ELEMENT_ALL_RESTYLE_FLAGS: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_ALL_RESTYLE_FLAGS; - pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_79 = - _bindgen_ty_79::ELEMENT_TYPE_SPECIFIC_BITS_OFFSET; + _bindgen_ty_85::ELEMENT_HAS_CHILD_WITH_LATER_SIBLINGS_HINT; + pub const ELEMENT_PENDING_RESTYLE_FLAGS: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_PENDING_RESTYLE_FLAGS; + pub const ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_POTENTIAL_RESTYLE_ROOT_FLAGS; + pub const ELEMENT_ALL_RESTYLE_FLAGS: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_ALL_RESTYLE_FLAGS; + pub const ELEMENT_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_85 = + _bindgen_ty_85::ELEMENT_TYPE_SPECIFIC_BITS_OFFSET; #[repr(u32)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] - pub enum _bindgen_ty_79 { + pub enum _bindgen_ty_85 { ELEMENT_SHARED_RESTYLE_BIT_1 = 8388608, ELEMENT_SHARED_RESTYLE_BIT_2 = 16777216, ELEMENT_SHARED_RESTYLE_BIT_3 = 33554432, @@ -32443,15 +32347,28 @@ pub mod root { root::nsTString<::std::os::raw::c_char> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCString_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char_close1_close0_instantiation() { + assert_eq!(::std::mem::size_of::>>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + root::nsTArray> ) + )); + assert_eq!(::std::mem::align_of::>>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray> ) + )); + } + #[test] + fn __bindgen_test_layout_nsTString_open0_char_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() + , 16usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); } #[test] fn __bindgen_test_layout_UniquePtr_open0_JSErrorNotes_DeletePolicy_open1_JSErrorNotes_close1_close0_instantiation() { @@ -32568,26 +32485,26 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , 8usize , - concat ! ( + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , 8usize , - concat ! ( + root::nsTArray<::std::os::raw::c_uint> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() , 8usize , - concat ! ( + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , 8usize , - concat ! ( + root::nsTArray<::std::os::raw::c_uint> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_gfxFontFeatureValueSet_ValueList_close0_instantiation() { @@ -32603,37 +32520,37 @@ pub mod root { )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_2() { - assert_eq!(::std::mem::size_of::>() , 8usize , - concat ! ( + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , 8usize , - concat ! ( + root::nsTArray<::std::os::raw::c_uint> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_3() { - assert_eq!(::std::mem::size_of::>() , 8usize , - concat ! ( + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , 8usize , - concat ! ( + root::nsTArray<::std::os::raw::c_uint> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_uint32_t_close0_instantiation_4() { - assert_eq!(::std::mem::size_of::>() , 8usize , - concat ! ( + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_4() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , 8usize , - concat ! ( + root::nsTArray<::std::os::raw::c_uint> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_gfxAlternateValue_close0_instantiation() { @@ -32669,18 +32586,18 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_gfxFontVariation_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0_FontVariation_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_199273_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214690_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33047,18 +32964,29 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_201083_close0_instantiation() { + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_216503_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33223,7 +33151,7 @@ pub mod root { root::JS::DeletePolicy ) )); } #[test] - fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_206661__bindgen_ty_id_206668_close0_instantiation() { + fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_222100__bindgen_ty_id_222107_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33366,26 +33294,52 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCString_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char_close1_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + root::nsTArray> ) + )); + assert_eq!(::std::mem::align_of::>>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray> ) + )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCString_close0_instantiation_2() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTString_open0_char_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::>() + , 16usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + root::nsTString<::std::os::raw::c_char> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTString<::std::os::raw::c_char> ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char_close1_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::>>() + , 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTArray> ) + )); + assert_eq!(::std::mem::align_of::>>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTArray> ) + )); + } + #[test] + fn __bindgen_test_layout_nsTString_open0_char_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::>() + , 16usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIDocument_close0_instantiation() { @@ -33592,15 +33546,15 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_209212_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224662_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<*mut root::nsIDocument_Element> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray<*mut root::mozilla::dom::Element> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<*mut root::nsIDocument_Element> ) )); + root::nsTArray<*mut root::mozilla::dom::Element> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_Element_close1_close0_instantiation() { @@ -33660,15 +33614,15 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_209517_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224967_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray<*mut root::nsIDocument_Element> ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray<*mut root::mozilla::dom::Element> ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray<*mut root::nsIDocument_Element> ) )); + root::nsTArray<*mut root::mozilla::dom::Element> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_Element_close1_close0_instantiation_1() { @@ -33772,16 +33726,16 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_210068_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_225518_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::mozilla::NotNull<*const root::nsIDocument_Encoding> ) + root::mozilla::NotNull<*const root::mozilla::Encoding> ) )); - assert_eq!(::std::mem::align_of::>() + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::mozilla::NotNull<*const root::nsIDocument_Encoding> ) + root::mozilla::NotNull<*const root::mozilla::Encoding> ) )); } #[test] @@ -33983,15 +33937,26 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsWeakPtr_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , + fn __bindgen_test_layout_nsTArray_open0_nsCOMPtr_open1_nsIWeakReference_close1_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); + } + #[test] + fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation() { + assert_eq!(::std::mem::size_of::() , 8usize , concat ! + ( + "Size of template specialization: " , stringify ! ( + root::nsCOMPtr ) )); + assert_eq!(::std::mem::align_of::() , 8usize , concat + ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsCOMPtr ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIDocumentEncoder_close0_instantiation() { @@ -34196,7 +34161,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_210493_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_225947_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34262,15 +34227,28 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCString_close0_instantiation_3() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char_close1_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::>>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + root::nsTArray> ) + )); + assert_eq!(::std::mem::align_of::>>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray> ) + )); + } + #[test] + fn __bindgen_test_layout_nsTString_open0_char_close0_instantiation_4() { + assert_eq!(::std::mem::size_of::>() + , 16usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); } #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_ServoStyleSheet_close1_close0_instantiation() { @@ -34299,7 +34277,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_210904_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226361_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34422,18 +34400,29 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_211869_close0_instantiation() { + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227320_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34464,17 +34453,13 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsAutoPtr_open0_nsBindingManager_WrapperHashtable_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsAutoPtr ) + fn __bindgen_test_layout_nsAutoPtr_open0_nsInterfaceHashtable_open1_nsISupportsHashKey_nsIXPConnectWrappedJS_close1_close0_instantiation() { + assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( u64 ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( + assert_eq!(::std::mem::align_of::() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsAutoPtr ) - )); + u64 ) )); } #[test] fn __bindgen_test_layout_nsAutoPtr_open0_nsRefPtrHashtable_open1_nsURIHashKey_nsXBLDocumentInfo_close1_close0_instantiation() { @@ -34526,7 +34511,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212176_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227630_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34537,7 +34522,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212181_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227635_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34594,7 +34579,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_212661_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_228112_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34959,29 +34944,53 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsCString_close0_instantiation_4() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char_close1_close0_instantiation_4() { + assert_eq!(::std::mem::size_of::>>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + root::nsTArray> ) + )); + assert_eq!(::std::mem::align_of::>>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray> ) + )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_2() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTString_open0_char_close0_instantiation_5() { + assert_eq!(::std::mem::size_of::>() + , 16usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::nsTString<::std::os::raw::c_char> ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_2() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsDOMAttributeMap_Element_close0_instantiation() { + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsCOMPtr_open0_Element_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35207,7 +35216,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation() { + fn __bindgen_test_layout_nsCOMPtr_open0_nsIWeakReference_close0_instantiation_1() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35218,7 +35227,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_215419_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230800_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35297,7 +35306,7 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_221579_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_236844_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35387,7 +35396,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_223962_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_239153_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35398,17 +35407,28 @@ pub mod root { root::nsTArray<*mut root::nsISupports> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_3() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_3() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_4() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsIURI_close0_instantiation_10() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( @@ -35530,17 +35550,28 @@ pub mod root { root::nsStyleAutoArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_4() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_4() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_5() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_RefPtr_open1_SheetLoadData_close1_close0_instantiation() { assert_eq!(::std::mem::size_of::>>() , 8usize , concat ! ( @@ -35635,52 +35666,6 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsCOMPtr_open0_nsPIDOMWindowInner_close0_instantiation() { - assert_eq!(::std::mem::size_of::() , 8usize , concat ! - ( - "Size of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); - assert_eq!(::std::mem::align_of::() , 8usize , concat - ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsCOMPtr ) )); - } - #[test] - fn __bindgen_test_layout_RefPtr_open0_nsIDocument_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); - } - #[test] - fn __bindgen_test_layout_RefPtr_open0_IntersectionCallback_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::RefPtr ) - )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) - )); - } - #[test] - fn __bindgen_test_layout_RefPtr_open0_Element_close0_instantiation_3() { - assert_eq!(::std::mem::size_of::>() - , 8usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); - } - #[test] fn __bindgen_test_layout_nsTArray_open0_double_close0_instantiation_1() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -35692,7 +35677,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226099_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_241307_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35740,17 +35725,28 @@ pub mod root { root::mozilla::UniquePtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_5() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_5() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_6() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_9() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -35797,7 +35793,7 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_228468_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_243679_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35830,17 +35826,28 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_6() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_6() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_7() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_UniquePtr_open0_URLParams_DefaultDelete_open1_URLParams_close1_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -35865,17 +35872,28 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_7() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_7() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_8() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_URLParams_Param_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -35942,15 +35960,15 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_imgRequestProxy_ImageURL_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_RefPtr_open0_ImageURL_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::RefPtr ) )); - assert_eq!(::std::mem::align_of::>() + root::RefPtr ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::RefPtr ) )); + root::RefPtr ) )); } #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsILoadGroup_close0_instantiation() { @@ -36030,17 +36048,28 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_8() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_8() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_9() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_nsCSSValueGradientStop_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -36085,39 +36114,72 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_9() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_9() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_10() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_10() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_10() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_11() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_11() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_11() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_12() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_nsStyleGradientStop_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -36285,18 +36347,18 @@ pub mod root { )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nscolor_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_5() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + root::nsTArray<::std::os::raw::c_uint> ) )); + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_pair_open1_nsString_nsString_close1_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0_pair_open1_nsTString_open2_char16_t_close2_nsTString_open2_char16_t_close2_close1_close0_instantiation() { assert_eq!(::std::mem::size_of::>>() , 8usize , concat ! ( @@ -36311,18 +36373,44 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_pair_open0_nsString_nsString_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_pair_open0_nsTString_open1_char16_t_close1_nsTString_open1_char16_t_close1_close0_instantiation() { + assert_eq!(::std::mem::size_of::>() , 32usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() + root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr> + ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr> ) )); + root::std::pair<::nsstring::nsStringRepr, ::nsstring::nsStringRepr> + ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsTArray_open1_nsString_close1_close0_instantiation() { + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_13() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_14() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0_nsTArray_open1_nsTString_open2_char16_t_close2_close1_close0_instantiation() { assert_eq!(::std::mem::size_of::>>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36333,17 +36421,28 @@ pub mod root { root::nsTArray> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_12() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_12() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_15() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_nsStyleCoord_close0_instantiation_1() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -36366,28 +36465,50 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_13() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_13() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_14() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_16() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_14() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_17() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_10() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -36548,7 +36669,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230765_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_246027_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36719,7 +36840,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_238095_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_249916_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36730,7 +36851,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_238100_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_249921_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36818,7 +36939,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_238213_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_250034_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36862,19 +36983,6 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsRefPtrHashKey_open0_DOMIntersectionObserver_close0_instantiation() { - assert_eq!(::std::mem::size_of::>() - , 16usize , concat ! ( - "Size of template specialization: " , stringify ! ( - root::nsRefPtrHashKey - ) )); - assert_eq!(::std::mem::align_of::>() - , 8usize , concat ! ( - "Alignment of template specialization: " , stringify ! ( - root::nsRefPtrHashKey - ) )); - } - #[test] fn __bindgen_test_layout_nsCOMPtr_open0_nsISupports_close0_instantiation_4() { assert_eq!(::std::mem::size_of::() , 8usize , concat ! ( @@ -37070,7 +37178,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_Element_close0_instantiation_4() { + fn __bindgen_test_layout_RefPtr_open0_Element_close0_instantiation_3() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37092,7 +37200,7 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_239950_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251760_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37103,7 +37211,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_Element_close0_instantiation_5() { + fn __bindgen_test_layout_RefPtr_open0_Element_close0_instantiation_4() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37114,7 +37222,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240106_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251918_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37125,7 +37233,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_240111_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251923_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37158,7 +37266,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0_unsigned_int_close0_instantiation_6() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37169,17 +37277,28 @@ pub mod root { root::nsTArray<::std::os::raw::c_uint> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_nsString_close0_instantiation_15() { - assert_eq!(::std::mem::size_of::>() , - 8usize , concat ! ( + fn __bindgen_test_layout_nsTArray_open0_nsTString_open1_char16_t_close1_close0_instantiation_15() { + assert_eq!(::std::mem::size_of::>() + , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); - assert_eq!(::std::mem::align_of::>() , - 8usize , concat ! ( + assert_eq!(::std::mem::align_of::>() + , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root::nsTArray<::nsstring::nsStringRepr> ) )); } #[test] + fn __bindgen_test_layout_nsTString_open0_char16_t_close0_instantiation_18() { + assert_eq!(::std::mem::size_of::<::nsstring::nsStringRepr>() , 16usize , + concat ! ( + "Size of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + assert_eq!(::std::mem::align_of::<::nsstring::nsStringRepr>() , 8usize , + concat ! ( + "Alignment of template specialization: " , stringify ! ( + ::nsstring::nsStringRepr ) )); + } + #[test] fn __bindgen_test_layout_UniquePtr_open0_nsStyleGridTemplate_DefaultDelete_open1_nsStyleGridTemplate_close1_close0_instantiation_2() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -37268,18 +37387,18 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0_gfxFontVariation_close0_instantiation_1() { - assert_eq!(::std::mem::size_of::>() + fn __bindgen_test_layout_nsTArray_open0_FontVariation_close0_instantiation_1() { + assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( - root::nsTArray ) )); - assert_eq!(::std::mem::align_of::>() + root::nsTArray ) )); + assert_eq!(::std::mem::align_of::>() , 8usize , concat ! ( "Alignment of template specialization: " , stringify ! ( - root::nsTArray ) )); + root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242541_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_254366_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37290,7 +37409,7 @@ pub mod root { root::nsTArray<*mut root::mozilla::css::DocumentRule> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_242547_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_254372_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs index 7fdd75f5d5fd..56a49f4743a9 100644 --- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -7,7 +7,10 @@ use cssparser::{BasicParseError, Parser, ToCss, Token, CowRcStr}; use element_state::ElementState; use gecko_bindings::structs::CSSPseudoClassType; +use gecko_bindings::structs::RawServoSelectorList; +use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use selector_parser::{SelectorParser, PseudoElementCascadeType}; +use selectors::SelectorList; use selectors::parser::{Selector, SelectorMethods, SelectorParseError}; use selectors::visitor::SelectorVisitor; use std::fmt; @@ -438,3 +441,9 @@ fn utf16_to_ascii_lowercase(unit: u16) -> u16 { _ => unit } } + +unsafe impl HasFFI for SelectorList { + type FFIType = RawServoSelectorList; +} +unsafe impl HasSimpleFFI for SelectorList {} +unsafe impl HasBoxFFI for SelectorList {} diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 1c975c5767b0..8e5751c5c895 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -43,6 +43,7 @@ use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaLi use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed}; use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed}; +use style::gecko_bindings::bindings::{RawServoSelectorListBorrowed, RawServoSelectorListOwned}; use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetOwned}; use style::gecko_bindings::bindings::{RawServoStyleSheetContentsBorrowed, ServoComputedDataBorrowed}; use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ServoStyleContextBorrowed}; @@ -91,6 +92,7 @@ use style::gecko_bindings::structs::OriginFlags_User; use style::gecko_bindings::structs::OriginFlags_UserAgent; use style::gecko_bindings::structs::RawGeckoGfxMatrix4x4; use style::gecko_bindings::structs::RawGeckoPresContextOwned; +use style::gecko_bindings::structs::RawServoSelectorList; use style::gecko_bindings::structs::SeenPtrs; use style::gecko_bindings::structs::ServoElementSnapshotTable; use style::gecko_bindings::structs::ServoStyleSetSizes; @@ -1521,8 +1523,10 @@ pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(rule: RawServoStyleRule #[no_mangle] pub unsafe extern "C" fn Servo_SelectorList_Matches( element: RawGeckoElementBorrowed, - selectors: &::selectors::SelectorList, + selectors: RawServoSelectorListBorrowed, ) -> bool { + use std::borrow::Borrow; + let element = GeckoElement(element); let mut context = MatchingContext::new( MatchingMode::Normal, @@ -1532,7 +1536,8 @@ pub unsafe extern "C" fn Servo_SelectorList_Matches( ); context.scope_element = Some(element.opaque()); - selectors::matching::matches_selector_list(selectors, &element, &mut context) + let selectors = ::selectors::SelectorList::from_ffi(selectors).borrow(); + selectors::matching::matches_selector_list(&selectors, &element, &mut context) } #[no_mangle] @@ -4113,7 +4118,7 @@ pub extern "C" fn Servo_HasPendingRestyleAncestor(element: RawGeckoElementBorrow #[no_mangle] pub unsafe extern "C" fn Servo_SelectorList_Parse( selector_list: *const nsACString, -) -> *mut ::selectors::SelectorList { +) -> *mut RawServoSelectorList { use style::selector_parser::SelectorParser; debug_assert!(!selector_list.is_null()); @@ -4124,10 +4129,10 @@ pub unsafe extern "C" fn Servo_SelectorList_Parse( Err(..) => return ptr::null_mut(), }; - Box::into_raw(Box::new(selector_list)) + Box::into_raw(Box::new(selector_list)) as *mut RawServoSelectorList } #[no_mangle] -pub unsafe extern "C" fn Servo_SelectorList_Drop(list: *mut ::selectors::SelectorList) { - let _ = Box::from_raw(list); +pub unsafe extern "C" fn Servo_SelectorList_Drop(list: RawServoSelectorListOwned) { + let _ = list.into_box::<::selectors::SelectorList>(); } From 9b69f7bcd1d4ebf3c44f05ecea56c6fd61fc026d Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Tue, 10 Oct 2017 07:57:34 +0900 Subject: [PATCH 03/68] Bug 1406811 - Fix mismatched arguments for Servo_SelectorXXX. r=emilio MozReview-Commit-ID: 7OgrwTOHTtQ --HG-- extra : rebase_source : db5affc188e3c949149658eb3bc7769649759623 --- layout/style/ServoBindingList.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index 2819ec43007a..46b9d66ba429 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -130,7 +130,7 @@ SERVO_BINDING_FUNC(Servo_StyleSet_ResolveForDeclarations, ServoStyleContextBorrowedOrNull parent_style, RawServoDeclarationBlockBorrowed declarations) SERVO_BINDING_FUNC(Servo_SelectorList_Drop, void, - RawServoSelectorList* selector_list) + RawServoSelectorListOwned selector_list) SERVO_BINDING_FUNC(Servo_SelectorList_Parse, RawServoSelectorList*, const nsACString* selector_list) From 3079b3e5d94e836042486bf47828a6d3504a69aa Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Tue, 10 Oct 2017 07:57:41 +0900 Subject: [PATCH 04/68] Bug 1406811 - Remove a duplicate entry for RawServoSelectorListBorrowed. r=emilio MozReview-Commit-ID: CN4LbkY4IcU --HG-- extra : rebase_source : 9de4bf17fdaf39edba3595d61add944551941fbf --- layout/style/ServoBindingTypes.h | 1 - 1 file changed, 1 deletion(-) diff --git a/layout/style/ServoBindingTypes.h b/layout/style/ServoBindingTypes.h index bf3e500ec5ef..ce7090d144f7 100644 --- a/layout/style/ServoBindingTypes.h +++ b/layout/style/ServoBindingTypes.h @@ -146,7 +146,6 @@ DECL_OWNED_REF_TYPE_FOR(RawServoAnimationValueMap) // it only asks Gecko to do so. In case we wish to in // the future, we should ensure that things being mutated // are protected from noalias violations by a cell type -DECL_BORROWED_REF_TYPE_FOR(RawServoSelectorList) DECL_BORROWED_REF_TYPE_FOR(RawGeckoNode) DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoNode) DECL_BORROWED_REF_TYPE_FOR(RawGeckoElement) From 61b4d3510c0b2b3f4c9e040b03642794d15ae228 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Mon, 9 Oct 2017 14:20:50 +0100 Subject: [PATCH 05/68] Bug 1399116 - browser_google_*codes.js don't need to show the search bar in their tests. Remove showing it to help avoid intermittents. r=Paolo MozReview-Commit-ID: 2ovv1ckOvwb --HG-- extra : rebase_source : 335e7d14ea5727007eb61e6d5d7ecc00e87a8aed --- browser/components/search/test/browser_google_codes.js | 6 ------ browser/components/search/test/browser_google_nocodes.js | 6 ------ 2 files changed, 12 deletions(-) diff --git a/browser/components/search/test/browser_google_codes.js b/browser/components/search/test/browser_google_codes.js index eca814dc091d..4162a533e8b1 100644 --- a/browser/components/search/test/browser_google_codes.js +++ b/browser/components/search/test/browser_google_codes.js @@ -120,12 +120,6 @@ add_task(async function tests() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); - // Show the search bar after initializing the search service, to avoid the - // synchronous initialization to interfere. - await SpecialPowers.pushPrefEnv({ set: [ - ["browser.search.widget.inNavBar", true], - ]}); - let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b"; // Keyword uses a slightly different code diff --git a/browser/components/search/test/browser_google_nocodes.js b/browser/components/search/test/browser_google_nocodes.js index c8f3a6b1ae2d..f222214ce9b6 100644 --- a/browser/components/search/test/browser_google_nocodes.js +++ b/browser/components/search/test/browser_google_nocodes.js @@ -120,12 +120,6 @@ add_task(async function tests() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); - // Show the search bar after initializing the search service, to avoid the - // synchronous initialization to interfere. - await SpecialPowers.pushPrefEnv({ set: [ - ["browser.search.widget.inNavBar", true], - ]}); - let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"; let url; From 9468ce9b2896fcfa14f3495f5a51a35460087d8c Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 9 Oct 2017 11:05:49 +0200 Subject: [PATCH 06/68] Bug 1405110 - P1. Lock device when allocating D3D11 surface. r=mattwoodrow MozReview-Commit-ID: 8qWPIj3hdZW --HG-- extra : rebase_source : 1b9104e06e8921490f73c7683fd310ba5046f7bd --- gfx/layers/D3D11YCbCrImage.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/gfx/layers/D3D11YCbCrImage.cpp b/gfx/layers/D3D11YCbCrImage.cpp index c87d7a47410e..632ace6f4c4d 100644 --- a/gfx/layers/D3D11YCbCrImage.cpp +++ b/gfx/layers/D3D11YCbCrImage.cpp @@ -289,9 +289,24 @@ D3D11YCbCrRecycleAllocator::Allocate(SurfaceFormat aFormat, 1, 1); newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; + RefPtr mt; + HRESULT hr = mDevice->QueryInterface( + (ID3D10Multithread**)getter_AddRefs(mt)); + + if (FAILED(hr) || !mt) { + gfxCriticalError() << "Multithread safety interface not supported. " << hr; + return nullptr; + } + + if (!mt->GetMultithreadProtected()) { + gfxCriticalError() << "Device used not marked as multithread-safe."; + return nullptr; + } + + D3D11MTAutoEnter mtAutoEnter(mt.forget()); + RefPtr textureY; - HRESULT hr = - mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); + hr = mDevice->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); newDesc.Width = CbCrSize.width; From 0de5aed9f71462c3948fe121939b55064a6cd871 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 9 Oct 2017 11:10:18 +0200 Subject: [PATCH 07/68] Bug 1405110 - P2. Never attempts to upload to D3D11 surface in parent process. r=mattwoodrow Accessing the graphic device driver from the parent process, should the drivers crash have serious consequences (the whole browser dies). MozReview-Commit-ID: EXXRBnDobQw --HG-- extra : rebase_source : d5609f1e088c7bbe92d6e46e66e1fb5538d5caac --- dom/media/MediaData.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp index dbd0c283dfc8..a6cb630ddec7 100644 --- a/dom/media/MediaData.cpp +++ b/dom/media/MediaData.cpp @@ -319,7 +319,8 @@ VideoData::CreateAndCopyData(const VideoInfo& aInfo, // Currently our decoder only knows how to output to ImageFormat::PLANAR_YCBCR // format. #if XP_WIN - if (aAllocator && aAllocator->GetCompositorBackendType() + if (!XRE_IsParentProcess() && + aAllocator && aAllocator->GetCompositorBackendType() == layers::LayersBackend::LAYERS_D3D11) { RefPtr d3d11Image = new layers::D3D11YCbCrImage(); PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture); From 681eaac8bed926fffa481a5c6987c52681cb8d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 10 Oct 2017 02:47:29 -0500 Subject: [PATCH 08/68] servo: Merge #18798 - style: Optimize custom properties cycle removal (from emilio:faster-custom-props); r=SimonSapin After #18791, this is the major custom_properties perf bottleneck in the testcase from bug 1405411. I'm looking into how to efficiently merge this into `substitute_all`, but meanwhile this is worth landing, and makes most of the overhead go away. Source-Repo: https://github.com/servo/servo Source-Revision: 27cb13314e5d4a0653887768c374cbc81d7f098b --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 3bfc9b547e6d4c9d5376a543af3cfbb66c505006 --- servo/components/style/custom_properties.rs | 42 ++++++++++++--------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/servo/components/style/custom_properties.rs b/servo/components/style/custom_properties.rs index 5507739a71fe..ca9e41949700 100644 --- a/servo/components/style/custom_properties.rs +++ b/servo/components/style/custom_properties.rs @@ -13,6 +13,7 @@ use properties::{CSSWideKeyword, DeclaredValue}; use selector_map::{PrecomputedHashSet, PrecomputedHashMap, PrecomputedDiagnosticHashMap}; use selectors::parser::SelectorParseError; use servo_arc::Arc; +use smallvec::SmallVec; use std::ascii::AsciiExt; use std::borrow::{Borrow, Cow}; use std::fmt; @@ -546,41 +547,48 @@ impl<'a> CustomPropertiesBuilder<'a> { fn remove_cycles(map: &mut CustomPropertiesMap) { let mut to_remove = PrecomputedHashSet::default(); { + type VisitedNamesStack<'a> = SmallVec<[&'a Name; 10]>; + let mut visited = PrecomputedHashSet::default(); - let mut stack = Vec::new(); - for name in &map.index { - walk(map, name, &mut stack, &mut visited, &mut to_remove); + let mut stack = VisitedNamesStack::new(); + for (name, value) in map.iter() { + walk(map, name, value, &mut stack, &mut visited, &mut to_remove); fn walk<'a>( map: &'a CustomPropertiesMap, name: &'a Name, - stack: &mut Vec<&'a Name>, + value: &'a Arc, + stack: &mut VisitedNamesStack<'a>, visited: &mut PrecomputedHashSet<&'a Name>, to_remove: &mut PrecomputedHashSet, ) { + if value.references.is_empty() { + return; + } + let already_visited_before = !visited.insert(name); if already_visited_before { return } - if let Some(ref value) = map.get(name) { - if !value.references.is_empty() { - stack.push(name); - for next in value.references.iter() { - if let Some(position) = stack.iter().position(|x| *x == next) { - // Found a cycle - for &in_cycle in &stack[position..] { - to_remove.insert(in_cycle.clone()); - } - } else { - walk(map, next, stack, visited, to_remove); - } + + stack.push(name); + for next in value.references.iter() { + if let Some(position) = stack.iter().position(|x| *x == next) { + // Found a cycle + for &in_cycle in &stack[position..] { + to_remove.insert(in_cycle.clone()); + } + } else { + if let Some(value) = map.get(next) { + walk(map, next, value, stack, visited, to_remove); } - stack.pop(); } } + stack.pop(); } } } + for name in to_remove { map.remove(&name); } From 1af68a0e2a10eb2be34e837ff15059b02d8c5cd2 Mon Sep 17 00:00:00 2001 From: Nihanth Subramanya Date: Tue, 10 Oct 2017 00:56:55 +0530 Subject: [PATCH 09/68] Bug 1407021 - Ensure in-content button font-size is not overridden by widget styling (e.g. in forms.css). r=johannh MozReview-Commit-ID: 2CRNOWClWmZ --HG-- extra : rebase_source : d54915c771f56dfc5635c61f626e181c3d89ffda --- toolkit/themes/shared/in-content/common.inc.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 89c5986e2c27..2d42e4aa683b 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -193,6 +193,8 @@ xul|menulist { border-radius: 2px; background-color: var(--in-content-page-background); margin: 4px 8px; + /* Ensure font-size isn't overridden by widget styling (e.g. in forms.css) */ + font-size: 1em; } xul|button, From 87b9ced2a343d3a7c2f8d6756d030fd33d86f47f Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 10 Oct 2017 11:44:38 +0200 Subject: [PATCH 10/68] Backed out 1 changesets (bug 1399116) for frequently failing modified browser_google_codes.js in test-verify. r=backout Backed out changeset 95618704ca66 (bug 1399116) --- browser/components/search/test/browser_google_codes.js | 6 ++++++ browser/components/search/test/browser_google_nocodes.js | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/browser/components/search/test/browser_google_codes.js b/browser/components/search/test/browser_google_codes.js index 4162a533e8b1..eca814dc091d 100644 --- a/browser/components/search/test/browser_google_codes.js +++ b/browser/components/search/test/browser_google_codes.js @@ -120,6 +120,12 @@ add_task(async function tests() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); + // Show the search bar after initializing the search service, to avoid the + // synchronous initialization to interfere. + await SpecialPowers.pushPrefEnv({ set: [ + ["browser.search.widget.inNavBar", true], + ]}); + let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b"; // Keyword uses a slightly different code diff --git a/browser/components/search/test/browser_google_nocodes.js b/browser/components/search/test/browser_google_nocodes.js index f222214ce9b6..c8f3a6b1ae2d 100644 --- a/browser/components/search/test/browser_google_nocodes.js +++ b/browser/components/search/test/browser_google_nocodes.js @@ -120,6 +120,12 @@ add_task(async function tests() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); + // Show the search bar after initializing the search service, to avoid the + // synchronous initialization to interfere. + await SpecialPowers.pushPrefEnv({ set: [ + ["browser.search.widget.inNavBar", true], + ]}); + let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"; let url; From 3e6be7780c83deedd7a51a891ecff88076ca9f54 Mon Sep 17 00:00:00 2001 From: Nihanth Subramanya Date: Tue, 10 Oct 2017 00:59:16 +0530 Subject: [PATCH 11/68] Bug 1403904 - Buttons in about: pages need a 2px border radius to match button styles in design system guide. r=johannh MozReview-Commit-ID: 2URqeso0MK7 --HG-- extra : rebase_source : ba2fdb3bb62056fdec22cbf6b503dc36470d6573 --- toolkit/themes/shared/in-content/info-pages.inc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/toolkit/themes/shared/in-content/info-pages.inc.css b/toolkit/themes/shared/in-content/info-pages.inc.css index ffe80f68ba95..884569ddcfec 100644 --- a/toolkit/themes/shared/in-content/info-pages.inc.css +++ b/toolkit/themes/shared/in-content/info-pages.inc.css @@ -101,7 +101,6 @@ ul.columns { button { padding: 0 1.5em; - border-radius: 0; } .button-container > button:first-child { From b6f526449ed76d4c1c533fd61ed1380c4086e8f9 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 28 Sep 2017 12:10:59 +1300 Subject: [PATCH 12/68] bug 1406831 simplify AssertOnGraphThreadOrNotRunning() r=pehrsons mLifecycleState is always > LIFECYCLE_RUNNING when mDetectedNotRunning MozReview-Commit-ID: Ds6ybTv4miA --HG-- extra : rebase_source : 71aea6693026dc919ea6d2096f55152ae12bc58e --- dom/media/MediaStreamGraph.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 3deb28e0aa7c..ee0a21b5207d 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1126,7 +1126,6 @@ MediaStreamGraph::AssertOnGraphThreadOrNotRunning() const // if all the safety checks fail, assert we own the monitor if (!graph->mDriver->OnThread()) { if (!(graph->mDetectedNotRunning && - graph->mLifecycleState > MediaStreamGraphImpl::LIFECYCLE_RUNNING && NS_IsMainThread())) { graph->mMonitor.AssertCurrentThreadOwns(); } From 4bd4041ca07bbd5004b6d6bf17821ed14474d797 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 28 Sep 2017 12:17:22 +1300 Subject: [PATCH 13/68] bug 1406831 tighten AssertOnGraphThreadOrNotRunning() to not accept graph thread after mDetectedNotRunning r=pehrsons This also permits setting mDriver to null after mDetectedNotRunning, which is useful for fixing bug 1406830. MozReview-Commit-ID: EEgAxqPQPRI --HG-- extra : rebase_source : 56e1583a0090e683e92463536637d0f1460cb727 --- dom/media/MediaStreamGraph.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index ee0a21b5207d..43091cfc3486 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1124,11 +1124,10 @@ MediaStreamGraph::AssertOnGraphThreadOrNotRunning() const MediaStreamGraphImpl const * graph = static_cast(this); // if all the safety checks fail, assert we own the monitor - if (!graph->mDriver->OnThread()) { - if (!(graph->mDetectedNotRunning && - NS_IsMainThread())) { + if (!(graph->mDetectedNotRunning ? + NS_IsMainThread() : graph->mDriver->OnThread())) + { graph->mMonitor.AssertCurrentThreadOwns(); - } } #endif } From 449d985d8e9764476a26597778a8e543005c6f52 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 28 Sep 2017 15:30:48 +1300 Subject: [PATCH 14/68] bug 1406831 don't tolerate just owning the monitor if AssertOnGraphThreadOrNotRunning() is not called on the correct thread r=pehrsons Owning the monitor is not sufficient for consistent state if state can be accessed without the monitor. The requirements for SetCurrentDriver() are tighted to require both the monitor and correct thread, as CurrentDriver() can be called either with the monitor or on the graph thread. MozReview-Commit-ID: 90q7Pfa8jxn --HG-- extra : rebase_source : 6cbcc334dc2bd355d2e9afdebda45a9624edda4b --- dom/media/MediaStreamGraph.cpp | 16 ++++++---------- dom/media/MediaStreamGraph.h | 9 ++++++++- dom/media/MediaStreamGraphImpl.h | 9 ++++++++- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 43091cfc3486..d75ac5ace38a 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1115,21 +1115,17 @@ MediaStreamGraph::NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames, } } -void -MediaStreamGraph::AssertOnGraphThreadOrNotRunning() const +bool +MediaStreamGraph::OnGraphThreadOrNotRunning() const { // either we're on the right thread (and calling CurrentDriver() is safe), - // or we're going to assert anyways, so don't cross-check CurrentDriver -#ifdef DEBUG + // or we're going to fail the assert anyway, so don't cross-check + // via CurrentDriver(). MediaStreamGraphImpl const * graph = static_cast(this); // if all the safety checks fail, assert we own the monitor - if (!(graph->mDetectedNotRunning ? - NS_IsMainThread() : graph->mDriver->OnThread())) - { - graph->mMonitor.AssertCurrentThreadOwns(); - } -#endif + return graph->mDetectedNotRunning ? + NS_IsMainThread() : graph->mDriver->OnThread(); } bool diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 0f9a0a147af3..ef081d0c6362 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -1367,7 +1367,10 @@ public: void NotifyOutputData(AudioDataValue* aBuffer, size_t aFrames, TrackRate aRate, uint32_t aChannels); - void AssertOnGraphThreadOrNotRunning() const; + void AssertOnGraphThreadOrNotRunning() const + { + MOZ_ASSERT(OnGraphThreadOrNotRunning()); + } protected: explicit MediaStreamGraph(TrackRate aSampleRate) @@ -1380,6 +1383,10 @@ protected: MOZ_COUNT_DTOR(MediaStreamGraph); } + // Intended only for assertions, either on graph thread, not running, or + // with monitor held. + bool OnGraphThreadOrNotRunning() const; + // Media graph thread only nsTArray > mPendingUpdateRunnables; diff --git a/dom/media/MediaStreamGraphImpl.h b/dom/media/MediaStreamGraphImpl.h index d1ac3742d6ee..1cd0b76e1be3 100644 --- a/dom/media/MediaStreamGraphImpl.h +++ b/dom/media/MediaStreamGraphImpl.h @@ -456,7 +456,11 @@ public: */ GraphDriver* CurrentDriver() const { - AssertOnGraphThreadOrNotRunning(); +#ifdef DEBUG + if (!OnGraphThreadOrNotRunning()) { + mMonitor.AssertCurrentThreadOwns(); + } +#endif return mDriver; } @@ -475,7 +479,10 @@ public: */ void SetCurrentDriver(GraphDriver* aDriver) { +#ifdef DEBUG + mMonitor.AssertCurrentThreadOwns(); AssertOnGraphThreadOrNotRunning(); +#endif mDriver = aDriver; } From dfac1cc60d4e0aff38676bcb34c03a139d4c8c28 Mon Sep 17 00:00:00 2001 From: Christian Holler Date: Sat, 7 Oct 2017 17:59:37 +0200 Subject: [PATCH 15/68] Bug 1403668 - Use SA_ONSTACK for several SIGSEGV handlers. r=ted MozReview-Commit-ID: IwVYiBF3Ek8 --HG-- extra : rebase_source : 3bbcdee6042aa9e159432c8d0df6f922dba002f1 --- js/src/ds/MemoryProtectionExceptionHandler.cpp | 2 +- js/src/wasm/WasmSignalHandlers.cpp | 4 ++-- toolkit/profile/nsProfileLock.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/src/ds/MemoryProtectionExceptionHandler.cpp b/js/src/ds/MemoryProtectionExceptionHandler.cpp index 52fe3004db18..066b43929146 100644 --- a/js/src/ds/MemoryProtectionExceptionHandler.cpp +++ b/js/src/ds/MemoryProtectionExceptionHandler.cpp @@ -282,7 +282,7 @@ MemoryProtectionExceptionHandler::install() // Install our new exception handler and save the previous one. struct sigaction faultHandler = {}; - faultHandler.sa_flags = SA_SIGINFO | SA_NODEFER; + faultHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK; faultHandler.sa_sigaction = UnixExceptionHandler; sigemptyset(&faultHandler.sa_mask); sExceptionHandlerInstalled = !sigaction(SIGSEGV, &faultHandler, &sPrevSEGVHandler); diff --git a/js/src/wasm/WasmSignalHandlers.cpp b/js/src/wasm/WasmSignalHandlers.cpp index 7067fd990ca1..55b4c9299037 100644 --- a/js/src/wasm/WasmSignalHandlers.cpp +++ b/js/src/wasm/WasmSignalHandlers.cpp @@ -1617,7 +1617,7 @@ ProcessHasSignalHandlers() // Allow handling OOB with signals on all architectures struct sigaction faultHandler; - faultHandler.sa_flags = SA_SIGINFO | SA_NODEFER; + faultHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK; faultHandler.sa_sigaction = WasmFaultHandler; sigemptyset(&faultHandler.sa_mask); if (sigaction(SIGSEGV, &faultHandler, &sPrevSEGVHandler)) @@ -1626,7 +1626,7 @@ ProcessHasSignalHandlers() # if defined(JS_CODEGEN_ARM) // On Arm Handle Unaligned Accesses struct sigaction busHandler; - busHandler.sa_flags = SA_SIGINFO | SA_NODEFER; + busHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK; busHandler.sa_sigaction = WasmFaultHandler; sigemptyset(&busHandler.sa_mask); if (sigaction(SIGBUS, &busHandler, &sPrevSIGBUSHandler)) diff --git a/toolkit/profile/nsProfileLock.cpp b/toolkit/profile/nsProfileLock.cpp index ed5e38064cd1..690c0551c211 100644 --- a/toolkit/profile/nsProfileLock.cpp +++ b/toolkit/profile/nsProfileLock.cpp @@ -374,7 +374,7 @@ nsresult nsProfileLock::LockWithSymlink(nsIFile *aLockFile, bool aHaveFcntlLock) struct sigaction act, oldact; #ifdef SA_SIGINFO act.sa_sigaction = FatalSignalHandler; - act.sa_flags = SA_SIGINFO; + act.sa_flags = SA_SIGINFO | SA_ONSTACK; #else act.sa_handler = FatalSignalHandler; #endif From e61621baf8dada40b046751018fce3ee568ed8dd Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Tue, 10 Oct 2017 12:50:22 +0200 Subject: [PATCH 16/68] Bug 1399116 - browser_google_*codes.js don't need to show the search bar in their tests. Remove showing it to help avoid intermittents. r=Paolo --- browser/components/search/test/browser_google_codes.js | 6 ------ browser/components/search/test/browser_google_nocodes.js | 6 ------ 2 files changed, 12 deletions(-) diff --git a/browser/components/search/test/browser_google_codes.js b/browser/components/search/test/browser_google_codes.js index eca814dc091d..4162a533e8b1 100644 --- a/browser/components/search/test/browser_google_codes.js +++ b/browser/components/search/test/browser_google_codes.js @@ -120,12 +120,6 @@ add_task(async function tests() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); - // Show the search bar after initializing the search service, to avoid the - // synchronous initialization to interfere. - await SpecialPowers.pushPrefEnv({ set: [ - ["browser.search.widget.inNavBar", true], - ]}); - let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b"; // Keyword uses a slightly different code diff --git a/browser/components/search/test/browser_google_nocodes.js b/browser/components/search/test/browser_google_nocodes.js index c8f3a6b1ae2d..f222214ce9b6 100644 --- a/browser/components/search/test/browser_google_nocodes.js +++ b/browser/components/search/test/browser_google_nocodes.js @@ -120,12 +120,6 @@ add_task(async function tests() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); - // Show the search bar after initializing the search service, to avoid the - // synchronous initialization to interfere. - await SpecialPowers.pushPrefEnv({ set: [ - ["browser.search.widget.inNavBar", true], - ]}); - let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"; let url; From ef74dc495c9e103559374b66c00c0d39a2a14569 Mon Sep 17 00:00:00 2001 From: Mike de Boer Date: Tue, 10 Oct 2017 12:44:04 +0200 Subject: [PATCH 17/68] Bug 1403466 - Don't set a max-height on panelviews used by WebExtensions, because it causes browser contents to be cut-off. r=Gijs Setting a max-height caused the '_handleDOMChange' method in ext-browser-content.js to consistently lie about the scrollHeight, since it was never allowed to grow beyond the maxHeight - even when the document needs to be larger to fit its contents. We don't need this aggressiveness in Photon panels anyway, so that makes it doubly safe to remove this code. MozReview-Commit-ID: HJVMXXHS4By --HG-- extra : rebase_source : 19cc957619afdd90d04fea0307b6323b33293841 --- browser/components/extensions/ExtensionPopups.jsm | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/browser/components/extensions/ExtensionPopups.jsm b/browser/components/extensions/ExtensionPopups.jsm index 5ac4f43943f1..cc02e48b32dd 100644 --- a/browser/components/extensions/ExtensionPopups.jsm +++ b/browser/components/extensions/ExtensionPopups.jsm @@ -123,7 +123,6 @@ class BasePopup { if (this.viewNode) { this.viewNode.removeEventListener(this.DESTROY_EVENT, this); - this.viewNode.style.maxHeight = ""; delete this.viewNode.customRectGetter; } @@ -331,16 +330,9 @@ class BasePopup { height = Math.min(height, maxHeight); this.browser.style.height = `${height}px`; - // Set a maximum height on the element to our preferred - // maximum height, so that the PanelUI resizing code can make an accurate - // calculation. If we don't do this, the flex sizing logic will prevent us - // from ever reporting a preferred size smaller than the height currently - // available to us in the panel. - height = Math.max(height, this.viewHeight); - this.viewNode.style.maxHeight = `${height}px`; // Used by the panelmultiview code to figure out sizing without reparenting // (which would destroy the browser and break us). - this.lastCalculatedInViewHeight = height; + this.lastCalculatedInViewHeight = Math.max(height, this.viewHeight); } else { this.browser.style.width = `${width}px`; this.browser.style.minWidth = `${width}px`; From f1daedfa9253b5615a04a3d1086b9968e21cdd31 Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Tue, 10 Oct 2017 09:13:19 +0100 Subject: [PATCH 18/68] Bug 1407164 - Fix strict warnings in Bookmarks.jsm relating to undefined property source - don't delete item properties too soon. r=mak MozReview-Commit-ID: AJJRSHYqPch --HG-- extra : rebase_source : bb2d043215be9e2493ddd5dff452999dd95d1db2 --- toolkit/components/places/Bookmarks.jsm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toolkit/components/places/Bookmarks.jsm b/toolkit/components/places/Bookmarks.jsm index 92bdcf38ceac..4f67f5e6f031 100644 --- a/toolkit/components/places/Bookmarks.jsm +++ b/toolkit/components/places/Bookmarks.jsm @@ -478,14 +478,14 @@ var Bookmarks = Object.freeze({ PlacesUtils.toPRTime(item.dateAdded), item.guid, item.parentGuid, item.source ], { isTagging: false }); - // Remove non-enumerable properties. - delete item.source; - // Note, annotations for livemark data are deleted from insertInfo // within appendInsertionInfoForInfoArray, so we won't be duplicating // the insertions here. await handleBookmarkItemSpecialData(itemId, item); + // Remove non-enumerable properties. + delete item.source; + insertInfos[i] = Object.assign({}, item); } return insertInfos; @@ -1548,7 +1548,7 @@ async function handleBookmarkItemSpecialData(itemId, item) { } if ("tags" in item) { try { - PlacesUtils.tagging.tagURI(NetUtil.newURI(item.url), item.tags, item._source); + PlacesUtils.tagging.tagURI(NetUtil.newURI(item.url), item.tags, item.source); } catch (ex) { // Invalid tag child, skip it. Cu.reportError(`Unable to set tags "${item.tags.join(", ")}" for ${item.url}: ${ex}`); From f9e18f3217f2cec04597a6110edefe287bfb7771 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Mon, 9 Oct 2017 17:56:11 +0100 Subject: [PATCH 19/68] Bug 1406965 - Add docs on enabling trace logs. r=automatedtester DONTBUILD MozReview-Commit-ID: L2uZuPjA2ig --HG-- extra : rebase_source : 4d1099d2999f619ceea7b96d58d3ec0731d978e5 --- testing/geckodriver/doc/TraceLogs.md | 159 +++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 testing/geckodriver/doc/TraceLogs.md diff --git a/testing/geckodriver/doc/TraceLogs.md b/testing/geckodriver/doc/TraceLogs.md new file mode 100644 index 000000000000..ca921448e337 --- /dev/null +++ b/testing/geckodriver/doc/TraceLogs.md @@ -0,0 +1,159 @@ +Enabling trace logs +=================== + +geckodriver provides different bands of logs for different audiences. +The most important log entries are shown to everyone by default, +and these include which port geckodriver provides the WebDriver +API on, as well as informative warnings, errors, and fatal exceptions. + +The different log bands are, in ascending bandwidth: + +1. `fatal` is reserved for exceptional circumstances when geckodriver + or Firefox cannot recover. This usually entails that either + one or both of the processes will exit. + +2. `error` messages are mistakes in the program code which it is + possible to recover from. + +3. `warn` shows warnings of more informative nature that are not + necessarily problems in geckodriver. This could for example happen + if you use the legacy `desiredCapabilities`/`requiredCapabilities` + objects instead of the new `alwaysMatch`/`firstMatch` structures. + +4. `info` (default) contains information about which port geckodriver + binds to, but also all messages from the lower-bandwidth levels + listed above. + +5. `config` additionally shows the negotiated capabilities after + matching the `alwaysMatch` capabilities with the sequence of + `firstMatch` capabilities. + +6. `debug` is reserved for information that is useful when programming. + +7. `trace`, where in addition to itself, all previous levels + are included. The trace level shows all HTTP requests received + by geckodriver, packets sent to and from the remote protocol in + Firefox, and responses sent back to your client. + +In other words this means that the configured level will coalesce +entries from all lower bands including itself. If you set the log +level to `error`, you will get log entries for both `fatal` and `error`. +Similarly for `trace`, you will get all the logs that are offered. + +To help debug a problem with geckodriver or Firefox, the trace-level +output is vital to understand what is going on. This is why we ask +that trace logs are included when filing bugs gainst geckodriver. +It is only under very special circumstances that a trace log is +not needed, so you will normally find that our first action when +triaging your issue will be to ask you to include one. Do yourself +and us a favour and provide a trace-level log right away. + +To silence geckodriver altogether you may for example either redirect +all output to append to some log files: + + % geckodriver >>geckodriver.log 2>>geckodriver.err.log + +Or a black hole somewhere: + + % geckodriver >/dev/null 2>&1 + +The log level set for geckodriver is propagated to the Marionette +logger in Firefox. Marionette is the remote protocol that geckodriver +uses to implement WebDriver. This means enabling trace logs for +geckodriver will also implicitly enable them for Marionette. + +The log level is set in different ways. Either by using the +`--log ` option, where `LEVEL` is one of the log levels +from the list above, or by using the `-v` (for debug) or `-vv` +(for trace) shorthands. For example, the following command will +enable trace logs for both geckodriver and Marionette: + + % geckodriver -vv + +The second way of setting the log level is through capabilities. +geckodriver accepts a Mozila-specific configuration object +in [`moz:firefoxOptions`]. This JSON Object, which is further +described in the [README] can hold Firefox-specific configuration, +such as which Firefox binary to use, additional preferences to set, +and of course which log level to use. + +[`moz:firefoxOptions`]: ../README.md#firefox-capabilities +[README]: ../README.md + +Each client has its own way of specifying capabilities, and some clients +include “helpers” for providing browser-specific configuration. +It is often advisable to use these helpers instead of encoding the +JSON Object yourself because it can be difficult to get the exact +details right, but if you choose to, it should look like this: + + {"moz:firefoxOptions": {"log": {"level": "trace"}}} + +Note that most known WebDriver clients, such as those provided by +the Selenium project, do not expose a way to actually _see_ the logs +unless you redirect the log output to a particular file (using the +method shown above) or let the client “inherit” geckodriver’s +output, for example by redirecting the stdout and stderr streams to +its own. The notable exceptions are the Python and Ruby bindings, +which surface geckodriver logs in a remarkable easy and efficient way. + +See the client-specific documentation below for the most idiomatic +way to enable trace logs in your language. We want to expand this +documentation to cover all the best known clients people use with +geckodriver. If you find your language missing, please consider +[submitting a patch]. + +[submitting a patch]: ../CONTRIBUTING.md + + +Python +------ + +The Selenium [Python client] comes with an +[`selenium.webdriver.firefox.options.Options`] helper that can +be used programmatically to construct the [`moz:firefoxOptions`] +capabilities object: + + from selenium.webdriver import Firefox + from selenium.webdriver.firefox.options import Options + + opts = Options() + opts.log.level = "trace" + driver = Firefox(firefox_options=opts) + +The log output is stored in a file called _geckodriver.log_ in your +script’s current working directory. + +[Python client]: https://selenium-python.readthedocs.io/ +[`selenium.webdriver.firefox.options.Options`]: https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/firefox/options.py + + +Ruby +---- + +The Selenium [Ruby client] comes with an [`Options`] helper to +generate the correct [`moz:firefoxOptions`] capabilities object: + + opts = Selenium::WebDriver::Firefox::Options.new(log_level: :trace) + driver = Selenium::WebDriver.for :firefox, options: opts + +To show the logs, set the `DEBUG=1` output variable or start your +Ruby interpreter with the `-d` flag. + +[Ruby client]: http://seleniumhq.github.io/selenium/docs/api/rb/ +[`Options`]: http://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/Firefox/Options.html + + +Java +---- + +The Selenium [Java client] also comes with +a [`org.openqa.selenium.firefox.FirefoxOptions`] helper for +constructing the [`moz:firefoxOptions`] capabilities object: + + FirefoxOptions opts = new FirefoxOptions().setLogLevel(Level.ALL); + WebDriver driver = new FirefoxDriver(opts); + +The log output is helpfully propagated to stdout. + +[Java client]: https://seleniumhq.github.io/selenium/docs/api/java/ +[`org.openqa.selenium.firefox.FirefoxOptions`]: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/firefox/FirefoxOptions.html From 4c2629b20025816fc10dc2368b99edd96b02f7f4 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Mon, 9 Oct 2017 19:05:59 +0100 Subject: [PATCH 20/68] Bug 1407000 - Fix error for string WebDriver capabilities. r=automatedtester MozReview-Commit-ID: I4Il8CoUBiz --HG-- extra : rebase_source : 8c128eb9b5a9a4130816eed4227ff39b6566e2d2 --- testing/webdriver/src/capabilities.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/webdriver/src/capabilities.rs b/testing/webdriver/src/capabilities.rs index 8196911ccaf0..2708a2e99e99 100644 --- a/testing/webdriver/src/capabilities.rs +++ b/testing/webdriver/src/capabilities.rs @@ -93,7 +93,7 @@ impl SpecNewSessionParameters { x @ "browserVersion" | x @ "platformName" => if !value.is_string() { return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - format!("{} was not a boolean", x))) + format!("{} is not a string", x))) }, "pageLoadStrategy" => { try!(SpecNewSessionParameters::validate_page_load_strategy(value)) From 6034b21f9620ac57def56828424e87c7ba53344a Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Mon, 9 Oct 2017 19:08:46 +0100 Subject: [PATCH 21/68] Bug 1407000 - Prefer error messages in the present. r=automatedtester s/was/is/ in various error messages for harmony. MozReview-Commit-ID: IrRw4Vl8bIK --HG-- extra : rebase_source : 2e4a26077733fc4a182dca0feedd14291675d6ad --- testing/webdriver/src/capabilities.rs | 44 +++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/testing/webdriver/src/capabilities.rs b/testing/webdriver/src/capabilities.rs index 2708a2e99e99..6a5fb3ad14fd 100644 --- a/testing/webdriver/src/capabilities.rs +++ b/testing/webdriver/src/capabilities.rs @@ -87,7 +87,7 @@ impl SpecNewSessionParameters { match &**key { "acceptInsecureCerts" => if !value.is_boolean() { return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - "acceptInsecureCerts was not a boolean")) + "acceptInsecureCerts is not a boolean")) }, x @ "browserName" | x @ "browserVersion" | @@ -110,7 +110,7 @@ impl SpecNewSessionParameters { x => { if !x.contains(":") { return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - format!("{} was not a the name of a known capability or a valid extension capability", x))) + format!("{} is not a the name of a known capability or a valid extension capability", x))) } else { try!(browser_capabilities.validate_custom(x, value)); } @@ -135,7 +135,7 @@ impl SpecNewSessionParameters { } } _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - "pageLoadStrategy was not a string")) + "pageLoadStrategy is not a string")) } Ok(()) } @@ -143,7 +143,7 @@ impl SpecNewSessionParameters { fn validate_proxy(proxy_value: &Json) -> WebDriverResult<()> { let obj = try_opt!(proxy_value.as_object(), ErrorStatus::InvalidArgument, - "proxy was not an object"); + "proxy is not an object"); for (key, value) in obj.iter() { match &**key { "proxyType" => match value.as_string() { @@ -154,20 +154,20 @@ impl SpecNewSessionParameters { Some("manual") => {}, Some(x) => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - format!("{} was not a valid proxyType value", x))), + format!("{} is not a valid proxyType value", x))), None => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - "proxyType value was not a string")), + "proxyType value is not a string")), }, "proxyAutoconfigUrl" => match value.as_string() { Some(x) => { try!(Url::parse(x).or(Err(WebDriverError::new( ErrorStatus::InvalidArgument, - "proxyAutoconfigUrl was not a valid url")))); + "proxyAutoconfigUrl is not a valid url")))); }, None => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - "proxyAutoconfigUrl was not a string" + "proxyAutoconfigUrl is not a string" )) }, "ftpProxy" => try!(SpecNewSessionParameters::validate_host(value)), @@ -177,11 +177,11 @@ impl SpecNewSessionParameters { "socksProxy" => try!(SpecNewSessionParameters::validate_host(value)), "socksVersion" => if !value.is_number() { return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - "socksVersion was not a number")) + "socksVersion is not a number")) }, x => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - format!("{} was not a valid proxy configuration capability", x))) + format!("{} is not a valid proxy configuration capability", x))) } } Ok(()) @@ -195,14 +195,14 @@ impl SpecNewSessionParameters { Some(_) => {}, None => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - format!("{} was not a string", host) + format!("{} is not a string", host) )) } } }, None => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - format!("{} was not an array", value) + format!("{} is not an array", value) )) } @@ -233,12 +233,12 @@ impl SpecNewSessionParameters { url.fragment() != None { return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - format!("{} was not of the form host[:port]", host))); + format!("{} is not of the form host[:port]", host))); } }, None => return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - format!("{} was not a string", value) + format!("{} is not a string", value) )) } Ok(()) @@ -247,7 +247,7 @@ impl SpecNewSessionParameters { fn validate_timeouts(value: &Json) -> WebDriverResult<()> { let obj = try_opt!(value.as_object(), ErrorStatus::InvalidArgument, - "timeouts capability was not an object"); + "timeouts capability is not an object"); for (key, value) in obj.iter() { match &**key { x @ "script" | @@ -255,14 +255,14 @@ impl SpecNewSessionParameters { x @ "implicit" => { let timeout = try_opt!(value.as_i64(), ErrorStatus::InvalidArgument, - format!("{} timeouts value was not an integer", x)); + format!("{} timeouts value is not an integer", x)); if timeout < 0 { return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - format!("{} timeouts value was negative", x))) + format!("{} timeouts value is negative", x))) } }, x => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - format!("{} was not a valid timeouts capability", x))) + format!("{} is not a valid timeouts capability", x))) } } Ok(()) @@ -271,12 +271,12 @@ impl SpecNewSessionParameters { fn validate_unhandled_prompt_behaviour(value: &Json) -> WebDriverResult<()> { let behaviour = try_opt!(value.as_string(), ErrorStatus::InvalidArgument, - "unhandledPromptBehavior capability was not a string"); + "unhandledPromptBehavior capability is not a string"); match behaviour { "dismiss" | "accept" => {}, x => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, - format!("{} was not a valid unhandledPromptBehavior value", x))) } + format!("{} is not a valid unhandledPromptBehavior value", x))) } Ok(()) } } @@ -285,7 +285,7 @@ impl Parameters for SpecNewSessionParameters { fn from_json(body: &Json) -> WebDriverResult { let data = try_opt!(body.as_object(), ErrorStatus::UnknownError, - "Message body was not an object"); + "Message body is not an object"); let capabilities = try_opt!( try_opt!(data.get("capabilities"), @@ -471,7 +471,7 @@ impl Parameters for LegacyNewSessionParameters { fn from_json(body: &Json) -> WebDriverResult { let data = try_opt!(body.as_object(), ErrorStatus::UnknownError, - "Message body was not an object"); + "Message body is not an object"); let desired_capabilities = if let Some(capabilities) = data.get("desiredCapabilities") { From cc5abdb455665daa6375d5e426d18b13bcd7ecda Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Mon, 9 Oct 2017 19:11:31 +0100 Subject: [PATCH 22/68] Bug 1407000 - Lint match_browser. r=automatedtester No functional changes here, but the indentation was wrong in many places, making it very hard to read the code. MozReview-Commit-ID: Iku7yPD30QV --HG-- extra : rebase_source : 31aa77135ca7f89eab60335b5bb968c4d6f1294a --- testing/webdriver/src/capabilities.rs | 68 +++++++++++++++------------ 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/testing/webdriver/src/capabilities.rs b/testing/webdriver/src/capabilities.rs index 6a5fb3ad14fd..395489761a98 100644 --- a/testing/webdriver/src/capabilities.rs +++ b/testing/webdriver/src/capabilities.rs @@ -333,8 +333,10 @@ impl ToJson for SpecNewSessionParameters { } impl CapabilitiesMatching for SpecNewSessionParameters { - fn match_browser(&self, browser_capabilities: &mut T) - -> WebDriverResult> { + fn match_browser( + &self, + browser_capabilities: &mut T, + ) -> WebDriverResult> { let default = vec![BTreeMap::new()]; let capabilities_list = if self.firstMatch.len() > 0 { &self.firstMatch @@ -342,22 +344,26 @@ impl CapabilitiesMatching for SpecNewSessionParameters { &default }; - let merged_capabilities = try!(capabilities_list + let merged_capabilities = capabilities_list .iter() .map(|first_match_entry| { - if first_match_entry.keys().any(|k| { - self.alwaysMatch.contains_key(k) - }) { + if first_match_entry.keys().any( + |k| self.alwaysMatch.contains_key(k), + ) + { return Err(WebDriverError::new( ErrorStatus::InvalidArgument, - "'firstMatch' key shadowed a value in 'alwaysMatch'")); + "'firstMatch' key shadowed a value in 'alwaysMatch'", + )); } let mut merged = self.alwaysMatch.clone(); merged.append(&mut first_match_entry.clone()); Ok(merged) }) - .map(|merged| merged.and_then(|x| self.validate(x, browser_capabilities))) - .collect::>>()); + .map(|merged| { + merged.and_then(|x| self.validate(x, browser_capabilities)) + }) + .collect::>>()?; let selected = merged_capabilities .iter() @@ -373,9 +379,9 @@ impl CapabilitiesMatching for SpecNewSessionParameters { .and_then(|x| x); if value.as_string() != browserValue.as_ref().map(|x| &**x) { - return None; + return None; } - }, + } "browserVersion" => { let browserValue = browser_capabilities .browser_version(merged) @@ -386,13 +392,14 @@ impl CapabilitiesMatching for SpecNewSessionParameters { if let Some(version) = browserValue { if !browser_capabilities .compare_browser_version(&*version, version_cond) - .unwrap_or(false) { - return None; - } + .unwrap_or(false) + { + return None; + } } else { - return None + return None; } - }, + } "platformName" => { let browserValue = browser_capabilities .platform_name(merged) @@ -405,27 +412,30 @@ impl CapabilitiesMatching for SpecNewSessionParameters { "acceptInsecureCerts" => { if value.as_boolean().unwrap_or(false) && !browser_capabilities - .accept_insecure_certs(merged) - .unwrap_or(false) { + .accept_insecure_certs(merged) + .unwrap_or(false) + { return None; } - }, + } "proxy" => { let default = BTreeMap::new(); let proxy = value.as_object().unwrap_or(&default); - if !browser_capabilities.accept_proxy(&proxy, - merged) - .unwrap_or(false) { - return None + if !browser_capabilities + .accept_proxy(&proxy, merged) + .unwrap_or(false) + { + return None; } - }, + } name => { if name.contains(":") { if !browser_capabilities .accept_custom(name, value, merged) - .unwrap_or(false) { - return None - } + .unwrap_or(false) + { + return None; + } } else { // Accept the capability } @@ -433,11 +443,11 @@ impl CapabilitiesMatching for SpecNewSessionParameters { } } - return Some(merged) + return Some(merged); }) .next() .map(|x| x.clone()); - Ok(selected) + Ok(selected) } } From 3e7151b4363efeaa7fb7e520da70d83702d2e5a4 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Tue, 10 Oct 2017 04:34:47 -0500 Subject: [PATCH 23/68] servo: Merge #18738 - Use atom for animation name property (from hiikezoe:use-atom-for-animation-name-property); r=xidorn https://bugzilla.mozilla.org/show_bug.cgi?id=1329169 --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors Source-Repo: https://github.com/servo/servo Source-Revision: 55a7fd75b4c081a92ebdac932afbc9b19b91e87c --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 26a2cb5dd281aa36cf1f1fe4ae87743c870eb90c --- .../style/gecko/generated/bindings.rs | 18 ++- .../style/gecko/generated/structs.rs | 109 ++++++++++-------- .../components/style/properties/gecko.mako.rs | 31 ++--- servo/components/style/values/mod.rs | 11 ++ servo/ports/geckolib/glue.rs | 4 +- 5 files changed, 100 insertions(+), 73 deletions(-) diff --git a/servo/components/style/gecko/generated/bindings.rs b/servo/components/style/gecko/generated/bindings.rs index 57f08684e8f5..2dd2506136be 100644 --- a/servo/components/style/gecko/generated/bindings.rs +++ b/servo/components/style/gecko/generated/bindings.rs @@ -235,6 +235,7 @@ use gecko_bindings::structs::UpdateAnimationsTasks; use gecko_bindings::structs::ParsingMode; use gecko_bindings::structs::InheritTarget; use gecko_bindings::structs::URLMatchingFunction; +use gecko_bindings::structs::StyleAnimation; use gecko_bindings::structs::StyleRuleInclusion; use gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator; unsafe impl Send for nsStyleTransformMatrix::MatrixTransformOperator {} @@ -281,8 +282,6 @@ pub type RawServoDeclarationBlockStrongBorrowed<'a> = &'a RawServoDeclarationBlo pub type RawServoDeclarationBlockStrongBorrowedOrNull<'a> = Option<&'a RawServoDeclarationBlockStrong>; pub type RawGeckoPresContextBorrowed<'a> = &'a RawGeckoPresContext; pub type RawGeckoPresContextBorrowedOrNull<'a> = Option<&'a RawGeckoPresContext>; -pub type RawGeckoStyleAnimationListBorrowed<'a> = &'a RawGeckoStyleAnimationList; -pub type RawGeckoStyleAnimationListBorrowedOrNull<'a> = Option<&'a RawGeckoStyleAnimationList>; pub type RawGeckoXBLBindingBorrowed<'a> = &'a RawGeckoXBLBinding; pub type RawGeckoXBLBindingBorrowedOrNull<'a> = Option<&'a RawGeckoXBLBinding>; pub type nsCSSPropertyIDSetBorrowed<'a> = &'a nsCSSPropertyIDSet; @@ -333,6 +332,10 @@ pub type RawGeckoServoAnimationValueListBorrowed<'a> = &'a RawGeckoServoAnimatio pub type RawGeckoServoAnimationValueListBorrowedOrNull<'a> = Option<&'a RawGeckoServoAnimationValueList>; pub type RawGeckoServoAnimationValueListBorrowedMut<'a> = &'a mut RawGeckoServoAnimationValueList; pub type RawGeckoServoAnimationValueListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoServoAnimationValueList>; +pub type RawGeckoStyleAnimationListBorrowed<'a> = &'a RawGeckoStyleAnimationList; +pub type RawGeckoStyleAnimationListBorrowedOrNull<'a> = Option<&'a RawGeckoStyleAnimationList>; +pub type RawGeckoStyleAnimationListBorrowedMut<'a> = &'a mut RawGeckoStyleAnimationList; +pub type RawGeckoStyleAnimationListBorrowedMutOrNull<'a> = Option<&'a mut RawGeckoStyleAnimationList>; pub type RawGeckoStyleChildrenIteratorBorrowed<'a> = &'a RawGeckoStyleChildrenIterator; pub type RawGeckoStyleChildrenIteratorBorrowedOrNull<'a> = Option<&'a RawGeckoStyleChildrenIterator>; pub type RawGeckoStyleChildrenIteratorBorrowedMut<'a> = &'a mut RawGeckoStyleChildrenIterator; @@ -788,6 +791,15 @@ extern "C" { RawGeckoStyleAnimationListBorrowed) -> bool; } +extern "C" { + pub fn Gecko_CopyAnimationNames(aDest: + RawGeckoStyleAnimationListBorrowedMut, + aSrc: RawGeckoStyleAnimationListBorrowed); +} +extern "C" { + pub fn Gecko_SetAnimationName(aStyleAnimation: *mut StyleAnimation, + aAtom: *mut nsAtom); +} extern "C" { pub fn Gecko_UpdateAnimations(aElementOrPseudo: RawGeckoElementBorrowed, aOldComputedValues: @@ -2066,7 +2078,7 @@ extern "C" { } extern "C" { pub fn Servo_StyleSet_GetKeyframesForName(set: RawServoStyleSetBorrowed, - property: *const nsACString, + name: *mut nsAtom, timing_function: nsTimingFunctionBorrowed, keyframe_list: diff --git a/servo/components/style/gecko/generated/structs.rs b/servo/components/style/gecko/generated/structs.rs index 69253f300a61..4d0c256f69d5 100644 --- a/servo/components/style/gecko/generated/structs.rs +++ b/servo/components/style/gecko/generated/structs.rs @@ -4517,7 +4517,7 @@ pub mod root { } #[test] fn bindgen_test_layout_GeckoDisplay() { - assert_eq!(::std::mem::size_of::() , 424usize , + assert_eq!(::std::mem::size_of::() , 416usize , concat ! ( "Size of: " , stringify ! ( GeckoDisplay ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -6229,7 +6229,7 @@ pub mod root { pub mTimingFunction: root::nsTimingFunction, pub mDuration: f32, pub mDelay: f32, - pub mName: ::nsstring::nsStringRepr, + pub mName: root::RefPtr, pub mDirection: root::mozilla::dom::PlaybackDirection, pub mFillMode: root::mozilla::dom::FillMode, pub mPlayState: u8, @@ -6237,7 +6237,7 @@ pub mod root { } #[test] fn bindgen_test_layout_StyleAnimation() { - assert_eq!(::std::mem::size_of::() , 56usize , + assert_eq!(::std::mem::size_of::() , 48usize , concat ! ( "Size of: " , stringify ! ( StyleAnimation ) )); assert_eq! (::std::mem::align_of::() , 8usize , @@ -6266,22 +6266,22 @@ pub mod root { ) , "::" , stringify ! ( mName ) )); assert_eq! (unsafe { & ( * ( 0 as * const StyleAnimation ) ) . mDirection - as * const _ as usize } , 48usize , concat ! ( + as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( StyleAnimation ) , "::" , stringify ! ( mDirection ) )); assert_eq! (unsafe { & ( * ( 0 as * const StyleAnimation ) ) . mFillMode as - * const _ as usize } , 49usize , concat ! ( + * const _ as usize } , 41usize , concat ! ( "Alignment of field: " , stringify ! ( StyleAnimation ) , "::" , stringify ! ( mFillMode ) )); assert_eq! (unsafe { & ( * ( 0 as * const StyleAnimation ) ) . mPlayState - as * const _ as usize } , 50usize , concat ! ( + as * const _ as usize } , 42usize , concat ! ( "Alignment of field: " , stringify ! ( StyleAnimation ) , "::" , stringify ! ( mPlayState ) )); assert_eq! (unsafe { & ( * ( 0 as * const StyleAnimation ) ) . - mIterationCount as * const _ as usize } , 52usize , + mIterationCount as * const _ as usize } , 44usize , concat ! ( "Alignment of field: " , stringify ! ( StyleAnimation ) , "::" , stringify ! ( mIterationCount ) )); @@ -13511,7 +13511,7 @@ pub mod root { pub const nsStyleDisplay_kHasFinishStyle: bool = false; #[test] fn bindgen_test_layout_nsStyleDisplay() { - assert_eq!(::std::mem::size_of::() , 424usize , concat + assert_eq!(::std::mem::size_of::() , 416usize , concat ! ( "Size of: " , stringify ! ( nsStyleDisplay ) )); assert_eq! (::std::mem::align_of::() , 8usize , concat ! ( "Alignment of " , stringify ! ( nsStyleDisplay ) )); @@ -13746,54 +13746,54 @@ pub mod root { assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . mAnimationTimingFunctionCount as * const _ as usize } , - 368usize , concat ! ( + 360usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationTimingFunctionCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . - mAnimationDurationCount as * const _ as usize } , 372usize + mAnimationDurationCount as * const _ as usize } , 364usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationDurationCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . - mAnimationDelayCount as * const _ as usize } , 376usize , + mAnimationDelayCount as * const _ as usize } , 368usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationDelayCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . - mAnimationNameCount as * const _ as usize } , 380usize , + mAnimationNameCount as * const _ as usize } , 372usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationNameCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . mAnimationDirectionCount as * const _ as usize } , - 384usize , concat ! ( + 376usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationDirectionCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . - mAnimationFillModeCount as * const _ as usize } , 388usize + mAnimationFillModeCount as * const _ as usize } , 380usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationFillModeCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . mAnimationPlayStateCount as * const _ as usize } , - 392usize , concat ! ( + 384usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationPlayStateCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . mAnimationIterationCountCount as * const _ as usize } , - 396usize , concat ! ( + 388usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mAnimationIterationCountCount ) )); assert_eq! (unsafe { & ( * ( 0 as * const nsStyleDisplay ) ) . mShapeOutside as - * const _ as usize } , 400usize , concat ! ( + * const _ as usize } , 392usize , concat ! ( "Alignment of field: " , stringify ! ( nsStyleDisplay ) , "::" , stringify ! ( mShapeOutside ) )); } @@ -26280,6 +26280,8 @@ pub mod root { *const root::RawGeckoPropertyValuePairList; pub type RawGeckoComputedKeyframeValuesListBorrowedMut = *mut root::RawGeckoComputedKeyframeValuesList; + pub type RawGeckoStyleAnimationListBorrowedMut = + *mut root::RawGeckoStyleAnimationList; pub type RawGeckoStyleAnimationListBorrowed = *const root::RawGeckoStyleAnimationList; pub type RawGeckoFontFaceRuleListBorrowedMut = @@ -32597,7 +32599,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214690_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_214713_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -32845,7 +32847,7 @@ pub mod root { #[test] fn __bindgen_test_layout_nsStyleAutoArray_open0_StyleAnimation_close0_instantiation() { assert_eq!(::std::mem::size_of::>() - , 64usize , concat ! ( + , 56usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsStyleAutoArray ) )); assert_eq!(::std::mem::align_of::>() @@ -32986,7 +32988,7 @@ pub mod root { ::nsstring::nsStringRepr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_216503_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_216526_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33151,7 +33153,7 @@ pub mod root { root::JS::DeletePolicy ) )); } #[test] - fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_222100__bindgen_ty_id_222107_close0_instantiation() { + fn __bindgen_test_layout_iterator_open0_input_iterator_tag_UniquePtr_open1_JSErrorNotes_Note_DeletePolicy_open2_JSErrorNotes_Note_close2_close1_long__bindgen_ty_id_222123__bindgen_ty_id_222130_close0_instantiation() { assert_eq!(::std::mem::size_of::() , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33546,7 +33548,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224662_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224685_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33614,7 +33616,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224967_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_224990_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -33726,7 +33728,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_225518_close0_instantiation() { + fn __bindgen_test_layout_NotNull_open0__bindgen_ty_id_225541_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34161,7 +34163,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_225947_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_225970_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34277,7 +34279,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226361_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_226384_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34422,7 +34424,7 @@ pub mod root { ::nsstring::nsStringRepr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227320_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227343_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34511,7 +34513,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227630_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227653_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34522,7 +34524,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227635_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_227658_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -34579,7 +34581,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_228112_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_228135_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35227,7 +35229,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230800_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_230823_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35306,7 +35308,7 @@ pub mod root { root::mozilla::DefaultDelete ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_236844_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_236867_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35396,7 +35398,7 @@ pub mod root { ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_239153_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_239176_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35451,6 +35453,17 @@ pub mod root { root::nsTArray ) )); } #[test] + fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_9() { + assert_eq!(::std::mem::size_of::>() , + 8usize , concat ! ( + "Size of template specialization: " , stringify ! ( + root::RefPtr ) )); + assert_eq!(::std::mem::align_of::>() , + 8usize , concat ! ( + "Alignment of template specialization: " , stringify ! ( + root::RefPtr ) )); + } + #[test] fn __bindgen_test_layout_nsTArray_open0_PropertyValuePair_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( @@ -35541,7 +35554,7 @@ pub mod root { #[test] fn __bindgen_test_layout_nsStyleAutoArray_open0_StyleAnimation_close0_instantiation_1() { assert_eq!(::std::mem::size_of::>() - , 64usize , concat ! ( + , 56usize , concat ! ( "Size of template specialization: " , stringify ! ( root::nsStyleAutoArray ) )); assert_eq!(::std::mem::align_of::>() @@ -35677,7 +35690,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_241307_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_241338_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35747,7 +35760,7 @@ pub mod root { ::nsstring::nsStringRepr ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_9() { + fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_10() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -35793,7 +35806,7 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_243679_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_243710_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36509,7 +36522,7 @@ pub mod root { ::nsstring::nsStringRepr ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_10() { + fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_11() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36669,7 +36682,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_246027_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_246058_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36840,7 +36853,7 @@ pub mod root { root::nsCOMPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_249916_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_249947_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36851,7 +36864,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_249921_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_249952_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -36939,7 +36952,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_250034_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_250065_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37200,7 +37213,7 @@ pub mod root { root::nsRefPtrHashKey ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251760_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251791_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37222,7 +37235,7 @@ pub mod root { root::RefPtr ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251918_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251949_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37233,7 +37246,7 @@ pub mod root { root::nsTArray<*mut root::nsIContent> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251923_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_251954_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37398,7 +37411,7 @@ pub mod root { root::nsTArray ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_254366_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_254403_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37409,7 +37422,7 @@ pub mod root { root::nsTArray<*mut root::mozilla::css::DocumentRule> ) )); } #[test] - fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_254372_close0_instantiation() { + fn __bindgen_test_layout_nsTArray_open0__bindgen_ty_id_254409_close0_instantiation() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( @@ -37420,7 +37433,7 @@ pub mod root { root::nsTArray<*mut root::mozilla::css::DocumentRule> ) )); } #[test] - fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_11() { + fn __bindgen_test_layout_RefPtr_open0_nsAtom_close0_instantiation_12() { assert_eq!(::std::mem::size_of::>() , 8usize , concat ! ( "Size of template specialization: " , stringify ! ( diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index c20470a27aa3..e1625ff74910 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -3215,42 +3215,33 @@ fn static_assert() { where I: IntoIterator, I::IntoIter: ExactSizeIterator { - let v = v.into_iter(); debug_assert!(v.len() != 0); unsafe { self.gecko.mAnimations.ensure_len(v.len()) }; self.gecko.mAnimationNameCount = v.len() as u32; for (servo, gecko) in v.zip(self.gecko.mAnimations.iter_mut()) { - // TODO This is inefficient. We should fix this in bug 1329169. - gecko.mName.assign(match servo.0 { - Some(ref name) => name.as_atom().as_slice(), - None => &[], // Empty string for 'none' - }); + let atom = match servo.0 { + None => atom!(""), + Some(ref name) => name.as_atom().clone(), + }; + unsafe { bindings::Gecko_SetAnimationName(gecko, atom.into_addrefed()); } } } pub fn animation_name_at(&self, index: usize) -> longhands::animation_name::computed_value::SingleComputedValue { use properties::longhands::animation_name::single_value::SpecifiedValue as AnimationName; - // XXX: Is there any effective ways? - let atom = &self.gecko.mAnimations[index].mName; - if atom.is_empty() { + + let atom = self.gecko.mAnimations[index].mName.mRawPtr; + if atom == atom!("").as_ptr() { AnimationName(None) } else { - AnimationName(Some(KeyframesName::from_ident(&atom.to_string()))) + AnimationName(Some(KeyframesName::from_atom(atom.into()))) } } pub fn copy_animation_name_from(&mut self, other: &Self) { - unsafe { self.gecko.mAnimations.ensure_len(other.gecko.mAnimations.len()) }; - - let count = other.gecko.mAnimationNameCount; - self.gecko.mAnimationNameCount = count; - - // The length of mAnimations is often greater than mAnimationXXCount, - // don't copy values over the count. - for (index, animation) in self.gecko.mAnimations.iter_mut().enumerate().take(count as usize) { - animation.mName.assign(&*other.gecko.mAnimations[index].mName); - } + self.gecko.mAnimationNameCount = other.gecko.mAnimationNameCount; + unsafe { bindings::Gecko_CopyAnimationNames(&mut self.gecko.mAnimations, &other.gecko.mAnimations); } } pub fn reset_animation_name(&mut self, other: &Self) { diff --git a/servo/components/style/values/mod.rs b/servo/components/style/values/mod.rs index 15978aa04a3f..f338cb357c0b 100644 --- a/servo/components/style/values/mod.rs +++ b/servo/components/style/values/mod.rs @@ -146,6 +146,17 @@ impl KeyframesName { } } + /// Create a new KeyframesName from Atom. + #[cfg(feature = "gecko")] + pub fn from_atom(atom: Atom) -> Self { + debug_assert_ne!(atom, atom!("")); + + // FIXME: We might want to preserve , but currently Gecko + // stores both of and into nsAtom, so + // we can't tell it. + KeyframesName::Ident(CustomIdent(atom)) + } + /// The name as an Atom pub fn as_atom(&self) -> &Atom { match *self { diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 8e5751c5c895..e41ff305d59f 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -3625,14 +3625,14 @@ fn fill_in_missing_keyframe_values( #[no_mangle] pub extern "C" fn Servo_StyleSet_GetKeyframesForName(raw_data: RawServoStyleSetBorrowed, - name: *const nsACString, + name: *mut nsAtom, inherited_timing_function: nsTimingFunctionBorrowed, keyframes: RawGeckoKeyframeListBorrowedMut) -> bool { debug_assert!(keyframes.len() == 0, "keyframes should be initially empty"); let data = PerDocumentStyleData::from_ffi(raw_data).borrow(); - let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) }; + let name = Atom::from(name); let animation = match data.stylist.get_animation(&name) { Some(animation) => animation, From 5e34bc1f57b397530e57634e0ca2bf02e5757b48 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Tue, 10 Oct 2017 17:00:28 +0900 Subject: [PATCH 24/68] Bug 1329169 - Use atom for animation-name property. r=xidorn MozReview-Commit-ID: 9yVWXVi1oXf --HG-- extra : rebase_source : f0d8a731c3e6caaf248a0b0e25ef96370af3ecd8 --- .../rootAnalysis/analyzeHeapWrites.js | 2 ++ layout/style/ServoBindingList.h | 2 +- layout/style/ServoBindingTypes.h | 1 + layout/style/ServoBindings.cpp | 21 +++++++++++++++++++ layout/style/ServoBindings.h | 5 +++++ layout/style/ServoBindings.toml | 3 ++- layout/style/ServoStyleSet.cpp | 5 ++--- layout/style/ServoStyleSet.h | 2 +- layout/style/nsAnimationManager.cpp | 6 +++--- layout/style/nsAnimationManager.h | 20 ++++++++++-------- layout/style/nsCSSParser.cpp | 4 ++-- layout/style/nsCSSRuleProcessor.cpp | 15 +++---------- layout/style/nsCSSRuleProcessor.h | 2 +- layout/style/nsCSSRules.cpp | 10 ++++----- layout/style/nsCSSRules.h | 6 +++--- layout/style/nsComputedDOMStyle.cpp | 7 ++++--- layout/style/nsRuleNode.cpp | 9 ++++---- layout/style/nsStyleSet.cpp | 2 +- layout/style/nsStyleSet.h | 2 +- layout/style/nsStyleStruct.cpp | 2 +- layout/style/nsStyleStruct.h | 7 ++++--- 21 files changed, 78 insertions(+), 55 deletions(-) diff --git a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js index e02d5165e01d..7658a295cd3e 100644 --- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js +++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js @@ -153,7 +153,9 @@ function treatAsSafeArgument(entry, varName, csuName) // Various Servo binding out parameters. This is a mess and there needs // to be a way to indicate which params are out parameters, either using // an attribute or a naming convention. + ["Gecko_CopyAnimationNames", "aDest", null], ["Gecko_CopyFontFamilyFrom", "dst", null], + ["Gecko_SetAnimationName", "aStyleAnimation", null], ["Gecko_SetCounterStyleToName", "aPtr", null], ["Gecko_SetCounterStyleToSymbols", "aPtr", null], ["Gecko_SetCounterStyleToString", "aPtr", null], diff --git a/layout/style/ServoBindingList.h b/layout/style/ServoBindingList.h index 46b9d66ba429..1142101e5286 100644 --- a/layout/style/ServoBindingList.h +++ b/layout/style/ServoBindingList.h @@ -112,7 +112,7 @@ SERVO_BINDING_FUNC(Servo_StyleSet_NoteStyleSheetsChanged, void, mozilla::OriginFlags changed_origins) SERVO_BINDING_FUNC(Servo_StyleSet_GetKeyframesForName, bool, RawServoStyleSetBorrowed set, - const nsACString* property, + nsAtom* name, nsTimingFunctionBorrowed timing_function, RawGeckoKeyframeListBorrowedMut keyframe_list) SERVO_BINDING_FUNC(Servo_StyleSet_GetFontFaceRules, void, diff --git a/layout/style/ServoBindingTypes.h b/layout/style/ServoBindingTypes.h index ce7090d144f7..4aea6d2cf523 100644 --- a/layout/style/ServoBindingTypes.h +++ b/layout/style/ServoBindingTypes.h @@ -167,6 +167,7 @@ DECL_BORROWED_REF_TYPE_FOR(RawGeckoKeyframeList) DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoPropertyValuePairList) DECL_BORROWED_REF_TYPE_FOR(RawGeckoPropertyValuePairList) DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoComputedKeyframeValuesList) +DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoStyleAnimationList) DECL_BORROWED_REF_TYPE_FOR(RawGeckoStyleAnimationList) DECL_BORROWED_MUT_REF_TYPE_FOR(nsTimingFunction) DECL_BORROWED_REF_TYPE_FOR(nsTimingFunction) diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 8b7f46b43d61..bed37f9f9f47 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -645,6 +645,27 @@ Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA, return *aA == *aB; } +void +Gecko_CopyAnimationNames(RawGeckoStyleAnimationListBorrowedMut aDest, + RawGeckoStyleAnimationListBorrowed aSrc) +{ + size_t srcLength = aSrc->Length(); + aDest->EnsureLengthAtLeast(srcLength); + + for (size_t index = 0; index < srcLength; index++) { + (*aDest)[index].SetName((*aSrc)[index].GetName()); + } +} + +void +Gecko_SetAnimationName(StyleAnimation* aStyleAnimation, + nsAtom* aAtom) +{ + MOZ_ASSERT(aStyleAnimation); + + aStyleAnimation->SetName(already_AddRefed(aAtom)); +} + void Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement, ServoStyleContextBorrowedOrNull aOldComputedData, diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index cd336d149c67..7137b39b8b62 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -245,6 +245,11 @@ RawServoDeclarationBlockStrongBorrowedOrNull Gecko_GetSMILOverrideDeclarationBlock(RawGeckoElementBorrowed element); bool Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed, RawGeckoStyleAnimationListBorrowed); +void Gecko_CopyAnimationNames(RawGeckoStyleAnimationListBorrowedMut aDest, + RawGeckoStyleAnimationListBorrowed aSrc); +// This function takes an already addrefed nsAtom +void Gecko_SetAnimationName(mozilla::StyleAnimation* aStyleAnimation, + nsAtom* aAtom); void Gecko_UpdateAnimations(RawGeckoElementBorrowed aElementOrPseudo, ServoStyleContextBorrowedOrNull aOldComputedValues, ServoStyleContextBorrowedOrNull aComputedValues, diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index 924d607f6e3f..2e4585495e94 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -520,6 +520,7 @@ structs-types = [ "ParsingMode", "InheritTarget", "URLMatchingFunction", + "StyleAnimation", "StyleRuleInclusion", "nsStyleTransformMatrix::MatrixTransformOperator", "RawGeckoGfxMatrix4x4", @@ -541,7 +542,6 @@ servo-immutable-borrow-types = [ "RawGeckoDocument", "RawServoDeclarationBlockStrong", "RawGeckoPresContext", - "RawGeckoStyleAnimationList", "RawGeckoXBLBinding", ] servo-borrow-types = [ @@ -557,6 +557,7 @@ servo-borrow-types = [ "RawGeckoFontFaceRuleList", "RawGeckoServoStyleRuleList", "RawGeckoServoAnimationValueList", + "RawGeckoStyleAnimationList", "RawGeckoStyleChildrenIterator", ] fixups = [ diff --git a/layout/style/ServoStyleSet.cpp b/layout/style/ServoStyleSet.cpp index 0943a75fda36..58f425c10390 100644 --- a/layout/style/ServoStyleSet.cpp +++ b/layout/style/ServoStyleSet.cpp @@ -1159,15 +1159,14 @@ ServoStyleSet::AssertTreeIsClean() #endif bool -ServoStyleSet::GetKeyframesForName(const nsString& aName, +ServoStyleSet::GetKeyframesForName(nsAtom* aName, const nsTimingFunction& aTimingFunction, nsTArray& aKeyframes) { UpdateStylistIfNeeded(); - NS_ConvertUTF16toUTF8 name(aName); return Servo_StyleSet_GetKeyframesForName(mRawSet.get(), - &name, + aName, &aTimingFunction, &aKeyframes); } diff --git a/layout/style/ServoStyleSet.h b/layout/style/ServoStyleSet.h index 87ac8f6f1a66..0f3b814cda90 100644 --- a/layout/style/ServoStyleSet.h +++ b/layout/style/ServoStyleSet.h @@ -365,7 +365,7 @@ public: */ already_AddRefed ResolveServoStyle(dom::Element* aElement); - bool GetKeyframesForName(const nsString& aName, + bool GetKeyframesForName(nsAtom* aName, const nsTimingFunction& aTimingFunction, nsTArray& aKeyframes); diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 310a517e4f07..e7aa1d988dba 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -334,7 +334,7 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsAnimationManager, Release) // Find the matching animation by |aName| in the old list // of animations and remove the matched animation from the list. static already_AddRefed -PopExistingAnimation(const nsAString& aName, +PopExistingAnimation(const nsAtom* aName, nsAnimationManager::CSSAnimationCollection* aCollection) { if (!aCollection) { @@ -971,7 +971,7 @@ BuildAnimations(nsPresContext* aPresContext, // "none" which is represented by an empty name in the StyleAnimation. // Since such animations neither affect style nor dispatch events, we do // not generate a corresponding CSSAnimation for them. - if (src.GetName().IsEmpty()) { + if (src.GetName() == nsGkAtoms::_empty) { continue; } @@ -1057,7 +1057,7 @@ nsAnimationManager::DoUpdateAnimations( aTarget.mPseudoType); if (!collection && aStyleDisplay.mAnimationNameCount == 1 && - aStyleDisplay.mAnimations[0].GetName().IsEmpty()) { + aStyleDisplay.mAnimations[0].GetName() == nsGkAtoms::_empty) { return; } diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 69808a2db71c..846f4be1ffbc 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -43,7 +43,7 @@ struct AnimationEventInfo { AnimationEventInfo(dom::Element* aElement, CSSPseudoElementType aPseudoType, EventMessage aMessage, - const nsAString& aAnimationName, + nsAtom* aAnimationName, const StickyTimeDuration& aElapsedTime, const TimeStamp& aTimeStamp, dom::Animation* aAnimation) @@ -53,7 +53,7 @@ struct AnimationEventInfo { , mTimeStamp(aTimeStamp) { // XXX Looks like nobody initialize WidgetEvent::time - mEvent.mAnimationName = aAnimationName; + aAnimationName->ToString(mEvent.mAnimationName); mEvent.mElapsedTime = nsRFPService::ReduceTimePrecisionAsSecs(aElapsedTime.ToSeconds()); mEvent.mPseudoElement = @@ -78,7 +78,7 @@ class CSSAnimation final : public Animation { public: explicit CSSAnimation(nsIGlobalObject* aGlobal, - const nsAString& aAnimationName) + nsAtom* aAnimationName) : dom::Animation(aGlobal) , mAnimationName(aAnimationName) , mIsStylePaused(false) @@ -90,7 +90,8 @@ public: // We might need to drop this assertion once we add a script-accessible // constructor but for animations generated from CSS markup the // animation-name should never be empty. - MOZ_ASSERT(!mAnimationName.IsEmpty(), "animation-name should not be empty"); + MOZ_ASSERT(mAnimationName != nsGkAtoms::_empty, + "animation-name should not be 'none'"); } JSObject* WrapObject(JSContext* aCx, @@ -100,11 +101,12 @@ public: const CSSAnimation* AsCSSAnimation() const override { return this; } // CSSAnimation interface - void GetAnimationName(nsString& aRetVal) const { aRetVal = mAnimationName; } + void GetAnimationName(nsString& aRetVal) const + { + mAnimationName->ToString(aRetVal); + } - // Alternative to GetAnimationName that returns a reference to the member - // for more efficient internal usage. - const nsString& AnimationName() const { return mAnimationName; } + nsAtom* AnimationName() const { return mAnimationName; } // Animation interface overrides virtual Promise* GetReady(ErrorResult& aRv) override; @@ -203,7 +205,7 @@ protected: TimeDuration(); } - nsString mAnimationName; + RefPtr mAnimationName; // The (pseudo-)element whose computed animation-name refers to this // animation (if any). diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 7c4e1cfabb3f..ba9bec879df9 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -4281,8 +4281,8 @@ CSSParserImpl::ParseKeyframesRule(RuleAppendFunc aAppendFunc, void* aData) return false; } - RefPtr rule = new nsCSSKeyframesRule(name, - linenum, colnum); + RefPtr rule = + new nsCSSKeyframesRule(NS_Atomize(name), linenum, colnum); while (!ExpectSymbol('}', true)) { RefPtr kid = ParseKeyframeRule(); diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index aceced01a32a..ac985d95e43f 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -894,7 +894,8 @@ struct RuleCascadeData { nsTArray mPageRules; nsTArray mCounterStyleRules; - nsDataHashtable mKeyframesRuleTable; + nsDataHashtable, + nsCSSKeyframesRule*> mKeyframesRuleTable; // The hashtable doesn't need to hold a strong reference to the name // atom, because nsCSSCounterStyleRule always does. If the name changes // we need to discard this table and rebuild it anyway. @@ -952,17 +953,7 @@ RuleCascadeData::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const n += mFontFeatureValuesRules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mPageRules.ShallowSizeOfExcludingThis(aMallocSizeOf); n += mCounterStyleRules.ShallowSizeOfExcludingThis(aMallocSizeOf); - n += mKeyframesRuleTable.ShallowSizeOfExcludingThis(aMallocSizeOf); - for (auto iter = mKeyframesRuleTable.ConstIter(); !iter.Done(); iter.Next()) { - // We don't own the nsCSSKeyframesRule objects so we don't count them. We - // do care about the size of the keys' nsAString members' buffers though. - // - // Note that we depend on nsStringHashKey::GetKey() returning a reference, - // since otherwise aKey would be a copy of the string key and we would not - // be measuring the right object here. - n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf); - } return n; } @@ -3103,7 +3094,7 @@ nsCSSRuleProcessor::AppendFontFaceRules( nsCSSKeyframesRule* nsCSSRuleProcessor::KeyframesRuleForName(nsPresContext* aPresContext, - const nsString& aName) + const nsAtom* aName) { RuleCascadeData* cascade = GetRuleCascade(aPresContext); diff --git a/layout/style/nsCSSRuleProcessor.h b/layout/style/nsCSSRuleProcessor.h index 6f02bbb5995d..b3596dd21c45 100644 --- a/layout/style/nsCSSRuleProcessor.h +++ b/layout/style/nsCSSRuleProcessor.h @@ -212,7 +212,7 @@ public: nsTArray& aArray); nsCSSKeyframesRule* KeyframesRuleForName(nsPresContext* aPresContext, - const nsString& aName); + const nsAtom* aName); nsCSSCounterStyleRule* CounterStyleRuleForName(nsPresContext* aPresContext, nsAtom* aName); diff --git a/layout/style/nsCSSRules.cpp b/layout/style/nsCSSRules.cpp index 2dba3b43559f..bb915d580e3e 100644 --- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -1726,7 +1726,7 @@ nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const } fprintf_stderr(out, "%s@keyframes %s {\n", - indentStr.get(), NS_ConvertUTF16toUTF8(mName).get()); + indentStr.get(), nsAtomCString(mName).get()); GroupRule::List(out, aIndent); @@ -1738,7 +1738,7 @@ void nsCSSKeyframesRule::GetCssTextImpl(nsAString& aCssText) const { aCssText.AssignLiteral("@keyframes "); - aCssText.Append(mName); + aCssText.Append(nsDependentAtomString(mName)); aCssText.AppendLiteral(" {\n"); nsAutoString tmp; for (const Rule* rule : GeckoRules()) { @@ -1752,21 +1752,21 @@ nsCSSKeyframesRule::GetCssTextImpl(nsAString& aCssText) const NS_IMETHODIMP nsCSSKeyframesRule::GetName(nsAString& aName) { - aName = mName; + mName->ToString(aName); return NS_OK; } NS_IMETHODIMP nsCSSKeyframesRule::SetName(const nsAString& aName) { - if (mName == aName) { + if (mName->Equals(aName)) { return NS_OK; } nsIDocument* doc = GetDocument(); MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true); - mName = aName; + mName = NS_Atomize(aName); if (StyleSheet* sheet = GetStyleSheet()) { sheet->AsGecko()->SetModifiedByChildRule(); diff --git a/layout/style/nsCSSRules.h b/layout/style/nsCSSRules.h index acf93fc6d251..fbc0bdde4475 100644 --- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -296,7 +296,7 @@ private: class nsCSSKeyframesRule final : public mozilla::dom::CSSKeyframesRule { public: - nsCSSKeyframesRule(const nsAString& aName, + nsCSSKeyframesRule(already_AddRefed aName, uint32_t aLineNumber, uint32_t aColumnNumber) : mozilla::dom::CSSKeyframesRule(aLineNumber, aColumnNumber) , mName(aName) @@ -326,14 +326,14 @@ public: mozilla::dom::CSSRuleList* CssRules() final { return GroupRule::CssRules(); } nsCSSKeyframeRule* FindRule(const nsAString& aKey) final; - const nsString& GetName() { return mName; } + const nsAtom* GetName() const { return mName; } virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override; private: uint32_t FindRuleIndexForKey(const nsAString& aKey); - nsString mName; + RefPtr mName; }; class nsCSSPageRule; diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 3e29f63455ff..2361d8d63b88 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -6867,12 +6867,13 @@ nsComputedDOMStyle::DoGetAnimationName() const StyleAnimation *animation = &display->mAnimations[i]; RefPtr property = new nsROCSSPrimitiveValue; - const nsString& name = animation->GetName(); - if (name.IsEmpty()) { + nsAtom* name = animation->GetName(); + if (name == nsGkAtoms::_empty) { property->SetIdent(eCSSKeyword_none); } else { + nsDependentAtomString nameStr(name); nsAutoString escaped; - nsStyleUtil::AppendEscapedCSSIdent(animation->GetName(), escaped); + nsStyleUtil::AppendEscapedCSSIdent(nameStr, escaped); property->SetString(escaped); // really want SetIdent } valueList->AppendCSSValue(property.forget()); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 22bd8d10c301..8f68cf6cadb7 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -5901,18 +5901,17 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct, animation->SetName(parentDisplay->mAnimations[i].GetName()); } else if (animName.unit == eCSSUnit_Initial || animName.unit == eCSSUnit_Unset) { - animation->SetName(EmptyString()); + animation->SetName(nsGkAtoms::_empty); } else if (animName.list) { switch (animName.list->mValue.GetUnit()) { case eCSSUnit_String: case eCSSUnit_Ident: { - nsDependentString - nameStr(animName.list->mValue.GetStringBufferValue()); - animation->SetName(nameStr); + animation->SetName( + NS_Atomize(animName.list->mValue.GetStringBufferValue())); break; } case eCSSUnit_None: { - animation->SetName(EmptyString()); + animation->SetName(nsGkAtoms::_empty); break; } default: diff --git a/layout/style/nsStyleSet.cpp b/layout/style/nsStyleSet.cpp index 48f0eb261fb8..9dbc15e1ccd7 100644 --- a/layout/style/nsStyleSet.cpp +++ b/layout/style/nsStyleSet.cpp @@ -2241,7 +2241,7 @@ nsStyleSet::AppendFontFaceRules(nsTArray& aArray) } nsCSSKeyframesRule* -nsStyleSet::KeyframesRuleForName(const nsString& aName) +nsStyleSet::KeyframesRuleForName(nsAtom* aName) { NS_ENSURE_FALSE(mInShutdown, nullptr); NS_ASSERTION(mBatching == 0, "rule processors out of date"); diff --git a/layout/style/nsStyleSet.h b/layout/style/nsStyleSet.h index b7094175a8dd..4d69242e64ac 100644 --- a/layout/style/nsStyleSet.h +++ b/layout/style/nsStyleSet.h @@ -315,7 +315,7 @@ class nsStyleSet final bool AppendFontFaceRules(nsTArray& aArray); // Return the winning (in the cascade) @keyframes rule for the given name. - nsCSSKeyframesRule* KeyframesRuleForName(const nsString& aName); + nsCSSKeyframesRule* KeyframesRuleForName(nsAtom* aName); // Return the winning (in the cascade) @counter-style rule for the given name. nsCSSCounterStyleRule* CounterStyleRuleForName(nsAtom* aName); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 34d15b842efd..a158e132c5a4 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3436,7 +3436,7 @@ StyleAnimation::SetInitialValues() mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE); mDuration = 0.0; mDelay = 0.0; - mName = EmptyString(); + mName = nsGkAtoms::_empty; mDirection = dom::PlaybackDirection::Normal; mFillMode = dom::FillMode::None; mPlayState = NS_STYLE_ANIMATION_PLAY_STATE_RUNNING; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 78acb6636add..6764d33851be 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -2310,7 +2310,7 @@ struct StyleAnimation const nsTimingFunction& GetTimingFunction() const { return mTimingFunction; } float GetDelay() const { return mDelay; } float GetDuration() const { return mDuration; } - const nsString& GetName() const { return mName; } + nsAtom* GetName() const { return mName; } dom::PlaybackDirection GetDirection() const { return mDirection; } dom::FillMode GetFillMode() const { return mFillMode; } uint8_t GetPlayState() const { return mPlayState; } @@ -2320,7 +2320,8 @@ struct StyleAnimation { mTimingFunction = aTimingFunction; } void SetDelay(float aDelay) { mDelay = aDelay; } void SetDuration(float aDuration) { mDuration = aDuration; } - void SetName(const nsAString& aName) { mName = aName; } + void SetName(already_AddRefed aName) { mName = aName; } + void SetName(nsAtom* aName) { mName = aName; } void SetDirection(dom::PlaybackDirection aDirection) { mDirection = aDirection; } void SetFillMode(dom::FillMode aFillMode) { mFillMode = aFillMode; } void SetPlayState(uint8_t aPlayState) { mPlayState = aPlayState; } @@ -2337,7 +2338,7 @@ private: nsTimingFunction mTimingFunction; float mDuration; float mDelay; - nsString mName; // empty string for 'none' + RefPtr mName; // nsGkAtoms::_empty for 'none' dom::PlaybackDirection mDirection; dom::FillMode mFillMode; uint8_t mPlayState; From f0c8fb3d0962f2002e183cee4cd7bda8c94b22df Mon Sep 17 00:00:00 2001 From: abhinav Date: Fri, 6 Oct 2017 00:18:05 +0530 Subject: [PATCH 25/68] Bug 1168092 - Introduce defaultIncrement property in InplaceEditor so that css properties like opacity can increment by 0.1 instead of 1. r=jdescottes MozReview-Commit-ID: KvCJ1HCQxIJ --HG-- extra : rebase_source : 9688ebdd443944781cff30deed0e682ec27f790c --- .../browser_rules_edit-property-increments.js | 24 +++++++++++++++++++ .../rules/views/text-property-editor.js | 1 + devtools/client/shared/inplace-editor.js | 7 ++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js b/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js index 2c88ef02a92c..d6dbeaae6af1 100644 --- a/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js +++ b/devtools/client/inspector/rules/test/browser_rules_edit-property-increments.js @@ -20,6 +20,7 @@ const TEST_URI = ` background: none; transition: initial; z-index: 0; + opacity: 1; }
@@ -39,6 +40,7 @@ add_task(function* () { yield testShorthandIncrements(view); yield testOddCases(view); yield testZeroValueIncrements(view); + yield testOpacityIncrements(view); }); function* testMarginIncrements(view) { @@ -227,7 +229,29 @@ function* testZeroValueIncrements(view) { }); } +function* testOpacityIncrements(view) { + info("Testing keyboard increments on the opacity property"); + + let idRuleEditor = getRuleViewRuleEditor(view, 1); + let opacityPropEditor = idRuleEditor.rule.textProps[7].editor; + + yield runIncrementTest(opacityPropEditor, view, { + 1: {alt: true, start: "0.5", end: "0.51", selectAll: true}, + 2: {start: "0", end: "0.1", selectAll: true}, + 3: {shift: true, start: "0", end: "1", selectAll: true}, + 4: {down: true, alt: true, start: "0.1", end: "0.09", selectAll: true}, + 5: {down: true, start: "0", end: "-0.1", selectAll: true}, + 6: {down: true, shift: true, start: "0", end: "-1", selectAll: true}, + 7: {pageUp: true, shift: true, start: "0", end: "10", selectAll: true}, + 8: {pageDown: true, shift: true, start: "0", end: "-10", + selectAll: true}, + 9: {start: "0.7", end: "0.8", selectAll: true}, + 10: {down: true, start: "0", end: "-0.1", selectAll: true}, + }); +} + function* runIncrementTest(propertyEditor, view, tests) { + propertyEditor.valueSpan.scrollIntoView(); let editor = yield focusEditableField(view, propertyEditor.valueSpan); for (let test in tests) { diff --git a/devtools/client/inspector/rules/views/text-property-editor.js b/devtools/client/inspector/rules/views/text-property-editor.js index 219e67bac68d..008f50721cfa 100644 --- a/devtools/client/inspector/rules/views/text-property-editor.js +++ b/devtools/client/inspector/rules/views/text-property-editor.js @@ -295,6 +295,7 @@ TextPropertyEditor.prototype = { advanceChars: advanceValidate, contentType: InplaceEditor.CONTENT_TYPES.CSS_VALUE, property: this.prop, + defaultIncrement: this.prop.name === "opacity" ? 0.1 : 1, popup: this.popup, multiline: true, maxWidth: () => this.container.getBoundingClientRect().width, diff --git a/devtools/client/shared/inplace-editor.js b/devtools/client/shared/inplace-editor.js index aaa175252d0d..4ea354ae9a21 100644 --- a/devtools/client/shared/inplace-editor.js +++ b/devtools/client/shared/inplace-editor.js @@ -122,6 +122,8 @@ function isKeyIn(key, ...keys) { * from `element` to the new input. * defaults to false * {Object} cssProperties: An instance of CSSProperties. + * {Number} defaultIncrement: The value by which the input is incremented + * or decremented by default (0.1 for properties like opacity and 1 by default) */ function editableField(options) { return editableItem(options, function (element, event) { @@ -225,6 +227,7 @@ function InplaceEditor(options, event) { this.change = options.change; this.done = options.done; this.contextMenu = options.contextMenu; + this.defaultIncrement = options.defaultIncrement || 1; this.destroy = options.destroy; this.initial = options.initial ? options.initial : this.elt.textContent; this.multiline = options.multiline || false; @@ -1209,9 +1212,9 @@ InplaceEditor.prototype = { let key = event.keyCode; if (isKeyIn(key, "UP", "PAGE_UP")) { - increment = 1; + increment = 1 * this.defaultIncrement; } else if (isKeyIn(key, "DOWN", "PAGE_DOWN")) { - increment = -1; + increment = -1 * this.defaultIncrement; } if (event.shiftKey && !event.altKey) { From 29339a1cb1191b853cfed2cbe4899d4bfe8538b0 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 3 Oct 2017 15:27:26 +0100 Subject: [PATCH 26/68] Bug 1405325 - Rename wdspec cookies test to match command name. r=maja_zf MozReview-Commit-ID: CYVo0n3mLbB --HG-- rename : testing/web-platform/tests/webdriver/tests/cookies/cookies.py => testing/web-platform/tests/webdriver/tests/cookies/get_named_cookie.py extra : rebase_source : 6af6e1b53e2b5115720fb186b4aa985e067c109b --- testing/web-platform/meta/MANIFEST.json | 8 ++++---- .../tests/cookies/{cookies.py => get_named_cookie.py} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename testing/web-platform/tests/webdriver/tests/cookies/{cookies.py => get_named_cookie.py} (100%) diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 55708da27d0e..919cc66cac42 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -409322,9 +409322,9 @@ {} ] ], - "webdriver/tests/cookies/cookies.py": [ + "webdriver/tests/cookies/get_named_cookie.py": [ [ - "/webdriver/tests/cookies/cookies.py", + "/webdriver/tests/cookies/get_named_cookie.py", {} ] ], @@ -601252,7 +601252,7 @@ "support" ], "html/syntax/parsing/empty-doctype-ids.html": [ - "79b4a278f0e35646cfdffeebf8f0523e2772bc9b", + "9fa4f9bdc3bdfc2241a9aec3180b94a32af91385", "testharness" ], "html/syntax/parsing/foreign_content_001.html": [ @@ -631827,7 +631827,7 @@ "479379109115668183643e8a050396219332887d", "wdspec" ], - "webdriver/tests/cookies/cookies.py": [ + "webdriver/tests/cookies/get_named_cookie.py": [ "afa7bcffd838c939aa6483c26a49d43c4b2dc94b", "wdspec" ], diff --git a/testing/web-platform/tests/webdriver/tests/cookies/cookies.py b/testing/web-platform/tests/webdriver/tests/cookies/get_named_cookie.py similarity index 100% rename from testing/web-platform/tests/webdriver/tests/cookies/cookies.py rename to testing/web-platform/tests/webdriver/tests/cookies/get_named_cookie.py From 1f920edde69a0b1a7b3fbaf8a9c8d1c2ffc013c8 Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 3 Oct 2017 16:19:36 +0100 Subject: [PATCH 27/68] Bug 1405325 - Fix webdriver.transport.HTTPWireProtocol#url. r=maja_zf The self.path_prefix attribute does not exist. It should be self.url_prefix. MozReview-Commit-ID: 8LGES8GsTsm --HG-- extra : rebase_source : a59f92070a6f35acda166836528704d03248c48c --- .../web-platform/tests/tools/webdriver/webdriver/transport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py index 206fd3ca7a07..5e0c1db7a6ef 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py @@ -63,7 +63,7 @@ class HTTPWireProtocol(object): self._timeout = timeout def url(self, suffix): - return urlparse.urljoin(self.path_prefix, suffix) + return urlparse.urljoin(self.url_prefix, suffix) def send(self, method, url, body=None, headers=None): """Send a command to the remote. From e3c307effe9bb1513913f0d6052c5c9e223eeded Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 3 Oct 2017 16:21:25 +0100 Subject: [PATCH 28/68] Bug 1405325 - Use HTTPWireProtocol#url to build full URL. r=maja_zf Instead of using string concatentation for building the command URL, rely on self.url which internally uses urlparse.urljoin. MozReview-Commit-ID: DqakZJIgdJF --HG-- extra : rebase_source : ae9702ea22f7a2a3108b1e78e70182371ddb7b79 --- .../web-platform/tests/tools/webdriver/webdriver/transport.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py index 5e0c1db7a6ef..4ef6b0125d4b 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py @@ -65,7 +65,7 @@ class HTTPWireProtocol(object): def url(self, suffix): return urlparse.urljoin(self.url_prefix, suffix) - def send(self, method, url, body=None, headers=None): + def send(self, method, uri, body=None, headers=None): """Send a command to the remote. :param method: "POST" or "GET". @@ -89,7 +89,7 @@ class HTTPWireProtocol(object): if headers is None: headers = {} - url = self.url_prefix + url + url = self.url(uri) kwargs = {} if self._timeout is not None: From d94c69c0f995a25e488cd19dfb3f2e920fca2d1a Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 3 Oct 2017 16:23:24 +0100 Subject: [PATCH 29/68] Bug 1405325 - Assign actual response to variable. r=maja_zf This is a non-functional change, but if anything should be assigned to the "response" value, it should be the actual response. I had to do this because I was debugging a low-level HTTP problem with geckodriver, so this will be more useful in the future. In any case, we can return the webdriver.transport.Response representation directly because the finally clause is always called. MozReview-Commit-ID: 8JKNKAEbOAe --HG-- extra : rebase_source : 9bf14127d22d75e89df4d2377d4f73168055f673 --- .../tests/tools/webdriver/webdriver/transport.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py index 4ef6b0125d4b..0f8223f66ed7 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py @@ -100,8 +100,7 @@ class HTTPWireProtocol(object): conn.request(method, url, body, headers) try: - response = Response.from_http_response(conn.getresponse()) + response = conn.getresponse() + return Response.from_http_response(response) finally: conn.close() - - return response From 3304020e4107150ebc5fdf58f85b10fddcd9c9be Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 3 Oct 2017 16:24:22 +0100 Subject: [PATCH 30/68] Bug 1405325 - Correct HTTPWireProtocol#send documentation. r=maja_zf MozReview-Commit-ID: 3ZfXYHOaKRC --HG-- extra : rebase_source : 0cd2e89ce271bae1c95e3896af5af6b705fed134 --- .../tests/tools/webdriver/webdriver/transport.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py index 0f8223f66ed7..cc07b9191f1b 100644 --- a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py +++ b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py @@ -68,15 +68,16 @@ class HTTPWireProtocol(object): def send(self, method, uri, body=None, headers=None): """Send a command to the remote. - :param method: "POST" or "GET". - :param url: "command part" of the requests URL path - :param body: Body of the request. Defaults to an empty dictionary - if ``method`` is "POST". + :param method: `GET`, `POST`, or `DELETE`. + :param uri: Relative endpoint of the requests URL path. + :param body: Body of the request. Defaults to an empty + dictionary if ``method`` is `POST`. :param headers: Additional headers to include in the request. - :return: an instance of wdclient.Response describing the HTTP response - received from the remote end. - """ + :return: Instance of ``wdclient.Response`` describing the + HTTP response received from the remote end. + + """ if body is None and method == "POST": body = {} From d4164733550850dedc364f5fe94b7c7719f75aec Mon Sep 17 00:00:00 2001 From: Andreas Tolfsen Date: Tue, 3 Oct 2017 16:25:57 +0100 Subject: [PATCH 31/68] Bug 1405325 - Align WebDriver:DeleteCookie with specification. r=maja_zf The Delete Cookie command should not return an error if the cookie does not exist. The variable names "toDelete" and "candidateName" was also juxtapositioned and wrong. Here I am using the approximate names used in the specification prose for clarity. Fixes: https://github.com/mozilla/geckodriver/issues/989 MozReview-Commit-ID: 6IIGGpB1JWn --HG-- extra : rebase_source : f3149d2195c0e871370eef3d2c1306a8212c5751 --- testing/marionette/driver.js | 10 +- testing/web-platform/meta/MANIFEST.json | 10 ++ .../tests/cookies/delete_cookie.py.ini | 7 + .../webdriver/tests/cookies/delete_cookie.py | 123 ++++++++++++++++++ 4 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 testing/web-platform/meta/webdriver/tests/cookies/delete_cookie.py.ini create mode 100644 testing/web-platform/tests/webdriver/tests/cookies/delete_cookie.py diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js index 7feb92531b0c..a535e4b320ba 100644 --- a/testing/marionette/driver.js +++ b/testing/marionette/driver.js @@ -2697,14 +2697,12 @@ GeckoDriver.prototype.deleteCookie = function(cmd) { assert.noUserPrompt(this.dialog); let {hostname, pathname} = this.currentURL; - let candidateName = assert.string(cmd.parameters.name); - for (let toDelete of cookie.iter(hostname, pathname)) { - if (toDelete.name === candidateName) { - return cookie.remove(toDelete); + let name = assert.string(cmd.parameters.name); + for (let c of cookie.iter(hostname, pathname)) { + if (c.name === name) { + cookie.remove(c); } } - - throw new UnknownError("Unable to find cookie"); }; /** diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 919cc66cac42..3351c73d00d3 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -409322,6 +409322,12 @@ {} ] ], + "webdriver/tests/cookies/delete_cookie.py": [ + [ + "/webdriver/tests/cookies/delete_cookie.py", + {} + ] + ], "webdriver/tests/cookies/get_named_cookie.py": [ [ "/webdriver/tests/cookies/get_named_cookie.py", @@ -631827,6 +631833,10 @@ "479379109115668183643e8a050396219332887d", "wdspec" ], + "webdriver/tests/cookies/delete_cookie.py": [ + "4e846b0f0538bbfc88e7dc6b637f19260a8d3c3e", + "wdspec" + ], "webdriver/tests/cookies/get_named_cookie.py": [ "afa7bcffd838c939aa6483c26a49d43c4b2dc94b", "wdspec" diff --git a/testing/web-platform/meta/webdriver/tests/cookies/delete_cookie.py.ini b/testing/web-platform/meta/webdriver/tests/cookies/delete_cookie.py.ini new file mode 100644 index 000000000000..7a4f1df30173 --- /dev/null +++ b/testing/web-platform/meta/webdriver/tests/cookies/delete_cookie.py.ini @@ -0,0 +1,7 @@ +[delete_cookie.py] + type: wdspec + [delete_cookie.py::test_handle_prompt_accept] + expected: FAIL + + [delete_cookie.py::test_handle_prompt_missing_value] + expected: FAIL diff --git a/testing/web-platform/tests/webdriver/tests/cookies/delete_cookie.py b/testing/web-platform/tests/webdriver/tests/cookies/delete_cookie.py new file mode 100644 index 000000000000..adb9674909c9 --- /dev/null +++ b/testing/web-platform/tests/webdriver/tests/cookies/delete_cookie.py @@ -0,0 +1,123 @@ +from tests.support.asserts import assert_error, assert_dialog_handled, assert_success +from tests.support.fixtures import create_dialog +from tests.support.inline import inline + + +def delete_cookie(session, name): + return session.transport.send("DELETE", "/session/%s/cookie/%s" % (session.session_id, name)) + + +# 16.4 Delete Cookie + + +def test_no_browsing_context(session, create_window): + """ + 1. If the current top-level browsing context is no longer open, + return error with error code no such window. + + """ + session.window_handle = create_window() + session.close() + response = delete_cookie(session, "foo") + assert_error(response, "no such window") + + +def test_handle_prompt_dismiss_and_notify(): + """TODO""" + + +def test_handle_prompt_accept_and_notify(): + """TODO""" + + +def test_handle_prompt_ignore(): + """TODO""" + + +def test_handle_prompt_accept(new_session): + """ + 2. Handle any user prompts and return its value if it is an error. + + [...] + + In order to handle any user prompts a remote end must take the + following steps: + + [...] + + 2. Perform the following substeps based on the current session's + user prompt handler: + + [...] + + - accept state + Accept the current user prompt. + + """ + _, session = new_session({"alwaysMatch": {"unhandledPromptBehavior": "accept"}}) + session.url = inline("WD doc title") + + create_dialog(session)("alert", text="dismiss #1", result_var="dismiss1") + response = delete_cookie(session, "foo") + assert response.status == 200 + assert_dialog_handled(session, "dismiss #1") + + create_dialog(session)("confirm", text="dismiss #2", result_var="dismiss2") + response = delete_cookie(session, "foo") + assert response.status == 200 + assert_dialog_handled(session, "dismiss #2") + + create_dialog(session)("prompt", text="dismiss #3", result_var="dismiss3") + response = delete_cookie(session, "foo") + assert response.status == 200 + assert_dialog_handled(session, "dismiss #3") + + +def test_handle_prompt_missing_value(session, create_dialog): + """ + 2. Handle any user prompts and return its value if it is an error. + + [...] + + In order to handle any user prompts a remote end must take the + following steps: + + [...] + + 2. Perform the following substeps based on the current session's + user prompt handler: + + [...] + + - missing value default state + 1. Dismiss the current user prompt. + 2. Return error with error code unexpected alert open. + + """ + session.url = inline("WD doc title") + create_dialog("alert", text="dismiss #1", result_var="dismiss1") + + response = delete_cookie(session, "foo") + + assert_error(response, "unexpected alert open") + assert_dialog_handled(session, "dismiss #1") + + create_dialog("confirm", text="dismiss #2", result_var="dismiss2") + + response = delete_cookie(session, "foo") + assert_error(response, "unexpected alert open") + assert_dialog_handled(session, "dismiss #2") + + create_dialog("prompt", text="dismiss #3", result_var="dismiss3") + + response = delete_cookie(session, "foo") + assert_error(response, "unexpected alert open") + assert_dialog_handled(session, "dismiss #3") + + +def test_unknown_cookie(session): + response = delete_cookie(session, "stilton") + assert response.status == 200 + assert "value" in response.body + assert isinstance(response.body["value"], dict) + assert response.body["value"] == {} From 5a9cffd40a09306badf896f5ee4c9e2236a3bbcf Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Mon, 9 Oct 2017 22:03:18 +0200 Subject: [PATCH 32/68] Bug 1407026 - Fix CPOW class mistake in the console. r=nchevobbe MozReview-Commit-ID: LDmbQEuU3JE --HG-- extra : rebase_source : c1293c2780a22953a8783795a82d4db2e1b34540 --- .../new-console-output/test/mochitest/browser_console.js | 4 ++++ devtools/client/webconsole/test/browser_console.js | 4 ++++ devtools/server/actors/object.js | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js index c70039bec41c..e1a73a2cc7b6 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js @@ -197,4 +197,8 @@ function* testCPOWInspection(hud) { // Just a sanity check to make sure a valid packet came back is(prototypeAndProperties.prototype.class, "XBL prototype JSClass", "Looks like a valid response"); + + // The CPOW is in the _contentWindow property. + let cpow = prototypeAndProperties.ownProperties._contentWindow.value; + is(cpow.class, "CPOW: Window", "The CPOW grip has the right class."); } diff --git a/devtools/client/webconsole/test/browser_console.js b/devtools/client/webconsole/test/browser_console.js index c70039bec41c..e1a73a2cc7b6 100644 --- a/devtools/client/webconsole/test/browser_console.js +++ b/devtools/client/webconsole/test/browser_console.js @@ -197,4 +197,8 @@ function* testCPOWInspection(hud) { // Just a sanity check to make sure a valid packet came back is(prototypeAndProperties.prototype.class, "XBL prototype JSClass", "Looks like a valid response"); + + // The CPOW is in the _contentWindow property. + let cpow = prototypeAndProperties.ownProperties._contentWindow.value; + is(cpow.class, "CPOW: Window", "The CPOW grip has the right class."); } diff --git a/devtools/server/actors/object.js b/devtools/server/actors/object.js index db855c6dda0e..4539dcd7d413 100644 --- a/devtools/server/actors/object.js +++ b/devtools/server/actors/object.js @@ -83,7 +83,7 @@ ObjectActor.prototype = { let unwrapped = DevToolsUtils.unwrap(this.obj); if (!unwrapped) { if (DevToolsUtils.isCPOW(this.obj)) { - g.class = "CPOW: " + g.class; + g.class = "CPOW: " + this.obj.class; } else { g.class = "Inaccessible"; } From 3705a463732c32d24debf45f560fba5c86aabc55 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Mon, 9 Oct 2017 11:05:34 +0200 Subject: [PATCH 33/68] Bug 1402389 - CamelCase all React components oin devtools/client/memory/components; r=ystartsev+600802 MozReview-Commit-ID: 7xYrykIkLIv --HG-- rename : devtools/client/memory/components/census.js => devtools/client/memory/components/Census.js rename : devtools/client/memory/components/census-header.js => devtools/client/memory/components/CensusHeader.js rename : devtools/client/memory/components/census-tree-item.js => devtools/client/memory/components/CensusTreeItem.js rename : devtools/client/memory/components/dominator-tree.js => devtools/client/memory/components/DominatorTree.js rename : devtools/client/memory/components/dominator-tree-header.js => devtools/client/memory/components/DominatorTreeHeader.js rename : devtools/client/memory/components/dominator-tree-item.js => devtools/client/memory/components/DominatorTreeItem.js rename : devtools/client/memory/components/heap.js => devtools/client/memory/components/Heap.js rename : devtools/client/memory/components/individuals.js => devtools/client/memory/components/Individuals.js rename : devtools/client/memory/components/individuals-header.js => devtools/client/memory/components/IndividualsHeader.js rename : devtools/client/memory/components/list.js => devtools/client/memory/components/List.js rename : devtools/client/memory/components/shortest-paths.js => devtools/client/memory/components/ShortestPaths.js rename : devtools/client/memory/components/snapshot-list-item.js => devtools/client/memory/components/SnapshotListItem.js rename : devtools/client/memory/components/toolbar.js => devtools/client/memory/components/Toolbar.js rename : devtools/client/memory/components/tree-map.js => devtools/client/memory/components/TreeMap.js extra : rebase_source : 03964042473cbad89e83578b9dcf664f1b2f99ea --- devtools/client/memory/app.js | 8 +++--- .../components/{census.js => Census.js} | 2 +- .../{census-header.js => CensusHeader.js} | 0 ...{census-tree-item.js => CensusTreeItem.js} | 0 .../{dominator-tree.js => DominatorTree.js} | 2 +- ...-tree-header.js => DominatorTreeHeader.js} | 0 ...ator-tree-item.js => DominatorTreeItem.js} | 0 .../memory/components/{heap.js => Heap.js} | 16 +++++------ .../{individuals.js => Individuals.js} | 2 +- ...viduals-header.js => IndividualsHeader.js} | 0 .../memory/components/{list.js => List.js} | 0 .../{shortest-paths.js => ShortestPaths.js} | 0 ...pshot-list-item.js => SnapshotListItem.js} | 0 .../components/{toolbar.js => Toolbar.js} | 0 .../components/{tree-map.js => TreeMap.js} | 0 devtools/client/memory/components/moz.build | 28 +++++++++---------- devtools/client/memory/test/chrome/head.js | 18 ++++++------ devtools/client/themes/memory.css | 2 +- 18 files changed, 39 insertions(+), 39 deletions(-) rename devtools/client/memory/components/{census.js => Census.js} (97%) rename devtools/client/memory/components/{census-header.js => CensusHeader.js} (100%) rename devtools/client/memory/components/{census-tree-item.js => CensusTreeItem.js} (100%) rename devtools/client/memory/components/{dominator-tree.js => DominatorTree.js} (98%) rename devtools/client/memory/components/{dominator-tree-header.js => DominatorTreeHeader.js} (100%) rename devtools/client/memory/components/{dominator-tree-item.js => DominatorTreeItem.js} (100%) rename devtools/client/memory/components/{heap.js => Heap.js} (96%) rename devtools/client/memory/components/{individuals.js => Individuals.js} (95%) rename devtools/client/memory/components/{individuals-header.js => IndividualsHeader.js} (100%) rename devtools/client/memory/components/{list.js => List.js} (100%) rename devtools/client/memory/components/{shortest-paths.js => ShortestPaths.js} (100%) rename devtools/client/memory/components/{snapshot-list-item.js => SnapshotListItem.js} (100%) rename devtools/client/memory/components/{toolbar.js => Toolbar.js} (100%) rename devtools/client/memory/components/{tree-map.js => TreeMap.js} (100%) diff --git a/devtools/client/memory/app.js b/devtools/client/memory/app.js index 66e5b328f3bf..44189afe3208 100644 --- a/devtools/client/memory/app.js +++ b/devtools/client/memory/app.js @@ -45,10 +45,10 @@ const { } = require("./actions/snapshot"); const { changeViewAndRefresh, popViewAndRefresh } = require("./actions/view"); const { resizeShortestPaths } = require("./actions/sizes"); -const Toolbar = createFactory(require("./components/toolbar")); -const List = createFactory(require("./components/list")); -const SnapshotListItem = createFactory(require("./components/snapshot-list-item")); -const Heap = createFactory(require("./components/heap")); +const Toolbar = createFactory(require("./components/Toolbar")); +const List = createFactory(require("./components/List")); +const SnapshotListItem = createFactory(require("./components/SnapshotListItem")); +const Heap = createFactory(require("./components/Heap")); const { app: appModel } = require("./models"); const MemoryApp = createClass({ diff --git a/devtools/client/memory/components/census.js b/devtools/client/memory/components/Census.js similarity index 97% rename from devtools/client/memory/components/census.js rename to devtools/client/memory/components/Census.js index 3ca8984025be..b198a1c4ee99 100644 --- a/devtools/client/memory/components/census.js +++ b/devtools/client/memory/components/Census.js @@ -6,7 +6,7 @@ const { createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react"); const Tree = createFactory(require("devtools/client/shared/components/Tree")); -const CensusTreeItem = createFactory(require("./census-tree-item")); +const CensusTreeItem = createFactory(require("./CensusTreeItem")); const { TREE_ROW_HEIGHT } = require("../constants"); const { censusModel, diffingModel } = require("../models"); diff --git a/devtools/client/memory/components/census-header.js b/devtools/client/memory/components/CensusHeader.js similarity index 100% rename from devtools/client/memory/components/census-header.js rename to devtools/client/memory/components/CensusHeader.js diff --git a/devtools/client/memory/components/census-tree-item.js b/devtools/client/memory/components/CensusTreeItem.js similarity index 100% rename from devtools/client/memory/components/census-tree-item.js rename to devtools/client/memory/components/CensusTreeItem.js diff --git a/devtools/client/memory/components/dominator-tree.js b/devtools/client/memory/components/DominatorTree.js similarity index 98% rename from devtools/client/memory/components/dominator-tree.js rename to devtools/client/memory/components/DominatorTree.js index f720aeead6e4..b535490c69fa 100644 --- a/devtools/client/memory/components/dominator-tree.js +++ b/devtools/client/memory/components/DominatorTree.js @@ -8,7 +8,7 @@ const { DOM: dom, createClass, PropTypes, createFactory } = require("devtools/cl const { assert } = require("devtools/shared/DevToolsUtils"); const { createParentMap } = require("devtools/shared/heapsnapshot/CensusUtils"); const Tree = createFactory(require("devtools/client/shared/components/Tree")); -const DominatorTreeItem = createFactory(require("./dominator-tree-item")); +const DominatorTreeItem = createFactory(require("./DominatorTreeItem")); const { L10N } = require("../utils"); const { TREE_ROW_HEIGHT, dominatorTreeState } = require("../constants"); const { dominatorTreeModel } = require("../models"); diff --git a/devtools/client/memory/components/dominator-tree-header.js b/devtools/client/memory/components/DominatorTreeHeader.js similarity index 100% rename from devtools/client/memory/components/dominator-tree-header.js rename to devtools/client/memory/components/DominatorTreeHeader.js diff --git a/devtools/client/memory/components/dominator-tree-item.js b/devtools/client/memory/components/DominatorTreeItem.js similarity index 100% rename from devtools/client/memory/components/dominator-tree-item.js rename to devtools/client/memory/components/DominatorTreeItem.js diff --git a/devtools/client/memory/components/heap.js b/devtools/client/memory/components/Heap.js similarity index 96% rename from devtools/client/memory/components/heap.js rename to devtools/client/memory/components/Heap.js index 661ef34d9bff..6565446c1dea 100644 --- a/devtools/client/memory/components/heap.js +++ b/devtools/client/memory/components/Heap.js @@ -6,15 +6,15 @@ const { DOM: dom, createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react"); const { assert, safeErrorString } = require("devtools/shared/DevToolsUtils"); -const Census = createFactory(require("./census")); -const CensusHeader = createFactory(require("./census-header")); -const DominatorTree = createFactory(require("./dominator-tree")); -const DominatorTreeHeader = createFactory(require("./dominator-tree-header")); -const TreeMap = createFactory(require("./tree-map")); +const Census = createFactory(require("./Census")); +const CensusHeader = createFactory(require("./CensusHeader")); +const DominatorTree = createFactory(require("./DominatorTree")); +const DominatorTreeHeader = createFactory(require("./DominatorTreeHeader")); +const TreeMap = createFactory(require("./TreeMap")); const HSplitBox = createFactory(require("devtools/client/shared/components/HSplitBox")); -const Individuals = createFactory(require("./individuals")); -const IndividualsHeader = createFactory(require("./individuals-header")); -const ShortestPaths = createFactory(require("./shortest-paths")); +const Individuals = createFactory(require("./Individuals")); +const IndividualsHeader = createFactory(require("./IndividualsHeader")); +const ShortestPaths = createFactory(require("./ShortestPaths")); const { getStatusTextFull, L10N } = require("../utils"); const { snapshotState: states, diff --git a/devtools/client/memory/components/individuals.js b/devtools/client/memory/components/Individuals.js similarity index 95% rename from devtools/client/memory/components/individuals.js rename to devtools/client/memory/components/Individuals.js index 891d78f32734..44f817046c90 100644 --- a/devtools/client/memory/components/individuals.js +++ b/devtools/client/memory/components/Individuals.js @@ -6,7 +6,7 @@ const { createClass, PropTypes, createFactory } = require("devtools/client/shared/vendor/react"); const Tree = createFactory(require("devtools/client/shared/components/Tree")); -const DominatorTreeItem = createFactory(require("./dominator-tree-item")); +const DominatorTreeItem = createFactory(require("./DominatorTreeItem")); const { TREE_ROW_HEIGHT } = require("../constants"); const models = require("../models"); diff --git a/devtools/client/memory/components/individuals-header.js b/devtools/client/memory/components/IndividualsHeader.js similarity index 100% rename from devtools/client/memory/components/individuals-header.js rename to devtools/client/memory/components/IndividualsHeader.js diff --git a/devtools/client/memory/components/list.js b/devtools/client/memory/components/List.js similarity index 100% rename from devtools/client/memory/components/list.js rename to devtools/client/memory/components/List.js diff --git a/devtools/client/memory/components/shortest-paths.js b/devtools/client/memory/components/ShortestPaths.js similarity index 100% rename from devtools/client/memory/components/shortest-paths.js rename to devtools/client/memory/components/ShortestPaths.js diff --git a/devtools/client/memory/components/snapshot-list-item.js b/devtools/client/memory/components/SnapshotListItem.js similarity index 100% rename from devtools/client/memory/components/snapshot-list-item.js rename to devtools/client/memory/components/SnapshotListItem.js diff --git a/devtools/client/memory/components/toolbar.js b/devtools/client/memory/components/Toolbar.js similarity index 100% rename from devtools/client/memory/components/toolbar.js rename to devtools/client/memory/components/Toolbar.js diff --git a/devtools/client/memory/components/tree-map.js b/devtools/client/memory/components/TreeMap.js similarity index 100% rename from devtools/client/memory/components/tree-map.js rename to devtools/client/memory/components/TreeMap.js diff --git a/devtools/client/memory/components/moz.build b/devtools/client/memory/components/moz.build index 529454dd92f8..5172333c08d7 100644 --- a/devtools/client/memory/components/moz.build +++ b/devtools/client/memory/components/moz.build @@ -8,18 +8,18 @@ DIRS += [ ] DevToolsModules( - 'census-header.js', - 'census-tree-item.js', - 'census.js', - 'dominator-tree-header.js', - 'dominator-tree-item.js', - 'dominator-tree.js', - 'heap.js', - 'individuals-header.js', - 'individuals.js', - 'list.js', - 'shortest-paths.js', - 'snapshot-list-item.js', - 'toolbar.js', - 'tree-map.js', + 'Census.js', + 'CensusHeader.js', + 'CensusTreeItem.js', + 'DominatorTree.js', + 'DominatorTreeHeader.js', + 'DominatorTreeItem.js', + 'Heap.js', + 'Individuals.js', + 'IndividualsHeader.js', + 'List.js', + 'ShortestPaths.js', + 'SnapshotListItem.js', + 'Toolbar.js', + 'TreeMap.js', ) diff --git a/devtools/client/memory/test/chrome/head.js b/devtools/client/memory/test/chrome/head.js index 00fb4c4823b0..591aab2be5e3 100644 --- a/devtools/client/memory/test/chrome/head.js +++ b/devtools/client/memory/test/chrome/head.js @@ -49,15 +49,15 @@ var models = require("devtools/client/memory/models"); var Immutable = require("devtools/client/shared/vendor/immutable"); var React = require("devtools/client/shared/vendor/react"); var ReactDOM = require("devtools/client/shared/vendor/react-dom"); -var Heap = React.createFactory(require("devtools/client/memory/components/heap")); -var CensusTreeItem = React.createFactory(require("devtools/client/memory/components/census-tree-item")); -var DominatorTreeComponent = React.createFactory(require("devtools/client/memory/components/dominator-tree")); -var DominatorTreeItem = React.createFactory(require("devtools/client/memory/components/dominator-tree-item")); -var ShortestPaths = React.createFactory(require("devtools/client/memory/components/shortest-paths")); -var TreeMap = React.createFactory(require("devtools/client/memory/components/tree-map")); -var SnapshotListItem = React.createFactory(require("devtools/client/memory/components/snapshot-list-item")); -var List = React.createFactory(require("devtools/client/memory/components/list")); -var Toolbar = React.createFactory(require("devtools/client/memory/components/toolbar")); +var Heap = React.createFactory(require("devtools/client/memory/components/Heap")); +var CensusTreeItem = React.createFactory(require("devtools/client/memory/components/CensusTreeItem")); +var DominatorTreeComponent = React.createFactory(require("devtools/client/memory/components/DominatorTree")); +var DominatorTreeItem = React.createFactory(require("devtools/client/memory/components/DominatorTreeItem")); +var ShortestPaths = React.createFactory(require("devtools/client/memory/components/ShortestPaths")); +var TreeMap = React.createFactory(require("devtools/client/memory/components/TreeMap")); +var SnapshotListItem = React.createFactory(require("devtools/client/memory/components/SnapshotListItem")); +var List = React.createFactory(require("devtools/client/memory/components/List")); +var Toolbar = React.createFactory(require("devtools/client/memory/components/Toolbar")); // All tests are asynchronous. SimpleTest.waitForExplicitFinish(); diff --git a/devtools/client/themes/memory.css b/devtools/client/themes/memory.css index c7afd55affca..16875377d09a 100644 --- a/devtools/client/themes/memory.css +++ b/devtools/client/themes/memory.css @@ -34,7 +34,7 @@ html, body, #app, #memory-tool { --sidebar-width: 185px; /** * If --heap-tree-row-height changes, be sure to change HEAP_TREE_ROW_HEIGHT - * in `devtools/client/memory/components/heap.js`. + * in `devtools/client/memory/components/Heap.js`. */ --heap-tree-row-height: 18px; --heap-tree-header-height: 18px; From 2acc2e8b7e4fd96f4ae6f763777af4ee68d83e1f Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Fri, 6 Oct 2017 12:42:11 +0200 Subject: [PATCH 34/68] Bug 1406027 - Always use the mixer so AudioCallbackDriver can track processed samples. r=padenot This is unnecessary work but simpler than adding a path to, or refactoring, AudioCallbackDriver::DataCallback. MozReview-Commit-ID: GLNoBqxEuwz --HG-- extra : rebase_source : b5ef6b2e1506e68d41b22ad557968d70214fbd9f --- dom/media/AudioMixer.h | 7 ++++++- dom/media/MediaStreamGraph.cpp | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dom/media/AudioMixer.h b/dom/media/AudioMixer.h index c86aa33455b3..1df492997ece 100644 --- a/dom/media/AudioMixer.h +++ b/dom/media/AudioMixer.h @@ -73,7 +73,8 @@ public: mSampleRate = mChannels = mFrames = 0; } - /* Add a buffer to the mix. */ + /* Add a buffer to the mix. The buffer can be null if there's nothing to mix + * but the callback is still needed. */ void Mix(AudioDataValue* aSamples, uint32_t aChannels, uint32_t aFrames, @@ -89,6 +90,10 @@ public: MOZ_ASSERT(aChannels == mChannels); MOZ_ASSERT(aSampleRate == mSampleRate); + if (!aSamples) { + return; + } + for (uint32_t i = 0; i < aFrames * aChannels; i++) { mMixedAudio[i] += aSamples[i]; } diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index d75ac5ace38a..5bfaff9cc41f 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1401,7 +1401,16 @@ MediaStreamGraphImpl::Process() } } - if (CurrentDriver()->AsAudioCallbackDriver() && ticksPlayed) { + if (CurrentDriver()->AsAudioCallbackDriver()) { + if (!ticksPlayed) { + // Nothing was played, so the mixer doesn't know how many frames were + // processed. We still tell it so AudioCallbackDriver knows how much has + // been processed. (bug 1406027) + mMixer.Mix(nullptr, + CurrentDriver()->AsAudioCallbackDriver()->OutputChannelCount(), + mStateComputedTime - mProcessedTime, + mSampleRate); + } mMixer.FinishMixing(); } From 240fb73d6883f21d444f369a6c3fdd36c680894f Mon Sep 17 00:00:00 2001 From: Dale Harvey Date: Tue, 10 Oct 2017 13:07:59 +0100 Subject: [PATCH 35/68] Bug 1407007 - Fix RTL alignment of search icon. r=dao MozReview-Commit-ID: BT8ZVOIPQND --HG-- extra : rebase_source : 116e4d7309df66bf406a9c480389fe9879007fd4 --- browser/themes/shared/urlbar-searchbar.inc.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/browser/themes/shared/urlbar-searchbar.inc.css b/browser/themes/shared/urlbar-searchbar.inc.css index 4bc27fc00fff..6a01f822b335 100644 --- a/browser/themes/shared/urlbar-searchbar.inc.css +++ b/browser/themes/shared/urlbar-searchbar.inc.css @@ -402,6 +402,11 @@ height: 11px; } +.searchbar-search-button[addengines=true] > .searchbar-search-icon-overlay:-moz-locale-dir(rtl) { + margin-inline-start: -25px; + margin-inline-end: 14px; +} + .searchbar-search-button:hover:not([addengines=true]) > .searchbar-search-icon-overlay { list-style-image: url(chrome://global/skin/icons/arrow-dropdown-12.svg); -moz-context-properties: fill; @@ -410,3 +415,8 @@ width: 6px; height: 6px; } + +.searchbar-search-button:hover:not([addengines=true]) > .searchbar-search-icon-overlay:-moz-locale-dir(rtl) { + margin-inline-start: -26px; + margin-inline-end: 20px; +} From 880fdf7f5e4185e7e77446c4ed64425ba0c3ddc4 Mon Sep 17 00:00:00 2001 From: Dale Harvey Date: Mon, 9 Oct 2017 13:23:05 +0100 Subject: [PATCH 36/68] Bug 1402290 - Update notification alignment. r=dao MozReview-Commit-ID: 4Oxqtl9wEig --HG-- extra : rebase_source : 221c3c60bbc554abd0983ab78e2164bd9efcf979 --- toolkit/themes/shared/notification.inc.css | 1 + 1 file changed, 1 insertion(+) diff --git a/toolkit/themes/shared/notification.inc.css b/toolkit/themes/shared/notification.inc.css index 6e44904a3fd2..1767c4d5713c 100644 --- a/toolkit/themes/shared/notification.inc.css +++ b/toolkit/themes/shared/notification.inc.css @@ -40,6 +40,7 @@ notification[type="critical"] { .messageText { margin-inline-start: 12px !important; + margin-bottom: 1px !important; } .messageText > .text-link { From 1200f0d0cb0a03f541a39e2c30a221f0c102dd5f Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 10 Oct 2017 06:17:15 -0500 Subject: [PATCH 37/68] =?UTF-8?q?servo:=20Merge=20#18804=20-=20Another=20c?= =?UTF-8?q?ouple=20of=20low-key=20media=20improvements=20=F0=9F=91=B6?= =?UTF-8?q?=F0=9F=91=A3=20(from=20servo:media);=20r=3Demilio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Source-Repo: https://github.com/servo/servo Source-Revision: 826352ab4cae13f5154d13ab53885d80a8057337 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 76086eaff3ce8c62041c2ffadfb24cbd7d9b9183 --- .../components/script/dom/htmlmediaelement.rs | 41 +++++++++++++------ .../dom/webidls/HTMLMediaElement.webidl | 39 ++++++++---------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/servo/components/script/dom/htmlmediaelement.rs b/servo/components/script/dom/htmlmediaelement.rs index 0d66f1d63aa2..739025544e7b 100644 --- a/servo/components/script/dom/htmlmediaelement.rs +++ b/servo/components/script/dom/htmlmediaelement.rs @@ -20,6 +20,7 @@ use dom::bindings::refcounted::Trusted; use dom::bindings::reflector::DomObject; use dom::bindings::root::{DomRoot, MutNullableDom}; use dom::bindings::str::DOMString; +use dom::blob::Blob; use dom::document::Document; use dom::element::{Element, AttributeMutation}; use dom::eventtarget::EventTarget; @@ -57,6 +58,8 @@ pub struct HTMLMediaElement { network_state: Cell, /// https://html.spec.whatwg.org/multipage/#dom-media-readystate ready_state: Cell, + /// https://html.spec.whatwg.org/multipage/#dom-media-srcobject + src_object: MutNullableDom, /// https://html.spec.whatwg.org/multipage/#dom-media-currentsrc current_src: DomRefCell, /// Incremented whenever tasks associated with this element are cancelled. @@ -112,6 +115,7 @@ impl HTMLMediaElement { htmlelement: HTMLElement::new_inherited(tag_name, prefix, document), network_state: Cell::new(NetworkState::Empty), ready_state: Cell::new(ReadyState::HaveNothing), + src_object: Default::default(), current_src: DomRefCell::new("".to_owned()), generation_id: Cell::new(0), fired_loadeddata_event: Cell::new(false), @@ -430,6 +434,7 @@ impl HTMLMediaElement { let doc = document_from_node(self); let task = MediaElementMicrotask::ResourceSelectionTask { elem: DomRoot::from_ref(self), + generation_id: self.generation_id.get(), base_url: doc.base_url() }; @@ -447,13 +452,14 @@ impl HTMLMediaElement { // Step 6. enum Mode { - // FIXME(nox): Support media object provider. - #[allow(dead_code)] Object, Attribute(String), Children(DomRoot), } fn mode(media: &HTMLMediaElement) -> Option { + if media.src_object.get().is_some() { + return Some(Mode::Object); + } if let Some(attr) = media.upcast::().get_attribute(&ns!(), &local_name!("src")) { return Some(Mode::Attribute(attr.Value().into())); } @@ -499,7 +505,6 @@ impl HTMLMediaElement { // Step 9.obj.3. // Note that the resource fetch algorithm itself takes care // of the cleanup in case of failure itself. - // FIXME(nox): Pass the assigned media provider here. self.resource_fetch_algorithm(Resource::Object); }, Mode::Attribute(src) => { @@ -612,7 +617,7 @@ impl HTMLMediaElement { document.loader().fetch_async_background(request, action_sender); }, Resource::Object => { - // FIXME(nox): Use the current media resource. + // FIXME(nox): Actually do something with the object. self.queue_dedicated_media_source_failure_steps(); }, } @@ -672,12 +677,10 @@ impl HTMLMediaElement { // this invokation of the load algorithm. self.fired_loadeddata_event.set(false); - // Step 1. - // FIXME(nox): Abort any already-running instance of the - // resource selection algorithm. - - // Steps 2-4. + // Step 1-2. self.generation_id.set(self.generation_id.get() + 1); + + // Steps 3-4. while !self.in_flight_play_promises_queue.borrow().is_empty() { self.fulfill_in_flight_play_promises(|| ()); } @@ -837,6 +840,17 @@ impl HTMLMediaElementMethods for HTMLMediaElement { // https://html.spec.whatwg.org/multipage/#dom-media-src make_setter!(SetSrc, "src"); + // https://html.spec.whatwg.org/multipage/#dom-media-srcobject + fn GetSrcObject(&self) -> Option> { + self.src_object.get() + } + + // https://html.spec.whatwg.org/multipage/#dom-media-srcobject + fn SetSrcObject(&self, value: Option<&Blob>) { + self.src_object.set(value); + self.media_element_load_algorithm(); + } + // https://html.spec.whatwg.org/multipage/#attr-media-preload // Missing value default is user-agent defined. make_enumerated_getter!(Preload, "preload", "", "none" | "metadata" | "auto"); @@ -929,7 +943,8 @@ impl VirtualMethods for HTMLMediaElement { pub enum MediaElementMicrotask { ResourceSelectionTask { elem: DomRoot, - base_url: ServoUrl + generation_id: u32, + base_url: ServoUrl, }, PauseIfNotInDocumentTask { elem: DomRoot, @@ -939,8 +954,10 @@ pub enum MediaElementMicrotask { impl MicrotaskRunnable for MediaElementMicrotask { fn handler(&self) { match self { - &MediaElementMicrotask::ResourceSelectionTask { ref elem, ref base_url } => { - elem.resource_selection_algorithm_sync(base_url.clone()); + &MediaElementMicrotask::ResourceSelectionTask { ref elem, generation_id, ref base_url } => { + if generation_id == elem.generation_id.get() { + elem.resource_selection_algorithm_sync(base_url.clone()); + } }, &MediaElementMicrotask::PauseIfNotInDocumentTask { ref elem } => { if !elem.upcast::().is_in_doc() { diff --git a/servo/components/script/dom/webidls/HTMLMediaElement.webidl b/servo/components/script/dom/webidls/HTMLMediaElement.webidl index b9c112bf44d9..b67a5e3c1fef 100644 --- a/servo/components/script/dom/webidls/HTMLMediaElement.webidl +++ b/servo/components/script/dom/webidls/HTMLMediaElement.webidl @@ -3,25 +3,26 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://html.spec.whatwg.org/multipage/#htmlmediaelement + enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" }; +typedef /* (MediaStream or MediaSource or */ Blob /* ) */ MediaProvider; + [Abstract] interface HTMLMediaElement : HTMLElement { // error state readonly attribute MediaError? error; // network state - [CEReactions] - attribute DOMString src; + [CEReactions] attribute DOMString src; + attribute MediaProvider? srcObject; readonly attribute DOMString currentSrc; - // [CEReactions] - // attribute DOMString crossOrigin; + // [CEReactions] attribute DOMString crossOrigin; const unsigned short NETWORK_EMPTY = 0; const unsigned short NETWORK_IDLE = 1; const unsigned short NETWORK_LOADING = 2; const unsigned short NETWORK_NO_SOURCE = 3; readonly attribute unsigned short networkState; - [CEReactions] - attribute DOMString preload; + [CEReactions] attribute DOMString preload; // readonly attribute TimeRanges buffered; void load(); CanPlayTypeResult canPlayType(DOMString type); @@ -36,34 +37,26 @@ interface HTMLMediaElement : HTMLElement { // readonly attribute boolean seeking; // playback state - // attribute double currentTime; + // attribute double currentTime; // void fastSeek(double time); // readonly attribute unrestricted double duration; // Date getStartDate(); readonly attribute boolean paused; - // attribute double defaultPlaybackRate; - // attribute double playbackRate; + // attribute double defaultPlaybackRate; + // attribute double playbackRate; // readonly attribute TimeRanges played; // readonly attribute TimeRanges seekable; // readonly attribute boolean ended; - [CEReactions] - attribute boolean autoplay; - // [CEReactions] - // attribute boolean loop; + [CEReactions] attribute boolean autoplay; + // [CEReactions] attribute boolean loop; Promise play(); void pause(); - // media controller - // attribute DOMString mediaGroup; - // attribute MediaController? controller; - // controls - // [CEReactions] - // attribute boolean controls; - // attribute double volume; - // attribute boolean muted; - // [CEReactions] - // attribute boolean defaultMuted; + // [CEReactions] attribute boolean controls; + // attribute double volume; + // attribute boolean muted; + // [CEReactions] attribute boolean defaultMuted; // tracks // readonly attribute AudioTrackList audioTracks; From dc06aafe95888a72c484dfce19257572d3529b5b Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Wed, 4 Oct 2017 13:29:53 +0100 Subject: [PATCH 38/68] Bug 1404651 - keep focus in the tabstrip when the focus has shifted with the arrow keys, r=dao MozReview-Commit-ID: Brm9jImW9bc --HG-- extra : rebase_source : 2dcce2264bde286e07f20fbf944ce1f73d89602b --- browser/base/content/tabbrowser.xml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 199bb33858f8..672593367822 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1423,13 +1423,11 @@ findBar._findField.getAttribute("focused") == "true"); } - // If focus is in the tab bar, retain it there. - if (document.activeElement == oldTab) { - // We need to explicitly focus the new tab, because - // tabbox.xml does this only in some cases. - newTab.focus(); - } else if (gMultiProcessBrowser && document.activeElement !== newBrowser) { - + let activeEl = document.activeElement; + // In e10s, if focus isn't already in the tabstrip or on the new browser, + // and the new browser's previous focus wasn't in the url bar but focus is + // there now, we need to adjust focus further. + if (gMultiProcessBrowser && activeEl != newBrowser && activeEl != newTab) { let keepFocusOnUrlBar = newBrowser && newBrowser._urlbarFocused && gURLBar && From f05a6f95b84a27c0333b54a9ea93db53c391603b Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 10 Oct 2017 08:01:29 -0400 Subject: [PATCH 39/68] Bug 1405790 - Update webrender to commit 6440dff485271cdfd24a22c920cea31e01e2b164. r=Gankro MozReview-Commit-ID: JRPtTtZ1jNz --HG-- extra : rebase_source : 25d5198d1ddc09c7345e3ef77ef7a40f4f5a2b31 --- gfx/doc/README.webrender | 2 +- gfx/webrender/Cargo.toml | 2 +- gfx/webrender/examples/nested_display_list.rs | 158 ------ gfx/webrender/res/cs_clip_rectangle.glsl | 23 +- gfx/webrender/res/cs_text_run.glsl | 2 +- gfx/webrender/res/prim_shared.glsl | 3 +- gfx/webrender/res/ps_border_corner.glsl | 46 +- .../res/ps_hardware_composite.fs.glsl | 8 - gfx/webrender/res/ps_hardware_composite.glsl | 31 ++ .../res/ps_hardware_composite.vs.glsl | 25 - gfx/webrender/res/ps_radial_gradient.glsl | 17 +- gfx/webrender/res/ps_text_run.glsl | 11 +- gfx/webrender/src/device.rs | 5 + gfx/webrender/src/frame.rs | 126 +---- gfx/webrender/src/frame_builder.rs | 107 ++-- gfx/webrender/src/glyph_cache.rs | 1 + gfx/webrender/src/glyph_rasterizer.rs | 38 +- gfx/webrender/src/lib.rs | 1 + gfx/webrender/src/picture.rs | 79 +++ gfx/webrender/src/platform/macos/font.rs | 15 +- gfx/webrender/src/platform/unix/font.rs | 479 +++++++++++++----- gfx/webrender/src/platform/windows/font.rs | 41 +- gfx/webrender/src/prim_store.rs | 128 ++--- gfx/webrender/src/render_backend.rs | 2 - gfx/webrender/src/render_task.rs | 21 +- gfx/webrender/src/renderer.rs | 6 +- gfx/webrender/src/resource_cache.rs | 47 +- gfx/webrender/src/texture_cache.rs | 14 +- gfx/webrender/src/tiling.rs | 135 ++--- gfx/webrender/src/util.rs | 5 + gfx/webrender_api/Cargo.toml | 3 +- gfx/webrender_api/src/display_item.rs | 19 +- gfx/webrender_api/src/display_list.rs | 233 +++++---- gfx/webrender_api/src/font.rs | 114 ++++- gfx/webrender_api/src/lib.rs | 5 - gfx/webrender_bindings/Cargo.toml | 4 +- .../webrender_ffi_generated.h | 44 +- toolkit/library/gtest/rust/Cargo.lock | 11 +- toolkit/library/rust/Cargo.lock | 11 +- 39 files changed, 1120 insertions(+), 902 deletions(-) delete mode 100644 gfx/webrender/examples/nested_display_list.rs delete mode 100644 gfx/webrender/res/ps_hardware_composite.fs.glsl delete mode 100644 gfx/webrender/res/ps_hardware_composite.vs.glsl create mode 100644 gfx/webrender/src/picture.rs diff --git a/gfx/doc/README.webrender b/gfx/doc/README.webrender index 993786fddd97..72650ce82ba3 100644 --- a/gfx/doc/README.webrender +++ b/gfx/doc/README.webrender @@ -79,4 +79,4 @@ to make sure that mozjs_sys also has its Cargo.lock file updated if needed, henc the need to run the cargo update command in js/src as well. Hopefully this will be resolved soon. -Latest Commit: a884e676449e5b41669cd6de51af14e70cbe3512 +Latest Commit: 6440dff485271cdfd24a22c920cea31e01e2b164 diff --git a/gfx/webrender/Cargo.toml b/gfx/webrender/Cargo.toml index ad297b50f617..3f587831059f 100644 --- a/gfx/webrender/Cargo.toml +++ b/gfx/webrender/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webrender" -version = "0.52.0" +version = "0.52.1" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" diff --git a/gfx/webrender/examples/nested_display_list.rs b/gfx/webrender/examples/nested_display_list.rs deleted file mode 100644 index 1f532367eec2..000000000000 --- a/gfx/webrender/examples/nested_display_list.rs +++ /dev/null @@ -1,158 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -extern crate gleam; -extern crate glutin; -extern crate webrender; - -#[path = "common/boilerplate.rs"] -mod boilerplate; - -use boilerplate::{Example, HandyDandyRectBuilder}; -use webrender::api::*; - -struct App { - cursor_position: WorldPoint, -} - -impl Example for App { - fn render( - &mut self, - _api: &RenderApi, - builder: &mut DisplayListBuilder, - _resources: &mut ResourceUpdates, - layout_size: LayoutSize, - pipeline_id: PipelineId, - _document_id: DocumentId, - ) { - let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size); - let info = LayoutPrimitiveInfo::new(bounds); - builder.push_stacking_context( - &info, - ScrollPolicy::Scrollable, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new(), - ); - - let outer_scroll_frame_rect = (100, 100).to(600, 400); - let info = LayoutPrimitiveInfo::new(outer_scroll_frame_rect); - builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0)); - - let nested_clip_id = builder.define_scroll_frame( - None, - (100, 100).to(1000, 1000), - outer_scroll_frame_rect, - vec![], - None, - ScrollSensitivity::ScriptAndInputEvents, - ); - builder.push_clip_id(nested_clip_id); - - let mut builder2 = DisplayListBuilder::new(pipeline_id, layout_size); - let mut builder3 = DisplayListBuilder::new(pipeline_id, layout_size); - - let info = LayoutPrimitiveInfo::new((110, 110).to(210, 210)); - builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); - - // A fixed position rectangle should be fixed to the reference frame that starts - // in the outer display list. - let info = LayoutPrimitiveInfo::new((220, 110).to(320, 210)); - builder3.push_stacking_context( - &info, - ScrollPolicy::Fixed, - None, - TransformStyle::Flat, - None, - MixBlendMode::Normal, - Vec::new(), - ); - - let info = LayoutPrimitiveInfo::new((0, 0).to(100, 100)); - builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); - builder3.pop_stacking_context(); - - // Now we push an inner scroll frame that should have the same id as the outer one, - // but the WebRender nested display list replacement code should convert it into - // a unique ClipId. - let inner_scroll_frame_rect = (330, 110).to(530, 360); - let info = LayoutPrimitiveInfo::new(inner_scroll_frame_rect); - builder3.push_rect(&info, ColorF::new(1.0, 0.0, 1.0, 0.5)); - let inner_nested_clip_id = builder3.define_scroll_frame( - None, - (330, 110).to(2000, 2000), - inner_scroll_frame_rect, - vec![], - None, - ScrollSensitivity::ScriptAndInputEvents, - ); - builder3.push_clip_id(inner_nested_clip_id); - let info = LayoutPrimitiveInfo::new((340, 120).to(440, 220)); - builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0)); - builder3.pop_clip_id(); - - let (_, _, built_list) = builder3.finalize(); - builder2.push_nested_display_list(&built_list); - let (_, _, built_list) = builder2.finalize(); - builder.push_nested_display_list(&built_list); - - builder.pop_clip_id(); - - builder.pop_stacking_context(); - } - - fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool { - match event { - glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => { - let offset = match key { - glutin::VirtualKeyCode::Down => (0.0, -10.0), - glutin::VirtualKeyCode::Up => (0.0, 10.0), - glutin::VirtualKeyCode::Right => (-10.0, 0.0), - glutin::VirtualKeyCode::Left => (10.0, 0.0), - _ => return false, - }; - - api.scroll( - document_id, - ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)), - self.cursor_position, - ScrollEventPhase::Start, - ); - } - glutin::Event::MouseMoved(x, y) => { - self.cursor_position = WorldPoint::new(x as f32, y as f32); - } - glutin::Event::MouseWheel(delta, _, event_cursor_position) => { - if let Some((x, y)) = event_cursor_position { - self.cursor_position = WorldPoint::new(x as f32, y as f32); - } - - const LINE_HEIGHT: f32 = 38.0; - let (dx, dy) = match delta { - glutin::MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT), - glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy), - }; - - api.scroll( - document_id, - ScrollLocation::Delta(LayoutVector2D::new(dx, dy)), - self.cursor_position, - ScrollEventPhase::Start, - ); - } - _ => (), - } - - false - } -} - -fn main() { - let mut app = App { - cursor_position: WorldPoint::zero(), - }; - boilerplate::main_wrapper(&mut app, None); -} diff --git a/gfx/webrender/res/cs_clip_rectangle.glsl b/gfx/webrender/res/cs_clip_rectangle.glsl index a8aec7955cbe..c15d07eaa916 100644 --- a/gfx/webrender/res/cs_clip_rectangle.glsl +++ b/gfx/webrender/res/cs_clip_rectangle.glsl @@ -27,8 +27,7 @@ struct ClipCorner { vec4 outer_inner_radius; }; -ClipCorner fetch_clip_corner(ivec2 address, int index) { - address += ivec2(2 + 2 * index, 0); +ClipCorner fetch_clip_corner(ivec2 address) { vec4 data[2] = fetch_from_resource_cache_2_direct(address); return ClipCorner(RectWithSize(data[0].xy, data[0].zw), data[1]); } @@ -45,10 +44,22 @@ ClipData fetch_clip(ivec2 address) { ClipData clip; clip.rect = fetch_clip_rect(address); - clip.top_left = fetch_clip_corner(address, 0); - clip.top_right = fetch_clip_corner(address, 1); - clip.bottom_left = fetch_clip_corner(address, 2); - clip.bottom_right = fetch_clip_corner(address, 3); + + // Read the corners in groups of two texels, and adjust the read address + // before every read. + // The address adjustment is done inside this function, and not by passing + // the corner index to fetch_clip_corner and computing the correct address + // there, because doing so was hitting a driver bug on certain Intel macOS + // drivers which creates wrong results when doing arithmetic with integer + // variables (under certain, unknown, circumstances). + address.x += 2; + clip.top_left = fetch_clip_corner(address); + address.x += 2; + clip.top_right = fetch_clip_corner(address); + address.x += 2; + clip.bottom_left = fetch_clip_corner(address); + address.x += 2; + clip.bottom_right = fetch_clip_corner(address); return clip; } diff --git a/gfx/webrender/res/cs_text_run.glsl b/gfx/webrender/res/cs_text_run.glsl index 9eaf6e0b0aa8..772f8510f82b 100644 --- a/gfx/webrender/res/cs_text_run.glsl +++ b/gfx/webrender/res/cs_text_run.glsl @@ -38,7 +38,7 @@ void main(void) { // Glyphs size is already in device-pixels. // The render task origin is in device-pixels. Offset that by // the glyph offset, relative to its primitive bounding rect. - vec2 size = res.uv_rect.zw - res.uv_rect.xy; + vec2 size = (res.uv_rect.zw - res.uv_rect.xy) * res.scale; vec2 local_pos = glyph.offset + vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio; vec2 origin = prim.task.render_target_origin + uDevicePixelRatio * (local_pos + shadow.offset - shadow_geom.local_rect.p0); diff --git a/gfx/webrender/res/prim_shared.glsl b/gfx/webrender/res/prim_shared.glsl index f568f224ae80..9156da91dc03 100644 --- a/gfx/webrender/res/prim_shared.glsl +++ b/gfx/webrender/res/prim_shared.glsl @@ -627,11 +627,12 @@ struct GlyphResource { vec4 uv_rect; float layer; vec2 offset; + float scale; }; GlyphResource fetch_glyph_resource(int address) { vec4 data[2] = fetch_from_resource_cache_2(address); - return GlyphResource(data[0], data[1].x, data[1].yz); + return GlyphResource(data[0], data[1].x, data[1].yz, data[1].w); } struct ImageResource { diff --git a/gfx/webrender/res/ps_border_corner.glsl b/gfx/webrender/res/ps_border_corner.glsl index c3ce7f4794d0..0f39a48e7484 100644 --- a/gfx/webrender/res/ps_border_corner.glsl +++ b/gfx/webrender/res/ps_border_corner.glsl @@ -110,10 +110,10 @@ void write_color(vec4 color0, vec4 color1, int style, vec2 delta, int instance_k break; } - vColor00 = vec4(color0.rgb * modulate.x, color0.a); - vColor01 = vec4(color0.rgb * modulate.y, color0.a); - vColor10 = vec4(color1.rgb * modulate.z, color1.a); - vColor11 = vec4(color1.rgb * modulate.w, color1.a); + vColor00 = vec4(clamp(color0.rgb * modulate.x, vec3(0.0), vec3(1.0)), color0.a); + vColor01 = vec4(clamp(color0.rgb * modulate.y, vec3(0.0), vec3(1.0)), color0.a); + vColor10 = vec4(clamp(color1.rgb * modulate.z, vec3(0.0), vec3(1.0)), color1.a); + vColor11 = vec4(clamp(color1.rgb * modulate.w, vec3(0.0), vec3(1.0)), color1.a); } int select_style(int color_select, vec2 fstyle) { @@ -325,8 +325,11 @@ void main(void) { alpha = min(alpha, do_clip()); // Find the appropriate distance to apply the AA smoothstep over. + // Using 0.7 instead of 0.5 for the step compensates for the fact that smoothstep + // is smooth at its endpoints and has a steeper maximum slope than a linear ramp. vec2 fw = fwidth(local_pos); - float afwidth = length(fw); + float aa_step = 0.7 * length(fw); + float distance_for_color; float color_mix_factor; @@ -336,28 +339,39 @@ void main(void) { if (all(lessThan(local_pos * vClipSign, vClipCenter * vClipSign))) { vec2 p = local_pos - vClipCenter; + // The coordinate system is snapped to pixel boundaries. To sample the distance, + // however, we are interested in the center of the pixels which introduces an + // error of half a pixel towards the exterior of the curve (See issue #1750). + // This error is corrected by offsetting the distance by half a device pixel. + // This not entirely correct: it leaves an error that varries between + // 0 and (sqrt(2) - 1)/2 = 0.2 pixels but it is hardly noticeable and is better + // than the constant sqrt(2)/2 px error without the correction. + // To correct this exactly we would need to offset p by half a pixel in the + // direction of the center of the ellipse (a different offset for each corner). + + // A half device pixel in css pixels (using the average of width and height in case + // there is any kind of transform applied). + float half_px = 0.25 * (fw.x + fw.y); // Get signed distance from the inner/outer clips. - float d0 = distance_to_ellipse(p, vRadii0.xy); - float d1 = distance_to_ellipse(p, vRadii0.zw); - float d2 = distance_to_ellipse(p, vRadii1.xy); - float d3 = distance_to_ellipse(p, vRadii1.zw); + float d0 = distance_to_ellipse(p, vRadii0.xy) + half_px; + float d1 = distance_to_ellipse(p, vRadii0.zw) + half_px; + float d2 = distance_to_ellipse(p, vRadii1.xy) + half_px; + float d3 = distance_to_ellipse(p, vRadii1.zw) + half_px; // SDF subtract main radii - float d_main = max(d0, 0.5 * afwidth - d1); + float d_main = max(d0, aa_step - d1); // SDF subtract inner radii (double style borders) - float d_inner = max(d2 - 0.5 * afwidth, -d3); + float d_inner = max(d2 - aa_step, -d3); // Select how to combine the SDF based on border style. float d = mix(max(d_main, -d_inner), d_main, vSDFSelect); // Only apply AA to fragments outside the signed distance field. - alpha = min(alpha, 1.0 - smoothstep(0.0, 0.5 * afwidth, d)); + alpha = min(alpha, 1.0 - smoothstep(0.0, aa_step, d)); // Get the groove/ridge mix factor. - color_mix_factor = smoothstep(-0.5 * afwidth, - 0.5 * afwidth, - -d2); + color_mix_factor = smoothstep(-aa_step, aa_step, -d2); } else { // Handle the case where the fragment is outside the clip // region in a corner. This occurs when border width is @@ -389,7 +403,7 @@ void main(void) { // Select color based on side of line. Get distance from the // reference line, and then apply AA along the edge. float ld = distance_to_line(vColorEdgeLine.xy, vColorEdgeLine.zw, local_pos); - float m = smoothstep(-0.5 * afwidth, 0.5 * afwidth, ld); + float m = smoothstep(-aa_step, aa_step, ld); vec4 color = mix(color0, color1, m); oFragColor = color * vec4(1.0, 1.0, 1.0, alpha); diff --git a/gfx/webrender/res/ps_hardware_composite.fs.glsl b/gfx/webrender/res/ps_hardware_composite.fs.glsl deleted file mode 100644 index ce9b138ee648..000000000000 --- a/gfx/webrender/res/ps_hardware_composite.fs.glsl +++ /dev/null @@ -1,8 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -void main(void) { - vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw); - oFragColor = texture(sCacheRGBA8, vec3(uv, vUv.z)); -} diff --git a/gfx/webrender/res/ps_hardware_composite.glsl b/gfx/webrender/res/ps_hardware_composite.glsl index d401cefe2cef..956558cf7448 100644 --- a/gfx/webrender/res/ps_hardware_composite.glsl +++ b/gfx/webrender/res/ps_hardware_composite.glsl @@ -6,3 +6,34 @@ varying vec3 vUv; flat varying vec4 vUvBounds; + +#ifdef WR_VERTEX_SHADER +void main(void) { + CompositeInstance ci = fetch_composite_instance(); + AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index); + AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index); + + vec2 dest_origin = dest_task.render_target_origin - + dest_task.screen_space_origin + + vec2(ci.user_data0, ci.user_data1); + + vec2 local_pos = mix(dest_origin, + dest_origin + src_task.size, + aPosition.xy); + + vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0)); + vec2 st0 = src_task.render_target_origin; + vec2 st1 = src_task.render_target_origin + src_task.size; + vUv = vec3(mix(st0, st1, aPosition.xy) / texture_size, src_task.render_target_layer_index); + vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy; + + gl_Position = uTransform * vec4(local_pos, ci.z, 1.0); +} +#endif + +#ifdef WR_FRAGMENT_SHADER +void main(void) { + vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw); + oFragColor = texture(sCacheRGBA8, vec3(uv, vUv.z)); +} +#endif diff --git a/gfx/webrender/res/ps_hardware_composite.vs.glsl b/gfx/webrender/res/ps_hardware_composite.vs.glsl deleted file mode 100644 index cc379000559e..000000000000 --- a/gfx/webrender/res/ps_hardware_composite.vs.glsl +++ /dev/null @@ -1,25 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -void main(void) { - CompositeInstance ci = fetch_composite_instance(); - AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index); - AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index); - - vec2 dest_origin = dest_task.render_target_origin - - dest_task.screen_space_origin + - vec2(ci.user_data0, ci.user_data1); - - vec2 local_pos = mix(dest_origin, - dest_origin + src_task.size, - aPosition.xy); - - vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0)); - vec2 st0 = src_task.render_target_origin; - vec2 st1 = src_task.render_target_origin + src_task.size; - vUv = vec3(mix(st0, st1, aPosition.xy) / texture_size, src_task.render_target_layer_index); - vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy; - - gl_Position = uTransform * vec4(local_pos, ci.z, 1.0); -} diff --git a/gfx/webrender/res/ps_radial_gradient.glsl b/gfx/webrender/res/ps_radial_gradient.glsl index ba985de9bdb5..33616cb078b7 100644 --- a/gfx/webrender/res/ps_radial_gradient.glsl +++ b/gfx/webrender/res/ps_radial_gradient.glsl @@ -53,6 +53,8 @@ void main(void) { // Whether to repeat the gradient instead of clamping. vGradientRepeat = float(int(gradient.start_end_radius_ratio_xy_extend_mode.w) != EXTEND_MODE_CLAMP); + + write_clip(vi.screen_pos, prim.clip_area); } #endif @@ -104,8 +106,21 @@ void main(void) { } } - oFragColor = sample_gradient(vGradientAddress, + vec4 color = sample_gradient(vGradientAddress, offset, vGradientRepeat); + + // Un-premultiply the color from sampling the gradient. + if (color.a > 0.0) { + color.rgb /= color.a; + + // Apply the clip mask + color.a = min(color.a, do_clip()); + + // Pre-multiply the result. + color.rgb *= color.a; + } + + oFragColor = color; } #endif diff --git a/gfx/webrender/res/ps_text_run.glsl b/gfx/webrender/res/ps_text_run.glsl index 971d601d1bd9..92f5cdcafb85 100644 --- a/gfx/webrender/res/ps_text_run.glsl +++ b/gfx/webrender/res/ps_text_run.glsl @@ -30,7 +30,7 @@ void main(void) { vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio; RectWithSize local_rect = RectWithSize(local_pos, - (res.uv_rect.zw - res.uv_rect.xy) / uDevicePixelRatio); + (res.uv_rect.zw - res.uv_rect.xy) * res.scale / uDevicePixelRatio); #ifdef WR_FEATURE_TRANSFORM TransformVertexInfo vi = write_transform_vertex(local_rect, @@ -57,7 +57,7 @@ void main(void) { vec2 st0 = res.uv_rect.xy / texture_size; vec2 st1 = res.uv_rect.zw / texture_size; - vColor = text.color; + vColor = vec4(text.color.rgb * text.color.a, text.color.a); vUv = vec3(mix(st0, st1, f), res.layer); vUvBorder = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy; } @@ -71,13 +71,14 @@ void main(void) { oFragColor = texture(sColor0, tc); #else vec4 color = texture(sColor0, tc) * vColor; + float alpha = 1.0; #ifdef WR_FEATURE_TRANSFORM float a = 0.0; init_transform_fs(vLocalPos, a); - color.a *= a; + alpha *= a; #endif - color.a = min(color.a, do_clip()); - oFragColor = color; + alpha = min(alpha, do_clip()); + oFragColor = color * alpha; #endif } #endif diff --git a/gfx/webrender/src/device.rs b/gfx/webrender/src/device.rs index 37fd6dffb88e..688f374e9ddc 100644 --- a/gfx/webrender/src/device.rs +++ b/gfx/webrender/src/device.rs @@ -183,6 +183,11 @@ pub fn build_shader_strings( vs_source.push_str(gl_version_string); fs_source.push_str(gl_version_string); + // Insert the shader name to make debugging easier. + let name_string = format!("// {}\n", base_filename); + vs_source.push_str(&name_string); + fs_source.push_str(&name_string); + // Define a constant depending on whether we are compiling VS or FS. vs_source.push_str(SHADER_KIND_VERTEX); fs_source.push_str(SHADER_KIND_FRAGMENT); diff --git a/gfx/webrender/src/frame.rs b/gfx/webrender/src/frame.rs index 16ac7f9552a5..937ba0651ad6 100644 --- a/gfx/webrender/src/frame.rs +++ b/gfx/webrender/src/frame.rs @@ -31,80 +31,12 @@ static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF { a: 0.6, }; -/// Nested display lists cause two types of replacements to ClipIds inside the nesting: -/// 1. References to the root scroll frame are replaced by the ClipIds that -/// contained the nested display list. -/// 2. Other ClipIds (that aren't custom or reference frames) are assumed to be -/// local to the nested display list and are converted to an id that is unique -/// outside of the nested display list as well. -/// -/// This structure keeps track of what ids are the "root" for one particular level of -/// nesting as well as keeping and index, which can make ClipIds used internally unique -/// in the full ClipScrollTree. -#[derive(Debug)] -struct NestedDisplayListInfo { - /// The index of this nested display list, which is used to generate - /// new ClipIds for clips that are defined inside it. - nest_index: u64, - - /// The ClipId of the scroll frame node which contains this nested - /// display list. This is used to replace references to the root with - /// the proper ClipId. - scroll_node_id: ClipId, - - /// The ClipId of the clip node which contains this nested display list. - /// This is used to replace references to the root with the proper ClipId. - clip_node_id: ClipId, -} - -impl NestedDisplayListInfo { - fn convert_id_to_nested(&self, id: &ClipId) -> ClipId { - match *id { - ClipId::Clip(id, _, pipeline_id) => ClipId::Clip(id, self.nest_index, pipeline_id), - _ => *id, - } - } - - fn convert_scroll_id_to_nested(&self, id: &ClipId) -> ClipId { - if id.pipeline_id() != self.scroll_node_id.pipeline_id() { - return *id; - } - - if id.is_root_scroll_node() { - self.scroll_node_id - } else { - self.convert_id_to_nested(id) - } - } - - fn convert_clip_id_to_nested(&self, id: &ClipId) -> ClipId { - if id.pipeline_id() != self.clip_node_id.pipeline_id() { - return *id; - } - - if id.is_root_scroll_node() { - self.clip_node_id - } else { - self.convert_id_to_nested(id) - } - } - - fn convert_new_id_to_nested(&self, id: &ClipId) -> ClipId { - if id.pipeline_id() != self.clip_node_id.pipeline_id() { - return *id; - } - self.convert_id_to_nested(id) - } -} - struct FlattenContext<'a> { scene: &'a Scene, builder: &'a mut FrameBuilder, resource_cache: &'a ResourceCache, tiled_image_map: TiledImageMap, replacements: Vec<(ClipId, ClipId)>, - nested_display_list_info: Vec, - current_nested_display_list_index: u64, } impl<'a> FlattenContext<'a> { @@ -119,49 +51,9 @@ impl<'a> FlattenContext<'a> { resource_cache, tiled_image_map: resource_cache.get_tiled_image_map(), replacements: Vec::new(), - nested_display_list_info: Vec::new(), - current_nested_display_list_index: 0, } } - fn push_nested_display_list_ids(&mut self, info: ClipAndScrollInfo) { - self.current_nested_display_list_index += 1; - self.nested_display_list_info.push(NestedDisplayListInfo { - nest_index: self.current_nested_display_list_index, - scroll_node_id: info.scroll_node_id, - clip_node_id: info.clip_node_id(), - }); - } - - fn pop_nested_display_list_ids(&mut self) { - self.nested_display_list_info.pop(); - } - - fn convert_new_id_to_nested(&self, id: &ClipId) -> ClipId { - if let Some(nested_info) = self.nested_display_list_info.last() { - nested_info.convert_new_id_to_nested(id) - } else { - *id - } - } - - fn convert_clip_scroll_info_to_nested(&self, info: &mut ClipAndScrollInfo) { - if let Some(nested_info) = self.nested_display_list_info.last() { - info.scroll_node_id = nested_info.convert_scroll_id_to_nested(&info.scroll_node_id); - info.clip_node_id = info.clip_node_id - .map(|ref id| nested_info.convert_clip_id_to_nested(id)); - } - - // We only want to produce nested ClipIds if we are in a nested display - // list situation. - debug_assert!( - !info.scroll_node_id.is_nested() || !self.nested_display_list_info.is_empty() - ); - debug_assert!( - !info.clip_node_id().is_nested() || !self.nested_display_list_info.is_empty() - ); - } - /// Since WebRender still handles fixed position and reference frame content internally /// we need to apply this table of id replacements only to the id that affects the /// position of a node. We can eventually remove this when clients start handling @@ -337,9 +229,8 @@ impl Frame { new_clip_id: &ClipId, clip_region: ClipRegion, ) { - let new_clip_id = context.convert_new_id_to_nested(new_clip_id); context.builder.add_clip_node( - new_clip_id, + *new_clip_id, *parent_id, pipeline_id, clip_region, @@ -367,9 +258,8 @@ impl Frame { &mut self.clip_scroll_tree, ); - let new_scroll_frame_id = context.convert_new_id_to_nested(new_scroll_frame_id); context.builder.add_scroll_frame( - new_scroll_frame_id, + *new_scroll_frame_id, clip_id, pipeline_id, &frame_rect, @@ -555,7 +445,6 @@ impl Frame { reference_frame_relative_offset: LayerVector2D, ) -> Option> { let mut clip_and_scroll = item.clip_and_scroll(); - context.convert_clip_scroll_info_to_nested(&mut clip_and_scroll); let unreplaced_scroll_id = clip_and_scroll.scroll_node_id; clip_and_scroll.scroll_node_id = @@ -777,22 +666,13 @@ impl Frame { } SpecificDisplayItem::StickyFrame(ref info) => { let frame_rect = item.rect().translate(&reference_frame_relative_offset); - let new_clip_id = context.convert_new_id_to_nested(&info.id); self.clip_scroll_tree.add_sticky_frame( - new_clip_id, + info.id, clip_and_scroll.scroll_node_id, /* parent id */ frame_rect, info.sticky_frame_info, ); } - SpecificDisplayItem::PushNestedDisplayList => { - // Using the clip and scroll already processed for nesting here - // means that in the case of multiple nested display lists, we - // will enter the outermost ids into the table and avoid having - // to do a replacement for every level of nesting. - context.push_nested_display_list_ids(clip_and_scroll); - } - SpecificDisplayItem::PopNestedDisplayList => context.pop_nested_display_list_ids(), // Do nothing; these are dummy items for the display list parser SpecificDisplayItem::SetGradientStops => {} diff --git a/gfx/webrender/src/frame_builder.rs b/gfx/webrender/src/frame_builder.rs index e9083ee21e8a..b9a30de8582a 100644 --- a/gfx/webrender/src/frame_builder.rs +++ b/gfx/webrender/src/frame_builder.rs @@ -10,7 +10,7 @@ use api::{GlyphInstance, GlyphOptions, GradientStop, HitTestFlags, HitTestItem, use api::{ImageKey, ImageRendering, ItemRange, ItemTag, LayerPoint, LayerPrimitiveInfo, LayerRect}; use api::{LayerSize, LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation}; use api::{LineStyle, LocalClip, POINT_RELATIVE_TO_PIPELINE_VIEWPORT, PipelineId, RepeatMode}; -use api::{ScrollSensitivity, SubpixelDirection, Shadow, TileOffset, TransformStyle}; +use api::{ScrollSensitivity, Shadow, TileOffset, TransformStyle}; use api::{WorldPixel, WorldPoint, YuvColorSpace, YuvData, device_length}; use app_units::Au; use border::ImageBorderSegment; @@ -21,12 +21,13 @@ use euclid::{SideOffsets2D, vec2, vec3}; use frame::FrameId; use gpu_cache::GpuCache; use internal_types::{FastHashMap, FastHashSet, HardwareCompositeOp}; +use picture::PicturePrimitive; use plane_split::{BspSplitter, Polygon, Splitter}; use prim_store::{BoxShadowPrimitiveCpu, TexelRect, YuvImagePrimitiveCpu}; use prim_store::{GradientPrimitiveCpu, ImagePrimitiveCpu, LinePrimitive, PrimitiveKind}; use prim_store::{PrimitiveContainer, PrimitiveIndex}; use prim_store::{PrimitiveStore, RadialGradientPrimitiveCpu}; -use prim_store::{RectanglePrimitive, TextRunPrimitiveCpu, ShadowPrimitiveCpu}; +use prim_store::{RectanglePrimitive, TextRunPrimitiveCpu}; use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters}; use render_task::{AlphaRenderItem, ClipWorkItem, RenderTask}; use render_task::{RenderTaskId, RenderTaskLocation, RenderTaskTree}; @@ -584,11 +585,7 @@ impl FrameBuilder { clip_and_scroll: ClipAndScrollInfo, info: &LayerPrimitiveInfo, ) { - let prim = ShadowPrimitiveCpu { - shadow, - primitives: Vec::new(), - render_task_id: None, - }; + let prim = PicturePrimitive::new_shadow(shadow); // Create an empty shadow primitive. Insert it into // the draw lists immediately so that it will be drawn @@ -598,7 +595,7 @@ impl FrameBuilder { clip_and_scroll, info, Vec::new(), - PrimitiveContainer::Shadow(prim), + PrimitiveContainer::Picture(prim), ); self.shadow_prim_stack.push(prim_index); @@ -614,9 +611,10 @@ impl FrameBuilder { // safe to offset the local rect by the offset of the shadow, which // is then used when blitting the shadow to the final location. let metadata = &mut self.prim_store.cpu_metadata[prim_index.0]; - let prim = &self.prim_store.cpu_shadows[metadata.cpu_prim_index.0]; + let prim = &self.prim_store.cpu_pictures[metadata.cpu_prim_index.0]; + let shadow = prim.as_shadow(); - metadata.local_rect = metadata.local_rect.translate(&prim.shadow.offset); + metadata.local_rect = metadata.local_rect.translate(&shadow.offset); } pub fn add_solid_rectangle( @@ -686,9 +684,10 @@ impl FrameBuilder { let mut fast_shadow_prims = Vec::new(); for shadow_prim_index in &self.shadow_prim_stack { let shadow_metadata = &self.prim_store.cpu_metadata[shadow_prim_index.0]; - let shadow_prim = &self.prim_store.cpu_shadows[shadow_metadata.cpu_prim_index.0]; - if shadow_prim.shadow.blur_radius == 0.0 { - fast_shadow_prims.push(shadow_prim.shadow); + let picture = &self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0]; + let shadow = picture.as_shadow(); + if shadow.blur_radius == 0.0 { + fast_shadow_prims.push(shadow.clone()); } } for shadow in fast_shadow_prims { @@ -720,18 +719,19 @@ impl FrameBuilder { for shadow_prim_index in &self.shadow_prim_stack { let shadow_metadata = &mut self.prim_store.cpu_metadata[shadow_prim_index.0]; - debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::Shadow); - let shadow_prim = - &mut self.prim_store.cpu_shadows[shadow_metadata.cpu_prim_index.0]; + debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::Picture); + let picture = + &mut self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0]; + let blur_radius = picture.as_shadow().blur_radius; // Only run real blurs here (fast path zero blurs are handled above). - if shadow_prim.shadow.blur_radius > 0.0 { + if blur_radius > 0.0 { let shadow_rect = new_rect.inflate( - shadow_prim.shadow.blur_radius, - shadow_prim.shadow.blur_radius, + blur_radius, + blur_radius, ); shadow_metadata.local_rect = shadow_metadata.local_rect.union(&shadow_rect); - shadow_prim.primitives.push(prim_index); + picture.add_primitive(prim_index, clip_and_scroll); } } } @@ -1132,19 +1132,18 @@ impl FrameBuilder { // TODO(gw): Use a proper algorithm to select // whether this item should be rendered with // subpixel AA! - let mut default_render_mode = self.config + let mut render_mode = self.config .default_font_render_mode .limit_by(font.render_mode); if let Some(options) = glyph_options { - default_render_mode = default_render_mode.limit_by(options.render_mode); + render_mode = render_mode.limit_by(options.render_mode); } // There are some conditions under which we can't use // subpixel text rendering, even if enabled. - let mut normal_render_mode = default_render_mode; - if normal_render_mode == FontRenderMode::Subpixel { + if render_mode == FontRenderMode::Subpixel { if color.a != 1.0 { - normal_render_mode = FontRenderMode::Alpha; + render_mode = FontRenderMode::Alpha; } // text on a stacking context that has filters @@ -1155,36 +1154,17 @@ impl FrameBuilder { if let Some(sc_index) = self.stacking_context_stack.last() { let stacking_context = &self.stacking_context_store[sc_index.0]; if stacking_context.composite_ops.count() > 0 { - normal_render_mode = FontRenderMode::Alpha; + render_mode = FontRenderMode::Alpha; } } } - let color = match font.render_mode { - FontRenderMode::Bitmap => ColorF::new(1.0, 1.0, 1.0, 1.0), - FontRenderMode::Subpixel | - FontRenderMode::Alpha | - FontRenderMode::Mono => *color, - }; - - // Shadows never use subpixel AA, but need to respect the alpha/mono flag - // for reftests. - let (shadow_render_mode, subpx_dir) = match default_render_mode { - FontRenderMode::Subpixel | FontRenderMode::Alpha => { - // TODO(gw): Expose subpixel direction in API once WR supports - // vertical text runs. - (FontRenderMode::Alpha, font.subpx_dir) - } - FontRenderMode::Mono => (FontRenderMode::Mono, SubpixelDirection::None), - FontRenderMode::Bitmap => (FontRenderMode::Bitmap, font.subpx_dir), - }; - let prim_font = FontInstance::new( font.font_key, font.size, - color, - normal_render_mode, - subpx_dir, + *color, + render_mode, + font.subpx_dir, font.platform_options, font.variations.clone(), font.synthetic_italics, @@ -1195,9 +1175,7 @@ impl FrameBuilder { glyph_count, glyph_gpu_blocks: Vec::new(), glyph_keys: Vec::new(), - shadow_render_mode, offset: run_offset, - color: color, }; // Text shadows that have a blur radius of 0 need to be rendered as normal @@ -1211,20 +1189,18 @@ impl FrameBuilder { let mut fast_shadow_prims = Vec::new(); for shadow_prim_index in &self.shadow_prim_stack { let shadow_metadata = &self.prim_store.cpu_metadata[shadow_prim_index.0]; - let shadow_prim = &self.prim_store.cpu_shadows[shadow_metadata.cpu_prim_index.0]; - if shadow_prim.shadow.blur_radius == 0.0 { + let picture_prim = &self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0]; + let shadow = picture_prim.as_shadow(); + if shadow.blur_radius == 0.0 { let mut text_prim = prim.clone(); - if font.render_mode != FontRenderMode::Bitmap { - text_prim.font.color = shadow_prim.shadow.color.into(); - } + text_prim.font.color = shadow.color.into(); // If we have translucent text, we need to ensure it won't go // through the subpixel blend mode, which doesn't work with // traditional alpha blending. - if shadow_prim.shadow.color.a != 1.0 { + if shadow.color.a != 1.0 { text_prim.font.render_mode = text_prim.font.render_mode.limit_by(FontRenderMode::Alpha); } - text_prim.color = shadow_prim.shadow.color; - text_prim.offset += shadow_prim.shadow.offset; + text_prim.offset += shadow.offset; fast_shadow_prims.push(text_prim); } } @@ -1264,18 +1240,19 @@ impl FrameBuilder { // the indices as sub-primitives to the shadow primitives. for shadow_prim_index in &self.shadow_prim_stack { let shadow_metadata = &mut self.prim_store.cpu_metadata[shadow_prim_index.0]; - debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::Shadow); - let shadow_prim = - &mut self.prim_store.cpu_shadows[shadow_metadata.cpu_prim_index.0]; + debug_assert_eq!(shadow_metadata.prim_kind, PrimitiveKind::Picture); + let picture_prim = + &mut self.prim_store.cpu_pictures[shadow_metadata.cpu_prim_index.0]; // Only run real blurs here (fast path zero blurs are handled above). - if shadow_prim.shadow.blur_radius > 0.0 { + let blur_radius = picture_prim.as_shadow().blur_radius; + if blur_radius > 0.0 { let shadow_rect = rect.inflate( - shadow_prim.shadow.blur_radius, - shadow_prim.shadow.blur_radius, + blur_radius, + blur_radius, ); shadow_metadata.local_rect = shadow_metadata.local_rect.union(&shadow_rect); - shadow_prim.primitives.push(prim_index); + picture_prim.add_primitive(prim_index, clip_and_scroll); } } } diff --git a/gfx/webrender/src/glyph_cache.rs b/gfx/webrender/src/glyph_cache.rs index c06ea005cb3f..b5d91ffd5924 100644 --- a/gfx/webrender/src/glyph_cache.rs +++ b/gfx/webrender/src/glyph_cache.rs @@ -13,6 +13,7 @@ pub struct CachedGlyphInfo { pub glyph_bytes: Arc>, pub size: DeviceUintSize, pub offset: DevicePoint, + pub scale: f32, } pub type GlyphKeyCache = ResourceClassCache>; diff --git a/gfx/webrender/src/glyph_rasterizer.rs b/gfx/webrender/src/glyph_rasterizer.rs index 31b097da9c32..4c76cf8af7fe 100644 --- a/gfx/webrender/src/glyph_rasterizer.rs +++ b/gfx/webrender/src/glyph_rasterizer.rs @@ -3,10 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #[cfg(test)] -use api::{ColorF, FontRenderMode, IdNamespace, LayoutPoint, SubpixelDirection}; +use api::{ColorF, IdNamespace, LayoutPoint}; use api::{DevicePoint, DeviceUintSize, FontInstance}; -use api::{FontKey, FontTemplate}; -use api::{GlyphDimensions, GlyphKey}; +use api::{FontKey, FontTemplate, FontRenderMode, ColorU}; +use api::{GlyphDimensions, GlyphKey, SubpixelDirection}; use api::{ImageData, ImageDescriptor, ImageFormat}; #[cfg(test)] use app_units::Au; @@ -144,6 +144,29 @@ impl GlyphRasterizer { self.fonts_to_remove.push(font_key); } + pub fn prepare_font(&self, font: &mut FontInstance) { + // In alpha/mono mode, the color of the font is irrelevant. + // Forcing it to black in those cases saves rasterizing glyphs + // of different colors when not needed. + match font.render_mode { + FontRenderMode::Mono | FontRenderMode::Bitmap => { + font.color = ColorU::new(255, 255, 255, 255); + // Subpixel positioning is disabled in mono and bitmap modes. + font.subpx_dir = SubpixelDirection::None; + } + FontRenderMode::Alpha => { + font.color = ColorU::new(255, 255, 255, 255); + } + FontRenderMode::Subpixel => { + // In subpixel mode, we only actually need the color if preblending + // is used in the font backend. + if !FontContext::has_gamma_correct_subpixel_aa() { + font.color = ColorU::new(255, 255, 255, 255); + } + } + } + } + pub fn request_glyphs( &mut self, glyph_cache: &mut GlyphCache, @@ -183,7 +206,7 @@ impl GlyphRasterizer { }, TextureFilter::Linear, ImageData::Raw(glyph_info.glyph_bytes.clone()), - [glyph_info.offset.x, glyph_info.offset.y], + [glyph_info.offset.x, glyph_info.offset.y, glyph_info.scale], None, gpu_cache, ); @@ -246,10 +269,10 @@ impl GlyphRasterizer { .get_glyph_dimensions(font, glyph_key) } - pub fn is_bitmap_font(&self, font_key: FontKey) -> bool { + pub fn is_bitmap_font(&self, font: &FontInstance) -> bool { self.font_contexts .lock_shared_context() - .is_bitmap_font(font_key) + .is_bitmap_font(font) } pub fn get_glyph_index(&mut self, font_key: FontKey, ch: char) -> Option { @@ -312,7 +335,7 @@ impl GlyphRasterizer { }, TextureFilter::Linear, ImageData::Raw(glyph_bytes.clone()), - [glyph.left, glyph.top], + [glyph.left, glyph.top, glyph.scale], None, gpu_cache, ); @@ -321,6 +344,7 @@ impl GlyphRasterizer { glyph_bytes, size: DeviceUintSize::new(glyph.width, glyph.height), offset: DevicePoint::new(glyph.left, glyph.top), + scale: glyph.scale, }) } else { None diff --git a/gfx/webrender/src/lib.rs b/gfx/webrender/src/lib.rs index ba803f91adf4..1517d53bb75d 100644 --- a/gfx/webrender/src/lib.rs +++ b/gfx/webrender/src/lib.rs @@ -69,6 +69,7 @@ mod glyph_rasterizer; mod gpu_cache; mod gpu_types; mod internal_types; +mod picture; mod prim_store; mod print_tree; mod profiler; diff --git a/gfx/webrender/src/picture.rs b/gfx/webrender/src/picture.rs new file mode 100644 index 000000000000..45f34fe69b03 --- /dev/null +++ b/gfx/webrender/src/picture.rs @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use api::{ClipAndScrollInfo, Shadow}; +use prim_store::PrimitiveIndex; +use render_task::RenderTaskId; + +/* + A picture represents a dynamically rendered image. It consists of: + + * A number of primitives that are drawn onto the picture. + * A composite operation describing how to composite this + picture into its parent. + * A configuration describing how to draw the primitives on + this picture (e.g. in screen space or local space). + */ + +#[derive(Clone, Debug)] +pub struct PrimitiveRun { + pub prim_index: PrimitiveIndex, + pub count: usize, + pub clip_and_scroll: ClipAndScrollInfo, +} + +#[derive(Debug)] +pub enum CompositeOp { + Shadow(Shadow), + + // TODO(gw): Support other composite ops, such + // as blur, blend etc. +} + +#[derive(Debug)] +pub struct PicturePrimitive { + pub prim_runs: Vec, + pub composite_op: CompositeOp, + pub render_task_id: Option, + + // TODO(gw): Add a mode that specifies if this + // picture should be rasterized in + // screen-space or local-space. +} + +impl PicturePrimitive { + pub fn new_shadow(shadow: Shadow) -> PicturePrimitive { + PicturePrimitive { + prim_runs: Vec::new(), + composite_op: CompositeOp::Shadow(shadow), + render_task_id: None, + } + } + + pub fn as_shadow(&self) -> &Shadow { + match self.composite_op { + CompositeOp::Shadow(ref shadow) => shadow, + } + } + + pub fn add_primitive( + &mut self, + prim_index: PrimitiveIndex, + clip_and_scroll: ClipAndScrollInfo + ) { + if let Some(ref mut run) = self.prim_runs.last_mut() { + if run.clip_and_scroll == clip_and_scroll && + run.prim_index.0 + run.count == prim_index.0 { + run.count += 1; + return; + } + } + + self.prim_runs.push(PrimitiveRun { + prim_index, + count: 1, + clip_and_scroll, + }); + } +} diff --git a/gfx/webrender/src/platform/macos/font.rs b/gfx/webrender/src/platform/macos/font.rs index bcd3a2cc25e4..4053d771370c 100644 --- a/gfx/webrender/src/platform/macos/font.rs +++ b/gfx/webrender/src/platform/macos/font.rs @@ -42,6 +42,7 @@ pub struct RasterizedGlyph { pub left: f32, pub width: u32, pub height: u32, + pub scale: f32, pub bytes: Vec, } @@ -52,6 +53,7 @@ impl RasterizedGlyph { left: 0.0, width: 0, height: 0, + scale: 1.0, bytes: vec![], } } @@ -422,18 +424,20 @@ impl FontContext { } } - pub fn is_bitmap_font(&mut self, font_key: FontKey) -> bool { - match self.get_ct_font(font_key, Au(16 * 60), &[]) { + pub fn is_bitmap_font(&mut self, font: &FontInstance) -> bool { + match self.get_ct_font(font.font_key, font.size, &font.variations) { Some(ref ct_font) => { let traits = ct_font.symbolic_traits(); (traits & kCTFontColorGlyphsTrait) != 0 } - None => { - false - } + None => false, } } + pub fn has_gamma_correct_subpixel_aa() -> bool { + true + } + pub fn rasterize_glyph( &mut self, font: &FontInstance, @@ -585,6 +589,7 @@ impl FontContext { top: metrics.rasterized_ascent as f32, width: metrics.rasterized_width, height: metrics.rasterized_height, + scale: 1.0, bytes: rasterized_pixels, }) } diff --git a/gfx/webrender/src/platform/unix/font.rs b/gfx/webrender/src/platform/unix/font.rs index e9173597bef7..730a21a51bb7 100644 --- a/gfx/webrender/src/platform/unix/font.rs +++ b/gfx/webrender/src/platform/unix/font.rs @@ -3,29 +3,33 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{FontInstance, FontKey, FontRenderMode, GlyphDimensions}; -use api::{NativeFontHandle, SubpixelDirection}; -use api::GlyphKey; +use api::{FontInstancePlatformOptions, FontLCDFilter, FontHinting}; +use api::{NativeFontHandle, SubpixelDirection, GlyphKey}; +use api::{FONT_FORCE_AUTOHINT, FONT_NO_AUTOHINT, FONT_EMBEDDED_BITMAP}; +use api::{FONT_EMBOLDEN, FONT_VERTICAL_LAYOUT, FONT_SUBPIXEL_BGR}; use freetype::freetype::{FT_BBox, FT_Outline_Translate, FT_Pixel_Mode, FT_Render_Mode}; use freetype::freetype::{FT_Done_Face, FT_Error, FT_Get_Char_Index, FT_Int32}; use freetype::freetype::{FT_Done_FreeType, FT_Library_SetLcdFilter, FT_Pos}; use freetype::freetype::{FT_F26Dot6, FT_Face, FT_Glyph_Format, FT_Long, FT_UInt}; -use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Memory_Face, FT_Outline_Transform}; +use freetype::freetype::{FT_GlyphSlot, FT_LcdFilter, FT_New_Memory_Face}; use freetype::freetype::{FT_Init_FreeType, FT_Load_Glyph, FT_Render_Glyph}; -use freetype::freetype::{FT_Library, FT_Matrix, FT_Outline_Get_CBox, FT_Set_Char_Size}; +use freetype::freetype::{FT_Library, FT_Outline_Get_CBox, FT_Set_Char_Size, FT_Select_Size}; +use freetype::freetype::{FT_LOAD_COLOR, FT_LOAD_DEFAULT, FT_LOAD_FORCE_AUTOHINT}; +use freetype::freetype::{FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH, FT_LOAD_NO_AUTOHINT}; +use freetype::freetype::{FT_LOAD_NO_BITMAP, FT_LOAD_NO_HINTING, FT_LOAD_VERTICAL_LAYOUT}; +use freetype::freetype::{FT_FACE_FLAG_SCALABLE, FT_FACE_FLAG_FIXED_SIZES, FT_Err_Cannot_Render_Glyph}; use internal_types::FastHashMap; -use std::{mem, ptr, slice}; +use std::{cmp, mem, ptr, slice}; use std::sync::Arc; -// This constant is not present in the freetype +// These constants are not present in the freetype // bindings due to bindgen not handling the way -// the macro is defined. -const FT_LOAD_TARGET_LIGHT: FT_Int32 = 1 << 16; - -// Default to slight hinting, which is what most -// Linux distros use by default, and is a better -// default than no hinting. -// TODO(gw): Make this configurable. -const GLYPH_LOAD_FLAGS: FT_Int32 = FT_LOAD_TARGET_LIGHT; +// the macros are defined. +//const FT_LOAD_TARGET_NORMAL: FT_UInt = 0 << 16; +const FT_LOAD_TARGET_LIGHT: FT_UInt = 1 << 16; +const FT_LOAD_TARGET_MONO: FT_UInt = 2 << 16; +const FT_LOAD_TARGET_LCD: FT_UInt = 3 << 16; +const FT_LOAD_TARGET_LCD_V: FT_UInt = 4 << 16; struct Face { face: FT_Face, @@ -50,17 +54,25 @@ pub struct RasterizedGlyph { pub left: f32, pub width: u32, pub height: u32, + pub scale: f32, pub bytes: Vec, } -const SUCCESS: FT_Error = FT_Error(0); +extern "C" { + fn FT_GlyphSlot_Embolden(slot: FT_GlyphSlot); + fn FT_GlyphSlot_Oblique(slot: FT_GlyphSlot); +} impl FontContext { pub fn new() -> FontContext { let mut lib: FT_Library = ptr::null_mut(); - // Per Skia, using a filter adds one full pixel to each side. - let mut lcd_extra_pixels = 1; + // Using an LCD filter may add one full pixel to each side if support is built in. + // As of FreeType 2.8.1, an LCD filter is always used regardless of settings + // if support for the patent-encumbered LCD filter algorithms is not built in. + // Thus, the only reasonable way to guess padding is to unconditonally add it if + // subpixel AA is used. + let lcd_extra_pixels = 1; unsafe { let result = FT_Init_FreeType(&mut lib); @@ -69,22 +81,12 @@ impl FontContext { "Unable to initialize FreeType library {:?}", result ); - - // TODO(gw): Check result of this to determine if freetype build supports subpixel. - let result = FT_Library_SetLcdFilter(lib, FT_LcdFilter::FT_LCD_FILTER_DEFAULT); - - if !result.succeeded() { - println!( - "WARN: Initializing a FreeType library build without subpixel AA enabled!" - ); - lcd_extra_pixels = 0; - } } FontContext { lib, faces: FastHashMap::default(), - lcd_extra_pixels: lcd_extra_pixels, + lcd_extra_pixels, } } @@ -132,25 +134,71 @@ impl FontContext { fn load_glyph(&self, font: &FontInstance, glyph: &GlyphKey) -> Option { debug_assert!(self.faces.contains_key(&font.font_key)); let face = self.faces.get(&font.font_key).unwrap(); - let char_size = font.size.to_f64_px() * 64.0 + 0.5; - assert_eq!(SUCCESS, unsafe { - FT_Set_Char_Size(face.face, char_size as FT_F26Dot6, 0, 0, 0) - }); + let mut load_flags = FT_LOAD_DEFAULT; + let FontInstancePlatformOptions { flags, hinting, .. } = font.platform_options.unwrap_or_default(); + match (hinting, font.render_mode) { + (FontHinting::None, _) => load_flags |= FT_LOAD_NO_HINTING, + (FontHinting::Mono, _) => load_flags = FT_LOAD_TARGET_MONO, + (FontHinting::Light, _) => load_flags = FT_LOAD_TARGET_LIGHT, + (FontHinting::LCD, FontRenderMode::Subpixel) => { + load_flags = match font.subpx_dir { + SubpixelDirection::Vertical => FT_LOAD_TARGET_LCD_V, + _ => FT_LOAD_TARGET_LCD, + }; + if (flags & FONT_FORCE_AUTOHINT) != 0 { + load_flags |= FT_LOAD_FORCE_AUTOHINT; + } + } + _ => { + if (flags & FONT_FORCE_AUTOHINT) != 0 { + load_flags |= FT_LOAD_FORCE_AUTOHINT; + } + } + } - let result = unsafe { FT_Load_Glyph(face.face, glyph.index as FT_UInt, GLYPH_LOAD_FLAGS) }; + if (flags & FONT_NO_AUTOHINT) != 0 { + load_flags |= FT_LOAD_NO_AUTOHINT; + } + if (flags & FONT_EMBEDDED_BITMAP) == 0 { + load_flags |= FT_LOAD_NO_BITMAP; + } + if (flags & FONT_VERTICAL_LAYOUT) != 0 { + load_flags |= FT_LOAD_VERTICAL_LAYOUT; + } - if result == SUCCESS { + load_flags |= FT_LOAD_COLOR; + load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; + + let mut result = if font.render_mode == FontRenderMode::Bitmap { + if (load_flags & FT_LOAD_NO_BITMAP) != 0 { + FT_Error(FT_Err_Cannot_Render_Glyph as i32) + } else { + self.choose_bitmap_size(face.face, font.size.to_f64_px()) + } + } else { + let char_size = font.size.to_f64_px() * 64.0 + 0.5; + unsafe { FT_Set_Char_Size(face.face, char_size as FT_F26Dot6, 0, 0, 0) } + }; + + if result.succeeded() { + result = unsafe { FT_Load_Glyph(face.face, glyph.index as FT_UInt, load_flags as FT_Int32) }; + }; + + if result.succeeded() { let slot = unsafe { (*face.face).glyph }; assert!(slot != ptr::null_mut()); - // TODO(gw): We use the FT_Outline_* APIs to manage sub-pixel offsets. - // We will need a custom code path for bitmap fonts (which - // are very rare). - match unsafe { (*slot).format } { - FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => Some(slot), + if (flags & FONT_EMBOLDEN) != 0 { + unsafe { FT_GlyphSlot_Embolden(slot) }; + } + + let format = unsafe { (*slot).format }; + match format { + FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE | + FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => Some(slot), _ => { - error!("TODO: Support bitmap fonts!"); + error!("Unsupported {:?}", format); None } } @@ -178,6 +226,11 @@ impl FontContext { // Get the estimated bounding box from FT (control points). unsafe { FT_Outline_Get_CBox(&(*slot).outline, &mut cbox); + + // For spaces and other non-printable characters, early out. + if (*slot).outline.n_contours == 0 { + return cbox; + } } // Convert the subpixel offset to floats. @@ -185,13 +238,11 @@ impl FontContext { // Apply extra pixel of padding for subpixel AA, due to the filter. let padding = match font.render_mode { - FontRenderMode::Subpixel => self.lcd_extra_pixels * 64, + FontRenderMode::Subpixel => (self.lcd_extra_pixels * 64) as FT_Pos, FontRenderMode::Alpha | FontRenderMode::Mono | - FontRenderMode::Bitmap => 0, + FontRenderMode::Bitmap => 0 as FT_Pos, }; - cbox.xMin -= padding as FT_Pos; - cbox.xMax += padding as FT_Pos; // Offset the bounding box by subpixel positioning. // Convert to 26.6 fixed point format for FT. @@ -199,13 +250,13 @@ impl FontContext { SubpixelDirection::None => {} SubpixelDirection::Horizontal => { let dx = (dx * 64.0 + 0.5) as FT_Long; - cbox.xMin += dx; - cbox.xMax += dx; + cbox.xMin += dx - padding; + cbox.xMax += dx + padding; } SubpixelDirection::Vertical => { let dy = (dy * 64.0 + 0.5) as FT_Long; - cbox.yMin += dy; - cbox.yMax += dy; + cbox.yMin += dy - padding; + cbox.yMax += dy + padding; } } @@ -223,23 +274,58 @@ impl FontContext { slot: FT_GlyphSlot, font: &FontInstance, glyph: &GlyphKey, + scale_bitmaps: bool, ) -> Option { let metrics = unsafe { &(*slot).metrics }; // If there's no advance, no need to consider this glyph // for layout. if metrics.horiAdvance == 0 { - None - } else { - let cbox = self.get_bounding_box(slot, font, glyph); + return None + } - Some(GlyphDimensions { - left: (cbox.xMin >> 6) as i32, - top: (cbox.yMax >> 6) as i32, - width: ((cbox.xMax - cbox.xMin) >> 6) as u32, - height: ((cbox.yMax - cbox.yMin) >> 6) as u32, - advance: metrics.horiAdvance as f32 / 64.0, - }) + let advance = metrics.horiAdvance as f32 / 64.0; + match unsafe { (*slot).format } { + FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => { + let left = unsafe { (*slot).bitmap_left }; + let top = unsafe { (*slot).bitmap_top }; + let width = unsafe { (*slot).bitmap.width }; + let height = unsafe { (*slot).bitmap.rows }; + if scale_bitmaps { + let y_size = unsafe { (*(*(*slot).face).size).metrics.y_ppem }; + let scale = font.size.to_f32_px() / y_size as f32; + let x0 = left as f32 * scale; + let x1 = width as f32 * scale + x0; + let y1 = top as f32 * scale; + let y0 = y1 - height as f32 * scale; + Some(GlyphDimensions { + left: x0.round() as i32, + top: y1.round() as i32, + width: (x1.ceil() - x0.floor()) as u32, + height: (y1.ceil() - y0.floor()) as u32, + advance: advance * scale, + }) + } else { + Some(GlyphDimensions { + left, + top, + width, + height, + advance, + }) + } + } + FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => { + let cbox = self.get_bounding_box(slot, font, glyph); + Some(GlyphDimensions { + left: (cbox.xMin >> 6) as i32, + top: (cbox.yMax >> 6) as i32, + width: ((cbox.xMax - cbox.xMin) >> 6) as u32, + height: ((cbox.yMax - cbox.yMin) >> 6) as u32, + advance, + }) + } + _ => None, } } @@ -261,42 +347,54 @@ impl FontContext { key: &GlyphKey, ) -> Option { let slot = self.load_glyph(font, key); - slot.and_then(|slot| self.get_glyph_dimensions_impl(slot, font, key)) + slot.and_then(|slot| self.get_glyph_dimensions_impl(slot, font, key, true)) } - pub fn is_bitmap_font(&mut self, _font_key: FontKey) -> bool { - // TODO(gw): Support bitmap fonts in Freetype. + pub fn is_bitmap_font(&mut self, font: &FontInstance) -> bool { + debug_assert!(self.faces.contains_key(&font.font_key)); + let face = self.faces.get(&font.font_key).unwrap(); + let face_flags = unsafe { (*face.face).face_flags }; + // If the face has embedded bitmaps, they should only be used if either + // embedded bitmaps are explicitly requested or if the face has no outline. + if (face_flags & (FT_FACE_FLAG_FIXED_SIZES as FT_Long)) != 0 { + let FontInstancePlatformOptions { flags, .. } = font.platform_options.unwrap_or_default(); + if (flags & FONT_EMBEDDED_BITMAP) != 0 { + return true; + } + (face_flags & (FT_FACE_FLAG_SCALABLE as FT_Long)) == 0 + } else { + false + } + } + + fn choose_bitmap_size(&self, face: FT_Face, requested_size: f64) -> FT_Error { + let mut best_dist = unsafe { *(*face).available_sizes.offset(0) }.y_ppem as f64 / 64.0 - requested_size; + let mut best_size = 0; + let num_fixed_sizes = unsafe { (*face).num_fixed_sizes }; + for i in 1 .. num_fixed_sizes { + // Distance is positive if strike is larger than desired size, + // or negative if smaller. If previously a found smaller strike, + // then prefer a larger strike. Otherwise, minimize distance. + let dist = unsafe { *(*face).available_sizes.offset(i as isize) }.y_ppem as f64 / 64.0 - requested_size; + if (best_dist < 0.0 && dist >= best_dist) || dist.abs() <= best_dist { + best_dist = dist; + best_size = i; + } + } + unsafe { FT_Select_Size(face, best_size) } + } + + pub fn has_gamma_correct_subpixel_aa() -> bool { + // We don't do any preblending with FreeType currently, so the color is not used. false } - pub fn rasterize_glyph( + fn rasterize_glyph_outline( &mut self, + slot: FT_GlyphSlot, font: &FontInstance, key: &GlyphKey, - ) -> Option { - let slot = match self.load_glyph(font, key) { - Some(slot) => slot, - None => return None, - }; - - let render_mode = match font.render_mode { - FontRenderMode::Mono => FT_Render_Mode::FT_RENDER_MODE_MONO, - FontRenderMode::Alpha => FT_Render_Mode::FT_RENDER_MODE_NORMAL, - FontRenderMode::Subpixel => FT_Render_Mode::FT_RENDER_MODE_LCD, - FontRenderMode::Bitmap => FT_Render_Mode::FT_RENDER_MODE_NORMAL, - }; - - // Get dimensions of the glyph, to see if we need to rasterize it. - let dimensions = match self.get_glyph_dimensions_impl(slot, font, key) { - Some(val) => val, - None => return None, - }; - - // For spaces and other non-printable characters, early out. - if dimensions.width == 0 || dimensions.height == 0 { - return None; - } - + ) -> bool { // Get the subpixel offsets in FT 26.6 format. let (dx, dy) = font.get_subpx_offset(key); let dx = (dx * 64.0 + 0.5) as FT_Long; @@ -315,93 +413,204 @@ impl FontContext { ); if font.synthetic_italics { - // These magic numbers are pre-encoded fixed point - // values that apply ~12 degree shear. Borrowed - // from the Freetype implementation of the - // FT_GlyphSlot_Oblique function. - let transform = FT_Matrix { - xx: 0x10000, - yx: 0x00000, - xy: 0x0366A, - yy: 0x10000, - }; - FT_Outline_Transform(outline, &transform); + FT_GlyphSlot_Oblique(slot); } } + if font.render_mode == FontRenderMode::Subpixel { + let FontInstancePlatformOptions { lcd_filter, .. } = font.platform_options.unwrap_or_default(); + let filter = match lcd_filter { + FontLCDFilter::None => FT_LcdFilter::FT_LCD_FILTER_NONE, + FontLCDFilter::Default => FT_LcdFilter::FT_LCD_FILTER_DEFAULT, + FontLCDFilter::Light => FT_LcdFilter::FT_LCD_FILTER_LIGHT, + FontLCDFilter::Legacy => FT_LcdFilter::FT_LCD_FILTER_LEGACY, + }; + unsafe { FT_Library_SetLcdFilter(self.lib, filter) }; + } + let render_mode = match (font.render_mode, font.subpx_dir) { + (FontRenderMode::Mono, _) => FT_Render_Mode::FT_RENDER_MODE_MONO, + (FontRenderMode::Alpha, _) | (FontRenderMode::Bitmap, _) => FT_Render_Mode::FT_RENDER_MODE_NORMAL, + (FontRenderMode::Subpixel, SubpixelDirection::Vertical) => FT_Render_Mode::FT_RENDER_MODE_LCD_V, + (FontRenderMode::Subpixel, _) => FT_Render_Mode::FT_RENDER_MODE_LCD, + }; let result = unsafe { FT_Render_Glyph(slot, render_mode) }; - if result != SUCCESS { + if !result.succeeded() { error!( "Unable to rasterize {:?} with {:?}, {:?}", key, render_mode, result ); + false + } else { + true + } + } + + pub fn rasterize_glyph( + &mut self, + font: &FontInstance, + key: &GlyphKey, + ) -> Option { + let slot = match self.load_glyph(font, key) { + Some(slot) => slot, + None => return None, + }; + + // Get dimensions of the glyph, to see if we need to rasterize it. + let dimensions = match self.get_glyph_dimensions_impl(slot, font, key, false) { + Some(val) => val, + None => return None, + }; + + // For spaces and other non-printable characters, early out. + if dimensions.width == 0 || dimensions.height == 0 { return None; } + let format = unsafe { (*slot).format }; + let mut scale = 1.0; + match format { + FT_Glyph_Format::FT_GLYPH_FORMAT_BITMAP => { + let y_size = unsafe { (*(*(*slot).face).size).metrics.y_ppem }; + scale = font.size.to_f32_px() / y_size as f32; + } + FT_Glyph_Format::FT_GLYPH_FORMAT_OUTLINE => { + if !self.rasterize_glyph_outline(slot, font, key) { + return None; + } + } + _ => { + error!("Unsupported {:?}", format); + return None; + } + } + let bitmap = unsafe { &(*slot).bitmap }; let pixel_mode = unsafe { mem::transmute(bitmap.pixel_mode as u32) }; info!( "Rasterizing {:?} as {:?} with dimensions {:?}", key, - render_mode, + font.render_mode, dimensions ); - let actual_width = match pixel_mode { + let (actual_width, actual_height) = match pixel_mode { FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { assert!(bitmap.width % 3 == 0); - bitmap.width / 3 + ((bitmap.width / 3) as i32, bitmap.rows as i32) } - FT_Pixel_Mode::FT_PIXEL_MODE_MONO | FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => bitmap.width, - _ => { - panic!("Unexpected pixel mode!"); + FT_Pixel_Mode::FT_PIXEL_MODE_LCD_V => { + assert!(bitmap.rows % 3 == 0); + (bitmap.width as i32, (bitmap.rows / 3) as i32) } - } as i32; - - let actual_height = bitmap.rows as i32; - let top = unsafe { (*slot).bitmap_top }; - let left = unsafe { (*slot).bitmap_left }; + FT_Pixel_Mode::FT_PIXEL_MODE_MONO | FT_Pixel_Mode::FT_PIXEL_MODE_GRAY | FT_Pixel_Mode::FT_PIXEL_MODE_BGRA => { + (bitmap.width as i32, bitmap.rows as i32) + } + _ => panic!("Unsupported {:?}", pixel_mode), + }; + let (left, top) = unsafe { ((*slot).bitmap_left, (*slot).bitmap_top) }; let mut final_buffer = vec![0; (actual_width * actual_height * 4) as usize]; // Extract the final glyph from FT format into RGBA8 format, which is // what WR expects. - for y in 0 .. actual_height { - // Get pointer to the bytes for this row. - let mut src = unsafe { bitmap.buffer.offset((y * bitmap.pitch) as isize) }; - - for x in 0 .. actual_width { - let value = match pixel_mode { - FT_Pixel_Mode::FT_PIXEL_MODE_MONO => { - let mask = 0x80 >> (x & 0x7); - let byte = unsafe { *src.offset((x >> 3) as isize) }; - let alpha = if byte & mask != 0 { 0xff } else { 0 }; - [0xff, 0xff, 0xff, alpha] - } - FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => { - let alpha = unsafe { *src }; + let FontInstancePlatformOptions { flags, .. } = font.platform_options.unwrap_or_default(); + let subpixel_bgr = (flags & FONT_SUBPIXEL_BGR) != 0; + let mut src_row = bitmap.buffer; + let mut dest: usize = 0; + while dest < final_buffer.len() { + let mut src = src_row; + let row_end = dest + actual_width as usize * 4; + match pixel_mode { + FT_Pixel_Mode::FT_PIXEL_MODE_MONO => { + while dest < row_end { + // Cast the byte to signed so that we can left shift each bit into + // the top bit, then right shift to fill out the bits with 0s or 1s. + let mut byte: i8 = unsafe { *src as i8 }; src = unsafe { src.offset(1) }; - [0xff, 0xff, 0xff, alpha] + let byte_end = cmp::min(row_end, dest + 8 * 4); + while dest < byte_end { + let alpha = (byte >> 7) as u8; + final_buffer[dest + 0] = alpha; + final_buffer[dest + 1] = alpha; + final_buffer[dest + 2] = alpha; + final_buffer[dest + 3] = alpha; + dest += 4; + byte <<= 1; + } } - FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { - let t = unsafe { slice::from_raw_parts(src, 3) }; - src = unsafe { src.offset(3) }; - [t[2], t[1], t[0], 0xff] + } + FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => { + while dest < row_end { + let alpha = unsafe { *src }; + final_buffer[dest + 0] = alpha; + final_buffer[dest + 1] = alpha; + final_buffer[dest + 2] = alpha; + final_buffer[dest + 3] = alpha; + src = unsafe { src.offset(1) }; + dest += 4; } - _ => panic!("Unsupported {:?}", pixel_mode), - }; - let i = 4 * (y * actual_width + x) as usize; - let dest = &mut final_buffer[i .. i + 4]; - dest.clone_from_slice(&value); + } + FT_Pixel_Mode::FT_PIXEL_MODE_LCD => { + if subpixel_bgr { + while dest < row_end { + final_buffer[dest + 0] = unsafe { *src }; + final_buffer[dest + 1] = unsafe { *src.offset(1) }; + final_buffer[dest + 2] = unsafe { *src.offset(2) }; + final_buffer[dest + 3] = 0xff; + src = unsafe { src.offset(3) }; + dest += 4; + } + } else { + while dest < row_end { + final_buffer[dest + 2] = unsafe { *src }; + final_buffer[dest + 1] = unsafe { *src.offset(1) }; + final_buffer[dest + 0] = unsafe { *src.offset(2) }; + final_buffer[dest + 3] = 0xff; + src = unsafe { src.offset(3) }; + dest += 4; + } + } + } + FT_Pixel_Mode::FT_PIXEL_MODE_LCD_V => { + if subpixel_bgr { + while dest < row_end { + final_buffer[dest + 0] = unsafe { *src }; + final_buffer[dest + 1] = unsafe { *src.offset(bitmap.pitch as isize) }; + final_buffer[dest + 2] = unsafe { *src.offset((2 * bitmap.pitch) as isize) }; + final_buffer[dest + 3] = 0xff; + src = unsafe { src.offset(1) }; + dest += 4; + } + } else { + while dest < row_end { + final_buffer[dest + 2] = unsafe { *src }; + final_buffer[dest + 1] = unsafe { *src.offset(bitmap.pitch as isize) }; + final_buffer[dest + 0] = unsafe { *src.offset((2 * bitmap.pitch) as isize) }; + final_buffer[dest + 3] = 0xff; + src = unsafe { src.offset(1) }; + dest += 4; + } + } + src_row = unsafe { src_row.offset((2 * bitmap.pitch) as isize) }; + } + FT_Pixel_Mode::FT_PIXEL_MODE_BGRA => { + // The source is premultiplied BGRA data. + let dest_slice = &mut final_buffer[dest .. row_end]; + let src_slice = unsafe { slice::from_raw_parts(src, dest_slice.len()) }; + dest_slice.copy_from_slice(src_slice); + } + _ => panic!("Unsupported {:?}", pixel_mode), } + src_row = unsafe { src_row.offset(bitmap.pitch as isize) }; } Some(RasterizedGlyph { - left: (dimensions.left + left) as f32, - top: (dimensions.top + top - actual_height) as f32, + left: ((dimensions.left + left) as f32 * scale).round(), + top: ((dimensions.top + top - actual_height) as f32 * scale).round(), width: actual_width as u32, height: actual_height as u32, + scale, bytes: final_buffer, }) } diff --git a/gfx/webrender/src/platform/windows/font.rs b/gfx/webrender/src/platform/windows/font.rs index 13287aeb1228..d251106268df 100644 --- a/gfx/webrender/src/platform/windows/font.rs +++ b/gfx/webrender/src/platform/windows/font.rs @@ -33,6 +33,7 @@ pub struct RasterizedGlyph { pub left: f32, pub width: u32, pub height: u32, + pub scale: f32, pub bytes: Vec, } @@ -304,11 +305,15 @@ impl FontContext { } } - pub fn is_bitmap_font(&mut self, _font_key: FontKey) -> bool { + pub fn is_bitmap_font(&mut self, _font: &FontInstance) -> bool { // TODO(gw): Support bitmap fonts in DWrite. false } + pub fn has_gamma_correct_subpixel_aa() -> bool { + true + } + pub fn rasterize_glyph( &mut self, font: &FontInstance, @@ -329,22 +334,25 @@ impl FontContext { let mut pixels = analysis.create_alpha_texture(texture_type, bounds); - if font.render_mode != FontRenderMode::Mono { - let lut_correction = match font.platform_options { - Some(option) => if option.force_gdi_rendering { - &self.gdi_gamma_lut - } else { - &self.gamma_lut - }, - None => &self.gamma_lut, - }; + match font.render_mode { + FontRenderMode::Mono | FontRenderMode::Bitmap => {} + FontRenderMode::Alpha | FontRenderMode::Subpixel => { + let lut_correction = match font.platform_options { + Some(option) => if option.force_gdi_rendering { + &self.gdi_gamma_lut + } else { + &self.gamma_lut + }, + None => &self.gamma_lut, + }; - lut_correction.preblend_rgb( - &mut pixels, - width, - height, - ColorLut::new(font.color.r, font.color.g, font.color.b, font.color.a), - ); + lut_correction.preblend_rgb( + &mut pixels, + width, + height, + ColorLut::new(font.color.r, font.color.g, font.color.b, font.color.a), + ); + } } let rgba_pixels = self.convert_to_rgba(&mut pixels, font.render_mode); @@ -354,6 +362,7 @@ impl FontContext { top: -bounds.top as f32, width: width as u32, height: height as u32, + scale: 1.0, bytes: rgba_pixels, }) } diff --git a/gfx/webrender/src/prim_store.rs b/gfx/webrender/src/prim_store.rs index 8cfdffda8af2..9d2b7c2064a2 100644 --- a/gfx/webrender/src/prim_store.rs +++ b/gfx/webrender/src/prim_store.rs @@ -5,7 +5,7 @@ use api::{BorderRadius, BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect, DeviceIntSize}; use api::{DevicePoint, ExtendMode, FontInstance, FontRenderMode, GlyphInstance, GlyphKey}; use api::{GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag, LayerPoint, LayerRect}; -use api::{LayerSize, LayerVector2D, LineOrientation, LineStyle, Shadow}; +use api::{LayerSize, LayerVector2D, LineOrientation, LineStyle}; use api::{TileOffset, YuvColorSpace, YuvFormat, device_length}; use app_units::Au; use border::BorderCornerInstance; @@ -14,6 +14,7 @@ use euclid::Size2D; use frame_builder::PrimitiveContext; use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest, ToGpuBlocks}; +use picture::PicturePrimitive; use render_task::{ClipWorkItem, RenderTask, RenderTaskId, RenderTaskTree}; use renderer::MAX_VERTEX_TEXTURE_WIDTH; use resource_cache::{ImageProperties, ResourceCache}; @@ -110,8 +111,8 @@ pub enum PrimitiveKind { AngleGradient, RadialGradient, BoxShadow, - Shadow, Line, + Picture, } impl GpuCacheHandle { @@ -514,13 +515,6 @@ impl RadialGradientPrimitiveCpu { } } -#[derive(Debug)] -pub struct ShadowPrimitiveCpu { - pub shadow: Shadow, - pub primitives: Vec, - pub render_task_id: Option, -} - #[derive(Debug, Clone)] pub struct TextRunPrimitiveCpu { pub font: FontInstance, @@ -529,8 +523,6 @@ pub struct TextRunPrimitiveCpu { pub glyph_count: usize, pub glyph_keys: Vec, pub glyph_gpu_blocks: Vec, - pub shadow_render_mode: FontRenderMode, - pub color: ColorF, } #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -540,6 +532,23 @@ pub enum TextRunMode { } impl TextRunPrimitiveCpu { + pub fn get_font(&self, + run_mode: TextRunMode, + device_pixel_ratio: f32, + ) -> FontInstance { + let mut font = self.font.clone(); + match run_mode { + TextRunMode::Normal => {} + TextRunMode::Shadow => { + // Shadows never use subpixel AA, but need to respect the alpha/mono flag + // for reftests. + font.render_mode = font.render_mode.limit_by(FontRenderMode::Alpha); + } + }; + font.size = font.size.scale_by(device_pixel_ratio); + font + } + fn prepare_for_render( &mut self, resource_cache: &mut ResourceCache, @@ -548,33 +557,22 @@ impl TextRunPrimitiveCpu { run_mode: TextRunMode, gpu_cache: &mut GpuCache, ) { - let mut font = self.font.clone(); - font.size = font.size.scale_by(device_pixel_ratio); - match run_mode { - TextRunMode::Shadow => { - font.render_mode = self.shadow_render_mode; - } - TextRunMode::Normal => {} - } - - if run_mode == TextRunMode::Shadow { - font.render_mode = self.shadow_render_mode; - } + let font = self.get_font(run_mode, device_pixel_ratio); // Cache the glyph positions, if not in the cache already. // TODO(gw): In the future, remove `glyph_instances` // completely, and just reference the glyphs // directly from the display list. if self.glyph_keys.is_empty() { + let subpx_dir = font.subpx_dir.limit_by(font.render_mode); let src_glyphs = display_list.get(self.glyph_range); // TODO(gw): If we support chunks() on AuxIter // in the future, this code below could // be much simpler... let mut gpu_block = GpuBlockData::empty(); - for (i, src) in src_glyphs.enumerate() { - let key = GlyphKey::new(src.index, src.point, font.render_mode, font.subpx_dir); + let key = GlyphKey::new(src.index, src.point, font.render_mode, subpx_dir); self.glyph_keys.push(key); // Two glyphs are packed per GPU block. @@ -600,11 +598,11 @@ impl TextRunPrimitiveCpu { } fn write_gpu_blocks(&self, request: &mut GpuDataRequest) { - request.push(self.color); + request.push(ColorF::from(self.font.color)); request.push([ self.offset.x, self.offset.y, - self.font.subpx_dir as u32 as f32, + self.font.subpx_dir.limit_by(self.font.render_mode) as u32 as f32, 0.0, ]); request.extend_from_slice(&self.glyph_gpu_blocks); @@ -807,7 +805,7 @@ pub enum PrimitiveContainer { AngleGradient(GradientPrimitiveCpu), RadialGradient(RadialGradientPrimitiveCpu), BoxShadow(BoxShadowPrimitiveCpu), - Shadow(ShadowPrimitiveCpu), + Picture(PicturePrimitive), Line(LinePrimitive), } @@ -815,7 +813,7 @@ pub struct PrimitiveStore { /// CPU side information only. pub cpu_rectangles: Vec, pub cpu_text_runs: Vec, - pub cpu_shadows: Vec, + pub cpu_pictures: Vec, pub cpu_images: Vec, pub cpu_yuv_images: Vec, pub cpu_gradients: Vec, @@ -832,7 +830,7 @@ impl PrimitiveStore { cpu_metadata: Vec::new(), cpu_rectangles: Vec::new(), cpu_text_runs: Vec::new(), - cpu_shadows: Vec::new(), + cpu_pictures: Vec::new(), cpu_images: Vec::new(), cpu_yuv_images: Vec::new(), cpu_gradients: Vec::new(), @@ -848,7 +846,7 @@ impl PrimitiveStore { cpu_metadata: recycle_vec(self.cpu_metadata), cpu_rectangles: recycle_vec(self.cpu_rectangles), cpu_text_runs: recycle_vec(self.cpu_text_runs), - cpu_shadows: recycle_vec(self.cpu_shadows), + cpu_pictures: recycle_vec(self.cpu_pictures), cpu_images: recycle_vec(self.cpu_images), cpu_yuv_images: recycle_vec(self.cpu_yuv_images), cpu_gradients: recycle_vec(self.cpu_gradients), @@ -920,15 +918,15 @@ impl PrimitiveStore { self.cpu_text_runs.push(text_cpu); metadata } - PrimitiveContainer::Shadow(shadow) => { + PrimitiveContainer::Picture(picture) => { let metadata = PrimitiveMetadata { opacity: PrimitiveOpacity::translucent(), - prim_kind: PrimitiveKind::Shadow, - cpu_prim_index: SpecificPrimitiveIndex(self.cpu_shadows.len()), + prim_kind: PrimitiveKind::Picture, + cpu_prim_index: SpecificPrimitiveIndex(self.cpu_pictures.len()), ..base_metadata }; - self.cpu_shadows.push(shadow); + self.cpu_pictures.push(picture); metadata } PrimitiveContainer::Image(image_cpu) => { @@ -1035,9 +1033,9 @@ impl PrimitiveStore { let box_shadow = &self.cpu_box_shadows[metadata.cpu_prim_index.0]; box_shadow.render_task_id } - PrimitiveKind::Shadow => { - let shadow = &self.cpu_shadows[metadata.cpu_prim_index.0]; - shadow.render_task_id + PrimitiveKind::Picture => { + let picture = &self.cpu_pictures[metadata.cpu_prim_index.0]; + picture.render_task_id } PrimitiveKind::Rectangle | PrimitiveKind::TextRun | @@ -1114,8 +1112,8 @@ impl PrimitiveStore { // ignore the new task if we are in a dependency context box_shadow.render_task_id = render_tasks.map(|rt| rt.add(render_task)); } - PrimitiveKind::Shadow => { - let shadow = &mut self.cpu_shadows[metadata.cpu_prim_index.0]; + PrimitiveKind::Picture => { + let picture = &mut self.cpu_pictures[metadata.cpu_prim_index.0]; // This is a shadow element. Create a render task that will // render the text run to a target, and then apply a gaussian @@ -1126,14 +1124,15 @@ impl PrimitiveStore { let cache_height = (metadata.local_rect.size.height * prim_context.device_pixel_ratio).ceil() as i32; let cache_size = DeviceIntSize::new(cache_width, cache_height); - let blur_radius = device_length(shadow.shadow.blur_radius, prim_context.device_pixel_ratio); + let blur_radius = picture.as_shadow().blur_radius; + let blur_radius = device_length(blur_radius, prim_context.device_pixel_ratio); // ignore new tasks if we are in a dependency context - shadow.render_task_id = render_tasks.map(|rt| { - let prim_cache_task = RenderTask::new_prim_cache(cache_size, prim_index); - let prim_cache_task_id = rt.add(prim_cache_task); + picture.render_task_id = render_tasks.map(|rt| { + let picture_task = RenderTask::new_picture(cache_size, prim_index); + let picture_task_id = rt.add(picture_task); let render_task = - RenderTask::new_blur(blur_radius, prim_cache_task_id, rt); + RenderTask::new_blur(blur_radius, picture_task_id, rt); rt.add(render_task) }); } @@ -1234,13 +1233,14 @@ impl PrimitiveStore { let text = &self.cpu_text_runs[metadata.cpu_prim_index.0]; text.write_gpu_blocks(&mut request); } - PrimitiveKind::Shadow => { - let prim = &self.cpu_shadows[metadata.cpu_prim_index.0]; - request.push(prim.shadow.color); + PrimitiveKind::Picture => { + let picture = &self.cpu_pictures[metadata.cpu_prim_index.0]; + let shadow = picture.as_shadow(); + request.push(shadow.color); request.push([ - prim.shadow.offset.x, - prim.shadow.offset.y, - prim.shadow.blur_radius, + shadow.offset.x, + shadow.offset.y, + shadow.blur_radius, 0.0, ]); } @@ -1374,8 +1374,8 @@ impl PrimitiveStore { }; let dependencies = match metadata.prim_kind { - PrimitiveKind::Shadow => - self.cpu_shadows[metadata.cpu_prim_index.0].primitives.clone(), + PrimitiveKind::Picture => + self.cpu_pictures[metadata.cpu_prim_index.0].prim_runs.clone(), _ => Vec::new(), }; (geometry, dependencies) @@ -1386,15 +1386,19 @@ impl PrimitiveStore { // Specifically, the clone() below on the primitive list for // text shadow primitives. Consider restructuring this code to // avoid borrow checker issues. - for sub_prim_index in dependent_primitives { - self.prepare_prim_for_render_inner( - sub_prim_index, - prim_context, - resource_cache, - gpu_cache, - None, - TextRunMode::Shadow, - ); + for run in dependent_primitives { + for i in 0 .. run.count { + let sub_prim_index = PrimitiveIndex(run.prim_index.0 + i); + + self.prepare_prim_for_render_inner( + sub_prim_index, + prim_context, + resource_cache, + gpu_cache, + None, + TextRunMode::Shadow, + ); + } } if !self.update_clip_task( diff --git a/gfx/webrender/src/render_backend.rs b/gfx/webrender/src/render_backend.rs index 3bb96fec3cc0..7781b52165ce 100644 --- a/gfx/webrender/src/render_backend.rs +++ b/gfx/webrender/src/render_backend.rs @@ -712,8 +712,6 @@ impl ToDebugString for SpecificDisplayItem { SpecificDisplayItem::Clip(..) => String::from("clip"), SpecificDisplayItem::ScrollFrame(..) => String::from("scroll_frame"), SpecificDisplayItem::StickyFrame(..) => String::from("sticky_frame"), - SpecificDisplayItem::PushNestedDisplayList => String::from("push_nested_display_list"), - SpecificDisplayItem::PopNestedDisplayList => String::from("pop_nested_display_list"), SpecificDisplayItem::SetGradientStops => String::from("set_gradient_stops"), SpecificDisplayItem::PopStackingContext => String::from("pop_stacking_context"), SpecificDisplayItem::PushShadow(..) => String::from("push_shadow"), diff --git a/gfx/webrender/src/render_task.rs b/gfx/webrender/src/render_task.rs index 7bc6b4ea4c26..22435513605a 100644 --- a/gfx/webrender/src/render_task.rs +++ b/gfx/webrender/src/render_task.rs @@ -226,7 +226,7 @@ pub struct RenderTaskData { #[derive(Debug)] pub enum RenderTaskKind { Alpha(AlphaRenderTask), - CachePrimitive(PrimitiveIndex), + Picture(PrimitiveIndex), BoxShadow(PrimitiveIndex), CacheMask(CacheMaskTask), VerticalBlur(DeviceIntLength), @@ -269,12 +269,12 @@ impl RenderTask { Self::new_alpha_batch(rect.origin, location, frame_output_pipeline_id) } - pub fn new_prim_cache(size: DeviceIntSize, prim_index: PrimitiveIndex) -> RenderTask { + pub fn new_picture(size: DeviceIntSize, prim_index: PrimitiveIndex) -> RenderTask { RenderTask { cache_key: None, children: Vec::new(), location: RenderTaskLocation::Dynamic(None, size), - kind: RenderTaskKind::CachePrimitive(prim_index), + kind: RenderTaskKind::Picture(prim_index), } } @@ -329,7 +329,10 @@ impl RenderTask { } match clip_info.bounds.inner { - Some(ref inner) if !inner.device_rect.is_empty() => { + // Inner rects aren't valid if the item is not axis-aligned, which can + // be determined by the apply_rectangles field. This is mostly a band-aid + // until we have better handling of inner rectangles for transformed clips. + Some(ref inner) if !work_item.apply_rectangles && !inner.device_rect.is_empty() => { inner_rect = inner_rect.and_then(|r| r.intersection(&inner.device_rect)); !inner.device_rect.contains_rect(&task_rect) } @@ -423,7 +426,7 @@ impl RenderTask { pub fn as_alpha_batch_mut<'a>(&'a mut self) -> &'a mut AlphaRenderTask { match self.kind { RenderTaskKind::Alpha(ref mut task) => task, - RenderTaskKind::CachePrimitive(..) | + RenderTaskKind::Picture(..) | RenderTaskKind::BoxShadow(..) | RenderTaskKind::CacheMask(..) | RenderTaskKind::VerticalBlur(..) | @@ -436,7 +439,7 @@ impl RenderTask { pub fn as_alpha_batch<'a>(&'a self) -> &'a AlphaRenderTask { match self.kind { RenderTaskKind::Alpha(ref task) => task, - RenderTaskKind::CachePrimitive(..) | + RenderTaskKind::Picture(..) | RenderTaskKind::BoxShadow(..) | RenderTaskKind::CacheMask(..) | RenderTaskKind::VerticalBlur(..) | @@ -478,7 +481,7 @@ impl RenderTask { ], } } - RenderTaskKind::CachePrimitive(..) | RenderTaskKind::BoxShadow(..) => { + RenderTaskKind::Picture(..) | RenderTaskKind::BoxShadow(..) => { let (target_rect, target_index) = self.get_target_rect(); RenderTaskData { data: [ @@ -580,7 +583,7 @@ impl RenderTask { pub fn target_kind(&self) -> RenderTargetKind { match self.kind { RenderTaskKind::Alpha(..) | - RenderTaskKind::CachePrimitive(..) | + RenderTaskKind::Picture(..) | RenderTaskKind::VerticalBlur(..) | RenderTaskKind::Readback(..) | RenderTaskKind::HorizontalBlur(..) => RenderTargetKind::Color, @@ -604,7 +607,7 @@ impl RenderTask { pub fn is_shared(&self) -> bool { match self.kind { RenderTaskKind::Alpha(..) | - RenderTaskKind::CachePrimitive(..) | + RenderTaskKind::Picture(..) | RenderTaskKind::VerticalBlur(..) | RenderTaskKind::Readback(..) | RenderTaskKind::HorizontalBlur(..) => false, diff --git a/gfx/webrender/src/renderer.rs b/gfx/webrender/src/renderer.rs index 5f88b89d85b5..16041fb8fcf0 100644 --- a/gfx/webrender/src/renderer.rs +++ b/gfx/webrender/src/renderer.rs @@ -10,7 +10,7 @@ //! [renderer]: struct.Renderer.html use api::{channel, BlobImageRenderer, FontRenderMode}; -use api::{ColorF, Epoch, PipelineId, RenderApiSender, RenderNotifier}; +use api::{ColorF, ColorU, Epoch, PipelineId, RenderApiSender, RenderNotifier}; use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUintSize}; use api::{ExternalImageId, ExternalImageType, ImageFormat}; use api::{YUV_COLOR_SPACES, YUV_FORMATS}; @@ -627,7 +627,7 @@ pub enum BlendMode { PremultipliedAlpha, // Use the color of the text itself as a constant color blend factor. - Subpixel(ColorF), + Subpixel(ColorU), } // Tracks the state of each row in the GPU cache texture. @@ -2747,7 +2747,7 @@ impl Renderer { } BlendMode::Subpixel(color) => { self.device.set_blend(true); - self.device.set_blend_mode_subpixel(color); + self.device.set_blend_mode_subpixel(color.into()); } } prev_blend_mode = batch.key.blend_mode; diff --git a/gfx/webrender/src/resource_cache.rs b/gfx/webrender/src/resource_cache.rs index aaca81c1c976..aae4ae46056d 100644 --- a/gfx/webrender/src/resource_cache.rs +++ b/gfx/webrender/src/resource_cache.rs @@ -4,7 +4,7 @@ use api::{AddFont, BlobImageData, BlobImageResources, ResourceUpdate, ResourceUpdates}; use api::{BlobImageDescriptor, BlobImageError, BlobImageRenderer, BlobImageRequest}; -use api::{ColorF, FontRenderMode, SubpixelDirection}; +use api::{ColorF, FontRenderMode}; use api::{DevicePoint, DeviceUintRect, DeviceUintSize}; use api::{Epoch, FontInstance, FontInstanceKey, FontKey, FontTemplate}; use api::{ExternalImageData, ExternalImageType}; @@ -337,29 +337,26 @@ impl ResourceCache { platform_options: Option, variations: Vec, ) { - let mut requested_render_mode = FontRenderMode::Subpixel; - let mut subpx_dir = SubpixelDirection::Horizontal; - if let Some(options) = options { - if let Some(render_mode) = options.render_mode { - requested_render_mode = render_mode; - } - } - if self.glyph_rasterizer.is_bitmap_font(font_key) { - requested_render_mode = requested_render_mode.limit_by(FontRenderMode::Bitmap); - } - if requested_render_mode == FontRenderMode::Mono { - subpx_dir = SubpixelDirection::None; - } - let instance = FontInstance::new( + let FontInstanceOptions { + render_mode, + subpx_dir, + synthetic_italics, + .. + } = options.unwrap_or_default(); + assert!(render_mode != FontRenderMode::Bitmap); + let mut instance = FontInstance::new( font_key, glyph_size, ColorF::new(0.0, 0.0, 0.0, 1.0), - requested_render_mode, + render_mode, subpx_dir, platform_options, variations, - options.map_or(false, |opts| opts.synthetic_italics), + synthetic_italics, ); + if self.glyph_rasterizer.is_bitmap_font(&instance) { + instance.render_mode = instance.render_mode.limit_by(FontRenderMode::Bitmap); + } self.resources.font_instances.insert(instance_key, instance); } @@ -564,12 +561,13 @@ impl ResourceCache { pub fn request_glyphs( &mut self, - font: FontInstance, + mut font: FontInstance, glyph_keys: &[GlyphKey], gpu_cache: &mut GpuCache, ) { debug_assert_eq!(self.state, State::AddResources); + self.glyph_rasterizer.prepare_font(&mut font); self.glyph_rasterizer.request_glyphs( &mut self.cached_glyphs, font, @@ -585,7 +583,7 @@ impl ResourceCache { pub fn fetch_glyphs( &self, - font: FontInstance, + mut font: FontInstance, glyph_keys: &[GlyphKey], fetch_buffer: &mut Vec, gpu_cache: &GpuCache, @@ -594,17 +592,16 @@ impl ResourceCache { F: FnMut(SourceTexture, &[GlyphFetchResult]), { debug_assert_eq!(self.state, State::QueryResources); + + self.glyph_rasterizer.prepare_font(&mut font); let glyph_key_cache = self.cached_glyphs.get_glyph_key_cache_for_font(&font); let mut current_texture_id = SourceTexture::Invalid; debug_assert!(fetch_buffer.is_empty()); for (loop_index, key) in glyph_keys.iter().enumerate() { - let glyph = glyph_key_cache.get(key); - let cache_item = glyph - .as_ref() - .map(|info| self.texture_cache.get(&info.texture_cache_handle)); - if let Some(cache_item) = cache_item { + if let Some(ref glyph) = *glyph_key_cache.get(key) { + let cache_item = self.texture_cache.get(&glyph.texture_cache_handle); if current_texture_id != cache_item.texture_id { if !fetch_buffer.is_empty() { f(current_texture_id, fetch_buffer); @@ -825,7 +822,7 @@ impl ResourceCache { descriptor, filter, image_data, - [0.0; 2], + [0.0; 3], image_template.dirty_rect, gpu_cache, ); diff --git a/gfx/webrender/src/texture_cache.rs b/gfx/webrender/src/texture_cache.rs index 91113685a971..4d98e1230f6b 100644 --- a/gfx/webrender/src/texture_cache.rs +++ b/gfx/webrender/src/texture_cache.rs @@ -84,7 +84,7 @@ struct CacheEntry { // Details specific to standalone or shared items. kind: EntryKind, // Arbitrary user data associated with this item. - user_data: [f32; 2], + user_data: [f32; 3], // The last frame this item was requested for rendering. last_access: FrameId, // Handle to the resource rect in the GPU cache. @@ -101,7 +101,7 @@ impl CacheEntry { texture_id: CacheTextureId, size: DeviceUintSize, format: ImageFormat, - user_data: [f32; 2], + user_data: [f32; 3], last_access: FrameId, ) -> CacheEntry { CacheEntry { @@ -135,7 +135,7 @@ impl CacheEntry { (origin.x + self.size.width) as f32, (origin.y + self.size.height) as f32, ]); - request.push([layer_index, self.user_data[0], self.user_data[1], 0.0]); + request.push([layer_index, self.user_data[0], self.user_data[1], self.user_data[2]]); } } } @@ -275,7 +275,7 @@ impl TextureCache { descriptor: ImageDescriptor, filter: TextureFilter, data: ImageData, - user_data: [f32; 2], + user_data: [f32; 3], mut dirty_rect: Option, gpu_cache: &mut GpuCache, ) { @@ -512,7 +512,7 @@ impl TextureCache { fn allocate_from_shared_cache( &mut self, descriptor: &ImageDescriptor, - user_data: [f32; 2], + user_data: [f32; 3], ) -> Option { // Work out which cache it goes in, based on format. let texture_array = match descriptor.format { @@ -561,7 +561,7 @@ impl TextureCache { handle: &mut TextureCacheHandle, descriptor: ImageDescriptor, filter: TextureFilter, - user_data: [f32; 2], + user_data: [f32; 3], ) { assert!(descriptor.width > 0 && descriptor.height > 0); @@ -855,7 +855,7 @@ impl TextureArray { &mut self, width: u32, height: u32, - user_data: [f32; 2], + user_data: [f32; 3], frame_id: FrameId, ) -> Option { // Lazily allocate the regions if not already created. diff --git a/gfx/webrender/src/tiling.rs b/gfx/webrender/src/tiling.rs index d811a25b108e..0453951d079c 100644 --- a/gfx/webrender/src/tiling.rs +++ b/gfx/webrender/src/tiling.rs @@ -16,7 +16,7 @@ use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveIn use internal_types::{FastHashMap, SourceTexture}; use internal_types::BatchTextures; use prim_store::{PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore}; -use prim_store::DeferredResolve; +use prim_store::{DeferredResolve, TextRunMode}; use profiler::FrameProfileCounters; use render_task::{AlphaRenderItem, ClipWorkItem, MaskGeometryKind, MaskSegment}; use render_task::{RenderTaskAddress, RenderTaskId, RenderTaskKey, RenderTaskKind}; @@ -26,7 +26,8 @@ use renderer::ImageBufferKind; use resource_cache::{GlyphFetchResult, ResourceCache}; use std::{cmp, usize, f32, i32}; use texture_allocator::GuillotineAllocator; -use util::{TransformedRect, TransformedRectKind}; +use util::{MatrixHelpers, TransformedRect, TransformedRectKind}; +use euclid::rect; // Special sentinel value recognized by the shader. It is considered to be // a dummy task that doesn't mask out anything. @@ -54,17 +55,17 @@ impl AlphaBatchHelpers for PrimitiveStore { PrimitiveKind::TextRun => { let text_run_cpu = &self.cpu_text_runs[metadata.cpu_prim_index.0]; match text_run_cpu.font.render_mode { - FontRenderMode::Subpixel => BlendMode::Subpixel(text_run_cpu.color), + FontRenderMode::Subpixel => BlendMode::Subpixel(text_run_cpu.font.color), FontRenderMode::Alpha | FontRenderMode::Mono | - FontRenderMode::Bitmap => BlendMode::Alpha, + FontRenderMode::Bitmap => BlendMode::PremultipliedAlpha, } } PrimitiveKind::Image | PrimitiveKind::AlignedGradient | PrimitiveKind::AngleGradient | PrimitiveKind::RadialGradient | - PrimitiveKind::Shadow => if needs_blending { + PrimitiveKind::Picture => if needs_blending { BlendMode::PremultipliedAlpha } else { BlendMode::None @@ -507,8 +508,7 @@ impl AlphaRenderItem { let text_cpu = &ctx.prim_store.cpu_text_runs[prim_metadata.cpu_prim_index.0]; - let mut font = text_cpu.font.clone(); - font.size = font.size.scale_by(ctx.device_pixel_ratio); + let font = text_cpu.get_font(TextRunMode::Normal, ctx.device_pixel_ratio); ctx.resource_cache.fetch_glyphs( font, @@ -528,6 +528,7 @@ impl AlphaRenderItem { transform_kind, TransformBatchKind::TextRun, ); + let key = BatchKey::new(kind, blend_mode, textures); let batch = batch_list.get_suitable_batch(key, item_bounding_rect); @@ -541,10 +542,10 @@ impl AlphaRenderItem { }, ); } - PrimitiveKind::Shadow => { - let shadow = - &ctx.prim_store.cpu_shadows[prim_metadata.cpu_prim_index.0]; - let cache_task_id = shadow.render_task_id.expect("no render task!"); + PrimitiveKind::Picture => { + let picture = + &ctx.prim_store.cpu_pictures[prim_metadata.cpu_prim_index.0]; + let cache_task_id = picture.render_task_id.expect("no render task!"); let cache_task_address = render_tasks.get_task_address(cache_task_id); let textures = BatchTextures::render_target_cache(); let kind = BatchKind::Transformable( @@ -1135,67 +1136,69 @@ impl RenderTarget for ColorRenderTarget { blur_direction: BlurDirection::Horizontal, }); } - RenderTaskKind::CachePrimitive(prim_index) => { + RenderTaskKind::Picture(prim_index) => { let prim_metadata = ctx.prim_store.get_metadata(prim_index); let prim_address = prim_metadata.gpu_location.as_int(gpu_cache); match prim_metadata.prim_kind { - PrimitiveKind::Shadow => { - let prim = &ctx.prim_store.cpu_shadows[prim_metadata.cpu_prim_index.0]; + PrimitiveKind::Picture => { + let prim = &ctx.prim_store.cpu_pictures[prim_metadata.cpu_prim_index.0]; let task_index = render_tasks.get_task_address(task_id); - for sub_prim_index in &prim.primitives { - let sub_metadata = ctx.prim_store.get_metadata(*sub_prim_index); - let sub_prim_address = - gpu_cache.get_address(&sub_metadata.gpu_location); - let instance = SimplePrimitiveInstance::new( - sub_prim_address, - task_index, - RenderTaskAddress(0), - PackedLayerIndex(0).into(), - 0, - ); // z is disabled for rendering cache primitives + for run in &prim.prim_runs { + for i in 0 .. run.count { + let sub_prim_index = PrimitiveIndex(run.prim_index.0 + i); - match sub_metadata.prim_kind { - PrimitiveKind::TextRun => { - // Add instances that reference the text run GPU location. Also supply - // the parent shadow prim address as a user data field, allowing - // the shader to fetch the shadow parameters. - let text = &ctx.prim_store.cpu_text_runs - [sub_metadata.cpu_prim_index.0]; - let text_run_cache_prims = &mut self.text_run_cache_prims; + let sub_metadata = ctx.prim_store.get_metadata(sub_prim_index); + let sub_prim_address = + gpu_cache.get_address(&sub_metadata.gpu_location); + let instance = SimplePrimitiveInstance::new( + sub_prim_address, + task_index, + RenderTaskAddress(0), + PackedLayerIndex(0).into(), + 0, + ); // z is disabled for rendering cache primitives - let mut font = text.font.clone(); - font.size = font.size.scale_by(ctx.device_pixel_ratio); - font.render_mode = text.shadow_render_mode; + match sub_metadata.prim_kind { + PrimitiveKind::TextRun => { + // Add instances that reference the text run GPU location. Also supply + // the parent shadow prim address as a user data field, allowing + // the shader to fetch the shadow parameters. + let text = &ctx.prim_store.cpu_text_runs + [sub_metadata.cpu_prim_index.0]; + let text_run_cache_prims = &mut self.text_run_cache_prims; - ctx.resource_cache.fetch_glyphs( - font, - &text.glyph_keys, - &mut self.glyph_fetch_buffer, - gpu_cache, - |texture_id, glyphs| { - let batch = text_run_cache_prims - .entry(texture_id) - .or_insert(Vec::new()); + let font = text.get_font(TextRunMode::Shadow, ctx.device_pixel_ratio); - for glyph in glyphs { - batch.push(instance.build( - glyph.index_in_text_run, - glyph.uv_rect_address.as_int(), - prim_address, - )); - } - }, - ); - } - PrimitiveKind::Line => { - self.line_cache_prims - .push(instance.build(prim_address, 0, 0)); - } - _ => { - unreachable!("Unexpected sub primitive type"); + ctx.resource_cache.fetch_glyphs( + font, + &text.glyph_keys, + &mut self.glyph_fetch_buffer, + gpu_cache, + |texture_id, glyphs| { + let batch = text_run_cache_prims + .entry(texture_id) + .or_insert(Vec::new()); + + for glyph in glyphs { + batch.push(instance.build( + glyph.index_in_text_run, + glyph.uv_rect_address.as_int(), + prim_address, + )); + } + }, + ); + } + PrimitiveKind::Line => { + self.line_cache_prims + .push(instance.build(prim_address, 0, 0)); + } + _ => { + unreachable!("Unexpected sub primitive type"); + } } } } @@ -1255,7 +1258,7 @@ impl RenderTarget for AlphaRenderTarget { RenderTaskKind::Alpha(..) | RenderTaskKind::VerticalBlur(..) | RenderTaskKind::HorizontalBlur(..) | - RenderTaskKind::CachePrimitive(..) | + RenderTaskKind::Picture(..) | RenderTaskKind::Readback(..) => { panic!("Should not be added to alpha target!"); } @@ -1686,7 +1689,13 @@ impl PackedLayer { screen_rect: &DeviceIntRect, device_pixel_ratio: f32, ) -> Option<(TransformedRectKind, DeviceIntRect)> { - self.local_clip_rect = *local_rect; + self.local_clip_rect = if self.transform.has_perspective_component() { + // Given a very large rect which means any rect would be inside this rect. + // That is, nothing would be clipped. + rect(f32::MIN / 2.0, f32::MIN / 2.0, f32::MAX, f32::MAX) + } else { + *local_rect + }; let xf_rect = TransformedRect::new(local_rect, &self.transform, device_pixel_ratio); xf_rect .bounding_rect diff --git a/gfx/webrender/src/util.rs b/gfx/webrender/src/util.rs index 1a20912846b9..61babac9e0d5 100644 --- a/gfx/webrender/src/util.rs +++ b/gfx/webrender/src/util.rs @@ -17,6 +17,7 @@ pub trait MatrixHelpers { fn transform_rect(&self, rect: &TypedRect) -> TypedRect; fn is_identity(&self) -> bool; fn preserves_2d_axis_alignment(&self) -> bool; + fn has_perspective_component(&self) -> bool; fn inverse_project(&self, target: &TypedPoint2D) -> Option>; fn inverse_rect_footprint(&self, rect: &TypedRect) -> TypedRect; } @@ -66,6 +67,10 @@ impl MatrixHelpers for TypedTransform3D { col0 < 2 && col1 < 2 && row0 < 2 && row1 < 2 } + fn has_perspective_component(&self) -> bool { + self.m14 != 0.0 || self.m24 != 0.0 || self.m34 != 0.0 || self.m44 != 1.0 + } + fn inverse_project(&self, target: &TypedPoint2D) -> Option> { let m: TypedTransform2D; m = TypedTransform2D::column_major( diff --git a/gfx/webrender_api/Cargo.toml b/gfx/webrender_api/Cargo.toml index dcf051e23a61..d48d086d2d8e 100644 --- a/gfx/webrender_api/Cargo.toml +++ b/gfx/webrender_api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webrender_api" -version = "0.52.0" +version = "0.52.1" authors = ["Glenn Watson "] license = "MPL-2.0" repository = "https://github.com/servo/webrender" @@ -15,7 +15,6 @@ bincode = "0.8" bitflags = "0.9" byteorder = "1.0" euclid = "0.15" -fxhash = "0.2.1" heapsize = ">= 0.3.6, < 0.5" ipc-channel = {version = "0.8", optional = true} serde = { version = "1.0", features = ["rc", "derive"] } diff --git a/gfx/webrender_api/src/display_item.rs b/gfx/webrender_api/src/display_item.rs index 7833bbe0017c..856b00fe9f15 100644 --- a/gfx/webrender_api/src/display_item.rs +++ b/gfx/webrender_api/src/display_item.rs @@ -102,8 +102,6 @@ pub enum SpecificDisplayItem { PushStackingContext(PushStackingContextDisplayItem), PopStackingContext, SetGradientStops, - PushNestedDisplayList, - PopNestedDisplayList, PushShadow(Shadow), PopShadow, } @@ -629,18 +627,16 @@ impl ComplexClipRegion { } } -pub type NestingIndex = u64; - #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum ClipId { - Clip(u64, NestingIndex, PipelineId), + Clip(u64, PipelineId), ClipExternalId(u64, PipelineId), DynamicallyAddedNode(u64, PipelineId), } impl ClipId { pub fn root_scroll_node(pipeline_id: PipelineId) -> ClipId { - ClipId::Clip(0, 0, pipeline_id) + ClipId::Clip(0, pipeline_id) } pub fn root_reference_frame(pipeline_id: PipelineId) -> ClipId { @@ -659,7 +655,7 @@ impl ClipId { pub fn pipeline_id(&self) -> PipelineId { match *self { - ClipId::Clip(_, _, pipeline_id) | + ClipId::Clip(_, pipeline_id) | ClipId::ClipExternalId(_, pipeline_id) | ClipId::DynamicallyAddedNode(_, pipeline_id) => pipeline_id, } @@ -674,14 +670,7 @@ impl ClipId { pub fn is_root_scroll_node(&self) -> bool { match *self { - ClipId::Clip(0, 0, _) => true, - _ => false, - } - } - - pub fn is_nested(&self) -> bool { - match *self { - ClipId::Clip(_, nesting_level, _) => nesting_level != 0, + ClipId::Clip(0, _) => true, _ => false, } } diff --git a/gfx/webrender_api/src/display_list.rs b/gfx/webrender_api/src/display_list.rs index 2a23482e9bdf..5a1c5b65203e 100644 --- a/gfx/webrender_api/src/display_list.rs +++ b/gfx/webrender_api/src/display_list.rs @@ -4,7 +4,7 @@ use {BorderDetails, BorderDisplayItem, BorderWidths, BoxShadowClipMode, BoxShadowDisplayItem}; use {ClipAndScrollInfo, ClipDisplayItem, ClipId, ColorF, ComplexClipRegion, DisplayItem}; -use {ExtendMode, FastHashMap, FastHashSet, FilterOp, FontInstanceKey, GlyphIndex, GlyphInstance}; +use {ExtendMode, FilterOp, FontInstanceKey, GlyphInstance}; use {GlyphOptions, Gradient, GradientDisplayItem, GradientStop, IframeDisplayItem}; use {ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo, LayoutPoint}; use {LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; @@ -17,6 +17,8 @@ use YuvImageDisplayItem; use bincode; use serde::{Deserialize, Serialize, Serializer}; use serde::ser::{SerializeMap, SerializeSeq}; +use std::io::Write; +use std::{io, ptr}; use std::marker::PhantomData; use time::precise_time_ns; @@ -70,8 +72,6 @@ pub struct BuiltDisplayListDescriptor { builder_finish_time: u64, /// The third IPC time stamp: just before sending send_start_time: u64, - /// The offset where DisplayItems stop and the Glyph list starts - glyph_offset: usize, } pub struct BuiltDisplayListIter<'a> { @@ -89,12 +89,6 @@ pub struct DisplayItemRef<'a: 'b, 'b> { iter: &'b BuiltDisplayListIter<'a>, } -pub struct GlyphsIter<'a> { - list: &'a BuiltDisplayList, - data: &'a [u8], -} - - #[derive(PartialEq)] enum Peek { StartPeeking, @@ -125,12 +119,9 @@ impl BuiltDisplayList { &self.data[..] } + // Currently redundant with data, but may be useful if we add extra data to dl pub fn item_slice(&self) -> &[u8] { - &self.data[.. self.descriptor.glyph_offset] - } - - pub fn glyph_slice(&self) -> &[u8] { - &self.data[self.descriptor.glyph_offset ..] + &self.data[..] } pub fn descriptor(&self) -> &BuiltDisplayListDescriptor { @@ -149,13 +140,6 @@ impl BuiltDisplayList { BuiltDisplayListIter::new(self) } - pub fn glyphs(&self) -> GlyphsIter { - GlyphsIter { - list: self, - data: self.glyph_slice(), - } - } - pub fn get<'de, T: Deserialize<'de>>(&self, range: ItemRange) -> AuxIter { AuxIter::new(&self.data[range.start .. range.start + range.length]) } @@ -312,21 +296,6 @@ impl<'a> BuiltDisplayListIter<'a> { } } -impl<'a> Iterator for GlyphsIter<'a> { - type Item = (FontInstanceKey, ColorF, ItemRange); - - fn next(&mut self) -> Option { - if self.data.len() == 0 { - return None; - } - - let (font_key, color) = bincode::deserialize_from(&mut self.data, bincode::Infinite) - .expect("MEH: malicious process?"); - let glyph_indices = skip_slice::(self.list, &mut self.data).0; - Some((font_key, color, glyph_indices)) - } -} - // Some of these might just become ItemRanges impl<'a, 'b> DisplayItemRef<'a, 'b> { pub fn display_item(&self) -> &DisplayItem { @@ -483,19 +452,98 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> { } } +// This is a replacement for bincode::serialize_into(&vec) +// The default implementation Write for Vec will basically +// call extend_from_slice(). Serde ends up calling that for every +// field of a struct that we're serializing. extend_from_slice() +// does not get inlined and thus we end up calling a generic memcpy() +// implementation. If we instead reserve enough room for the serialized +// struct in the Vec ahead of time we can rely on that and use +// the following UnsafeVecWriter to write into the vec without +// any checks. This writer assumes that size returned by the +// serialize function will not change between calls to serialize_into: +// +// For example, the following struct will cause memory unsafety when +// used with UnsafeVecWriter. +// +// struct S { +// first: Cell, +// } +// +// impl Serialize for S { +// fn serialize(&self, serializer: S) -> Result +// where S: Serializer +// { +// if self.first.get() { +// self.first.set(false); +// ().serialize(serializer) +// } else { +// 0.serialize(serializer) +// } +// } +// } +// + +struct UnsafeVecWriter(*mut u8); + +impl Write for UnsafeVecWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + unsafe { + ptr::copy_nonoverlapping(buf.as_ptr(), self.0, buf.len()); + self.0 = self.0.offset(buf.len() as isize); + } + Ok(buf.len()) + } + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} + +struct SizeCounter(usize); + +impl<'a> Write for SizeCounter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.0 += buf.len(); + Ok(buf.len()) + } + fn flush(&mut self) -> io::Result<()> { Ok(()) } +} + +fn serialize_fast(vec: &mut Vec, e: &T) { + // manually counting the size is faster than vec.reserve(bincode::serialized_size(&e) as usize) for some reason + let mut size = SizeCounter(0); + bincode::serialize_into(&mut size,e , bincode::Infinite).unwrap(); + vec.reserve(size.0); + + let old_len = vec.len(); + let ptr = unsafe { vec.as_mut_ptr().offset(old_len as isize) }; + let mut w = UnsafeVecWriter(ptr); + bincode::serialize_into(&mut w, e, bincode::Infinite).unwrap(); + + // fix up the length + unsafe { vec.set_len(old_len + size.0); } + + // make sure we wrote the right amount + debug_assert!(((w.0 as usize) - (vec.as_ptr() as usize)) == vec.len()); +} + +#[derive(Clone, Debug)] +pub struct SaveState { + dl_len: usize, + clip_stack_len: usize, + next_clip_id: u64, +} + #[derive(Clone)] pub struct DisplayListBuilder { pub data: Vec, pub pipeline_id: PipelineId, clip_stack: Vec, - // FIXME: audit whether fast hashers (FNV?) are safe here - glyphs: FastHashMap<(FontInstanceKey, ColorF), FastHashSet>, next_clip_id: u64, builder_start_time: u64, /// The size of the content of this display list. This is used to allow scrolling /// outside the bounds of the display list items themselves. content_size: LayoutSize, + save_state: Option, } impl DisplayListBuilder { @@ -519,13 +567,44 @@ impl DisplayListBuilder { clip_stack: vec![ ClipAndScrollInfo::simple(ClipId::root_scroll_node(pipeline_id)), ], - glyphs: FastHashMap::default(), next_clip_id: FIRST_CLIP_ID, builder_start_time: start_time, content_size, + save_state: None, } } + /// Saves the current display list state, so it may be `restore()`'d. + /// + /// # Conditions: + /// + /// * Doesn't support popping clips that were pushed before the save. + /// * Doesn't support nested saves. + /// * Must call `clear_save()` if the restore becomes unnecessary. + pub fn save(&mut self) { + assert!(self.save_state.is_none(), "DisplayListBuilder doesn't support nested saves"); + + self.save_state = Some(SaveState { + clip_stack_len: self.clip_stack.len(), + dl_len: self.data.len(), + next_clip_id: self.next_clip_id, + }); + } + + /// Restores the state of the builder to when `save()` was last called. + pub fn restore(&mut self) { + let state = self.save_state.take().expect("No save to restore DisplayListBuilder from"); + + self.clip_stack.truncate(state.clip_stack_len); + self.data.truncate(state.dl_len); + self.next_clip_id = state.next_clip_id; + } + + /// Discards the builder's save (indicating the attempted operation was sucessful). + pub fn clear_save(&mut self) { + self.save_state.take().expect("No save to clear in DisplayListBuilder"); + } + pub fn print_display_list(&mut self) { let mut temp = BuiltDisplayList::default(); ::std::mem::swap(&mut temp.data, &mut self.data); @@ -541,28 +620,26 @@ impl DisplayListBuilder { } fn push_item(&mut self, item: SpecificDisplayItem, info: &LayoutPrimitiveInfo) { - bincode::serialize_into( + serialize_fast( &mut self.data, &DisplayItem { item, clip_and_scroll: *self.clip_stack.last().unwrap(), info: *info, }, - bincode::Infinite, - ).unwrap(); + ) } fn push_new_empty_item(&mut self, item: SpecificDisplayItem) { let info = LayoutPrimitiveInfo::new(LayoutRect::zero()); - bincode::serialize_into( + serialize_fast( &mut self.data, &DisplayItem { item, clip_and_scroll: *self.clip_stack.last().unwrap(), info, - }, - bincode::Infinite, - ).unwrap(); + } + ) } fn push_iter(&mut self, iter: I) @@ -575,10 +652,10 @@ impl DisplayListBuilder { let len = iter.len(); let mut count = 0; - bincode::serialize_into(&mut self.data, &len, bincode::Infinite).unwrap(); + serialize_fast(&mut self.data, &len); for elem in iter { count += 1; - bincode::serialize_into(&mut self.data, &elem, bincode::Infinite).unwrap(); + serialize_fast(&mut self.data, &elem); } debug_assert_eq!(len, count); @@ -664,29 +741,9 @@ impl DisplayListBuilder { for split_glyphs in glyphs.chunks(MAX_TEXT_RUN_LENGTH) { self.push_item(item, info); self.push_iter(split_glyphs); - - // Remember that we've seen these glyphs - self.cache_glyphs( - font_key, - color, - split_glyphs.iter().map(|glyph| glyph.index), - ); } } - fn cache_glyphs>( - &mut self, - font_key: FontInstanceKey, - color: ColorF, - glyphs: I, - ) { - let font_glyphs = self.glyphs - .entry((font_key, color)) - .or_insert(FastHashSet::default()); - - font_glyphs.extend(glyphs); - } - // Gradients can be defined with stops outside the range of [0, 1] // when this happens the gradient needs to be normalized by adjusting // the gradient stops and gradient line into an equivalent gradient @@ -969,7 +1026,7 @@ impl DisplayListBuilder { fn generate_clip_id(&mut self, id: Option) -> ClipId { id.unwrap_or_else(|| { self.next_clip_id += 1; - ClipId::Clip(self.next_clip_id - 1, 0, self.pipeline_id) + ClipId::Clip(self.next_clip_id - 1, self.pipeline_id) }) } @@ -1104,6 +1161,10 @@ impl DisplayListBuilder { pub fn pop_clip_id(&mut self) { self.clip_stack.pop(); + if let Some(save_state) = self.save_state.as_ref() { + assert!(self.clip_stack.len() >= save_state.clip_stack_len, + "Cannot pop clips that were pushed before the DisplayListBuilder save."); + } assert!(self.clip_stack.len() > 0); } @@ -1114,25 +1175,6 @@ impl DisplayListBuilder { self.push_item(item, info); } - // Don't use this function. It will go away. - // - // We're using this method as a hack in Gecko to retain parts sub-parts of display - // lists so that we can regenerate them without building Gecko display items. WebRender - // will replace references to the root scroll frame id with the current scroll frame - // id. - pub fn push_nested_display_list(&mut self, built_display_list: &BuiltDisplayList) { - self.push_new_empty_item(SpecificDisplayItem::PushNestedDisplayList); - - // Need to read out all the glyph data to update the cache - for (font_key, color, glyphs) in built_display_list.glyphs() { - self.cache_glyphs(font_key, color, built_display_list.get(glyphs)); - } - - // Only append the actual items, not any caches - self.data.extend_from_slice(built_display_list.item_slice()); - self.push_new_empty_item(SpecificDisplayItem::PopNestedDisplayList); - } - pub fn push_shadow(&mut self, info: &LayoutPrimitiveInfo, shadow: Shadow) { self.push_item(SpecificDisplayItem::PushShadow(shadow), info); } @@ -1141,18 +1183,8 @@ impl DisplayListBuilder { self.push_new_empty_item(SpecificDisplayItem::PopShadow); } - pub fn finalize(mut self) -> (PipelineId, LayoutSize, BuiltDisplayList) { - let glyph_offset = self.data.len(); - - // Want to use self.push_iter, so can't borrow self - let glyphs = ::std::mem::replace(&mut self.glyphs, FastHashMap::default()); - - // Append glyph data to the end - for ((font_key, color), sub_glyphs) in glyphs { - bincode::serialize_into(&mut self.data, &font_key, bincode::Infinite).unwrap(); - bincode::serialize_into(&mut self.data, &color, bincode::Infinite).unwrap(); - self.push_iter(sub_glyphs); - } + pub fn finalize(self) -> (PipelineId, LayoutSize, BuiltDisplayList) { + assert!(self.save_state.is_none(), "Finalized DisplayListBuilder with a pending save"); let end_time = precise_time_ns(); @@ -1165,7 +1197,6 @@ impl DisplayListBuilder { builder_start_time: self.builder_start_time, builder_finish_time: end_time, send_start_time: 0, - glyph_offset, }, data: self.data, }, diff --git a/gfx/webrender_api/src/font.rs b/gfx/webrender_api/src/font.rs index 224a17a318d3..dbb525f36c28 100644 --- a/gfx/webrender_api/src/font.rs +++ b/gfx/webrender_api/src/font.rs @@ -137,6 +137,16 @@ impl FontRenderMode { } } +impl SubpixelDirection { + // Limit the subpixel direction to what is supported by the render mode. + pub fn limit_by(self, render_mode: FontRenderMode) -> SubpixelDirection { + match render_mode { + FontRenderMode::Mono | FontRenderMode::Bitmap => SubpixelDirection::None, + FontRenderMode::Alpha | FontRenderMode::Subpixel => self, + } + } +} + #[repr(u8)] #[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum SubpixelOffset { @@ -196,18 +206,103 @@ pub struct GlyphOptions { #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)] pub struct FontInstanceOptions { - pub render_mode: Option, + pub render_mode: FontRenderMode, + pub subpx_dir: SubpixelDirection, pub synthetic_italics: bool, } +impl Default for FontInstanceOptions { + fn default() -> FontInstanceOptions { + FontInstanceOptions { + render_mode: FontRenderMode::Subpixel, + subpx_dir: SubpixelDirection::Horizontal, + synthetic_italics: false, + } + } +} + +#[cfg(target_os = "windows")] #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)] pub struct FontInstancePlatformOptions { - // These are currently only used on windows for dwrite fonts. pub use_embedded_bitmap: bool, pub force_gdi_rendering: bool, } +#[cfg(target_os = "windows")] +impl Default for FontInstancePlatformOptions { + fn default() -> FontInstancePlatformOptions { + FontInstancePlatformOptions { + use_embedded_bitmap: false, + force_gdi_rendering: false, + } + } +} + +#[cfg(target_os = "macos")] +#[repr(C)] +#[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)] +pub struct FontInstancePlatformOptions { + pub unused: u32, +} + +#[cfg(target_os = "macos")] +impl Default for FontInstancePlatformOptions { + fn default() -> FontInstancePlatformOptions { + FontInstancePlatformOptions { + unused: 0, + } + } +} + +pub const FONT_FORCE_AUTOHINT: u16 = 0b1; +pub const FONT_NO_AUTOHINT: u16 = 0b10; +pub const FONT_EMBEDDED_BITMAP: u16 = 0b100; +pub const FONT_EMBOLDEN: u16 = 0b1000; +pub const FONT_VERTICAL_LAYOUT: u16 = 0b10000; +pub const FONT_SUBPIXEL_BGR: u16 = 0b100000; + +#[cfg(not(any(target_os = "macos", target_os = "windows")))] +#[repr(u8)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize)] +pub enum FontLCDFilter { + None, + Default, + Light, + Legacy, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows")))] +#[repr(u8)] +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize)] +pub enum FontHinting { + None, + Mono, + Light, + Normal, + LCD, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows")))] +#[repr(C)] +#[derive(Clone, Copy, Debug, Deserialize, Hash, Eq, PartialEq, PartialOrd, Ord, Serialize)] +pub struct FontInstancePlatformOptions { + pub flags: u16, + pub lcd_filter: FontLCDFilter, + pub hinting: FontHinting, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows")))] +impl Default for FontInstancePlatformOptions { + fn default() -> FontInstancePlatformOptions { + FontInstancePlatformOptions { + flags: 0, + lcd_filter: FontLCDFilter::Default, + hinting: FontHinting::LCD, + } + } +} + #[derive(Clone, Hash, PartialEq, Eq, Debug, Deserialize, Serialize, Ord, PartialOrd)] pub struct FontInstance { pub font_key: FontKey, @@ -229,26 +324,13 @@ impl FontInstance { pub fn new( font_key: FontKey, size: Au, - mut color: ColorF, + color: ColorF, render_mode: FontRenderMode, subpx_dir: SubpixelDirection, platform_options: Option, variations: Vec, synthetic_italics: bool, ) -> FontInstance { - // In alpha/mono mode, the color of the font is irrelevant. - // Forcing it to black in those cases saves rasterizing glyphs - // of different colors when not needed. - match render_mode { - FontRenderMode::Alpha | FontRenderMode::Mono => { - color = ColorF::new(0.0, 0.0, 0.0, 1.0); - } - FontRenderMode::Bitmap => { - color = ColorF::new(1.0, 1.0, 1.0, 1.0); - } - FontRenderMode::Subpixel => {} - } - FontInstance { font_key, size, diff --git a/gfx/webrender_api/src/lib.rs b/gfx/webrender_api/src/lib.rs index 3e7831e8068a..c9d3d11d937a 100644 --- a/gfx/webrender_api/src/lib.rs +++ b/gfx/webrender_api/src/lib.rs @@ -13,7 +13,6 @@ extern crate byteorder; #[cfg(feature = "nightly")] extern crate core; extern crate euclid; -extern crate fxhash; #[macro_use] extern crate heapsize; #[cfg(feature = "ipc")] @@ -46,8 +45,4 @@ pub use display_item::*; pub use display_list::*; pub use font::*; pub use image::*; -use std::collections::{HashMap, HashSet}; -use std::hash::BuildHasherDefault; pub use units::*; -type FastHashMap = HashMap>; -type FastHashSet = HashSet>; diff --git a/gfx/webrender_bindings/Cargo.toml b/gfx/webrender_bindings/Cargo.toml index 700332c6568d..2617609fafad 100644 --- a/gfx/webrender_bindings/Cargo.toml +++ b/gfx/webrender_bindings/Cargo.toml @@ -5,7 +5,7 @@ authors = ["The Mozilla Project Developers"] license = "MPL-2.0" [dependencies] -webrender_api = {path = "../webrender_api", version = "0.52.0"} +webrender_api = {path = "../webrender_api", version = "0.52.1"} bincode = "0.8" rayon = "0.8" thread_profiler = "0.1.1" @@ -15,5 +15,5 @@ gleam = "0.4" [dependencies.webrender] path = "../webrender" -version = "0.52.0" +version = "0.52.1" default-features = false diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index 2ce997c9b8f4..b804df5fde6a 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -59,6 +59,25 @@ enum class ExternalImageType : uint32_t { Sentinel /* this must be last for serialization purposes. */ }; +enum class FontHinting : uint8_t { + None = 0, + Mono = 1, + Light = 2, + Normal = 3, + LCD = 4, + + Sentinel /* this must be last for serialization purposes. */ +}; + +enum class FontLCDFilter : uint8_t { + None = 0, + Default = 1, + Light = 2, + Legacy = 3, + + Sentinel /* this must be last for serialization purposes. */ +}; + enum class FontRenderMode : uint32_t { Mono = 0, Alpha = 1, @@ -252,14 +271,11 @@ struct BuiltDisplayListDescriptor { uint64_t builder_finish_time; // The third IPC time stamp: just before sending uint64_t send_start_time; - // The offset where DisplayItems stop and the Glyph list starts - size_t glyph_offset; bool operator==(const BuiltDisplayListDescriptor& aOther) const { return builder_start_time == aOther.builder_start_time && builder_finish_time == aOther.builder_finish_time && - send_start_time == aOther.send_start_time && - glyph_offset == aOther.glyph_offset; + send_start_time == aOther.send_start_time; } }; @@ -752,6 +768,26 @@ struct FontInstancePlatformOptions { } }; +struct FontInstancePlatformOptions { + uint32_t unused; + + bool operator==(const FontInstancePlatformOptions& aOther) const { + return unused == aOther.unused; + } +}; + +struct FontInstancePlatformOptions { + uint16_t flags; + FontLCDFilter lcd_filter; + FontHinting hinting; + + bool operator==(const FontInstancePlatformOptions& aOther) const { + return flags == aOther.flags && + lcd_filter == aOther.lcd_filter && + hinting == aOther.hinting; + } +}; + /* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. * To generate this file: * 1. Get the latest cbindgen using `cargo install --force cbindgen` diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index 6e67dafb6067..0733ca3a474e 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -1584,7 +1584,7 @@ dependencies = [ [[package]] name = "webrender" -version = "0.52.0" +version = "0.52.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1606,12 +1606,12 @@ dependencies = [ "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_api 0.52.0", + "webrender_api 0.52.1", ] [[package]] name = "webrender_api" -version = "0.52.0" +version = "0.52.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1621,7 +1621,6 @@ dependencies = [ "core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1637,8 +1636,8 @@ dependencies = [ "gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.52.0", - "webrender_api 0.52.0", + "webrender 0.52.1", + "webrender_api 0.52.1", ] [[package]] diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index cfc9af0619bd..ae1eecf99103 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -1596,7 +1596,7 @@ dependencies = [ [[package]] name = "webrender" -version = "0.52.0" +version = "0.52.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1618,12 +1618,12 @@ dependencies = [ "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_api 0.52.0", + "webrender_api 0.52.1", ] [[package]] name = "webrender_api" -version = "0.52.0" +version = "0.52.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1633,7 +1633,6 @@ dependencies = [ "core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1649,8 +1648,8 @@ dependencies = [ "gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.52.0", - "webrender_api 0.52.0", + "webrender 0.52.1", + "webrender_api 0.52.1", ] [[package]] From 147f3c1673b031d9d8c26b0add37e64965ee9522 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 10 Oct 2017 08:06:51 -0400 Subject: [PATCH 40/68] Bug 1405790 - Fix for ClipId change in WR cset b4fbc86. r=Gankro MozReview-Commit-ID: 1MOrMCx8eVF --HG-- extra : rebase_source : f33cfc104b995a1b40d06dec5028f1ed07669501 --- gfx/webrender_bindings/src/bindings.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 0d58db16422c..2fef86c61f51 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -1206,9 +1206,8 @@ pub extern "C" fn wr_dp_define_clip(state: &mut WrState, let clip_id = state.frame_builder.dl_builder.define_clip(None, clip_rect, complex_iter, mask); // return the u64 id value from inside the ClipId::Clip(..) match clip_id { - ClipId::Clip(id, nesting_index, pipeline_id) => { + ClipId::Clip(id, pipeline_id) => { assert!(pipeline_id == state.pipeline_id); - assert!(nesting_index == 0); id }, _ => panic!("Got unexpected clip id type"), @@ -1219,7 +1218,7 @@ pub extern "C" fn wr_dp_define_clip(state: &mut WrState, pub extern "C" fn wr_dp_push_clip(state: &mut WrState, clip_id: u64) { debug_assert!(unsafe { is_in_main_thread() }); - state.frame_builder.dl_builder.push_clip_id(ClipId::Clip(clip_id, 0, state.pipeline_id)); + state.frame_builder.dl_builder.push_clip_id(ClipId::Clip(clip_id, state.pipeline_id)); } #[no_mangle] @@ -1244,9 +1243,8 @@ pub extern "C" fn wr_dp_define_sticky_frame(state: &mut WrState, unsafe { bottom_range.as_ref() }.cloned(), unsafe { left_range.as_ref() }.cloned())); match clip_id { - ClipId::Clip(id, nesting_index, pipeline_id) => { + ClipId::Clip(id, pipeline_id) => { assert!(pipeline_id == state.pipeline_id); - assert!(nesting_index == 0); id }, _ => panic!("Got unexpected clip id type"), @@ -1298,7 +1296,7 @@ pub extern "C" fn wr_dp_push_clip_and_scroll_info(state: &mut WrState, let info = if let Some(&id) = unsafe { clip_id.as_ref() } { ClipAndScrollInfo::new( scroll_id, - ClipId::Clip(id, 0, state.pipeline_id)) + ClipId::Clip(id, state.pipeline_id)) } else { ClipAndScrollInfo::simple(scroll_id) }; From c25073bde9a377c11f4cb91368eb458f62a915a2 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 10 Oct 2017 08:07:04 -0400 Subject: [PATCH 41/68] Bug 1405790 - Mark some tests as passing from WR cset 90aa4c28. r=Gankro MozReview-Commit-ID: FMcBLsne2mk --HG-- extra : rebase_source : 9b13420056902de15acd6de914e6dfa150292f13 --- layout/reftests/transform-3d/reftest.list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/reftests/transform-3d/reftest.list b/layout/reftests/transform-3d/reftest.list index 604eb70d1585..0682efea73d6 100644 --- a/layout/reftests/transform-3d/reftest.list +++ b/layout/reftests/transform-3d/reftest.list @@ -38,7 +38,7 @@ fuzzy-if(webrender,0-1,0-6) == rotate3d-2a.html rotatey-1-ref.html == backface-visibility-1c.html about:blank fuzzy-if(winWidget&&!layersGPUAccelerated,1,251) == backface-visibility-2.html backface-visibility-2-ref.html == backface-visibility-3.html backface-visibility-3-ref.html -fails-if(webrender) == perspective-clipping-1.html perspective-clipping-1-ref.html +== perspective-clipping-1.html perspective-clipping-1-ref.html == perspective-clipping-2.html perspective-clipping-2-ref.html != perspective-origin-1a.html rotatex-perspective-1a.html fuzzy-if(webrender,0-1,0-3) == perspective-origin-1b.html perspective-origin-1a.html @@ -81,7 +81,7 @@ fuzzy(1,10000) == opacity-preserve3d-4.html opacity-preserve3d-4-ref.html == opacity-preserve3d-5.html opacity-preserve3d-5-ref.html fails-if(webrender) == snap-perspective-1.html snap-perspective-1-ref.html == mask-layer-1.html mask-layer-ref.html -fails-if(webrender) == mask-layer-2.html mask-layer-ref.html +== mask-layer-2.html mask-layer-ref.html fails-if(webrender) == mask-layer-3.html mask-layer-ref.html fails-if(webrender) == split-intersect1.html split-intersect1-ref.html fuzzy(255,150) fails-if(webrender) == split-intersect2.html split-intersect2-ref.html From 892650be6cba709b7410177bf1ced15d98255131 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 5 Oct 2017 15:26:01 -0400 Subject: [PATCH 42/68] Bug 1405790 - supply FontInstancePlatformOptions to WebRender. r=jrmuizel Patch originally developed in bug 1406138, but landed in bug 1405790 since it needs to land together with the upstream WR changes in PR 1816. MozReview-Commit-ID: IHVoKhVncd5 --HG-- extra : rebase_source : 912e3d903d71c1b664817457e67aa6d81be3f4dd --- gfx/2d/2D.h | 4 +- gfx/2d/ScaledFontDWrite.cpp | 23 ++++ gfx/2d/ScaledFontDWrite.h | 4 + gfx/2d/ScaledFontFontconfig.cpp | 130 ++++++++++++++++++ gfx/2d/ScaledFontFontconfig.h | 4 + gfx/2d/ScaledFontMac.cpp | 2 +- gfx/2d/ScaledFontMac.h | 2 +- gfx/webrender_bindings/WebRenderTypes.h | 1 - gfx/webrender_bindings/cbindgen.toml | 5 + gfx/webrender_bindings/src/bindings.rs | 23 +--- .../webrender_ffi_generated.h | 26 +++- 11 files changed, 195 insertions(+), 29 deletions(-) diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index 812b7b511f4c..f12b228c9b95 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -73,7 +73,7 @@ namespace mozilla { class Mutex; namespace wr { -struct WrFontInstanceOptions; +struct FontInstanceOptions; struct FontInstancePlatformOptions; } @@ -836,7 +836,7 @@ public: virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; } - virtual bool GetWRFontInstanceOptions(Maybe* aOutOptions, + virtual bool GetWRFontInstanceOptions(Maybe* aOutOptions, Maybe* aOutPlatformOptions, std::vector* aOutVariations) { diff --git a/gfx/2d/ScaledFontDWrite.cpp b/gfx/2d/ScaledFontDWrite.cpp index 1b211331bce4..02699023d496 100644 --- a/gfx/2d/ScaledFontDWrite.cpp +++ b/gfx/2d/ScaledFontDWrite.cpp @@ -8,6 +8,7 @@ #include "PathD2D.h" #include "gfxFont.h" #include "Logging.h" +#include "mozilla/webrender/WebRenderTypes.h" using namespace std; @@ -300,6 +301,28 @@ ScaledFontDWrite::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) return true; } +bool +ScaledFontDWrite::GetWRFontInstanceOptions(Maybe* aOutOptions, + Maybe* aOutPlatformOptions, + std::vector* aOutVariations) +{ + AntialiasMode aaMode = GetDefaultAAMode(); + if (aaMode != AntialiasMode::SUBPIXEL) { + wr::FontInstanceOptions options; + options.render_mode = + aaMode == AntialiasMode::NONE ? wr::FontRenderMode::Mono : wr::FontRenderMode::Alpha; + options.subpx_dir = wr::SubpixelDirection::Horizontal; + options.synthetic_italics = false; + *aOutOptions = Some(options); + } + + wr::FontInstancePlatformOptions platformOptions; + platformOptions.use_embedded_bitmap = UseEmbeddedBitmaps(); + platformOptions.force_gdi_rendering = ForceGDIMode(); + *aOutPlatformOptions = Some(platformOptions); + return true; +} + already_AddRefed UnscaledFontDWrite::CreateScaledFont(Float aGlyphSize, const uint8_t* aInstanceData, diff --git a/gfx/2d/ScaledFontDWrite.h b/gfx/2d/ScaledFontDWrite.h index b0b924da7cd2..5be2ca1add4c 100644 --- a/gfx/2d/ScaledFontDWrite.h +++ b/gfx/2d/ScaledFontDWrite.h @@ -56,6 +56,10 @@ public: bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override; + bool GetWRFontInstanceOptions(Maybe* aOutOptions, + Maybe* aOutPlatformOptions, + std::vector* aOutVariations) override; + AntialiasMode GetDefaultAAMode() override; bool UseEmbeddedBitmaps() { return mUseEmbeddedBitmap; } diff --git a/gfx/2d/ScaledFontFontconfig.cpp b/gfx/2d/ScaledFontFontconfig.cpp index decf9b0ceb57..54ad16beca72 100644 --- a/gfx/2d/ScaledFontFontconfig.cpp +++ b/gfx/2d/ScaledFontFontconfig.cpp @@ -6,6 +6,7 @@ #include "ScaledFontFontconfig.h" #include "UnscaledFontFreeType.h" #include "Logging.h" +#include "mozilla/webrender/WebRenderTypes.h" #ifdef USE_SKIA #include "skia/include/ports/SkTypeface_cairo.h" @@ -14,6 +15,17 @@ #include namespace mozilla { +namespace wr { + enum { + FONT_FORCE_AUTOHINT = 1 << 0, + FONT_NO_AUTOHINT = 1 << 1, + FONT_EMBEDDED_BITMAP = 1 << 2, + FONT_EMBOLDEN = 1 << 3, + FONT_VERTICAL_LAYOUT = 1 << 4, + FONT_SUBPIXEL_BGR = 1 << 5 + }; +} + namespace gfx { // On Linux and Android our "platform" font is a cairo_scaled_font_t and we use @@ -231,6 +243,124 @@ ScaledFontFontconfig::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBat return true; } +bool +ScaledFontFontconfig::GetWRFontInstanceOptions(Maybe* aOutOptions, + Maybe* aOutPlatformOptions, + std::vector* aOutVariations) +{ + wr::FontInstanceOptions options; + options.render_mode = wr::FontRenderMode::Alpha; + options.subpx_dir = wr::SubpixelDirection::Horizontal; + options.synthetic_italics = false; + + wr::FontInstancePlatformOptions platformOptions; + platformOptions.flags = 0; + platformOptions.lcd_filter = wr::FontLCDFilter::Legacy; + platformOptions.hinting = wr::FontHinting::Normal; + + FcBool autohint; + if (FcPatternGetBool(mPattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch && autohint) { + platformOptions.flags |= wr::FONT_FORCE_AUTOHINT; + } + FcBool embolden; + if (FcPatternGetBool(mPattern, FC_EMBOLDEN, 0, &embolden) == FcResultMatch && embolden) { + platformOptions.flags |= wr::FONT_EMBOLDEN; + } + FcBool vertical; + if (FcPatternGetBool(mPattern, FC_VERTICAL_LAYOUT, 0, &vertical) == FcResultMatch && vertical) { + platformOptions.flags |= wr::FONT_VERTICAL_LAYOUT; + } + + FcBool antialias; + if (FcPatternGetBool(mPattern, FC_ANTIALIAS, 0, &antialias) != FcResultMatch || antialias) { + int rgba; + if (FcPatternGetInteger(mPattern, FC_RGBA, 0, &rgba) == FcResultMatch) { + switch (rgba) { + case FC_RGBA_RGB: + case FC_RGBA_BGR: + case FC_RGBA_VRGB: + case FC_RGBA_VBGR: + options.render_mode = wr::FontRenderMode::Subpixel; + if (rgba == FC_RGBA_VRGB || rgba == FC_RGBA_VBGR) { + options.subpx_dir = wr::SubpixelDirection::Vertical; + } + platformOptions.hinting = wr::FontHinting::LCD; + if (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR) { + platformOptions.flags |= wr::FONT_SUBPIXEL_BGR; + } + break; + case FC_RGBA_NONE: + case FC_RGBA_UNKNOWN: + default: + break; + } + } + + if (options.render_mode == wr::FontRenderMode::Subpixel) { + int filter; + if (FcPatternGetInteger(mPattern, FC_LCD_FILTER, 0, &filter) == FcResultMatch) { + switch (filter) { + case FC_LCD_NONE: + platformOptions.lcd_filter = wr::FontLCDFilter::None; + break; + case FC_LCD_DEFAULT: + platformOptions.lcd_filter = wr::FontLCDFilter::Default; + break; + case FC_LCD_LIGHT: + platformOptions.lcd_filter = wr::FontLCDFilter::Light; + break; + case FC_LCD_LEGACY: + default: + break; + } + } + } + + // Match cairo-ft's handling of embeddedbitmap: + // If AA is explicitly disabled, leave bitmaps enabled. + // Otherwise, disable embedded bitmaps unless explicitly enabled. + FcBool bitmap; + if (FcPatternGetBool(mPattern, FC_EMBEDDED_BITMAP, 0, &bitmap) == FcResultMatch && bitmap) { + platformOptions.flags |= wr::FONT_EMBEDDED_BITMAP; + } + } else { + options.render_mode = wr::FontRenderMode::Mono; + options.subpx_dir = wr::SubpixelDirection::None; + platformOptions.hinting = wr::FontHinting::Mono; + platformOptions.flags |= wr::FONT_EMBEDDED_BITMAP; + } + + FcBool hinting; + int hintstyle; + if (FcPatternGetBool(mPattern, FC_HINTING, 0, &hinting) != FcResultMatch || hinting) { + if (FcPatternGetInteger(mPattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) { + hintstyle = FC_HINT_FULL; + } + } else { + hintstyle = FC_HINT_NONE; + } + + if (hintstyle == FC_HINT_NONE) { + platformOptions.hinting = wr::FontHinting::None; + } else if (options.render_mode != wr::FontRenderMode::Mono) { + switch (hintstyle) { + case FC_HINT_SLIGHT: + platformOptions.hinting = wr::FontHinting::Light; + break; + case FC_HINT_MEDIUM: + platformOptions.hinting = wr::FontHinting::Normal; + break; + case FC_HINT_FULL: + default: + break; + } + } + + *aOutOptions = Some(options); + *aOutPlatformOptions = Some(platformOptions); + return true; +} + already_AddRefed UnscaledFontFontconfig::CreateScaledFont(Float aGlyphSize, const uint8_t* aInstanceData, diff --git a/gfx/2d/ScaledFontFontconfig.h b/gfx/2d/ScaledFontFontconfig.h index e50aee126cae..18d5ce73cde8 100644 --- a/gfx/2d/ScaledFontFontconfig.h +++ b/gfx/2d/ScaledFontFontconfig.h @@ -34,6 +34,10 @@ public: bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override; + bool GetWRFontInstanceOptions(Maybe* aOutOptions, + Maybe* aOutPlatformOptions, + std::vector* aOutVariations) override; + private: friend class NativeFontResourceFontconfig; friend class UnscaledFontFontconfig; diff --git a/gfx/2d/ScaledFontMac.cpp b/gfx/2d/ScaledFontMac.cpp index 9191521c4f1c..18ce3a441907 100644 --- a/gfx/2d/ScaledFontMac.cpp +++ b/gfx/2d/ScaledFontMac.cpp @@ -359,7 +359,7 @@ ScaledFontMac::GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) } bool -ScaledFontMac::GetWRFontInstanceOptions(Maybe* aOutOptions, +ScaledFontMac::GetWRFontInstanceOptions(Maybe* aOutOptions, Maybe* aOutPlatformOptions, std::vector* aOutVariations) { diff --git a/gfx/2d/ScaledFontMac.h b/gfx/2d/ScaledFontMac.h index a484329ac595..99df8866b841 100644 --- a/gfx/2d/ScaledFontMac.h +++ b/gfx/2d/ScaledFontMac.h @@ -52,7 +52,7 @@ public: bool GetFontInstanceData(FontInstanceDataOutput aCb, void* aBaton) override; - bool GetWRFontInstanceOptions(Maybe* aOutOptions, + bool GetWRFontInstanceOptions(Maybe* aOutOptions, Maybe* aOutPlatformOptions, std::vector* aOutVariations) override; diff --git a/gfx/webrender_bindings/WebRenderTypes.h b/gfx/webrender_bindings/WebRenderTypes.h index c5672f3103c4..213144101f1e 100644 --- a/gfx/webrender_bindings/WebRenderTypes.h +++ b/gfx/webrender_bindings/WebRenderTypes.h @@ -28,7 +28,6 @@ typedef wr::WrPipelineId PipelineId; typedef wr::WrImageKey ImageKey; typedef wr::WrFontKey FontKey; typedef wr::WrFontInstanceKey FontInstanceKey; -typedef wr::WrFontInstanceOptions FontInstanceOptions; typedef wr::WrEpoch Epoch; typedef wr::WrExternalImageId ExternalImageId; typedef wr::WrDebugFlags DebugFlags; diff --git a/gfx/webrender_bindings/cbindgen.toml b/gfx/webrender_bindings/cbindgen.toml index 408c634aca4d..39fb31336392 100644 --- a/gfx/webrender_bindings/cbindgen.toml +++ b/gfx/webrender_bindings/cbindgen.toml @@ -31,3 +31,8 @@ generic_template_specialization = false [enum] add_sentinel = true + +[defines] +"target_os = windows" = "XP_WIN" +"target_os = macos" = "XP_MACOSX" + diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 2fef86c61f51..5a273fea6bb5 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -174,22 +174,6 @@ impl MutByteSlice { } } -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct WrFontInstanceOptions { - pub render_mode: FontRenderMode, - pub synthetic_italics: bool, -} - -impl Into for WrFontInstanceOptions { - fn into(self) -> FontInstanceOptions { - FontInstanceOptions { - render_mode: Some(self.render_mode), - synthetic_italics: self.synthetic_italics, - } - } -} - #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct WrImageMask { @@ -985,18 +969,15 @@ pub extern "C" fn wr_resource_updates_add_font_instance( key: WrFontInstanceKey, font_key: WrFontKey, glyph_size: f32, - options: *const WrFontInstanceOptions, + options: *const FontInstanceOptions, platform_options: *const FontInstancePlatformOptions, variations: &mut WrVecU8, ) { - let instance_options: Option = unsafe { - options.as_ref().map(|opts|{ (*opts).into() }) - }; resources.add_font_instance( key, font_key, Au::from_f32_px(glyph_size), - instance_options, + unsafe { options.as_ref().cloned() }, unsafe { platform_options.as_ref().cloned() }, variations.convert_into_vec::(), ); diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index b804df5fde6a..5b2e0b903945 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -59,6 +59,7 @@ enum class ExternalImageType : uint32_t { Sentinel /* this must be last for serialization purposes. */ }; +#if !(defined(XP_MACOSX) || defined(XP_WIN)) enum class FontHinting : uint8_t { None = 0, Mono = 1, @@ -68,7 +69,9 @@ enum class FontHinting : uint8_t { Sentinel /* this must be last for serialization purposes. */ }; +#endif +#if !(defined(XP_MACOSX) || defined(XP_WIN)) enum class FontLCDFilter : uint8_t { None = 0, Default = 1, @@ -77,6 +80,7 @@ enum class FontLCDFilter : uint8_t { Sentinel /* this must be last for serialization purposes. */ }; +#endif enum class FontRenderMode : uint32_t { Mono = 0, @@ -152,6 +156,14 @@ enum class RepeatMode : uint32_t { Sentinel /* this must be last for serialization purposes. */ }; +enum class SubpixelDirection : uint32_t { + None = 0, + Horizontal = 1, + Vertical = 2, + + Sentinel /* this must be last for serialization purposes. */ +}; + enum class TransformStyle : uint32_t { Flat = 0, Preserve3D = 1, @@ -748,16 +760,19 @@ struct FontKey { typedef FontKey WrFontKey; -struct WrFontInstanceOptions { +struct FontInstanceOptions { FontRenderMode render_mode; + SubpixelDirection subpx_dir; bool synthetic_italics; - bool operator==(const WrFontInstanceOptions& aOther) const { + bool operator==(const FontInstanceOptions& aOther) const { return render_mode == aOther.render_mode && + subpx_dir == aOther.subpx_dir && synthetic_italics == aOther.synthetic_italics; } }; +#if defined(XP_WIN) struct FontInstancePlatformOptions { bool use_embedded_bitmap; bool force_gdi_rendering; @@ -767,7 +782,9 @@ struct FontInstancePlatformOptions { force_gdi_rendering == aOther.force_gdi_rendering; } }; +#endif +#if defined(XP_MACOSX) struct FontInstancePlatformOptions { uint32_t unused; @@ -775,7 +792,9 @@ struct FontInstancePlatformOptions { return unused == aOther.unused; } }; +#endif +#if !(defined(XP_MACOSX) || defined(XP_WIN)) struct FontInstancePlatformOptions { uint16_t flags; FontLCDFilter lcd_filter; @@ -787,6 +806,7 @@ struct FontInstancePlatformOptions { hinting == aOther.hinting; } }; +#endif /* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. * To generate this file: @@ -1248,7 +1268,7 @@ void wr_resource_updates_add_font_instance(ResourceUpdates *aResources, WrFontInstanceKey aKey, WrFontKey aFontKey, float aGlyphSize, - const WrFontInstanceOptions *aOptions, + const FontInstanceOptions *aOptions, const FontInstancePlatformOptions *aPlatformOptions, WrVecU8 *aVariations) WR_FUNC; From f38b88316e29beebd943c1aae25c236f384eba54 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 10 Oct 2017 08:07:28 -0400 Subject: [PATCH 43/68] Bug 1405790 - Update some reftest annotations for changes in WR PR 1791. r=Gankro,jrmuizel MozReview-Commit-ID: FGY3B9DxyNA --HG-- extra : rebase_source : 056e04dad89857d11fdb6088d83d200487634bf0 --- layout/reftests/border-radius/reftest.list | 10 +++++----- layout/reftests/box-shadow/reftest.list | 2 +- layout/reftests/bugs/reftest.list | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/layout/reftests/border-radius/reftest.list b/layout/reftests/border-radius/reftest.list index c33a2d8b75a2..d37d12f5e764 100644 --- a/layout/reftests/border-radius/reftest.list +++ b/layout/reftests/border-radius/reftest.list @@ -23,14 +23,14 @@ fuzzy-if(skiaContent,1,342) == percent-2.html percent-2-ref.html fuzzy-if(skiaContent,1,343) == percent-3.html percent-3-ref.html # more serious tests, using SVG reference -fuzzy-if(skiaContent,17,58) fuzzy-if(webrender,168-168,74-74) == border-circle-2.html border-circle-2-ref.xhtml +fuzzy-if(skiaContent,17,58) fuzzy-if(webrender,41-41,66-66) == border-circle-2.html border-circle-2-ref.xhtml fuzzy-if(gtkWidget,14,280) fuzzy-if(cocoaWidget,4,582) fuzzy-if(Android,36,264) fuzzy-if(d2d,51,323) fuzzy-if(winWidget&&!d2d,16,377) fuzzy-if(skiaContent,63,398) == curved-stripe-border.html curved-stripe-border-ref.svg # bug 459945 # Corners -fuzzy-if(skiaContent,17,47) fuzzy-if(webrender,166-166,58-58) == corner-1.html corner-1-ref.svg # bottom corners different radius than top corners -fuzzy-if(gtkWidget,23,5) fuzzy-if(winWidget&&!d2d,23,5) fuzzy-if(d2d,32,8) fuzzy-if(Android,10,8) fuzzy-if(skiaContent,18,49) fuzzy-if(webrender,164-164,57-57) == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804 +fuzzy-if(skiaContent,17,47) fuzzy-if(webrender,41-41,52-52) == corner-1.html corner-1-ref.svg # bottom corners different radius than top corners +fuzzy-if(gtkWidget,23,5) fuzzy-if(winWidget&&!d2d,23,5) fuzzy-if(d2d,32,8) fuzzy-if(Android,10,8) fuzzy-if(skiaContent,18,49) fuzzy-if(webrender,41-41,51-51) == corner-2.html corner-2-ref.svg # right corners different radius than left corners; see bug 500804 fuzzy-if(gtkWidget,3,10) fuzzy-if(winWidget&&!d2d,3,10) fuzzy-if(d2d,15,32) fuzzy-if(Android,3,15) fuzzy-if(skiaContent,18,90) fails-if(webrender) == corner-3.html corner-3-ref.svg -fuzzy-if(skiaContent,12,83) fuzzy-if(webrender,79-79,110-110) == corner-4.html corner-4-ref.svg +fuzzy-if(skiaContent,12,83) fuzzy-if(webrender,19-19,96-96) == corner-4.html corner-4-ref.svg # Test that radii too long are reduced == border-reduce-height.html border-reduce-height-ref.html @@ -39,7 +39,7 @@ fuzzy-if(skiaContent,12,83) fuzzy-if(webrender,79-79,110-110) == corner-4.html c fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572 != clipping-2.html about:blank # background color clipped to inner/outer border, can't get # great tests for this due to antialiasing problems described in bug 466572 -fuzzy-if(skiaContent,17,62) fuzzy-if(webrender,168-168,74-74) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background +fuzzy-if(skiaContent,17,62) fuzzy-if(webrender,41-41,66-66) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background # Tests for clipping the contents of replaced elements and overflow!=visible != clipping-4-ref.html clipping-4-notref.html diff --git a/layout/reftests/box-shadow/reftest.list b/layout/reftests/box-shadow/reftest.list index 2d6e297fd36e..3c9265e20d7b 100644 --- a/layout/reftests/box-shadow/reftest.list +++ b/layout/reftests/box-shadow/reftest.list @@ -39,7 +39,7 @@ fuzzy(13,9445) fuzzy-if(d2d,13,10926) fuzzy-if(webrender,14,14307) == boxshadow- == overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html fuzzy-if(webrender,1,655) == 611574-1.html 611574-1-ref.html fuzzy-if(webrender,4,144) == 611574-2.html 611574-2-ref.html -fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) fuzzy-if(webrender,162-162,120-120) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows +fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) fuzzy-if(webrender,51-51,120-120) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) fails-if(webrender) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows == 1178575.html 1178575-ref.html == 1178575-2.html 1178575-2-ref.html diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 1483ee8b2c9a..1681f42ff893 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -305,7 +305,7 @@ fuzzy-if(Android,3,50) fuzzy-if(skiaContent,1,133) == 273681-1.html 273681-1-ref == 283686-2.html 283686-2-ref.html == 283686-3.html about:blank == 289384-1.xhtml 289384-ref.xhtml -random-if(d2d) fuzzy-if(Android,8,1439) skip-if(styloVsGecko) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures, bug 1354406 +random-if(d2d) fuzzy-if(Android,8,1439) skip-if(styloVsGecko) fuzzy-if(webrender,14-14,88-88) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures, bug 1354406 == 290129-1.html 290129-1-ref.html == 291078-1.html 291078-1-ref.html == 291078-2.html 291078-2-ref.html @@ -1196,10 +1196,10 @@ test-pref(dom.use_xbl_scopes_for_remote_xul,true) != 449149-1b.html about:blank == 455280-1.xhtml 455280-1-ref.xhtml == 455826-1.html 455826-1-ref.html fails-if(Android||cocoaWidget) == 456147.xul 456147-ref.html # bug 458047 -fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) fuzzy-if(webrender,53-53,732-732) == 456219-1a.html 456219-1-ref.html # bug 1128229 -fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) fuzzy-if(webrender,53-53,732-732) == 456219-1b.html 456219-1-ref.html # bug 1128229 -fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) fuzzy-if(webrender,53-53,732-732) == 456219-1c.html 456219-1-ref.html # bug 1128229 -fuzzy-if(skiaContent,1,45) fuzzy-if(webrender,43-43,8-8) == 456219-2.html 456219-2-ref.html +fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) == 456219-1a.html 456219-1-ref.html # bug 1128229 +fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) == 456219-1b.html 456219-1-ref.html # bug 1128229 +fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) == 456219-1c.html 456219-1-ref.html # bug 1128229 +fuzzy-if(skiaContent,1,45) == 456219-2.html 456219-2-ref.html == 456330-1.gif 456330-1-ref.png == 456484-1.html 456484-1-ref.html == 457398-1.html 457398-1-ref.html From 5459fdb30ee02ac03aaa5be8491a66f3609f4e8c Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Thu, 5 Oct 2017 17:07:24 +0200 Subject: [PATCH 44/68] Bug 1407077 - use photon colors for highlighted devtools toolbar icons;r=gl MozReview-Commit-ID: LCEArSoizyk --HG-- extra : rebase_source : 944a57f9aa0c3ebec7e2f7d8f9c66f9c22ce36af --- devtools/client/themes/variables.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/devtools/client/themes/variables.css b/devtools/client/themes/variables.css index 4ef5f0393be6..45f9de180dc6 100644 --- a/devtools/client/themes/variables.css +++ b/devtools/client/themes/variables.css @@ -27,7 +27,7 @@ --theme-toolbar-color: var(--grey-90); --theme-toolbar-selected-color: var(--blue-60); --theme-toolbar-checked-color: var(--blue-60); - --theme-toolbar-highlighted-color: #5FC749; + --theme-toolbar-highlighted-color: var(--green-60); --theme-toolbar-background-hover: rgba(221, 225, 228, 0.66); --theme-toolbar-background-alt: #f5f5f5; --theme-toolbar-hover: var(--grey-20); @@ -112,7 +112,7 @@ --theme-toolbar-color: var(--grey-40); --theme-toolbar-selected-color: white; --theme-toolbar-checked-color: #75BFFF; - --theme-toolbar-highlighted-color: #5FC749; + --theme-toolbar-highlighted-color: var(--green-50); --theme-toolbar-background-hover: #20232B; --theme-toolbar-background-alt: #2F343E; --theme-toolbar-hover: #252526; @@ -298,6 +298,8 @@ --red-70: #a4000f; + --green-50: #30e60b; + --green-60: #12bc00; --green-70: #058b00; --yellow-80: #715100; From 38de8f751ad1c124309b11ee64076ce7d65c6151 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 10 Oct 2017 01:05:35 +0200 Subject: [PATCH 45/68] Bug 1407077 - remove background color for highlighted devtools tabs;r=gl MozReview-Commit-ID: 7r2tCtFiTuA --HG-- extra : rebase_source : 500e836f9415ef60501e76452af531f56b532f0b --- devtools/client/themes/toolbox.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/devtools/client/themes/toolbox.css b/devtools/client/themes/toolbox.css index 1fda7b670674..8438489574dd 100644 --- a/devtools/client/themes/toolbox.css +++ b/devtools/client/themes/toolbox.css @@ -152,10 +152,6 @@ background-color: var(--theme-toolbar-hover-active); } -.devtools-tab:not(.selected).highlighted { - background-color: var(--theme-toolbar-background-alt); -} - .devtools-tab.selected { color: var(--theme-toolbar-selected-color); } From 7ec87779b1eb897587dab9f40ba421846d5cda11 Mon Sep 17 00:00:00 2001 From: Jing-wei Wu Date: Mon, 9 Oct 2017 10:36:56 +0800 Subject: [PATCH 46/68] Bug 1406338 - Part 1: Support applying specific text size while creating a favicon. r=nechen MozReview-Commit-ID: Dcx1RgcRdka --HG-- extra : rebase_source : 04971e5592d6d8aa58c9192ae501ea9eb0a5fae9 --- .../org/mozilla/gecko/icons/IconRequest.java | 12 ++++++++++ .../gecko/icons/IconRequestBuilder.java | 18 +++++++++++++++ .../gecko/icons/loader/IconGenerator.java | 23 ++++++++++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/icons/IconRequest.java b/mobile/android/base/java/org/mozilla/gecko/icons/IconRequest.java index bfe17b72ef3d..8161b9510f3f 100644 --- a/mobile/android/base/java/org/mozilla/gecko/icons/IconRequest.java +++ b/mobile/android/base/java/org/mozilla/gecko/icons/IconRequest.java @@ -31,6 +31,7 @@ public class IconRequest { /* package-private */ int targetSize; /* package-private */ int minimumSizePxAfterScaling; /* package-private */ boolean prepareOnly; + /* package-private */ float textSize; private IconCallback callback; /* package-private */ IconRequest(Context context) { @@ -45,6 +46,9 @@ public class IconRequest { this.targetSize = context.getResources().getDimensionPixelSize(R.dimen.favicon_bg); this.minimumSizePxAfterScaling = 0; this.prepareOnly = false; + + // textSize is only used in IconGenerator.java for creating a icon with specific text size. + this.textSize = 0; } /** @@ -145,6 +149,14 @@ public class IconRequest { return icons.iterator(); } + /** + * Get the required text size of the icon created by + * {@link org.mozilla.gecko.icons.loader.IconGenerator}. + */ + public float getTextSize() { + return textSize; + } + /** * Create a builder to modify this request. * diff --git a/mobile/android/base/java/org/mozilla/gecko/icons/IconRequestBuilder.java b/mobile/android/base/java/org/mozilla/gecko/icons/IconRequestBuilder.java index 8a8eb51cd320..ddae3b64bc64 100644 --- a/mobile/android/base/java/org/mozilla/gecko/icons/IconRequestBuilder.java +++ b/mobile/android/base/java/org/mozilla/gecko/icons/IconRequestBuilder.java @@ -106,6 +106,14 @@ public class IconRequestBuilder { return this; } + /** + * The icon will be scaled to the given size. + */ + public IconRequestBuilder targetSize(final int targetSize) { + internal.targetSize = targetSize; + return this; + } + /** * The icon will be used in Activity Stream: a minimum size for the icon will be set. */ @@ -136,6 +144,15 @@ public class IconRequestBuilder { return this; } + /** + * The text size will be resized to the given size, and this field is only used by + * {@link org.mozilla.gecko.icons.loader.IconGenerator} for creating a new icon. + */ + public IconRequestBuilder textSize(final float textSize) { + internal.textSize = textSize; + return this; + } + /** * Return the request built with this builder. */ @@ -156,6 +173,7 @@ public class IconRequestBuilder { request.targetSize = internal.targetSize; request.minimumSizePxAfterScaling = internal.minimumSizePxAfterScaling; request.prepareOnly = internal.prepareOnly; + request.textSize = internal.textSize; return request; } diff --git a/mobile/android/base/java/org/mozilla/gecko/icons/loader/IconGenerator.java b/mobile/android/base/java/org/mozilla/gecko/icons/loader/IconGenerator.java index d2916587207d..602c7d6497bc 100644 --- a/mobile/android/base/java/org/mozilla/gecko/icons/loader/IconGenerator.java +++ b/mobile/android/base/java/org/mozilla/gecko/icons/loader/IconGenerator.java @@ -49,15 +49,22 @@ public class IconGenerator implements IconLoader { return null; } - return generate(request.getContext(), request.getPageUrl()); + return generate(request.getContext(), request.getPageUrl(), request.getTargetSize(), request.getTextSize()); + } + + public static IconResponse generate(Context context, String pageURL) { + return generate(context, pageURL, 0, 0); } /** * Generate default favicon for the given page URL. */ - public static IconResponse generate(Context context, String pageURL) { + public static IconResponse generate(final Context context, final String pageURL, + int widthAndHeight, float textSize) { final Resources resources = context.getResources(); - final int widthAndHeight = resources.getDimensionPixelSize(R.dimen.favicon_bg); + if (widthAndHeight == 0) { + widthAndHeight = resources.getDimensionPixelSize(R.dimen.favicon_bg); + } final int roundedCorners = resources.getDimensionPixelOffset(R.dimen.favicon_corner_radius); final Bitmap favicon = Bitmap.createBitmap(widthAndHeight, widthAndHeight, Bitmap.Config.ARGB_8888); @@ -74,9 +81,13 @@ public class IconGenerator implements IconLoader { final String character = getRepresentativeCharacter(pageURL); - // The text size is calculated dynamically based on the target icon size (1/8th). For an icon - // size of 112dp we'd use a text size of 14dp (112 / 8). - final float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, widthAndHeight / 8, context.getResources().getDisplayMetrics()); + if (textSize == 0) { + // The text size is calculated dynamically based on the target icon size (1/8th). For an icon + // size of 112dp we'd use a text size of 14dp (112 / 8). + textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + widthAndHeight / 8, + resources.getDisplayMetrics()); + } paint.setTextAlign(Paint.Align.CENTER); paint.setTextSize(textSize); From 4bcdd48869a94424c547b9095879ae968d1dd2f2 Mon Sep 17 00:00:00 2001 From: Jing-wei Wu Date: Mon, 9 Oct 2017 11:02:52 +0800 Subject: [PATCH 47/68] Bug 1406338 - Part 2: Show favicons in tabs tray page. r=nechen MozReview-Commit-ID: BXOFuxwI0sl --HG-- extra : rebase_source : 24060ab31fb3df81fa341f54b0aa969b31e4564c --- .../layout-large/tabs_layout_item_view.xml | 64 +++++++++------- .../main/res/layout/tabs_layout_item_view.xml | 66 ++++++++++------- .../main/res/layout/tabs_list_item_view.xml | 73 +++++++++---------- .../app/src/photon/res/values-v17/styles.xml | 9 +++ .../app/src/photon/res/values/dimens.xml | 2 + .../app/src/photon/res/values/styles.xml | 9 +++ .../gecko/tabs/TabsLayoutItemView.java | 30 +++++++- 7 files changed, 158 insertions(+), 95 deletions(-) diff --git a/mobile/android/app/src/main/res/layout-large/tabs_layout_item_view.xml b/mobile/android/app/src/main/res/layout-large/tabs_layout_item_view.xml index 2db707d874b5..20e2d484ff0c 100644 --- a/mobile/android/app/src/main/res/layout-large/tabs_layout_item_view.xml +++ b/mobile/android/app/src/main/res/layout-large/tabs_layout_item_view.xml @@ -20,35 +20,47 @@ android:paddingRight="@dimen/tab_highlight_stroke_width" android:paddingBottom="@dimen/tab_highlight_stroke_width"> - + + + - + diff --git a/mobile/android/app/src/main/res/layout/tabs_layout_item_view.xml b/mobile/android/app/src/main/res/layout/tabs_layout_item_view.xml index 03896513471c..9c389f819036 100644 --- a/mobile/android/app/src/main/res/layout/tabs_layout_item_view.xml +++ b/mobile/android/app/src/main/res/layout/tabs_layout_item_view.xml @@ -20,35 +20,45 @@ android:paddingRight="@dimen/tab_highlight_stroke_width" android:paddingBottom="@dimen/tab_highlight_stroke_width"> - + - - + + + diff --git a/mobile/android/app/src/main/res/layout/tabs_list_item_view.xml b/mobile/android/app/src/main/res/layout/tabs_list_item_view.xml index fc2acc300440..0caf13bf0a04 100644 --- a/mobile/android/app/src/main/res/layout/tabs_list_item_view.xml +++ b/mobile/android/app/src/main/res/layout/tabs_list_item_view.xml @@ -4,6 +4,7 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> + android:id="@+id/wrapper" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="4dip" + android:background="@drawable/tab_thumbnail" + android:duplicateParentState="true" + android:clipToPadding="false"> - + - - - + + style="@style/TabsItemClose" + android:layout_width="34dip" + android:layout_height="match_parent" + android:contentDescription="@string/close_tab" + android:duplicateParentState="true" + android:scaleType="center" + android:src="@drawable/tab_item_close_button"/> \ No newline at end of file diff --git a/mobile/android/app/src/photon/res/values-v17/styles.xml b/mobile/android/app/src/photon/res/values-v17/styles.xml index 096abc6d3160..b5116cd18dfa 100644 --- a/mobile/android/app/src/photon/res/values-v17/styles.xml +++ b/mobile/android/app/src/photon/res/values-v17/styles.xml @@ -77,6 +77,15 @@ -3dp + + + + + + + + + + + + diff --git a/mobile/android/app/src/photon/res/values/colors.xml b/mobile/android/app/src/photon/res/values/colors.xml index 4c9fa2aca437..9eac814fc943 100644 --- a/mobile/android/app/src/photon/res/values/colors.xml +++ b/mobile/android/app/src/photon/res/values/colors.xml @@ -263,6 +263,8 @@ #FF919191 #737373 + #0060DF + #8000D7 #FCFCFC diff --git a/mobile/android/app/src/photon/res/values/styles.xml b/mobile/android/app/src/photon/res/values/styles.xml index 7dfc99779bf7..9474f4e0435e 100644 --- a/mobile/android/app/src/photon/res/values/styles.xml +++ b/mobile/android/app/src/photon/res/values/styles.xml @@ -961,4 +961,15 @@ 8dp + + + + diff --git a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java index fab90c827413..d2046bade747 100644 --- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java +++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripItemView.java @@ -11,7 +11,7 @@ import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.annotation.RobocopTarget; import org.mozilla.gecko.widget.themed.ThemedImageButton; -import org.mozilla.gecko.widget.themed.ThemedLinearLayout; +import org.mozilla.gecko.widget.themed.ThemedRelativeLayout; import org.mozilla.gecko.widget.themed.ThemedTextView; import android.content.Context; @@ -28,7 +28,7 @@ import android.view.View; import android.widget.Checkable; import android.widget.ImageView; -public class TabStripItemView extends ThemedLinearLayout +public class TabStripItemView extends ThemedRelativeLayout implements Checkable { private static final String LOGTAG = "GeckoTabStripItem"; @@ -42,6 +42,7 @@ public class TabStripItemView extends ThemedLinearLayout private final ImageView faviconView; private final ThemedTextView titleView; private final ThemedImageButton closeView; + private final View indicatorView; private final int faviconSize; private Bitmap lastFavicon; @@ -52,7 +53,6 @@ public class TabStripItemView extends ThemedLinearLayout public TabStripItemView(Context context, AttributeSet attrs) { super(context, attrs); - setOrientation(HORIZONTAL); final Resources res = context.getResources(); @@ -85,6 +85,8 @@ public class TabStripItemView extends ThemedLinearLayout tabs.closeTab(tabs.getTab(id), true); } }); + + indicatorView = findViewById(R.id.indicator); } @RobocopTarget @@ -153,6 +155,15 @@ public class TabStripItemView extends ThemedLinearLayout updateTitle(tab); updateFavicon(tab.getFavicon()); setPrivateMode(tab.isPrivate()); + + if (checked) { + indicatorView.setBackgroundResource(isPrivateMode() + ? R.color.tablet_tab_strip_indicator_private + : R.color.tablet_tab_strip_indicator); + indicatorView.setVisibility(VISIBLE); + } else { + indicatorView.setVisibility(GONE); + } } private void updateTitle(Tab tab) { From 799345fd87f6c3bae71696911b6309d308e5cf20 Mon Sep 17 00:00:00 2001 From: sole Date: Mon, 9 Oct 2017 16:57:06 +0100 Subject: [PATCH 50/68] Bug 1391738 - Screenshot with filename fails with unknown error in Linux. r=jwalker MozReview-Commit-ID: 7XLXyNkL4Le --HG-- extra : rebase_source : 3acb676de8ae1b5393dc66a9b8aea092efde75b6 --- devtools/shared/gcli/commands/screenshot.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/devtools/shared/gcli/commands/screenshot.js b/devtools/shared/gcli/commands/screenshot.js index 6b8900f43c05..e9d2bcd150c8 100644 --- a/devtools/shared/gcli/commands/screenshot.js +++ b/devtools/shared/gcli/commands/screenshot.js @@ -36,11 +36,7 @@ const CONTAINER_FLASHING_DURATION = 500; */ const filenameParam = { name: "filename", - type: { - name: "file", - filetype: "file", - existing: "maybe", - }, + type: "string", defaultValue: FILENAME_DEFAULT_VALUE, description: l10n.lookup("screenshotFilenameDesc"), manual: l10n.lookup("screenshotFilenameManual") From da46f0c3cf912c9a9416f96b54960e571196d5ac Mon Sep 17 00:00:00 2001 From: Miguel Useche Date: Mon, 9 Oct 2017 22:56:20 -0400 Subject: [PATCH 51/68] Bug 1402391 - CamelCase all React component files in \devtools\client\responsive.html\src\components\. r=jdescottes MozReview-Commit-ID: Am14gw4EugN --HG-- rename : devtools/client/responsive.html/components/browser.js => devtools/client/responsive.html/components/Browser.js rename : devtools/client/responsive.html/components/device-adder.js => devtools/client/responsive.html/components/DeviceAdder.js rename : devtools/client/responsive.html/components/device-modal.js => devtools/client/responsive.html/components/DeviceModal.js rename : devtools/client/responsive.html/components/device-selector.js => devtools/client/responsive.html/components/DeviceSelector.js rename : devtools/client/responsive.html/components/dpr-selector.js => devtools/client/responsive.html/components/DprSelector.js rename : devtools/client/responsive.html/components/global-toolbar.js => devtools/client/responsive.html/components/GlobalToolbar.js rename : devtools/client/responsive.html/components/network-throttling-selector.js => devtools/client/responsive.html/components/NetworkThrottlingSelector.js rename : devtools/client/responsive.html/components/resizable-viewport.js => devtools/client/responsive.html/components/ResizableViewport.js rename : devtools/client/responsive.html/components/viewport.js => devtools/client/responsive.html/components/Viewport.js rename : devtools/client/responsive.html/components/viewport-dimension.js => devtools/client/responsive.html/components/ViewportDimension.js rename : devtools/client/responsive.html/components/viewport-toolbar.js => devtools/client/responsive.html/components/ViewportToolbar.js rename : devtools/client/responsive.html/components/viewports.js => devtools/client/responsive.html/components/Viewports.js extra : rebase_source : cc84e61c907200af8e99c5b59cb6d705270305c8 extra : amend_source : 5f0bc9ca7d1abb107d451d57d0c76291340f8fc8 --- devtools/client/responsive.html/app.js | 6 ++--- .../components/{browser.js => Browser.js} | 0 .../{device-adder.js => DeviceAdder.js} | 2 +- .../{device-modal.js => DeviceModal.js} | 2 +- .../{device-selector.js => DeviceSelector.js} | 0 .../{dpr-selector.js => DprSelector.js} | 0 .../{global-toolbar.js => GlobalToolbar.js} | 4 ++-- ...lector.js => NetworkThrottlingSelector.js} | 0 ...zable-viewport.js => ResizableViewport.js} | 4 ++-- .../components/{viewport.js => Viewport.js} | 4 ++-- ...port-dimension.js => ViewportDimension.js} | 0 ...viewport-toolbar.js => ViewportToolbar.js} | 2 +- .../components/{viewports.js => Viewports.js} | 2 +- .../responsive.html/components/moz.build | 24 +++++++++---------- 14 files changed, 25 insertions(+), 25 deletions(-) rename devtools/client/responsive.html/components/{browser.js => Browser.js} (100%) rename devtools/client/responsive.html/components/{device-adder.js => DeviceAdder.js} (98%) rename devtools/client/responsive.html/components/{device-modal.js => DeviceModal.js} (99%) rename devtools/client/responsive.html/components/{device-selector.js => DeviceSelector.js} (100%) rename devtools/client/responsive.html/components/{dpr-selector.js => DprSelector.js} (100%) rename devtools/client/responsive.html/components/{global-toolbar.js => GlobalToolbar.js} (95%) rename devtools/client/responsive.html/components/{network-throttling-selector.js => NetworkThrottlingSelector.js} (100%) rename devtools/client/responsive.html/components/{resizable-viewport.js => ResizableViewport.js} (97%) rename devtools/client/responsive.html/components/{viewport.js => Viewport.js} (94%) rename devtools/client/responsive.html/components/{viewport-dimension.js => ViewportDimension.js} (100%) rename devtools/client/responsive.html/components/{viewport-toolbar.js => ViewportToolbar.js} (95%) rename devtools/client/responsive.html/components/{viewports.js => Viewports.js} (96%) diff --git a/devtools/client/responsive.html/app.js b/devtools/client/responsive.html/app.js index 5826a9559bfe..4b1152007775 100644 --- a/devtools/client/responsive.html/app.js +++ b/devtools/client/responsive.html/app.js @@ -27,9 +27,9 @@ const { resizeViewport, rotateViewport, } = require("./actions/viewports"); -const DeviceModal = createFactory(require("./components/device-modal")); -const GlobalToolbar = createFactory(require("./components/global-toolbar")); -const Viewports = createFactory(require("./components/viewports")); +const DeviceModal = createFactory(require("./components/DeviceModal")); +const GlobalToolbar = createFactory(require("./components/GlobalToolbar")); +const Viewports = createFactory(require("./components/Viewports")); const Types = require("./types"); let App = createClass({ diff --git a/devtools/client/responsive.html/components/browser.js b/devtools/client/responsive.html/components/Browser.js similarity index 100% rename from devtools/client/responsive.html/components/browser.js rename to devtools/client/responsive.html/components/Browser.js diff --git a/devtools/client/responsive.html/components/device-adder.js b/devtools/client/responsive.html/components/DeviceAdder.js similarity index 98% rename from devtools/client/responsive.html/components/device-adder.js rename to devtools/client/responsive.html/components/DeviceAdder.js index b7e2d60e793f..4f8f85f951d8 100644 --- a/devtools/client/responsive.html/components/device-adder.js +++ b/devtools/client/responsive.html/components/DeviceAdder.js @@ -11,7 +11,7 @@ const { DOM: dom, createClass, createFactory, PropTypes, addons } = const { getFormatStr, getStr } = require("../utils/l10n"); const Types = require("../types"); -const ViewportDimension = createFactory(require("./viewport-dimension")); +const ViewportDimension = createFactory(require("./ViewportDimension.js")); module.exports = createClass({ displayName: "DeviceAdder", diff --git a/devtools/client/responsive.html/components/device-modal.js b/devtools/client/responsive.html/components/DeviceModal.js similarity index 99% rename from devtools/client/responsive.html/components/device-modal.js rename to devtools/client/responsive.html/components/DeviceModal.js index 53f25adebd66..2fad6c6c181c 100644 --- a/devtools/client/responsive.html/components/device-modal.js +++ b/devtools/client/responsive.html/components/DeviceModal.js @@ -11,7 +11,7 @@ const { DOM: dom, createClass, createFactory, PropTypes, addons } = const { getStr, getFormatStr } = require("../utils/l10n"); const Types = require("../types"); -const DeviceAdder = createFactory(require("./device-adder")); +const DeviceAdder = createFactory(require("./DeviceAdder")); module.exports = createClass({ displayName: "DeviceModal", diff --git a/devtools/client/responsive.html/components/device-selector.js b/devtools/client/responsive.html/components/DeviceSelector.js similarity index 100% rename from devtools/client/responsive.html/components/device-selector.js rename to devtools/client/responsive.html/components/DeviceSelector.js diff --git a/devtools/client/responsive.html/components/dpr-selector.js b/devtools/client/responsive.html/components/DprSelector.js similarity index 100% rename from devtools/client/responsive.html/components/dpr-selector.js rename to devtools/client/responsive.html/components/DprSelector.js diff --git a/devtools/client/responsive.html/components/global-toolbar.js b/devtools/client/responsive.html/components/GlobalToolbar.js similarity index 95% rename from devtools/client/responsive.html/components/global-toolbar.js rename to devtools/client/responsive.html/components/GlobalToolbar.js index d55f75cb7eed..494e76c1f967 100644 --- a/devtools/client/responsive.html/components/global-toolbar.js +++ b/devtools/client/responsive.html/components/GlobalToolbar.js @@ -9,8 +9,8 @@ const { DOM: dom, createClass, createFactory, PropTypes, addons } = const { getStr } = require("../utils/l10n"); const Types = require("../types"); -const DPRSelector = createFactory(require("./dpr-selector")); -const NetworkThrottlingSelector = createFactory(require("./network-throttling-selector")); +const DPRSelector = createFactory(require("./DprSelector")); +const NetworkThrottlingSelector = createFactory(require("./NetworkThrottlingSelector")); module.exports = createClass({ displayName: "GlobalToolbar", diff --git a/devtools/client/responsive.html/components/network-throttling-selector.js b/devtools/client/responsive.html/components/NetworkThrottlingSelector.js similarity index 100% rename from devtools/client/responsive.html/components/network-throttling-selector.js rename to devtools/client/responsive.html/components/NetworkThrottlingSelector.js diff --git a/devtools/client/responsive.html/components/resizable-viewport.js b/devtools/client/responsive.html/components/ResizableViewport.js similarity index 97% rename from devtools/client/responsive.html/components/resizable-viewport.js rename to devtools/client/responsive.html/components/ResizableViewport.js index 14572d8870e1..43c59b38d8a0 100644 --- a/devtools/client/responsive.html/components/resizable-viewport.js +++ b/devtools/client/responsive.html/components/ResizableViewport.js @@ -11,8 +11,8 @@ const { DOM: dom, createClass, createFactory, PropTypes } = const Constants = require("../constants"); const Types = require("../types"); -const Browser = createFactory(require("./browser")); -const ViewportToolbar = createFactory(require("./viewport-toolbar")); +const Browser = createFactory(require("./Browser")); +const ViewportToolbar = createFactory(require("./ViewportToolbar")); const VIEWPORT_MIN_WIDTH = Constants.MIN_VIEWPORT_DIMENSION; const VIEWPORT_MIN_HEIGHT = Constants.MIN_VIEWPORT_DIMENSION; diff --git a/devtools/client/responsive.html/components/viewport.js b/devtools/client/responsive.html/components/Viewport.js similarity index 94% rename from devtools/client/responsive.html/components/viewport.js rename to devtools/client/responsive.html/components/Viewport.js index 9bec9a664a43..054ff692529a 100644 --- a/devtools/client/responsive.html/components/viewport.js +++ b/devtools/client/responsive.html/components/Viewport.js @@ -8,8 +8,8 @@ const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react"); const Types = require("../types"); -const ResizableViewport = createFactory(require("./resizable-viewport")); -const ViewportDimension = createFactory(require("./viewport-dimension")); +const ResizableViewport = createFactory(require("./ResizableViewport")); +const ViewportDimension = createFactory(require("./ViewportDimension")); module.exports = createClass({ diff --git a/devtools/client/responsive.html/components/viewport-dimension.js b/devtools/client/responsive.html/components/ViewportDimension.js similarity index 100% rename from devtools/client/responsive.html/components/viewport-dimension.js rename to devtools/client/responsive.html/components/ViewportDimension.js diff --git a/devtools/client/responsive.html/components/viewport-toolbar.js b/devtools/client/responsive.html/components/ViewportToolbar.js similarity index 95% rename from devtools/client/responsive.html/components/viewport-toolbar.js rename to devtools/client/responsive.html/components/ViewportToolbar.js index 664da1578cc4..9076edd14d47 100644 --- a/devtools/client/responsive.html/components/viewport-toolbar.js +++ b/devtools/client/responsive.html/components/ViewportToolbar.js @@ -9,7 +9,7 @@ const { DOM: dom, createClass, createFactory, PropTypes, addons } = const { getStr } = require("../utils/l10n"); const Types = require("../types"); -const DeviceSelector = createFactory(require("./device-selector")); +const DeviceSelector = createFactory(require("./DeviceSelector")); module.exports = createClass({ displayName: "ViewportToolbar", diff --git a/devtools/client/responsive.html/components/viewports.js b/devtools/client/responsive.html/components/Viewports.js similarity index 96% rename from devtools/client/responsive.html/components/viewports.js rename to devtools/client/responsive.html/components/Viewports.js index 82942c214e49..01b0edf107e6 100644 --- a/devtools/client/responsive.html/components/viewports.js +++ b/devtools/client/responsive.html/components/Viewports.js @@ -8,7 +8,7 @@ const { DOM: dom, createClass, createFactory, PropTypes } = require("devtools/client/shared/vendor/react"); const Types = require("../types"); -const Viewport = createFactory(require("./viewport")); +const Viewport = createFactory(require("./Viewport")); module.exports = createClass({ diff --git a/devtools/client/responsive.html/components/moz.build b/devtools/client/responsive.html/components/moz.build index 8bdfc2008edd..fbe8b6f64592 100644 --- a/devtools/client/responsive.html/components/moz.build +++ b/devtools/client/responsive.html/components/moz.build @@ -5,16 +5,16 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DevToolsModules( - 'browser.js', - 'device-adder.js', - 'device-modal.js', - 'device-selector.js', - 'dpr-selector.js', - 'global-toolbar.js', - 'network-throttling-selector.js', - 'resizable-viewport.js', - 'viewport-dimension.js', - 'viewport-toolbar.js', - 'viewport.js', - 'viewports.js', + 'Browser.js', + 'DeviceAdder.js', + 'DeviceModal.js', + 'DeviceSelector.js', + 'DprSelector.js', + 'GlobalToolbar.js', + 'NetworkThrottlingSelector.js', + 'ResizableViewport.js', + 'Viewport.js', + 'ViewportDimension.js', + 'Viewports.js', + 'ViewportToolbar.js', ) From 4401878e5edcc9bddf57e06d4b494749279ef859 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 10 Oct 2017 17:48:02 +0200 Subject: [PATCH 52/68] Backed out changeset 6bec02f9a646 (bug 1404651) for frequently failing browser-chrome's browser/base/content/test/general/browser_tabfocus.js. r=backout --HG-- extra : amend_source : 962cb65ee3c3b52439b47496d70924dd49efe51d --- browser/base/content/tabbrowser.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 672593367822..199bb33858f8 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1423,11 +1423,13 @@ findBar._findField.getAttribute("focused") == "true"); } - let activeEl = document.activeElement; - // In e10s, if focus isn't already in the tabstrip or on the new browser, - // and the new browser's previous focus wasn't in the url bar but focus is - // there now, we need to adjust focus further. - if (gMultiProcessBrowser && activeEl != newBrowser && activeEl != newTab) { + // If focus is in the tab bar, retain it there. + if (document.activeElement == oldTab) { + // We need to explicitly focus the new tab, because + // tabbox.xml does this only in some cases. + newTab.focus(); + } else if (gMultiProcessBrowser && document.activeElement !== newBrowser) { + let keepFocusOnUrlBar = newBrowser && newBrowser._urlbarFocused && gURLBar && From 0c903578be0fcc4f70eab228cc4b42ae81ff9154 Mon Sep 17 00:00:00 2001 From: Dale Harvey Date: Sat, 30 Sep 2017 10:43:02 +0100 Subject: [PATCH 53/68] Bug 1394248 - Update plugins icon. r=dao MozReview-Commit-ID: L3UrtSwDxW2 --HG-- extra : rebase_source : 26cfb27434edd394b3db3136c8560270fc7b3e5d --- browser/base/content/browser-plugins.js | 2 +- .../test/static/browser_all_files_referenced.js | 2 -- .../themes/linux/preferences/applications.css | 2 +- browser/themes/osx/preferences/applications.css | 2 +- browser/themes/shared/notification-icons.inc.css | 2 +- .../themes/windows/preferences/applications.css | 2 +- toolkit/mozapps/extensions/nsBlocklistService.js | 2 +- toolkit/themes/linux/mozapps/jar.mn | 3 --- .../linux/mozapps/plugins/pluginBlocked.png | Bin 1573 -> 0 bytes toolkit/themes/osx/mozapps/extensions/about.css | 2 +- toolkit/themes/osx/mozapps/extensions/eula.css | 2 +- .../osx/mozapps/extensions/xpinstallConfirm.css | 2 +- toolkit/themes/osx/mozapps/jar.mn | 8 +------- .../osx/mozapps/plugins/notifyPluginGeneric.png | Bin 313 -> 0 bytes .../osx/mozapps/plugins/pluginBlocked-64.png | Bin 4563 -> 0 bytes .../themes/osx/mozapps/plugins/pluginBlocked.png | Bin 2152 -> 0 bytes .../themes/shared/extensions/extensions.inc.css | 2 +- .../themes/shared/extensions/newaddon.inc.css | 2 +- toolkit/themes/shared/mozapps.inc.mn | 4 +++- toolkit/themes/shared/non-mac.jar.inc.mn | 3 --- toolkit/themes/shared/plugins/pluginBlocked.svg | 8 ++++++++ .../themes/windows/mozapps/extensions/about.css | 2 +- .../themes/windows/mozapps/extensions/eula.css | 2 +- .../mozapps/extensions/xpinstallConfirm.css | 2 +- toolkit/themes/windows/mozapps/jar.mn | 3 --- .../windows/mozapps/plugins/pluginBlocked-64.png | Bin 3427 -> 0 bytes .../windows/mozapps/plugins/pluginBlocked.png | Bin 1200 -> 0 bytes 27 files changed, 26 insertions(+), 33 deletions(-) delete mode 100644 toolkit/themes/linux/mozapps/plugins/pluginBlocked.png delete mode 100644 toolkit/themes/osx/mozapps/plugins/notifyPluginGeneric.png delete mode 100644 toolkit/themes/osx/mozapps/plugins/pluginBlocked-64.png delete mode 100644 toolkit/themes/osx/mozapps/plugins/pluginBlocked.png create mode 100644 toolkit/themes/shared/plugins/pluginBlocked.svg delete mode 100644 toolkit/themes/windows/mozapps/plugins/pluginBlocked-64.png delete mode 100644 toolkit/themes/windows/mozapps/plugins/pluginBlocked.png diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js index 9cbf0dd96cd4..76ed61e0a8cd 100644 --- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -560,7 +560,7 @@ var gPluginHandler = { // Configure the notification bar let priority = notificationBox.PRIORITY_WARNING_MEDIUM; - let iconURL = "chrome://mozapps/skin/plugins/notifyPluginCrashed.png"; + let iconURL = "chrome://mozapps/skin/plugins/pluginGeneric.svg"; let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label"); let reloadKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey"); diff --git a/browser/base/content/test/static/browser_all_files_referenced.js b/browser/base/content/test/static/browser_all_files_referenced.js index 5c3c571c1871..85ba47b7b632 100644 --- a/browser/base/content/test/static/browser_all_files_referenced.js +++ b/browser/base/content/test/static/browser_all_files_referenced.js @@ -154,8 +154,6 @@ var whitelist = [ // Bug 1348533 {file: "chrome://mozapps/skin/downloads/buttons.png", platforms: ["macosx"]}, {file: "chrome://mozapps/skin/downloads/downloadButtons.png", platforms: ["linux", "win"]}, - // Bug 1348556 - {file: "chrome://mozapps/skin/plugins/pluginBlocked.png"}, // Bug 1348558 {file: "chrome://mozapps/skin/update/downloadButtons.png", platforms: ["linux"]}, diff --git a/browser/themes/linux/preferences/applications.css b/browser/themes/linux/preferences/applications.css index 508076304f9d..7c31b758d06a 100644 --- a/browser/themes/linux/preferences/applications.css +++ b/browser/themes/linux/preferences/applications.css @@ -47,7 +47,7 @@ menuitem[appHandlerIcon="feed"] { richlistitem[appHandlerIcon="plugin"], menuitem[appHandlerIcon="plugin"] { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } .actionsMenu .menulist-icon { diff --git a/browser/themes/osx/preferences/applications.css b/browser/themes/osx/preferences/applications.css index 8a4a015007f3..3ffce0e01b9f 100644 --- a/browser/themes/osx/preferences/applications.css +++ b/browser/themes/osx/preferences/applications.css @@ -58,7 +58,7 @@ menuitem[appHandlerIcon="feed"] { richlistitem[appHandlerIcon="plugin"], menuitem[appHandlerIcon="plugin"] { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } /* Repeat what menu.css does for .menuitem-iconic */ diff --git a/browser/themes/shared/notification-icons.inc.css b/browser/themes/shared/notification-icons.inc.css index ca0f59aa6783..e86bccfe0f20 100644 --- a/browser/themes/shared/notification-icons.inc.css +++ b/browser/themes/shared/notification-icons.inc.css @@ -205,7 +205,7 @@ html|*#webRTC-previewVideo { } .popup-notification-icon[popupid="click-to-play-plugins"] { - list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked-64.png); + list-style-image: url(chrome://mozapps/skin/plugins/pluginBlocked.svg); } /* OFFLINE APPS */ diff --git a/browser/themes/windows/preferences/applications.css b/browser/themes/windows/preferences/applications.css index 2b1904ef9421..640f6d9917ec 100644 --- a/browser/themes/windows/preferences/applications.css +++ b/browser/themes/windows/preferences/applications.css @@ -47,7 +47,7 @@ menuitem[appHandlerIcon="feed"] { richlistitem[appHandlerIcon="plugin"], menuitem[appHandlerIcon="plugin"] { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } .actionsMenu .menulist-icon { diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index c20c2169ba7d..c4ed06c7a326 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -1375,7 +1375,7 @@ Blocklist.prototype = { addonList.push({ name: plugin.name, version: plugin.version, - icon: "chrome://mozapps/skin/plugins/pluginGeneric.png", + icon: "chrome://mozapps/skin/plugins/pluginGeneric.svg", disable: false, blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED, item: plugin, diff --git a/toolkit/themes/linux/mozapps/jar.mn b/toolkit/themes/linux/mozapps/jar.mn index cc1dc36f6bee..7d5226851632 100644 --- a/toolkit/themes/linux/mozapps/jar.mn +++ b/toolkit/themes/linux/mozapps/jar.mn @@ -8,9 +8,6 @@ toolkit.jar: * skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css) * skin/classic/mozapps/extensions/newaddon.css (extensions/newaddon.css) skin/classic/mozapps/extensions/heart.png (extensions/heart.png) - skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png) - skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png) - skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png) skin/classic/mozapps/update/updates.css (update/updates.css) skin/classic/mozapps/viewsource/viewsource.css (viewsource/viewsource.css) diff --git a/toolkit/themes/linux/mozapps/plugins/pluginBlocked.png b/toolkit/themes/linux/mozapps/plugins/pluginBlocked.png deleted file mode 100644 index 7238c8dbdd168d94cec7dac3c3e1155683c4e94f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1573 zcmV+=2HN?FP)N0$gZ>c!000+sMObt} zb#!QNasW(WaBm<(VQgV-VQyq{Woh4$8Y%z)02p*dSad^jWnpw_Z*Cw|X>DZyGB7YW zEio}IFf_X303`qb1v*JYK~z|U&6iDVR8p4ikjn0;qAJ zNfUQss4=?Gy(PYmAd)DB!>@_sY_sL^CNU->@RNGp8~v)Ew~H_BY9J*t5*ix%IPuCWansw2 zL?YOQ1-x&*@pFd`{nlSDZw5$3qd#};+m{UQ*x{J2F0@p_rqg6zdZ`$Uk3ZRtL`wz! z5E(|~2+-rKUF$G8iJhJXYq9h5$mFD>zJLFeNKpWRm=lShlapA-LGyWRI*oz22cP_5 z%(SYG4yc}9QGwq@Vqs%uRv$jx<)1%K>BI>-ckhN$3B7RxEfnzQ<|tjhO#IC^>4-#_ zfA(2A9(|O^rcG#}faY@8`FRRw&%*BA#O}L~{Hw2K%huk#QMJ@o0S87S+qOC3_3QCY zotBY{4NNjKrck^aP zFI*S}-fF8r%9ty6jg4(AeflY~W)1PtQOxSqNM|Q@aS=N+L-EKF^x8E#Mn(WA96N?t zzn=Ksy_oLq3O19$Ub|MoE-Vn)xs%+%gTMD%JJ^_SNgJj_9x)p?-W^URDSi7b@y8#> z^z}h^H>_HPtXV^-uaDT4Ex14aSYPM<@Iy1Ux0lembrtN{vqX|fq_1ynO5~AckHCr? zShZ(Qhn<-LK*z@kE?q)188n+k=jPC25vr>B*5Vj*6Z`A0XfB7=>Lr&0&jX;G$q;|+ zvCiDP?;Ze7H7RgKWJnWUN+!u1JxY0M3R^6K@1vfFf8z%Eix**V5H|=a zyGSO<9X*OaHB}+#`>5*@T)$57;zeX|kka+*L?3(*)6uatB{I}h1HXy9)ARiE&#c<9 z!vvQuq1KZ9>MPud3H-S^)OC?agiv=kp$!}8*tLsTB!U1`vE?e(dL9xEW2)GA6>EBW z$e%uK^Phe8-Uij@mJqlgQX2Z@m#Bn7;QQQa3YBEHVd}a_G}=623^tSD%GRy!kZNp6 z4U`~S`uc0!GiNHTR*&`%J}pHE_4MFEon4)P2l(UTxTj84dcK9#sr+41A~^Tni`y_% zC*T4S1eN5=5U3qNXkdW54jdq|eS3xcci*x2^2-EQuP!Cpf`A0U@&r&tjA^^W(7*s| zzx)!DNYuyTPdq_%c$nGYVS=kyk>%ElAgXu`L-jUv0a3*mg9(KyZVYmZC-(1OlDr-$ zksz^ue+3r`HG3_F>TM{{NV@TlD$(uRN%!}++~7Uu&NZ#SRRKg=6Y#1Ev<+|@W>z53 zQUMV$Z*%hq+SPdZ`|nwoO0}GGj~!c4ff@l3F{)~7Xj5Y))w5sD3u9wwHro_ivsvyB& diff --git a/toolkit/themes/osx/mozapps/extensions/about.css b/toolkit/themes/osx/mozapps/extensions/about.css index a8988af4c5ac..353307ba978f 100644 --- a/toolkit/themes/osx/mozapps/extensions/about.css +++ b/toolkit/themes/osx/mozapps/extensions/about.css @@ -34,7 +34,7 @@ } #genericAbout[addontype="plugin"] #extensionIcon { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } #genericAbout[addontype="dictionary"] #extensionIcon { diff --git a/toolkit/themes/osx/mozapps/extensions/eula.css b/toolkit/themes/osx/mozapps/extensions/eula.css index aca97f9cce96..5c9c0576b02b 100644 --- a/toolkit/themes/osx/mozapps/extensions/eula.css +++ b/toolkit/themes/osx/mozapps/extensions/eula.css @@ -18,7 +18,7 @@ } #eula-dialog[addontype="plugin"] #icon { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } #eula-dialog[addontype="dictionary"] #icon { diff --git a/toolkit/themes/osx/mozapps/extensions/xpinstallConfirm.css b/toolkit/themes/osx/mozapps/extensions/xpinstallConfirm.css index 496356eeeb97..039b4113e504 100644 --- a/toolkit/themes/osx/mozapps/extensions/xpinstallConfirm.css +++ b/toolkit/themes/osx/mozapps/extensions/xpinstallConfirm.css @@ -77,7 +77,7 @@ installitem[type="locale"] .xpinstallItemIcon { } installitem[type="plugin"] .xpinstallItemIcon { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } installitem[type="dictionary"] .xpinstallItemIcon { diff --git a/toolkit/themes/osx/mozapps/jar.mn b/toolkit/themes/osx/mozapps/jar.mn index 293e7186128c..d2ef25a62e24 100644 --- a/toolkit/themes/osx/mozapps/jar.mn +++ b/toolkit/themes/osx/mozapps/jar.mn @@ -18,11 +18,6 @@ toolkit.jar: skin/classic/mozapps/extensions/eula.css (extensions/eula.css) skin/classic/mozapps/extensions/blocklist.css (extensions/blocklist.css) * skin/classic/mozapps/extensions/newaddon.css (extensions/newaddon.css) - skin/classic/mozapps/plugins/notifyPluginGeneric.png (plugins/notifyPluginGeneric.png) - skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png) - skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png) - skin/classic/mozapps/plugins/pluginBlocked-64.png (plugins/pluginBlocked-64.png) - skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) skin/classic/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16.png) skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png) skin/classic/mozapps/profile/profileSelection.css (profile/profileSelection.css) @@ -37,5 +32,4 @@ toolkit.jar: [browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: #elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES [extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar: -#endif -% override chrome://mozapps/skin/plugins/notifyPluginCrashed.png chrome://mozapps/skin/plugins/notifyPluginGeneric.png +#endif \ No newline at end of file diff --git a/toolkit/themes/osx/mozapps/plugins/notifyPluginGeneric.png b/toolkit/themes/osx/mozapps/plugins/notifyPluginGeneric.png deleted file mode 100644 index 449e081496f7f0e460de087d76f3cad549d25df1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 313 zcmV-90mlA`P)oABaI+t`GP*qh2LqCs)LB@GWXW#`qfPGSN18&3o0*6F*0S^~&3kIDS z^4JiVK$Ga)y+DNIX|}%z6P|yA^AC9#C}-){<=IMzvMfh@;fb;sCou}nxj}#>2ACLN z$N@!Bm=8zvFMI=y2AbGFi@L7crfGJR0Hsvxeu@+3J#h=&TYv!onE6{3`a=V500000 LNkvXXu0mjf%UXO& diff --git a/toolkit/themes/osx/mozapps/plugins/pluginBlocked-64.png b/toolkit/themes/osx/mozapps/plugins/pluginBlocked-64.png deleted file mode 100644 index 56b8a3322d9d5054480d8ae5d70386ecfe51ea0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4563 zcmV;^5iIVBP)6k#SBl?fS_8IYt*W??GER1z)BB$L#n zEXGWzGMb?j!=TYfnZ!vHXM~8sQj*ejsUFSQe&ZSS?zK_?yKuMYZ z)nBLXcJBH9^Z(!fpYz^huIthVSv2~9iw-5m7@euq^B~#3mf635T_lsaS|1)>9yW}n zBx-wxH0vmLum=Sn2-fgL+m89R4w48QTlOsZ7qR1zjy z8Xg>68jr z@3w6+GR~QtTMoGWl1nD#-+h;cdwVI-)<&^pl47wKrCM8wf%Ld&XdTS93r(LmLAi37 zMzUEtJ}^KL$DzNw^iu8x$LJghuLJ5a>1i=|C7Ik^*t#{Fj7I-977nlc7*O7&pcaI+*|5B+F766NB+RFIs z*(ZCEvPqC3^tue5$#54u zEd~$4<;}^H$?fkart4y009{k5#(9K?07jZdP9j0}i!X{}RSBTgW7Qxw!pL~^(V306 z+`_ZTZ=j`#lHgf0cmYJl2gByfA&1Ag>(*AHaT#V=%(PCN^^T=Q_{vtV#x zfN&^8gfNKUxkl(znz-nAmiNIWXe^C<9Gn1MSEvi)5T424nOrVMBk&q;ED$yk1F+6D zYvv}y;hQ76zUFNZ4wsR^L8?M0%-{-v=>X3qK655De&|DD;Gt4U3>d6E)(*|ShxL<;f5#o`aKquNXNNO^>m3$XtmW0~97cpsYk(qH=0bB1mIYQ~l= zB0YKrh?~XYe>OBViGg^+qzj%AgJbqWmt9890N{W}loVB$#ciHK4<9C^J_>#ElVttj z4`)3V4_7o2Ss50SOiw_Io&g&AJ3A?h7)^qNQXsAncg-0y$UzJ_mgTXt!rHYpgxH)4 zm$$1`a^cQ_GcJJ#8bw~O9y~~)#fwSf_kzrvqestZEYoJqB9|Kw#OR=JXYho;tQtT& ze&R$&b!23DY04DJA%}AYPJ(bOfN}GAauBx$0GUufgA){$A2s0xO~}_Rcs7jZ@-S*F z9w#LIFj8ldIVekY4YVgKh5aD6C|6ks41Mg3O3nP^_Kx>W#_b@bZ^wEZy2k8Rz z2wA;-f@ocQOxMkG%&GzG0%M1!5nYZ0!O8{1ZXunf1iYaE+Ju+dJP%hY6HZ|U03SvC z4*(Q5W&(zc17Hl-nB$D?Cdu?w#6cE@9tH=b@tj#I2{tF5PBl&NKphb&vZZ|n#S`&y zz&(yg8^$4ynN$xLHHF3^55nG@LINi{#3CgG2`?DZ*Xz$BvN!MXDNG z6v-AUI4A5W1}s_$%Bv^*i#G4w8e`lmME205nDI;oYmsguS;Z>gg=8(OZ=45=*mjQ! zUUer&8UksF8$oCykr0El3?pz~Fal$qwI~L_%2Lz_eu=`Xnx;=D4ZvLhH!phV;r9S*Khcm0fQVfWwA!lYgh%9jhL{Ah zN$NU9;rbz{xF3UdizN=?OjYoPSX1CQiFepAID@-~IPiRqtasia*E9k_tH9N3|1$(v z_8Gu|njpgcDc4=*2hX5tM>rm5h&)f9&=h9A1u019&wwvD!P$iZ*biL;^F$P+dj z2^fH(AcHpv;Pw##JQ%PFy2dqxP>y2_S`67mq(XqZ+#ma-fR7?SH_V?eQf21A0Wxzr z@4BecveF}RJS?D50Md{Jq6m*B#O*{S3d1#{@Im?%MVJHNXaloA7~^5++d%mY;{*U7 z%LHlD6e%#s0M<~Y(l;L+sWYsSVe2*5Q2Q6YKupt40v_74hkCKz<{J@A-p9`ik3dlc zBM42vBf^HkJwWy!EDZoW32Oiy`J8aSjY`ldN>FSJl?K3#x8FuFEVg)fK*XLv?!li> z1^W@CramSghGb1sq`*KA7`Ch)HTKm|XqY>fF8bmZRm+O)uGXurq9jVzPHcWwl$9Hk zb;L0jW`F_zS~zC{}DC3QTUi2r## z8Q=#S@AZ3&jWT*Lo$jgW0lTWzj=%E7xo3nFEUk*l0a2u*#Td}R?|+}FoM2VblpK*k z5#)Jf(0~zy zS1eq<9KcO7j}C}@UUTb4x_#>2dnNeV62dOCFn^Z+`c? z)b+?CR2?23=MB?Vte{4)vH&bWGt~$IeS<6Ng4fY!9DEZbrG5LT4_~14ZP-AbIBjM+1q`+VU*jdLpO$^(w+utH>`!0Pnr~ZtDNu_o&+0IW`d-JP26;S1=4&mP~=Q4PfOQr;mIy z#&0Sj9dU{CbS7P&d&R)>&(mHE0^j8e*XGi6@x_#AZyy7#_UA9G>L~}sm(rJ9LY@?m z<~Z;H05`k4DW+*+i7n!sG2!|S7~gNitZl0)FxUf5V5JmP|K|{2TpH%g5eA4sBaD&e zx}wxQ^28Ig7X&qg!D$#!+owN0-UFa4zyksmKs=3JafK+U3)my*`P$cL;Qsr`Kw%UG z=qS!>95lvY!Alvc$O;OyAVUt>woHMwx5cg9w%u{P2V6cFVoZ2I89TdE;og&$ETMk5 ze*Ueugau7pH+h)A?K&TNh?XO@wS4rW^xk8Skt1hattOe*LQhrFGMRy5cpsMmWEeh{ z7?igHnBxeRkANd)Aw6=b?A`^(|qV8vU{1FSdrst~TEW`dAx2Y2isk|}Y)H@-ph z?z&49FA;uD-bYXqE~vu@an$e%8LF+1V}iH2C2>&{UI*c>E@xbVH%tm4m9}l%NYj7% zQ)-m8O8&(c{j)E0SFtElpw9#RsW6XKVKY{RU{di7tOYIby?~cqqL$Bnj$+8+T;iwz z=fUcOIN$foGh`s;*o;v*pBFP1#-^$xxr3?2lV^yN?oKtu)^*ZTDM4&Z0_PGzHQ2Oz zHO0UUsuZz@Xkz!6d>$~Qq`-P#jhUmxVvZo*=7TE%7%;?jwg|Wr}6!zwHM?tu>y18$$*w5jHP0O}hr1=ja~98nMR zfp--HSa8R;9(aH*M%s&{Qh`j4nt-RyKo4NPgCKF0HV;;B`OIf(g12%x>H#UcXjSkk z5AaRj346dRMEgK)?$A;H*ekM7_}aKSA`r ze?zo(Hqn);5n|qcK3wxn7-2eo6Ex$qpQSih-$Fq$h+=49>sAF+Z4YqqQF(wVu`9N~ zMn=S%qYIVaTvUEKHbl9YI5)a;Cmn@x!Y~pGi2HX84knJqg@B@Vt9YEAT4VmdSd zZGld|mFU_}5#2VKXrW4E25*Db?5FYLzP~_5!79#g90A?}NZx6|6`# zUL`^`-xvlhtMl1HVcUb5%r5y8yAf!~ZvbGgX#i4quMye`opu+|Uw@2fb)0C52ioGQ zaD}FXNv%#*S;h?j=2l%FWv!TbPi$UgLRBx(0Xz&<-M;8JLob)hPu-JFKaIoV&@{9F zHI>`y8$cBWQxe)XmuTKPqFa{}tx^cDm5T+<{hPXT@%!(R+#d!4J>h!PwtVciqeA%tc+TiPfAb!Phjd4^f|G z?fvoS=uduEDs{+NABC1{0k1=Xbq!IJ{Fi?farLU}9=eUOYgQ6{IY~6@3@sq*dV@?b zIzOI>WE`h=dp^JU;cWJIGR}wP_^fmNTVV^DlUB}dbKT)>M0@ULY}FNvt*}@0eznjPtA#=XIqH37(nA=QWu&o1xP`!Pv5Y(6p~3Z7!lZ zG7DQ>xmR8}<;nKlE(E|tfv-k1y(ARKx!pWn1Oms8`s0N~d9@(&YoU|DD%wDZ3lXZwwowfZ&J z{TVKlg52B1$MJ2ART1aN=Rf<@z`$yN-_HAzeP%iM_w^qpTnHM2F*YJuIrA^J{U37} z`|odtLhI39NvZ*Sdjj32`SQPJGMlXq9`}1@(^+Ip8u3VW7<)aov%xSk^ah z2!%ejTGPHVg|UUCY=>jVrt|S)@!@BR#n*}Gs4QR0xNcvtf0>a0ZOIR!e)zR*4@39; zQz*3ZI$d8^0Q)~vDn0V!Z1y=B=R-2iO*$WPp8q<_pi#NDSOUFD>JoV_D(^XO*mXLe xA~{Z}+K$Wf-jBW=I?wXwKTp#KTmEc-{{w_c#nFh4DjEO)002ovPDHLkV1jrzohbkS diff --git a/toolkit/themes/osx/mozapps/plugins/pluginBlocked.png b/toolkit/themes/osx/mozapps/plugins/pluginBlocked.png deleted file mode 100644 index 6e8e1761bf87e41def9bc2567680c2ab0f4c6c4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2152 zcmV-u2$%PXP))fGN>c4ptZUO(2^ z#10NCCAM4Kkcfg%A|6d7L<&ME{Am8rh^j@3sDvsc)E|k|Dj=0gMQYNf6`<14ieD)W zjUuF~Jn|q3Bu=6@@q^e7#&&kS-iP<$-Pw8dJL8${Iw^%9_|cJ$c4zLLbH4kX@0@!_ z(5+o!>eQ)ZyQ==olgX@a9x&qZi&>xVH@Dq;?*wkGFY8dgmEix{y}LItH8rdh3OA4D za+{P`Y#06oV6`vp^cDa}u=x1nkEc4;t|eb<>#{*LpQnkD5!&$f+i~2^e^mfd;q>Vr z`RC^!qiQwQcp3;4%7!r{ojLQ^rTzQ+${r7yem|8kREBv>lhjIuy!AS5f9|>AN@wS9 zBgy1|IXb%D(sgo8>hHf;?&(>UrsfpLnK$1&7#$kgAq?Xtq+XBb`?c}jXM5;;_e%Z9+$2UdqzkgYpngRIE?cbl@Ffc&jM1nj% z-+u%KC;98wNiAW`y}hK&&y!NE+Fnei&9bNs^Anw&WC7Uq^XDlV4uhVuy>e62$bu1` zjh{NjF2gPWPJtMC^2wwuNk1qL4LvhAHkQx=0jf!oO|c5+9=xo<*~X0<$qyFV0Mg5W zd39jJL`v$g{O~X(SFE7Hg9qt5~da(bEHzt??UrdOrAxyTsUYp_yR#!k^ zrgss)OmB#h!ui^J?jik?Pi#s}rWPRh*8_`y9RYEEQJQX#MD|#UvWHW_0K%i7CDzqN zUcBsGxsv2!k$iB#L1hLY1a*SGprTN1a*}9afvj3>2>=6OCg9vensgRiPY-daDtI2i z`>ZGre%rxp{~dSObBvi;I~AOQ#G%g4lP!vpl!HME$K&Jy69zjr&1FI~G8volAedm} zI>t3PCZ-pZr)FoVyQ71oK;VYjk|+v&v__*O`MR;Zxs6TQcdZDKzrT$Bio>YywG zp~-L%MUW5xNpNmCKvY?#EI_1kIVxg)5ziJlH5d;%)&&+L5TwPx5I6uppehZA!>&f9*BO4G!9=Nih&G(guyRqI9ER zCJ;vhDnMLZA*>0EN1uI`e0Sct)I~RMCJoxrMn~b(Bm?`#XfDT-4c=h%BSe#yvw8;M zhttZ`)Y9Ux>f}>TQ4lL+vDvACK4#Gi#$f)oHqx$5l7X_b9GW9LcQ%4^newIJo;#wB zE^45Jf0xZN09|slQ!kt5gm3^DXhh?$yh0=U_E81&b9wgc*g@{NYZ^Km&t);Xrl8IP z4?JK8t$?+u=bxwi;lo7m!7Olj7Yu{NQFp7rZd~YGB^IK+!gSg$!}+skX$XBi{@{bu zy=@ys*R7)kY`KyXj2uOqZcj%_{0Lq}OV0e|uT&qtLS8g6-rVXlGj?C$wAPnOQ0Lf^ zBTPLIDDB_GtCe&-#UK5~Rw@4Cwl&hxlGNDctkH zzy)PsYnVW59rCd9c@!lzcHjVM*m!t#3QDVZ=@Pl)u32t(gH^}JsdVmKBe)5HPQCad z)dAdan3~hHp$Sc65!$C7kGmQ`sz9qJa1P7fM%0JnNKnP*QiXD54vrem96d?`DwZ7N z_93yqpLBFazO+<|7C!ojbj&FO?DWeollt+;_B>SC{NKvueLqg6etoW18{;Bj?4s#x z$Xj&_tP{5K1)`_FMYIk7gYE%M`7ejaUNkLjZjKDJUK4cN8;z4D85MwhFJ4g9qfe*P zf5fBfusLTB(-?rKdAD_rNqm4Qy-RfA4ABPzLL@qb=wWA)D?TB_%+LQ^EdGO24@I$aWC=yoC2goWsE1G^SM z+11djns>#tVT}B~P}uv6T<-OpVT|(T=NydcH-5BuKIgb@Ig@Q5NZ8EZE$jU*Ar=!t zBo!foE&%>M(6K*o|EM6(?^dgS`pMkfuP)c?=ke}muq>?ld0$JOFZgcY%2A!PluugL z$XN)rTL?KWNozbpD7-yai^awBs(N@&KL5g@O68xJ`>B)bimUdo>&uAii$950Y?h>f zAIkF15H#?Iv9Z^W)oPcReOTUEvH5j>nl*n<@>!(KG5gEVvBhSAeNzCM%hvsRQQfkl e|F`Sk0t^5p7Iq5lfsGmf0000 + + + + + diff --git a/toolkit/themes/windows/mozapps/extensions/about.css b/toolkit/themes/windows/mozapps/extensions/about.css index 9378472e8add..133e198234df 100644 --- a/toolkit/themes/windows/mozapps/extensions/about.css +++ b/toolkit/themes/windows/mozapps/extensions/about.css @@ -46,7 +46,7 @@ } #genericAbout[addontype="plugin"] #extensionIcon { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } #genericAbout[addontype="dictionary"] #extensionIcon { diff --git a/toolkit/themes/windows/mozapps/extensions/eula.css b/toolkit/themes/windows/mozapps/extensions/eula.css index aca97f9cce96..5c9c0576b02b 100644 --- a/toolkit/themes/windows/mozapps/extensions/eula.css +++ b/toolkit/themes/windows/mozapps/extensions/eula.css @@ -18,7 +18,7 @@ } #eula-dialog[addontype="plugin"] #icon { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } #eula-dialog[addontype="dictionary"] #icon { diff --git a/toolkit/themes/windows/mozapps/extensions/xpinstallConfirm.css b/toolkit/themes/windows/mozapps/extensions/xpinstallConfirm.css index 4d06250baa95..553b0a882a33 100644 --- a/toolkit/themes/windows/mozapps/extensions/xpinstallConfirm.css +++ b/toolkit/themes/windows/mozapps/extensions/xpinstallConfirm.css @@ -88,7 +88,7 @@ installitem[type="locale"] .xpinstallItemIcon { } installitem[type="plugin"] .xpinstallItemIcon { - list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); + list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg"); } installitem[type="dictionary"] .xpinstallItemIcon { diff --git a/toolkit/themes/windows/mozapps/jar.mn b/toolkit/themes/windows/mozapps/jar.mn index 8dfd12219d3d..89991c023904 100644 --- a/toolkit/themes/windows/mozapps/jar.mn +++ b/toolkit/themes/windows/mozapps/jar.mn @@ -8,9 +8,6 @@ toolkit.jar: * skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css) skin/classic/mozapps/extensions/heart.png (extensions/heart.png) * skin/classic/mozapps/extensions/newaddon.css (extensions/newaddon.css) - skin/classic/mozapps/plugins/pluginGeneric.png (plugins/pluginGeneric.png) - skin/classic/mozapps/plugins/pluginBlocked.png (plugins/pluginBlocked.png) - skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png) skin/classic/mozapps/update/updates.css (update/updates.css) skin/classic/mozapps/viewsource/viewsource.css (viewsource/viewsource.css) diff --git a/toolkit/themes/windows/mozapps/plugins/pluginBlocked-64.png b/toolkit/themes/windows/mozapps/plugins/pluginBlocked-64.png deleted file mode 100644 index 3263cc1be981199ee8a5502ef3d047995e1c0331..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3427 zcmV-p4V?0cP)nfHyoi>mTw7Q>rc{-1!D9_7{Fy%SVPX4=?PHL*^8 zX^99D8KMPWgH)<5tNy+}_z;9u61S#kRv%uG#J)atD$H>v6tRM!9_IN<~$ zVd;ACi*q3UFFFnPwFTlqY7I@ z0_7mzP#|FNPmr_ZwOQQK|HZZ8w(tGzGU{R#81K{moyCF)J6t53uqLC4hGG zNMChudAreaX*`Fx+Knq^v{^rlsVL(9ou$Xrq=G!#0~(Q`uoSJZoQ1k zhM&Te%VBTj(5B5a+X-}cb<(A&O+k<(S;LBm%N2BZn9}G9 z23B8??)wmtd?ZF!QMvjCrp692bL<$c|MAtB#%6wqBTTuUs9K}6bcA?hIjuOxHk$O6 zO7y2bje>~Tc}@s;-}~=eo_6PVwpD4Sz^7X+EXqK&N`IwHeEu3@V=x&ot4d;(nWRl) zxjX8=i(&`K=r;bp|bBh&_maDJm`UcX7J1x8$H8MrOI){g+KMI}I@ z=)JU)l1qPt+VT+wD+4alYAvXuR!P+QZixZ<;}Vr6WtJ`*VX9uIF5@D-m&ZT&@ne{((rI0Am)#uZp1Xi?7`K z(b`)+`{3zCAwXiYoi;`yg8+@RK@E&7r`>3x?Y2+T{QNGG83E%`o_L_2dfMQkI3h1B zvR~lDL$mom!heu#9ohL82Iw+T$#{S0JLpsPuFQo9O2Xtf57n<{sY@;0bt?+??t~CrG9@l^}C{z->Hs%^L>SD(raJ6 z{+`bt?uh`2q8&&(-?c?R72BTS#EZ{6J!=thQ(q7|``!Dz)3cT0$s#7*ZwLOcCjzYM zc13cN+fX{EPyYBI3z6!&^+;bl>vv~fJwR6yt|@noieOcD_C&zJFW$Eql}$eVy{vur zFERel-{RCu-*;(yHX_C_a`9%?+;9_7xlAXyaNF&SJ^d6X_U-M;@9v*9^itTZ{fVFuI2St_ER7GF^!)bW9G~ml4b*dsK1|5 zwdQJg@Pc&=ziktJwI$3Yrd($IwqIuT4L7>_o=UT9`shUJ_cTc(^IPsGu2!imTh74h z^QmokE2Y69R25V^VYmahcVPq|J3{&g#>pN~_Kl1%I{J3E785y}eV-|r2;E3IC2wU) z9E2kfs}7_l30Ui_CYiMsv05NO5kTIzU;>iH^pU7sSqmyY`hkEbXq>8XYe$yk2oM%7 zfdB{2+5kGJADf-#vp}>tIXSW5CqmC&vO)Vw5rX&;6OoLFOx+p)K?;Bs)yxJUPH`4c z>-Isz-dfxqx6VGpy0!K92ySgj+}^sqQ+1y+lUR06)MY^#P%=V)6eA{pl>+$8&KhkG zR8c(epr~SL!6;E9KY z04g8~3KZh+|0+4~nd3YesQ<|Ay+^kszt_wHgwM5DJPO*|B&eVoV1;BxkU&BJkCK-_ zU;wWLB0RDHlp+xXQ~|VeLvHUZftnsNKnqR+NDU-(1Yhg}0ld#Gr^V3M z^nUZv4!_Z!GoZ+$%(~Z(Mc_*yUcQp*weMtb>lKtQ+(H?`~D73TGD=o1Z9 zQ$jXSef!m{`i+ls@~I~n`{OUroH&9i9#}E`p->8*7y?XjgdLDc}10Y-XNPyqXSL?;^hHt%% zRlj);7(=&jp`*bn8@}|X9K8ScnE2)+kO%GoW5c>w8uVBK%*mnx;tlvL01y{>R^9zc zoLI|3L@=!T#C5RR&QD5_{`SkrDfX)qG=lw$1 z_}MS<{B1YVm>3TcFO~o{UnVF(Pp5!qaK7lPf{5R;;@3ZnR0dJ2v%&1L90pnUk>BQ} zdwwei+yc%PO9LhByCNW7vIZ}E)*7r;L?}oh`s&uiD^^mw_C~PD+28Ky{CTnL`ghUy z-~&vLk7GS(XNx4*TzPm*LE5j6b$1K~@xk`k{XW2{U41=>pw`m65He82k?`8r{wxPH zSg#cN!a_^Hcqblh{;wkb&{OdwFt~Z^oY7ahuL=)g$=1uUfAvs4141LjQi#4&zyP)z z0u0a>2*@bNN8Q^T3FUQfDZKlC@w%;r@zmRJlN3OB;;(pSA3JkEQ!gGO~lGiLT zfuvgkYMuatk9Nnj&-VeF6iUEaEj}R06BEw%Kti5K#qDh&`bAapqyRNw3Yh7p1cn@g z)?%dyRzf@x#2*6g{|J;uS9Y2w0uTc5;;|NhVe?~i>(q$=G(^9k*89p77y?W;JwSkx zwH9jx0R%<-yq{$QE(^jqpc^M)Mh}KSe>nTe9g61b75O8GolhltK&Qd;rFRTGe zo(yEc1SpBB18qVh3}i^~?#lz_K`d0kMb(nkxZ7vZjcJ(HKF%&Fimx`EzXion0U@e+C2+ittt0_l4h2qd#7l{ez_g z8H&>51ChivK@BCKLWn*mCpU1AV4>O+ko?d8V~`(8!Zy-9HJTE)4(C% z6kxk0pq~BsB+v&K{&$H5TEG<0?2>>$g46%QVtA9we*>Xa40%5L!^8jp002ovPDHLk FV1laaaYz6F diff --git a/toolkit/themes/windows/mozapps/plugins/pluginBlocked.png b/toolkit/themes/windows/mozapps/plugins/pluginBlocked.png deleted file mode 100644 index 49997c06dbad50fbc994bee7518ac52aeedb2f94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1200 zcmV;h1W)^kP)E-$JXRO7=5y!H=q+0`u^1G2tKG-`kF(Kq*V`Jvx;`eZz&*|1wbp1CynY_RE z>eU-THY2^g8v|%VKa;^!y;_B$s!%m;6skHx`yv2n+Al^brP=j59NUH#iTp^r-xA+w zXIODT*qDJo&z<{$mS6e$?`O}D(sdX+b_khOD42RRk%gbK**KIM-WXLd12q&=^ z5(5J;i$yrAtI#tU#P;k#7oFHCmxXTM2~wquH0r?BQPsgsmtgwhMIk6Yc_L0^WV6r{ z30S2P%(rhvnzs!PBdiY5_Ct5?7DHuVW_)}=q3D_Zs#H*W{Tg8Q5K9L(p+hu8JQ->Z zD2DM3F|UZL{-c8TS*}K-ZFMAn5gG%ku7BlT@5<#+nVG?V1ga%!vy`Txn*bTV+BAVRoP8ELfQ6~4tZz=)5E~|DNA4a2*_L3oq^ix#viJAt zeWBaX?+qy(3o$#Fjv*b{l&$q^x$nq8;90{3U|G#Ec}|=@c@mk^r?G8lNCdU?^eO(i za|i$4yN9|PRD)C7w!;Uo?#z=B_q09ZeSll`5Eb)OHvQ`@bS%n<+H~|J~?}K?PWvAUZs&+p#j8P z<1tKo7L~3{Em^*O8(w#=^CFGv7>#yAwr_9%KG6z5QHp12WdAWZD0D0j%9##4dW6W4 zBQOI_J45rNgIYO3!UH*Zsix=oTdK8D~q(M}A{yZ=P^7Wv$0wHH1!sE0+T;`L@ zzGmh&Ye$8L57+e@nQcoSfdPmNRCv Date: Mon, 9 Oct 2017 12:03:38 +0200 Subject: [PATCH 54/68] Bug 1406097 - Use the cached attribution code in the environment. r=mhowell This adds a new sync function to AttributionCode.jsm that returns the cached attribution data. The cached data is then used to populate the environment instead of relying on the async function. MozReview-Commit-ID: F0se7kXspo2 --HG-- extra : rebase_source : 0a2631651e3da6edde9592eabd354b070ffa6ae8 --- browser/modules/AttributionCode.jsm | 10 ++++ .../telemetry/TelemetryEnvironment.jsm | 51 +++++++++++++------ 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/browser/modules/AttributionCode.jsm b/browser/modules/AttributionCode.jsm index 4d8815febda6..ed5b46ed2db0 100644 --- a/browser/modules/AttributionCode.jsm +++ b/browser/modules/AttributionCode.jsm @@ -90,6 +90,16 @@ var AttributionCode = { })(); }, + /** + * Return the cached attribution data synchronously without hitting + * the disk. + * @returns A dictionary with the attribution data if it's available, + * null otherwise. + */ + getCachedAttributionData() { + return gCachedAttrData; + }, + /** * Deletes the attribution data file. * Returns a promise that resolves when the file is deleted, diff --git a/toolkit/components/telemetry/TelemetryEnvironment.jsm b/toolkit/components/telemetry/TelemetryEnvironment.jsm index dc37ce2271b8..8abf1390deff 100644 --- a/toolkit/components/telemetry/TelemetryEnvironment.jsm +++ b/toolkit/components/telemetry/TelemetryEnvironment.jsm @@ -867,7 +867,7 @@ function EnvironmentCache() { this._currentEnvironment.profile = {}; p.push(this._updateProfile()); if (AppConstants.MOZ_BUILD_APP == "browser") { - p.push(this._updateAttribution()); + p.push(this._loadAttributionAsync()); } for (const [id, {branch, options}] of gActiveExperimentStartupBuffer.entries()) { @@ -1363,13 +1363,7 @@ EnvironmentCache.prototype = { updateChannel = UpdateUtils.getUpdateChannel(false); } catch (e) {} - // Make sure to retain the attribution code across environment changes. - const attributionCode = - (this._currentEnvironment.settings && - this._currentEnvironment.settings.attribution) || {}; - this._currentEnvironment.settings = { - attribution: attributionCode, blocklistEnabled: Services.prefs.getBoolPref(PREF_BLOCKLIST_ENABLED, true), e10sEnabled: Services.appinfo.browserTabsRemoteAutostart, e10sMultiProcesses: Services.appinfo.maxWebProcessCount, @@ -1388,6 +1382,7 @@ EnvironmentCache.prototype = { this._currentEnvironment.settings.addonCompatibilityCheckEnabled = AddonManager.checkCompatibility; + this._updateAttribution(); this._updateDefaultBrowser(); this._updateSearchEngine(); }, @@ -1425,18 +1420,42 @@ EnvironmentCache.prototype = { }, /** - * Update the cached attribution data object. + * Load the attribution data object and updates the environment. * @returns Promise<> resolved when the I/O is complete. */ - async _updateAttribution() { - let data = await AttributionCode.getAttrDataAsync(); - if (Object.keys(data).length > 0) { - this._currentEnvironment.settings.attribution = {}; - for (let key in data) { - this._currentEnvironment.settings.attribution[key] = - limitStringToLength(data[key], MAX_ATTRIBUTION_STRING_LENGTH); - } + async _loadAttributionAsync() { + try { + await AttributionCode.getAttrDataAsync(); + } catch (e) { + // The AttributionCode.jsm module might not be always available + // (e.g. tests). Gracefully handle this. + return; } + this._updateAttribution(); + }, + + /** + * Update the environment with the cached attribution data. + */ + _updateAttribution() { + let data = null; + try { + data = AttributionCode.getCachedAttributionData(); + } catch (e) { + // The AttributionCode.jsm module might not be always available + // (e.g. tests). Gracefully handle this. + } + + if (!data || !Object.keys(data).length) { + return; + } + + let attributionData = {}; + for (let key in data) { + attributionData[key] = + limitStringToLength(data[key], MAX_ATTRIBUTION_STRING_LENGTH); + } + this._currentEnvironment.settings.attribution = attributionData; }, /** From 6a80cdfeb903471f046b73bae853208e9550035c Mon Sep 17 00:00:00 2001 From: Jan-Ivar Bruaroey Date: Fri, 29 Sep 2017 15:06:51 -0400 Subject: [PATCH 55/68] Bug 1406988 - Assert MediaManager invariant where applicable, and check for existence everywhere else. r=pehrsons MozReview-Commit-ID: KfGP96IE17G --HG-- extra : rebase_source : d03aeea5f8809b07d2172ee706a616b863526505 --- dom/media/MediaManager.cpp | 43 ++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp index de95a3f54eeb..2eb77a78ca36 100644 --- a/dom/media/MediaManager.cpp +++ b/dom/media/MediaManager.cpp @@ -410,7 +410,7 @@ public: MOZ_ASSERT(mInactiveListeners.Length() == 0); MOZ_ASSERT(mActiveListeners.Length() == 0); - RefPtr mgr = MediaManager::GetIfExists(); + MediaManager* mgr = MediaManager::GetIfExists(); if (!mgr) { MOZ_ASSERT(false, "MediaManager should stay until everything is removed"); return; @@ -1289,7 +1289,10 @@ public: self->mOnFailure.forget()))); NS_DispatchToMainThread(NS_NewRunnableFunction("MediaManager::SendPendingGUMRequest", []() -> void { - RefPtr manager = MediaManager::GetInstance(); + MediaManager* manager = MediaManager::GetIfExists(); + if (!manager) { + return; + } manager->SendPendingGUMRequest(); })); return NS_OK; @@ -1356,7 +1359,6 @@ GetSources(MediaEngine *engine, MediaSourceEnum aSrcType, // TODO: Remove once upgraded to GCC 4.8+ on linux. Bogus error on static func: // error: 'this' was not captured for this lambda function -static auto& MediaManager_GetInstance = MediaManager::GetInstance; static auto& MediaManager_ToJSArray = MediaManager::ToJSArray; static auto& MediaManager_AnonymizeDevices = MediaManager::AnonymizeDevices; @@ -1419,7 +1421,10 @@ MediaManager::SelectSettings( } } NS_DispatchToMainThread(NewRunnableFrom([id, badConstraint]() mutable { - RefPtr mgr = MediaManager_GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); + if (!mgr) { + return NS_OK; + } RefPtr p = mgr->mOutstandingCharPledges.Remove(id); if (p) { p->Resolve(badConstraint); @@ -1548,7 +1553,10 @@ public: } NS_DispatchToMainThread(NS_NewRunnableFunction("MediaManager::SendPendingGUMRequest", []() -> void { - RefPtr manager = MediaManager::GetInstance(); + MediaManager* manager = MediaManager::GetIfExists(); + if (!manager) { + return; + } manager->SendPendingGUMRequest(); })); return NS_OK; @@ -1726,7 +1734,8 @@ MediaManager::EnumerateRawDevices(uint64_t aWindowId, fakeBackend = new MediaEngineDefault(); } if ((!fakeCams && hasVideo) || (!fakeMics && hasAudio)) { - RefPtr manager = MediaManager_GetInstance(); + MediaManager* manager = MediaManager::GetIfExists(); + MOZ_RELEASE_ASSERT(manager); // Must exist while media thread is alive realBackend = manager->GetBackend(aWindowId); // We need to listen to this event even JS didn't listen to it. realBackend->AddDeviceChangeCallback(manager); @@ -1755,7 +1764,7 @@ MediaManager::EnumerateRawDevices(uint64_t aWindowId, SourceSet* handoff = result.release(); NS_DispatchToMainThread(NewRunnableFrom([id, handoff]() mutable { UniquePtr result(handoff); // grab result - RefPtr mgr = MediaManager_GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); if (!mgr) { return NS_OK; } @@ -2036,7 +2045,8 @@ int MediaManager::AddDeviceChangeCallback(DeviceChangeCallback* aCallback) { bool fakeDeviceChangeEventOn = mPrefs.mFakeDeviceChangeEventOn; MediaManager::PostTask(NewTaskFrom([fakeDeviceChangeEventOn]() { - RefPtr manager = MediaManager_GetInstance(); + MediaManager* manager = MediaManager::GetIfExists(); + MOZ_RELEASE_ASSERT(manager); // Must exist while media thread is alive if (fakeDeviceChangeEventOn) manager->GetBackend(0)->SetFakeDeviceChangeEvents(); })); @@ -2698,7 +2708,10 @@ MediaManager::EnumerateDevicesImpl(uint64_t aWindowId, p->Then([id, aWindowId, aVideoType, aAudioType, aFake](const nsCString& aOriginKey) mutable { MOZ_ASSERT(NS_IsMainThread()); - RefPtr mgr = MediaManager_GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); + if (!mgr) { + return; + } RefPtr p = mgr->EnumerateRawDevices(aWindowId, aVideoType, aAudioType, aFake); @@ -2711,7 +2724,7 @@ MediaManager::EnumerateDevicesImpl(uint64_t aWindowId, UniquePtr devices(aDevices); // secondary result // Only run if window is still on our active list. - RefPtr mgr = MediaManager_GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); if (!mgr) { return NS_OK; } @@ -3942,7 +3955,10 @@ SourceListener::ApplyConstraintsToTrack( "MozNoiseSuppressionWarning", aWindow); - RefPtr mgr = MediaManager::GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); + if (!mgr) { + return p.forget(); + } uint32_t id = mgr->mOutstandingVoidPledges.Append(*p); uint64_t windowId = aWindow->WindowID(); bool isChrome = (aCallerType == dom::CallerType::System); @@ -3951,7 +3967,8 @@ SourceListener::ApplyConstraintsToTrack( audioDevice, videoDevice, c, isChrome]() mutable { MOZ_ASSERT(MediaManager::IsInMediaThread()); - RefPtr mgr = MediaManager::GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); + MOZ_RELEASE_ASSERT(mgr); // Must exist while media thread is alive const char* badConstraint = nullptr; nsresult rv = NS_OK; @@ -3975,7 +3992,7 @@ SourceListener::ApplyConstraintsToTrack( NS_DispatchToMainThread(NewRunnableFrom([id, windowId, rv, badConstraint]() mutable { MOZ_ASSERT(NS_IsMainThread()); - RefPtr mgr = MediaManager_GetInstance(); + MediaManager* mgr = MediaManager::GetIfExists(); if (!mgr) { return NS_OK; } From 5171c16eb058d0157af01efb6a6375505b5f3a59 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Tue, 10 Oct 2017 19:11:17 +0200 Subject: [PATCH 56/68] Backed out changeset 804b3282f778 (bug 1407026) for failing devtools/client/webconsole/test/browser_console.js on Windows 7 debug without e10s. r=backout --HG-- extra : amend_source : 969438fbe7623611a02be5d05fa776269bbd7adc --- .../new-console-output/test/mochitest/browser_console.js | 4 ---- devtools/client/webconsole/test/browser_console.js | 4 ---- devtools/server/actors/object.js | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js b/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js index e1a73a2cc7b6..c70039bec41c 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js +++ b/devtools/client/webconsole/new-console-output/test/mochitest/browser_console.js @@ -197,8 +197,4 @@ function* testCPOWInspection(hud) { // Just a sanity check to make sure a valid packet came back is(prototypeAndProperties.prototype.class, "XBL prototype JSClass", "Looks like a valid response"); - - // The CPOW is in the _contentWindow property. - let cpow = prototypeAndProperties.ownProperties._contentWindow.value; - is(cpow.class, "CPOW: Window", "The CPOW grip has the right class."); } diff --git a/devtools/client/webconsole/test/browser_console.js b/devtools/client/webconsole/test/browser_console.js index e1a73a2cc7b6..c70039bec41c 100644 --- a/devtools/client/webconsole/test/browser_console.js +++ b/devtools/client/webconsole/test/browser_console.js @@ -197,8 +197,4 @@ function* testCPOWInspection(hud) { // Just a sanity check to make sure a valid packet came back is(prototypeAndProperties.prototype.class, "XBL prototype JSClass", "Looks like a valid response"); - - // The CPOW is in the _contentWindow property. - let cpow = prototypeAndProperties.ownProperties._contentWindow.value; - is(cpow.class, "CPOW: Window", "The CPOW grip has the right class."); } diff --git a/devtools/server/actors/object.js b/devtools/server/actors/object.js index 4539dcd7d413..db855c6dda0e 100644 --- a/devtools/server/actors/object.js +++ b/devtools/server/actors/object.js @@ -83,7 +83,7 @@ ObjectActor.prototype = { let unwrapped = DevToolsUtils.unwrap(this.obj); if (!unwrapped) { if (DevToolsUtils.isCPOW(this.obj)) { - g.class = "CPOW: " + this.obj.class; + g.class = "CPOW: " + g.class; } else { g.class = "Inaccessible"; } From e729ce7f9a8e2ff2220a8d07f5cf7bcef6eb2496 Mon Sep 17 00:00:00 2001 From: Mike de Boer Date: Tue, 10 Oct 2017 19:14:01 +0200 Subject: [PATCH 57/68] Bug 1397989 - Make sure to only set non-empty values as the content-type of a document in the remote browser binding. r=mconley What happens is the following: - browser-child.js sends a statechange up to RemoteWebProgress.jsm that contains a `documentContentType` value of `null`, along with `requestURI` and `originalRequestURI` _after_ other state changes that did send a valid content-type. - The content-type is used by the WebProgressListener in browser.js to toggle the disabled state of the 'isImage' broadcaster. - The 'isImage' broadcaster is used by the 'cmd_find' and 'cmd_findAgain' commands to determine whether they should be enabled. In this case: not. The fix here is to _not_ set the documentContentType in the browser binding when it's `null`. MozReview-Commit-ID: IELoCrnOH0j --HG-- extra : rebase_source : 51211b7aee13eabc71f91e73df4fc6d69e5c624b --- toolkit/modules/RemoteWebProgress.jsm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/toolkit/modules/RemoteWebProgress.jsm b/toolkit/modules/RemoteWebProgress.jsm index 90449d0ddc4c..b6c48533adf0 100644 --- a/toolkit/modules/RemoteWebProgress.jsm +++ b/toolkit/modules/RemoteWebProgress.jsm @@ -222,7 +222,11 @@ RemoteWebProgressManager.prototype = { if (isTopLevel) { this._browser._contentWindow = objects.contentWindow; - this._browser._documentContentType = json.documentContentType; + // Setting a content-type back to `null` is quite nonsensical for the + // frontend, especially since we're not expecting it. + if (json.documentContentType !== null) { + this._browser._documentContentType = json.documentContentType; + } if (typeof json.inLoadURI != "undefined") { this._browser.inLoadURI = json.inLoadURI; } From ea13b520369bdaf47febdc959b2d0ad7683b433d Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 10 Oct 2017 19:49:04 +0200 Subject: [PATCH 58/68] Bug 1407326 - remove references to invertIconForLightTheme in extensions codebase;r=rpl MozReview-Commit-ID: B2eTpm6qbOh --HG-- extra : rebase_source : 4435d53e0f96a2beea27d5e727642479fba7d1f2 --- browser/components/extensions/ext-devtools-panels.js | 1 - .../extensions/test/browser/browser_ext_devtools_panel.js | 3 --- 2 files changed, 4 deletions(-) diff --git a/browser/components/extensions/ext-devtools-panels.js b/browser/components/extensions/ext-devtools-panels.js index e4b9a0c6b841..23829947b053 100644 --- a/browser/components/extensions/ext-devtools-panels.js +++ b/browser/components/extensions/ext-devtools-panels.js @@ -88,7 +88,6 @@ class ParentDevToolsPanel { icon: icon, label: title, tooltip: `DevTools Panel added by "${extensionName}" add-on.`, - invertIconForLightTheme: false, visibilityswitch: `devtools.webext-${this.id}.enabled`, isTargetSupported: target => target.isLocalTab, build: (window, toolbox) => { diff --git a/browser/components/extensions/test/browser/browser_ext_devtools_panel.js b/browser/components/extensions/test/browser/browser_ext_devtools_panel.js index 31423a14bfbe..6e0cd29724d7 100644 --- a/browser/components/extensions/test/browser/browser_ext_devtools_panel.js +++ b/browser/components/extensions/test/browser/browser_ext_devtools_panel.js @@ -214,9 +214,6 @@ add_task(async function test_devtools_page_panels_create() { const panelDef = toolboxAdditionalTools[0]; const panelId = panelDef.id; - is(panelDef.invertIconForLightTheme, false, - "devtools.panel.create set invertIconForLightTheme to false by default"); - await gDevTools.showToolbox(target, panelId); const {devtoolsPageTabId} = await extension.awaitMessage("devtools_panel_shown"); const devtoolsPanelTabId = await extension.awaitMessage("devtools_panel_inspectedWindow_tabId"); From 18b14bf9ff4ce3fc7d7451f894b891cfc3bb7446 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 10 Oct 2017 19:44:27 +0200 Subject: [PATCH 59/68] Bug 1407322 - use currentColor for selected stylesheet icon in styleeditor;r=ntim MozReview-Commit-ID: HysqhWk4y4G --HG-- extra : rebase_source : d1a9416336dc53e05890c11e95a73c77e8450696 --- devtools/client/themes/styleeditor.css | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/devtools/client/themes/styleeditor.css b/devtools/client/themes/styleeditor.css index 18e299ddc582..e7568bbb0465 100644 --- a/devtools/client/themes/styleeditor.css +++ b/devtools/client/themes/styleeditor.css @@ -173,19 +173,16 @@ li.error > .stylesheet-info > .stylesheet-more > .stylesheet-error-message { background-size: 16px; width: 24px; height: 40px; + + /* The icon color should always match the text color. */ -moz-context-properties: fill; - fill: var(--theme-toolbar-color); + fill: currentColor; } .disabled > .stylesheet-enabled { opacity: 0.3; } -/* Invert the toggle icon in the active row for light theme */ -.splitview-nav > li.splitview-active .stylesheet-enabled { - fill: var(--theme-toolbar-selected-color); -} - .splitview-nav > li > .stylesheet-enabled:focus, .splitview-nav > li:hover > .stylesheet-enabled { outline: 0; From 3ca2df25d7e33e20850bd9e2dd97aba26ebfaf82 Mon Sep 17 00:00:00 2001 From: Grigory Kruglov Date: Tue, 10 Oct 2017 13:33:50 -0400 Subject: [PATCH 60/68] Bug 1401318 - Fix some of the 'shared-state' access problems around Account r=nalexander This patch fixes several symptoms of shared state (internal 'account' instance) getting out-of-sync with the world. We maintain a representation of an internal Account in the AndroidFxAccount, but nothing is preventing that representation to become irrelevant in certain situations. This patch ensures we 'update our internal cache', so to speak, before trying to act upon it. Changes in the 'profile JSON fetched' flow are necessary to support the 'email might change' case. Locking is necessary to ensure correct behaviour in case of overlapping syncing and profile fetching. Changes in 'getState' are necessary to ensure we behave correctly when a long-lived AndroidFxAccount instance is interrogated (as in the Sync Prefs UI) after internal account changes. There are likely to be other "symptoms", but this patch aims to be safely upliftable in order to support changing of a primary email. See Bug 1407316 for further root-cause analysis and proposed solution. MozReview-Commit-ID: AXmTBMzL2cf --HG-- extra : rebase_source : f34bdab349363981851c0936cbb2da64c327e657 --- .../fxa/authenticator/AndroidFxAccount.java | 107 +++++++++++------- 1 file changed, 68 insertions(+), 39 deletions(-) diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/authenticator/AndroidFxAccount.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/authenticator/AndroidFxAccount.java index a11a372a0360..77938620cb68 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/authenticator/AndroidFxAccount.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/authenticator/AndroidFxAccount.java @@ -701,6 +701,13 @@ public class AndroidFxAccount { } public synchronized State getState() { + // Ensure we're working with the latest 'account' state. It might have changed underneath us. + // Note that this "state refresh" is inefficient for some callers, since they might have + // created this object (and thus fetched an account from the accounts system) just moments ago. + // Other callers maintain this object for a while, and thus might be out-of-sync with the world. + // See Bug 1407316 for higher-order improvements that will make this unnecessary. + account = FirefoxAccounts.getFirefoxAccount(context); + String stateLabelString = getBundleData(BUNDLE_KEY_STATE_LABEL); String stateString = getBundleData(BUNDLE_KEY_STATE); if (stateLabelString == null || stateString == null) { @@ -722,6 +729,10 @@ public class AndroidFxAccount { * For debugging only! */ public void dump() { + // Make sure we dump using the latest 'account'. It might have changed since this object was + // initialized. + account = FirefoxAccounts.getFirefoxAccount(context); + if (!FxAccountUtils.LOG_PERSONAL_INFORMATION) { return; } @@ -1046,56 +1057,74 @@ public class AndroidFxAccount { } final String email = profileJSON.getString("email"); - // If primary email didn't change, there's nothing for us to do. - if (account.name.equals(email)) { + // To prevent race against a shared state, we need to hold a lock which is released after + // account is renamed, or it's determined that the rename isn't necessary. + try { + acquireSharedAccountStateLock(LOG_TAG); + } catch (InterruptedException e) { + Logger.error(LOG_TAG, "Could not acquire a shared account state lock."); callback.run(); return; } - Logger.info(LOG_TAG, "Renaming Android Account."); - FxAccountUtils.pii(LOG_TAG, "Renaming Android account from " + account.name + " to " + email); + try { + // Update our internal state. It's possible that the account changed underneath us while + // we were fetching profile information. See Bug 1401318. + account = FirefoxAccounts.getFirefoxAccount(context); - // Then, get the currently auto-syncing authorities. - // We'll toggle these on once we re-add the account. - final Map currentAuthoritiesToSync = getAuthoritiesToSyncAutomaticallyMap(); + // If primary email didn't change, there's nothing for us to do. + if (account.name.equals(email)) { + callback.run(); + return; + } - // We also need to manually carry over current sync intervals. - final Map> periodicSyncsForAuthorities = new HashMap<>(); - for (String authority : currentAuthoritiesToSync.keySet()) { - periodicSyncsForAuthorities.put(authority, ContentResolver.getPeriodicSyncs(account, authority)); - } + Logger.info(LOG_TAG, "Renaming Android Account."); + FxAccountUtils.pii(LOG_TAG, "Renaming Android account from " + account.name + " to " + email); - final Runnable migrateSyncSettings = new Runnable() { - @Override - public void run() { - // Set up auto-syncing for the newly added account. - setAuthoritiesToSyncAutomaticallyMap(currentAuthoritiesToSync); + // Then, get the currently auto-syncing authorities. + // We'll toggle these on once we re-add the account. + final Map currentAuthoritiesToSync = getAuthoritiesToSyncAutomaticallyMap(); - // Set up all of the periodic syncs we had prior. - for (String authority : periodicSyncsForAuthorities.keySet()) { - final List periodicSyncs = periodicSyncsForAuthorities.get(authority); - for (PeriodicSync periodicSync : periodicSyncs) { - ContentResolver.addPeriodicSync( - account, - periodicSync.authority, - periodicSync.extras, - periodicSync.period - ); + // We also need to manually carry over current sync intervals. + final Map> periodicSyncsForAuthorities = new HashMap<>(); + for (String authority : currentAuthoritiesToSync.keySet()) { + periodicSyncsForAuthorities.put(authority, ContentResolver.getPeriodicSyncs(account, authority)); + } + + final Runnable migrateSyncSettings = new Runnable() { + @Override + public void run() { + // Set up auto-syncing for the newly added account. + setAuthoritiesToSyncAutomaticallyMap(currentAuthoritiesToSync); + + // Set up all of the periodic syncs we had prior. + for (String authority : periodicSyncsForAuthorities.keySet()) { + final List periodicSyncs = periodicSyncsForAuthorities.get(authority); + for (PeriodicSync periodicSync : periodicSyncs) { + ContentResolver.addPeriodicSync( + account, + periodicSync.authority, + periodicSync.extras, + periodicSync.period + ); + } } } + }; + + // On API21+, we can simply "rename" the account, which will recreate it carrying over user data. + // Our regular "account was just deleted" side-effects will not run. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + doOptionalProfileRename21Plus(email, migrateSyncSettings, callback); + + // Prior to API21, we have to perform this operation manually: make a copy of the user data, + // delete current account, and then re-create it. + // We also need to ensure our regular "account was just deleted" side-effects are not invoked. + } else { + doOptionalProfileRenamePre21(email, migrateSyncSettings, callback); } - }; - - // On API21+, we can simply "rename" the account, which will recreate it carrying over user data. - // Our regular "account was just deleted" side-effects will not run. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - doOptionalProfileRename21Plus(email, migrateSyncSettings, callback); - - // Prior to API21, we have to perform this operation manually: make a copy of the user data, - // delete current account, and then re-create it. - // We also need to ensure our regular "account was just deleted" side-effects are not invoked. - } else { - doOptionalProfileRenamePre21(email, migrateSyncSettings, callback); + } finally { + releaseSharedAccountStateLock(); } } From 0892e733f3841bff254991b49d766a1f70a5e33e Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 10 Oct 2017 07:35:49 -0600 Subject: [PATCH 61/68] Bug 1407230 - Don't set devtools.debugger.client-source-maps-enabled pref; r=jdescottes This removes the last spot that sets the obsolete devtools.debugger.client-source-maps-enabled pref. Note that the definition of the pref remains; it will be deleted upstream once this lands, and then removed from M-C by the next debugger bundle landing. MozReview-Commit-ID: DTd2iDJI1y0 --HG-- extra : rebase_source : f7ac30f2ef707c11ad3d717ea49d13e1e883bd95 --- devtools/client/framework/toolbox-process-window.js | 1 - 1 file changed, 1 deletion(-) diff --git a/devtools/client/framework/toolbox-process-window.js b/devtools/client/framework/toolbox-process-window.js index 2e1224f48f02..4eaea9b4655f 100644 --- a/devtools/client/framework/toolbox-process-window.js +++ b/devtools/client/framework/toolbox-process-window.js @@ -76,7 +76,6 @@ function setPrefDefaults() { // Bug 1225160 - Using source maps with browser debugging can lead to a crash Services.prefs.setBoolPref("devtools.debugger.source-maps-enabled", false); Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true); - Services.prefs.setBoolPref("devtools.debugger.client-source-maps-enabled", true); Services.prefs.setBoolPref("devtools.webconsole.new-frontend-enabled", false); } window.addEventListener("load", function () { From a31bec0c1ff9f78d5014289a39ffc195f8eb7656 Mon Sep 17 00:00:00 2001 From: Jan Henning Date: Mon, 9 Oct 2017 21:54:54 +0200 Subject: [PATCH 62/68] Bug 1407029 - Accept Android lint dependencies from SDK versions 26.0.0*. r=nalexander MozReview-Commit-ID: GHMRossAUaB --HG-- extra : rebase_source : c4ad6eddd4436c6169b98913a5aa9e085e15a70e --- build/autoconf/android.m4 | 1 + old-configure.in | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 index c60b48c29371..bfcd3923c879 100644 --- a/build/autoconf/android.m4 +++ b/build/autoconf/android.m4 @@ -316,6 +316,7 @@ for version in $4; do ANDROID_LINT_CLASSPATH="$ANDROID_LINT_CLASSPATH $ANDROID_SDK_ROOT/tools/lib/repository-$version.jar" ANDROID_LINT_CLASSPATH="$ANDROID_LINT_CLASSPATH $ANDROID_SDK_ROOT/tools/lib/common-$version.jar" ANDROID_LINT_CLASSPATH="$ANDROID_LINT_CLASSPATH $ANDROID_SDK_ROOT/tools/lib/lint-api-$version.jar" + ANDROID_LINT_CLASSPATH="$ANDROID_LINT_CLASSPATH $ANDROID_SDK_ROOT/tools/lib/manifest-merger-$version.jar" break fi done diff --git a/old-configure.in b/old-configure.in index 497aa29b170a..a5b69514a1c6 100644 --- a/old-configure.in +++ b/old-configure.in @@ -2220,7 +2220,7 @@ dnl ======================================================== case "$MOZ_BUILD_APP" in mobile/android) - MOZ_ANDROID_SDK(23, 23, 23.0.3 23.0.1, 25.3.2 25.3.1) + MOZ_ANDROID_SDK(23, 23, 23.0.3 23.0.1, 26.0.0 26.0.0-dev 25.3.2 25.3.1) ;; esac From 4f4b90db1ff294d6df0713ff0daf520e7af553cb Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 10 Oct 2017 12:31:24 -0500 Subject: [PATCH 63/68] servo: Merge #18808 - Use the current parser location for CSS error (from servo:error-location_); r=emilio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … rather than the start location of the current construct. This likely places the error just *after* of the unexpected token whereas before would be best, but that’s likely a much bigger change. See https://bugzilla.mozilla.org/show_bug.cgi?id=1378861 Source-Repo: https://github.com/servo/servo Source-Revision: c79a54dbd9d3a590f5fd8191b8e57a0b9d1d0fdb --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 7a78da26aa9801972da42123730f90bcddc92930 --- servo/Cargo.lock | 28 +- servo/components/canvas/Cargo.toml | 2 +- servo/components/canvas_traits/Cargo.toml | 2 +- servo/components/malloc_size_of/Cargo.toml | 2 +- servo/components/script/Cargo.toml | 2 +- .../script_layout_interface/Cargo.toml | 2 +- servo/components/selectors/Cargo.toml | 2 +- servo/components/selectors/parser.rs | 314 ++++++++++-------- servo/components/style/Cargo.toml | 2 +- servo/components/style/counter_style/mod.rs | 44 +-- servo/components/style/custom_properties.rs | 37 ++- servo/components/style/error_reporting.rs | 17 +- servo/components/style/font_face.rs | 19 +- servo/components/style/gecko/media_queries.rs | 92 ++--- .../components/style/gecko/selector_parser.rs | 39 ++- servo/components/style/macros.rs | 13 +- servo/components/style/media_queries.rs | 12 +- .../style/properties/declaration_block.rs | 32 +- .../style/properties/helpers.mako.rs | 14 +- .../helpers/animated_properties.mako.rs | 7 +- .../properties/longhand/background.mako.rs | 2 +- .../style/properties/longhand/border.mako.rs | 2 +- .../style/properties/longhand/box.mako.rs | 15 +- .../properties/longhand/counters.mako.rs | 17 +- .../style/properties/longhand/font.mako.rs | 59 ++-- .../properties/longhand/inherited_box.mako.rs | 2 +- .../properties/longhand/inherited_svg.mako.rs | 11 +- .../longhand/inherited_text.mako.rs | 2 +- .../style/properties/longhand/list.mako.rs | 8 +- .../style/properties/longhand/outline.mako.rs | 2 +- .../properties/longhand/pointing.mako.rs | 3 +- .../properties/longhand/position.mako.rs | 7 +- .../style/properties/longhand/table.mako.rs | 4 +- .../style/properties/longhand/text.mako.rs | 15 +- .../style/properties/longhand/ui.mako.rs | 2 +- .../style/properties/properties.mako.rs | 32 +- .../properties/shorthand/background.mako.rs | 6 +- .../style/properties/shorthand/border.mako.rs | 6 +- .../style/properties/shorthand/box.mako.rs | 10 +- .../style/properties/shorthand/column.mako.rs | 4 +- .../style/properties/shorthand/font.mako.rs | 6 +- .../shorthand/inherited_text.mako.rs | 4 +- .../style/properties/shorthand/list.mako.rs | 4 +- .../style/properties/shorthand/mask.mako.rs | 4 +- .../properties/shorthand/outline.mako.rs | 2 +- .../properties/shorthand/position.mako.rs | 24 +- .../style/properties/shorthand/text.mako.rs | 2 +- servo/components/style/servo/media_queries.rs | 4 +- .../components/style/servo/selector_parser.rs | 50 +-- .../style/stylesheets/document_rule.rs | 9 +- .../stylesheets/font_feature_values_rule.rs | 46 +-- .../style/stylesheets/keyframes_rule.rs | 31 +- .../style/stylesheets/rule_parser.rs | 47 +-- .../style/stylesheets/stylesheet.rs | 7 +- .../style/stylesheets/supports_rule.rs | 20 +- .../style/stylesheets/viewport_rule.rs | 17 +- .../components/style/values/generics/grid.rs | 23 +- servo/components/style/values/generics/mod.rs | 13 +- servo/components/style/values/generics/svg.rs | 8 +- servo/components/style/values/mod.rs | 25 +- .../style/values/specified/align.rs | 38 ++- .../style/values/specified/angle.rs | 6 +- .../style/values/specified/background.rs | 5 +- .../style/values/specified/basic_shape.rs | 11 +- .../style/values/specified/border.rs | 2 +- .../components/style/values/specified/box.rs | 2 +- .../components/style/values/specified/calc.rs | 29 +- .../style/values/specified/color.rs | 28 +- .../style/values/specified/effects.rs | 19 +- .../components/style/values/specified/flex.rs | 2 +- .../components/style/values/specified/font.rs | 2 +- .../components/style/values/specified/grid.rs | 25 +- .../style/values/specified/image.rs | 27 +- .../style/values/specified/length.rs | 34 +- .../components/style/values/specified/mod.rs | 25 +- .../style/values/specified/percentage.rs | 5 +- .../components/style/values/specified/svg.rs | 8 +- .../components/style/values/specified/text.rs | 5 +- .../components/style/values/specified/time.rs | 11 +- .../style/values/specified/transform.rs | 11 +- servo/components/style_traits/Cargo.toml | 2 +- servo/components/style_traits/lib.rs | 96 +++--- servo/components/style_traits/values.rs | 20 +- servo/components/style_traits/viewport.rs | 5 +- servo/ports/geckolib/Cargo.toml | 2 +- servo/ports/geckolib/error_reporter.rs | 299 +++++++++-------- servo/tests/unit/gfx/Cargo.toml | 2 +- servo/tests/unit/style/Cargo.toml | 2 +- servo/tests/unit/style/size_of.rs | 9 + servo/tests/unit/style/stylesheets.rs | 101 ++++-- servo/tests/unit/stylo/Cargo.toml | 2 +- 91 files changed, 1146 insertions(+), 926 deletions(-) diff --git a/servo/Cargo.lock b/servo/Cargo.lock index 38e39eab333e..9b1985dfe389 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -309,7 +309,7 @@ dependencies = [ "azure 0.21.2 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", "compositing 0.0.1", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -325,7 +325,7 @@ dependencies = [ name = "canvas_traits" version = "0.0.1" dependencies = [ - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.21.2" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1060,7 +1060,7 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1130,7 +1130,7 @@ dependencies = [ name = "gfx_tests" version = "0.0.1" dependencies = [ - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "gfx 0.0.1", "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", @@ -1737,7 +1737,7 @@ name = "malloc_size_of" version = "0.0.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", "servo_arc 0.0.1", @@ -2594,7 +2594,7 @@ dependencies = [ "caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "deny_public_fields 0.0.1", "devtools_traits 0.0.1", "dom_struct 0.0.1", @@ -2667,7 +2667,7 @@ dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2740,7 +2740,7 @@ name = "selectors" version = "0.19.0" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", @@ -3145,7 +3145,7 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "fallible 0.0.1", @@ -3207,7 +3207,7 @@ version = "0.0.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3229,7 +3229,7 @@ version = "0.0.1" dependencies = [ "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3247,7 +3247,7 @@ name = "stylo_tests" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", @@ -3836,7 +3836,7 @@ dependencies = [ "checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" "checksum core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd47addfc77b7e574d24e5434f95bb64a863769dfd4f1d451ca4ff5530ba01a" "checksum core-text 7.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a23bef779fab70e5e6af23e36eed03a48e1c1687dea8929505d405ea48d1f5e" -"checksum cssparser 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)" = "05012fcdbdeb4c6f59f67db47c1f879929339274a691ee1fb90c26b297783629" +"checksum cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44313341610282488e1156ad1fedebca51c54766c87a041d0287b10499c04ba1" "checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" "checksum darling 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9861a8495606435477df581bc858ccf15a3469747edf175b94a4704fd9aaedac" "checksum darling_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1486a8b00b45062c997f767738178b43219133dd0c8c826cb811e60563810821" diff --git a/servo/components/canvas/Cargo.toml b/servo/components/canvas/Cargo.toml index fbba07aed828..00eb302369a3 100644 --- a/servo/components/canvas/Cargo.toml +++ b/servo/components/canvas/Cargo.toml @@ -13,7 +13,7 @@ path = "lib.rs" azure = {git = "https://github.com/servo/rust-azure"} canvas_traits = {path = "../canvas_traits"} compositing = {path = "../compositing"} -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" fnv = "1.0" gleam = "0.4" diff --git a/servo/components/canvas_traits/Cargo.toml b/servo/components/canvas_traits/Cargo.toml index 79cb182a5af0..091c01dc6303 100644 --- a/servo/components/canvas_traits/Cargo.toml +++ b/servo/components/canvas_traits/Cargo.toml @@ -10,7 +10,7 @@ name = "canvas_traits" path = "lib.rs" [dependencies] -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" heapsize = "0.4" heapsize_derive = "0.1" diff --git a/servo/components/malloc_size_of/Cargo.toml b/servo/components/malloc_size_of/Cargo.toml index a47ef2d4c4cd..b3c2faa0f055 100644 --- a/servo/components/malloc_size_of/Cargo.toml +++ b/servo/components/malloc_size_of/Cargo.toml @@ -10,7 +10,7 @@ path = "lib.rs" [dependencies] app_units = "0.5.5" -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" hashglobe = { path = "../hashglobe" } servo_arc = { path = "../servo_arc" } diff --git a/servo/components/script/Cargo.toml b/servo/components/script/Cargo.toml index 5cbfa701bb0d..be1af3a2ad52 100644 --- a/servo/components/script/Cargo.toml +++ b/servo/components/script/Cargo.toml @@ -33,7 +33,7 @@ byteorder = "1.0" canvas_traits = {path = "../canvas_traits"} caseless = "0.1.0" cookie = "0.6" -cssparser = "0.21.1" +cssparser = "0.22.0" deny_public_fields = {path = "../deny_public_fields"} devtools_traits = {path = "../devtools_traits"} dom_struct = {path = "../dom_struct"} diff --git a/servo/components/script_layout_interface/Cargo.toml b/servo/components/script_layout_interface/Cargo.toml index 322bdc857b5c..0928de561565 100644 --- a/servo/components/script_layout_interface/Cargo.toml +++ b/servo/components/script_layout_interface/Cargo.toml @@ -13,7 +13,7 @@ path = "lib.rs" app_units = "0.5" atomic_refcell = "0.1" canvas_traits = {path = "../canvas_traits"} -cssparser = "0.21.1" +cssparser = "0.22.0" euclid = "0.15" gfx_traits = {path = "../gfx_traits"} heapsize = "0.4" diff --git a/servo/components/selectors/Cargo.toml b/servo/components/selectors/Cargo.toml index 0fa01f994b3a..a7df20358fab 100644 --- a/servo/components/selectors/Cargo.toml +++ b/servo/components/selectors/Cargo.toml @@ -25,7 +25,7 @@ unstable = [] [dependencies] bitflags = "0.7" matches = "0.1" -cssparser = "0.21.1" +cssparser = "0.22.0" log = "0.3" fnv = "1.0" malloc_size_of = { path = "../malloc_size_of" } diff --git a/servo/components/selectors/parser.rs b/servo/components/selectors/parser.rs index 44ff450aa3e0..6b87ed96720a 100644 --- a/servo/components/selectors/parser.rs +++ b/servo/components/selectors/parser.rs @@ -7,7 +7,8 @@ use attr::{ParsedCaseSensitivity, SELECTOR_WHITESPACE, NamespaceConstraint}; use bloom::BLOOM_HASH_MASK; use builder::{SelectorBuilder, SpecificityAndFlags}; use context::QuirksMode; -use cssparser::{ParseError, BasicParseError, CowRcStr, Delimiter}; +use cssparser::{ParseError, ParseErrorKind, BasicParseError, BasicParseErrorKind}; +use cssparser::{SourceLocation, CowRcStr, Delimiter}; use cssparser::{Token, Parser as CssParser, parse_nth, ToCss, serialize_identifier, CssStringWriter}; use precomputed_hash::PrecomputedHash; use servo_arc::ThinArc; @@ -46,8 +47,10 @@ fn to_ascii_lowercase(s: &str) -> Cow { } } +pub type SelectorParseError<'i> = ParseError<'i, SelectorParseErrorKind<'i>>; + #[derive(Clone, Debug, PartialEq)] -pub enum SelectorParseError<'i, T> { +pub enum SelectorParseErrorKind<'i> { PseudoElementInComplexSelector, NoQualifiedNameInAttributeSelector(Token<'i>), EmptySelector, @@ -66,13 +69,6 @@ pub enum SelectorParseError<'i, T> { ExplicitNamespaceUnexpectedToken(Token<'i>), ClassNeedsIdent(Token<'i>), EmptyNegation, - Custom(T), -} - -impl<'a, T> Into>> for SelectorParseError<'a, T> { - fn into(self) -> ParseError<'a, SelectorParseError<'a, T>> { - ParseError::Custom(self) - } } macro_rules! with_all_bounds { @@ -128,7 +124,7 @@ with_bounds! { pub trait Parser<'i> { type Impl: SelectorImpl; - type Error: 'i; + type Error: 'i + From>; /// Whether the name is a pseudo-element that can be specified with /// the single colon syntax in addition to the double-colon syntax. @@ -138,31 +134,32 @@ pub trait Parser<'i> { /// This function can return an "Err" pseudo-element in order to support CSS2.1 /// pseudo-elements. - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result<::NonTSPseudoClass, - ParseError<'i, SelectorParseError<'i, Self::Error>>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + ParseError<'i, Self::Error>> + { + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_non_ts_functional_pseudo_class<'t> - (&self, name: CowRcStr<'i>, _arguments: &mut CssParser<'i, 't>) - -> Result<::NonTSPseudoClass, - ParseError<'i, SelectorParseError<'i, Self::Error>>> + (&self, name: CowRcStr<'i>, arguments: &mut CssParser<'i, 't>) + -> Result<::NonTSPseudoClass, ParseError<'i, Self::Error>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + Err(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result<::PseudoElement, - ParseError<'i, SelectorParseError<'i, Self::Error>>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + ParseError<'i, Self::Error>> + { + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_functional_pseudo_element<'t> - (&self, name: CowRcStr<'i>, _arguments: &mut CssParser<'i, 't>) - -> Result<::PseudoElement, - ParseError<'i, SelectorParseError<'i, Self::Error>>> { - Err(ParseError::Custom(SelectorParseError::UnsupportedPseudoClassOrElement(name))) + (&self, name: CowRcStr<'i>, arguments: &mut CssParser<'i, 't>) + -> Result<::PseudoElement, ParseError<'i, Self::Error>> + { + Err(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn default_namespace(&self) -> Option<::NamespaceUrl> { @@ -183,9 +180,9 @@ impl SelectorList { /// https://drafts.csswg.org/selectors/#grouping /// /// Return the Selectors or Err if there is an invalid selector. - pub fn parse<'i, 't, P, E>(parser: &P, input: &mut CssParser<'i, 't>) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E> { + pub fn parse<'i, 't, P>(parser: &P, input: &mut CssParser<'i, 't>) + -> Result> + where P: Parser<'i, Impl=Impl> { let mut values = SmallVec::new(); loop { values.push(input.parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?); @@ -1052,24 +1049,28 @@ fn display_to_css_identifier(x: &T, dest: &mut W) -> /// selector : simple_selector_sequence [ combinator simple_selector_sequence ]* ; /// /// `Err` means invalid selector. -fn parse_selector<'i, 't, P, E, Impl>( +fn parse_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>) - -> Result, ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let mut builder = SelectorBuilder::default(); - let mut parsed_pseudo_element; + let mut has_pseudo_element; 'outer_loop: loop { // Parse a sequence of simple selectors. - parsed_pseudo_element = match parse_compound_selector(parser, input, &mut builder) { - Ok(result) => result, - Err(ParseError::Custom(SelectorParseError::EmptySelector)) if builder.has_combinators() => - return Err(SelectorParseError::DanglingCombinator.into()), - Err(e) => return Err(e), + has_pseudo_element = match parse_compound_selector(parser, input, &mut builder)? { + Some(has_pseudo_element) => has_pseudo_element, + None => { + return Err(input.new_custom_error(if builder.has_combinators() { + SelectorParseErrorKind::DanglingCombinator + } else { + SelectorParseErrorKind::EmptySelector + })) + } }; - if parsed_pseudo_element { + if has_pseudo_element { break; } @@ -1107,18 +1108,18 @@ fn parse_selector<'i, 't, P, E, Impl>( builder.push_combinator(combinator); } - Ok(Selector(builder.build(parsed_pseudo_element))) + Ok(Selector(builder.build(has_pseudo_element))) } impl Selector { /// Parse a selector, without any pseudo-element. - pub fn parse<'i, 't, P, E>(parser: &P, input: &mut CssParser<'i, 't>) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E> + pub fn parse<'i, 't, P>(parser: &P, input: &mut CssParser<'i, 't>) + -> Result> + where P: Parser<'i, Impl=Impl> { let selector = parse_selector(parser, input)?; if selector.has_pseudo_element() { - return Err(ParseError::Custom(SelectorParseError::PseudoElementInComplexSelector)) + return Err(input.new_custom_error(SelectorParseErrorKind::PseudoElementInComplexSelector)) } Ok(selector) } @@ -1127,14 +1128,14 @@ impl Selector { /// * `Err(())`: Invalid selector, abort /// * `Ok(false)`: Not a type selector, could be something else. `input` was not consumed. /// * `Ok(true)`: Length 0 (`*|*`), 1 (`*|E` or `ns|*`) or 2 (`|E` or `ns|E`) -fn parse_type_selector<'i, 't, P, E, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E>, +fn parse_type_selector<'i, 't, P, Impl, S>(parser: &P, input: &mut CssParser<'i, 't>, sink: &mut S) + -> Result> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl, S: Push>, { match parse_qualified_name(parser, input, /* in_attr_selector = */ false) { - Err(ParseError::Basic(BasicParseError::EndOfInput)) | + Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) | Ok(OptionalQName::None(_)) => Ok(false), Ok(OptionalQName::Some(namespace, local_name)) => { match namespace { @@ -1214,12 +1215,11 @@ enum OptionalQName<'i, Impl: SelectorImpl> { /// * `Ok(None(token))`: Not a simple selector, could be something else. `input` was not consumed, /// but the token is still returned. /// * `Ok(Some(namespace, local_name))`: `None` for the local name means a `*` universal selector -fn parse_qualified_name<'i, 't, P, E, Impl> +fn parse_qualified_name<'i, 't, P, Impl> (parser: &P, input: &mut CssParser<'i, 't>, in_attr_selector: bool) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let default_namespace = |local_name| { let namespace = match parser.default_namespace() { @@ -1230,16 +1230,25 @@ fn parse_qualified_name<'i, 't, P, E, Impl> }; let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| { + let location = input.current_source_location(); match input.next_including_whitespace() { Ok(&Token::Delim('*')) if !in_attr_selector => { Ok(OptionalQName::Some(namespace, None)) - }, + } Ok(&Token::Ident(ref local_name)) => { Ok(OptionalQName::Some(namespace, Some(local_name.clone()))) - }, - Ok(t) if in_attr_selector => Err(SelectorParseError::InvalidQualNameInAttr(t.clone()).into()), - Ok(t) => Err(SelectorParseError::ExplicitNamespaceUnexpectedToken(t.clone()).into()), - Err(e) => Err(ParseError::Basic(e)), + } + Ok(t) if in_attr_selector => { + Err(location.new_custom_error( + SelectorParseErrorKind::InvalidQualNameInAttr(t.clone()) + )) + } + Ok(t) => { + Err(location.new_custom_error( + SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t.clone()) + )) + } + Err(e) => Err(e.into()), } }; @@ -1252,8 +1261,8 @@ fn parse_qualified_name<'i, 't, P, E, Impl> Ok(&Token::Delim('|')) => { let prefix = value.as_ref().into(); let result = parser.namespace_for_prefix(&prefix); - let url = result.ok_or(ParseError::Custom( - SelectorParseError::ExpectedNamespace(value)))?; + let url = result.ok_or(after_ident.source_location().new_custom_error( + SelectorParseErrorKind::ExpectedNamespace(value)))?; explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url)) }, _ => { @@ -1277,8 +1286,10 @@ fn parse_qualified_name<'i, 't, P, E, Impl> input.reset(&after_star); if in_attr_selector { match result { - Ok(t) => Err(SelectorParseError::ExpectedBarInAttr(t).into()), - Err(e) => Err(ParseError::Basic(e)), + Ok(t) => Err(after_star.source_location().new_custom_error( + SelectorParseErrorKind::ExpectedBarInAttr(t) + )), + Err(e) => Err(e.into()), } } else { default_namespace(None) @@ -1301,16 +1312,18 @@ fn parse_qualified_name<'i, 't, P, E, Impl> } -fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParser<'i, 't>) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_attribute_selector<'i, 't, P, Impl>(parser: &P, input: &mut CssParser<'i, 't>) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let namespace; let local_name; match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? { - OptionalQName::None(t) => - return Err(ParseError::Custom(SelectorParseError::NoQualifiedNameInAttributeSelector(t))), + OptionalQName::None(t) => { + return Err(input.new_custom_error( + SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t) + )) + } OptionalQName::Some(_, None) => unreachable!(), OptionalQName::Some(ns, Some(ln)) => { local_name = ln; @@ -1333,6 +1346,7 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse } } + let location = input.current_source_location(); let operator = match input.next() { // [foo] Err(_) => { @@ -1366,13 +1380,16 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring, // [foo$=bar] Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix, - Ok(t) => return Err(SelectorParseError::UnexpectedTokenInAttributeSelector(t.clone()).into()) + Ok(t) => return Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone()) + )) }; let value = match input.expect_ident_or_string() { Ok(t) => t.clone(), - Err(BasicParseError::UnexpectedToken(t)) => - return Err(SelectorParseError::BadValueInAttr(t.clone()).into()), + Err(BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location }) => { + return Err(location.new_custom_error(SelectorParseErrorKind::BadValueInAttr(t))) + } Err(e) => return Err(e.into()), }; let never_matches = match operator { @@ -1431,9 +1448,10 @@ fn parse_attribute_selector<'i, 't, P, E, Impl>(parser: &P, input: &mut CssParse } -fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>) - -> Result>> { +fn parse_attribute_flags<'i, 't>(input: &mut CssParser<'i, 't>) + -> Result> +{ + let location = input.current_source_location(); match input.next() { Err(_) => { // Selectors spec says language-defined, but HTML says sensitive. @@ -1442,18 +1460,17 @@ fn parse_attribute_flags<'i, 't, E>(input: &mut CssParser<'i, 't>) Ok(&Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => { Ok(ParsedCaseSensitivity::AsciiCaseInsensitive) } - Ok(t) => Err(ParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))) + Ok(t) => Err(location.new_basic_unexpected_token_error(t.clone())) } } /// Level 3: Parse **one** simple_selector. (Though we might insert a second /// implied "|*" type selector.) -fn parse_negation<'i, 't, P, E, Impl>(parser: &P, - input: &mut CssParser<'i, 't>) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_negation<'i, 't, P, Impl>(parser: &P, + input: &mut CssParser<'i, 't>) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { // We use a sequence because a type selector may be represented as two Components. let mut sequence = SmallVec::<[Component; 2]>::new(); @@ -1464,8 +1481,9 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, // that there are no trailing tokens after we're done. let is_type_sel = match parse_type_selector(parser, input, &mut sequence) { Ok(result) => result, - Err(ParseError::Basic(BasicParseError::EndOfInput)) => - return Err(SelectorParseError::EmptyNegation.into()), + Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) => { + return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation)) + } Err(e) => return Err(e.into()), }; if !is_type_sel { @@ -1474,10 +1492,10 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, sequence.push(s); }, None => { - return Err(ParseError::Custom(SelectorParseError::EmptyNegation)); + return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation)); }, Some(SimpleSelectorParseResult::PseudoElement(_)) => { - return Err(ParseError::Custom(SelectorParseError::NonSimpleSelectorInNegation)); + return Err(input.new_custom_error(SelectorParseErrorKind::NonSimpleSelectorInNegation)); } } } @@ -1491,14 +1509,15 @@ fn parse_negation<'i, 't, P, E, Impl>(parser: &P, /// | [ HASH | class | attrib | pseudo | negation ]+ /// /// `Err(())` means invalid selector. +/// `Ok(None)` is an empty selector /// /// The boolean represent whether a pseudo-element has been parsed. -fn parse_compound_selector<'i, 't, P, E, Impl>( +fn parse_compound_selector<'i, 't, P, Impl>( parser: &P, input: &mut CssParser<'i, 't>, builder: &mut SelectorBuilder) - -> Result>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { input.skip_whitespace(); @@ -1528,24 +1547,32 @@ fn parse_compound_selector<'i, 't, P, E, Impl>( let mut state_selectors = SmallVec::<[Component; 3]>::new(); loop { + let location = input.current_source_location(); match input.next_including_whitespace() { Ok(&Token::Colon) => {}, Ok(&Token::WhiteSpace(_)) | Err(_) => break, Ok(t) => - return Err(SelectorParseError::PseudoElementExpectedColon(t.clone()).into()), + return Err(location.new_custom_error( + SelectorParseErrorKind::PseudoElementExpectedColon(t.clone()) + )), } + let location = input.current_source_location(); // TODO(emilio): Functional pseudo-classes too? // We don't need it for now. let name = match input.next_including_whitespace()? { &Token::Ident(ref name) => name.clone(), - t => return Err(SelectorParseError::NoIdentForPseudo(t.clone()).into()), + t => return Err(location.new_custom_error( + SelectorParseErrorKind::NoIdentForPseudo(t.clone()) + )), }; let pseudo_class = - P::parse_non_ts_pseudo_class(parser, name.clone())?; + P::parse_non_ts_pseudo_class(parser, location, name.clone())?; if !p.supports_pseudo_class(&pseudo_class) { - return Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into()); + return Err(input.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name) + )); } state_selectors.push(Component::NonTSPseudoClass(pseudo_class)); } @@ -1567,28 +1594,29 @@ fn parse_compound_selector<'i, 't, P, E, Impl>( } if empty { // An empty selector is invalid. - Err(ParseError::Custom(SelectorParseError::EmptySelector)) + Ok(None) } else { - Ok(pseudo) + Ok(Some(pseudo)) } } -fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P, - input: &mut CssParser<'i, 't>, - name: CowRcStr<'i>, - inside_negation: bool) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_functional_pseudo_class<'i, 't, P, Impl>(parser: &P, + input: &mut CssParser<'i, 't>, + name: CowRcStr<'i>, + inside_negation: bool) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { match_ignore_ascii_case! { &name, - "nth-child" => return parse_nth_pseudo_class(input, Component::NthChild), - "nth-of-type" => return parse_nth_pseudo_class(input, Component::NthOfType), - "nth-last-child" => return parse_nth_pseudo_class(input, Component::NthLastChild), - "nth-last-of-type" => return parse_nth_pseudo_class(input, Component::NthLastOfType), + "nth-child" => return Ok(parse_nth_pseudo_class(input, Component::NthChild)?), + "nth-of-type" => return Ok(parse_nth_pseudo_class(input, Component::NthOfType)?), + "nth-last-child" => return Ok(parse_nth_pseudo_class(input, Component::NthLastChild)?), + "nth-last-of-type" => return Ok(parse_nth_pseudo_class(input, Component::NthLastOfType)?), "not" => { if inside_negation { - return Err(ParseError::Custom(SelectorParseError::UnexpectedIdent("not".into()))); + return Err(input.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent("not".into()) + )); } return parse_negation(parser, input) }, @@ -1599,9 +1627,8 @@ fn parse_functional_pseudo_class<'i, 't, P, E, Impl>(parser: &P, } -fn parse_nth_pseudo_class<'i, 't, Impl, F, E>(input: &mut CssParser<'i, 't>, selector: F) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> +fn parse_nth_pseudo_class<'i, 't, Impl, F>(input: &mut CssParser<'i, 't>, selector: F) + -> Result, BasicParseError<'i>> where Impl: SelectorImpl, F: FnOnce(i32, i32) -> Component { let (a, b) = parse_nth(input)?; Ok(selector(a, b)) @@ -1624,12 +1651,12 @@ pub fn is_css2_pseudo_element<'i>(name: &CowRcStr<'i>) -> bool { /// * `Err(())`: Invalid selector, abort /// * `Ok(None)`: Not a simple selector, could be something else. `input` was not consumed. /// * `Ok(Some(_))`: Parsed a simple selector or pseudo-element -fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, - input: &mut CssParser<'i, 't>, - inside_negation: bool) - -> Result>, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_one_simple_selector<'i, 't, P, Impl>(parser: &P, + input: &mut CssParser<'i, 't>, + inside_negation: bool) + -> Result>, + ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { let start = input.state(); // FIXME: remove clone() when lifetimes are non-lexical @@ -1639,12 +1666,15 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, Ok(Some(SimpleSelectorParseResult::SimpleSelector(id))) } Ok(Token::Delim('.')) => { + let location = input.current_source_location(); match *input.next_including_whitespace()? { Token::Ident(ref class) => { let class = Component::Class(class.as_ref().into()); Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) } - ref t => Err(SelectorParseError::ClassNeedsIdent(t.clone()).into()), + ref t => Err(location.new_custom_error( + SelectorParseErrorKind::ClassNeedsIdent(t.clone()) + )), } } Ok(Token::SquareBracketBlock) => { @@ -1652,6 +1682,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr))) } Ok(Token::Colon) => { + let location = input.current_source_location(); let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() { Token::Colon => (false, input.next_including_whitespace()?.clone()), t => (true, t), @@ -1659,7 +1690,9 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, let (name, is_functional) = match next_token { Token::Ident(name) => (name, false), Token::Function(name) => (name, true), - t => return Err(SelectorParseError::PseudoElementExpectedIdent(t).into()), + t => return Err(input.new_custom_error( + SelectorParseErrorKind::PseudoElementExpectedIdent(t) + )), }; let is_pseudo_element = !is_single_colon || P::is_pseudo_element_allows_single_colon(&name); @@ -1669,7 +1702,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, P::parse_functional_pseudo_element(parser, name, input) })? } else { - P::parse_pseudo_element(parser, name)? + P::parse_pseudo_element(parser, location, name)? }; Ok(Some(SimpleSelectorParseResult::PseudoElement(pseudo_element))) } else { @@ -1678,7 +1711,7 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, parse_functional_pseudo_class(parser, input, name, inside_negation) })? } else { - parse_simple_pseudo_class(parser, name)? + parse_simple_pseudo_class(parser, location, name)? }; Ok(Some(SimpleSelectorParseResult::SimpleSelector(pseudo_class))) } @@ -1690,10 +1723,10 @@ fn parse_one_simple_selector<'i, 't, P, E, Impl>(parser: &P, } } -fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>) - -> Result, - ParseError<'i, SelectorParseError<'i, E>>> - where P: Parser<'i, Impl=Impl, Error=E>, Impl: SelectorImpl +fn parse_simple_pseudo_class<'i, P, Impl>(parser: &P, location: SourceLocation, + name: CowRcStr<'i>) + -> Result, ParseError<'i, P::Error>> + where P: Parser<'i, Impl=Impl>, Impl: SelectorImpl { (match_ignore_ascii_case! { &name, "first-child" => Ok(Component::FirstChild), @@ -1707,7 +1740,7 @@ fn parse_simple_pseudo_class<'i, P, E, Impl>(parser: &P, name: CowRcStr<'i>) "only-of-type" => Ok(Component::OnlyOfType), _ => Err(()) }).or_else(|()| { - P::parse_non_ts_pseudo_class(parser, name) + P::parse_non_ts_pseudo_class(parser, location, name) .map(Component::NonTSPseudoClass) }) } @@ -1843,36 +1876,37 @@ pub mod tests { impl<'i> Parser<'i> for DummyParser { type Impl = DummySelectorImpl; - type Error = (); + type Error = SelectorParseErrorKind<'i>; - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) - -> Result>> { + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) + -> Result> { match_ignore_ascii_case! { &name, - "hover" => Ok(PseudoClass::Hover), - "active" => Ok(PseudoClass::Active), - _ => Err(SelectorParseError::Custom(()).into()) + "hover" => return Ok(PseudoClass::Hover), + "active" => return Ok(PseudoClass::Active), + _ => {} } + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn parse_non_ts_functional_pseudo_class<'t>(&self, name: CowRcStr<'i>, parser: &mut CssParser<'i, 't>) - -> Result>> { + -> Result> { match_ignore_ascii_case! { &name, - "lang" => Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.as_ref().to_owned())), - _ => Err(SelectorParseError::Custom(()).into()) + "lang" => return Ok(PseudoClass::Lang(parser.expect_ident_or_string()?.as_ref().to_owned())), + _ => {} } + Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result>> { + SelectorParseError<'i>> { match_ignore_ascii_case! { &name, - "before" => Ok(PseudoElement::Before), - "after" => Ok(PseudoElement::After), - _ => Err(SelectorParseError::Custom(()).into()) + "before" => return Ok(PseudoElement::Before), + "after" => return Ok(PseudoElement::After), + _ => {} } + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } fn default_namespace(&self) -> Option { @@ -1885,17 +1919,17 @@ pub mod tests { } fn parse<'i>(input: &'i str) - -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + -> Result, SelectorParseError<'i>> { parse_ns(input, &DummyParser::default()) } fn parse_expected<'i, 'a>(input: &'i str, expected: Option<&'a str>) - -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + -> Result, SelectorParseError<'i>> { parse_ns_expected(input, &DummyParser::default(), expected) } fn parse_ns<'i>(input: &'i str, parser: &DummyParser) - -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + -> Result, SelectorParseError<'i>> { parse_ns_expected(input, parser, None) } @@ -1903,7 +1937,7 @@ pub mod tests { input: &'i str, parser: &DummyParser, expected: Option<&'a str> - ) -> Result, ParseError<'i, SelectorParseError<'i, ()>>> { + ) -> Result, SelectorParseError<'i>> { let mut parser_input = ParserInput::new(input); let result = SelectorList::parse(parser, &mut CssParser::new(&mut parser_input)); if let Ok(ref selectors) = result { diff --git a/servo/components/style/Cargo.toml b/servo/components/style/Cargo.toml index 786373c399fd..23130d091289 100644 --- a/servo/components/style/Cargo.toml +++ b/servo/components/style/Cargo.toml @@ -36,7 +36,7 @@ atomic_refcell = "0.1" bitflags = "0.7" byteorder = "1.0" cfg-if = "0.1.0" -cssparser = "0.21.2" +cssparser = "0.22.0" encoding = {version = "0.2", optional = true} euclid = "0.15" fallible = { path = "../fallible" } diff --git a/servo/components/style/counter_style/mod.rs b/servo/components/style/counter_style/mod.rs index cb0a9f3d8c76..60e865f7ea8d 100644 --- a/servo/components/style/counter_style/mod.rs +++ b/servo/components/style/counter_style/mod.rs @@ -8,18 +8,18 @@ use Atom; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser}; -use cssparser::{Parser, Token, serialize_identifier, BasicParseError, CowRcStr}; +use cssparser::{Parser, Token, serialize_identifier, CowRcStr}; use error_reporting::{ContextualParseError, ParseErrorReporter}; #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors; #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc; use parser::{ParserContext, ParserErrorContext, Parse}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::ascii::AsciiExt; use std::borrow::Cow; use std::fmt; use std::ops::Range; -use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; +use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss}; use values::CustomIdent; /// Parse the prelude of an @counter-style rule @@ -36,12 +36,13 @@ pub fn parse_counter_style_name<'i, 't>(input: &mut Parser<'i, 't>) -> Result(name: CustomIdent, }; let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { - if let Err(err) = declaration { - let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(err.slice, err.error); - context.log_css_error(error_context, err.location, error) + if let Err((error, slice)) = declaration { + let location = error.location; + let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(slice, error); + context.log_css_error(error_context, location, error) } } } @@ -101,7 +103,7 @@ pub fn parse_counter_style_body<'i, 't, R>(name: CustomIdent, }; if let Some(error) = error { context.log_css_error(error_context, start, error); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(rule) } @@ -117,7 +119,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for CounterStyleRuleParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } macro_rules! accessor { @@ -186,7 +188,7 @@ macro_rules! counter_style_descriptors { impl<'a, 'b, 'i> DeclarationParser<'i> for CounterStyleRuleParser<'a, 'b> { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { @@ -201,7 +203,7 @@ macro_rules! counter_style_descriptors { self.rule.$ident = Some(value) } )* - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } Ok(()) } @@ -299,7 +301,7 @@ pub enum System { impl Parse for System { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident_cloned()?, + try_match_ident_ignore_ascii_case! { input, "cyclic" => Ok(System::Cyclic), "numeric" => Ok(System::Numeric), "alphabetic" => Ok(System::Alphabetic), @@ -356,10 +358,11 @@ pub enum Symbol { impl Parse for Symbol { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match input.next() { Ok(&Token::QuotedString(ref s)) => Ok(Symbol::String(s.as_ref().to_owned())), Ok(&Token::Ident(ref s)) => Ok(Symbol::Ident(s.as_ref().to_owned())), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } } @@ -414,7 +417,7 @@ impl Parse for Ranges { let opt_end = parse_bound(input)?; if let (Some(start), Some(end)) = (opt_start, opt_end) { if start > end { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } Ok(opt_start..opt_end) @@ -424,10 +427,11 @@ impl Parse for Ranges { } fn parse_bound<'i, 't>(input: &mut Parser<'i, 't>) -> Result, ParseError<'i>> { + let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(v), .. }) => Ok(Some(v)), Ok(&Token::Ident(ref ident)) if ident.eq_ignore_ascii_case("infinite") => Ok(None), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } } @@ -472,7 +476,7 @@ impl Parse for Pad { let pad_with = input.try(|input| Symbol::parse(context, input)); let min_length = input.expect_integer()?; if min_length < 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let pad_with = pad_with.or_else(|_| Symbol::parse(context, input))?; Ok(Pad(min_length as u32, pad_with)) @@ -502,7 +506,7 @@ impl Parse for Symbols { symbols.push(s) } else { if symbols.is_empty() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { return Ok(Symbols(symbols)) } @@ -533,7 +537,7 @@ impl Parse for AdditiveSymbols { let tuples = Vec::::parse(context, input)?; // FIXME maybe? https://github.com/w3c/csswg-drafts/issues/1220 if tuples.windows(2).any(|window| window[0].weight <= window[1].weight) { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(AdditiveSymbols(tuples)) } @@ -557,7 +561,7 @@ impl Parse for AdditiveTuple { let symbol = input.try(|input| Symbol::parse(context, input)); let weight = input.expect_integer()?; if weight < 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let symbol = symbol.or_else(|_| Symbol::parse(context, input))?; Ok(AdditiveTuple { @@ -604,7 +608,7 @@ impl Parse for SpeakAs { if is_spell_out { // spell-out is not supported, but don’t parse it as a . // See bug 1024178. - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } result.or_else(|_| { Ok(SpeakAs::Other(parse_counter_style_name(input)?)) diff --git a/servo/components/style/custom_properties.rs b/servo/components/style/custom_properties.rs index ca9e41949700..86dd60631141 100644 --- a/servo/components/style/custom_properties.rs +++ b/servo/components/style/custom_properties.rs @@ -11,14 +11,14 @@ use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSeri use precomputed_hash::PrecomputedHash; use properties::{CSSWideKeyword, DeclaredValue}; use selector_map::{PrecomputedHashSet, PrecomputedHashMap, PrecomputedDiagnosticHashMap}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; use smallvec::SmallVec; use std::ascii::AsciiExt; use std::borrow::{Borrow, Cow}; use std::fmt; use std::hash::Hash; -use style_traits::{ToCss, StyleParseError, ParseError}; +use style_traits::{ToCss, StyleParseErrorKind, ParseError}; /// A custom property name is just an `Atom`. /// @@ -357,16 +357,27 @@ fn parse_declaration_value_block<'i, 't>( } token.serialization_type() } - Token::BadUrl(u) => - return Err(StyleParseError::BadUrlInDeclarationValueBlock(u).into()), - Token::BadString(s) => - return Err(StyleParseError::BadStringInDeclarationValueBlock(s).into()), - Token::CloseParenthesis => - return Err(StyleParseError::UnbalancedCloseParenthesisInDeclarationValueBlock.into()), - Token::CloseSquareBracket => - return Err(StyleParseError::UnbalancedCloseSquareBracketInDeclarationValueBlock.into()), - Token::CloseCurlyBracket => - return Err(StyleParseError::UnbalancedCloseCurlyBracketInDeclarationValueBlock.into()), + Token::BadUrl(u) => { + return Err(input.new_custom_error(StyleParseErrorKind::BadUrlInDeclarationValueBlock(u))) + } + Token::BadString(s) => { + return Err(input.new_custom_error(StyleParseErrorKind::BadStringInDeclarationValueBlock(s))) + } + Token::CloseParenthesis => { + return Err(input.new_custom_error( + StyleParseErrorKind::UnbalancedCloseParenthesisInDeclarationValueBlock + )) + } + Token::CloseSquareBracket => { + return Err(input.new_custom_error( + StyleParseErrorKind::UnbalancedCloseSquareBracketInDeclarationValueBlock + )) + } + Token::CloseCurlyBracket => { + return Err(input.new_custom_error( + StyleParseErrorKind::UnbalancedCloseCurlyBracketInDeclarationValueBlock + )) + } Token::Function(ref name) => { if name.eq_ignore_ascii_case("var") { let args_start = input.state(); @@ -446,7 +457,7 @@ fn parse_var_function<'i, 't>( let name = input.expect_ident_cloned()?; let name: Result<_, ParseError> = parse_name(&name) - .map_err(|()| SelectorParseError::UnexpectedIdent(name.clone()).into()); + .map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))); let name = name?; if input.try(|input| input.expect_comma()).is_ok() { // Exclude `!` and `;` at the top level diff --git a/servo/components/style/error_reporting.rs b/servo/components/style/error_reporting.rs index 718306323a30..19e89e2338f5 100644 --- a/servo/components/style/error_reporting.rs +++ b/servo/components/style/error_reporting.rs @@ -6,8 +6,7 @@ #![deny(missing_docs)] -use cssparser::{BasicParseError, Token, SourceLocation}; -use cssparser::ParseError as CssParseError; +use cssparser::{Token, SourceLocation, ParseErrorKind, BasicParseErrorKind}; use log; use std::fmt; use style_traits::ParseError; @@ -91,24 +90,24 @@ impl<'a> fmt::Display for ContextualParseError<'a> { } fn parse_error_to_str(err: &ParseError, f: &mut fmt::Formatter) -> fmt::Result { - match *err { - CssParseError::Basic(BasicParseError::UnexpectedToken(ref t)) => { + match err.kind { + ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(ref t)) => { write!(f, "found unexpected ")?; token_to_str(t, f) } - CssParseError::Basic(BasicParseError::EndOfInput) => { + ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput) => { write!(f, "unexpected end of input") } - CssParseError::Basic(BasicParseError::AtRuleInvalid(ref i)) => { + ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(ref i)) => { write!(f, "@ rule invalid: {}", i) } - CssParseError::Basic(BasicParseError::AtRuleBodyInvalid) => { + ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid) => { write!(f, "@ rule invalid") } - CssParseError::Basic(BasicParseError::QualifiedRuleInvalid) => { + ParseErrorKind::Basic(BasicParseErrorKind::QualifiedRuleInvalid) => { write!(f, "qualified rule invalid") } - CssParseError::Custom(ref err) => { + ParseErrorKind::Custom(ref err) => { write!(f, "{:?}", err) } } diff --git a/servo/components/style/font_face.rs b/servo/components/style/font_face.rs index 30eb242a6d4f..fec122d344c1 100644 --- a/servo/components/style/font_face.rs +++ b/servo/components/style/font_face.rs @@ -19,10 +19,10 @@ use error_reporting::{ContextualParseError, ParseErrorReporter}; use parser::{ParserContext, ParserErrorContext, Parse}; #[cfg(feature = "gecko")] use properties::longhands::font_language_override; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; +use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss}; use values::specified::url::SpecifiedUrl; /// A source for a font-face rule. @@ -100,7 +100,7 @@ impl Parse for FontWeight { result.or_else(|_| { font_weight::T::from_int(input.expect_integer()?) .map(FontWeight::Weight) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) }) } } @@ -123,9 +123,10 @@ pub fn parse_font_face_block(context: &ParserContext, }; let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { - if let Err(err) = declaration { - let error = ContextualParseError::UnsupportedFontFaceDescriptor(err.slice, err.error); - context.log_css_error(error_context, err.location, error) + if let Err((error, slice)) = declaration { + let location = error.location; + let error = ContextualParseError::UnsupportedFontFaceDescriptor(slice, error); + context.log_css_error(error_context, location, error) } } } @@ -186,7 +187,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for FontFaceRuleParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl Parse for Source { @@ -287,7 +288,7 @@ macro_rules! font_face_descriptors_common { impl<'a, 'b, 'i> DeclarationParser<'i> for FontFaceRuleParser<'a, 'b> { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { @@ -302,7 +303,7 @@ macro_rules! font_face_descriptors_common { self.rule.$ident = Some(value) } )* - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } Ok(()) } diff --git a/servo/components/style/gecko/media_queries.rs b/servo/components/style/gecko/media_queries.rs index e0be4e7423f9..be42ecd120c6 100644 --- a/servo/components/style/gecko/media_queries.rs +++ b/servo/components/style/gecko/media_queries.rs @@ -7,7 +7,7 @@ use app_units::AU_PER_PX; use app_units::Au; use context::QuirksMode; -use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseError}; +use cssparser::{CssStringWriter, Parser, RGBA, Token, BasicParseErrorKind}; use euclid::ScaleFactor; use euclid::Size2D; use font_metrics::get_metrics_provider_for_product; @@ -30,7 +30,7 @@ use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering}; use str::starts_with_ignore_ascii_case; use string_cache::Atom; use style_traits::{CSSPixel, DevicePixel}; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::viewport::ViewportConstraints; use stylesheets::Origin; use values::{CSSFloat, CustomIdent, serialize_dimension}; @@ -285,15 +285,16 @@ impl Resolution { } fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let (value, unit) = match *input.next()? { Token::Dimension { value, ref unit, .. } => { (value, unit) }, - ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => return Err(location.new_unexpected_token_error(t.clone())), }; if value <= 0. { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (match_ignore_ascii_case! { &unit, @@ -301,7 +302,7 @@ impl Resolution { "dppx" => Ok(Resolution::Dppx(value)), "dpcm" => Ok(Resolution::Dpcm(value)), _ => Err(()) - }).map_err(|()| StyleParseError::UnexpectedDimension(unit.clone()).into()) + }).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedDimension(unit.clone()))) } } @@ -498,7 +499,7 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, // for parity with gecko. We should remove this check when we want // to support it. if let Length::Calc(_) = length { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::Length(length) }, @@ -508,14 +509,14 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, // supported in media queries per FIXME above. let i = input.expect_integer()?; if i < 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::Integer(i as u32) } nsMediaFeature_ValueType::eBoolInteger => { let i = input.expect_integer()?; if i < 0 || i > 1 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::BoolInteger(i == 1) } @@ -525,14 +526,14 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, nsMediaFeature_ValueType::eIntRatio => { let a = input.expect_integer()?; if a <= 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } input.expect_delim('/')?; let b = input.expect_integer()?; if b <= 0 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } MediaExpressionValue::IntRatio(a as u32, b as u32) } @@ -540,28 +541,26 @@ fn parse_feature_value<'i, 't>(feature: &nsMediaFeature, MediaExpressionValue::Resolution(Resolution::parse(input)?) } nsMediaFeature_ValueType::eEnumerated => { - let keyword = input.expect_ident()?; - let keyword = unsafe { - bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(), - keyword.len() as u32) - }; + let location = input.current_source_location(); + let keyword = input.expect_ident()?; + let keyword = unsafe { + bindings::Gecko_LookupCSSKeyword(keyword.as_bytes().as_ptr(), + keyword.len() as u32) + }; - let first_table_entry: *const nsCSSProps_KTableEntry = unsafe { - *feature.mData.mKeywordTable.as_ref() - }; + let first_table_entry: *const nsCSSProps_KTableEntry = unsafe { + *feature.mData.mKeywordTable.as_ref() + }; - let value = - match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } { - Some((_kw, value)) => { - value - } - None => return Err(StyleParseError::UnspecifiedError.into()), - }; + let value = match unsafe { find_in_table(first_table_entry, |kw, _| kw == keyword) } { + Some((_kw, value)) => value, + None => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)), + }; - MediaExpressionValue::Enumerated(value) + MediaExpressionValue::Enumerated(value) } nsMediaFeature_ValueType::eIdent => { - MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned()) + MediaExpressionValue::Ident(input.expect_ident()?.as_ref().to_owned()) } }; @@ -590,10 +589,10 @@ impl Expression { input: &mut Parser<'i, 't>, ) -> Result> { input.expect_parenthesis_block().map_err(|err| - match err { - BasicParseError::UnexpectedToken(t) => StyleParseError::ExpectedIdentifier(t), - _ => StyleParseError::UnspecifiedError, - } + err.location.new_custom_error(match err.kind { + BasicParseErrorKind::UnexpectedToken(t) => StyleParseErrorKind::ExpectedIdentifier(t), + _ => StyleParseErrorKind::UnspecifiedError, + }) )?; input.parse_nested_block(|input| { @@ -601,11 +600,12 @@ impl Expression { let feature; let range; { + let location = input.current_source_location(); let ident = input.expect_ident().map_err(|err| - match err { - BasicParseError::UnexpectedToken(t) => StyleParseError::ExpectedIdentifier(t), - _ => StyleParseError::UnspecifiedError, - } + err.location.new_custom_error(match err.kind { + BasicParseErrorKind::UnexpectedToken(t) => StyleParseErrorKind::ExpectedIdentifier(t), + _ => StyleParseErrorKind::UnspecifiedError, + }) )?; let mut flags = 0; @@ -648,19 +648,25 @@ impl Expression { Ok((f, r)) => { feature = f; range = r; - }, + } Err(()) => { - return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into()) - }, + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()) + )) + } } if (feature.mReqFlags & !flags) != 0 { - return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into()); + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()) + )) } if range != nsMediaExpression_Range::eEqual && feature.mRangeType != nsMediaFeature_RangeType::eMinMaxAllowed { - return Err(StyleParseError::MediaQueryExpectedFeatureName(ident.clone()).into()); + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()) + )) } } @@ -671,15 +677,15 @@ impl Expression { // reject them here too. if input.try(|i| i.expect_colon()).is_err() { if range != nsMediaExpression_Range::eEqual { - return Err(StyleParseError::RangedExpressionWithNoValue.into()) + return Err(input.new_custom_error(StyleParseErrorKind::RangedExpressionWithNoValue)) } return Ok(Expression::new(feature, None, range)); } let value = parse_feature_value(feature, feature.mValueType, - context, input).map_err(|_| - StyleParseError::MediaQueryExpectedFeatureValue + context, input).map_err(|err| + err.location.new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue) )?; Ok(Expression::new(feature, Some(value), range)) diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs index 56a49f4743a9..e9464b657b19 100644 --- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -4,18 +4,18 @@ //! Gecko-specific bits for selector-parsing. -use cssparser::{BasicParseError, Parser, ToCss, Token, CowRcStr}; +use cssparser::{BasicParseError, BasicParseErrorKind, Parser, ToCss, Token, CowRcStr, SourceLocation}; use element_state::ElementState; use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::RawServoSelectorList; use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use selector_parser::{SelectorParser, PseudoElementCascadeType}; use selectors::SelectorList; -use selectors::parser::{Selector, SelectorMethods, SelectorParseError}; +use selectors::parser::{Selector, SelectorMethods, SelectorParseErrorKind}; use selectors::visitor::SelectorVisitor; use std::fmt; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; -use style_traits::{ParseError, StyleParseError}; +use style_traits::{ParseError, StyleParseErrorKind}; pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, SIMPLE_PSEUDO_COUNT}; pub use gecko::snapshot::SnapshotMap; @@ -298,14 +298,14 @@ impl<'a> SelectorParser<'a> { impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { type Impl = SelectorImpl; - type Error = StyleParseError<'i>; + type Error = StyleParseErrorKind<'i>; fn is_pseudo_element_allows_single_colon(name: &CowRcStr<'i>) -> bool { ::selectors::parser::is_css2_pseudo_element(name) || name.starts_with("-moz-tree-") // tree pseudo-elements } - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result> { macro_rules! pseudo_class_parse { (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], @@ -313,8 +313,9 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { keyword: [$(($k_css:expr, $k_name:ident, $k_gecko_type:tt, $k_state:tt, $k_flags:tt),)*]) => { match_ignore_ascii_case! { &name, $($css => NonTSPseudoClass::$name,)* - _ => return Err(::selectors::parser::SelectorParseError::UnsupportedPseudoClassOrElement( - name.clone()).into()) + _ => return Err(location.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()) + )) } } } @@ -322,7 +323,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { if self.is_pseudo_class_enabled(&pseudo_class) { Ok(pseudo_class) } else { - Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into()) + Err(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } } @@ -355,11 +356,15 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { })?; // Selectors inside `:-moz-any` may not include combinators. if selectors.iter().flat_map(|x| x.iter_raw_match_order()).any(|s| s.is_combinator()) { - return Err(SelectorParseError::UnexpectedIdent("-moz-any".into()).into()) + return Err(parser.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent("-moz-any".into()) + )) } NonTSPseudoClass::MozAny(selectors.into_boxed_slice()) } - _ => return Err(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into()) + _ => return Err(parser.new_custom_error( + SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()) + )) } } } @@ -367,13 +372,14 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { if self.is_pseudo_class_enabled(&pseudo_class) { Ok(pseudo_class) } else { - Err(SelectorParseError::UnsupportedPseudoClassOrElement(name).into()) + Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name))) } } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result> { + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) + -> Result> { PseudoElement::from_slice(&name, self.in_user_agent_stylesheet()) - .ok_or(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into()) + .ok_or(location.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()))) } fn parse_functional_pseudo_element<'t>(&self, name: CowRcStr<'i>, @@ -384,11 +390,12 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { // separated by either comma or space. let mut args = Vec::new(); loop { + let location = parser.current_source_location(); match parser.next() { Ok(&Token::Ident(ref ident)) => args.push(ident.as_ref().to_owned()), Ok(&Token::Comma) => {}, - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), - Err(BasicParseError::EndOfInput) => break, + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), + Err(BasicParseError { kind: BasicParseErrorKind::EndOfInput, .. }) => break, _ => unreachable!("Parser::next() shouldn't return any other error"), } } @@ -397,7 +404,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { return Ok(pseudo); } } - Err(SelectorParseError::UnsupportedPseudoClassOrElement(name.clone()).into()) + Err(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone()))) } fn default_namespace(&self) -> Option { diff --git a/servo/components/style/macros.rs b/servo/components/style/macros.rs index 7a5d8ba9abfe..a93f7f545e44 100644 --- a/servo/components/style/macros.rs +++ b/servo/components/style/macros.rs @@ -26,14 +26,17 @@ macro_rules! trivial_to_computed_value { /// FIXME(emilio): The fact that `UnexpectedIdent` is a `SelectorParseError` /// doesn't make a lot of sense to me. macro_rules! try_match_ident_ignore_ascii_case { - ($ident:expr, $( $match_body:tt )*) => { - let __ident = $ident; - (match_ignore_ascii_case! { &*__ident, + ($input:expr, $( $match_body:tt )*) => { + let location = $input.current_source_location(); + let ident = $input.expect_ident_cloned()?; + (match_ignore_ascii_case! { &ident, $( $match_body )* _ => Err(()), }) .map_err(|()| { - ::selectors::parser::SelectorParseError::UnexpectedIdent(__ident.clone()).into() + location.new_custom_error( + ::selectors::parser::SelectorParseErrorKind::UnexpectedIdent(ident.clone()) + ) }) } } @@ -56,7 +59,7 @@ macro_rules! define_numbered_css_keyword_enum { _context: &$crate::parser::ParserContext, input: &mut ::cssparser::Parser<'i, 't>, ) -> Result<$name, ::style_traits::ParseError<'i>> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, $( $css => Ok($name::$variant), )+ } } diff --git a/servo/components/style/media_queries.rs b/servo/components/style/media_queries.rs index 83b3f580922d..724011667461 100644 --- a/servo/components/style/media_queries.rs +++ b/servo/components/style/media_queries.rs @@ -12,11 +12,11 @@ use cssparser::{Delimiter, Parser}; use cssparser::{Token, ParserInput}; use error_reporting::{ContextualParseError, ParseErrorReporter}; use parser::{ParserContext, ParserErrorContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use serialize_comma_separated_list; use std::fmt; use str::string_as_ascii_lowercase; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use values::CustomIdent; #[cfg(feature = "servo")] @@ -210,13 +210,13 @@ impl MediaQuery { let media_type = match input.try(|i| i.expect_ident_cloned()) { Ok(ident) => { let result: Result<_, ParseError> = MediaQueryType::parse(&*ident) - .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()); + .map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); result? } Err(_) => { // Media type is only optional if qualifier is not specified. if qualifier.is_some() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } // Without a media type, require at least one expression. @@ -257,17 +257,17 @@ where let mut media_queries = vec![]; loop { let start_position = input.position(); - let start_location = input.current_source_location(); match input.parse_until_before(Delimiter::Comma, |i| MediaQuery::parse(context, i)) { Ok(mq) => { media_queries.push(mq); }, Err(err) => { media_queries.push(MediaQuery::never_matching()); + let location = err.location; let error = ContextualParseError::InvalidMediaRule( input.slice_from(start_position), err); let error_context = ParserErrorContext { error_reporter }; - context.log_css_error(&error_context, start_location, error); + context.log_css_error(&error_context, location, error); }, } diff --git a/servo/components/style/properties/declaration_block.rs b/servo/components/style/properties/declaration_block.rs index df4840f0dda1..64b33ea86e89 100644 --- a/servo/components/style/properties/declaration_block.rs +++ b/servo/components/style/properties/declaration_block.rs @@ -8,19 +8,18 @@ use context::QuirksMode; use cssparser::{DeclarationListParser, parse_important, ParserInput, CowRcStr}; -use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseError as CssParseError}; +use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter, ParseErrorKind}; use custom_properties::CustomPropertiesBuilder; use error_reporting::{ParseErrorReporter, ContextualParseError}; use parser::{ParserContext, ParserErrorContext}; use properties::animated_properties::AnimationValue; -use selectors::parser::SelectorParseError; use shared_lock::Locked; use smallbitvec::{self, SmallBitVec}; use smallvec::SmallVec; use std::fmt; use std::iter::{DoubleEndedIterator, Zip}; use std::slice::Iter; -use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseError}; +use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseErrorKind}; use stylesheets::{CssRuleType, Origin, UrlExtraData}; use super::*; use values::computed::Context; @@ -1035,16 +1034,16 @@ pub fn parse_one_declaration_into(declarations: &mut SourcePropertyDeclaratio let mut input = ParserInput::new(input); let mut parser = Parser::new(&mut input); let start_position = parser.position(); - let start_location = parser.current_source_location(); parser.parse_entirely(|parser| { let name = id.name().into(); PropertyDeclaration::parse_into(declarations, id, name, &context, parser) .map_err(|e| e.into()) }).map_err(|err| { + let location = err.location; let error = ContextualParseError::UnsupportedPropertyDeclaration( parser.slice_from(start_position), err); let error_context = ParserErrorContext { error_reporter: error_reporter }; - context.log_css_error(&error_context, start_location, error); + context.log_css_error(&error_context, location, error); }) } @@ -1060,7 +1059,7 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for PropertyDeclarationParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = Importance; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } /// Based on NonMozillaVendorIdentifier from Gecko's CSS parser. @@ -1071,7 +1070,7 @@ fn is_non_mozilla_vendor_identifier(name: &str) -> bool { impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { type Declaration = Importance; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result> { @@ -1079,11 +1078,11 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { let id = match PropertyId::parse(&name, Some(&prop_context)) { Ok(id) => id, Err(()) => { - return Err(if is_non_mozilla_vendor_identifier(&name) { - PropertyDeclarationParseError::UnknownVendorProperty + return Err(input.new_custom_error(if is_non_mozilla_vendor_identifier(&name) { + StyleParseErrorKind::UnknownVendorProperty } else { - PropertyDeclarationParseError::UnknownProperty(name) - }.into()); + StyleParseErrorKind::UnknownProperty(name) + })); } }; input.parse_until_before(Delimiter::Bang, |input| { @@ -1121,19 +1120,18 @@ pub fn parse_property_declaration_list(context: &ParserContext, Ok(importance) => { block.extend(iter.parser.declarations.drain(), importance); } - Err(err) => { + Err((error, slice)) => { iter.parser.declarations.clear(); // If the unrecognized property looks like a vendor-specific property, // silently ignore it instead of polluting the error output. - if let CssParseError::Custom(SelectorParseError::Custom( - StyleParseError::PropertyDeclaration( - PropertyDeclarationParseError::UnknownVendorProperty))) = err.error { + if let ParseErrorKind::Custom(StyleParseErrorKind::UnknownVendorProperty) = error.kind { continue; } - let error = ContextualParseError::UnsupportedPropertyDeclaration(err.slice, err.error); - context.log_css_error(error_context, err.location, error); + let location = error.location; + let error = ContextualParseError::UnsupportedPropertyDeclaration(slice, error); + context.log_css_error(error_context, location, error); } } } diff --git a/servo/components/style/properties/helpers.mako.rs b/servo/components/style/properties/helpers.mako.rs index 41995060941d..d8f6b10f4442 100644 --- a/servo/components/style/properties/helpers.mako.rs +++ b/servo/components/style/properties/helpers.mako.rs @@ -93,9 +93,9 @@ #[allow(unused_imports)] use properties::ShorthandId; #[allow(unused_imports)] - use selectors::parser::SelectorParseError; + use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; #[allow(unused_imports)] use values::computed::{Context, ToComputedValue}; #[allow(unused_imports)] @@ -285,11 +285,11 @@ #[allow(unused_imports)] use properties::style_structs; #[allow(unused_imports)] - use selectors::parser::SelectorParseError; + use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] use servo_arc::Arc; #[allow(unused_imports)] - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; #[allow(unused_imports)] use values::computed::{Context, ToComputedValue}; #[allow(unused_imports)] @@ -699,11 +699,11 @@ use parser::ParserContext; use properties::{PropertyDeclaration, SourcePropertyDeclaration, MaybeBoxed, longhands}; #[allow(unused_imports)] - use selectors::parser::SelectorParseError; + use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] use std::fmt; #[allow(unused_imports)] - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; #[allow(unused_imports)] use style_traits::ToCss; @@ -992,7 +992,7 @@ // Keyword values don't make sense in the block direction; don't parse them % if "block" in name: if let Ok(${length_type}::ExtremumLength(..)) = ret { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } % endif ret.map(SpecifiedValue) diff --git a/servo/components/style/properties/helpers/animated_properties.mako.rs b/servo/components/style/properties/helpers/animated_properties.mako.rs index 5bf10a8b3dc1..f36df1abd483 100644 --- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -25,7 +25,7 @@ use properties::longhands::visibility::computed_value::T as Visibility; #[cfg(feature = "gecko")] use properties::PropertyId; use properties::{LonghandId, ShorthandId}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; use smallvec::SmallVec; use std::borrow::Cow; @@ -134,6 +134,7 @@ impl TransitionProperty { /// Parse a transition-property value. pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let ident = input.expect_ident()?; match_ignore_ascii_case! { &ident, "all" => Ok(TransitionProperty::All), @@ -143,8 +144,8 @@ impl TransitionProperty { % for prop in data.longhands: "${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})), % endfor - "none" => Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()), - _ => CustomIdent::from_ident(ident, &[]).map(TransitionProperty::Unsupported), + "none" => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))), + _ => CustomIdent::from_ident(location, ident, &[]).map(TransitionProperty::Unsupported), } } diff --git a/servo/components/style/properties/longhand/background.mako.rs b/servo/components/style/properties/longhand/background.mako.rs index f2eb5f2e0381..3cf41d5ca0af 100644 --- a/servo/components/style/properties/longhand/background.mako.rs +++ b/servo/components/style/properties/longhand/background.mako.rs @@ -132,7 +132,7 @@ ${helpers.predefined_type("background-image", "ImageLayer", _ => Err(()), }).or_else(|()| { let horizontal: Result<_, ParseError> = RepeatKeyword::from_ident(&ident) - .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()); + .map_err(|()| input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); let horizontal = horizontal?; let vertical = input.try(RepeatKeyword::parse).ok(); Ok(SpecifiedValue::Other(horizontal, vertical)) diff --git a/servo/components/style/properties/longhand/border.mako.rs b/servo/components/style/properties/longhand/border.mako.rs index 6931eaa3f6ec..845a100f98e8 100644 --- a/servo/components/style/properties/longhand/border.mako.rs +++ b/servo/components/style/properties/longhand/border.mako.rs @@ -187,7 +187,7 @@ ${helpers.gecko_keyword_conversion(Keyword('border-style', if !result.is_empty() { Ok(SpecifiedValue::Colors(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/longhand/box.mako.rs b/servo/components/style/properties/longhand/box.mako.rs index 665e6893347b..8299ceade3d3 100644 --- a/servo/components/style/properties/longhand/box.mako.rs +++ b/servo/components/style/properties/longhand/box.mako.rs @@ -165,7 +165,7 @@ /// Parse a display value. pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, % for value in values: "${value}" => { Ok(computed_value::T::${to_rust_ident(value)}) @@ -545,7 +545,7 @@ ${helpers.predefined_type("animation-timing-function", let number = input.expect_number()?; if number < 0.0 { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(SpecifiedValue::Number(number)) @@ -1177,7 +1177,7 @@ ${helpers.predefined_type( _ => Err(()), }; result - .map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))) }) })?)) } @@ -1730,7 +1730,7 @@ ${helpers.predefined_type("transform-origin", }; let flag = match flag { Some(flag) if !result.contains(flag) => flag, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) }; result.insert(flag); } @@ -1738,7 +1738,7 @@ ${helpers.predefined_type("transform-origin", if !result.is_empty() { Ok(result) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -1839,7 +1839,8 @@ ${helpers.single_keyword("-moz-orient", Ok(computed_value::T::Auto) } else { input.parse_comma_separated(|i| { - CustomIdent::from_ident(i.expect_ident()?, &[ + let location = i.current_source_location(); + CustomIdent::from_ident(location, i.expect_ident()?, &[ "will-change", "none", "all", @@ -1914,7 +1915,7 @@ ${helpers.predefined_type( pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { // FIXME: remove clone() when lifetimes are non-lexical - try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(), + try_match_ident_ignore_ascii_case! { input, "auto" => Ok(TOUCH_ACTION_AUTO), "none" => Ok(TOUCH_ACTION_NONE), "manipulation" => Ok(TOUCH_ACTION_MANIPULATION), diff --git a/servo/components/style/properties/longhand/counters.mako.rs b/servo/components/style/properties/longhand/counters.mako.rs index fa1eab1a6235..a5b54fab150c 100644 --- a/servo/components/style/properties/longhand/counters.mako.rs +++ b/servo/components/style/properties/longhand/counters.mako.rs @@ -205,7 +205,9 @@ }; match result { Some(result) => content.push(result?), - None => return Err(StyleParseError::UnexpectedFunction(name.clone()).into()) + None => return Err(input.new_custom_error( + StyleParseErrorKind::UnexpectedFunction(name.clone()) + )) } } Ok(Token::Ident(ref ident)) => { @@ -218,15 +220,15 @@ _ => false, }; if !valid { - return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()) + return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } Err(_) => break, - Ok(t) => return Err(BasicParseError::UnexpectedToken(t).into()) + Ok(t) => return Err(input.new_unexpected_token_error(t)) } } if content.is_empty() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(SpecifiedValue::Items(content)) } @@ -332,9 +334,10 @@ let mut counters = Vec::new(); loop { + let location = input.current_source_location(); let counter_name = match input.next() { - Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(ident, &["none"])?, - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(&Token::Ident(ref ident)) => CustomIdent::from_ident(location, ident, &["none"])?, + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, }; let counter_delta = input.try(|input| specified::parse_integer(context, input)) @@ -345,7 +348,7 @@ if !counters.is_empty() { Ok(SpecifiedValue(counters)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/longhand/font.mako.rs b/servo/components/style/properties/longhand/font.mako.rs index ac35c271ec27..04d6c694a212 100644 --- a/servo/components/style/properties/longhand/font.mako.rs +++ b/servo/components/style/properties/longhand/font.mako.rs @@ -587,7 +587,7 @@ macro_rules! impl_gecko_keyword_conversions { fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { match FontFamily::parse(input) { Ok(FontFamily::FamilyName(name)) => Ok(name), - Ok(FontFamily::Generic(_)) => Err(StyleParseError::UnspecifiedError.into()), + Ok(FontFamily::Generic(_)) => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), Err(e) => Err(e) } } @@ -744,7 +744,7 @@ ${helpers.single_keyword_system("font-variant-caps", fn parse<'i, 't>(_: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { Self::from_int(input.expect_integer()?) - .map_err(|_| StyleParseError::UnspecifiedError.into()) + .map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -837,7 +837,7 @@ ${helpers.single_keyword_system("font-variant-caps", return Ok(SpecifiedValue::Keyword(kw.into())) } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "smaller" => Ok(SpecifiedValue::Smaller), "larger" => Ok(SpecifiedValue::Larger), } @@ -1082,7 +1082,7 @@ ${helpers.single_keyword_system("font-variant-caps", -> Result> { let mut result = SpecifiedValue { weight: false, style: false }; // FIXME: remove clone() when lifetimes are non-lexical - try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(), + try_match_ident_ignore_ascii_case! { input, "none" => Ok(result), "weight" => { result.weight = true; @@ -1298,9 +1298,9 @@ ${helpers.single_keyword_system("font-kerning", let mut parsed_alternates = ParsingFlags::empty(); macro_rules! check_if_parsed( - ($flag:ident) => ( + ($input:expr, $flag:ident) => ( if parsed_alternates.contains($flag) { - return Err(StyleParseError::UnspecifiedError.into()) + return Err($input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } parsed_alternates |= $flag; ) @@ -1310,11 +1310,11 @@ ${helpers.single_keyword_system("font-kerning", match input.next()?.clone() { Token::Ident(ref ident) => { if *ident == "historical-forms" { - check_if_parsed!(HISTORICAL_FORMS); + check_if_parsed!(input, HISTORICAL_FORMS); alternates.push(VariantAlternates::HistoricalForms); Ok(()) } else { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } }, Token::Function(ref name) => { @@ -1322,31 +1322,34 @@ ${helpers.single_keyword_system("font-kerning", match_ignore_ascii_case! { &name, % for value in "swash stylistic ornaments annotation".split(): "${value}" => { - check_if_parsed!(${value.upper()}); - let ident = CustomIdent::from_ident(i.expect_ident()?, &[])?; + check_if_parsed!(i, ${value.upper()}); + let location = i.current_source_location(); + let ident = CustomIdent::from_ident(location, i.expect_ident()?, &[])?; alternates.push(VariantAlternates::${to_camel_case(value)}(ident)); Ok(()) }, % endfor % for value in "styleset character-variant".split(): "${value}" => { - check_if_parsed!(${to_rust_ident(value).upper()}); - let idents = i.parse_comma_separated(|i| - CustomIdent::from_ident(i.expect_ident()?, &[]))?; + check_if_parsed!(i, ${to_rust_ident(value).upper()}); + let idents = i.parse_comma_separated(|i| { + let location = i.current_source_location(); + CustomIdent::from_ident(location, i.expect_ident()?, &[]) + })?; alternates.push(VariantAlternates::${to_camel_case(value)}(idents.into_boxed_slice())); Ok(()) }, % endfor - _ => return Err(StyleParseError::UnspecifiedError.into()), + _ => return Err(i.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } }) }, - _ => Err(StyleParseError::UnspecifiedError.into()), + _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } }) { } if parsed_alternates.is_empty() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(SpecifiedValue::Value(VariantAlternatesList(alternates.into_boxed_slice()))) } @@ -1501,7 +1504,7 @@ macro_rules! exclusive_value { if !result.is_empty() { Ok(SpecifiedValue::Value(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -1661,7 +1664,7 @@ macro_rules! exclusive_value { if !result.is_empty() { Ok(SpecifiedValue::Value(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -1809,7 +1812,7 @@ macro_rules! exclusive_value { if !result.is_empty() { Ok(SpecifiedValue::Value(result)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -2082,10 +2085,10 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control- computed_value::T(atom!("")) } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2105,10 +2108,10 @@ https://drafts.csswg.org/css-fonts-4/#low-level-font-variation-settings-control- ::gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_SIZE_MULTIPLIER as f32 } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2254,10 +2257,10 @@ ${helpers.single_keyword("-moz-math-variant", Length::new(NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * (AU_PER_PT / AU_PER_PX)) } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2287,10 +2290,10 @@ ${helpers.single_keyword("-moz-math-variant", computed_value::T(true) } - pub fn parse<'i, 't>(_context: &ParserContext, _input: &mut Parser<'i, 't>) + pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { debug_assert!(false, "Should be set directly by presentation attributes only."); - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } @@ -2445,7 +2448,7 @@ ${helpers.single_keyword("-moz-math-variant", impl SystemFont { pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, % for font in system_fonts: "${font}" => Ok(SystemFont::${to_camel_case(font)}), % endfor diff --git a/servo/components/style/properties/longhand/inherited_box.mako.rs b/servo/components/style/properties/longhand/inherited_box.mako.rs index 115a2de202f0..6b7ad377c022 100644 --- a/servo/components/style/properties/longhand/inherited_box.mako.rs +++ b/servo/components/style/properties/longhand/inherited_box.mako.rs @@ -241,7 +241,7 @@ ${helpers.single_keyword("image-rendering", // Handle | flip let angle = input.try(|input| Angle::parse(context, input)).ok(); if angle.is_none() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let flipped = input.try(|input| input.expect_ident_matching("flip")).is_ok(); diff --git a/servo/components/style/properties/longhand/inherited_svg.mako.rs b/servo/components/style/properties/longhand/inherited_svg.mako.rs index 920c12f3f44f..6b49c1ed5cc9 100644 --- a/servo/components/style/properties/longhand/inherited_svg.mako.rs +++ b/servo/components/style/properties/longhand/inherited_svg.mako.rs @@ -207,8 +207,8 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", let mut pos = 0; loop { - let result: Result<_, ParseError> = input.try(|i| { - try_match_ident_ignore_ascii_case! { i.expect_ident()?, + let result: Result<_, ParseError> = input.try(|input| { + try_match_ident_ignore_ascii_case! { input, "fill" => Ok(PaintOrder::Fill), "stroke" => Ok(PaintOrder::Stroke), "markers" => Ok(PaintOrder::Markers), @@ -219,7 +219,7 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", Ok(val) => { if (seen & (1 << val as u8)) != 0 { // don't parse the same ident twice - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } value |= (val as u8) << (pos * SHIFT); @@ -232,7 +232,7 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", if value == 0 { // Couldn't find any keyword - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } // fill in rest @@ -293,7 +293,8 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)", pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let i = input.expect_ident()?; - CustomIdent::from_ident(i, &["all", "none", "auto"]) + CustomIdent::from_ident(location, i, &["all", "none", "auto"]) } diff --git a/servo/components/style/properties/longhand/inherited_text.mako.rs b/servo/components/style/properties/longhand/inherited_text.mako.rs index 5a93dba2c40d..e42830309d35 100644 --- a/servo/components/style/properties/longhand/inherited_text.mako.rs +++ b/servo/components/style/properties/longhand/inherited_text.mako.rs @@ -585,7 +585,7 @@ ${helpers.predefined_type( (Some(fill), Ok(shape)) => KeywordValue::FillAndShape(fill,shape), (Some(fill), Err(_)) => KeywordValue::Fill(fill), (None, Ok(shape)) => KeywordValue::Shape(shape), - _ => return Err(StyleParseError::UnspecifiedError.into()), + _ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), }; Ok(SpecifiedValue::Keyword(keyword_value)) } diff --git a/servo/components/style/properties/longhand/list.mako.rs b/servo/components/style/properties/longhand/list.mako.rs index 4554f3082215..8f9b8d9b103c 100644 --- a/servo/components/style/properties/longhand/list.mako.rs +++ b/servo/components/style/properties/longhand/list.mako.rs @@ -188,14 +188,16 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu let mut quotes = Vec::new(); loop { + let location = input.current_source_location(); let first = match input.next() { Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(), - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, }; + let location = input.current_source_location(); let second = match input.next() { Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned(), - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(e) => return Err(e.into()), }; quotes.push((first, second)) @@ -203,7 +205,7 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu if !quotes.is_empty() { Ok(SpecifiedValue(quotes)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/longhand/outline.mako.rs b/servo/components/style/properties/longhand/outline.mako.rs index 7c349be62f84..1fe1cf3910e2 100644 --- a/servo/components/style/properties/longhand/outline.mako.rs +++ b/servo/components/style/properties/longhand/outline.mako.rs @@ -58,7 +58,7 @@ ${helpers.predefined_type( // The outline-style property accepts the same values as // border-style, except that 'hidden' is not a legal outline // style. - Err(SelectorParseError::UnexpectedIdent("hidden".into()).into()) + Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into()))) } else { Ok(result) } diff --git a/servo/components/style/properties/longhand/pointing.mako.rs b/servo/components/style/properties/longhand/pointing.mako.rs index 968052d6024a..858f6f10f735 100644 --- a/servo/components/style/properties/longhand/pointing.mako.rs +++ b/servo/components/style/properties/longhand/pointing.mako.rs @@ -92,13 +92,14 @@ -> Result> { use std::ascii::AsciiExt; use style_traits::cursor::Cursor; + let location = input.current_source_location(); let ident = input.expect_ident()?; if ident.eq_ignore_ascii_case("auto") { Ok(computed_value::Keyword::Auto) } else { Cursor::from_css_keyword(&ident) .map(computed_value::Keyword::Cursor) - .map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()) + .map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } } diff --git a/servo/components/style/properties/longhand/position.mako.rs b/servo/components/style/properties/longhand/position.mako.rs index 1eb1582134f2..45f7c0771880 100644 --- a/servo/components/style/properties/longhand/position.mako.rs +++ b/servo/components/style/properties/longhand/position.mako.rs @@ -340,6 +340,7 @@ ${helpers.predefined_type("object-position", let mut dense = false; while !input.is_exhausted() { + let location = input.current_source_location(); let ident = input.expect_ident()?; let success = match_ignore_ascii_case! { &ident, "row" if value.is_none() => { @@ -357,7 +358,7 @@ ${helpers.predefined_type("object-position", _ => false }; if !success { - return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()); + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); } } @@ -367,7 +368,7 @@ ${helpers.predefined_type("object-position", dense: dense, }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -465,7 +466,7 @@ ${helpers.predefined_type("object-position", } TemplateAreas::from_vec(strings) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/longhand/table.mako.rs b/servo/components/style/properties/longhand/table.mako.rs index 7d6c7aacea86..788805878b9b 100644 --- a/servo/components/style/properties/longhand/table.mako.rs +++ b/servo/components/style/properties/longhand/table.mako.rs @@ -39,8 +39,8 @@ ${helpers.single_keyword("table-layout", "auto fixed", // never parse it, only set via presentation attribute fn parse<'i, 't>( _: &ParserContext, - _: &mut Parser<'i, 't>, + input: &mut Parser<'i, 't>, ) -> Result> { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } diff --git a/servo/components/style/properties/longhand/text.mako.rs b/servo/components/style/properties/longhand/text.mako.rs index 586519333d6e..d59063eba633 100644 --- a/servo/components/style/properties/longhand/text.mako.rs +++ b/servo/components/style/properties/longhand/text.mako.rs @@ -119,17 +119,21 @@ impl Parse for Side { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match *input.next()? { Token::Ident(ref ident) => { - try_match_ident_ignore_ascii_case! { ident, + match_ignore_ascii_case! { ident, "clip" => Ok(Side::Clip), "ellipsis" => Ok(Side::Ellipsis), + _ => Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent(ident.clone()) + )) } } Token::QuotedString(ref v) => { Ok(Side::String(v.as_ref().to_owned().into_boxed_str())) } - ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => Err(location.new_unexpected_token_error(t.clone())), } } } @@ -222,6 +226,7 @@ ${helpers.single_keyword("unicode-bidi", loop { let result: Result<_, ParseError> = input.try(|input| { + let location = input.current_source_location(); match input.expect_ident() { Ok(ident) => { (match_ignore_ascii_case! { &ident, @@ -234,7 +239,9 @@ ${helpers.single_keyword("unicode-bidi", "blink" => if result.contains(BLINK) { Err(()) } else { empty = false; result.insert(BLINK); Ok(()) }, _ => Err(()) - }).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()) + }).map_err(|()| { + location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())) + }) } Err(e) => return Err(e.into()) } @@ -244,7 +251,7 @@ ${helpers.single_keyword("unicode-bidi", } } - if !empty { Ok(result) } else { Err(StyleParseError::UnspecifiedError.into()) } + if !empty { Ok(result) } else { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } % if product == "servo": diff --git a/servo/components/style/properties/longhand/ui.mako.rs b/servo/components/style/properties/longhand/ui.mako.rs index c174360133be..5976b01b2880 100644 --- a/servo/components/style/properties/longhand/ui.mako.rs +++ b/servo/components/style/properties/longhand/ui.mako.rs @@ -77,7 +77,7 @@ ${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet" match input.expect_integer()? { 0 => Ok(computed_value::T(false)), 1 => Ok(computed_value::T(true)), - _ => Err(StyleParseError::UnspecifiedError.into()), + _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } } diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs index 128bb4fbf0ab..de736e7dda5f 100644 --- a/servo/components/style/properties/properties.mako.rs +++ b/servo/components/style/properties/properties.mako.rs @@ -35,11 +35,10 @@ use parser::ParserContext; #[cfg(feature = "gecko")] use properties::longhands::system_font::SystemFont; use rule_cache::{RuleCache, RuleCacheConditions}; use selector_parser::PseudoElement; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; #[cfg(feature = "servo")] use servo_config::prefs::PREFS; use shared_lock::StylesheetGuards; -use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError}; -use style_traits::{PropertyDeclarationParseError, StyleParseError, ValueParseError}; +use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseErrorKind}; use stylesheets::{CssRuleType, Origin, UrlExtraData}; #[cfg(feature = "servo")] use values::Either; use values::generics::text::LineHeight; @@ -153,7 +152,7 @@ macro_rules! unwrap_or_initial { pub mod shorthands { use cssparser::Parser; use parser::{Parse, ParserContext}; - use style_traits::{ParseError, StyleParseError}; + use style_traits::{ParseError, StyleParseErrorKind}; use values::specified; <%include file="/shorthand/serialize.mako.rs" /> @@ -553,7 +552,9 @@ impl LonghandId { % if not property.derived_from: longhands::${property.ident}::parse_declared(context, input) % else: - Err(PropertyDeclarationParseError::UnknownProperty("${property.ident}".into()).into()) + Err(input.new_custom_error( + StyleParseErrorKind::UnknownProperty("${property.ident}".into()) + )) % endif } % endfor @@ -878,7 +879,7 @@ impl ShorthandId { } % endfor // 'all' accepts no value other than CSS-wide keywords - ShorthandId::All => Err(StyleParseError::UnspecifiedError.into()) + ShorthandId::All => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } } @@ -962,7 +963,7 @@ impl UnparsedValue { Some(ShorthandId::All) => { // No need to parse the 'all' shorthand as anything other than a CSS-wide // keyword, after variable substitution. - Err(SelectorParseError::UnexpectedIdent("all".into()).into()) + Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("all".into()))) } % for shorthand in data.shorthands_except_all(): Some(ShorthandId::${shorthand.camel_case}) => { @@ -1630,7 +1631,7 @@ impl PropertyDeclaration { pub fn parse_into<'i, 't>(declarations: &mut SourcePropertyDeclaration, id: PropertyId, name: CowRcStr<'i>, context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<(), PropertyDeclarationParseError<'i>> { + -> Result<(), ParseError<'i>> { assert!(declarations.is_empty()); let start = input.state(); match id { @@ -1642,8 +1643,7 @@ impl PropertyDeclaration { Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword), Err(()) => match ::custom_properties::SpecifiedValue::parse(input) { Ok(value) => DeclaredValueOwned::Value(value), - Err(e) => return Err(PropertyDeclarationParseError::InvalidValue(name.to_string().into(), - ValueParseError::from_parse_error(e))), + Err(e) => return Err(StyleParseErrorKind::new_invalid(name, e)), } }; declarations.push(PropertyDeclaration::Custom(property_name, value)); @@ -1662,8 +1662,7 @@ impl PropertyDeclaration { input.reset(&start); let (first_token_type, css) = ::custom_properties::parse_non_custom_with_var(input).map_err(|e| { - PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(e)) + StyleParseErrorKind::new_invalid(name, e) })?; Ok(PropertyDeclaration::WithVariables(id, Arc::new(UnparsedValue { css: css.into_owned(), @@ -1672,8 +1671,7 @@ impl PropertyDeclaration { from_shorthand: None, }))) } else { - Err(PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(err))) + Err(StyleParseErrorKind::new_invalid(name, err)) } }) }).map(|declaration| { @@ -1701,8 +1699,7 @@ impl PropertyDeclaration { input.reset(&start); let (first_token_type, css) = ::custom_properties::parse_non_custom_with_var(input).map_err(|e| { - PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(e)) + StyleParseErrorKind::new_invalid(name, e) })?; let unparsed = Arc::new(UnparsedValue { css: css.into_owned(), @@ -1721,8 +1718,7 @@ impl PropertyDeclaration { } Ok(()) } else { - Err(PropertyDeclarationParseError::InvalidValue(name, - ValueParseError::from_parse_error(err))) + Err(StyleParseErrorKind::new_invalid(name, err)) } }) } diff --git a/servo/components/style/properties/shorthand/background.mako.rs b/servo/components/style/properties/shorthand/background.mako.rs index 32cf30b6db6d..3f135e67ce8e 100644 --- a/servo/components/style/properties/shorthand/background.mako.rs +++ b/servo/components/style/properties/shorthand/background.mako.rs @@ -47,7 +47,7 @@ // background-color can only be in the last element, so if it // is parsed anywhere before, the value is invalid. if background_color.is_some() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } % for name in "image position repeat size attachment origin clip".split(): @@ -112,7 +112,7 @@ % endfor Ok(()) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } })?; @@ -217,7 +217,7 @@ Ok(()) })?; if !any { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/servo/components/style/properties/shorthand/border.mako.rs b/servo/components/style/properties/shorthand/border.mako.rs index 81093d91b3ce..5a7eaf89f6d9 100644 --- a/servo/components/style/properties/shorthand/border.mako.rs +++ b/servo/components/style/properties/shorthand/border.mako.rs @@ -83,7 +83,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) style.unwrap_or(BorderStyle::none), width.unwrap_or(BorderSideWidth::Medium))) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -276,7 +276,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) border_image_outset::parse(context, input) }).ok(); if w.is_none() && o.is_none() { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok((w, o)) @@ -312,7 +312,7 @@ pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) % endfor Ok(()) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } }); result?; diff --git a/servo/components/style/properties/shorthand/box.mako.rs b/servo/components/style/properties/shorthand/box.mako.rs index 19c8e0e7c1e6..94510e12c1f6 100644 --- a/servo/components/style/properties/shorthand/box.mako.rs +++ b/servo/components/style/properties/shorthand/box.mako.rs @@ -14,8 +14,8 @@ pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { % if product == "gecko": - let moz_kw_found = input.try(|i| { - try_match_ident_ignore_ascii_case! { i.expect_ident()?, + let moz_kw_found = input.try(|input| { + try_match_ident_ignore_ascii_case! { input, "-moz-scrollbars-horizontal" => { Ok(expanded! { overflow_x: SpecifiedValue::scroll, @@ -141,7 +141,7 @@ macro_rules! try_parse_one { Some(transition_property::single_value::get_initial_specified_value())), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -158,7 +158,7 @@ macro_rules! try_parse_one { // If there is more than one item, and any of transitions has 'none', // then it's invalid. Othersize, leave propertys to be empty (which // means "transition-property: none"); - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } % for prop in "duration timing_function delay".split(): @@ -269,7 +269,7 @@ macro_rules! try_parse_one { // If nothing is parsed, this is an invalid entry. if parsed == 0 { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(SingleAnimation { % for prop in props: diff --git a/servo/components/style/properties/shorthand/column.mako.rs b/servo/components/style/properties/shorthand/column.mako.rs index 166de6e34d10..cf1071def1ee 100644 --- a/servo/components/style/properties/shorthand/column.mako.rs +++ b/servo/components/style/properties/shorthand/column.mako.rs @@ -44,7 +44,7 @@ let values = autos + column_count.iter().len() + column_width.iter().len(); if values == 0 || values > 2 { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(expanded! { column_count: unwrap_or_initial!(column_count), @@ -89,7 +89,7 @@ column_rule_color: unwrap_or_initial!(column_rule_color), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/shorthand/font.mako.rs b/servo/components/style/properties/shorthand/font.mako.rs index 0bd11277e74c..b06f03a74e2c 100644 --- a/servo/components/style/properties/shorthand/font.mako.rs +++ b/servo/components/style/properties/shorthand/font.mako.rs @@ -98,7 +98,7 @@ } if size.is_none() || (count(&style) + count(&weight) + count(&variant_caps) + count(&stretch) + nb_normals) > 4 { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let line_height = if input.try(|input| input.expect_delim('/')).is_ok() { Some(LineHeight::parse(context, input)?) @@ -262,7 +262,7 @@ loop { if input.try(|input| input.expect_ident_matching("normal")).is_ok() || input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } % for prop in sub_properties: if ${prop}.is_none() { @@ -278,7 +278,7 @@ } if !has_custom_value { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/shorthand/inherited_text.mako.rs b/servo/components/style/properties/shorthand/inherited_text.mako.rs index 784caf43d2f6..664d5238d577 100644 --- a/servo/components/style/properties/shorthand/inherited_text.mako.rs +++ b/servo/components/style/properties/shorthand/inherited_text.mako.rs @@ -36,7 +36,7 @@ text_emphasis_style: unwrap_or_initial!(text_emphasis_style, style), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -78,7 +78,7 @@ _webkit_text_stroke_width: unwrap_or_initial!(_webkit_text_stroke_width, width), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/shorthand/list.mako.rs b/servo/components/style/properties/shorthand/list.mako.rs index c92d5c7170e9..9cdeea469ebf 100644 --- a/servo/components/style/properties/shorthand/list.mako.rs +++ b/servo/components/style/properties/shorthand/list.mako.rs @@ -21,7 +21,7 @@ if input.try(|input| input.expect_ident_matching("none")).is_ok() { nones = nones + 1; if nones > 2 { - return Err(SelectorParseError::UnexpectedIdent("none".into()).into()) + return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("none".into()))) } any = true; continue @@ -106,7 +106,7 @@ list_style_type: unwrap_or_initial!(list_style_type), }) } - _ => Err(StyleParseError::UnspecifiedError.into()), + _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } } diff --git a/servo/components/style/properties/shorthand/mask.mako.rs b/servo/components/style/properties/shorthand/mask.mako.rs index b0e298317fe4..ebf9f215f91f 100644 --- a/servo/components/style/properties/shorthand/mask.mako.rs +++ b/servo/components/style/properties/shorthand/mask.mako.rs @@ -108,7 +108,7 @@ % endfor Ok(()) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } })?; @@ -203,7 +203,7 @@ Ok(()) })?; if any == false { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/servo/components/style/properties/shorthand/outline.mako.rs b/servo/components/style/properties/shorthand/outline.mako.rs index 5d816965fae4..0fe8a11118be 100644 --- a/servo/components/style/properties/shorthand/outline.mako.rs +++ b/servo/components/style/properties/shorthand/outline.mako.rs @@ -50,7 +50,7 @@ outline_width: unwrap_or_initial!(outline_width, width), }) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/properties/shorthand/position.mako.rs b/servo/components/style/properties/shorthand/position.mako.rs index 6a4661c4f56b..82e0ef3cbad7 100644 --- a/servo/components/style/properties/shorthand/position.mako.rs +++ b/servo/components/style/properties/shorthand/position.mako.rs @@ -32,7 +32,7 @@ } if direction.is_none() && wrap.is_none() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(expanded! { flex_direction: unwrap_or_initial!(flex_direction, direction), @@ -87,7 +87,7 @@ } if grow.is_none() && basis.is_none() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(expanded! { flex_grow: grow.unwrap_or(NonNegativeNumber::new(1.0)), @@ -309,7 +309,7 @@ } let template_areas = TemplateAreas::from_vec(strings) - .map_err(|()| StyleParseError::UnspecifiedError)?; + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))?; let template_rows = TrackList { list_type: TrackListType::Normal, values: values, @@ -321,7 +321,7 @@ let value = GridTemplateComponent::parse_without_none(context, input)?; if let GenericGridTemplateComponent::TrackList(ref list) = value { if list.list_type != TrackListType::Explicit { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -340,7 +340,7 @@ if list.line_names[0].is_empty() { list.line_names[0] = first_line_names; // won't panic } else { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } } @@ -501,7 +501,7 @@ autoflow: flow, dense: dense, } - }).ok_or(StyleParseError::UnspecifiedError.into()) + }).ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } if let Ok((rows, cols, areas)) = input.try(|i| super::grid_template::parse_grid_template(context, i)) { @@ -617,12 +617,12 @@ -> Result> { let align = align_content::parse(context, input)?; if align.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let justify = input.try(|input| justify_content::parse(context, input)) .unwrap_or(justify_content::SpecifiedValue::from(align)); if justify.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { @@ -653,11 +653,11 @@ -> Result> { let align = AlignJustifySelf::parse(context, input)?; if align.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let justify = input.try(|input| AlignJustifySelf::parse(context, input)).unwrap_or(align.clone()); if justify.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { @@ -695,12 +695,12 @@ -> Result> { let align = AlignItems::parse(context, input)?; if align.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let justify = input.try(|input| JustifyItems::parse(context, input)) .unwrap_or(JustifyItems::from(align)); if justify.has_extra_flags() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/servo/components/style/properties/shorthand/text.mako.rs b/servo/components/style/properties/shorthand/text.mako.rs index bd119f7cd8af..49c3f80fc906 100644 --- a/servo/components/style/properties/shorthand/text.mako.rs +++ b/servo/components/style/properties/shorthand/text.mako.rs @@ -48,7 +48,7 @@ } if !any { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(expanded! { diff --git a/servo/components/style/servo/media_queries.rs b/servo/components/style/servo/media_queries.rs index 8d99b8ba81e1..137058f38261 100644 --- a/servo/components/style/servo/media_queries.rs +++ b/servo/components/style/servo/media_queries.rs @@ -14,7 +14,7 @@ use parser::ParserContext; use properties::{ComputedValues, StyleBuilder}; use properties::longhands::font_size; use rule_cache::RuleCacheConditions; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use std::cell::RefCell; use std::fmt; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; @@ -198,7 +198,7 @@ impl Expression { "width" => { ExpressionKind::Width(Range::Eq(specified::Length::parse_non_negative(context, input)?)) }, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) })) }) } diff --git a/servo/components/style/servo/selector_parser.rs b/servo/components/style/servo/selector_parser.rs index 201fbd1b6fee..887503f9a11a 100644 --- a/servo/components/style/servo/selector_parser.rs +++ b/servo/components/style/servo/selector_parser.rs @@ -8,7 +8,7 @@ use {Atom, Prefix, Namespace, LocalName, CaseSensitivityExt}; use attr::{AttrIdentifier, AttrValue}; -use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CowRcStr}; +use cssparser::{Parser as CssParser, ToCss, serialize_identifier, CowRcStr, SourceLocation}; use dom::{OpaqueNode, TElement, TNode}; use element_state::ElementState; use fnv::FnvHashMap; @@ -19,14 +19,14 @@ use properties::longhands::display::computed_value as display; use selector_parser::{AttrValue as SelectorAttrValue, ElementExt, PseudoElementCascadeType, SelectorParser}; use selectors::Element; use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity}; -use selectors::parser::{SelectorMethods, SelectorParseError}; +use selectors::parser::{SelectorMethods, SelectorParseErrorKind}; use selectors::visitor::SelectorVisitor; use std::ascii::AsciiExt; use std::fmt; use std::fmt::Debug; use std::mem; use std::ops::{Deref, DerefMut}; -use style_traits::{ParseError, StyleParseError}; +use style_traits::{ParseError, StyleParseErrorKind}; /// A pseudo-element, both public and private. /// @@ -395,9 +395,9 @@ impl ::selectors::SelectorImpl for SelectorImpl { impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { type Impl = SelectorImpl; - type Error = StyleParseError<'i>; + type Error = StyleParseErrorKind<'i>; - fn parse_non_ts_pseudo_class(&self, name: CowRcStr<'i>) + fn parse_non_ts_pseudo_class(&self, location: SourceLocation, name: CowRcStr<'i>) -> Result> { use self::NonTSPseudoClass::*; let pseudo_class = match_ignore_ascii_case! { &name, @@ -418,12 +418,13 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { "visited" => Visited, "-servo-nonzero-border" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent( - "-servo-nonzero-border".into()).into()); + return Err(location.new_custom_error( + SelectorParseErrorKind::UnexpectedIdent("-servo-nonzero-border".into()) + )) } ServoNonZeroBorder }, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()), + _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))), }; Ok(pseudo_class) @@ -440,17 +441,18 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { } "-servo-case-sensitive-type-attr" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()); + return Err(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))); } ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?.as_ref())) } - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) }; Ok(pseudo_class) } - fn parse_pseudo_element(&self, name: CowRcStr<'i>) -> Result> { + fn parse_pseudo_element(&self, location: SourceLocation, name: CowRcStr<'i>) + -> Result> { use self::PseudoElement::*; let pseudo_element = match_ignore_ascii_case! { &name, "before" => Before, @@ -458,77 +460,77 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { "selection" => Selection, "-servo-details-summary" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } DetailsSummary }, "-servo-details-content" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } DetailsContent }, "-servo-text" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoText }, "-servo-input-text" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoInputText }, "-servo-table-wrapper" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoTableWrapper }, "-servo-anonymous-table-wrapper" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTableWrapper }, "-servo-anonymous-table" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTable }, "-servo-anonymous-table-row" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTableRow }, "-servo-anonymous-table-cell" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousTableCell }, "-servo-anonymous-block" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoAnonymousBlock }, "-servo-inline-block-wrapper" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoInlineBlockWrapper }, "-servo-input-absolute" => { if !self.in_user_agent_stylesheet() { - return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) } ServoInlineAbsolute }, - _ => return Err(SelectorParseError::UnexpectedIdent(name.clone()).into()) + _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))) }; diff --git a/servo/components/style/stylesheets/document_rule.rs b/servo/components/style/stylesheets/document_rule.rs index e85d0c314965..e407aa1b3fa8 100644 --- a/servo/components/style/stylesheets/document_rule.rs +++ b/servo/components/style/stylesheets/document_rule.rs @@ -6,7 +6,7 @@ //! initially in CSS Conditional Rules Module Level 3, @document has been postponed to the level 4. //! We implement the prefixed `@-moz-document`. -use cssparser::{Parser, Token, SourceLocation, BasicParseError}; +use cssparser::{Parser, Token, SourceLocation}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use media_queries::Device; @@ -14,7 +14,7 @@ use parser::{Parse, ParserContext}; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use stylesheets::CssRules; use values::specified::url::SpecifiedUrl; @@ -100,10 +100,11 @@ macro_rules! parse_quoted_or_unquoted_string { $input.parse_nested_block(|input| { let start = input.position(); input.parse_entirely(|input| { + let location = input.current_source_location(); match input.next() { Ok(&Token::QuotedString(ref value)) => Ok($url_matching_function(value.as_ref().to_owned())), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } }).or_else(|_: ParseError| { @@ -129,7 +130,7 @@ impl UrlMatchingFunction { } else if let Ok(url) = input.try(|input| SpecifiedUrl::parse(context, input)) { Ok(UrlMatchingFunction::Url(url)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/stylesheets/font_feature_values_rule.rs b/servo/components/style/stylesheets/font_feature_values_rule.rs index e2adac1fc8bd..932ac08e9b38 100644 --- a/servo/components/style/stylesheets/font_feature_values_rule.rs +++ b/servo/components/style/stylesheets/font_feature_values_rule.rs @@ -8,7 +8,7 @@ use Atom; use computed_values::font_family::FamilyName; -use cssparser::{AtRuleParser, AtRuleType, BasicParseError, DeclarationListParser, DeclarationParser, Parser}; +use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{CowRcStr, RuleListParser, SourceLocation, QualifiedRuleParser, Token, serialize_identifier}; use error_reporting::{ContextualParseError, ParseErrorReporter}; #[cfg(feature = "gecko")] @@ -16,10 +16,9 @@ use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry; #[cfg(feature = "gecko")] use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray}; use parser::{ParserContext, ParserErrorContext, Parse}; -use selectors::parser::SelectorParseError; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{ParseError, StyleParseError, ToCss}; +use style_traits::{ParseError, StyleParseErrorKind, ToCss}; use stylesheets::CssRuleType; /// A @font-feature-values block declaration. @@ -59,9 +58,10 @@ pub struct SingleValue(pub u32); impl Parse for SingleValue { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match *input.next()? { Token::Number { int_value: Some(v), .. } if v >= 0 => Ok(SingleValue(v as u32)), - ref t => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => Err(location.new_unexpected_token_error(t.clone())), } } } @@ -87,16 +87,18 @@ pub struct PairValues(pub u32, pub Option); impl Parse for PairValues { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let first = match *input.next()? { Token::Number { int_value: Some(a), .. } if a >= 0 => a as u32, - ref t => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + ref t => return Err(location.new_unexpected_token_error(t.clone())), }; + let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(b), .. }) if b >= 0 => { Ok(PairValues(first, Some(b as u32))) } // It can't be anything other than number. - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), // It can be just one value. Err(_) => Ok(PairValues(first, None)) } @@ -136,18 +138,19 @@ impl Parse for VectorValues { -> Result> { let mut vec = vec![]; loop { + let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(a), .. }) if a >= 0 => { vec.push(a as u32); }, // It can't be anything other than number. - Ok(t) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, } } if vec.len() == 0 { - return Err(BasicParseError::EndOfInput.into()); + return Err(input.new_error(BasicParseErrorKind::EndOfInput)); } Ok(VectorValues(vec)) @@ -197,14 +200,14 @@ impl<'a, 'b, 'i, T> AtRuleParser<'i> for FFVDeclarationsParser<'a, 'b, T> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'b, 'i, T> DeclarationParser<'i> for FFVDeclarationsParser<'a, 'b, T> where T: Parse { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { @@ -271,9 +274,10 @@ macro_rules! font_feature_values_blocks { rule: &mut rule, }); while let Some(result) = iter.next() { - if let Err(err) = result { - let error = ContextualParseError::UnsupportedRule(err.slice, err.error); - context.log_css_error(error_context, err.location, error); + if let Err((error, slice)) = result { + let location = error.location; + let error = ContextualParseError::UnsupportedRule(slice, error); + context.log_css_error(error_context, location, error); } } } @@ -387,24 +391,24 @@ macro_rules! font_feature_values_blocks { impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { type Prelude = (); type QualifiedRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for FontFeatureValuesRuleParser<'a, R> { type PreludeNoBlock = (); type PreludeBlock = BlockType; type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>(&mut self, name: CowRcStr<'i>, - _input: &mut Parser<'i, 't>) + input: &mut Parser<'i, 't>) -> Result, ParseError<'i>> { match_ignore_ascii_case! { &*name, $( $name => Ok(AtRuleType::WithBlock(BlockType::$ident_camel)), )* - _ => Err(BasicParseError::AtRuleBodyInvalid.into()), + _ => Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid)), } } @@ -424,10 +428,12 @@ macro_rules! font_feature_values_blocks { let mut iter = DeclarationListParser::new(input, parser); while let Some(declaration) = iter.next() { - if let Err(err) = declaration { + if let Err((error, slice)) = declaration { + let location = error.location; let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration( - err.slice, err.error); - self.context.log_css_error(self.error_context, err.location, error); + slice, error + ); + self.context.log_css_error(self.error_context, location, error); } } }, diff --git a/servo/components/style/stylesheets/keyframes_rule.rs b/servo/components/style/stylesheets/keyframes_rule.rs index 8541f58d248d..97fcd6d3bf2b 100644 --- a/servo/components/style/stylesheets/keyframes_rule.rs +++ b/servo/components/style/stylesheets/keyframes_rule.rs @@ -12,12 +12,10 @@ use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, Prop use properties::{PropertyDeclarationId, LonghandId, SourcePropertyDeclaration}; use properties::LonghandIdSet; use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; -use selectors::parser::SelectorParseError; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard}; use std::fmt; -use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseError}; -use style_traits::PropertyDeclarationParseError; +use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, StyleParseErrorKind}; use stylesheets::{CssRuleType, StylesheetContents}; use stylesheets::rule_parser::VendorPrefix; use values::{KeyframesName, serialize_percentage}; @@ -137,7 +135,7 @@ impl KeyframePercentage { if percentage >= 0. && percentage <= 1. { KeyframePercentage::new(percentage) } else { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } }; @@ -500,7 +498,7 @@ impl<'a, 'i, R> AtRuleParser<'i> for KeyframeListParser<'a, R> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = Arc>; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } /// A wrapper to wraps the KeyframeSelector with its source location @@ -512,7 +510,7 @@ struct KeyframeSelectorParserPrelude { impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListParser<'a, R> { type Prelude = KeyframeSelectorParserPrelude; type QualifiedRule = Arc>; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>(&mut self, input: &mut Parser<'i, 't>) -> Result> { let start_position = input.position(); @@ -525,8 +523,9 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars }) }, Err(e) => { + let location = e.location; let error = ContextualParseError::InvalidKeyframeRule(input.slice_from(start_position), e.clone()); - self.context.log_css_error(self.error_context, start_location, error); + self.context.log_css_error(self.error_context, location, error); Err(e) } } @@ -552,10 +551,11 @@ impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for KeyframeListPars Ok(()) => { block.extend(iter.parser.declarations.drain(), Importance::Normal); } - Err(err) => { + Err((error, slice)) => { iter.parser.declarations.clear(); - let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(err.slice, err.error); - context.log_css_error(self.error_context, err.location, error); + let location = error.location; + let error = ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error); + context.log_css_error(self.error_context, location, error); } } // `parse_important` is not called here, `!important` is not allowed in keyframe blocks. @@ -578,25 +578,26 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for KeyframeDeclarationParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> { type Declaration = (); - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result<(), ParseError<'i>> { let property_context = PropertyParserContext::new(self.context); - let id = PropertyId::parse(&name, Some(&property_context)) - .map_err(|()| PropertyDeclarationParseError::UnknownProperty(name.clone()))?; + let id = PropertyId::parse(&name, Some(&property_context)).map_err(|()| { + input.new_custom_error(StyleParseErrorKind::UnknownProperty(name.clone())) + })?; match PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input) { Ok(()) => { // In case there is still unparsed text in the declaration, we should roll back. input.expect_exhausted().map_err(|e| e.into()) } - Err(_e) => Err(StyleParseError::UnspecifiedError.into()) + Err(e) => Err(e.into()) } } } diff --git a/servo/components/style/stylesheets/rule_parser.rs b/servo/components/style/stylesheets/rule_parser.rs index 30d1219dab1d..2c25d64e8c81 100644 --- a/servo/components/style/stylesheets/rule_parser.rs +++ b/servo/components/style/stylesheets/rule_parser.rs @@ -8,7 +8,7 @@ use {Namespace, Prefix}; use computed_values::font_family::FamilyName; use counter_style::{parse_counter_style_body, parse_counter_style_name}; use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser}; -use cssparser::{CowRcStr, SourceLocation, BasicParseError}; +use cssparser::{CowRcStr, SourceLocation, BasicParseError, BasicParseErrorKind}; use error_reporting::{ContextualParseError, ParseErrorReporter}; use font_face::parse_font_face_block; use media_queries::{parse_media_query_list, MediaList}; @@ -16,11 +16,10 @@ use parser::{Parse, ParserContext, ParserErrorContext}; use properties::parse_property_declaration_list; use selector_parser::{SelectorImpl, SelectorParser}; use selectors::SelectorList; -use selectors::parser::SelectorParseError; use servo_arc::Arc; use shared_lock::{Locked, SharedRwLock}; use str::starts_with_ignore_ascii_case; -use style_traits::{StyleParseError, ParseError}; +use style_traits::{StyleParseErrorKind, ParseError}; use stylesheets::{CssRule, CssRules, CssRuleType, Origin, StylesheetLoader}; use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule}; use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule}; @@ -160,7 +159,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeBlock = AtRuleBlockPrelude; type AtRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>( &mut self, @@ -173,7 +172,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, if self.state > State::Imports { // "@import must be before any rule but @charset" self.had_hierarchy_error = true; - return Err(StyleParseError::UnexpectedImportRule.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedImportRule)) } let url_string = input.expect_url_or_string()?.as_ref().to_owned(); @@ -190,15 +189,16 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, if self.state > State::Namespaces { // "@namespace must be before any rule but @charset and @import" self.had_hierarchy_error = true; - return Err(StyleParseError::UnexpectedNamespaceRule.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedNamespaceRule)) } let prefix = input.try(|i| i.expect_ident_cloned()) .map(|s| Prefix::from(s.as_ref())).ok(); let maybe_namespace = match input.expect_url_or_string() { Ok(url_or_string) => url_or_string, - Err(BasicParseError::UnexpectedToken(t)) => - return Err(StyleParseError::UnexpectedTokenWithinNamespace(t).into()), + Err(BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location }) => { + return Err(location.new_custom_error(StyleParseErrorKind::UnexpectedTokenWithinNamespace(t))) + } Err(e) => return Err(e.into()), }; let url = Namespace::from(maybe_namespace.as_ref()); @@ -209,7 +209,7 @@ impl<'a, 'i, R: ParseErrorReporter> AtRuleParser<'i> for TopLevelRuleParser<'a, // anything left is invalid. "charset" => { self.had_hierarchy_error = true; - return Err(StyleParseError::UnexpectedCharsetRule.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedCharsetRule)) } _ => {} } @@ -279,7 +279,7 @@ pub struct QualifiedRuleParserPrelude { impl<'a, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for TopLevelRuleParser<'a, R> { type Prelude = QualifiedRuleParserPrelude; type QualifiedRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; #[inline] fn parse_prelude<'t>( @@ -331,9 +331,10 @@ impl<'a, 'b, R: ParseErrorReporter> NestedRuleParser<'a, 'b, R> { while let Some(result) = iter.next() { match result { Ok(rule) => rules.push(rule), - Err(err) => { - let error = ContextualParseError::UnsupportedRule(err.slice, err.error); - self.context.log_css_error(self.error_context, err.location, error); + Err((error, slice)) => { + let location = error.location; + let error = ContextualParseError::UnsupportedRule(slice, error); + self.context.log_css_error(self.error_context, location, error); } } } @@ -345,7 +346,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a type PreludeNoBlock = AtRuleNonBlockPrelude; type PreludeBlock = AtRuleBlockPrelude; type AtRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>( &mut self, @@ -371,7 +372,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a "font-feature-values" => { if !cfg!(feature = "gecko") { // Support for this rule is not fully implemented in Servo yet. - return Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } let family_names = parse_family_name_list(self.context, input)?; Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::FontFeatureValues(family_names, location))) @@ -379,14 +380,14 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a "counter-style" => { if !cfg!(feature = "gecko") { // Support for this rule is not fully implemented in Servo yet. - return Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } let name = parse_counter_style_name(input)?; // ASCII-case-insensitive matches for "decimal" and "disc". // The name is already lower-cased by `parse_counter_style_name` // so we can use == here. if name.0 == atom!("decimal") || name.0 == atom!("disc") { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::CounterStyle(name))) }, @@ -394,7 +395,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a if viewport_rule::enabled() { Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Viewport)) } else { - Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } }, "keyframes" | "-webkit-keyframes" | "-moz-keyframes" => { @@ -408,7 +409,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a if cfg!(feature = "servo") && prefix.as_ref().map_or(false, |p| matches!(*p, VendorPrefix::Moz)) { // Servo should not support @-moz-keyframes. - return Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } let name = KeyframesName::parse(self.context, input)?; @@ -418,7 +419,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a if cfg!(feature = "gecko") { Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Page(location))) } else { - Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } }, "-moz-document" => { @@ -426,10 +427,10 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a let cond = DocumentCondition::parse(self.context, input)?; Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::Document(cond, location))) } else { - Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } }, - _ => Err(StyleParseError::UnsupportedAtRule(name.clone()).into()) + _ => Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone()))) } } @@ -548,7 +549,7 @@ impl<'a, 'b, 'i, R: ParseErrorReporter> AtRuleParser<'i> for NestedRuleParser<'a impl<'a, 'b, 'i, R: ParseErrorReporter> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b, R> { type Prelude = QualifiedRuleParserPrelude; type QualifiedRule = CssRule; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_prelude<'t>( &mut self, diff --git a/servo/components/style/stylesheets/stylesheet.rs b/servo/components/style/stylesheets/stylesheet.rs index 1b5d2285af6a..e8d22e19bb23 100644 --- a/servo/components/style/stylesheets/stylesheet.rs +++ b/servo/components/style/stylesheets/stylesheet.rs @@ -394,10 +394,11 @@ impl Stylesheet { break; } }, - Err(err) => { - let error = ContextualParseError::InvalidRule(err.slice, err.error); + Err((error, slice)) => { + let location = error.location; + let error = ContextualParseError::InvalidRule(slice, error); iter.parser.context.log_css_error(&iter.parser.error_context, - err.location, error); + location, error); } } } diff --git a/servo/components/style/stylesheets/supports_rule.rs b/servo/components/style/stylesheets/supports_rule.rs index 07f42c4c5c3e..e378a49b9bbe 100644 --- a/servo/components/style/stylesheets/supports_rule.rs +++ b/servo/components/style/stylesheets/supports_rule.rs @@ -4,17 +4,17 @@ //! [@supports rules](https://drafts.csswg.org/css-conditional-3/#at-supports) -use cssparser::{BasicParseError, ParseError as CssParseError, ParserInput}; use cssparser::{Delimiter, parse_important, Parser, SourceLocation, Token}; +use cssparser::{ParseError as CssParseError, ParserInput}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; use parser::ParserContext; use properties::{PropertyId, PropertyDeclaration, PropertyParserContext, SourcePropertyDeclaration}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use servo_arc::Arc; use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError}; use stylesheets::{CssRuleType, CssRules}; /// An [`@supports`][supports] rule. @@ -104,6 +104,7 @@ impl SupportsCondition { let in_parens = SupportsCondition::parse_in_parens(input)?; + let location = input.current_source_location(); let (keyword, wrapper) = match input.next() { Err(_) => { // End of input @@ -113,10 +114,10 @@ impl SupportsCondition { match_ignore_ascii_case! { &ident, "and" => ("and", SupportsCondition::And as fn(_) -> _), "or" => ("or", SupportsCondition::Or as fn(_) -> _), - _ => return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()) + _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } - Ok(t) => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t.clone()))) + Ok(t) => return Err(location.new_unexpected_token_error(t.clone())) }; let mut conditions = Vec::with_capacity(2); @@ -138,6 +139,7 @@ impl SupportsCondition { // but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases. while input.try(Parser::expect_whitespace).is_ok() {} let pos = input.position(); + let location = input.current_source_location(); // FIXME: remove clone() when lifetimes are non-lexical match input.next()?.clone() { Token::ParenthesisBlock => { @@ -149,7 +151,7 @@ impl SupportsCondition { } } Token::Function(_) => {} - t => return Err(CssParseError::Basic(BasicParseError::UnexpectedToken(t))), + t => return Err(location.new_unexpected_token_error(t)), } input.parse_nested_block(|i| consume_any_value(i))?; Ok(SupportsCondition::FutureSyntax(input.slice_from(pos).to_owned())) @@ -258,18 +260,18 @@ impl Declaration { let mut input = ParserInput::new(&self.0); let mut input = Parser::new(&mut input); - input.parse_entirely(|input| { + input.parse_entirely(|input| -> Result<(), CssParseError<()>> { let prop = input.expect_ident().unwrap().as_ref().to_owned(); input.expect_colon().unwrap(); let property_context = PropertyParserContext::new(&context); let id = PropertyId::parse(&prop, Some(&property_context)) - .map_err(|_| StyleParseError::UnspecifiedError)?; + .map_err(|()| input.new_custom_error(()))?; let mut declarations = SourcePropertyDeclaration::new(); input.parse_until_before(Delimiter::Bang, |input| { PropertyDeclaration::parse_into(&mut declarations, id, prop.into(), &context, input) - .map_err(|e| StyleParseError::PropertyDeclaration(e).into()) + .map_err(|_| input.new_custom_error(())) })?; let _ = input.try(parse_important); Ok(()) diff --git a/servo/components/style/stylesheets/viewport_rule.rs b/servo/components/style/stylesheets/viewport_rule.rs index d0263e1366d1..635fe9ca82c2 100644 --- a/servo/components/style/stylesheets/viewport_rule.rs +++ b/servo/components/style/stylesheets/viewport_rule.rs @@ -18,7 +18,7 @@ use media_queries::Device; use parser::{ParserContext, ParserErrorContext}; use properties::StyleBuilder; use rule_cache::RuleCacheConditions; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; use std::ascii::AsciiExt; use std::borrow::Cow; @@ -26,7 +26,7 @@ use std::cell::RefCell; use std::fmt; use std::iter::Enumerate; use std::str::Chars; -use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseError}; +use style_traits::{PinchZoomFactor, ToCss, ParseError, StyleParseErrorKind}; use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom}; use stylesheets::{StylesheetInDocument, Origin}; use values::computed::{Context, ToComputedValue}; @@ -276,12 +276,12 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for ViewportRuleParser<'a, 'b> { type PreludeNoBlock = (); type PreludeBlock = (); type AtRule = Vec; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; } impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> { type Declaration = Vec; - type Error = SelectorParseError<'i, StyleParseError<'i>>; + type Error = StyleParseErrorKind<'i>; fn parse_value<'t>(&mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>) -> Result, ParseError<'i>> { @@ -323,7 +323,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> { "max-zoom" => ok!(MaxZoom(Zoom::parse)), "user-zoom" => ok!(UserZoom(UserZoom::parse)), "orientation" => ok!(Orientation(Orientation::parse)), - _ => Err(SelectorParseError::UnexpectedIdent(name.clone()).into()), + _ => Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))), } } } @@ -368,9 +368,10 @@ impl ViewportRule { cascade.add(Cow::Owned(declarations)) } } - Err(err) => { - let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(err.slice, err.error); - context.log_css_error(error_context, err.location, error); + Err((error, slice)) => { + let location = error.location; + let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration(slice, error); + context.log_css_error(error_context, location, error); } } } diff --git a/servo/components/style/values/generics/grid.rs b/servo/components/style/values/generics/grid.rs index a8814a6f8253..04c643a4b505 100644 --- a/servo/components/style/values/generics/grid.rs +++ b/servo/components/style/values/generics/grid.rs @@ -8,7 +8,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::{fmt, mem, usize}; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use values::{CSSFloat, CustomIdent, serialize_dimension}; use values::computed::{Context, ToComputedValue}; use values::specified; @@ -88,9 +88,10 @@ impl Parse for GridLine { let mut val_before_span = false; for _ in 0..3 { // Maximum possible entities for + let location = input.current_source_location(); if input.try(|i| i.expect_ident_matching("span")).is_ok() { if grid_line.is_span { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } if grid_line.line_num.is_some() || grid_line.ident.is_some() { @@ -101,31 +102,31 @@ impl Parse for GridLine { } else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) { // FIXME(emilio): Probably shouldn't reject if it's calc()... if i.value() == 0 || val_before_span || grid_line.line_num.is_some() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } grid_line.line_num = Some(i); } else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) { if val_before_span || grid_line.ident.is_some() { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } - grid_line.ident = Some(CustomIdent::from_ident(&name, &[])?); + grid_line.ident = Some(CustomIdent::from_ident(location, &name, &[])?); } else { break } } if grid_line.is_auto() { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } if grid_line.is_span { if let Some(i) = grid_line.line_num { if i.value() <= 0 { // disallow negative integers for grid spans - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } else if grid_line.ident.is_none() { // integer could be omitted - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -369,7 +370,7 @@ impl Parse for RepeatCount { } Ok(RepeatCount::Number(i)) } else { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "auto-fill" => Ok(RepeatCount::AutoFill), "auto-fit" => Ok(RepeatCount::AutoFit), } @@ -612,14 +613,14 @@ impl Parse for LineNameList { RepeatCount::AutoFill if fill_idx.is_none() => { // `repeat(autof-fill, ..)` should have just one line name. if names_list.len() != 1 { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } let names = names_list.pop().unwrap(); line_names.push(names); fill_idx = Some(line_names.len() as u32 - 1); }, - _ => return Err(StyleParseError::UnspecifiedError.into()), + _ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), } } else if let Ok(names) = input.try(parse_line_names) { line_names.push(names); diff --git a/servo/components/style/values/generics/mod.rs b/servo/components/style/values/generics/mod.rs index 4603523d9204..7491337eaf96 100644 --- a/servo/components/style/values/generics/mod.rs +++ b/servo/components/style/values/generics/mod.rs @@ -9,7 +9,7 @@ use counter_style::{Symbols, parse_counter_style_name}; use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; -use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss}; +use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss}; use super::CustomIdent; pub mod background; @@ -114,16 +114,16 @@ impl Parse for CounterStyleOrNone { // numeric system. if (symbols_type == SymbolsType::Alphabetic || symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } // Identifier is not allowed in symbols() function. if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) { - return Err(StyleParseError::UnspecifiedError.into()); + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } Ok(CounterStyleOrNone::Symbols(symbols_type, symbols)) }); } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -170,13 +170,14 @@ impl Parse for FontSettingTag { let u_tag; { + let location = input.current_source_location(); let tag = input.expect_string()?; // allowed strings of length 4 containing chars: if tag.len() != 4 || tag.chars().any(|c| c < ' ' || c > '~') { - return Err(StyleParseError::UnspecifiedError.into()) + return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } let mut raw = Cursor::new(tag.as_bytes()); @@ -248,7 +249,7 @@ impl Parse for FontSettingTagInt { if value >= 0 { Ok(FontSettingTagInt(value as u32)) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } else if let Ok(_) = input.try(|input| input.expect_ident_matching("on")) { // on is an alias for '1' diff --git a/servo/components/style/values/generics/svg.rs b/servo/components/style/values/generics/svg.rs index 24444da88946..49efbe40256f 100644 --- a/servo/components/style/values/generics/svg.rs +++ b/servo/components/style/values/generics/svg.rs @@ -7,7 +7,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::fmt; -use style_traits::{ParseError, StyleParseError, ToCss}; +use style_traits::{ParseError, StyleParseErrorKind, ToCss}; use values::{Either, None_}; use values::computed::NumberOrPercentage; use values::computed::length::LengthOrPercentage; @@ -54,7 +54,7 @@ pub enum SVGPaintKind { impl SVGPaintKind { /// Parse a keyword value only fn parse_ident<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "none" => Ok(SVGPaintKind::None), "context-fill" => Ok(SVGPaintKind::ContextFill), "context-stroke" => Ok(SVGPaintKind::ContextStroke), @@ -104,7 +104,7 @@ impl Parse for SVGPaint Parse for if let Ok(lop) = input.try(|i| LengthOrPercentageType::parse(context, i)) { return Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop)); } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/values/mod.rs b/servo/components/style/values/mod.rs index f338cb357c0b..02e2d8e82cfe 100644 --- a/servo/components/style/values/mod.rs +++ b/servo/components/style/values/mod.rs @@ -9,13 +9,13 @@ #![deny(missing_docs)] use Atom; -pub use cssparser::{RGBA, Token, Parser, serialize_identifier, BasicParseError, CowRcStr}; +pub use cssparser::{RGBA, Token, Parser, serialize_identifier, CowRcStr, SourceLocation}; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use std::ascii::AsciiExt; use std::fmt::{self, Debug}; use std::hash; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; pub mod animated; pub mod computed; @@ -57,9 +57,9 @@ pub enum Impossible {} impl Parse for Impossible { fn parse<'i, 't>( _context: &ParserContext, - _input: &mut Parser<'i, 't>) + input: &mut Parser<'i, 't>) -> Result> { - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -103,16 +103,17 @@ pub struct CustomIdent(pub Atom); impl CustomIdent { /// Parse an already-tokenizer identifier - pub fn from_ident<'i>(ident: &CowRcStr<'i>, excluding: &[&str]) -> Result> { + pub fn from_ident<'i>(location: SourceLocation, ident: &CowRcStr<'i>, excluding: &[&str]) + -> Result> { let valid = match_ignore_ascii_case! { ident, "initial" | "inherit" | "unset" | "default" => false, _ => true }; if !valid { - return Err(SelectorParseError::UnexpectedIdent(ident.clone()).into()); + return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); } if excluding.iter().any(|s| ident.eq_ignore_ascii_case(s)) { - Err(StyleParseError::UnspecifiedError.into()) + Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } else { Ok(CustomIdent(Atom::from(ident.as_ref()))) } @@ -139,7 +140,8 @@ pub enum KeyframesName { impl KeyframesName { /// https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-name pub fn from_ident(value: &str) -> Self { - let custom_ident = CustomIdent::from_ident(&value.into(), &["none"]).ok(); + let location = SourceLocation { line: 0, column: 0 }; + let custom_ident = CustomIdent::from_ident(location, &value.into(), &["none"]).ok(); match custom_ident { Some(ident) => KeyframesName::Ident(ident), None => KeyframesName::QuotedString(value.into()), @@ -182,10 +184,11 @@ impl hash::Hash for KeyframesName { impl Parse for KeyframesName { fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); match input.next() { - Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(s, &["none"])?)), + Ok(&Token::Ident(ref s)) => Ok(KeyframesName::Ident(CustomIdent::from_ident(location, s, &["none"])?)), Ok(&Token::QuotedString(ref s)) => Ok(KeyframesName::QuotedString(Atom::from(s.as_ref()))), - Ok(t) => Err(BasicParseError::UnexpectedToken(t.clone()).into()), + Ok(t) => Err(location.new_unexpected_token_error(t.clone())), Err(e) => Err(e.into()), } } diff --git a/servo/components/style/values/specified/align.rs b/servo/components/style/values/specified/align.rs index 9e2281bba43b..4996ed6f5df3 100644 --- a/servo/components/style/values/specified/align.rs +++ b/servo/components/style/values/specified/align.rs @@ -9,10 +9,10 @@ use cssparser::Parser; use gecko_bindings::structs; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use std::ascii::AsciiExt; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; bitflags! { /// Constants shared by multiple CSS Box Alignment properties @@ -201,7 +201,7 @@ impl Parse for AlignJustifyContent { } return Ok(AlignJustifyContent::new(fallback)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -239,7 +239,7 @@ impl Parse for AlignJustifySelf { if let Ok(value) = input.try(parse_overflow_self_position) { return Ok(AlignJustifySelf(value)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -277,7 +277,7 @@ impl Parse for AlignItems { if let Ok(value) = input.try(parse_overflow_self_position) { return Ok(AlignItems(value)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -326,7 +326,7 @@ impl Parse for JustifyItems { if let Ok(value) = parse_overflow_self_position(input) { return Ok(JustifyItems(value)) } - Err(StyleParseError::UnspecifiedError.into()) + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } @@ -351,7 +351,7 @@ fn parse_auto_normal_stretch_baseline<'i, 't>(input: &mut Parser<'i, 't>) return Ok(baseline); } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "auto" => Ok(ALIGN_AUTO), "normal" => Ok(ALIGN_NORMAL), "stretch" => Ok(ALIGN_STRETCH), @@ -364,7 +364,7 @@ fn parse_normal_stretch_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result Ok(ALIGN_NORMAL), "stretch" => Ok(ALIGN_STRETCH), } @@ -383,7 +383,7 @@ fn parse_normal_or_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { // FIXME: remove clone() when lifetimes are non-lexical - try_match_ident_ignore_ascii_case! { input.expect_ident()?.clone(), + try_match_ident_ignore_ascii_case! { input, "baseline" => Ok(ALIGN_BASELINE), "first" => { input.expect_ident_matching("baseline")?; @@ -398,7 +398,7 @@ fn parse_baseline<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_content_distribution<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "stretch" => Ok(ALIGN_STRETCH), "space-between" => Ok(ALIGN_SPACE_BETWEEN), "space-around" => Ok(ALIGN_SPACE_AROUND), @@ -421,12 +421,12 @@ fn parse_overflow_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result return Ok(overflow | content) } } - return Err(StyleParseError::UnspecifiedError.into()) + return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } // fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "start" => Ok(ALIGN_START), "end" => Ok(ALIGN_END), "flex-start" => Ok(ALIGN_FLEX_START), @@ -439,7 +439,7 @@ fn parse_content_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_overflow_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "safe" => Ok(ALIGN_SAFE), "unsafe" => Ok(ALIGN_UNSAFE), } @@ -460,12 +460,12 @@ fn parse_overflow_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "start" => Ok(ALIGN_START), "end" => Ok(ALIGN_END), "flex-start" => Ok(ALIGN_FLEX_START), @@ -480,7 +480,9 @@ fn parse_self_position<'i, 't>(input: &mut Parser<'i, 't>) -> Result(input: &mut Parser<'i, 't>) -> Result> { + let a_location = input.current_source_location(); let a = input.expect_ident()?.clone(); + let b_location = input.current_source_location(); let b = input.expect_ident()?; if a.eq_ignore_ascii_case("legacy") { (match_ignore_ascii_case! { &b, @@ -488,15 +490,15 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result Ok(ALIGN_LEGACY | ALIGN_RIGHT), "center" => Ok(ALIGN_LEGACY | ALIGN_CENTER), _ => Err(()) - }).map_err(|()| SelectorParseError::UnexpectedIdent(b.clone()).into()) + }).map_err(|()| b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone()))) } else if b.eq_ignore_ascii_case("legacy") { (match_ignore_ascii_case! { &a, "left" => Ok(ALIGN_LEGACY | ALIGN_LEFT), "right" => Ok(ALIGN_LEGACY | ALIGN_RIGHT), "center" => Ok(ALIGN_LEGACY | ALIGN_CENTER), _ => Err(()) - }).map_err(|()| SelectorParseError::UnexpectedIdent(a).into()) + }).map_err(|()| a_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(a))) } else { - Err(StyleParseError::UnspecifiedError.into()) + Err(a_location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } } diff --git a/servo/components/style/values/specified/angle.rs b/servo/components/style/values/specified/angle.rs index c1cb7505bf13..11ecd53f77e6 100644 --- a/servo/components/style/values/specified/angle.rs +++ b/servo/components/style/values/specified/angle.rs @@ -4,7 +4,7 @@ //! Specified angles. -use cssparser::{Parser, Token, BasicParseError}; +use cssparser::{Parser, Token}; use parser::{ParserContext, Parse}; use std::ascii::AsciiExt; use std::fmt; @@ -112,7 +112,7 @@ impl Parse for Angle { return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) } _ => Err(()) - }.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into()) + }.map_err(|()| input.new_unexpected_token_error(token.clone())) } } @@ -155,6 +155,6 @@ impl Angle { return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) } _ => Err(()) - }.map_err(|()| BasicParseError::UnexpectedToken(token.clone()).into()) + }.map_err(|()| input.new_unexpected_token_error(token.clone())) } } diff --git a/servo/components/style/values/specified/background.rs b/servo/components/style/values/specified/background.rs index c358feefaec6..dd9949adf268 100644 --- a/servo/components/style/values/specified/background.rs +++ b/servo/components/style/values/specified/background.rs @@ -6,7 +6,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseError; +use selectors::parser::SelectorParseErrorKind; use style_traits::ParseError; use values::generics::background::BackgroundSize as GenericBackgroundSize; use values::specified::length::LengthOrPercentageOrAuto; @@ -22,12 +22,13 @@ impl Parse for BackgroundSize { .unwrap_or(LengthOrPercentageOrAuto::Auto); return Ok(GenericBackgroundSize::Explicit { width, height }); } + let location = input.current_source_location(); let ident = input.expect_ident()?; (match_ignore_ascii_case! { &ident, "cover" => Ok(GenericBackgroundSize::Cover), "contain" => Ok(GenericBackgroundSize::Contain), _ => Err(()), - }).map_err(|()| SelectorParseError::UnexpectedIdent(ident.clone()).into()) + }).map_err(|()| location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) } } diff --git a/servo/components/style/values/specified/basic_shape.rs b/servo/components/style/values/specified/basic_shape.rs index cabed5994ed9..3332ce94d6a6 100644 --- a/servo/components/style/values/specified/basic_shape.rs +++ b/servo/components/style/values/specified/basic_shape.rs @@ -11,7 +11,7 @@ use cssparser::Parser; use parser::{Parse, ParserContext}; use std::borrow::Cow; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use values::computed::Percentage; use values::generics::basic_shape::{Circle as GenericCircle}; use values::generics::basic_shape::{ClippingShape as GenericClippingShape, Ellipse as GenericEllipse}; @@ -81,7 +81,7 @@ impl Parse for ShapeSource Ok(GeometryBox::FillBox), "stroke-box" => Ok(GeometryBox::StrokeBox), "view-box" => Ok(GeometryBox::ViewBox), @@ -101,6 +101,7 @@ impl Parse for GeometryBox { impl Parse for BasicShape { fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result> { + let location = input.current_source_location(); let function = input.expect_function()?.clone(); input.parse_nested_block(move |i| { (match_ignore_ascii_case! { &function, @@ -109,7 +110,7 @@ impl Parse for BasicShape { "ellipse" => return Ellipse::parse_function_arguments(context, i).map(GenericBasicShape::Ellipse), "polygon" => return Polygon::parse_function_arguments(context, i).map(GenericBasicShape::Polygon), _ => Err(()) - }).map_err(|()| StyleParseError::UnexpectedFunction(function.clone()).into()) + }).map_err(|()| location.new_custom_error(StyleParseErrorKind::UnexpectedFunction(function.clone()))) }) } } @@ -229,7 +230,7 @@ impl Parse for ShapeRadius { return Ok(GenericShapeRadius::Length(lop)) } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "closest-side" => Ok(GenericShapeRadius::ClosestSide), "farthest-side" => Ok(GenericShapeRadius::FarthestSide), } diff --git a/servo/components/style/values/specified/border.rs b/servo/components/style/values/specified/border.rs index aef0b0b28540..2223648c1a5b 100644 --- a/servo/components/style/values/specified/border.rs +++ b/servo/components/style/values/specified/border.rs @@ -62,7 +62,7 @@ impl BorderSideWidth { if let Ok(length) = input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) { return Ok(BorderSideWidth::Length(length)); } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "thin" => Ok(BorderSideWidth::Thin), "medium" => Ok(BorderSideWidth::Medium), "thick" => Ok(BorderSideWidth::Thick), diff --git a/servo/components/style/values/specified/box.rs b/servo/components/style/values/specified/box.rs index 53c5d086b33b..b5482b0cc2ba 100644 --- a/servo/components/style/values/specified/box.rs +++ b/servo/components/style/values/specified/box.rs @@ -23,7 +23,7 @@ impl Parse for VerticalAlign { return Ok(GenericVerticalAlign::Length(lop)); } - try_match_ident_ignore_ascii_case! { input.expect_ident()?, + try_match_ident_ignore_ascii_case! { input, "baseline" => Ok(GenericVerticalAlign::Baseline), "sub" => Ok(GenericVerticalAlign::Sub), "super" => Ok(GenericVerticalAlign::Super), diff --git a/servo/components/style/values/specified/calc.rs b/servo/components/style/values/specified/calc.rs index 3ac81d5903c9..dd0a6f8c6765 100644 --- a/servo/components/style/values/specified/calc.rs +++ b/servo/components/style/values/specified/calc.rs @@ -6,11 +6,11 @@ //! //! [calc]: https://drafts.csswg.org/css-values/#calc-notation -use cssparser::{Parser, Token, BasicParseError}; +use cssparser::{Parser, Token}; use parser::ParserContext; use std::ascii::AsciiExt; use std::fmt; -use style_traits::{ToCss, ParseError, StyleParseError}; +use style_traits::{ToCss, ParseError, StyleParseErrorKind}; use style_traits::values::specified::AllowedNumericType; use values::{CSSInteger, CSSFloat}; use values::computed; @@ -170,6 +170,7 @@ impl CalcNode { input: &mut Parser<'i, 't>, expected_unit: CalcUnit ) -> Result> { + let location = input.current_source_location(); // FIXME: remove early returns when lifetimes are non-lexical match (input.next()?, expected_unit) { (&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)), @@ -177,17 +178,17 @@ impl CalcNode { (&Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage) => { return NoCalcLength::parse_dimension(context, value, unit) .map(CalcNode::Length) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (&Token::Dimension { value, ref unit, .. }, CalcUnit::Angle) => { return Angle::parse_dimension(value, unit, /* from_calc = */ true) .map(CalcNode::Angle) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (&Token::Dimension { value, ref unit, .. }, CalcUnit::Time) => { return Time::parse_dimension(value, unit, /* from_calc = */ true) .map(CalcNode::Time) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } (&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) | (&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { @@ -195,7 +196,7 @@ impl CalcNode { } (&Token::ParenthesisBlock, _) => {} (&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {} - (t, _) => return Err(BasicParseError::UnexpectedToken(t.clone()).into()) + (t, _) => return Err(location.new_unexpected_token_error(t.clone())) } input.parse_nested_block(|i| { CalcNode::parse(context, i, expected_unit) @@ -236,7 +237,7 @@ impl CalcNode { CalcNode::Sub(Box::new(root), Box::new(rhs)); root = new_root; } - t => return Err(BasicParseError::UnexpectedToken(t).into()), + t => return Err(input.new_unexpected_token_error(t)), } } _ => { @@ -559,7 +560,7 @@ impl CalcNode { Self::parse(context, input, CalcUnit::Integer)? .to_number() .map(|n| n as CSSInteger) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ` | `. @@ -570,7 +571,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::LengthOrPercentage)? .to_length_or_percentage(clamping_mode) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for percentages. @@ -580,7 +581,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Percentage)? .to_percentage() - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ``. @@ -591,7 +592,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Length)? .to_length_or_percentage(clamping_mode) - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ``. @@ -601,7 +602,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Number)? .to_number() - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for ``. @@ -611,7 +612,7 @@ impl CalcNode { ) -> Result> { Self::parse(context, input, CalcUnit::Angle)? .to_angle() - .map_err(|()| StyleParseError::UnspecifiedError.into()) + .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } /// Convenience parsing function for `