Bug 1363182 - Add a "send to device" subview to the page action menu. r=eoger,mikedeboer
Add a Send to Device subview to the page action panel. When the page isn't sendable, disable the Send to Device menu item. When the user doesn't have any devices, show a menu item that opens the Firefox Account preferences pane. Generalize gSync.populateSendTabToDevicesMenu() so that it can be used to populate any kind of container, not only a menupopup with menuitems. Add an SVG that shows a phone and an SVG that shows a desktop. MozReview-Commit-ID: EZQKAEAr08q --HG-- extra : rebase_source : bda87f105712a6c6ba83da1a78179eee93b5f4d0
@ -280,10 +280,20 @@ var gSync = {
|
||||
Weave.Service.clientsEngine.sendURIToClientForDisplay(url, clientId, title);
|
||||
},
|
||||
|
||||
populateSendTabToDevicesMenu(devicesPopup, url, title) {
|
||||
populateSendTabToDevicesMenu(devicesPopup, url, title, createDeviceNodeFn) {
|
||||
if (!createDeviceNodeFn) {
|
||||
createDeviceNodeFn = (clientId, name, clientType) => {
|
||||
let eltName = name ? "menuitem" : "menuseparator";
|
||||
return document.createElement(eltName);
|
||||
};
|
||||
}
|
||||
|
||||
// remove existing menu items
|
||||
while (devicesPopup.hasChildNodes()) {
|
||||
devicesPopup.firstChild.remove();
|
||||
for (let i = devicesPopup.childNodes.length - 1; i >= 0; --i) {
|
||||
let child = devicesPopup.childNodes[i];
|
||||
if (child.classList.contains("sync-menuitem")) {
|
||||
child.remove();
|
||||
}
|
||||
}
|
||||
|
||||
const fragment = document.createDocumentFragment();
|
||||
@ -296,26 +306,28 @@ var gSync = {
|
||||
clients.forEach(clientId => this.sendTabToDevice(url, clientId, title));
|
||||
}
|
||||
|
||||
function addTargetDevice(clientId, name) {
|
||||
const targetDevice = document.createElement("menuitem");
|
||||
function addTargetDevice(clientId, name, clientType) {
|
||||
const targetDevice = createDeviceNodeFn(clientId, name, clientType);
|
||||
targetDevice.addEventListener("command", onTargetDeviceCommand, true);
|
||||
targetDevice.setAttribute("class", "sendtab-target");
|
||||
targetDevice.classList.add("sync-menuitem", "sendtab-target");
|
||||
targetDevice.setAttribute("clientId", clientId);
|
||||
targetDevice.setAttribute("clientType", clientType);
|
||||
targetDevice.setAttribute("label", name);
|
||||
fragment.appendChild(targetDevice);
|
||||
}
|
||||
|
||||
const clients = this.remoteClients;
|
||||
for (let client of clients) {
|
||||
addTargetDevice(client.id, client.name);
|
||||
addTargetDevice(client.id, client.name, client.type);
|
||||
}
|
||||
|
||||
// "All devices" menu item
|
||||
if (clients.length > 1) {
|
||||
const separator = document.createElement("menuseparator");
|
||||
const separator = createDeviceNodeFn();
|
||||
separator.classList.add("sync-menuitem");
|
||||
fragment.appendChild(separator);
|
||||
const allDevicesLabel = this.fxaStrings.GetStringFromName("sendTabToAllDevices.menuitem");
|
||||
addTargetDevice("", allDevicesLabel);
|
||||
addTargetDevice("", allDevicesLabel, "");
|
||||
}
|
||||
|
||||
devicesPopup.appendChild(fragment);
|
||||
|
@ -1333,4 +1333,11 @@ toolbarpaletteitem[place="palette"][hidden] {
|
||||
-moz-window-shadow: none;
|
||||
}
|
||||
|
||||
/* Page action menu */
|
||||
#page-action-sendToDeviceView-body[signedin] > #page-action-sendToDevice-fxa-button,
|
||||
#page-action-sendToDeviceView-body:not([signedin]) > #page-action-no-devices-button,
|
||||
#page-action-sendToDeviceView-body[hasdevices] > #page-action-no-devices-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
%include theme-vars.inc.css
|
||||
|
@ -7737,6 +7737,11 @@ var gPageActionButton = {
|
||||
return this.panel = document.getElementById("page-action-panel");
|
||||
},
|
||||
|
||||
get sendToDeviceBody() {
|
||||
delete this.sendToDeviceBody;
|
||||
return this.sendToDeviceBody = document.getElementById("page-action-sendToDeviceView-body");
|
||||
},
|
||||
|
||||
init() {
|
||||
if (getBoolPref("browser.photon.structure.enabled")) {
|
||||
this.button.hidden = false;
|
||||
@ -7752,10 +7757,20 @@ var gPageActionButton = {
|
||||
return; // Left click, space or enter only
|
||||
}
|
||||
|
||||
this._preparePanelToBeShown();
|
||||
this.panel.hidden = false;
|
||||
this.panel.openPopup(this.button, "bottomcenter topright");
|
||||
},
|
||||
|
||||
_preparePanelToBeShown() {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let url = browser.currentURI.spec;
|
||||
|
||||
let sendToDeviceItem =
|
||||
document.getElementById("page-action-send-to-device-button");
|
||||
sendToDeviceItem.disabled = !gSync.isSendableURI(url);
|
||||
},
|
||||
|
||||
copyURL() {
|
||||
this.panel.hidePopup();
|
||||
Cc["@mozilla.org/widget/clipboardhelper;1"]
|
||||
@ -7767,6 +7782,44 @@ var gPageActionButton = {
|
||||
this.panel.hidePopup();
|
||||
MailIntegration.sendLinkForBrowser(gBrowser.selectedBrowser);
|
||||
},
|
||||
|
||||
showSendToDeviceView(subviewButton) {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let url = browser.currentURI.spec;
|
||||
let title = browser.contentTitle;
|
||||
let body = this.sendToDeviceBody;
|
||||
|
||||
gSync.populateSendTabToDevicesMenu(body, url, title, (clientId, name, clientType) => {
|
||||
if (!name) {
|
||||
return document.createElement("toolbarseparator");
|
||||
}
|
||||
let item = document.createElement("toolbarbutton");
|
||||
item.classList.add("page-action-sendToDevice-device", "subviewbutton");
|
||||
if (clientId) {
|
||||
item.classList.add("subviewbutton-iconic");
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
if (gSync.remoteClients.length) {
|
||||
body.setAttribute("hasdevices", "true");
|
||||
} else {
|
||||
body.removeAttribute("hasdevices");
|
||||
}
|
||||
|
||||
if (UIState.get().status == UIState.STATUS_SIGNED_IN) {
|
||||
body.setAttribute("signedin", "true");
|
||||
} else {
|
||||
body.removeAttribute("signedin");
|
||||
}
|
||||
|
||||
PanelUI.showSubView("page-action-sendToDeviceView", subviewButton);
|
||||
},
|
||||
|
||||
fxaButtonClicked() {
|
||||
this.panel.hidePopup();
|
||||
gSync.openPrefs();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -465,6 +465,26 @@
|
||||
class="subviewbutton subviewbutton-iconic"
|
||||
label="&emailPageCmd.label;"
|
||||
command="PageAction:emailLink"/>
|
||||
<toolbarbutton id="page-action-send-to-device-button"
|
||||
class="subviewbutton subviewbutton-iconic subviewbutton-nav"
|
||||
label="&sendToDevice.label;"
|
||||
closemenu="none"
|
||||
oncommand="gPageActionButton.showSendToDeviceView(this);"/>
|
||||
</vbox>
|
||||
</panelview>
|
||||
<panelview id="page-action-sendToDeviceView"
|
||||
class="PanelUI-subView"
|
||||
title="&sendToDevice.viewTitle;">
|
||||
<vbox id="page-action-sendToDeviceView-body" class="panel-subview-body">
|
||||
<toolbarbutton id="page-action-sendToDevice-fxa-button"
|
||||
class="subviewbutton subviewbutton-iconic"
|
||||
label="&syncBrand.fxAccount.label;"
|
||||
shortcut="&sendToDevice.fxaRequired.label;"
|
||||
oncommand="gPageActionButton.fxaButtonClicked();"/>
|
||||
<toolbarbutton id="page-action-no-devices-button"
|
||||
class="subviewbutton"
|
||||
label="&sendToDevice.noDevices.label;"
|
||||
disabled="true"/>
|
||||
</vbox>
|
||||
</panelview>
|
||||
</photonpanelmultiview>
|
||||
|
@ -48,8 +48,8 @@ function getVisibleMenuItems(aMenu, aData) {
|
||||
var isPageMenuItem = item.hasAttribute("generateditemid");
|
||||
|
||||
if (item.nodeName == "menuitem") {
|
||||
var isGenerated = item.className == "spell-suggestion"
|
||||
|| item.className == "sendtab-target";
|
||||
var isGenerated = item.classList.contains("spell-suggestion")
|
||||
|| item.classList.contains("sendtab-target");
|
||||
if (isGenerated) {
|
||||
is(item.id, "", "child menuitem #" + i + " is generated");
|
||||
} else if (isPageMenuItem) {
|
||||
|
@ -114,3 +114,5 @@ run-if = e10s
|
||||
subsuite = clipboard
|
||||
support-files =
|
||||
test_wyciwyg_copying.html
|
||||
[browser_page_action_menu.js]
|
||||
run-if = nightly_build # Photon only
|
||||
|
317
browser/base/content/test/urlbar/browser_page_action_menu.js
Normal file
@ -0,0 +1,317 @@
|
||||
"use strict";
|
||||
|
||||
let gPanel = document.getElementById("page-action-panel");
|
||||
|
||||
add_task(async function copyURL() {
|
||||
// Open the panel.
|
||||
await promisePanelOpen();
|
||||
|
||||
// Click Copy URL.
|
||||
let copyURLButton = document.getElementById("page-action-copy-url-button");
|
||||
let hiddenPromise = promisePanelHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(copyURLButton, {});
|
||||
await hiddenPromise;
|
||||
|
||||
// Check the clipboard.
|
||||
let transferable = Cc["@mozilla.org/widget/transferable;1"]
|
||||
.createInstance(Ci.nsITransferable);
|
||||
transferable.init(null);
|
||||
let flavor = "text/unicode";
|
||||
transferable.addDataFlavor(flavor);
|
||||
Services.clipboard.getData(transferable, Services.clipboard.kGlobalClipboard);
|
||||
let strObj = {};
|
||||
transferable.getTransferData(flavor, strObj, {});
|
||||
Assert.ok(!!strObj.value);
|
||||
strObj.value.QueryInterface(Ci.nsISupportsString);
|
||||
Assert.equal(strObj.value.data, gBrowser.selectedBrowser.currentURI.spec);
|
||||
});
|
||||
|
||||
add_task(async function emailLink() {
|
||||
// Replace the email-link entry point to check whether it's called.
|
||||
let originalFn = MailIntegration.sendLinkForBrowser;
|
||||
let fnCalled = false;
|
||||
MailIntegration.sendLinkForBrowser = () => {
|
||||
fnCalled = true;
|
||||
};
|
||||
registerCleanupFunction(() => {
|
||||
MailIntegration.sendLinkForBrowser = originalFn;
|
||||
});
|
||||
|
||||
// Open the panel and click Email Link.
|
||||
await promisePanelOpen();
|
||||
let emailLinkButton =
|
||||
document.getElementById("page-action-email-link-button");
|
||||
let hiddenPromise = promisePanelHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(emailLinkButton, {});
|
||||
await hiddenPromise;
|
||||
|
||||
Assert.ok(fnCalled);
|
||||
});
|
||||
|
||||
add_task(async function sendToDevice_nonSendable() {
|
||||
// Open a tab that's not sendable.
|
||||
await BrowserTestUtils.withNewTab("about:blank", async () => {
|
||||
// Open the panel. Send to Device should be disabled.
|
||||
await promisePanelOpen();
|
||||
let sendToDeviceButton =
|
||||
document.getElementById("page-action-send-to-device-button");
|
||||
Assert.ok(sendToDeviceButton.disabled);
|
||||
let hiddenPromise = promisePanelHidden();
|
||||
gPanel.hidePopup();
|
||||
await hiddenPromise;
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function sendToDevice_notSignedIn() {
|
||||
// Open a tab that's sendable.
|
||||
await BrowserTestUtils.withNewTab("http://example.com/", async () => {
|
||||
await promiseSyncReady();
|
||||
|
||||
// Open the panel.
|
||||
await promisePanelOpen();
|
||||
let sendToDeviceButton =
|
||||
document.getElementById("page-action-send-to-device-button");
|
||||
Assert.ok(!sendToDeviceButton.disabled);
|
||||
|
||||
// Click Send to Device.
|
||||
let viewPromise = promiseViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(sendToDeviceButton, {});
|
||||
let view = await viewPromise;
|
||||
Assert.equal(view.id, "page-action-sendToDeviceView");
|
||||
|
||||
// The Fxa button should be shown.
|
||||
checkSendToDeviceItems([
|
||||
{
|
||||
id: "page-action-sendToDevice-fxa-button",
|
||||
},
|
||||
{
|
||||
id: "page-action-no-devices-button",
|
||||
display: "none",
|
||||
disabled: true,
|
||||
},
|
||||
]);
|
||||
|
||||
// Click the Fxa button.
|
||||
let body = view.firstChild;
|
||||
let fxaButton = body.childNodes[0];
|
||||
Assert.equal(fxaButton.id, "page-action-sendToDevice-fxa-button");
|
||||
let prefsTabPromise = BrowserTestUtils.waitForNewTab(gBrowser);
|
||||
let hiddenPromise = promisePanelHidden();
|
||||
EventUtils.synthesizeMouseAtCenter(fxaButton, {});
|
||||
let values = await Promise.all([prefsTabPromise, hiddenPromise]);
|
||||
let tab = values[0];
|
||||
|
||||
// The Fxa prefs pane should open. The full URL is something like:
|
||||
// about:preferences?entrypoint=syncbutton#sync
|
||||
// Just make sure it's about:preferences#sync.
|
||||
let urlObj = new URL(gBrowser.selectedBrowser.currentURI.spec);
|
||||
let url = urlObj.protocol + urlObj.pathname + urlObj.hash;
|
||||
Assert.equal(url, "about:preferences#sync");
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function sendToDevice_noDevices() {
|
||||
// Open a tab that's sendable.
|
||||
await BrowserTestUtils.withNewTab("http://example.com/", async () => {
|
||||
await promiseSyncReady();
|
||||
UIState._internal._state = { status: UIState.STATUS_SIGNED_IN };
|
||||
|
||||
// Open the panel.
|
||||
await promisePanelOpen();
|
||||
let sendToDeviceButton =
|
||||
document.getElementById("page-action-send-to-device-button");
|
||||
Assert.ok(!sendToDeviceButton.disabled);
|
||||
|
||||
// Click Send to Device.
|
||||
let viewPromise = promiseViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(sendToDeviceButton, {});
|
||||
let view = await viewPromise;
|
||||
Assert.equal(view.id, "page-action-sendToDeviceView");
|
||||
|
||||
// The no-devices item should be shown.
|
||||
checkSendToDeviceItems([
|
||||
{
|
||||
id: "page-action-sendToDevice-fxa-button",
|
||||
display: "none",
|
||||
},
|
||||
{
|
||||
id: "page-action-no-devices-button",
|
||||
disabled: true,
|
||||
},
|
||||
]);
|
||||
|
||||
// Done, hide the panel.
|
||||
let hiddenPromise = promisePanelHidden();
|
||||
gPanel.hidePopup();
|
||||
await hiddenPromise;
|
||||
|
||||
await UIState.reset();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function sendToDevice_devices() {
|
||||
// Open a tab that's sendable.
|
||||
await BrowserTestUtils.withNewTab("http://example.com/", async () => {
|
||||
await promiseSyncReady();
|
||||
UIState._internal._state = { status: UIState.STATUS_SIGNED_IN };
|
||||
|
||||
// Set up mock remote clients.
|
||||
let mockRemoteClients = [
|
||||
{ id: "0", name: "foo", type: "mobile" },
|
||||
{ id: "1", name: "bar", type: "desktop" },
|
||||
{ id: "2", name: "baz", type: "mobile" },
|
||||
];
|
||||
let originalGetter =
|
||||
Object.getOwnPropertyDescriptor(gSync, "remoteClients").get;
|
||||
Object.defineProperty(gSync, "remoteClients", {
|
||||
get() { return mockRemoteClients; }
|
||||
});
|
||||
let cleanUp = () => {
|
||||
Object.defineProperty(gSync, "remoteClients", {
|
||||
get: originalGetter
|
||||
});
|
||||
};
|
||||
registerCleanupFunction(cleanUp);
|
||||
|
||||
// Open the panel.
|
||||
await promisePanelOpen();
|
||||
let sendToDeviceButton =
|
||||
document.getElementById("page-action-send-to-device-button");
|
||||
Assert.ok(!sendToDeviceButton.disabled);
|
||||
|
||||
// Click Send to Device.
|
||||
let viewPromise = promiseViewShown();
|
||||
EventUtils.synthesizeMouseAtCenter(sendToDeviceButton, {});
|
||||
let view = await viewPromise;
|
||||
Assert.equal(view.id, "page-action-sendToDeviceView");
|
||||
|
||||
// The devices should be shown in the subview.
|
||||
let expectedItems = [
|
||||
{
|
||||
id: "page-action-sendToDevice-fxa-button",
|
||||
display: "none",
|
||||
},
|
||||
{
|
||||
id: "page-action-no-devices-button",
|
||||
display: "none",
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
for (let client of mockRemoteClients) {
|
||||
expectedItems.push({
|
||||
attrs: {
|
||||
clientId: client.id,
|
||||
label: client.name,
|
||||
clientType: client.type,
|
||||
},
|
||||
});
|
||||
}
|
||||
expectedItems.push(
|
||||
null,
|
||||
{
|
||||
label: "All Devices",
|
||||
}
|
||||
);
|
||||
checkSendToDeviceItems(expectedItems);
|
||||
|
||||
// Done, hide the panel.
|
||||
let hiddenPromise = promisePanelHidden();
|
||||
gPanel.hidePopup();
|
||||
await hiddenPromise;
|
||||
|
||||
cleanUp();
|
||||
await UIState.reset();
|
||||
});
|
||||
});
|
||||
|
||||
function promisePanelOpen() {
|
||||
let button = document.getElementById("urlbar-page-action-button");
|
||||
let shownPromise = promisePanelShown();
|
||||
EventUtils.synthesizeMouseAtCenter(button, {});
|
||||
return shownPromise;
|
||||
}
|
||||
|
||||
function promisePanelShown() {
|
||||
return promisePanelEvent("popupshown");
|
||||
}
|
||||
|
||||
function promisePanelHidden() {
|
||||
return promisePanelEvent("popuphidden");
|
||||
}
|
||||
|
||||
function promisePanelEvent(name) {
|
||||
return new Promise(resolve => {
|
||||
gPanel.addEventListener(name, () => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
});
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
function promiseViewShown() {
|
||||
return Promise.all([
|
||||
promiseViewShowing(),
|
||||
promiseTransitionEnd(),
|
||||
]).then(values => {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(values[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function promiseViewShowing() {
|
||||
return new Promise(resolve => {
|
||||
gPanel.addEventListener("ViewShowing", (event) => {
|
||||
resolve(event.target);
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
function promiseTransitionEnd() {
|
||||
return new Promise(resolve => {
|
||||
gPanel.addEventListener("transitionend", (event) => {
|
||||
resolve(event.target);
|
||||
}, { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
function promiseSyncReady() {
|
||||
let service = Cc["@mozilla.org/weave/service;1"]
|
||||
.getService(Components.interfaces.nsISupports)
|
||||
.wrappedJSObject;
|
||||
return service.whenLoaded().then(() => {
|
||||
UIState.isReady();
|
||||
return UIState.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
function checkSendToDeviceItems(expectedItems) {
|
||||
let body = document.getElementById("page-action-sendToDeviceView-body");
|
||||
Assert.equal(body.childNodes.length, expectedItems.length);
|
||||
for (let i = 0; i < expectedItems.length; i++) {
|
||||
let expected = expectedItems[i];
|
||||
let actual = body.childNodes[i];
|
||||
if (!expected) {
|
||||
Assert.equal(actual.localName, "toolbarseparator");
|
||||
continue;
|
||||
}
|
||||
if ("id" in expected) {
|
||||
Assert.equal(actual.id, expected.id);
|
||||
}
|
||||
let display = "display" in expected ? expected.display : "-moz-box";
|
||||
Assert.equal(getComputedStyle(actual).display, display);
|
||||
let disabled = "disabled" in expected ? expected.disabled : false;
|
||||
Assert.equal(actual.disabled, disabled);
|
||||
if ("attrs" in expected) {
|
||||
for (let name in expected.attrs) {
|
||||
Assert.ok(actual.hasAttribute(name));
|
||||
Assert.equal(actual.getAttribute(name), expected.attrs[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -948,3 +948,8 @@ you can use these alternative items. Otherwise, their values should be empty. -
|
||||
<!ENTITY updateRestart.panelUI.label2 "Restart to update &brandShorterName;">
|
||||
|
||||
<!ENTITY pageActionButton.tooltip "Page actions">
|
||||
|
||||
<!ENTITY sendToDevice.label "Send to Device…">
|
||||
<!ENTITY sendToDevice.viewTitle "Send to Device">
|
||||
<!ENTITY sendToDevice.fxaRequired.label "Required">
|
||||
<!ENTITY sendToDevice.noDevices.label "No Devices Available">
|
||||
|
@ -78,9 +78,9 @@
|
||||
-moz-appearance: none;
|
||||
border-style: none;
|
||||
list-style-image: url("chrome://browser/skin/page-action.svg");
|
||||
-moz-context-properties: fill;
|
||||
margin: 0;
|
||||
padding: 0 6px;
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
@ -90,12 +90,24 @@
|
||||
|
||||
#page-action-copy-url-button {
|
||||
list-style-image: url("chrome://browser/skin/copy-url.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
#page-action-email-link-button {
|
||||
list-style-image: url("chrome://browser/skin/email-link.svg");
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
#page-action-send-to-device-button {
|
||||
list-style-image: url("chrome://browser/skin/device-mobile.svg");
|
||||
}
|
||||
|
||||
.page-action-sendToDevice-device[clientType=mobile] {
|
||||
list-style-image: url("chrome://browser/skin/device-mobile.svg");
|
||||
}
|
||||
|
||||
.page-action-sendToDevice-device[clientType=desktop] {
|
||||
list-style-image: url("chrome://browser/skin/device-desktop.svg");
|
||||
}
|
||||
|
||||
#page-action-sendToDevice-fxa-button {
|
||||
list-style-image: url("chrome://browser/skin/sync.svg");
|
||||
}
|
||||
|
@ -1297,10 +1297,14 @@ photonpanelmultiview .PanelUI-subView .panel-subview-footer {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
photonpanelmultiview .subviewbutton {
|
||||
-moz-context-properties: fill;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
photonpanelmultiview .subviewbutton[checked="true"] {
|
||||
background: none;
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/check.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
photonpanelmultiview .subviewbutton > .menu-iconic-left {
|
||||
|
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
Before Width: | Height: | Size: 622 B After Width: | Height: | Size: 600 B |
6
browser/themes/shared/icons/device-desktop.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill="context-fill" d="M0 12h16a1.959 1.959 0 0 1-2 2H2a1.959 1.959 0 0 1-2-2zM13.107 2H2.894A1.894 1.894 0 0 0 1 3.894V11h14V3.893A1.893 1.893 0 0 0 13.107 2zM14 10H2V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 516 B |
6
browser/themes/shared/icons/device-mobile.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<!-- 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/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill="context-fill" d="M10 1H6a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm1 11.5a.5.5 0 0 1-.5.5h-5a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 491 B |
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
Before Width: | Height: | Size: 657 B After Width: | Height: | Size: 635 B |
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
Before Width: | Height: | Size: 439 B After Width: | Height: | Size: 417 B |
@ -203,6 +203,8 @@
|
||||
skin/classic/browser/page-action.svg (../shared/icons/page-action.svg)
|
||||
skin/classic/browser/copy-url.svg (../shared/icons/copy-url.svg)
|
||||
skin/classic/browser/email-link.svg (../shared/icons/email-link.svg)
|
||||
skin/classic/browser/device-mobile.svg (../shared/icons/device-mobile.svg)
|
||||
skin/classic/browser/device-desktop.svg (../shared/icons/device-desktop.svg)
|
||||
skin/classic/browser/menu-icons/back.svg (../shared/menu-icons/back.svg)
|
||||
skin/classic/browser/menu-icons/back-small.svg (../shared/menu-icons/back-small.svg)
|
||||
skin/classic/browser/menu-icons/addons.svg (../shared/menu-icons/addons.svg)
|
||||
|
@ -184,47 +184,38 @@ toolbarpaletteitem[place="palette"] > #zoom-controls > #zoom-in-button {
|
||||
|
||||
#appMenu-new-window-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/new-window.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-private-window-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/private-window.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-print-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/print.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-library-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/library.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-addons-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/addons.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-preferences-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/settings.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-customize-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/customize.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-find-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/find.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-help-button {
|
||||
list-style-image: url(chrome://browser/skin/menu-icons/help.svg);
|
||||
-moz-context-properties: fill;
|
||||
}
|
||||
|
||||
#appMenu-cut-button {
|
||||
|