update readme
[dotfiles/.git] / .config / BraveSoftware / Brave-Browser / Default / Extensions / cimiefiiaegbelhefglklhhakcgmhkai / 1.7.6_0 / extension.js
1 /*
2     Copyright (C) 2017 Kai Uwe Broulik <kde@privat.broulik.de>
3
4     This program is free software; you can redistribute it and/or
5     modify it under the terms of the GNU General Public License as
6     published by the Free Software Foundation; either version 3 of
7     the License, or (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
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/>.
16  */
17
18 function sendEnvironment() {
19     var browser = "";
20
21     var ua = navigator.userAgent;
22     // Try to match the most derived first
23     if (ua.match(/vivaldi/i)) {
24         browser = "vivaldi";
25     } else if(ua.match(/OPR/i)) {
26         browser = "opera";
27     } else if(ua.match(/chrome/i)) {
28         browser = "chromium";
29         // Apparently there is no better way to distinuish chromium from chrome
30         for (i in window.navigator.plugins) {
31             if (window.navigator.plugins[i].name === "Chrome PDF Viewer") {
32                 browser = "chrome";
33                 break;
34             }
35         }
36     } else if(ua.match(/firefox/i)) {
37         browser = "firefox";
38     }
39
40     sendPortMessage("settings", "setEnvironment", {browserName: browser});
41 }
42
43 function sendSettings() {
44     SettingsUtils.get().then((items) => {
45         sendPortMessage("settings", "changed", items);
46     });
47 }
48
49 // activates giveb tab and raises its window, used by tabs runner and mpris Raise command
50 function raiseTab(tabId) {
51 // first activate the tab, this means it's current in its window
52     chrome.tabs.update(tabId, {active: true}, function (tab) {
53
54         if (chrome.runtime.lastError || !tab) { // this "lastError" stuff feels so archaic
55             // failed to update
56             return;
57         }
58
59         // then raise the tab's window too
60         chrome.windows.update(tab.windowId, {focused: true});
61     });
62 }
63
64 // Debug
65 // ------------------------------------------------------------------------
66 //
67 addCallback("debug", "debug", function(payload) {
68     console.log("From host:", payload.message);
69 }
70 )
71
72 addCallback("debug", "warning", function(payload) {
73     console.warn("From host:", payload.message);
74 }
75 )
76
77 // System
78 // ------------------------------------------------------------------------
79 //
80
81 // When connecting to native host fails (e.g. not installed), we immediately get a disconnect
82 // event immediately afterwards. Also avoid infinite restart loop then.
83 var receivedMessageOnce = false;
84
85 var portStatus = "";
86 var portLastErrorMessage = undefined;
87
88 function updateBrowserAction() {
89     if (portStatus === "UNSUPPORTED_OS" || portStatus === "STARTUP_FAILED") {
90         chrome.browserAction.setIcon({
91             path: {
92                 "16": "icons/plasma-disabled-16.png",
93                 "32": "icons/plasma-disabled-32.png",
94                 "48": "icons/plasma-disabled-48.png",
95                 "128": "icons/plasma-disabled-128.png"
96             }
97         });
98     }
99
100     if (portLastErrorMessage && receivedMessageOnce) {
101         chrome.browserAction.setBadgeText({ text: "!" });
102         chrome.browserAction.setBadgeBackgroundColor({ color: "#da4453" }); // breeze "negative" color
103     } else {
104         chrome.browserAction.setBadgeText({ text: "" });
105     }
106 }
107 updateBrowserAction();
108
109 // Check for supported platform to avoid loading it on e.g. Windows and then failing
110 // when the extension got synced to another device and then failing
111 chrome.runtime.getPlatformInfo(function (info) {
112     if (!SUPPORTED_PLATFORMS.includes(info.os)) {
113         console.log("This extension is not supported on", info.os);
114         portStatus = "UNSUPPORTED_OS";
115         updateBrowserAction();
116         return;
117     }
118
119     connectHost();
120 });
121
122 function connectHost() {
123     port = chrome.runtime.connectNative("org.kde.plasma.browser_integration");
124
125     port.onMessage.addListener(function (message) {
126         var subsystem = message.subsystem;
127         var action = message.action;
128
129         let isReply = message.hasOwnProperty("replyToSerial");
130         let replyToSerial = message.replyToSerial;
131
132         if (!isReply && (!subsystem || !action)) {
133             return;
134         }
135
136         if (portStatus) {
137             portStatus = "";
138             updateBrowserAction();
139         }
140
141         receivedMessageOnce = true;
142
143         if (isReply) {
144             let replyResolver = pendingMessageReplyResolvers[replyToSerial];
145             if (replyResolver) {
146                 replyResolver(message.payload);
147                 delete pendingMessageReplyResolvers[replyToSerial];
148             } else {
149                 console.warn("There is no reply resolver for message with serial", replyToSerial);
150             }
151             return;
152         }
153
154         if (callbacks[subsystem] && callbacks[subsystem][action]) {
155             callbacks[subsystem][action](message.payload, action);
156         } else {
157             console.warn("Don't know what to do with host message", subsystem, action);
158         }
159     });
160
161     port.onDisconnect.addListener(function(port) {
162         var error = chrome.runtime.lastError;
163         // Firefox passes in the port which may then have an error set
164         if (port && port.error) {
165             error = port.error;
166         }
167
168         console.warn("Host disconnected", error && error.message);
169
170         // Remove all kde connect menu entries since they won't work without a host
171         try {
172             Object.keys(kdeConnectDevices).forEach((deviceId) => {
173                 callbacks.kdeconnect.deviceRemoved({
174                     id: deviceId
175                 });
176             });
177         } catch (e) {
178             console.warn("Failed to cleanup after port disconnect", e);
179         }
180
181         portLastErrorMessage = error && error.message || "UNKNOWN";
182         if (receivedMessageOnce) {
183             portStatus = "DISCONNECTED";
184
185             console.log("Auto-restarting it");
186             connectHost();
187         } else {
188             portStatus = "STARTUP_FAILED";
189
190             console.warn("Not auto-restarting host as we haven't received any message from it before. Check that it's working/installed correctly");
191         }
192         updateBrowserAction();
193     });
194
195     sendEnvironment();
196     sendSettings();
197     sendDownloads();
198
199     updatePurposeMenu();
200 }
201
202 SettingsUtils.onChanged().addListener(() => {
203     sendSettings();
204 });
205
206 addRuntimeCallback("settings", "openKRunnerSettings", function () {
207     sendPortMessage("settings", "openKRunnerSettings");
208 });
209
210 addRuntimeCallback("settings", "getSubsystemStatus", (message, sender, action) => {
211     return sendPortMessageWithReply("settings", "getSubsystemStatus");
212 });
213
214 addRuntimeCallback("settings", "getVersion", () => {
215     return sendPortMessageWithReply("settings", "getVersion");
216 });
217
218 addRuntimeCallback("browserAction", "getStatus", (message) => {
219     let info = {
220         portStatus,
221         portLastErrorMessage
222     };
223
224     return Promise.resolve(info);
225 });
226
227 addRuntimeCallback("browserAction", "ready", () => {
228
229     // HACK there's no way to tell whether the browser action popup got closed
230     // None of onunload, onbeforeunload, onvisibilitychanged are fired.
231     // Instead, we create a port once the browser action is ready and then
232     // listen for the port being disconnected.
233
234     let browserActionPort = chrome.runtime.connect({
235         name: "browserActionPort"
236     });
237     browserActionPort.onDisconnect.addListener((port) => {
238         if (port.name !== "browserActionPort") {
239             return;
240         }
241
242         // disabling the browser action immediately when opening it
243         // causes opening to fail on Firefox, so clear the error only when it's being closed.
244         // Only clear error when it was a transient error, not a startup failure
245         if (receivedMessageOnce) {
246             portLastErrorMessage = "";
247             updateBrowserAction();
248         }
249     });
250 });