mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Content server: When a category contains only one item, go directly to the book list instead of forcing the user to click ont hat one item
This commit is contained in:
parent
a1efc0cf1b
commit
344b72e74b
@ -38,6 +38,7 @@ Monocle.Browser.on = {
|
|||||||
iPad: navigator.userAgent.indexOf("iPad") != -1,
|
iPad: navigator.userAgent.indexOf("iPad") != -1,
|
||||||
BlackBerry: navigator.userAgent.indexOf("BlackBerry") != -1,
|
BlackBerry: navigator.userAgent.indexOf("BlackBerry") != -1,
|
||||||
Android: navigator.userAgent.indexOf('Android') != -1,
|
Android: navigator.userAgent.indexOf('Android') != -1,
|
||||||
|
MacOSX: navigator.userAgent.indexOf('Mac OS X') != -1,
|
||||||
Kindle3: navigator.userAgent.match(/Kindle\/3/)
|
Kindle3: navigator.userAgent.match(/Kindle\/3/)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,12 +163,23 @@ Monocle.Browser.has.transform3d = Monocle.Browser.CSSProps.isSupported([
|
|||||||
'OPerspective',
|
'OPerspective',
|
||||||
'msPerspective'
|
'msPerspective'
|
||||||
]) && Monocle.Browser.CSSProps.supportsMediaQueryProperty('transform-3d');
|
]) && Monocle.Browser.CSSProps.supportsMediaQueryProperty('transform-3d');
|
||||||
|
Monocle.Browser.has.embedded = (top != self);
|
||||||
|
|
||||||
Monocle.Browser.has.iframeTouchBug = Monocle.Browser.iOSVersionBelow("4.2");
|
Monocle.Browser.has.iframeTouchBug = Monocle.Browser.iOSVersionBelow("4.2");
|
||||||
|
|
||||||
Monocle.Browser.has.selectThruBug = Monocle.Browser.iOSVersionBelow("4.2");
|
Monocle.Browser.has.selectThruBug = Monocle.Browser.iOSVersionBelow("4.2");
|
||||||
|
|
||||||
Monocle.Browser.has.mustScrollSheaf = Monocle.Browser.is.MobileSafari;
|
Monocle.Browser.has.mustScrollSheaf = Monocle.Browser.is.MobileSafari;
|
||||||
Monocle.Browser.has.iframeDoubleWidthBug = Monocle.Browser.has.mustScrollSheaf;
|
Monocle.Browser.has.iframeDoubleWidthBug = Monocle.Browser.has.mustScrollSheaf;
|
||||||
|
|
||||||
Monocle.Browser.has.floatColumnBug = Monocle.Browser.is.WebKit;
|
Monocle.Browser.has.floatColumnBug = Monocle.Browser.is.WebKit;
|
||||||
|
|
||||||
|
Monocle.Browser.has.relativeIframeWidthBug = Monocle.Browser.on.Android;
|
||||||
|
|
||||||
|
|
||||||
|
Monocle.Browser.has.jumpFlickerBug =
|
||||||
|
Monocle.Browser.on.MacOSX && Monocle.Browser.is.WebKit;
|
||||||
|
|
||||||
|
|
||||||
if (typeof window.console == "undefined") {
|
if (typeof window.console == "undefined") {
|
||||||
window.console = {
|
window.console = {
|
||||||
@ -1091,11 +1103,29 @@ Monocle.Reader = function (node, bookData, options, onLoadCallback) {
|
|||||||
cmpt.dom.setStyles(Monocle.Styles.component);
|
cmpt.dom.setStyles(Monocle.Styles.component);
|
||||||
Monocle.Styles.applyRules(cmpt.contentDocument.body, Monocle.Styles.body);
|
Monocle.Styles.applyRules(cmpt.contentDocument.body, Monocle.Styles.body);
|
||||||
}
|
}
|
||||||
|
lockFrameWidths();
|
||||||
dom.find('overlay').dom.setStyles(Monocle.Styles.overlay);
|
dom.find('overlay').dom.setStyles(Monocle.Styles.overlay);
|
||||||
dispatchEvent('monocle:styles');
|
dispatchEvent('monocle:styles');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function lockingFrameWidths() {
|
||||||
|
if (!Monocle.Browser.has.relativeIframeWidthBug) { return; }
|
||||||
|
for (var i = 0, cmpt; cmpt = dom.find('component', i); ++i) {
|
||||||
|
cmpt.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function lockFrameWidths() {
|
||||||
|
if (!Monocle.Browser.has.relativeIframeWidthBug) { return; }
|
||||||
|
for (var i = 0, cmpt; cmpt = dom.find('component', i); ++i) {
|
||||||
|
cmpt.style.width = cmpt.parentNode.offsetWidth+"px";
|
||||||
|
cmpt.style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function setBook(bk, place, callback) {
|
function setBook(bk, place, callback) {
|
||||||
p.book = bk;
|
p.book = bk;
|
||||||
var pageCount = 0;
|
var pageCount = 0;
|
||||||
@ -1121,12 +1151,14 @@ Monocle.Reader = function (node, bookData, options, onLoadCallback) {
|
|||||||
if (!p.initialized) {
|
if (!p.initialized) {
|
||||||
console.warn('Attempt to resize book before initialization.');
|
console.warn('Attempt to resize book before initialization.');
|
||||||
}
|
}
|
||||||
|
lockingFrameWidths();
|
||||||
if (!dispatchEvent("monocle:resizing", {}, true)) {
|
if (!dispatchEvent("monocle:resizing", {}, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clearTimeout(p.resizeTimer);
|
clearTimeout(p.resizeTimer);
|
||||||
p.resizeTimer = setTimeout(
|
p.resizeTimer = setTimeout(
|
||||||
function () {
|
function () {
|
||||||
|
lockFrameWidths();
|
||||||
p.flipper.moveTo({ page: pageNumber() });
|
p.flipper.moveTo({ page: pageNumber() });
|
||||||
dispatchEvent("monocle:resize");
|
dispatchEvent("monocle:resize");
|
||||||
},
|
},
|
||||||
@ -1765,12 +1797,7 @@ Monocle.Book = function (dataSource) {
|
|||||||
|
|
||||||
|
|
||||||
function componentIdMatching(str) {
|
function componentIdMatching(str) {
|
||||||
for (var i = 0; i < p.componentIds.length; ++i) {
|
return p.componentIds.indexOf(str) >= 0 ? str : null;
|
||||||
if (str.indexOf(p.componentIds[i]) > -1) {
|
|
||||||
return p.componentIds[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2018,6 +2045,12 @@ Monocle.Component = function (book, id, index, chapters, source) {
|
|||||||
|
|
||||||
|
|
||||||
function loadFrameFromURL(url, frame, callback) {
|
function loadFrameFromURL(url, frame, callback) {
|
||||||
|
if (!url.match(/^\//)) {
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.setAttribute('href', url);
|
||||||
|
url = link.href;
|
||||||
|
delete(link);
|
||||||
|
}
|
||||||
frame.onload = function () {
|
frame.onload = function () {
|
||||||
frame.onload = null;
|
frame.onload = null;
|
||||||
Monocle.defer(callback);
|
Monocle.defer(callback);
|
||||||
@ -2460,7 +2493,7 @@ Monocle.Flippers.Legacy = function (reader) {
|
|||||||
function moveTo(locus, callback) {
|
function moveTo(locus, callback) {
|
||||||
var fn = frameToLocus;
|
var fn = frameToLocus;
|
||||||
if (typeof callback == "function") {
|
if (typeof callback == "function") {
|
||||||
fn = function () { frameToLocus(); callback(); }
|
fn = function (locus) { frameToLocus(locus); callback(locus); }
|
||||||
}
|
}
|
||||||
p.reader.getBook().setOrLoadPageAt(page(), locus, fn);
|
p.reader.getBook().setOrLoadPageAt(page(), locus, fn);
|
||||||
}
|
}
|
||||||
@ -2794,7 +2827,9 @@ Monocle.Dimensions.Columns = function (pageDiv) {
|
|||||||
function scrollerWidth() {
|
function scrollerWidth() {
|
||||||
var bdy = p.page.m.activeFrame.contentDocument.body;
|
var bdy = p.page.m.activeFrame.contentDocument.body;
|
||||||
if (Monocle.Browser.has.iframeDoubleWidthBug) {
|
if (Monocle.Browser.has.iframeDoubleWidthBug) {
|
||||||
if (Monocle.Browser.iOSVersion < "4.1") {
|
if (Monocle.Browser.on.Android) {
|
||||||
|
return bdy.scrollWidth * 1.5; // I actually have no idea why 1.5.
|
||||||
|
} else if (Monocle.Browser.iOSVersion < "4.1") {
|
||||||
var hbw = bdy.scrollWidth / 2;
|
var hbw = bdy.scrollWidth / 2;
|
||||||
var sew = scrollerElement().scrollWidth;
|
var sew = scrollerElement().scrollWidth;
|
||||||
return Math.max(sew, hbw);
|
return Math.max(sew, hbw);
|
||||||
@ -2969,6 +3004,7 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
|
|
||||||
|
|
||||||
function setPage(pageDiv, locus, callback) {
|
function setPage(pageDiv, locus, callback) {
|
||||||
|
ensureWaitControl();
|
||||||
p.reader.getBook().setOrLoadPageAt(
|
p.reader.getBook().setOrLoadPageAt(
|
||||||
pageDiv,
|
pageDiv,
|
||||||
locus,
|
locus,
|
||||||
@ -3048,6 +3084,7 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
checkPoint(boxPointX);
|
checkPoint(boxPointX);
|
||||||
|
|
||||||
p.turnData.releasing = true;
|
p.turnData.releasing = true;
|
||||||
|
showWaitControl(lowerPage());
|
||||||
|
|
||||||
if (dir == k.FORWARDS) {
|
if (dir == k.FORWARDS) {
|
||||||
if (
|
if (
|
||||||
@ -3088,14 +3125,18 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
|
|
||||||
|
|
||||||
function onGoingBackward(x) {
|
function onGoingBackward(x) {
|
||||||
var lp = lowerPage();
|
var lp = lowerPage(), up = upperPage();
|
||||||
|
showWaitControl(up);
|
||||||
jumpOut(lp, // move lower page off-screen
|
jumpOut(lp, // move lower page off-screen
|
||||||
function () {
|
function () {
|
||||||
flipPages(); // flip lower to upper
|
flipPages(); // flip lower to upper
|
||||||
setPage( // set upper page to previous
|
setPage( // set upper page to previous
|
||||||
lp,
|
lp,
|
||||||
getPlace(lowerPage()).getLocus({ direction: k.BACKWARDS }),
|
getPlace(lowerPage()).getLocus({ direction: k.BACKWARDS }),
|
||||||
function () { lifted(x); }
|
function () {
|
||||||
|
lifted(x);
|
||||||
|
hideWaitControl(up);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -3103,8 +3144,10 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
|
|
||||||
|
|
||||||
function afterGoingForward() {
|
function afterGoingForward() {
|
||||||
var up = upperPage();
|
var up = upperPage(), lp = lowerPage();
|
||||||
if (p.interactive) {
|
if (p.interactive) {
|
||||||
|
showWaitControl(up);
|
||||||
|
showWaitControl(lp);
|
||||||
setPage( // set upper (off screen) to current
|
setPage( // set upper (off screen) to current
|
||||||
up,
|
up,
|
||||||
getPlace().getLocus({ direction: k.FORWARDS }),
|
getPlace().getLocus({ direction: k.FORWARDS }),
|
||||||
@ -3113,6 +3156,7 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
showWaitControl(lp);
|
||||||
flipPages();
|
flipPages();
|
||||||
jumpIn(up, function () { prepareNextPage(announceTurn); });
|
jumpIn(up, function () { prepareNextPage(announceTurn); });
|
||||||
}
|
}
|
||||||
@ -3171,6 +3215,8 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
|
|
||||||
|
|
||||||
function announceTurn() {
|
function announceTurn() {
|
||||||
|
hideWaitControl(upperPage());
|
||||||
|
hideWaitControl(lowerPage());
|
||||||
p.reader.dispatchEvent('monocle:turn');
|
p.reader.dispatchEvent('monocle:turn');
|
||||||
resetTurnData();
|
resetTurnData();
|
||||||
}
|
}
|
||||||
@ -3319,12 +3365,14 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
|
|
||||||
|
|
||||||
function jumpIn(pageDiv, callback) {
|
function jumpIn(pageDiv, callback) {
|
||||||
setX(pageDiv, 0, { duration: 1 }, callback);
|
var dur = Monocle.Browser.has.jumpFlickerBug ? 1 : 0;
|
||||||
|
setX(pageDiv, 0, { duration: dur }, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function jumpOut(pageDiv, callback) {
|
function jumpOut(pageDiv, callback) {
|
||||||
setX(pageDiv, 0 - pageDiv.offsetWidth, { duration: 1 }, callback);
|
var dur = Monocle.Browser.has.jumpFlickerBug ? 1 : 0;
|
||||||
|
setX(pageDiv, 0 - pageDiv.offsetWidth, { duration: dur }, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3357,6 +3405,28 @@ Monocle.Flippers.Slider = function (reader) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ensureWaitControl() {
|
||||||
|
if (p.waitControl) { return; }
|
||||||
|
p.waitControl = {
|
||||||
|
createControlElements: function (holder) {
|
||||||
|
return holder.dom.make('div', 'flippers_slider_wait');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.reader.addControl(p.waitControl, 'page');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function showWaitControl(page) {
|
||||||
|
var ctrl = p.reader.dom.find('flippers_slider_wait', page.m.pageIndex);
|
||||||
|
ctrl.style.opacity = 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function hideWaitControl(page) {
|
||||||
|
var ctrl = p.reader.dom.find('flippers_slider_wait', page.m.pageIndex);
|
||||||
|
ctrl.style.opacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
API.pageCount = p.pageCount;
|
API.pageCount = p.pageCount;
|
||||||
API.addPage = addPage;
|
API.addPage = addPage;
|
||||||
API.getPlace = getPlace;
|
API.getPlace = getPlace;
|
||||||
|
@ -794,7 +794,7 @@ class TagBrowserMixin(object): # {{{
|
|||||||
cc_label = None
|
cc_label = None
|
||||||
if category in db.field_metadata:
|
if category in db.field_metadata:
|
||||||
cc_label = db.field_metadata[category]['label']
|
cc_label = db.field_metadata[category]['label']
|
||||||
result = self.db.get_custom_items_with_ids(label=cc_label)
|
result = db.get_custom_items_with_ids(label=cc_label)
|
||||||
else:
|
else:
|
||||||
result = []
|
result = []
|
||||||
compare = (lambda x,y:cmp(x.lower(), y.lower()))
|
compare = (lambda x,y:cmp(x.lower(), y.lower()))
|
||||||
|
@ -5,7 +5,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import operator, os, json
|
import operator, os, json, re
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
from urllib import quote, unquote
|
from urllib import quote, unquote
|
||||||
|
|
||||||
@ -401,6 +401,16 @@ class BrowseServer(object):
|
|||||||
|
|
||||||
script = 'true'
|
script = 'true'
|
||||||
|
|
||||||
|
if len(items) == 1:
|
||||||
|
# Only one item in category, go directly to book list
|
||||||
|
prefix = '' if self.is_wsgi else self.opts.url_prefix
|
||||||
|
html = get_category_items(category, items,
|
||||||
|
self.search_restriction_name, datatype,
|
||||||
|
self.opts.url_prefix)
|
||||||
|
href = re.search(r'<a href="([^"]+)"', html)
|
||||||
|
if href is not None:
|
||||||
|
raise cherrypy.HTTPRedirect(prefix+href.group(1))
|
||||||
|
|
||||||
if len(items) <= self.opts.max_opds_ungrouped_items:
|
if len(items) <= self.opts.max_opds_ungrouped_items:
|
||||||
script = 'false'
|
script = 'false'
|
||||||
items = get_category_items(category, items,
|
items = get_category_items(category, items,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user