Moved common JS and CSS to separate file.

This commit is contained in:
flash 2025-02-02 21:27:31 +00:00
commit 2d6f9d0f1b
36 changed files with 204 additions and 564 deletions

View file

@ -1 +1 @@
20250202.2 20250202.3

View file

@ -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;
}

27
assets/common.js/array.js Normal file
View file

@ -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;
}
};

View file

@ -1,10 +1,10 @@
#include utility.js #include html.js
const MszCSRF = (() => { const $csrf = (() => {
let elem; let elem;
const getElement = () => { const getElement = () => {
if(elem === undefined) if(elem === undefined)
elem = $q('meta[name="csrf-token"]'); elem = $query('meta[name="csrf-token"]');
return elem; return elem;
}; };

View file

@ -1,32 +1,20 @@
const $i = document.getElementById.bind(document); const $id = document.getElementById.bind(document);
const $c = document.getElementsByClassName.bind(document); const $query = document.querySelector.bind(document);
const $q = document.querySelector.bind(document); const $queryAll = document.querySelectorAll.bind(document);
const $qa = document.querySelectorAll.bind(document); const $text = document.createTextNode.bind(document);
const $t = document.createTextNode.bind(document);
const $r = function(element) { const $insertBefore = function(ref, elem) {
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); ref.parentNode.insertBefore(elem, ref);
}; };
const $rc = function(element) { const $removeChildren = function(element) {
while(element.lastChild) while(element.firstChild)
element.removeChild(element.lastChild); 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 || {}; info = info || {};
if(typeof info === 'string') { if(typeof info === 'string') {
@ -117,15 +105,15 @@ const $e = function(info, attrs, child, created) {
if(childElem instanceof Element) if(childElem instanceof Element)
elem.appendChild(childElem); elem.appendChild(childElem);
else else
elem.appendChild($e(child)); elem.appendChild($create(child));
} else if('getElement' in child) { } else if('getElement' in child) {
const childElem = child.getElement(); const childElem = child.getElement();
if(childElem instanceof Element) if(childElem instanceof Element)
elem.appendChild(childElem); elem.appendChild(childElem);
else else
elem.appendChild($e(child)); elem.appendChild($create(child));
} else { } else {
elem.appendChild($e(child)); elem.appendChild($create(child));
} }
break; break;
@ -141,30 +129,3 @@ const $e = function(info, attrs, child, created) {
return 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;
}
};

5
assets/common.js/main.js Normal file
View file

@ -0,0 +1,5 @@
#include array.js
#include csrf.js
#include html.js
#include uniqstr.js
#include xhr.js

View file

@ -1,4 +1,4 @@
const MszRandomInt = function(min, max) { const $rngi = function(min, max) {
let ret = 0; let ret = 0;
const range = max - min; const range = max - min;
@ -21,18 +21,18 @@ const MszRandomInt = function(min, max) {
ret &= mask; ret &= mask;
if(ret >= range) if(ret >= range)
return MszRandomInt(min, max); return $rngi(min, max);
return min + ret; return min + ret;
}; };
const MszUniqueStr = (function() { const $rngs = (function() {
const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'; const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789';
return function(length) { return function(length) {
let str = ''; let str = '';
for(let i = 0; i < length; ++i) for(let i = 0; i < length; ++i)
str += chars[MszRandomInt(0, chars.length)]; str += chars[$rngi(0, chars.length)];
return str; return str;
}; };
})(); })();

View file

@ -1,6 +1,6 @@
#include csrf.js #include csrf.js
const $x = (function() { const $xhr = (function() {
const send = function(method, url, options, body) { const send = function(method, url, options, body) {
if(options === undefined) if(options === undefined)
options = {}; options = {};
@ -18,7 +18,7 @@ const $x = (function() {
requestHeaders.set(name.toLowerCase(), options.headers[name]); requestHeaders.set(name.toLowerCase(), options.headers[name]);
if(options.csrf) if(options.csrf)
requestHeaders.set('x-csrf-token', MszCSRF.token); requestHeaders.set('x-csrf-token', $csrf.token);
if(typeof options.download === 'function') { if(typeof options.download === 'function') {
xhr.onloadstart = ev => options.download(ev); xhr.onloadstart = ev => options.download(ev);
@ -81,7 +81,7 @@ const $x = (function() {
})(xhr.getAllResponseHeaders()); })(xhr.getAllResponseHeaders());
if(options.csrf && headers.has('x-csrf-token')) if(options.csrf && headers.has('x-csrf-token'))
MszCSRF.token = headers.get('x-csrf-token'); $csrf.token = headers.get('x-csrf-token');
resolve({ resolve({
get ev() { return ev; }, get ev() { return ev; },

View file

@ -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 { :root {
--font-size: 12px; --font-size: 12px;
--line-height: 20px; --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-max-width: 1200px;
--site-mobile-width: 800px; --site-mobile-width: 800px;

View file

@ -1,4 +1,3 @@
#include utility.js
#include watcher.js #include watcher.js
const MszAudioEmbedPlayerEvents = function() { const MszAudioEmbedPlayerEvents = function() {
@ -10,7 +9,7 @@ const MszAudioEmbedPlayerEvents = function() {
}; };
const MszAudioEmbed = function(player) { const MszAudioEmbed = function(player) {
const elem = $e({ const elem = $create({
attrs: { attrs: {
classList: ['aembed', 'aembed-' + player.getType()], classList: ['aembed', 'aembed-' + player.getType()],
}, },
@ -25,14 +24,14 @@ const MszAudioEmbed = function(player) {
target.appendChild(elem); target.appendChild(elem);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, elem); $insertBefore(ref, elem);
}, },
nuke: function() { nuke: function() {
$r(elem); elem.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, elem); $insertBefore(target, elem);
$r(target); target.remove();
}, },
getPlayer: function() { getPlayer: function() {
return player; return player;
@ -59,7 +58,7 @@ const MszAudioEmbedPlayer = function(metadata, options) {
const watchers = new MszWatchers; const watchers = new MszWatchers;
watchers.define(MszAudioEmbedPlayerEvents()); watchers.define(MszAudioEmbedPlayerEvents());
const player = $e({ const player = $create({
tag: 'audio', tag: 'audio',
attrs: playerAttrs, attrs: playerAttrs,
}); });
@ -72,14 +71,14 @@ const MszAudioEmbedPlayer = function(metadata, options) {
target.appendChild(player); target.appendChild(player);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, player); $insertBefore(ref, player);
}, },
nuke: function() { nuke: function() {
$r(player); player.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, player); $insertBefore(target, player);
$r(target); target.remove();
}, },
getType: function() { return 'external'; }, getType: function() { return 'external'; },
}; };
@ -236,7 +235,7 @@ const MszAudioEmbedPlaceholder = function(metadata, options) {
if(typeof metadata.color !== 'undefined') if(typeof metadata.color !== 'undefined')
style.push('--aembedph-colour: ' + metadata.color); style.push('--aembedph-colour: ' + metadata.color);
const coverBackground = $e({ const coverBackground = $create({
attrs: { attrs: {
className: 'aembedph-bg', className: 'aembedph-bg',
}, },
@ -252,7 +251,7 @@ const MszAudioEmbedPlaceholder = function(metadata, options) {
}, },
}); });
const coverPreview = $e({ const coverPreview = $create({
attrs: { attrs: {
className: 'aembedph-info-cover', className: 'aembedph-info-cover',
}, },
@ -270,7 +269,7 @@ const MszAudioEmbedPlaceholder = function(metadata, options) {
const pub = {}; const pub = {};
const elem = $e({ const elem = $create({
attrs: { attrs: {
className: ('aembedph aembedph-' + (options.type || 'external')), className: ('aembedph aembedph-' + (options.type || 'external')),
style: style.join(';'), style: style.join(';'),
@ -355,13 +354,13 @@ const MszAudioEmbedPlaceholder = function(metadata, options) {
pub.getElement = function() { return elem; }; pub.getElement = function() { return elem; };
pub.appendTo = function(target) { target.appendChild(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() { pub.nuke = function() {
$r(elem); elem.remove();
}; };
pub.replaceElement = function(target) { pub.replaceElement = function(target) {
$ib(target, elem); $insertBefore(target, elem);
$r(target); target.remove();
}; };
return pub; return pub;

View file

@ -1,4 +1,3 @@
#include utility.js
#include embed/audio.js #include embed/audio.js
#include embed/image.js #include embed/image.js
#include embed/video.js #include embed/video.js
@ -30,8 +29,8 @@ const MszEmbed = (function() {
continue; continue;
} }
$rc(target); $removeChildren(target);
target.appendChild($e({ target.appendChild($create({
tag: 'i', tag: 'i',
attrs: { attrs: {
className: 'fas fa-2x fa-spinner fa-pulse', className: 'fas fa-2x fa-spinner fa-pulse',
@ -52,7 +51,7 @@ const MszEmbed = (function() {
const replaceWithUrl = function(targets, url) { const replaceWithUrl = function(targets, url) {
for(const target of targets) { for(const target of targets) {
let body = $e({ let body = $create({
tag: 'a', tag: 'a',
attrs: { attrs: {
className: 'link', className: 'link',
@ -62,8 +61,8 @@ const MszEmbed = (function() {
}, },
child: url child: url
}); });
$ib(target, body); $insertBefore(target, body);
$r(target); target.remove();
} }
}; };

View file

@ -1,9 +1,7 @@
#include utility.js
const MszImageEmbed = function(metadata, options, target) { const MszImageEmbed = function(metadata, options, target) {
options = options || {}; options = options || {};
const image = $e({ const image = $create({
tag: 'img', tag: 'img',
attrs: { attrs: {
alt: target.dataset.mszEmbedAlt || '', alt: target.dataset.mszEmbedAlt || '',
@ -19,14 +17,14 @@ const MszImageEmbed = function(metadata, options, target) {
target.appendChild(image); target.appendChild(image);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, image); $insertBefore(ref, image);
}, },
nuke: function() { nuke: function() {
$r(image); image.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, image); $insertBefore(target, image);
$r(target); target.remove();
}, },
getType: function() { return 'external'; }, getType: function() { return 'external'; },
}; };

View file

@ -1,5 +1,3 @@
#include utility.js
#include uniqstr.js
#include watcher.js #include watcher.js
const MszVideoEmbedPlayerEvents = function() { const MszVideoEmbedPlayerEvents = function() {
@ -49,7 +47,7 @@ const MszVideoEmbed = function(playerOrFrame) {
const frame = playerOrFrame; const frame = playerOrFrame;
const player = 'getPlayer' in frame ? frame.getPlayer() : frame; const player = 'getPlayer' in frame ? frame.getPlayer() : frame;
const elem = $e({ const elem = $create({
attrs: { attrs: {
classList: ['embed', 'embed-' + player.getType()], classList: ['embed', 'embed-' + player.getType()],
}, },
@ -64,14 +62,14 @@ const MszVideoEmbed = function(playerOrFrame) {
target.appendChild(elem); target.appendChild(elem);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, elem); $insertBefore(ref, elem);
}, },
nuke: function() { nuke: function() {
$r(elem); elem.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, elem); $insertBefore(target, elem);
$r(target); target.remove();
}, },
getFrame: function() { getFrame: function() {
return frame; return frame;
@ -93,7 +91,7 @@ const MszVideoEmbedFrame = function(player, options) {
icoVolQuiet = 'fa-volume-down', icoVolQuiet = 'fa-volume-down',
icoVolLoud = 'fa-volume-up'; icoVolLoud = 'fa-volume-up';
const btnPlayPause = $e({ const btnPlayPause = $create({
attrs: {}, attrs: {},
child: { child: {
tag: 'i', tag: 'i',
@ -103,7 +101,7 @@ const MszVideoEmbedFrame = function(player, options) {
} }
}); });
const btnStop = $e({ const btnStop = $create({
attrs: {}, attrs: {},
child: { child: {
tag: 'i', tag: 'i',
@ -113,20 +111,20 @@ const MszVideoEmbedFrame = function(player, options) {
}, },
}); });
const numCurrentTime = $e({ const numCurrentTime = $create({
attrs: {}, attrs: {},
}); });
const sldProgress = $e({ const sldProgress = $create({
attrs: {}, attrs: {},
child: [], child: [],
}); });
const numDurationRemaining = $e({ const numDurationRemaining = $create({
attrs: {}, attrs: {},
}); });
const btnVolMute = $e({ const btnVolMute = $create({
attrs: {}, attrs: {},
child: { child: {
tag: 'i', tag: 'i',
@ -140,7 +138,7 @@ const MszVideoEmbedFrame = function(player, options) {
}, },
}); });
const elem = $e({ const elem = $create({
attrs: { attrs: {
className: 'embedvf', className: 'embedvf',
style: { style: {
@ -185,14 +183,14 @@ const MszVideoEmbedFrame = function(player, options) {
target.appendChild(elem); target.appendChild(elem);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, elem); $insertBefore(ref, elem);
}, },
nuke: function() { nuke: function() {
$r(elem); elem.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, elem); $insertBefore(target, elem);
$r(target); target.remove();
}, },
getPlayer: function() { getPlayer: function() {
return player; return player;
@ -232,7 +230,7 @@ const MszVideoEmbedPlayer = function(metadata, options) {
const watchers = new MszWatchers; const watchers = new MszWatchers;
watchers.define(MszVideoEmbedPlayerEvents()); watchers.define(MszVideoEmbedPlayerEvents());
const player = $e({ const player = $create({
tag: 'video', tag: 'video',
attrs: videoAttrs, attrs: videoAttrs,
}); });
@ -251,14 +249,14 @@ const MszVideoEmbedPlayer = function(metadata, options) {
target.appendChild(player); target.appendChild(player);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, player); $insertBefore(ref, player);
}, },
nuke: function() { nuke: function() {
$r(player); player.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, player); $insertBefore(target, player);
$r(target); target.remove();
}, },
getType: function() { return 'external'; }, getType: function() { return 'external'; },
getWidth: function() { return width; }, getWidth: function() { return width; },
@ -350,7 +348,7 @@ const MszVideoEmbedYouTube = function(metadata, options) {
options = options || {}; options = options || {};
const ytOrigin = 'https://www.youtube.com', const ytOrigin = 'https://www.youtube.com',
playerId = 'yt-' + MszUniqueStr(8), playerId = 'yt-' + $rngs(8),
shouldAutoplay = options.autoplay === undefined || options.autoplay; shouldAutoplay = options.autoplay === undefined || options.autoplay;
let embedUrl = 'https://www.youtube.com/embed/' + metadata.youtube_video_id + '?enablejsapi=1'; 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; const watchers = new MszWatchers;
watchers.define(MszVideoEmbedPlayerEvents()); watchers.define(MszVideoEmbedPlayerEvents());
const player = $e({ const player = $create({
tag: 'iframe', tag: 'iframe',
attrs: { attrs: {
frameborder: 0, frameborder: 0,
@ -396,14 +394,14 @@ const MszVideoEmbedYouTube = function(metadata, options) {
target.appendChild(player); target.appendChild(player);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, player); $insertBefore(ref, player);
}, },
nuke: function() { nuke: function() {
$r(player); player.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, player); $insertBefore(target, player);
$r(target); target.remove();
}, },
getType: function() { return 'youtube'; }, getType: function() { return 'youtube'; },
getWidth: function() { return 560; }, getWidth: function() { return 560; },
@ -562,7 +560,7 @@ const MszVideoEmbedNicoNico = function(metadata, options) {
options = options || {}; options = options || {};
const nndOrigin = 'https://embed.nicovideo.jp', const nndOrigin = 'https://embed.nicovideo.jp',
playerId = 'nnd-' + MszUniqueStr(8), playerId = 'nnd-' + $rngs(8),
shouldAutoplay = options.autoplay === undefined || options.autoplay; shouldAutoplay = options.autoplay === undefined || options.autoplay;
let embedUrl = 'https://embed.nicovideo.jp/watch/' + metadata.nicovideo_video_id + '?jsapi=1&playerId=' + playerId; 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; const watchers = new MszWatchers;
watchers.define(MszVideoEmbedPlayerEvents()); watchers.define(MszVideoEmbedPlayerEvents());
const player = $e({ const player = $create({
tag: 'iframe', tag: 'iframe',
attrs: { attrs: {
frameborder: 0, frameborder: 0,
@ -597,14 +595,14 @@ const MszVideoEmbedNicoNico = function(metadata, options) {
target.appendChild(player); target.appendChild(player);
}, },
insertBefore: function(ref) { insertBefore: function(ref) {
$ib(ref, player); $insertBefore(ref, player);
}, },
nuke: function() { nuke: function() {
$r(player); player.remove();
}, },
replaceElement(target) { replaceElement(target) {
$ib(target, player); $insertBefore(target, player);
$r(target); target.remove();
}, },
getType: function() { return 'nicovideo'; }, getType: function() { return 'nicovideo'; },
getWidth: function() { return 640; }, getWidth: function() { return 640; },
@ -792,7 +790,7 @@ const MszVideoEmbedPlaceholder = function(metadata, options) {
const pub = {}; const pub = {};
const elem = $e({ const elem = $create({
attrs: { attrs: {
className: ('embedph embedph-' + (options.type || 'external')), className: ('embedph embedph-' + (options.type || 'external')),
style: style.join(';'), style: style.join(';'),
@ -894,13 +892,13 @@ const MszVideoEmbedPlaceholder = function(metadata, options) {
pub.getElement = function() { return elem; }; pub.getElement = function() { return elem; };
pub.appendTo = function(target) { target.appendChild(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() { pub.nuke = function() {
$r(elem); elem.remove();
}; };
pub.replaceElement = function(target) { pub.replaceElement = function(target) {
$ib(target, elem); $insertBefore(target, elem);
$r(target); target.remove();
}; };
return pub; return pub;

View file

@ -1,5 +1,3 @@
#include utility.js
const MszChristmas2019EventInfo = function() { const MszChristmas2019EventInfo = function() {
return { return {
isActive: () => { isActive: () => {
@ -16,8 +14,8 @@ const MszChristmas2019EventInfo = function() {
const MszChristmas2019Event = function() { const MszChristmas2019Event = function() {
const propName = 'msz-christmas-' + (new Date).getFullYear().toString(); const propName = 'msz-christmas-' + (new Date).getFullYear().toString();
const headerBg = $q('.header__background'); const headerBg = $query('.header__background');
const menuBgs = Array.from($qa('.header__desktop__submenu__background')); const menuBgs = Array.from($queryAll('.header__desktop__submenu__background'));
if(!localStorage.getItem(propName)) if(!localStorage.getItem(propName))
localStorage.setItem(propName, '0'); localStorage.setItem(propName, '0');

View file

@ -1,5 +1,3 @@
#include xhr.js
const MszEEPROM = function(appId, endPoint) { const MszEEPROM = function(appId, endPoint) {
if(typeof appId !== 'string') if(typeof appId !== 'string')
throw 'appId must be a string'; throw 'appId must be a string';
@ -44,7 +42,7 @@ const MszEEPROM = function(appId, endPoint) {
formData.append('src', appId); formData.append('src', appId);
formData.append('file', fileInput); formData.append('file', fileInput);
const { status, body } = await $x.post(`${endPoint}/uploads`, { const { status, body } = await $xhr.post(`${endPoint}/uploads`, {
type: 'json', type: 'json',
authed: true, authed: true,
upload: reportProgress, upload: reportProgress,
@ -79,7 +77,7 @@ const MszEEPROM = function(appId, endPoint) {
if(typeof fileInfo.urlf !== 'string') if(typeof fileInfo.urlf !== 'string')
throw 'fileInfo.urlf must be a 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', type: 'json',
authed: true, authed: true,
}); });

View file

@ -1,5 +1,3 @@
#include xhr.js
const MszUiharu = function(apiUrl) { const MszUiharu = function(apiUrl) {
const maxBatchSize = 4; const maxBatchSize = 4;
const lookupOneUrl = apiUrl + '/metadata'; const lookupOneUrl = apiUrl + '/metadata';
@ -9,7 +7,7 @@ const MszUiharu = function(apiUrl) {
if(typeof targetUrl !== 'string') if(typeof targetUrl !== 'string')
throw 'targetUrl must be a string'; throw 'targetUrl must be a string';
return $x.post(lookupOneUrl, { type: 'json' }, targetUrl); return $xhr.post(lookupOneUrl, { type: 'json' }, targetUrl);
}, },
}; };
}; };

View file

@ -1,7 +1,6 @@
#include msgbox.jsx #include msgbox.jsx
#include parsing.js #include parsing.js
#include utility.js #include utility.js
#include xhr.js
#include ext/eeprom.js #include ext/eeprom.js
let MszForumEditorAllowClose = false; let MszForumEditorAllowClose = false;
@ -38,12 +37,9 @@ const MszForumEditor = function(form) {
</div> </div>
</div>; </div>;
if(eepromHistory.children.length > 0) eepromHistory.insertAdjacentElement('afterbegin', uploadElem);
$ib(eepromHistory.firstChild, uploadElem);
else
eepromHistory.appendChild(uploadElem);
const explodeUploadElem = () => $r(uploadElem); const explodeUploadElem = () => { uploadElem.remove(); };
const uploadTask = eepromClient.create(file); const uploadTask = eepromClient.create(file);
uploadTask.onProgress(prog => { uploadTask.onProgress(prog => {
@ -79,7 +75,7 @@ const MszForumEditor = function(form) {
}; };
uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => insertTheLinkIntoTheBoxEx2()}>Insert</a>); 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={() => { uploadElemProgressText.appendChild(<a href="javascript:void(0)" onclick={() => {
eepromClient.delete(fileInfo) eepromClient.delete(fileInfo)
.then(() => explodeUploadElem()) .then(() => explodeUploadElem())
@ -172,7 +168,7 @@ const MszForumEditor = function(form) {
}); });
const switchButtons = parser => { const switchButtons = parser => {
$rc(markupActs); $removeChildren(markupActs);
const tags = MszParsing.getTagsFor(parser); const tags = MszParsing.getTagsFor(parser);
for(const tag of tags) for(const tag of tags)
@ -191,7 +187,7 @@ const MszForumEditor = function(form) {
formData.append('post[text]', text); formData.append('post[text]', text);
formData.append('post[parser]', parseInt(parser)); 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>; const previewBtn = <button class="input__button" type="button" value="preview">Preview</button>;
@ -233,7 +229,7 @@ const MszForumEditor = function(form) {
lastPostParser = postParser; lastPostParser = postParser;
previewElem.innerHTML = body; previewElem.innerHTML = body;
MszEmbed.handle($qa('.js-msz-embed-media')); MszEmbed.handle($queryAll('.js-msz-embed-media'));
previewElem.removeAttribute('hidden'); previewElem.removeAttribute('hidden');
textElem.setAttribute('hidden', 'hidden'); textElem.setAttribute('hidden', 'hidden');
@ -276,7 +272,7 @@ const MszForumEditor = function(form) {
lastPostParser = postParser; lastPostParser = postParser;
previewElem.innerHTML = body; previewElem.innerHTML = body;
MszEmbed.handle($qa('.js-msz-embed-media')); MszEmbed.handle($queryAll('.js-msz-embed-media'));
previewBtn.removeAttribute('disabled'); previewBtn.removeAttribute('disabled');
parserElem.removeAttribute('disabled'); parserElem.removeAttribute('disabled');

View file

@ -1,6 +1,4 @@
#include msgbox.jsx #include msgbox.jsx
#include utility.js
#include xhr.js
#include embed/embed.js #include embed/embed.js
#include events/christmas2019.js #include events/christmas2019.js
#include events/events.js #include events/events.js
@ -10,7 +8,7 @@
(async () => { (async () => {
const initLoginPage = async () => { const initLoginPage = async () => {
const forms = Array.from($qa('.js-login-form')); const forms = Array.from($queryAll('.js-login-form'));
if(forms.length < 1) if(forms.length < 1)
return; return;
@ -18,7 +16,7 @@
if(!(avatar instanceof Element) || !(userName instanceof Element)) if(!(avatar instanceof Element) || !(userName instanceof Element))
return; 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; avatar.src = body.avatar;
if(body.name.length > 0) if(body.name.length > 0)
@ -48,7 +46,7 @@
}; };
const initQuickSubmit = () => { 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) if(elems.length < 1)
return; return;
@ -66,7 +64,7 @@
}; };
const initXhrActions = () => { 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) { for(const target of targets) {
target.onclick = async () => { target.onclick = async () => {
if(target.disabled) if(target.disabled)
@ -89,7 +87,7 @@
if(target.dataset.confirm && !await MszShowConfirmBox(target.dataset.confirm, 'Are you sure?')) if(target.dataset.confirm && !await MszShowConfirmBox(target.dataset.confirm, 'Are you sure?'))
return; return;
const { status, body } = await $x.send( const { status, body } = await $xhr.send(
target.dataset.method ?? 'GET', target.dataset.method ?? 'GET',
url, url,
{ {
@ -125,7 +123,7 @@
}; };
try { try {
MszSakuya.trackElements($qa('time')); MszSakuya.trackElements($queryAll('time'));
hljs.highlightAll(); hljs.highlightAll();
MszEmbed.init(`${location.protocol}//uiharu.${location.host}`); MszEmbed.init(`${location.protocol}//uiharu.${location.host}`);
@ -134,7 +132,7 @@
// only used by the forum posting form // only used by the forum posting form
initQuickSubmit(); initQuickSubmit();
const forumPostingForm = $q('.js-forum-posting'); const forumPostingForm = $query('.js-forum-posting');
if(forumPostingForm !== null) if(forumPostingForm !== null)
MszForumEditor(forumPostingForm); MszForumEditor(forumPostingForm);
@ -146,7 +144,7 @@
MszMessages(); MszMessages();
MszEmbed.handle($qa('.js-msz-embed-media')); MszEmbed.handle($queryAll('.js-msz-embed-media'));
} catch(ex) { } catch(ex) {
console.error(ex); console.error(ex);
} }

View file

@ -1,4 +1,3 @@
#include utility.js
#include watcher.js #include watcher.js
const MsgMessagesList = function(list) { const MsgMessagesList = function(list) {
@ -55,8 +54,8 @@ const MsgMessagesList = function(list) {
return selected; return selected;
}, },
removeItem: item => { removeItem: item => {
$ari(items, item); $arrayRemoveValue(items, item);
$r(item.getElement()); item.getElement().remove();
recountSelected(); recountSelected();
watchers.call('select', selectedCount, items.length); watchers.call('select', selectedCount, items.length);
}, },

View file

@ -1,6 +1,4 @@
#include msgbox.jsx #include msgbox.jsx
#include utility.js
#include xhr.js
#include messages/actbtn.js #include messages/actbtn.js
#include messages/list.js #include messages/list.js
#include messages/recipient.js #include messages/recipient.js
@ -40,7 +38,7 @@ const MszMessages = () => {
formData.append('recipient', recipient); formData.append('recipient', recipient);
formData.append('reply', replyTo); 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) if(body.error !== undefined)
throw body.error; throw body.error;
@ -54,7 +52,7 @@ const MszMessages = () => {
formData.append('parser', parser); formData.append('parser', parser);
formData.append('draft', draft); 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) if(body.error !== undefined)
throw body.error; throw body.error;
@ -62,7 +60,7 @@ const MszMessages = () => {
}; };
const msgsMark = async (msgs, state) => { 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, type: state,
messages: msgs.map(extractMsgIds).join(','), messages: msgs.map(extractMsgIds).join(','),
}); });
@ -73,7 +71,7 @@ const MszMessages = () => {
}; };
const msgsDelete = async msgs => { 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(','), messages: msgs.map(extractMsgIds).join(','),
}); });
if(body.error !== undefined) if(body.error !== undefined)
@ -83,7 +81,7 @@ const MszMessages = () => {
}; };
const msgsRestore = async msgs => { 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(','), messages: msgs.map(extractMsgIds).join(','),
}); });
if(body.error !== undefined) if(body.error !== undefined)
@ -93,7 +91,7 @@ const MszMessages = () => {
}; };
const msgsNuke = async msgs => { 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(','), messages: msgs.map(extractMsgIds).join(','),
}); });
if(body.error !== undefined) if(body.error !== undefined)
@ -102,28 +100,28 @@ const MszMessages = () => {
return true; return true;
}; };
const msgsUserBtns = Array.from($qa('.js-header-pms-button')); const msgsUserBtns = Array.from($queryAll('.js-header-pms-button'));
if(msgsUserBtns.length > 0) if(msgsUserBtns.length > 0)
$x.get('/messages/stats', { type: 'json' }).then(result => { $xhr.get('/messages/stats', { type: 'json' }).then(result => {
const body = result.body; const body = result.body;
if(typeof body === 'object' && typeof body.unread === 'number') if(typeof body === 'object' && typeof body.unread === 'number')
if(body.unread > 0) if(body.unread > 0)
for(const msgsUserBtn of msgsUserBtns) 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 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 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 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; const msgsReply = msgsReplyElem instanceof Element ? new MszMessagesReply(msgsReplyElem) : undefined;
if(msgsReply !== undefined) { if(msgsReply !== undefined) {
@ -165,7 +163,7 @@ const MszMessages = () => {
let actSelectAll, actMarkRead, actMoveTrash, actNuke; 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) { if(actSelectAllBtn instanceof Element) {
actSelectAll = new MszMessagesActionButton(actSelectAllBtn); 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) { if(actMarkReadBtn instanceof Element) {
actMarkRead = new MszMessagesActionButton(actMarkReadBtn); 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) { if(actMoveTrashBtn instanceof Element) {
actMoveTrash = new MszMessagesActionButton(actMoveTrashBtn); 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) { if(actNukeBtn instanceof Element) {
actNuke = new MszMessagesActionButton(actNukeBtn, true); actNuke = new MszMessagesActionButton(actNukeBtn, true);

View file

@ -1,5 +1,3 @@
#include xhr.js
const MszMessagesRecipient = function(element) { const MszMessagesRecipient = function(element) {
if(!(element instanceof Element)) if(!(element instanceof Element))
throw 'element must be an instance of Element'; throw 'element must be an instance of Element';
@ -9,7 +7,7 @@ const MszMessagesRecipient = function(element) {
let updateHandler = undefined; let updateHandler = undefined;
const update = async () => { 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, name: nameInput.value,
}); });

View file

@ -1,4 +1,5 @@
#include parsing.js #include parsing.js
#include utility.js
#include ext/eeprom.js #include ext/eeprom.js
const MszMessagesReply = function(element) { const MszMessagesReply = function(element) {
@ -46,7 +47,7 @@ const MszMessagesReply = function(element) {
}); });
const switchButtons = parser => { const switchButtons = parser => {
$rc(actsElem); $removeChildren(actsElem);
const tags = MszParsing.getTagsFor(parser); const tags = MszParsing.getTagsFor(parser);
actsElem.hidden = tags.length < 1; actsElem.hidden = tags.length < 1;

View file

@ -1,5 +1,3 @@
#include utility.js
const MszShowConfirmBox = async (text, title, target) => { const MszShowConfirmBox = async (text, title, target) => {
let result = false; let result = false;

View file

@ -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) { const $insertTags = function(target, tagOpen, tagClose) {
tagOpen = tagOpen || ''; tagOpen = tagOpen || '';
tagClose = tagClose || ''; tagClose = tagClose || '';

View file

@ -13,7 +13,7 @@ const MszWatcher = function() {
}; };
const unwatch = handler => { const unwatch = handler => {
$ari(handlers, handler); $arrayRemoveValue(handlers, handler);
}; };
return { return {

View file

@ -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),
};
})();

View file

@ -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 { body {
background-color: #111; background-color: #111;
color: #fff; color: #fff;

View file

@ -1,5 +1,4 @@
#include loading.jsx #include loading.jsx
#include xhr.js
#include app/info.jsx #include app/info.jsx
#include app/scope.jsx #include app/scope.jsx
#include header/header.js #include header/header.js
@ -158,7 +157,7 @@ const MszOAuth2Authorise = async () => {
} }
try { 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) if(!body)
throw 'authorisation resolve failed'; throw 'authorisation resolve failed';
if(typeof body.error === 'string') { if(typeof body.error === 'string') {
@ -185,7 +184,7 @@ const MszOAuth2Authorise = async () => {
params.scope = scope; params.scope = scope;
try { 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) if(!body)
throw 'authorisation failed'; throw 'authorisation failed';
if(typeof body.error === 'string') if(typeof body.error === 'string')

View file

@ -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;
},
};
})();

View file

@ -1,4 +1,3 @@
#include utility.js
#include authorise.js #include authorise.js
#include verify.js #include verify.js

View file

@ -1,5 +1,4 @@
#include loading.jsx #include loading.jsx
#include xhr.js
#include app/info.jsx #include app/info.jsx
#include app/scope.jsx #include app/scope.jsx
#include header/header.js #include header/header.js
@ -22,7 +21,7 @@ const MszOAuth2Verify = () => {
const verifyAuthsRequest = async approve => { const verifyAuthsRequest = async approve => {
try { 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, code: userCode,
approve: approve === true ? 'yes' : 'no', approve: approve === true ? 'yes' : 'no',
}); });
@ -91,7 +90,7 @@ const MszOAuth2Verify = () => {
fCode.classList.add('hidden'); fCode.classList.add('hidden');
userCode = encodeURIComponent(eUserCode.value); 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 => { .then(result => {
const body = result.body; const body = result.body;

View file

@ -12,11 +12,13 @@ const fs = require('fs');
debug: isDebug, debug: isDebug,
swc: { swc: {
es: 'es2021', es: 'es2021',
jsx: '$jsx',
}, },
}; };
const tasks = { const tasks = {
js: [ js: [
{ source: 'common.js', target: '/assets', name: 'common.{hash}.js', },
{ source: 'misuzu.js', target: '/assets', name: 'misuzu.{hash}.js', }, { source: 'misuzu.js', target: '/assets', name: 'misuzu.{hash}.js', },
{ source: 'oauth2.js', target: '/assets', name: 'oauth2.{hash}.js', }, { source: 'oauth2.js', target: '/assets', name: 'oauth2.{hash}.js', },
{ source: 'redir-bsky.js', target: '/assets', name: 'redir-bsky.{hash}.js', }, { source: 'redir-bsky.js', target: '/assets', name: 'redir-bsky.{hash}.js', },
@ -24,6 +26,7 @@ const fs = require('fs');
], ],
css: [ css: [
{ source: 'errors.css', target: '/', name: 'errors.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: 'misuzu.css', target: '/assets', name: 'misuzu.{hash}.css', },
{ source: 'oauth2.css', target: '/assets', name: 'oauth2.{hash}.css', }, { source: 'oauth2.css', target: '/assets', name: 'oauth2.{hash}.css', },
], ],

View file

@ -7,7 +7,7 @@
{% block html_head %} {% block html_head %}
<meta name="description" content="{{ error_blerb }}"> <meta name="description" content="{{ error_blerb }}">
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet"> <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> <style>
:root { :root {
--error-colour: {{ error_colour }}; --error-colour: {{ error_colour }};

View file

@ -51,10 +51,10 @@
<script> <script>
window.addEventListener('load', function() { window.addEventListener('load', function() {
const ubExpires = $i('ub_expires'), const ubExpires = $id('ub_expires'),
ubExpiresCustom = $i('ub_expires_custom'), ubExpiresCustom = $id('ub_expires_custom'),
ubSeverity = $i('ub_severity'), ubSeverity = $id('ub_severity'),
ubSeverityDisplay = $i('ub_severity_display'); ubSeverityDisplay = $id('ub_severity_display');
const updateExpires = function() { const updateExpires = function() {
ubExpiresCustom.parentNode.classList.toggle('manage__ban__duration__value__custom--hidden', ubExpires.value != '-2'); ubExpiresCustom.parentNode.classList.toggle('manage__ban__duration__value__custom--hidden', ubExpires.value != '-2');

View file

@ -3,6 +3,7 @@
{% block html_head %} {% block html_head %}
{% include '_layout/meta.twig' %} {% include '_layout/meta.twig' %}
<link href="/vendor/fontawesome/css/all.min.css" type="text/css" rel="stylesheet"> <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"> <link href="{{ asset('misuzu.css') }}" type="text/css" rel="stylesheet">
{% if site_background is defined %} {% if site_background is defined %}
<style> <style>
@ -62,5 +63,6 @@
{% endblock %} {% endblock %}
<script src="/vendor/highlightjs/highlight.min.js" type="text/javascript"></script> <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> <script src="{{ asset('misuzu.js') }}" type="text/javascript"></script>
{% endblock %} {% endblock %}

View file

@ -3,6 +3,7 @@
{% set html_title = (title is defined ? (title ~ ' :: ') : '') ~ globals.site_info.name %} {% set html_title = (title is defined ? (title ~ ' :: ') : '') ~ globals.site_info.name %}
{% block html_head %} {% block html_head %}
<link href="{{ asset('common.css') }}" rel="stylesheet">
<link href="{{ asset('oauth2.css') }}" rel="stylesheet"> <link href="{{ asset('oauth2.css') }}" rel="stylesheet">
{% endblock %} {% endblock %}
@ -35,5 +36,6 @@
</div> </div>
</div> </div>
</div> </div>
<script src="{{ asset('common.js') }}"></script>
<script src="{{ asset('oauth2.js') }}"></script> <script src="{{ asset('oauth2.js') }}"></script>
{% endblock %} {% endblock %}