author | Drew Willcoxon <adw@mozilla.com> |
Thu, 06 Aug 2015 20:13:00 -0700 | |
changeset 256672 | 4e2489f7cc7d09bb279c62b34b5d56836f4a980a |
parent 256671 | 4218f5a569ad33636d8ae2918ddbbbbd6e5f32ac |
child 256673 | 91de9c6708006c45824bc972b576fb5532a8b9ff |
child 256794 | 2dac39ceb9903de46375abc09916df0e5b454a26 |
push id | 29186 |
push user | cbook@mozilla.com |
push date | Fri, 07 Aug 2015 09:53:22 +0000 |
treeherder | mozilla-central@91de9c670800 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mak |
bugs | 959567 |
milestone | 42.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -305,17 +305,18 @@ pref("browser.urlbar.restrict.searches", pref("browser.urlbar.match.title", "#"); pref("browser.urlbar.match.url", "@"); // The default behavior for the urlbar can be configured to use any combination // of the match filters with each additional filter adding more results (union). pref("browser.urlbar.suggest.history", true); pref("browser.urlbar.suggest.bookmark", true); pref("browser.urlbar.suggest.openpage", true); -pref("browser.urlbar.suggest.searches", true); +pref("browser.urlbar.suggest.searches", false); +pref("browser.urlbar.userMadeSearchSuggestionsChoice", false); // Limit the number of characters sent to the current search engine to fetch // suggestions. pref("browser.urlbar.maxCharsForSearchSuggestions", 20); // Restrictions to current suggestions can also be applied (intersection). // Typed suggestion works only if history is set to true. pref("browser.urlbar.suggest.history.onlyTyped", false);
--- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -472,16 +472,37 @@ panel[noactions] > richlistbox > richlis searchbar[oneoffui] { -moz-binding: url("chrome://browser/content/search/search.xml#searchbar-flare") !important; } #PopupAutoCompleteRichResult { -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup"); } +#PopupAutoCompleteRichResult.showSearchSuggestionsNotification { + transition: height 100ms; +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] { + visibility: collapse; + transition: margin-top 100ms; +} + +#PopupAutoCompleteRichResult.showSearchSuggestionsNotification > hbox[anonid="search-suggestions-notification"] { + visibility: visible; +} + +#PopupAutoCompleteRichResult > richlistbox { + transition: height 100ms; +} + +#PopupAutoCompleteRichResult.showSearchSuggestionsNotification > richlistbox { + transition: none; +} + #urlbar[pageproxystate="invalid"] > #urlbar-icons > .urlbar-icon, #urlbar[pageproxystate="invalid"][focused="true"] > #urlbar-go-button ~ toolbarbutton, #urlbar[pageproxystate="valid"] > #urlbar-go-button, #urlbar:not([focused="true"]) > #urlbar-go-button { visibility: collapse; } #urlbar[pageproxystate="invalid"] > #identity-box > #identity-icon-labels {
--- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -453,16 +453,17 @@ skip-if = e10s # Bug 1100700 - test reli [browser_urlbarAutoFillTrimURLs.js] [browser_urlbarCopying.js] [browser_urlbarDelete.js] [browser_urlbarEnter.js] [browser_urlbarEnterAfterMouseOver.js] skip-if = os == "linux" || e10s # Bug 1073339 - Investigate autocomplete test unreliability on Linux/e10s [browser_urlbarRevert.js] [browser_urlbarSearchSingleWordNotification.js] +[browser_urlbarSearchSuggestionsNotification.js] [browser_urlbarStop.js] [browser_urlbarTrimURLs.js] [browser_urlbar_autoFill_backspaced.js] [browser_urlbar_search_healthreport.js] [browser_urlbar_searchsettings.js] [browser_utilityOverlay.js] [browser_visibleFindSelection.js] [browser_visibleLabel.js]
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/general/browser_urlbarSearchSuggestionsNotification.js @@ -0,0 +1,192 @@ +const SUGGEST_ALL_PREF = "browser.search.suggest.enabled"; +const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches"; +const CHOICE_PREF = "browser.urlbar.userMadeSearchSuggestionsChoice"; +const TEST_ENGINE_BASENAME = "searchSuggestionEngine.xml"; + +// Must run first. +add_task(function* prepare() { + let engine = yield promiseNewEngine(TEST_ENGINE_BASENAME); + let oldCurrentEngine = Services.search.currentEngine; + Services.search.currentEngine = engine; + registerCleanupFunction(function () { + Services.search.currentEngine = oldCurrentEngine; + Services.prefs.clearUserPref(SUGGEST_ALL_PREF); + Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF); + + // Disable the notification for future tests so it doesn't interfere with + // them. clearUserPref() won't work because by default the pref is false. + Services.prefs.setBoolPref(CHOICE_PREF, true); + + // Make sure the popup is closed for the next test. + gURLBar.blur(); + Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed"); + }); +}); + +add_task(function* focus_allSuggestionsDisabled() { + Services.prefs.setBoolPref(SUGGEST_ALL_PREF, false); + Services.prefs.setBoolPref(CHOICE_PREF, false); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed"); + yield promiseAutocompleteResultPopup("foo"); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(false); +}); + +add_task(function* focus_noChoiceMade() { + Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true); + Services.prefs.setBoolPref(CHOICE_PREF, false); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(true); + gURLBar.blur(); + Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed"); + gURLBar.focus(); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open again"); + assertVisible(true); +}); + +add_task(function* dismissWithoutResults() { + Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true); + Services.prefs.setBoolPref(CHOICE_PREF, false); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(true); + Assert.equal(gURLBar.popup._matchCount, 0, "popup should have no results"); + let disableButton = document.getAnonymousElementByAttribute( + gURLBar.popup, "anonid", "search-suggestions-notification-disable" + ); + let transitionPromise = promiseTransition(); + disableButton.click(); + yield transitionPromise; + Assert.ok(!gURLBar.popup.popupOpen, "popup should be closed"); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(!gURLBar.popup.popupOpen, "popup should remain closed"); + yield promiseAutocompleteResultPopup("foo"); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(false); +}); + +add_task(function* dismissWithResults() { + Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true); + Services.prefs.setBoolPref(CHOICE_PREF, false); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(true); + yield promiseAutocompleteResultPopup("foo"); + Assert.ok(gURLBar.popup._matchCount > 0, "popup should have results"); + let disableButton = document.getAnonymousElementByAttribute( + gURLBar.popup, "anonid", "search-suggestions-notification-disable" + ); + let transitionPromise = promiseTransition(); + disableButton.click(); + yield transitionPromise; + Assert.ok(gURLBar.popup.popupOpen, "popup should remain open"); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(!gURLBar.popup.popupOpen, "popup should remain closed"); + yield promiseAutocompleteResultPopup("foo"); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(false); +}); + +add_task(function* disable() { + Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true); + Services.prefs.setBoolPref(CHOICE_PREF, false); + gURLBar.blur(); + gURLBar.focus(); + Assert.ok(gURLBar.popup.popupOpen, "popup should be open"); + assertVisible(true); + let disableButton = document.getAnonymousElementByAttribute( + gURLBar.popup, "anonid", "search-suggestions-notification-disable" + ); + let transitionPromise = promiseTransition(); + disableButton.click(); + yield transitionPromise; + gURLBar.blur(); + yield promiseAutocompleteResultPopup("foo"); + assertSuggestionsPresent(false); +}); + +add_task(function* enable() { + Services.prefs.setBoolPref(SUGGEST_ALL_PREF, true); + Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, false); + Services.prefs.setBoolPref(CHOICE_PREF, false); + gURLBar.blur(); + gURLBar.focus(); + yield promiseAutocompleteResultPopup("foo"); + assertVisible(true); + assertSuggestionsPresent(false); + let enableButton = document.getAnonymousElementByAttribute( + gURLBar.popup, "anonid", "search-suggestions-notification-enable" + ); + let searchPromise = promiseSearchComplete(); + enableButton.click(); + yield searchPromise; + // Clicking Yes should trigger a new search so that suggestions appear + // immediately. + assertSuggestionsPresent(true); + gURLBar.blur(); + gURLBar.focus(); + // Suggestions should still be present in a new search of course. + yield promiseAutocompleteResultPopup("bar"); + assertSuggestionsPresent(true); +}); + +function assertSuggestionsPresent(expectedPresent) { + let controller = gURLBar.popup.input.controller; + let matchCount = controller.matchCount; + let actualPresent = false; + for (let i = 0; i < matchCount; i++) { + let url = controller.getValueAt(i); + let [, type, paramStr] = url.match(/^moz-action:([^,]+),(.*)$/); + let params = {}; + try { + params = JSON.parse(paramStr); + } catch (err) {} + let isSuggestion = type == "searchengine" && "searchSuggestion" in params; + actualPresent = actualPresent || isSuggestion; + } + Assert.equal(actualPresent, expectedPresent); +} + +function assertVisible(visible) { + let style = + window.getComputedStyle(gURLBar.popup.searchSuggestionsNotification); + Assert.equal(style.visibility, visible ? "visible" : "collapse"); +} + +function promiseNewEngine(basename) { + return new Promise((resolve, reject) => { + info("Waiting for engine to be added: " + basename); + let url = getRootDirectory(gTestPath) + basename; + Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", + false, { + onSuccess: function (engine) { + info("Search engine added: " + basename); + registerCleanupFunction(() => Services.search.removeEngine(engine)); + resolve(engine); + }, + onError: function (errCode) { + Assert.ok(false, "addEngine failed with error code " + errCode); + reject(); + }, + }); + }); +} + +function promiseTransition() { + return new Promise(resolve => { + gURLBar.popup.addEventListener("transitionend", function onEnd() { + gURLBar.popup.removeEventListener("transitionend", onEnd, true); + // The urlbar needs to handle the transitionend first, but that happens + // naturally since promises are resolved at the end of the current tick. + resolve(); + }, true); + }); +}
--- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -61,16 +61,18 @@ file, You can obtain one at http://mozil this._prefs.addObserver("", this, false); this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll"); this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll"); this.completeDefaultIndex = this._prefs.getBoolPref("autoFill"); this.timeout = this._prefs.getIntPref("delay"); this._formattingEnabled = this._prefs.getBoolPref("formatting.enabled"); this._mayTrimURLs = this._prefs.getBoolPref("trimURLs"); + this._userMadeSearchSuggestionsChoice = + this._prefs.getBoolPref("userMadeSearchSuggestionsChoice"); this._ignoreNextSelect = false; this.inputField.controllers.insertControllerAt(0, this._copyCutController); this.inputField.addEventListener("paste", this, false); this.inputField.addEventListener("mousedown", this, false); this.inputField.addEventListener("mousemove", this, false); this.inputField.addEventListener("mouseout", this, false); this.inputField.addEventListener("overflow", this, false); @@ -655,16 +657,20 @@ file, You can obtain one at http://mozil this.completeDefaultIndex = this._prefs.getBoolPref(aData); break; case "delay": this.timeout = this._prefs.getIntPref(aData); break; case "formatting.enabled": this._formattingEnabled = this._prefs.getBoolPref(aData); break; + case "userMadeSearchSuggestionsChoice": + this._userMadeSearchSuggestionsChoice = + this._prefs.getBoolPref(aData); + break; case "trimURLs": this._mayTrimURLs = this._prefs.getBoolPref(aData); break; case "unifiedcomplete": let useUnifiedComplete = false; try { useUnifiedComplete = this._prefs.getBoolPref(aData); } catch (ex) {} @@ -908,16 +914,35 @@ file, You can obtain one at http://mozil if (Services.prefs.getBoolPref("browser.urlbar.unifiedcomplete") && this.popup.selectedIndex == 0) { return this.mController.handleText(); } return this.mController.handleDelete(); ]]></body> </method> + <field name="_userMadeSearchSuggestionsChoice"><![CDATA[ + false + ]]></field> + + <method name="_maybeShowSearchSuggestionsNotification"> + <body><![CDATA[ + let showNotification = + !this._userMadeSearchSuggestionsChoice && + // When _urlbarFocused is true, tabbrowser would close the popup if + // it's opened here, so don't show the notification. + !gBrowser.selectedBrowser._urlbarFocused && + Services.prefs.getBoolPref("browser.search.suggest.enabled") && + this._prefs.getBoolPref("unifiedcomplete"); + if (showNotification) { + this.popup.showSearchSuggestionsNotification(this, this); + } + ]]></body> + </method> + </implementation> <handlers> <handler event="keydown"><![CDATA[ if ((event.keyCode === KeyEvent.DOM_VK_ALT || event.keyCode === KeyEvent.DOM_VK_SHIFT) && this.popup.selectedIndex >= 0 && !this._noActionsKeys.has(event.keyCode)) { @@ -938,16 +963,17 @@ file, You can obtain one at http://mozil this._clearNoActions(); } ]]></handler> <handler event="focus"><![CDATA[ if (event.originalTarget == this.inputField) { this._hideURLTooltip(); this.formatValue(); + this._maybeShowSearchSuggestionsNotification(); } ]]></handler> <handler event="blur"><![CDATA[ if (event.originalTarget == this.inputField) { this._clearNoActions(); this.formatValue(); } @@ -1469,25 +1495,81 @@ file, You can obtain one at http://mozil <binding id="addengine-icon" extends="xul:box"> <content> <xul:image class="addengine-icon" xbl:inherits="src"/> <xul:image class="addengine-badge"/> </content> </binding> <binding id="urlbar-rich-result-popup" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup"> + + <content ignorekeys="true" level="top" consumeoutsideclicks="never"> + <xul:hbox anonid="search-suggestions-notification" align="center"> + <xul:description flex="1"> + &urlbar.searchSuggestionsNotification.question; + <xul:label anonid="search-suggestions-notification-learn-more" + class="text-link" + value="&urlbar.searchSuggestionsNotification.learnMore;"/> + </xul:description> + <xul:button anonid="search-suggestions-notification-disable" + label="&urlbar.searchSuggestionsNotification.disable;" + onclick="document.getBindingParent(this).dismissSearchSuggestionsNotification(false);"/> + <xul:button anonid="search-suggestions-notification-enable" + label="&urlbar.searchSuggestionsNotification.enable;" + onclick="document.getBindingParent(this).dismissSearchSuggestionsNotification(true);"/> + </xul:hbox> + <xul:richlistbox anonid="richlistbox" class="autocomplete-richlistbox" + flex="1"/> + <xul:hbox anonid="footer"> + <children/> + </xul:hbox> + </content> + <implementation> <field name="_maxResults">0</field> <field name="_bundle" readonly="true"> Cc["@mozilla.org/intl/stringbundle;1"]. getService(Ci.nsIStringBundleService). createBundle("chrome://browser/locale/places/places.properties"); </field> + <field name="searchSuggestionsNotification" readonly="true"> + document.getAnonymousElementByAttribute( + this, "anonid", "search-suggestions-notification" + ); + </field> + + <field name="searchSuggestionsNotificationLearnMoreLink" readonly="true"> + document.getAnonymousElementByAttribute( + this, "anonid", "search-suggestions-notification-learn-more" + ); + </field> + + <field name="footer" readonly="true"> + document.getAnonymousElementByAttribute(this, "anonid", "footer"); + </field> + + <method name="dismissSearchSuggestionsNotification"> + <parameter name="enableSuggestions"/> + <body><![CDATA[ + Services.prefs.setBoolPref( + "browser.urlbar.userMadeSearchSuggestionsChoice", true + ); + Services.prefs.setBoolPref( + "browser.urlbar.suggest.searches", enableSuggestions + ); + this._hideSearchSuggestionsNotification(true); + if (enableSuggestions && this.input.textValue) { + // Start a new search so that suggestions appear immediately. + this.input.controller.startSearch(this.input.textValue); + } + ]]></body> + </method> + <!-- Override this so that when UnifiedComplete is enabled, navigating between items results in an item always being selected. This is contrary to the old behaviour (UnifiedComplete disabled) where if you navigate beyond either end of the list, no item will be selected. --> <method name="getNextIndex"> <parameter name="reverse"/> <parameter name="amount"/> @@ -1544,19 +1626,112 @@ file, You can obtain one at http://mozil <parameter name="aInput"/> <parameter name="aElement"/> <body> <![CDATA[ // initially the panel is hidden // to avoid impacting startup / new window performance aInput.popup.hidden = false; - // this method is defined on the base binding + // The popup may already be open if it's showing the search + // suggestions notification. In that case, its footer visibility + // needs to be updated. + if (this.popupOpen) { + this._updateFooterVisibility(); + } + this._openAutocompletePopup(aInput, aElement); - ]]></body> + ]]> + </body> + </method> + + <method name="_updateFooterVisibility"> + <body> + <![CDATA[ + this.footer.collapsed = this._matchCount == 0; + ]]> + </body> + </method> + + <method name="showSearchSuggestionsNotification"> + <parameter name="aInput"/> + <parameter name="aElement"/> + <body> + <![CDATA[ + // Set the learn-more link href. + let link = this.searchSuggestionsNotificationLearnMoreLink; + if (!link.hasAttribute("href")) { + let url = Services.urlFormatter.formatURL( + Services.prefs.getCharPref("app.support.baseURL") + "suggestions" + ); + link.setAttribute("href", url); + } + + // With the notification shown, the listbox's height can sometimes be + // too small when it's flexed, as it normally is. Also, it can start + // out slightly scrolled down. Both problems appear together, most + // often when the popup is very narrow and the notification's text + // must wrap. Work around them by removing the flex. + // + // But without flexing the listbox, the listbox's height animation + // sometimes fails to complete, leaving the popup too tall. Work + // around that problem by disabling the listbox animation. + this.richlistbox.flex = 0; + this.setAttribute("dontanimate", "true"); + + this.classList.add("showSearchSuggestionsNotification"); + this._updateFooterVisibility(); + this.openAutocompletePopup(aInput, aElement); + ]]> + </body> + </method> + + <method name="_hideSearchSuggestionsNotification"> + <parameter name="animate"/> + <body> + <![CDATA[ + if (animate) { + this._hideSearchSuggestionsNotificationWithAnimation(); + return; + } + this.classList.remove("showSearchSuggestionsNotification"); + this.richlistbox.flex = 1; + this.removeAttribute("dontanimate"); + if (this._matchCount) { + // Update popup height. + this._invalidate(); + } else { + this.closePopup(); + } + ]]> + </body> + </method> + + <method name="_hideSearchSuggestionsNotificationWithAnimation"> + <body> + <![CDATA[ + let notificationHeight = this.searchSuggestionsNotification + .getBoundingClientRect() + .height; + this.searchSuggestionsNotification.style.marginTop = + "-" + notificationHeight + "px"; + + let popupHeightPx = + (this.getBoundingClientRect().height - notificationHeight) + "px"; + this.style.height = popupHeightPx; + + let onTransitionEnd = () => { + this.removeEventListener("transitionend", onTransitionEnd, true); + this.searchSuggestionsNotification.style.marginTop = "0px"; + this.style.removeProperty("height"); + this._hideSearchSuggestionsNotification(false); + }; + this.addEventListener("transitionend", onTransitionEnd, true); + ]]> + </body> </method> <method name="onPopupClick"> <parameter name="aEvent"/> <body> <![CDATA[ // Ignore right-clicks if (aEvent.button == 2) @@ -1664,16 +1839,25 @@ file, You can obtain one at http://mozil // When the user selects one of matches, stop the search to avoid // changing the underlying result unexpectedly. if (!this._ignoreNextSelect && this.selectedIndex >= 0) { let controller = this.view.QueryInterface(Components.interfaces.nsIAutoCompleteController); controller.stopSearch(); } ]]></handler> + <handler event="mousedown"><![CDATA[ + // Required to make the xul:label.text-link elements in the search + // suggestions notification work correctly when clicked on Linux. + // This is copied from the mousedown handler in + // browser-search-autocomplete-result-popup, which apparently had a + // similar problem. + event.preventDefault(); + ]]></handler> + </handlers> </binding> <binding id="addon-progress-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification"> <implementation> <constructor><![CDATA[ if (!this.notification) return;
--- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -390,16 +390,21 @@ These should match what Safari and other <!ENTITY customizeMenu.addMoreItems.label "Add More Items…"> <!ENTITY customizeMenu.addMoreItems.accesskey "A"> <!ENTITY openCmd.commandkey "l"> <!ENTITY urlbar.placeholder2 "Search or enter address"> <!ENTITY urlbar.accesskey "d"> <!ENTITY urlbar.switchToTab.label "Switch to tab:"> +<!ENTITY urlbar.searchSuggestionsNotification.question "Would you like to improve your search experience with suggestions?"> +<!ENTITY urlbar.searchSuggestionsNotification.learnMore "Learn more…"> +<!ENTITY urlbar.searchSuggestionsNotification.disable "No"> +<!ENTITY urlbar.searchSuggestionsNotification.enable "Yes"> + <!-- Comment duplicated from browser-sets.inc: Search Command Key Logic works like this: Unix: Ctrl+J (0.8, 0.9 support) Ctrl+K (cross platform binding) Mac: Cmd+K (cross platform binding)
--- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -957,19 +957,17 @@ toolbarbutton[constrain-size="true"][cui .urlbar-display { margin-top: 0; margin-bottom: 0; -moz-margin-start: 0; color: GrayText; } -#PopupAutoCompleteRichResult > richlistbox { - transition: height 100ms; -} +%include ../shared/urlbarSearchSuggestionsNotification.inc.css #search-container { min-width: calc(54px + 11ch); } /* identity box */ #identity-box:-moz-locale-dir(ltr) { @@ -1131,17 +1129,19 @@ richlistitem[type~="action"][actiontype= .ac-result-type-tag, .autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) { list-style-image: url("chrome://browser/skin/places/tag.png"); width: 16px; height: 16px; } -.ac-comment { +.ac-comment, +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > description, +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button { font-size: 1.05em; } .ac-extra > .ac-comment { font-size: inherit; } .ac-url-text,
--- a/browser/themes/linux/jar.mn +++ b/browser/themes/linux/jar.mn @@ -91,16 +91,17 @@ browser.jar: skin/classic/browser/search-pref.png (../shared/search/search-pref.png) skin/classic/browser/search-indicator.png (../shared/search/search-indicator.png) skin/classic/browser/search-engine-placeholder.png (../shared/search/search-engine-placeholder.png) skin/classic/browser/badge-add-engine.png (../shared/search/badge-add-engine.png) skin/classic/browser/search-indicator-badge-add.png (../shared/search/search-indicator-badge-add.png) skin/classic/browser/search-history-icon.svg (../shared/search/history-icon.svg) skin/classic/browser/search-indicator-magnifying-glass.svg (../shared/search/search-indicator-magnifying-glass.svg) skin/classic/browser/search-arrow-go.svg (../shared/search/search-arrow-go.svg) + skin/classic/browser/info.svg (../shared/info.svg) skin/classic/browser/Security-broken.png skin/classic/browser/setDesktopBackground.css skin/classic/browser/slowStartup-16.png skin/classic/browser/theme-switcher-icon.png (../shared/theme-switcher-icon.png) skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar-inverted.png skin/classic/browser/Toolbar-small.png skin/classic/browser/undoCloseTab.png (../shared/undoCloseTab.png)
--- a/browser/themes/osx/browser.css +++ b/browser/themes/osx/browser.css @@ -1787,24 +1787,22 @@ toolbarbutton[constrain-size="true"][cui } .urlbar-display { margin-top: 0; margin-bottom: 0; color: GrayText; } -#PopupAutoCompleteRichResult > richlistbox { - transition: height 100ms; -} - #PopupAutoCompleteRichResult { margin-top: 2px; } +%include ../shared/urlbarSearchSuggestionsNotification.inc.css + /* ----- AUTOCOMPLETE ----- */ #treecolAutoCompleteImage { max-width: 36px; } .ac-result-type-bookmark, .autocomplete-treebody::-moz-tree-image(bookmark, treecolAutoCompleteImage) { @@ -1840,18 +1838,18 @@ richlistitem[selected="true"][current="t } .ac-extra > .ac-comment { font-size: inherit; } .ac-url-text, .ac-action-text { + font: message-box; color: -moz-nativehyperlinktext; - font: message-box; } richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon { list-style-image: url("chrome://browser/skin/actionicon-tab.png"); -moz-image-region: rect(0, 16px, 11px, 0); padding: 0 3px; }
--- a/browser/themes/osx/jar.mn +++ b/browser/themes/osx/jar.mn @@ -122,16 +122,17 @@ browser.jar: skin/classic/browser/search-engine-placeholder@2x.png (../shared/search/search-engine-placeholder@2x.png) skin/classic/browser/badge-add-engine.png (../shared/search/badge-add-engine.png) skin/classic/browser/badge-add-engine@2x.png (../shared/search/badge-add-engine@2x.png) skin/classic/browser/search-indicator-badge-add.png (../shared/search/search-indicator-badge-add.png) skin/classic/browser/search-indicator-badge-add@2x.png (../shared/search/search-indicator-badge-add@2x.png) skin/classic/browser/search-history-icon.svg (../shared/search/history-icon.svg) skin/classic/browser/search-indicator-magnifying-glass.svg (../shared/search/search-indicator-magnifying-glass.svg) skin/classic/browser/search-arrow-go.svg (../shared/search/search-arrow-go.svg) + skin/classic/browser/info.svg (../shared/info.svg) skin/classic/browser/slowStartup-16.png skin/classic/browser/theme-switcher-icon.png (../shared/theme-switcher-icon.png) skin/classic/browser/theme-switcher-icon@2x.png (../shared/theme-switcher-icon@2x.png) skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar@2x.png skin/classic/browser/Toolbar-inverted.png skin/classic/browser/Toolbar-inverted@2x.png skin/classic/browser/toolbarbutton-dropmarker.png
new file mode 100644 --- /dev/null +++ b/browser/themes/shared/info.svg @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> + <circle fill="#00a1f2" cx="8" cy="8" r="8" /> + <circle fill="#fff" cx="8" cy="4" r="1.25" /> + <rect x="7" y="7" width="2" height="6" rx="1" ry="1" fill="#fff" /> +</svg>
new file mode 100644 --- /dev/null +++ b/browser/themes/shared/urlbarSearchSuggestionsNotification.inc.css @@ -0,0 +1,55 @@ +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] { + border-bottom: 1px solid hsla(210, 4%, 10%, 0.14); + background-color: hsla(210, 4%, 10%, 0.07); + padding: 6px 0; + -moz-padding-start: 44px; + -moz-padding-end: 6px; + background-image: url("chrome://browser/skin/info.svg"); + background-clip: padding-box; + background-position: 20px center; + background-repeat: no-repeat; + background-size: 16px 16px; +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"]:-moz-locale-dir(rtl) { + background-position: right 20px center; +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > description { + margin: 0; + padding: 0; +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > description > label.text-link { + -moz-margin-start: 0; +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button { + -moz-appearance: none; + -moz-user-focus: ignore; + min-width: 80px; + border-radius: 3px; + padding: 4px 16px; + margin: 0; + -moz-margin-start: 10px; +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-disable"] { + color: hsl(210, 0%, 38%); + background-color: hsl(210, 0%, 88%); + border: 1px solid hsl(210, 0%, 82%); +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-disable"]:hover { + background-color: hsl(210, 0%, 84%); +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-enable"] { + color: white; + background-color: hsl(93, 82%, 44%); + border: 1px solid hsl(93, 82%, 44%); +} + +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button[anonid="search-suggestions-notification-enable"]:hover { + background-color: hsl(93, 82%, 40%); +}
--- a/browser/themes/windows/browser.css +++ b/browser/themes/windows/browser.css @@ -1424,19 +1424,17 @@ html|*.urlbar-input:-moz-lwtheme::-moz-p .urlbar-display { margin-top: 0; margin-bottom: 0; -moz-margin-start: 0; color: GrayText; } -#PopupAutoCompleteRichResult > richlistbox { - transition: height 100ms; -} +%include ../shared/urlbarSearchSuggestionsNotification.inc.css #search-container { min-width: calc(54px + 11ch); } /* identity box */ #identity-box:-moz-locale-dir(ltr) { @@ -1559,27 +1557,30 @@ richlistitem[type~="action"][actiontype= .ac-result-type-tag, .autocomplete-treebody::-moz-tree-image(tag, treecolAutoCompleteImage) { list-style-image: url("chrome://browser/skin/places/tag.png"); width: 16px; height: 16px; } -.ac-comment { +.ac-comment, +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > description, +#PopupAutoCompleteRichResult > hbox[anonid="search-suggestions-notification"] > button { font-size: 1.06em; } -.ac-extra > .ac-comment { +.ac-extra > .ac-comment, +.ac-url-text, +.ac-action-text { font-size: 1em; } .ac-url-text, .ac-action-text { - font-size: 1em; color: -moz-nativehyperlinktext; } @media (-moz-os-version: windows-xp) and (-moz-windows-default-theme) { .ac-url-text:not([selected="true"]), .ac-action-text:not([selected="true"]) { color: #008800; }
--- a/browser/themes/windows/jar.mn +++ b/browser/themes/windows/jar.mn @@ -119,16 +119,17 @@ browser.jar: skin/classic/browser/search-engine-placeholder@2x.png (../shared/search/search-engine-placeholder@2x.png) skin/classic/browser/badge-add-engine.png (../shared/search/badge-add-engine.png) skin/classic/browser/badge-add-engine@2x.png (../shared/search/badge-add-engine@2x.png) skin/classic/browser/search-indicator-badge-add.png (../shared/search/search-indicator-badge-add.png) skin/classic/browser/search-indicator-badge-add@2x.png (../shared/search/search-indicator-badge-add@2x.png) skin/classic/browser/search-history-icon.svg (../shared/search/history-icon.svg) skin/classic/browser/search-indicator-magnifying-glass.svg (../shared/search/search-indicator-magnifying-glass.svg) skin/classic/browser/search-arrow-go.svg (../shared/search/search-arrow-go.svg) + skin/classic/browser/info.svg (../shared/info.svg) skin/classic/browser/setDesktopBackground.css skin/classic/browser/slowStartup-16.png skin/classic/browser/theme-switcher-icon.png (../shared/theme-switcher-icon.png) skin/classic/browser/Toolbar.png skin/classic/browser/Toolbar@2x.png skin/classic/browser/Toolbar-aero.png skin/classic/browser/Toolbar-aero@2x.png skin/classic/browser/Toolbar-inverted.png
--- a/testing/marionette/client/marionette/tests/unit/unit-tests.ini +++ b/testing/marionette/client/marionette/tests/unit/unit-tests.ini @@ -142,16 +142,17 @@ browser = false b2g = false [test_set_window_size.py] b2g = false skip-if = os == "linux" # Bug 1085717 [test_with_using_context.py] [test_modal_dialogs.py] b2g = false +skip-if = true # Disabled so bug 959567 can land [test_key_actions.py] [test_mouse_action.py] b2g = false [test_teardown_context_preserved.py] b2g = false [test_file_upload.py] b2g = false skip-if = os == "win" # http://bugs.python.org/issue14574
--- a/testing/profiles/prefs_general.js +++ b/testing/profiles/prefs_general.js @@ -330,9 +330,13 @@ user_pref("dom.serviceWorkers.periodic-u // Enable speech synth test service, and disable built in platform services. user_pref("media.webspeech.synth.test", true); // Turn off search suggestions in the location bar so as not to trigger network // connections. user_pref("browser.urlbar.suggest.searches", false); +// Turn off the location bar search suggestions opt-in. It interferes with +// tests that don't expect it to be there. +user_pref("browser.urlbar.userMadeSearchSuggestionsChoice", true); + user_pref("dom.audiochannel.mutedByDefault", false);
--- a/toolkit/components/places/UnifiedComplete.js +++ b/toolkit/components/places/UnifiedComplete.js @@ -31,17 +31,17 @@ const PREF_RESTRICT_SWITCHTAB = [ "r const PREF_RESTRICT_SEARCHES = [ "restrict.searces", "$" ]; const PREF_MATCH_TITLE = [ "match.title", "#" ]; const PREF_MATCH_URL = [ "match.url", "@" ]; const PREF_SUGGEST_HISTORY = [ "suggest.history", true ]; const PREF_SUGGEST_BOOKMARK = [ "suggest.bookmark", true ]; const PREF_SUGGEST_OPENPAGE = [ "suggest.openpage", true ]; const PREF_SUGGEST_HISTORY_ONLYTYPED = [ "suggest.history.onlyTyped", false ]; -const PREF_SUGGEST_SEARCHES = [ "suggest.searches", true ]; +const PREF_SUGGEST_SEARCHES = [ "suggest.searches", false ]; const PREF_MAX_CHARS_FOR_SUGGEST = [ "maxCharsForSearchSuggestions", 20]; // Match type constants. // These indicate what type of search function we should be using. const MATCH_ANYWHERE = Ci.mozIPlacesAutoComplete.MATCH_ANYWHERE; const MATCH_BOUNDARY_ANYWHERE = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY_ANYWHERE; const MATCH_BOUNDARY = Ci.mozIPlacesAutoComplete.MATCH_BOUNDARY;
--- a/toolkit/components/places/tests/unifiedcomplete/test_enabled.js +++ b/toolkit/components/places/tests/unifiedcomplete/test_enabled.js @@ -54,11 +54,15 @@ add_task(function* test_sync_enabled() { } Assert.equal(Services.prefs.getBoolPref("browser.urlbar.autocomplete.enabled"), true); // Disable autocoplete again, then re-enable it and check suggest prefs // have been reset. Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", false); Services.prefs.setBoolPref("browser.urlbar.autocomplete.enabled", true); for (let type of types.filter(t => t != "history")) { - Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), true); + if (type == "searches") { + Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), false); + } else { + Assert.equal(Services.prefs.getBoolPref("browser.urlbar.suggest." + type), true); + } } });
--- a/toolkit/content/widgets/autocomplete.xml +++ b/toolkit/content/widgets/autocomplete.xml @@ -1073,35 +1073,27 @@ extends="chrome://global/content/binding this._invalidate(); ]]> </body> </method> <method name="_invalidate"> <body> <![CDATA[ - // To get a fixed height for the popup, instead of the default - // behavior that grows and shrinks it on result change, a consumer - // can set the height attribute. In such a case, instead of adjusting - // the richlistbox height, we just need to collapse unused items. - if (!this.hasAttribute("height")) { - // collapsed if no matches - this.richlistbox.collapsed = (this._matchCount == 0); + // collapsed if no matches + this.richlistbox.collapsed = (this._matchCount == 0); - // Update the richlistbox height. - if (this._adjustHeightTimeout) { - clearTimeout(this._adjustHeightTimeout); - } - if (this._shrinkTimeout) { - clearTimeout(this._shrinkTimeout); - } - this._adjustHeightTimeout = setTimeout(() => this.adjustHeight(), 0); - } else { - this._collapseUnusedItems(); + // Update the richlistbox height. + if (this._adjustHeightTimeout) { + clearTimeout(this._adjustHeightTimeout); } + if (this._shrinkTimeout) { + clearTimeout(this._shrinkTimeout); + } + this._adjustHeightTimeout = setTimeout(() => this.adjustHeight(), 0); this._currentIndex = 0; if (this._appendResultTimeout) { clearTimeout(this._appendResultTimeout); } this._appendCurrentResult(); ]]> </body> @@ -1138,48 +1130,59 @@ extends="chrome://global/content/binding <method name="adjustHeight"> <body> <![CDATA[ // Figure out how many rows to show let rows = this.richlistbox.childNodes; let numRows = Math.min(this._matchCount, this.maxRows, rows.length); + this.removeAttribute("height"); + // Default the height to 0 if we have no rows to show let height = 0; if (numRows) { if (!this._rowHeight) { let firstRowRect = rows[0].getBoundingClientRect(); this._rowHeight = firstRowRect.height; - this._rlbAnimated = !!window.getComputedStyle(this.richlistbox).transitionProperty; + + let transition = + window.getComputedStyle(this.richlistbox).transitionProperty; + this._rlbAnimated = transition && transition != "none"; // Set a fixed max-height to avoid flicker when growing the panel. this.richlistbox.style.maxHeight = (this._rowHeight * this.maxRows) + "px"; } // Calculate the height to have the first row to last row shown height = this._rowHeight * numRows; } + let animate = this._rlbAnimated && + this.getAttribute("dontanimate") != "true"; let currentHeight = this.richlistbox.getBoundingClientRect().height; if (height > currentHeight) { // Grow immediately. - this.richlistbox.style.height = height + "px"; + if (animate) { + this.richlistbox.removeAttribute("height"); + this.richlistbox.style.height = height + "px"; + } else { + this.richlistbox.style.removeProperty("height"); + this.richlistbox.height = height; + } } else { // Delay shrinking to avoid flicker. this._shrinkTimeout = setTimeout(() => { - this.richlistbox.style.height = height + "px"; - if (this._rlbAnimated) { - let onTransitionEnd = () => { - this.removeEventListener("transitionend", onTransitionEnd, true); - this._collapseUnusedItems(); - }; - this.addEventListener("transitionend", onTransitionEnd, true); + this._collapseUnusedItems(); + if (animate) { + this.richlistbox.removeAttribute("height"); + this.richlistbox.style.height = height + "px"; } else { - this._collapseUnusedItems(); + this.richlistbox.style.removeProperty("height"); + this.richlistbox.height = height; } }, this.mInput.shrinkDelay); } ]]> </body> </method> <method name="_getImageURLForResolution">