annotate background.js @ 23:4704e5216412

Create menus on-the-fly Refactor and eliminate the window tracking code by using the onShown/onHidden events available in Firefox 60 in order to create menu entries on-the-fly. Switch from the Firefox-specific contextMenu to the menu API.
author Guido Berhoerster <guido+tab-mover@berhoerster.name>
date Sun, 25 Nov 2018 13:27:47 +0100
parents 6b4680867e49
children f418a6305f17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
1 /*
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
2 * Copyright (C) 2018 Guido Berhoerster <guido+tab-mover@berhoerster.name>
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
3 *
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
4 * This Source Code Form is subject to the terms of the Mozilla Public
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
7 */
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
8
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
9 'use strict';
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
10
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
11 const ALLOWED_PROTOCOLS = new Set(['http:', 'https:', 'ftp:']);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
12 var windowMenuIds = [];
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
13 var lastMenuInstanceId = 0;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
14 var nextMenuInstanceId = 1;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
15
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
16 function createMenuItem(createProperties) {
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
17 return new Promise((resolve, reject) => {
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
18 let id = browser.menus.create(createProperties, () => {
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
19 if (browser.runtime.lastError) {
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
20 reject(browser.runtime.lastError);
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
21 } else {
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
22 resolve(id);
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
23 }
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
24 });
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
25 });
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
26 }
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
27
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
28 async function moveTab(tab, targetWindowId) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
29 browser.tabs.move(tab.id, {windowId: targetWindowId, index: -1});
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
30 }
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
31
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
32 async function reopenTab(tab, targetWindowId) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
33 if (!ALLOWED_PROTOCOLS.has(new URL(tab.url).protocol)) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
34 // privileged tab URL which cannot be reopened
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
35 return;
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
36 }
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
37 await browser.tabs.create({
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
38 url: tab.url,
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
39 windowId: targetWindowId
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
40 });
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
41 browser.tabs.remove(tab.id);
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
42 }
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
43
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
44 async function onMenuShown(info, tab) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
45 let menuInstanceId = nextMenuInstanceId++;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
46 lastMenuInstanceId = menuInstanceId;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
47 let targetWindows = await browser.windows.getAll({
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
48 populate: true,
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
49 windowTypes: ['normal']
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
50 });
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
51 let creatingMenus = [];
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
52 let moveMenuItems = 0;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
53 let reopenMenuItems = 0;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
54 for (let targetWindow of targetWindows) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
55 if (targetWindow.id === tab.windowId) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
56 // ignore active window
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
57 continue;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
58 }
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
59 if (tab.incognito === targetWindow.incognito) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
60 creatingMenus.push(createMenuItem({
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
61 onclick: (info, tab) => moveTab(tab, targetWindow.id),
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
62 parentId: 'move-menu',
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
63 title: targetWindow.title
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
64 }));
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
65 moveMenuItems++;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
66 } else {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
67 creatingMenus.push(createMenuItem({
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
68 onclick: (info, tab) => reopenTab(tab, targetWindow.id),
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
69 parentId: 'reopen-menu',
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
70 title: targetWindow.title
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
71 }));
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
72 reopenMenuItems++;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
73 }
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
74 }
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
75 let updatingMenus = [
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
76 browser.menus.update('move-menu', {enabled: moveMenuItems > 0}),
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
77 browser.menus.update('reopen-menu', {enabled: reopenMenuItems > 0})
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
78 ];
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
79 await Promise.all([...creatingMenus, ...updatingMenus]);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
80 let newWindowMenuIds = await Promise.all(creatingMenus);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
81 if (menuInstanceId !== lastMenuInstanceId) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
82 // menu has been closed and opened again, remove the items of this
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
83 // instance again
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
84 for (let menuId of newWindowMenuIds) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
85 browser.menus.remove(menuId);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
86 }
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
87 return;
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
88 }
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
89 windowMenuIds = newWindowMenuIds;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
90 browser.menus.refresh();
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
91 }
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
92
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
93 async function onMenuHidden() {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
94 lastMenuInstanceId = 0;
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
95 browser.menus.update('move-menu', {enabled: false});
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
96 browser.menus.update('reopen-menu', {enabled: false});
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
97 for (let menuId of windowMenuIds) {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
98 browser.menus.remove(menuId);
0
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
99 }
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
100 }
480f8e4f4500 Initial revision
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents:
diff changeset
101
23
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
102 (async () => {
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
103 await Promise.all([
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
104 // create submenus
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
105 createMenuItem({
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
106 id: 'move-menu',
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
107 title: browser.i18n.getMessage('moveToWindowMenu'),
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
108 enabled: false,
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
109 contexts: ['tab']
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
110 }),
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
111 createMenuItem({
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
112 id: 'reopen-menu',
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
113 title: browser.i18n.getMessage('reopenInWindowMenu'),
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
114 enabled: false,
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
115 contexts: ['tab']
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
116 })
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
117 ]);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
118 browser.menus.onShown.addListener(onMenuShown);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
119 browser.menus.onHidden.addListener(onMenuHidden);
4704e5216412 Create menus on-the-fly
Guido Berhoerster <guido+tab-mover@berhoerster.name>
parents: 17
diff changeset
120 })();