1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 10:37:23 +00:00

Merge branch 'master' into Develop

# Conflicts:
#	cps/kobo.py
This commit is contained in:
Ozzie Isaacs 2021-05-14 19:59:35 +02:00
commit f29088e854
67 changed files with 4520 additions and 6786 deletions

View File

@ -59,7 +59,7 @@ except ImportError:
log = logger.create()
cc_exceptions = ['datetime', 'comments', 'composite', 'series']
cc_exceptions = ['composite', 'series']
cc_classes = {}
Base = declarative_base()
@ -473,7 +473,7 @@ class CalibreDB():
}
books_custom_column_links[row.id] = type(str('books_custom_column_' + str(row.id) + '_link'),
(Base,), dicttable)
else:
if row.datatype in ['rating', 'text', 'enumeration']:
books_custom_column_links[row.id] = Table('books_custom_column_' + str(row.id) + '_link',
Base.metadata,
Column('book', Integer, ForeignKey('books.id'),
@ -491,23 +491,25 @@ class CalibreDB():
ccdict['value'] = Column(Float)
elif row.datatype == 'int':
ccdict['value'] = Column(Integer)
elif row.datatype == 'datetime':
ccdict['value'] = Column(TIMESTAMP)
elif row.datatype == 'bool':
ccdict['value'] = Column(Boolean)
else:
ccdict['value'] = Column(String)
if row.datatype in ['float', 'int', 'bool']:
if row.datatype in ['float', 'int', 'bool', 'datetime', 'comments']:
ccdict['book'] = Column(Integer, ForeignKey('books.id'))
cc_classes[row.id] = type(str('custom_column_' + str(row.id)), (Base,), ccdict)
for cc_id in cc_ids:
if (cc_id[1] == 'bool') or (cc_id[1] == 'int') or (cc_id[1] == 'float'):
if cc_id[1] in ['bool', 'int', 'float', 'datetime', 'comments']:
setattr(Books,
'custom_column_' + str(cc_id[0]),
relationship(cc_classes[cc_id[0]],
primaryjoin=(
Books.id == cc_classes[cc_id[0]].book),
backref='books'))
elif (cc_id[1] == 'series'):
elif cc_id[1] == 'series':
setattr(Books,
'custom_column_' + str(cc_id[0]),
relationship(books_custom_column_links[cc_id[0]],

View File

@ -495,12 +495,17 @@ def edit_book_publisher(publishers, book):
return changed
def edit_cc_data_number(book_id, book, c, to_save, cc_db_value, cc_string):
def edit_cc_data_value(book_id, book, c, to_save, cc_db_value, cc_string):
changed = False
if to_save[cc_string] == 'None':
to_save[cc_string] = None
elif c.datatype == 'bool':
to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0
elif c.datatype == 'datetime':
try:
to_save[cc_string] = datetime.strptime(to_save[cc_string], "%Y-%m-%d")
except ValueError:
to_save[cc_string] = db.Books.DEFAULT_PUBDATE
if to_save[cc_string] != cc_db_value:
if cc_db_value is not None:
@ -559,8 +564,8 @@ def edit_cc_data(book_id, book, to_save):
else:
cc_db_value = None
if to_save[cc_string].strip():
if c.datatype == 'int' or c.datatype == 'bool' or c.datatype == 'float':
changed, to_save = edit_cc_data_number(book_id, book, c, to_save, cc_db_value, cc_string)
if c.datatype in ['int', 'bool', 'float', "datetime", "comments"]:
changed, to_save = edit_cc_data_value(book_id, book, c, to_save, cc_db_value, cc_string)
else:
changed, to_save = edit_cc_data_string(book, c, to_save, cc_db_value, cc_string)
else:

View File

@ -10,58 +10,38 @@ if ($("#description").length) {
menubar: "edit view format",
language: language
});
}
if (!Modernizr.inputtypes.date) {
$("#pubdate").datepicker({
format: "yyyy-mm-dd",
language: language
}).on("change", function () {
// Show localized date over top of the standard YYYY-MM-DD date
var pubDate;
var results = /(\d{4})[-\/\\](\d{1,2})[-\/\\](\d{1,2})/.exec(this.value); // YYYY-MM-DD
if (results) {
pubDate = new Date(results[1], parseInt(results[2], 10) - 1, results[3]) || new Date(this.value);
$("#fake_pubdate")
.val(pubDate.toLocaleDateString(language))
.removeClass("hidden");
}
}).trigger("change");
if ($(".tiny_editor").length) {
tinymce.init({
selector: ".tiny_editor",
branding: false,
menubar: "edit view format",
language: language
});
}
$(".datepicker").datepicker({
format: "yyyy-mm-dd",
language: language
}).on("change", function () {
// Show localized date over top of the standard YYYY-MM-DD date
var pubDate;
var results = /(\d{4})[-\/\\](\d{1,2})[-\/\\](\d{1,2})/.exec(this.value); // YYYY-MM-DD
if (results) {
pubDate = new Date(results[1], parseInt(results[2], 10) - 1, results[3]) || new Date(this.value);
$(this).next('input')
.val(pubDate.toLocaleDateString(language))
.removeClass("hidden");
}
}
}).trigger("change");
if (!Modernizr.inputtypes.date) {
$("#Publishstart").datepicker({
format: "yyyy-mm-dd",
language: language
}).on("change", function () {
// Show localized date over top of the standard YYYY-MM-DD date
var pubDate;
var results = /(\d{4})[-\/\\](\d{1,2})[-\/\\](\d{1,2})/.exec(this.value); // YYYY-MM-DD
if (results) {
pubDate = new Date(results[1], parseInt(results[2], 10) - 1, results[3]) || new Date(this.value);
$("#fake_Publishstart")
.val(pubDate.toLocaleDateString(language))
.removeClass("hidden");
}
}).trigger("change");
}
$(".datepicker_delete").click(function() {
var inputs = $(this).parent().siblings('input');
$(inputs[0]).data('datepicker').clearDates();
$(inputs[1]).addClass('hidden');
});
if (!Modernizr.inputtypes.date) {
$("#Publishend").datepicker({
format: "yyyy-mm-dd",
language: language
}).on("change", function () {
// Show localized date over top of the standard YYYY-MM-DD date
var pubDate;
var results = /(\d{4})[-\/\\](\d{1,2})[-\/\\](\d{1,2})/.exec(this.value); // YYYY-MM-DD
if (results) {
pubDate = new Date(results[1], parseInt(results[2], 10) - 1, results[3]) || new Date(this.value);
$("#fake_Publishend")
.val(pubDate.toLocaleDateString(language))
.removeClass("hidden");
}
}).trigger("change");
}
/*
Takes a prefix, query typeahead callback, Bloodhound typeahead adapter
@ -78,11 +58,6 @@ function prefixedSource(prefix, query, cb, bhAdapter) {
});
}
/*function getPath() {
var jsFileLocation = $("script[src*=edit_books]").attr("src"); // the js file path
return jsFileLocation.substr(0, jsFileLocation.search("/static/js/edit_books.js")); // the js folder path
}*/
var authors = new Bloodhound({
name: "authors",
datumTokenizer: function datumTokenizer(datum) {

File diff suppressed because one or more lines are too long

View File

@ -1,639 +0,0 @@
/* Copyright 2012 Mozilla Foundation
*
* 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.
*/
/* eslint strict: ["error", "function"] */
/* eslint-disable no-extend-native */
/* globals VBArray, PDFJS */
(function compatibilityWrapper() {
'use strict';
var userAgent = navigator.userAgent;
var isAndroid = /Android/.test(userAgent);
var isAndroidPre3 = /Android\s[0-2][^\d]/.test(userAgent);
var isAndroidPre5 = /Android\s[0-4][^\d]/.test(userAgent);
var isChrome = userAgent.indexOf('Chrom') >= 0;
var isChromeWithRangeBug = /Chrome\/(39|40)\./.test(userAgent);
var isIE = userAgent.indexOf('Trident') >= 0;
var isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent);
var isOpera = userAgent.indexOf('Opera') >= 0;
var isSafari = /Safari\//.test(userAgent) &&
!/(Chrome\/|Android\s)/.test(userAgent);
// Initializing PDFJS global object here, it case if we need to change/disable
// some PDF.js features, e.g. range requests
if (typeof PDFJS === 'undefined') {
(typeof window !== 'undefined' ? window : this).PDFJS = {};
}
// Checking if the typed arrays are supported
// Support: iOS<6.0 (subarray), IE<10, Android<4.0
(function checkTypedArrayCompatibility() {
if (typeof Uint8Array !== 'undefined') {
// Support: iOS<6.0
if (typeof Uint8Array.prototype.subarray === 'undefined') {
Uint8Array.prototype.subarray = function subarray(start, end) {
return new Uint8Array(this.slice(start, end));
};
Float32Array.prototype.subarray = function subarray(start, end) {
return new Float32Array(this.slice(start, end));
};
}
// Support: Android<4.1
if (typeof Float64Array === 'undefined') {
window.Float64Array = Float32Array;
}
return;
}
function subarray(start, end) {
return new TypedArray(this.slice(start, end));
}
function setArrayOffset(array, offset) {
if (arguments.length < 2) {
offset = 0;
}
for (var i = 0, n = array.length; i < n; ++i, ++offset) {
this[offset] = array[i] & 0xFF;
}
}
function TypedArray(arg1) {
var result, i, n;
if (typeof arg1 === 'number') {
result = [];
for (i = 0; i < arg1; ++i) {
result[i] = 0;
}
} else if ('slice' in arg1) {
result = arg1.slice(0);
} else {
result = [];
for (i = 0, n = arg1.length; i < n; ++i) {
result[i] = arg1[i];
}
}
result.subarray = subarray;
result.buffer = result;
result.byteLength = result.length;
result.set = setArrayOffset;
if (typeof arg1 === 'object' && arg1.buffer) {
result.buffer = arg1.buffer;
}
return result;
}
window.Uint8Array = TypedArray;
window.Int8Array = TypedArray;
// we don't need support for set, byteLength for 32-bit array
// so we can use the TypedArray as well
window.Uint32Array = TypedArray;
window.Int32Array = TypedArray;
window.Uint16Array = TypedArray;
window.Float32Array = TypedArray;
window.Float64Array = TypedArray;
})();
// URL = URL || webkitURL
// Support: Safari<7, Android 4.2+
(function normalizeURLObject() {
if (!window.URL) {
window.URL = window.webkitURL;
}
})();
// Object.defineProperty()?
// Support: Android<4.0, Safari<5.1
(function checkObjectDefinePropertyCompatibility() {
if (typeof Object.defineProperty !== 'undefined') {
var definePropertyPossible = true;
try {
// some browsers (e.g. safari) cannot use defineProperty() on DOM objects
// and thus the native version is not sufficient
Object.defineProperty(new Image(), 'id', { value: 'test' });
// ... another test for android gb browser for non-DOM objects
var Test = function Test() {};
Test.prototype = { get id() { } };
Object.defineProperty(new Test(), 'id',
{ value: '', configurable: true, enumerable: true, writable: false });
} catch (e) {
definePropertyPossible = false;
}
if (definePropertyPossible) {
return;
}
}
Object.defineProperty = function objectDefineProperty(obj, name, def) {
delete obj[name];
if ('get' in def) {
obj.__defineGetter__(name, def['get']);
}
if ('set' in def) {
obj.__defineSetter__(name, def['set']);
}
if ('value' in def) {
obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
this.__defineGetter__(name, function objectDefinePropertyGetter() {
return value;
});
return value;
});
obj[name] = def.value;
}
};
})();
// No XMLHttpRequest#response?
// Support: IE<11, Android <4.0
(function checkXMLHttpRequestResponseCompatibility() {
var xhrPrototype = XMLHttpRequest.prototype;
var xhr = new XMLHttpRequest();
if (!('overrideMimeType' in xhr)) {
// IE10 might have response, but not overrideMimeType
// Support: IE10
Object.defineProperty(xhrPrototype, 'overrideMimeType', {
value: function xmlHttpRequestOverrideMimeType(mimeType) {}
});
}
if ('responseType' in xhr) {
return;
}
// The worker will be using XHR, so we can save time and disable worker.
PDFJS.disableWorker = true;
Object.defineProperty(xhrPrototype, 'responseType', {
get: function xmlHttpRequestGetResponseType() {
return this._responseType || 'text';
},
set: function xmlHttpRequestSetResponseType(value) {
if (value === 'text' || value === 'arraybuffer') {
this._responseType = value;
if (value === 'arraybuffer' &&
typeof this.overrideMimeType === 'function') {
this.overrideMimeType('text/plain; charset=x-user-defined');
}
}
}
});
// Support: IE9
if (typeof VBArray !== 'undefined') {
Object.defineProperty(xhrPrototype, 'response', {
get: function xmlHttpRequestResponseGet() {
if (this.responseType === 'arraybuffer') {
return new Uint8Array(new VBArray(this.responseBody).toArray());
}
return this.responseText;
}
});
return;
}
Object.defineProperty(xhrPrototype, 'response', {
get: function xmlHttpRequestResponseGet() {
if (this.responseType !== 'arraybuffer') {
return this.responseText;
}
var text = this.responseText;
var i, n = text.length;
var result = new Uint8Array(n);
for (i = 0; i < n; ++i) {
result[i] = text.charCodeAt(i) & 0xFF;
}
return result.buffer;
}
});
})();
// window.btoa (base64 encode function) ?
// Support: IE<10
(function checkWindowBtoaCompatibility() {
if ('btoa' in window) {
return;
}
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
window.btoa = function windowBtoa(chars) {
var buffer = '';
var i, n;
for (i = 0, n = chars.length; i < n; i += 3) {
var b1 = chars.charCodeAt(i) & 0xFF;
var b2 = chars.charCodeAt(i + 1) & 0xFF;
var b3 = chars.charCodeAt(i + 2) & 0xFF;
var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
buffer += (digits.charAt(d1) + digits.charAt(d2) +
digits.charAt(d3) + digits.charAt(d4));
}
return buffer;
};
})();
// window.atob (base64 encode function)?
// Support: IE<10
(function checkWindowAtobCompatibility() {
if ('atob' in window) {
return;
}
// https://github.com/davidchambers/Base64.js
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
window.atob = function (input) {
input = input.replace(/=+$/, '');
if (input.length % 4 === 1) {
throw new Error('bad atob input');
}
for (
// initialize result and counters
var bc = 0, bs, buffer, idx = 0, output = '';
// get next character
(buffer = input.charAt(idx++));
// character found in table?
// initialize bit storage and add its ascii value
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
// and if not first of each 4 characters,
// convert the first 8 bits to one ascii character
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
) {
// try to find character in table (0-63, not found => -1)
buffer = digits.indexOf(buffer);
}
return output;
};
})();
// Function.prototype.bind?
// Support: Android<4.0, iOS<6.0
(function checkFunctionPrototypeBindCompatibility() {
if (typeof Function.prototype.bind !== 'undefined') {
return;
}
Function.prototype.bind = function functionPrototypeBind(obj) {
var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
var bound = function functionPrototypeBindBound() {
var args = headArgs.concat(Array.prototype.slice.call(arguments));
return fn.apply(obj, args);
};
return bound;
};
})();
// HTMLElement dataset property
// Support: IE<11, Safari<5.1, Android<4.0
(function checkDatasetProperty() {
var div = document.createElement('div');
if ('dataset' in div) {
return; // dataset property exists
}
Object.defineProperty(HTMLElement.prototype, 'dataset', {
get: function() {
if (this._dataset) {
return this._dataset;
}
var dataset = {};
for (var j = 0, jj = this.attributes.length; j < jj; j++) {
var attribute = this.attributes[j];
if (attribute.name.substring(0, 5) !== 'data-') {
continue;
}
var key = attribute.name.substring(5).replace(/\-([a-z])/g,
function(all, ch) {
return ch.toUpperCase();
});
dataset[key] = attribute.value;
}
Object.defineProperty(this, '_dataset', {
value: dataset,
writable: false,
enumerable: false
});
return dataset;
},
enumerable: true
});
})();
// HTMLElement classList property
// Support: IE<10, Android<4.0, iOS<5.0
(function checkClassListProperty() {
var div = document.createElement('div');
if ('classList' in div) {
return; // classList property exists
}
function changeList(element, itemName, add, remove) {
var s = element.className || '';
var list = s.split(/\s+/g);
if (list[0] === '') {
list.shift();
}
var index = list.indexOf(itemName);
if (index < 0 && add) {
list.push(itemName);
}
if (index >= 0 && remove) {
list.splice(index, 1);
}
element.className = list.join(' ');
return (index >= 0);
}
var classListPrototype = {
add: function(name) {
changeList(this.element, name, true, false);
},
contains: function(name) {
return changeList(this.element, name, false, false);
},
remove: function(name) {
changeList(this.element, name, false, true);
},
toggle: function(name) {
changeList(this.element, name, true, true);
}
};
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function() {
if (this._classList) {
return this._classList;
}
var classList = Object.create(classListPrototype, {
element: {
value: this,
writable: false,
enumerable: true
}
});
Object.defineProperty(this, '_classList', {
value: classList,
writable: false,
enumerable: false
});
return classList;
},
enumerable: true
});
})();
// Check console compatibility
// In older IE versions the console object is not available
// unless console is open.
// Support: IE<10
(function checkConsoleCompatibility() {
if (!('console' in window)) {
window.console = {
log: function() {},
error: function() {},
warn: function() {}
};
} else if (!('bind' in console.log)) {
// native functions in IE9 might not have bind
console.log = (function(fn) {
return function(msg) { return fn(msg); };
})(console.log);
console.error = (function(fn) {
return function(msg) { return fn(msg); };
})(console.error);
console.warn = (function(fn) {
return function(msg) { return fn(msg); };
})(console.warn);
}
})();
// Check onclick compatibility in Opera
// Support: Opera<15
(function checkOnClickCompatibility() {
// workaround for reported Opera bug DSK-354448:
// onclick fires on disabled buttons with opaque content
function ignoreIfTargetDisabled(event) {
if (isDisabled(event.target)) {
event.stopPropagation();
}
}
function isDisabled(node) {
return node.disabled || (node.parentNode && isDisabled(node.parentNode));
}
if (isOpera) {
// use browser detection since we cannot feature-check this bug
document.addEventListener('click', ignoreIfTargetDisabled, true);
}
})();
// Checks if possible to use URL.createObjectURL()
// Support: IE
(function checkOnBlobSupport() {
// sometimes IE loosing the data created with createObjectURL(), see #3977
if (isIE) {
PDFJS.disableCreateObjectURL = true;
}
})();
// Checks if navigator.language is supported
(function checkNavigatorLanguage() {
if ('language' in navigator) {
return;
}
PDFJS.locale = navigator.userLanguage || 'en-US';
})();
// Support: Safari 6.0+, Android<3.0, Chrome 39/40, iOS
(function checkRangeRequests() {
// Safari has issues with cached range requests see:
// https://github.com/mozilla/pdf.js/issues/3260
// Last tested with version 6.0.4.
// Older versions of Android (pre 3.0) has issues with range requests, see:
// https://github.com/mozilla/pdf.js/issues/3381.
// Make sure that we only match webkit-based Android browsers,
// since Firefox/Fennec works as expected.
// Range requests are broken in Chrome 39 and 40, https://crbug.com/442318
if (isSafari || isAndroidPre3 || isChromeWithRangeBug || isIOS) {
PDFJS.disableRange = true;
PDFJS.disableStream = true;
}
})();
// Check if the browser supports manipulation of the history.
// Support: IE<10, Android<4.2
(function checkHistoryManipulation() {
// Android 2.x has so buggy pushState support that it was removed in
// Android 3.0 and restored as late as in Android 4.2.
// Support: Android 2.x
if (!history.pushState || isAndroidPre3) {
PDFJS.disableHistory = true;
}
})();
// Support: IE<11, Chrome<21, Android<4.4, Safari<6
(function checkSetPresenceInImageData() {
// IE < 11 will use window.CanvasPixelArray which lacks set function.
if (window.CanvasPixelArray) {
if (typeof window.CanvasPixelArray.prototype.set !== 'function') {
window.CanvasPixelArray.prototype.set = function(arr) {
for (var i = 0, ii = this.length; i < ii; i++) {
this[i] = arr[i];
}
};
}
} else {
// Old Chrome and Android use an inaccessible CanvasPixelArray prototype.
// Because we cannot feature detect it, we rely on user agent parsing.
var polyfill = false, versionMatch;
if (isChrome) {
versionMatch = userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
// Chrome < 21 lacks the set function.
polyfill = versionMatch && parseInt(versionMatch[2]) < 21;
} else if (isAndroid) {
// Android < 4.4 lacks the set function.
// Android >= 4.4 will contain Chrome in the user agent,
// thus pass the Chrome check above and not reach this block.
polyfill = isAndroidPre5;
} else if (isSafari) {
versionMatch = userAgent.
match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//);
// Safari < 6 lacks the set function.
polyfill = versionMatch && parseInt(versionMatch[1]) < 6;
}
if (polyfill) {
var contextPrototype = window.CanvasRenderingContext2D.prototype;
var createImageData = contextPrototype.createImageData;
contextPrototype.createImageData = function(w, h) {
var imageData = createImageData.call(this, w, h);
imageData.data.set = function(arr) {
for (var i = 0, ii = this.length; i < ii; i++) {
this[i] = arr[i];
}
};
return imageData;
};
// this closure will be kept referenced, so clear its vars
contextPrototype = null;
}
}
})();
// Support: IE<10, Android<4.0, iOS
(function checkRequestAnimationFrame() {
function fakeRequestAnimationFrame(callback) {
window.setTimeout(callback, 20);
}
if (isIOS) {
// requestAnimationFrame on iOS is broken, replacing with fake one.
window.requestAnimationFrame = fakeRequestAnimationFrame;
return;
}
if ('requestAnimationFrame' in window) {
return;
}
window.requestAnimationFrame =
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
fakeRequestAnimationFrame;
})();
// Support: Android, iOS
(function checkCanvasSizeLimitation() {
if (isIOS || isAndroid) {
// 5MP
PDFJS.maxCanvasPixels = 5242880;
}
})();
// Disable fullscreen support for certain problematic configurations.
// Support: IE11+ (when embedded).
(function checkFullscreenSupport() {
if (isIE && window.parent !== window) {
PDFJS.disableFullscreen = true;
}
})();
// Provides document.currentScript support
// Support: IE, Chrome<29.
(function checkCurrentScript() {
if ('currentScript' in document) {
return;
}
Object.defineProperty(document, 'currentScript', {
get: function () {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
},
enumerable: true,
configurable: true
});
})();
// Provides `input.type = 'type'` runtime failure protection.
// Support: IE9,10.
(function checkInputTypeNumberAssign() {
var el = document.createElement('input');
try {
el.type = 'number';
} catch (ex) {
var inputProto = el.constructor.prototype;
var typeProperty = Object.getOwnPropertyDescriptor(inputProto, 'type');
Object.defineProperty(inputProto, 'type', {
get: function () { return typeProperty.get.call(this); },
set: function (value) {
typeProperty.set.call(this, value === 'number' ? 'text' : value);
},
enumerable: true,
configurable: true
});
}
})();
// Provides correct document.readyState value for legacy browsers.
// Support: IE9,10.
(function checkDocumentReadyState() {
if (!document.attachEvent) {
return;
}
var documentProto = document.constructor.prototype;
var readyStateProto = Object.getOwnPropertyDescriptor(documentProto,
'readyState');
Object.defineProperty(documentProto, 'readyState', {
get: function () {
var value = readyStateProto.get.call(this);
return value === 'interactive' ? 'loading' : value;
},
set: function (value) { readyStateProto.set.call(this, value); },
enumerable: true,
configurable: true
});
})();
}).call((typeof window === 'undefined') ? this : window);

