diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index ee622ab69dc4..bbd8398d4af5 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1056,6 +1056,7 @@ var gBrowserInit = { gPrefService.addObserver(gHomeButton.prefDomain, gHomeButton, false); var homeButton = document.getElementById("home-button"); + gHomeButton.init(); gHomeButton.updateTooltip(homeButton); gHomeButton.updatePersonalToolbarStyle(homeButton); @@ -1247,6 +1248,7 @@ var gBrowserInit = { } BookmarkingUI.uninit(); + gHomeButton.uninit(); TabsInTitlebar.uninit(); @@ -4756,6 +4758,16 @@ function fireSidebarFocusedEvent() { var gHomeButton = { + init: function() { + gNavToolbox.addEventListener("customizationchange", + this.onCustomizationChange); + }, + + uninit: function() { + gNavToolbox.removeEventListener("customizationchange", + this.onCustomizationChange); + }, + prefDomain: "browser.startup.homepage", observe: function (aSubject, aTopic, aPrefName) { @@ -4807,7 +4819,11 @@ var gHomeButton = { || homeButton.parentNode.parentNode.id == "PersonalToolbar" ? homeButton.className.replace("toolbarbutton-1", "bookmark-item") : homeButton.className.replace("bookmark-item", "toolbarbutton-1"); - } + }, + + onCustomizationChange: function(aEvent) { + gHomeButton.updatePersonalToolbarStyle(); + }, }; /** diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index 27bee0949ff7..34a8fa84ca4b 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -100,6 +100,7 @@ support-files = test_no_mcb_on_http_site_font.css test_no_mcb_on_http_site_font2.html test_no_mcb_on_http_site_font2.css + xul_tooltiptext.xhtml [browser_CTP_context_menu.js] skip-if = toolkit == "gtk2" || toolkit == "gtk3" # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342) @@ -129,6 +130,7 @@ skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (b [browser_bug321000.js] skip-if = true # browser_bug321000.js is disabled because newline handling is shaky (bug 592528) [browser_bug329212.js] +[browser_bug331772_xul_tooltiptext_in_html.js] [browser_bug356571.js] [browser_bug380960.js] [browser_bug386835.js] diff --git a/browser/base/content/test/general/browser_bug331772_xul_tooltiptext_in_html.js b/browser/base/content/test/general/browser_bug331772_xul_tooltiptext_in_html.js new file mode 100644 index 000000000000..c88f049af3c3 --- /dev/null +++ b/browser/base/content/test/general/browser_bug331772_xul_tooltiptext_in_html.js @@ -0,0 +1,23 @@ +/** + * Tests that the tooltiptext attribute is used for XUL elements in an HTML doc. + */ +function test () { + waitForExplicitFinish(); + gBrowser.selectedTab = gBrowser.addTab(); + gBrowser.selectedBrowser.addEventListener("load", function () { + gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); + + let doc = gBrowser.contentDocument; + let tooltip = document.getElementById("aHTMLTooltip"); + + ok(tooltip.fillInPageTooltip(doc.getElementById("xulToolbarButton")), "should get tooltiptext"); + is(tooltip.getAttribute("label"), "XUL tooltiptext"); + + gBrowser.removeCurrentTab(); + finish(); + }, true); + + content.location = + "http://mochi.test:8888/browser/browser/base/content/test/general/xul_tooltiptext.xhtml"; +} + diff --git a/browser/base/content/test/general/xul_tooltiptext.xhtml b/browser/base/content/test/general/xul_tooltiptext.xhtml new file mode 100644 index 000000000000..4a80864ddc24 --- /dev/null +++ b/browser/base/content/test/general/xul_tooltiptext.xhtml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/browser/components/customizableui/src/CustomizableUI.jsm b/browser/components/customizableui/src/CustomizableUI.jsm index 6e0cb152e7ec..8c6f26b0c11a 100644 --- a/browser/components/customizableui/src/CustomizableUI.jsm +++ b/browser/components/customizableui/src/CustomizableUI.jsm @@ -2889,7 +2889,8 @@ function WidgetGroupWrapper(aWidget) { }); this.__defineGetter__("areaType", function() { - return gAreas.get(aWidget.currentArea).get("type"); + let areaProps = gAreas.get(aWidget.currentArea); + return areaProps && areaProps.get("type"); }); Object.freeze(this); @@ -2990,7 +2991,8 @@ function XULWidgetGroupWrapper(aWidgetId) { return null; } - return gAreas.get(placement.area).get("type"); + let areaProps = gAreas.get(placement.area); + return areaProps && areaProps.get("type"); }); this.__defineGetter__("instances", function() { diff --git a/browser/components/customizableui/src/CustomizeMode.jsm b/browser/components/customizableui/src/CustomizeMode.jsm index 9cb9da6e95bc..f78e8aa3d767 100644 --- a/browser/components/customizableui/src/CustomizeMode.jsm +++ b/browser/components/customizableui/src/CustomizeMode.jsm @@ -396,6 +396,9 @@ CustomizeMode.prototype = { aNode = aNode.firstChild; } CustomizableUI.addWidgetToArea(aNode.id, CustomizableUI.AREA_NAVBAR); + if (!this._customizing) { + this.dispatchToolboxEvent("customizationchange"); + } }, addToPanel: function(aNode) { @@ -404,6 +407,9 @@ CustomizeMode.prototype = { aNode = aNode.firstChild; } CustomizableUI.addWidgetToArea(aNode.id, CustomizableUI.AREA_PANEL); + if (!this._customizing) { + this.dispatchToolboxEvent("customizationchange"); + } }, removeFromArea: function(aNode) { @@ -412,6 +418,9 @@ CustomizeMode.prototype = { aNode = aNode.firstChild; } CustomizableUI.removeWidgetFromArea(aNode.id); + if (!this._customizing) { + this.dispatchToolboxEvent("customizationchange"); + } }, populatePalette: function() { diff --git a/browser/components/customizableui/test/browser.ini b/browser/components/customizableui/test/browser.ini index e80ed076dbc1..3278e5b79371 100644 --- a/browser/components/customizableui/test/browser.ini +++ b/browser/components/customizableui/test/browser.ini @@ -41,6 +41,7 @@ skip-if = os == "mac" [browser_938980_navbar_collapsed.js] [browser_938995_indefaultstate_nonremovable.js] [browser_940013_registerToolbarNode_calls_registerArea.js] +[browser_940107_home_button_in_bookmarks_toolbar.js] [browser_940946_removable_from_navbar_customizemode.js] [browser_941083_invalidate_wrapper_cache_createWidget.js] [browser_942581_unregisterArea_keeps_placements.js] @@ -49,4 +50,5 @@ skip-if = os == "mac" [browser_945739_showInPrivateBrowsing_customize_mode.js] [browser_947987_removable_default.js] [browser_948985_non_removable_defaultArea.js] +[browser_952963_areaType_getter_no_area.js] [browser_panel_toggle.js] diff --git a/browser/components/customizableui/test/browser_940107_home_button_in_bookmarks_toolbar.js b/browser/components/customizableui/test/browser_940107_home_button_in_bookmarks_toolbar.js new file mode 100644 index 000000000000..e91f6198942a --- /dev/null +++ b/browser/components/customizableui/test/browser_940107_home_button_in_bookmarks_toolbar.js @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +// Bug 940107 - Home icon not displayed correctly when in bookmarks toolbar. +add_task(function() { + ok(CustomizableUI.inDefaultState, "Should be in default state when test starts."); + let bookmarksToolbar = document.getElementById(CustomizableUI.AREA_BOOKMARKS); + bookmarksToolbar.collapsed = false; + + let homeButton = document.getElementById("home-button"); + ok(homeButton.classList.contains("toolbarbutton-1"), "Home Button should have toolbarbutton-1 when in the nav-bar"); + ok(!homeButton.classList.contains("bookmark-item"), "Home Button should not be displayed as a bookmarks item"); + + yield startCustomizing(); + CustomizableUI.addWidgetToArea(homeButton.id, CustomizableUI.AREA_BOOKMARKS); + yield endCustomizing(); + ok(homeButton.classList.contains("bookmark-item"), "Home Button should be displayed as a bookmarks item"); + ok(!homeButton.classList.contains("toolbarbutton-1"), "Home Button should not be displayed as a nav-bar item"); + + gCustomizeMode.addToPanel(homeButton); + let panelShownPromise = promisePanelShown(window); + PanelUI.toggle(); + yield panelShownPromise; + + ok(homeButton.classList.contains("toolbarbutton-1"), "Home Button should have toolbarbutton-1 when in the panel"); + ok(!homeButton.classList.contains("bookmark-item"), "Home Button should not be displayed as a bookmarks item"); + + gCustomizeMode.addToToolbar(homeButton); + let panelHiddenPromise = promisePanelHidden(window); + PanelUI.toggle(); + yield panelHiddenPromise; + + ok(homeButton.classList.contains("toolbarbutton-1"), "Home Button should have toolbarbutton-1 when in the nav-bar"); + ok(!homeButton.classList.contains("bookmark-item"), "Home Button should not be displayed as a bookmarks item"); + + bookmarksToolbar.collapsed = true; + CustomizableUI.reset(); +}); diff --git a/browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js b/browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js new file mode 100644 index 000000000000..f8c62ca642a5 --- /dev/null +++ b/browser/components/customizableui/test/browser_952963_areaType_getter_no_area.js @@ -0,0 +1,52 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const kToolbarName = "test-unregisterArea-areaType"; +const kUnregisterAreaTestWidget = "test-widget-for-unregisterArea-areaType"; +const kTestWidget = "test-widget-no-area-areaType"; +registerCleanupFunction(removeCustomToolbars); + +function checkAreaType(widget) { + try { + is(widget.areaType, null, "areaType should be null"); + } catch (ex) { + info("Fetching areaType threw: " + ex); + ok(false, "areaType getter shouldn't throw."); + } +} + +// widget wrappers in unregisterArea'd areas and nowhere shouldn't throw when checking areaTypes. +add_task(function() { + // Using the ID before it's been created will imply a XUL wrapper; we'll test + // an API-based wrapper below + let toolbarNode = createToolbarWithPlacements(kToolbarName, [kUnregisterAreaTestWidget]); + CustomizableUI.unregisterArea(kToolbarName); + toolbarNode.remove(); + + let w = CustomizableUI.getWidget(kUnregisterAreaTestWidget); + checkAreaType(w); + + w = CustomizableUI.getWidget(kTestWidget); + checkAreaType(w); + + let spec = {id: kUnregisterAreaTestWidget, type: 'button', removable: true, + label: "areaType test", tooltiptext: "areaType test"}; + CustomizableUI.createWidget(spec); + let toolbarNode = createToolbarWithPlacements(kToolbarName, [kUnregisterAreaTestWidget]); + CustomizableUI.unregisterArea(kToolbarName); + toolbarNode.remove(); + w = CustomizableUI.getWidget(spec.id); + checkAreaType(w); + CustomizableUI.removeWidgetFromArea(kUnregisterAreaTestWidget); + checkAreaType(w); + //XXXgijs: ensure cleanup function doesn't barf: + gAddedToolbars.delete(kToolbarName); +}); + +add_task(function asyncCleanup() { + yield resetCustomization(); +}); + diff --git a/browser/metro/base/content/helperui/FindHelperUI.js b/browser/metro/base/content/helperui/FindHelperUI.js index 1ef15d18adf4..bba612ba3cd9 100644 --- a/browser/metro/base/content/helperui/FindHelperUI.js +++ b/browser/metro/base/content/helperui/FindHelperUI.js @@ -109,8 +109,16 @@ var FindHelperUI = { }, show: function findHelperShow() { - if (BrowserUI.isStartTabVisible || this._open) + if (BrowserUI.isStartTabVisible) { return; + } + if (this._open) { + setTimeout(() => { + this._textbox.select(); + this._textbox.focus(); + }, 0); + return; + } // Hide any menus ContextUI.dismiss(); diff --git a/browser/metro/base/tests/mochitest/browser_findbar.js b/browser/metro/base/tests/mochitest/browser_findbar.js index c845e65967bb..dc285b201350 100644 --- a/browser/metro/base/tests/mochitest/browser_findbar.js +++ b/browser/metro/base/tests/mochitest/browser_findbar.js @@ -26,6 +26,12 @@ gTests.push({ EventUtils.sendString("bar"); is(textbox.value, "bar", "Type 'bar' into find bar"); + EventUtils.synthesizeKey("f", { accelKey: true}); + yield waitForEvent(Elements.findbar, "transitionend"); + ok(document.commandDispatcher.focusedElement, textbox.inputField, "textbox field is focused with Ctrl-F"); + is(textbox.selectionStart, 0, "textbox field is selected with Ctrl-F."); + is(textbox.selectionEnd, textbox.value.length, "textbox field is selected with Ctrl-F."); + EventUtils.synthesizeKey("VK_ESCAPE", { accelKey: true }); yield waitForEvent(Elements.findbar, "transitionend"); is(Elements.findbar.isShowing, false, "Hide find bar with Esc"); diff --git a/browser/themes/linux/downloads/indicator.css b/browser/themes/linux/downloads/indicator.css index 086baf4fad6a..b9ccad1557a6 100644 --- a/browser/themes/linux/downloads/indicator.css +++ b/browser/themes/linux/downloads/indicator.css @@ -99,7 +99,7 @@ } #downloads-indicator-progress { - width: 16px; + width: 18px; height: 6px; min-width: 0; min-height: 0; diff --git a/toolkit/content/widgets/popup.xml b/toolkit/content/widgets/popup.xml index 7671ef2cfbd4..da106803027a 100644 --- a/toolkit/content/widgets/popup.xml +++ b/toolkit/content/widgets/popup.xml @@ -517,6 +517,7 @@ var titleText = null; var XLinkTitleText = null; var SVGTitleText = null; + var XULtooltiptextText = null; var lookingForSVGTitle = true; var direction = tipElement.ownerDocument.dir; @@ -575,11 +576,17 @@ } catch(e) {} } - while ((titleText == null) && (XLinkTitleText == null) && - (SVGTitleText == null) && tipElement) { - if (tipElement.nodeType == Node.ELEMENT_NODE && - tipElement.namespaceURI != XULNS) { - titleText = tipElement.getAttribute("title"); + // Check texts against null so that title="" can be used to undefine a + // title on a child element. + while (tipElement && + (titleText == null) && (XLinkTitleText == null) && + (SVGTitleText == null) && (XULtooltiptextText == null)) { + + if (tipElement.nodeType == Node.ELEMENT_NODE) { + if (tipElement.namespaceURI == XULNS) + XULtooltiptextText = tipElement.getAttribute("tooltiptext"); + else + titleText = tipElement.getAttribute("title"); if ((tipElement instanceof HTMLAnchorElement || tipElement instanceof HTMLAreaElement || @@ -610,7 +617,7 @@ this.style.direction = direction; - return [titleText, XLinkTitleText, SVGTitleText].some(function (t) { + return [titleText, XLinkTitleText, SVGTitleText, XULtooltiptextText].some(function (t) { if (t && /\S/.test(t)) { // Make CRLF and CR render one line break each. this.label = t.replace(/\r\n?/g, '\n');