diff options
| -rw-r--r-- | ext/bg/js/search-main.js | 3 | ||||
| -rw-r--r-- | ext/bg/settings-popup-preview.html | 1 | ||||
| -rw-r--r-- | ext/fg/js/popup.js | 78 | ||||
| -rw-r--r-- | ext/manifest.json | 1 | ||||
| -rw-r--r-- | ext/mixed/js/dynamic-loader.js | 77 | 
5 files changed, 70 insertions, 90 deletions
| diff --git a/ext/bg/js/search-main.js b/ext/bg/js/search-main.js index 6e092fbc..54fa549d 100644 --- a/ext/bg/js/search-main.js +++ b/ext/bg/js/search-main.js @@ -23,9 +23,6 @@   */  async function injectSearchFrontend() { -    dynamicLoader.loadStyles([ -        '/fg/css/client.css' -    ]);      await dynamicLoader.loadScripts([          '/mixed/js/text-scanner.js',          '/fg/js/frontend-api-receiver.js', diff --git a/ext/bg/settings-popup-preview.html b/ext/bg/settings-popup-preview.html index 3d7f6455..2f0b841b 100644 --- a/ext/bg/settings-popup-preview.html +++ b/ext/bg/settings-popup-preview.html @@ -121,6 +121,7 @@          <script src="/mixed/js/core.js"></script>          <script src="/mixed/js/dom.js"></script>          <script src="/mixed/js/api.js"></script> +        <script src="/mixed/js/dynamic-loader.js"></script>          <script src="/mixed/js/text-scanner.js"></script>          <script src="/fg/js/document.js"></script> diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 9e9debd8..b7d4b57e 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -17,8 +17,8 @@  /* global   * DOM - * apiInjectStylesheet   * apiOptionsGet + * dynamicLoader   */  class Popup { @@ -180,12 +180,7 @@ class Popup {      }      async setCustomOuterCss(css, useWebExtensionApi) { -        return await this._injectStylesheet( -            'yomichan-popup-outer-user-stylesheet', -            'code', -            css, -            useWebExtensionApi -        ); +        return await dynamicLoader.loadStyle('yomichan-popup-outer-user-stylesheet', 'code', css, useWebExtensionApi);      }      setChildrenSupported(value) { @@ -391,7 +386,7 @@ class Popup {      async _injectStyles() {          try { -            await this._injectStylesheet('yomichan-popup-outer-stylesheet', 'file', '/fg/css/client.css', true); +            await dynamicLoader.loadStyle('yomichan-popup-outer-stylesheet', 'file', '/fg/css/client.css', true);          } catch (e) {              // NOP          } @@ -717,71 +712,6 @@ class Popup {          };      } -    async _injectStylesheet(id, type, value, useWebExtensionApi) { -        const injectedStylesheets = Popup._injectedStylesheets; - -        if (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); -            } - -            await apiInjectStylesheet(type, value); - -            injectedStylesheets.set(id, null); -            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); -            styleNode.id = id; -        } - -        // Update node style -        if (isFile) { -            styleNode.rel = value; -        } else { -            styleNode.textContent = value; -        } - -        // Update parent -        if (styleNode.parentNode !== parentNode) { -            parentNode.appendChild(styleNode); -        } - -        // Add to map -        injectedStylesheets.set(id, styleNode); -        return styleNode; -    } -      static isFrameAboutBlank(frame) {          try {              const contentDocument = frame.contentDocument; @@ -793,5 +723,3 @@ class Popup {          }      }  } - -Popup._injectedStylesheets = new Map(); diff --git a/ext/manifest.json b/ext/manifest.json index 865fe3f3..c87b9296 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -38,6 +38,7 @@              "mixed/js/core.js",              "mixed/js/dom.js",              "mixed/js/api.js", +            "mixed/js/dynamic-loader.js",              "mixed/js/text-scanner.js",              "fg/js/document.js",              "fg/js/frontend-api-sender.js", 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      };  })(); |