зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1602123: Add a page action to open the current tab into a standalone window. r=Gijs
The action should open the SSB UI to show the page. No other custom behaviour is expecgterd at this point. Differential Revision: https://phabricator.services.mozilla.com/D56283 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
0ae5a64d9b
Коммит
c696551b78
|
@ -1085,6 +1085,37 @@ BrowserPageActions.pinTab = {
|
|||
},
|
||||
};
|
||||
|
||||
// SiteSpecificBrowser
|
||||
BrowserPageActions.launchSSB = {
|
||||
updateState() {
|
||||
let action = PageActions.actionForID("launchSSB");
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
action.setDisabled(!browser.currentURI.schemeIs("https"), window);
|
||||
},
|
||||
|
||||
onCommand(event, buttonNode) {
|
||||
if (!gBrowser.currentURI.schemeIs("https")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let sa = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
let uri = Cc["@mozilla.org/supports-string;1"].createInstance(
|
||||
Ci.nsISupportsString
|
||||
);
|
||||
uri.data = gBrowser.currentURI.spec;
|
||||
sa.appendElement(uri);
|
||||
Services.ww.openWindow(
|
||||
null,
|
||||
"chrome://browser/content/ssb/ssb.html",
|
||||
"_blank",
|
||||
"chrome,dialog=no,all",
|
||||
sa
|
||||
);
|
||||
|
||||
gBrowser.removeTab(gBrowser.selectedTab, { closeWindowWithLastTab: false });
|
||||
},
|
||||
};
|
||||
|
||||
// copy URL
|
||||
BrowserPageActions.copyURL = {
|
||||
onBeforePlacedInWindow(browserWindow) {
|
||||
|
|
|
@ -3153,7 +3153,10 @@
|
|||
this.removeTab(this.selectedTab, aParams);
|
||||
},
|
||||
|
||||
removeTab(aTab, { animate, byMouse, skipPermitUnload } = {}) {
|
||||
removeTab(
|
||||
aTab,
|
||||
{ animate, byMouse, skipPermitUnload, closeWindowWithLastTab } = {}
|
||||
) {
|
||||
// Telemetry stopwatches may already be running if removeTab gets
|
||||
// called again for an already closing tab.
|
||||
if (
|
||||
|
@ -3185,6 +3188,7 @@
|
|||
!this._beginRemoveTab(aTab, {
|
||||
closeWindowFastpath: true,
|
||||
skipPermitUnload,
|
||||
closeWindowWithLastTab,
|
||||
})
|
||||
) {
|
||||
TelemetryStopwatch.cancel("FX_TAB_CLOSE_TIME_ANIM_MS", aTab);
|
||||
|
|
|
@ -52,6 +52,7 @@ DIRS += [
|
|||
'search',
|
||||
'sessionstore',
|
||||
'shell',
|
||||
'ssb',
|
||||
'syncedtabs',
|
||||
'uitour',
|
||||
'urlbar',
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# 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/.
|
||||
|
||||
browser.jar:
|
||||
content/browser/ssb/ssb.html
|
||||
content/browser/ssb/ssb.js
|
||||
content/browser/ssb/ssb.css
|
|
@ -0,0 +1,14 @@
|
|||
/* 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/. */
|
||||
|
||||
html,
|
||||
body,
|
||||
#browser-container,
|
||||
#browser {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html width="800" height="600">
|
||||
<head>
|
||||
<link rel="stylesheet" href="chrome://global/skin/">
|
||||
<link rel="stylesheet" href="ssb.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="browser-container"></div>
|
||||
<script type="text/javascript" src="ssb.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
/* 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/. */
|
||||
|
||||
let gSSBBrowser = null;
|
||||
|
||||
function init() {
|
||||
gSSBBrowser = document.createXULElement("browser");
|
||||
gSSBBrowser.setAttribute("id", "browser");
|
||||
gSSBBrowser.setAttribute("type", "content");
|
||||
gSSBBrowser.setAttribute("remote", "true");
|
||||
document.getElementById("browser-container").appendChild(gSSBBrowser);
|
||||
gSSBBrowser.src = window.arguments[0];
|
||||
}
|
||||
|
||||
window.addEventListener("load", init, true);
|
|
@ -0,0 +1,8 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
JAR_MANIFESTS += ['content/jar.mn']
|
||||
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
|
|
@ -0,0 +1,10 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
head.js
|
||||
test_page.html
|
||||
prefs =
|
||||
browser.ssb.enabled=true
|
||||
|
||||
[browser_ssb_lasttab.js]
|
||||
[browser_ssb_menu.js]
|
||||
[browser_ssb_open.js]
|
|
@ -0,0 +1,34 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Opening from the last browser tab should not close the window.
|
||||
add_task(async () => {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
let windowClosed = false;
|
||||
BrowserTestUtils.windowClosed(win).then(() => {
|
||||
windowClosed = true;
|
||||
});
|
||||
|
||||
Assert.equal(win.gBrowser.tabs.length, 1, "Should be only one tab.");
|
||||
let tab = win.gBrowser.selectedTab;
|
||||
|
||||
let loaded = BrowserTestUtils.browserLoaded(
|
||||
win.gBrowser.selectedBrowser,
|
||||
false,
|
||||
gHttpsTestRoot + "test_page.html"
|
||||
);
|
||||
BrowserTestUtils.loadURI(
|
||||
win.gBrowser.selectedBrowser,
|
||||
gHttpsTestRoot + "test_page.html"
|
||||
);
|
||||
await loaded;
|
||||
|
||||
let ssb = await openSSBFromBrowserWindow(win);
|
||||
Assert.equal(win.gBrowser.tabs.length, 1, "Should still be only one tab.");
|
||||
Assert.notEqual(tab, win.gBrowser.selectedTab, "Should be a new tab.");
|
||||
|
||||
Assert.ok(!windowClosed, "Should not have seen the window close.");
|
||||
await BrowserTestUtils.closeWindow(ssb);
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that it is correctly enabled/disabled based on the displaying page.
|
||||
add_task(async () => {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: gHttpTestRoot + "test_page.html",
|
||||
});
|
||||
|
||||
// Must open the panel before the item gets added.
|
||||
let pageActionButton = document.getElementById("pageActionButton");
|
||||
let panel = document.getElementById("pageActionPanel");
|
||||
let popupShown = BrowserTestUtils.waitForEvent(panel, "popupshown");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(pageActionButton, {}, window);
|
||||
await popupShown;
|
||||
|
||||
let popupHidden = BrowserTestUtils.waitForEvent(panel, "popuphidden");
|
||||
panel.hidePopup();
|
||||
await popupHidden;
|
||||
|
||||
Assert.ok(
|
||||
document.getElementById("pageAction-panel-launchSSB").disabled,
|
||||
"Menu should be disabled for a http: page."
|
||||
);
|
||||
|
||||
let uri = gHttpsTestRoot + "test_page.html";
|
||||
BrowserTestUtils.loadURI(tab.linkedBrowser, uri);
|
||||
await BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, uri);
|
||||
|
||||
Assert.ok(
|
||||
!document.getElementById("pageAction-panel-launchSSB").disabled,
|
||||
"Menu should not be disabled for a https: page."
|
||||
);
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Verify that clicking the menu button opens an ssb.
|
||||
add_task(async () => {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab({
|
||||
gBrowser,
|
||||
url: gHttpsTestRoot + "test_page.html",
|
||||
});
|
||||
|
||||
let ssb = await openSSBFromBrowserWindow();
|
||||
Assert.equal(
|
||||
getBrowser(ssb).currentURI.spec,
|
||||
gHttpsTestRoot + "test_page.html"
|
||||
);
|
||||
|
||||
Assert.equal(tab.parentNode, null, "The tab should have been closed");
|
||||
await BrowserTestUtils.closeWindow(ssb);
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,49 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// An insecure site to use. SSBs cannot be insecure.
|
||||
const gHttpTestRoot = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"http://example.com/"
|
||||
);
|
||||
|
||||
// A secure site to use.
|
||||
const gHttpsTestRoot = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
"https://example.com/"
|
||||
);
|
||||
|
||||
// The chrome url for the SSB UI.
|
||||
const SSB_WINDOW = "chrome://browser/content/ssb/ssb.html";
|
||||
|
||||
// Simulates opening a SSB from the main browser window. Resolves to the SSB
|
||||
// DOM window after the SSB content has loaded.
|
||||
async function openSSBFromBrowserWindow(win = window) {
|
||||
let doc = win.document;
|
||||
let pageActionButton = doc.getElementById("pageActionButton");
|
||||
let panel = doc.getElementById("pageActionPanel");
|
||||
let popupShown = BrowserTestUtils.waitForEvent(panel, "popupshown");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(pageActionButton, {}, win);
|
||||
await popupShown;
|
||||
|
||||
let openItem = doc.getElementById("pageAction-panel-launchSSB");
|
||||
Assert.ok(!openItem.disabled, "Open menu item should not be disabled");
|
||||
Assert.ok(!openItem.hidden, "Open menu item should not be hidden");
|
||||
|
||||
let openPromise = BrowserTestUtils.domWindowOpened(null, async domwin => {
|
||||
await BrowserTestUtils.waitForEvent(domwin, "load");
|
||||
return domwin.location.toString() == SSB_WINDOW;
|
||||
});
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(openItem, {}, win);
|
||||
let ssbwin = await openPromise;
|
||||
let browser = ssbwin.document.getElementById("browser");
|
||||
await BrowserTestUtils.browserLoaded(browser, true);
|
||||
return ssbwin;
|
||||
}
|
||||
|
||||
// Given the SSB UI DOM window gets the browser element showing the content.
|
||||
function getBrowser(ssbwin) {
|
||||
return ssbwin.document.getElementById("browser");
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -1280,6 +1280,20 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
|
|||
});
|
||||
}
|
||||
|
||||
if (Services.prefs.getBoolPref("browser.ssb.enabled", false)) {
|
||||
gBuiltInActions.push({
|
||||
id: "launchSSB",
|
||||
// Hardcoded for now. Localization tracked in bug 1602528.
|
||||
title: "Launch Site Specific Browser",
|
||||
onLocationChange(browserWindow) {
|
||||
browserPageActions(browserWindow).launchSSB.updateState();
|
||||
},
|
||||
onCommand(event, buttonNode) {
|
||||
browserPageActions(buttonNode).launchSSB.onCommand(event, buttonNode);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// share URL
|
||||
if (AppConstants.platform == "macosx") {
|
||||
gBuiltInActions.push({
|
||||
|
|
Загрузка…
Ссылка в новой задаче