Skip to content

Commit

Permalink
add scene overview
Browse files Browse the repository at this point in the history
  • Loading branch information
Zyie committed Feb 5, 2024
1 parent 6f0557c commit cdbec2e
Show file tree
Hide file tree
Showing 28 changed files with 2,324 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
"globals": {
"chrome": "readonly"
},
"ignorePatterns": ["watch.js", "dist/**"]
"ignorePatterns": ["dist/**"]
}

10 changes: 10 additions & 0 deletions global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
declare global {
interface Window {
__PIXI_APP__: import('pixi.js').Application | undefined;
__PIXI_STAGE__: import('pixi.js').Container | undefined;
__PIXI_RENDERER__: import('pixi.js').Renderer | undefined;
__PIXI__: import('pixi.js');
}
}

export {};
38 changes: 37 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"react-dom": "^18.2.0",
"smoothie": "^1.36.1",
"styled-components": "^6.1.8",
"webextension-polyfill": "^0.10.0"
"webextension-polyfill": "^0.10.0",
"zustand": "^4.5.0"
},
"devDependencies": {
"@crxjs/vite-plugin": "^2.0.0-beta.23",
Expand All @@ -66,7 +67,6 @@
"@typescript-eslint/parser": "^5.49.0",
"@vitejs/plugin-react-swc": "^3.0.1",
"@webdoc/cli": "^2.2.0",
"autoprefixer": "^10.4.16",
"copyfiles": "^2.4.1",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.6.0",
Expand Down
64 changes: 36 additions & 28 deletions src/chrome/manifest.dev.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
{
"action": {
"default_popup": "src/popup/index.html",
"default_icon": {
"16": "icon-inactive-16.png",
"32": "icon-inactive-32.png",
"48": "icon-inactive-48.png",
"128": "icon-inactive-128.png"
}
},
"icons": {
"16": "icon-active-16.png",
"32": "icon-active-32.png",
"48": "icon-active-48.png",
"128": "icon-active-128.png"
},
"web_accessible_resources": [
{
"resources": [
"contentStyle.css",
"icon-active-128.png",
"icon-inactive-32.png"
],
"matches": ["<all_urls>"]
}
],
"devtools_page": "src/devtools/index.html"
}

"action": {
"default_popup": "src/popup/index.html",
"default_icon": {
"16": "icon-inactive-16.png",
"32": "icon-inactive-32.png",
"48": "icon-inactive-48.png",
"128": "icon-inactive-128.png"
}
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*", "<all_urls>"],
"js": ["src/content/index.ts"],
"css": ["contentStyle.css"],
"run_at": "document_start"
}
],
"background": {
"service_worker": "src/background/index.ts",
"type": "module"
},
"icons": {
"16": "icon-active-16.png",
"32": "icon-active-32.png",
"48": "icon-active-48.png",
"128": "icon-active-128.png"
},
"permissions": ["activeTab"],
"devtools_page": "src/devtools/index.html",
"web_accessible_resources": [
{
"resources": ["contentStyle.css", "icon-active-128.png", "icon-inactive-32.png"],
"matches": ["<all_urls>"]
}
]
}
56 changes: 35 additions & 21 deletions src/chrome/src/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
enum MessageType {
Inactive = 'inactive',
Active = 'active',
PopupOpened = 'popup-opened',
PixiDetected = 'pixi-detected',
}
import { MessageType, convertPostMessage, convertPostMessageData } from '../test';

