This commit is contained in:
Loïc Guibert
2022-09-30 20:02:02 +01:00
commit 66dafc36c3
2561 changed files with 454489 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
import $ from 'jquery';
import '../../utils/jquery-utils';
import request from '../../utils/request';
import { config } from 'grav-config';
let custom = false;
let folder = $('[data-remodal-id="modal"] input[name="data[folder]"], [data-remodal-id="module"] input[name="data[folder]"], [data-remodal-id="modal-page-copy"] input[name="data[folder]"]');
let title = $('[data-remodal-id="modal"] input[name="data[title]"], [data-remodal-id="module"] input[name="data[title]"], [data-remodal-id="modal-page-copy"] input[name="data[title]"]');
let getFields = (type, target) => {
target = $(target);
let query = `[data-remodal-id="${target.closest('[data-remodal-id]').data('remodal-id')}"]`;
return {
title: type === 'title' ? $(target) : $(`${query} input[name="data[title]"]`),
folder: type === 'folder' ? $(target) : $(`${query} input[name="data[folder]"]`)
};
};
title.on('input focus blur', (event) => {
if (custom) { return true; }
let elements = getFields('title', event.currentTarget);
let slug = $.slugify(elements.title.val(), {custom: { "'": '', '': '', '': '' }});
elements.folder.val(slug);
});
folder.on('input', (event) => {
let elements = getFields('folder', event.currentTarget);
let input = elements.folder.get(0);
let value = elements.folder.val();
let selection = {
start: input.selectionStart,
end: input.selectionEnd
};
value = value.toLowerCase().replace(/\s/g, '-').replace(/[^a-z0-9_\-]/g, '');
elements.folder.val(value);
custom = !!value;
// restore cursor position
input.setSelectionRange(selection.start, selection.end);
});
folder.on('focus blur', (event) => {
getFields('title').title.trigger('input');
});
$(document).on('change', '[name="data[route]"]', (event) => {
const rawroute = $(event.currentTarget).val();
const pageTemplate = $('[name="data[name]"]');
const URI = `${config.base_url_relative}/ajax.json/task${config.param_sep}getChildTypes`;
if (pageTemplate.length === 0) {
return;
}
request(URI, {
method: 'post',
body: { rawroute }
}, (response) => {
const type = response.child_type;
if (type !== '' && type !== 'default') {
pageTemplate.val(type);
pageTemplate.data('selectize').setValue(type);
}
});
});

View File

@@ -0,0 +1,15 @@
import $ from 'jquery';
$(document).on('click', '[data-remodal-target="delete"]', function() {
let confirm = $('[data-remodal-id="delete"] [data-delete-action]');
let link = $(this).data('delete-url');
confirm.data('delete-action', link);
});
$(document).on('click', '[data-delete-action]', function() {
let remodal = $.remodal.lookup[$('[data-remodal-id="delete"]').data('remodal')];
global.location.href = $(this).data('delete-action');
remodal.close();
});

View File

@@ -0,0 +1,5 @@
import $ from 'jquery';
$('.disable-after-click').on('click', function() {
$(this).addClass('pointer-events-disabled');
});

View File

@@ -0,0 +1,47 @@
import $ from 'jquery';
import './add';
import './move';
import './delete';
import './unset';
import './disable-buttons';
import PageMedia, { Instance as PageMediaInstances } from './media';
import './multilang';
const switcher = $('input[type="radio"][name="mode-switch"]');
if (switcher) {
let link = switcher.closest(':checked').data('leave-url');
let fakeLink = $(`<a href="${link}" />`);
switcher.parent().append(fakeLink);
switcher.siblings('label').on('mousedown touchdown', (event) => {
event.preventDefault();
// let remodal = $.remodal.lookup[$('[data-remodal-id="changes"]').data('remodal')];
let confirm = $('[data-remodal-id="changes"] [data-leave-action="continue"]');
confirm.one('click', () => {
$(global).on('beforeunload._grav');
fakeLink.off('click._grav');
$(event.target).trigger('click');
});
fakeLink.trigger('click._grav');
});
switcher.on('change', (event) => {
let radio = $(event.target);
link = radio.data('leave-url');
setTimeout(() => fakeLink.attr('href', link).get(0).click(), 5);
});
}
export default {
Media: {
PageMedia,
PageMediaInstances
}
};

View File

