Skip to content

Commit

Permalink
add inject script again
Browse files Browse the repository at this point in the history
  • Loading branch information
pyanderson committed Nov 5, 2023
1 parent 739b947 commit 7c7f96c
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 36 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ Essa extensão usa content scripts por que precisa acessar diretamente os recurs
- [Chrome](https://developer.chrome.com/docs/extensions/mv3/content_scripts/)
- [Firefox](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts)

Isso significa que a extensão é executada em um "mundo isolado", sem acesso a recursos importantes, como a API interna do Roll20, em versões antigas da extensão foi implementada uma injeção de script que burlava esse comportamento, resolvi remover por que ela não era necessária, facilitva, mas os problemas poderiam ser resolvidos dentro do ambiente isolado da extensão. Essa remoção não significa que essa estratégia está banida, apenas que ela será usada quando de fato for necessária.
Isso significa que a extensão é executada em um "mundo isolado", sem acesso a recursos importantes, como a API interna do Roll20, por isso, é utilizada uma técnica de injeção de script para conseguir acessar esses recursos. Mas existe uma contrapartida, temos que aceitar as limitações e uma certa imprevisibilidade da aplicação Roll20, por exemplo, no momento a versão jQuery utilizada é a 1.9.1, e não temos controle sobre isso, a qualquer momento eles podem atualizar para uma versão incompatível com algo que está sendo utilizado por essa extensão, embora seja improvável grandes mudanças do tipo, essa é uma opção factível.

Sendo assim, o uso de jQuery é o mínimo possível, se limitando à casos que se precisa de compatibilidade de layout com o Roll20 (diálogos).

### Documentação

Expand Down
7 changes: 3 additions & 4 deletions manifest.v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
"src/css/enhancement.css"
],
"js": [
"src/vendor/jquery-3.7.1.min.js",
"src/vendor/jquery-ui-1.12.1.min.js",
"index.js"
"main.js"
],
"run_at": "document_end"
}
],
"web_accessible_resources": [
"static.db.json",
"index.js",
"static/db.json",
"src/css/sheet.css",
"static/icons/32.png"
]
Expand Down
5 changes: 2 additions & 3 deletions manifest.v3.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@
"src/css/enhancement.css"
],
"js": [
"src/vendor/jquery-3.7.1.min.js",
"src/vendor/jquery-ui-1.12.1.min.js",
"index.js"
"main.js"
],
"run_at": "document_end"
}
],
"web_accessible_resources": [
{
"resources": [
"index.js",
"static/db.json",
"src/css/sheet.css",
"static/icons/32.png"
Expand Down
8 changes: 4 additions & 4 deletions src/features/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
slugify,
} from '../common/helpers';

const ICON_PATH = 'static/icons/32.png';
const ZOOM_DIV_ID = 'zoomclick';
const BOOK_BUTTON_ID = 'tormenta20-book-button';
const BOOK_DIALOG_ID = 'tormenta20-dialog-book';
Expand Down Expand Up @@ -290,15 +289,16 @@ function createBookButton({ cssText, bookItems }) {
*
* @param props
* @param {BookItem[]} props.bookItems - The book items list.
* @param {string} props.buttonIconURL - The URL to the icon in the extension files.
* @param {number} props.retry - Number of retries.
*/
export function loadBook({ bookItems, retry = 5 }) {
export function loadBook({ bookItems, buttonIconURL, retry = 5 }) {
const zoomDiv = document.getElementById(ZOOM_DIV_ID);
// Wait until the zoom button is available
if (!zoomDiv)
// wait one second and try again
return setTimeout(() => {
loadBook({ bookItems, retry: retry - 1 });
loadBook({ bookItems, buttonIconURL, retry: retry - 1 });
}, 1000);
// Remove the old button and old dialog if it exists, this is useful during development where you need to reload the extension several times
document.getElementById(BOOK_DIALOG_ID)?.parentNode?.remove();
Expand All @@ -313,7 +313,7 @@ export function loadBook({ bookItems, retry = 5 }) {
right: ${calcRightValue(zoomDivStyle.getPropertyValue('right'))};
top: ${zoomDivStyle.getPropertyValue('height')};
z-index: ${zoomDivStyle.getPropertyValue('z-index')};
background-image: url(${chrome.runtime.getURL(ICON_PATH)});
background-image: url(${buttonIconURL});
`;
// Create the button and add it to the page
const button = createBookButton({ cssText: buttonCSSText, bookItems });
Expand Down
17 changes: 11 additions & 6 deletions src/features/character-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import { loadPowersEnhancement } from './powers';
import { loadRacesEnhancement } from './races';
import { calcCD, loadSpellsEnhancement } from './spells';

const CHARACTER_SHEET_CSS_PATH = 'src/css/sheet.css';

/**
* Create the the CD row element.
*
Expand Down Expand Up @@ -145,8 +143,7 @@ function init({ iframe, characterId }) {
* @param {object} props
* @param {HTMLDocument} props.iframe - The character sheet iframe document.
*/
function loadSheetExtraCSS({ iframe }) {
const url = chrome.runtime.getURL(CHARACTER_SHEET_CSS_PATH);
function loadSheetExtraCSS({ iframe, url }) {
if (hasCSS({ iframe, url })) return;
iframe.head.appendChild(
createElement('link', { rel: 'stylesheet', href: url }),
Expand All @@ -159,8 +156,13 @@ function loadSheetExtraCSS({ iframe }) {
* @param {object} props
* @param {T20Data} props.db - The Tormenta20 data.
* @param {string} props.characterId - The character ID in the Roll20 game.
* @param {string} props.characterSheetCssURL - URL for the custom URL to be applied to the character sheet.
*/
export function loadSheetEnhancement({ db: data, characterId }) {
export function loadSheetEnhancement({
db: data,
characterId,
characterSheetCssURL,
}) {
// Load the functionalities
const iframe = document.querySelector(`iframe[name="iframe_${characterId}"]`);
if (!iframe) {
Expand Down Expand Up @@ -229,5 +231,8 @@ export function loadSheetEnhancement({ db: data, characterId }) {
});
observer.observe(iframe.contentDocument, observerOptions);

loadSheetExtraCSS({ iframe: iframe.contentDocument });
loadSheetExtraCSS({
iframe: iframe.contentDocument,
url: characterSheetCssURL,
});
}
57 changes: 39 additions & 18 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { loadBook } from './features/book';
import { loadSheetEnhancement } from './features/character-sheet';
import { loadChatEnhancement } from './features/enhancement';

const DB_PATH = 'static/db.json';

// https://youmightnotneedjquery.com/#ready
function ready(fn) {
if (document.readyState !== 'loading') {
Expand All @@ -16,21 +14,44 @@ function ready(fn) {
}

ready(() => {
// Loading all game data in one place to avoid loading this multiple times through the extension.
fetch(chrome.runtime.getURL(DB_PATH))
.then((response) => response.json())
.then((db) => {
loadBook({ bookItems: db.book });
// As it is necessary to reload the extension several times during development,
// it is necessary to remove old listners added by previous versions.
// If this is not done, it will be necessary to refresh the page every time we need to see a change.
// https://stackoverflow.com/a/63914090
if (!window.patched) {
window.listeners = [];
const orig = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (...args) {
if (
args[0] === 'message' &&
args[1].name === 't20EventListener' &&
this === window
) {
window.listeners.push(args[1]);
}
return orig.apply(this, args);
};
window.patched = true;
}
window.listeners.forEach((listener) => {
window.removeEventListener('message', listener, false);
});
window.listeners = [];
const resources = { db: {}, characterSheetCssURL: '', buttonIconURL: '' };
const t20EventListener = ({ data }) => {
if (data?.type && data.type === 't20-data') {
const { db, buttonIconURL, characterSheetCssURL } = data;
loadBook({ bookItems: db.book, buttonIconURL });
loadChatEnhancement({ bookItems: db.book });
window.addEventListener(
'message',
({ data }) => {
// only add the sheet improvements when a character sheet is opened
if (data.type === 'loaded') {
loadSheetEnhancement({ db, characterId: data.characterId });
}
},
false,
);
});
Object.assign(resources, { db, buttonIconURL, characterSheetCssURL });
}
if (data?.type && data.type === 'loaded') {
loadSheetEnhancement({
db: resources.db,
characterId: data.characterId,
characterSheetCssURL: resources.characterSheetCssURL,
});
}
};
window.addEventListener('message', t20EventListener, false);
});
37 changes: 37 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
function loadScript(path) {
const s = document.createElement('script');
s.src = chrome.runtime.getURL(path);
s.type = 'text/javascript';
s.onload = () => {
s.remove();
};
(document.head || document.documentElement).appendChild(s);
}

// https://youmightnotneedjquery.com/#ready
function ready(fn) {
if (document.readyState !== 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}

ready(() => {
const DB_PATH = 'static/db.json';
const CHARACTER_SHEET_CSS_PATH = 'src/css/sheet.css';
const ICON_PATH = 'static/icons/32.png';
loadScript('index.js');
fetch(chrome.runtime.getURL(DB_PATH))
.then((response) => response.json())
.then((db) => {
const characterSheetCssURL = chrome.runtime.getURL(
CHARACTER_SHEET_CSS_PATH,
);
const buttonIconURL = chrome.runtime.getURL(ICON_PATH);
window.postMessage(
{ type: 't20-data', db, characterSheetCssURL, buttonIconURL },
'*',
);
});
});
1 change: 1 addition & 0 deletions webpack.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const config = {
plugins: [
new CopyPlugin({
patterns: [
{ from: 'src/main.js' },
{ from: 'static', to: 'static' },
{ from: 'src', to: 'src' },
{
Expand Down

0 comments on commit 7c7f96c

Please sign in to comment.