File diff suppressed because one or more lines are too long

View File

@ -1,147 +0,0 @@
/*!
* context.js Library associated with > v0.9.6.2 of intention.js
* http://intentionjs.com/
*
* Copyright 2011, 2013 Dowjones and other contributors
* Released under the MIT license
*
*/
(function () {
'use strict';
var context = function($, Intention){
// create a brand spankin new intention object
var intent=new Intention(),
// placeholder for the horizontal axis
horizontal_axis,
orientation_axis;
// throttle funtion used for keeping calls to the resize responive
// callback to a minimum
function throttle(callback, interval){
var lastExec = new Date(),
timer = null;
return function(e){
var d = new Date();
if (d-lastExec < interval) {
if (timer) {
window.clearTimeout(timer);
}
var callbackWrapper = function(event){
return function(){
callback(event);
};
};
timer = window.setTimeout(callbackWrapper(e), interval);
return false;
}
callback(e);
lastExec = d;
};
}
// catchall
// =======================================================================
intent.responsive([{name:'base'}]).respond('base');
// width context?
// =======================================================================
horizontal_axis = intent.responsive({
ID:'width',
contexts: [
{name:'standard', min:840},
{name:'tablet', min:510},
{name:'mobile', min:0}],
// compare the return value of the callback to each context
// return true for a match
matcher: function(test, context){
if(typeof test === 'string'){
return test === context.name;
}
return test>=context.min;
},
// callback, return value is passed to matcher()
// to compare against current context
measure: function(arg){
if(typeof arg === 'string'){
return arg;
}
return $(window).width();
}});
// orientation context?
// =======================================================================
orientation_axis = intent.responsive({
ID:'orientation',
contexts: [{name:'portrait', rotation: 0},
{name:'landscape', rotation:90}],
matcher: function(measure, ctx){
return measure === ctx.rotation;
},
measure: function(){
var test = Math.abs(window.orientation);
if(test > 0) {
test = 180 - test;
}
return test;
}
});
// ONE TIME CHECK AXES:
// touch device?
// =======================================================================
intent.responsive({
ID:'touch',
contexts:[{name:'touch'}],
matcher: function() {
return "ontouchstart" in window;
}}).respond();
// retina display?
// =======================================================================
intent.responsive({
ID: 'highres',
// contexts
contexts:[{name:'highres'}],
// matching:
matcher: function(){
return window.devicePixelRatio > 1;
}}).respond();
// bind events to the window
$(window).on('resize', throttle(horizontal_axis.respond, 100))
.on('orientationchange', horizontal_axis.respond)
.on('orientationchange', orientation_axis.respond);
// register the current width and orientation without waiting for a window
// resize
horizontal_axis.respond();
orientation_axis.respond();
$(function(){
// at doc ready grab all of the elements in the doc
intent.elements(document);
});
// return the intention object so that it can be extended by other plugins
return intent;
};
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define('context', ['jquery', 'intention'], factory);
} else {
// Browser globals
root.intent = factory(root.jQuery, root.Intention);
}
}(this, function ($, Intention) {
return context($, Intention);
}));
}).call(this);

