author | Ed Morley <emorley@mozilla.com> |
Fri, 15 Aug 2014 17:37:16 +0100 | |
changeset 199841 | 4f430621992c83787aed08ffe8411841bb82d760 |
parent 199785 | e05ba2d89374f1807f805915b86e1e14b0094044 (current diff) |
parent 199840 | abd2919b124b47afd188ffe709517835811150a6 (diff) |
child 199842 | 54179c9a121a3d23d3dbc5167fa6b1bcbf65ed52 |
push id | 47750 |
push user | ryanvm@gmail.com |
push date | Fri, 15 Aug 2014 21:04:12 +0000 |
treeherder | mozilla-inbound@baea646f5a80 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 34.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 @@ -1275,18 +1275,18 @@ pref("devtools.toolbar.enabled", true); pref("devtools.toolbar.visible", false); pref("devtools.commands.dir", ""); // Enable the app manager pref("devtools.appmanager.enabled", true); pref("devtools.appmanager.lastTab", "help"); pref("devtools.appmanager.manifestEditor.enabled", true); -// Disable devtools webide until bug 1007059 -pref("devtools.webide.enabled", false); +// Enable DevTools WebIDE by default +pref("devtools.webide.enabled", true); // Toolbox preferences pref("devtools.toolbox.footer.height", 250); pref("devtools.toolbox.sidebar.width", 500); pref("devtools.toolbox.host", "bottom"); pref("devtools.toolbox.selectedTool", "webconsole"); pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","tilt toggle","scratchpad","resize toggle","eyedropper","screenshot --fullpage"]'); pref("devtools.toolbox.sideEnabled", true);
--- a/browser/base/content/aboutneterror/netError.css +++ b/browser/base/content/aboutneterror/netError.css @@ -1,13 +1,13 @@ /* 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/. */ -@import url("chrome://browser/skin/in-content/common.css"); +@import url("chrome://global/skin/in-content/common.css"); body { display: flex; box-sizing: padding-box; min-height: 100vh; padding: 0 48px; align-items: center; justify-content: center;
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -18,16 +18,20 @@ XPCOMUtils.defineLazyModuleGetter(this, XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu", "resource://gre/modules/CharsetMenu.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "ShortcutUtils", "resource://gre/modules/ShortcutUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch", + "resource:///modules/ContentSearch.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "AboutHome", + "resource:///modules/AboutHome.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "gDNSService", "@mozilla.org/network/dns-service;1", "nsIDNSService"); const nsIWebNavigation = Ci.nsIWebNavigation; var gLastBrowserCharset = null; var gPrevCharset = null; @@ -3090,18 +3094,27 @@ const BrowserSearch = { win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", "about:blank"); Services.obs.addObserver(observer, "browser-delayed-startup-finished", false); } return; } #endif let openSearchPageIfFieldIsNotActive = function(aSearchBar) { - if (!aSearchBar || document.activeElement != aSearchBar.textbox.inputField) + let doc = gBrowser.selectedBrowser.contentDocument; + let url = doc.documentURI.toLowerCase(); + let mm = gBrowser.selectedBrowser.messageManager; + + if (url === "about:home") { + AboutHome.focusInput(mm); + } else if (url === "about:newtab") { + ContentSearch.focusInput(mm); + } else if (!aSearchBar || document.activeElement != aSearchBar.textbox.inputField) { openUILinkIn("about:home", "current"); + } }; let searchBar = this.searchBar; let placement = CustomizableUI.getPlacementOfWidget("search-container"); let focusSearchBar = () => { searchBar = this.searchBar; searchBar.select(); openSearchPageIfFieldIsNotActive(searchBar);
--- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -101,16 +101,19 @@ let AboutHomeListener = { } }, receiveMessage: function(aMessage) { switch (aMessage.name) { case "AboutHome:Update": this.onUpdate(aMessage.data); break; + case "AboutHome:FocusInput": + this.onFocusInput(); + break; } }, onUpdate: function(aData) { let doc = content.document; if (doc.documentURI.toLowerCase() != "about:home") return; @@ -133,16 +136,17 @@ let AboutHomeListener = { if (doc.documentURI.toLowerCase() != "about:home" || doc.documentElement.hasAttribute("hasBrowserHandlers")) { return; } doc.documentElement.setAttribute("hasBrowserHandlers", "true"); let self = this; addMessageListener("AboutHome:Update", self); + addMessageListener("AboutHome:FocusInput", self); addEventListener("click", this.onClick, true); addEventListener("pagehide", function onPageHide(event) { if (event.target.defaultView.frameElement) return; removeMessageListener("AboutHome:Update", self); removeEventListener("click", self.onClick, true); removeEventListener("pagehide", onPageHide, true); if (event.target.documentElement) @@ -207,16 +211,20 @@ let AboutHomeListener = { sendAsyncMessage("AboutHome:Sync"); break; case "settings": sendAsyncMessage("AboutHome:Settings"); break; } }, + + onFocusInput: function () { + content.document.getElementById("searchText").focus(); + }, }; AboutHomeListener.init(this); // An event listener for custom "WebChannelMessageToChrome" events on pages addEventListener("WebChannelMessageToChrome", function (e) { // if target is window then we want the document principal, otherwise fallback to target itself. let principal = e.target.nodePrincipal ? e.target.nodePrincipal : e.target.document.nodePrincipal;
--- a/browser/base/content/newtab/search.js +++ b/browser/base/content/newtab/search.js @@ -71,16 +71,20 @@ let gSearch = { onCurrentEngine: function (engineName) { if (this._initialStateReceived) { this._nodes.panel.hidePopup(); this._setCurrentEngine(engineName); } }, + onFocusInput: function () { + this._nodes.text.focus(); + }, + _nodeIDSuffixes: [ "form", "logo", "manage", "panel", "text", ],
--- a/browser/base/content/test/general/browser_aboutHome.js +++ b/browser/base/content/test/general/browser_aboutHome.js @@ -414,16 +414,32 @@ let gTests = [ // Empty the search input, causing the suggestions to be hidden. EventUtils.synthesizeKey("a", { accelKey: true }); EventUtils.synthesizeKey("VK_DELETE", {}); ok(table.hidden, "Search suggestion table hidden"); }); } }, +{ + desc: "Cmd+k should focus the search bar element", + setup: function () {}, + run: Task.async(function* () { + let doc = gBrowser.selectedTab.linkedBrowser.contentDocument; + let logo = doc.getElementById("brandLogo"); + let searchInput = doc.getElementById("searchText"); + + EventUtils.synthesizeMouseAtCenter(logo, {}); + isnot(searchInput, doc.activeElement, "Search input should not be the active element."); + + EventUtils.synthesizeKey("k", { accelKey: true }); + yield promiseWaitForCondition(() => doc.activeElement === searchInput); + is(searchInput, doc.activeElement, "Search input should be the active element."); + }) +}, ]; function test() { waitForExplicitFinish(); requestLongerTimeout(2); ignoreAllUncaughtExceptions();
--- a/browser/base/content/test/general/head.js +++ b/browser/base/content/test/general/head.js @@ -77,16 +77,22 @@ function waitForCondition(condition, nex if (conditionPassed) { moveOn(); } tries++; }, 100); var moveOn = function() { clearInterval(interval); nextTest(); }; } +function promiseWaitForCondition(aConditionFn) { + let deferred = Promise.defer(); + waitForCondition(aConditionFn, deferred.resolve, "Condition didn't pass."); + return deferred.promise; +} + function getTestPlugin(aName) { var pluginName = aName || "Test Plug-in"; var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); var tags = ph.getPluginTags(); // Find the test plugin for (var i = 0; i < tags.length; i++) { if (tags[i].name == pluginName)
--- a/browser/base/content/test/newtab/browser_newtab_search.js +++ b/browser/base/content/test/newtab/browser_newtab_search.js @@ -181,16 +181,26 @@ function runTests() { yield undefined; yield suggestionsPromise.then(TestRunner.next); // Empty the search input, causing the suggestions to be hidden. EventUtils.synthesizeKey("a", { accelKey: true }); EventUtils.synthesizeKey("VK_DELETE", {}); ok(table.hidden, "Search suggestion table hidden"); + // Focus a different element than the search input. + let btn = getContentDocument().getElementById("newtab-customize-button"); + yield promiseClick(btn).then(TestRunner.next); + + isnot(input, getContentDocument().activeElement, "Search input should not be focused"); + // Test that Ctrl/Cmd + K will focus the input field. + EventUtils.synthesizeKey("k", { accelKey: true }); + yield promiseSearchEvents(["FocusInput"]).then(TestRunner.next); + is(input, getContentDocument().activeElement, "Search input should be focused"); + // Done. Revert the current engine and remove the new engines. Services.search.currentEngine = oldCurrentEngine; yield promiseSearchEvents(["CurrentEngine"]).then(TestRunner.next); let events = []; for (let engine of gNewEngines) { Services.search.removeEngine(engine); events.push("CurrentState");
--- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -304,16 +304,18 @@ function openLinkIn(url, where, params) loadInBackground = false; } } // Raise the target window before loading the URI, since loading it may // result in a new frontmost window (e.g. "javascript:window.open('');"). w.focus(); + let newTab; + switch (where) { case "current": let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE; if (aAllowThirdPartyFixup) { flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FIXUP_SCHEME_TYPOS; } @@ -327,32 +329,39 @@ function openLinkIn(url, where, params) w.gBrowser.loadURIWithFlags(url, flags, aReferrerURI, null, aPostData); break; case "tabshifted": loadInBackground = !loadInBackground; // fall through case "tab": let browser = w.gBrowser; - browser.loadOneTab(url, { - referrerURI: aReferrerURI, - charset: aCharset, - postData: aPostData, - inBackground: loadInBackground, - allowThirdPartyFixup: aAllowThirdPartyFixup, - relatedToCurrent: aRelatedToCurrent, - skipAnimation: aSkipTabAnimation, - allowMixedContent: aAllowMixedContent }); + newTab = browser.loadOneTab(url, { + referrerURI: aReferrerURI, + charset: aCharset, + postData: aPostData, + inBackground: loadInBackground, + allowThirdPartyFixup: aAllowThirdPartyFixup, + relatedToCurrent: aRelatedToCurrent, + skipAnimation: aSkipTabAnimation, + allowMixedContent: aAllowMixedContent }); break; } w.gBrowser.selectedBrowser.focus(); - if (!loadInBackground && w.isBlankPageURL(url)) + if (!loadInBackground && w.isBlankPageURL(url)) { + if (newTab) { + // Remote tab content does not focus synchronously, so we set the flag + // on this tab to skip focusing the content if we want to focus the URL + // bar instead. + newTab._urlbarFocused = true; + } w.focusAndSelectUrlBar(); + } } // Used as an onclick handler for UI elements with link-like behavior. // e.g. onclick="checkForMiddleClick(this, event);" function checkForMiddleClick(node, event) { // We should be using the disabled property here instead of the attribute, // but some elements that this function is used with don't support it (e.g. // menuitem).
--- a/browser/components/loop/MozLoopAPI.jsm +++ b/browser/components/loop/MozLoopAPI.jsm @@ -156,16 +156,37 @@ function injectLoopAPI(targetWindow) { enumerable: true, writable: true, value: function(prefName) { return MozLoopService.getLoopCharPref(prefName); } }, /** + * Return any preference under "loop." that's coercible to a boolean + * preference. + * + * @param {String} prefName The name of the pref without the preceding + * "loop." + * + * Any errors thrown by the Mozilla pref API are logged to the console + * and cause null to be returned. This includes the case of the preference + * not being found. + * + * @return {String} on success, null on error + */ + getLoopBoolPref: { + enumerable: true, + writable: true, + value: function(prefName) { + return MozLoopService.getLoopBoolPref(prefName); + } + }, + + /** * Starts alerting the user about an incoming call */ startAlerting: { enumerable: true, writable: true, value: function() { let chromeWindow = getChromeWindow(targetWindow); chromeWindow.getAttention();
--- a/browser/components/loop/MozLoopService.jsm +++ b/browser/components/loop/MozLoopService.jsm @@ -609,16 +609,39 @@ this.MozLoopService = { } catch (ex) { console.log("getLoopCharPref had trouble getting " + prefName + "; exception: " + ex); return null; } }, /** + * Return any preference under "loop." that's coercible to a character + * preference. + * + * @param {String} prefName The name of the pref without the preceding + * "loop." + * + * Any errors thrown by the Mozilla pref API are logged to the console + * and cause null to be returned. This includes the case of the preference + * not being found. + * + * @return {String} on success, null on error + */ + getLoopBoolPref: function(prefName) { + try { + return Services.prefs.getBoolPref("loop." + prefName); + } catch (ex) { + console.log("getLoopBoolPref had trouble getting " + prefName + + "; exception: " + ex); + return null; + } + }, + + /** * Performs a hawk based request to the loop server. * * @param {String} path The path to make the request to. * @param {String} method The request method, e.g. 'POST', 'GET'. * @param {Object} payloadObj An object which is converted to JSON and * transmitted with the request. * @returns {Promise} * Returns a promise that resolves to the response of the API call,
--- a/browser/components/loop/test/mochitest/browser.ini +++ b/browser/components/loop/test/mochitest/browser.ini @@ -1,8 +1,8 @@ [DEFAULT] support-files = head.js [browser_mozLoop_appVersionInfo.js] -[browser_mozLoop_charPref.js] +[browser_mozLoop_prefs.js] [browser_mozLoop_doNotDisturb.js] skip-if = buildapp == 'mulet'
rename from browser/components/loop/test/mochitest/browser_mozLoop_charPref.js rename to browser/components/loop/test/mochitest/browser_mozLoop_prefs.js --- a/browser/components/loop/test/mochitest/browser_mozLoop_charPref.js +++ b/browser/components/loop/test/mochitest/browser_mozLoop_prefs.js @@ -19,8 +19,22 @@ add_task(function* test_mozLoop_charPref gMozLoopAPI.setLoopCharPref("test", "foo"); Assert.equal(Services.prefs.getCharPref("loop.test"), "foo", "should set loop pref value correctly"); // Test getLoopCharPref Assert.equal(gMozLoopAPI.getLoopCharPref("test"), "foo", "should get loop pref value correctly"); }); + +add_task(function* test_mozLoop_boolPref() { + registerCleanupFunction(function () { + Services.prefs.clearUserPref("loop.testBool"); + }); + + Assert.ok(gMozLoopAPI, "mozLoop should exist"); + + Services.prefs.setBoolPref("loop.testBool", true); + + // Test getLoopCharPref + Assert.equal(gMozLoopAPI.getLoopBoolPref("testBool"), true, + "should get loop pref value correctly"); +});
rename from browser/components/loop/test/xpcshell/test_loopservice_get_loop_char_pref.js rename to browser/components/loop/test/xpcshell/test_loopservice_loop_prefs.js --- a/browser/components/loop/test/xpcshell/test_loopservice_get_loop_char_pref.js +++ b/browser/components/loop/test/xpcshell/test_loopservice_loop_prefs.js @@ -1,47 +1,106 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /*global XPCOMUtils, Services, Assert */ -var fakePrefName = "color"; +var fakeCharPrefName = "color"; +var fakeBoolPrefName = "boolean"; var fakePrefValue = "green"; function test_getLoopCharPref() { - Services.prefs.setCharPref("loop." + fakePrefName, fakePrefValue); + Services.prefs.setCharPref("loop." + fakeCharPrefName, fakePrefValue); - var returnedPref = MozLoopService.getLoopCharPref(fakePrefName); + var returnedPref = MozLoopService.getLoopCharPref(fakeCharPrefName); Assert.equal(returnedPref, fakePrefValue, "Should return a char pref under the loop. branch"); - Services.prefs.clearUserPref("loop." + fakePrefName); + Services.prefs.clearUserPref("loop." + fakeCharPrefName); } function test_getLoopCharPref_not_found() { - var returnedPref = MozLoopService.getLoopCharPref(fakePrefName); + var returnedPref = MozLoopService.getLoopCharPref(fakeCharPrefName); Assert.equal(returnedPref, null, "Should return null if a preference is not found"); } function test_getLoopCharPref_non_coercible_type() { - Services.prefs.setBoolPref("loop." + fakePrefName, false ); + Services.prefs.setBoolPref("loop." + fakeCharPrefName, false); - var returnedPref = MozLoopService.getLoopCharPref(fakePrefName); + var returnedPref = MozLoopService.getLoopCharPref(fakeCharPrefName); Assert.equal(returnedPref, null, "Should return null if the preference exists & is of a non-coercible type"); } +function test_setLoopCharPref() +{ + Services.prefs.setCharPref("loop." + fakeCharPrefName, "red"); + MozLoopService.setLoopCharPref(fakeCharPrefName, fakePrefValue); + + var returnedPref = Services.prefs.getCharPref("loop." + fakeCharPrefName); + + Assert.equal(returnedPref, fakePrefValue, + "Should set a char pref under the loop. branch"); + Services.prefs.clearUserPref("loop." + fakeCharPrefName); +} + +function test_setLoopCharPref_new() +{ + Services.prefs.clearUserPref("loop." + fakeCharPrefName); + MozLoopService.setLoopCharPref(fakeCharPrefName, fakePrefValue); + + var returnedPref = Services.prefs.getCharPref("loop." + fakeCharPrefName); + + Assert.equal(returnedPref, fakePrefValue, + "Should set a new char pref under the loop. branch"); + Services.prefs.clearUserPref("loop." + fakeCharPrefName); +} + +function test_setLoopCharPref_non_coercible_type() +{ + MozLoopService.setLoopCharPref(fakeCharPrefName, true); + + ok(true, "Setting non-coercible type should not fail"); +} + + +function test_getLoopBoolPref() +{ + Services.prefs.setBoolPref("loop." + fakeBoolPrefName, true); + + var returnedPref = MozLoopService.getLoopBoolPref(fakeBoolPrefName); + + Assert.equal(returnedPref, true, + "Should return a bool pref under the loop. branch"); + Services.prefs.clearUserPref("loop." + fakeBoolPrefName); +} + +function test_getLoopBoolPref_not_found() +{ + var returnedPref = MozLoopService.getLoopBoolPref(fakeBoolPrefName); + + Assert.equal(returnedPref, null, + "Should return null if a preference is not found"); +} + function run_test() { test_getLoopCharPref(); test_getLoopCharPref_not_found(); test_getLoopCharPref_non_coercible_type(); + test_setLoopCharPref(); + test_setLoopCharPref_new(); + test_setLoopCharPref_non_coercible_type(); + + test_getLoopBoolPref(); + test_getLoopBoolPref_not_found(); do_register_cleanup(function() { - Services.prefs.clearUserPref("loop." + fakePrefName); + Services.prefs.clearUserPref("loop." + fakeCharPrefName); + Services.prefs.clearUserPref("loop." + fakeBoolPrefName); }); }
deleted file mode 100644 --- a/browser/components/loop/test/xpcshell/test_loopservice_set_loop_char_pref.js +++ /dev/null @@ -1,49 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ -/*global XPCOMUtils, Services, Assert */ - -var fakePrefName = "color"; -var fakePrefValue = "green"; - -function test_setLoopCharPref() -{ - Services.prefs.setCharPref("loop." + fakePrefName, "red"); - MozLoopService.setLoopCharPref(fakePrefName, fakePrefValue); - - var returnedPref = Services.prefs.getCharPref("loop." + fakePrefName); - - Assert.equal(returnedPref, fakePrefValue, - "Should set a char pref under the loop. branch"); - Services.prefs.clearUserPref("loop." + fakePrefName); -} - -function test_setLoopCharPref_new() -{ - Services.prefs.clearUserPref("loop." + fakePrefName); - MozLoopService.setLoopCharPref(fakePrefName, fakePrefValue); - - var returnedPref = Services.prefs.getCharPref("loop." + fakePrefName); - - Assert.equal(returnedPref, fakePrefValue, - "Should set a new char pref under the loop. branch"); - Services.prefs.clearUserPref("loop." + fakePrefName); -} - -function test_setLoopCharPref_non_coercible_type() -{ - MozLoopService.setLoopCharPref(fakePrefName, true); - - ok(true, "Setting non-coercible type should not fail"); -} - - -function run_test() -{ - test_setLoopCharPref(); - test_setLoopCharPref_new(); - test_setLoopCharPref_non_coercible_type(); - - do_register_cleanup(function() { - Services.prefs.clearUserPref("loop." + fakePrefName); - }); -}
--- a/browser/components/loop/test/xpcshell/xpcshell.ini +++ b/browser/components/loop/test/xpcshell/xpcshell.ini @@ -1,17 +1,16 @@ [DEFAULT] head = head.js tail = firefox-appdir = browser [test_looppush_initialize.js] [test_loopservice_dnd.js] [test_loopservice_expiry.js] -[test_loopservice_get_loop_char_pref.js] -[test_loopservice_set_loop_char_pref.js] +[test_loopservice_loop_prefs.js] [test_loopservice_initialize.js] [test_loopservice_locales.js] [test_loopservice_registration.js] [test_loopservice_token_invalid.js] [test_loopservice_token_save.js] [test_loopservice_token_send.js] [test_loopservice_token_validation.js]
--- a/browser/components/preferences/in-content/preferences.xul +++ b/browser/components/preferences/in-content/preferences.xul @@ -3,17 +3,17 @@ - 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/. --> <?xml-stylesheet href="chrome://global/skin/global.css"?> <?xml-stylesheet href="chrome://mozapps/content/preferences/preferences.css"?> <?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?> -<?xml-stylesheet href="chrome://browser/skin/in-content/common.css"?> +<?xml-stylesheet href="chrome://global/skin/in-content/common.css"?> <?xml-stylesheet href="chrome://browser/skin/preferences/in-content/preferences.css"?> <?xml-stylesheet href="chrome://browser/content/preferences/handlers.css"?> <?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?> <!DOCTYPE page [ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
--- a/browser/components/preferences/in-content/subdialogs.js +++ b/browser/components/preferences/in-content/subdialogs.js @@ -6,17 +6,17 @@ let gSubDialog = { _closingCallback: null, _frame: null, _overlay: null, _box: null, _injectedStyleSheets: ["chrome://mozapps/content/preferences/preferences.css", "chrome://browser/skin/preferences/preferences.css", - "chrome://browser/skin/in-content/common.css", + "chrome://global/skin/in-content/common.css", "chrome://browser/skin/preferences/in-content/preferences.css"], init: function() { this._frame = document.getElementById("dialogFrame"); this._overlay = document.getElementById("dialogOverlay"); this._box = document.getElementById("dialogBox"); // Make the close button work.
--- a/browser/devtools/framework/test/browser_dynamic_tool_enabling.js +++ b/browser/devtools/framework/test/browser_dynamic_tool_enabling.js @@ -1,16 +1,15 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Tests that toggling prefs immediately (de)activates the relevant menuitem let gItemsToTest = { "menu_devToolbar": "devtools.toolbar.enabled", - "menu_devAppMgr": "devtools.appmanager.enabled", "menu_browserToolbox": ["devtools.chrome.enabled", "devtools.debugger.remote-enabled", "devtools.debugger.chrome-enabled"], "javascriptConsole": "devtools.errorconsole.enabled", "menu_devtools_connect": "devtools.debugger.remote-enabled", }; function expectedAttributeValueFromPrefs(prefs) { return prefs.every((pref) => Services.prefs.getBoolPref(pref)) ? "" : "true";
--- a/browser/devtools/framework/toolbox.js +++ b/browser/devtools/framework/toolbox.js @@ -71,16 +71,17 @@ function Toolbox(target, selectedTool, h this._refreshHostTitle = this._refreshHostTitle.bind(this); this._splitConsoleOnKeypress = this._splitConsoleOnKeypress.bind(this); this.destroy = this.destroy.bind(this); this.highlighterUtils = getHighlighterUtils(this); this._highlighterReady = this._highlighterReady.bind(this); this._highlighterHidden = this._highlighterHidden.bind(this); this._prefChanged = this._prefChanged.bind(this); this._saveSplitConsoleHeight = this._saveSplitConsoleHeight.bind(this); + this._onFocus = this._onFocus.bind(this); this._target.on("close", this.destroy); if (!hostType) { hostType = Services.prefs.getCharPref(this._prefs.LAST_HOST); } if (!selectedTool) { selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL); @@ -248,36 +249,39 @@ Toolbox.prototype = { gDevTools.on("pref-changed", this._prefChanged); this._buildDockButtons(); this._buildOptions(); this._buildTabs(); this._applyCacheSettings(); this._addKeysToWindow(); this._addReloadKeys(); - this._addToolSwitchingKeys(); + this._addHostListeners(); this._addZoomKeys(); this._loadInitialZoom(); this.webconsolePanel = this.doc.querySelector("#toolbox-panel-webconsole"); this.webconsolePanel.height = Services.prefs.getIntPref(SPLITCONSOLE_HEIGHT_PREF); this.webconsolePanel.addEventListener("resize", this._saveSplitConsoleHeight); - let splitConsolePromise = promise.resolve(); - if (Services.prefs.getBoolPref(SPLITCONSOLE_ENABLED_PREF)) { - splitConsolePromise = this.openSplitConsole(); - } - let buttonsPromise = this._buildButtons(); this._telemetry.toolOpened("toolbox"); this.selectTool(this._defaultToolId).then(panel => { + + // Wait until the original tool is selected so that the split + // console input will receive focus. + let splitConsolePromise = promise.resolve(); + if (Services.prefs.getBoolPref(SPLITCONSOLE_ENABLED_PREF)) { + splitConsolePromise = this.openSplitConsole(); + } + promise.all([ splitConsolePromise, buttonsPromise ]).then(() => { this.emit("ready"); deferred.resolve(); }, deferred.reject); }); @@ -340,25 +344,27 @@ Toolbox.prototype = { ["toolbox-force-reload-key2", true] ].forEach(([id, force]) => { this.doc.getElementById(id).addEventListener("command", (event) => { this.reloadTarget(force); }, true); }); }, - _addToolSwitchingKeys: function() { + _addHostListeners: function() { let nextKey = this.doc.getElementById("toolbox-next-tool-key"); nextKey.addEventListener("command", this.selectNextTool.bind(this), true); let prevKey = this.doc.getElementById("toolbox-previous-tool-key"); prevKey.addEventListener("command", this.selectPreviousTool.bind(this), true); // Split console uses keypress instead of command so the event can be // cancelled with stopPropagation on the keypress, and not preventDefault. this.doc.addEventListener("keypress", this._splitConsoleOnKeypress, false); + + this.doc.addEventListener("focus", this._onFocus, true); }, _saveSplitConsoleHeight: function() { Services.prefs.setIntPref(SPLITCONSOLE_HEIGHT_PREF, this.webconsolePanel.height); }, /** @@ -971,49 +977,71 @@ Toolbox.prototype = { let iframe = this.doc.getElementById("toolbox-panel-iframe-" + id); iframe.focus(); }, /** * Focus split console's input line */ focusConsoleInput: function() { - let hud = this.getPanel("webconsole").hud; - if (hud && hud.jsterm) { - hud.jsterm.inputNode.focus(); + let consolePanel = this.getPanel("webconsole"); + if (consolePanel) { + consolePanel.focusInput(); } }, /** + * If the console is split and we are focusing an element outside + * of the console, then store the newly focused element, so that + * it can be restored once the split console closes. + */ + _onFocus: function({originalTarget}) { + // Ignore any non element nodes, or any elements contained + // within the webconsole frame. + let webconsoleURL = gDevTools.getToolDefinition("webconsole").url; + if (originalTarget.nodeType !== 1 || + originalTarget.baseURI === webconsoleURL) { + return; + } + + this._lastFocusedElement = originalTarget; + }, + + /** * Opens the split console. * * @returns {Promise} a promise that resolves once the tool has been * loaded and focused. */ openSplitConsole: function() { this._splitConsole = true; Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, true); this._refreshConsoleDisplay(); this.emit("split-console"); + return this.loadTool("webconsole").then(() => { this.focusConsoleInput(); }); }, /** * Closes the split console. * * @returns {Promise} a promise that resolves once the tool has been * closed. */ closeSplitConsole: function() { this._splitConsole = false; Services.prefs.setBoolPref(SPLITCONSOLE_ENABLED_PREF, false); this._refreshConsoleDisplay(); this.emit("split-console"); + + if (this._lastFocusedElement) { + this._lastFocusedElement.focus(); + } return promise.resolve(); }, /** * Toggles the split state of the webconsole. If the webconsole panel * is already selected then this command is ignored. * * @returns {Promise} a promise that resolves once the tool has been @@ -1307,16 +1335,17 @@ Toolbox.prototype = { /** * Destroy the current host, and remove event listeners from its frame. * * @return {promise} to be resolved when the host is destroyed. */ destroyHost: function() { this.doc.removeEventListener("keypress", this._splitConsoleOnKeypress, false); + this.doc.removeEventListener("focus", this._onFocus, true); return this._host.destroy(); }, /** * Remove all UI elements, detach from target and clear up */ destroy: function() { // If several things call destroy then we give them all the same @@ -1329,16 +1358,17 @@ Toolbox.prototype = { this.off("select", this._refreshHostTitle); this.off("host-changed", this._refreshHostTitle); gDevTools.off("tool-registered", this._toolRegistered); gDevTools.off("tool-unregistered", this._toolUnregistered); gDevTools.off("pref-changed", this._prefChanged); + this._lastFocusedElement = null; this._saveSplitConsoleHeight(); this.webconsolePanel.removeEventListener("resize", this._saveSplitConsoleHeight); this.closeButton.removeEventListener("command", this.destroy, true); let outstanding = []; for (let [id, panel] of this._toolPanels) { try {
--- a/browser/devtools/scratchpad/scratchpad.js +++ b/browser/devtools/scratchpad/scratchpad.js @@ -1609,18 +1609,21 @@ var Scratchpad = { }; this.editor = new Editor(config); let editorElement = document.querySelector("#scratchpad-editor"); this.editor.appendTo(editorElement).then(() => { var lines = initialText.split("\n"); this.editor.on("change", this._onChanged); + let okstring = this.strings.GetStringFromName("selfxss.okstring"); + let msg = this.strings.formatStringFromName("selfxss.msg", [okstring], 1); this._onPaste = WebConsoleUtils.pasteHandlerGen(this.editor.container.contentDocument.body, - document.querySelector('#scratchpad-notificationbox')); + document.querySelector('#scratchpad-notificationbox'), + msg, okstring); editorElement.addEventListener("paste", this._onPaste); editorElement.addEventListener("drop", this._onPaste); this.editor.on("save", () => this.saveFile()); this.editor.focus(); this.editor.setCursor({ line: lines.length, ch: lines.pop().length }); if (state) this.dirty = !state.saved;
--- a/browser/devtools/webaudioeditor/test/browser_wa_inspector-toggle.js +++ b/browser/devtools/webaudioeditor/test/browser_wa_inspector-toggle.js @@ -53,14 +53,14 @@ function spawnTest() { click(panelWin, findGraphNode(panelWin, nodeIds[1])); yield once(panelWin, EVENTS.UI_INSPECTOR_NODE_SET); ok(!isVisible($("#web-audio-editor-details-pane-empty")), "Empty message hides even when loading node while open."); ok(isVisible($("#web-audio-editor-tabs")), "Switches to tab view when loading node while open."); - is($("#web-audio-inspector-title").value, "OscillatorNode (" + nodeIds[1] + ")", + is($("#web-audio-inspector-title").value, "Oscillator", "Inspector title updates when loading node while open."); yield teardown(panel); finish(); }
--- a/browser/devtools/webaudioeditor/test/browser_wa_inspector.js +++ b/browser/devtools/webaudioeditor/test/browser_wa_inspector.js @@ -38,23 +38,23 @@ function spawnTest() { ]); ok(WebAudioInspectorView.isVisible(), "InspectorView shown once node selected."); ok(!isVisible($("#web-audio-editor-details-pane-empty")), "InspectorView empty message hidden when node selected."); ok(isVisible($("#web-audio-editor-tabs")), "InspectorView tabs view visible when node selected."); - is($("#web-audio-inspector-title").value, "OscillatorNode (" + nodeIds[1] + ")", + is($("#web-audio-inspector-title").value, "Oscillator", "Inspector should have the node title when a node is selected."); is($("#web-audio-editor-tabs").selectedIndex, 0, "default tab selected should be the parameters tab."); click(panelWin, findGraphNode(panelWin, nodeIds[2])); yield once(panelWin, EVENTS.UI_INSPECTOR_NODE_SET); - is($("#web-audio-inspector-title").value, "GainNode (" + nodeIds[2] + ")", + is($("#web-audio-inspector-title").value, "Gain", "Inspector title updates when a new node is selected."); yield teardown(panel); finish(); }
--- a/browser/devtools/webaudioeditor/webaudioeditor-view.js +++ b/browser/devtools/webaudioeditor/webaudioeditor-view.js @@ -151,17 +151,21 @@ let WebAudioGraphView = { // Clear out previous SVG information this.clearGraph(); let graph = new dagreD3.Digraph(); let edges = []; AudioNodes.forEach(node => { // Add node to graph - graph.addNode(node.id, { label: node.type, id: node.id }); + graph.addNode(node.id, { + type: node.type, // Just for storing type data + label: node.type.replace(/Node$/, ""), // Displayed in SVG node + id: node.id // Identification + }); // Add all of the connections from this node to the edge array to be added // after all the nodes are added, otherwise edges will attempted to be created // for nodes that have not yet been added AudioNodeConnections.get(node, new Set()).forEach(dest => edges.push([node, dest])); }); edges.forEach(([node, dest]) => graph.addEdge(null, node.id, dest.id, { @@ -172,17 +176,17 @@ let WebAudioGraphView = { let renderer = new dagreD3.Renderer(); // Post-render manipulation of the nodes let oldDrawNodes = renderer.drawNodes(); renderer.drawNodes(function(graph, root) { let svgNodes = oldDrawNodes(graph, root); svgNodes.attr("class", (n) => { let node = graph.node(n); - return "audionode type-" + node.label; + return "audionode type-" + node.type; }); svgNodes.attr("data-id", (n) => { let node = graph.node(n); return node.id; }); return svgNodes; }); @@ -447,17 +451,17 @@ let WebAudioInspectorView = { this.toggleInspector({ visible: false, animated: false, delayed: false }); }, /** * Sets the title of the Inspector view */ _setTitle: function () { let node = this._currentNode; - let title = node.type + " (" + node.id + ")"; + let title = node.type.replace(/Node$/, ""); $("#web-audio-inspector-title").setAttribute("value", title); }, /** * Reconstructs the `Properties` tab in the inspector * with the `this._currentNode` as it's source. */ _buildPropertiesView: Task.async(function* () {
--- a/browser/devtools/webconsole/test/browser.ini +++ b/browser/devtools/webconsole/test/browser.ini @@ -276,16 +276,17 @@ skip-if = buildapp == 'mulet' [browser_webconsole_notifications.js] [browser_webconsole_open-links-without-callback.js] [browser_webconsole_output_copy_newlines.js] [browser_webconsole_output_order.js] [browser_webconsole_property_provider.js] [browser_webconsole_scratchpad_panel_link.js] [browser_webconsole_split.js] [browser_webconsole_split_escape_key.js] +[browser_webconsole_split_focus.js] [browser_webconsole_split_persist.js] [browser_webconsole_view_source.js] [browser_webconsole_reflow.js] [browser_webconsole_log_file_filter.js] [browser_webconsole_expandable_timestamps.js] [browser_webconsole_autocomplete_in_debugger_stackframe.js] [browser_webconsole_autocomplete_popup_close_on_tab_switch.js] [browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js]
new file mode 100644 --- /dev/null +++ b/browser/devtools/webconsole/test/browser_webconsole_split_focus.js @@ -0,0 +1,74 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +function test() { + info("Test that the split console state is persisted"); + + let toolbox; + let TEST_URI = "data:text/html;charset=utf-8,<p>Web Console test for splitting</p>"; + + Task.spawn(runner).then(finish); + + function* runner() { + info("Opening a tab while there is no user setting on split console pref"); + let {tab} = yield loadTab(TEST_URI); + let target = TargetFactory.forTab(tab); + toolbox = yield gDevTools.showToolbox(target, "inspector"); + + ok(!toolbox.splitConsole, "Split console is hidden by default"); + + info ("Focusing the search box before opening the split console"); + let inspector = toolbox.getPanel("inspector"); + inspector.searchBox.focus(); + + // Use the binding element since inspector.searchBox is a XUL element. + let activeElement = getActiveElement(inspector.panelDoc); + activeElement = activeElement.ownerDocument.getBindingParent(activeElement); + is (activeElement, inspector.searchBox, "Search box is focused"); + + yield toolbox.openSplitConsole(); + + ok(toolbox.splitConsole, "Split console is now visible"); + + // Use the binding element since jsterm.inputNode is a XUL textarea element. + let activeElement = getActiveElement(toolbox.doc); + activeElement = activeElement.ownerDocument.getBindingParent(activeElement); + let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode; + is(activeElement, inputNode, "Split console input is focused by default"); + + yield toolbox.closeSplitConsole(); + + info ("Making sure that the search box is refocused after closing the split console"); + // Use the binding element since inspector.searchBox is a XUL element. + let activeElement = getActiveElement(inspector.panelDoc); + activeElement = activeElement.ownerDocument.getBindingParent(activeElement); + is (activeElement, inspector.searchBox, "Search box is focused"); + + yield toolbox.destroy(); + } + + function getActiveElement(doc) { + let activeElement = doc.activeElement; + while (activeElement && activeElement.contentDocument) { + activeElement = activeElement.contentDocument.activeElement; + } + return activeElement; + } + + function toggleSplitConsoleWithEscape() { + let onceSplitConsole = toolbox.once("split-console"); + let contentWindow = toolbox.frame.contentWindow; + contentWindow.focus(); + EventUtils.sendKey("ESCAPE", contentWindow); + return onceSplitConsole; + } + + function finish() { + toolbox = TEST_URI = null; + Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled"); + Services.prefs.clearUserPref("devtools.toolbox.splitconsoleHeight"); + finishTest(); + } +}
--- a/browser/devtools/webconsole/test/browser_webconsole_split_persist.js +++ b/browser/devtools/webconsole/test/browser_webconsole_split_persist.js @@ -30,16 +30,22 @@ function test() { info("Opening a tab while there is a true user setting on split console pref"); let {tab} = yield loadTab(TEST_URI); let target = TargetFactory.forTab(tab); toolbox = yield gDevTools.showToolbox(target, "inspector"); ok(toolbox.splitConsole, "Split console is visible by default."); is(getHeightPrefValue(), 200, "Height is set based on panel height after closing"); + // Use the binding element since jsterm.inputNode is a XUL textarea element. + let activeElement = getActiveElement(toolbox.doc); + activeElement = activeElement.ownerDocument.getBindingParent(activeElement); + let inputNode = toolbox.getPanel("webconsole").hud.jsterm.inputNode; + is(activeElement, inputNode, "Split console input is focused by default"); + toolbox.webconsolePanel.height = 1; ok (toolbox.webconsolePanel.clientHeight > 1, "The actual height of the console is bound with a min height"); toolbox.webconsolePanel.height = 10000; ok (toolbox.webconsolePanel.clientHeight < 10000, "The actual height of the console is bound with a max height"); @@ -58,16 +64,24 @@ function test() { toolbox = yield gDevTools.showToolbox(target, "inspector"); ok(!toolbox.splitConsole, "Split console is hidden by default."); ok(!getVisiblePrefValue(), "Visibility pref is false"); yield toolbox.destroy(); } + function getActiveElement(doc) { + let activeElement = doc.activeElement; + while (activeElement && activeElement.contentDocument) { + activeElement = activeElement.contentDocument.activeElement; + } + return activeElement; + } + function getVisiblePrefValue() { return Services.prefs.getBoolPref("devtools.toolbox.splitconsoleEnabled"); } function getHeightPrefValue() { return Services.prefs.getIntPref("devtools.toolbox.splitconsoleHeight"); }
--- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -3132,17 +3132,21 @@ JSTerm.prototype = { this.completeNode = doc.querySelector(".jsterm-complete-node"); this.inputNode = doc.querySelector(".jsterm-input-node"); if (this.hud.owner._browserConsole && !Services.prefs.getBoolPref("devtools.chrome.enabled")) { inputContainer.style.display = "none"; } else { - this._onPaste = WebConsoleUtils.pasteHandlerGen(this.inputNode, doc.getElementById("webconsole-notificationbox")); + let okstring = l10n.getStr("selfxss.okstring"); + let msg = l10n.getFormatStr("selfxss.msg", [okstring]); + this._onPaste = WebConsoleUtils.pasteHandlerGen(this.inputNode, + doc.getElementById("webconsole-notificationbox"), + msg, okstring); this.inputNode.addEventListener("keypress", this._keyPress, false); this.inputNode.addEventListener("paste", this._onPaste); this.inputNode.addEventListener("drop", this._onPaste); this.inputNode.addEventListener("input", this._inputEventHandler, false); this.inputNode.addEventListener("keyup", this._inputEventHandler, false); this.inputNode.addEventListener("focus", this._focusEventHandler, false); }
--- a/browser/locales/en-US/chrome/browser/devtools/scratchpad.properties +++ b/browser/locales/en-US/chrome/browser/devtools/scratchpad.properties @@ -98,8 +98,18 @@ scratchpad.label=Scratchpad # LOCALIZATION NOTE (scratchpad.panelLabel): this is used as the # label for the toolbox panel. scratchpad.panelLabel=Scratchpad Panel # LOCALIZATION NOTE (scratchpad.tooltip): This string is displayed in the # tooltip of the tab when the Scratchpad is displayed inside the developer tools # window. scratchpad.tooltip=Scratchpad + +# LOCALIZATION NOTE (selfxss.msg): the text that is displayed when +# a new user of the developer tools pastes code into the console +# %1 is the text of selfxss.okstring +selfxss.msg=Scam Warning: Take care when pasting things you don't understand. This could allow attackers to steal your identity or take control of your computer. Please type '%S' in the scratchpad below to allow pasting. + +# LOCALIZATION NOTE (selfxss.msg): the string to be typed +# in by a new user of the developer tools when they receive the sefxss.msg prompt. +# Please avoid using non-keyboard characters here +selfxss.okstring=allow pasting
--- a/browser/modules/AboutHome.jsm +++ b/browser/modules/AboutHome.jsm @@ -246,9 +246,18 @@ let AboutHome = { } else { let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager); mm.broadcastAsyncMessage("AboutHome:Update", data); } }).then(null, function onError(x) { Cu.reportError("Error in AboutHome.sendAboutHomeData: " + x); }); }, + + /** + * Focuses the search input in the page with the given message manager. + * @param messageManager + * The MessageManager object of the selected browser. + */ + focusInput: function (messageManager) { + messageManager.sendAsyncMessage("AboutHome:FocusInput"); + } };
--- a/browser/modules/ContentSearch.jsm +++ b/browser/modules/ContentSearch.jsm @@ -89,16 +89,27 @@ this.ContentSearch = { init: function () { Cc["@mozilla.org/globalmessagemanager;1"]. getService(Ci.nsIMessageListenerManager). addMessageListener(INBOUND_MESSAGE, this); Services.obs.addObserver(this, "browser-search-engine-modified", false); }, + /** + * Focuses the search input in the page with the given message manager. + * @param messageManager + * The MessageManager object of the selected browser. + */ + focusInput: function (messageManager) { + messageManager.sendAsyncMessage(OUTBOUND_MESSAGE, { + type: "FocusInput" + }); + }, + receiveMessage: function (msg) { // Add a temporary event handler that exists only while the message is in // the event queue. If the message's source docshell changes browsers in // the meantime, then we need to update msg.target. event.detail will be // the docshell's new parent <xul:browser> element. msg.handleEvent = event => { let browserData = this._suggestionMap.get(msg.target); if (browserData) {
--- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -876,17 +876,16 @@ toolbarbutton[sdk-button="true"][cui-are -moz-box-direction: reverse; } #urlbar-icons { -moz-box-align: center; } .urlbar-icon { - cursor: pointer; padding: 0 3px; } #urlbar-search-splitter { -moz-appearance: none; width: 8px; -moz-margin-start: -4px; } @@ -1519,17 +1518,16 @@ richlistitem[type~="action"][actiontype= border-top: 1px solid GrayText; } /* Combined go/reload/stop button in location bar */ #urlbar > toolbarbutton { -moz-appearance: none; padding: 0 2px; - cursor: pointer; list-style-image: url("chrome://browser/skin/reload-stop-go.png"); } #urlbar-reload-button { -moz-image-region: rect(0, 14px, 14px, 0); } #urlbar-reload-button:not([disabled]):hover {
--- a/browser/themes/linux/jar.mn +++ b/browser/themes/linux/jar.mn @@ -30,27 +30,16 @@ browser.jar: skin/classic/browser/Geolocation-64.png skin/classic/browser/identity.png skin/classic/browser/identity-icons-generic.png skin/classic/browser/identity-icons-https.png skin/classic/browser/identity-icons-https-ev.png skin/classic/browser/identity-icons-https-mixed-active.png skin/classic/browser/identity-icons-https-mixed-display.png skin/classic/browser/Info.png -* skin/classic/browser/in-content/common.css (in-content/common.css) - skin/classic/browser/in-content/check.png (../shared/in-content/check.png) - skin/classic/browser/in-content/check@2x.png (../shared/in-content/check@2x.png) - skin/classic/browser/in-content/dropdown.png (../shared/in-content/dropdown.png) - skin/classic/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png) - skin/classic/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png) - skin/classic/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png) - skin/classic/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png) - skin/classic/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png) - skin/classic/browser/in-content/sorter.png (../shared/in-content/sorter.png) - skin/classic/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png) skin/classic/browser/menuPanel.png skin/classic/browser/menuPanel-customize.png skin/classic/browser/menuPanel-exit.png skin/classic/browser/menuPanel-help.png skin/classic/browser/menuPanel-small.png skin/classic/browser/mixed-content-blocked-16.png skin/classic/browser/mixed-content-blocked-64.png skin/classic/browser/monitor.png
--- a/browser/themes/linux/searchbar.css +++ b/browser/themes/linux/searchbar.css @@ -52,17 +52,16 @@ /* Search go button */ .search-go-container { -moz-box-align: center; } .search-go-button { padding: 1px; list-style-image: url(moz-icon://stock/gtk-find?size=menu); - cursor: pointer; } menuitem[cmd="cmd_clearhistory"] { list-style-image: url("moz-icon://stock/gtk-clear?size=menu"); } menuitem[cmd="cmd_clearhistory"][disabled] { list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
--- a/browser/themes/osx/jar.mn +++ b/browser/themes/osx/jar.mn @@ -38,27 +38,16 @@ browser.jar: skin/classic/browser/identity-icons-https@2x.png skin/classic/browser/identity-icons-https-ev.png skin/classic/browser/identity-icons-https-ev@2x.png skin/classic/browser/identity-icons-https-mixed-active.png skin/classic/browser/identity-icons-https-mixed-active@2x.png skin/classic/browser/identity-icons-https-mixed-display.png skin/classic/browser/identity-icons-https-mixed-display@2x.png skin/classic/browser/Info.png -* skin/classic/browser/in-content/common.css (in-content/common.css) - skin/classic/browser/in-content/check.png (../shared/in-content/check.png) - skin/classic/browser/in-content/check@2x.png (../shared/in-content/check@2x.png) - skin/classic/browser/in-content/dropdown.png (../shared/in-content/dropdown.png) - skin/classic/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png) - skin/classic/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png) - skin/classic/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png) - skin/classic/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png) - skin/classic/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png) - skin/classic/browser/in-content/sorter.png (../shared/in-content/sorter.png) - skin/classic/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png) skin/classic/browser/keyhole-circle.png skin/classic/browser/keyhole-circle@2x.png skin/classic/browser/KUI-background.png skin/classic/browser/subtle-pattern.png skin/classic/browser/menu-back.png skin/classic/browser/menu-forward.png skin/classic/browser/notification-16.png skin/classic/browser/notification-16@2x.png
--- a/browser/themes/shared/customizableui/panelUIOverlay.inc.css +++ b/browser/themes/shared/customizableui/panelUIOverlay.inc.css @@ -892,24 +892,24 @@ toolbarbutton[panel-multiview-anchor="tr background-repeat: no-repeat; background-color: Highlight; background-position: left 10px center, 0; /* this doesn't need to be changed for RTL */ } toolbarbutton[panel-multiview-anchor="true"] { background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted.png), linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0)); - background-position: right 5px center; + background-position: right calc(@menuPanelButtonWidth@ / 2 - @exitSubviewGutterWidth@ + 2px) center; background-repeat: no-repeat, repeat; } toolbarbutton[panel-multiview-anchor="true"]:-moz-locale-dir(rtl) { background-image: url(chrome://browser/skin/customizableui/subView-arrow-back-inverted-rtl.png), linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0)); - background-position: left 5px center; + background-position: left calc(@menuPanelButtonWidth@ / 2 - @exitSubviewGutterWidth@ + 2px) center; } toolbarpaletteitem[place="palette"] > .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker, #bookmarks-menu-button[cui-areatype="menu-panel"] > .toolbarbutton-menubutton-dropmarker { display: none; } #search-container[cui-areatype="menu-panel"],
--- a/browser/themes/shared/devtools/webaudioeditor.inc.css +++ b/browser/themes/shared/devtools/webaudioeditor.inc.css @@ -94,16 +94,20 @@ text { .theme-light g.selected text { fill: #f0f1f2; /* Toolbars */ } /** * Inspector Styles */ +#web-audio-inspector-title { + margin: 6px; +} + .web-audio-inspector .error { background-image: url(alerticon-warning.png); background-size: 13px 12px; -moz-appearance: none; opacity: 0; transition: opacity .5s ease-out 0s; }
--- a/browser/themes/shared/incontentprefs/preferences.css +++ b/browser/themes/shared/incontentprefs/preferences.css @@ -162,32 +162,32 @@ prefpane { padding: 0 10px; } #typeColumn > .treecol-sortdirection[sortDirection=ascending], #actionColumn > .treecol-sortdirection[sortDirection=ascending], #typeColumn > .treecol-sortdirection[sortDirection=descending], #actionColumn > .treecol-sortdirection[sortDirection=descending] { -moz-appearance: none; - list-style-image: url("chrome://browser/skin/in-content/sorter.png"); + list-style-image: url("chrome://global/skin/in-content/sorter.png"); } #typeColumn > .treecol-sortdirection[sortDirection=descending], #actionColumn > .treecol-sortdirection[sortDirection=descending] { transform: scaleY(-1); } @media (min-resolution: 2dppx) { #typeColumn > .treecol-sortdirection[sortDirection=ascending], #actionColumn > .treecol-sortdirection[sortDirection=ascending], #typeColumn > .treecol-sortdirection[sortDirection=descending], #actionColumn > .treecol-sortdirection[sortDirection=descending] { width: 12px; height: 8px; - list-style-image: url("chrome://browser/skin/in-content/sorter@2x.png"); + list-style-image: url("chrome://global/skin/in-content/sorter@2x.png"); } } #handlersView > richlistitem { min-height: 40px !important; } .typeIcon {
--- a/browser/themes/windows/jar.mn +++ b/browser/themes/windows/jar.mn @@ -32,27 +32,16 @@ browser.jar: skin/classic/browser/Geolocation-64.png skin/classic/browser/Info.png skin/classic/browser/identity.png skin/classic/browser/identity-icons-generic.png skin/classic/browser/identity-icons-https.png skin/classic/browser/identity-icons-https-ev.png skin/classic/browser/identity-icons-https-mixed-active.png skin/classic/browser/identity-icons-https-mixed-display.png -* skin/classic/browser/in-content/common.css (in-content/common.css) - skin/classic/browser/in-content/check.png (../shared/in-content/check.png) - skin/classic/browser/in-content/check@2x.png (../shared/in-content/check@2x.png) - skin/classic/browser/in-content/dropdown.png (../shared/in-content/dropdown.png) - skin/classic/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png) - skin/classic/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png) - skin/classic/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png) - skin/classic/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png) - skin/classic/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png) - skin/classic/browser/in-content/sorter.png (../shared/in-content/sorter.png) - skin/classic/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png) skin/classic/browser/keyhole-forward-mask.svg skin/classic/browser/KUI-background.png skin/classic/browser/livemark-folder.png skin/classic/browser/menu-back.png skin/classic/browser/menu-forward.png skin/classic/browser/menuPanel.png skin/classic/browser/menuPanel-customize.png skin/classic/browser/menuPanel-exit.png @@ -452,27 +441,16 @@ browser.jar: skin/classic/aero/browser/Geolocation-64.png skin/classic/aero/browser/Info.png (Info-aero.png) skin/classic/aero/browser/identity.png (identity-aero.png) skin/classic/aero/browser/identity-icons-generic.png skin/classic/aero/browser/identity-icons-https.png skin/classic/aero/browser/identity-icons-https-ev.png skin/classic/aero/browser/identity-icons-https-mixed-active.png skin/classic/aero/browser/identity-icons-https-mixed-display.png -* skin/classic/aero/browser/in-content/common.css (in-content/common.css) - skin/classic/aero/browser/in-content/check.png (../shared/in-content/check.png) - skin/classic/aero/browser/in-content/check@2x.png (../shared/in-content/check@2x.png) - skin/classic/aero/browser/in-content/dropdown.png (../shared/in-content/dropdown.png) - skin/classic/aero/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png) - skin/classic/aero/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png) - skin/classic/aero/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png) - skin/classic/aero/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png) - skin/classic/aero/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png) - skin/classic/aero/browser/in-content/sorter.png (../shared/in-content/sorter.png) - skin/classic/aero/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png) skin/classic/aero/browser/keyhole-forward-mask.svg skin/classic/aero/browser/KUI-background.png skin/classic/aero/browser/livemark-folder.png (livemark-folder-aero.png) skin/classic/aero/browser/menu-back.png (menu-back-aero.png) skin/classic/aero/browser/menu-forward.png (menu-forward-aero.png) skin/classic/aero/browser/menuPanel.png skin/classic/aero/browser/menuPanel-aero.png skin/classic/aero/browser/menuPanel-customize.png
--- a/dom/plugins/base/nsIPluginTag.idl +++ b/dom/plugins/base/nsIPluginTag.idl @@ -1,16 +1,16 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */ #include "nsISupports.idl" -[scriptable, uuid(0e56f04d-cda4-4a55-ab83-e5e29ddd370e)] +[scriptable, uuid(231df043-3a32-43c4-aaac-7ad2da81e84f)] interface nsIPluginTag : nsISupports { // enabledState is stored as one of the following as an integer in prefs, // so if new states are added, they must not renumber the existing states. const unsigned long STATE_DISABLED = 0; const unsigned long STATE_CLICKTOPLAY = 1; const unsigned long STATE_ENABLED = 2; @@ -20,16 +20,21 @@ interface nsIPluginTag : nsISupports readonly attribute AUTF8String version; readonly attribute AUTF8String name; /** * true only if this plugin is "hardblocked" and cannot be enabled. */ readonly attribute boolean blocklisted; + /** + * true if the state is non-default and locked, false otherwise. + */ + readonly attribute boolean isEnabledStateLocked; + readonly attribute boolean disabled; readonly attribute boolean clicktoplay; attribute unsigned long enabledState; readonly attribute PRTime lastModifiedTime; void getMimeTypes([optional] out unsigned long aCount, [retval, array, size_is(aCount)] out wstring aResults);
--- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -11,16 +11,17 @@ #include "nsPluginsDir.h" #include "nsPluginHost.h" #include "nsIBlocklistService.h" #include "nsIUnicodeDecoder.h" #include "nsIPlatformCharset.h" #include "nsPluginLogging.h" #include "nsNPAPIPlugin.h" #include "mozilla/Preferences.h" +#include "mozilla/unused.h" #include <cctype> #include "mozilla/dom/EncodingUtils.h" using mozilla::dom::EncodingUtils; using namespace mozilla; // These legacy flags are used in the plugin registry. The states are now // stored in prefs, but we still need to be able to import them. @@ -335,16 +336,32 @@ nsPluginTag::IsBlocklisted() NS_IMETHODIMP nsPluginTag::GetBlocklisted(bool* aBlocklisted) { *aBlocklisted = IsBlocklisted(); return NS_OK; } +NS_IMETHODIMP +nsPluginTag::GetIsEnabledStateLocked(bool* aIsEnabledStateLocked) +{ + *aIsEnabledStateLocked = false; + nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + + if (NS_WARN_IF(!prefs)) { + return NS_ERROR_FAILURE; + } + + unused << prefs->PrefIsLocked(GetStatePrefNameForPlugin(this).get(), + aIsEnabledStateLocked); + + return NS_OK; +} + bool nsPluginTag::IsClicktoplay() { const PluginState state = GetPluginState(); return (state == ePluginState_Clicktoplay); } NS_IMETHODIMP
rename from mobile/android/base/home/SuggestClient.java rename to mobile/android/base/SuggestClient.java --- a/mobile/android/base/home/SuggestClient.java +++ b/mobile/android/base/SuggestClient.java @@ -1,16 +1,18 @@ /* 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/. */ -package org.mozilla.gecko.home; +package org.mozilla.gecko; +import org.mozilla.gecko.AppConstants; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.mozglue.RobocopTarget; +import org.mozilla.gecko.util.HardwareUtils; import org.json.JSONArray; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.text.TextUtils; import android.util.Log; @@ -23,17 +25,21 @@ import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; /** * Use network-based search suggestions. */ public class SuggestClient { private static final String LOGTAG = "GeckoSuggestClient"; - private static final String USER_AGENT = GeckoAppShell.getGeckoInterface().getDefaultUAString(); + + // This should go through GeckoInterface to get the UA, but the search activity + // doesn't use a GeckoView yet. Until it does, get the UA directly. + private static final String USER_AGENT = HardwareUtils.isTablet() ? + AppConstants.USER_AGENT_FENNEC_TABLET : AppConstants.USER_AGENT_FENNEC_MOBILE; private final Context mContext; private final int mTimeout; // should contain the string "__searchTerms__", which is replaced with the query private final String mSuggestTemplate; // the maximum number of suggestions to return @@ -107,17 +113,17 @@ public class SuggestClient { if (json != null) { /* * Sample result: * ["foo",["food network","foothill college","foot locker",...]] */ JSONArray results = new JSONArray(json); JSONArray jsonSuggestions = results.getJSONArray(1); - + int added = 0; for (int i = 0; (i < jsonSuggestions.length()) && (added < mMaxResults); i++) { String suggestion = jsonSuggestions.getString(i); if (!suggestion.equalsIgnoreCase(query)) { suggestions.add(suggestion); added++; } }
--- a/mobile/android/base/home/BrowserSearch.java +++ b/mobile/android/base/home/BrowserSearch.java @@ -14,16 +14,17 @@ import java.util.Locale; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.mozilla.gecko.EventDispatcher; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoEvent; import org.mozilla.gecko.PrefsHelper; import org.mozilla.gecko.R; +import org.mozilla.gecko.SuggestClient; import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.Telemetry; import org.mozilla.gecko.TelemetryContract; import org.mozilla.gecko.db.BrowserContract.History; import org.mozilla.gecko.db.BrowserContract.URLColumns; import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; import org.mozilla.gecko.home.SearchLoader.SearchCursorLoader;
--- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -297,17 +297,16 @@ gbjar.sources += [ 'home/PinSiteDialog.java', 'home/ReadingListPanel.java', 'home/ReadingListRow.java', 'home/RecentTabsPanel.java', 'home/SearchEngine.java', 'home/SearchEngineRow.java', 'home/SearchLoader.java', 'home/SimpleCursorLoader.java', - 'home/SuggestClient.java', 'home/TabMenuStrip.java', 'home/TabMenuStripLayout.java', 'home/TopSitesGridItemView.java', 'home/TopSitesGridView.java', 'home/TopSitesPanel.java', 'home/TopSitesThumbnailView.java', 'home/TwoLinePageRow.java', 'InputMethods.java', @@ -374,16 +373,17 @@ gbjar.sources += [ 'SessionParser.java', 'SharedPreferencesHelper.java', 'SiteIdentity.java', 'SmsManager.java', 'sqlite/ByteBufferInputStream.java', 'sqlite/MatrixBlobCursor.java', 'sqlite/SQLiteBridge.java', 'sqlite/SQLiteBridgeException.java', + 'SuggestClient.java', 'SurfaceBits.java', 'Tab.java', 'Tabs.java', 'tabs/PrivateTabsPanel.java', 'tabs/RemoteTabsContainerPanel.java', 'tabs/RemoteTabsList.java', 'tabs/RemoteTabsPanel.java', 'tabs/RemoteTabsSetupPanel.java',
--- a/mobile/android/base/resources/layout-large-land-v11/tabs_panel.xml +++ b/mobile/android/base/resources/layout-large-land-v11/tabs_panel.xml @@ -41,21 +41,20 @@ gecko:tabs="tabs_normal"/> <org.mozilla.gecko.tabs.PrivateTabsPanel android:id="@+id/private_tabs_panel" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"/> - <org.mozilla.gecko.tabs.RemoteTabsPanel - android:id="@+id/remote_tabs" - android:layout_height="match_parent" - android:layout_width="match_parent" - android:visibility="gone"/> + <ViewStub android:id="@+id/remote_tabs_panel_stub" + android:layout="@layout/remote_tabs_panel_view" + android:layout_width="match_parent" + android:layout_height="match_parent"/> </view> <RelativeLayout android:id="@+id/tabs_panel_footer" android:layout_width="match_parent" android:layout_height="@dimen/browser_toolbar_height"> <view class="org.mozilla.gecko.tabs.TabsPanel$TabsPanelToolbar"
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/layout/remote_tabs_panel_view.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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/. --> + +<org.mozilla.gecko.tabs.RemoteTabsPanel xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/remote_tabs_panel" + android:layout_width="match_parent" + android:layout_height="match_parent"/>
--- a/mobile/android/base/resources/layout/tabs_panel.xml +++ b/mobile/android/base/resources/layout/tabs_panel.xml @@ -40,17 +40,16 @@ gecko:tabs="tabs_normal"/> <org.mozilla.gecko.tabs.PrivateTabsPanel android:id="@+id/private_tabs_panel" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"/> - <org.mozilla.gecko.tabs.RemoteTabsPanel - android:id="@+id/remote_tabs" - android:layout_height="match_parent" - android:layout_width="match_parent" - android:visibility="gone"/> + <ViewStub android:id="@+id/remote_tabs_panel_stub" + android:layout="@layout/remote_tabs_panel_view" + android:layout_width="match_parent" + android:layout_height="match_parent"/> </view> </merge>
--- a/mobile/android/base/tabs/TabsPanel.java +++ b/mobile/android/base/tabs/TabsPanel.java @@ -27,16 +27,17 @@ import android.content.res.Resources; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.view.ViewStub; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.RelativeLayout; public class TabsPanel extends LinearLayout implements GeckoPopupMenu.OnMenuItemClickListener, @@ -108,43 +109,56 @@ public class TabsPanel extends LinearLay LayoutInflater.from(context).inflate(R.layout.tabs_panel, this); initialize(); mAppStateListener = new AppStateListener() { @Override public void onResume() { if (mPanel == mPanelRemote) { // Refresh the remote panel. - mPanelRemote.show(); + getRemotePanelView().show(); } } @Override public void onOrientationChanged() { // Remote panel is already refreshed by chrome refresh. } @Override public void onPause() {} }; } + /** + * Initializes views in tabs_panel layout + * + * @throws IllegalStateException + * mCurrentPanel must have a non-null value + */ private void initialize() { + if (mCurrentPanel == null) { + throw new IllegalStateException( + "mCurrentPanel cannot be null in order for RemotePanelView to be initialized"); + } + + if (mCurrentPanel == Panel.REMOTE_TABS) { + // Initializes mPanelRemote + getRemotePanelView(); + } + mHeader = (RelativeLayout) findViewById(R.id.tabs_panel_header); mTabsContainer = (TabsListContainer) findViewById(R.id.tabs_container); mPanelNormal = (PanelView) findViewById(R.id.normal_tabs); mPanelNormal.setTabsPanel(this); mPanelPrivate = (PanelView) findViewById(R.id.private_tabs_panel); mPanelPrivate.setTabsPanel(this); - mPanelRemote = (PanelView) findViewById(R.id.remote_tabs); - mPanelRemote.setTabsPanel(this); - mFooter = (RelativeLayout) findViewById(R.id.tabs_panel_footer); mAddTab = (ImageButton) findViewById(R.id.add_tab); mAddTab.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { TabsPanel.this.addTab(); } @@ -411,17 +425,17 @@ public class TabsPanel extends LinearLay switch (panelToShow) { case NORMAL_TABS: mPanel = mPanelNormal; break; case PRIVATE_TABS: mPanel = mPanelPrivate; break; case REMOTE_TABS: - mPanel = mPanelRemote; + mPanel = getRemotePanelView(); break; default: throw new IllegalArgumentException("Unknown panel type " + panelToShow); } mPanel.show(); if (mCurrentPanel == Panel.REMOTE_TABS) { @@ -467,16 +481,19 @@ public class TabsPanel extends LinearLay mPopupMenu.dismiss(); dispatchLayoutChange(0, 0); } } public void refresh() { removeAllViews(); + // The View that mPanelRemote points to is invalidated because the layout is invalidated. + // mPanelRemote must be null in order to properly initialize RemotePanelView. + mPanelRemote = null; LayoutInflater.from(mContext).inflate(R.layout.tabs_panel, this); initialize(); if (mVisible) show(mCurrentPanel); } public void autoHidePanel() { @@ -565,9 +582,23 @@ public class TabsPanel extends LinearLay */ public Drawable getIconDrawable(Panel panel) { return mTabWidget.getIconDrawable(panel.ordinal()); } public void setIconDrawable(Panel panel, int resource) { mTabWidget.setIconDrawable(panel.ordinal(), resource); } + + /** + * Initializes mPanelRemote if necessary and provides getter because you + * should probably not access mPanelRemote directly + * + * @return PanelView + */ + private PanelView getRemotePanelView() { + if (mPanelRemote == null) { + mPanelRemote = (PanelView) ((ViewStub) findViewById(R.id.remote_tabs_panel_stub)).inflate(); + mPanelRemote.setTabsPanel(TabsPanel.this); + } + return mPanelRemote; + } }
--- a/mobile/android/base/tests/testSearchSuggestions.java +++ b/mobile/android/base/tests/testSearchSuggestions.java @@ -1,17 +1,17 @@ package org.mozilla.gecko.tests; import java.util.ArrayList; import java.util.HashMap; import org.mozilla.gecko.Actions; import org.mozilla.gecko.R; +import org.mozilla.gecko.SuggestClient; import org.mozilla.gecko.home.BrowserSearch; -import org.mozilla.gecko.home.SuggestClient; import android.app.Activity; import android.support.v4.app.Fragment; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /**
deleted file mode 100644 --- a/mobile/android/search/java/org/mozilla/search/autocomplete/SuggestClient.java +++ /dev/null @@ -1,145 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.search.autocomplete; - -import org.json.JSONArray; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.text.TextUtils; -import android.util.Log; - -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; - -/** - * Use network-based search suggestions. - */ -public class SuggestClient { - private static final String LOGTAG = "GeckoSuggestClient"; - private static final String USER_AGENT = ""; - - private final Context mContext; - private final int mTimeout; - - // should contain the string "__searchTerms__", which is replaced with the query - private final String mSuggestTemplate; - - // the maximum number of suggestions to return - private final int mMaxResults; - - // used by robocop for testing - private boolean mCheckNetwork; - - // used to make suggestions appear instantly after opt-in - private String mPrevQuery; - private ArrayList<String> mPrevResults; - - public SuggestClient(Context context, String suggestTemplate, int timeout, int maxResults) { - mContext = context; - mMaxResults = maxResults; - mSuggestTemplate = suggestTemplate; - mTimeout = timeout; - mCheckNetwork = true; - } - - /** - * Queries for a given search term and returns an ArrayList of suggestions. - */ - public ArrayList<String> query(String query) { - if (query.equals(mPrevQuery)) - return mPrevResults; - - ArrayList<String> suggestions = new ArrayList<String>(); - if (TextUtils.isEmpty(mSuggestTemplate) || TextUtils.isEmpty(query)) { - return suggestions; - } - - if (!isNetworkConnected() && mCheckNetwork) { - Log.i(LOGTAG, "Not connected to network"); - return suggestions; - } - - try { - String encoded = URLEncoder.encode(query, "UTF-8"); - String suggestUri = mSuggestTemplate.replace("__searchTerms__", encoded); - - URL url = new URL(suggestUri); - String json = null; - HttpURLConnection urlConnection = null; - InputStream in = null; - try { - urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setConnectTimeout(mTimeout); - urlConnection.setRequestProperty("User-Agent", USER_AGENT); - in = new BufferedInputStream(urlConnection.getInputStream()); - json = convertStreamToString(in); - } finally { - if (urlConnection != null) - urlConnection.disconnect(); - if (in != null) { - try { - in.close(); - } catch (IOException e) { - Log.e(LOGTAG, "error", e); - } - } - } - - if (json != null) { - /* - * Sample result: - * ["foo",["food network","foothill college","foot locker",...]] - */ - JSONArray results = new JSONArray(json); - JSONArray jsonSuggestions = results.getJSONArray(1); - - int added = 0; - for (int i = 0; (i < jsonSuggestions.length()) && (added < mMaxResults); i++) { - String suggestion = jsonSuggestions.getString(i); - if (!suggestion.equalsIgnoreCase(query)) { - suggestions.add(suggestion); - added++; - } - } - } else { - Log.e(LOGTAG, "Suggestion query failed"); - } - } catch (Exception e) { - Log.e(LOGTAG, "Error", e); - } - - mPrevQuery = query; - mPrevResults = suggestions; - return suggestions; - } - - private boolean isNetworkConnected() { - NetworkInfo networkInfo = getActiveNetworkInfo(); - return networkInfo != null && networkInfo.isConnected(); - } - - private NetworkInfo getActiveNetworkInfo() { - ConnectivityManager connectivity = (ConnectivityManager) mContext - .getSystemService(Context.CONNECTIVITY_SERVICE); - if (connectivity == null) - return null; - return connectivity.getActiveNetworkInfo(); - } - - private String convertStreamToString(java.io.InputStream is) { - try { - return new java.util.Scanner(is).useDelimiter("\\A").next(); - } catch (java.util.NoSuchElementException e) { - return ""; - } - } -}
--- a/mobile/android/search/java/org/mozilla/search/autocomplete/SuggestionsFragment.java +++ b/mobile/android/search/java/org/mozilla/search/autocomplete/SuggestionsFragment.java @@ -16,16 +16,17 @@ import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import org.mozilla.gecko.SuggestClient; import org.mozilla.gecko.Telemetry; import org.mozilla.gecko.TelemetryContract; import org.mozilla.search.AcceptsSearchQuery; import org.mozilla.search.AcceptsSearchQuery.SuggestionAnimation; import org.mozilla.search.Constants; import org.mozilla.search.R; import org.mozilla.search.providers.SearchEngine; import org.mozilla.search.providers.SearchEngineManager;
--- a/mobile/android/search/search_activity_sources.mozbuild +++ b/mobile/android/search/search_activity_sources.mozbuild @@ -3,17 +3,16 @@ # 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/. search_activity_sources = [ 'java/org/mozilla/search/AcceptsSearchQuery.java', 'java/org/mozilla/search/autocomplete/AutoCompleteAdapter.java', 'java/org/mozilla/search/autocomplete/ClearableEditText.java', - 'java/org/mozilla/search/autocomplete/SuggestClient.java', 'java/org/mozilla/search/autocomplete/SuggestionsFragment.java', 'java/org/mozilla/search/Constants.java', 'java/org/mozilla/search/MainActivity.java', 'java/org/mozilla/search/PostSearchFragment.java', 'java/org/mozilla/search/PreSearchFragment.java', 'java/org/mozilla/search/providers/BingSearchEngine.java', 'java/org/mozilla/search/providers/GoogleSearchEngine.java', 'java/org/mozilla/search/providers/SearchEngine.java',
--- a/toolkit/devtools/webconsole/utils.js +++ b/toolkit/devtools/webconsole/utils.js @@ -565,31 +565,29 @@ let WebConsoleUtils = { }, /** * The inputNode "paste" event handler generator. Helps prevent self-xss attacks * * @param nsIDOMElement inputField * @param nsIDOMElement notificationBox * @returns A function to be added as a handler to 'paste' and 'drop' events on the input field */ - pasteHandlerGen: function WCU_pasteHandlerGen(inputField, notificationBox){ + pasteHandlerGen: function WCU_pasteHandlerGen(inputField, notificationBox, msg, okstring) { let handler = function WCU_pasteHandler(aEvent) { if (WebConsoleUtils.usageCount >= CONSOLE_ENTRY_THRESHOLD) { inputField.removeEventListener("paste", handler); inputField.removeEventListener("drop", handler); return true; } if (notificationBox.getNotificationWithValue("selfxss-notification")) { aEvent.preventDefault(); aEvent.stopPropagation(); return false; } - let l10n = new WebConsoleUtils.l10n("chrome://browser/locale/devtools/webconsole.properties"); - let okstring = l10n.getStr("selfxss.okstring"); - let msg = l10n.getFormatStr("selfxss.msg", [okstring]); + let notification = notificationBox.appendNotification(msg, "selfxss-notification", null, notificationBox.PRIORITY_WARNING_HIGH, null, function(eventType) { // Cleanup function if notification is dismissed if (eventType == "removed") { inputField.removeEventListener("keyup", pasteKeyUpHandler); }
--- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -3101,31 +3101,34 @@ var gDetailView = { warning.textContent = gStrings.ext.GetStringFromName("details.notification.openH264Pending"); } else { this.node.removeAttribute("notification"); } } let menulist = document.getElementById("detail-state-menulist"); let addonType = AddonManager.addonTypes[this._addon.type]; - if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE && - (hasPermission(this._addon, "ask_to_activate") || - hasPermission(this._addon, "enable") || - hasPermission(this._addon, "disable"))) { + if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE) { let askItem = document.getElementById("detail-ask-to-activate-menuitem"); let alwaysItem = document.getElementById("detail-always-activate-menuitem"); let neverItem = document.getElementById("detail-never-activate-menuitem"); + let hasActivatePermission = + ["ask_to_activate", "enable", "disable"].some(perm => hasPermission(this._addon, perm)); + if (this._addon.userDisabled === true) { menulist.selectedItem = neverItem; } else if (this._addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) { menulist.selectedItem = askItem; } else { menulist.selectedItem = alwaysItem; } + + menulist.disabled = !hasActivatePermission; menulist.hidden = false; + menulist.classList.add('no-auto-hide'); } else { menulist.hidden = true; } this.node.setAttribute("active", this._addon.isActive); }, clearLoading: function gDetailView_clearLoading() {
--- a/toolkit/mozapps/extensions/content/extensions.xml +++ b/toolkit/mozapps/extensions/content/extensions.xml @@ -1301,36 +1301,36 @@ this.removeAttribute("notification"); } } this._preferencesBtn.hidden = (!this.mAddon.optionsURL) || this.mAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE_INFO; let addonType = AddonManager.addonTypes[this.mAddon.type]; - if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE && - (this.hasPermission("ask_to_activate") || - this.hasPermission("enable") || - this.hasPermission("disable"))) { + if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE) { this._enableBtn.disabled = true; this._disableBtn.disabled = true; this._askToActivateMenuitem.disabled = !this.hasPermission("ask_to_activate"); this._alwaysActivateMenuitem.disabled = !this.hasPermission("enable"); this._neverActivateMenuitem.disabled = !this.hasPermission("disable"); if (this.mAddon.userDisabled === true) { this._stateMenulist.selectedItem = this._neverActivateMenuitem; } else if (this.mAddon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) { this._stateMenulist.selectedItem = this._askToActivateMenuitem; } else { this._stateMenulist.selectedItem = this._alwaysActivateMenuitem; } - this._stateMenulist.selectedItem.disabled = false; - this._stateMenulist.disabled = false; + let hasActivatePermission = + ["ask_to_activate", "enable", "disable"].some(perm => this.hasPermission(perm)); + this._stateMenulist.disabled = !hasActivatePermission; + this._stateMenulist.hidden = false; + this._stateMenulist.classList.add('no-auto-hide'); } else { - this._stateMenulist.disabled = true; + this._stateMenulist.hidden = true; if (this.hasPermission("enable")) { this._enableBtn.hidden = false; let tooltip = gViewController.commands["cmd_enableItem"] .getTooltip(this.mAddon); this._enableBtn.setAttribute("tooltiptext", tooltip); } else { this._enableBtn.hidden = true; }
--- a/toolkit/mozapps/extensions/internal/PluginProvider.jsm +++ b/toolkit/mozapps/extensions/internal/PluginProvider.jsm @@ -456,16 +456,19 @@ function PluginWrapper(aId, aName, aDesc }); this.__defineGetter__("operationsRequiringRestart", function() { return AddonManager.OP_NEEDS_RESTART_NONE; }); this.__defineGetter__("permissions", function() { let permissions = 0; + if (aTags[0].isEnabledStateLocked) { + return permissions; + } if (!this.appDisabled) { if (this.userDisabled !== true) permissions |= AddonManager.PERM_CAN_DISABLE; let blocklistState = this.blocklistState; let isCTPBlocklisted = (blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE ||
--- a/toolkit/mozapps/extensions/test/browser/browser-common.ini +++ b/toolkit/mozapps/extensions/test/browser/browser-common.ini @@ -39,16 +39,17 @@ skip-if = e10s # Bug ?????? - test times [browser_dragdrop.js] skip-if = buildapp == 'mulet' [browser_experiments.js] [browser_list.js] [browser_metadataTimeout.js] [browser_searching.js] [browser_sorting.js] [browser_sorting_plugins.js] +[browser_plugin_enabled_state_locked.js] skip-if = e10s # Bug ?????? - leaked until shutdown [nsGlobalWindow #1760 about:blank] [browser_uninstalling.js] skip-if = e10s # Bug ?????? - leaked until shutdown [nsGlobalWindow #1760 about:blank] [browser_install.js] [browser_recentupdates.js] [browser_manualupdates.js] [browser_globalwarnings.js] [browser_globalinformations.js]
--- a/toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js +++ b/toolkit/mozapps/extensions/test/browser/browser_CTP_plugins.js @@ -195,26 +195,26 @@ function part11() { }); } function part12(aWindow) { gManagerWindow = aWindow; let pluginEl = get_addon_element(gManagerWindow, gTestPluginId); pluginEl.parentNode.ensureElementIsVisible(pluginEl); let menu = gManagerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "state-menulist"); - is_element_hidden(menu, "part12: state menu should be hidden"); + is(menu.disabled, true, "part12: state menu should be disabled"); let details = gManagerWindow.document.getAnonymousElementByAttribute(pluginEl, "anonid", "details-btn"); EventUtils.synthesizeMouseAtCenter(details, {}, gManagerWindow); wait_for_view_load(gManagerWindow, part13); } function part13() { let menu = gManagerWindow.document.getElementById("detail-state-menulist"); - is_element_hidden(menu, "part13: detail state menu should be hidden"); + is(menu.disabled, true, "part13: detail state menu should be disabled"); setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml", function() { run_next_test(); }); } function end_test() { Services.prefs.clearUserPref("plugins.click_to_play");
new file mode 100644 --- /dev/null +++ b/toolkit/mozapps/extensions/test/browser/browser_plugin_enabled_state_locked.js @@ -0,0 +1,121 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Tests that state menu is displayed correctly (enabled or disabled) in the add-on manager +// when the preference is unlocked / locked +const {classes: Cc, interfaces: Ci} = Components; +const gIsWindows = ("@mozilla.org/windows-registry-key;1" in Cc); +const gIsOSX = ("nsILocalFileMac" in Ci); +const gIsLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc) || + ("@mozilla.org/gio-service;1" in Cc); + +let gManagerWindow; +let gCategoryUtilities; +let gPluginElement; + +function getTestPluginPref() { + let prefix = "plugin.state."; + if (gIsWindows) + return prefix + "nptest"; + else if (gIsLinux) + return prefix + "libnptest"; + else + return prefix + "test"; +} + +registerCleanupFunction(() => { + Services.prefs.unlockPref(getTestPluginPref()); + Services.prefs.clearUserPref(getTestPluginPref()); +}); + +function getPlugins() { + let deferred = Promise.defer(); + AddonManager.getAddonsByTypes(["plugin"], plugins => deferred.resolve(plugins)); + return deferred.promise; +} + +function getTestPlugin(aPlugins) { + let testPluginId; + + for (let plugin of aPlugins) { + if (plugin.name == "Test Plug-in") { + testPluginId = plugin.id; + break; + } + } + + Assert.ok(testPluginId, "Test Plug-in should exist"); + + let pluginElement = get_addon_element(gManagerWindow, testPluginId); + pluginElement.parentNode.ensureElementIsVisible(pluginElement); + + return pluginElement; +} + +function checkStateMenu(locked) { + Assert.equal(Services.prefs.prefIsLocked(getTestPluginPref()), locked, + "Preference lock state should be correct."); + let menuList = gManagerWindow.document.getAnonymousElementByAttribute(gPluginElement, "anonid", "state-menulist"); + + is_element_visible(menuList, "State menu should be visible."); + Assert.equal(menuList.disabled, locked, + "State menu should" + (locked === true ? "" : " not") + " be disabled."); +} + +function checkStateMenuDetail(locked) { + Assert.equal(Services.prefs.prefIsLocked(getTestPluginPref()), locked, + "Preference should be " + (locked === true ? "" : "un") + "locked."); + + // open details menu + let details = gManagerWindow.document.getAnonymousElementByAttribute(gPluginElement, "anonid", "details-btn"); + is_element_visible(details, "Details link should be visible."); + EventUtils.synthesizeMouseAtCenter(details, {}, gManagerWindow); + + let deferred = Promise.defer(); + wait_for_view_load(gManagerWindow, function() { + let menuList = gManagerWindow.document.getElementById("detail-state-menulist"); + is_element_visible(menuList, "Details state menu should be visible."); + Assert.equal(menuList.disabled, locked, + "Details state menu enabled state should be correct."); + deferred.resolve(); + }); + return deferred.promise; +} + +add_task(function* initializeState() { + Services.prefs.setIntPref(getTestPluginPref(), Ci.nsIPluginTag.STATE_ENABLED); + Services.prefs.unlockPref(getTestPluginPref()); + gManagerWindow = yield open_manager(); + gCategoryUtilities = new CategoryUtilities(gManagerWindow); + yield gCategoryUtilities.openType("plugin"); + + let plugins = yield getPlugins(); + gPluginElement = getTestPlugin(plugins); +}); + +// Tests that plugin state menu is enabled if the preference is unlocked +add_task(function* taskCheckStateMenuIsEnabled() { + checkStateMenu(false); + yield checkStateMenuDetail(false); +}); + +// Lock the preference and then reload the plugin category +add_task(function* reinitializeState() { + // lock the preference + Services.prefs.lockPref(getTestPluginPref()); + yield gCategoryUtilities.openType("plugin"); + // Retrieve the test plugin element + let plugins = yield getPlugins(); + gPluginElement = getTestPlugin(plugins); +}); + +// Tests that plugin state menu is disabled if the preference is locked +add_task(function* taskCheckStateMenuIsDisabled() { + checkStateMenu(true); + yield checkStateMenuDetail(true); +}); + +add_task(function* testCleanup() { + yield close_manager(gManagerWindow); +});
rename from browser/themes/linux/in-content/common.css rename to toolkit/themes/linux/global/in-content/common.css --- a/browser/themes/linux/in-content/common.css +++ b/toolkit/themes/linux/global/in-content/common.css @@ -1,13 +1,13 @@ /* - 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/. */ -%include ../../shared/in-content/common.inc.css +%include ../../../shared/in-content/common.inc.css xul|tab[selected] { /* Override styles for tab[selected] from toolkit/themes/linux/global/tabbox.css */ margin-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
--- a/toolkit/themes/linux/global/jar.mn +++ b/toolkit/themes/linux/global/jar.mn @@ -49,9 +49,20 @@ toolkit.jar: + skin/classic/global/icons/panelarrow-horizontal.svg (icons/panelarrow-horizontal.svg) + skin/classic/global/icons/panelarrow-vertical.svg (icons/panelarrow-vertical.svg) + skin/classic/global/icons/resizer.png (icons/resizer.png) + skin/classic/global/icons/sslWarning.png (icons/sslWarning.png) + skin/classic/global/icons/wrap.png (icons/wrap.png) + skin/classic/global/icons/webapps-16.png (icons/webapps-16.png) + skin/classic/global/icons/webapps-64.png (icons/webapps-64.png) skin/classic/global/menu/shared-menu-check.png (../../shared/menu-check.png) +* skin/classic/global/in-content/common.css (in-content/common.css) + skin/classic/global/in-content/check.png (../../shared/in-content/check.png) + skin/classic/global/in-content/check@2x.png (../../shared/in-content/check@2x.png) + skin/classic/global/in-content/dropdown.png (../../shared/in-content/dropdown.png) + skin/classic/global/in-content/dropdown@2x.png (../../shared/in-content/dropdown@2x.png) + skin/classic/global/in-content/dropdown-disabled.png (../../shared/in-content/dropdown-disabled.png) + skin/classic/global/in-content/dropdown-disabled@2x.png (../../shared/in-content/dropdown-disabled@2x.png) + skin/classic/global/in-content/help-glyph.png (../../shared/in-content/help-glyph.png) + skin/classic/global/in-content/help-glyph@2x.png (../../shared/in-content/help-glyph@2x.png) + skin/classic/global/in-content/sorter.png (../../shared/in-content/sorter.png) + skin/classic/global/in-content/sorter@2x.png (../../shared/in-content/sorter@2x.png) + skin/classic/global/toolbar/spring.png (toolbar/spring.png)
--- a/toolkit/themes/linux/mozapps/extensions/extensions.css +++ b/toolkit/themes/linux/mozapps/extensions/extensions.css @@ -879,16 +879,20 @@ setting[type="radio"] > radiogroup { /*** buttons ***/ .addon-control[disabled="true"] { display: none; } +.addon-control.no-auto-hide { + display: block; +} + .addon-control.enable { list-style-image: url("moz-icon://stock/gtk-yes?size=button"); } .addon-control.disable { list-style-image: url("moz-icon://stock/gtk-no?size=button"); }
rename from browser/themes/osx/in-content/common.css rename to toolkit/themes/osx/global/in-content/common.css --- a/browser/themes/osx/in-content/common.css +++ b/toolkit/themes/osx/global/in-content/common.css @@ -1,13 +1,13 @@ /* - 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/. */ -%include ../../shared/in-content/common.inc.css +%include ../../../shared/in-content/common.inc.css xul|tabs { padding-right: 0; padding-left: 0; } xul|tab[selected] { text-shadow: none;
--- a/toolkit/themes/osx/global/jar.mn +++ b/toolkit/themes/osx/global/jar.mn @@ -179,16 +179,27 @@ toolkit.jar: skin/classic/global/media/volume-full.png (media/volume-full.png) skin/classic/global/media/volume-full@2x.png (media/volume-full@2x.png) skin/classic/global/media/clicktoplay-bgtexture.png (media/clicktoplay-bgtexture.png) skin/classic/global/media/videoClickToPlayButton.svg (media/videoClickToPlayButton.svg) skin/classic/global/menu/menu-arrow.png (menu/menu-arrow.png) skin/classic/global/menu/menu-arrow@2x.png (menu/menu-arrow@2x.png) skin/classic/global/menu/shared-menu-check.png (../../shared/menu-check.png) skin/classic/global/menu/shared-menu-check@2x.png (../../shared/menu-check@2x.png) +* skin/classic/global/in-content/common.css (in-content/common.css) + skin/classic/global/in-content/check.png (../../shared/in-content/check.png) + skin/classic/global/in-content/check@2x.png (../../shared/in-content/check@2x.png) + skin/classic/global/in-content/dropdown.png (../../shared/in-content/dropdown.png) + skin/classic/global/in-content/dropdown@2x.png (../../shared/in-content/dropdown@2x.png) + skin/classic/global/in-content/dropdown-disabled.png (../../shared/in-content/dropdown-disabled.png) + skin/classic/global/in-content/dropdown-disabled@2x.png (../../shared/in-content/dropdown-disabled@2x.png) + skin/classic/global/in-content/help-glyph.png (../../shared/in-content/help-glyph.png) + skin/classic/global/in-content/help-glyph@2x.png (../../shared/in-content/help-glyph@2x.png) + skin/classic/global/in-content/sorter.png (../../shared/in-content/sorter.png) + skin/classic/global/in-content/sorter@2x.png (../../shared/in-content/sorter@2x.png) skin/classic/global/scale/scale-tray-horiz.gif (scale/scale-tray-horiz.gif) skin/classic/global/scale/scale-tray-vert.gif (scale/scale-tray-vert.gif) skin/classic/global/splitter/dimple.png (splitter/dimple.png) skin/classic/global/splitter/grip-bottom.gif (splitter/grip-bottom.gif) skin/classic/global/splitter/grip-top.gif (splitter/grip-top.gif) skin/classic/global/splitter/grip-left.gif (splitter/grip-left.gif) skin/classic/global/splitter/grip-right.gif (splitter/grip-right.gif) skin/classic/global/toolbar/spring.png (toolbar/spring.png)
--- a/toolkit/themes/osx/mozapps/extensions/extensions.css +++ b/toolkit/themes/osx/mozapps/extensions/extensions.css @@ -1103,16 +1103,20 @@ setting[type="radio"] > radiogroup { /*** buttons ***/ .addon-control[disabled="true"] { display: none; } +.addon-control.no-auto-hide { + display: block; +} + button.button-link { -moz-appearance: none; background: transparent; border: none; box-shadow: none; text-decoration: underline; color: #0066CC; cursor: pointer;
rename from browser/themes/shared/in-content/check.png rename to toolkit/themes/shared/in-content/check.png
rename from browser/themes/shared/in-content/check@2x.png rename to toolkit/themes/shared/in-content/check@2x.png
rename from browser/themes/shared/in-content/common.inc.css rename to toolkit/themes/shared/in-content/common.inc.css --- a/browser/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -189,17 +189,17 @@ xul|button[type="menu"] > xul|*.button-b -moz-appearance: none; margin: 1px 0; -moz-margin-start: 10px; padding: 0; width: 10px; height: 16px; border: none; background-color: transparent; - list-style-image: url("chrome://browser/skin/in-content/dropdown.png"); + list-style-image: url("chrome://global/skin/in-content/dropdown.png"); } xul|*.help-button { min-width: 30px; border-radius: 2px; border: 1px solid #c1c1c1; background-color: #ffcb00; background-image: none; @@ -222,24 +222,24 @@ xul|*.help-button > xul|*.button-box { padding-bottom: 0; padding-right: 0 !important; padding-left: 0 !important; } xul|*.help-button > xul|*.button-box > xul|*.button-icon { width: 26px; height: 26px; - background-image: url("chrome://browser/skin/in-content/help-glyph.png"); + background-image: url("chrome://global/skin/in-content/help-glyph.png"); background-position: center; } @media (min-resolution: 2dppx) { xul|*.help-button > xul|*.button-box > xul|*.button-icon { background-size: 26px 26px; - background-image: url("chrome://browser/skin/in-content/help-glyph@2x.png"); + background-image: url("chrome://global/skin/in-content/help-glyph@2x.png"); } } xul|*.help-button > xul|*.button-box > xul|*.button-text { display: none; } xul|*.spinbuttons-button { @@ -278,31 +278,31 @@ xul|*.spinbuttons-down[disabled="true"] } xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker { -moz-appearance: none; -moz-margin-end: 10px; padding: 0; border: none; background-color: transparent; - list-style-image: url("chrome://browser/skin/in-content/dropdown.png"); + list-style-image: url("chrome://global/skin/in-content/dropdown.png"); } xul|menulist[disabled="true"]:not([editable="true"]) > xul|*.menulist-dropmarker { - list-style-image: url("chrome://browser/skin/in-content/dropdown-disabled.png") + list-style-image: url("chrome://global/skin/in-content/dropdown-disabled.png") } @media (min-resolution: 2dppx) { xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker, xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker { - list-style-image: url("chrome://browser/skin/in-content/dropdown@2x.png"); + list-style-image: url("chrome://global/skin/in-content/dropdown@2x.png"); } xul|menulist[disabled="true"]:not([editable="true"]) > xul|*.menulist-dropmarker { - list-style-image: url("chrome://browser/skin/in-content/dropdown-disabled@2x.png") + list-style-image: url("chrome://global/skin/in-content/dropdown-disabled@2x.png") } xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker > xul|*.dropmarker-icon, xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker > xul|*.dropmarker-icon { width: 10px; height: 16px; } } @@ -426,34 +426,34 @@ xul|*.checkbox-check { box-shadow: 0 1px 1px 0 #fff, inset 0 2px 0 0 rgba(0,0,0,0.03); } xul|checkbox:not([disabled="true"]):hover > xul|*.checkbox-check { border-color: #0095dd; } xul|*.checkbox-check[checked] { - background-image: url("chrome://browser/skin/in-content/check.png"), + background-image: url("chrome://global/skin/in-content/check.png"), /* !important needed to override toolkit !important rule */ linear-gradient(#fff, rgba(255,255,255,0.8)) !important; } xul|checkbox[disabled="true"] > xul|*.checkbox-check { opacity: 0.5; } xul|*.checkbox-label-box { -moz-margin-start: -1px; /* negative margin for the transparent border */ -moz-padding-start: 0; } @media (min-resolution: 2dppx) { xul|*.checkbox-check[checked] { background-size: 12px 12px, auto; - background-image: url("chrome://browser/skin/in-content/check@2x.png"), + background-image: url("chrome://global/skin/in-content/check@2x.png"), linear-gradient(#fff, rgba(255,255,255,0.8)) !important; } } xul|*.radio-check { -moz-appearance: none; width: 23px; height: 23px;
rename from browser/themes/shared/in-content/dropdown-disabled.png rename to toolkit/themes/shared/in-content/dropdown-disabled.png
rename from browser/themes/shared/in-content/dropdown-disabled@2x.png rename to toolkit/themes/shared/in-content/dropdown-disabled@2x.png
rename from browser/themes/shared/in-content/dropdown.png rename to toolkit/themes/shared/in-content/dropdown.png
rename from browser/themes/shared/in-content/dropdown@2x.png rename to toolkit/themes/shared/in-content/dropdown@2x.png
rename from browser/themes/shared/in-content/help-glyph.png rename to toolkit/themes/shared/in-content/help-glyph.png
rename from browser/themes/shared/in-content/help-glyph@2x.png rename to toolkit/themes/shared/in-content/help-glyph@2x.png
rename from browser/themes/shared/in-content/sorter.png rename to toolkit/themes/shared/in-content/sorter.png
rename from browser/themes/shared/in-content/sorter@2x.png rename to toolkit/themes/shared/in-content/sorter@2x.png
rename from browser/themes/windows/in-content/common.css rename to toolkit/themes/windows/global/in-content/common.css --- a/browser/themes/windows/in-content/common.css +++ b/toolkit/themes/windows/global/in-content/common.css @@ -1,13 +1,13 @@ /* - 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/. */ -%include ../../shared/in-content/common.inc.css +%include ../../../shared/in-content/common.inc.css xul|caption { background-color: transparent; } xul|button, xul|colorpicker[type="button"], xul|menulist {
--- a/toolkit/themes/windows/global/jar.mn +++ b/toolkit/themes/windows/global/jar.mn @@ -164,16 +164,27 @@ toolkit.jar: skin/classic/global/media/throbber.png (media/throbber.png) skin/classic/global/media/stalled.png (media/stalled.png) skin/classic/global/media/volume-empty.png (media/volume-empty.png) skin/classic/global/media/volume-full.png (media/volume-full.png) skin/classic/global/media/error.png (media/error.png) skin/classic/global/media/clicktoplay-bgtexture.png (media/clicktoplay-bgtexture.png) skin/classic/global/media/videoClickToPlayButton.svg (media/videoClickToPlayButton.svg) skin/classic/global/menu/shared-menu-check.png (../../shared/menu-check.png) +* skin/classic/global/in-content/common.css (in-content/common.css) + skin/classic/global/in-content/check.png (../../shared/in-content/check.png) + skin/classic/global/in-content/check@2x.png (../../shared/in-content/check@2x.png) + skin/classic/global/in-content/dropdown.png (../../shared/in-content/dropdown.png) + skin/classic/global/in-content/dropdown@2x.png (../../shared/in-content/dropdown@2x.png) + skin/classic/global/in-content/dropdown-disabled.png (../../shared/in-content/dropdown-disabled.png) + skin/classic/global/in-content/dropdown-disabled@2x.png (../../shared/in-content/dropdown-disabled@2x.png) + skin/classic/global/in-content/help-glyph.png (../../shared/in-content/help-glyph.png) + skin/classic/global/in-content/help-glyph@2x.png (../../shared/in-content/help-glyph@2x.png) + skin/classic/global/in-content/sorter.png (../../shared/in-content/sorter.png) + skin/classic/global/in-content/sorter@2x.png (../../shared/in-content/sorter@2x.png) skin/classic/global/printpreview/arrow-left.png (printpreview/arrow-left.png) skin/classic/global/printpreview/arrow-left-end.png (printpreview/arrow-left-end.png) skin/classic/global/printpreview/arrow-right.png (printpreview/arrow-right.png) skin/classic/global/printpreview/arrow-right-end.png (printpreview/arrow-right-end.png) skin/classic/global/radio/radio-check.gif (radio/radio-check.gif) skin/classic/global/radio/radio-check-dis.gif (radio/radio-check-dis.gif) skin/classic/global/scrollbar/slider.gif (scrollbar/slider.gif) skin/classic/global/splitter/grip-bottom.gif (splitter/grip-bottom.gif) @@ -347,16 +358,27 @@ toolkit.jar: skin/classic/aero/global/media/throbber.png (media/throbber.png) skin/classic/aero/global/media/stalled.png (media/stalled.png) skin/classic/aero/global/media/volume-empty.png (media/volume-empty.png) skin/classic/aero/global/media/volume-full.png (media/volume-full.png) skin/classic/aero/global/media/error.png (media/error.png) skin/classic/aero/global/media/clicktoplay-bgtexture.png (media/clicktoplay-bgtexture.png) skin/classic/aero/global/media/videoClickToPlayButton.svg (media/videoClickToPlayButton.svg) skin/classic/aero/global/menu/shared-menu-check.png (../../shared/menu-check.png) +* skin/classic/aero/global/in-content/common.css (in-content/common.css) + skin/classic/aero/global/in-content/check.png (../../shared/in-content/check.png) + skin/classic/aero/global/in-content/check@2x.png (../../shared/in-content/check@2x.png) + skin/classic/aero/global/in-content/dropdown.png (../../shared/in-content/dropdown.png) + skin/classic/aero/global/in-content/dropdown@2x.png (../../shared/in-content/dropdown@2x.png) + skin/classic/aero/global/in-content/dropdown-disabled.png (../../shared/in-content/dropdown-disabled.png) + skin/classic/aero/global/in-content/dropdown-disabled@2x.png (../../shared/in-content/dropdown-disabled@2x.png) + skin/classic/aero/global/in-content/help-glyph.png (../../shared/in-content/help-glyph.png) + skin/classic/aero/global/in-content/help-glyph@2x.png (../../shared/in-content/help-glyph@2x.png) + skin/classic/aero/global/in-content/sorter.png (../../shared/in-content/sorter.png) + skin/classic/aero/global/in-content/sorter@2x.png (../../shared/in-content/sorter@2x.png) skin/classic/aero/global/printpreview/arrow-left.png (printpreview/arrow-left-aero.png) skin/classic/aero/global/printpreview/arrow-left-end.png (printpreview/arrow-left-end-aero.png) skin/classic/aero/global/printpreview/arrow-right.png (printpreview/arrow-right-aero.png) skin/classic/aero/global/printpreview/arrow-right-end.png (printpreview/arrow-right-end-aero.png) skin/classic/aero/global/radio/radio-check.gif (radio/radio-check.gif) skin/classic/aero/global/radio/radio-check-dis.gif (radio/radio-check-dis.gif) skin/classic/aero/global/scrollbar/slider.gif (scrollbar/slider.gif) skin/classic/aero/global/splitter/grip-bottom.gif (splitter/grip-bottom.gif)
--- a/toolkit/themes/windows/mozapps/extensions/extensions.css +++ b/toolkit/themes/windows/mozapps/extensions/extensions.css @@ -1119,16 +1119,20 @@ menulist { /* Fixes some styling inconsi /*** buttons ***/ .addon-control[disabled="true"] { display: none; } +.addon-control.no-auto-hide { + display: block; +} + button.button-link { -moz-appearance: none; background: transparent; border: none; box-shadow: none; text-decoration: underline; color: #0066CC; cursor: pointer;