diff --git a/b2g/components/test/mochitest/SandboxPromptTest.html b/b2g/components/test/mochitest/SandboxPromptTest.html
new file mode 100644
index 00000000000..1fcaf09d822
--- /dev/null
+++ b/b2g/components/test/mochitest/SandboxPromptTest.html
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/b2g/components/test/mochitest/mochitest.ini b/b2g/components/test/mochitest/mochitest.ini
new file mode 100644
index 00000000000..9470fd792fa
--- /dev/null
+++ b/b2g/components/test/mochitest/mochitest.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+run-if = toolkit == "gonk"
+support-files =
+ permission_handler_chrome.js
+ SandboxPromptTest.html
+
+[test_sandbox_permission.html]
diff --git a/b2g/components/test/mochitest/permission_handler_chrome.js b/b2g/components/test/mochitest/permission_handler_chrome.js
new file mode 100644
index 00000000000..1c8f4888fd3
--- /dev/null
+++ b/b2g/components/test/mochitest/permission_handler_chrome.js
@@ -0,0 +1,76 @@
+/* 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";
+
+function debug(str) {
+ dump("CHROME PERMISSON HANDLER -- " + str + "\n");
+}
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+const { Services } = Cu.import("resource://gre/modules/Services.jsm");
+
+let browser = Services.wm.getMostRecentWindow("navigator:browser");
+let shell;
+let test_counts = 0;
+
+function loadShell() {
+ if (!browser) {
+ debug("no browser");
+ return false;
+ }
+ shell = browser.shell;
+ return true;
+}
+
+function getContentWindow() {
+ return shell.contentBrowser.contentWindow;
+}
+
+function addChromeEventListener(type, listener) {
+ let content = getContentWindow();
+ content.addEventListener("mozChromeEvent", function chromeListener(evt) {
+ if (!evt.detail || evt.detail.type !== type) {
+ return;
+ }
+
+ let remove = listener(evt);
+ if (remove) {
+ content.removeEventListener("mozChromeEvent", chromeListener);
+ }
+ });
+}
+
+function checkPromptEvent(prompt_evt) {
+ let detail = prompt_evt.detail;
+
+ if (detail.permission == "audio-capture") {
+ sendAsyncMessage("permission.granted", "audio-capture");
+ test_counts--;
+ } else if (detail.permission == "desktop-notification") {
+ sendAsyncMessage("permission.granted", "desktop-notification");
+ test_counts--;
+ } else if (detail.permission == "geolocation") {
+ sendAsyncMessage("permission.granted", "geolocation");
+ test_counts--;
+ }
+
+ if (!test_counts) {
+ debug("remove prompt event listener.");
+ return true;
+ }
+
+ return false;
+}
+
+if (loadShell()) {
+ addMessageListener("test.counts", function (counts) {
+ test_counts = counts;
+ });
+
+ addChromeEventListener("permission-prompt", checkPromptEvent);
+}
diff --git a/b2g/components/test/mochitest/test_sandbox_permission.html b/b2g/components/test/mochitest/test_sandbox_permission.html
new file mode 100644
index 00000000000..360489e5ce9
--- /dev/null
+++ b/b2g/components/test/mochitest/test_sandbox_permission.html
@@ -0,0 +1,78 @@
+
+
+
+
+
+ Permission Prompt Test
+
+
+
+
+Permission prompt web content test
+
+
+
+
diff --git a/b2g/components/test/moz.build b/b2g/components/test/moz.build
index 191c90f0b92..b985130de0c 100644
--- a/b2g/components/test/moz.build
+++ b/b2g/components/test/moz.build
@@ -5,3 +5,4 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
+MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini']
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index ee622ab69dc..bbd8398d4af 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 27bee0949ff..34a8fa84ca4 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 00000000000..c88f049af3c
--- /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 00000000000..4a80864ddc2
--- /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 6e0cb152e7e..8c6f26b0c11 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 9cb9da6e95b..f78e8aa3d76 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 e80ed076dbc..3278e5b7937 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 00000000000..e91f6198942
--- /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 00000000000..f8c62ca642a
--- /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 1ef15d18adf..bba612ba3cd 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 c845e65967b..dc285b20135 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 086baf4fad6..b9ccad1557a 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/dom/fmradio/FMRadio.cpp b/dom/fmradio/FMRadio.cpp
index b325ce1c8a3..b625290e589 100644
--- a/dom/fmradio/FMRadio.cpp
+++ b/dom/fmradio/FMRadio.cpp
@@ -234,7 +234,8 @@ FMRadio::Enabled()
bool
FMRadio::AntennaAvailable() const
{
- return mHasInternalAntenna ? true : mHeadphoneState != SWITCH_STATE_OFF;
+ return mHasInternalAntenna ? true : (mHeadphoneState != SWITCH_STATE_OFF) &&
+ (mHeadphoneState != SWITCH_STATE_UNKNOWN);
}
Nullable
diff --git a/testing/mochitest/b2g-debug.json b/testing/mochitest/b2g-debug.json
index 3c9d71d5c41..653d34b2db5 100644
--- a/testing/mochitest/b2g-debug.json
+++ b/testing/mochitest/b2g-debug.json
@@ -1,5 +1,6 @@
{
"runtests": {
+ "b2g": "",
"caps": "",
"content": "",
"docshell": "",
diff --git a/testing/mochitest/b2g-desktop.json b/testing/mochitest/b2g-desktop.json
index f611c621657..f3c9ca7111a 100644
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -1,5 +1,6 @@
{
"runtests": {
+ "b2g": "",
"caps": "",
"content": "",
"docshell": "",
diff --git a/testing/mochitest/b2g.json b/testing/mochitest/b2g.json
index 788ddc94c77..3ebd6a20bd4 100644
--- a/testing/mochitest/b2g.json
+++ b/testing/mochitest/b2g.json
@@ -1,5 +1,6 @@
{
"runtests": {
+ "b2g": "",
"caps": "",
"content": "",
"docshell": "",
diff --git a/toolkit/content/widgets/popup.xml b/toolkit/content/widgets/popup.xml
index 7671ef2cfbd..da106803027 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');