View File

@ -14,37 +14,41 @@
*/
/* eslint-disable no-var */
'use strict';
"use strict";
var FontInspector = (function FontInspectorClosure() {
var fonts, createObjectURL;
var fonts;
var active = false;
var fontAttribute = 'data-font-name';
var fontAttribute = "data-font-name";
function removeSelection() {
let divs = document.querySelectorAll(`span[${fontAttribute}]`);
for (let div of divs) {
div.className = '';
const divs = document.querySelectorAll(`span[${fontAttribute}]`);
for (const div of divs) {
div.className = "";
}
}
function resetSelection() {
let divs = document.querySelectorAll(`span[${fontAttribute}]`);
for (let div of divs) {
div.className = 'debuggerHideText';
const divs = document.querySelectorAll(`span[${fontAttribute}]`);
for (const div of divs) {
div.className = "debuggerHideText";
}
}
function selectFont(fontName, show) {
let divs = document.querySelectorAll(`span[${fontAttribute}=${fontName}]`);
for (let div of divs) {
div.className = show ? 'debuggerShowText' : 'debuggerHideText';
const divs = document.querySelectorAll(
`span[${fontAttribute}=${fontName}]`
);
for (const div of divs) {
div.className = show ? "debuggerShowText" : "debuggerHideText";
}
}
function textLayerClick(e) {
if (!e.target.dataset.fontName ||
e.target.tagName.toUpperCase() !== 'SPAN') {
if (
!e.target.dataset.fontName ||
e.target.tagName.toUpperCase() !== "SPAN"
) {
return;
}
var fontName = e.target.dataset.fontName;
var selects = document.getElementsByTagName('input');
var selects = document.getElementsByTagName("input");
for (var i = 0; i < selects.length; ++i) {
var select = selects[i];
if (select.dataset.fontName !== fontName) {
@ -57,25 +61,22 @@ var FontInspector = (function FontInspectorClosure() {
}
return {
// Properties/functions needed by PDFBug.
id: 'FontInspector',
name: 'Font Inspector',
id: "FontInspector",
name: "Font Inspector",
panel: null,
manager: null,
init: function init(pdfjsLib) {
var panel = this.panel;
panel.setAttribute('style', 'padding: 5px;');
var tmp = document.createElement('button');
tmp.addEventListener('click', resetSelection);
tmp.textContent = 'Refresh';
var tmp = document.createElement("button");
tmp.addEventListener("click", resetSelection);
tmp.textContent = "Refresh";
panel.appendChild(tmp);
fonts = document.createElement('div');
fonts = document.createElement("div");
panel.appendChild(fonts);
createObjectURL = pdfjsLib.createObjectURL;
},
cleanup: function cleanup() {
fonts.textContent = '';
fonts.textContent = "";
},
enabled: false,
get active() {
@ -84,62 +85,62 @@ var FontInspector = (function FontInspectorClosure() {
set active(value) {
active = value;
if (active) {
document.body.addEventListener('click', textLayerClick, true);
document.body.addEventListener("click", textLayerClick, true);
resetSelection();
} else {
document.body.removeEventListener('click', textLayerClick, true);
document.body.removeEventListener("click", textLayerClick, true);
removeSelection();
}
},
// FontInspector specific functions.
fontAdded: function fontAdded(fontObj, url) {
function properties(obj, list) {
var moreInfo = document.createElement('table');
var moreInfo = document.createElement("table");
for (var i = 0; i < list.length; i++) {
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var tr = document.createElement("tr");
var td1 = document.createElement("td");
td1.textContent = list[i];
tr.appendChild(td1);
var td2 = document.createElement('td');
var td2 = document.createElement("td");
td2.textContent = obj[list[i]].toString();
tr.appendChild(td2);
moreInfo.appendChild(tr);
}
return moreInfo;
}
var moreInfo = properties(fontObj, ['name', 'type']);
var fontName = fontObj.loadedName;
var font = document.createElement('div');
var name = document.createElement('span');
var moreInfo = properties(fontObj, ["name", "type"]);
const fontName = fontObj.loadedName;
var font = document.createElement("div");
var name = document.createElement("span");
name.textContent = fontName;
var download = document.createElement('a');
var download = document.createElement("a");
if (url) {
url = /url\(['"]?([^\)"']+)/.exec(url);
url = /url\(['"]?([^)"']+)/.exec(url);
download.href = url[1];
} else if (fontObj.data) {
download.href = createObjectURL(fontObj.data, fontObj.mimeType);
download.href = URL.createObjectURL(
new Blob([fontObj.data], { type: fontObj.mimeType })
);
}
download.textContent = 'Download';
var logIt = document.createElement('a');
logIt.href = '';
logIt.textContent = 'Log';
logIt.addEventListener('click', function(event) {
download.textContent = "Download";
var logIt = document.createElement("a");
logIt.href = "";
logIt.textContent = "Log";
logIt.addEventListener("click", function (event) {
event.preventDefault();
console.log(fontObj);
});
var select = document.createElement('input');
select.setAttribute('type', 'checkbox');
const select = document.createElement("input");
select.setAttribute("type", "checkbox");
select.dataset.fontName = fontName;
select.addEventListener('click', (function(select, fontName) {
return (function() {
selectFont(fontName, select.checked);
});
})(select, fontName));
select.addEventListener("click", function () {
selectFont(fontName, select.checked);
});
font.appendChild(select);
font.appendChild(name);
font.appendChild(document.createTextNode(' '));
font.appendChild(document.createTextNode(" "));
font.appendChild(download);
font.appendChild(document.createTextNode(' '));
font.appendChild(document.createTextNode(" "));
font.appendChild(logIt);
font.appendChild(moreInfo);
fonts.appendChild(font);
@ -165,24 +166,23 @@ var StepperManager = (function StepperManagerClosure() {
var breakPoints = Object.create(null);
return {
// Properties/functions needed by PDFBug.
id: 'Stepper',
name: 'Stepper',
id: "Stepper",
name: "Stepper",
panel: null,
manager: null,
init: function init(pdfjsLib) {
var self = this;
this.panel.setAttribute('style', 'padding: 5px;');
stepperControls = document.createElement('div');
stepperChooser = document.createElement('select');
stepperChooser.addEventListener('change', function(event) {
stepperControls = document.createElement("div");
stepperChooser = document.createElement("select");
stepperChooser.addEventListener("change", function (event) {
self.selectStepper(this.value);
});
stepperControls.appendChild(stepperChooser);
stepperDiv = document.createElement('div');
stepperDiv = document.createElement("div");
this.panel.appendChild(stepperControls);
this.panel.appendChild(stepperDiv);
if (sessionStorage.getItem('pdfjsBreakPoints')) {
breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints'));
if (sessionStorage.getItem("pdfjsBreakPoints")) {
breakPoints = JSON.parse(sessionStorage.getItem("pdfjsBreakPoints"));
}
opMap = Object.create(null);
@ -191,21 +191,21 @@ var StepperManager = (function StepperManagerClosure() {
}
},
cleanup: function cleanup() {
stepperChooser.textContent = '';
stepperDiv.textContent = '';
stepperChooser.textContent = "";
stepperDiv.textContent = "";
steppers = [];
},
enabled: false,
active: false,
// Stepper specific functions.
create: function create(pageIndex) {
var debug = document.createElement('div');
debug.id = 'stepper' + pageIndex;
debug.setAttribute('hidden', true);
debug.className = 'stepper';
var debug = document.createElement("div");
debug.id = "stepper" + pageIndex;
debug.setAttribute("hidden", true);
debug.className = "stepper";
stepperDiv.appendChild(debug);
var b = document.createElement('option');
b.textContent = 'Page ' + (pageIndex + 1);
var b = document.createElement("option");
b.textContent = "Page " + (pageIndex + 1);
b.value = pageIndex;
stepperChooser.appendChild(b);
var initBreakPoints = breakPoints[pageIndex] || [];
@ -225,9 +225,9 @@ var StepperManager = (function StepperManagerClosure() {
for (i = 0; i < steppers.length; ++i) {
var stepper = steppers[i];
if (stepper.pageIndex === pageIndex) {
stepper.panel.removeAttribute('hidden');
stepper.panel.removeAttribute("hidden");
} else {
stepper.panel.setAttribute('hidden', true);
stepper.panel.setAttribute("hidden", true);
}
}
var options = stepperChooser.options;
@ -238,7 +238,7 @@ var StepperManager = (function StepperManagerClosure() {
},
saveBreakPoints: function saveBreakPoints(pageIndex, bps) {
breakPoints[pageIndex] = bps;
sessionStorage.setItem('pdfjsBreakPoints', JSON.stringify(breakPoints));
sessionStorage.setItem("pdfjsBreakPoints", JSON.stringify(breakPoints));
},
};
})();
@ -255,22 +255,26 @@ var Stepper = (function StepperClosure() {
}
function simplifyArgs(args) {
if (typeof args === 'string') {
if (typeof args === "string") {
var MAX_STRING_LENGTH = 75;
return args.length <= MAX_STRING_LENGTH ? args :
args.substring(0, MAX_STRING_LENGTH) + '...';
return args.length <= MAX_STRING_LENGTH
? args
: args.substring(0, MAX_STRING_LENGTH) + "...";
}
if (typeof args !== 'object' || args === null) {
if (typeof args !== "object" || args === null) {
return args;
}
if ('length' in args) { // array
var simpleArgs = [], i, ii;
if ("length" in args) {
// array
var simpleArgs = [],
i,
ii;
var MAX_ITEMS = 10;
for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) {
simpleArgs.push(simplifyArgs(args[i]));
}
if (i < args.length) {
simpleArgs.push('...');
simpleArgs.push("...");
}
return simpleArgs;
}
@ -281,6 +285,7 @@ var Stepper = (function StepperClosure() {
return simpleObj;
}
// eslint-disable-next-line no-shadow
function Stepper(panel, pageIndex, initialBreakPoints) {
this.panel = panel;
this.breakPoint = 0;
@ -293,16 +298,16 @@ var Stepper = (function StepperClosure() {
Stepper.prototype = {
init: function init(operatorList) {
var panel = this.panel;
var content = c('div', 'c=continue, s=step');
var table = c('table');
var content = c("div", "c=continue, s=step");
var table = c("table");
content.appendChild(table);
table.cellSpacing = 0;
var headerRow = c('tr');
var headerRow = c("tr");
table.appendChild(headerRow);
headerRow.appendChild(c('th', 'Break'));
headerRow.appendChild(c('th', 'Idx'));
headerRow.appendChild(c('th', 'fn'));
headerRow.appendChild(c('th', 'args'));
headerRow.appendChild(c("th", "Break"));
headerRow.appendChild(c("th", "Idx"));
headerRow.appendChild(c("th", "fn"));
headerRow.appendChild(c("th", "args"));
panel.appendChild(content);
this.table = table;
this.updateOperatorList(operatorList);
@ -326,56 +331,57 @@ var Stepper = (function StepperClosure() {
}
var chunk = document.createDocumentFragment();
var operatorsToDisplay = Math.min(MAX_OPERATORS_COUNT,
operatorList.fnArray.length);
var operatorsToDisplay = Math.min(
MAX_OPERATORS_COUNT,
operatorList.fnArray.length
);
for (var i = this.operatorListIdx; i < operatorsToDisplay; i++) {
var line = c('tr');
line.className = 'line';
var line = c("tr");
line.className = "line";
line.dataset.idx = i;
chunk.appendChild(line);
var checked = this.breakPoints.includes(i);
var args = operatorList.argsArray[i] || [];
var breakCell = c('td');
var cbox = c('input');
cbox.type = 'checkbox';
cbox.className = 'points';
var breakCell = c("td");
var cbox = c("input");
cbox.type = "checkbox";
cbox.className = "points";
cbox.checked = checked;
cbox.dataset.idx = i;
cbox.onclick = cboxOnClick;
breakCell.appendChild(cbox);
line.appendChild(breakCell);
line.appendChild(c('td', i.toString()));
line.appendChild(c("td", i.toString()));
var fn = opMap[operatorList.fnArray[i]];
var decArgs = args;
if (fn === 'showText') {
if (fn === "showText") {
var glyphs = args[0];
var newArgs = [];
var str = [];
for (var j = 0; j < glyphs.length; j++) {
var glyph = glyphs[j];
if (typeof glyph === 'object' && glyph !== null) {
if (typeof glyph === "object" && glyph !== null) {
str.push(glyph.fontChar);
} else {
if (str.length > 0) {
newArgs.push(str.join(''));
newArgs.push(str.join(""));
str = [];
}
newArgs.push(glyph); // null or number
}
}
if (str.length > 0) {
newArgs.push(str.join(''));
newArgs.push(str.join(""));
}
decArgs = [newArgs];
}
line.appendChild(c('td', fn));
line.appendChild(c('td', JSON.stringify(simplifyArgs(decArgs))));
line.appendChild(c("td", fn));
line.appendChild(c("td", JSON.stringify(simplifyArgs(decArgs))));
}
if (operatorsToDisplay < operatorList.fnArray.length) {
line = c('tr');
var lastCell = c('td', '...');
var lastCell = c("td", "...");
lastCell.colspan = 4;
chunk.appendChild(lastCell);
}
@ -383,7 +389,7 @@ var Stepper = (function StepperClosure() {
this.table.appendChild(chunk);
},
getNextBreakPoint: function getNextBreakPoint() {
this.breakPoints.sort(function(a, b) {
this.breakPoints.sort(function (a, b) {
return a - b;
});
for (var i = 0; i < this.breakPoints.length; i++) {
@ -398,16 +404,16 @@ var Stepper = (function StepperClosure() {
var self = this;
var dom = document;
self.currentIdx = idx;
var listener = function(e) {
var listener = function (e) {
switch (e.keyCode) {
case 83: // step
dom.removeEventListener('keydown', listener);
dom.removeEventListener("keydown", listener);
self.nextBreakPoint = self.currentIdx + 1;
self.goTo(-1);
callback();
break;
case 67: // continue
dom.removeEventListener('keydown', listener);
dom.removeEventListener("keydown", listener);
var breakPoint = self.getNextBreakPoint();
self.nextBreakPoint = breakPoint;
self.goTo(-1);
@ -415,15 +421,15 @@ var Stepper = (function StepperClosure() {
break;
}
};
dom.addEventListener('keydown', listener);
dom.addEventListener("keydown", listener);
self.goTo(idx);
},
goTo: function goTo(idx) {
var allRows = this.panel.getElementsByClassName('line');
var allRows = this.panel.getElementsByClassName("line");
for (var x = 0, xx = allRows.length; x < xx; ++x) {
var row = allRows[x];
if ((row.dataset.idx | 0) === idx) {
row.style.backgroundColor = 'rgb(251,250,207)';
row.style.backgroundColor = "rgb(251,250,207)";
row.scrollIntoView();
} else {
row.style.backgroundColor = null;
@ -451,13 +457,11 @@ var Stats = (function Stats() {
}
return {
// Properties/functions needed by PDFBug.
id: 'Stats',
name: 'Stats',
id: "Stats",
name: "Stats",
panel: null,
manager: null,
init(pdfjsLib) {
this.panel.setAttribute('style', 'padding: 5px;');
},
init(pdfjsLib) {},
enabled: false,
active: false,
// Stats specific functions.
@ -467,21 +471,21 @@ var Stats = (function Stats() {
}
var statsIndex = getStatIndex(pageNumber);
if (statsIndex !== false) {
var b = stats[statsIndex];
const b = stats[statsIndex];
this.panel.removeChild(b.div);
stats.splice(statsIndex, 1);
}
var wrapper = document.createElement('div');
wrapper.className = 'stats';
var title = document.createElement('div');
title.className = 'title';
title.textContent = 'Page: ' + pageNumber;
var statsDiv = document.createElement('div');
var wrapper = document.createElement("div");
wrapper.className = "stats";
var title = document.createElement("div");
title.className = "title";
title.textContent = "Page: " + pageNumber;
var statsDiv = document.createElement("div");
statsDiv.textContent = stat.toString();
wrapper.appendChild(title);
wrapper.appendChild(statsDiv);
stats.push({ pageNumber, div: wrapper, });
stats.sort(function(a, b) {
stats.push({ pageNumber, div: wrapper });
stats.sort(function (a, b) {
return a.pageNumber - b.pageNumber;
});
clear(this.panel);
@ -503,14 +507,11 @@ window.PDFBug = (function PDFBugClosure() {
var activePanel = null;
return {
tools: [
FontInspector,
StepperManager,
Stats
],
tools: [FontInspector, StepperManager, Stats],
enable(ids) {
var all = false, tools = this.tools;
if (ids.length === 1 && ids[0] === 'all') {
var all = false,
tools = this.tools;
if (ids.length === 1 && ids[0] === "all") {
all = true;
}
for (var i = 0; i < tools.length; ++i) {
@ -521,7 +522,7 @@ window.PDFBug = (function PDFBugClosure() {
}
if (!all) {
// Sort the tools by the order they are enabled.
tools.sort(function(a, b) {
tools.sort(function (a, b) {
var indexA = ids.indexOf(a.id);
indexA = indexA < 0 ? tools.length : indexA;
var indexB = ids.indexOf(b.id);
@ -540,34 +541,37 @@ window.PDFBug = (function PDFBugClosure() {
* Panel
* ...
*/
var ui = document.createElement('div');
ui.id = 'PDFBug';
var ui = document.createElement("div");
ui.id = "PDFBug";
var controls = document.createElement('div');
controls.setAttribute('class', 'controls');
var controls = document.createElement("div");
controls.setAttribute("class", "controls");
ui.appendChild(controls);
var panels = document.createElement('div');
panels.setAttribute('class', 'panels');
var panels = document.createElement("div");
panels.setAttribute("class", "panels");
ui.appendChild(panels);
container.appendChild(ui);
container.style.right = panelWidth + 'px';
container.style.right = panelWidth + "px";
// Initialize all the debugging tools.
var tools = this.tools;
var self = this;
for (var i = 0; i < tools.length; ++i) {
var tool = tools[i];
var panel = document.createElement('div');
var panelButton = document.createElement('button');
var panel = document.createElement("div");
var panelButton = document.createElement("button");
panelButton.textContent = tool.name;
panelButton.addEventListener('click', (function(selected) {
return function(event) {
event.preventDefault();
self.selectPanel(selected);
};
})(i));
panelButton.addEventListener(
"click",
(function (selected) {
return function (event) {
event.preventDefault();
self.selectPanel(selected);
};
})(i)
);
controls.appendChild(panelButton);
panels.appendChild(panel);
tool.panel = panel;
@ -575,9 +579,13 @@ window.PDFBug = (function PDFBugClosure() {
if (tool.enabled) {
tool.init(pdfjsLib);
} else {
panel.textContent = tool.name + ' is disabled. To enable add ' +
' "' + tool.id + '" to the pdfBug parameter ' +
'and refresh (separate multiple by commas).';
panel.textContent =
tool.name +
" is disabled. To enable add " +
' "' +
tool.id +
'" to the pdfBug parameter ' +
"and refresh (separate multiple by commas).";
}
buttons.push(panelButton);
}
@ -591,7 +599,7 @@ window.PDFBug = (function PDFBugClosure() {
}
},
selectPanel(index) {
if (typeof index !== 'number') {
if (typeof index !== "number") {
index = this.tools.indexOf(index);
}
if (index === activePanel) {
@ -601,13 +609,13 @@ window.PDFBug = (function PDFBugClosure() {
var tools = this.tools;
for (var j = 0; j < tools.length; ++j) {
if (j === index) {
buttons[j].setAttribute('class', 'active');
buttons[j].setAttribute("class", "active");
tools[j].active = true;
tools[j].panel.removeAttribute('hidden');
tools[j].panel.removeAttribute("hidden");
} else {
buttons[j].setAttribute('class', '');
buttons[j].setAttribute("class", "");
tools[j].active = false;
tools[j].panel.setAttribute('hidden', 'true');
tools[j].panel.setAttribute("hidden", "true");
}
}
},

View File

@ -1,564 +0,0 @@
/*!
* intention.js Library v0.9.7.2
* http://intentionjs.com/
*
* Copyright 2011, 2013 Dowjones and other contributors
* Released under the MIT license
*
*/
(function(root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define('intention', ['jquery', 'underscore'], factory);
} else {
root.Intention = factory(root.jQuery, root._);
}
}(this, function($, _) {
'use strict';
var Intention = function(params){
var intent = _.extend(this, params,
{_listeners:{}, contexts:[], elms:$(), axes:{}, priority:[]});
return intent;
};
Intention.prototype = {
// public methods
responsive:function responsive(contexts, options){
// for generating random ids for axis when not specified
var idChars = 'abcdefghijklmnopqrstuvwxyz0123456789',
id='', i;
// create a random id for the axis
for(i=0; i<5; i++){
id += idChars[Math.floor(Math.random() * idChars.length)];
}
var defaults = {
// if no matcher function is specified expect to compare a
// string to the ctx.name property
matcher: function(measure, ctx){
return measure === ctx.name;
},
// function takes one arg and returns it
measure: _.identity,
ID: id
};
if(_.isObject(options) === false) {
options = {};
}
if((_.isArray(contexts)) && (_.isArray(contexts[0].contexts))){
_.each(contexts, function(axis){
responsive.apply(this, axis);
}, this);
return;
}
if((_.isArray(contexts) === false) && _.isObject(contexts)){
options = contexts;
} else {
options.contexts = contexts;
}
// fill in the options
options = _.extend({}, defaults, options);
// bind an the respond function to the axis ID and prefix it
// with an underscore so that it does not get whomped accidentally
this.on('_' + options.ID + ':', _.bind(
function(e){
this.axes = this._contextualize(
options.ID, e.context, this.axes);
this._respond(this.axes, this.elms);
}, this));
var axis = {
ID:options.ID,
current:null,
contexts:options.contexts,
respond:_.bind(this._responder(options.ID, options.contexts,
options.matcher, options.measure), this)
};
this.axes[options.ID] = axis;
this.axes.__keys__ = this.priority;
this.priority.unshift(options.ID);
return axis;
},
elements: function(scope){
// find all responsive elms in a specific dom scope
if(!scope){
scope = document;
}
$('[data-intent],[intent],[data-in],[in]',
scope).each(_.bind(function(i, elm){
this.add($(elm));
}, this));
return this;
},
add: function(elms, options){
var spec;
if(!options) {
options = {};
}
// is expecting a jquery object
elms.each(_.bind(function(i, elm){
var exists = false;
this.elms.each(function(i, respElm){
if(elm === respElm) {
exists=true;
return false;
}
return true;
});
if(exists === false){
// create the elements responsive data
spec = this._fillSpec(
_.extend(options, this._attrsToSpec(elm.attributes, this.axes)));
// make any appropriate changes based on the current contexts
this._makeChanges($(elm), spec, this.axes);
this.elms.push({
elm: elm,
spec: spec
});
}
}, this));
return this;
},
remove: function(elms){
// is expecting a jquery object
var respElms = this.elms;
// elms to remove
elms.each(function(i, elm){
// elms to check against
respElms.each(function(i, candidate){
if(elm === candidate.elm){
respElms.splice(i, 1);
// found the match, break the loop
return false;
}
return true;
});
});
return this;
},
is: function(ctxName){
var axes = this.axes;
return _.some(axes.__keys__, function(key){
return ctxName === axes[key].current;
});
},
current: function(axisName){
if(this.axes.hasOwnProperty(axisName)){
return this.axes[axisName].current;
} else {
return false;
}
},
// code and concept taken from simple implementation of
// observer pattern outlined here:
// http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/
on: function(type, listener){
var events = type.split(' '),
i=0;
for(i;i<events.length;i++){
if(this._listeners[events[i]] === undefined) {
this._listeners[events[i]]=[];
}
this._listeners[events[i]].push(listener);
}
return this;
},
off: function(type, listener){
if(_.isArray(this._listeners[type])){
var listeners = this._listeners[type],
i;
for(i=0;listeners.length; i++){
if(listeners[i] === listener){
listeners.splice(i,1);
break;
}
}
}
return this;
},
// privates
_responder: function(axisID, contexts, matcher, measure){
var currentContext;
// called to perform a check
return function(){
var measurement = measure.apply(this, arguments);
_.every(contexts, function(ctx){
if( matcher(measurement, ctx)) {
// first time, or different than last context
if( (currentContext===undefined) ||
(ctx.name !== currentContext.name)){
currentContext = ctx;
// event emitting!
// emit the private axis event
this._emitter(
{_type: '_' + axisID + ':', context:currentContext.name},
currentContext, this)
// emit the public axis event
._emitter({_type: axisID + ':', context:currentContext.name},
currentContext, this)
// attempt to trigger the axis to context pair
._emitter(_.extend({},
{_type: axisID + ':' + currentContext.name},
currentContext), currentContext, this)
// then emit the context event (second ensures the context
// changes happen after all dom manipulations)
._emitter(_.extend({}, {_type:currentContext.name},
currentContext), currentContext, this);
// done, break the loop
return false;
}
// same context, break the loop
return false;
}
return true;
}, this);
// return the intention object for chaining
return this;
};
},
_emitter: function(event){
if(typeof event === 'string') {
event={_type:event};
}
if(!event.target){
event.target=this;
}
if(!event._type){
throw new Error(event._type + ' is not a supported event.');
}
if(_.isArray(this._listeners[event._type])){
var listeners = this._listeners[event._type],
i;
for(i=0; i<listeners.length; i++){
listeners[i].apply(this, arguments);
}
}
return this;
},
_fillSpec: function(spec){
var applySpec = function(fn){
_.each(spec, function(axisOptions, axis){
_.each(axisOptions, function(ctxOptions, ctx){
fn(ctxOptions, ctx, axis);
});
});
}, filler={};
applySpec(function(options){
// check to see if the ctx val is an object, could be a string
if(_.isObject(options)){
_.each(options, function(val, func){
filler[func] = '';
});
}
});
applySpec(function(options, ctx, axis){
if(_.isObject(options)){
spec[axis][ctx] = _.extend({}, filler, options);
}
});
return spec;
},
_assocAxis: function(ctx, axes){
var match=false;
_.every(axes.__keys__, function(axis){
if(match === false){
_.every(axes[axis].contexts, function(ctxCandidate){
if(ctxCandidate.name === ctx){
match = axis;
return false;
}
return true;
});
return true;
}else {
return false;
}
});
return match;
},
_makeSpec: function(axis, ctx, sAttr, value, spec){
var axisObj,
ctxObj;
if(spec[axis] !== undefined){
axisObj = spec[axis];
if(axisObj[ctx] === undefined) {
axisObj[ctx] = {};
}
} else {
axisObj = {};
axisObj[ctx] = {};
spec[axis] = axisObj;
}
axisObj[ctx][sAttr] = value;
return spec;
},
_attrsToSpec: function(attrs, axes){
var spec={},
fullPattern = new RegExp(
'^(data-)?(in|intent)-(([a-zA-Z0-9][a-zA-Z0-9]*:)?([a-zA-Z0-9]*))-([A-Za-z:-]+)'),
axisPattern = new RegExp(
'^(data-)?(in|intent)-([a-zA-Z0-9][_a-zA-Z0-9]*):$');
_.each(attrs, function(attr){
var specMatch = attr.name.match(fullPattern),
axisName;
if(specMatch !== null) {
specMatch = specMatch.slice(-3);
axisName = specMatch[0];
if(specMatch[0] === undefined){
// if there is no axis find one:
specMatch[0] = this._assocAxis(specMatch[1], axes);
if(specMatch[0] === false) {
// there is no context, so get outa here
return; // skipt the attr
}
} else {
specMatch[0] = specMatch[0].replace(/:$/, '');}
specMatch.push(attr.value);
specMatch.push(spec);
spec = this._makeSpec.apply(this, specMatch);
} else if(axisPattern.test(attr.name)){
axisName = attr.name.match(axisPattern)[3];
_.each(axes[axisName].contexts,
function(context){
this._makeSpec(axisName, context.name, 'class', context.name +
' ' + attr.value, spec);
},
this);}},
this);
return spec;
},
_contextSpec: function(ctxObj, specs){
if(specs.hasOwnProperty(ctxObj.axis) &&
specs[ctxObj.axis].hasOwnProperty(ctxObj.ctx)){
return specs[ctxObj.axis][ctxObj.ctx];
}
return {};
},
_resolveSpecs: function(currentContexts, specs){
var changes={},
moveFuncs=['append', 'prepend', 'before', 'after'];
_.each(currentContexts, function(ctxObj){
// if the axis or the context to not exist in the specs object
// skip to the next one
_.each(this._contextSpec(ctxObj, specs), function(val, func){
if(func==='class'){
if(!changes[func]){
changes[func] = [];
}
changes[func] = _.union(changes[func], val.split(' '));
} else if(((changes.move === undefined) ||
(changes.move.value === '')) &&
($.inArray(func, moveFuncs) !== -1)){
changes.move = {value:val, placement:func};
} else {
if((changes[func] === undefined) || (changes[func] === '')){
changes[func]=val;
}
}
}, this);
}, this);
return changes;
},
_currentContexts: function(axes) {
var contexts = [];
_.each(axes.__keys__, function(ID){
if(axes[ID].current !== null) {
contexts.push({ctx:axes[ID].current, axis:ID});
return;
}
});
return contexts;
},
_removeClasses: function(specs, axes) {
var toRemove = [];
_.each(axes.__keys__, function(key){
var axis = axes[key];
_.each(axis.contexts, function(ctx){
// ignore the current context, those classes SHOULD be applied
if(ctx.name === axis.current) {
return;
}
var contextSpec = this._contextSpec(
{axis:axis.ID, ctx:ctx.name}, specs),
classes;
if(contextSpec !== undefined) {
if(contextSpec['class'] !== undefined) {
classes = contextSpec['class'].split(' ');
if(classes !== undefined){
toRemove = _.union(toRemove, classes);
}
}
}
}, this);
}, this);
return toRemove;
},
_contextConfig: function(specs, axes){
return this._resolveSpecs(this._currentContexts(axes), specs, axes);
},
_makeChanges: function(elm, specs, axes){
if(_.isEmpty(axes)===false){
var ctxConfig = this._contextConfig(specs, axes);
_.each(ctxConfig, function(change, func){
if(func==='move'){
if( (specs.__placement__ !== change.placement) ||
(specs.__move__ !== change.value)){
$(change.value)[change.placement](elm);
// save the last placement of the element so
// we're not moving it around for no good reason
specs.__placement__ = change.placement;
specs.__move__ = change.value;
}
} else if(func === 'class') {
var classes = elm.attr('class') || '';
// the class add/remove formula
classes = _.union(change,
_.difference(classes.split(' '),
this._removeClasses(specs, axes)));
elm.attr('class', classes.join(' '));
} else {
elm.attr(func, change);
}
}, this);
}
return elm;
},
_respond: function(axes, elms){
// go through all of the responsive elms
elms.each(_.bind(function(i, elm){
var $elm = $(elm.elm);
this._makeChanges($elm, elm.spec, axes);
$elm.trigger('intent', this);
}, this));
},
_contextualize: function(axisID, context, axes){
axes[axisID].current = context;
return axes;
},
// private props
// axis test, does it begin with an underscore? for testing inside
// spec objects
_axis_test_pattern: new RegExp("^_[a-zA-Z0-9]"),
// match a group after the underscore:
_axis_match_pattern: new RegExp("^_([a-zA-Z0-9][_a-zA-Z0-9]*)"),
// simple trim
_trim_pattern:new RegExp( "^\s+|\s+$", "g" )
};
return Intention;
}));

File diff suppressed because it is too large Load Diff

23
cps/static/js/libs/jquery.form.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,3 @@
/* Function to select for custom build: form input types
/*! modernizr 3.6.0 (Custom Build) | MIT *
* https://modernizr.com/download/?-inputtypes-setclasses !*/
!function(e,t,n){function a(e,t){return typeof e===t}function s(){var e,t,n,s,i,o,c;for(var u in r)if(r.hasOwnProperty(u)){if(e=[],t=r[u],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(s=a(t.fn,"function")?t.fn():t.fn,i=0;i<e.length;i++)o=e[i],c=o.split("."),1===c.length?Modernizr[c[0]]=s:(!Modernizr[c[0]]||Modernizr[c[0]]instanceof Boolean||(Modernizr[c[0]]=new Boolean(Modernizr[c[0]])),Modernizr[c[0]][c[1]]=s),l.push((s?"":"no-")+c.join("-"))}}function i(e){var t=u.className,n=Modernizr._config.classPrefix||"";if(f&&(t=t.baseVal),Modernizr._config.enableJSClass){var a=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(a,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(t+=" "+n+e.join(" "+n),f?u.className.baseVal=t:u.className=t)}function o(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):f?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}var l=[],r=[],c={_version:"3.6.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){r.push({name:e,fn:t,options:n})},addAsyncTest:function(e){r.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=c,Modernizr=new Modernizr;var u=t.documentElement,f="svg"===u.nodeName.toLowerCase(),p=o("input"),d="search tel url email datetime date month week time datetime-local number range color".split(" "),m={};Modernizr.inputtypes=function(e){for(var a,s,i,o=e.length,l="1)",r=0;o>r;r++)p.setAttribute("type",a=e[r]),i="text"!==p.type&&"style"in p,i&&(p.value=l,p.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(a)&&p.style.WebkitAppearance!==n?(u.appendChild(p),s=t.defaultView,i=s.getComputedStyle&&"textfield"!==s.getComputedStyle(p,null).WebkitAppearance&&0!==p.offsetHeight,u.removeChild(p)):/^(search|tel)$/.test(a)||(i=/^(url|email)$/.test(a)?p.checkValidity&&p.checkValidity()===!1:p.value!=l)),m[e[r]]=!!i;return m}(d),s(),i(l),delete c.addTest,delete c.addAsyncTest;for(var h=0;h<Modernizr._q.length;h++)Modernizr._q[h]();e.Modernizr=Modernizr}(window,document);
/*!
* @fileOverview TouchSwipe - jQuery Plugin
* @version 1.6.18

View File

@ -1,7 +1,7 @@
/*!
* screenfull
* v4.2.0 - 2019-04-01
* v5.1.0 - 2020-12-24
* (c) Sindre Sorhus; MIT License
*/
!function(){"use strict";var u="undefined"!=typeof window&&void 0!==window.document?window.document:{},e="undefined"!=typeof module&&module.exports,t="undefined"!=typeof Element&&"ALLOW_KEYBOARD_INPUT"in Element,c=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],l=0,r=n.length,t={};l<r;l++)if((e=n[l])&&e[1]in u){for(l=0;l<e.length;l++)t[n[0][l]]=e[l];return t}return!1}(),r={change:c.fullscreenchange,error:c.fullscreenerror},n={request:function(r){return new Promise(function(e){var n=c.requestFullscreen,l=function(){this.off("change",l),e()}.bind(this);r=r||u.documentElement,/ Version\/5\.1(?:\.\d+)? Safari\//.test(navigator.userAgent)?r[n]():r[n](t?Element.ALLOW_KEYBOARD_INPUT:{}),this.on("change",l)}.bind(this))},exit:function(){return new Promise(function(e){if(this.isFullscreen){var n=function(){this.off("change",n),e()}.bind(this);u[c.exitFullscreen](),this.on("change",n)}else e()}.bind(this))},toggle:function(e){return this.isFullscreen?this.exit():this.request(e)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,n){var l=r[e];l&&u.addEventListener(l,n,!1)},off:function(e,n){var l=r[e];l&&u.removeEventListener(l,n,!1)},raw:c};c?(Object.defineProperties(n,{isFullscreen:{get:function(){return Boolean(u[c.fullscreenElement])}},element:{enumerable:!0,get:function(){return u[c.fullscreenElement]}},enabled:{enumerable:!0,get:function(){return Boolean(u[c.fullscreenEnabled])}}}),e?(module.exports=n,module.exports.default=n):window.screenfull=n):e?module.exports=!1:window.screenfull=!1}();
!function(){"use strict";var c="undefined"!=typeof window&&void 0!==window.document?window.document:{},e="undefined"!=typeof module&&module.exports,s=function(){for(var e,n=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],l=0,r=n.length,t={};l<r;l++)if((e=n[l])&&e[1]in c){for(l=0;l<e.length;l++)t[n[0][l]]=e[l];return t}return!1}(),l={change:s.fullscreenchange,error:s.fullscreenerror},n={request:function(t,u){return new Promise(function(e,n){var l=function(){this.off("change",l),e()}.bind(this);this.on("change",l);var r=(t=t||c.documentElement)[s.requestFullscreen](u);r instanceof Promise&&r.then(l).catch(n)}.bind(this))},exit:function(){return new Promise(function(e,n){var l,r;this.isFullscreen?(l=function(){this.off("change",l),e()}.bind(this),this.on("change",l),(r=c[s.exitFullscreen]())instanceof Promise&&r.then(l).catch(n)):e()}.bind(this))},toggle:function(e,n){return this.isFullscreen?this.exit():this.request(e,n)},onchange:function(e){this.on("change",e)},onerror:function(e){this.on("error",e)},on:function(e,n){e=l[e];e&&c.addEventListener(e,n,!1)},off:function(e,n){e=l[e];e&&c.removeEventListener(e,n,!1)},raw:s};s?(Object.defineProperties(n,{isFullscreen:{get:function(){return Boolean(c[s.fullscreenElement])}},element:{enumerable:!0,get:function(){return c[s.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(c[s.fullscreenEnabled])}}}),e?module.exports=n:window.screenfull=n):e?module.exports={isEnabled:!1}:window.screenfull={isEnabled:!1}}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -533,7 +533,7 @@ $(function() {
$("#pub_new").toggleClass("disabled");
$("#pub_old").toggleClass("disabled");
var alternative_text = $("#toggle_order_shelf").data('alt-text');
$("#toggle_order_shelf")[0].attributes['data-alt-text'].value = $("#toggle_order_shelf").html();
$("#toggle_order_shelf").data('alt-text', $("#toggle_order_shelf").html());
$("#toggle_order_shelf").html(alternative_text);
});

View File

@ -105,12 +105,13 @@
</div>
{% endif %}
{% endif %}
<div class="form-group">
<label for="pubdate">{{_('Published Date')}}</label>
<div style="position: relative">
<input type="date" class="form-control" name="pubdate" id="pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdateinput}}{% endif %}">
<input type="text" class="form-control fake-input hidden" id="fake_pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdate}}{% endif %}">
</div>
<label for="pubdate">{{_('Published Date')}}</label>
<div class="form-group input-group">
<input type="text" style="position: static;" class="datepicker form-control" name="pubdate" id="pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdateinput}}{% endif %}">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdate}}{% endif %}">
<span class="input-group-btn">
<button type="button" id="pubdate_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
<div class="form-group">
<label for="publisher">{{_('Publisher')}}</label>
@ -149,7 +150,25 @@
{% endif %}>
{% endif %}
{% if c.datatype == 'datetime' %}
<div class="input-group">
<input type="text" style="position: static;" class="datepicker form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}"
{% if book['custom_column_' ~ c.id]|length > 0 %}
value="{% if book['custom_column_' ~ c.id][0].value %}{{ book['custom_column_' ~ c.id][0].value|formatdateinput}}{% endif %}"
{% endif %}>
<input type="text" style="position: absolute;" class="fake_custom_column_{{ c.id }} form-control fake-input hidden" id="fake_pubdate"
{% if book['custom_column_' ~ c.id]|length > 0 %}
value="{% if book['custom_column_' ~ c.id][0].value %}{{book['custom_column_' ~ c.id][0].value|formatdate}}{% endif %}"
{% endif %}>
<span class="input-group-btn">
<button type="button" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
{% endif %}
{% if c.datatype == 'comments' %}
<textarea class="form-control tiny_editor" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" rows="7">{% if book['custom_column_' ~ c.id]|length > 0 %}{{book['custom_column_' ~ c.id][0].value}}{%endif%}</textarea>
{% endif %}
{% if c.datatype == 'enumeration' %}
<select class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}">
<option></option>

View File

@ -100,7 +100,7 @@
<h2 id="title">{{entry.title}}</h2>
<p class="author">
{% for author in entry.authors %}
<a href="{{url_for('web.books_list', data='author', sort_param='new', book_id=author.id ) }}">{{author.name.replace('|',',')}}</a>
<a href="{{url_for('web.books_list', data='author', sort_param='stored', book_id=author.id ) }}">{{author.name.replace('|',',')}}</a>
{% if not loop.last %}
&amp;
{% endif %}
@ -122,7 +122,7 @@
{% endif %}
{% if entry.series|length > 0 %}
<p>{{_('Book')}} {{entry.series_index}} {{_('of')}} <a href="{{url_for('web.books_list', data='series', sort_param='abc', book_id=entry.series[0].id)}}">{{entry.series[0].name}}</a></p>
<p>{{_('Book')}} {{entry.series_index}} {{_('of')}} <a href="{{url_for('web.books_list', data='series', sort_param='stored', book_id=entry.series[0].id)}}">{{entry.series[0].name}}</a></p>
{% endif %}
{% if entry.languages.__len__() > 0 %}
@ -151,7 +151,7 @@
<span class="glyphicon glyphicon-tags"></span>
{% for tag in entry.tags %}
<a href="{{ url_for('web.books_list', data='category', sort_param='new', book_id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a>
<a href="{{ url_for('web.books_list', data='category', sort_param='stored', book_id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a>
{%endfor%}
</p>
@ -162,7 +162,7 @@
<div class="publishers">
<p>
<span>{{_('Publisher')}}:
<a href="{{url_for('web.books_list', data='publisher', sort_param='new', book_id=entry.publishers[0].id ) }}">{{entry.publishers[0].name}}</a>
<a href="{{url_for('web.books_list', data='publisher', sort_param='stored', book_id=entry.publishers[0].id ) }}">{{entry.publishers[0].name}}</a>
</span>
</p>
</div>
@ -193,14 +193,16 @@
{% else %}
{% if c.datatype == 'float' %}
{{ column.value|formatfloat(2) }}
{% else %}
{% if c.datatype == 'series' %}
{% elif c.datatype == 'datetime' %}
{{ column.value|formatdate }}
{% elif c.datatype == 'comments' %}
{{column.value|safe}}
{% elif c.datatype == 'series' %}
{{ '%s [%s]' % (column.value, column.extra|formatfloat(2)) }}
{% else %}
{{ column.value }}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}

View File

@ -27,7 +27,7 @@
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book sortable" {% if entry[0].sort %}data-name="{{entry[0].series[0].name}}"{% endif %} data-id="{% if entry[0].series[0].name %}{{entry[0].series[0].name}}{% endif %}">
<div class="cover">
<a href="{{url_for('web.books_list', data=data, sort_param='new', book_id=entry[0].series[0].id )}}">
<a href="{{url_for('web.books_list', data=data, sort_param='stored', book_id=entry[0].series[0].id )}}">
<span class="img">
<img src="{{ url_for('web.get_cover', book_id=entry[0].id) }}" alt="{{ entry[0].name }}"/>
<span class="badge">{{entry.count}}</span>
@ -35,7 +35,7 @@
</a>
</div>
<div class="meta">
<a href="{{url_for('web.books_list', data=data, sort_param='new', book_id=entry[0].series[0].id )}}">
<a href="{{url_for('web.books_list', data=data, sort_param='stored', book_id=entry[0].series[0].id )}}">
<p class="title">{{entry[0].series[0].name|shortentitle}}</p>
</a>
</div>

View File

@ -193,11 +193,11 @@
<script src="{{ url_for('static', filename='js/libs/jquery.min.js') }}"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename='js/libs/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/underscore-min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/underscore-umd-min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/intention.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/context.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/plugins.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/jquery.form.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/jquery.form.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/uploadprogress.js') }}"> </script>
<script type="text/javascript">
$(function() {

View File

@ -32,7 +32,7 @@
{% endif %}
<div class="row" {% if entry[0].sort %}data-name="{{entry[0].name}}"{% endif %} data-id="{% if entry[0].sort %}{{entry[0].sort}}{% else %}{% if entry.name %}{{entry.name}}{% else %}{{entry[0].name}}{% endif %}{% endif %}">
<div class="col-xs-2 col-sm-2 col-md-1" align="left"><span class="badge">{{entry.count}}</span></div>
<div class="col-xs-10 col-sm-10 col-md-11"><a id="list_{{loop.index0}}" href="{% if entry.format %}{{url_for('web.books_list', data=data, sort_param='new', book_id=entry.format )}}{% else %}{{url_for('web.books_list', data=data, sort_param='new', book_id=entry[0].id )}}{% endif %}">
<div class="col-xs-10 col-sm-10 col-md-11"><a id="list_{{loop.index0}}" href="{% if entry.format %}{{url_for('web.books_list', data=data, sort_param='stored', book_id=entry.format )}}{% else %}{{url_for('web.books_list', data=data, sort_param='stored', book_id=entry[0].id )}}{% endif %}">
{% if entry.name %}
<div class="rating">
{% for number in range(entry.name) %}

View File

@ -2,7 +2,7 @@
{% block body %}
<div class="discover">
{% if entries|length < 1 %}
<h2>{{_('No Results Found')}} {{adv_searchterm}}</h2>
<h2>{{_('No Results Found')}}</h2>
<p>{{_('Search Term:')}} {{adv_searchterm}}</p>
{% else %}
<h2>{{result_count}} {{_('Results for:')}} {{adv_searchterm}}</h2>
@ -16,7 +16,7 @@
</button>
<ul id="add-to-shelves" class="dropdown-menu" aria-labelledby="add-to-shelf">
{% for shelf in g.shelves_access %}
{% if not shelf.id in books_shelfs and ( not shelf.is_public or g.user.role_edit_shelfs() ) %}
{% if not shelf.is_public or g.user.role_edit_shelfs() %}
<li><a href="{{ url_for('shelf.search_to_shelf', shelf_id=shelf.id) }}"> {{shelf.name}}{% if shelf.is_public == 1 %} {{_('(Public)')}}{% endif %}</a></li>
{% endif %}
{%endfor%}

View File

@ -18,16 +18,22 @@
<div class="row">
<div class="form-group col-sm-6">
<label for="Publishstart">{{_('Published Date From')}}</label>
<div style="position: relative">
<input type="date" class="form-control" name="Publishstart" id="Publishstart" value="">
<input type="text" class="form-control fake-input hidden" id="fake_Publishstart" value="">
<div class="input-group">
<input type="text" style="position: static;" class="datepicker form-control" name="Publishstart" id="Publishstart" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_Publishstart" value="">
<span class="input-group-btn">
<button type="button" id="pubstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
<div class="form-group col-sm-6">
<label for="Publishend">{{_('Published Date To')}}</label>
<div style="position: relative">
<input type="date" class="form-control" name="Publishend" id="Publishend" value="">
<input type="text" class="form-control fake-input hidden" id="fake_Publishend" value="">
<div class="input-group ">
<input type="text" style="position: static;" class="datepicker form-control" name="Publishend" id="Publishend" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_Publishend" value="">
<span class="input-group-btn">
<button type="button" id="pubend_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
</div>
@ -167,7 +173,32 @@
<input type="number" step="0.01" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" value="">
{% endif %}
{% if c.datatype in ['text', 'series'] and not c.is_multiple %}
{% if c.datatype == 'datetime' %}
<div class="row">
<div class="form-group col-sm-6">
<label for="{{ 'custom_column_' ~ c.id }}">{{_('From:')}}</label>
<div class="input-group">
<input type="text" style="position: static;" class="datepicker form-control" name="{{ 'custom_column_' ~ c.id }}_start" id="{{ 'custom_column_' ~ c.id }}_start" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_{{ 'custom_column_' ~ c.id }}_start" value="">
<span class="input-group-btn">
<button type="button" id="pubstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
<div class="form-group col-sm-6">
<label for="{{ 'custom_column_' ~ c.id }}">{{_('To:')}}</label>
<div class="input-group ">
<input type="text" style="position: static;" class="datepicker form-control" name="{{ 'custom_column_' ~ c.id }}_end" id="{{ 'custom_column_' ~ c.id }}_end" value="">
<input type="text" style="position: absolute;" class="form-control fake-input hidden" id="fake_{{ 'custom_column_' ~ c.id }}_end" value="">
<span class="input-group-btn">
<button type="button" id="pubend_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
</span>
</div>
</div>
</div>
{% endif %}
{% if c.datatype in ['text', 'series', 'comments'] and not c.is_multiple %}
<input type="text" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" value="">
{% endif %}

View File

@ -123,8 +123,8 @@
{{ user_table_row('kindle_mail', _('Enter Kindle E-mail Address'), _('Kindle E-mail'), false) }}
{{ user_select_translations('locale', url_for('admin.table_get_locale'), _('Locale'), true) }}
{{ user_select_languages('default_language', url_for('admin.table_get_default_lang'), _('Visible Book Languages'), true) }}
{{ user_table_row('denied_tags', _("Edit Denied Tags"), _("Denied Tags"), false, tags) }}
{{ user_table_row('allowed_tags', _("Edit Allowed Tags"), _("Allowed Tags"), false, tags) }}
{{ user_table_row('denied_tags', _("Edit Denied Tags"), _("Denied Tags"), false, tags) }}
{{ user_table_row('allowed_column_value', _("Edit Allowed Column Values"), _("Allowed Column Values"), false, custom_values) }}
{{ user_table_row('denied_column_value', _("Edit Denied Column Values"), _("Denied Columns Values"), false, custom_values) }}
{{ user_checkbox_row("role", "admin_role", _('Admin'), visiblility, all_roles)}}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1052,9 +1052,7 @@ def reconnect():
def search():
term = request.args.get("query")
if term:
# flask_session['query'] = json.dumps(request.form)
return redirect(url_for('web.books_list', data="search", sort_param='stored', query=term))
# return render_search_results(term, 0, None, config.config_books_per_page)
else:
return render_title_template('search.html',
searchterm="",
@ -1067,8 +1065,8 @@ def search():
@login_required_if_no_ano
def advanced_search():
values = dict(request.form)
params = ['include_tag', 'exclude_tag', 'include_serie', 'exclude_serie', 'include_shelf','exclude_shelf','include_language',
'exclude_language', 'include_extension', 'exclude_extension']
params = ['include_tag', 'exclude_tag', 'include_serie', 'exclude_serie', 'include_shelf', 'exclude_shelf',
'include_language', 'exclude_language', 'include_extension', 'exclude_extension']
for param in params:
values[param] = list(request.form.getlist(param))
flask_session['query'] = json.dumps(values)
@ -1077,20 +1075,30 @@ def advanced_search():
def adv_search_custom_columns(cc, term, q):
for c in cc:
custom_query = term.get('custom_column_' + str(c.id))
if custom_query != '' and custom_query is not None:
if c.datatype == 'bool':
if c.datatype == "datetime":
custom_start = term.get('custom_column_' + str(c.id) + '_start')
custom_end = term.get('custom_column_' + str(c.id) + '_end')
if custom_start:
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value == (custom_query == "True")))
elif c.datatype == 'int' or c.datatype == 'float':
db.cc_classes[c.id].value >= custom_start))
if custom_end:
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value == custom_query))
elif c.datatype == 'rating':
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value == int(float(custom_query) * 2)))
else:
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
func.lower(db.cc_classes[c.id].value).ilike("%" + custom_query + "%")))
db.cc_classes[c.id].value <= custom_end))
else:
custom_query = term.get('custom_column_' + str(c.id))
if custom_query != '' and custom_query is not None:
if c.datatype == 'bool':
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value == (custom_query == "True")))
elif c.datatype == 'int' or c.datatype == 'float':
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value == custom_query))
elif c.datatype == 'rating':
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
db.cc_classes[c.id].value == int(float(custom_query) * 2)))
else:
q = q.filter(getattr(db.Books, 'custom_column_' + str(c.id)).any(
func.lower(db.cc_classes[c.id].value).ilike("%" + custom_query + "%")))
return q
@ -1262,10 +1270,28 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
searchterm = []
cc_present = False
for c in cc:
if term.get('custom_column_' + str(c.id)):
searchterm.extend([(u"%s: %s" % (c.name, term.get('custom_column_' + str(c.id))))])
if c.datatype == "datetime":
column_start = term.get('custom_column_' + str(c.id) + '_start')
column_end = term.get('custom_column_' + str(c.id) + '_end')
if column_start:
searchterm.extend([u"{} >= {}".format(c.name,
format_date(datetime.strptime(column_start, "%Y-%m-%d"),
format='medium',
locale=get_locale())
)])
cc_present = True
if column_end:
searchterm.extend([u"{} <= {}".format(c.name,
format_date(datetime.strptime(column_end, "%Y-%m-%d").date(),
format='medium',
locale=get_locale())
)])
cc_present = True
elif term.get('custom_column_' + str(c.id)):
searchterm.extend([(u"{}: {}".format(c.name, term.get('custom_column_' + str(c.id))))])
cc_present = True
if any(tags.values()) or author_name or book_title or publisher or pub_start or pub_end or rating_low \
or rating_high or description or cc_present or read_status:
searchterm, pub_start, pub_end = extend_search_term(searchterm,

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@ Babel>=1.3, <2.9
Flask-Babel>=0.11.1,<2.1.0
Flask-Login>=0.3.2,<0.5.1
Flask-Principal>=0.3.2,<0.5.1
singledispatch>=3.4.0.0,<3.5.0.0
backports_abc>=0.4
Flask>=1.0.2,<1.2.0
iso-639>=0.4.5,<0.5.0

View File

@ -38,7 +38,6 @@ install_requires =
Flask-Babel>=0.11.1,<2.1.0
Flask-Login>=0.3.2,<0.5.1
Flask-Principal>=0.3.2,<0.5.1
singledispatch>=3.4.0.0,<3.5.0.0
backports_abc>=0.4
Flask>=1.0.2,<1.2.0
iso-639>=0.4.5,<0.5.0