Skip to content

Instantly share code, notes, and snippets.

@kucheruk
Last active October 15, 2021 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kucheruk/8369ae5009d737f63d46886febf00b28 to your computer and use it in GitHub Desktop.
Save kucheruk/8369ae5009d737f63d46886febf00b28 to your computer and use it in GitHub Desktop.
ATI.su morpheus gist.
//content script = ship, feature component = morpheus.
console.log("Morpheus injected");
const features = new Map();
function messageToMorpheus(msg) {
window.postMessage({ direction: "from-ship", message: msg }, "*");
}
chrome.runtime.onMessage.addListener((msg, _, sendResponse) => {
if (msg.command == "init") {
sendResponse({
features: Object.fromEntries(features)
});
}
if (msg.command == "toggle") {
messageToMorpheus({
command: "toggle",
feature: msg.body.feature,
value: msg.body.value,
});
}
});
window.addEventListener(
"message",
(event) => {
if (
event.source == window &&
event.data &&
event.data.direction == "from-morpheus"
) {
const m = event.data.message;
if ((m.type && m.type == "feature") || m.type == undefined) {
features.set(m.name, m);
}
}
},
false
);
// send message to contentscript.js
function messageToShip(command, body, response) {
if (typeof chrome !== "undefined") {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
tabs.forEach((tab) => {
console.log("send message for ", tab, command, body);
chrome.tabs.sendMessage(tab.id, { command, body }, function (resp) {
console.log("response for message is", resp);
response(resp);
});
});
});
} else {
log("chrome not defined");
}
}
function handleCbChanged(e) {
try {
const d = this.dataset["feature"];
messageToShip("toggle", { feature: d, value: this.checked });
} catch (e) {
document.body.innerText = JSON.stringify(e);
}
}
messageToShip("init", null, (response) => {
if (response && response.features) {
if (response.features) {
features = Object.assign(features, response.features);
}
render(features); // делаем банальный набор чекбоксов с описаниями и вешаемся на onclick
} else {
log("no entries in response");
}
});
export function msgToShip(msg) {
window.postMessage({ direction: "from-morpheus", message: msg }, "*");
}
function handleBrowserAddonToolCommand(msg) {
if (
msg.source == window &&
msg.data.direction &&
msg.data.direction == "from-ship"
) {
const m = msg.data.message;
if (m.command == "call") {
if (window && window.features) {
for (let f of window.features) {
if (f.name == m.tool) {
f.callback();
}
}
}
}
}
}
export function registerTool(name, callback) {
sendEntryToBrowserAddon({
name,
expire: 0,
value: false,
type: "tool",
callback,
});
if (window) {
window.addEventListener("message", handleBrowserAddonToolCommand);
}
return () => {
window.removeEventListener("message", handleBrowserAddonToolCommand);
};
}
export function sendEntryToBrowserAddon({
name,
expire,
value = false,
type = "feature",
callback = null,
}) {
if (window) {
if (window.features == undefined) {
window.features = {};
}
if (window.features) {
let msgToShipNeeded = false;
if (window.features[name] === undefined) {
window.features[name] = { expire, on: false, callback };
msgToShipNeeded = true;
}
if (window.features[name].on != value) {
msgToShipNeeded = true;
}
window.features[name] = { expire, on: value, callback }; // по умолчанию - выключено, если никто не включал
if (msgToShipNeeded) {
msgToShip({ name, expire, value, type });
}
}
}
}
import { useCallback, useEffect, useState } from "react";
import { getFeatureEnabled, setFeatureState } from "./localStorage";
import { sendEntryToBrowserAddon } from "./communication";
const Feature = ({ name, expire, off, on }) => {
const feature = window && window.features && window.features[name];
const defaultState = getFeatureEnabled(name) || (feature && feature.on) || false;
const [enabled, setEnabled] = useState(defaultState);
sendEntryToBrowserAddon({ name, expire, value: enabled, type: "feature" });
const handleMessageFromBrowserAddon = useCallback(
(msg) => {
if (
msg.source == window &&
msg.data.direction &&
msg.data.direction == "from-ship"
) {
const m = msg.data.message;
if (m.command == "toggle") {
if (m.feature == name && m.value != enabled) {
setEnabled(m.value);
setFeatureState(name, m.value);
sendEntryToBrowserAddon({
name,
expire,
value: m.value,
type: "feature",
});
}
}
}
},
[setEnabled, enabled]
);
useEffect(() => {
if (window) {
window.addEventListener("message", handleMessageFromBrowserAddon);
}
return () => {
if (window) {
window.removeEventListener("message", handleMessageFromBrowserAddon);
}
};
}, [handleMessageFromBrowserAddon]);
if (window && enabled) {
return on();
}
return off();
};
export default Feature;
export function getFeatureEnabled(name) {
const localStorageKey = `morpheus-feature-${name}`;
return localStorage.getItem(localStorageKey) === "1";
}
export function setFeatureState(name, value) {
const localStorageKey = `morpheus-feature-${name}`;
const localStorageValue = localStorage.getItem(localStorageKey);
const val = value ? "1" : "0";
if (localStorageValue !== val) {
localStorage.setItem(localStorageKey, val);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment