Fix logger popup initialization.

This commit is contained in:
Tamius Han 2020-03-09 21:29:39 +01:00
parent 2a1419eb53
commit cf1cc3d87a
3 changed files with 79 additions and 15 deletions

View File

@ -9,14 +9,12 @@ class CommsServer {
this.ports = []; this.ports = [];
this.popupPort = null; this.popupPort = null;
var ths = this;
if (BrowserDetect.firefox) { if (BrowserDetect.firefox) {
browser.runtime.onConnect.addListener(p => this.onConnect(p)); browser.runtime.onConnect.addListener(p => this.onConnect(p));
browser.runtime.onMessage.addListener((m, sender) => ths.processReceivedMessage_nonpersistent(m, sender)); browser.runtime.onMessage.addListener((m, sender) => this.processReceivedMessage_nonpersistent(m, sender));
} else { } else {
chrome.runtime.onConnect.addListener(p => ths.onConnect(p)); chrome.runtime.onConnect.addListener(p => ths.onConnect(p));
chrome.runtime.onMessage.addListener((m, sender, callback) => ths.processReceivedMessage_nonpersistent(m, sender, callback)); chrome.runtime.onMessage.addListener((m, sender, callback) => this.processReceivedMessage_nonpersistent(m, sender, callback));
} }
// commands — functions that handle incoming messages // commands — functions that handle incoming messages
@ -230,7 +228,6 @@ class CommsServer {
for (const frame in this.ports[tabs[0].id]) { for (const frame in this.ports[tabs[0].id]) {
this.sendToContentScripts(message, tabs[0].id, frame); this.sendToContentScripts(message, tabs[0].id, frame);
this.ports[tabs[0].id][frame].postMessage(message);
} }
} }
@ -238,7 +235,7 @@ class CommsServer {
// poseben primer | special case // poseben primer | special case
if (port.name === 'popup-port') { if (port.name === 'popup-port') {
this.popupPort = port; this.popupPort = port;
this.popupPort.onMessage.addListener( (m,p) => ths.processReceivedMessage(m,p)); this.popupPort.onMessage.addListener( (m,p) => this.processReceivedMessage(m,p));
return; return;
} }
@ -251,10 +248,14 @@ class CommsServer {
this.ports[tabId][frameId] = {}; this.ports[tabId][frameId] = {};
} }
this.ports[tabId][frameId][port.name] = port; this.ports[tabId][frameId][port.name] = port;
this.ports[tabId][frameId][port.name].onMessage.addListener( (m,p) => ths.processReceivedMessage(m, p)); this.ports[tabId][frameId][port.name].onMessage.addListener( (m,p) => this.processReceivedMessage(m, p));
this.ports[tabId][frameId][port.name].onDisconnect.addListener( (p) => { this.ports[tabId][frameId][port.name].onDisconnect.addListener( (p) => {
delete this.ports[p.sender.tab.id][p.sender.frameId][port.name]; try {
delete this.ports[p.sender.tab.id][p.sender.frameId][port.name];
} catch (e) {
// no biggie if the thing above doesn't exist.
}
if (Object.keys(this.ports[tabId][frameId].length === 0)) { if (Object.keys(this.ports[tabId][frameId].length === 0)) {
delete this.ports[tabId][frameId]; delete this.ports[tabId][frameId];
if(Object.keys(this.ports[p.sender.tab.id]).length === 0) { if(Object.keys(this.ports[p.sender.tab.id]).length === 0) {
@ -273,7 +274,11 @@ class CommsServer {
); );
if (this.commands[message.cmd]) { if (this.commands[message.cmd]) {
for (const c of this.commands[message.cmd]) { for (const c of this.commands[message.cmd]) {
await c(message, portOrSender, sendResponse); try {
await c(message, portOrSender, sendResponse);
} catch (e) {
this.logger.log('error', 'debug', "[CommsServer.js::execCmd] failed to execute command.", e)
}
} }
} }
} }

View File

@ -4,7 +4,15 @@ import CommsServer from './lib/comms/CommsServer';
import Settings from './lib/Settings'; import Settings from './lib/Settings';
import Logger from './lib/Logger'; import Logger from './lib/Logger';
import sleep from '../common/js/utils'; import { sleep } from '../common/js/utils';
// we need vue in bg script, so we can get vuex.
// and we need vuex so popup will be initialized
// after the first click without resorting to ugly,
// dirty hacks
import Vue from 'vue';
import Vuex from 'vuex';
import VuexWebExtensions from 'vuex-webextensions';
var BgVars = { var BgVars = {
arIsActive: true, arIsActive: true,
@ -29,6 +37,8 @@ class UWServer {
'siteSettings': undefined, 'siteSettings': undefined,
'videoSettings': undefined, 'videoSettings': undefined,
} }
this.uiLoggerInitialized = false;
} }
async setup() { async setup() {
@ -51,8 +61,9 @@ class UWServer {
this.settings = new Settings({logger: this.logger}); this.settings = new Settings({logger: this.logger});
await this.settings.init(); await this.settings.init();
this.comms = new CommsServer(this); this.comms = new CommsServer(this);
this.comms.subscribe('show-logger', async () => await this.initUi()); this.comms.subscribe('show-logger', async () => await this.initUiAndShowLogger());
this.comms.subscribe('init-vue', async () => await this.initUi()); this.comms.subscribe('init-vue', async () => await this.initUi());
this.comms.subscribe('uwui-vue-initialized', () => this.uiLoggerInitialized = true);
var ths = this; var ths = this;
@ -103,6 +114,10 @@ class UWServer {
extractHostname(url){ extractHostname(url){
var hostname; var hostname;
if (!url) {
return "<no url>";
}
// extract hostname // extract hostname
if (url.indexOf("://") > -1) { //find & remove protocol (http, ftp, etc.) and get hostname if (url.indexOf("://") > -1) { //find & remove protocol (http, ftp, etc.) and get hostname
hostname = url.split('/')[2]; hostname = url.split('/')[2];
@ -218,11 +233,41 @@ class UWServer {
}, () => resolve()) }, () => resolve())
); );
} }
} catch (e) { } catch (e) {
this.logger.log('ERROR', 'uwbg', 'UI initialization failed. Reason:', e); this.logger.log('ERROR', 'uwbg', 'UI initialization failed. Reason:', e);
} }
} }
async initUiAndShowLogger() {
// this implementation is less than optimal and very hacky, but it should work
// just fine for our use case.
this.uiLoggerInitialized = false;
await this.initUi();
await new Promise( async (resolve, reject) => {
// if content script doesn't give us a response within 5 seconds, something is
// obviously wrong and we stop waiting,
// oh and btw, resolve/reject do not break the loops, so we need to do that
// ourselves:
// https://stackoverflow.com/questions/55207256/will-resolve-in-promise-loop-break-loop-iteration
let isRejected = false;
setTimeout( async () => {isRejected = true; reject()}, 5000);
// check whether UI has been initiated on the FE. If it was, we resolve the
// promise and off we go
while (!isRejected) {
if (this.uiLoggerInitialized) {
resolve();
return; // remember the bit about resolve() not breaking the loop?
}
await sleep(100);
}
})
}
async getCurrentTab() { async getCurrentTab() {
if (BrowserDetect.firefox) { if (BrowserDetect.firefox) {
return (await browser.tabs.query({active: true, currentWindow: true}))[0]; return (await browser.tabs.query({active: true, currentWindow: true}))[0];

View File

@ -8,6 +8,7 @@ import LoggerUi from '../csui/LoggerUi';
import Logger from './lib/Logger'; import Logger from './lib/Logger';
import Settings from './lib/Settings'; import Settings from './lib/Settings';
import CommsClient from './lib/comms/CommsClient'; import CommsClient from './lib/comms/CommsClient';
import Comms from './lib/comms/Comms';
class UwUi { class UwUi {
@ -31,8 +32,8 @@ class UwUi {
// * if video/player is detected (which can only happen if extension is enabled // * if video/player is detected (which can only happen if extension is enabled
// for that particular site) // for that particular site)
// initialize vuejs, but only once (check handled in initVue()) // NOTE: we need to setup logger and comms _before_ initializing vue (unless we're starting)
this.initVue(); // because logger settings say we should
// setup logger // setup logger
try { try {
@ -74,7 +75,7 @@ class UwUi {
if (this.logger.isLoggingAllowed()) { if (this.logger.isLoggingAllowed()) {
console.info("[uw::init] Logging is allowed! Initalizing vue and UI!"); console.info("[uw::init] Logging is allowed! Initalizing vue and UI!");
this.initVue(); this.initVue();
this.initUi(); this.initLoggerUi();
this.logger.setVuexStore(this.vuexStore); this.logger.setVuexStore(this.vuexStore);
} }
@ -107,11 +108,17 @@ class UwUi {
} }
this.comms = new CommsClient('content-ui-port', this.logger, this.commsHandlers); this.comms = new CommsClient('content-ui-port', this.logger, this.commsHandlers);
// initialize vuejs, but only once (check handled in initVue())
// we need to initialize this _after_ initializing comms.
this.initVue();
} }
initVue() { initVue() {
// never init twice // never init twice
if (this.vueInitiated) { if (this.vueInitiated) {
// let background script know it can proceed with sending 'show-logger' command.
Comms.sendMessage({cmd: 'uwui-vue-initialized'});
return; return;
} }
@ -154,6 +161,9 @@ class UwUi {
// make sure we don't init twice // make sure we don't init twice
this.vueInitiated = true; this.vueInitiated = true;
// let background script know it can proceed with sending 'show-logger' command.
Comms.sendMessage({cmd: 'uwui-vue-initialized'});
} }
async initLoggerUi() { async initLoggerUi() {
@ -188,6 +198,7 @@ class UwUi {
if (!this.loggerUiInitiated) { if (!this.loggerUiInitiated) {
await this.initLoggerUi(); await this.initLoggerUi();
} }
try { try {
this.vuexStore.dispatch('uw-show-logger'); this.vuexStore.dispatch('uw-show-logger');
@ -215,5 +226,8 @@ if (! document.getElementById(markerId)) {
const uwui = new UwUi(); const uwui = new UwUi();
uwui.init(); uwui.init();
} else {
// let background script know it can proceed with sending 'show-logger' command.
Comms.sendMessage({cmd: 'uwui-vue-initialized'});
} }