Changeset View
Changeset View
Standalone View
Standalone View
extension/extension-purpose.js
Show All 9 Lines | 1 | /* | |||
---|---|---|---|---|---|
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | 12 | GNU General Public License for more details. | ||
13 | 13 | | |||
14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | 16 | */ | ||
17 | 17 | | |||
18 | let purposeShareMenuId = "purpose_share"; | 18 | const purposeShareMenuId = "purpose_share"; | ||
19 | let hasPurposeMenu = false; | ||||
19 | 20 | | |||
20 | // Stores <notification id, share url> so that when you click the finished | 21 | // Stores <notification id, share url> so that when you click the finished | ||
21 | // notification it will open the URL | 22 | // notification it will open the URL | ||
22 | let purposeNotificationUrls = {}; | 23 | let purposeNotificationUrls = {}; | ||
23 | 24 | | |||
24 | function purposeShare(data) { | 25 | function purposeShare(data) { | ||
25 | return new Promise((resolve, reject) => { | 26 | return new Promise((resolve, reject) => { | ||
26 | sendPortMessageWithReply("purpose", "share", {data}).then((reply) => { | 27 | sendPortMessageWithReply("purpose", "share", {data}).then((reply) => { | ||
Show All 29 Lines | 45 | if (url) { | |||
56 | }); | 57 | }); | ||
57 | } | 58 | } | ||
58 | 59 | | |||
59 | resolve(); | 60 | resolve(); | ||
60 | }); | 61 | }); | ||
61 | }); | 62 | }); | ||
62 | } | 63 | } | ||
63 | 64 | | |||
65 | function checkPurposeEnabled() { | ||||
66 | return Promise.all([ | ||||
67 | sendPortMessageWithReply("settings", "getSubsystemStatus"), | ||||
68 | SettingsUtils.get() | ||||
69 | ]).then((result) => { | ||||
70 | | ||||
71 | const subsystemStatus = result[0]; | ||||
72 | const settings = result[1]; | ||||
73 | | ||||
74 | // HACK Unfortunately I removed the loaded/unloaded signals for plugins | ||||
75 | // so we can't reliably know on settings change whether a module is enabled | ||||
76 | // sending settings is also legacy done without a reply we could wait for. | ||||
77 | // Instead, check whether the module is known and enabled in settings, | ||||
78 | // which should be close enough, since purpose plugin also has no additional | ||||
79 | // dependencies that could make it fail to load. | ||||
80 | return subsystemStatus.hasOwnProperty("purpose") | ||||
81 | && settings.purpose && settings.purpose.enabled; | ||||
82 | }); | ||||
83 | } | ||||
84 | | ||||
85 | function updatePurposeMenu() { | ||||
86 | checkPurposeEnabled().then((enabled) => { | ||||
87 | if (enabled && !hasPurposeMenu) { | ||||
88 | chrome.contextMenus.create({ | ||||
89 | id: purposeShareMenuId, | ||||
90 | contexts: ["link", "page", "image", "audio", "video", "selection"], | ||||
91 | title: chrome.i18n.getMessage("purpose_share") | ||||
92 | }, () => { | ||||
93 | const error = chrome.runtime.lastError; | ||||
94 | if (error) { | ||||
95 | console.warn("Error creating purpose context menu", error.message); | ||||
96 | return; | ||||
97 | } | ||||
98 | hasPurposeMenu = true; | ||||
99 | }); | ||||
100 | } else if (!enabled && hasPurposeMenu) { | ||||
101 | chrome.contextMenus.remove(purposeShareMenuId, () => { | ||||
102 | const error = chrome.runtime.lastError; | ||||
103 | if (error) { | ||||
104 | console.warn("Error removing purpose context menu", error.message); | ||||
105 | return; | ||||
106 | } | ||||
107 | hasPurposeMenu = false; | ||||
108 | }); | ||||
109 | } | ||||
110 | }); | ||||
111 | } | ||||
112 | | ||||
64 | chrome.contextMenus.onClicked.addListener((info) => { | 113 | chrome.contextMenus.onClicked.addListener((info) => { | ||
65 | if (info.menuItemId !== purposeShareMenuId) { | 114 | if (info.menuItemId !== purposeShareMenuId) { | ||
66 | return; | 115 | return; | ||
67 | } | 116 | } | ||
68 | 117 | | |||
69 | let url = info.linkUrl || info.srcUrl || info.pageUrl; | 118 | let url = info.linkUrl || info.srcUrl || info.pageUrl; | ||
70 | let selection = info.selectionText; | 119 | let selection = info.selectionText; | ||
71 | if (!url && !selection) { | 120 | if (!url && !selection) { | ||
Show All 30 Lines | 150 | }).then((title) => { | |||
102 | if (title) { | 151 | if (title) { | ||
103 | shareData.title = title; | 152 | shareData.title = title; | ||
104 | } | 153 | } | ||
105 | 154 | | |||
106 | purposeShare(shareData); | 155 | purposeShare(shareData); | ||
107 | }); | 156 | }); | ||
108 | }); | 157 | }); | ||
109 | 158 | | |||
110 | // FIXME only add context menu if purpose is enabled and supported | 159 | SettingsUtils.onChanged().addListener((delta) => { | ||
111 | /*chrome.contextMenus.create({ | 160 | if (delta.purpose) { | ||
112 | id: purposeShareMenuId, | 161 | updatePurposeMenu(); | ||
113 | contexts: ["link", "page", "image", "audio", "video", "selection"], | 162 | } | ||
114 | title: chrome.i18n.getMessage("purpose_share") | 163 | }); | ||
115 | });*/ | | |||
116 | 164 | | |||
117 | addRuntimeCallback("purpose", "share", (message, sender, action) => { | 165 | addRuntimeCallback("purpose", "share", (message, sender, action) => { | ||
118 | return purposeShare(message); | 166 | return purposeShare(message); | ||
119 | }); | 167 | }); | ||
120 | 168 | | |||
121 | chrome.notifications.onClicked.addListener((notificationId) => { | 169 | chrome.notifications.onClicked.addListener((notificationId) => { | ||
122 | const url = purposeNotificationUrls[notificationId]; | 170 | const url = purposeNotificationUrls[notificationId]; | ||
123 | if (url) { | 171 | if (url) { | ||
124 | chrome.tabs.create({url}); | 172 | chrome.tabs.create({url}); | ||
125 | } | 173 | } | ||
126 | }); | 174 | }); | ||
127 | 175 | | |||
128 | chrome.notifications.onClosed.addListener((notificationId) => { | 176 | chrome.notifications.onClosed.addListener((notificationId) => { | ||
129 | delete purposeNotificationUrls[notificationId]; | 177 | delete purposeNotificationUrls[notificationId]; | ||
130 | }); | 178 | }); |