@@ -0,0 +1,293 @@
import $ from 'jquery';
import Cookies from '../../utils/cookies.js';
import request from '../../utils/request';
import FilesField, { UriToMarkdown } from '../../forms/fields/files';
import { config, translations } from 'grav-config';
import { Instance as Editor } from '../../forms/fields/editor';
import Sortable from 'sortablejs';
const previewTemplate = `
<div class="dz-preview dz-file-preview">
<div class="dz-details">
<div class="dz-filename"><span data-dz-name></span></div>
<div class="dz-size" data-dz-size></div>
<img data-dz-thumbnail />
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-success-mark"><span>✔</span></div>
<div class="dz-error-mark"><span>✘</span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<a class="dz-remove" title="${translations.PLUGIN_ADMIN.DELETE}" href="javascript:undefined;" data-dz-remove>${translations.PLUGIN_ADMIN.DELETE}</a>
<a class="dz-metadata" title="${translations.PLUGIN_ADMIN.METADATA}" href="#" target="_blank" data-dz-metadata>${translations.PLUGIN_ADMIN.METADATA}</a>
<a class="dz-view" title="${translations.PLUGIN_ADMIN.VIEW}" href="#" target="_blank" data-dz-view>${translations.PLUGIN_ADMIN.VIEW}</a>
<a class="dz-insert" title="${translations.PLUGIN_ADMIN.INSERT}" href="javascript:undefined;" data-dz-insert>${translations.PLUGIN_ADMIN.INSERT}</a>
</div>`.trim();
export default class PageMedia extends FilesField {
constructor({ container = '#grav-dropzone', options = {} } = {}) {
options = Object.assign(options, { previewTemplate });
super({ container, options });
if (!this.container.length) { return; }
this.urls = {
fetch: `${this.container.data('media-url')}/task${config.param_sep}listmedia`,
add: `${this.container.data('media-url')}/task${config.param_sep}addmedia`,
delete: `${this.container.data('media-url')}/task${config.param_sep}delmedia`
};
this.dropzone.options.url = this.urls.add;
if (typeof this.options.fetchMedia === 'undefined' || this.options.fetchMedia) {
this.fetchMedia();
}
if (typeof this.options.attachDragDrop === 'undefined' || this.options.attachDragDrop) {
this.attachDragDrop();
}
const field = $(`[name="${this.container.data('dropzone-field')}"]`);
if (field.length) {
this.sortable = new Sortable(this.container.get(0), {
animation: 150,
// forceFallback: true,
setData: (dataTransfer, target) => {
target = $(target);
let uri = encodeURI(target.find('.dz-filename').text());
let shortcode = UriToMarkdown(uri);
this.dropzone.disable();
target.addClass('hide-backface');
dataTransfer.effectAllowed = 'copy';
dataTransfer.setData('text', shortcode);
},
onSort: () => {
let names = [];
this.container.find('[data-dz-name]').each((index, file) => {
file = $(file);
const name = file.text().trim();
names.push(name);
});
field.val(names.join(','));
}
});
}
}
fetchMedia() {
const order = this.container.closest('.form-field').find('[name="data[header][media_order]"]').val();
const body = { uri: this.getURI(), order };
let url = this.urls.fetch;
request(url, { method: 'post', body }, (response) => {
let results = response.results;
Object.keys(results).forEach((name) => {
let data = results[name];
let mock = { name, size: data.size, accepted: true, extras: data };
this.dropzone.files.push(mock);
this.dropzone.options.addedfile.call(this.dropzone, mock);
this.dropzone.options.thumbnail.call(this.dropzone, mock, data.url);
});
this.updateThumbsSize();
this.container.find('.dz-preview').prop('draggable', 'true');
});
}
onDropzoneSending(file, xhr, formData) {
/*
// Cannot call super because Safari and IE API don't implement `delete`
super.onDropzoneSending(file, xhr, formData);
formData.delete('task');
*/
formData.append('name', this.options.dotNotation || file.name);
formData.append('admin-nonce', config.admin_nonce);
formData.append('uri', this.getURI());
}
onDropzoneComplete(file) {
super.onDropzoneComplete(file);
if (this.sortable) {
this.sortable.options.onSort();
}
// accepted
this.updateThumbsSize();
this.updateMediaCount();
$('.dz-preview').prop('draggable', 'true');
}
onDropzoneAddedFile(file, ...extra) {
super.onDropzoneAddedFile(file, extra);
this.updateThumbsSize();
}
onDropzoneRemovedFile(file, ...extra) {
super.onDropzoneRemovedFile(file, ...extra);
this.updateMediaCount();
if (this.sortable) {
this.sortable.options.onSort();
}
}
updateThumbsSize() {
const status = JSON.parse(Cookies.get('grav-admin-pagemedia') || '{}');
if (status.width) {
const input = this.container.closest('.pagemedia-field').find('.media-resizer');
updateMediaSizes(input[0], status.width, false);
}
}
updateMediaCount() {
const element = this.container.closest('.pagemedia-field').find('[data-pagemedia-count]');
element.text(`(${this.dropzone.files.length})`);
}
attachDragDrop() {
this.container.delegate('[data-dz-insert]', 'click', (e) => {
let target = $(e.currentTarget).parent('.dz-preview').find('.dz-filename');
let editor = Editor.editors.filter((index, editor) => $(editor).attr('name') === 'data[content]');
if (editor.length) {
editor = editor.data('codemirror');
editor.focus();
let filename = encodeURI(target.text());
let shortcode = UriToMarkdown(filename);
editor.doc.replaceSelection(shortcode);
}
});
this.container.delegate('[data-dz-view]', 'mouseenter', (e) => {
let target = $(e.currentTarget);
let file = target.parent('.dz-preview').find('.dz-filename');
let filename = encodeURI(file.text());
let URL = target.closest('[data-media-path]').data('media-path');
let original = this.dropzone.files.filter((file) => encodeURI(file.name) === filename).shift();
original = original && ((original.extras && original.extras.original) || encodeURI(original.name));
target.attr('href', `${URL}/${original}`);
});
this.container.delegate('[data-dz-metadata]', 'click', (e) => {
e.preventDefault();
const target = $(e.currentTarget);
const file = target.parent('.dz-preview').find('.dz-filename');
const filename = encodeURI(file.text());
const cleanName = file.text().replace('<', '&lt;').replace('>', '&gt;');
let fileObj = this.dropzone.files.filter((file) => file.name === global.decodeURI(filename)).shift() || {};
if (!fileObj.extras) {
fileObj.extras = { metadata: [] };
}
if (Array.isArray(fileObj.extras.metadata) && !fileObj.extras.metadata.length) {
fileObj.extras.metadata = { '': `${cleanName}.meta.yaml doesn't exist` };
}
fileObj = fileObj.extras;
const modal_element = $('body').find('[data-remodal-id="metadata"]');
const modal = $.remodal.lookup[modal_element.data('remodal')];
modal_element.find('h1 strong').html(cleanName);
if (fileObj.url) {
modal_element.find('.meta-preview').html(`<img src="${fileObj.url}" />`);
}
const container = modal_element.find('.meta-content').html('<ul />').find('ul');
Object.keys(fileObj.metadata).forEach((meta) => {
const cleanMeta = fileObj.metadata[meta].replace('<', '&lt;').replace('>', '&gt;');
container.append(`<li><strong>${meta ? meta + ':' : ''}</strong> ${cleanMeta}</li>`);
});
modal.open();
});
this.container.delegate('.dz-preview', 'dragstart', (e) => {
let target = $(e.currentTarget);
let uri = encodeURI(target.find('.dz-filename').text());
let shortcode = UriToMarkdown(uri);
this.dropzone.disable();
target.addClass('hide-backface');
e.originalEvent.dataTransfer.effectAllowed = 'copy';
e.originalEvent.dataTransfer.setData('text', shortcode);
});
this.container.delegate('.dz-preview', 'dragend', (e) => {
let target = $(e.currentTarget);
this.dropzone.enable();
target.removeClass('hide-backface');
});
}
}
export const updateMediaSizes = (input, width, store = true) => {
const storageLocation = input.dataset.storageLocation || 'grav-admin-pagemedia';
const status = JSON.parse(Cookies.get(storageLocation) || '{}');
const height = 150 * width / 200;
const media = $(input).closest('.pagemedia-field').find('.dz-details, [data-dz-thumbnail]');
media.css({ width, height });
if (store) {
const data = Object.assign({}, status, { width });
Cookies.set(storageLocation, JSON.stringify(data), { expires: Infinity });
}
};
export const updateMediaCollapseStatus = (element, store = true) => {
const storageLocation = element.dataset.storageLocation || 'grav-admin-pagemedia';
const status = JSON.parse(Cookies.get(storageLocation) || '{}');
element = $(element);
const icon = element.find('i.fa');
const container = element.closest('.pagemedia-field');
const panel = container.find('.form-data');
const slider = container.find('.media-resizer').parent();
const isCollapsed = !icon.hasClass('fa-chevron-down');
const collapsed = !isCollapsed;
icon.removeClass('fa-chevron-down fa-chevron-right').addClass(isCollapsed ? 'fa-chevron-down' : 'fa-chevron-right');
slider[isCollapsed ? 'removeClass' : 'addClass']('hidden');
panel[isCollapsed ? 'slideDown' : 'slideUp']();
if (store) {
const data = Object.assign({}, status, { collapsed });
Cookies.set(storageLocation, JSON.stringify(data), { expires: Infinity });
}
};
$(document).on('input', '.media-resizer', (event) => {
const target = $(event.currentTarget);
const width = target.val();
updateMediaSizes(event.currentTarget, width);
});
$(document).on('click', '.media-collapser', (event) => {
updateMediaCollapseStatus(event.currentTarget);
});
$(document).ready(() => {
$('.media-resizer').each((index, input) => {
const storageLocation = input.dataset.storageLocation || 'grav-admin-pagemedia';
const status = JSON.parse(Cookies.get(storageLocation) || '{}');
if (status.width) {
updateMediaSizes(input, status.width, false);
}
});
});
export let Instance = new PageMedia();