interface Message {
method: MessageType;
Expand Down Expand Up @@ -37,32 +32,51 @@ let devToolsConnection: chrome.runtime.Port | null = null;
let popupTabId: string | null = null;

chrome.runtime.onMessage.addListener((request: Message, sender: chrome.runtime.MessageSender) => {
console.log('Message received in background script', request, sender);
if (request.method === MessageType.PopupOpened) {
const converted = convertPostMessageData(request);
if (converted.method === MessageType.PopupOpened) {
sendRuntimeMessage(MessageType.PixiDetected, { data: MessageType.PopupOpened });
popupTabId = sender.id ?? null;
} else if (request.method === MessageType.PixiDetected) {
} else if (converted.method === MessageType.PixiDetected) {
setIconAndPopup(MessageType.Active, sender.tab?.id ?? 0);
if (popupTabId) {
sendRuntimeMessage(MessageType.PixiDetected, request.data);
sendRuntimeMessage(MessageType.PixiDetected, converted.data);
}
}

// Forward the message to the devtools
devToolsConnection?.postMessage(request);
if (devToolsConnection) {
const message = convertPostMessage(converted.method, converted.data);
devToolsConnection?.postMessage({
id: 'pixi-devtools',
...message,
});
}
});

chrome.runtime.onConnect.addListener(function (dtc) {
// assign the listener function to a variable so we can remove it later
const devToolsListener = function () {

chrome.runtime.onConnect.addListener(function (port) {
if (port.name !== 'devtools-connection') return;

devToolsConnection = port;

devToolsConnection.onMessage.addListener(function () {
// Handle message from devtools here
};
// add the listener
dtc.onMessage.addListener(devToolsListener);
});

dtc.onDisconnect.addListener(function () {
dtc.onMessage.removeListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function () {
devToolsConnection = null;
});

devToolsConnection = dtc;
console.log('Connected to devtools', port);
});

// update icon and popup when the active tab changes
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (tab.active && changeInfo.status === 'loading') {
setIconAndPopup(MessageType.Inactive, tabId);
const message = convertPostMessage(MessageType.Inactive, {});
devToolsConnection?.postMessage({
id: 'pixi-devtools',
...message,
});
}
});
16 changes: 13 additions & 3 deletions src/chrome/src/content/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { MessageType, convertPostMessage, convertPostMessageData } from '../test';

function injectScript(file_path: string, tag: string) {
const node = document.getElementsByTagName(tag)[0];
const script = document.createElement('script');
Expand All @@ -11,12 +13,20 @@ window.addEventListener(
'message',
(event) => {
// We only accept messages from ourselves
if (event.source !== window) {
if (event.source !== window || !event.data.method) {
return;
}

if (event.data?.type === 'pixi-detected') {
chrome.runtime.sendMessage({ method: 'pixi-detected', data: JSON.stringify(event.data) });
const converted = convertPostMessageData(event.data);

if (!converted.method.startsWith('pixi-')) return;

if (converted.method === MessageType.PixiDetected) {
const message = convertPostMessage(MessageType.PixiDetected, converted.data);
chrome.runtime.sendMessage(message);
} else if (converted.method === MessageType.StateUpdate) {
const message = convertPostMessage(MessageType.StateUpdate, converted.data);
chrome.runtime.sendMessage(message);
}
},
false
Expand Down
34 changes: 1 addition & 33 deletions src/chrome/src/inject/index.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1 @@
// Function to check if a global variable exists
function hasGlobal(varname: string) {
return window[varname as keyof Window] || Array.from(window.frames).some((frame) => frame[varname as keyof Window]);
}

// Function to detect PixiJS
function detectPixi() {
return hasGlobal('__PIXI_APP__') || hasGlobal('__PIXI_STAGE__') || hasGlobal('__PIXI_RENDERER__')
? 'detected'
: 'disabled';
}

let pixiPollingInterval: number | undefined;

// Function to start polling for PixiJS
function startPixiPolling() {
pixiPollingInterval = window.setInterval(() => {
try {
const pixiDetectionResult = detectPixi();

if (pixiDetectionResult === 'detected') {
clearInterval(pixiPollingInterval);
window.postMessage({ type: 'pixi-detected' }, '*');
}
} catch (error) {
clearInterval(pixiPollingInterval);
}
}, 300);

return pixiPollingInterval;
}

startPixiPolling();
import '@lib/src/detection'
8 changes: 5 additions & 3 deletions src/chrome/src/popup/popup.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { createRoot } from 'react-dom/client';
import { useEffect, useState } from 'react';
import { MessageType, convertPostMessage } from '../test';

const Popup = () => {
const [message, setMessage] = useState('hello world');

// send a message to the background script to let it know the popup has been opened
// background script will then send a message back if it detects pixi
useEffect(() => {
chrome.runtime.sendMessage({ method: 'popup-opened' });
chrome.runtime.sendMessage(convertPostMessage(MessageType.PopupOpened, {}));
}, []);

// listen for messages from the background script
useEffect(() => {
const listener = (request: any) => {
if (request.method === 'pixi-detected') {
if (request.method === MessageType.PixiDetected) {
console.log('pixi detected');
setMessage(request.data);
}
};
Expand All @@ -31,4 +33,4 @@ const Popup = () => {

const container = document.getElementById('app-container');
const root = createRoot(container!);
root.render(<Popup />);
root.render(<Popup />);
40 changes: 40 additions & 0 deletions src/chrome/src/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export enum MessageType {
Inactive = 'inactive',
Active = 'active',
PopupOpened = 'popup-opened',
PixiDetected = 'pixi-detected',

InjectSettingsChanged = 'inject-settings-changed',

StateUpdate = 'pixi-state-update',
}

/**
* Standard message format
* @param method - The message type
* @param data - The message data
* @returns
*/
export function convertPostMessage(method: MessageType, data: unknown) {
return { method, data: JSON.stringify(data) };
}

/**
* Convert the message data to a standard format
* @param a - The original message
*/
export function convertPostMessageData(a: ReturnType<typeof convertPostMessage>) {
let data: string | object = a.data;

if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (error) {
data = {};
}
}
return {
method: a.method,
data,
};
}
Loading

0 comments on commit cdbec2e

Please sign in to comment.