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:
parent
dd6c3015c4
commit
dd673f0b26
@ -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',
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user