v1.0.0.0
StocketBase
- (function () {
- var MAX_BYTES = 25 * 1024 * 1024;
- var ACCEPT = {
- image: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
- video: ['video/mp4', 'video/webm']
- };
-
- function csrfToken() {
- var field = document.querySelector('input[name="csrf_token"]');
-
- return field ? field.value : '';
- }
-
- function element(tag, className, text) {
- var node = document.createElement(tag);
- if (className) {
- node.className = className;
- }
- if (text !== undefined) {
- node.textContent = text;
- }
-
- return node;
- }
-
- function open(options) {
- var type = options && options.type === 'video' ? 'video' : 'image';
- var onSelect = options && typeof options.onSelect === 'function' ? options.onSelect : function () {};
- var previousFocus = document.activeElement;
-
- var overlay = element('div', 'media-modal-overlay');
- var dialog = element('div', 'media-modal');
- dialog.setAttribute('role', 'dialog');
- dialog.setAttribute('aria-modal', 'true');
- dialog.setAttribute('aria-label', type === 'video' ? 'Video' : 'Image');
-
- var header = element('div', 'media-modal-header');
- var tabs = element('div', 'media-modal-tabs');
- var tabUpload = element('button', 'media-modal-tab is-active', 'Upload');
- var tabLibrary = element('button', 'media-modal-tab', 'Library');
- tabUpload.type = 'button';
- tabLibrary.type = 'button';
- tabs.appendChild(tabUpload);
- tabs.appendChild(tabLibrary);
-
- var close = element('button', 'media-modal-close');
- close.type = 'button';
- close.setAttribute('aria-label', 'Close');
- close.innerHTML = '×';
-
- header.appendChild(tabs);
- header.appendChild(close);
-
- var body = element('div', 'media-modal-body');
- var uploadPane = element('div', 'media-modal-pane');
- var libraryPane = element('div', 'media-modal-pane');
- libraryPane.hidden = true;
-
- var drop = element('label', 'media-drop');
- var dropTitle = element('div', 'media-drop-title', 'Drop a file here or click to choose');
- var dropHint = element('div', 'media-drop-hint', type === 'video' ? 'MP4 or WebM, up to 25 MB' : 'JPG, PNG, GIF or WebP, up to 25 MB');
- var fileInput = document.createElement('input');
- fileInput.type = 'file';
- fileInput.accept = ACCEPT[type].join(',');
- fileInput.hidden = true;
- drop.appendChild(dropTitle);
- drop.appendChild(dropHint);
- drop.appendChild(fileInput);
-
- var status = element('div', 'media-status');
- uploadPane.appendChild(drop);
- uploadPane.appendChild(status);
-
- var grid = element('div', 'media-grid');
- var libraryStatus = element('div', 'media-status');
- libraryPane.appendChild(libraryStatus);
- libraryPane.appendChild(grid);
-
- body.appendChild(uploadPane);
- body.appendChild(libraryPane);
- dialog.appendChild(header);
- dialog.appendChild(body);
- overlay.appendChild(dialog);
- document.body.appendChild(overlay);
- document.body.classList.add('media-modal-open');
-
- var libraryLoaded = false;
-
- function shut() {
- document.removeEventListener('keydown', onKey);
- overlay.remove();
- document.body.classList.remove('media-modal-open');
- if (previousFocus && typeof previousFocus.focus === 'function') {
- previousFocus.focus();
- }
- }
-
- function finish(url) {
- shut();
- onSelect(url);
- }
-
- function onKey(event) {
- if (event.key === 'Escape') {
- shut();
- }
- }
-
- function showTab(name) {
- var library = name === 'library';
- tabUpload.classList.toggle('is-active', !library);
- tabLibrary.classList.toggle('is-active', library);
- uploadPane.hidden = library;
- libraryPane.hidden = !library;
- if (library && !libraryLoaded) {
- loadLibrary();
- }
- }
-
- function loadLibrary() {
- libraryLoaded = true;
- libraryStatus.textContent = 'Loading…';
-
- fetch('media-library.php?type=' + type, { credentials: 'same-origin' })
- .then(function (response) { return response.json(); })
- .then(function (result) {
- if (!result.success) {
- throw new Error(result.error || 'Could not load the library.');
- }
-
- grid.innerHTML = '';
- libraryStatus.textContent = result.items.length === 0 ? 'Nothing uploaded yet.' : '';
-
- result.items.forEach(function (item) {
- var tile = element('button', 'media-tile');
- tile.type = 'button';
- tile.setAttribute('title', item.name);
-
- if (type === 'video') {
- var video = document.createElement('video');
- video.src = item.url + '#t=0.1';
- video.preload = 'metadata';
- video.muted = true;
- tile.appendChild(video);
- } else {
- var image = document.createElement('img');
- image.src = item.url;
- image.alt = '';
- image.loading = 'lazy';
- tile.appendChild(image);
- }
-
- tile.addEventListener('click', function () {
- finish(item.url);
- });
- grid.appendChild(tile);
- });
-
- if (result.total > result.items.length) {
- libraryStatus.textContent = 'Showing the newest ' + result.items.length + ' of ' + result.total + '.';
- }
- })
- .catch(function (error) {
- libraryLoaded = false;
- libraryStatus.textContent = error.message;
- });
- }
-
- function upload(file) {
- if (!file) {
- return;
- }
- if (ACCEPT[type].indexOf(file.type) === -1) {
- status.textContent = type === 'video' ? 'Use an MP4 or WebM video.' : 'Use a JPG, PNG, GIF or WebP image.';
- return;
- }
- if (file.size > MAX_BYTES) {
- status.textContent = 'The file is too large (max 25 MB).';
- return;
- }
-
- var data = new FormData();
- data.append('file', file);
- data.append('csrf_token', csrfToken());
- status.textContent = 'Uploading…';
- drop.classList.add('is-busy');
-
- fetch('media-upload.php', { method: 'POST', body: data, credentials: 'same-origin' })
- .then(function (response) { return response.json(); })
- .then(function (result) {
- if (!result.success) {
- throw new Error(result.error || 'Upload failed.');
- }
- finish(result.url);
- })
- .catch(function (error) {
- status.textContent = error.message;
- drop.classList.remove('is-busy');
- });
- }
-
- tabUpload.addEventListener('click', function () { showTab('upload'); });
- tabLibrary.addEventListener('click', function () { showTab('library'); });
- close.addEventListener('click', shut);
- overlay.addEventListener('mousedown', function (event) {
- if (event.target === overlay) {
- shut();
- }
- });
- document.addEventListener('keydown', onKey);
-
- fileInput.addEventListener('change', function () {
- upload(fileInput.files[0]);
- fileInput.value = '';
- });
-
- ['dragenter', 'dragover'].forEach(function (name) {
- drop.addEventListener(name, function (event) {
- event.preventDefault();
- drop.classList.add('is-over');
- });
- });
- ['dragleave', 'drop'].forEach(function (name) {
- drop.addEventListener(name, function (event) {
- event.preventDefault();
- drop.classList.remove('is-over');
- });
- });
- drop.addEventListener('drop', function (event) {
- if (event.dataTransfer && event.dataTransfer.files.length) {
- upload(event.dataTransfer.files[0]);
- }
- });
-
- tabUpload.focus();
- }
-
- window.StocketBaseMedia = { open: open };
- })();
-