View File

@@ -0,0 +1,63 @@
import $ from 'jquery';
$(document).on('click', '[data-page-move] button[name="task"][value="save"]', (event) => {
/* let route = $('form#blueprints:first select[name="data[route]"]');
let moveTo = $('[data-page-move] select').val();
if (route.length && route.val() !== moveTo) {
let selectize = route.data('selectize');
route.val(moveTo);
if (selectize) selectize.setValue(moveTo);
}*/
const modal = $(event.currentTarget).closest('[data-remodal-id]');
const parents = modal.data('parents') || {};
const finder = parents.finder;
if (!parents || !finder) { return true; }
const field = parents.field;
const parentLabel = parents.parentLabel;
const parentName = parents.parentName;
const selection = finder.findLastActive().item[0];
const value = selection._item[finder.config.valueKey];
const name = selection._item[finder.config.labelKey];
field.val(value);
parentLabel.text(value);
parentName.text(name);
finder.config.defaultPath = value;
$('<div />').css({
backgroundColor: 'rgba(255, 255, 255, 0.1)',
position: 'fixed',
top: 0,
left: 0,
width: '100vw',
height: '100vh',
zIndex: 15000
}).appendTo($('body'));
});
/*
$(document).on('click', '[data-remodal-id="parents"] [data-parents-select]', (event) => {
const modal = $(event.currentTarget).closest('[data-remodal-id]');
const parents = modal.data('parents');
const finder = parents.finder;
const field = parents.field;
const parentLabel = parents.parentLabel;
const parentName = parents.parentName;
const selection = finder.findLastActive().item[0];
const value = selection._item[finder.config.valueKey];
const name = selection._item[finder.config.labelKey];
field.val(value);
parentLabel.text(value);
parentName.text(name);
finder.config.defaultPath = value;
const remodal = $.remodal.lookup[$(`[data-remodal-id="${modal.data('remodalId')}"]`).data('remodal')];
remodal.close();
});
*/

