diff options
56 files changed, 541 insertions, 457 deletions
diff --git a/.taskcluster.yml b/.taskcluster.yml index 360af84ad3a..1aba72b9aa6 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -8,7 +8,10 @@ policy: tasks: $let: task_common: - provisionerId: aws-provisioner-v1 + provisionerId: + $if: "taskcluster_root_url == 'https://taskcluster.net'" + then: aws-provisioner-v1 + else: proj-servo created: {$fromNow: ''} deadline: {$fromNow: '1 day'} extra: @@ -44,7 +47,18 @@ tasks: $if: "event.ref[:11] == 'refs/heads/'" then: "${event.ref[11:]}" in: - $if: "branch in ['auto', 'try', 'master'] || branch[:4] == 'try-'" + $if: >- + ( + taskcluster_root_url == 'https://community-tc.services.mozilla.com' && + branch == 'try-communitytc' + ) || ( + taskcluster_root_url == 'https://taskcluster.net' && + branch != 'try-communitytc' && + ( + branch in ['auto', 'try', 'master'] || + branch[:4] == 'try-' + ) + ) then: $mergeDeep: - {$eval: "task_common"} @@ -53,7 +67,10 @@ tasks: description: "" owner: ${event.pusher.name}@users.noreply.github.com source: ${event.compare} - workerType: servo-docker-worker + workerType: + $if: "taskcluster_root_url == 'https://taskcluster.net'" + then: servo-docker-worker + else: docker scopes: - "assume:repo:github.com/servo/servo:branch:${branch}" routes: @@ -82,7 +99,10 @@ tasks: description: "" owner: ${event.sender.login}@users.noreply.github.com source: ${event.pull_request.url} - workerType: servo-docker-untrusted + workerType: + $if: "taskcluster_root_url == 'https://taskcluster.net'" + then: servo-docker-untrusted + else: docker-untrusted scopes: - "assume:repo:github.com/servo/servo:pull-request" routes: diff --git a/Cargo.lock b/Cargo.lock index 8770e753390..02e09f392cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5069,7 +5069,7 @@ dependencies = [ [[package]] name = "surfman" version = "0.23.0" -source = "git+https://github.com/pcwalton/surfman#9d8b8062fba129f058b47388f4f0262a19ff65c3" +source = "git+https://github.com/jdm/rust-offscreen-rendering-context?branch=servo#dc5cf4369105f566fe95daac75bce748ae1a1c41" dependencies = [ "bitflags", "cgl 0.3.2", @@ -5995,7 +5995,7 @@ dependencies = [ [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#94bf6c6f64007a42d74ee4d1d162a5ed4d32d12a" +source = "git+https://github.com/jdm/webxr?branch=no-gl-readback2#12e04bafc2c692bce303b2a9fa5e811e76fbaa0e" dependencies = [ "bindgen", "euclid", @@ -6014,7 +6014,7 @@ dependencies = [ [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#94bf6c6f64007a42d74ee4d1d162a5ed4d32d12a" +source = "git+https://github.com/jdm/webxr?branch=no-gl-readback2#12e04bafc2c692bce303b2a9fa5e811e76fbaa0e" dependencies = [ "euclid", "ipc-channel", diff --git a/Cargo.toml b/Cargo.toml index ee35ba935a9..45a645eb194 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,12 @@ opt-level = 3 mio = { git = "https://github.com/servo/mio.git", branch = "servo" } # https://github.com/retep998/winapi-rs/pull/816 winapi = { git = "https://github.com/servo/winapi-rs", branch = "patch-1" } + + +# temporary +[patch."https://github.com/pcwalton/surfman"] +surfman = { git = "https://github.com/jdm/rust-offscreen-rendering-context", branch = "servo" } + +[patch."https://github.com/servo/webxr"] +webxr = { git = "https://github.com/jdm/webxr", branch = "no-gl-readback2" } +webxr-api = { git = "https://github.com/jdm/webxr", branch = "no-gl-readback2" } diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index af7147d8edb..1d5cbeaff1e 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -837,6 +837,7 @@ malloc_size_of_is_0!(app_units::Au); malloc_size_of_is_0!(cssparser::RGBA, cssparser::TokenSerializationType); +#[cfg(feature = "servo")] malloc_size_of_is_0!(csp::Destination); #[cfg(feature = "url")] diff --git a/components/script/dom/mouseevent.rs b/components/script/dom/mouseevent.rs index 48600f1155e..b6ba307af52 100644 --- a/components/script/dom/mouseevent.rs +++ b/components/script/dom/mouseevent.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods; use crate::dom::bindings::codegen::Bindings::MouseEventBinding; use crate::dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; use crate::dom::bindings::codegen::Bindings::UIEventBinding::UIEventMethods; @@ -12,6 +13,7 @@ use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::str::DOMString; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; +use crate::dom::node::Node; use crate::dom::uievent::UIEvent; use crate::dom::window::Window; use dom_struct::dom_struct; @@ -29,6 +31,10 @@ pub struct MouseEvent { client_y: Cell<i32>, page_x: Cell<i32>, page_y: Cell<i32>, + x: Cell<i32>, + y: Cell<i32>, + offset_x: Cell<i32>, + offset_y: Cell<i32>, ctrl_key: Cell<bool>, shift_key: Cell<bool>, alt_key: Cell<bool>, @@ -49,6 +55,10 @@ impl MouseEvent { client_y: Cell::new(0), page_x: Cell::new(0), page_y: Cell::new(0), + x: Cell::new(0), + y: Cell::new(0), + offset_x: Cell::new(0), + offset_y: Cell::new(0), ctrl_key: Cell::new(false), shift_key: Cell::new(false), alt_key: Cell::new(false), @@ -192,6 +202,56 @@ impl MouseEventMethods for MouseEvent { } } + // https://drafts.csswg.org/cssom-view/#dom-mouseevent-x + fn X(&self) -> i32 { + self.client_x.get() + } + + // https://drafts.csswg.org/cssom-view/#dom-mouseevent-y + fn Y(&self) -> i32 { + self.client_y.get() + } + + // https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx + fn OffsetX(&self) -> i32 { + let event = self.upcast::<Event>(); + if event.dispatching() { + match event.GetTarget() { + Some(target) => { + if let Some(node) = target.downcast::<Node>() { + let rect = node.client_rect(); + self.client_x.get() - rect.origin.x + } else { + self.offset_x.get() + } + }, + None => self.offset_x.get(), + } + } else { + self.PageX() + } + } + + // https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsety + fn OffsetY(&self) -> i32 { + let event = self.upcast::<Event>(); + if event.dispatching() { + match event.GetTarget() { + Some(target) => { + if let Some(node) = target.downcast::<Node>() { + let rect = node.client_rect(); + self.client_y.get() - rect.origin.y + } else { + self.offset_y.get() + } + }, + None => self.offset_y.get(), + } + } else { + self.PageY() + } + } + // https://w3c.github.io/uievents/#widl-MouseEvent-ctrlKey fn CtrlKey(&self) -> bool { self.ctrl_key.get() diff --git a/components/script/dom/webidls/MouseEvent.webidl b/components/script/dom/webidls/MouseEvent.webidl index 253463e7eae..0b7cb644368 100644 --- a/components/script/dom/webidls/MouseEvent.webidl +++ b/components/script/dom/webidls/MouseEvent.webidl @@ -12,6 +12,10 @@ interface MouseEvent : UIEvent { readonly attribute long clientY; readonly attribute long pageX; readonly attribute long pageY; + readonly attribute long x; + readonly attribute long y; + readonly attribute long offsetX; + readonly attribute long offsetY; readonly attribute boolean ctrlKey; readonly attribute boolean shiftKey; readonly attribute boolean altKey; diff --git a/components/selectors/context.rs b/components/selectors/context.rs index d159891ff02..44d586c8d84 100644 --- a/components/selectors/context.rs +++ b/components/selectors/context.rs @@ -189,15 +189,6 @@ where } } - /// Override the quirks mode we're matching against. - /// - /// FIXME(emilio): This is a hack for XBL quirks-mode mismatches. - #[inline] - pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) { - self.quirks_mode = quirks_mode; - self.classes_and_ids_case_sensitivity = quirks_mode.classes_and_ids_case_sensitivity(); - } - /// Whether we're matching a nested selector. #[inline] pub fn is_nested(&self) -> bool { diff --git a/components/selectors/matching.rs b/components/selectors/matching.rs index 45acc13e7e1..49b7f3dbd32 100644 --- a/components/selectors/matching.rs +++ b/components/selectors/matching.rs @@ -667,7 +667,7 @@ where match *selector { Component::Combinator(_) => unreachable!(), - Component::Part(ref part) => element.is_part(part), + Component::Part(ref parts) => parts.iter().all(|part| element.is_part(part)), Component::Slotted(ref selector) => { // <slots> are never flattened tree slottables. !element.is_html_slot_element() && diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 982dff793a8..507121bbf97 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -607,7 +607,7 @@ impl<Impl: SelectorImpl> Selector<Impl> { } #[inline] - pub fn part(&self) -> Option<&Impl::PartName> { + pub fn parts(&self) -> Option<&[Impl::PartName]> { if !self.is_part() { return None; } @@ -1013,7 +1013,7 @@ pub enum Component<Impl: SelectorImpl> { Slotted(Selector<Impl>), /// The `::part` pseudo-element. /// https://drafts.csswg.org/css-shadow-parts/#part - Part(#[shmem(field_bound)] Impl::PartName), + Part(#[shmem(field_bound)] Box<[Impl::PartName]>), /// The `:host` pseudo-class: /// /// https://drafts.csswg.org/css-scoping/#host-selector @@ -1302,9 +1302,14 @@ impl<Impl: SelectorImpl> ToCss for Component<Impl> { selector.to_css(dest)?; dest.write_char(')') }, - Part(ref part_name) => { + Part(ref part_names) => { dest.write_str("::part(")?; - display_to_css_identifier(part_name, dest)?; + for (i, name) in part_names.iter().enumerate() { + if i != 0 { + dest.write_char(' ')?; + } + display_to_css_identifier(name, dest)?; + } dest.write_char(')') }, PseudoElement(ref p) => p.to_css(dest), @@ -1626,7 +1631,7 @@ enum SimpleSelectorParseResult<Impl: SelectorImpl> { SimpleSelector(Component<Impl>), PseudoElement(Impl::PseudoElement), SlottedPseudo(Selector<Impl>), - PartPseudo(Impl::PartName), + PartPseudo(Box<[Impl::PartName]>), } #[derive(Debug)] @@ -2029,10 +2034,10 @@ where SimpleSelectorParseResult::SimpleSelector(s) => { builder.push_simple_selector(s); }, - SimpleSelectorParseResult::PartPseudo(part_name) => { + SimpleSelectorParseResult::PartPseudo(part_names) => { state.insert(SelectorParsingState::AFTER_PART); builder.push_combinator(Combinator::Part); - builder.push_simple_selector(Component::Part(part_name)); + builder.push_simple_selector(Component::Part(part_names)); }, SimpleSelectorParseResult::SlottedPseudo(selector) => { state.insert(SelectorParsingState::AFTER_SLOTTED); @@ -2193,10 +2198,15 @@ where input.new_custom_error(SelectorParseErrorKind::InvalidState) ); } - let name = input.parse_nested_block(|input| { - Ok(input.expect_ident()?.as_ref().into()) + let names = input.parse_nested_block(|input| { + let mut result = Vec::with_capacity(1); + result.push(input.expect_ident()?.as_ref().into()); + while !input.is_exhausted() { + result.push(input.expect_ident()?.as_ref().into()); + } + Ok(result.into_boxed_slice()) })?; - return Ok(Some(SimpleSelectorParseResult::PartPseudo(name))); + return Ok(Some(SimpleSelectorParseResult::PartPseudo(names))); } if P::parse_slotted(parser) && name.eq_ignore_ascii_case("slotted") { if !state.allows_slotted() { @@ -3051,8 +3061,7 @@ pub mod tests { assert!(parse("::part()").is_err()); assert!(parse("::part(42)").is_err()); - // Though note https://github.com/w3c/csswg-drafts/issues/3502 - assert!(parse("::part(foo bar)").is_err()); + assert!(parse("::part(foo bar)").is_ok()); assert!(parse("::part(foo):hover").is_ok()); assert!(parse("::part(foo) + bar").is_err()); diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 1a727387b7e..f15c64e2f56 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -25,7 +25,6 @@ servo-layout-2020 = [] gecko_debug = [] gecko_refcount_logging = [] gecko_profiler = [] -moz_xbl = [] [dependencies] app_units = "0.7" diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index 86d2098d063..a502b7d45f9 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -109,7 +109,10 @@ fn add_headers_recursively(path: PathBuf, added_paths: &mut HashSet<PathBuf>) { fn add_include(name: &str) -> String { let mut added_paths = ADDED_PATHS.lock().unwrap(); - let file = search_include(name).expect("Include not found!"); + let file = match search_include(name) { + Some(file) => file, + None => panic!("Include not found: {}", name), + }; let result = String::from(file.to_str().unwrap()); add_headers_recursively(file, &mut *added_paths); result diff --git a/components/style/dom.rs b/components/style/dom.rs index 7d56cc543e7..2ea64bbb3dc 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -776,14 +776,6 @@ pub trait TElement: return data.hint.has_animation_hint(); } - /// Returns the anonymous content for the current element's XBL binding, - /// given if any. - /// - /// This is used in Gecko for XBL. - fn xbl_binding_anonymous_content(&self) -> Option<Self::ConcreteNode> { - None - } - /// The shadow root this element is a host of. fn shadow_root(&self) -> Option<<Self::ConcreteNode as TNode>::ConcreteShadowRoot>; diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index ce084c9d16b..e3de8dbfaaa 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -598,8 +598,7 @@ lazy_static! { atom!("device-pixel-ratio"), AllowsRanges::Yes, Evaluator::Float(eval_device_pixel_ratio), - ParsingRequirements::WEBKIT_PREFIX | - ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED, + ParsingRequirements::WEBKIT_PREFIX, ), // -webkit-transform-3d. feature!( diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index fd0ac9db8a6..c2c4a0c0feb 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -44,8 +44,6 @@ use crate::gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWThe use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsChangeHint; -#[cfg(feature = "moz_xbl")] -use crate::gecko_bindings::structs::nsXBLBinding as RawGeckoXBLBinding; use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme; use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT; @@ -86,8 +84,6 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::mem; use std::ptr; -#[cfg(not(feature = "moz_xbl"))] -use values::Impossible; #[inline] fn elements_with_id<'a, 'le>( @@ -317,7 +313,7 @@ impl<'ln> GeckoNode<'ln> { } if let Some(parent) = parent_el { - if parent.shadow_root().is_some() || parent.xbl_binding().is_some() { + if parent.shadow_root().is_some() { return false; } } @@ -530,52 +526,6 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> { } } -/// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer. -#[cfg(feature = "moz_xbl")] -#[derive(Clone, Copy)] -pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding); - -#[cfg(feature = "moz_xbl")] -impl<'lb> GeckoXBLBinding<'lb> { - #[inline] - fn base_binding(&self) -> Option<Self> { - unsafe { self.0.mNextBinding.mRawPtr.as_ref().map(GeckoXBLBinding) } - } - - #[inline] - fn anon_content(&self) -> *const nsIContent { - self.0.mContent.raw::<nsIContent>() - } - - // This duplicates the logic in Gecko's - // nsBindingManager::GetBindingWithContent. - fn binding_with_content(&self) -> Option<Self> { - let mut binding = *self; - loop { - if !binding.anon_content().is_null() { - return Some(binding); - } - binding = binding.base_binding()?; - } - } -} - -/// A stub wraper for GeckoXBLBinding. -#[cfg(not(feature = "moz_xbl"))] -pub struct GeckoXBLBinding<'lb>(&'lb Impossible); - -#[cfg(not(feature = "moz_xbl"))] -impl<'lb> GeckoXBLBinding<'lb> { - #[inline] - fn anon_content(&self) -> *const nsIContent { - match *self.0 {} - } - - fn binding_with_content(&self) -> Option<Self> { - None - } -} - /// A simple wrapper over a non-null Gecko `Element` pointer. #[derive(Clone, Copy)] pub struct GeckoElement<'le>(pub &'le RawGeckoElement); @@ -701,39 +651,6 @@ impl<'le> GeckoElement<'le> { }) } - #[cfg(feature = "moz_xbl")] - #[inline] - fn may_be_in_binding_manager(&self) -> bool { - self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) != 0 - } - - #[cfg(feature = "moz_xbl")] - #[inline] - fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> { - if !self.may_be_in_binding_manager() { - return None; - } - - let slots = self.extended_slots()?; - unsafe { slots.mXBLBinding.mRawPtr.as_ref().map(GeckoXBLBinding) } - } - - #[cfg(not(feature = "moz_xbl"))] - #[inline] - fn xbl_binding(&self) -> Option<GeckoXBLBinding<'le>> { - None - } - - #[inline] - fn xbl_binding_with_content(&self) -> Option<GeckoXBLBinding<'le>> { - self.xbl_binding().and_then(|b| b.binding_with_content()) - } - - #[inline] - fn has_xbl_binding_with_content(&self) -> bool { - !self.xbl_binding_with_content().is_none() - } - #[inline] fn namespace_id(&self) -> i32 { self.as_node().node_info().mInner.mNamespaceID @@ -1107,9 +1024,8 @@ impl<'le> TElement for GeckoElement<'le> { // This condition is similar to the check that // StyleChildrenIterator::IsNeeded does, except that it might return // true if we used to (but no longer) have anonymous content from - // ::before/::after, XBL bindings, or nsIAnonymousContentCreators. + // ::before/::after, or nsIAnonymousContentCreators. if self.is_in_anonymous_subtree() || - self.has_xbl_binding_with_content() || self.is_html_slot_element() || self.shadow_root().is_some() || self.may_have_anonymous_children() @@ -1595,11 +1511,6 @@ impl<'le> TElement for GeckoElement<'le> { self.may_have_animations() && unsafe { Gecko_ElementHasCSSTransitions(self.0) } } - fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> { - self.xbl_binding_with_content() - .map(|b| unsafe { GeckoNode::from_content(&*b.anon_content()) }) - } - fn might_need_transitions_update( &self, old_style: Option<&ComputedValues>, diff --git a/components/style/invalidation/element/document_state.rs b/components/style/invalidation/element/document_state.rs index 77b205f1b26..4e29e91eb0e 100644 --- a/components/style/invalidation/element/document_state.rs +++ b/components/style/invalidation/element/document_state.rs @@ -31,9 +31,6 @@ impl Default for InvalidationMatchingData { /// An invalidation processor for style changes due to state and attribute /// changes. pub struct DocumentStateInvalidationProcessor<'a, E: TElement, I> { - // TODO(emilio): We might want to just run everything for every possible - // binding along with the document data, or just apply the XBL stuff to the - // bound subtrees. rules: I, matching_context: MatchingContext<'a, E::Impl>, document_states_changed: DocumentState, diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs index 2889c3e7b9d..3487d7b9353 100644 --- a/components/style/invalidation/element/invalidator.rs +++ b/components/style/invalidation/element/invalidator.rs @@ -28,7 +28,7 @@ where /// Whether the invalidation processor only cares about light-tree /// descendants of a given element, that is, doesn't invalidate - /// pseudo-elements, NAC, or XBL anon content. + /// pseudo-elements, NAC, shadow dom... fn light_tree_only(&self) -> bool { false } @@ -455,11 +455,6 @@ where let mut sibling_invalidations = InvalidationVector::new(); for child in parent.dom_children() { - // TODO(emilio): We handle <xbl:children> fine, because they appear - // in selector-matching (note bug 1374247, though). - // - // This probably needs a shadow root check on `child` here, and - // recursing if that's the case. let child = match child.as_element() { Some(e) => e, None => continue, @@ -574,13 +569,6 @@ where any_descendant |= self.invalidate_dom_descendants_of(root.as_node(), invalidations); } - // This is needed for XBL (technically) unconditionally, because XBL - // bindings do not block combinators in any way. However this is kinda - // broken anyway, since we should be looking at XBL rules too. - if let Some(anon_content) = self.element.xbl_binding_anonymous_content() { - any_descendant |= self.invalidate_dom_descendants_of(anon_content, invalidations); - } - if let Some(marker) = self.element.marker_pseudo_element() { any_descendant |= self.invalidate_pseudo_element_or_nac(marker, invalidations); } diff --git a/components/style/lib.rs b/components/style/lib.rs index 35070b0f254..354950f9c15 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -78,7 +78,6 @@ extern crate parking_lot; extern crate precomputed_hash; extern crate rayon; extern crate selectors; -#[cfg(feature = "servo")] #[macro_use] extern crate serde; pub extern crate servo_arc; diff --git a/components/style/media_queries/media_feature.rs b/components/style/media_queries/media_feature.rs index c5251f7419f..a273e7f51be 100644 --- a/components/style/media_queries/media_feature.rs +++ b/components/style/media_queries/media_feature.rs @@ -123,9 +123,6 @@ bitflags! { const CHROME_AND_UA_ONLY = 1 << 0; /// The feature requires a -webkit- prefix. const WEBKIT_PREFIX = 1 << 1; - /// The feature requires the webkit-device-pixel-ratio preference to be - /// enabled. - const WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED = 1 << 2; } } diff --git a/components/style/media_queries/media_feature_expression.rs b/components/style/media_queries/media_feature_expression.rs index d4124450dc5..4704fab0ffc 100644 --- a/components/style/media_queries/media_feature_expression.rs +++ b/components/style/media_queries/media_feature_expression.rs @@ -242,6 +242,17 @@ fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, () })) } +#[allow(unused_variables)] +fn disabled_by_pref(feature: &Atom) -> bool { + #[cfg(feature = "gecko")] + { + if *feature == atom!("-moz-touch-enabled") { + return !static_prefs::pref!("layout.css.moz-touch-enabled.enabled"); + } + } + false +} + impl MediaFeatureExpression { fn new( feature_index: usize, @@ -279,81 +290,53 @@ impl MediaFeatureExpression { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - // FIXME: remove extra indented block when lifetimes are non-lexical - let feature_index; - let feature; - let range; - { - let location = input.current_source_location(); - let ident = input.expect_ident()?; + let mut requirements = ParsingRequirements::empty(); + let location = input.current_source_location(); + let ident = input.expect_ident()?; - let mut requirements = ParsingRequirements::empty(); - - if context.in_ua_or_chrome_sheet() { - requirements.insert(ParsingRequirements::CHROME_AND_UA_ONLY); - } + if context.in_ua_or_chrome_sheet() { + requirements.insert(ParsingRequirements::CHROME_AND_UA_ONLY); + } - let result = { - let mut feature_name = &**ident; + let mut feature_name = &**ident; - #[cfg(feature = "gecko")] - { - if starts_with_ignore_ascii_case(feature_name, "-webkit-") { - feature_name = &feature_name[8..]; - requirements.insert(ParsingRequirements::WEBKIT_PREFIX); - if static_prefs::pref!("layout.css.prefixes.device-pixel-ratio-webkit") { - requirements.insert( - ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED, - ); - } - } - } + if starts_with_ignore_ascii_case(feature_name, "-webkit-") { + feature_name = &feature_name[8..]; + requirements.insert(ParsingRequirements::WEBKIT_PREFIX); + } - let range = if starts_with_ignore_ascii_case(feature_name, "min-") { - feature_name = &feature_name[4..]; - Some(Range::Min) - } else if starts_with_ignore_ascii_case(feature_name, "max-") { - feature_name = &feature_name[4..]; - Some(Range::Max) - } else { - None - }; - - let atom = Atom::from(string_as_ascii_lowercase(feature_name)); - match MEDIA_FEATURES - .iter() - .enumerate() - .find(|(_, f)| f.name == atom) - { - Some((i, f)) => Ok((i, f, range)), - None => Err(()), - } - }; + let range = if starts_with_ignore_ascii_case(feature_name, "min-") { + feature_name = &feature_name[4..]; + Some(Range::Min) + } else if starts_with_ignore_ascii_case(feature_name, "max-") { + feature_name = &feature_name[4..]; + Some(Range::Max) + } else { + None + }; - match result { - Ok((i, f, r)) => { - feature_index = i; - feature = f; - range = r; - }, - Err(()) => { - return Err(location.new_custom_error( - StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )); - }, - } + let atom = Atom::from(string_as_ascii_lowercase(feature_name)); - if !(feature.requirements & !requirements).is_empty() { + let (feature_index, feature) = match MEDIA_FEATURES + .iter() + .enumerate() + .find(|(_, f)| f.name == atom) + { + Some((i, f)) => (i, f), + None => { return Err(location.new_custom_error( StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )); - } + )) + }, + }; - if range.is_some() && !feature.allows_ranges() { - return Err(location.new_custom_error( - StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )); - } + if disabled_by_pref(&feature.name) || + !requirements.contains(feature.requirements) || + (range.is_some() && !feature.allows_ranges()) + { + return Err(location.new_custom_error( + StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), + )); } let operator = input.try(consume_operation_or_colon); diff --git a/components/style/properties/counted_unknown_properties.py b/components/style/properties/counted_unknown_properties.py index 826bbf740a3..de36199e77a 100644 --- a/components/style/properties/counted_unknown_properties.py +++ b/components/style/properties/counted_unknown_properties.py @@ -13,7 +13,6 @@ # "offset" COUNTED_UNKNOWN_PROPERTIES = [ "-webkit-font-smoothing", - "zoom", "-webkit-tap-highlight-color", "speak", "text-size-adjust", diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 97321fcbd38..7783c7eebd3 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -276,11 +276,6 @@ impl ComputedValuesInner { pub fn get_raw_visited_style(&self) -> &Option<RawOffsetArc<ComputedValues>> { &self.visited_style } - - #[allow(non_snake_case)] - pub fn has_moz_binding(&self) -> bool { - !self.get_box().gecko.mBinding.is_none() - } } <%def name="declare_style_struct(style_struct)"> diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 815dcab313e..a68b179c4c0 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -396,7 +396,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", - flags="CREATES_STACKING_CONTEXT FIXPOS_CB", + flags="CREATES_STACKING_CONTEXT FIXPOS_CB CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-path-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -409,6 +409,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-distance-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -421,6 +422,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-rotate-property", servo_restyle_damage="reflow_out_of_flow" )} @@ -433,6 +435,7 @@ ${helpers.predefined_type( engines="gecko", animation_value_type="ComputedValue", gecko_pref="layout.css.motion-path.enabled", + flags="CAN_ANIMATE_ON_COMPOSITOR", spec="https://drafts.fxtf.org/motion-1/#offset-anchor-property", servo_restyle_damage="reflow_out_of_flow", boxed=True @@ -453,7 +456,6 @@ ${helpers.predefined_type( "ScrollSnapAlign", "computed::ScrollSnapAlign::none()", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align", animation_value_type="discrete", )} @@ -631,18 +633,6 @@ ${helpers.predefined_type( gecko_ffi_name="mAppearance", )} -${helpers.predefined_type( - "-moz-binding", - "url::UrlOrNone", - "computed::url::UrlOrNone::none()", - engines="gecko", - animation_value_type="none", - gecko_ffi_name="mBinding", - gecko_pref="layout.css.moz-binding.content.enabled", - enabled_in="chrome", - spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-binding)", -)} - ${helpers.single_keyword( "-moz-orient", "inline block horizontal vertical", diff --git a/components/style/properties/longhands/margin.mako.rs b/components/style/properties/longhands/margin.mako.rs index 4ad056f05b2..80c765faab7 100644 --- a/components/style/properties/longhands/margin.mako.rs +++ b/components/style/properties/longhands/margin.mako.rs @@ -34,7 +34,6 @@ "Length", "computed::Length::zero()", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", logical=side[1], logical_group="scroll-margin", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-%s" % side[0], diff --git a/components/style/properties/longhands/padding.mako.rs b/components/style/properties/longhands/padding.mako.rs index 3089c0acb92..79668df7bbf 100644 --- a/components/style/properties/longhands/padding.mako.rs +++ b/components/style/properties/longhands/padding.mako.rs @@ -33,7 +33,6 @@ "NonNegativeLengthPercentageOrAuto", "computed::NonNegativeLengthPercentageOrAuto::auto()", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", logical=side[1], logical_group="scroll-padding", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-%s" % side[0], diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 24dfe1c57b6..fe4d3cceaf8 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1876,7 +1876,19 @@ impl PropertyId { if let Some(id) = static_id(property_name) { return Ok(match *id { StaticId::Longhand(id) => PropertyId::Longhand(id), - StaticId::Shorthand(id) => PropertyId::Shorthand(id), + StaticId::Shorthand(id) => { + #[cfg(feature = "gecko")] + { + // We want to count `zoom` even if disabled. + if matches!(id, ShorthandId::Zoom) { + if let Some(counters) = use_counters { + counters.non_custom_properties.record(id.into()); + } + } + } + + PropertyId::Shorthand(id) + }, StaticId::LonghandAlias(id, alias) => PropertyId::LonghandAlias(id, alias), StaticId::ShorthandAlias(id, alias) => PropertyId::ShorthandAlias(id, alias), StaticId::CountedUnknown(unknown_prop) => { @@ -3065,10 +3077,6 @@ impl ComputedValuesInner { self.rules.as_ref().unwrap() } - /// Whether this style has a -moz-binding value. This is always false for - /// Servo for obvious reasons. - pub fn has_moz_binding(&self) -> bool { false } - #[inline] /// Returns whether the "content" property for the given style is completely /// ineffective, and would yield an empty `::before` or `::after` diff --git a/components/style/properties/shorthands/box.mako.rs b/components/style/properties/shorthands/box.mako.rs index 84d2cb220bd..7b4ce131922 100644 --- a/components/style/properties/shorthands/box.mako.rs +++ b/components/style/properties/shorthands/box.mako.rs @@ -441,3 +441,58 @@ ${helpers.two_properties_shorthand( } } </%helpers:shorthand> + +<%helpers:shorthand name="zoom" engines="gecko" + sub_properties="transform transform-origin" + gecko_pref="layout.css.zoom-transform-hack.enabled" + flags="SHORTHAND_IN_GETCS IS_LEGACY_SHORTHAND" + spec="Not a standard, only a compat hack"> + use crate::parser::Parse; + use crate::values::specified::{Number, NumberOrPercentage, TransformOrigin}; + use crate::values::generics::transform::{Transform, TransformOperation}; + + pub fn parse_value<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result<Longhands, ParseError<'i>> { + let zoom = match input.try(|input| NumberOrPercentage::parse(context, input)) { + Ok(number_or_percent) => number_or_percent.to_number(), + Err(..) => { + input.expect_ident_matching("normal")?; + Number::new(1.0) + }, + }; + + // Make sure that the initial value matches the values for the + // longhands, just for general sanity. + // + // FIXME: Should we just do this for the "normal" case? Seems weird + // either way, so maybe not? + Ok(if zoom.get() == 1.0 { + expanded! { + transform: Transform::none(), + transform_origin: TransformOrigin::initial_value(), + } + } else { + expanded! { + transform: Transform(vec![TransformOperation::Scale(zoom, zoom)].into()), + transform_origin: TransformOrigin::zero_zero(), + } + }) + } + + impl<'a> ToCss for LonghandsToSerialize<'a> { + fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: fmt::Write { + if self.transform.0.is_empty() && *self.transform_origin == TransformOrigin::initial_value() { + return 1.0f32.to_css(dest); + } + if *self.transform_origin != TransformOrigin::zero_zero() { + return Ok(()) + } + match &*self.transform.0 { + [TransformOperation::Scale(x, y)] if x == y => x.to_css(dest), + _ => Ok(()), + } + } + } +</%helpers:shorthand> diff --git a/components/style/properties/shorthands/margin.mako.rs b/components/style/properties/shorthands/margin.mako.rs index 5d5f2101563..128fc5fb303 100644 --- a/components/style/properties/shorthands/margin.mako.rs +++ b/components/style/properties/shorthands/margin.mako.rs @@ -38,7 +38,6 @@ ${helpers.four_sides_shorthand( "specified::Length::parse", engines="gecko", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin", - gecko_pref="layout.css.scroll-snap-v1.enabled", )} ${helpers.two_properties_shorthand( @@ -48,7 +47,6 @@ ${helpers.two_properties_shorthand( "specified::Length::parse", engines="gecko", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-block", - gecko_pref="layout.css.scroll-snap-v1.enabled", )} ${helpers.two_properties_shorthand( @@ -58,5 +56,4 @@ ${helpers.two_properties_shorthand( "specified::Length::parse", engines="gecko", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-margin-inline", - gecko_pref="layout.css.scroll-snap-v1.enabled", )} diff --git a/components/style/properties/shorthands/padding.mako.rs b/components/style/properties/shorthands/padding.mako.rs index 02db51a88d6..4d2ea361e15 100644 --- a/components/style/properties/shorthands/padding.mako.rs +++ b/components/style/properties/shorthands/padding.mako.rs @@ -36,7 +36,6 @@ ${helpers.four_sides_shorthand( "scroll-padding-%s", "specified::NonNegativeLengthPercentageOrAuto::parse", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding" )} @@ -46,7 +45,6 @@ ${helpers.two_properties_shorthand( "scroll-padding-block-end", "specified::NonNegativeLengthPercentageOrAuto::parse", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-block" )} @@ -56,7 +54,6 @@ ${helpers.two_properties_shorthand( "scroll-padding-inline-end", "specified::NonNegativeLengthPercentageOrAuto::parse", engines="gecko", - gecko_pref="layout.css.scroll-snap-v1.enabled", spec="https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-padding-inline" )} diff --git a/components/style/stylist.rs b/components/style/stylist.rs index ed9af91af14..ab6fe309f3f 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -2032,11 +2032,17 @@ impl CascadeData { // Part is special, since given it doesn't have any // selectors inside, it's not worth using a whole // SelectorMap for it. - if let Some(part) = selector.part() { + if let Some(parts) = selector.parts() { + // ::part() has all semantics, so we just need to + // put any of them in the selector map. + // + // We choose the last one quite arbitrarily, + // expecting it's slightly more likely to be more + // specific. self.part_rules .get_or_insert_with(|| Box::new(Default::default())) .for_insertion(pseudo_element) - .try_entry(part.clone())? + .try_entry(parts.last().unwrap().clone())? .or_insert_with(SmallVec::new) .try_push(rule)?; } else { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 1f64e7f22f0..360f5b6a25c 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -267,7 +267,6 @@ pub trait DomTraversal<E: TElement>: Sync { context: &mut StyleContext<E>, parent: E, parent_data: &ElementData, - is_initial_style: bool, ) -> bool { debug_assert!( parent.has_current_styles_for_traversal(parent_data, context.shared.traversal_flags) @@ -279,21 +278,6 @@ pub trait DomTraversal<E: TElement>: Sync { return true; } - // Gecko-only XBL handling. - // - // When we apply the XBL binding during frame construction, we restyle - // the whole subtree again if the binding is valid, so assuming it's - // likely to load valid bindings, we avoid wasted work here, which may - // be a very big perf hit when elements with bindings are nested - // heavily. - if cfg!(feature = "gecko") && - is_initial_style && - parent_data.styles.primary().has_moz_binding() - { - debug!("Parent {:?} has XBL binding, deferring traversal", parent); - return true; - } - return false; } @@ -520,8 +504,8 @@ pub fn recalc_style_at<E, D, F>( !child_cascade_requirement.can_skip_cascade() || is_servo_nonincremental_layout(); - traverse_children = traverse_children && - !traversal.should_cull_subtree(context, element, &data, is_initial_style); + traverse_children = + traverse_children && !traversal.should_cull_subtree(context, element, &data); // Examine our children, and enqueue the appropriate ones for traversal. if traverse_children { diff --git a/components/style/values/computed/angle.rs b/components/style/values/computed/angle.rs index d8cdefb5263..ea321d22337 100644 --- a/components/style/values/computed/angle.rs +++ b/components/style/values/computed/angle.rs @@ -13,16 +13,17 @@ use std::{f32, f64}; use style_traits::{CssWriter, ToCss}; /// A computed angle in degrees. -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( Add, Animate, Clone, Copy, Debug, + Deserialize, MallocSizeOf, PartialEq, PartialOrd, + Serialize, ToAnimatedZero, ToResolvedValue, )] diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 6d61198d364..53cf7cbd696 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -75,7 +75,9 @@ impl ToComputedValue for specified::Length { /// /// https://drafts.csswg.org/css-values-4/#typedef-length-percentage #[allow(missing_docs)] -#[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero, ToResolvedValue)] +#[derive( + Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize, ToAnimatedZero, ToResolvedValue, +)] #[repr(C)] pub struct LengthPercentage { length: Length, @@ -605,15 +607,16 @@ impl Size { } /// The computed `<length>` value. -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( Animate, Clone, ComputeSquaredDistance, Copy, + Deserialize, MallocSizeOf, PartialEq, PartialOrd, + Serialize, ToAnimatedValue, ToAnimatedZero, ToResolvedValue, diff --git a/components/style/values/computed/percentage.rs b/components/style/values/computed/percentage.rs index c22f8ed5683..b5a734367b2 100644 --- a/components/style/values/computed/percentage.rs +++ b/components/style/values/computed/percentage.rs @@ -12,7 +12,6 @@ use std::fmt; use style_traits::{CssWriter, ToCss}; /// A computed percentage. -#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[derive( Animate, Clone, @@ -20,9 +19,11 @@ use style_traits::{CssWriter, ToCss}; Copy, Debug, Default, + Deserialize, MallocSizeOf, PartialEq, PartialOrd, + Serialize, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, diff --git a/components/style/values/generics/motion.rs b/components/style/values/generics/motion.rs index e9ccc045186..685eaad43e2 100644 --- a/components/style/values/generics/motion.rs +++ b/components/style/values/generics/motion.rs @@ -14,9 +14,11 @@ use crate::values::specified::SVGPathData; Clone, Copy, Debug, + Deserialize, MallocSizeOf, Parse, PartialEq, + Serialize, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, @@ -41,8 +43,10 @@ pub enum RaySize { Clone, ComputeSquaredDistance, Debug, + Deserialize, MallocSizeOf, PartialEq, + Serialize, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index acad3383014..01e5890d015 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -119,6 +119,10 @@ pub enum SystemColor { Buttonshadow, Buttontext, Captiontext, + #[parse(aliases = "-moz-field")] + Field, + #[parse(aliases = "-moz-fieldtext")] + Fieldtext, Graytext, Highlight, Highlighttext, @@ -139,8 +143,6 @@ pub enum SystemColor { Windowframe, Windowtext, MozButtondefault, - MozField, - MozFieldtext, MozDialog, MozDialogtext, /// Used to highlight valid regions to drop something onto. diff --git a/components/style/values/specified/image.rs b/components/style/values/specified/image.rs index c7a6ac1870c..7488e631e54 100644 --- a/components/style/values/specified/image.rs +++ b/components/style/values/specified/image.rs @@ -435,10 +435,7 @@ impl Gradient { let (color, mut p) = i.parse_nested_block(|i| { let p = match_ignore_ascii_case! { &function, "color-stop" => { - let p = match NumberOrPercentage::parse(context, i)? { - NumberOrPercentage::Number(number) => Percentage::new(number.value), - NumberOrPercentage::Percentage(p) => p, - }; + let p = NumberOrPercentage::parse(context, i)?.to_percentage(); i.expect_comma()?; p }, diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 160295c8f55..d10a399dd01 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -179,13 +179,26 @@ impl Parse for Number { impl Number { /// Returns a new number with the value `val`. - pub fn new(val: CSSFloat) -> Self { - Number { - value: val, - calc_clamping_mode: None, + fn new_with_clamping_mode( + value: CSSFloat, + calc_clamping_mode: Option<AllowedNumericType>, + ) -> Self { + Self { + value, + calc_clamping_mode, } } + /// Returns this percentage as a number. + pub fn to_percentage(&self) -> Percentage { + Percentage::new_with_clamping_mode(self.value, self.calc_clamping_mode) + } + + /// Returns a new number with the value `val`. + pub fn new(val: CSSFloat) -> Self { + Self::new_with_clamping_mode(val, None) + } + /// Returns whether this number came from a `calc()` expression. #[inline] pub fn was_calc(&self) -> bool { @@ -370,6 +383,22 @@ impl NumberOrPercentage { ) -> Result<Self, ParseError<'i>> { Self::parse_with_clamping_mode(context, input, AllowedNumericType::NonNegative) } + + /// Convert the number or the percentage to a number. + pub fn to_percentage(self) -> Percentage { + match self { + Self::Percentage(p) => p, + Self::Number(n) => n.to_percentage(), + } + } + + /// Convert the number or the percentage to a number. + pub fn to_number(self) -> Number { + match self { + Self::Percentage(p) => p.to_number(), + Self::Number(n) => n, + } + } } impl Parse for NumberOrPercentage { @@ -419,17 +448,7 @@ impl Parse for Opacity { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - let number = match NumberOrPercentage::parse(context, input)? { - NumberOrPercentage::Percentage(p) => Number { - value: p.get(), - calc_clamping_mode: if p.is_calc() { - Some(AllowedNumericType::All) - } else { - None - }, - }, - NumberOrPercentage::Number(n) => n, - }; + let number = NumberOrPercentage::parse(context, input)?.to_number(); Ok(Opacity(number)) } } diff --git a/components/style/values/specified/percentage.rs b/components/style/values/specified/percentage.rs index acfa6db64af..64cb02bb424 100644 --- a/components/style/values/specified/percentage.rs +++ b/components/style/values/specified/percentage.rs @@ -8,6 +8,7 @@ use crate::parser::{Parse, ParserContext}; use crate::values::computed::percentage::Percentage as ComputedPercentage; use crate::values::computed::{Context, ToComputedValue}; use crate::values::specified::calc::CalcNode; +use crate::values::specified::Number; use crate::values::{serialize_percentage, CSSFloat}; use cssparser::{Parser, Token}; use std::fmt::{self, Write}; @@ -46,13 +47,21 @@ impl ToCss for Percentage { impl Percentage { /// Creates a percentage from a numeric value. - pub fn new(value: CSSFloat) -> Self { + pub(super) fn new_with_clamping_mode( + value: CSSFloat, + calc_clamping_mode: Option<AllowedNumericType>, + ) -> Self { Self { value, - calc_clamping_mode: None, + calc_clamping_mode, } } + /// Creates a percentage from a numeric value. + pub fn new(value: CSSFloat) -> Self { + Self::new_with_clamping_mode(value, None) + } + /// `0%` #[inline] pub fn zero() -> Self { @@ -70,12 +79,18 @@ impl Percentage { calc_clamping_mode: None, } } + /// Gets the underlying value for this float. pub fn get(&self) -> CSSFloat { self.calc_clamping_mode .map_or(self.value, |mode| mode.clamp(self.value)) } + /// Returns this percentage as a number. + pub fn to_number(&self) -> Number { + Number::new_with_clamping_mode(self.value, self.calc_clamping_mode) + } + /// Returns whether this percentage is a `calc()` value. pub fn is_calc(&self) -> bool { self.calc_clamping_mode.is_some() diff --git a/components/style/values/specified/svg_path.rs b/components/style/values/specified/svg_path.rs index 4f49029b51e..9a94af6a82f 100644 --- a/components/style/values/specified/svg_path.rs +++ b/components/style/values/specified/svg_path.rs @@ -46,7 +46,7 @@ impl SVGPathData { /// Create a normalized copy of this path by converting each relative /// command to an absolute command. - fn normalize(&self) -> Box<[PathCommand]> { + pub fn normalize(&self) -> Self { let mut state = PathTraversalState { subpath_start: CoordPair::new(0.0, 0.0), pos: CoordPair::new(0.0, 0.0), @@ -56,7 +56,8 @@ impl SVGPathData { .iter() .map(|seg| seg.normalize(&mut state)) .collect::<Vec<_>>(); - result.into_boxed_slice() + + SVGPathData(crate::ArcSlice::from_iter(result.into_iter())) } } @@ -119,8 +120,9 @@ impl Animate for SVGPathData { // re-normalize again. let result = self .normalize() + .0 .iter() - .zip(other.normalize().iter()) + .zip(other.normalize().0.iter()) .map(|(a, b)| a.animate(&b, procedure)) .collect::<Result<Vec<_>, _>>()?; @@ -134,8 +136,9 @@ impl ComputeSquaredDistance for SVGPathData { return Err(()); } self.normalize() + .0 .iter() - .zip(other.normalize().iter()) + .zip(other.normalize().0.iter()) .map(|(this, other)| this.compute_squared_distance(&other)) .sum() } diff --git a/components/style/values/specified/transform.rs b/components/style/values/specified/transform.rs index 9d33fd4188f..157c6504856 100644 --- a/components/style/values/specified/transform.rs +++ b/components/style/values/specified/transform.rs @@ -33,6 +33,27 @@ pub type TransformOrigin = generic::TransformOrigin< Length, >; +impl TransformOrigin { + /// Returns the initial specified value for `transform-origin`. + #[inline] + pub fn initial_value() -> Self { + Self::new( + OriginComponent::Length(LengthPercentage::Percentage(ComputedPercentage(0.5))), + OriginComponent::Length(LengthPercentage::Percentage(ComputedPercentage(0.5))), + Length::zero(), + ) + } + + /// Returns the `0 0` value. + pub fn zero_zero() -> Self { + Self::new( + OriginComponent::Length(LengthPercentage::zero()), + OriginComponent::Length(LengthPercentage::zero()), + Length::zero(), + ) + } +} + impl Transform { /// Internal parse function for deciding if we wish to accept prefixed values or not /// @@ -260,7 +281,7 @@ impl Parse for TransformOrigin { let parse_depth = |input: &mut Parser| { input .try(|i| Length::parse(context, i)) - .unwrap_or(Length::from_px(0.)) + .unwrap_or(Length::zero()) }; match input.try(|i| OriginComponent::parse(context, i)) { Ok(x_origin @ OriginComponent::Center) => { diff --git a/components/style_traits/Cargo.toml b/components/style_traits/Cargo.toml index 213c09b08df..f3dd0df744f 100644 --- a/components/style_traits/Cargo.toml +++ b/components/style_traits/Cargo.toml @@ -10,7 +10,7 @@ name = "style_traits" path = "lib.rs" [features] -servo = ["serde", "servo_atoms", "cssparser/serde", "webrender_api", "servo_url", "euclid/serde"] +servo = ["servo_atoms", "cssparser/serde", "webrender_api", "servo_url", "euclid/serde"] gecko = [] [dependencies] @@ -22,7 +22,7 @@ lazy_static = "1" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = "0.1" selectors = { path = "../selectors" } -serde = {version = "1.0", optional = true} +serde = "1.0" webrender_api = {git = "https://github.com/servo/webrender", optional = true} servo_atoms = {path = "../atoms", optional = true} servo_arc = { path = "../servo_arc" } diff --git a/components/style_traits/lib.rs b/components/style_traits/lib.rs index b2dcc8431cb..3fb17743c13 100644 --- a/components/style_traits/lib.rs +++ b/components/style_traits/lib.rs @@ -22,7 +22,6 @@ extern crate malloc_size_of; #[macro_use] extern crate malloc_size_of_derive; extern crate selectors; -#[cfg(feature = "servo")] #[macro_use] extern crate serde; extern crate servo_arc; diff --git a/components/style_traits/values.rs b/components/style_traits/values.rs index 0c3166858a2..66c1d79cd07 100644 --- a/components/style_traits/values.rs +++ b/components/style_traits/values.rs @@ -507,7 +507,9 @@ pub mod specified { /// Whether to allow negative lengths or not. #[repr(u8)] - #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, PartialOrd, ToShmem)] + #[derive( + Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, PartialOrd, Serialize, ToShmem, + )] pub enum AllowedNumericType { /// Allow all kind of numeric values. All, diff --git a/etc/taskcluster/decision_task.py b/etc/taskcluster/decision_task.py index 00af26c0200..358e1af0b3b 100644 --- a/etc/taskcluster/decision_task.py +++ b/etc/taskcluster/decision_task.py @@ -157,7 +157,9 @@ windows_sparse_checkout = [ def linux_tidy_unit_untrusted(): return ( decisionlib.DockerWorkerTask("Tidy + dev build + unit tests") - .with_worker_type("servo-docker-untrusted") + .with_worker_type( + "servo-docker-untrusted" if CONFIG.legacy_tc_deployment else "docker-untrusted" + ) .with_treeherder("Linux x64", "Tidy+Unit") .with_max_run_time_minutes(60) .with_dockerfile(dockerfile_path("build")) @@ -732,7 +734,7 @@ def dockerfile_path(name): def linux_task(name): return ( decisionlib.DockerWorkerTask(name) - .with_worker_type("servo-docker-worker") + .with_worker_type("servo-docker-worker" if CONFIG.legacy_tc_deployment else "docker") .with_treeherder_required() ) @@ -740,7 +742,7 @@ def linux_task(name): def windows_task(name): return ( decisionlib.WindowsGenericWorkerTask(name) - .with_worker_type("servo-win2016") + .with_worker_type("servo-win2016" if CONFIG.legacy_tc_deployment else "win2016") .with_treeherder_required() ) @@ -971,10 +973,15 @@ def magicleap_nightly(): CONFIG.task_name_template = "Servo: %s" -CONFIG.index_prefix = "project.servo.servo" -CONFIG.docker_image_build_worker_type = "servo-docker-worker" CONFIG.docker_images_expire_in = build_dependencies_artifacts_expire_in CONFIG.repacked_msi_files_expire_in = build_dependencies_artifacts_expire_in +if CONFIG.legacy_tc_deployment: + CONFIG.index_prefix = "project.servo.servo" + CONFIG.docker_image_build_worker_type = "servo-docker-worker" +else: # pragma: no cover + CONFIG.index_prefix = "project.servo" + CONFIG.default_provisioner_id = "proj-servo" + CONFIG.docker_image_build_worker_type = "docker" if __name__ == "__main__": # pragma: no cover diff --git a/etc/taskcluster/decisionlib.py b/etc/taskcluster/decisionlib.py index 93a5f3a8706..0436612dafa 100644 --- a/etc/taskcluster/decisionlib.py +++ b/etc/taskcluster/decisionlib.py @@ -57,6 +57,15 @@ class Config: self.git_ref = os.environ.get("GIT_REF") self.git_sha = os.environ.get("GIT_SHA") + root_url = os.environ.get("TASKCLUSTER_ROOT_URL") + self.legacy_tc_deployment = root_url == "https://taskcluster.net" + + if self.legacy_tc_deployment: + self.default_provisioner_id = "aws-provisioner-v1" + else: # pragma: no cover + self.default_provisioner_id = "proj-example" + + def task_id(self): if hasattr(self, "_task_id"): return self._task_id @@ -131,7 +140,7 @@ class Task: self.name = name self.description = "" self.scheduler_id = "taskcluster-github" - self.provisioner_id = "aws-provisioner-v1" + self.provisioner_id = CONFIG.default_provisioner_id self.worker_type = "github-worker" self.deadline_in = "1 day" self.expires_in = "1 year" @@ -755,24 +764,24 @@ class DockerWorkerTask(UnixTaskMixin, Task): .with_index_and_artifacts_expire_in(CONFIG.docker_images_expire_in) .with_features("dind") .with_env(DOCKERFILE=dockerfile_contents) - .with_artifacts("/image.tar.lz4") + .with_artifacts("/image.tar") .with_script(""" echo "$DOCKERFILE" | docker build -t taskcluster-built - - docker save taskcluster-built | lz4 > /image.tar.lz4 + docker save taskcluster-built > /image.tar """) .with_docker_image( # https://github.com/servo/taskcluster-bootstrap-docker-images#image-builder "servobrowser/taskcluster-bootstrap:image-builder@sha256:" \ "0a7d012ce444d62ffb9e7f06f0c52fedc24b68c2060711b313263367f7272d9d" ) - .find_or_create("docker-image." + digest) + .find_or_create("docker-image-uncompressed." + digest) ) return self \ .with_dependencies(image_build_task) \ .with_docker_image({ "type": "task-image", - "path": "public/image.tar.lz4", + "path": "public/image.tar", "taskId": image_build_task, }) diff --git a/etc/taskcluster/mock.py b/etc/taskcluster/mock.py index 559c837ef82..10fe23b22a1 100755 --- a/etc/taskcluster/mock.py +++ b/etc/taskcluster/mock.py @@ -44,6 +44,7 @@ sys.modules["taskcluster"] = sys.modules[__name__] sys.dont_write_bytecode = True os.environ.update(**{k: k for k in "TASK_ID TASK_OWNER TASK_SOURCE GIT_URL GIT_SHA".split()}) os.environ["GIT_REF"] = "refs/heads/auto" +os.environ["TASKCLUSTER_ROOT_URL"] = "https://taskcluster.net" import decision_task print("\n# Push:") diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 53e7c3c901f..1aa2b0961e5 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -341,7 +341,7 @@ class MachCommands(CommandBase): clangfmt_failed = False if not no_cpp: - available, cmd, files = setup_clangfmt(all_files) + available, cmd, files = setup_clangfmt() if available: for file in files: stdout = subprocess.check_output([cmd, "-output-replacements-xml", file]) @@ -480,7 +480,7 @@ class MachCommands(CommandBase): def format_code(self, no_cpp): if not no_cpp: - available, cmd, files = setup_clangfmt(True) + available, cmd, files = setup_clangfmt() if available and len(files) > 0: check_call([cmd, "-i"] + files) @@ -797,7 +797,7 @@ def create_parser_create(): return p -def setup_clangfmt(all_files): +def setup_clangfmt(): cmd = "clang-format.exe" if sys.platform == "win32" else "clang-format" try: version = subprocess.check_output([cmd, "--version"]).rstrip() @@ -809,8 +809,6 @@ def setup_clangfmt(all_files): print("clang-format not installed. Skipping CPP formatting.") return False, None, None gitcmd = ['git', 'ls-files'] - if not all_files: - gitcmd.append('-m') gitfiles = subprocess.check_output(gitcmd + CLANGFMT_CPP_DIRS).splitlines() filtered = [line for line in gitfiles if line.endswith(".h") or line.endswith(".cpp")] return True, cmd, filtered diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index a9de7e2942d..98521ccd7da 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -7,6 +7,7 @@ #include "BrowserPage.h" #include "BrowserPage.g.cpp" +using namespace std::placeholders; using namespace winrt::Windows::Foundation; using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Core; @@ -50,6 +51,17 @@ void BrowserPage::BindServoEvents() { }); servoControl().OnCaptureGesturesEnded( [=] { navigationBar().IsHitTestVisible(true); }); + urlTextbox().GotFocus(std::bind(&BrowserPage::OnURLFocused, this, _1)); +} + +void BrowserPage::OnURLFocused(Windows::Foundation::IInspectable const &) { + urlTextbox().SelectAll(); +} + +void BrowserPage::OnURLKeyboardAccelerator( + Windows::Foundation::IInspectable const &, + Windows::UI::Xaml::Input::KeyboardAcceleratorInvokedEventArgs const &) { + urlTextbox().Focus(FocusState::Programmatic); } void BrowserPage::LoadServoURI(Uri uri) { diff --git a/support/hololens/ServoApp/BrowserPage.h b/support/hololens/ServoApp/BrowserPage.h index 8c3a540d4c1..6c1af3f9059 100644 --- a/support/hololens/ServoApp/BrowserPage.h +++ b/support/hololens/ServoApp/BrowserPage.h @@ -26,6 +26,10 @@ public: Windows::UI::Xaml::RoutedEventArgs const &); void OnURLEdited(Windows::Foundation::IInspectable const &, Windows::UI::Xaml::Input::KeyRoutedEventArgs const &); + void OnURLFocused(Windows::Foundation::IInspectable const &); + void OnURLKeyboardAccelerator( + Windows::Foundation::IInspectable const &, + Windows::UI::Xaml::Input::KeyboardAcceleratorInvokedEventArgs const &); void Shutdown(); void LoadServoURI(Windows::Foundation::Uri uri); void SetTransientMode(bool); diff --git a/support/hololens/ServoApp/BrowserPage.xaml b/support/hololens/ServoApp/BrowserPage.xaml index 386a20accac..3cd8aabff55 100644 --- a/support/hololens/ServoApp/BrowserPage.xaml +++ b/support/hololens/ServoApp/BrowserPage.xaml @@ -7,108 +7,124 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> - <Page.Resources> - <Style x:Key="NavigationBarButton" TargetType="Button"> - <Setter Property="Background" Value="Transparent"/> - <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/> - <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/> - <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/> - <Setter Property="Padding" Value="0"/> - <Setter Property="Margin" Value="10,2"/> - <Setter Property="MinWidth" Value="30"/> - <Setter Property="MinHeight" Value="30"/> - <Setter Property="HorizontalAlignment" Value="Center"/> - <Setter Property="VerticalAlignment" Value="Center"/> - <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/> - <Setter Property="FontWeight" Value="Normal"/> - <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/> - <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/> - <Setter Property="FocusVisualMargin" Value="-3"/> - <Setter Property="Template"> - <Setter.Value> - <ControlTemplate TargetType="Button"> - <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" CornerRadius="{TemplateBinding CornerRadius}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"> - <VisualStateManager.VisualStateGroups> - <VisualStateGroup x:Name="CommonStates"> - <VisualState x:Name="Normal"> - <Storyboard> - <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/> - </Storyboard> - </VisualState> - <VisualState x:Name="PointerOver"> - <Storyboard> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> - <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}"/> - </ObjectAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> - <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}"/> - </ObjectAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> - <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"/> - </ObjectAnimationUsingKeyFrames> - <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/> - </Storyboard> - </VisualState> - <VisualState x:Name="Pressed"> - <Storyboard> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> - <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}"/> - </ObjectAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> - <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}"/> - </ObjectAnimationUsingKeyFrames> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> - <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}"/> - </ObjectAnimationUsingKeyFrames> - <PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/> - </Storyboard> - </VisualState> - <VisualState x:Name="Disabled"> - <Storyboard> - <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Opacity"> - <DiscreteObjectKeyFrame KeyTime="0" Value="0.2"/> - </ObjectAnimationUsingKeyFrames> - </Storyboard> - </VisualState> - </VisualStateGroup> - </VisualStateManager.VisualStateGroups> - </ContentPresenter> - </ControlTemplate> - </Setter.Value> - </Setter> - </Style> - </Page.Resources> + <Page.Resources> + <Style x:Key="NavigationBarButton" TargetType="Button"> + <Setter Property="Background" Value="Transparent"/> + <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}"/> + <Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}"/> + <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/> + <Setter Property="Padding" Value="0"/> + <Setter Property="Margin" Value="10,2"/> + <Setter Property="MinWidth" Value="30"/> + <Setter Property="MinHeight" Value="30"/> + <Setter Property="HorizontalAlignment" Value="Center"/> + <Setter Property="VerticalAlignment" Value="Center"/> + <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/> + <Setter Property="FontWeight" Value="Normal"/> + <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/> + <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/> + <Setter Property="FocusVisualMargin" Value="-3"/> + <Setter Property="Template"> + <Setter.Value> + <ControlTemplate TargetType="Button"> + <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" CornerRadius="{TemplateBinding CornerRadius}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"> + <VisualStateManager.VisualStateGroups> + <VisualStateGroup x:Name="CommonStates"> + <VisualState x:Name="Normal"> + <Storyboard> + <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/> + </Storyboard> + </VisualState> + <VisualState x:Name="PointerOver"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> + <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPointerOver}"/> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> + <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPointerOver}"/> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> + <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPointerOver}"/> + </ObjectAnimationUsingKeyFrames> + <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter"/> + </Storyboard> + </VisualState> + <VisualState x:Name="Pressed"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Background"> + <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBackgroundPressed}"/> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="BorderBrush"> + <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonBorderBrushPressed}"/> + </ObjectAnimationUsingKeyFrames> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Foreground"> + <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonForegroundPressed}"/> + </ObjectAnimationUsingKeyFrames> + <PointerDownThemeAnimation Storyboard.TargetName="ContentPresenter"/> + </Storyboard> + </VisualState> + <VisualState x:Name="Disabled"> + <Storyboard> + <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter" Storyboard.TargetProperty="Opacity"> + <DiscreteObjectKeyFrame KeyTime="0" Value="0.2"/> + </ObjectAnimationUsingKeyFrames> + </Storyboard> + </VisualState> + </VisualStateGroup> + </VisualStateManager.VisualStateGroups> + </ContentPresenter> + </ControlTemplate> + </Setter.Value> + </Setter> + </Style> + </Page.Resources> - <Grid VerticalAlignment="Stretch"> - <Grid.RowDefinitions> - <RowDefinition Height="auto"/> - <RowDefinition Height="*"/> - <RowDefinition Height="auto"/> - </Grid.RowDefinitions> - <Grid Grid.Row="0" x:Name="navigationBar" Background="{ThemeResource InkToolbarButtonBackgroundThemeBrush}"> - <Grid.ColumnDefinitions> - <ColumnDefinition Width="auto"/> - <ColumnDefinition Width="*"/> - <ColumnDefinition Width="auto"/> - </Grid.ColumnDefinitions> - <StackPanel Orientation="Horizontal" Grid.Column="0"> - <Button Style="{StaticResource NavigationBarButton}" x:Name="backButton" IsTabStop="true" IsEnabled="false" Click="OnBackButtonClicked" AutomationProperties.Name="Back"> - <Image Source="Assets/UI/back.png" Height="12"></Image> - </Button> - <Button Style="{StaticResource NavigationBarButton}" x:Name="forwardButton" IsTabStop="true" IsEnabled="false" Click="OnForwardButtonClicked" AutomationProperties.Name="Forward"> - <Image Source="Assets/UI/forward.png" Height="12"></Image> - </Button> - <Button Style="{StaticResource NavigationBarButton}" x:Name="reloadButton" IsTabStop="true" IsEnabled="false" Visibility="Visible" Click="OnReloadButtonClicked" AutomationProperties.Name="Reload"> - <Image Source="Assets/UI/reload.png" Height="12"></Image> - </Button> - <Button Style="{StaticResource NavigationBarButton}" x:Name="stopButton" IsTabStop="true" IsEnabled="false" Visibility="Collapsed" Click="OnStopButtonClicked" AutomationProperties.Name="Stop"> - <Image Source="Assets/UI/stop.png" Height="12"></Image> - </Button> - </StackPanel> - <TextBox Text="" IsTabStop="true" InputScope="Url" PlaceholderText="Type a URL" x:Name="urlTextbox" Grid.Column="1" KeyUp="OnURLEdited" IsSpellCheckEnabled="False" Margin="3,0"/> - <ProgressRing x:Name="urlbarLoadingIndicator" Grid.Column="2" Margin="10,0"/> + <Grid VerticalAlignment="Stretch"> + <Grid.RowDefinitions> + <RowDefinition Height="auto"/> + <RowDefinition Height="*"/> + <RowDefinition Height="auto"/> + </Grid.RowDefinitions> + <Grid Grid.Row="0" x:Name="navigationBar" Background="{ThemeResource InkToolbarButtonBackgroundThemeBrush}"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="auto"/> + <ColumnDefinition Width="*"/> + <ColumnDefinition Width="auto"/> + </Grid.ColumnDefinitions> + <StackPanel Orientation="Horizontal" Grid.Column="0"> + <Button Style="{StaticResource NavigationBarButton}" x:Name="backButton" IsTabStop="true" IsEnabled="false" Click="OnBackButtonClicked" AutomationProperties.Name="Back"> + <Image Source="Assets/UI/back.png" Height="12"></Image> + <Button.KeyboardAccelerators> + <KeyboardAccelerator Key="Left" Modifiers="Menu" /> + </Button.KeyboardAccelerators> + </Button> + <Button Style="{StaticResource NavigationBarButton}" x:Name="forwardButton" IsTabStop="true" IsEnabled="false" Click="OnForwardButtonClicked" AutomationProperties.Name="Forward"> + <Image Source="Assets/UI/forward.png" Height="12"></Image> + <Button.KeyboardAccelerators> + <KeyboardAccelerator Key="Right" Modifiers="Menu" /> + </Button.KeyboardAccelerators> + </Button> + <Button Style="{StaticResource NavigationBarButton}" x:Name="reloadButton" IsTabStop="true" IsEnabled="false" Visibility="Visible" Click="OnReloadButtonClicked" AutomationProperties.Name="Reload"> + <Image Source="Assets/UI/reload.png" Height="12"></Image> + <Button.KeyboardAccelerators> + <KeyboardAccelerator Key="R" Modifiers="Control" /> + </Button.KeyboardAccelerators> + </Button> + <Button Style="{StaticResource NavigationBarButton}" x:Name="stopButton" IsTabStop="true" IsEnabled="false" Visibility="Collapsed" Click="OnStopButtonClicked" AutomationProperties.Name="Stop"> + <Image Source="Assets/UI/stop.png" Height="12"></Image> + <Button.KeyboardAccelerators> + <KeyboardAccelerator Key="Escape" Modifiers="None" /> + </Button.KeyboardAccelerators> + </Button> + </StackPanel> + <TextBox Text="" IsTabStop="true" InputScope="Url" PlaceholderText="Type a URL" x:Name="urlTextbox" Grid.Column="1" KeyUp="OnURLEdited" IsSpellCheckEnabled="False" Margin="3,0"> + <TextBox.KeyboardAccelerators> + <KeyboardAccelerator Key="L" Modifiers="Control" Invoked="OnURLKeyboardAccelerator"/> + </TextBox.KeyboardAccelerators> + </TextBox> + <ProgressRing x:Name="urlbarLoadingIndicator" Grid.Column="2" Margin="10,0"/> + </Grid> + <local:ServoControl TabIndex="0" x:Name="servoControl" Grid.Row="1"/> + <ProgressBar x:Name="transientLoadingIndicator" Visibility="Collapsed" Grid.Row="2"/> </Grid> - <local:ServoControl TabIndex="0" x:Name="servoControl" Grid.Row="1"/> - <ProgressBar x:Name="transientLoadingIndicator" Visibility="Collapsed" Grid.Row="2"/> - </Grid> </Page> diff --git a/support/hololens/ServoApp/ServoControl/Servo.h b/support/hololens/ServoApp/ServoControl/Servo.h index 3cf3bc63d93..b89ca1c8d76 100644 --- a/support/hololens/ServoApp/ServoControl/Servo.h +++ b/support/hololens/ServoApp/ServoControl/Servo.h @@ -62,9 +62,7 @@ public: void MouseUp(float x, float y, capi::CMouseButton b) { capi::mouse_up(x, y, b); } - void MouseMove(float x, float y) { - capi::mouse_move(x, y); - } + void MouseMove(float x, float y) { capi::mouse_move(x, y); } void Reload() { capi::reload(); } void Stop() { capi::stop(); } diff --git a/support/hololens/ServoApp/ServoControl/ServoControl.cpp b/support/hololens/ServoApp/ServoControl/ServoControl.cpp index 9e7323ae8f2..c8444b57d2d 100644 --- a/support/hololens/ServoApp/ServoControl/ServoControl.cpp +++ b/support/hololens/ServoApp/ServoControl/ServoControl.cpp @@ -149,7 +149,7 @@ void ServoControl::OnSurfacePointerPressed( void ServoControl::OnSurfacePointerCanceled( IInspectable const &, Input::PointerRoutedEventArgs const &e) { - mPressedMouseButton = {}; + mPressedMouseButton = {}; } void ServoControl::OnSurfacePointerMoved( diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 99a4907821f..fe263de0516 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -616088,7 +616088,7 @@ "testharness" ], "css/cssom-view/mouseEvent.html": [ - "7e194b8909317806ff80e300cd480b31680a397e", + "d50959729239599ff057a71143553b4a53f88975", "testharness" ], "css/cssom-view/negativeMargins.html": [ diff --git a/tests/wpt/metadata/css/cssom-view/idlharness.html.ini b/tests/wpt/metadata/css/cssom-view/idlharness.html.ini index 0b7ddfcc064..e62f2ff3e12 100644 --- a/tests/wpt/metadata/css/cssom-view/idlharness.html.ini +++ b/tests/wpt/metadata/css/cssom-view/idlharness.html.ini @@ -128,12 +128,6 @@ [Range interface: operation getClientRects()] expected: FAIL - [MouseEvent interface: attribute y] - expected: FAIL - - [MouseEvent interface: attribute x] - expected: FAIL - [Element interface: calling scrollIntoView([object Object\],[object Object\]) on document.createElement("img") with too few arguments must throw TypeError] expected: FAIL @@ -251,12 +245,6 @@ [Element interface: calling convertRectFromNode(DOMRectReadOnly, GeometryNode, ConvertCoordinateOptions) on document.createElement("div") with too few arguments must throw TypeError] expected: FAIL - [MouseEvent interface: attribute offsetX] - expected: FAIL - - [MouseEvent interface: attribute offsetY] - expected: FAIL - [CSSPseudoElement interface: operation convertRectFromNode(DOMRectReadOnly, GeometryNode, ConvertCoordinateOptions)] expected: FAIL @@ -298,15 +286,3 @@ [Partial dictionary MouseEventInit: member names are unique] expected: FAIL - - [MouseEvent interface: new MouseEvent("foo") must inherit property "offsetY" with the proper type] - expected: FAIL - - [MouseEvent interface: new MouseEvent("foo") must inherit property "y" with the proper type] - expected: FAIL - - [MouseEvent interface: new MouseEvent("foo") must inherit property "x" with the proper type] - expected: FAIL - - [MouseEvent interface: new MouseEvent("foo") must inherit property "offsetX" with the proper type] - expected: FAIL diff --git a/tests/wpt/metadata/css/cssom-view/mouseEvent.html.ini b/tests/wpt/metadata/css/cssom-view/mouseEvent.html.ini deleted file mode 100644 index 4ed417f91fa..00000000000 --- a/tests/wpt/metadata/css/cssom-view/mouseEvent.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[mouseEvent.html] - [MouseEvent's x and y must be equal to clientX and clientY.] - expected: FAIL - diff --git a/tests/wpt/web-platform-tests/css/cssom-view/mouseEvent.html b/tests/wpt/web-platform-tests/css/cssom-view/mouseEvent.html index 7e194b89093..d5095972923 100644 --- a/tests/wpt/web-platform-tests/css/cssom-view/mouseEvent.html +++ b/tests/wpt/web-platform-tests/css/cssom-view/mouseEvent.html @@ -29,5 +29,14 @@ test(function () { assert_equals(mouseEvent2.pageX, 10); assert_equals(mouseEvent2.pageY, 5020); }, 'MouseEvent\'s pageX and pageY attributes should be the sum of the scroll offset and clientX/clientY'); + +test(function () { + var mouseEvent = new MouseEvent('mousedown', {clientX: 10, clientY: 20}); + assert_equals(mouseEvent.offsetX, mouseEvent.pageX); + assert_equals(mouseEvent.offsetY, mouseEvent.pageY); + scrollBy(0, 5000); + assert_equals(mouseEvent.offsetX, mouseEvent.pageX); + assert_equals(mouseEvent.offsetY, mouseEvent.pageY); +}, 'MouseEvent\'s offsetX/offsetY attributes should be the same value as its pageX/pageY attributes.'); </script> </head> |