From 985bc39a60bd63b98e35320971678a9278e6aed2 Mon Sep 17 00:00:00 2001 From: Floorb <132411956+Neetpone@users.noreply.github.com> Date: Tue, 23 Nov 2021 03:17:29 -0500 Subject: [PATCH] Various front and backend code improvements --- api/ajax_pastes.php | 11 +- archive.php | 1 + assets/bundle/bundle.js | 354 -------------------------------- assets/bundle/bundle.min.js | 2 - assets/bundle/bundle.min.js.map | 1 - includes/common.php | 10 + index.php | 2 +- js/archive.js | 43 +++- js/dom.js | 9 +- js/generic.js | 4 + js/main.js | 88 ++++---- paste.php | 8 +- rollup.config.js | 41 ++-- theme/bulma/archive.php | 3 +- theme/bulma/common.php | 47 +---- theme/bulma/css/paste.css | 2 - theme/bulma/view.php | 65 +----- user.php | 2 +- 18 files changed, 165 insertions(+), 528 deletions(-) delete mode 100644 assets/bundle/bundle.js delete mode 100644 assets/bundle/bundle.min.js delete mode 100644 assets/bundle/bundle.min.js.map create mode 100644 js/generic.js diff --git a/api/ajax_pastes.php b/api/ajax_pastes.php index 226ad4a..db81e0d 100644 --- a/api/ajax_pastes.php +++ b/api/ajax_pastes.php @@ -11,7 +11,16 @@ $pastes = Paste::with([ 'tags' => function($query) { $query->select('tags.id', 'name', 'slug'); } -])->select(['id', 'user_id', 'title'])->get(); +])->select(['id', 'user_id', 'title']); + +if (!empty($_GET['q']) && is_string($_GET['q'])) { + $tags = explode(',', $_GET['q']); + $pastes = $pastes->whereHas('tags', function($query) use ($tags) { + $query->where('name', $tags); + }); +} + +$pastes = $pastes->get(); header('Content-Type: application/json; charset=UTF-8'); diff --git a/archive.php b/archive.php index 9248616..e8980e1 100644 --- a/archive.php +++ b/archive.php @@ -15,4 +15,5 @@ updatePageViews($conn); // Theme $page_template = 'archive'; $page_title = 'Pastes Archive'; +array_push($script_bundles, 'archive'); require_once('theme/' . $default_theme . '/common.php'); diff --git a/assets/bundle/bundle.js b/assets/bundle/bundle.js deleted file mode 100644 index 5556f4a..0000000 --- a/assets/bundle/bundle.js +++ /dev/null @@ -1,354 +0,0 @@ -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 clearEl = function(el) { - while (el.firstChild) { - el.removeChild(el.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, ">") - .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 = makeEl('
'); - this.inputNode = makeEl(''); - 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('' + escape(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(); - } - } -} - -class SimplePaginator { - constructor(element) { - this.element = element; - } - - attach(pageCallback) { - this.element.addEventListener('click', evt => { - if (evt.target && evt.target.classList.contains('paginator__button')) { - pageCallback(+evt.target.dataset.page); - } - }); - } - - update(totalRecords, perPage, currentPage) { - clearEl(this.element); - - /* First and last page in existence */ - const firstPage = 0; - const lastPage = Math.floor(totalRecords / perPage); // ish? - const numPagesToShow = 2; - - /* First and last page the main paginator will show */ - const firstPageShow = (currentPage - firstPage) < numPagesToShow ? firstPage : ((currentPage - numPagesToShow < 0) ? currentPage : currentPage - numPagesToShow); - const lastPageShow = (firstPageShow + numPagesToShow) > lastPage ? lastPage : (firstPageShow + numPagesToShow + numPagesToShow); - - /* Whether to show the first and last pages in existence at the ends of the paginator */ - const showFirstPage = (Math.abs(firstPage - currentPage)) > (numPagesToShow); - const showLastPage = (Math.abs(lastPage - currentPage)) > (numPagesToShow); - - - const prevButtonDisabled = currentPage === firstPage ? 'disabled' : ''; - - /* Previous button */ - this.element.appendChild(makeEl( - `` - )); - - /* First page button */ - if (showFirstPage) { - this.element.appendChild(makeEl( - `${firstPage}` - )); - this.element.appendChild(makeEl(``)); - } - - /* "window" buttons */ - for (let i = firstPageShow; i <= lastPageShow; i++) { - const selected = (i === currentPage ? 'paginator__button--selected' : ''); - this.element.appendChild(makeEl( - `${i}` - )); - } - - /* Last page button */ - if (showLastPage) { - this.element.appendChild(makeEl(``)); - this.element.appendChild(makeEl( - `${lastPage}` - )); - } - - const nextButtonDisabled = currentPage === lastPage ? 'disabled' : ''; - /* Next button */ - this.element.appendChild(makeEl( - `` - )); - } -} - -class DataTable { - constructor(element, options) { - this.element = element; - this.container = element.parentElement; - this.options = options; - - this.ajaxCallback = options.ajaxCallback; - this.data = []; - - this.totalRecords = -1; - this.perPage = 20; - this.currentPage = 0; - - this.paginator = new SimplePaginator(this.container.querySelector('.paginator')); - - } - - attach() { - this.paginator.attach(this._updatePage.bind(this)); - this._loadEntries(); - } - - /* Load the requested data from the server, and when done, update the DOM. */ - _loadEntries() { - new Promise(this.ajaxCallback) - .then(this._updateEntries.bind(this)); - } - - /* Update the DOM to reflect the current state of the data we have loaded */ - _updateEntries(data) { - this.data = data.data; - this.totalRecords = this.data.length; - - const bodyElement = this.element.querySelector('tbody'); - clearEl(bodyElement); - - const firstIndex = (this.perPage * this.currentPage); - const lastIndex = (firstIndex + this.perPage) > this.totalRecords ? this.totalRecords : (firstIndex + this.perPage); - - - for (let i = firstIndex; i < lastIndex; i++) { - const rowElem = makeEl(this.options.rowCallback(this.data[i])); - rowElem.classList.add(i % 2 === 0 ? 'odd' : 'even'); - - bodyElement.appendChild(rowElem); - } - - this.paginator.update(this.totalRecords, this.perPage, this.currentPage); - } - - _updatePage(n) { - this.currentPage = n; - this.paginator.update(this.totalRecords, this.perPage, this.currentPage); - this._updateEntries({data: this.data}); - } - - _updateSort(field, direction) { - - } -} - -const setupSite = function() { - Array.prototype.forEach.call($$('.js-tag-input'), (el) => { - new TagsInput(el).attach(); - }); - - if (document.querySelector('#archive')) { - const table = new DataTable(document.querySelector('#archive'), { - ajaxCallback: (resolve) => { - fetch('/api/ajax_pastes.php') - .then(r => r.json()) - .then(resolve); - }, - rowCallback: (rowData) => { - const tags = rowData.tags.map((tagData) => { - let tagColorClass; - if (tagData.name.indexOf('nsfw') !== -1) { - tagColorClass = 'is-danger'; - } else if (tagData.name.indexOf('safe') !== -1) { - tagColorClass = 'is-success'; - } else if (tagData.name.indexOf('/') !== -1) { - tagColorClass = 'is-primary'; - } else { - tagColorClass = 'is-info'; - } - - return ` - ${escape(tagData.name)} - `; - }).join(''); - - return ` - ${escape(rowData.title)} - ${escape(rowData.author)} - ${tags} - `; - } - }); - table.attach(); - } - - 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 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'); - } - } - }); - } -}; - -if (document.readyState !== 'loading') { - setupSite(); -} else { - document.addEventListener('DOMContentLoaded', setupSite); -} diff --git a/assets/bundle/bundle.min.js b/assets/bundle/bundle.min.js deleted file mode 100644 index 85d1860..0000000 --- a/assets/bundle/bundle.min.js +++ /dev/null @@ -1,2 +0,0 @@ -function t(t,a){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!n){if(Array.isArray(t)||(n=function(t,a){if(!t)return;if("string"==typeof t)return e(t,a);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return e(t,a)}(t))||a&&t&&"number"==typeof t.length){n&&(t=n);var i=0,s=function(){};return{s:s,n:function(){return i>=t.length?{done:!0}:{done:!1,value:t[i++]}},e:function(t){throw t},f:s}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var r,o=!0,l=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return o=t.done,t},e:function(t){l=!0,r=t},f:function(){try{o||null==n.return||n.return()}finally{if(l)throw r}}}}function e(t,e){(null==e||e>t.length)&&(e=t.length);for(var a=0,n=new Array(e);a/g,">").replace(/"/g,""").replace(/'/g,"'")},c=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};a(this,e),this.element=t,this.tags=[],this.options=n,this.maxTags=n.maxTags||10,this.inputNode=null,this.containerNode=null}return i(e,[{key:"attach",value:function(){if(this.element.style.display="none",this.containerNode=r('
'),this.inputNode=r(''),this.containerNode.appendChild(this.inputNode),this.element.parentNode.insertBefore(this.containerNode,this.element.nextSibling),this.element.value){var e,a=t(this.element.value.split(","));try{for(a.s();!(e=a.n()).done;){var n=e.value;this.addTag(n)}}catch(t){a.e(t)}finally{a.f()}}this.containerNode.addEventListener("keydown",this._handleInputKeyUp.bind(this)),this.containerNode.addEventListener("click",this._handleContainerClick.bind(this))}},{key:"detach",value:function(){this.tags.clear(),this.containerNode.remove(),this.element.style.display="inline-block"}},{key:"updateHiddenInputValue",value:function(){this.element.value=this.tags.join(",")}},{key:"deleteTagNode",value:function(t){this.tags.splice(this.tags.indexOf(t.dataset.value.toLowerCase()),1),t.remove(),this.tags.length'+l(t)+''),this.inputNode),this.tags.length>=this.maxTags&&(this.inputNode.disabled=!0))}},{key:"_handleInputKeyUp",value:function(t){var e=this.inputNode.value;"Backspace"===t.key&&""===e?this.inputNode.previousSibling&&(this.deleteTagNode(this.inputNode.previousSibling),this.updateHiddenInputValue()):","===t.key&&(this.addTag(e),this.inputNode.value="",this.updateHiddenInputValue(),t.preventDefault())}},{key:"_handleContainerClick",value:function(t){t.target&&t.target.classList.contains("delete")&&(this.deleteTagNode(t.target.closest(".tag")),this.updateHiddenInputValue())}}]),e}(),d=function(){function t(e){a(this,t),this.element=e}return i(t,[{key:"attach",value:function(t){this.element.addEventListener("click",(function(e){e.target&&e.target.classList.contains("paginator__button")&&t(+e.target.dataset.page)}))}},{key:"update",value:function(t,e,a){o(this.element);var n=Math.floor(t/e),i=a-0<2?0:a-2<0?a:a-2,s=i+2>n?n:i+2+2,l=Math.abs(0-a)>2,c=Math.abs(n-a)>2,d=0===a?"disabled":"";this.element.appendChild(r(''))),l&&(this.element.appendChild(r('').concat(0,""))),this.element.appendChild(r('')));for(var u=i;u<=s;u++){var h=u===a?"paginator__button--selected":"";this.element.appendChild(r('').concat(u,"")))}c&&(this.element.appendChild(r('')),this.element.appendChild(r('').concat(n,""))));var p=a===n?"disabled":"";this.element.appendChild(r('')))}}]),t}(),u=function(){function t(e,n){a(this,t),this.element=e,this.container=e.parentElement,this.options=n,this.ajaxCallback=n.ajaxCallback,this.data=[],this.totalRecords=-1,this.perPage=20,this.currentPage=0,this.paginator=new d(this.container.querySelector(".paginator"))}return i(t,[{key:"attach",value:function(){this.paginator.attach(this._updatePage.bind(this)),this._loadEntries()}},{key:"_loadEntries",value:function(){new Promise(this.ajaxCallback).then(this._updateEntries.bind(this))}},{key:"_updateEntries",value:function(t){this.data=t.data,this.totalRecords=this.data.length;var e=this.element.querySelector("tbody");o(e);for(var a=this.perPage*this.currentPage,n=a+this.perPage>this.totalRecords?this.totalRecords:a+this.perPage,i=a;i\n ').concat(l(t.name),"\n ")})).join("");return'\n ').concat(l(t.title),'\n ').concat(l(t.author),"\n ").concat(e,"\n ")}}).attach();var e=s('[data-target~="#signin"],[data-target~="#signup"]');e&&(e.addEventListener("click",(function(){s(".modal").classList.add("is-active")})),s(".modal-button-close").addEventListener("click",(function(){s(".modal").classList.remove("is-active")})));var a=s(".panel-tools .embed-tool");a&&a.addEventListener("click",(function(t){var e;t.target&&t.target.closest(".panel-tools")&&((e=t.target.closest(".panel-tools").querySelector(".panel-embed")).classList.contains("is-hidden")?e.classList.remove("is-hidden"):e.classList.add("is-hidden"))}));var n=s(".expand-tool");n&&n.addEventListener("click",(function(t){if(t.target&&t.target.closest(".panel")){var e=t.target.closest(".panel");e.classList.contains("panel-fullsize")?e.classList.remove("panel-fullsize"):e.classList.add("panel-fullsize")}}))};"loading"!==document.readyState?h():document.addEventListener("DOMContentLoaded",h); -//# sourceMappingURL=bundle.min.js.map diff --git a/assets/bundle/bundle.min.js.map b/assets/bundle/bundle.min.js.map deleted file mode 100644 index 29cbc78..0000000 --- a/assets/bundle/bundle.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"bundle.min.js","sources":["../../js/dom.js","../../js/tag_input.js","../../js/data_tables.js","../../js/main.js"],"sourcesContent":["const $ = function(selector) {\n return document.querySelector(selector);\n};\n\nconst $$ = function(selector) {\n return document.querySelectorAll(selector) || [];\n};\n\nconst makeEl = function(html) {\n const template = document.createElement('template');\n\n template.innerHTML = html.trim();\n\n return template.content.firstChild;\n};\n\nconst clearEl = function(el) {\n while (el.firstChild) {\n el.removeChild(el.firstChild);\n }\n};\n\nconst toggleEl = function(el) {\n if (el.classList.contains('is-hidden')) {\n el.classList.remove('is-hidden');\n } else {\n el.classList.add('is-hidden');\n }\n};\n\nconst escape = function(unsafe) {\n return unsafe\n .replace(/&/g, \"&\")\n .replace(//g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n\nexport { $, $$, makeEl, clearEl, toggleEl, escape };","import { makeEl, escape } from \"./dom\";\n\nclass TagsInput {\n constructor(element, options = {}) {\n this.element = element;\n this.tags = [];\n this.options = options\n\n this.maxTags = options.maxTags || 10;\n this.inputNode = null;\n this.containerNode = null;\n }\n\n attach() {\n this.element.style.display = 'none';\n\n this.containerNode = makeEl('
');\n this.inputNode = makeEl('');\n this.containerNode.appendChild(this.inputNode);\n\n this.element.parentNode.insertBefore(this.containerNode, this.element.nextSibling);\n\n /* Load existing tags from input */\n if (this.element.value) {\n for (const tag of this.element.value.split(',')) {\n this.addTag(tag);\n }\n }\n\n /* Handle addition and removal of tags via key-presses */\n this.containerNode.addEventListener('keydown', this._handleInputKeyUp.bind(this));\n\n /* Handle deletions by clicking the delete button */\n this.containerNode.addEventListener('click', this._handleContainerClick.bind(this));\n }\n\n detach() {\n this.tags.clear();\n this.containerNode.remove();\n this.element.style.display = 'inline-block';\n }\n\n updateHiddenInputValue() {\n this.element.value = this.tags.join(',');\n }\n\n deleteTagNode(node) {\n this.tags.splice(this.tags.indexOf(node.dataset.value.toLowerCase()), 1);\n node.remove();\n\n /* Below the limit? Make sure the input is enabled. */\n if (this.tags.length < this.maxTags) {\n this.inputNode.disabled = false;\n }\n }\n\n addTag(tagValue) {\n tagValue = tagValue.trim();\n\n /* Tag value is probably not empty and we don't already have the same tag. */\n if (tagValue !== '' && this.tags.indexOf(tagValue.toLowerCase()) === -1) {\n this.tags.push(tagValue.toLowerCase());\n\n this.inputNode.parentNode.insertBefore(\n makeEl('' + escape(tagValue) + ''),\n this.inputNode\n );\n\n /* Too many tags, disable the input for now. */\n if (this.tags.length >= this.maxTags) {\n this.inputNode.disabled = true;\n }\n }\n }\n\n _handleInputKeyUp(evt) {\n let tagValue = this.inputNode.value;\n\n if (evt.key === 'Backspace' && tagValue === '') {\n // Remove the child\n if (this.inputNode.previousSibling) {\n this.deleteTagNode(this.inputNode.previousSibling);\n\n this.updateHiddenInputValue();\n }\n } else if (evt.key === ',') {\n this.addTag(tagValue);\n\n this.inputNode.value = ''\n this.updateHiddenInputValue();\n\n evt.preventDefault();\n }\n }\n\n _handleContainerClick(evt) {\n if (evt.target && evt.target.classList.contains('delete')) {\n this.deleteTagNode(evt.target.closest('.tag'));\n this.updateHiddenInputValue();\n }\n }\n}\n\nexport { TagsInput };\n","import { makeEl, clearEl } from \"./dom\";\n\n\nclass SimplePaginator {\n constructor(element) {\n this.element = element;\n }\n\n attach(pageCallback) {\n this.element.addEventListener('click', evt => {\n if (evt.target && evt.target.classList.contains('paginator__button')) {\n pageCallback(+evt.target.dataset.page);\n }\n });\n }\n\n update(totalRecords, perPage, currentPage) {\n clearEl(this.element);\n\n /* First and last page in existence */\n const firstPage = 0;\n const lastPage = Math.floor(totalRecords / perPage); // ish?\n const numPagesToShow = 2;\n\n /* First and last page the main paginator will show */\n const firstPageShow = (currentPage - firstPage) < numPagesToShow ? firstPage : ((currentPage - numPagesToShow < 0) ? currentPage : currentPage - numPagesToShow);\n const lastPageShow = (firstPageShow + numPagesToShow) > lastPage ? lastPage : (firstPageShow + numPagesToShow + numPagesToShow);\n\n /* Whether to show the first and last pages in existence at the ends of the paginator */\n const showFirstPage = (Math.abs(firstPage - currentPage)) > (numPagesToShow);\n const showLastPage = (Math.abs(lastPage - currentPage)) > (numPagesToShow);\n\n\n const prevButtonDisabled = currentPage === firstPage ? 'disabled' : ''\n\n /* Previous button */\n this.element.appendChild(makeEl(\n `Previous`\n ));\n\n /* First page button */\n if (showFirstPage) {\n this.element.appendChild(makeEl(\n `${firstPage}`\n ));\n this.element.appendChild(makeEl(``));\n }\n\n /* \"window\" buttons */\n for (let i = firstPageShow; i <= lastPageShow; i++) {\n const selected = (i === currentPage ? 'paginator__button--selected' : '');\n this.element.appendChild(makeEl(\n `${i}`\n ));\n }\n\n /* Last page button */\n if (showLastPage) {\n this.element.appendChild(makeEl(``));\n this.element.appendChild(makeEl(\n `${lastPage}`\n ));\n }\n\n const nextButtonDisabled = currentPage === lastPage ? 'disabled' : ''\n /* Next button */\n this.element.appendChild(makeEl(\n `Next`\n ));\n }\n}\n\nclass DataTable {\n constructor(element, options) {\n this.element = element;\n this.container = element.parentElement;\n this.options = options;\n\n this.ajaxCallback = options.ajaxCallback;\n this.data = [];\n\n this.totalRecords = -1;\n this.perPage = 20;\n this.currentPage = 0;\n\n this.paginator = new SimplePaginator(this.container.querySelector('.paginator'));\n\n }\n\n attach() {\n this.paginator.attach(this._updatePage.bind(this));\n this._loadEntries();\n }\n\n /* Load the requested data from the server, and when done, update the DOM. */\n _loadEntries() {\n new Promise(this.ajaxCallback)\n .then(this._updateEntries.bind(this));\n }\n\n /* Update the DOM to reflect the current state of the data we have loaded */\n _updateEntries(data) {\n this.data = data.data;\n this.totalRecords = this.data.length;\n\n const bodyElement = this.element.querySelector('tbody');\n clearEl(bodyElement);\n\n const firstIndex = (this.perPage * this.currentPage);\n const lastIndex = (firstIndex + this.perPage) > this.totalRecords ? this.totalRecords : (firstIndex + this.perPage);\n\n\n for (let i = firstIndex; i < lastIndex; i++) {\n const rowElem = makeEl(this.options.rowCallback(this.data[i]));\n rowElem.classList.add(i % 2 === 0 ? 'odd' : 'even');\n\n bodyElement.appendChild(rowElem);\n }\n\n this.paginator.update(this.totalRecords, this.perPage, this.currentPage);\n }\n\n _updatePage(n) {\n this.currentPage = n;\n this.paginator.update(this.totalRecords, this.perPage, this.currentPage);\n this._updateEntries({data: this.data});\n }\n\n _updateSort(field, direction) {\n\n }\n}\n\nexport { DataTable };\n","import { $, $$, escape, toggleEl } from './dom';\nimport { TagsInput } from \"./tag_input\";\nimport { DataTable } from \"./data_tables\";\n\nconst setupSite = function() {\n Array.prototype.forEach.call($$('.js-tag-input'), (el) => {\n new TagsInput(el).attach();\n });\n\n if (document.querySelector('#archive')) {\n const table = new DataTable(document.querySelector('#archive'), {\n ajaxCallback: (resolve) => {\n fetch('/api/ajax_pastes.php')\n .then(r => r.json())\n .then(resolve);\n },\n rowCallback: (rowData) => {\n const tags = rowData.tags.map((tagData) => {\n let tagColorClass;\n if (tagData.name.indexOf('nsfw') !== -1) {\n tagColorClass = 'is-danger';\n } else if (tagData.name.indexOf('safe') !== -1) {\n tagColorClass = 'is-success';\n } else if (tagData.name.indexOf('/') !== -1) {\n tagColorClass = 'is-primary';\n } else {\n tagColorClass = 'is-info';\n }\n\n return `\n ${escape(tagData.name)}\n `;\n }).join('');\n\n return `\n ${escape(rowData.title)}\n ${escape(rowData.author)}\n ${tags}\n `;\n }\n });\n table.attach();\n }\n\n const signupButton = $('[data-target~=\"#signin\"],[data-target~=\"#signup\"]');\n\n if (signupButton) {\n signupButton.addEventListener('click', () => {\n $('.modal').classList.add('is-active');\n });\n\n $('.modal-button-close').addEventListener('click', () => {\n $('.modal').classList.remove('is-active');\n });\n }\n\n const embedButton = $('.panel-tools .embed-tool');\n\n if (embedButton){\n embedButton.addEventListener('click', (evt) => {\n if (evt.target && evt.target.closest('.panel-tools')) {\n toggleEl(evt.target.closest('.panel-tools').querySelector('.panel-embed'));\n }\n });\n }\n\n const expandButton = $('.expand-tool');\n\n if (expandButton) {\n expandButton.addEventListener('click', (evt) => {\n if (evt.target && evt.target.closest('.panel')) {\n const panel = evt.target.closest('.panel');\n\n if (panel.classList.contains('panel-fullsize')) {\n panel.classList.remove('panel-fullsize');\n } else {\n panel.classList.add('panel-fullsize');\n }\n }\n });\n }\n};\n\nif (document.readyState !== 'loading') {\n setupSite();\n} else {\n document.addEventListener('DOMContentLoaded', setupSite);\n}\n"],"names":["$","selector","document","querySelector","makeEl","html","template","createElement","innerHTML","trim","content","firstChild","clearEl","el","removeChild","escape","unsafe","replace","TagsInput","element","options","tags","maxTags","inputNode","containerNode","style","display","appendChild","this","parentNode","insertBefore","nextSibling","value","split","tag","addTag","addEventListener","_handleInputKeyUp","bind","_handleContainerClick","clear","remove","join","node","splice","indexOf","dataset","toLowerCase","length","disabled","tagValue","push","evt","key","previousSibling","deleteTagNode","updateHiddenInputValue","preventDefault","target","classList","contains","closest","SimplePaginator","pageCallback","page","totalRecords","perPage","currentPage","lastPage","Math","floor","firstPageShow","lastPageShow","showFirstPage","abs","showLastPage","prevButtonDisabled","i","selected","nextButtonDisabled","DataTable","container","parentElement","ajaxCallback","data","paginator","attach","_updatePage","_loadEntries","Promise","then","_updateEntries","bodyElement","firstIndex","lastIndex","rowElem","rowCallback","add","update","n","field","direction","setupSite","Array","prototype","forEach","call","querySelectorAll","resolve","fetch","r","json","rowData","map","tagData","tagColorClass","name","slug","id","title","author","signupButton","embedButton","expandButton","panel","readyState"],"mappings":"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"} \ No newline at end of file diff --git a/includes/common.php b/includes/common.php index 3933acb..87db6c3 100644 --- a/includes/common.php +++ b/includes/common.php @@ -15,6 +15,14 @@ use PonePaste\Models\Paste; use PonePaste\Models\User; /* View functions */ +function javascriptIncludeTag(string $name) : string { + if (PP_DEBUG) { + return ""; + } + + return ""; +} + function urlForPage($page = '') : string { if (!PP_MOD_REWRITE) { $page .= '.php'; @@ -204,6 +212,8 @@ $total_unique_views = PageView::select('tvisit')->orderBy('id', 'desc')->first() $current_user = SessionHelper::currentUser(); +$script_bundles = []; + /* Security headers */ header('X-Frame-Options: SAMEORIGIN'); header('X-Content-Type-Options: nosniff'); diff --git a/index.php b/index.php index beb88dd..ced4c5c 100644 --- a/index.php +++ b/index.php @@ -126,7 +126,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($editing) { $paste = Paste::find($_POST['paste_id']); if ($current_user && - $current_user->user_id === $paste->user_id) { + $current_user->id === $paste->user_id) { $paste_id = $paste->id; $paste->update([ 'title' => $paste_title, diff --git a/js/archive.js b/js/archive.js index 9d317cf..3241ce8 100644 --- a/js/archive.js +++ b/js/archive.js @@ -1,3 +1,44 @@ -import { $ } from './dom'; +import { escape, whenReady } from './dom'; import { DataTable } from './data_tables'; +import { globalSetup } from './main'; +whenReady(() => { + globalSetup(); + + const urlParams = new URLSearchParams(window.location.search); + const myParam = urlParams.get('q'); + const apiUrl = myParam !== null ? '/api/ajax_pastes.php?q=' + myParam : '/api/ajax_pastes.php'; + + const table = new DataTable(document.getElementById('archive'), { + ajaxCallback: (resolve) => { + fetch(apiUrl) + .then(r => r.json()) + .then(resolve); + }, + rowCallback: (rowData) => { + const tags = rowData.tags.map((tagData) => { + let tagColorClass; + if (tagData.name.indexOf('nsfw') !== -1) { + tagColorClass = 'is-danger'; + } else if (tagData.name.indexOf('safe') !== -1) { + tagColorClass = 'is-success'; + } else if (tagData.name.indexOf('/') !== -1) { + tagColorClass = 'is-primary'; + } else { + tagColorClass = 'is-info'; + } + + return ` + ${escape(tagData.name)} + `; + }).join(''); + + return ` + ${escape(rowData.title)} + ${escape(rowData.author)} + ${tags} + `; + } + }); + table.attach(); +}); \ No newline at end of file diff --git a/js/dom.js b/js/dom.js index 6212b6e..3e8cbe1 100644 --- a/js/dom.js +++ b/js/dom.js @@ -37,5 +37,12 @@ const escape = function(unsafe) { .replace(/'/g, "'"); } +const whenReady = function(funcp) { + if (document.readyState !== 'loading') { + funcp(); + } else { + document.addEventListener('DOMContentLoaded', funcp); + } +} -export { $, $$, makeEl, clearEl, toggleEl, escape }; \ No newline at end of file +export { whenReady, $, $$, makeEl, clearEl, toggleEl, escape }; \ No newline at end of file diff --git a/js/generic.js b/js/generic.js new file mode 100644 index 0000000..a9cc177 --- /dev/null +++ b/js/generic.js @@ -0,0 +1,4 @@ +import { whenReady } from "./dom"; +import { globalSetup } from "./main"; + +whenReady(globalSetup); diff --git a/js/main.js b/js/main.js index 1aaf269..826f55a 100644 --- a/js/main.js +++ b/js/main.js @@ -1,47 +1,7 @@ -import { $, $$, escape, toggleEl } from './dom'; +import { $, $$, toggleEl } from './dom'; import { TagsInput } from "./tag_input"; -import { DataTable } from "./data_tables"; - -const setupSite = function() { - Array.prototype.forEach.call($$('.js-tag-input'), (el) => { - new TagsInput(el).attach(); - }); - - if (document.querySelector('#archive')) { - const table = new DataTable(document.querySelector('#archive'), { - ajaxCallback: (resolve) => { - fetch('/api/ajax_pastes.php') - .then(r => r.json()) - .then(resolve); - }, - rowCallback: (rowData) => { - const tags = rowData.tags.map((tagData) => { - let tagColorClass; - if (tagData.name.indexOf('nsfw') !== -1) { - tagColorClass = 'is-danger'; - } else if (tagData.name.indexOf('safe') !== -1) { - tagColorClass = 'is-success'; - } else if (tagData.name.indexOf('/') !== -1) { - tagColorClass = 'is-primary'; - } else { - tagColorClass = 'is-info'; - } - - return ` - ${escape(tagData.name)} - `; - }).join(''); - - return ` - ${escape(rowData.title)} - ${escape(rowData.author)} - ${tags} - `; - } - }); - table.attach(); - } +const setupSignupModal = () => { const signupButton = $('[data-target~="#signin"],[data-target~="#signup"]'); if (signupButton) { @@ -53,6 +13,14 @@ const setupSite = function() { $('.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'); @@ -79,10 +47,36 @@ const setupSite = function() { } }); } -}; -if (document.readyState !== 'loading') { - setupSite(); -} else { - document.addEventListener('DOMContentLoaded', setupSite); + // 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 = ''; + } } + +export { globalSetup }; \ No newline at end of file diff --git a/paste.php b/paste.php index 81414bf..e3f30c9 100644 --- a/paste.php +++ b/paste.php @@ -8,6 +8,10 @@ use Highlight\Highlighter; use PonePaste\Models\Paste; use PonePaste\Models\User; +function isRequesterLikelyBot() : bool { + return str_contains(strtolower($_SERVER['HTTP_USER_AGENT']), 'bot'); +} + function rawView($content, $p_code) { if ($p_code) { header('Content-Type: text/plain'); @@ -147,7 +151,7 @@ if (isset($_GET['raw'])) { // Deletion if (isset($_POST['delete'])) { - if (!$current_user || ($paste_owner_id !== $current_user->user_id)) { + if (!$current_user || ($paste_owner_id !== $current_user->id)) { flashError('You must be logged in and own this paste to delete it.'); } else { $paste->delete(); @@ -210,7 +214,7 @@ if ($password_required && $password_valid) { } // View counter -if (@$_SESSION['not_unique'] !== $paste_id) { +if (!isRequesterLikelyBot() && @$_SESSION['not_unique'] !== $paste_id) { $_SESSION['not_unique'] = $paste_id; $paste->views += 1; $paste->save(); diff --git a/rollup.config.js b/rollup.config.js index ba2ed03..91f3ed9 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,20 +1,27 @@ -// noinspection JSUnusedGlobalSymbols +// noinspection JSUnusedGlobalSymbols,JSCheckFunctionSignatures -import { getBabelOutputPlugin } from '@rollup/plugin-babel'; -import { terser } from 'rollup-plugin-terser'; +import {getBabelOutputPlugin} from '@rollup/plugin-babel'; +import {terser} from 'rollup-plugin-terser'; -export default { - input: 'js/main.js', - output: [ - { - file: 'assets/bundle/bundle.js', - format: 'esm' - }, - { - file: 'assets/bundle/bundle.min.js', - format: 'esm', - plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] }), terser()], - sourcemap: true - } - ] +const output = (name) => { + return { + input: `js/${name}.js`, + output: [ + { + file: `assets/bundle/${name}.js`, + format: 'esm' + }, + { + file: `assets/bundle/${name}.min.js`, + format: 'esm', + plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] }), terser()], + sourcemap: true + } + ] + } }; + +export default [ + output('generic'), + output('archive') +]; \ No newline at end of file diff --git a/theme/bulma/archive.php b/theme/bulma/archive.php index fc3e992..0fc2b53 100644 --- a/theme/bulma/archive.php +++ b/theme/bulma/archive.php @@ -4,7 +4,7 @@ rowReorder: {selector: 'td:nth-child(2)'}, responsive: true, processing: true, - language: {processing: 'Loading... '}, + language: {processing: ''}, autoWidth: false, ajax: "api/ajax_pastes.php", initComplete: function () { @@ -57,6 +57,7 @@ + diff --git a/theme/bulma/common.php b/theme/bulma/common.php index 66d988b..2dd29ce 100644 --- a/theme/bulma/common.php +++ b/theme/bulma/common.php @@ -32,9 +32,6 @@ $flashes = getFlashes(); - - - @@ -288,16 +285,15 @@ $flashes = getFlashes(); - + + + + + + + + - - - \ No newline at end of file diff --git a/theme/bulma/css/paste.css b/theme/bulma/css/paste.css index f217628..59cc2cc 100644 --- a/theme/bulma/css/paste.css +++ b/theme/bulma/css/paste.css @@ -4,10 +4,8 @@ /* Bulma */ @import url("bulma.min.css"); -@import url("bulma.modal-fx.min.css"); @import url("bulma.tooltip.min.css"); @import url("bulma.checkradio.min.css"); -@import url("bulma.social.all.min.css"); /* DataTables.js */ @import url("datatables.min.css"); diff --git a/theme/bulma/view.php b/theme/bulma/view.php index 223b3be..0178eef 100644 --- a/theme/bulma/view.php +++ b/theme/bulma/view.php @@ -1,40 +1,5 @@ - @@ -242,7 +194,7 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was - user_id !== $paste['user_id'])) { ?> + id !== $paste_owner_id)) { ?>
File Size: 1000/1000Kb


-
- + +
+ +
@@ -418,7 +367,7 @@ $selectedloader = "$bg[$i]"; // set variable equal to which random filename was Encrypt on Server user_id == $paste['user_id']) { + if ($current_user->id == $paste['user_id']) { ?> diff --git a/user.php b/user.php index bf11026..a43e681 100644 --- a/user.php +++ b/user.php @@ -57,7 +57,7 @@ if (isset($_GET['del'])) { $paste_id = intval(trim($_GET['id'])); $paste = Paste::find($paste_id); - if (!$paste || $paste->user_id !== $current_user->user_id) { + if (!$paste || $paste->user_id !== $current_user->id) { $error = 'That paste does not exist, or you are not the owner of it.'; } else { $paste->delete();