From a9801371b62cdaeb2b040480401da9b53408cfc2 Mon Sep 17 00:00:00 2001 From: Cervinko Cera Date: Fri, 15 Apr 2016 23:35:18 +0200 Subject: [PATCH] show 'better author and tags editing; partly copied from https://bitbucket.org/SpeedProg/calibreserver --- cps/static/css/typeaheadjs.css | 93 ----- cps/static/js/bootstrap3-typeahead.js | 523 -------------------------- cps/templates/detail.html | 11 +- cps/templates/edit_book.html | 35 +- cps/templates/index.html | 9 +- cps/templates/layout.html | 3 +- cps/templates/search.html | 9 +- cps/web.py | 152 ++++++-- 8 files changed, 152 insertions(+), 683 deletions(-) delete mode 100644 cps/static/css/typeaheadjs.css delete mode 100644 cps/static/js/bootstrap3-typeahead.js diff --git a/cps/static/css/typeaheadjs.css b/cps/static/css/typeaheadjs.css deleted file mode 100644 index 64c10736..00000000 --- a/cps/static/css/typeaheadjs.css +++ /dev/null @@ -1,93 +0,0 @@ -span.twitter-typeahead .tt-menu, -span.twitter-typeahead .tt-dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 14px; - text-align: left; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - background-clip: padding-box; -} -span.twitter-typeahead .tt-suggestion { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.42857143; - color: #333333; - white-space: nowrap; -} -span.twitter-typeahead .tt-suggestion.tt-cursor, -span.twitter-typeahead .tt-suggestion:hover, -span.twitter-typeahead .tt-suggestion:focus { - color: #ffffff; - text-decoration: none; - outline: 0; - background-color: #337ab7; -} -.input-group.input-group-lg span.twitter-typeahead .form-control { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px; -} -.input-group.input-group-sm span.twitter-typeahead .form-control { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -span.twitter-typeahead { - width: 100%; -} -.input-group span.twitter-typeahead { - display: block !important; - height: 34px; -} -.input-group span.twitter-typeahead .tt-menu, -.input-group span.twitter-typeahead .tt-dropdown-menu { - top: 32px !important; -} -.input-group span.twitter-typeahead:not(:first-child):not(:last-child) .form-control { - border-radius: 0; -} -.input-group span.twitter-typeahead:first-child .form-control { - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.input-group span.twitter-typeahead:last-child .form-control { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; -} -.input-group.input-group-sm span.twitter-typeahead { - height: 30px; -} -.input-group.input-group-sm span.twitter-typeahead .tt-menu, -.input-group.input-group-sm span.twitter-typeahead .tt-dropdown-menu { - top: 30px !important; -} -.input-group.input-group-lg span.twitter-typeahead { - height: 46px; -} -.input-group.input-group-lg span.twitter-typeahead .tt-menu, -.input-group.input-group-lg span.twitter-typeahead .tt-dropdown-menu { - top: 46px !important; -} diff --git a/cps/static/js/bootstrap3-typeahead.js b/cps/static/js/bootstrap3-typeahead.js deleted file mode 100644 index 936d8937..00000000 --- a/cps/static/js/bootstrap3-typeahead.js +++ /dev/null @@ -1,523 +0,0 @@ -/* ============================================================= - * bootstrap3-typeahead.js v3.1.0 - * https://github.com/bassjobsen/Bootstrap-3-Typeahead - * ============================================================= - * Original written by @mdo and @fat - * ============================================================= - * Copyright 2014 Bass Jobsen @bassjobsen - * - * Licensed under the Apache License, Version 2.0 (the 'License'); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an 'AS IS' BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -(function (root, factory) { - - 'use strict'; - - // CommonJS module is defined - if (typeof module !== 'undefined' && module.exports) { - module.exports = factory(require('jquery')); - } - // AMD module is defined - else if (typeof define === 'function' && define.amd) { - define(['jquery'], function ($) { - return factory ($); - }); - } else { - factory(root.jQuery); - } - -}(this, function ($) { - - 'use strict'; - // jshint laxcomma: true - - - /* TYPEAHEAD PUBLIC CLASS DEFINITION - * ================================= */ - - var Typeahead = function (element, options) { - this.$element = $(element); - this.options = $.extend({}, $.fn.typeahead.defaults, options); - this.matcher = this.options.matcher || this.matcher; - this.sorter = this.options.sorter || this.sorter; - this.select = this.options.select || this.select; - this.autoSelect = typeof this.options.autoSelect == 'boolean' ? this.options.autoSelect : true; - this.highlighter = this.options.highlighter || this.highlighter; - this.render = this.options.render || this.render; - this.updater = this.options.updater || this.updater; - this.displayText = this.options.displayText || this.displayText; - this.source = this.options.source; - this.delay = this.options.delay; - this.$menu = $(this.options.menu); - this.$appendTo = this.options.appendTo ? $(this.options.appendTo) : null; - this.shown = false; - this.listen(); - this.showHintOnFocus = typeof this.options.showHintOnFocus == 'boolean' ? this.options.showHintOnFocus : false; - this.afterSelect = this.options.afterSelect; - this.addItem = false; - }; - - Typeahead.prototype = { - - constructor: Typeahead, - - select: function () { - var val = this.$menu.find('.active').data('value'); - this.$element.data('active', val); - if(this.autoSelect || val) { - var newVal = this.updater(val); - // Updater can be set to any random functions via "options" parameter in constructor above. - // Add null check for cases when updater returns void or undefined. - if (!newVal) { - newVal = ""; - } - this.$element - .val(this.displayText(newVal) || newVal) - .change(); - this.afterSelect(newVal); - } - return this.hide(); - }, - - updater: function (item) { - return item; - }, - - setSource: function (source) { - this.source = source; - }, - - show: function () { - var pos = $.extend({}, this.$element.position(), { - height: this.$element[0].offsetHeight - }), scrollHeight; - - scrollHeight = typeof this.options.scrollHeight == 'function' ? - this.options.scrollHeight.call() : - this.options.scrollHeight; - - var element; - if (this.shown) { - element = this.$menu; - } else if (this.$appendTo) { - element = this.$menu.appendTo(this.$appendTo); - } else { - element = this.$menu.insertAfter(this.$element); - } - element.css({ - top: pos.top + pos.height + scrollHeight - , left: pos.left - }) - .show(); - - this.shown = true; - return this; - }, - - hide: function () { - this.$menu.hide(); - this.shown = false; - return this; - }, - - lookup: function (query) { - var items; - if (typeof(query) != 'undefined' && query !== null) { - this.query = query; - } else { - this.query = this.$element.val() || ''; - } - - if (this.query.length < this.options.minLength && !this.options.showHintOnFocus) { - return this.shown ? this.hide() : this; - } - - var worker = $.proxy(function() { - - if($.isFunction(this.source)) this.source(this.query, $.proxy(this.process, this)); - else if (this.source) { - this.process(this.source); - } - }, this); - - clearTimeout(this.lookupWorker); - this.lookupWorker = setTimeout(worker, this.delay); - }, - - process: function (items) { - var that = this; - - items = $.grep(items, function (item) { - return that.matcher(item); - }); - - items = this.sorter(items); - - if (!items.length && !this.options.addItem) { - return this.shown ? this.hide() : this; - } - - if (items.length > 0) { - this.$element.data('active', items[0]); - } else { - this.$element.data('active', null); - } - - // Add item - if (this.options.addItem){ - items.push(this.options.addItem); - } - - if (this.options.items == 'all') { - return this.render(items).show(); - } else { - return this.render(items.slice(0, this.options.items)).show(); - } - }, - - matcher: function (item) { - var it = this.displayText(item); - return ~it.toLowerCase().indexOf(this.query.toLowerCase()); - }, - - sorter: function (items) { - var beginswith = [] - , caseSensitive = [] - , caseInsensitive = [] - , item; - - while ((item = items.shift())) { - var it = this.displayText(item); - if (!it.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item); - else if (~it.indexOf(this.query)) caseSensitive.push(item); - else caseInsensitive.push(item); - } - - return beginswith.concat(caseSensitive, caseInsensitive); - }, - - highlighter: function (item) { - var html = $('
'); - var query = this.query; - var i = item.toLowerCase().indexOf(query.toLowerCase()); - var len, leftPart, middlePart, rightPart, strong; - len = query.length; - if(len === 0){ - return html.text(item).html(); - } - while (i > -1) { - leftPart = item.substr(0, i); - middlePart = item.substr(i, len); - rightPart = item.substr(i + len); - strong = $('').text(middlePart); - html - .append(document.createTextNode(leftPart)) - .append(strong); - item = rightPart; - i = item.toLowerCase().indexOf(query.toLowerCase()); - } - return html.append(document.createTextNode(item)).html(); - }, - - render: function (items) { - var that = this; - var self = this; - var activeFound = false; - var data = []; - var _category = that.options.separator; - - $.each(items, function (key,value) { - // inject separator - if (key > 0 && value[_category] !== items[key - 1][_category]){ - data.push({ - __type: 'divider' - }); - } - - // inject category header - if (value[_category] && (key === 0 || value[_category] !== items[key - 1][_category])){ - data.push({ - __type: 'category', - name: value[_category] - }); - } - data.push(value); - }); - - items = $(data).map(function (i, item) { - - if ((item.__type || false) == 'category'){ - return $(that.options.headerHtml).text(item.name)[0]; - } - - if ((item.__type || false) == 'divider'){ - return $(that.options.headerDivider)[0]; - } - - var text = self.displayText(item); - i = $(that.options.item).data('value', item); - i.find('a').html(that.highlighter(text, item)); - if (text == self.$element.val()) { - i.addClass('active'); - self.$element.data('active', item); - activeFound = true; - } - return i[0]; - }); - - if (this.autoSelect && !activeFound) { - items.filter(':not(.dropdown-header)').first().addClass('active'); - this.$element.data('active', items.first().data('value')); - } - this.$menu.html(items); - return this; - }, - - displayText: function(item) { - return typeof item !== 'undefined' && typeof item.name != 'undefined' && item.name || item; - }, - - next: function (event) { - var active = this.$menu.find('.active').removeClass('active') - , next = active.next(); - - if (!next.length) { - next = $(this.$menu.find('li')[0]); - } - - next.addClass('active'); - }, - - prev: function (event) { - var active = this.$menu.find('.active').removeClass('active') - , prev = active.prev(); - - if (!prev.length) { - prev = this.$menu.find('li').last(); - } - - prev.addClass('active'); - }, - - listen: function () { - this.$element - .on('focus', $.proxy(this.focus, this)) - .on('blur', $.proxy(this.blur, this)) - .on('keypress', $.proxy(this.keypress, this)) - .on('input', $.proxy(this.input, this)) - .on('keyup', $.proxy(this.keyup, this)); - - if (this.eventSupported('keydown')) { - this.$element.on('keydown', $.proxy(this.keydown, this)); - } - - this.$menu - .on('click', $.proxy(this.click, this)) - .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) - .on('mouseleave', 'li', $.proxy(this.mouseleave, this)); - }, - - destroy : function () { - this.$element.data('typeahead',null); - this.$element.data('active',null); - this.$element - .off('focus') - .off('blur') - .off('keypress') - .off('input') - .off('keyup'); - - if (this.eventSupported('keydown')) { - this.$element.off('keydown'); - } - - this.$menu.remove(); - }, - - eventSupported: function(eventName) { - var isSupported = eventName in this.$element; - if (!isSupported) { - this.$element.setAttribute(eventName, 'return;'); - isSupported = typeof this.$element[eventName] === 'function'; - } - return isSupported; - }, - - move: function (e) { - if (!this.shown) return; - - switch(e.keyCode) { - case 9: // tab - case 13: // enter - case 27: // escape - e.preventDefault(); - break; - - case 38: // up arrow - // with the shiftKey (this is actually the left parenthesis) - if (e.shiftKey) return; - e.preventDefault(); - this.prev(); - break; - - case 40: // down arrow - // with the shiftKey (this is actually the right parenthesis) - if (e.shiftKey) return; - e.preventDefault(); - this.next(); - break; - } - }, - - keydown: function (e) { - this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]); - if (!this.shown && e.keyCode == 40) { - this.lookup(); - } else { - this.move(e); - } - }, - - keypress: function (e) { - if (this.suppressKeyPressRepeat) return; - this.move(e); - }, - - input: function (e) { - this.lookup(); - e.preventDefault(); - }, - - keyup: function (e) { - switch(e.keyCode) { - case 40: // down arrow - case 38: // up arrow - case 16: // shift - case 17: // ctrl - case 18: // alt - break; - - case 9: // tab - case 13: // enter - if (!this.shown) return; - this.select(); - break; - - case 27: // escape - if (!this.shown) return; - this.hide(); - break; - } - - e.preventDefault(); - }, - - focus: function (e) { - if (!this.focused) { - this.focused = true; - if (this.options.showHintOnFocus) { - this.lookup(''); - } - } - }, - - blur: function (e) { - this.focused = false; - if (!this.mousedover && this.shown) this.hide(); - }, - - click: function (e) { - e.preventDefault(); - this.select(); - this.$element.focus(); - this.hide(); - }, - - mouseenter: function (e) { - this.mousedover = true; - this.$menu.find('.active').removeClass('active'); - $(e.currentTarget).addClass('active'); - }, - - mouseleave: function (e) { - this.mousedover = false; - if (!this.focused && this.shown) this.hide(); - } - - }; - - - /* TYPEAHEAD PLUGIN DEFINITION - * =========================== */ - - var old = $.fn.typeahead; - - $.fn.typeahead = function (option) { - var arg = arguments; - if (typeof option == 'string' && option == 'getActive') { - return this.data('active'); - } - return this.each(function () { - var $this = $(this) - , data = $this.data('typeahead') - , options = typeof option == 'object' && option; - if (!data) $this.data('typeahead', (data = new Typeahead(this, options))); - if (typeof option == 'string' && data[option]) { - if (arg.length > 1) { - data[option].apply(data, Array.prototype.slice.call(arg ,1)); - } else { - data[option](); - } - } - }); - }; - - $.fn.typeahead.defaults = { - source: [], - items: 8, - menu: '', - item: '
  • ', - minLength: 1, - scrollHeight: 0, - autoSelect: true, - afterSelect: $.noop, - addItem: false, - delay: 0, - separator: 'category', - headerHtml: '', - headerDivider: '' - }; - - $.fn.typeahead.Constructor = Typeahead; - - - /* TYPEAHEAD NO CONFLICT - * =================== */ - - $.fn.typeahead.noConflict = function () { - $.fn.typeahead = old; - return this; - }; - - - /* TYPEAHEAD DATA-API - * ================== */ - - $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { - var $this = $(this); - if ($this.data('typeahead')) return; - $this.typeahead($this.data()); - }); - -})); diff --git a/cps/templates/detail.html b/cps/templates/detail.html index 6a8aafd3..bcaad48a 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -11,9 +11,14 @@

    {{entry.title}}

    -

    {{entry.authors[0].name}} -

    - +

    + {% for author in entry.authors %} + {{author.name}} + {% if not loop.last %} + & + {% endif %} + {% endfor %} +

    {% if entry.ratings.__len__() > 0 %}

    diff --git a/cps/templates/edit_book.html b/cps/templates/edit_book.html index 75858c77..b4ec3661 100644 --- a/cps/templates/edit_book.html +++ b/cps/templates/edit_book.html @@ -1,26 +1,6 @@ {% extends "layout.html" %} {% block body %} {% if book %} - -

    {% if book.has_cover is defined %} @@ -36,12 +16,7 @@ $(document).ready(function(){
    - {% if book.authors|length > 1 %} - {% for author in book.authors %} -

    {{author.name.join(" & ")}}

    - {% endfor %} - {% endif %} - +
    @@ -78,3 +53,11 @@ $(document).ready(function(){
    {% endif %} {% endblock %} + +{% block js %} + + +{% endblock %} +{% block header %} + +{% endblock %} diff --git a/cps/templates/index.html b/cps/templates/index.html index f2b43112..6ee0ff2b 100755 --- a/cps/templates/index.html +++ b/cps/templates/index.html @@ -50,7 +50,14 @@

    {{entry.title|shortentitle}}

    -

    {{entry.authors[0].name}}

    +

    + {% for author in entry.authors %} + {{author.name}} + {% if not loop.last %} + & + {% endif %} + {% endfor %} +

    {% if entry.ratings.__len__() > 0 %}
    {% for number in range((entry.ratings[0].rating/2)|int(2)) %} diff --git a/cps/templates/layout.html b/cps/templates/layout.html index f47d3ea1..8acea8c7 100644 --- a/cps/templates/layout.html +++ b/cps/templates/layout.html @@ -23,12 +23,12 @@ - + {% block header %}{% endblock %}