diff --git a/resources/content_server/browse/browse.css b/resources/content_server/browse/browse.css
index 80f71db55e..92ed4c3ce6 100644
--- a/resources/content_server/browse/browse.css
+++ b/resources/content_server/browse/browse.css
@@ -417,12 +417,12 @@ h2.library_name {
margin-bottom: 2ex;
}
-#book_details_dialog .details a {
+.details .right .formats a {
color: blue;
text-decoration: none;
}
-#book_details_dialog .details a:hover {
+.details .right .formats a:hover {
color: red;
}
diff --git a/resources/content_server/browse/browse.js b/resources/content_server/browse/browse.js
index b19b1c0804..29b84ac2d7 100644
--- a/resources/content_server/browse/browse.js
+++ b/resources/content_server/browse/browse.js
@@ -235,8 +235,10 @@ function load_page(elem) {
elem.show();
}
+function hidesort() {$("#content > .sort_select").hide();}
+
function booklist(hide_sort) {
- if (hide_sort) $("#content > .sort_select").hide();
+ if (hide_sort) hidesort();
var test = $("#booklist #page0").html();
if (!test) {
$("#booklist").html(render_error("No books found"));
@@ -275,3 +277,13 @@ function show_details(a_dom) {
}
// }}}
+
+function book() {
+ hidesort();
+ $('.details .left img').load(function() {
+ var img = $('.details .left img');
+ var height = $('#main').height();
+ height = Math.max(height, img.height() + 100);
+ $('#main').height(height);
+ });
+}
diff --git a/resources/content_server/browse/summary.html b/resources/content_server/browse/summary.html
index 4e9c9d2a77..de175d3b53 100644
--- a/resources/content_server/browse/summary.html
+++ b/resources/content_server/browse/summary.html
@@ -8,6 +8,7 @@
{stars}
{series}
{details}
+ {permalink}
{title}
{authors}
diff --git a/src/calibre/library/server/browse.py b/src/calibre/library/server/browse.py
index 7331442934..247e6945e6 100644
--- a/src/calibre/library/server/browse.py
+++ b/src/calibre/library/server/browse.py
@@ -197,6 +197,8 @@ class BrowseServer(object):
self.browse_search)
connect('browse_details', base_href+'/details/{id}',
self.browse_details)
+ connect('browse_book', base_href+'/book/{id}',
+ self.browse_book)
connect('browse_category_icon', base_href+'/icon/{name}',
self.browse_icon)
@@ -589,23 +591,19 @@ class BrowseServer(object):
args['series'] = args['series']
args['details'] = xml(_('Details'), True)
args['details_tt'] = xml(_('Show book details'), True)
+ args['permalink'] = xml(_('Permalink'), True)
+ args['permalink_tt'] = xml(_('A permanent link to this book'), True)
summs.append(self.browse_summary_template.format(**args))
return json.dumps('\n'.join(summs), ensure_ascii=False)
- @Endpoint(mimetype='application/json; charset=utf-8')
- def browse_details(self, id=None):
- try:
- id_ = int(id)
- except:
- raise cherrypy.HTTPError(404, 'invalid id: %r'%id)
-
+ def browse_render_details(self, id_):
try:
mi = self.db.get_metadata(id_, index_is_id=True)
except:
- ans = _('This book has been deleted')
+ return _('This book has been deleted')
else:
args, fmt, fmts, fname = self.browse_get_book_args(mi, id_)
args['formats'] = ''
@@ -646,13 +644,34 @@ class BrowseServer(object):
u'') % (xml(c[0]),
c[1]) for c in comments]
comments = u''%('\n\n'.join(comments))
- ans = self.browse_details_template.format(id=id_,
+
+ return self.browse_details_template.format(id=id_,
title=xml(mi.title, True), fields=fields,
formats=args['formats'], comments=comments)
+ @Endpoint(mimetype='application/json; charset=utf-8')
+ def browse_details(self, id=None):
+ try:
+ id_ = int(id)
+ except:
+ raise cherrypy.HTTPError(404, 'invalid id: %r'%id)
+
+ ans = self.browse_render_details(id_)
+
return json.dumps(ans, ensure_ascii=False)
+ @Endpoint()
+ def browse_book(self, id=None, category_sort=None):
+ try:
+ id_ = int(id)
+ except:
+ raise cherrypy.HTTPError(404, 'invalid id: %r'%id)
+
+ ans = self.browse_render_details(id_)
+ return self.browse_template('').format(
+ title='', script='book();', main=ans)
+
# }}}