View File

@@ -0,0 +1,22 @@
import $ from 'jquery';
$('[name="task"][value="saveas"], [name="task"][value="switchlanguage"]').on('mousedown touchstart', (event) => {
let fields = ['lang', 'redirect'];
let element = $(event.currentTarget);
let form = $(`#${element.attr('form')}`);
if (!form.length) { return; }
fields.forEach((field) => {
let value = element.attr(field);
if (!value) { return; }
let input = form.find(`[name="data[${field}]"]`);
if (!input.length) {
input = $(`<input type="hidden" name="data[${field}]" value="" />`);
form.append(input);
}
input.val(value);
});
return true;
});

View File

@@ -0,0 +1,18 @@
import $ from 'jquery';
$(document).on('click', '.dz-unset', function() {
const file_upload = $(this).closest('.files-upload');
$(this).closest('.dz-image-preview').remove();
const unset_image = $(this).closest('.dz-image-preview').find('[data-dz-name]').text().trim();
const images = JSON.parse(file_upload.find('input[data-grav-field="hidden"]').val()) || {};
let image_array = {};
$.each(images, function(ind, obj) {
if (!ind.endsWith(unset_image)) {
image_array[ind] = obj;
}
});
file_upload.find('input[data-grav-field="hidden"]').val(JSON.stringify(image_array));
});