UNPKG

@ima/devtools

Version:

IMA.js debugging panel in the Chrome Developer Tools window.

116 lines (102 loc) 3.04 kB
/** * @typedef {string} InjectResourceType * @enum {InjectResourceType} */ const InjectType = Object.freeze({ SCRIPT: 'script', STYLE: 'style', }); /** * Takes care of injecting entire JS or CSS source files into the website * * @param {string} src * @param {InjectResourceType} resourceType * @param {boolean} removeOnceExecuted * @param {HTMLElement} rootElement * @param {string} action * @returns {Promise<any>} */ function injectFile( src, resourceType = InjectType.SCRIPT, removeOnceExecuted = true, rootElement = document.head || document.documentElement, action = 'appendChild' ) { return new Promise((resolve, reject) => { if (!rootElement) { reject(new Error('Missing parent rootElement')); return; } // Resolve src to chrome extension url const url = chrome.extension.getURL(src); let element = null; if (resourceType === InjectType.SCRIPT) { element = document.createElement('script'); element.src = url; } else { element = document.createElement('link'); element.rel = 'stylesheet'; element.href = url; } // We want to remove scripts once they execute, but styles has to stay element.onload = () => { if (resourceType === InjectType.SCRIPT && removeOnceExecuted) { element.remove(); } resolve(); }; element.onerror = error => { element.remove(); reject(error); }; if (action === 'appendChild' || action === 'prepend') { rootElement[action](element); } else { const parentContainer = rootElement.parentNode; parentContainer[action](element, parentContainer.firstChild); } }); } /** * Takes care of injecting JS or CSS code into website * * @param {string} code * @param {InjectResourceType} resourceType * @param {boolean} removeOnceExecuted * @param {HTMLElement} rootElement * @param {string} action * @returns {Promise<any>} */ function injectCode( code, resourceType = InjectType.SCRIPT, removeOnceExecuted = true, rootElement = document.head || document.documentElement || document.body, action = 'appendChild' ) { return new Promise((resolve, reject) => { if (!rootElement) { reject(new Error('Missing parent rootElement')); return; } let element = null; if (resourceType === InjectType.SCRIPT) { element = document.createElement('script'); } else { element = document.createElement('style'); } element.textContent = code; if (action === 'appendChild' || action === 'prepend') { rootElement[action](element); } else { const parentContainer = rootElement.parentNode; parentContainer[action](element, parentContainer.firstChild); } if (resourceType === InjectType.SCRIPT && removeOnceExecuted) { element.remove(); } resolve(); }); } export { InjectType, injectFile, injectCode };