mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
refactor: extract inline JS into app/ modules, remove dead overtype-webcomponent
- Remove overtype-webcomponent.min.js (zero references) - Extract copyLogContent + fallbackCopy + HTMX tab-updater → app/admin-logs.js (removes duplicate from both system.php and parametres.php) - Extract copyUrl → app/clipboard.js (shared by acces.php) - Extract tag/language pill-search logic → app/pill-search.js Generalized with data-pill-search attributes, auto-inits via DOMContentLoaded + htmx:afterSwap - Extract access-request form handler → app/access-request.js (was inline in templates/public/tfe.php) Files created: admin-logs.js, clipboard.js, pill-search.js, access-request.js Files modified: 9 templates/controllers to drop inline scripts and reference external JS files
This commit is contained in:
@@ -29,6 +29,7 @@ extract($vars);
|
||||
$pageTitle = 'Accès';
|
||||
$isAdmin = true;
|
||||
$bodyClass = 'admin-body';
|
||||
$extraJs = ['/assets/js/app/clipboard.js'];
|
||||
|
||||
require_once APP_ROOT . '/templates/head.php';
|
||||
echo '<link rel="stylesheet" href="/assets/css/file-access.css">';
|
||||
|
||||
@@ -55,7 +55,7 @@ function wasSelected($key, $value) {
|
||||
$isAdmin = true;
|
||||
$bodyClass = 'admin-body';
|
||||
$extraCss = ['/assets/css/form.css', '/assets/css/filepond.min.css', '/assets/css/filepond-plugin-image-preview.min.css'];
|
||||
$extraJs = ['/assets/js/filepond.min.js', '/assets/js/filepond-plugin-file-validate-type.min.js', '/assets/js/filepond-plugin-file-validate-size.min.js', '/assets/js/filepond-plugin-image-preview.min.js', '/assets/js/filepond-plugin-image-exif-orientation.min.js', '/assets/js/file-upload-filepond.js', '/assets/js/beforeunload-guard.js', '/assets/js/upload-progress.js'];
|
||||
$extraJs = ['/assets/js/vendor/filepond.min.js', '/assets/js/vendor/filepond-plugin-file-validate-type.min.js', '/assets/js/vendor/filepond-plugin-file-validate-size.min.js', '/assets/js/vendor/filepond-plugin-image-preview.min.js', '/assets/js/vendor/filepond-plugin-image-exif-orientation.min.js', '/assets/js/app/file-upload-filepond.js', '/assets/js/app/beforeunload-guard.js', '/assets/js/app/upload-progress.js', '/assets/js/app/pill-search.js'];
|
||||
require_once APP_ROOT . '/templates/head.php';
|
||||
include APP_ROOT . '/templates/header.php';
|
||||
include APP_ROOT . '/templates/admin/add.php';
|
||||
|
||||
@@ -70,7 +70,7 @@ $extraJsInline = '';
|
||||
|
||||
if ($editType === 'page' || $editType === 'about_page') {
|
||||
$initialContent = $page["content"] ?? "";
|
||||
$extraJs = ["/assets/js/overtype.min.js"];
|
||||
$extraJs = ["/assets/js/vendor/overtype.min.js"];
|
||||
$extraJsInline = <<<'JS'
|
||||
var OT = window.OverType.default || window.OverType;
|
||||
var hidden = document.getElementById('content');
|
||||
@@ -83,7 +83,7 @@ var editor = new OT(document.getElementById('editor'), {
|
||||
JS;
|
||||
} elseif ($editType === 'form_help') {
|
||||
$initialContent = $formHelpContent;
|
||||
$extraJs = ["/assets/js/overtype.min.js"];
|
||||
$extraJs = ["/assets/js/vendor/overtype.min.js"];
|
||||
$extraJsInline = <<<'JS'
|
||||
var OT = window.OverType.default || window.OverType;
|
||||
var hidden = document.getElementById('content');
|
||||
|
||||
@@ -40,7 +40,7 @@ try {
|
||||
|
||||
$isAdmin = true; $bodyClass = 'admin-body';
|
||||
$extraCss = ['/assets/css/form.css', '/assets/css/filepond.min.css', '/assets/css/filepond-plugin-image-preview.min.css'];
|
||||
$extraJs = ['/assets/js/filepond.min.js', '/assets/js/filepond-plugin-file-validate-type.min.js', '/assets/js/filepond-plugin-file-validate-size.min.js', '/assets/js/filepond-plugin-image-preview.min.js', '/assets/js/filepond-plugin-image-exif-orientation.min.js', '/assets/js/file-upload-filepond.js', '/assets/js/beforeunload-guard.js', '/assets/js/upload-progress.js'];
|
||||
$extraJs = ['/assets/js/vendor/filepond.min.js', '/assets/js/vendor/filepond-plugin-file-validate-type.min.js', '/assets/js/vendor/filepond-plugin-file-validate-size.min.js', '/assets/js/vendor/filepond-plugin-image-preview.min.js', '/assets/js/vendor/filepond-plugin-image-exif-orientation.min.js', '/assets/js/app/file-upload-filepond.js', '/assets/js/app/beforeunload-guard.js', '/assets/js/app/upload-progress.js', '/assets/js/app/pill-search.js'];
|
||||
require_once APP_ROOT . '/templates/head.php';
|
||||
include APP_ROOT . '/templates/header.php';
|
||||
include APP_ROOT . '/templates/admin/edit.php';
|
||||
|
||||
97
app/public/assets/js/app/access-request.js
Normal file
97
app/public/assets/js/app/access-request.js
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* access-request.js — handles the "Demander l'accès" form on public thesis pages.
|
||||
*
|
||||
* Shows/hides the justification textarea based on email domain (@erg.school / @erg.be).
|
||||
* Submits via fetch() to /request-access and displays success/error messages.
|
||||
* Handles the special "recipient_rejected" status to let the user fix their email.
|
||||
*
|
||||
* Expects a form with:
|
||||
* #access-request-form — the form (needs data-thesis-id)
|
||||
* #access-email — email input
|
||||
* #justification-container — wrapper div for justification
|
||||
* #access-justification — justification textarea
|
||||
* #access-request-message — message display div
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var form = document.getElementById('access-request-form');
|
||||
if (!form) return;
|
||||
|
||||
var emailInput = document.getElementById('access-email');
|
||||
var justificationContainer = document.getElementById('justification-container');
|
||||
var justificationInput = document.getElementById('access-justification');
|
||||
var messageDiv = document.getElementById('access-request-message');
|
||||
|
||||
if (!emailInput || !messageDiv) return;
|
||||
|
||||
// Show/hide justification based on email domain
|
||||
emailInput.addEventListener('input', function () {
|
||||
var email = this.value.trim().toLowerCase();
|
||||
var isErg = email.endsWith('@erg.school') || email.endsWith('@erg.be');
|
||||
if (justificationContainer) justificationContainer.style.display = isErg ? 'none' : 'block';
|
||||
if (justificationInput) justificationInput.required = !isErg;
|
||||
});
|
||||
|
||||
function showRetryPrompt(rejectedEmail, serverMessage) {
|
||||
messageDiv.style.display = 'block';
|
||||
messageDiv.className = 'tfe-access-message tfe-access-error';
|
||||
messageDiv.innerHTML =
|
||||
'<strong>Adresse e-mail introuvable sur le serveur de l\'ERG.</strong><br>' +
|
||||
'<small>' + serverMessage.replace(/</g, '<') + '</small><br><br>' +
|
||||
'Corrigez votre adresse e-mail et réessayez.';
|
||||
emailInput.value = rejectedEmail;
|
||||
emailInput.classList.add('input-error');
|
||||
emailInput.focus();
|
||||
emailInput.select();
|
||||
emailInput.addEventListener('input', function clearError() {
|
||||
emailInput.classList.remove('input-error');
|
||||
emailInput.removeEventListener('input', clearError);
|
||||
});
|
||||
}
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var submitBtn = form.querySelector('button[type="submit"]');
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = 'Envoi en cours...';
|
||||
messageDiv.style.display = 'none';
|
||||
|
||||
var submittedEmail = emailInput.value.trim();
|
||||
var formData = new FormData(form);
|
||||
formData.append('thesis_id', form.getAttribute('data-thesis-id'));
|
||||
|
||||
fetch('/request-access', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(function (response) { return response.json(); })
|
||||
.then(function (data) {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Demander l\'accès';
|
||||
|
||||
if (data.status === 'recipient_rejected') {
|
||||
showRetryPrompt(submittedEmail, data.message);
|
||||
return;
|
||||
}
|
||||
|
||||
messageDiv.style.display = 'block';
|
||||
if (data.success) {
|
||||
messageDiv.className = 'tfe-access-message tfe-access-success';
|
||||
messageDiv.textContent = data.message;
|
||||
form.reset();
|
||||
} else {
|
||||
messageDiv.className = 'tfe-access-message tfe-access-error';
|
||||
messageDiv.textContent = data.message || 'Une erreur est survenue. Veuillez réessayer.';
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = 'Demander l\'accès';
|
||||
messageDiv.style.display = 'block';
|
||||
messageDiv.className = 'tfe-access-message tfe-access-error';
|
||||
messageDiv.textContent = 'Erreur de connexion. Veuillez réessayer.';
|
||||
});
|
||||
});
|
||||
})();
|
||||
64
app/public/assets/js/app/admin-logs.js
Normal file
64
app/public/assets/js/app/admin-logs.js
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* admin-logs.js — log viewer utilities shared by system.php and parametres.php.
|
||||
*
|
||||
* Provides:
|
||||
* - copyLogContent(btn) — copy visible log lines to clipboard
|
||||
* - HTMX afterSwap handler to update active tab class on #sys-tab-panel
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
window.copyLogContent = function (btn) {
|
||||
var logOut = document.querySelector('#log-output');
|
||||
if (!logOut) return;
|
||||
var text = Array.from(logOut.querySelectorAll('.log-line'))
|
||||
.map(function (el) { return el.textContent; }).join('\n');
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(text).then(function () {
|
||||
btn.textContent = '\u2713 Copi\u00e9';
|
||||
btn.classList.add('copied');
|
||||
setTimeout(function () { btn.textContent = 'Copier'; btn.classList.remove('copied'); }, 2000);
|
||||
});
|
||||
} else {
|
||||
window._fallbackCopy(text, btn);
|
||||
}
|
||||
};
|
||||
|
||||
window._fallbackCopy = function (text, btn) {
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = text;
|
||||
ta.style.cssText = 'position:fixed;opacity:0';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
btn.textContent = '\u2713 Copi\u00e9';
|
||||
btn.classList.add('copied');
|
||||
setTimeout(function () { btn.textContent = 'Copier'; btn.classList.remove('copied'); }, 2000);
|
||||
} catch (e) {}
|
||||
document.body.removeChild(ta);
|
||||
};
|
||||
|
||||
// Update active tab class after each HTMX swap on #sys-tab-panel
|
||||
document.body.addEventListener('htmx:afterSwap', function (evt) {
|
||||
if (!(evt.detail.target && evt.detail.target.id === 'sys-tab-panel')) return;
|
||||
var rc = evt.detail.requestConfig;
|
||||
var tab = null;
|
||||
// Tab clicks carry ?tab=… in the path
|
||||
var qIdx = rc.path.indexOf('?');
|
||||
if (qIdx !== -1) {
|
||||
tab = new URLSearchParams(rc.path.substring(qIdx + 1)).get('tab');
|
||||
}
|
||||
// Line-count form sends tab via hx-vals in parameters
|
||||
if (!tab && rc.parameters && rc.parameters.tab) {
|
||||
tab = rc.parameters.tab;
|
||||
}
|
||||
if (!tab) return;
|
||||
document.querySelectorAll('.sys-tabs .sys-tab').forEach(function (a) {
|
||||
var isActive = a.getAttribute('data-tab') === tab;
|
||||
a.classList.toggle('active', isActive);
|
||||
if (isActive) a.setAttribute('aria-current', 'page');
|
||||
else a.removeAttribute('aria-current');
|
||||
});
|
||||
});
|
||||
})();
|
||||
38
app/public/assets/js/app/clipboard.js
Normal file
38
app/public/assets/js/app/clipboard.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* clipboard.js — lightweight URL copy helper.
|
||||
*
|
||||
* Usage:
|
||||
* <input type="hidden" id="url-123" value="https://...">
|
||||
* <button onclick="copyUrl(123)">Copier</button>
|
||||
*
|
||||
* Or with a custom selector pattern:
|
||||
* <button onclick="copyUrlFrom(document.getElementById('my-url'))">Copier</button>
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
window.copyUrl = function (id) {
|
||||
var input = document.getElementById('url-' + id);
|
||||
if (input) {
|
||||
window.copyUrlFrom(input);
|
||||
}
|
||||
};
|
||||
|
||||
window.copyUrlFrom = function (sourceEl) {
|
||||
var text = sourceEl.value || sourceEl.textContent || '';
|
||||
if (!text) return;
|
||||
navigator.clipboard.writeText(text).then(function () {
|
||||
var btn = window.event && window.event.target ? window.event.target.closest('button') : null;
|
||||
if (btn) {
|
||||
var origTitle = btn.getAttribute('title') || '';
|
||||
var origText = btn.textContent;
|
||||
btn.setAttribute('title', '\u2713 Copi\u00e9');
|
||||
btn.textContent = '\u2713 Copi\u00e9';
|
||||
setTimeout(function () {
|
||||
btn.setAttribute('title', origTitle);
|
||||
btn.textContent = origText;
|
||||
}, 1200);
|
||||
}
|
||||
});
|
||||
};
|
||||
})();
|
||||
171
app/public/assets/js/app/pill-search.js
Normal file
171
app/public/assets/js/app/pill-search.js
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* pill-search.js — generalized pill-based search component for tags and languages.
|
||||
*
|
||||
* Initialisez avec un conteneur ayant l'attribut data-pill-search :
|
||||
* <div data-pill-search data-pill-name="tag" data-pill-max="10" data-pill-min="3" data-pill-required="1">
|
||||
*
|
||||
* DOM attendu à l'intérieur du conteneur :
|
||||
* - .tag-search-pills → conteneur des pills
|
||||
* - .tag-search-input → champ de recherche (avec hx-post, hx-trigger, etc.)
|
||||
* - .tag-search-suggestions → dropdown
|
||||
* - .tag-search-count → compteur
|
||||
* - .tag-search-counter → wrapper du compteur
|
||||
* - .tag-search-input-wrap → wrapper du champ de recherche
|
||||
* - .tag-search-max-msg → message "maximum atteint"
|
||||
*
|
||||
* Options (par attribut data) :
|
||||
* data-pill-name → nom pour les inputs cachés (ex: "tag", "language_autre")
|
||||
* data-pill-max → max pills (default 10)
|
||||
* data-pill-min → min pills requis (default 0)
|
||||
* data-pill-required → si "1", active l'affichage du minimum
|
||||
* data-pill-role → "tag" (lowercase) ou "lang" (ucfirst)
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function initAll() {
|
||||
document.querySelectorAll('[data-pill-search]:not([data-pill-search-initialized])').forEach(function (container) {
|
||||
container.setAttribute('data-pill-search-initialized', '1');
|
||||
initPillSearch(container);
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', initAll);
|
||||
document.body.addEventListener('htmx:afterSwap', initAll);
|
||||
|
||||
function initPillSearch(container) {
|
||||
var pills = container.querySelector('.tag-search-pills');
|
||||
var search = container.querySelector('.tag-search-input');
|
||||
var dropdown = container.querySelector('.tag-search-suggestions');
|
||||
var countEl = container.querySelector('.tag-search-count');
|
||||
var counter = container.querySelector('.tag-search-counter');
|
||||
var maxTags = parseInt(container.getAttribute('data-pill-max')) || 10;
|
||||
var minTags = parseInt(container.getAttribute('data-pill-min')) || 0;
|
||||
var required = container.getAttribute('data-pill-required') === '1';
|
||||
var inputName = container.getAttribute('data-pill-name') || 'tag';
|
||||
var role = container.getAttribute('data-pill-role') || 'tag';
|
||||
var selectedIdx = -1;
|
||||
|
||||
if (!pills || !search || !dropdown) return;
|
||||
|
||||
function normalize(name) {
|
||||
return name.trim().replace(/\s+/g, ' ').toLowerCase();
|
||||
}
|
||||
|
||||
function pillAlreadyExists(name) {
|
||||
var norm = normalize(name);
|
||||
var existing = pills.querySelectorAll('.tag-pill-name');
|
||||
for (var i = 0; i < existing.length; i++) {
|
||||
if (normalize(existing[i].textContent) === norm) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateCount() {
|
||||
var n = pills.querySelectorAll('.tag-pill').length;
|
||||
var suffix = required ? ' (min ' + minTags + ')' : '';
|
||||
if (countEl) countEl.textContent = n + '/' + maxTags + suffix;
|
||||
if (counter) counter.style.display = (n > 0 || required) ? '' : 'none';
|
||||
if (countEl && required) {
|
||||
countEl.style.color = n < minTags ? 'var(--text-danger)' : 'var(--accent)';
|
||||
}
|
||||
|
||||
var wrap = container.querySelector('.tag-search-input-wrap');
|
||||
var maxMsg = container.querySelector('.tag-search-max-msg');
|
||||
if (n >= maxTags) {
|
||||
if (wrap) wrap.style.display = 'none';
|
||||
if (maxMsg) maxMsg.style.display = '';
|
||||
} else {
|
||||
if (wrap) { wrap.style.display = ''; if (search) search.style.display = ''; }
|
||||
if (maxMsg) maxMsg.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
pills.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('.tag-pill-remove');
|
||||
if (!btn) return;
|
||||
var pill = btn.closest('.tag-pill');
|
||||
pill.remove();
|
||||
updateCount();
|
||||
var wrap = container.querySelector('.tag-search-input-wrap');
|
||||
var inp = container.querySelector('.tag-search-input');
|
||||
if (wrap && inp) { wrap.style.display = ''; inp.style.display = ''; }
|
||||
});
|
||||
|
||||
function highlight(idx) {
|
||||
var items = dropdown.querySelectorAll('.tag-search-item');
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
items[i].classList.toggle('tag-search-item--highlight', i === idx);
|
||||
}
|
||||
}
|
||||
|
||||
function selectPill(btn) {
|
||||
var name = normalize(btn.getAttribute('data-tag-name') || '');
|
||||
if (!name) return;
|
||||
if (pillAlreadyExists(name)) return;
|
||||
if ((pills.querySelectorAll('.tag-pill').length) >= maxTags) return;
|
||||
|
||||
var escaped = htmlEscape(name);
|
||||
var pill = document.createElement('span');
|
||||
pill.className = 'tag-pill';
|
||||
pill.innerHTML = '<input type="hidden" name="' + inputName + '[]" value="' + escaped + '">'
|
||||
+ '<span class="tag-pill-name">' + escaped + '</span>'
|
||||
+ '<button type="button" class="tag-pill-remove" title="Retirer \u00AB\u00A0' + escaped + '\u00A0\u00BB" aria-label="Retirer ' + escaped + '">'
|
||||
+ '<svg width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M216,48H176V40a24,24,0,0,0-24-24H104A24,24,0,0,0,80,40v8H40a8,8,0,0,0,0,16h8V208a16,16,0,0,0,16,16H192a16,16,0,0,0,16-16V64h8a8,8,0,0,0,0-16ZM112,168V104a8,8,0,0,1,16,0v64a8,8,0,0,1-16,0Zm48,0V104a8,8,0,0,1,16,0v64a8,8,0,0,1-16,0Z"></path></svg>'
|
||||
+ '</button>';
|
||||
pills.appendChild(pill);
|
||||
updateCount();
|
||||
search.value = '';
|
||||
dropdown.innerHTML = '';
|
||||
selectedIdx = -1;
|
||||
search.focus();
|
||||
}
|
||||
|
||||
dropdown.addEventListener('click', function (e) {
|
||||
var btn = e.target.closest('.tag-search-item');
|
||||
if (!btn) return;
|
||||
selectPill(btn);
|
||||
});
|
||||
|
||||
search.addEventListener('keydown', function (e) {
|
||||
var items = dropdown.querySelectorAll('.tag-search-item');
|
||||
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
if (items.length === 0) return;
|
||||
if (e.key === 'ArrowDown') {
|
||||
selectedIdx = (selectedIdx + 1) % items.length;
|
||||
} else {
|
||||
selectedIdx = selectedIdx <= 0 ? items.length - 1 : selectedIdx - 1;
|
||||
}
|
||||
highlight(selectedIdx);
|
||||
} else if (e.key === 'Enter') {
|
||||
if (items.length > 0) {
|
||||
e.preventDefault();
|
||||
if (selectedIdx >= 0 && selectedIdx < items.length) {
|
||||
selectPill(items[selectedIdx]);
|
||||
} else {
|
||||
selectPill(items[0]);
|
||||
}
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
dropdown.innerHTML = '';
|
||||
selectedIdx = -1;
|
||||
}
|
||||
});
|
||||
|
||||
search.addEventListener('blur', function () {
|
||||
setTimeout(function () {
|
||||
if (!dropdown.contains(document.activeElement)) {
|
||||
dropdown.innerHTML = '';
|
||||
selectedIdx = -1;
|
||||
}
|
||||
}, 150);
|
||||
});
|
||||
|
||||
function htmlEscape(str) {
|
||||
var el = document.createElement('span');
|
||||
el.textContent = str;
|
||||
return el.innerHTML;
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -1,9 +0,0 @@
|
||||
/*!
|
||||
* FilePondPluginFileValidateSize 2.2.8
|
||||
* Licensed under MIT, https://opensource.org/licenses/MIT/
|
||||
* Please visit https://pqina.nl/filepond/ for details.
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
!function(e,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(e=e||self).FilePondPluginFileValidateSize=i()}(this,function(){"use strict";var e=function(e){var i=e.addFilter,E=e.utils,l=E.Type,_=E.replaceInString,n=E.toNaturalFileSize;return i("ALLOW_HOPPER_ITEM",function(e,i){var E=i.query;if(!E("GET_ALLOW_FILE_SIZE_VALIDATION"))return!0;var l=E("GET_MAX_FILE_SIZE");if(null!==l&&e.size>l)return!1;var _=E("GET_MIN_FILE_SIZE");return!(null!==_&&e.size<_)}),i("LOAD_FILE",function(e,i){var E=i.query;return new Promise(function(i,l){if(!E("GET_ALLOW_FILE_SIZE_VALIDATION"))return i(e);var I=E("GET_FILE_VALIDATE_SIZE_FILTER");if(I&&!I(e))return i(e);var t=E("GET_MAX_FILE_SIZE");if(null!==t&&e.size>t)l({status:{main:E("GET_LABEL_MAX_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MAX_FILE_SIZE"),{filesize:n(t,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}});else{var L=E("GET_MIN_FILE_SIZE");if(null!==L&&e.size<L)l({status:{main:E("GET_LABEL_MIN_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MIN_FILE_SIZE"),{filesize:n(L,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}});else{var a=E("GET_MAX_TOTAL_FILE_SIZE");if(null!==a)if(E("GET_ACTIVE_ITEMS").reduce(function(e,i){return e+i.fileSize},0)>a)return void l({status:{main:E("GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MAX_TOTAL_FILE_SIZE"),{filesize:n(a,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}});i(e)}}})}),{options:{allowFileSizeValidation:[!0,l.BOOLEAN],maxFileSize:[null,l.INT],minFileSize:[null,l.INT],maxTotalFileSize:[null,l.INT],fileValidateSizeFilter:[null,l.FUNCTION],labelMinFileSizeExceeded:["File is too small",l.STRING],labelMinFileSize:["Minimum file size is {filesize}",l.STRING],labelMaxFileSizeExceeded:["File is too large",l.STRING],labelMaxFileSize:["Maximum file size is {filesize}",l.STRING],labelMaxTotalFileSizeExceeded:["Maximum total size exceeded",l.STRING],labelMaxTotalFileSize:["Maximum total file size is {filesize}",l.STRING]}}};return"undefined"!=typeof window&&void 0!==window.document&&document.dispatchEvent(new CustomEvent("FilePond:pluginloaded",{detail:e})),e});
|
||||
@@ -1,9 +0,0 @@
|
||||
/*!
|
||||
* FilePondPluginFileValidateType 1.2.9
|
||||
* Licensed under MIT, https://opensource.org/licenses/MIT/
|
||||
* Please visit https://pqina.nl/filepond/ for details.
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).FilePondPluginFileValidateType=t()}(this,function(){"use strict";var e=function(e){var t=e.addFilter,n=e.utils,i=n.Type,T=n.isString,E=n.replaceInString,l=n.guesstimateMimeType,o=n.getExtensionFromFilename,r=n.getFilenameFromURL,u=function(e,t){return e.some(function(e){return/\*$/.test(e)?(n=e,(/^[^/]+/.exec(t)||[]).pop()===n.slice(0,-2)):e===t;var n})},a=function(e,t,n){if(0===t.length)return!0;var i=function(e){var t="";if(T(e)){var n=r(e),i=o(n);i&&(t=l(i))}else t=e.type;return t}(e);return n?new Promise(function(T,E){n(e,i).then(function(e){u(t,e)?T():E()}).catch(E)}):u(t,i)};return t("SET_ATTRIBUTE_TO_OPTION_MAP",function(e){return Object.assign(e,{accept:"acceptedFileTypes"})}),t("ALLOW_HOPPER_ITEM",function(e,t){var n=t.query;return!n("GET_ALLOW_FILE_TYPE_VALIDATION")||a(e,n("GET_ACCEPTED_FILE_TYPES"))}),t("LOAD_FILE",function(e,t){var n=t.query;return new Promise(function(t,i){if(n("GET_ALLOW_FILE_TYPE_VALIDATION")){var T=n("GET_ACCEPTED_FILE_TYPES"),l=n("GET_FILE_VALIDATE_TYPE_DETECT_TYPE"),o=a(e,T,l),r=function(){var e,t=T.map((e=n("GET_FILE_VALIDATE_TYPE_LABEL_EXPECTED_TYPES_MAP"),function(t){return null!==e[t]&&(e[t]||t)})).filter(function(e){return!1!==e}),l=t.filter(function(e,n){return t.indexOf(e)===n});i({status:{main:n("GET_LABEL_FILE_TYPE_NOT_ALLOWED"),sub:E(n("GET_FILE_VALIDATE_TYPE_LABEL_EXPECTED_TYPES"),{allTypes:l.join(", "),allButLastType:l.slice(0,-1).join(", "),lastType:l[l.length-1]})}})};if("boolean"==typeof o)return o?t(e):r();o.then(function(){t(e)}).catch(r)}else t(e)})}),{options:{allowFileTypeValidation:[!0,i.BOOLEAN],acceptedFileTypes:[[],i.ARRAY],labelFileTypeNotAllowed:["File is of invalid type",i.STRING],fileValidateTypeLabelExpectedTypes:["Expects {allButLastType} or {lastType}",i.STRING],fileValidateTypeLabelExpectedTypesMap:[{},i.OBJECT],fileValidateTypeDetectType:[null,i.FUNCTION]}}};return"undefined"!=typeof window&&void 0!==window.document&&document.dispatchEvent(new CustomEvent("FilePond:pluginloaded",{detail:e})),e});
|
||||
@@ -1,9 +0,0 @@
|
||||
/*!
|
||||
* FilePondPluginImageExifOrientation 1.0.11
|
||||
* Licensed under MIT, https://opensource.org/licenses/MIT/
|
||||
* Please visit https://pqina.nl/filepond/ for details.
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
!function(A,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(A=A||self).FilePondPluginImageExifOrientation=e()}(this,function(){"use strict";var A=65496,e=65505,n=1165519206,t=18761,i=274,r=65280,o=function(A,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return A.getUint16(e,n)},a=function(A,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return A.getUint32(e,n)},u="undefined"!=typeof window&&void 0!==window.document,d=void 0,f=u?new Image:{};f.onload=function(){return d=f.naturalWidth>f.naturalHeight},f.src="data:image/jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4QA6RXhpZgAATU0AKgAAAAgAAwESAAMAAAABAAYAAAEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wAALCAABAAIBASIA/8QAJgABAAAAAAAAAAAAAAAAAAAAAxABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQAAPwBH/9k=";var l=function(u){var f=u.addFilter,l=u.utils,c=l.Type,g=l.isFile;return f("DID_LOAD_ITEM",function(u,f){var l=f.query;return new Promise(function(f,c){var s=u.file;if(!(g(s)&&function(A){return/^image\/jpeg/.test(A.type)}(s)&&l("GET_ALLOW_IMAGE_EXIF_ORIENTATION")&&d))return f(u);(function(u){return new Promise(function(d,f){var l=new FileReader;l.onload=function(u){var f=new DataView(u.target.result);if(o(f,0)===A){for(var l=f.byteLength,c=2;c<l;){var g=o(f,c);if(c+=2,g===e){if(a(f,c+=2)!==n)break;var s=o(f,c+=6)===t;c+=a(f,c+4,s);var v=o(f,c,s);c+=2;for(var w=0;w<v;w++)if(o(f,c+12*w,s)===i)return void d(o(f,c+12*w+8,s))}else{if((g&r)!==r)break;c+=o(f,c)}}d(-1)}else d(-1)},l.readAsArrayBuffer(u.slice(0,65536))})})(s).then(function(A){u.setMetadata("exif",{orientation:A}),f(u)})})}),{options:{allowImageExifOrientation:[!0,c.BOOLEAN]}}};return"undefined"!=typeof window&&void 0!==window.document&&document.dispatchEvent(new CustomEvent("FilePond:pluginloaded",{detail:l})),l});
|
||||
File diff suppressed because one or more lines are too long
9
app/public/assets/js/filepond.min.js
vendored
9
app/public/assets/js/filepond.min.js
vendored
File diff suppressed because one or more lines are too long
1
app/public/assets/js/htmx.min.js
vendored
1
app/public/assets/js/htmx.min.js
vendored
File diff suppressed because one or more lines are too long
126
app/public/assets/js/overtype-webcomponent.min.js
vendored
126
app/public/assets/js/overtype-webcomponent.min.js
vendored
File diff suppressed because one or more lines are too long
1005
app/public/assets/js/overtype.min.js
vendored
1005
app/public/assets/js/overtype.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -396,15 +396,16 @@ function renderShareLinkForm(string $slug, array $link): void
|
||||
<link rel="stylesheet" href="<?= App::assetV('/assets/css/form.css') ?>">
|
||||
<link rel="stylesheet" href="<?= App::assetV('/assets/css/filepond.min.css') ?>">
|
||||
<link rel="stylesheet" href="<?= App::assetV('/assets/css/filepond-plugin-image-preview.min.css') ?>">
|
||||
<script src="<?= App::assetV('/assets/js/filepond.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/filepond-plugin-file-validate-type.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/filepond-plugin-file-validate-size.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/filepond-plugin-image-preview.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/filepond-plugin-image-exif-orientation.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/file-upload-filepond.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/beforeunload-guard.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/upload-progress.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/htmx.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/vendor/filepond.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/vendor/filepond-plugin-file-validate-type.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/vendor/filepond-plugin-file-validate-size.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/vendor/filepond-plugin-image-preview.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/vendor/filepond-plugin-image-exif-orientation.min.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/app/file-upload-filepond.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/app/beforeunload-guard.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/app/upload-progress.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/app/pill-search.js') ?>" defer></script>
|
||||
<script src="<?= App::assetV('/assets/js/vendor/htmx.min.js') ?>" defer></script>
|
||||
</head>
|
||||
<body class="student-body">
|
||||
<main id="main-content">
|
||||
|
||||
Reference in New Issue
Block a user