Merge fx-team to m-c on a CLOSED TREE.

This commit is contained in:
Ryan VanderMeulen 2013-11-14 22:19:19 -05:00
commit 56e157765f
13 changed files with 278 additions and 24 deletions

View File

@ -404,7 +404,8 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
DebuggerController.SourceScripts.togglePrettyPrint(source)
.then(resetEditor, printError)
.then(DebuggerView.showEditor);
.then(DebuggerView.showEditor)
.then(this.updateToolbarButtonsState);
},
/**

View File

@ -128,6 +128,7 @@ skip-if = true
[browser_dbg_pretty-print-09.js]
[browser_dbg_pretty-print-10.js]
[browser_dbg_pretty-print-11.js]
[browser_dbg_pretty-print-12.js]
[browser_dbg_progress-listener-bug.js]
[browser_dbg_reload-preferred-script-01.js]
[browser_dbg_reload-preferred-script-02.js]

View File

@ -0,0 +1,54 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that we don't leave the pretty print button checked when we fail to
* pretty print a source (because it isn't a JS file, for example).
*/
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gSources;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gSources = gDebugger.DebuggerView.Sources;
waitForSourceShown(gPanel, "")
.then(() => {
let shown = ensureSourceIs(gPanel, TAB_URL, true)
gSources.selectedValue = TAB_URL;
return shown;
})
.then(clickPrettyPrintButton)
.then(testButtonIsntChecked)
.then(() => closeDebuggerAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
});
});
}
function clickPrettyPrintButton() {
gDebugger.document.getElementById("pretty-print").click();
}
function testButtonIsntChecked() {
is(gDebugger.document.getElementById("pretty-print").checked, false,
"The button shouldn't be checked after trying to pretty print a non-js file.");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gSources = null;
});

View File

