From 9327a21b5c30cda6d4c83ce20d93feef0a64f718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 3 Oct 2017 00:40:03 -0500 Subject: [PATCH 01/39] servo: Merge #18703 - style: Allow passing an nth-index-cache to the invalidation code (from emilio:nth-index-cache-invalidate); r=bholley style: Allow passing an nth-index-cache to the invalidation code. Source-Repo: https://github.com/servo/servo Source-Revision: 2a5121357a76e2b558ecd0dae7689d709b6a2b41 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 698ea0c490b0fa689461e29c8c97ab6f2de3ce95 --- servo/components/style/data.rs | 4 + .../style/invalidation/element/invalidator.rs | 163 ++++++++++-------- servo/components/style/traversal.rs | 8 +- servo/ports/geckolib/glue.rs | 12 +- 4 files changed, 114 insertions(+), 73 deletions(-) diff --git a/servo/components/style/data.rs b/servo/components/style/data.rs index 8d9a982b897a..bc3f0b174972 100644 --- a/servo/components/style/data.rs +++ b/servo/components/style/data.rs @@ -14,6 +14,7 @@ use properties::ComputedValues; use properties::longhands::display::computed_value as display; use rule_tree::StrongRuleNode; use selector_parser::{EAGER_PSEUDO_COUNT, PseudoElement, RestyleDamage}; +use selectors::NthIndexCache; use servo_arc::Arc; use shared_lock::StylesheetGuards; use std::fmt; @@ -236,6 +237,7 @@ impl ElementData { element: E, shared_context: &SharedStyleContext, stack_limit_checker: Option<&StackLimitChecker>, + nth_index_cache: Option<&mut NthIndexCache>, ) -> InvalidationResult { // In animation-only restyle we shouldn't touch snapshot at all. if shared_context.traversal_flags.for_animation_only() { @@ -261,7 +263,9 @@ impl ElementData { Some(self), shared_context, stack_limit_checker, + nth_index_cache, ); + let result = invalidator.invalidate(); unsafe { element.set_handled_snapshot() } debug_assert!(element.handled_snapshot()); diff --git a/servo/components/style/invalidation/element/invalidator.rs b/servo/components/style/invalidation/element/invalidator.rs index 2080ba7676ef..80d5f704360d 100644 --- a/servo/components/style/invalidation/element/invalidator.rs +++ b/servo/components/style/invalidation/element/invalidator.rs @@ -15,6 +15,7 @@ use invalidation::element::invalidation_map::*; use invalidation::element::restyle_hints::*; use selector_map::SelectorMap; use selector_parser::{SelectorImpl, Snapshot}; +use selectors::NthIndexCache; use selectors::attr::CaseSensitivity; use selectors::matching::{MatchingContext, MatchingMode, VisitedHandlingMode}; use selectors::matching::{matches_selector, matches_compound_selector}; @@ -47,6 +48,7 @@ pub struct TreeStyleInvalidator<'a, 'b: 'a, E> data: Option<&'a mut ElementData>, shared_context: &'a SharedStyleContext<'b>, stack_limit_checker: Option<&'a StackLimitChecker>, + nth_index_cache: Option<&'a mut NthIndexCache>, } type InvalidationVector = SmallVec<[Invalidation; 10]>; @@ -174,12 +176,14 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> data: Option<&'a mut ElementData>, shared_context: &'a SharedStyleContext<'b>, stack_limit_checker: Option<&'a StackLimitChecker>, + nth_index_cache: Option<&'a mut NthIndexCache>, ) -> Self { Self { element, data, shared_context, stack_limit_checker, + nth_index_cache, } } @@ -252,16 +256,17 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> let mut sibling_invalidations = InvalidationVector::new(); let invalidated_self = { let mut collector = InvalidationCollector { - wrapper: wrapper, + wrapper, + lookup_element, + nth_index_cache: self.nth_index_cache.as_mut().map(|c| &mut **c), + state_changes, element: self.element, snapshot: &snapshot, shared_context: self.shared_context, - lookup_element: lookup_element, removed_id: id_removed.as_ref(), added_id: id_added.as_ref(), classes_removed: &classes_removed, classes_added: &classes_added, - state_changes: state_changes, descendant_invalidations: &mut descendant_invalidations, sibling_invalidations: &mut sibling_invalidations, invalidates_self: false, @@ -325,6 +330,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> sibling_data, self.shared_context, self.stack_limit_checker, + self.nth_index_cache.as_mut().map(|c| &mut **c), ); let mut invalidations_for_descendants = InvalidationVector::new(); @@ -388,6 +394,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> child_data, self.shared_context, self.stack_limit_checker, + self.nth_index_cache.as_mut().map(|c| &mut **c), ); let mut invalidations_for_descendants = InvalidationVector::new(); @@ -633,22 +640,22 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> debug!("TreeStyleInvalidator::process_invalidation({:?}, {:?}, {:?})", self.element, invalidation, invalidation_kind); - // FIXME(bholley): Consider passing an nth-index cache here. - let mut context = - MatchingContext::new_for_visited( + let matching_result = { + let mut context = MatchingContext::new_for_visited( MatchingMode::Normal, None, - None, + self.nth_index_cache.as_mut().map(|c| &mut **c), VisitedHandlingMode::AllLinksVisitedAndUnvisited, self.shared_context.quirks_mode(), ); - let matching_result = matches_compound_selector( - &invalidation.selector, - invalidation.offset, - &mut context, - &self.element - ); + matches_compound_selector( + &invalidation.selector, + invalidation.offset, + &mut context, + &self.element + ) + }; let mut invalidated_self = false; let mut matched = false; @@ -814,6 +821,7 @@ struct InvalidationCollector<'a, 'b: 'a, E> { element: E, wrapper: ElementWrapper<'b, E>, + nth_index_cache: Option<&'a mut NthIndexCache>, snapshot: &'a Snapshot, shared_context: &'a SharedStyleContext<'b>, lookup_element: E, @@ -923,6 +931,64 @@ impl<'a, 'b: 'a, E> InvalidationCollector<'a, 'b, E> ); } + /// Check whether a dependency should be taken into account, using a given + /// visited handling mode. + fn check_dependency( + &mut self, + visited_handling_mode: VisitedHandlingMode, + dependency: &Dependency, + relevant_link_found: &mut bool, + ) -> bool { + let (matches_now, relevant_link_found_now) = { + let mut context = MatchingContext::new_for_visited( + MatchingMode::Normal, + None, + self.nth_index_cache.as_mut().map(|c| &mut **c), + visited_handling_mode, + self.shared_context.quirks_mode(), + ); + + let matches_now = matches_selector( + &dependency.selector, + dependency.selector_offset, + None, + &self.element, + &mut context, + &mut |_, _| {}, + ); + + (matches_now, context.relevant_link_found) + }; + + let (matched_then, relevant_link_found_then) = { + let mut context = MatchingContext::new_for_visited( + MatchingMode::Normal, + None, + self.nth_index_cache.as_mut().map(|c| &mut **c), + visited_handling_mode, + self.shared_context.quirks_mode(), + ); + + let matched_then = matches_selector( + &dependency.selector, + dependency.selector_offset, + None, + &self.wrapper, + &mut context, + &mut |_, _| {}, + ); + + (matched_then, context.relevant_link_found) + }; + + *relevant_link_found = relevant_link_found_now; + + // Check for mismatches in both the match result and also the status + // of whether a relevant link was found. + matched_then != matches_now || + relevant_link_found_now != relevant_link_found_then + } + fn scan_dependency( &mut self, dependency: &Dependency, @@ -937,47 +1003,15 @@ impl<'a, 'b: 'a, E> InvalidationCollector<'a, 'b, E> return; } - // TODO(emilio): Add a bloom filter here? - // - // If we decide to do so, we can't use the bloom filter for snapshots, - // given that arbitrary elements in the parent chain may have mutated - // their id's/classes, which means that they won't be in the filter, and - // as such we may fast-reject selectors incorrectly. - // - // We may be able to improve this if we record as we go down the tree - // whether any parent had a snapshot, and whether those snapshots were - // taken due to an element class/id change, but it's not clear it'd be - // worth it. - // - // FIXME(bholley): Consider passing an nth-index cache here. - let mut now_context = - MatchingContext::new_for_visited(MatchingMode::Normal, None, None, - VisitedHandlingMode::AllLinksUnvisited, - self.shared_context.quirks_mode()); - let mut then_context = - MatchingContext::new_for_visited(MatchingMode::Normal, None, None, - VisitedHandlingMode::AllLinksUnvisited, - self.shared_context.quirks_mode()); + let mut relevant_link_found = false; - let matched_then = - matches_selector(&dependency.selector, - dependency.selector_offset, - None, - &self.wrapper, - &mut then_context, - &mut |_, _| {}); - let matches_now = - matches_selector(&dependency.selector, - dependency.selector_offset, - None, - &self.element, - &mut now_context, - &mut |_, _| {}); + let should_account_for_dependency = self.check_dependency( + VisitedHandlingMode::AllLinksUnvisited, + dependency, + &mut relevant_link_found, + ); - // Check for mismatches in both the match result and also the status - // of whether a relevant link was found. - if matched_then != matches_now || - then_context.relevant_link_found != now_context.relevant_link_found { + if should_account_for_dependency { return self.note_dependency(dependency); } @@ -997,25 +1031,14 @@ impl<'a, 'b: 'a, E> InvalidationCollector<'a, 'b, E> // // NOTE: This thing is actually untested because testing it is flaky, // see the tests that were added and then backed out in bug 1328509. - if is_visited_dependent == VisitedDependent::Yes && now_context.relevant_link_found { - then_context.visited_handling = VisitedHandlingMode::RelevantLinkVisited; - let matched_then = - matches_selector(&dependency.selector, - dependency.selector_offset, - None, - &self.wrapper, - &mut then_context, - &mut |_, _| {}); + if is_visited_dependent == VisitedDependent::Yes && relevant_link_found { + let should_account_for_dependency = self.check_dependency( + VisitedHandlingMode::RelevantLinkVisited, + dependency, + &mut false, + ); - now_context.visited_handling = VisitedHandlingMode::RelevantLinkVisited; - let matches_now = - matches_selector(&dependency.selector, - dependency.selector_offset, - None, - &self.element, - &mut now_context, - &mut |_, _| {}); - if matched_then != matches_now { + if should_account_for_dependency { return self.note_dependency(dependency); } } diff --git a/servo/components/style/traversal.rs b/servo/components/style/traversal.rs index a1eb17b50028..d31d1abff0ec 100644 --- a/servo/components/style/traversal.rs +++ b/servo/components/style/traversal.rs @@ -169,8 +169,11 @@ pub trait DomTraversal : Sync { if !traversal_flags.for_animation_only() { // Invalidate our style, and that of our siblings and // descendants as needed. + // + // FIXME(emilio): an nth-index cache could be worth here, even + // if temporary? let invalidation_result = - data.invalidate_style_if_needed(root, shared_context, None); + data.invalidate_style_if_needed(root, shared_context, None, None); if invalidation_result.has_invalidated_siblings() { let actual_root = @@ -895,7 +898,8 @@ where child_data.invalidate_style_if_needed( child, &context.shared, - Some(&context.thread_local.stack_limit_checker) + Some(&context.thread_local.stack_limit_checker), + Some(&mut context.thread_local.nth_index_cache) ); } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 1fb702b767c5..bbbacc275952 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -4058,7 +4058,17 @@ pub extern "C" fn Servo_ProcessInvalidations(set: RawServoStyleSetBorrowed, let mut data = data.as_mut().map(|d| &mut **d); if let Some(ref mut data) = data { - let result = data.invalidate_style_if_needed(element, &shared_style_context, None); + // FIXME(emilio): an nth-index cache could be worth here, even + // if temporary? + // + // Also, ideally we could share them across all the elements? + let result = data.invalidate_style_if_needed( + element, + &shared_style_context, + None, + None, + ); + if result.has_invalidated_siblings() { let parent = element.traversal_parent().expect("How could we invalidate siblings without a common parent?"); unsafe { From 105a559cc8d902129ff99bce719487de067fe2f4 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Mon, 2 Oct 2017 18:31:16 +0200 Subject: [PATCH 02/39] Bug 1400297 - Increase color contrast for JSON Viewer and Netmonitor headers. r=Honza MozReview-Commit-ID: DmdzPesJEo --HG-- extra : rebase_source : c52b54dea22783f84298cff221f9d8ff4b5adf7c --- devtools/client/jsonview/css/headers-panel.css | 2 +- devtools/client/netmonitor/src/assets/styles/netmonitor.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devtools/client/jsonview/css/headers-panel.css b/devtools/client/jsonview/css/headers-panel.css index 89cec46e0321..3b2567a7b011 100644 --- a/devtools/client/jsonview/css/headers-panel.css +++ b/devtools/client/jsonview/css/headers-panel.css @@ -24,7 +24,7 @@ } .headersPanelBox .netInfoHeadersGroup { - color: var(--theme-body-color-alt); + color: var(--theme-toolbar-color); margin-bottom: 10px; border-bottom: 1px solid var(--theme-splitter-color); padding-top: 8px; diff --git a/devtools/client/netmonitor/src/assets/styles/netmonitor.css b/devtools/client/netmonitor/src/assets/styles/netmonitor.css index b7244ec7e8ca..1b004e54e3b2 100644 --- a/devtools/client/netmonitor/src/assets/styles/netmonitor.css +++ b/devtools/client/netmonitor/src/assets/styles/netmonitor.css @@ -903,7 +903,7 @@ body, .tree-container .treeTable .treeRow.tree-section > .treeLabelCell > .treeLabel, .tree-container .treeTable .treeRow.tree-section > .treeLabelCell > .treeLabel:hover, .tree-container .treeTable .treeRow.tree-section > .treeValueCell:not(:hover) * { - color: var(--theme-body-color-alt); + color: var(--theme-toolbar-color); } .tree-container .treeTable .treeValueCell { From d9b2faa09a55978449f57eb96c385a3391506031 Mon Sep 17 00:00:00 2001 From: Johann Hofmann Date: Mon, 2 Oct 2017 15:43:18 +0200 Subject: [PATCH 03/39] Bug 1404497 - Don't hide the post-tabs titlebar placeholder in maximized windows. r=dao MozReview-Commit-ID: 39x18t1GBRP --HG-- extra : rebase_source : a5e382521626417829c5cc4bb4e6f1c9cbaed8ed --- browser/base/content/browser.css | 1 - 1 file changed, 1 deletion(-) diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index 213468baaafa..f00494398caf 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -245,7 +245,6 @@ window:not([chromehidden~="toolbar"]) #nav-bar[nonemptyoverflow] > .overflow-but %endif %ifndef MOZ_WIDGET_COCOA #main-window:not([sizemode=normal]) .titlebar-placeholder[type="pre-tabs"], -#main-window:not([sizemode=normal]) .titlebar-placeholder[type="post-tabs"], %endif #main-window:not([chromemargin]) > #titlebar, #main-window[inFullscreen] > #titlebar, From 21c0321d34bc9fc064fb9f5d62e699804d5f2a03 Mon Sep 17 00:00:00 2001 From: Ricky Chien Date: Tue, 3 Oct 2017 17:04:14 +0800 Subject: [PATCH 04/39] Bug 1405237 - Revert unexpected npm-shrinkwrap.json changes in bug 1349689 r=Gijs MozReview-Commit-ID: 4jnBJcxBYiA --HG-- extra : rebase_source : 46985a8192ac288e89f1a51a1d31e39d2e298ce6 --- npm-shrinkwrap.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 717807745b38..08c9460a4880 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1004,6 +1004,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -1014,14 +1022,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", From d9dae67b93df0d5a9eee8972b5c3c49482a791fe Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Fri, 29 Sep 2017 17:55:50 +0100 Subject: [PATCH 05/39] Bug 1402929 - try to make overflow panel in customize mode easier to understand, r=mikedeboer This moves the explanatory text from a pseudoelement to a real element, and keeps only the image in a pseudoelement. It then uses a transitioned opacity to fade that image in and out. Because we need to fade this based on dragging items over the panel when it's empty, it adds/removes a 'draggingover' attribute to handle the fade. To cope with the extra element in the drag/drop container in customize mode, this also makes the following changes: - bail out of _onDragStart if there's no actual selected item. - pick the fixed list in the panelHolder more reliably - add a max-width to avoid the description making the panel wider MozReview-Commit-ID: 9PEJSoJJ0Rp --HG-- extra : rebase_source : 0a7865fcfd11eb5baca858cde71ea4e8b30d5afc --- .../customizableui/CustomizeMode.jsm | 13 ++++-- .../content/customizeMode.inc.xul | 4 +- .../customizableui/content/panelUI.inc.xul | 3 +- .../customizableui/customizeMode.inc.css | 45 ++++++++++++++----- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/browser/components/customizableui/CustomizeMode.jsm b/browser/components/customizableui/CustomizeMode.jsm index 13b87ae027d5..0f011b99eb03 100644 --- a/browser/components/customizableui/CustomizeMode.jsm +++ b/browser/components/customizableui/CustomizeMode.jsm @@ -1648,7 +1648,8 @@ CustomizeMode.prototype = { __dumpDragData(aEvent); let item = aEvent.target; while (item && item.localName != "toolbarpaletteitem") { - if (item.localName == "toolbar") { + if (item.localName == "toolbar" || item.id == kPaletteId || + item.id == "customization-panelHolder") { return; } item = item.parentNode; @@ -1688,6 +1689,8 @@ CustomizeMode.prototype = { this._setDragActive(item.previousSibling, "after", draggedItem.id, placeForItem); this._dragOverItem = item.previousSibling; } + let currentArea = this._getCustomizableParent(item); + currentArea.setAttribute("draggingover", "true"); } this._initializeDragAfterMove = null; this.window.clearTimeout(this._dragInitializeTimeout); @@ -1796,6 +1799,7 @@ CustomizeMode.prototype = { this._setDragActive(dragOverItem, dragValue, draggedItemId, targetAreaType); } this._dragOverItem = dragOverItem; + targetArea.setAttribute("draggingover", "true"); } aEvent.preventDefault(); @@ -2119,6 +2123,10 @@ CustomizeMode.prototype = { if (!currentArea) { return; } + let nextArea = aNextItem ? this._getCustomizableParent(aNextItem) : null; + if (currentArea != nextArea) { + currentArea.removeAttribute("draggingover"); + } let areaType = CustomizableUI.getAreaType(currentArea.id); if (areaType) { if (aNoTransition) { @@ -2139,7 +2147,6 @@ CustomizeMode.prototype = { } else { aItem.removeAttribute("dragover"); if (aNextItem) { - let nextArea = this._getCustomizableParent(aNextItem); if (nextArea == currentArea) { // No need to do anything if we're still dragging in this area: return; @@ -2227,7 +2234,7 @@ CustomizeMode.prototype = { // Deal with drag/drop on the padding of the panel. let containingPanelHolder = aElement.closest("#customization-panelHolder"); if (containingPanelHolder) { - return containingPanelHolder.firstChild; + return containingPanelHolder.querySelector("#widget-overflow-fixed-list"); } } diff --git a/browser/components/customizableui/content/customizeMode.inc.xul b/browser/components/customizableui/content/customizeMode.inc.xul index c41591f06b75..9c466d3182b4 100644 --- a/browser/components/customizableui/content/customizeMode.inc.xul +++ b/browser/components/customizableui/content/customizeMode.inc.xul @@ -26,7 +26,9 @@ - + + &customizeMode.emptyOverflowList.description; + diff --git a/browser/components/customizableui/content/panelUI.inc.xul b/browser/components/customizableui/content/panelUI.inc.xul index e2e501f1dae9..a837ba03005d 100644 --- a/browser/components/customizableui/content/panelUI.inc.xul +++ b/browser/components/customizableui/content/panelUI.inc.xul @@ -339,8 +339,7 @@ - &customizeMode.emptyOverflowList.description; + &customizeMode.overflowList.title; + &customizeMode.overflowList.description; diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index 9d836515fcce..fa4cb8d595c8 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -855,7 +855,8 @@ you can use these alternative items. Otherwise, their values should be empty. - - + + diff --git a/browser/themes/shared/customizableui/customizeMode.inc.css b/browser/themes/shared/customizableui/customizeMode.inc.css index 481814b5f2cb..9641025c590b 100644 --- a/browser/themes/shared/customizableui/customizeMode.inc.css +++ b/browser/themes/shared/customizableui/customizeMode.inc.css @@ -502,6 +502,13 @@ toolbarpaletteitem[place=toolbar] > toolbarspring { margin: 0; } +#customization-panelHeader { + font-size: 1.3em; + font-weight: 500; + padding: 2px 12px; + margin: 0; +} + #customization-panelHolder > #widget-overflow-fixed-list { padding-top: 10px; min-height: 225px; From b852f82f5a61dea6c1e1d153e29442d2c88b1663 Mon Sep 17 00:00:00 2001 From: Drew Willcoxon Date: Mon, 2 Oct 2017 10:55:00 -0700 Subject: [PATCH 07/39] Bug 1385882 - Intermittent browser/base/content/test/urlbar/browser_page_action_menu.js | Test timed out. r=Gijs MozReview-Commit-ID: 8uzQAPQEldP --HG-- extra : rebase_source : 3f7723da3e0b52abb6edcd4e571b37bed8ab965d --- browser/base/content/test/urlbar/head.js | 48 +++++++++-------- .../test/browser/browser_PageActions.js | 51 +++++++++++-------- 2 files changed, 58 insertions(+), 41 deletions(-) diff --git a/browser/base/content/test/urlbar/head.js b/browser/base/content/test/urlbar/head.js index f5e4ee4e733b..0dfe22791309 100644 --- a/browser/base/content/test/urlbar/head.js +++ b/browser/base/content/test/urlbar/head.js @@ -224,21 +224,27 @@ function promiseNewSearchEngine(basename) { } function promisePageActionPanelOpen() { - if (BrowserPageActions.panelNode.state == "open") { - return Promise.resolve(); - } - // The main page action button is hidden for some URIs, so make sure it's - // visible before trying to click it. let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); return BrowserTestUtils.waitForCondition(() => { + // Wait for the main page action button to become visible. It's hidden for + // some URIs, so depending on when this is called, it may not yet be quite + // visible. It's up to the caller to make sure it will be visible. info("Waiting for main page action button to have non-0 size"); let bounds = dwu.getBoundsWithoutFlushing(BrowserPageActions.mainButtonNode); return bounds.width > 0 && bounds.height > 0; }).then(() => { + // Wait for the panel to become open, by clicking the button if necessary. + info("Waiting for main page action panel to be open"); + if (BrowserPageActions.panelNode.state == "open") { + return Promise.resolve(); + } let shownPromise = promisePageActionPanelShown(); EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {}); return shownPromise; + }).then(() => { + // Wait for items in the panel to become visible. + return promisePageActionViewChildrenVisible(BrowserPageActions.mainViewNode); }); } @@ -275,28 +281,30 @@ function promisePanelEvent(panelIDOrNode, eventType) { } function promisePageActionViewShown() { - let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); info("promisePageActionViewShown waiting for ViewShown"); return BrowserTestUtils.waitForEvent(BrowserPageActions.panelNode, "ViewShown").then(async event => { let panelViewNode = event.originalTarget; - // Wait for the subview to be really truly shown by making sure there's at - // least one child with non-zero bounds. - info("promisePageActionViewShown waiting for a child node to be visible"); - await BrowserTestUtils.waitForCondition(() => { - let bodyNode = panelViewNode.firstChild; - for (let childNode of bodyNode.childNodes) { - let bounds = dwu.getBoundsWithoutFlushing(childNode); - if (bounds.width > 0 && bounds.height > 0) { - return true; - } - } - return false; - }); + await promisePageActionViewChildrenVisible(panelViewNode); return panelViewNode; }); } +function promisePageActionViewChildrenVisible(panelViewNode) { + info("promisePageActionViewChildrenVisible waiting for a child node to be visible"); + let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + return BrowserTestUtils.waitForCondition(() => { + let bodyNode = panelViewNode.firstChild; + for (let childNode of bodyNode.childNodes) { + let bounds = dwu.getBoundsWithoutFlushing(childNode); + if (bounds.width > 0 && bounds.height > 0) { + return true; + } + } + return false; + }); +} + function promiseSpeculativeConnection(httpserver) { return BrowserTestUtils.waitForCondition(() => { if (httpserver) { diff --git a/browser/modules/test/browser/browser_PageActions.js b/browser/modules/test/browser/browser_PageActions.js index bd4479d5e4bc..a78cbc709197 100644 --- a/browser/modules/test/browser/browser_PageActions.js +++ b/browser/modules/test/browser/browser_PageActions.js @@ -974,21 +974,28 @@ add_task(async function migrate1() { PageActions.actionForID("copyURL")._shownInUrlbar = false; }); - function promisePageActionPanelOpen() { - let button = document.getElementById("pageActionButton"); - // The main page action button is hidden for some URIs, so make sure it's - // visible before trying to click it. let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); return BrowserTestUtils.waitForCondition(() => { + // Wait for the main page action button to become visible. It's hidden for + // some URIs, so depending on when this is called, it may not yet be quite + // visible. It's up to the caller to make sure it will be visible. info("Waiting for main page action button to have non-0 size"); - let bounds = dwu.getBoundsWithoutFlushing(button); + let bounds = dwu.getBoundsWithoutFlushing(BrowserPageActions.mainButtonNode); return bounds.width > 0 && bounds.height > 0; }).then(() => { + // Wait for the panel to become open, by clicking the button if necessary. + info("Waiting for main page action panel to be open"); + if (BrowserPageActions.panelNode.state == "open") { + return Promise.resolve(); + } let shownPromise = promisePageActionPanelShown(); - EventUtils.synthesizeMouseAtCenter(button, {}); + EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {}); return shownPromise; + }).then(() => { + // Wait for items in the panel to become visible. + return promisePageActionViewChildrenVisible(BrowserPageActions.mainViewNode); }); } @@ -1025,24 +1032,26 @@ function promisePanelEvent(panelIDOrNode, eventType) { } function promisePageActionViewShown() { - let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); info("promisePageActionViewShown waiting for ViewShown"); return BrowserTestUtils.waitForEvent(BrowserPageActions.panelNode, "ViewShown").then(async event => { let panelViewNode = event.originalTarget; - // Wait for the subview to be really truly shown by making sure there's at - // least one child with non-zero bounds. - info("promisePageActionViewShown waiting for a child node to be visible"); - await BrowserTestUtils.waitForCondition(() => { - let bodyNode = panelViewNode.firstChild; - for (let childNode of bodyNode.childNodes) { - let bounds = dwu.getBoundsWithoutFlushing(childNode); - if (bounds.width > 0 && bounds.height > 0) { - return true; - } - } - return false; - }); + await promisePageActionViewChildrenVisible(panelViewNode); return panelViewNode; }); } + +function promisePageActionViewChildrenVisible(panelViewNode) { + info("promisePageActionViewChildrenVisible waiting for a child node to be visible"); + let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + return BrowserTestUtils.waitForCondition(() => { + let bodyNode = panelViewNode.firstChild; + for (let childNode of bodyNode.childNodes) { + let bounds = dwu.getBoundsWithoutFlushing(childNode); + if (bounds.width > 0 && bounds.height > 0) { + return true; + } + } + return false; + }); +} From 8dea08a240ebb2d21e97a7fa62b93ae343d924cf Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Mon, 2 Oct 2017 20:34:01 +0100 Subject: [PATCH 08/39] Bug 1389721 - fix page action menu to deal with not being passed an event, so the 'save link to pocket' context menu works, r=jaws This also removes the now-obsolete onBeforeCommand method from the pocket code. MozReview-Commit-ID: EjrMoAIv3xw --HG-- extra : rebase_source : 0921854ff6d1110a35bb225d946cea3caa2ae3c1 --- browser/base/content/browser-pageActions.js | 2 +- browser/extensions/pocket/content/Pocket.jsm | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/browser/base/content/browser-pageActions.js b/browser/base/content/browser-pageActions.js index f3b608e8827d..d68dcd5a1c1e 100644 --- a/browser/base/content/browser-pageActions.js +++ b/browser/base/content/browser-pageActions.js @@ -461,7 +461,7 @@ var BrowserPageActions = { }, doCommandForAction(action, event, buttonNode) { - if (event.type == "click" && event.button != 0) { + if (event && event.type == "click" && event.button != 0) { return; } PageActions.logTelemetry("used", action, buttonNode); diff --git a/browser/extensions/pocket/content/Pocket.jsm b/browser/extensions/pocket/content/Pocket.jsm index a525179bc13d..7b8912f93436 100644 --- a/browser/extensions/pocket/content/Pocket.jsm +++ b/browser/extensions/pocket/content/Pocket.jsm @@ -32,10 +32,6 @@ var Pocket = { /** * Functions related to the Pocket panel UI. */ - onBeforeCommand(event) { - BrowserUtils.setToolbarButtonHeightProperty(event.target); - }, - onShownInPhotonPageActionPanel(panel, iframe) { let window = panel.ownerGlobal; window.pktUI.setPhotonPageActionPanelFrame(iframe); From 36fffc11d14185f00cba717cd6f64697b3996711 Mon Sep 17 00:00:00 2001 From: Rakhi Sharma Date: Tue, 3 Oct 2017 04:16:00 -0500 Subject: [PATCH 09/39] servo: Merge #18714 - Parse sizes attribute values (from jdm:sizes); r=jdm Squashed version of #17808. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix (partially) #11416 - [x] There are tests for these changes Source-Repo: https://github.com/servo/servo Source-Revision: 77afc3f33a72627fd4d6e83485722f3b38ae8420 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : e4c391a022878d9d8032343ca5ffc6d1ea417dd4 --- servo/Cargo.lock | 1 + .../components/script/dom/htmlimageelement.rs | 69 ++++++++++++ servo/components/script/test.rs | 4 + servo/components/style/servo/media_queries.rs | 2 +- servo/tests/unit/script/Cargo.toml | 1 + servo/tests/unit/script/htmlimageelement.rs | 101 ++++++++++++++++++ servo/tests/unit/script/lib.rs | 2 + 7 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 servo/tests/unit/script/htmlimageelement.rs diff --git a/servo/Cargo.lock b/servo/Cargo.lock index 67e5cd38f213..194148cc7214 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -2695,6 +2695,7 @@ dependencies = [ "msg 0.0.1", "script 0.0.1", "servo_url 0.0.1", + "style 0.0.1", ] [[package]] diff --git a/servo/components/script/dom/htmlimageelement.rs b/servo/components/script/dom/htmlimageelement.rs index 7c2255d6696a..1fea05fc0d99 100644 --- a/servo/components/script/dom/htmlimageelement.rs +++ b/servo/components/script/dom/htmlimageelement.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::{Au, AU_PER_PX}; +use cssparser::{Parser, ParserInput}; use document_loader::{LoadType, LoadBlocker}; use dom::activation::Activatable; use dom::attr::Attr; @@ -52,10 +53,17 @@ use script_thread::ScriptThread; use servo_url::ServoUrl; use servo_url::origin::ImmutableOrigin; use std::cell::{Cell, RefMut}; +use std::char; use std::default::Default; use std::i32; use std::sync::{Arc, Mutex}; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; +use style::context::QuirksMode; +use style::media_queries::MediaQuery; +use style::parser::ParserContext; +use style::values::specified::{Length, ViewportPercentageLength}; +use style::values::specified::length::NoCalcLength; +use style_traits::ParsingMode; use task_source::TaskSource; #[derive(Clone, Copy, HeapSizeOf, JSTraceable)] @@ -66,6 +74,13 @@ enum State { CompletelyAvailable, Broken, } + +#[derive(Debug, PartialEq)] +pub struct Size { + pub query: Option, + pub length: Length, +} + #[derive(Clone, Copy, HeapSizeOf, JSTraceable)] enum ImageRequestPhase { Pending, @@ -728,6 +743,60 @@ impl LayoutHTMLImageElementHelpers for LayoutDom { } } +//https://html.spec.whatwg.org/multipage/#parse-a-sizes-attribute +pub fn parse_a_sizes_attribute(input: DOMString, width: Option) -> Vec { + let mut sizes = Vec::::new(); + for unparsed_size in input.split(',') { + let whitespace = unparsed_size.chars().rev().take_while(|c| char::is_whitespace(*c)).count(); + let trimmed: String = unparsed_size.chars().take(unparsed_size.chars().count() - whitespace).collect(); + + if trimmed.is_empty() { + continue; + } + let mut input = ParserInput::new(&trimmed); + let url = ServoUrl::parse("about:blank").unwrap(); + let context = ParserContext::new_for_cssom(&url, + None, + ParsingMode::empty(), + QuirksMode::NoQuirks); + let mut parser = Parser::new(&mut input); + let length = parser.try(|i| Length::parse_non_negative(&context, i)); + match length { + Ok(len) => sizes.push(Size { + length: len, + query: None + }), + Err(_) => { + let mut media_query_parser = parser; + let media_query = media_query_parser.try(|i| MediaQuery::parse(&context, i)); + if let Ok(query) = media_query { + let length = Length::parse_non_negative(&context, &mut media_query_parser); + if let Ok(length) = length { + sizes.push(Size { + length: length, + query: Some(query) + }) + } + } + }, + } + } + if sizes.is_empty() { + let size = match width { + Some(w) => Size { + length: Length::from_px(w as f32), + query: None + }, + None => Size { + length: Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(100.))), + query: None + }, + }; + sizes.push(size); + } + sizes +} + impl HTMLImageElementMethods for HTMLImageElement { // https://html.spec.whatwg.org/multipage/#dom-img-alt make_getter!(Alt, "alt"); diff --git a/servo/components/script/test.rs b/servo/components/script/test.rs index 0ff6811b14da..88baa21f42f7 100644 --- a/servo/components/script/test.rs +++ b/servo/components/script/test.rs @@ -15,6 +15,10 @@ pub mod area { pub use dom::htmlareaelement::{Area, Shape}; } +pub mod sizes { + pub use dom::htmlimageelement::{parse_a_sizes_attribute, Size}; +} + pub mod size_of { use dom::characterdata::CharacterData; use dom::element::Element; diff --git a/servo/components/style/servo/media_queries.rs b/servo/components/style/servo/media_queries.rs index 36e64ee47da9..8d99b8ba81e1 100644 --- a/servo/components/style/servo/media_queries.rs +++ b/servo/components/style/servo/media_queries.rs @@ -164,7 +164,7 @@ pub enum ExpressionKind { /// http://dev.w3.org/csswg/mediaqueries-3/#media1 #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -pub struct Expression(ExpressionKind); +pub struct Expression(pub ExpressionKind); impl Expression { /// The kind of expression we're, just for unit testing. diff --git a/servo/tests/unit/script/Cargo.toml b/servo/tests/unit/script/Cargo.toml index d88f4d9a75f6..7785cced6a9c 100644 --- a/servo/tests/unit/script/Cargo.toml +++ b/servo/tests/unit/script/Cargo.toml @@ -14,3 +14,4 @@ euclid = "0.15" msg = {path = "../../../components/msg"} script = {path = "../../../components/script"} servo_url = {path = "../../../components/url"} +style = {path = "../../../components/style"} diff --git a/servo/tests/unit/script/htmlimageelement.rs b/servo/tests/unit/script/htmlimageelement.rs new file mode 100644 index 000000000000..5c9106b6c0f0 --- /dev/null +++ b/servo/tests/unit/script/htmlimageelement.rs @@ -0,0 +1,101 @@ +/* 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 script::test::DOMString; +use script::test::sizes::{parse_a_sizes_attribute, Size}; +use style::media_queries::{MediaQuery, MediaQueryType}; +use style::media_queries::Expression; +use style::servo::media_queries::{ExpressionKind, Range}; +use style::values::specified::{Length, NoCalcLength, AbsoluteLength, ViewportPercentageLength}; + +pub fn test_length_for_no_default_provided(len: f32) -> Length { + let length = Length::NoCalc(NoCalcLength::ViewportPercentage(ViewportPercentageLength::Vw(len))); + return length; +} + +#[test] +fn no_default_provided() { + let mut a = vec![]; + let length = test_length_for_no_default_provided(100f32); + let size = Size { query: None, length: length }; + a.push(size); + assert_eq!(parse_a_sizes_attribute(DOMString::new(), None), a); +} + +pub fn test_length_for_default_provided(len: f32) -> Length { + let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len))); + return length; +} + +#[test] +fn default_provided() { + let mut a = vec![]; + let length = test_length_for_default_provided(2f32); + let size = Size { query: None, length: length }; + a.push(size); + assert_eq!(parse_a_sizes_attribute(DOMString::new(), Some(2)), a); +} + +pub fn test_media_query(len: f32) -> MediaQuery { + let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len))); + let expr = Expression(ExpressionKind::Width(Range::Max(length))); + let media_query = MediaQuery { + qualifier: None, + media_type: MediaQueryType::All, + expressions: vec![expr] + }; + media_query +} + +pub fn test_length(len: f32) -> Length { + let length = Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px(len))); + return length; +} + +#[test] +fn one_value() { + let mut a = vec![]; + let media_query = test_media_query(200f32); + let length = test_length(545f32); + let size = Size { query: Some(media_query), length: length }; + a.push(size); + assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 200px) 545px"), None), a); +} + +#[test] +fn more_then_one_value() { + let media_query = test_media_query(900f32); + let length = test_length(1000f32); + let size = Size { query: Some(media_query), length: length }; + let media_query1 = test_media_query(900f32); + let length1 = test_length(50f32); + let size1 = Size { query: Some(media_query1), length: length1 }; + let a = &[size, size1]; + assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 900px) 1000px, (max-width: 900px) 50px"), + None), a); +} + +#[test] +fn no_extra_whitespace() { + let mut a = vec![]; + let media_query = test_media_query(200f32); + let length = test_length(545f32); + let size = Size { query: Some(media_query), length: length }; + a.push(size); + assert_eq!(parse_a_sizes_attribute(DOMString::from("(max-width: 200px) 545px"), None), a); +} + +#[test] +fn extra_whitespace() { + let media_query = test_media_query(900f32); + let length = test_length(1000f32); + let size = Size { query: Some(media_query), length: length }; + let media_query1 = test_media_query(900f32); + let length1 = test_length(50f32); + let size1 = Size { query: Some(media_query1), length: length1 }; + let a = &[size, size1]; + assert_eq!(parse_a_sizes_attribute( + DOMString::from("(max-width: 900px) 1000px, (max-width: 900px) 50px"), + None), a); +} diff --git a/servo/tests/unit/script/lib.rs b/servo/tests/unit/script/lib.rs index 83131e51dd23..21b89a304c56 100644 --- a/servo/tests/unit/script/lib.rs +++ b/servo/tests/unit/script/lib.rs @@ -6,10 +6,12 @@ extern crate euclid; extern crate msg; extern crate script; extern crate servo_url; +extern crate style; #[cfg(test)] mod origin; #[cfg(all(test, target_pointer_width = "64"))] mod size_of; #[cfg(test)] mod textinput; #[cfg(test)] mod headers; #[cfg(test)] mod htmlareaelement; +#[cfg(test)] mod htmlimageelement; From 545ee1b25e3d3cb93db7ef161505b7f33fe492ed Mon Sep 17 00:00:00 2001 From: Evan Tseng Date: Fri, 29 Sep 2017 17:03:47 +0800 Subject: [PATCH 10/39] Bug 1379210 - Add a space between the trackingProtectionPBM checkbox and the learn more link. r=mconley,rickychien MozReview-Commit-ID: J8ameWQw6CX --HG-- extra : rebase_source : 69858edb79228c2114f60c58c9ed6c44d8948ae7 --- browser/components/preferences/in-content/privacy.xul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/components/preferences/in-content/privacy.xul b/browser/components/preferences/in-content/privacy.xul index d3b26df84430..6d6449260978 100644 --- a/browser/components/preferences/in-content/privacy.xul +++ b/browser/components/preferences/in-content/privacy.xul @@ -514,7 +514,7 @@ -