ponepaste/public/assets/bundle/generic.js

222 lines
6.4 KiB
JavaScript
Raw Normal View History

2022-07-30 17:55:17 -04:00
const $ = function(selector) {
return document.querySelector(selector);
};
const $$ = function(selector) {
return document.querySelectorAll(selector) || [];
};
const makeEl = function(html) {
const template = document.createElement('template');
template.innerHTML = html.trim();
return template.content.firstChild;
};
const toggleEl = function(el) {
if (el.classList.contains('is-hidden')) {
el.classList.remove('is-hidden');
} else {
el.classList.add('is-hidden');
}
};
const escape = function(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
};
const whenReady = function(funcp) {
if (document.readyState !== 'loading') {
funcp();
} else {
document.addEventListener('DOMContentLoaded', funcp);
}
};
class TagsInput {
constructor(element, options = {}) {
this.element = element;
this.tags = [];
this.options = options;
this.maxTags = options.maxTags || 10;
this.inputNode = null;
this.containerNode = null;
}
attach() {
this.element.style.display = 'none';
this.containerNode = makeEl('<div class="tags-input"></div>');
this.inputNode = makeEl('<input class="input" type="text" placeholder="10 tags maximum" value="" />');
this.containerNode.appendChild(this.inputNode);
this.element.parentNode.insertBefore(this.containerNode, this.element.nextSibling);
/* Load existing tags from input */
if (this.element.value) {
for (const tag of this.element.value.split(',')) {
this.addTag(tag);
}
}
/* Handle addition and removal of tags via key-presses */
this.containerNode.addEventListener('keydown', this._handleInputKeyUp.bind(this));
/* Handle deletions by clicking the delete button */
this.containerNode.addEventListener('click', this._handleContainerClick.bind(this));
}
detach() {
this.tags.clear();
this.containerNode.remove();
this.element.style.display = 'inline-block';
}
updateHiddenInputValue() {
this.element.value = this.tags.join(',');
}
deleteTagNode(node) {
this.tags.splice(this.tags.indexOf(node.dataset.value.toLowerCase()), 1);
node.remove();
/* Below the limit? Make sure the input is enabled. */
if (this.tags.length < this.maxTags) {
this.inputNode.disabled = false;
}
}
addTag(tagValue) {
tagValue = tagValue.trim();
/* Tag value is probably not empty and we don't already have the same tag. */
if (tagValue !== '' && this.tags.indexOf(tagValue.toLowerCase()) === -1) {
this.tags.push(tagValue.toLowerCase());
this.inputNode.parentNode.insertBefore(
makeEl('<span class="tag is-info" data-value="' + escape(tagValue) + '">' + escape(tagValue) + '<span class="delete is-small" /></span>'),
this.inputNode
);
/* Too many tags, disable the input for now. */
if (this.tags.length >= this.maxTags) {
this.inputNode.disabled = true;
}
}
}
_handleInputKeyUp(evt) {
let tagValue = this.inputNode.value;
if (evt.key === 'Backspace' && tagValue === '') {
// Remove the child
if (this.inputNode.previousSibling) {
this.deleteTagNode(this.inputNode.previousSibling);
this.updateHiddenInputValue();
}
} else if (evt.key === ',') {
this.addTag(tagValue);
this.inputNode.value = '';
this.updateHiddenInputValue();
evt.preventDefault();
}
}
_handleContainerClick(evt) {
if (evt.target && evt.target.classList.contains('delete')) {
this.deleteTagNode(evt.target.closest('.tag'));
this.updateHiddenInputValue();
}
}
}
const setupSignupModal = () => {
const signupButton = $('[data-target~="#signin"],[data-target~="#signup"]');
if (signupButton) {
signupButton.addEventListener('click', () => {
$('.modal').classList.add('is-active');
});
$('.modal-button-close').addEventListener('click', () => {
$('.modal').classList.remove('is-active');
});
}
};
const globalSetup = () => {
Array.prototype.forEach.call($$('.js-tag-input'), (el) => {
new TagsInput(el).attach();
});
setupSignupModal();
const embedButton = $('.panel-tools .embed-tool');
if (embedButton){
embedButton.addEventListener('click', (evt) => {
if (evt.target && evt.target.closest('.panel-tools')) {
toggleEl(evt.target.closest('.panel-tools').querySelector('.panel-embed'));
}
});
}
const expandButton = $('.expand-tool');
if (expandButton) {
expandButton.addEventListener('click', (evt) => {
if (evt.target && evt.target.closest('.panel')) {
const panel = evt.target.closest('.panel');
if (panel.classList.contains('panel-fullsize')) {
panel.classList.remove('panel-fullsize');
} else {
panel.classList.add('panel-fullsize');
}
}
});
}
// Notifications
(document.querySelectorAll('.notification .delete') || []).forEach(($delete) => {
const $notification = $delete.parentNode;
$delete.addEventListener('click', () => {
$notification.parentNode.removeChild($notification);
});
});
// Hamburger menu
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
if ($navbarBurgers.length > 0) {
$navbarBurgers.forEach(el => {
el.addEventListener('click', () => {
const target = el.dataset.target;
const $target = document.getElementById(target);
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
}
const preloader = $('.preloader');
const main = $('main');
if (preloader && main) {
preloader.remove();
main.id = '';
}
};
whenReady(globalSetup);