@ -170,9 +170,8 @@ var ContextCommands = {
// Link specific
openLinkInNewTab: function cc_openLinkInNewTab() {
let tab = Browser.addTab(ContextMenuUI.popupState.linkURL, false, Browser.selectedTab);
ContextUI.peekTabs(kOpenInNewTabAnimationDelayMsec);
Elements.tabList.strip.ensureElementIsVisible(tab.chromeTab);
let url = ContextMenuUI.popupState.linkURL;
BrowserUI.openLinkInNewTab(url, false, Browser.selectedTab);
},
copyLink: function cc_copyLink() {

View File

@ -161,7 +161,7 @@ var ContextUI = {
* Dismiss tab bar after a delay. Fires context ui events.
*/
dismissTabsWithDelay: function (aDelay) {
aDelay = aDelay || kNewTabAnimationDelayMsec;
aDelay = aDelay || kForegroundTabAnimationDelay;
this._clearDelayedTimeout();
this._hidingId = setTimeout(function () {
ContextUI.dismissTabs();

View File

@ -39,6 +39,9 @@ var APZCObserver = {
handleEvent: function APZC_handleEvent(aEvent) {
switch (aEvent.type) {
case 'pageshow':
if (aEvent.target != Browser.selectedBrowser.contentDocument)
break;
// fall through to TabSelect:
case 'TabSelect':
// ROOT_ID doesn't really identify the view we want. When we call
// this on a content document (tab), findElementWithViewId will

View File

@ -66,6 +66,9 @@ XPCOMUtils.defineLazyServiceGetter(window, "gFaviconService",
XPCOMUtils.defineLazyServiceGetter(window, "gFocusManager",
"@mozilla.org/focus-manager;1",
"nsIFocusManager");
XPCOMUtils.defineLazyServiceGetter(window, "gEventListenerService",
"@mozilla.org/eventlistenerservice;1",
"nsIEventListenerService");
#ifdef MOZ_CRASHREPORTER
XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
"@mozilla.org/xre/app-info;1",

View File

@ -14,12 +14,12 @@ Cu.import("resource://gre/modules/devtools/dbg-server.jsm")
const debugServerStateChanged = "devtools.debugger.remote-enabled";
const debugServerPortChanged = "devtools.debugger.remote-port";
// delay when showing the tab bar briefly after a new (empty) tab opens
const kNewTabAnimationDelayMsec = 1000;
// delay when showing the tab bar after opening a link on a new tab
const kOpenInNewTabAnimationDelayMsec = 3000;
// delay before closing tab bar after selecting another tab
const kSelectTabAnimationDelayMsec = 500;
// delay when showing the tab bar briefly after a new foreground tab opens
const kForegroundTabAnimationDelay = 1000;
// delay when showing the tab bar after opening a new background tab opens
const kBackgroundTabAnimationDelay = 3000;
// delay before closing tab bar after closing or selecting a tab
const kChangeTabAnimationDelay = 500;
/**
* Cache of commonly used elements.
@ -173,6 +173,14 @@ var BrowserUI = {
},
uninit: function() {
messageManager.removeMessageListener("DOMTitleChanged", this);
messageManager.removeMessageListener("DOMWillOpenModalDialog", this);
messageManager.removeMessageListener("DOMWindowClose", this);
messageManager.removeMessageListener("Browser:OpenURI", this);
messageManager.removeMessageListener("Browser:SaveAs:Return", this);
messageManager.removeMessageListener("Content:StateChange", this);
messageManager.removeMessageListener("Browser:MozApplicationManifest", OfflineApps);
Services.obs.removeObserver(this, "handle-xul-text-link");
@ -180,7 +188,6 @@ var BrowserUI = {
FlyoutPanelsUI.uninit();
MetroDownloadsView.uninit();
SettingsCharm.uninit();
messageManager.removeMessageListener("Content:StateChange", this);
PageThumbs.uninit();
this.stopDebugServer();
},
@ -436,10 +443,25 @@ var BrowserUI = {
* See Browser.addTab for more documentation.
*/
addAndShowTab: function (aURI, aOwner) {
ContextUI.peekTabs(kNewTabAnimationDelayMsec);
ContextUI.peekTabs(kForegroundTabAnimationDelay);
return Browser.addTab(aURI || kStartURI, true, aOwner);
},
/**
* Open a new tab in response to clicking a link in an existing tab.
* See Browser.addTab for more documentation.
*/
openLinkInNewTab: function (aURI, aBringFront, aOwner) {
ContextUI.peekTabs(aBringFront ? kForegroundTabAnimationDelay
: kBackgroundTabAnimationDelay);
let tab = Browser.addTab(aURI, aBringFront, aOwner, {
referrerURI: aOwner.browser.documentURI,
charset: aOwner.browser.characterSet,
});
Elements.tabList.strip.ensureElementIsVisible(tab.chromeTab);
return tab;
},
setOnTabAnimationEnd: function setOnTabAnimationEnd(aCallback) {
Elements.tabs.addEventListener("animationend", function onAnimationEnd() {
Elements.tabs.removeEventListener("animationend", onAnimationEnd);
@ -464,7 +486,7 @@ var BrowserUI = {
this.setOnTabAnimationEnd(function() {
Browser.closeTab(tabToClose, { forceClose: true } );
if (wasCollapsed)
ContextUI.dismissTabsWithDelay(kNewTabAnimationDelayMsec);
ContextUI.dismissTabsWithDelay(kChangeTabAnimationDelay);
});
},
@ -506,7 +528,7 @@ var BrowserUI = {
selectTabAndDismiss: function selectTabAndDismiss(aTab) {
this.selectTab(aTab);
ContextUI.dismissTabsWithDelay(kSelectTabAnimationDelayMsec);
ContextUI.dismissTabsWithDelay(kChangeTabAnimationDelay);
},
selectTabAtIndex: function selectTabAtIndex(aIndex) {

View File

@ -79,6 +79,7 @@ var Browser = {
// Call InputSourceHelper first so global listeners get called before
// we start processing input in TouchModule.
InputSourceHelper.init();
ClickEventHandler.init();
TouchModule.init();
GestureModule.init();
@ -213,6 +214,7 @@ var Browser = {
shutdown: function shutdown() {
APZCObserver.shutdown();
BrowserUI.uninit();
ClickEventHandler.uninit();
ContentAreaObserver.shutdown();
Appbar.shutdown();
@ -485,7 +487,7 @@ var Browser = {
if (aBringFront)
this.selectedTab = newTab;
this._announceNewTab(newTab, params, aBringFront);
this._announceNewTab(newTab);
return newTab;
},
@ -511,7 +513,7 @@ var Browser = {
* helper for addTab related methods. Fires events related to
* new tab creation.
*/
_announceNewTab: function _announceNewTab(aTab, aParams, aBringFront) {
_announceNewTab: function (aTab) {
let event = document.createEvent("UIEvents");
event.initUIEvent("TabOpen", true, false, window, 0);
aTab.chromeTab.dispatchEvent(event);
@ -1074,12 +1076,7 @@ nsBrowserAccess.prototype = {
if (openAction == Ci.nsIBrowserDOMWindow.OPEN_NEWTAB) {
let owner = isExternal ? null : Browser.selectedTab;
let tab = Browser.addTab("about:blank", true, owner);
// Link clicks in content need to trigger peek tab functionality
ContextUI.peekTabs(kOpenInNewTabAnimationDelayMsec);
if (isExternal) {
tab.closeOnExit = true;
}
let tab = BrowserUI.openLinkInNewTab("about:blank", true, owner);
browser = tab.browser;
} else {
browser = Browser.selectedBrowser;
@ -1580,3 +1577,68 @@ function rendererFactory(aBrowser, aCanvas) {
return wrapper;
};
// Based on ClickEventHandler from /browser/base/content/content.js
let ClickEventHandler = {
init: function () {
gEventListenerService.addSystemEventListener(Elements.browsers, "click", this, true);
},
uninit: function () {
gEventListenerService.removeSystemEventListener(Elements.browsers, "click", this, true);
},
handleEvent: function (aEvent) {
if (!aEvent.isTrusted || aEvent.defaultPrevented) {
return;
}
let [href, node] = this._hrefAndLinkNodeForClickEvent(aEvent);
if (href && (aEvent.button == 1 || aEvent.ctrlKey)) {
// Open link in a new tab for middle-click or ctrl-click
BrowserUI.openLinkInNewTab(href, aEvent.shiftKey, Browser.selectedTab);
}
},
/**
* Extracts linkNode and href for the current click target.
*
* @param event
* The click event.
* @return [href, linkNode].
*
* @note linkNode will be null if the click wasn't on an anchor
* element (or XLink).
*/
_hrefAndLinkNodeForClickEvent: function(event) {
function isHTMLLink(aNode) {
return ((aNode instanceof content.HTMLAnchorElement && aNode.href) ||
(aNode instanceof content.HTMLAreaElement && aNode.href) ||
aNode instanceof content.HTMLLinkElement);
}
let node = event.target;
while (node && !isHTMLLink(node)) {
node = node.parentNode;
}
if (node)
return [node.href, node];
// If there is no linkNode, try simple XLink.
let href, baseURI;
node = event.target;
while (node && !href) {
if (node.nodeType == content.Node.ELEMENT_NODE) {
href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
if (href)
baseURI = node.ownerDocument.baseURIObject;
}
node = node.parentNode;
}
// In case of XLink, we don't return the node we got href from since
// callers expect <a>-like elements.
// Note: makeURI() will throw if aUri is not a valid URI.
return [href ? Services.io.newURI(href, null, baseURI).spec : null, null];
}
};

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>link click test</title>
</head>
<body>
<a id="link" href="about:blank">link</a>
</body>
</html>

View File

@ -0,0 +1,97 @@
/* 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 test() {
waitForExplicitFinish();
runTests();
}
gTests.push({
desc: "regular link click",
run: function () {
let tab = yield addTab(chromeRoot + "browser_link_click.html");
let tabCount = Browser.tabs.length;
EventUtils.sendMouseEvent({type: "click"}, "link", tab.browser.contentWindow);
yield waitForCondition(() => tab.browser.currentURI.spec == "about:blank");
is(Browser.tabs.length, tabCount, "link loaded in the same tab");
}
});
gTests.push({
desc: "middle-click opens link in background tab",
run: function () {
let tab = yield addTab(chromeRoot + "browser_link_click.html");
let tabOpen = waitForEvent(window, "TabOpen");
EventUtils.sendMouseEvent({type: "click", button: 1}, "link", tab.browser.contentWindow);
let event = yield tabOpen;
let newTab = Browser.getTabFromChrome(event.originalTarget);
yield waitForEvent(newTab.browser, "pageshow");
is(newTab.browser.currentURI.spec, "about:blank");
ok(newTab != Browser.selectedTab, "new tab is in the background");
Browser.closeTab(newTab, { forceClose: true });
}
});
gTests.push({
desc: "shift-middle-click opens link in background tab",
run: function () {
let tab = yield addTab(chromeRoot + "browser_link_click.html");
let tabOpen = waitForEvent(window, "TabOpen");
EventUtils.sendMouseEvent({type: "click", button: 1, shiftKey: true}, "link", tab.browser.contentWindow);
let event = yield tabOpen;
let newTab = Browser.getTabFromChrome(event.originalTarget);
yield waitForEvent(newTab.browser, "pageshow");
is(newTab.browser.currentURI.spec, "about:blank");
ok(newTab == Browser.selectedTab, "new tab is in the foreground");
Browser.closeTab(newTab, { forceClose: true });
}
});
gTests.push({
desc: "ctrl-click opens link in background tab",
run: function () {
let tab = yield addTab(chromeRoot + "browser_link_click.html");
let tabOpen = waitForEvent(window, "TabOpen");
EventUtils.sendMouseEvent({type: "click", ctrlKey: true}, "link", tab.browser.contentWindow);
let event = yield tabOpen;
let newTab = Browser.getTabFromChrome(event.originalTarget);
yield waitForEvent(newTab.browser, "pageshow");
is(newTab.browser.currentURI.spec, "about:blank");
ok(newTab != Browser.selectedTab, "new tab is in the background");
Browser.closeTab(newTab, { forceClose: true });
}
});
gTests.push({
desc: "shift-ctrl-click opens link in background tab",
run: function () {
let tab = yield addTab(chromeRoot + "browser_link_click.html");
let tabOpen = waitForEvent(window, "TabOpen");
EventUtils.sendMouseEvent({type: "click", ctrlKey: true, shiftKey: true}, "link", tab.browser.contentWindow);
let event = yield tabOpen;
let newTab = Browser.getTabFromChrome(event.originalTarget);
yield waitForEvent(newTab.browser, "pageshow");
is(newTab.browser.currentURI.spec, "about:blank");
ok(newTab == Browser.selectedTab, "new tab is in the foreground");
Browser.closeTab(newTab, { forceClose: true });
}
});

View File

@ -6,6 +6,7 @@ support-files =
browser_context_menu_tests_04.html
browser_findbar.html
browser_form_auto_complete.html
browser_link_click.html
browser_onscreen_keyboard.html
browser_progress_indicator.xul
browser_selection_basic.html
@ -42,6 +43,7 @@ support-files =
[browser_form_auto_complete.js]
[browser_history.js]
[browser_inputsource.js]
[browser_link_click.js]
[browser_onscreen_keyboard.js]
[browser_prefs_ui.js]
[browser_remotetabs.js]

View File

@ -306,5 +306,5 @@ textarea:not([disabled]):active,
option:active,
label:active,
xul|menulist:active {
background-color: @color_background_highlight_overlay@ !important;
background-color: @color_background_highlight_overlay@;
}