fix forwarding data between server, content script, and popup

This commit is contained in:
Tamius Han 2022-09-20 01:34:59 +02:00
parent a0388689cf
commit 740f2e8f6f
6 changed files with 130 additions and 50 deletions

View File

@ -84,6 +84,7 @@ export default class UWServer {
this.settings = new Settings({logger: this.logger});
await this.settings.init();
this.eventBus = new EventBus();
for (const action in this.eventBusCommands) {
@ -93,6 +94,7 @@ export default class UWServer {
}
this.comms = new CommsServer(this);
this.eventBus.setComms(this.comms);
browser.tabs.onActivated.addListener((m) => {this.onTabSwitched(m)});
} catch (e) {

View File

@ -1,4 +1,4 @@
import CommsClient from './comms/CommsClient';
import CommsClient, { CommsOrigin } from './comms/CommsClient';
import CommsServer from './comms/CommsServer';
export interface EventBusCommand {
@ -10,7 +10,7 @@ export interface EventBusContext {
stopPropagation?: boolean,
// Context stuff added by Comms
fromComms?: boolean,
origin?: CommsOrigin,
comms?: {
sender?: any,
port?: any,
@ -86,8 +86,10 @@ export default class EventBus {
}
}
if (this.comms && !context?.fromComms) {
this.comms.sendMessage({command, config}, context);
// preventing messages from flowing back to their original senders is
// CommsServer's job. EventBus does not have enough data for this decision.
if (this.comms) {
this.comms.sendMessage({command, config, context}, context);
}
if (context?.stopPropagation) {

View File

@ -3,7 +3,7 @@ import BrowserDetect from '../../conf/BrowserDetect';
import Logger from '../Logger';
import { browser } from 'webextension-polyfill-ts';
import Settings from '../Settings';
import EventBus from '../EventBus';
import EventBus, { EventBusContext } from '../EventBus';
if (process.env.CHANNEL !== 'stable'){
console.info("Loading CommsClient");
@ -50,7 +50,7 @@ if (process.env.CHANNEL !== 'stable'){
* | (Connect to popup) X POPUP EVENT BUS
* | A (accessible within popup) /todo
* x eventBus.sendToTunnel() | |
* <iframe tunnel> \----------------> ??? X
* <iframe tunnel> \--------> CommsClient X
* A |
* | X App.vue
* V
@ -63,9 +63,15 @@ if (process.env.CHANNEL !== 'stable'){
* (accessible within player UI)
*/
export enum CommsOrigin {
ContentScript = 1,
Popup = 2,
Server = 3
}
class CommsClient {
commsId: string;
origin: CommsOrigin;
logger: Logger;
settings: any; // sus?
@ -81,6 +87,12 @@ class CommsClient {
this.logger = logger;
this.eventBus = eventBus;
if (name === 'popup-port') {
this.origin = CommsOrigin.Popup;
} else {
this.origin = CommsOrigin.ContentScript;
}
this.port = browser.runtime.connect(null, {name: name});
this.logger.onLogEnd(
@ -111,13 +123,18 @@ class CommsClient {
}
//#endregion
async sendMessage(message, context?){
async sendMessage(message, context?: EventBusContext){
message = JSON.parse(JSON.stringify(message)); // vue quirk. We should really use vue store instead
// content script client and popup client differ in this one thing
if (this.origin === CommsOrigin.Popup) {
return this.port.postMessage(message, context);
}
return browser.runtime.sendMessage(null, message, null);
}
processReceivedMessage(message){
this.eventBus.send(message.command, message.config, {fromComms: true});
this.eventBus.send(message.command, message.config, {origin: CommsOrigin.Server});
}
}

View File

@ -5,6 +5,7 @@ import Settings from '../Settings';
import { browser } from 'webextension-polyfill-ts';
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
import EventBus from '../EventBus';
import { CommsOrigin } from './CommsClient';
class CommsServer {
@ -76,17 +77,29 @@ class CommsServer {
//#endregion
sendMessage(message, context?) {
if (context?.comms.forwardTo === 'all') {
return this.sendToAll(message);
// stop messages from returning where they came from, and prevent
// cross-pollination between content scripts running in different
// tabs.
console.log('sendmessage of comms server. Received message:', message, 'and context:', context);
if (context?.origin !== CommsOrigin.ContentScript) {
console.log('origin is NOT content script. This means forwarding to content scripts is okay!');
if (context?.comms.forwardTo === 'all') {
return this.sendToAll(message);
}
if (context?.comms.forwardTo === 'active') {
console.log('forwarding message to active tab:', message);
return this.sendToActive(message);
}
if (context?.comms.forwardTo === 'contentScript') {
return this.sendToFrame(message, context.tab, context.frame, context.port);
}
}
if (context?.comms.forwardTo === 'active') {
return this.sendToActive(message);
}
if (context?.comms.forwardTo === 'contentScript') {
return this.sendToFrame(message, context.tab, context.frame, context.port);
}
if (context?.comms.forwardTo === 'popup') {
return this.sendToPopup(message);
if (context?.origin !== CommsOrigin.Popup) {
if (context?.comms.forwardTo === 'popup') {
return this.sendToPopup(message);
}
}
}
@ -169,7 +182,7 @@ class CommsServer {
}
private async processReceivedMessage(message, port){
this.logger.log('info', 'comms', "[CommsServer.js::processReceivedMessage] Received message from popup/content script!", message, "port", port);
console.log('processing received message!', {message, portName: port.name, port})
// this triggers events
this.eventBus.send(
@ -177,8 +190,14 @@ class CommsServer {
message.config,
{
...message.context,
comms: {port},
fromComms: true
comms: {
...message.context?.comms,
port
},
// origin is required to stop cross-pollination between content scripts, while still
// preserving the ability to send messages directly between popup and content scripts
origin: port.name === 'popup-port' ? CommsOrigin.Popup : CommsOrigin.ContentScript
}
);
}
@ -186,7 +205,17 @@ class CommsServer {
private processReceivedMessage_nonpersistent(message, sender){
this.logger.log('info', 'comms', "%c[CommsServer.js::processMessage_nonpersistent] Received message from background script!", "background-color: #11D; color: #aad", message, sender);
this.eventBus.send(message.command, message.config, {comms: {sender}, fromComms: true});
this.eventBus.send(
message.command,
message.config, {
...message.context,
comms: {
...message.context?.comms,
sender
},
origin: CommsOrigin.Server
}
);
}
}

View File

@ -10,55 +10,52 @@
-->
<div v-if="settingsInitialized"
class="popup flex flex-column no-overflow"
:class="{'popup-chrome': ! BrowserDetect.firefox}"
:class="{'popup-chrome': ! BrowserDetect?.firefox}"
>
<div class="flex-row flex-nogrow flex-noshrink relative"
:class="{'header': !narrowPopup, 'header-small': narrowPopup}"
>
<span class="smallcaps">Ultrawidify</span>: <small>Quick settings</small>
<div class="absolute channel-info" v-if="BrowserDetect.processEnvChannel !== 'stable'">
Build channel: {{BrowserDetect.processEnvChannel}}
<div class="absolute channel-info" v-if="BrowserDetect?.processEnvChannel !== 'stable'">
Build channel: {{BrowserDetect?.processEnvChannel}}
</div>
</div>
<div class="flex flex-row body no-overflow flex-grow">
<pre>
---- site:
{{site}}
----
</pre>
</div>
</div>
<pre>
---- site:
{{site}}
----
</pre>
</template>
<script>
import WhatsNewPanel from './panels/WhatsNewPanel.vue';
import SiteDetailsPanel from './panels/SiteDetailsPanel.vue';
import Donate from '../common/misc/Donate.vue';
import Debug from '../ext/conf/Debug';
import BrowserDetect from '../ext/conf/BrowserDetect';
import Comms from '../ext/lib/comms/Comms';
import VideoPanel from './panels/VideoPanel';
import PerformancePanel from './panels/PerformancePanel';
import CommsClient from '../ext/lib/comms/CommsClient';
import Settings from '../ext/lib/Settings';
import ExecAction from './js/ExecAction';
import DefaultSettingsPanel from './panels/DefaultSettingsPanel';
import AboutPanel from './panels/AboutPanel';
import ExtensionMode from '../common/enums/ExtensionMode.enum';
import Logger from '../ext/lib/Logger';
import EventBus from '../ext/lib/EventBus';
import {ChromeShittinessMitigations as CSM} from '../common/js/ChromeShittinessMitigations';
import { browser } from 'webextension-polyfill-ts';
export default {
data () {
return {
comms: new Comms(),
comms: undefined,
eventBus: new EventBus(),
settings: {},
settingsInitialized: false,
narrowPopup: null,
sideMenuVisible: null,
logger: undefined,
site: undefined
site: undefined,
}
},
async created() {
@ -71,9 +68,31 @@ export default {
await this.settings.init();
this.settingsInitialized = true;
const port = browser.runtime.connect({name: 'popup-port'});
port.onMessage.addListener( (m,p) => this.processReceivedMessage(m,p));
CSM.setProperty('port', port);
// const port = browser.runtime.connect({name: 'popup-port'});
// port.onMessage.addListener( (m,p) => this.processReceivedMessage(m,p));
// CSM.setProperty('port', port);
this.eventBus = new EventBus();
this.eventBus.subscribe(
'set-current-site',
{
function: (config, context) => {
if (this.site) {
if (!this.site.host) {
// dunno why this fix is needed, but sometimes it is
this.site.host = config.site.host;
}
}
this.site = config.site;
this.selectedSite = this.selectedSite || config.site.host;
this.loadFrames(this.site);
}
}
);
this.comms = new CommsClient('popup-port', this.logger, this.eventBus);
this.eventBus.setComms(this.comms);
// ensure we'll clean player markings on popup close
@ -94,8 +113,7 @@ export default {
while (true) {
try {
console.log('trying to get site ...');
this.getSite();
console.log('site gottne');
this.requestSite();
} catch (e) {
console.warn('failed to load site:', e);
}
@ -129,13 +147,24 @@ export default {
toObject(obj) {
return JSON.parse(JSON.stringify(obj));
},
getSite() {
requestSite() {
try {
this.logger.log('info','popup', '[popup::getSite] Requesting current site ...')
CSM.port.postMessage({cmd: 'get-current-site'});
console.info('requesting current site')
// CSM.port.postMessage({command: 'get-current-site'});
this.eventBus.send(
'get-current-site',
undefined,
{
comms: {forwardTo: 'active'}
}
);
} catch (e) {
this.logger.log('error','popup','[popup::getSite] sending get-current-site failed for some reason. Reason:', e);
}
},
setSite(data) {
},
getRandomColor() {
return `rgb(${Math.floor(Math.random() * 128)}, ${Math.floor(Math.random() * 128)}, ${Math.floor(Math.random() * 128)})`;
@ -143,8 +172,9 @@ export default {
processReceivedMessage(message, port) {
this.logger.log('info', 'popup', '[popup::processReceivedMessage] received message:', message)
console.info('[popup::processReceivedMessage] got message:', message);
if (message.cmd === 'set-current-site'){
if (message.command === 'set-current-site'){
if (this.site) {
if (!this.site.host) {
// dunno why this fix is needed, but sometimes it is

View File

@ -3,4 +3,4 @@ import App from './App';
import mdiVue from 'mdi-vue/v3';
import * as mdijs from '@mdi/js';
createApp(App).mount('#app').use(mdiVue, {icons: mdijs});
createApp(App).mount('#app') //.use(mdiVue, {icons: mdijs});