From 02f711aa97557b22e9980c42ba6f8c379ee1e1aa Mon Sep 17 00:00:00 2001 From: Las Zenow Date: Fri, 30 Apr 2021 13:47:59 +0000 Subject: [PATCH] Add tokenfield tag editor --- README.md | 2 + css/tokenfield.css | 97 ++++++++++++++++++++++++++++++++++++++++ css/tokenfield.css.map | 11 +++++ js/tokenfield.min.js | 1 + lib/admin.go | 5 +++ lib/database/database.go | 1 + lib/database/ro.go | 4 ++ lib/database/stats.go | 4 ++ templates/edit.html | 25 +++++++++-- templates/header.html | 1 + 10 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 css/tokenfield.css create mode 100644 css/tokenfield.css.map create mode 100644 js/tokenfield.min.js diff --git a/README.md b/README.md index 51049c7..834e781 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ file with the exception of: * css/bootstrap.bundle.min.css css/bootstrap.bundle.min.css.map js/bootstrap.bundle.min.js js/bootstrap.bundle.min.js.map img/bootstrap-icons.svg From the bootstrap framework: https://getbootstrap.com/ +* css/tokenfield.css css/tokenfield.css.map js/tokenfield.min.js + From tokenfield: https://github.com/KaneCohen/tokenfield * img/bright_squares.png From subtlepatterns: http://subtlepatterns.com/bright-squares/ * css/FredokaOne.ttf css/PTSerif.ttf diff --git a/css/tokenfield.css b/css/tokenfield.css new file mode 100644 index 0000000..532aba1 --- /dev/null +++ b/css/tokenfield.css @@ -0,0 +1,97 @@ +.tokenfield { + position: relative; } + .tokenfield:before, .tokenfield:after { + content: " "; + display: table; } + .tokenfield:after { + clear: both; } + .tokenfield.tokenfield-mode-tokens { + display: block; + width: 100%; + min-height: 34px; + padding: 6px 12px 0; + font-size: 14px; + line-height: 1.42857; + color: #555555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; } + .tokenfield.tokenfield-mode-tokens:focus { + border-color: #66afe9; + outline: 0; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); } + .tokenfield.tokenfield-mode-tokens::-moz-placeholder { + color: #999; + opacity: 1; } + .tokenfield.tokenfield-mode-tokens:-ms-input-placeholder { + color: #999; } + .tokenfield.tokenfield-mode-tokens::-webkit-input-placeholder { + color: #999; } + .tokenfield.tokenfield-mode-tokens::-ms-expand { + border: 0; + background-color: transparent; } + .tokenfield.tokenfield-mode-tokens[disabled], .tokenfield.tokenfield-mode-tokens[readonly], + fieldset[disabled] .tokenfield.tokenfield-mode-tokens { + background-color: #eeeeee; + opacity: 1; } + .tokenfield.tokenfield-mode-tokens[disabled], + fieldset[disabled] .tokenfield.tokenfield-mode-tokens { + cursor: not-allowed; } + .tokenfield.tokenfield-mode-tokens .focused { + box-shadow: 0 0 0 1px #337ab7 inset; } + .tokenfield.tokenfield-mode-tokens .selected { + background: rgba(0, 0, 0, 0.1); } + .tokenfield .tokenfield-set > ul { + margin: 0; + padding: 0; + list-style-type: none; } + .tokenfield .tokenfield-set > ul > li { + float: left; + margin-right: 5px; + margin-bottom: 5px; + padding: 0 5px; + border-radius: 4px; + line-height: 1.5; + cursor: pointer; + color: rgba(0, 0, 0, 0.6); + background: rgba(0, 0, 0, 0.08); } + .tokenfield .tokenfield-set > ul > li:hover { + color: black; + background: rgba(0, 0, 0, 0.16); } + .tokenfield .tokenfield-set > ul > li .item-remove { + display: inline-block; + font-weight: bold; + font-size: 0.9285em; + cursor: pointer; + color: rgba(0, 0, 0, 0.4); } + .tokenfield .tokenfield-input { + margin-bottom: 5px; + border: none; + outline: none; + float: left; } + .tokenfield .tokenfield-suggest { + position: absolute; + left: -1px; + top: 100%; + width: 100%; + z-index: 10; + overflow: auto; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-sizing: content-box; } + .tokenfield .tokenfield-suggest > ul { + margin: 0; + padding: 0; + list-style: none; } + .tokenfield .tokenfield-suggest > ul > li { + padding: 6px 10px; + cursor: pointer; } + +/*# sourceMappingURL=tokenfield.css.map */ \ No newline at end of file diff --git a/css/tokenfield.css.map b/css/tokenfield.css.map new file mode 100644 index 0000000..d14786c --- /dev/null +++ b/css/tokenfield.css.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "file": "tokenfield.css", + "sources": [ + "../lib/scss/tokenfield.scss", + "../lib/scss/mixins.scss", + "../lib/scss/variables.scss" + ], + "names": [], + "mappings": "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" +} \ No newline at end of file diff --git a/js/tokenfield.min.js b/js/tokenfield.min.js new file mode 100644 index 0000000..28fdc80 --- /dev/null +++ b/js/tokenfield.min.js @@ -0,0 +1 @@ +var Tokenfield=function(e){function t(n){if(s[n])return s[n].exports;var i=s[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var s={};return t.m=e,t.c=s,t.d=function(e,s,n){t.o(e,s)||Object.defineProperty(e,s,{configurable:!1,enumerable:!0,get:n})},t.n=function(e){var s=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(s,"a",s),s},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,s){e.exports=s(1).default},function(e,t,s){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function i(e){if(Array.isArray(e)){for(var t=0,s=Array(e.length);t=0}function m(e){for(var t=[e];e.parentNode;)e=e.parentNode,t.push(e);return t}function c(e){return e.nodeName?e:"string"==typeof e?document.querySelector(e):null}function d(e,t){return e.nodeName?e:(e=e.replace(/(\t|\n$)/g,""),O.innerHTML="",O.innerHTML=e,!0===t?O.childNodes:O.childNodes[0])}function f(e){if("string"==typeof e)return e;if(null===e)return"";var t=e+"";return"0"===t&&1/e==-1/0?"-0":t}function v(e){return e.key||e.keyIdentifier?e.key||String.fromCharCode(parseInt(e.keyIdentifier.substr(2),16)):null}function p(e){return e=f(e),e&&E.test(e)?e.replace(x,"\\$&"):e}function g(){return{_defaults:{focusedItem:null,cache:{},timer:null,xhr:null,suggested:!1,suggestedItems:[],setItems:[],events:{},delimiters:{}},_options:{el:null,form:!0,mode:"tokenfield",addItemOnBlur:!1,addItemsOnPaste:!1,keepItemsOrder:!0,setItems:[],items:[],newItems:!0,multiple:!0,maxItems:0,minLength:0,keys:{17:"ctrl",16:"shift",91:"meta",8:"delete",27:"esc",37:"left",38:"up",39:"right",40:"down",46:"delete",65:"select",67:"copy",88:"cut",9:"delimiter",13:"delimiter",108:"delimiter"},matchRegex:"{value}",matchFlags:"i",matchStart:!1,matchEnd:!1,delimiters:[],copyProperty:"name",copyDelimiter:", ",remote:{type:"GET",url:null,queryParam:"q",delay:300,timestampParam:"t",params:{},headers:{}},placeholder:null,inputType:"text",minChars:2,maxSuggest:10,maxSuggestWindow:10,filterSetItems:!0,filterMatchCase:!1,singleInput:!1,singleInputValue:"id",singleInputDelimiter:", ",itemLabel:"name",itemName:"items",newItemName:"items_new",itemValue:"id",newItemValue:"name",itemData:"name",validateNewItem:null}}}Object.defineProperty(t,"__esModule",{value:!0});var _="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},y=Object.assign||function(e){for(var t=1;t\n \n
\n
    \n
    \n \n
    \n
      \n
      \n ',containerList:'
      \n \n
      \n
        \n
        \n
        \n
          \n
          \n
          ',suggestItem:'
        • ',setItem:'
        • \n \n ×\n \n
        • '},C=function(e){function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};o(this,t);var s=u(this,(t.__proto__||Object.getPrototypeOf(t)).call(this)),n=g(),i=n._defaults,r=n._options;s.id=a(),s.key="key_"+s.id,s._vars=y({},i),s._options=y({},r,e),s._options.keys=y({},r.keys,e.keys),s._options.remote=y({},r.remote,e.remote),s._templates=y({},D,e.templates),s._vars.setItems=s._prepareData(s.remapData(s._options.setItems||[])),s._focused=!1,s._input=null,s._form=!1,s._html={};var l=s._options;l.delimiters.forEach(function(e){s._vars.delimiters[e]=!0});var h=c(l.el);if(!h)throw new Error("Selector: DOM Element "+l.el+" not found.");if(s.el=h,l.singleInput){var m=c(l.singleInput);s._input=m||s.el}if(s.el.tokenfield=s,null===l.placeholder&&(l.placeholder=l.el.placeholder||""),!l.form)throw new Error("Cannot create tokenfield without DOM Element.");var d=!1;if(l.form.nodeName)d=l.form;else if(!0===l.form)for(var f=s.el;f.parentNode;){if("FORM"===f.nodeName){d=f;break}f=f.parentNode}else if("string"==typeof d&&!(d=document.querySelector(d)))throw new Error("Selector: DOM Element "+l.form+" not found.");return s._form=d,L[s.id]=s,s._render(),s}return l(t,e),I(t,[{key:"_render",value:function(){var e=this._options,t=this._html;return"tokenfield"===e.mode?t.container=d(this._templates.containerTokenfield):t.container=d(this._templates.containerList),t.suggest=t.container.querySelector(".tokenfield-suggest"),t.suggestList=t.container.querySelector(".tokenfield-suggest-list"),t.items=t.container.querySelector(".tokenfield-set > ul"),t.input=t.container.querySelector(".tokenfield-input"),t.input.setAttribute("type",e.inputType),"tokenfield"===e.mode?t.input.placeholder=this._vars.setItems.length?"":e.placeholder:t.input.placeholder=e.placeholder,t.copyHelper=t.container.querySelector(".tokenfield-copy-helper"),e.el.style.display="none",t.suggest.style.display="none",this._renderSizer(),t.container.tokenfield=this,e.el.parentElement.insertBefore(t.container,e.el),t.container.insertBefore(e.el,t.container.firstChild),this._setEvents(),this._renderItems(),"tokenfield"===e.mode&&this._resizeInput(),this}},{key:"_renderSizer",value:function(){var e=this._html,t=this._getBounds(),s=window.getComputedStyle(e.container),n=parseInt(s.paddingLeft,10)+parseInt(s.paddingRight,10),i={width:"auto",height:"auto",overflow:"hidden",whiteSpace:"pre",maxWidth:t.width-n+"px",position:"fixed",top:-1e4+"px",left:1e4+"px",fontSize:s.fontSize,paddingLeft:s.paddingLeft,paddingRight:s.paddingRight};e.sizer=document.createElement("div"),e.sizer.id="tokenfield-sizer-"+this.id;for(var r in i)e.sizer.style[r]=i[r];e.container.appendChild(e.sizer)}},{key:"_minimizeInput",value:function(){return this._html.input.style.width="20px",this}},{key:"_refreshInput",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=this._vars,s=this._html;if(e&&(s.input.value=""),"tokenfield"===this._options.mode){this._resizeInput();var n=t.setItems.length?"":this._options.placeholder;s.input.setAttribute("placeholder",n)}else"list"===this._options.mode&&s.input.setAttribute("placeholder",this._options.placeholder);return this}},{key:"_resizeInput",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this._html,s=this._getBounds(),n=window.getComputedStyle(t.container),i=parseInt(n.paddingRight,10)+parseInt(n.borderRightWidth,10),r=i+parseInt(n.paddingLeft,10)+parseInt(n.borderLeftWidth,10);if(t.sizer.innerHTML=e,t.sizer.style.maxWidth=s.width-i+"px",0===s.width)return void(t.input.style.width="100%");t.input.style.width="20px";var o=t.sizer.getBoundingClientRect(),u=t.input.getBoundingClientRect(),l=s.width-(u.left-s.left)-i;o.width>l?t.input.style.width=s.width-r-1+"px":t.input.style.width=l-1+"px"}},{key:"_fetchData",value:function(e){var t=this,s=this._vars,n=this._options,i=n.remote,r=y({},n.params);for(var o in i.params)r[o]=i.params[o];i.limit&&(r[i.limit]=n.remote.limit),r[i.queryParam]=e,r[i.timestampParam]=Math.round((new Date).getTime()/1e3),s.xhr=(0,S.default)(r,n.remote,function(){if(s.xhr&&4==s.xhr.readyState){if(200==s.xhr.status){var i=JSON.parse(s.xhr.responseText);s.cache[e]=i;var r=t._prepareData(t.remapData(i)),o=t._filterData(e,r);s.suggestedItems=n.filterSetItems?t._filterSetItems(o):o,t.showSuggestions()}else if(s.xhr.status>0)throw new Error("Error while loading remote data.");t._abortXhr()}})}},{key:"remapData",value:function(e){return e}},{key:"_prepareData",value:function(e){var t=this;return e.map(function(e){return y({},e,r({},t.key,a()))})}},{key:"_filterData",value:function(e,t){var s=this._options,n=s.matchRegex.replace("{value}",p(e));s.matchStart?n="^"+n:s.matchEnd&&(n+="$");var i=new RegExp(n,s.matchFlags);return t.filter(function(e){return i.test(e[s.itemData])})}},{key:"_abortXhr",value:function(){var e=this._vars;null!==e.xhr&&(e.xhr.abort(),e.xhr=null)}},{key:"_filterSetItems",value:function(e){var t=this._options.itemValue,s=this._vars;if(!s.setItems.length)return e;var n=s.setItems.map(function(e){return e[t]});return e.filter(function(e){return-1===n.indexOf(e[t])})}},{key:"_setEvents",value:function(){var e=this._vars,t=this._html;e.events.onClick=this._onClick.bind(this),e.events.onMouseDown=this._onMouseDown.bind(this),e.events.onMouseOver=this._onMouseOver.bind(this),e.events.onFocus=this._onFocus.bind(this),e.events.onResize=this._onResize.bind(this),e.events.onReset=this._onReset.bind(this),e.events.onKeyDown=this._onKeyDown.bind(this),e.events.onFocusOut=this._onFocusOut.bind(this),t.container.addEventListener("click",e.events.onClick),1===Object.keys(L).length&&(document.addEventListener("mousedown",e.events.onMouseDown),window.addEventListener("resize",e.events.onResize)),this._form&&this._form.nodeName&&this._form.addEventListener("reset",e.events.onReset),t.suggestList.addEventListener("mouseover",e.events.onMouseOver),t.input.addEventListener("focus",e.events.onFocus)}},{key:"_onMouseOver",value:function(e){var t=e.target;if(t.classList.contains("tokenfield-suggest-item")){[].slice.call(this._html.suggestList.querySelectorAll(".selected")).forEach(function(e){e!==t&&e.classList.remove("selected")}),t.classList.add("selected"),this._selectItem(t.key,!1),this._refreshItemsSelection()}}},{key:"_onReset",value:function(){this.setItems(this._options.setItems)}},{key:"_onFocus",value:function(){var e=this._vars,t=this._html,s=this._options;t.input.removeEventListener("keydown",e.events.onKeyDown),t.input.addEventListener("keydown",e.events.onKeyDown),t.input.addEventListener("focusout",e.events.onFocusOut),s.addItemsOnPaste&&(e.events.onPaste=this._onPaste.bind(this),t.input.addEventListener("paste",e.events.onPaste)),this._focused=!0,this._html.container.classList.add("focused"),this._resizeInput(),t.input.value.trim().length>=s.minChars&&this.showSuggestions()}},{key:"_onFocusOut",value:function(e){var t=this._vars,s=this._options,n=this._html;if(n.input.removeEventListener("keydown",t.events.onKeyDown),n.input.removeEventListener("focusout",t.events.onFocusOut),void 0!==t.events.onPaste&&n.input.removeEventListener("paste",t.events.onPaste),!e.relatedTarget||e.relatedTarget!==n.copyHelper){var i=s.multiple&&!s.maxItems||!s.multiple&&!t.setItems.length||s.multiple&&s.maxItems&&t.setItems.length0&&e.length>=n.minLength&&void 0===s.delimiters[e]}).map(function(e){return t._newItem(e)}).length&&(setTimeout(function(){t._renderItems()._refreshInput()._deselectItems().hideSuggestions()},1),e.preventDefault())}},{key:"_onKeyDown",value:function(e){var t=this,s=this._vars,n=this._options,i=this._html;n.maxItems&&s.setItems.length>=n.maxItems&&e.preventDefault(),"tokenfield"===n.mode&&setTimeout(function(){t._resizeInput(i.input.value)},1);var r=v(e);if(void 0!==n.keys[e.keyCode]||h(n.delimiters,r)){if(this._keyAction(e))return!0}else this._defocusItems()._refreshItems();clearTimeout(s.timer),this._abortXhr(),(!n.maxItems||s.setItems.length=1)return!1;u=this.onInput(u,e),s?this._addItem(s):u.length&&(s=this._newItem(u)),s&&this._minimizeInput()._renderItems().focus()._refreshInput()._refreshSuggestions()._deselectItems(),e.preventDefault();break;case"select":if(u.length||!e.ctrlKey&&!e.metaKey)return!1;this._vars.setItems.forEach(function(e){e.focused=!0}),this._refreshItems();break;case"cut":if(!this.getFocusedItems().length||!e.ctrlKey&&!e.metaKey)return!1;this._copy()._delete(e);break;case"copy":if(!this.getFocusedItems().length||!e.ctrlKey&&!e.metaKey)return!1;this._copy();break;case"delete":this._abortXhr();var m=this.getFocusedItems();!r.input.selectionEnd&&8===e.keyCode||r.input.selectionStart===u.length&&46===e.keyCode||m.length?this._delete(e):n.timer=setTimeout(function(){t._keyInput(e)},i.delay)}return!0}},{key:"_copy",value:function(){var e=this._options,t=this._html,s=this.getFocusedItems().map(function(t){return t[e.copyProperty]}).join(e.copyDelimiter);return t.copyHelper.style.display="block",t.copyHelper.value=s,t.copyHelper.focus(),t.copyHelper.select(),document.execCommand("copy"),t.copyHelper.style.display="none",t.copyHelper.value="",t.input.focus(),this}},{key:"_delete",value:function(e){var t=this,s=this._vars,n=this._options,i=this.key,r=this._html,o=this.getFocusedItems();return"tokenfield"===n.mode&&s.setItems.length?o.length?(o.forEach(function(e){t._removeItem(e[i])}),this._refreshSuggestions()._keyInput(e)):r.input.selectionStart||this._focusItem(s.setItems[s.setItems.length-1][i]):o.length&&(o.forEach(function(e){t._removeItem(e[i])}),this._refreshSuggestions()._keyInput(e)),this._minimizeInput()._renderItems()._refreshInput(!1),this}},{key:"_keyInput",value:function(e){var t=this,s=this._vars,n=this._options,i=this._html;this._defocusItems()._refreshItems();var r=this.onInput(i.input.value.trim(),e);if("keydown"===e.type&&this.emit("input",this,r,e),r.length=1)return!1;if(void 0===s.cache[r]){if(n.remote.url)s.timer=setTimeout(function(){t._fetchData(r)},n.delay);else if(!n.remote.url&&n.items.length){var o=this._prepareData(n.items),u=this._filterData(r,o);s.suggestedItems=n.filterSetItems?this._filterSetItems(u):u,this.showSuggestions()}}else{var l=this._prepareData(this.remapData(s.cache[r])),a=this._filterData(r,l);s.suggestedItems=n.filterSetItems?this._filterSetItems(a):a,this.showSuggestions()}return this}},{key:"_onClick",value:function(e){var t=e.target;if(t.classList.contains("item-remove"))e.preventDefault(),this._removeItem(t.key)._defocusItems()._minimizeInput()._renderItems()._refreshInput(!1)._keyInput(e);else if(t.classList.contains("tokenfield-suggest-item")){var s=this._getSuggestedItem(t.key);this._addItem(s)._minimizeInput()._renderItems()._refreshInput()._refreshSuggestions()}else{var n=m(t).filter(function(e){return e.classList&&e.classList.contains("tokenfield-set-item")})[0];n?(this._focusItem(n.key,e.shiftKey,e.ctrlKey||e.metaKey,!0),this._refreshItems()):this._keyInput(e)}this.focus()}},{key:"_selectPrevItem",value:function(){var e=this.key,t=this._options,s=this._vars.suggestedItems,n=this._getSelectedItemIndex();return s.length?(null!==n?0===n?t.newItems?this._deselectItems():this._selectItem(s[s.length-1][e]):this._selectItem(s[n-1][e]):this._selectItem(s[s.length-1][e]),this):this}},{key:"_selectNextItem",value:function(){var e=this.key,t=this._options,s=this._vars.suggestedItems,n=this._getSelectedItemIndex();return s.length?(null!==n?n===s.length-1?t.newItems?this._deselectItems():this._selectItem(s[0][e]):this._selectItem(s[n+1][e]):this._selectItem(s[0][e]),this):this}},{key:"_focusPrevItem",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.key,s=this._vars.setItems,n=this._getFocusedItemIndex();if(!s.length)return this;if(null!==n)if(0!==n||e)if(0===n&&e){var i=this._getFocusedItemIndex(!0);this._defocusItem(s[i][t])}else this._focusItem(s[n-1][t],e,!1,!0);else this._defocusItems();else this._focusItem(s[s.length-1][t],!1,!1,!0);return this._refreshItems(),this}},{key:"_focusNextItem",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.key,s=this._vars.setItems,n=this._getFocusedItemIndex(!0);return s.length?(null!==n?n!==s.length-1||e?n===s.length-1&&e?this._focusItem(s[0][t],e):this._focusItem(s[n+1][t],e):this._defocusItems():this._focusItem(s[0][t],!1),this._refreshItems(),this):this}},{key:"_getSelectedItems",value:function(){var e=this.key,t=this._vars.setItems.map(function(t){return t[e]});return this._vars.suggestedItems.filter(function(s){return s.selected&&t.indexOf(s[e])<0})}},{key:"_selectItem",value:function(e){var t=this,s=arguments.length>1&&void 0!==arguments[1]&&arguments[1];this._vars.suggestedItems.forEach(function(n){if(n.selected=n[t.key]===e,n.selected&&s){var i=parseInt(t._html.suggest.style.maxHeight,10);if(i){var r=t._html.suggestList.getBoundingClientRect(),o=n.el.getBoundingClientRect(),u=o.top-r.top,l=u+o.height;l>=i+t._html.suggest.scrollTop?t._html.suggest.scrollTop=l-i:u0&&void 0!==arguments[0]&&arguments[0],t=null;return this._vars.setItems.every(function(s,n){return!(s.focused&&(t=n,!e))}),t}},{key:"_getItem",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;null===t&&(t=this.key);var s=this._filterItems(this._vars.setItems,e,t);return s.length?s[0]:null}},{key:"_getSuggestedItem",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;null===t&&(t=this.key);var s=this._filterItems(this._vars.suggestedItems,e,t);return s.length?s[0]:null}},{key:"_getAvailableItem",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;null===t&&(t=this.key);var s=this._filterItems(this._options.items,e,t);return s.length?s[0]:null}},{key:"_filterItems",value:function(e,t,s){var n=this._options.filterMatchCase;return e.filter(function(e){return"string"==typeof e[s]&&"string"==typeof t?n?e[s]===t:e[s].toLowerCase()==t.toLowerCase():e[s]==t})}},{key:"_removeItem",value:function(e){var t=this;return this._vars.setItems.every(function(s,n){return s[t.key]!==e||(t.emit("removeToken",t,s),t._vars.setItems.splice(n,1),t.emit("removedToken",t,s),t.emit("change",t),!1)}),this}},{key:"_addItem",value:function(e){e.focused=!1;var t=this._options;if((e.isNew&&!this._getItem(e[t.itemData],t.itemData)||!this._getItem(e[t.itemValue],t.itemValue))&&(this.emit("addToken",this,e),!this._options.maxItems||this._options.maxItems&&this._vars.setItems.length1&&void 0!==arguments[1]&&arguments[1],s=this,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(t){var r=null,o=null,u=null,l=this._vars.setItems.length;if(this._vars.setItems.forEach(function(t,n){t[s.key]===e&&(u=n),null===r&&t.focused&&(r=n),t.focused&&(o=n)}),(0===u||u===l-1)&&null===r&&null===o)return;null===r&&null===o?this._vars.setItems[u].focused=!0:0!==u||o!==l-1||i?(r=Math.min(u,r),o=Math.max(u,o),this._vars.setItems.forEach(function(e,t){e.focused=u===t||t>=r&&t<=o})):this._vars.setItems[r].focused=!1}else this._vars.setItems.forEach(function(t){t.focused=n?t[s.key]===e?!t.focused:t.focused:t[s.key]===e});return this}},{key:"_defocusItem",value:function(e){var t=this;return this._vars.setItems.filter(function(s){s[t.key]===e&&(s.focused=!1)})}},{key:"_defocusItems",value:function(){return this._vars.setItems.forEach(function(e){e.focused=!1}),this}},{key:"_newItem",value:function(e){var t=this._options;if("string"==typeof e&&(!e.length||e.length1&&"tokenfield"===s.mode?n.input.setAttribute("placeholder",""):"list"===s.mode&&n.input.setAttribute("placeholder",s.placeholder),this._input&&(this._input.value=t.setItems.map(function(e){return e[s.singleInputValue]}).join(s.singleInputDelimiter)),this}},{key:"_refreshItems",value:function(){this._vars.setItems.forEach(function(e){e.el&&(e.focused?e.el.classList.add("focused"):e.el.classList.remove("focused"))})}},{key:"_renderItem",value:function(e,t){var s=this._options,n=this.renderSetItemHtml(e),i=n.querySelector(".item-label"),r=n.querySelector(".item-input"),o=n.querySelector(".item-remove"),u=s.keepItemsOrder?"["+t+"]":"[]";return n.key=e[this.key],o.key=e[this.key],r.setAttribute("name",(e.isNew?s.newItemName:s.itemName)+u),r.value=e[e.isNew?s.newItemValue:s.itemValue]||null,i.textContent=this.renderSetItemLabel(e),e.focused&&n.classList.add("focused"),n}},{key:"onInput",value:function(e,t){return e}},{key:"renderSetItemHtml",value:function(){return this._buildEl(this._templates.setItem)}},{key:"renderSetItemLabel",value:function(e){return e[this._options.itemLabel]}},{key:"renderSuggestions",value:function(e){var t=this,s=this._vars,n=this._options,i=this._html,r=this._getSelectedItemIndex();if(!e.length)return this;if(0===n.maxSuggestWindow&&(i.suggest.style.maxHeight=null),!s.suggestedItems.length)return this;n.newItems||null!==r||(e[0].selected=!0);var o=0;e.every(function(e,s){if(s>=n.maxSuggest)return!1;var r=i.suggestList.childNodes[s],u=e.el=t.renderSuggestedItem(e);return r?r.itemValue===e[n.itemValue]?(r.key=e[t.key],e.el=r):i.suggestList.replaceChild(u,r):r||i.suggestList.appendChild(u),n.maxSuggestWindow>0&&s0&&s===n.maxSuggestWindow&&(i.suggest.style.maxHeight=o+"px"),!0});var u=i.suggestList.childElementCount-e.length;if(u>0)for(var l=u-1;l>=0;l--)i.suggestList.removeChild(i.suggestList.childNodes[e.length+l]);return this}},{key:"renderSuggestedItem",value:function(e){var t=this._options,s=this._buildEl(this._templates.suggestItem);if(s.key=e[this.key],s.itemValue=e[t.itemValue],s.innerHTML=this.renderSuggestedItemContent(e),s.setAttribute("title",e[t.itemData]),e.selected&&s.classList.add("selected"),!t.filterSetItems){(this._getItem(e[t.itemValue],t.itemValue)||this._getItem(e[t.itemData],t.itemData))&&s.classList.add("set")}return s}},{key:"renderSuggestedItemContent",value:function(e){return e[this._options.itemData]}},{key:"_refreshSuggestions",value:function(){var e=this._vars,t=this._options;if(this._html.input.value.length0&&void 0!==arguments[0]?arguments[0]:[];return this._vars.setItems=[],this.addItems(e),this}},{key:"addItems",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],s=this._options.itemValue;return Array.isArray(t)||(t=[t]),this._prepareData(t).forEach(function(t){(t.isNew||void 0!==t[s])&&e._addItem(t)}),this._minimizeInput()._renderItems()._refreshInput().hideSuggestions(),this}},{key:"sortItems",value:function(){var e=this,t=[];[].concat(i(this._html.items.childNodes)).forEach(function(s){var n=e._getItem(s.key);n&&t.push(n)}),this.setItems(t)}},{key:"removeItem",value:function(e){var t=this._options;"object"===(void 0===e?"undefined":_(e))&&(e[t.itemValue]||e[t.newItemValue])&&(e=e[t.itemValue]||e[t.newItemValue]);var s=this._getItem(e,t.itemValue)||this._getItem(e,t.newItemValue);return s?(this._removeItem(s[this.key])._renderItems(),this):this}},{key:"emptyItems",value:function(){return this._vars.setItems=[],this._renderItems()._refreshInput().hideSuggestions(),this.emit("change",this),this}},{key:"getSuggestedItems",value:function(){return this._vars.suggestedItems.map(function(e){return y({},e)})}},{key:"focus",value:function(){return this._html.container.classList.add("focused"),this._focused||this._html.input.focus(),this}},{key:"blur",value:function(){return this._html.container.classList.remove("focused"),this._focused&&this._html.input.blur(),this}},{key:"remove",value:function(){var e=this._html;e.container.parentElement.insertBefore(this.el,e.container),e.container.remove(),this.el.style.display="block",1===Object.keys(L).length&&(document.removeEventListener("mousedown",this._vars.events.onMouseDown),window.removeEventListener("resize",this._vars.events.onResize)),this._form&&this._form.nodeName&&this._form.removeEventListener("reset",this._vars.events.onReset),delete L[this.id],delete this.el.tokenfield}}]),t}(w.default);t.default=C},function(e,t,s){"use strict";function n(e){console&&console.warn&&console.warn(e)}function i(){i.init.call(this)}function r(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function o(e){return void 0===e._maxListeners?i.defaultMaxListeners:e._maxListeners}function u(e,t,s,i){var u,l,a;if(r(s),l=e._events,void 0===l?(l=e._events=Object.create(null),e._eventsCount=0):(void 0!==l.newListener&&(e.emit("newListener",t,s.listener?s.listener:s),l=e._events),a=l[t]),void 0===a)a=l[t]=s,++e._eventsCount;else if("function"==typeof a?a=l[t]=i?[s,a]:[a,s]:i?a.unshift(s):a.push(s),(u=o(e))>0&&a.length>u&&!a.warned){a.warned=!0;var h=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");h.name="MaxListenersExceededWarning",h.emitter=e,h.type=t,h.count=a.length,n(h)}return e}function l(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function a(e,t,s){var n={fired:!1,wrapFn:void 0,target:e,type:t,listener:s},i=l.bind(n);return i.listener=s,n.wrapFn=i,i}function h(e,t,s){var n=e._events;if(void 0===n)return[];var i=n[t];return void 0===i?[]:"function"==typeof i?s?[i.listener||i]:[i]:s?f(i):c(i,i.length)}function m(e){var t=this._events;if(void 0!==t){var s=t[e];if("function"==typeof s)return 1;if(void 0!==s)return s.length}return 0}function c(e,t){for(var s=new Array(t),n=0;n0&&(r=t[0]),r instanceof Error)throw r;var o=new Error("Unhandled error."+(r?" ("+r.message+")":""));throw o.context=r,o}var u=i[e];if(void 0===u)return!1;if("function"==typeof u)_(u,this,t);else for(var l=u.length,a=c(u,l),s=0;s=0;o--)if(s[o]===t||s[o].listener===t){u=s[o].listener,i=o;break}if(i<0)return this;0===i?s.shift():d(s,i),1===s.length&&(n[e]=s[0]),void 0!==n.removeListener&&this.emit("removeListener",e,u||t)}return this},i.prototype.off=i.prototype.removeListener,i.prototype.removeAllListeners=function(e){var t,s,n;if(void 0===(s=this._events))return this;if(void 0===s.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==s[e]&&(0==--this._eventsCount?this._events=Object.create(null):delete s[e]),this;if(0===arguments.length){var i,r=Object.keys(s);for(n=0;n=0;n--)this.removeListener(e,t[n]);return this},i.prototype.listeners=function(e){return h(this,e,!0)},i.prototype.rawListeners=function(e){return h(this,e,!1)},i.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):m.call(e,t)},i.prototype.listenerCount=m,i.prototype.eventNames=function(){return this._eventsCount>0?p(this._events):[]}},function(e,t,s){"use strict";function n(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,n=new XMLHttpRequest,i=t.url,r=[];for(var o in e)r.push(o+"="+encodeURIComponent(e[o]));var u=r.join("&");"get"===t.type.toLowerCase()&&(i+="?"+u),n.open(t.type,i,!0);for(var l in t.headers){var a=t.headers[l];"function"==typeof a&&(a=a(e,t)),n.setRequestHeader(l,a)}return s&&(n.onreadystatechange=s),n.send(e),n}Object.defineProperty(t,"__esModule",{value:!0}),t.default=n}]); \ No newline at end of file diff --git a/lib/admin.go b/lib/admin.go index 4acd7c8..3df96a8 100644 --- a/lib/admin.go +++ b/lib/admin.go @@ -59,6 +59,7 @@ type editData struct { S Status Book database.Book SubmissionID string + Tags []string } func editHandler(h handler) { @@ -78,6 +79,10 @@ func editHandler(h handler) { data.Book = book data.S = GetStatus(h) data.SubmissionID = submissionID + data.Tags, err = h.db.GetTags() + if err != nil { + log.Error("Error getting tags: ", err) + } author := "" if len(book.Authors) > 0 { author = " by " + book.Authors[0] diff --git a/lib/database/database.go b/lib/database/database.go index 150320b..f157a6c 100644 --- a/lib/database/database.go +++ b/lib/database/database.go @@ -33,6 +33,7 @@ type DB interface { IncDownloads(ID string) error GetDownloadCounter(ID string) (int, error) GetFrontPage() FrontPage + GetTags() ([]string, error) AddSubmission(submission Submission, userName string) (id int, err error) UpdateSubmission(id int, status string, book *Book) error UpdateSubmissionByBook(bookID string, status string, book *Book) error diff --git a/lib/database/ro.go b/lib/database/ro.go index a56735c..5d8786d 100644 --- a/lib/database/ro.go +++ b/lib/database/ro.go @@ -109,6 +109,10 @@ func (db *roDB) GetFrontPage() FrontPage { return db.db.GetFrontPage() } +func (db *roDB) GetTags() ([]string, error) { + return db.db.GetTags() +} + func (db *roDB) AddSubmission(submission Submission, userName string) (id int, err error) { return 0, errors.New("RO database") } diff --git a/lib/database/stats.go b/lib/database/stats.go index 6a2e77f..a2ffd92 100644 --- a/lib/database/stats.go +++ b/lib/database/stats.go @@ -96,6 +96,10 @@ func (db *pgDB) frontPageUpdater() { } } +func (db *pgDB) GetTags() ([]string, error) { + return db.frontPage.Tags, nil +} + func (db *pgDB) getVisitedBooks(num int) (books []Book, err error) { err = db.sql.Model(&books). Column("book.*"). diff --git a/templates/edit.html b/templates/edit.html index 55c4ad7..fb8a27e 100644 --- a/templates/edit.html +++ b/templates/edit.html @@ -1,7 +1,5 @@ {{template "header.html" .S}} - - {{$submissionID := .SubmissionID}} {{with .Book}}
          @@ -108,6 +106,27 @@
          {{end}} - + + {{template "footer.html" .S}} diff --git a/templates/header.html b/templates/header.html index d50b6d5..8b5316f 100644 --- a/templates/header.html +++ b/templates/header.html @@ -7,6 +7,7 @@ + {{.Title}}