Publish directory
This commit is contained in:
8
publish/wwwroot/js/app.js
Normal file
8
publish/wwwroot/js/app.js
Normal file
@ -0,0 +1,8 @@
|
||||
function subMenu(a) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
var li = a.parentElement, submenu = li.getElementsByTagName('ul')[0];
|
||||
submenu.style.display = submenu.style.display == "block" ? "none" : "block";
|
||||
return false;
|
||||
}
|
514
publish/wwwroot/js/interop.js
Normal file
514
publish/wwwroot/js/interop.js
Normal file
@ -0,0 +1,514 @@
|
||||
var Oqtane = Oqtane || {};
|
||||
|
||||
Oqtane.Interop = {
|
||||
setCookie: function (name, value, days, secure, sameSite) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
var expires = "expires=" + d.toUTCString();
|
||||
var cookieString = name + "=" + value + ";" + expires + ";path=/";
|
||||
if (secure) {
|
||||
cookieString += "; secure";
|
||||
}
|
||||
if (sameSite === "Lax" || sameSite === "Strict" || sameSite === "None") {
|
||||
cookieString += "; SameSite=" + sameSite;
|
||||
}
|
||||
document.cookie = cookieString;
|
||||
},
|
||||
setCookieString: function (cookieString) {
|
||||
document.cookie = cookieString;
|
||||
},
|
||||
getCookie: function (name) {
|
||||
name = name + "=";
|
||||
var decodedCookie = decodeURIComponent(document.cookie);
|
||||
var ca = decodedCookie.split(';');
|
||||
for (var i = 0; i < ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) === 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
},
|
||||
updateTitle: function (title) {
|
||||
if (document.title !== title) {
|
||||
document.title = title;
|
||||
}
|
||||
},
|
||||
includeMeta: function (id, attribute, name, content) {
|
||||
var meta = document.querySelector("meta[" + attribute + "=\"" + CSS.escape(name) + "\"]");
|
||||
if (meta === null) {
|
||||
meta = document.createElement("meta");
|
||||
meta.setAttribute(attribute, name);
|
||||
if (id !== "") {
|
||||
meta.id = id;
|
||||
}
|
||||
meta.content = content;
|
||||
document.head.appendChild(meta);
|
||||
}
|
||||
else {
|
||||
if (id !== "") {
|
||||
meta.setAttribute("id", id);
|
||||
}
|
||||
if (meta.content !== content) {
|
||||
meta.setAttribute("content", content);
|
||||
}
|
||||
}
|
||||
},
|
||||
includeLink: function (id, rel, href, type, integrity, crossorigin, insertbefore) {
|
||||
var link = document.querySelector("link[href=\"" + CSS.escape(href) + "\"]");
|
||||
if (link === null) {
|
||||
link = document.createElement("link");
|
||||
if (id !== "") {
|
||||
link.id = id;
|
||||
}
|
||||
link.rel = rel;
|
||||
if (type !== "") {
|
||||
link.type = type;
|
||||
}
|
||||
link.href = href;
|
||||
if (integrity !== "") {
|
||||
link.integrity = integrity;
|
||||
}
|
||||
if (crossorigin !== "") {
|
||||
link.crossOrigin = crossorigin;
|
||||
}
|
||||
if (insertbefore === "") {
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
else {
|
||||
var sibling = document.getElementById(insertbefore);
|
||||
sibling.parentNode.insertBefore(link, sibling);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (link.id !== id) {
|
||||
link.setAttribute('id', id);
|
||||
}
|
||||
if (link.rel !== rel) {
|
||||
link.setAttribute('rel', rel);
|
||||
}
|
||||
if (type !== "") {
|
||||
if (link.type !== type) {
|
||||
link.setAttribute('type', type);
|
||||
}
|
||||
} else {
|
||||
link.removeAttribute('type');
|
||||
}
|
||||
if (link.href !== this.getAbsoluteUrl(href)) {
|
||||
link.removeAttribute('integrity');
|
||||
link.removeAttribute('crossorigin');
|
||||
link.setAttribute('href', href);
|
||||
}
|
||||
if (integrity !== "") {
|
||||
if (link.integrity !== integrity) {
|
||||
link.setAttribute('integrity', integrity);
|
||||
}
|
||||
} else {
|
||||
link.removeAttribute('integrity');
|
||||
}
|
||||
if (crossorigin !== "") {
|
||||
if (link.crossOrigin !== crossorigin) {
|
||||
link.setAttribute('crossorigin', crossorigin);
|
||||
}
|
||||
} else {
|
||||
link.removeAttribute('crossorigin');
|
||||
}
|
||||
}
|
||||
},
|
||||
includeLinks: function (links) {
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
this.includeLink(links[i].id, links[i].rel, links[i].href, links[i].type, links[i].integrity, links[i].crossorigin, links[i].insertbefore);
|
||||
}
|
||||
},
|
||||
includeScript: function (id, src, integrity, crossorigin, type, content, location, dataAttributes) {
|
||||
var script;
|
||||
if (src !== "") {
|
||||
script = document.querySelector("script[src=\"" + CSS.escape(src) + "\"]");
|
||||
}
|
||||
else {
|
||||
if (id !== "") {
|
||||
script = document.getElementById(id);
|
||||
} else {
|
||||
const scripts = document.querySelectorAll("script:not([src])");
|
||||
for (let i = 0; i < scripts.length; i++) {
|
||||
if (scripts[i].textContent.includes(content)) {
|
||||
script = scripts[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (script !== null) {
|
||||
script.remove();
|
||||
script = null;
|
||||
}
|
||||
if (script === null) {
|
||||
script = document.createElement("script");
|
||||
if (id !== "") {
|
||||
script.id = id;
|
||||
}
|
||||
if (type !== "") {
|
||||
script.type = type;
|
||||
}
|
||||
if (src !== "") {
|
||||
script.src = src;
|
||||
if (integrity !== "") {
|
||||
script.integrity = integrity;
|
||||
}
|
||||
if (crossorigin !== "") {
|
||||
script.crossOrigin = crossorigin;
|
||||
}
|
||||
}
|
||||
else {
|
||||
script.innerHTML = content;
|
||||
}
|
||||
if (dataAttributes !== null) {
|
||||
for (var key in dataAttributes) {
|
||||
script.setAttribute(key, dataAttributes[key]);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
this.addScript(script, location);
|
||||
} catch (error) {
|
||||
if (src !== "") {
|
||||
console.error("Failed to load external script: ${src}", error);
|
||||
} else {
|
||||
console.error("Failed to load inline script: ${content}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
addScript: function (script, location) {
|
||||
return new Promise((resolve, reject) => {
|
||||
script.async = false;
|
||||
script.defer = false;
|
||||
|
||||
script.onload = () => resolve();
|
||||
script.onerror = (error) => reject(error);
|
||||
|
||||
if (location === 'head') {
|
||||
document.head.appendChild(script);
|
||||
} else {
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
});
|
||||
},
|
||||
includeScripts: async function (scripts) {
|
||||
const bundles = [];
|
||||
for (let s = 0; s < scripts.length; s++) {
|
||||
if (scripts[s].bundle === '') {
|
||||
scripts[s].bundle = scripts[s].href;
|
||||
}
|
||||
if (!bundles.includes(scripts[s].bundle)) {
|
||||
bundles.push(scripts[s].bundle);
|
||||
}
|
||||
}
|
||||
const promises = [];
|
||||
for (let b = 0; b < bundles.length; b++) {
|
||||
const urls = [];
|
||||
for (let s = 0; s < scripts.length; s++) {
|
||||
if (scripts[s].bundle === bundles[b]) {
|
||||
urls.push(scripts[s].href);
|
||||
}
|
||||
}
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
if (loadjs.isDefined(bundles[b])) {
|
||||
loadjs.ready(bundles[b], () => {
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
else {
|
||||
loadjs(urls, bundles[b], {
|
||||
async: false,
|
||||
returnPromise: true,
|
||||
before: function (path, element) {
|
||||
for (let s = 0; s < scripts.length; s++) {
|
||||
if (path === scripts[s].href) {
|
||||
if (scripts[s].integrity !== '') {
|
||||
element.integrity = scripts[s].integrity;
|
||||
}
|
||||
if (scripts[s].crossorigin !== '') {
|
||||
element.crossOrigin = scripts[s].crossorigin;
|
||||
}
|
||||
if (scripts[s].type !== '') {
|
||||
element.type = scripts[s].type;
|
||||
}
|
||||
if (scripts[s].dataAttributes !== null) {
|
||||
for (var key in scripts[s].dataAttributes) {
|
||||
element.setAttribute(key, scripts[s].dataAttributes[key]);
|
||||
}
|
||||
}
|
||||
if (scripts[s].location === 'body') {
|
||||
document.body.appendChild(element);
|
||||
return false; // return false to bypass default DOM insertion mechanism
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(function () { resolve(true) })
|
||||
.catch(function (pathsNotFound) { reject(false) });
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (promises.length !== 0) {
|
||||
await Promise.all(promises);
|
||||
}
|
||||
},
|
||||
getAbsoluteUrl: function (url) {
|
||||
var a = document.createElement('a');
|
||||
getAbsoluteUrl = function (url) {
|
||||
a.href = url;
|
||||
return a.href;
|
||||
}
|
||||
return getAbsoluteUrl(url);
|
||||
},
|
||||
removeElementsById: function (prefix, first, last) {
|
||||
var elements = document.querySelectorAll('[id^=' + prefix + ']');
|
||||
for (var i = elements.length - 1; i >= 0; i--) {
|
||||
var element = elements[i];
|
||||
if (element.id.startsWith(prefix) && (first === '' || element.id >= first) && (last === '' || element.id <= last)) {
|
||||
element.parentNode.removeChild(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
getElementByName: function (name) {
|
||||
var elements = document.getElementsByName(name);
|
||||
if (elements.length) {
|
||||
return elements[0].value;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
submitForm: function (path, fields) {
|
||||
const form = document.createElement('form');
|
||||
form.method = 'post';
|
||||
form.action = path;
|
||||
|
||||
for (const key in fields) {
|
||||
if (fields.hasOwnProperty(key)) {
|
||||
const hiddenField = document.createElement('input');
|
||||
hiddenField.type = 'hidden';
|
||||
hiddenField.name = key;
|
||||
hiddenField.value = fields[key];
|
||||
form.appendChild(hiddenField);
|
||||
}
|
||||
}
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
},
|
||||
getFiles: function (id) {
|
||||
var files = [];
|
||||
var fileinput = document.getElementById(id);
|
||||
if (fileinput !== null) {
|
||||
for (var i = 0; i < fileinput.files.length; i++) {
|
||||
files.push(fileinput.files[i].name + ":" + fileinput.files[i].size);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
},
|
||||
uploadFiles: async function (posturl, folder, id, antiforgerytoken, jwt, chunksize) {
|
||||
var success = true;
|
||||
var fileinput = document.getElementById('FileInput_' + id);
|
||||
var progressinfo = document.getElementById('ProgressInfo_' + id);
|
||||
var progressbar = document.getElementById('ProgressBar_' + id);
|
||||
|
||||
var totalSize = 0;
|
||||
for (var i = 0; i < fileinput.files.length; i++) {
|
||||
totalSize += fileinput.files[i].size;
|
||||
}
|
||||
let uploadSize = 0;
|
||||
|
||||
if (!chunksize || chunksize < 1) {
|
||||
chunksize = 1; // 1 MB default
|
||||
}
|
||||
|
||||
if (progressinfo !== null && progressbar !== null) {
|
||||
progressinfo.setAttribute('style', 'display: inline;');
|
||||
if (fileinput.files.length > 1) {
|
||||
progressinfo.innerHTML = fileinput.files[0].name + ', ...';
|
||||
}
|
||||
else {
|
||||
progressinfo.innerHTML = fileinput.files[0].name;
|
||||
}
|
||||
progressbar.setAttribute('style', 'width: 100%; display: inline;');
|
||||
progressbar.value = 0;
|
||||
}
|
||||
|
||||
const uploadFile = (file) => {
|
||||
const chunkSize = chunksize * (1024 * 1024);
|
||||
const totalParts = Math.ceil(file.size / chunkSize);
|
||||
let partCount = 0;
|
||||
|
||||
const uploadPart = () => {
|
||||
const start = partCount * chunkSize;
|
||||
const end = Math.min(start + chunkSize, file.size);
|
||||
const chunk = file.slice(start, end);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let formdata = new FormData();
|
||||
formdata.append('__RequestVerificationToken', antiforgerytoken);
|
||||
formdata.append('folder', folder);
|
||||
formdata.append('formfile', chunk, file.name);
|
||||
|
||||
var credentials = 'same-origin';
|
||||
var headers = new Headers();
|
||||
headers.append('PartCount', partCount + 1);
|
||||
headers.append('TotalParts', totalParts);
|
||||
if (jwt !== "") {
|
||||
headers.append('Authorization', 'Bearer ' + jwt);
|
||||
credentials = 'include';
|
||||
}
|
||||
|
||||
return fetch(posturl, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
credentials: credentials,
|
||||
body: formdata
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
if (progressinfo !== null) {
|
||||
progressinfo.innerHTML = 'Error: ' + response.statusText;
|
||||
}
|
||||
throw new Error('Failed');
|
||||
}
|
||||
return;
|
||||
})
|
||||
.then(data => {
|
||||
partCount++;
|
||||
if (progressbar !== null) {
|
||||
uploadSize += chunk.size;
|
||||
var percent = Math.ceil((uploadSize / totalSize) * 100);
|
||||
progressbar.value = (percent / 100);
|
||||
}
|
||||
if (partCount < totalParts) {
|
||||
uploadPart().then(resolve).catch(reject);
|
||||
}
|
||||
else {
|
||||
resolve(data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return uploadPart();
|
||||
};
|
||||
|
||||
try {
|
||||
for (const file of fileinput.files) {
|
||||
await uploadFile(file);
|
||||
}
|
||||
} catch (error) {
|
||||
success = false;
|
||||
}
|
||||
|
||||
fileinput.value = '';
|
||||
return success;
|
||||
},
|
||||
refreshBrowser: function (verify, wait) {
|
||||
async function attemptReload (verify) {
|
||||
if (verify) {
|
||||
await fetch('');
|
||||
}
|
||||
window.location.reload();
|
||||
}
|
||||
attemptReload(verify);
|
||||
setInterval(attemptReload, wait * 1000);
|
||||
},
|
||||
redirectBrowser: function (url, wait) {
|
||||
setInterval(function () {
|
||||
window.location.href = url;
|
||||
}, wait * 1000);
|
||||
},
|
||||
formValid: function (formRef) {
|
||||
return formRef.checkValidity();
|
||||
},
|
||||
setElementAttribute: function (id, attribute, value) {
|
||||
var element = document.getElementById(id);
|
||||
if (element !== null) {
|
||||
element.setAttribute(attribute, value);
|
||||
}
|
||||
},
|
||||
scrollTo: function (top, left, behavior) {
|
||||
const modal = document.querySelector('.modal');
|
||||
if (modal) {
|
||||
modal.scrollTo({
|
||||
top: top,
|
||||
left: left,
|
||||
behavior: behavior
|
||||
});
|
||||
} else {
|
||||
window.scrollTo({
|
||||
top: top,
|
||||
left: left,
|
||||
behavior: behavior
|
||||
});
|
||||
}
|
||||
},
|
||||
scrollToId: function (id) {
|
||||
var element = document.getElementById(id);
|
||||
if (element instanceof HTMLElement) {
|
||||
element.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
inline: "nearest"
|
||||
});
|
||||
}
|
||||
},
|
||||
getCaretPosition: function (id) {
|
||||
var element = document.getElementById(id);
|
||||
return element.selectionStart;
|
||||
},
|
||||
manageIndexedDBItems: async function (action, key, value) {
|
||||
var idb = indexedDB.open("oqtane", 1);
|
||||
|
||||
idb.onupgradeneeded = function () {
|
||||
let db = idb.result;
|
||||
db.createObjectStore("items");
|
||||
}
|
||||
|
||||
if (action.startsWith("get")) {
|
||||
let request = new Promise((resolve) => {
|
||||
idb.onsuccess = function () {
|
||||
let transaction = idb.result.transaction("items", "readonly");
|
||||
let collection = transaction.objectStore("items");
|
||||
let result;
|
||||
if (action === "get") {
|
||||
result = collection.get(key);
|
||||
}
|
||||
if (action === "getallkeys") {
|
||||
result = collection.getAllKeys();
|
||||
}
|
||||
|
||||
result.onsuccess = function (e) {
|
||||
resolve(result.result);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let result = await request;
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
idb.onsuccess = function () {
|
||||
let transaction = idb.result.transaction("items", "readwrite");
|
||||
let collection = transaction.objectStore("items");
|
||||
if (action === "put") {
|
||||
collection.put(value, key);
|
||||
}
|
||||
if (action === "delete") {
|
||||
collection.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
1
publish/wwwroot/js/loadjs.min.js
vendored
Normal file
1
publish/wwwroot/js/loadjs.min.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
loadjs=function(){var h=function(){},c={},u={},f={};function o(e,n){if(e){var r=f[e];if(u[e]=n,r)for(;r.length;)r[0](e,n),r.splice(0,1)}}function l(e,n){e.call&&(e={success:e}),n.length?(e.error||h)(n):(e.success||h)(e)}function d(r,t,s,i){var c,o,e=document,n=s.async,u=(s.numRetries||0)+1,f=s.before||h,l=r.replace(/[\?|#].*$/,""),a=r.replace(/^(css|img)!/,"");i=i||0,/(^css!|\.css$)/.test(l)?((o=e.createElement("link")).rel="stylesheet",o.href=a,(c="hideFocus"in o)&&o.relList&&(c=0,o.rel="preload",o.as="style")):/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(l)?(o=e.createElement("img")).src=a:((o=e.createElement("script")).src=r,o.async=void 0===n||n),!(o.onload=o.onerror=o.onbeforeload=function(e){var n=e.type[0];if(c)try{o.sheet.cssText.length||(n="e")}catch(e){18!=e.code&&(n="e")}if("e"==n){if((i+=1)<u)return d(r,t,s,i)}else if("preload"==o.rel&&"style"==o.as)return o.rel="stylesheet";t(r,n,e.defaultPrevented)})!==f(r,o)&&e.head.appendChild(o)}function r(e,n,r){var t,s;if(n&&n.trim&&(t=n),s=(t?r:n)||{},t){if(t in c)throw"LoadJS";c[t]=!0}function i(n,r){!function(e,t,n){var r,s,i=(e=e.push?e:[e]).length,c=i,o=[];for(r=function(e,n,r){if("e"==n&&o.push(e),"b"==n){if(!r)return;o.push(e)}--i||t(o)},s=0;s<c;s++)d(e[s],r,n)}(e,function(e){l(s,e),n&&l({success:n,error:r},e),o(t,e)},s)}if(s.returnPromise)return new Promise(i);i()}return r.ready=function(e,n){return function(e,r){e=e.push?e:[e];var n,t,s,i=[],c=e.length,o=c;for(n=function(e,n){n.length&&i.push(e),--o||r(i)};c--;)t=e[c],(s=u[t])?n(t,s):(f[t]=f[t]||[]).push(n)}(e,function(e){l(n,e)}),r},r.done=function(e){o(e,[])},r.reset=function(){c={},u={},f={}},r.isDefined=function(e){return e in c},r}();
|
1
publish/wwwroot/js/quill-blot-formatter.min.js
vendored
Normal file
1
publish/wwwroot/js/quill-blot-formatter.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
54
publish/wwwroot/js/quill-interop.js
Normal file
54
publish/wwwroot/js/quill-interop.js
Normal file
@ -0,0 +1,54 @@
|
||||
var Oqtane = Oqtane || {};
|
||||
|
||||
Oqtane.RichTextEditor = {
|
||||
createQuill: async function (
|
||||
quillElement, toolBar, readOnly,
|
||||
placeholder, theme, debugLevel) {
|
||||
|
||||
Quill.register('modules/blotFormatter', QuillBlotFormatter.default);
|
||||
|
||||
var options = {
|
||||
debug: debugLevel,
|
||||
modules: {
|
||||
toolbar: toolBar,
|
||||
blotFormatter: {}
|
||||
},
|
||||
placeholder: placeholder,
|
||||
readOnly: readOnly,
|
||||
theme: theme
|
||||
};
|
||||
|
||||
new Quill(quillElement, options);
|
||||
},
|
||||
getQuillContent: function (editorElement) {
|
||||
return JSON.stringify(editorElement.__quill.getContents());
|
||||
},
|
||||
getQuillText: function (editorElement) {
|
||||
return editorElement.__quill.getText();
|
||||
},
|
||||
getQuillHTML: function (editorElement) {
|
||||
return editorElement.__quill.root.innerHTML;
|
||||
},
|
||||
loadQuillContent: function (editorElement, editorContent) {
|
||||
return editorElement.__quill.root.innerHTML = editorContent;
|
||||
},
|
||||
enableQuillEditor: function (editorElement, mode) {
|
||||
editorElement.__quill.enable(mode);
|
||||
},
|
||||
getCurrentCursor: function (quillElement) {
|
||||
var editorIndex = 0;
|
||||
if (quillElement.__quill.getSelection() !== null) {
|
||||
editorIndex = quillElement.__quill.getSelection().index;
|
||||
}
|
||||
return editorIndex;
|
||||
},
|
||||
insertQuillImage: function (quillElement, imageURL, altText, editorIndex) {
|
||||
var Delta = Quill.import('delta');
|
||||
|
||||
return quillElement.__quill.updateContents(
|
||||
new Delta()
|
||||
.retain(editorIndex)
|
||||
.insert({ image: imageURL },
|
||||
{ alt: altText }));
|
||||
}
|
||||
};
|
8
publish/wwwroot/js/quill.min.js
vendored
Normal file
8
publish/wwwroot/js/quill.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
publish/wwwroot/js/quill.min.js.map
Normal file
1
publish/wwwroot/js/quill.min.js.map
Normal file
File diff suppressed because one or more lines are too long
8
publish/wwwroot/js/quill1.3.7.min.js
vendored
Normal file
8
publish/wwwroot/js/quill1.3.7.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
84
publish/wwwroot/js/reload.js
Normal file
84
publish/wwwroot/js/reload.js
Normal file
@ -0,0 +1,84 @@
|
||||
const scriptKeys = new Set();
|
||||
|
||||
export function onUpdate() {
|
||||
// determine if this is an initial request
|
||||
let initialRequest = scriptKeys.size === 0;
|
||||
|
||||
// iterate over all script elements in document
|
||||
const scripts = document.getElementsByTagName('script');
|
||||
for (const script of Array.from(scripts)) {
|
||||
// only process scripts that include a data-reload attribute
|
||||
if (script.hasAttribute('data-reload')) {
|
||||
let key = getKey(script);
|
||||
|
||||
if (!initialRequest) {
|
||||
// reload the script if data-reload is "always" or "true"... or if the script has not been loaded previously and data-reload is "once"
|
||||
let dataReload = script.getAttribute('data-reload');
|
||||
if ((dataReload === 'always' || dataReload === 'true') || (!scriptKeys.has(key) && dataReload == 'once')) {
|
||||
reloadScript(script);
|
||||
}
|
||||
}
|
||||
|
||||
// save the script key
|
||||
if (!scriptKeys.has(key)) {
|
||||
scriptKeys.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getKey(script) {
|
||||
if (script.src) {
|
||||
return script.src;
|
||||
} else if (script.id) {
|
||||
return script.id;
|
||||
} else {
|
||||
return script.innerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
function reloadScript(script) {
|
||||
try {
|
||||
if (isValid(script)) {
|
||||
injectScript(script);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Blazor Script Reload failed to load script: ${getKey(script)}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
function isValid(script) {
|
||||
if (script.innerHTML.includes('document.write(')) {
|
||||
console.log(`Blazor Script Reload does not support scripts using document.write(): ${script.innerHTML}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function injectScript(script) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var newScript = document.createElement('script');
|
||||
|
||||
// replicate attributes and content
|
||||
for (let i = 0; i < script.attributes.length; i++) {
|
||||
if (script.attributes[i].name !== 'data-reload') {
|
||||
newScript.setAttribute(script.attributes[i].name, script.attributes[i].value);
|
||||
}
|
||||
}
|
||||
newScript.nonce = script.nonce; // must be referenced explicitly
|
||||
newScript.innerHTML = script.innerHTML;
|
||||
|
||||
// dynamically injected scripts cannot be async or deferred
|
||||
newScript.async = false;
|
||||
newScript.defer = false;
|
||||
|
||||
newScript.onload = () => resolve();
|
||||
newScript.onerror = (error) => reject(error);
|
||||
|
||||
// inject script element in head to force execution in Blazor
|
||||
document.head.appendChild(newScript);
|
||||
|
||||
// remove data-reload attribute
|
||||
script.removeAttribute('data-reload');
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user