api/resources: initial add

This commit is contained in:
CanadaHonk 2023-04-09 00:27:32 +01:00
parent 2649c37c20
commit e250ea4853
2 changed files with 83 additions and 0 deletions

81
src/api/resources.js Normal file
View File

@ -0,0 +1,81 @@
export default async CDP => {
const run = async js => {
await CDP.send('Runtime.evaluate', {
expression: typeof js === 'string' ? js : `(${js.toString()})()`
});
};
const injectJS = async code => {
const toRun = `(async () => {
if (window.self !== window.top) return;
await new Promise(res => {
const check = () => {
if (!window.Gluon) return setTimeout(check, 20);
res();
};
check();
});
await new Promise(res => {
if (document.readyState !== 'loading') {
res();
} else {
document.addEventListener('DOMContentLoaded', res);
}
});
${code}
})();`;
await run(toRun);
const { identifier } = await CDP.send('Page.addScriptToEvaluateOnNewDocument', {
source: toRun
});
return async () => {
await CDP.send('Page.removeScriptToEvaluateOnNewDocument', {
identifier
});
};
};
const escapeCSS = code => code.replaceAll('`', '\\`').replaceAll('\\', '\\\\');
const injectCSS = async (code, id = 'gluon-resource-' + Math.random().toString().split('.')[1]) => {
const js = `const el = document.querySelector('style#${id}') ?? document.createElement('style');
el.id = '${id}';
el.textContent = \`${escapeCSS(code)}\`;
if (!el.isConnected) document.head.appendChild(el);`;
return [ id, await injectJS(js) ];
};
return {
js: async inp => {
const code = typeof inp === 'function' ? `(${inp.toString()})()` : inp;
const remove = await injectJS(code);
return {
remove
};
},
css: async css => {
let [ id, removeJS ] = await injectCSS(css);
return {
remove: async () => {
await removeJS(); // do not add in future
await run(`document.querySelector('style#${id}').remove()`); // remove current element
},
modify: async newCss => {
await removeJS(); // do not add old in future
[ id, removeJS ] = await injectCSS(newCss, id); // inject new css with same id
},
}
}
};
};

View File

@ -7,6 +7,7 @@ import LocalCDP from '../lib/local/cdp.js';
import PageApi from '../api/page.js';
import IdleApi from '../api/idle.js';
import ControlsApi from '../api/controls.js';
import ResourcesApi from '../api/resources.js';
import V8CacheApi from '../api/v8Cache.js';
const acquireTarget = async (CDP, filter = () => true) => {
@ -193,6 +194,7 @@ export default async (CDP, proc, injectionType = 'browser', { dataPath, browserN
Window.page = await PageApi(Window.cdp, evalInWindow, { pageLoadPromise });
Window.idle = await IdleApi(Window.cdp, { browserType, closeHandlers });
Window.controls = await ControlsApi(Window.cdp);
Window.resources = await ResourcesApi(Window.cdp);
Window.v8Cache = await V8CacheApi(Window.cdp, evalInWindow, { browserType, dataPath });
return Window;