diff options
| author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-05-19 20:33:06 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-05-19 20:33:06 -0400 | 
| commit | dd673f0b2626c2bffbcb301dc364009f077c3d08 (patch) | |
| tree | 64319346c3e9a9debe76e62b6adc77034aec52e8 /ext/mixed/js | |
| parent | dd6c3015c4af6db5f1deca797366ed6269b7d82c (diff) | |
Dynamic loader load style (#521)
* Remove unnecessary load of /fg/css/client.css
* Replace dynamicLoader.loadStyles with dynamicLoader.loadStyle
* Replace Popup._injectStylesheet with dynamicLoader.loadStyle
* Remove unused global
Diffstat (limited to 'ext/mixed/js')
| -rw-r--r-- | ext/mixed/js/dynamic-loader.js | 77 | 
1 files changed, 65 insertions, 12 deletions
| diff --git a/ext/mixed/js/dynamic-loader.js b/ext/mixed/js/dynamic-loader.js index 51b6821b..ce946109 100644 --- a/ext/mixed/js/dynamic-loader.js +++ b/ext/mixed/js/dynamic-loader.js @@ -15,19 +15,72 @@   * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ +/* global + * apiInjectStylesheet + */ +  const dynamicLoader = (() => { -    function loadStyles(urls) { -        const parent = document.head; -        for (const url of urls) { -            const node = parent.querySelector(`link[href='${escapeCSSAttribute(url)}']`); -            if (node !== null) { continue; } - -            const style = document.createElement('link'); -            style.rel = 'stylesheet'; -            style.type = 'text/css'; -            style.href = url; -            parent.appendChild(style); +    const injectedStylesheets = new Map(); + +    async function loadStyle(id, type, value, useWebExtensionApi=false) { +        if (useWebExtensionApi && yomichan.isExtensionUrl(window.location.href)) { +            // Permissions error will occur if trying to use the WebExtension API to inject into an extension page +            useWebExtensionApi = false; +        } + +        let styleNode = injectedStylesheets.get(id); +        if (typeof styleNode !== 'undefined') { +            if (styleNode === null) { +                // Previously injected via WebExtension API +                throw new Error(`Stylesheet with id ${id} has already been injected using the WebExtension API`); +            } +        } else { +            styleNode = null; +        } + +        if (useWebExtensionApi) { +            // Inject via WebExtension API +            if (styleNode !== null && styleNode.parentNode !== null) { +                styleNode.parentNode.removeChild(styleNode); +            } + +            injectedStylesheets.set(id, null); +            await apiInjectStylesheet(type, value); +            return null;          } + +        // Create node in document +        const parentNode = document.head; +        if (parentNode === null) { +            throw new Error('No parent node'); +        } + +        // Create or reuse node +        const isFile = (type === 'file'); +        const tagName = isFile ? 'link' : 'style'; +        if (styleNode === null || styleNode.nodeName.toLowerCase() !== tagName) { +            if (styleNode !== null && styleNode.parentNode !== null) { +                styleNode.parentNode.removeChild(styleNode); +            } +            styleNode = document.createElement(tagName); +        } + +        // Update node style +        if (isFile) { +            styleNode.rel = 'stylesheet'; +            styleNode.href = value; +        } else { +            styleNode.textContent = value; +        } + +        // Update parent +        if (styleNode.parentNode !== parentNode) { +            parentNode.appendChild(styleNode); +        } + +        // Add to map +        injectedStylesheets.set(id, styleNode); +        return styleNode;      }      function loadScripts(urls) { @@ -80,7 +133,7 @@ const dynamicLoader = (() => {      return { -        loadStyles, +        loadStyle,          loadScripts      };  })(); |