aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/bg/js/search-main.js3
-rw-r--r--ext/bg/settings-popup-preview.html1
-rw-r--r--ext/fg/js/popup.js78
-rw-r--r--ext/manifest.json1
-rw-r--r--ext/mixed/js/dynamic-loader.js77
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
};
})();