diff --git a/includes/common.php b/includes/common.php index d0e9f43..1997ab6 100644 --- a/includes/common.php +++ b/includes/common.php @@ -119,10 +119,10 @@ $site_permissions = $site_info['permissions']; if ($site_permissions) { $site_is_private = (bool) $site_permissions['private']; - $site_disable_guest = (bool) $site_permissions['disable_guest']; + $site_disable_guests = (bool) $site_permissions['disable_guest']; } else { $site_is_private = false; - $site_disable_guest = false; + $site_disable_guests = false; } // CAPTCHA configuration diff --git a/js/tag_input.js b/js/tag_input.js new file mode 100644 index 0000000..9d623a3 --- /dev/null +++ b/js/tag_input.js @@ -0,0 +1,110 @@ +function htmlToElement(html) { + const template = document.createElement('template'); + + template.innerHTML = html.trim(); + + return template.content.firstChild; +} + +function escapeHtml(unsafe) { + return unsafe + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +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 = htmlToElement('
'); + this.inputNode = htmlToElement(''); + this.containerNode.appendChild(this.inputNode); + + this.element.parentNode.insertBefore(this.containerNode, this.element.nextSibling); + + /* 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( + htmlToElement('' + escapeHtml(tagValue) + ''), + 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(); + } + } +} diff --git a/theme/bulma/main.php b/theme/bulma/main.php index 2c49f2d..6f8008d 100644 --- a/theme/bulma/main.php +++ b/theme/bulma/main.php @@ -1,10 +1,15 @@ +