Merge autoland to central, a=merge

This commit is contained in:
Wes Kocher 2016-09-19 15:34:31 -07:00
Родитель 857d1ac980 5b7356ae02
Коммит 3034405e55
25 изменённых файлов: 593 добавлений и 68 удалений

Просмотреть файл

@ -296,7 +296,7 @@ let gDecoderDoctorHandler = {
let existing = formatsInPref.split(",").map(String.trim);
// Keep given formats that were not already recorded.
let newbies = formats.split(",").map(String.trim)
.filter(x => existing.includes(x));
.filter(x => !existing.includes(x));
// And rewrite pref with the added new formats (if any).
if (newbies.length) {
Services.prefs.setCharPref(formatsPref,

Просмотреть файл

@ -14,7 +14,12 @@
dlgbuttons="accept,cancel,help"
onbeforeaccept="return gConnectionsDialog.beforeAccept();"
onload="gConnectionsDialog.checkForSystemProxy();"
ondialoghelp="openPrefsHelp()">
ondialoghelp="openPrefsHelp()"
#ifdef XP_MACOSX
style="width: &window.macWidth2; !important;">
#else
style="width: &window.width2; !important;">
#endif
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>

Просмотреть файл

@ -10,7 +10,7 @@ browser.jar:
* content/browser/preferences/colors.xul
* content/browser/preferences/cookies.xul
content/browser/preferences/cookies.js
content/browser/preferences/connection.xul
* content/browser/preferences/connection.xul
content/browser/preferences/connection.js
content/browser/preferences/donottrack.xul
* content/browser/preferences/fonts.xul

Просмотреть файл

@ -4,6 +4,8 @@
<!ENTITY connectionsDialog.title "Connection Settings">
<!ENTITY window.width2 "49em">
<!ENTITY window.macWidth2 "44em">
<!ENTITY proxyTitle.label "Configure Proxies to Access the Internet">
<!ENTITY noProxyTypeRadio.label "No proxy">

Просмотреть файл

@ -24,6 +24,8 @@ this.SitePermissions = {
*
* To receive a more detailed, albeit less performant listing see
* SitePermissions.getPermissionDetailsByURI().
*
* install addon permission is excluded, check bug 1303108
*/
getAllByURI: function (aURI) {
let result = [];
@ -37,6 +39,10 @@ this.SitePermissions = {
// filter out unknown permissions
if (gPermissionObject[permission.type]) {
// XXX Bug 1303108 - Control Center should only show non-default permissions
if (permission.type == "install") {
continue;
}
result.push({
id: permission.type,
state: permission.capability,

Просмотреть файл

@ -45,6 +45,11 @@ add_task(function* testGetAllByURI() {
SitePermissions.remove(uri, "camera");
SitePermissions.remove(uri, "desktop-notification");
Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
// XXX Bug 1303108 - Control Center should only show non-default permissions
SitePermissions.set(uri, "addon", SitePermissions.BLOCK);
Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
SitePermissions.remove(uri, "addon");
});
add_task(function* testGetPermissionDetailsByURI() {

Просмотреть файл

@ -28,9 +28,11 @@ this.Preferences = {
["paneAdvanced", "generalTab"],
["paneAdvanced", "dataChoicesTab"],
["paneAdvanced", "networkTab"],
["paneAdvanced", "networkTab", connectionDialog],
["paneAdvanced", "updateTab"],
["paneAdvanced", "encryptionTab"],
["paneAdvanced", "encryptionTab", certManager],
["paneAdvanced", "encryptionTab", deviceManager],
];
for (let [primary, advanced, customFn] of panes) {
let configName = primary.replace(/^pane/, "prefs") + (advanced ? "-" + advanced : "");
@ -99,8 +101,20 @@ function* DNTDialog(aBrowser) {
});
}
function* connectionDialog(aBrowser) {
yield ContentTask.spawn(aBrowser, null, function* () {
content.document.getElementById("connectionSettings").click();
});
}
function* certManager(aBrowser) {
yield ContentTask.spawn(aBrowser, null, function* () {
content.document.getElementById("viewCertificatesButton").click();
});
}
function* deviceManager(aBrowser) {
yield ContentTask.spawn(aBrowser, null, function* () {
content.document.getElementById("viewSecurityDevicesButton").click();
});
}

Просмотреть файл

@ -221,8 +221,8 @@ fi
])
dnl Configure an Android SDK.
dnl Arg 1: target SDK version, like 22.
dnl Arg 2: build tools version, like 22.0.1.
dnl Arg 1: target SDK version, like 23.
dnl Arg 2: list of build-tools versions, like "23.0.3 23.0.1".
AC_DEFUN([MOZ_ANDROID_SDK],
[
@ -254,12 +254,20 @@ case "$target" in
fi
AC_MSG_RESULT([$android_sdk])
android_build_tools="$android_sdk_root"/build-tools/$2
AC_MSG_CHECKING([for Android build-tools version $2])
if test -d "$android_build_tools" -a -f "$android_build_tools/aapt"; then
AC_MSG_RESULT([$android_build_tools])
else
AC_MSG_ERROR([You must install the Android build-tools version $2. Try |mach bootstrap|. (Looked for $android_build_tools)])
AC_MSG_CHECKING([for Android build-tools])
android_build_tools_base="$android_sdk_root"/build-tools
android_build_tools_version=""
for version in $2; do
android_build_tools="$android_build_tools_base"/$version
if test -d "$android_build_tools" -a -f "$android_build_tools/aapt"; then
android_build_tools_version=$version
AC_MSG_RESULT([$android_build_tools])
break
fi
done
if test "$android_build_tools_version" == ""; then
version=$(echo $2 | cut -d" " -f1)
AC_MSG_ERROR([You must install the Android build-tools version $version. Try |mach bootstrap|. (Looked for "$android_build_tools_base"/$version)])
fi
MOZ_PATH_PROG(ZIPALIGN, zipalign, :, [$android_build_tools])
@ -309,7 +317,7 @@ case "$target" in
ANDROID_SDK="${android_sdk}"
ANDROID_SDK_ROOT="${android_sdk_root}"
ANDROID_TOOLS="${android_tools}"
ANDROID_BUILD_TOOLS_VERSION="$2"
ANDROID_BUILD_TOOLS_VERSION="$android_build_tools_version"
AC_DEFINE_UNQUOTED(ANDROID_TARGET_SDK,$ANDROID_TARGET_SDK)
AC_SUBST(ANDROID_TARGET_SDK)
AC_SUBST(ANDROID_SDK_ROOT)

Просмотреть файл

@ -305,8 +305,9 @@ ResponsiveUI.prototype = {
init: Task.async(function* () {
let ui = this;
// Watch for tab close so we can clean up RDM synchronously
// Watch for tab close and window close so we can clean up RDM synchronously
this.tab.addEventListener("TabClose", this);
this.browserWindow.addEventListener("unload", this);
// Swap page content from the current tab into a viewport within RDM
this.swap = swapToInnerBrowser({
@ -348,7 +349,8 @@ ResponsiveUI.prototype = {
// If our tab is about to be closed, there's not enough time to exit
// gracefully, but that shouldn't be a problem since the tab will go away.
// So, skip any yielding when we're about to close the tab.
let isTabClosing = options && options.reason == "TabClose";
let isWindowClosing = options && options.reason === "unload";
let isTabClosing = (options && options.reason === "TabClose") || isWindowClosing;
// Ensure init has finished before starting destroy
if (!isTabClosing) {
@ -356,6 +358,7 @@ ResponsiveUI.prototype = {
}
this.tab.removeEventListener("TabClose", this);
this.browserWindow.removeEventListener("unload", this);
this.toolWindow.removeEventListener("message", this);
if (!isTabClosing) {
@ -381,8 +384,10 @@ ResponsiveUI.prototype = {
}
this.client = this.emulationFront = null;
// Undo the swap and return the content back to a normal tab
swap.stop();
if (!isWindowClosing) {
// Undo the swap and return the content back to a normal tab
swap.stop();
}
this.destroyed = true;
@ -407,6 +412,7 @@ ResponsiveUI.prototype = {
case "message":
this.handleMessage(event);
break;
case "unload":
case "TabClose":
ResponsiveUIManager.closeIfNeeded(browserWindow, tab, {
reason: event.type,

Просмотреть файл

@ -8,6 +8,7 @@ support-files =
doc_page_state.html
geolocation.html
head.js
touch.html
!/devtools/client/commandline/test/helpers.js
!/devtools/client/framework/test/shared-head.js
!/devtools/client/framework/test/shared-redux-head.js
@ -36,3 +37,4 @@ support-files =
[browser_toolbox_swap_browsers.js]
[browser_touch_simulation.js]
[browser_viewport_basics.js]
[browser_window_close.js]

Просмотреть файл

@ -5,15 +5,171 @@
// Test global touch simulation button
const TEST_URL = "data:text/html;charset=utf-8,";
const TEST_URL = `${URL_ROOT}touch.html`;
const PREF_DOM_META_VIEWPORT_ENABLED = "dom.meta-viewport.enabled";
addRDMTask(TEST_URL, function* ({ ui }) {
let { store, document } = ui.toolWindow;
let touchButton = document.querySelector("#global-touch-simulation-button");
yield waitBootstrap(ui);
yield testWithNoTouch(ui);
yield enableTouchSimulation(ui);
yield testWithTouch(ui);
yield testWithMetaViewportEnabled(ui);
yield testWithMetaViewportDisabled(ui);
testTouchButton(ui);
});
// Wait until the viewport has been added
yield waitUntilState(store, state => state.viewports.length == 1);
yield waitForFrameLoad(ui, TEST_URL);
function* testWithNoTouch(ui) {
yield injectEventUtils(ui);
yield ContentTask.spawn(ui.getViewportBrowser(), {}, function* () {
let { EventUtils } = content;
let div = content.document.querySelector("div");
let x = 0, y = 0;
info("testWithNoTouch: Initial test parameter and mouse mouse outside div");
x = -1; y = -1;
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mousemove", isSynthesized: false }, content);
div.style.transform = "none";
div.style.backgroundColor = "";
info("testWithNoTouch: Move mouse into the div element");
yield EventUtils.synthesizeMouseAtCenter(div,
{ type: "mousemove", isSynthesized: false }, content);
is(div.style.backgroundColor, "red", "mouseenter or mouseover should work");
info("testWithNoTouch: Drag the div element");
yield EventUtils.synthesizeMouseAtCenter(div,
{ type: "mousedown", isSynthesized: false }, content);
x = 100; y = 100;
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mousemove", isSynthesized: false }, content);
is(div.style.transform, "none", "touchmove shouldn't work");
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mouseup", isSynthesized: false }, content);
info("testWithNoTouch: Move mouse out of the div element");
x = -1; y = -1;
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mousemove", isSynthesized: false }, content);
is(div.style.backgroundColor, "blue", "mouseout or mouseleave should work");
info("testWithNoTouch: Click the div element");
yield EventUtils.synthesizeClick(div);
is(div.dataset.isDelay, "false",
"300ms delay between touch events and mouse events should not work");
});
}
function* testWithTouch(ui) {
yield injectEventUtils(ui);
yield ContentTask.spawn(ui.getViewportBrowser(), {}, function* () {
let { EventUtils } = content;
let div = content.document.querySelector("div");
let x = 0, y = 0;
info("testWithTouch: Initial test parameter and mouse mouse outside div");
x = -1; y = -1;
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mousemove", isSynthesized: false }, content);
div.style.transform = "none";
div.style.backgroundColor = "";
info("testWithTouch: Move mouse into the div element");
yield EventUtils.synthesizeMouseAtCenter(div,
{ type: "mousemove", isSynthesized: false }, content);
isnot(div.style.backgroundColor, "red",
"mouseenter or mouseover should not work");
info("testWithTouch: Drag the div element");
yield EventUtils.synthesizeMouseAtCenter(div,
{ type: "mousedown", isSynthesized: false }, content);
x = 100; y = 100;
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mousemove", isSynthesized: false }, content);
isnot(div.style.transform, "none", "touchmove should work");
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mouseup", isSynthesized: false }, content);
info("testWithTouch: Move mouse out of the div element");
x = -1; y = -1;
yield EventUtils.synthesizeMouse(div, x, y,
{ type: "mousemove", isSynthesized: false }, content);
isnot(div.style.backgroundColor, "blue",
"mouseout or mouseleave should not work");
});
}
function* testWithMetaViewportEnabled(ui) {
yield SpecialPowers.pushPrefEnv({set: [[PREF_DOM_META_VIEWPORT_ENABLED, true]]});
yield injectEventUtils(ui);
yield ContentTask.spawn(ui.getViewportBrowser(), {}, function* () {
let { synthesizeClick } = content.EventUtils;
let meta = content.document.querySelector("meta[name=viewport]");
let div = content.document.querySelector("div");
div.dataset.isDelay = "false";
info("testWithMetaViewportEnabled: " +
"click the div element with <meta name='viewport'>");
meta.content = "";
yield synthesizeClick(div);
is(div.dataset.isDelay, "true",
"300ms delay between touch events and mouse events should work");
info("testWithMetaViewportEnabled: " +
"click the div element with " +
"<meta name='viewport' content='user-scalable=no'>");
meta.content = "user-scalable=no";
yield synthesizeClick(div);
is(div.dataset.isDelay, "false",
"300ms delay between touch events and mouse events should not work");
info("testWithMetaViewportEnabled: " +
"click the div element with " +
"<meta name='viewport' content='minimum-scale=maximum-scale'>");
meta.content = "minimum-scale=maximum-scale";
yield synthesizeClick(div);
is(div.dataset.isDelay, "false",
"300ms delay between touch events and mouse events should not work");
info("testWithMetaViewportEnabled: " +
"click the div element with " +
"<meta name='viewport' content='width=device-width'>");
meta.content = "width=device-width";
yield synthesizeClick(div);
is(div.dataset.isDelay, "false",
"300ms delay between touch events and mouse events should not work");
});
}
function* testWithMetaViewportDisabled(ui) {
yield SpecialPowers.pushPrefEnv({set: [[PREF_DOM_META_VIEWPORT_ENABLED, false]]});
yield injectEventUtils(ui);
yield ContentTask.spawn(ui.getViewportBrowser(), {}, function* () {
let { synthesizeClick } = content.EventUtils;
let meta = content.document.querySelector("meta[name=viewport]");
let div = content.document.querySelector("div");
div.dataset.isDelay = "false";
info("testWithMetaViewportDisabled: click the div with <meta name='viewport'>");
meta.content = "";
yield synthesizeClick(div);
is(div.dataset.isDelay, "true",
"300ms delay between touch events and mouse events should work");
});
}
function testTouchButton(ui) {
let { document } = ui.toolWindow;
let touchButton = document.querySelector("#global-touch-simulation-button");
ok(!touchButton.classList.contains("active"),
"Touch simulation is not active by default.");
@ -22,4 +178,63 @@ addRDMTask(TEST_URL, function* ({ ui }) {
ok(touchButton.classList.contains("active"),
"Touch simulation is started on click.");
});
touchButton.click();
ok(!touchButton.classList.contains("active"),
"Touch simulation is stopped on click.");
}
function* waitBootstrap(ui) {
let { store } = ui.toolWindow;
yield waitUntilState(store, state => state.viewports.length == 1);
yield waitForFrameLoad(ui, TEST_URL);
}
function* injectEventUtils(ui) {
yield ContentTask.spawn(ui.getViewportBrowser(), {}, function* () {
if ("EventUtils" in content) {
return;
}
let EventUtils = content.EventUtils = {};
EventUtils.window = {};
EventUtils.parent = EventUtils.window;
/* eslint-disable camelcase */
EventUtils._EU_Ci = Components.interfaces;
EventUtils._EU_Cc = Components.classes;
/* eslint-enable camelcase */
// EventUtils' `sendChar` function relies on the navigator to synthetize events.
EventUtils.navigator = content.navigator;
EventUtils.KeyboardEvent = content.KeyboardEvent;
EventUtils.synthesizeClick = element => new Promise(resolve => {
element.addEventListener("click", function onClick() {
element.removeEventListener("click", onClick);
resolve();
});
EventUtils.synthesizeMouseAtCenter(element,
{ type: "mousedown", isSynthesized: false }, content);
EventUtils.synthesizeMouseAtCenter(element,
{ type: "mouseup", isSynthesized: false }, content);
});
Services.scriptloader.loadSubScript(
"chrome://mochikit/content/tests/SimpleTest/EventUtils.js", EventUtils);
});
}
const enableTouchSimulation = ui => new Promise(
Task.async(function* (resolve) {
let browser = ui.getViewportBrowser();
browser.addEventListener("mozbrowserloadend", function onLoad() {
browser.removeEventListener("mozbrowserloadend", onLoad);
resolve();
});
yield ui.updateTouchSimulation(true);
}));

Просмотреть файл

@ -0,0 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(function* () {
let newWindowPromise = BrowserTestUtils.waitForNewWindow();
window.open("data:text/html;charset=utf-8,", "_blank");
let newWindow = yield newWindowPromise;
newWindow.focus();
yield once(newWindow.gBrowser, "load", true);
let tab = newWindow.gBrowser.selectedTab;
yield openRDM(tab);
// Close the window on a tab with an active responsive design UI and
// wait for the UI to gracefully shutdown. This has leaked the window
// in the past.
ok(ResponsiveUIManager.isActiveForTab(tab),
"ResponsiveUI should be active for tab when the window is closed");
let offPromise = once(ResponsiveUIManager, "off");
yield BrowserTestUtils.closeWindow(newWindow);
yield offPromise;
});

Просмотреть файл

@ -0,0 +1,86 @@
<!DOCTYPE html>
<meta charset="utf-8" />
<meta name="viewport" />
<title>test</title>
<style>
div {
border :1px solid red;
width: 100px; height: 100px;
}
</style>
<div data-is-delay="false"></div>
<script type="text/javascript;version=1.8">
"use strict";
let div = document.querySelector("div");
let initX, initY;
let previousEvent = "", touchendTime = 0;
let updatePreviousEvent = function (e) {
previousEvent = e.type;
};
div.style.transform = "none";
div.style.backgroundColor = "";
div.addEventListener("touchstart", function (evt) {
let touch = evt.changedTouches[0];
initX = touch.pageX;
initY = touch.pageY;
updatePreviousEvent(evt);
}, true);
div.addEventListener("touchmove", function (evt) {
let touch = evt.changedTouches[0];
let deltaX = touch.pageX - initX;
let deltaY = touch.pageY - initY;
div.style.transform = "translate(" + deltaX + "px, " + deltaY + "px)";
updatePreviousEvent(evt);
}, true);
div.addEventListener("touchend", function (evt) {
if (!evt.touches.length) {
div.style.transform = "none";
}
touchendTime = performance.now();
updatePreviousEvent(evt);
}, true);
div.addEventListener("mouseenter", function (evt) {
div.style.backgroundColor = "red";
updatePreviousEvent(evt);
}, true);
div.addEventListener("mouseover", function(evt) {
div.style.backgroundColor = "red";
updatePreviousEvent(evt);
}, true);
div.addEventListener("mouseout", function (evt) {
div.style.backgroundColor = "blue";
updatePreviousEvent(evt);
}, true);
div.addEventListener("mouseleave", function (evt) {
div.style.backgroundColor = "blue";
updatePreviousEvent(evt);
}, true);
div.addEventListener("mousedown", function (evt) {
if (previousEvent === "touchend" && touchendTime !== 0) {
let now = performance.now();
div.dataset.isDelay = ((now - touchendTime) >= 300);
} else {
div.dataset.isDelay = false;
}
updatePreviousEvent(evt);
}, true);
div.addEventListener("mousemove", updatePreviousEvent, true);
div.addEventListener("mouseup", updatePreviousEvent, true);
div.addEventListener("click", updatePreviousEvent, true);
</script>

Просмотреть файл

@ -9,6 +9,19 @@
#define SkTypes_DEFINED
// IWYU pragma: begin_exports
// In at least two known scenarios when using GCC with libc++:
// * GCC 4.8 targeting ARMv7 with NEON
// * GCC 4.9 targeting ARMv8 64 bit
// we need to typedef float float32_t (or include <arm_neon.h> which does that)
// before #including <memory>. This makes no sense. I'm not very interested in
// understanding why... these are old, bizarre platform configuration that we
// should just let die.
#if defined(MOZ_B2G) && defined(__GNUC__) && __GNUC__ == 4
typedef float float32_t;
#include <memory>
#endif
#include "SkPreConfig.h"
#include "SkUserConfig.h"
#include "SkPostConfig.h"

Просмотреть файл

@ -2492,7 +2492,7 @@ dnl ========================================================
if test -z "$gonkdir" ; then
case "$MOZ_BUILD_APP" in
mobile/android)
MOZ_ANDROID_SDK(23, 23.0.3)
MOZ_ANDROID_SDK(23, 23.0.3 23.0.1)
;;
esac
fi

Просмотреть файл

@ -3,10 +3,10 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY devmgr.title "Device Manager">
<!-- LOCALIZATION NOTE (devmgr.style): This is CSS style for Device Manager
<!-- LOCALIZATION NOTE (devmgr.style2): This is CSS style for Device Manager
window size. Don't translate "width" nor "height". Adjust the numbers
to make window contents fit. -->
<!ENTITY devmgr.style "width: 52em; height: 32em;">
<!ENTITY devmgr.style2 "width: 67em; height: 32em;">
<!ENTITY devmgr.devlist.label "Security Modules and Devices">
<!ENTITY devmgr.details.title "Details">

Просмотреть файл

@ -14,9 +14,9 @@
<dialog id="devicemanager"
windowtype="mozilla:devicemanager"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&devmgr.title;"
style="&devmgr.style;"
style="&devmgr.style2;"
persist="screenX screenY width height"
onload="LoadModules();"
onunload="DeregisterSmartCardObservers();"
@ -31,8 +31,8 @@
<grid flex="1" style="margin:5px">
<columns>
<column flex="1"/>
<column flex="3"/>
<column flex="1"/>
<column flex="3"/>
<column/>
</columns>
<rows>
@ -41,7 +41,7 @@
<tree id="device_tree" seltype="single"
onselect="enableButtons();" hidecolumnpicker="true"
flex="1" style="min-width: 15em">
<treecols>
<treecols>
<treecol id="deviceCol" flex="1" primary="true" label="&devmgr.devlist.label;"/>
</treecols>
<treechildren id="device_list"/>
@ -50,35 +50,35 @@
<vbox> <!-- Device status -->
<tree id="info_tree" seltype="single" hidecolumnpicker="true"
flex="1" style="min-width: 10em">
<treecols>
<treecol id="title1Col" flex="5" primary="true" label="&devmgr.details.title;"/>
<treecol id="title2Col" flex="7" label="&devmgr.details.title2;"/>
<treecols>
<treecol id="title1Col" flex="5" primary="true" label="&devmgr.details.title;"/>
<treecol id="title2Col" flex="7" label="&devmgr.details.title2;"/>
</treecols>
<treechildren id="info_list"/>
</tree>
</vbox> <!-- / Device status -->
<vbox> <!-- Buttons for manipulating devices -->
<button id="login_button"
<button id="login_button"
label="&devmgr.button.login.label;"
accesskey="&devmgr.button.login.accesskey;"
oncommand="doLogin();" disabled="true"/>
<button id="logout_button"
oncommand="doLogin();" disabled="true"/>
<button id="logout_button"
label="&devmgr.button.logout.label;"
accesskey="&devmgr.button.logout.accesskey;"
oncommand="doLogout();" disabled="true"/>
<button id="change_pw_button"
oncommand="doLogout();" disabled="true"/>
<button id="change_pw_button"
label="&devmgr.button.changepw.label;"
accesskey="&devmgr.button.changepw.accesskey;"
oncommand="changePassword();" disabled="true"/>
<button id="load_button"
oncommand="changePassword();" disabled="true"/>
<button id="load_button"
label="&devmgr.button.load.label;"
accesskey="&devmgr.button.load.accesskey;"
oncommand="doLoad();"/>
<button id="unload_button"
oncommand="doLoad();"/>
<button id="unload_button"
label="&devmgr.button.unload.label;"
accesskey="&devmgr.button.unload.accesskey;"
oncommand="doUnload();" disabled="true"/>
<button id="fipsbutton"
oncommand="doUnload();" disabled="true"/>
<button id="fipsbutton"
label=""
accesskey="&devmgr.button.fips.accesskey;"
oncommand="toggleFIPS();"/>

Просмотреть файл

@ -15,11 +15,15 @@ interface nsILoginManagerPrompter : nsISupports {
* Initialize the prompter. Must be called before using other interfaces.
*
* @param aWindow
* The in which the user is doing some login-related action that's
* The window in which the user is doing some login-related action that's
* resulting in a need to prompt them for something. The prompt
* will be associated with this window (or, if a notification bar
* is being used, topmost opener in some cases).
*
* aWindow can be null if there is no associated window, e.g. in a JSM
* or Sandbox. In this case there will be no checkbox to save the login
* since the window is needed to know if this is a private context.
*
* If this window is a content window, the corresponding window and browser
* elements will be calculated. If this window is a chrome window, the
* corresponding browser element needs to be set using setBrowser.

Просмотреть файл

@ -269,6 +269,7 @@ LoginManagerPrompter.prototype = {
// will indeed pass down a window to us, and for those who don't,
// we can just assume that we don't want to save the entered login
// information.
this.log("We have no chromeWindow so assume we're in a private context");
return true;
},
@ -692,8 +693,12 @@ LoginManagerPrompter.prototype = {
/* ---------- nsILoginManagerPrompter prompts ---------- */
init : function (aWindow, aFactory) {
if (aWindow instanceof Ci.nsIDOMChromeWindow) {
init : function (aWindow = null, aFactory = null) {
if (!aWindow) {
// There may be no applicable window e.g. in a Sandbox or JSM.
this._chromeWindow = null;
this._browser = null;
} else if (aWindow instanceof Ci.nsIDOMChromeWindow) {
this._chromeWindow = aWindow;
// needs to be set explicitly using setBrowser
this._browser = null;

Просмотреть файл

@ -49,6 +49,8 @@ skip-if = toolkit == 'android' # autocomplete
skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_prompt_http.html]
skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_prompt_noWindow.html]
skip-if = e10s || toolkit == 'android' # Tests desktop prompts. e10s: bug 1217876
[test_prompt_promptAuth.html]
skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts
[test_prompt_promptAuth_proxy.html]

Просмотреть файл

@ -0,0 +1,81 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test HTTP auth prompts by loading authenticate.sjs with no window</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="pwmgr_common.js"></script>
<script type="text/javascript" src="prompt_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
// Force parent to not look for tab-modal prompts, as they're not used for auth prompts.
isTabModal = false;
let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js"));
runInParent(() => {
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login.init("http://mochi.test:8888", null, "mochitest",
"mochiuser1", "mochipass1", "", "");
Services.logins.addLogin(login);
});
add_task(function* test_sandbox_xhr() {
let state = {
msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest”",
title : "Authentication Required",
textValue : "mochiuser1",
passValue : "mochipass1",
iconClass : "authentication-icon question-icon",
titleHidden : true,
textHidden : false,
passHidden : false,
checkHidden : true,
checkMsg : "",
checked : false,
focused : "textField",
defButton : "button0",
};
let action = {
buttonClick : "ok",
};
let promptDone = handlePrompt(state, action);
let url = new URL("authenticate.sjs?user=mochiuser1&pass=mochipass1", window.location.href);
let sandboxConstructor = SpecialPowers.Cu.Sandbox;
let sandbox = new sandboxConstructor(this, {wantXrays: true});
function sandboxedRequest(url) {
let req = SpecialPowers.Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(SpecialPowers.Ci.nsIXMLHttpRequest);
req.open("GET", url, true);
req.send(null);
}
let loginModifiedPromise = promiseStorageChanged(["modifyLogin"]);
sandbox.sandboxedRequest = sandboxedRequest(url);
info("send the XHR request in the sandbox");
SpecialPowers.Cu.evalInSandbox("sandboxedRequest;", sandbox);
yield promptDone;
info("prompt shown, waiting for metadata updates");
// Ensure the timeLastUsed and timesUsed metadata are updated.
yield loginModifiedPromise;
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -152,6 +152,7 @@
// remote browser element.
if (!gBrowser.hasAttribute("remote"))
yield testFindAgainNotFound();
yield testToggleEntireWord();
}
function* testFindbarSelection() {
@ -235,9 +236,9 @@
function promiseFindResult() {
return new Promise(resolve => {
let listener = {
onFindResult: function() {
onFindResult: function(result) {
gFindBar.browser.finder.removeResultListener(listener);
resolve();
resolve(result);
}
};
gFindBar.browser.finder.addResultListener(listener);
@ -650,6 +651,24 @@
yield promise;
ok(gFindBar.hidden, "Successful Find Again leaves the find bar closed.");
}
function* testToggleEntireWord() {
yield openFindbar();
let promise = promiseFindResult();
yield enterStringIntoFindField("Tex", false);
let result = yield promise;
is(result.result, Ci.nsITypeAheadFind.FIND_FOUND, "Text should be found");
yield new Promise(resolve => setTimeout(resolve, ITERATOR_TIMEOUT));
promise = promiseFindResult();
let check = gFindBar.getElement("find-entire-word");
check.click();
result = yield promise;
is(result.result, Ci.nsITypeAheadFind.FIND_NOTFOUND, "Text should NOT be found");
check.click();
gFindBar.close(true);
}
]]></script>
<commandset>

Просмотреть файл

@ -199,7 +199,7 @@
label="&entireWord.label;"
accesskey="&entireWord.accesskey;"
tooltiptext="&entireWord.tooltiptext;"
oncommand="_setEntireWord(this.checked);"
oncommand="toggleEntireWord(this.checked);"
type="checkbox"
xbl:inherits="accesskey=entirewordaccesskey"/>
<xul:label anonid="match-case-status" class="findbar-find-fast"/>
@ -343,9 +343,7 @@
break;
case "findbar.entireword":
this._self._entireWord = prefsvc.getBoolPref(aPrefName);
this._self._updateEntireWord();
// Update the matches count.
this._updateMatchesCount(this.nsITypeAheadFind.FIND_FOUND);
this._self.toggleEntireWord(this._self._entireWord, true);
break;
case "findbar.highlightAll":
this._self.toggleHighlight(prefsvc.getBoolPref(aPrefName), true);
@ -638,7 +636,7 @@
<!--
- Updates the entire-word mode of the findbar and its UI.
-->
<method name="_updateEntireWord">
<method name="_setEntireWord">
<body><![CDATA[
let entireWord = this._entireWord;
let checkbox = this.getElement("find-entire-word");
@ -662,17 +660,18 @@
- @param aEntireWord (boolean)
- Whether or not entire-word mode should be turned on.
-->
<method name="_setEntireWord">
<method name="toggleEntireWord">
<parameter name="aEntireWord"/>
<parameter name="aFromPrefObserver"/>
<body><![CDATA[
let prefsvc =
Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
if (!aFromPrefObserver) {
// Just set the pref; our observer will change the find bar behavior.
this._prefsvc.setBoolPref("findbar.entireword", aEntireWord);
return;
}
// Just set the pref; our observer will change the find bar behavior.
prefsvc.setBoolPref("findbar.entireword", aEntireWord);
this._maybeHighlightAll();
this._findFailedString = null;
this._find();
]]></body>
</method>
@ -971,7 +970,7 @@
this.getElement("find-previous").hidden = showMinimalUI;
foundMatches.hidden = showMinimalUI || !foundMatches.value;
this._updateCaseSensitivity();
this._updateEntireWord();
this._setEntireWord();
this._setHighlightAll();
if (showMinimalUI)
@ -1019,7 +1018,7 @@
this._enableFindButtons(val);
this._updateCaseSensitivity(val);
this._updateEntireWord();
this._setEntireWord();
this.browser.finder.fastFind(val, this._findMode == this.FIND_LINKS,
this._findMode != this.FIND_NORMAL);

Просмотреть файл

@ -406,8 +406,7 @@ FinderHighlighter.prototype = {
return;
}
// Place the match placeholder on top of the current found range.
if (data.result == Ci.nsITypeAheadFind.FIND_NOTFOUND || !foundRange) {
if (data.result == Ci.nsITypeAheadFind.FIND_NOTFOUND || !data.searchString || !foundRange) {
this.hide();
return;
}
@ -446,7 +445,7 @@ FinderHighlighter.prototype = {
dict.animation.onfinish = () => dict.animation = null;
}
if (this._highlightAll && data.searchString)
if (this._highlightAll)
this.highlight(true, data.searchString, data.linksOnly);
},

Просмотреть файл

@ -390,3 +390,32 @@ add_task(function* testHideOnLocationChange() {
yield BrowserTestUtils.removeTab(tab);
});
add_task(function* testHideOnClear() {
let url = kFixtureBaseURL + "file_FinderSample.html";
yield BrowserTestUtils.withNewTab(url, function* (browser) {
let findbar = gBrowser.getFindBar();
yield promiseOpenFindbar(findbar);
let word = "Roland";
let expectedResult = {
rectCount: 1,
insertCalls: [2, 4],
removeCalls: [1, 2]
};
let promise = promiseTestHighlighterOutput(browser, word, expectedResult);
yield promiseEnterStringIntoFindField(findbar, word);
yield promise;
yield new Promise(resolve => setTimeout(resolve, kIteratorTimeout));
promise = promiseTestHighlighterOutput(browser, "", {
rectCount: 0,
insertCalls: [0, 0],
removeCalls: [1, 2]
});
findbar.clear();
yield promise;
findbar.close(true);
});
});