Merge mozilla-central and fx-team

This commit is contained in:
Ed Morley 2013-08-15 13:37:24 +01:00
commit 4f122221a3
36 changed files with 288 additions and 148 deletions

View File

@ -2,74 +2,85 @@
* 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/. */
const TEST_URL = "data:text/html;charset=utf-8,<input%20id=txt>" +
"<input%20type=checkbox%20id=chk>";
/**
* This test ensures that closing a window is a reversible action. We will
* close the the window, restore it and check that all data has been restored.
* This includes window-specific data as well as form data for tabs.
*/
function test() {
waitForExplicitFinish();
let testURL = "about:config";
let uniqueKey = "bug 394759";
let uniqueValue = "unik" + Date.now();
let uniqueText = "pi != " + Math.random();
// Be consistent: let the page actually display, as we are "interacting" with it.
Services.prefs.setBoolPref("general.warnOnAboutConfig", false);
// make sure that the next closed window will increase getClosedWindowCount
let max_windows_undo = Services.prefs.getIntPref("browser.sessionstore.max_windows_undo");
Services.prefs.setIntPref("browser.sessionstore.max_windows_undo", max_windows_undo + 1);
let closedWindowCount = ss.getClosedWindowCount();
// Clear the list of closed windows.
while (SessionStore.getClosedWindowCount()) {
SessionStore.forgetClosedWindow(0);
}
provideWindow(function onTestURLLoaded(newWin) {
newWin.gBrowser.addTab().linkedBrowser.stop();
// mark the window with some unique data to be restored later on
ss.setWindowValue(newWin, uniqueKey, uniqueValue);
let textbox = newWin.content.document.getElementById("textbox");
textbox.value = uniqueText;
let [txt, chk] = newWin.content.document.querySelectorAll("#txt, #chk");
txt.value = uniqueText;
newWin.close();
// Toggle the checkbox to cause a SessionStore:input message to be sent.
EventUtils.sendMouseEvent({type: "click"}, chk);
is(ss.getClosedWindowCount(), closedWindowCount + 1,
"The closed window was added to Recently Closed Windows");
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.title == testURL && JSON.stringify(data).indexOf(uniqueText) > -1,
"The closed window data was stored correctly");
let browser = newWin.gBrowser.selectedBrowser;
waitForContentMessage(browser, "SessionStore:input", 1000, result => {
ok(result, "received message for input changes");
// reopen the closed window and ensure its integrity
let newWin2 = ss.undoCloseWindow(0);
newWin.close();
ok(newWin2 instanceof ChromeWindow,
"undoCloseWindow actually returned a window");
is(ss.getClosedWindowCount(), closedWindowCount,
"The reopened window was removed from Recently Closed Windows");
is(ss.getClosedWindowCount(), 1,
"The closed window was added to Recently Closed Windows");
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.title == TEST_URL && JSON.stringify(data).indexOf(uniqueText) > -1,
"The closed window data was stored correctly");
// SSTabRestored will fire more than once, so we need to make sure we count them
let restoredTabs = 0;
let expectedTabs = data.tabs.length;
newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
++restoredTabs;
info("Restored tab " + restoredTabs + "/" + expectedTabs);
if (restoredTabs < expectedTabs) {
return;
}
// reopen the closed window and ensure its integrity
let newWin2 = ss.undoCloseWindow(0);
newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
ok(newWin2 instanceof ChromeWindow,
"undoCloseWindow actually returned a window");
is(ss.getClosedWindowCount(), 0,
"The reopened window was removed from Recently Closed Windows");
is(newWin2.gBrowser.tabs.length, 2,
"The window correctly restored 2 tabs");
is(newWin2.gBrowser.currentURI.spec, testURL,
"The window correctly restored the URL");
// SSTabRestored will fire more than once, so we need to make sure we count them
let restoredTabs = 0;
let expectedTabs = data.tabs.length;
newWin2.addEventListener("SSTabRestored", function sstabrestoredListener(aEvent) {
++restoredTabs;
info("Restored tab " + restoredTabs + "/" + expectedTabs);
if (restoredTabs < expectedTabs) {
return;
}
let textbox = newWin2.content.document.getElementById("textbox");
is(textbox.value, uniqueText,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
"The window correctly restored the data associated with it");
is(restoredTabs, expectedTabs, "correct number of tabs restored");
newWin2.removeEventListener("SSTabRestored", sstabrestoredListener, true);
// clean up
newWin2.close();
Services.prefs.clearUserPref("browser.sessionstore.max_windows_undo");
Services.prefs.clearUserPref("general.warnOnAboutConfig");
finish();
}, true);
}, testURL);
is(newWin2.gBrowser.tabs.length, 2,
"The window correctly restored 2 tabs");
is(newWin2.gBrowser.currentURI.spec, TEST_URL,
"The window correctly restored the URL");
let [txt, chk] = newWin2.content.document.querySelectorAll("#txt, #chk");
ok(txt.value == uniqueText && chk.checked,
"The window correctly restored the form");
is(ss.getWindowValue(newWin2, uniqueKey), uniqueValue,
"The window correctly restored the data associated with it");
// clean up
newWin2.close();
finish();
}, true);
});
}, TEST_URL);
}

