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
This commit is contained in:
toasted-nutbread 2020-05-19 20:33:06 -04:00 committed by GitHub
parent dd6c3015c4
commit dd673f0b26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 90 deletions

View File

@ -23,9 +23,6 @@
*/ */
async function injectSearchFrontend() { async function injectSearchFrontend() {
dynamicLoader.loadStyles([
'/fg/css/client.css'
]);
await dynamicLoader.loadScripts([ await dynamicLoader.loadScripts([
'/mixed/js/text-scanner.js', '/mixed/js/text-scanner.js',
'/fg/js/frontend-api-receiver.js', '/fg/js/frontend-api-receiver.js',

View File

@ -121,6 +121,7 @@
<script src="/mixed/js/core.js"></script> <script src="/mixed/js/core.js"></script>
<script src="/mixed/js/dom.js"></script> <script src="/mixed/js/dom.js"></script>
<script src="/mixed/js/api.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="/mixed/js/text-scanner.js"></script>
<script src="/fg/js/document.js"></script> <script src="/fg/js/document.js"></script>

View File

@ -17,8 +17,8 @@
/* global /* global
* DOM * DOM
* apiInjectStylesheet
* apiOptionsGet * apiOptionsGet
* dynamicLoader
*/ */
class Popup { class Popup {
@ -180,12 +180,7 @@ class Popup {
} }
async setCustomOuterCss(css, useWebExtensionApi) { async setCustomOuterCss(css, useWebExtensionApi) {
return await this._injectStylesheet( return await dynamicLoader.loadStyle('yomichan-popup-outer-user-stylesheet', 'code', css, useWebExtensionApi);
'yomichan-popup-outer-user-stylesheet',
'code',
css,
useWebExtensionApi
);
} }
setChildrenSupported(value) { setChildrenSupported(value) {
@ -391,7 +386,7 @@ class Popup {
async _injectStyles() { async _injectStyles() {
try { 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) { } catch (e) {
// NOP // 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) { static isFrameAboutBlank(frame) {
try { try {
const contentDocument = frame.contentDocument; const contentDocument = frame.contentDocument;
@ -793,5 +723,3 @@ class Popup {
} }
} }
} }
Popup._injectedStylesheets = new Map();

View File

@ -38,6 +38,7 @@
"mixed/js/core.js", "mixed/js/core.js",
"mixed/js/dom.js", "mixed/js/dom.js",
"mixed/js/api.js", "mixed/js/api.js",
"mixed/js/dynamic-loader.js",
"mixed/js/text-scanner.js", "mixed/js/text-scanner.js",
"fg/js/document.js", "fg/js/document.js",
"fg/js/frontend-api-sender.js", "fg/js/frontend-api-sender.js",

View File

@ -15,19 +15,72 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
const dynamicLoader = (() => { /* global
function loadStyles(urls) { * apiInjectStylesheet
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'); const dynamicLoader = (() => {
style.rel = 'stylesheet'; const injectedStylesheets = new Map();
style.type = 'text/css';
style.href = url; async function loadStyle(id, type, value, useWebExtensionApi=false) {
parent.appendChild(style); 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) { function loadScripts(urls) {
@ -80,7 +133,7 @@ const dynamicLoader = (() => {
return { return {
loadStyles, loadStyle,
loadScripts loadScripts
}; };
})(); })();