diff --git a/VERSION b/VERSION index 91d54fb4..decc1c18 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -20250202.2 +20250202.3 diff --git a/assets/common.css/main.css b/assets/common.css/main.css new file mode 100644 index 00000000..1dcafd4a --- /dev/null +++ b/assets/common.css/main.css @@ -0,0 +1,22 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + position: relative; +} + +html, body { + width: 100%; + height: 100%; +} + +[hidden], +.hidden { + display: none !important; + visibility: hidden !important; +} + +:root { + --font-regular: Verdana, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif; + --font-monospace: Consolas, 'Liberation Mono', Menlo, Courier, monospace; +} diff --git a/assets/common.js/array.js b/assets/common.js/array.js new file mode 100644 index 00000000..d3a05411 --- /dev/null +++ b/assets/common.js/array.js @@ -0,0 +1,27 @@ +const $arrayRemoveAt = function(array, index) { + array.splice(index, 1); +}; + +const $arrayRemoveValue = function(array, item) { + let index; + while(array.length > 0 && (index = array.indexOf(item)) >= 0) + $arrayRemoveAt(array, index); +}; + +const $arrayRemoveAny = function(array, predicate) { + let index; + while(array.length > 0 && (index = array.findIndex(predicate)) >= 0) + $arrayRemoveAt(array, index); +}; + +const $arrayShuffle = function(array) { + if(array.length < 2) + return; + + for(let i = array.length - 1; i > 0; --i) { + const j = Math.floor(Math.random() * (i + 1)); + const tmp = array[i]; + array[i] = array[j]; + array[j] = tmp; + } +}; diff --git a/assets/misuzu.js/csrf.js b/assets/common.js/csrf.js similarity index 83% rename from assets/misuzu.js/csrf.js rename to assets/common.js/csrf.js index 7df0610b..7f637da3 100644 --- a/assets/misuzu.js/csrf.js +++ b/assets/common.js/csrf.js @@ -1,10 +1,10 @@ -#include utility.js +#include html.js -const MszCSRF = (() => { +const $csrf = (() => { let elem; const getElement = () => { if(elem === undefined) - elem = $q('meta[name="csrf-token"]'); + elem = $query('meta[name="csrf-token"]'); return elem; }; diff --git a/assets/oauth2.js/utility.js b/assets/common.js/html.js similarity index 69% rename from assets/oauth2.js/utility.js rename to assets/common.js/html.js index 28bc48cd..b1fb2caf 100644 --- a/assets/oauth2.js/utility.js +++ b/assets/common.js/html.js @@ -1,32 +1,20 @@ -const $i = document.getElementById.bind(document); -const $c = document.getElementsByClassName.bind(document); -const $q = document.querySelector.bind(document); -const $qa = document.querySelectorAll.bind(document); -const $t = document.createTextNode.bind(document); +const $id = document.getElementById.bind(document); +const $query = document.querySelector.bind(document); +const $queryAll = document.querySelectorAll.bind(document); +const $text = document.createTextNode.bind(document); -const $r = function(element) { - if(element && element.parentNode) - element.parentNode.removeChild(element); -}; - -const $ri = function(name) { - $r($i(name)); -}; - -const $rq = function(query) { - $r($q(query)); -}; - -const $ib = function(ref, elem) { +const $insertBefore = function(ref, elem) { ref.parentNode.insertBefore(elem, ref); }; -const $rc = function(element) { - while(element.lastChild) - element.removeChild(element.lastChild); +const $removeChildren = function(element) { + while(element.firstChild) + element.firstChild.remove(); }; -const $e = function(info, attrs, child, created) { +const $jsx = (type, props, ...children) => $create({ tag: type, attrs: props, child: children }); + +const $create = function(info, attrs, child, created) { info = info || {}; if(typeof info === 'string') { @@ -117,15 +105,15 @@ const $e = function(info, attrs, child, created) { if(childElem instanceof Element) elem.appendChild(childElem); else - elem.appendChild($e(child)); + elem.appendChild($create(child)); } else if('getElement' in child) { const childElem = child.getElement(); if(childElem instanceof Element) elem.appendChild(childElem); else - elem.appendChild($e(child)); + elem.appendChild($create(child)); } else { - elem.appendChild($e(child)); + elem.appendChild($create(child)); } break; @@ -141,30 +129,3 @@ const $e = function(info, attrs, child, created) { return elem; }; -const $er = (type, props, ...children) => $e({ tag: type, attrs: props, child: children }); - -const $ar = function(array, index) { - array.splice(index, 1); -}; -const $ari = function(array, item) { - let index; - while(array.length > 0 && (index = array.indexOf(item)) >= 0) - $ar(array, index); -}; -const $arf = function(array, predicate) { - let index; - while(array.length > 0 && (index = array.findIndex(predicate)) >= 0) - $ar(array, index); -}; - -const $as = function(array) { - if(array.length < 2) - return; - - for(let i = array.length - 1; i > 0; --i) { - let j = Math.floor(Math.random() * (i + 1)), - tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } -}; diff --git a/assets/common.js/main.js b/assets/common.js/main.js new file mode 100644 index 00000000..d8d77481 --- /dev/null +++ b/assets/common.js/main.js @@ -0,0 +1,5 @@ +#include array.js +#include csrf.js +#include html.js +#include uniqstr.js +#include xhr.js diff --git a/assets/misuzu.js/uniqstr.js b/assets/common.js/uniqstr.js similarity index 81% rename from assets/misuzu.js/uniqstr.js rename to assets/common.js/uniqstr.js index 966ca6b6..96a2fc9c 100644 --- a/assets/misuzu.js/uniqstr.js +++ b/assets/common.js/uniqstr.js @@ -1,4 +1,4 @@ -const MszRandomInt = function(min, max) { +const $rngi = function(min, max) { let ret = 0; const range = max - min; @@ -21,18 +21,18 @@ const MszRandomInt = function(min, max) { ret &= mask; if(ret >= range) - return MszRandomInt(min, max); + return $rngi(min, max); return min + ret; }; -const MszUniqueStr = (function() { +const $rngs = (function() { const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'; return function(length) { let str = ''; for(let i = 0; i < length; ++i) - str += chars[MszRandomInt(0, chars.length)]; + str += chars[$rngi(0, chars.length)]; return str; }; })(); diff --git a/assets/oauth2.js/xhr.js b/assets/common.js/xhr.js similarity index 96% rename from assets/oauth2.js/xhr.js rename to assets/common.js/xhr.js index c6e4b870..4940aff0 100644 --- a/assets/oauth2.js/xhr.js +++ b/assets/common.js/xhr.js @@ -1,6 +1,6 @@ #include csrf.js -const $x = (function() { +const $xhr = (function() { const send = function(method, url, options, body) { if(options === undefined) options = {}; @@ -18,7 +18,7 @@ const $x = (function() { requestHeaders.set(name.toLowerCase(), options.headers[name]); if(options.csrf) - requestHeaders.set('x-csrf-token', MszCSRF.token); + requestHeaders.set('x-csrf-token', $csrf.token); if(typeof options.download === 'function') { xhr.onloadstart = ev => options.download(ev); @@ -81,7 +81,7 @@ const $x = (function() { })(xhr.getAllResponseHeaders()); if(options.csrf && headers.has('x-csrf-token')) - MszCSRF.token = headers.get('x-csrf-token'); + $csrf.token = headers.get('x-csrf-token'); resolve({ get ev() { return ev; }, diff --git a/assets/misuzu.css/main.css b/assets/misuzu.css/main.css index d761e8a0..f4088bce 100644 --- a/assets/misuzu.css/main.css +++ b/assets/misuzu.css/main.css @@ -1,27 +1,6 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; - position: relative; -} - -html, -body { - width: 100%; - height: 100%; -} - -[hidden], -.hidden { - display: none !important; - visibility: hidden !important; -} - :root { --font-size: 12px; --line-height: 20px; - --font-regular: Verdana, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif; - --font-monospace: Consolas, 'Liberation Mono', Menlo, Courier, monospace; --site-max-width: 1200px; --site-mobile-width: 800px; diff --git a/assets/misuzu.js/embed/audio.js b/assets/misuzu.js/embed/audio.js index ad61f37d..fdba11b0 100644 --- a/assets/misuzu.js/embed/audio.js +++ b/assets/misuzu.js/embed/audio.js @@ -1,4 +1,3 @@ -#include utility.js #include watcher.js const MszAudioEmbedPlayerEvents = function() { @@ -10,7 +9,7 @@ const MszAudioEmbedPlayerEvents = function() { }; const MszAudioEmbed = function(player) { - const elem = $e({ + const elem = $create({ attrs: { classList: ['aembed', 'aembed-' + player.getType()], }, @@ -25,14 +24,14 @@ const MszAudioEmbed = function(player) { target.appendChild(elem); }, insertBefore: function(ref) { - $ib(ref, elem); + $insertBefore(ref, elem); }, nuke: function() { - $r(elem); + elem.remove(); }, replaceElement(target) { - $ib(target, elem); - $r(target); + $insertBefore(target, elem); + target.remove(); }, getPlayer: function() { return player; @@ -59,7 +58,7 @@ const MszAudioEmbedPlayer = function(metadata, options) { const watchers = new MszWatchers; watchers.define(MszAudioEmbedPlayerEvents()); - const player = $e({ + const player = $create({ tag: 'audio', attrs: playerAttrs, }); @@ -72,14 +71,14 @@ const MszAudioEmbedPlayer = function(metadata, options) { target.appendChild(player); }, insertBefore: function(ref) { - $ib(ref, player); + $insertBefore(ref, player); }, nuke: function() { - $r(player); + player.remove(); }, replaceElement(target) { - $ib(target, player); - $r(target); + $insertBefore(target, player); + target.remove(); }, getType: function() { return 'external'; }, }; @@ -236,7 +235,7 @@ const MszAudioEmbedPlaceholder = function(metadata, options) { if(typeof metadata.color !== 'undefined') style.push('--aembedph-colour: ' + metadata.color); - const coverBackground = $e({ + const coverBackground = $create({ attrs: { className: 'aembedph-bg', }, @@ -252,7 +251,7 @@ const MszAudioEmbedPlaceholder = function(metadata, options) { }, }); - const coverPreview = $e({ + const coverPreview = $create({ attrs: { className: 'aembedph-info-cover', }, @@ -270,7 +269,7 @@ const MszAudioEmbedPlaceholder = function(metadata, options) { const pub = {}; - const elem = $e({ + const elem = $create({ attrs: { className: ('aembedph aembedph-' + (options.type || 'external')), style: style.join(';'), @@ -355,13 +354,13 @@ const MszAudioEmbedPlaceholder = function(metadata, options) { pub.getElement = function() { return elem; }; pub.appendTo = function(target) { target.appendChild(elem); }; - pub.insertBefore = function(ref) { $ib(ref, elem); }; + pub.insertBefore = function(ref) { $insertBefore(ref, elem); }; pub.nuke = function() { - $r(elem); + elem.remove(); }; pub.replaceElement = function(target) { - $ib(target, elem); - $r(target); + $insertBefore(target, elem); + target.remove(); }; return pub; diff --git a/assets/misuzu.js/embed/embed.js b/assets/misuzu.js/embed/embed.js index a9403be0..08201ad4 100644 --- a/assets/misuzu.js/embed/embed.js +++ b/assets/misuzu.js/embed/embed.js @@ -1,4 +1,3 @@ -#include utility.js #include embed/audio.js #include embed/image.js #include embed/video.js @@ -30,8 +29,8 @@ const MszEmbed = (function() { continue; } - $rc(target); - target.appendChild($e({ + $removeChildren(target); + target.appendChild($create({ tag: 'i', attrs: { className: 'fas fa-2x fa-spinner fa-pulse', @@ -52,7 +51,7 @@ const MszEmbed = (function() { const replaceWithUrl = function(targets, url) { for(const target of targets) { - let body = $e({ + let body = $create({ tag: 'a', attrs: { className: 'link', @@ -62,8 +61,8 @@ const MszEmbed = (function() { }, child: url }); - $ib(target, body); - $r(target); + $insertBefore(target, body); + target.remove(); } }; diff --git a/assets/misuzu.js/embed/image.js b/assets/misuzu.js/embed/image.js index 9cd387f2..4dddb6bd 100644 --- a/assets/misuzu.js/embed/image.js +++ b/assets/misuzu.js/embed/image.js @@ -1,9 +1,7 @@ -#include utility.js - const MszImageEmbed = function(metadata, options, target) { options = options || {}; - const image = $e({ + const image = $create({ tag: 'img', attrs: { alt: target.dataset.mszEmbedAlt || '', @@ -19,14 +17,14 @@ const MszImageEmbed = function(metadata, options, target) { target.appendChild(image); }, insertBefore: function(ref) { - $ib(ref, image); + $insertBefore(ref, image); }, nuke: function() { - $r(image); + image.remove(); }, replaceElement(target) { - $ib(target, image); - $r(target); + $insertBefore(target, image); + target.remove(); }, getType: function() { return 'external'; }, }; diff --git a/assets/misuzu.js/embed/video.js b/assets/misuzu.js/embed/video.js index 569816e7..8c30d064 100644 --- a/assets/misuzu.js/embed/video.js +++ b/assets/misuzu.js/embed/video.js @@ -1,5 +1,3 @@ -#include utility.js -#include uniqstr.js #include watcher.js const MszVideoEmbedPlayerEvents = function() { @@ -49,7 +47,7 @@ const MszVideoEmbed = function(playerOrFrame) { const frame = playerOrFrame; const player = 'getPlayer' in frame ? frame.getPlayer() : frame; - const elem = $e({ + const elem = $create({ attrs: { classList: ['embed', 'embed-' + player.getType()], }, @@ -64,14 +62,14 @@ const MszVideoEmbed = function(playerOrFrame) { target.appendChild(elem); }, insertBefore: function(ref) { - $ib(ref, elem); + $insertBefore(ref, elem); }, nuke: function() { - $r(elem); + elem.remove(); }, replaceElement(target) { - $ib(target, elem); - $r(target); + $insertBefore(target, elem); + target.remove(); }, getFrame: function() { return frame; @@ -93,7 +91,7 @@ const MszVideoEmbedFrame = function(player, options) { icoVolQuiet = 'fa-volume-down', icoVolLoud = 'fa-volume-up'; - const btnPlayPause = $e({ + const btnPlayPause = $create({ attrs: {}, child: { tag: 'i', @@ -103,7 +101,7 @@ const MszVideoEmbedFrame = function(player, options) { } }); - const btnStop = $e({ + const btnStop = $create({ attrs: {}, child: { tag: 'i', @@ -113,20 +111,20 @@ const MszVideoEmbedFrame = function(player, options) { }, }); - const numCurrentTime = $e({ + const numCurrentTime = $create({ attrs: {}, }); - const sldProgress = $e({ + const sldProgress = $create({ attrs: {}, child: [], }); - const numDurationRemaining = $e({ + const numDurationRemaining = $create({ attrs: {}, }); - const btnVolMute = $e({ + const btnVolMute = $create({ attrs: {}, child: { tag: 'i', @@ -140,7 +138,7 @@ const MszVideoEmbedFrame = function(player, options) { }, }); - const elem = $e({ + const elem = $create({ attrs: { className: 'embedvf', style: { @@ -185,14 +183,14 @@ const MszVideoEmbedFrame = function(player, options) { target.appendChild(elem); }, insertBefore: function(ref) { - $ib(ref, elem); + $insertBefore(ref, elem); }, nuke: function() { - $r(elem); + elem.remove(); }, replaceElement(target) { - $ib(target, elem); - $r(target); + $insertBefore(target, elem); + target.remove(); }, getPlayer: function() { return player; @@ -232,7 +230,7 @@ const MszVideoEmbedPlayer = function(metadata, options) { const watchers = new MszWatchers; watchers.define(MszVideoEmbedPlayerEvents()); - const player = $e({ + const player = $create({ tag: 'video', attrs: videoAttrs, }); @@ -251,14 +249,14 @@ const MszVideoEmbedPlayer = function(metadata, options) { target.appendChild(player); }, insertBefore: function(ref) { - $ib(ref, player); + $insertBefore(ref, player); }, nuke: function() { - $r(player); + player.remove(); }, replaceElement(target) { - $ib(target, player); - $r(target); + $insertBefore(target, player); + target.remove(); }, getType: function() { return 'external'; }, getWidth: function() { return width; }, @@ -350,7 +348,7 @@ const MszVideoEmbedYouTube = function(metadata, options) { options = options || {}; const ytOrigin = 'https://www.youtube.com', - playerId = 'yt-' + MszUniqueStr(8), + playerId = 'yt-' + $rngs(8), shouldAutoplay = options.autoplay === undefined || options.autoplay; let embedUrl = 'https://www.youtube.com/embed/' + metadata.youtube_video_id + '?enablejsapi=1'; @@ -378,7 +376,7 @@ const MszVideoEmbedYouTube = function(metadata, options) { const watchers = new MszWatchers; watchers.define(MszVideoEmbedPlayerEvents()); - const player = $e({ + const player = $create({ tag: 'iframe', attrs: { frameborder: 0, @@ -396,14 +394,14 @@ const MszVideoEmbedYouTube = function(metadata, options) { target.appendChild(player); }, insertBefore: function(ref) { - $ib(ref, player); + $insertBefore(ref, player); }, nuke: function() { - $r(player); + player.remove(); }, replaceElement(target) { - $ib(target, player); - $r(target); + $insertBefore(target, player); + target.remove(); }, getType: function() { return 'youtube'; }, getWidth: function() { return 560; }, @@ -562,7 +560,7 @@ const MszVideoEmbedNicoNico = function(metadata, options) { options = options || {}; const nndOrigin = 'https://embed.nicovideo.jp', - playerId = 'nnd-' + MszUniqueStr(8), + playerId = 'nnd-' + $rngs(8), shouldAutoplay = options.autoplay === undefined || options.autoplay; let embedUrl = 'https://embed.nicovideo.jp/watch/' + metadata.nicovideo_video_id + '?jsapi=1&playerId=' + playerId; @@ -579,7 +577,7 @@ const MszVideoEmbedNicoNico = function(metadata, options) { const watchers = new MszWatchers; watchers.define(MszVideoEmbedPlayerEvents()); - const player = $e({ + const player = $create({ tag: 'iframe', attrs: { frameborder: 0, @@ -597,14 +595,14 @@ const MszVideoEmbedNicoNico = function(metadata, options) { target.appendChild(player); }, insertBefore: function(ref) { - $ib(ref, player); + $insertBefore(ref, player); }, nuke: function() { - $r(player); + player.remove(); }, replaceElement(target) { - $ib(target, player); - $r(target); + $insertBefore(target, player); + target.remove(); }, getType: function() { return 'nicovideo'; }, getWidth: function() { return 640; }, @@ -792,7 +790,7 @@ const MszVideoEmbedPlaceholder = function(metadata, options) { const pub = {}; - const elem = $e({ + const elem = $create({ attrs: { className: ('embedph embedph-' + (options.type || 'external')), style: style.join(';'), @@ -894,13 +892,13 @@ const MszVideoEmbedPlaceholder = function(metadata, options) { pub.getElement = function() { return elem; }; pub.appendTo = function(target) { target.appendChild(elem); }; - pub.insertBefore = function(ref) { $ib(ref, elem); }; + pub.insertBefore = function(ref) { $insertBefore(ref, elem); }; pub.nuke = function() { - $r(elem); + elem.remove(); }; pub.replaceElement = function(target) { - $ib(target, elem); - $r(target); + $insertBefore(target, elem); + target.remove(); }; return pub; diff --git a/assets/misuzu.js/events/christmas2019.js b/assets/misuzu.js/events/christmas2019.js index bebdc27c..21254683 100644 --- a/assets/misuzu.js/events/christmas2019.js +++ b/assets/misuzu.js/events/christmas2019.js @@ -1,5 +1,3 @@ -#include utility.js - const MszChristmas2019EventInfo = function() { return { isActive: () => { @@ -16,8 +14,8 @@ const MszChristmas2019EventInfo = function() { const MszChristmas2019Event = function() { const propName = 'msz-christmas-' + (new Date).getFullYear().toString(); - const headerBg = $q('.header__background'); - const menuBgs = Array.from($qa('.header__desktop__submenu__background')); + const headerBg = $query('.header__background'); + const menuBgs = Array.from($queryAll('.header__desktop__submenu__background')); if(!localStorage.getItem(propName)) localStorage.setItem(propName, '0'); diff --git a/assets/misuzu.js/ext/eeprom.js b/assets/misuzu.js/ext/eeprom.js index 80abdecc..b9527d0b 100644 --- a/assets/misuzu.js/ext/eeprom.js +++ b/assets/misuzu.js/ext/eeprom.js @@ -1,5 +1,3 @@ -#include xhr.js - const MszEEPROM = function(appId, endPoint) { if(typeof appId !== 'string') throw 'appId must be a string'; @@ -44,7 +42,7 @@ const MszEEPROM = function(appId, endPoint) { formData.append('src', appId); formData.append('file', fileInput); - const { status, body } = await $x.post(`${endPoint}/uploads`, { + const { status, body } = await $xhr.post(`${endPoint}/uploads`, { type: 'json', authed: true, upload: reportProgress, @@ -79,7 +77,7 @@ const MszEEPROM = function(appId, endPoint) { if(typeof fileInfo.urlf !== 'string') throw 'fileInfo.urlf must be a string'; - const { status, body } = await $x.delete(fileInfo.urlf, { + const { status, body } = await $xhr.delete(fileInfo.urlf, { type: 'json', authed: true, }); diff --git a/assets/misuzu.js/ext/uiharu.js b/assets/misuzu.js/ext/uiharu.js index b288a8dd..089be168 100644 --- a/assets/misuzu.js/ext/uiharu.js +++ b/assets/misuzu.js/ext/uiharu.js @@ -1,5 +1,3 @@ -#include xhr.js - const MszUiharu = function(apiUrl) { const maxBatchSize = 4; const lookupOneUrl = apiUrl + '/metadata'; @@ -9,7 +7,7 @@ const MszUiharu = function(apiUrl) { if(typeof targetUrl !== 'string') throw 'targetUrl must be a string'; - return $x.post(lookupOneUrl, { type: 'json' }, targetUrl); + return $xhr.post(lookupOneUrl, { type: 'json' }, targetUrl); }, }; }; diff --git a/assets/misuzu.js/forum/editor.jsx b/assets/misuzu.js/forum/editor.jsx index 4f895722..d0719538 100644 --- a/assets/misuzu.js/forum/editor.jsx +++ b/assets/misuzu.js/forum/editor.jsx @@ -1,7 +1,6 @@ #include msgbox.jsx #include parsing.js #include utility.js -#include xhr.js #include ext/eeprom.js let MszForumEditorAllowClose = false; @@ -38,12 +37,9 @@ const MszForumEditor = function(form) { </div> </div>; - if(eepromHistory.children.length > 0) - $ib(eepromHistory.firstChild, uploadElem); - else - eepromHistory.appendChild(uploadElem); + eepromHistory.insertAdjacentElement('afterbegin', uploadElem); - const explodeUploadElem = () => $r(uploadElem); + const explodeUploadElem = () => { uploadElem.remove(); }; const uploadTask = eepromClient.create(file); uploadTask.onProgress(prog => { @@ -79,7 +75,7 @@ const MszForumEditor = function(form) { }; uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => insertTheLinkIntoTheBoxEx2()}>Insert</a>); - uploadElemProgressText.appendChild($t(' ')); + uploadElemProgressText.appendChild($text(' ')); uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => { eepromClient.delete(fileInfo) .then(() => explodeUploadElem()) @@ -172,7 +168,7 @@ const MszForumEditor = function(form) { }); const switchButtons = parser => { - $rc(markupActs); + $removeChildren(markupActs); const tags = MszParsing.getTagsFor(parser); for(const tag of tags) @@ -191,7 +187,7 @@ const MszForumEditor = function(form) { formData.append('post[text]', text); formData.append('post[parser]', parseInt(parser)); - return (await $x.post('/forum/posting.php', { authed: true }, formData)).body; + return (await $xhr.post('/forum/posting.php', { authed: true }, formData)).body; }; const previewBtn = <button class="input__button" type="button" value="preview">Preview</button>; @@ -233,7 +229,7 @@ const MszForumEditor = function(form) { lastPostParser = postParser; previewElem.innerHTML = body; - MszEmbed.handle($qa('.js-msz-embed-media')); + MszEmbed.handle($queryAll('.js-msz-embed-media')); previewElem.removeAttribute('hidden'); textElem.setAttribute('hidden', 'hidden'); @@ -276,7 +272,7 @@ const MszForumEditor = function(form) { lastPostParser = postParser; previewElem.innerHTML = body; - MszEmbed.handle($qa('.js-msz-embed-media')); + MszEmbed.handle($queryAll('.js-msz-embed-media')); previewBtn.removeAttribute('disabled'); parserElem.removeAttribute('disabled'); diff --git a/assets/misuzu.js/main.js b/assets/misuzu.js/main.js index d1e4b222..5f6c5dc9 100644 --- a/assets/misuzu.js/main.js +++ b/assets/misuzu.js/main.js @@ -1,6 +1,4 @@ #include msgbox.jsx -#include utility.js -#include xhr.js #include embed/embed.js #include events/christmas2019.js #include events/events.js @@ -10,7 +8,7 @@ (async () => { const initLoginPage = async () => { - const forms = Array.from($qa('.js-login-form')); + const forms = Array.from($queryAll('.js-login-form')); if(forms.length < 1) return; @@ -18,7 +16,7 @@ if(!(avatar instanceof Element) || !(userName instanceof Element)) return; - const { body } = await $x.get(`/auth/login.php?resolve=1&name=${encodeURIComponent(userName.value)}`, { type: 'json' }); + const { body } = await $xhr.get(`/auth/login.php?resolve=1&name=${encodeURIComponent(userName.value)}`, { type: 'json' }); avatar.src = body.avatar; if(body.name.length > 0) @@ -48,7 +46,7 @@ }; const initQuickSubmit = () => { - const elems = Array.from($qa('.js-quick-submit, .js-ctrl-enter-submit')); + const elems = Array.from($queryAll('.js-quick-submit, .js-ctrl-enter-submit')); if(elems.length < 1) return; @@ -66,7 +64,7 @@ }; const initXhrActions = () => { - const targets = Array.from($qa('a[data-url], button[data-url]')); + const targets = Array.from($queryAll('a[data-url], button[data-url]')); for(const target of targets) { target.onclick = async () => { if(target.disabled) @@ -89,7 +87,7 @@ if(target.dataset.confirm && !await MszShowConfirmBox(target.dataset.confirm, 'Are you sure?')) return; - const { status, body } = await $x.send( + const { status, body } = await $xhr.send( target.dataset.method ?? 'GET', url, { @@ -125,7 +123,7 @@ }; try { - MszSakuya.trackElements($qa('time')); + MszSakuya.trackElements($queryAll('time')); hljs.highlightAll(); MszEmbed.init(`${location.protocol}//uiharu.${location.host}`); @@ -134,7 +132,7 @@ // only used by the forum posting form initQuickSubmit(); - const forumPostingForm = $q('.js-forum-posting'); + const forumPostingForm = $query('.js-forum-posting'); if(forumPostingForm !== null) MszForumEditor(forumPostingForm); @@ -146,7 +144,7 @@ MszMessages(); - MszEmbed.handle($qa('.js-msz-embed-media')); + MszEmbed.handle($queryAll('.js-msz-embed-media')); } catch(ex) { console.error(ex); } diff --git a/assets/misuzu.js/messages/list.js b/assets/misuzu.js/messages/list.js index 45f12c1a..8a43bb7b 100644 --- a/assets/misuzu.js/messages/list.js +++ b/assets/misuzu.js/messages/list.js @@ -1,4 +1,3 @@ -#include utility.js #include watcher.js const MsgMessagesList = function(list) { @@ -55,8 +54,8 @@ const MsgMessagesList = function(list) { return selected; }, removeItem: item => { - $ari(items, item); - $r(item.getElement()); + $arrayRemoveValue(items, item); + item.getElement().remove(); recountSelected(); watchers.call('select', selectedCount, items.length); }, diff --git a/assets/misuzu.js/messages/messages.js b/assets/misuzu.js/messages/messages.js index 4f8f4d7c..597af8ec 100644 --- a/assets/misuzu.js/messages/messages.js +++ b/assets/misuzu.js/messages/messages.js @@ -1,6 +1,4 @@ #include msgbox.jsx -#include utility.js -#include xhr.js #include messages/actbtn.js #include messages/list.js #include messages/recipient.js @@ -40,7 +38,7 @@ const MszMessages = () => { formData.append('recipient', recipient); formData.append('reply', replyTo); - const { body } = await $x.post('/messages/create', { type: 'json', csrf: true }, formData); + const { body } = await $xhr.post('/messages/create', { type: 'json', csrf: true }, formData); if(body.error !== undefined) throw body.error; @@ -54,7 +52,7 @@ const MszMessages = () => { formData.append('parser', parser); formData.append('draft', draft); - const { body } = await $x.post(`/messages/${encodeURIComponent(messageId)}`, { type: 'json', csrf: true }, formData); + const { body } = await $xhr.post(`/messages/${encodeURIComponent(messageId)}`, { type: 'json', csrf: true }, formData); if(body.error !== undefined) throw body.error; @@ -62,7 +60,7 @@ const MszMessages = () => { }; const msgsMark = async (msgs, state) => { - const { body } = await $x.post('/messages/mark', { type: 'json', csrf: true }, { + const { body } = await $xhr.post('/messages/mark', { type: 'json', csrf: true }, { type: state, messages: msgs.map(extractMsgIds).join(','), }); @@ -73,7 +71,7 @@ const MszMessages = () => { }; const msgsDelete = async msgs => { - const { body } = await $x.post('/messages/delete', { type: 'json', csrf: true }, { + const { body } = await $xhr.post('/messages/delete', { type: 'json', csrf: true }, { messages: msgs.map(extractMsgIds).join(','), }); if(body.error !== undefined) @@ -83,7 +81,7 @@ const MszMessages = () => { }; const msgsRestore = async msgs => { - const { body } = await $x.post('/messages/restore', { type: 'json', csrf: true }, { + const { body } = await $xhr.post('/messages/restore', { type: 'json', csrf: true }, { messages: msgs.map(extractMsgIds).join(','), }); if(body.error !== undefined) @@ -93,7 +91,7 @@ const MszMessages = () => { }; const msgsNuke = async msgs => { - const { body } = await $x.post('/messages/nuke', { type: 'json', csrf: true }, { + const { body } = await $xhr.post('/messages/nuke', { type: 'json', csrf: true }, { messages: msgs.map(extractMsgIds).join(','), }); if(body.error !== undefined) @@ -102,28 +100,28 @@ const MszMessages = () => { return true; }; - const msgsUserBtns = Array.from($qa('.js-header-pms-button')); + const msgsUserBtns = Array.from($queryAll('.js-header-pms-button')); if(msgsUserBtns.length > 0) - $x.get('/messages/stats', { type: 'json' }).then(result => { + $xhr.get('/messages/stats', { type: 'json' }).then(result => { const body = result.body; if(typeof body === 'object' && typeof body.unread === 'number') if(body.unread > 0) for(const msgsUserBtn of msgsUserBtns) - msgsUserBtn.append($e({ child: body.unread.toLocaleString(), attrs: { className: 'header__desktop__user__button__count' } })); + msgsUserBtn.append($create({ child: body.unread.toLocaleString(), attrs: { className: 'header__desktop__user__button__count' } })); }); - const msgsListElem = $q('.js-messages-list'); + const msgsListElem = $query('.js-messages-list'); const msgsList = msgsListElem instanceof Element ? new MsgMessagesList(msgsListElem) : undefined; - const msgsListEmptyNotice = $q('.js-messages-folder-empty'); + const msgsListEmptyNotice = $query('.js-messages-folder-empty'); - const msgsThreadElem = $q('.js-messages-thread'); + const msgsThreadElem = $query('.js-messages-thread'); const msgsThread = msgsThreadElem instanceof Element ? new MszMessagesThread(msgsThreadElem) : undefined; - const msgsRecipientElem = $q('.js-messages-recipient'); + const msgsRecipientElem = $query('.js-messages-recipient'); const msgsRecipient = msgsRecipientElem instanceof Element ? new MszMessagesRecipient(msgsRecipientElem) : undefined; - const msgsReplyElem = $q('.js-messages-reply'); + const msgsReplyElem = $query('.js-messages-reply'); const msgsReply = msgsReplyElem instanceof Element ? new MszMessagesReply(msgsReplyElem) : undefined; if(msgsReply !== undefined) { @@ -165,7 +163,7 @@ const MszMessages = () => { let actSelectAll, actMarkRead, actMoveTrash, actNuke; - const actSelectAllBtn = $q('.js-messages-actions-select-all'); + const actSelectAllBtn = $query('.js-messages-actions-select-all'); if(actSelectAllBtn instanceof Element) { actSelectAll = new MszMessagesActionButton(actSelectAllBtn); @@ -181,7 +179,7 @@ const MszMessages = () => { } } - const actMarkReadBtn = $q('.js-messages-actions-mark-read'); + const actMarkReadBtn = $query('.js-messages-actions-mark-read'); if(actMarkReadBtn instanceof Element) { actMarkRead = new MszMessagesActionButton(actMarkReadBtn); @@ -241,7 +239,7 @@ const MszMessages = () => { } } - const actMoveTrashBtn = $q('.js-messages-actions-move-trash'); + const actMoveTrashBtn = $query('.js-messages-actions-move-trash'); if(actMoveTrashBtn instanceof Element) { actMoveTrash = new MszMessagesActionButton(actMoveTrashBtn); @@ -303,7 +301,7 @@ const MszMessages = () => { } } - const actNukeBtn = $q('.js-messages-actions-nuke'); + const actNukeBtn = $query('.js-messages-actions-nuke'); if(actNukeBtn instanceof Element) { actNuke = new MszMessagesActionButton(actNukeBtn, true); diff --git a/assets/misuzu.js/messages/recipient.js b/assets/misuzu.js/messages/recipient.js index 4dcb2591..3ebfd9f5 100644 --- a/assets/misuzu.js/messages/recipient.js +++ b/assets/misuzu.js/messages/recipient.js @@ -1,5 +1,3 @@ -#include xhr.js - const MszMessagesRecipient = function(element) { if(!(element instanceof Element)) throw 'element must be an instance of Element'; @@ -9,7 +7,7 @@ const MszMessagesRecipient = function(element) { let updateHandler = undefined; const update = async () => { - const { body } = await $x.post(element.dataset.msgLookup, { type: 'json', csrf: true }, { + const { body } = await $xhr.post(element.dataset.msgLookup, { type: 'json', csrf: true }, { name: nameInput.value, }); diff --git a/assets/misuzu.js/messages/reply.jsx b/assets/misuzu.js/messages/reply.jsx index 4660a8f5..3d41cb7d 100644 --- a/assets/misuzu.js/messages/reply.jsx +++ b/assets/misuzu.js/messages/reply.jsx @@ -1,4 +1,5 @@ #include parsing.js +#include utility.js #include ext/eeprom.js const MszMessagesReply = function(element) { @@ -46,7 +47,7 @@ const MszMessagesReply = function(element) { }); const switchButtons = parser => { - $rc(actsElem); + $removeChildren(actsElem); const tags = MszParsing.getTagsFor(parser); actsElem.hidden = tags.length < 1; diff --git a/assets/misuzu.js/msgbox.jsx b/assets/misuzu.js/msgbox.jsx index 0051eefa..4afa4377 100644 --- a/assets/misuzu.js/msgbox.jsx +++ b/assets/misuzu.js/msgbox.jsx @@ -1,5 +1,3 @@ -#include utility.js - const MszShowConfirmBox = async (text, title, target) => { let result = false; diff --git a/assets/misuzu.js/utility.js b/assets/misuzu.js/utility.js index cf35cc39..15a8d657 100644 --- a/assets/misuzu.js/utility.js +++ b/assets/misuzu.js/utility.js @@ -1,174 +1,3 @@ -const $i = document.getElementById.bind(document); -const $c = document.getElementsByClassName.bind(document); -const $q = document.querySelector.bind(document); -const $qa = document.querySelectorAll.bind(document); -const $t = document.createTextNode.bind(document); - -const $r = function(element) { - if(element && element.parentNode) - element.parentNode.removeChild(element); -}; - -const $ri = function(name) { - $r($i(name)); -}; - -const $rq = function(query) { - $r($q(query)); -}; - -const $ib = function(ref, elem) { - ref.parentNode.insertBefore(elem, ref); -}; - -const $rc = function(element) { - while(element.lastChild) - element.removeChild(element.lastChild); -}; - -const $e = function(info, attrs, child, created) { - info = info || {}; - - if(typeof info === 'string') { - info = {tag: info}; - if(attrs) - info.attrs = attrs; - if(child) - info.child = child; - if(created) - info.created = created; - } - - const elem = document.createElement(info.tag || 'div'); - - if(info.attrs) { - const attrs = info.attrs; - - for(let key in attrs) { - const attr = attrs[key]; - if(attr === undefined || attr === null) - continue; - - switch(typeof attr) { - case 'function': - if(key.substring(0, 2) === 'on') - key = key.substring(2).toLowerCase(); - elem.addEventListener(key, attr); - break; - - case 'object': - if(attr instanceof Array) { - if(key === 'class') - key = 'classList'; - - const prop = elem[key]; - let addFunc = null; - - if(prop instanceof Array) - addFunc = prop.push.bind(prop); - else if(prop instanceof DOMTokenList) - addFunc = prop.add.bind(prop); - - if(addFunc !== null) { - for(let j = 0; j < attr.length; ++j) - addFunc(attr[j]); - } else { - if(key === 'classList') - key = 'class'; - elem.setAttribute(key, attr.toString()); - } - } else { - for(const attrKey in attr) - elem[key][attrKey] = attr[attrKey]; - } - break; - - case 'boolean': - if(attr) - elem.setAttribute(key, ''); - break; - - default: - if(key === 'className') - key = 'class'; - elem.setAttribute(key, attr.toString()); - break; - } - } - } - - if(info.child) { - let children = info.child; - - if(!Array.isArray(children)) - children = [children]; - - for(const child of children) { - switch(typeof child) { - case 'string': - elem.appendChild(document.createTextNode(child)); - break; - - case 'object': - if(child instanceof Element) { - elem.appendChild(child); - } else if('element' in child) { - const childElem = child.element; - if(childElem instanceof Element) - elem.appendChild(childElem); - else - elem.appendChild($e(child)); - } else if('getElement' in child) { - const childElem = child.getElement(); - if(childElem instanceof Element) - elem.appendChild(childElem); - else - elem.appendChild($e(child)); - } else { - elem.appendChild($e(child)); - } - break; - - default: - elem.appendChild(document.createTextNode(child.toString())); - break; - } - } - } - - if(info.created) - info.created(elem); - - return elem; -}; -const $er = (type, props, ...children) => $e({ tag: type, attrs: props, child: children }); - -const $ar = function(array, index) { - array.splice(index, 1); -}; -const $ari = function(array, item) { - let index; - while(array.length > 0 && (index = array.indexOf(item)) >= 0) - $ar(array, index); -}; -const $arf = function(array, predicate) { - let index; - while(array.length > 0 && (index = array.findIndex(predicate)) >= 0) - $ar(array, index); -}; - -const $as = function(array) { - if(array.length < 2) - return; - - for(let i = array.length - 1; i > 0; --i) { - let j = Math.floor(Math.random() * (i + 1)), - tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } -}; - const $insertTags = function(target, tagOpen, tagClose) { tagOpen = tagOpen || ''; tagClose = tagClose || ''; diff --git a/assets/misuzu.js/watcher.js b/assets/misuzu.js/watcher.js index fdca3c17..2b6fbc71 100644 --- a/assets/misuzu.js/watcher.js +++ b/assets/misuzu.js/watcher.js @@ -13,7 +13,7 @@ const MszWatcher = function() { }; const unwatch = handler => { - $ari(handlers, handler); + $arrayRemoveValue(handlers, handler); }; return { diff --git a/assets/misuzu.js/xhr.js b/assets/misuzu.js/xhr.js deleted file mode 100644 index c6e4b870..00000000 --- a/assets/misuzu.js/xhr.js +++ /dev/null @@ -1,117 +0,0 @@ -#include csrf.js - -const $x = (function() { - const send = function(method, url, options, body) { - if(options === undefined) - options = {}; - else if(typeof options !== 'object') - throw 'options must be undefined or an object'; - - Object.freeze(options); - - const xhr = new XMLHttpRequest; - const requestHeaders = new Map; - - if('headers' in options && typeof options.headers === 'object') - for(const name in options.headers) - if(options.headers.hasOwnProperty(name)) - requestHeaders.set(name.toLowerCase(), options.headers[name]); - - if(options.csrf) - requestHeaders.set('x-csrf-token', MszCSRF.token); - - if(typeof options.download === 'function') { - xhr.onloadstart = ev => options.download(ev); - xhr.onprogress = ev => options.download(ev); - xhr.onloadend = ev => options.download(ev); - } - - if(typeof options.upload === 'function') { - xhr.upload.onloadstart = ev => options.upload(ev); - xhr.upload.onprogress = ev => options.upload(ev); - xhr.upload.onloadend = ev => options.upload(ev); - } - - if(options.authed) - xhr.withCredentials = true; - - if(typeof options.timeout === 'number') - xhr.timeout = options.timeout; - - if(typeof options.type === 'string') - xhr.responseType = options.type; - - if(typeof options.abort === 'function') - options.abort(() => xhr.abort()); - - if(typeof options.xhr === 'function') - options.xhr(() => xhr); - - if(typeof body === 'object') { - if(body instanceof URLSearchParams) { - requestHeaders.set('content-type', 'application/x-www-form-urlencoded'); - } else if(body instanceof FormData) { - // content-type is implicitly set - } else if(body instanceof Blob || body instanceof ArrayBuffer || body instanceof DataView) { - if(!requestHeaders.has('content-type')) - requestHeaders.set('content-type', 'application/octet-stream'); - } else if(!requestHeaders.has('content-type')) { - const bodyParts = []; - for(const name in body) - if(body.hasOwnProperty(name)) - bodyParts.push(encodeURIComponent(name) + '=' + encodeURIComponent(body[name])); - body = bodyParts.join('&'); - requestHeaders.set('content-type', 'application/x-www-form-urlencoded'); - } - } - - return new Promise((resolve, reject) => { - xhr.onload = ev => { - const headers = (headersString => { - const headers = new Map; - - const raw = headersString.trim().split(/[\r\n]+/); - for(const name in raw) - if(raw.hasOwnProperty(name)) { - const parts = raw[name].split(': '); - headers.set(parts.shift(), parts.join(': ')); - } - - return headers; - })(xhr.getAllResponseHeaders()); - - if(options.csrf && headers.has('x-csrf-token')) - MszCSRF.token = headers.get('x-csrf-token'); - - resolve({ - get ev() { return ev; }, - get xhr() { return xhr; }, - - get status() { return xhr.status; }, - get headers() { return headers; }, - get body() { return xhr.response; }, - get text() { return xhr.responseText; }, - }); - }; - - xhr.onerror = ev => reject({ - xhr: xhr, - ev: ev, - }); - - xhr.open(method, url); - for(const [name, value] of requestHeaders) - xhr.setRequestHeader(name, value); - xhr.send(body); - }); - }; - - return { - send: send, - get: (url, options, body) => send('GET', url, options, body), - post: (url, options, body) => send('POST', url, options, body), - delete: (url, options, body) => send('DELETE', url, options, body), - patch: (url, options, body) => send('PATCH', url, options, body), - put: (url, options, body) => send('PUT', url, options, body), - }; -})(); diff --git a/assets/oauth2.css/main.css b/assets/oauth2.css/main.css index cf9e4bce..8dbcda53 100644 --- a/assets/oauth2.css/main.css +++ b/assets/oauth2.css/main.css @@ -1,25 +1,3 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; - position: relative; -} - -html, body { - width: 100%; - height: 100%; -} - -[hidden], -.hidden { - display: none !important; -} - -:root { - --font-regular: Verdana, Geneva, 'Dejavu Sans', Arial, Helvetica, sans-serif; - --font-monospace: Consolas, 'Liberation Mono', Menlo, Courier, monospace; -} - body { background-color: #111; color: #fff; diff --git a/assets/oauth2.js/authorise.js b/assets/oauth2.js/authorise.js index 1a61babe..f76f30c4 100644 --- a/assets/oauth2.js/authorise.js +++ b/assets/oauth2.js/authorise.js @@ -1,5 +1,4 @@ #include loading.jsx -#include xhr.js #include app/info.jsx #include app/scope.jsx #include header/header.js @@ -158,7 +157,7 @@ const MszOAuth2Authorise = async () => { } try { - const { body } = await $x.get(`/oauth2/resolve-authorise-app?${resolveParams}`, { authed: true, csrf: true, type: 'json' }); + const { body } = await $xhr.get(`/oauth2/resolve-authorise-app?${resolveParams}`, { authed: true, csrf: true, type: 'json' }); if(!body) throw 'authorisation resolve failed'; if(typeof body.error === 'string') { @@ -185,7 +184,7 @@ const MszOAuth2Authorise = async () => { params.scope = scope; try { - const { body } = await $x.post('/oauth2/authorise', { authed: true, csrf: true, type: 'json' }, params); + const { body } = await $xhr.post('/oauth2/authorise', { authed: true, csrf: true, type: 'json' }, params); if(!body) throw 'authorisation failed'; if(typeof body.error === 'string') diff --git a/assets/oauth2.js/csrf.js b/assets/oauth2.js/csrf.js deleted file mode 100644 index 7df0610b..00000000 --- a/assets/oauth2.js/csrf.js +++ /dev/null @@ -1,24 +0,0 @@ -#include utility.js - -const MszCSRF = (() => { - let elem; - const getElement = () => { - if(elem === undefined) - elem = $q('meta[name="csrf-token"]'); - return elem; - }; - - return { - get token() { - return getElement()?.content ?? ''; - }, - set token(token) { - if(typeof token !== 'string') - throw 'token must be a string'; - - const elem = getElement(); - if(elem instanceof HTMLMetaElement) - elem.content = token; - }, - }; -})(); diff --git a/assets/oauth2.js/main.js b/assets/oauth2.js/main.js index e7238927..382b76b0 100644 --- a/assets/oauth2.js/main.js +++ b/assets/oauth2.js/main.js @@ -1,4 +1,3 @@ -#include utility.js #include authorise.js #include verify.js diff --git a/assets/oauth2.js/verify.js b/assets/oauth2.js/verify.js index 5b8ddb2c..9921ef84 100644 --- a/assets/oauth2.js/verify.js +++ b/assets/oauth2.js/verify.js @@ -1,5 +1,4 @@ #include loading.jsx -#include xhr.js #include app/info.jsx #include app/scope.jsx #include header/header.js @@ -22,7 +21,7 @@ const MszOAuth2Verify = () => { const verifyAuthsRequest = async approve => { try { - const { body } = await $x.post('/oauth2/verify', { authed: true, csrf: true, type: 'json' }, { + const { body } = await $xhr.post('/oauth2/verify', { authed: true, csrf: true, type: 'json' }, { code: userCode, approve: approve === true ? 'yes' : 'no', }); @@ -91,7 +90,7 @@ const MszOAuth2Verify = () => { fCode.classList.add('hidden'); userCode = encodeURIComponent(eUserCode.value); - $x.get(`/oauth2/resolve-verify?code=${userCode}`, { authed: true, csrf: true, type: 'json' }) + $xhr.get(`/oauth2/resolve-verify?code=${userCode}`, { authed: true, csrf: true, type: 'json' }) .then(result => { const body = result.body; diff --git a/build.js b/build.js index 35fe521b..6c9a5ee4 100644 --- a/build.js +++ b/build.js @@ -12,11 +12,13 @@ const fs = require('fs'); debug: isDebug, swc: { es: 'es2021', + jsx: '$jsx', }, }; const tasks = { js: [ + { source: 'common.js', target: '/assets', name: 'common.{hash}.js', }, { source: 'misuzu.js', target: '/assets', name: 'misuzu.{hash}.js', }, { source: 'oauth2.js', target: '/assets', name: 'oauth2.{hash}.js', }, { source: 'redir-bsky.js', target: '/assets', name: 'redir-bsky.{hash}.js', }, @@ -24,6 +26,7 @@ const fs = require('fs'); ], css: [ { source: 'errors.css', target: '/', name: 'errors.css', }, + { source: 'common.css', target: '/assets', name: 'common.{hash}.css', }, { source: 'misuzu.css', target: '/assets', name: 'misuzu.{hash}.css', }, { source: 'oauth2.css', target: '/assets', name: 'oauth2.{hash}.css', }, ], diff --git a/templates/errors/master.twig b/templates/errors/master.twig index 2c264bc8..89db9d99 100644 --- a/templates/errors/master.twig +++ b/templates/errors/master.twig @@ -7,7 +7,7 @@ {% block html_head %} <meta name="description" content="{{ error_blerb }}"> <link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet"> - <link href="{{ asset('errors.css') }}" rel="stylesheet"> + <link href="/errors.css" rel="stylesheet"> <style> :root { --error-colour: {{ error_colour }}; diff --git a/templates/manage/users/ban.twig b/templates/manage/users/ban.twig index c1b1ca4a..79e320da 100644 --- a/templates/manage/users/ban.twig +++ b/templates/manage/users/ban.twig @@ -51,10 +51,10 @@ <script> window.addEventListener('load', function() { - const ubExpires = $i('ub_expires'), - ubExpiresCustom = $i('ub_expires_custom'), - ubSeverity = $i('ub_severity'), - ubSeverityDisplay = $i('ub_severity_display'); + const ubExpires = $id('ub_expires'), + ubExpiresCustom = $id('ub_expires_custom'), + ubSeverity = $id('ub_severity'), + ubSeverityDisplay = $id('ub_severity_display'); const updateExpires = function() { ubExpiresCustom.parentNode.classList.toggle('manage__ban__duration__value__custom--hidden', ubExpires.value != '-2'); diff --git a/templates/master.twig b/templates/master.twig index 1b014ca5..962c13e0 100644 --- a/templates/master.twig +++ b/templates/master.twig @@ -3,6 +3,7 @@ {% block html_head %} {% include '_layout/meta.twig' %} <link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet"> + <link href="{{ asset('common.css') }}" type="text/css" rel="stylesheet"> <link href="{{ asset('misuzu.css') }}" type="text/css" rel="stylesheet"> {% if site_background is defined %} <style> @@ -62,5 +63,6 @@ {% endblock %} <script src="/vendor/highlightjs/highlight.min.js" type="text/javascript"></script> + <script src="{{ asset('common.js') }}" type="text/javascript"></script> <script src="{{ asset('misuzu.js') }}" type="text/javascript"></script> {% endblock %} diff --git a/templates/oauth2/master.twig b/templates/oauth2/master.twig index cecb0cde..342c7a93 100644 --- a/templates/oauth2/master.twig +++ b/templates/oauth2/master.twig @@ -3,6 +3,7 @@ {% set html_title = (title is defined ? (title ~ ' :: ') : '') ~ globals.site_info.name %} {% block html_head %} + <link href="{{ asset('common.css') }}" rel="stylesheet"> <link href="{{ asset('oauth2.css') }}" rel="stylesheet"> {% endblock %} @@ -35,5 +36,6 @@ </div> </div> </div> + <script src="{{ asset('common.js') }}"></script> <script src="{{ asset('oauth2.js') }}"></script> {% endblock %}