View File

@ -7,6 +7,57 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
const NET_STRINGS_URI = "chrome://browser/locale/devtools/netmonitor.properties";
const LISTENERS = [ "NetworkActivity" ];
const NET_PREFS = { "NetworkMonitor.saveRequestAndResponseBodies": true };
// The panel's window global is an EventEmitter firing the following events:
const EVENTS = {
// When the monitored target begins and finishes navigating.
TARGET_WILL_NAVIGATE: "NetMonitor:TargetWillNavigate",
TARGET_DID_NAVIGATE: "NetMonitor:TargetNavigate",
// When a network event is received.
// See https://developer.mozilla.org/docs/Tools/Web_Console/remoting for
// more information about what each packet is supposed to deliver.
NETWORK_EVENT: "NetMonitor:NetworkEvent",
// When request headers begin and finish receiving.
UPDATING_REQUEST_HEADERS: "NetMonitor:NetworkEventUpdating:RequestHeaders",
RECEIVED_REQUEST_HEADERS: "NetMonitor:NetworkEventUpdated:RequestHeaders",
// When request cookies begin and finish receiving.
UPDATING_REQUEST_COOKIES: "NetMonitor:NetworkEventUpdating:RequestCookies",
RECEIVED_REQUEST_COOKIES: "NetMonitor:NetworkEventUpdated:RequestCookies",
// When request post data begins and finishes receiving.
UPDATING_REQUEST_POST_DATA: "NetMonitor:NetworkEventUpdating:RequestPostData",
RECEIVED_REQUEST_POST_DATA: "NetMonitor:NetworkEventUpdated:RequestPostData",
// When response headers begin and finish receiving.
UPDATING_RESPONSE_HEADERS: "NetMonitor:NetworkEventUpdating:ResponseHeaders",
RECEIVED_RESPONSE_HEADERS: "NetMonitor:NetworkEventUpdated:ResponseHeaders",
// When response cookies begin and finish receiving.
UPDATING_RESPONSE_COOKIES: "NetMonitor:NetworkEventUpdating:ResponseCookies",
RECEIVED_RESPONSE_COOKIES: "NetMonitor:NetworkEventUpdated:ResponseCookies",
// When event timings begin and finish receiving.
UPDATING_EVENT_TIMINGS: "NetMonitor:NetworkEventUpdating:EventTimings",
RECEIVED_EVENT_TIMINGS: "NetMonitor:NetworkEventUpdated:EventTimings",
// When response content begins, updates and finishes receiving.
STARTED_RECEIVING_RESPONSE: "NetMonitor:NetworkEventUpdating:ResponseStart",
UPDATING_RESPONSE_CONTENT: "NetMonitor:NetworkEventUpdating:ResponseContent",
RECEIVED_RESPONSE_CONTENT: "NetMonitor:NetworkEventUpdated:ResponseContent",
// When the request post params are displayed in the UI.
REQUEST_POST_PARAMS_DISPLAYED: "NetMonitor:RequestPostParamsAvailable",
// When the response body is displayed in the UI.
RESPONSE_BODY_DISPLAYED: "NetMonitor:ResponseBodyAvailable"
}
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
let promise = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js").Promise;
@ -33,10 +84,6 @@ Object.defineProperty(this, "NetworkHelper", {
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
const NET_STRINGS_URI = "chrome://browser/locale/devtools/netmonitor.properties";
const LISTENERS = [ "NetworkActivity" ];
const NET_PREFS = { "NetworkMonitor.saveRequestAndResponseBodies": true };
/**
* Object defining the network monitor controller components.
*/
@ -255,11 +302,11 @@ TargetEventsHandler.prototype = {
nsIURL.store.clear();
drain.store.clear();
window.emit("NetMonitor:TargetWillNavigate");
window.emit(EVENTS.TARGET_WILL_NAVIGATE);
break;
}
case "navigate": {
window.emit("NetMonitor:TargetNavigate");
window.emit(EVENTS.TARGET_DID_NAVIGATE);
break;
}
}
@ -325,7 +372,7 @@ NetworkEventsHandler.prototype = {
let { actor, startedDateTime, method, url, isXHR } = aPacket.eventActor;
NetMonitorView.RequestsMenu.addRequest(actor, startedDateTime, method, url, isXHR);
window.emit("NetMonitor:NetworkEvent");
window.emit(EVENTS.NETWORK_EVENT);
},
/**
@ -342,23 +389,23 @@ NetworkEventsHandler.prototype = {
switch (aPacket.updateType) {
case "requestHeaders":
this.webConsoleClient.getRequestHeaders(actor, this._onRequestHeaders);
window.emit("NetMonitor:NetworkEventUpdating:RequestHeaders");
window.emit(EVENTS.UPDATING_REQUEST_HEADERS);
break;
case "requestCookies":
this.webConsoleClient.getRequestCookies(actor, this._onRequestCookies);
window.emit("NetMonitor:NetworkEventUpdating:RequestCookies");
window.emit(EVENTS.UPDATING_REQUEST_COOKIES);
break;
case "requestPostData":
this.webConsoleClient.getRequestPostData(actor, this._onRequestPostData);
window.emit("NetMonitor:NetworkEventUpdating:RequestPostData");
window.emit(EVENTS.UPDATING_REQUEST_POST_DATA);
break;
case "responseHeaders":
this.webConsoleClient.getResponseHeaders(actor, this._onResponseHeaders);
window.emit("NetMonitor:NetworkEventUpdating:ResponseHeaders");
window.emit(EVENTS.UPDATING_RESPONSE_HEADERS);
break;
case "responseCookies":
this.webConsoleClient.getResponseCookies(actor, this._onResponseCookies);
window.emit("NetMonitor:NetworkEventUpdating:ResponseCookies");
window.emit(EVENTS.UPDATING_RESPONSE_COOKIES);
break;
case "responseStart":
NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
@ -367,7 +414,7 @@ NetworkEventsHandler.prototype = {
statusText: aPacket.response.statusText,
headersSize: aPacket.response.headersSize
});
window.emit("NetMonitor:NetworkEventUpdating:ResponseStart");
window.emit(EVENTS.STARTED_RECEIVING_RESPONSE);
break;
case "responseContent":
NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
@ -375,14 +422,14 @@ NetworkEventsHandler.prototype = {
mimeType: aPacket.mimeType
});
this.webConsoleClient.getResponseContent(actor, this._onResponseContent);
window.emit("NetMonitor:NetworkEventUpdating:ResponseContent");
window.emit(EVENTS.UPDATING_RESPONSE_CONTENT);
break;
case "eventTimings":
NetMonitorView.RequestsMenu.updateRequest(aPacket.from, {
totalTime: aPacket.totalTime
});
this.webConsoleClient.getEventTimings(actor, this._onEventTimings);
window.emit("NetMonitor:NetworkEventUpdating:EventTimings");
window.emit(EVENTS.UPDATING_EVENT_TIMINGS);
break;
}
},
@ -397,7 +444,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
requestHeaders: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:RequestHeaders");
window.emit(EVENTS.RECEIVED_REQUEST_HEADERS);
},
/**
@ -410,7 +457,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
requestCookies: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:RequestCookies");
window.emit(EVENTS.RECEIVED_REQUEST_COOKIES);
},
/**
@ -423,7 +470,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
requestPostData: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:RequestPostData");
window.emit(EVENTS.RECEIVED_REQUEST_POST_DATA);
},
/**
@ -436,7 +483,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
responseHeaders: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:ResponseHeaders");
window.emit(EVENTS.RECEIVED_RESPONSE_HEADERS);
},
/**
@ -449,7 +496,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
responseCookies: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:ResponseCookies");
window.emit(EVENTS.RECEIVED_RESPONSE_COOKIES);
},
/**
@ -462,7 +509,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
responseContent: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:ResponseContent");
window.emit(EVENTS.RECEIVED_RESPONSE_CONTENT);
},
/**
@ -475,7 +522,7 @@ NetworkEventsHandler.prototype = {
NetMonitorView.RequestsMenu.updateRequest(aResponse.from, {
eventTimings: aResponse
});
window.emit("NetMonitor:NetworkEventUpdated:EventTimings");
window.emit(EVENTS.RECEIVED_EVENT_TIMINGS);
},
/**

View File

@ -1790,7 +1790,7 @@ NetworkDetailsView.prototype = {
aEditor.setText(aString);
});
}
window.emit("NetMonitor:ResponsePostParamsAvailable");
window.emit(EVENTS.REQUEST_POST_PARAMS_DISPLAYED);
});
},
@ -1913,7 +1913,7 @@ NetworkDetailsView.prototype = {
}
});
}
window.emit("NetMonitor:ResponseBodyAvailable");
window.emit(EVENTS.RESPONSE_BODY_DISPLAYED);
});
},

View File

@ -28,7 +28,7 @@ function test() {
document.querySelectorAll("#details-pane tab")[3]);
NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
is(aEditor.getText().indexOf("\u044F"), 189, // я
is(aEditor.getText().indexOf("\u044F"), 302, // я
"The text shown in the source editor is incorrect.");
is(aEditor.getMode(), SourceEditor.MODES.HTML,
"The mode active in the source editor is incorrect.");

View File

@ -29,7 +29,7 @@ function test() {
time: true
});
aMonitor.panelWin.once("NetMonitor:ResponseBodyAvailable", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED, () => {
testResponseTab();
teardown(aMonitor).then(finish);
});

View File

@ -25,7 +25,7 @@ function test() {
statusText: "OK"
});
aMonitor.panelWin.once("NetMonitor:ResponseBodyAvailable", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RESPONSE_BODY_DISPLAYED, () => {
NetMonitorView.editor("#response-content-textarea").then((aEditor) => {
ok(aEditor.getText().match(/^<p>/),
"The text shown in the source editor is incorrect.");

View File

@ -15,11 +15,11 @@ function test() {
function testNavigate(aCallback) {
info("Navigating forward...");
aMonitor.panelWin.once("NetMonitor:TargetWillNavigate", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.TARGET_WILL_NAVIGATE, () => {
is(aDebuggee.location, SIMPLE_URL,
"Target started navigating to the correct location.");
aMonitor.panelWin.once("NetMonitor:TargetNavigate", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.TARGET_DID_NAVIGATE, () => {
is(aDebuggee.location, NAVIGATE_URL,
"Target finished navigating to the correct location.");
@ -33,11 +33,11 @@ function test() {
function testNavigateBack(aCallback) {
info("Navigating backward...");
aMonitor.panelWin.once("NetMonitor:TargetWillNavigate", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.TARGET_WILL_NAVIGATE, () => {
is(aDebuggee.location, NAVIGATE_URL,
"Target started navigating back to the previous location.");
aMonitor.panelWin.once("NetMonitor:TargetNavigate", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.TARGET_DID_NAVIGATE, () => {
is(aDebuggee.location, SIMPLE_URL,
"Target finished navigating back to the previous location.");

View File

@ -26,7 +26,7 @@ function test() {
is(RequestsMenu.selectedItem, null,
"There should be no selected item in the requests menu.");
aMonitor.panelWin.once("NetMonitor:NetworkEvent", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.NETWORK_EVENT, () => {
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after the first request.");

View File

@ -18,7 +18,7 @@ function test() {
.then(() => teardown(aMonitor))
.then(finish);
aMonitor.panelWin.once("NetMonitor:NetworkEvent", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.NETWORK_EVENT, () => {
is(RequestsMenu.selectedItem, null,
"There shouldn't be any selected item in the requests menu.");
is(RequestsMenu.itemCount, 1,
@ -81,7 +81,7 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS);
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:RequestHeaders", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_REQUEST_HEADERS, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
ok(requestItem.attachment.requestHeaders,
@ -98,7 +98,7 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS);
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:RequestCookies", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_REQUEST_COOKIES, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
ok(requestItem.attachment.requestCookies,
@ -109,11 +109,11 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS);
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:RequestPostData", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_REQUEST_POST_DATA, () => {
ok(false, "Trap listener: this request doesn't have any post data.")
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:ResponseHeaders", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_RESPONSE_HEADERS, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
ok(requestItem.attachment.responseHeaders,
@ -126,7 +126,7 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS);
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:ResponseCookies", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_RESPONSE_COOKIES, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
ok(requestItem.attachment.responseCookies,
@ -137,7 +137,7 @@ function test() {
verifyRequestItemTarget(requestItem, "GET", SIMPLE_SJS);
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdating:ResponseStart", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.STARTED_RECEIVING_RESPONSE, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
is(requestItem.attachment.httpVersion, "HTTP/1.1",
@ -155,7 +155,7 @@ function test() {
});
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdating:ResponseContent", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_RESPONSE_CONTENT, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
is(requestItem.attachment.contentSize, "12",
@ -170,7 +170,7 @@ function test() {
});
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:ResponseContent", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_RESPONSE_CONTENT, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
ok(requestItem.attachment.responseContent,
@ -189,7 +189,7 @@ function test() {
});
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdating:EventTimings", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.UPDATING_EVENT_TIMINGS, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
is(typeof requestItem.attachment.totalTime, "number",
@ -207,7 +207,7 @@ function test() {
});
});
aMonitor.panelWin.once("NetMonitor:NetworkEventUpdated:EventTimings", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.RECEIVED_EVENT_TIMINGS, () => {
let requestItem = RequestsMenu.getItemAtIndex(0);
ok(requestItem.attachment.eventTimings,

View File

@ -25,7 +25,7 @@ function test() {
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should be hidden when the frontend is opened.");
aMonitor.panelWin.once("NetMonitor:NetworkEvent", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.NETWORK_EVENT, () => {
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), false,
"The pane toggle button should be enabled after the first request.");
@ -37,7 +37,7 @@ function test() {
is(NetMonitorView.detailsPaneHidden, true,
"The details pane should still be hidden after the first request.");
aMonitor.panelWin.once("NetMonitor:NetworkEvent", () => {
aMonitor.panelWin.once(aMonitor.panelWin.EVENTS.NETWORK_EVENT, () => {
is(document.querySelector("#details-pane-toggle")
.hasAttribute("disabled"), false,
"The pane toggle button should be still be enabled after a reload.");

View File

@ -148,41 +148,41 @@ function waitForNetworkEvents(aMonitor, aGetRequests, aPostRequests = 0) {
if (genericEvents == (aGetRequests + aPostRequests) * 13 &&
postEvents == aPostRequests * 2) {
panel.off("NetMonitor:NetworkEventUpdating:RequestHeaders", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdated:RequestHeaders", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:RequestCookies", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:RequestPostData", onPostEvent);
panel.off("NetMonitor:NetworkEventUpdated:RequestPostData", onPostEvent);
panel.off("NetMonitor:NetworkEventUpdated:RequestCookies", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:ResponseHeaders", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdated:ResponseHeaders", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:ResponseCookies", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdated:ResponseCookies", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:ResponseStart", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:ResponseContent", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdated:ResponseContent", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdating:EventTimings", onGenericEvent);
panel.off("NetMonitor:NetworkEventUpdated:EventTimings", onGenericEvent);
panel.off(panel.EVENTS.UPDATING_REQUEST_HEADERS, onGenericEvent);
panel.off(panel.EVENTS.RECEIVED_REQUEST_HEADERS, onGenericEvent);
panel.off(panel.EVENTS.UPDATING_REQUEST_COOKIES, onGenericEvent);
panel.off(panel.EVENTS.RECEIVED_REQUEST_COOKIES, onGenericEvent);
panel.off(panel.EVENTS.UPDATING_REQUEST_POST_DATA, onPostEvent);
panel.off(panel.EVENTS.RECEIVED_REQUEST_POST_DATA, onPostEvent);
panel.off(panel.EVENTS.UPDATING_RESPONSE_HEADERS, onGenericEvent);
panel.off(panel.EVENTS.RECEIVED_RESPONSE_HEADERS, onGenericEvent);
panel.off(panel.EVENTS.UPDATING_RESPONSE_COOKIES, onGenericEvent);
panel.off(panel.EVENTS.RECEIVED_RESPONSE_COOKIES, onGenericEvent);
panel.off(panel.EVENTS.STARTED_RECEIVING_RESPONSE, onGenericEvent);
panel.off(panel.EVENTS.UPDATING_RESPONSE_CONTENT, onGenericEvent);
panel.off(panel.EVENTS.RECEIVED_RESPONSE_CONTENT, onGenericEvent);
panel.off(panel.EVENTS.UPDATING_EVENT_TIMINGS, onGenericEvent);
panel.off(panel.EVENTS.RECEIVED_EVENT_TIMINGS, onGenericEvent);
executeSoon(deferred.resolve);
}
}
panel.on("NetMonitor:NetworkEventUpdating:RequestHeaders", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdated:RequestHeaders", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:RequestCookies", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:RequestPostData", onPostEvent);
panel.on("NetMonitor:NetworkEventUpdated:RequestPostData", onPostEvent);
panel.on("NetMonitor:NetworkEventUpdated:RequestCookies", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:ResponseHeaders", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdated:ResponseHeaders", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:ResponseCookies", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdated:ResponseCookies", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:ResponseStart", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:ResponseContent", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdated:ResponseContent", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdating:EventTimings", onGenericEvent);
panel.on("NetMonitor:NetworkEventUpdated:EventTimings", onGenericEvent);
panel.on(panel.EVENTS.UPDATING_REQUEST_HEADERS, onGenericEvent);
panel.on(panel.EVENTS.RECEIVED_REQUEST_HEADERS, onGenericEvent);
panel.on(panel.EVENTS.UPDATING_REQUEST_COOKIES, onGenericEvent);
panel.on(panel.EVENTS.RECEIVED_REQUEST_COOKIES, onGenericEvent);
panel.on(panel.EVENTS.UPDATING_REQUEST_POST_DATA, onPostEvent);
panel.on(panel.EVENTS.RECEIVED_REQUEST_POST_DATA, onPostEvent);
panel.on(panel.EVENTS.UPDATING_RESPONSE_HEADERS, onGenericEvent);
panel.on(panel.EVENTS.RECEIVED_RESPONSE_HEADERS, onGenericEvent);
panel.on(panel.EVENTS.UPDATING_RESPONSE_COOKIES, onGenericEvent);
panel.on(panel.EVENTS.RECEIVED_RESPONSE_COOKIES, onGenericEvent);
panel.on(panel.EVENTS.STARTED_RECEIVING_RESPONSE, onGenericEvent);
panel.on(panel.EVENTS.UPDATING_RESPONSE_CONTENT, onGenericEvent);
panel.on(panel.EVENTS.RECEIVED_RESPONSE_CONTENT, onGenericEvent);
panel.on(panel.EVENTS.UPDATING_EVENT_TIMINGS, onGenericEvent);
panel.on(panel.EVENTS.RECEIVED_EVENT_TIMINGS, onGenericEvent);
return deferred.promise;
}

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -1,3 +1,5 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>

View File

@ -93,12 +93,12 @@ var ContextCommands = {
let y = ContextMenuUI.popupState.y;
let json = {x: x, y: y, command: "paste" };
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
SelectionHelperUI.closeEditSession();
} else {
// chrome
CommandUpdater.doCommand("cmd_paste");
target.focus();
}
SelectionHelperUI.closeEditSession();
},
pasteAndGo: function cc_pasteAndGo() {

View File

@ -293,7 +293,7 @@ var ContextMenuHandler = {
// If this is text and has a selection, we want to bring
// up the copy option on the context menu.
let selection = targetWindow.getSelection();
if (selection && selection.toString().length > 0) {
if (selection && this._tapInSelection(selection, aX, aY)) {
state.string = targetWindow.getSelection().toString();
state.types.push("copy");
state.types.push("selected-text");
@ -323,6 +323,20 @@ var ContextMenuHandler = {
sendAsyncMessage("Content:ContextMenu", state);
},
_tapInSelection: function (aSelection, aX, aY) {
if (!aSelection || !aSelection.rangeCount) {
return false;
}
for (let idx = 0; idx < aSelection.rangeCount; idx++) {
let range = aSelection.getRangeAt(idx);
let rect = range.getBoundingClientRect();
if (Util.pointWithinDOMRect(aX, aY, rect)) {
return true;
}
}
return false;
},
_getLinkURL: function ch_getLinkURL(aLink) {
let href = aLink.href;
if (href)

View File

@ -22,6 +22,16 @@ was to get out again.
The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly
down, so suddenly that Alice had not a moment to think about stopping herself before she
found herself falling down a very deep well.
<div id="seldiv" style="width:300px; height:100px;">The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly
down, so suddenly that Alice had not a moment to think about stopping herself before she
found herself falling down a very deep well.
</div>
<br />
<br />
<br />
<br />
<br />
<div id="emptydiv" style="width:300px; height:100px; border: solid 1px black;"></div>
<br>
<br>
<br>

View File

@ -284,12 +284,15 @@ gTests.push({
400,
400,
400,
200);
350);
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
// cancel fling from scroll above
TouchModule.cancelPending();
// active state - should be disabled after a page scroll
is(SelectionHelperUI.isActive, false, "selection inactive");
},
@ -347,6 +350,32 @@ gTests.push({
tearDown: setUpAndTearDown,
});
gTests.push({
desc: "bug 903737 - right click targeting",
setUp: setUpAndTearDown,
run: function test() {
yield hideContextUI();
let range = gWindow.document.createRange();
range.selectNode(gWindow.document.getElementById("seldiv"));
gWindow.getSelection().addRange(range);
let promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(gWindow, gWindow.document.getElementById("seldiv"));
yield promise;
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
let emptydiv = gWindow.document.getElementById("emptydiv");
let coords = logicalCoordsForElement(emptydiv);
InputSourceHelper.isPrecise = true;
sendContextMenuClick(coords.x, coords.y);
yield waitForCondition(function () {
return ContextUI.tabbarVisible;
});
yield hideContextUI();
},
tearDown: setUpAndTearDown,
});
function test() {
if (!isLandscapeMode()) {
todo(false, "browser_selection_tests need landscape mode to run.");

View File

@ -134,7 +134,7 @@ gTests.push({
is(getTrimmedSelection(gFrame).toString(), "started", "selection test");
let promise = waitForEvent(document, "popupshown");
sendContextMenuClick(527, 188);
sendContextMenuClickToSelection(gFrame.contentDocument.defaultView);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");

View File

@ -79,7 +79,7 @@ gTests.push({
is(SelectionHelperUI.isActive, true, "selection active");
is(getTrimmedSelection(textarea).toString(), "Alice", "selection test");
let xpos = SelectionHelperUI.endMark.xPos;
let ypos = SelectionHelperUI.endMark.yPos + 10;

View File

@ -582,6 +582,26 @@ function sendContextMenuClick(aX, aY) {
1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
}
/*
* sendContextMenuClickToSelection - simulates a press-hold touch input event
* selected text in a window.
*/
function sendContextMenuClickToSelection(aWindow) {
let selection = aWindow.getSelection();
if (!selection || !selection.rangeCount) {
ok(false, "no selection to tap!");
return;
}
let range = selection.getRangeAt(0);
let rect = range.getBoundingClientRect();
let x = rect.left + (rect.width / 2);
let y = rect.top + (rect.height / 2);
let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.sendMouseEventToWindow("contextmenu", x, y, 2, 1, 0, true,
1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
}
/*
* sendContextMenuClickToWindow - simulates a press-hold touch input event.
*

View File

@ -407,15 +407,10 @@
}
.variables-view-scope > .variables-view-element-details:not(:empty) {
margin-top: 1px;
-moz-margin-start: 2px;
-moz-margin-end: 1px;
}
.variables-view-scope > .variables-view-element-details.enum:not(:empty) {
border-bottom: 1px solid #ddd;
}
/* Generic traits applied to both variables and properties */
.variable-or-property {

View File

@ -407,15 +407,10 @@
}
.variables-view-scope > .variables-view-element-details:not(:empty) {
margin-top: 1px;
-moz-margin-start: 2px;
-moz-margin-end: 1px;
}
.variables-view-scope > .variables-view-element-details.enum:not(:empty) {
border-bottom: 1px solid #ddd;
}
/* Generic traits applied to both variables and properties */
.variable-or-property {

View File

@ -410,15 +410,10 @@
}
.variables-view-scope > .variables-view-element-details:not(:empty) {
margin-top: 1px;
-moz-margin-start: 2px;
-moz-margin-end: 1px;
}
.variables-view-scope > .variables-view-element-details.enum:not(:empty) {
border-bottom: 1px solid #ddd;
}
/* Generic traits applied to both variables and properties */
.variable-or-property {

View File

@ -980,13 +980,9 @@ MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
POINT point;
if (GetCursorPos(&point)) {
ScreenToClient((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW), &point);
Foundation::Point oldMousePosition;
oldMousePosition.X = static_cast<FLOAT>(point.x);
oldMousePosition.Y = static_cast<FLOAT>(point.y);
mouseEvent.refPoint = aPoint;
mouseEvent.refPoint = LayoutDeviceIntPoint(point.x, point.y);
mouseEvent.message = NS_MOUSE_MOVE;
mouseEvent.button = 0;
DispatchEventIgnoreStatus(&mouseEvent);
}