bookreader 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.gitmodules +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bookreader.gemspec +42 -0
- data/lib/bookreader/engine.rb +6 -0
- data/lib/bookreader/version.rb +3 -0
- data/lib/bookreader.rb +8 -0
- data/vendor/assets/images/BRicons.png +0 -0
- data/vendor/assets/images/BRicons.svg +94 -0
- data/vendor/assets/images/BRicons_ia.png +0 -0
- data/vendor/assets/images/back_pages.png +0 -0
- data/vendor/assets/images/book_bottom_icon.png +0 -0
- data/vendor/assets/images/book_down_icon.png +0 -0
- data/vendor/assets/images/book_left_icon.png +0 -0
- data/vendor/assets/images/book_leftmost_icon.png +0 -0
- data/vendor/assets/images/book_right_icon.png +0 -0
- data/vendor/assets/images/book_rightmost_icon.png +0 -0
- data/vendor/assets/images/book_top_icon.png +0 -0
- data/vendor/assets/images/book_up_icon.png +0 -0
- data/vendor/assets/images/books_graphic.svg +177 -0
- data/vendor/assets/images/booksplit.png +0 -0
- data/vendor/assets/images/control_pause_icon.png +0 -0
- data/vendor/assets/images/control_play_icon.png +0 -0
- data/vendor/assets/images/embed_icon.png +0 -0
- data/vendor/assets/images/icon-home-ia.png +0 -0
- data/vendor/assets/images/icon_OL-logo-xs.png +0 -0
- data/vendor/assets/images/icon_alert-xs.png +0 -0
- data/vendor/assets/images/icon_book.svg +12 -0
- data/vendor/assets/images/icon_bookmark.svg +12 -0
- data/vendor/assets/images/icon_close-pop.png +0 -0
- data/vendor/assets/images/icon_download.png +0 -0
- data/vendor/assets/images/icon_gear.svg +17 -0
- data/vendor/assets/images/icon_hamburger.svg +20 -0
- data/vendor/assets/images/icon_home.png +0 -0
- data/vendor/assets/images/icon_home.svg +21 -0
- data/vendor/assets/images/icon_home_ia.png +0 -0
- data/vendor/assets/images/icon_indicator.png +0 -0
- data/vendor/assets/images/icon_info.svg +12 -0
- data/vendor/assets/images/icon_one_page.svg +16 -0
- data/vendor/assets/images/icon_return.png +0 -0
- data/vendor/assets/images/icon_search_button.svg +14 -0
- data/vendor/assets/images/icon_search_button_blue.svg +18 -0
- data/vendor/assets/images/icon_share.svg +17 -0
- data/vendor/assets/images/icon_speaker.svg +18 -0
- data/vendor/assets/images/icon_speaker_open.svg +26 -0
- data/vendor/assets/images/icon_thumbnails.svg +19 -0
- data/vendor/assets/images/icon_two_pages.svg +17 -0
- data/vendor/assets/images/icon_zoomer.png +0 -0
- data/vendor/assets/images/left_edges.png +0 -0
- data/vendor/assets/images/loading.gif +0 -0
- data/vendor/assets/images/logo_icon.png +0 -0
- data/vendor/assets/images/marker_chap-off.png +0 -0
- data/vendor/assets/images/marker_chap-off.svg +11 -0
- data/vendor/assets/images/marker_chap-off_ia.png +0 -0
- data/vendor/assets/images/marker_chap-on.png +0 -0
- data/vendor/assets/images/marker_chap-on.svg +11 -0
- data/vendor/assets/images/marker_srch-off.png +0 -0
- data/vendor/assets/images/marker_srch-off.svg +11 -0
- data/vendor/assets/images/marker_srch-on.png +0 -0
- data/vendor/assets/images/marker_srch-on.svg +11 -0
- data/vendor/assets/images/marker_srchchap-off.png +0 -0
- data/vendor/assets/images/marker_srchchap-on.png +0 -0
- data/vendor/assets/images/nav_control-dn.png +0 -0
- data/vendor/assets/images/nav_control-dn_ia.png +0 -0
- data/vendor/assets/images/nav_control-up.png +0 -0
- data/vendor/assets/images/nav_control-up_ia.png +0 -0
- data/vendor/assets/images/nav_control.png +0 -0
- data/vendor/assets/images/one_page_mode_icon.png +0 -0
- data/vendor/assets/images/paper-badge.png +0 -0
- data/vendor/assets/images/print_icon.png +0 -0
- data/vendor/assets/images/progressbar.gif +0 -0
- data/vendor/assets/images/right_edges.png +0 -0
- data/vendor/assets/images/slider.png +0 -0
- data/vendor/assets/images/slider_ia.png +0 -0
- data/vendor/assets/images/thumbnail_mode_icon.png +0 -0
- data/vendor/assets/images/transparent.png +0 -0
- data/vendor/assets/images/two_page_mode_icon.png +0 -0
- data/vendor/assets/images/zoom_in_icon.png +0 -0
- data/vendor/assets/images/zoom_out_icon.png +0 -0
- data/vendor/assets/javascripts/BookReader.js +4849 -0
- data/vendor/assets/javascripts/BookReaderJSAdvanced.js +115 -0
- data/vendor/assets/javascripts/BookReaderJSSimple.js +56 -0
- data/vendor/assets/javascripts/IIIFBookReader.js +207 -0
- data/vendor/assets/javascripts/demo-iiif.js +26 -0
- data/vendor/assets/javascripts/dragscrollable-br.js +261 -0
- data/vendor/assets/javascripts/excanvas.compiled.js +35 -0
- data/vendor/assets/javascripts/jquery-1.10.1.js +9807 -0
- data/vendor/assets/javascripts/jquery-ui-1.12.0.min.js +18686 -0
- data/vendor/assets/javascripts/jquery.browser.min.js +14 -0
- data/vendor/assets/javascripts/jquery.bt.min.js +8 -0
- data/vendor/assets/javascripts/jquery.colorbox-min.js +6 -0
- data/vendor/assets/javascripts/jquery.ui.touch-punch.min.js +11 -0
- data/vendor/assets/javascripts/mmenu/dist/addons/navbars/jquery.mmenu.navbars.min.js +43 -0
- data/vendor/assets/javascripts/mmenu/dist/addons/offcanvas/jquery.mmenu.offcanvas.min.js +7 -0
- data/vendor/assets/javascripts/mmenu/dist/addons/screenreader/jquery.mmenu.screenreader.min.js +7 -0
- data/vendor/assets/javascripts/mmenu/dist/addons/searchfield/jquery.mmenu.searchfield.min.js +7 -0
- data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.all.min.js +151 -0
- data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.all.min.umd.js +162 -0
- data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.min.js +25 -0
- data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.min.umd.js +36 -0
- data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.oncanvas.min.js +13 -0
- data/vendor/assets/javascripts/mmenu/jquery.mmenu.searchfield.js +510 -0
- data/vendor/assets/javascripts/plugins/plugin.archive_analytics.js +67 -0
- data/vendor/assets/javascripts/plugins/plugin.chapters.js +197 -0
- data/vendor/assets/javascripts/plugins/plugin.iframe.js +73 -0
- data/vendor/assets/javascripts/plugins/plugin.mobile_nav.js +197 -0
- data/vendor/assets/javascripts/plugins/plugin.print.js +70 -0
- data/vendor/assets/javascripts/plugins/plugin.resume.js +73 -0
- data/vendor/assets/javascripts/plugins/plugin.search.js +523 -0
- data/vendor/assets/javascripts/plugins/plugin.themes.js +49 -0
- data/vendor/assets/javascripts/plugins/plugin.tts.js +523 -0
- data/vendor/assets/javascripts/plugins/plugin.url.js +168 -0
- data/vendor/assets/javascripts/soundmanager/license.txt +29 -0
- data/vendor/assets/javascripts/soundmanager/script/soundmanager2-jsmin.js +113 -0
- data/vendor/assets/javascripts/soundmanager/script/soundmanager2-nodebug-jsmin.js +83 -0
- data/vendor/assets/javascripts/soundmanager/script/soundmanager2-nodebug.js +2765 -0
- data/vendor/assets/javascripts/soundmanager/script/soundmanager2.js +6325 -0
- data/vendor/assets/javascripts/soundmanager/swf/soundmanager2.swf +0 -0
- data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_debug.swf +0 -0
- data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_flash9.swf +0 -0
- data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_flash9_debug.swf +0 -0
- data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_flash_xdomain.zip +0 -0
- data/vendor/assets/stylesheets/BookReader.css +1887 -0
- data/vendor/assets/stylesheets/BookReaderDemo.css +18 -0
- data/vendor/assets/stylesheets/BookReaderEmbed.css +0 -0
- data/vendor/assets/stylesheets/demo.css +0 -0
- data/vendor/assets/stylesheets/dist/addons/navbars/jquery.mmenu.navbars.css +29 -0
- data/vendor/assets/stylesheets/dist/addons/offcanvas/jquery.mmenu.offcanvas.css +14 -0
- data/vendor/assets/stylesheets/dist/addons/screenreader/jquery.mmenu.screenreader.css +1 -0
- data/vendor/assets/stylesheets/dist/addons/searchfield/jquery.mmenu.searchfield.css +16 -0
- data/vendor/assets/stylesheets/dist/css/jquery.mmenu.all.css +413 -0
- data/vendor/assets/stylesheets/dist/css/jquery.mmenu.css +80 -0
- data/vendor/assets/stylesheets/dist/css/jquery.mmenu.oncanvas.css +66 -0
- metadata +226 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin for chapter markers in BookReader. Fetches from openlibrary.org
|
|
3
|
+
* Could be forked, or extended to alter behavior
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
jQuery.extend(BookReader.defaultOptions, {
|
|
7
|
+
olHost: 'https://openlibrary.org',
|
|
8
|
+
enableChaptersPlugin: true,
|
|
9
|
+
bookId: '',
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// Extend the constructor to add search properties
|
|
13
|
+
BookReader.prototype.setup = (function (super_) {
|
|
14
|
+
return function (options) {
|
|
15
|
+
super_.call(this, options);
|
|
16
|
+
|
|
17
|
+
this.olHost = options.olHost;
|
|
18
|
+
this.enableChaptersPlugin = options.enableChaptersPlugin;
|
|
19
|
+
this.bookId = options.bookId;
|
|
20
|
+
};
|
|
21
|
+
})(BookReader.prototype.setup);
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
// Extend br.init to call Open Library for TOC
|
|
25
|
+
BookReader.prototype.init = (function(super_) {
|
|
26
|
+
return function() {
|
|
27
|
+
super_.call(this);
|
|
28
|
+
|
|
29
|
+
if (this.enableChaptersPlugin && this.ui !== 'embed') {
|
|
30
|
+
this.getOpenLibraryRecord(this.gotOpenLibraryRecord);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
})(BookReader.prototype.init);
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
BookReader.prototype.addChapter = function(chapterTitle, pageNumber, pageIndex) {
|
|
37
|
+
var uiStringPage = 'Page'; // i18n
|
|
38
|
+
var self = this;
|
|
39
|
+
|
|
40
|
+
var percentThrough = BookReader.util.cssPercentage(pageIndex, this.getNumLeafs() - 1);
|
|
41
|
+
|
|
42
|
+
$('<div>'
|
|
43
|
+
+ '<div>'
|
|
44
|
+
+ 'Chapter: '
|
|
45
|
+
+ chapterTitle
|
|
46
|
+
+ ' | '
|
|
47
|
+
+ uiStringPage
|
|
48
|
+
+ ' '
|
|
49
|
+
+ pageNumber
|
|
50
|
+
+ '</div>'
|
|
51
|
+
+ '</div>'
|
|
52
|
+
)
|
|
53
|
+
.addClass('BRchapter')
|
|
54
|
+
.css({
|
|
55
|
+
left: percentThrough,
|
|
56
|
+
})
|
|
57
|
+
.appendTo(this.$('.BRnavline'))
|
|
58
|
+
.data({'self': this, 'pageIndex': pageIndex })
|
|
59
|
+
.bt({
|
|
60
|
+
contentSelector: '$(this).find("> div")',
|
|
61
|
+
trigger: 'hover',
|
|
62
|
+
closeWhenOthersOpen: true,
|
|
63
|
+
cssStyles: {
|
|
64
|
+
padding: '12px 14px',
|
|
65
|
+
backgroundColor: '#fff',
|
|
66
|
+
border: '4px solid rgb(216,216,216)',
|
|
67
|
+
color: 'rgb(52,52,52)'
|
|
68
|
+
},
|
|
69
|
+
shrinkToFit: false,
|
|
70
|
+
width: '230px',
|
|
71
|
+
padding: 0,
|
|
72
|
+
spikeGirth: 0,
|
|
73
|
+
spikeLength: 0,
|
|
74
|
+
overlap: '0px',
|
|
75
|
+
overlay: false,
|
|
76
|
+
killTitle: false,
|
|
77
|
+
offsetParent: null,
|
|
78
|
+
positions: ['top'],
|
|
79
|
+
fill: 'white',
|
|
80
|
+
windowMargin: 10,
|
|
81
|
+
strokeWidth: 0,
|
|
82
|
+
cornerRadius: 0,
|
|
83
|
+
centerPointX: 0,
|
|
84
|
+
centerPointY: 0,
|
|
85
|
+
shadow: false
|
|
86
|
+
})
|
|
87
|
+
.hover(
|
|
88
|
+
function() {
|
|
89
|
+
// remove hover effect from other markers then turn on just for this
|
|
90
|
+
self.$('.BRsearch,.BRchapter').removeClass('front');
|
|
91
|
+
$(this).addClass('front');
|
|
92
|
+
},
|
|
93
|
+
function() {
|
|
94
|
+
$(this).removeClass('front');
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
.bind('click', function() {
|
|
98
|
+
self.jumpToIndex($(this).data('pageIndex'));
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* Remove all chapters.
|
|
104
|
+
*/
|
|
105
|
+
BookReader.prototype.removeChapters = function() {
|
|
106
|
+
this.$('.BRnavpos .BRchapter').remove();
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* Update the table of contents based on array of TOC entries.
|
|
111
|
+
*/
|
|
112
|
+
BookReader.prototype.updateTOC = function(tocEntries) {
|
|
113
|
+
this.removeChapters();
|
|
114
|
+
for (var i = 0; i < tocEntries.length; i++) {
|
|
115
|
+
this.addChapterFromEntry(tocEntries[i]);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* Example table of contents entry - this format is defined by Open Library
|
|
121
|
+
* {
|
|
122
|
+
* "pagenum": "17",
|
|
123
|
+
* "level": 1,
|
|
124
|
+
* "label": "CHAPTER I",
|
|
125
|
+
* "type": {"key": "/type/toc_item"},
|
|
126
|
+
* "title": "THE COUNTRY AND THE MISSION"
|
|
127
|
+
* }
|
|
128
|
+
*/
|
|
129
|
+
BookReader.prototype.addChapterFromEntry = function(tocEntryObject) {
|
|
130
|
+
var pageIndex = this.getPageIndex(tocEntryObject['pagenum']);
|
|
131
|
+
// Only add if we know where it is
|
|
132
|
+
if (pageIndex) {
|
|
133
|
+
this.addChapter(tocEntryObject['title'], tocEntryObject['pagenum'], pageIndex);
|
|
134
|
+
}
|
|
135
|
+
this.$('.BRchapter').each(function(){
|
|
136
|
+
$(this).hover(function(){
|
|
137
|
+
$(this).addClass('front');
|
|
138
|
+
},function(){
|
|
139
|
+
$(this).removeClass('front');
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
this.$('.BRsearch').each(function(){
|
|
143
|
+
$(this).hover(function(){
|
|
144
|
+
$(this).addClass('front');
|
|
145
|
+
},function(){
|
|
146
|
+
$(this).removeClass('front');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// getOpenLibraryRecord
|
|
152
|
+
//
|
|
153
|
+
// The bookreader is designed to call openlibrary API and constructs the
|
|
154
|
+
// "Return book" button using the response.
|
|
155
|
+
//
|
|
156
|
+
// This makes a call to OL API and calls the given callback function with the
|
|
157
|
+
// response from the API.
|
|
158
|
+
BookReader.prototype.getOpenLibraryRecord = function(callback) {
|
|
159
|
+
// Try looking up by ocaid first, then by source_record
|
|
160
|
+
var self = this; // closure
|
|
161
|
+
var jsonURL = self.olHost + '/query.json?type=/type/edition&*=&ocaid=' + self.bookId;
|
|
162
|
+
$.ajax({
|
|
163
|
+
url: jsonURL,
|
|
164
|
+
success: function(data) {
|
|
165
|
+
if (data && data.length > 0) {
|
|
166
|
+
callback(self, data[0]);
|
|
167
|
+
} else {
|
|
168
|
+
// try sourceid
|
|
169
|
+
jsonURL = self.olHost + '/query.json?type=/type/edition&*=&source_records=ia:' + self.bookId;
|
|
170
|
+
$.ajax({
|
|
171
|
+
url: jsonURL,
|
|
172
|
+
success: function(data) {
|
|
173
|
+
if (data && data.length > 0) {
|
|
174
|
+
callback(self, data[0]);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
dataType: 'jsonp'
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
dataType: 'jsonp'
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Update based on received record from Open Library.
|
|
187
|
+
* Open Library record is used for extra metadata, and also for lending
|
|
188
|
+
*/
|
|
189
|
+
BookReader.prototype.gotOpenLibraryRecord = function(self, olObject) {
|
|
190
|
+
// $$$ could refactor this so that 'this' is available
|
|
191
|
+
if (olObject) {
|
|
192
|
+
if (olObject.table_of_contents) {
|
|
193
|
+
// XXX check here that TOC is valid
|
|
194
|
+
self.updateTOC(olObject.table_of_contents);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin for two-way communication between a BookReader in an IFrame and the
|
|
3
|
+
* parent web page
|
|
4
|
+
*/
|
|
5
|
+
(function setUpIframePlugin() {
|
|
6
|
+
var constMessageTypeFragmentChange = 'bookReaderFragmentChange';
|
|
7
|
+
|
|
8
|
+
BookReader.prototype.init = (function(super_) {
|
|
9
|
+
return function() {
|
|
10
|
+
super_.call(this);
|
|
11
|
+
attachEventListeners(this);
|
|
12
|
+
};
|
|
13
|
+
})(BookReader.prototype.init);
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Using window.postMessage() and event listeners, the plugin notifies the
|
|
17
|
+
* parent window when pages change, and the parent window can also
|
|
18
|
+
* explicitly request a page change by sending its own message.
|
|
19
|
+
*
|
|
20
|
+
* @param {BookReader} br
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
function attachEventListeners(br) {
|
|
24
|
+
// Not embedded, abort
|
|
25
|
+
if (!window.parent) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
br.bind(BookReader.eventNames.fragmentChange, function() {
|
|
30
|
+
var fragment = br.fragmentFromParams(br.paramsFromCurrent());
|
|
31
|
+
|
|
32
|
+
window.parent.postMessage(
|
|
33
|
+
createWindowMessage(constMessageTypeFragmentChange, {
|
|
34
|
+
fragment: fragment
|
|
35
|
+
}),
|
|
36
|
+
'*'
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
window.addEventListener('message', function updatePath(event) {
|
|
41
|
+
// Not a recognized message type, abort
|
|
42
|
+
if (
|
|
43
|
+
!event.data ||
|
|
44
|
+
event.data.type !== constMessageTypeFragmentChange
|
|
45
|
+
) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
br.updateFromParams(br.paramsFromFragment(event.data.fragment));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Create a message that can be sent to the parent window via
|
|
55
|
+
* window.postMessage()
|
|
56
|
+
*
|
|
57
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
|
|
58
|
+
*
|
|
59
|
+
* @param {String} type
|
|
60
|
+
* @param {Object} props
|
|
61
|
+
* @returns {Object}
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
function createWindowMessage(type, props) {
|
|
65
|
+
const message = { type };
|
|
66
|
+
|
|
67
|
+
Object.keys(props).forEach(function(prop) {
|
|
68
|
+
message[prop] = props[prop]
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return message;
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds mobile navigation at responsive breakpoint
|
|
3
|
+
* NOTE additional script and style tags must be included.
|
|
4
|
+
*
|
|
5
|
+
* <script src="../BookReader/mmenu/dist/js/jquery.mmenu.min.js"></script>
|
|
6
|
+
* <script src="../BookReader/mmenu/dist/addons/navbars/jquery.mmenu.navbars.min.js"></script>
|
|
7
|
+
* <link rel="stylesheet" href="../BookReader/mmenu/dist/css/jquery.mmenu.css" />
|
|
8
|
+
* <link rel="stylesheet" href="../BookReader/mmenu/dist/addons/navbars/jquery.mmenu.navbars.css" />
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
jQuery.extend(BookReader.defaultOptions, {
|
|
12
|
+
enableMobileNav: true,
|
|
13
|
+
mobileNavTitle: 'Internet Archive',
|
|
14
|
+
mobileNavFullscreenOnly: false,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
BookReader.prototype.setup = (function(super_) {
|
|
18
|
+
return function (options) {
|
|
19
|
+
super_.call(this, options);
|
|
20
|
+
|
|
21
|
+
this.enableMobileNav = options.enableMobileNav;
|
|
22
|
+
this.mobileNavTitle = options.mobileNavTitle;
|
|
23
|
+
this.mobileNavFullscreenOnly = options.mobileNavFullscreenOnly;
|
|
24
|
+
|
|
25
|
+
this.refs.$mmenu = null;
|
|
26
|
+
};
|
|
27
|
+
})(BookReader.prototype.setup);
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
// Extend initToolbar
|
|
31
|
+
BookReader.prototype.initToolbar = (function (super_) {
|
|
32
|
+
return function (mode, ui) {
|
|
33
|
+
var self = this;
|
|
34
|
+
|
|
35
|
+
if (this.enableMobileNav) {
|
|
36
|
+
var $drawerEl = this.buildMobileDrawerElement();
|
|
37
|
+
this.refs.$br.append($drawerEl);
|
|
38
|
+
|
|
39
|
+
// Render info into mobile info before mmenu
|
|
40
|
+
this.buildInfoDiv(this.$('.BRmobileInfo'));
|
|
41
|
+
this.buildShareDiv(this.$('.BRmobileShare'));
|
|
42
|
+
|
|
43
|
+
var $mmenuEl = $drawerEl;
|
|
44
|
+
$mmenuEl.mmenu({
|
|
45
|
+
navbars: [
|
|
46
|
+
{ "position": "top" },
|
|
47
|
+
],
|
|
48
|
+
navbar: {
|
|
49
|
+
add: true,
|
|
50
|
+
title: this.mobileNavTitle,
|
|
51
|
+
titleLink: 'panel'
|
|
52
|
+
},
|
|
53
|
+
extensions: [ "panelshadow" ],
|
|
54
|
+
}, {
|
|
55
|
+
offCanvas: {
|
|
56
|
+
wrapPageIfNeeded: false,
|
|
57
|
+
zposition: 'next',
|
|
58
|
+
pageSelector: this.el,
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
var $BRpageviewField = $mmenuEl.find('.BRpageviewValue');
|
|
63
|
+
$mmenuEl.data('mmenu').bind('opened', function() {
|
|
64
|
+
// Update "Link to this page view" link
|
|
65
|
+
if ($BRpageviewField.length)
|
|
66
|
+
$BRpageviewField.val(window.location.href);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// High contrast button
|
|
70
|
+
$drawerEl.find('.high-contrast-button').click(function() {
|
|
71
|
+
self.refs.$br.toggleClass('high-contrast');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Bind mobile switch buttons
|
|
75
|
+
$drawerEl.find('.DrawerLayoutButton.one_page_mode').click(function() {
|
|
76
|
+
self.switchMode(self.constMode1up);
|
|
77
|
+
});
|
|
78
|
+
$drawerEl.find('.DrawerLayoutButton.two_page_mode').click(function() {
|
|
79
|
+
self.switchMode(self.constMode2up);
|
|
80
|
+
});
|
|
81
|
+
$drawerEl.find('.DrawerLayoutButton.thumbnail_mode').click(function() {
|
|
82
|
+
self.switchMode(self.constModeThumb);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (this.mobileNavFullscreenOnly) {
|
|
86
|
+
$(document.body).addClass('BRbodyMobileNavEnabledFullscreen');
|
|
87
|
+
} else {
|
|
88
|
+
$(document.body).addClass('BRbodyMobileNavEnabled');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
this.refs.$mmenu = $mmenuEl;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Call the parent method at the end, because it binds events to DOM
|
|
95
|
+
super_.apply(this, arguments);
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if (this.enableMobileNav) {
|
|
99
|
+
// Need to bind more, console after toolbar is initialized
|
|
100
|
+
this.$('.BRmobileHamburger').click(function() {
|
|
101
|
+
if ($mmenuEl.data('mmenu').getInstance().vars.opened) {
|
|
102
|
+
$mmenuEl.data('mmenu').close();
|
|
103
|
+
} else {
|
|
104
|
+
$mmenuEl.data('mmenu').open();
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
})(BookReader.prototype.initToolbar);
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
BookReader.prototype.buildToolbarElement = (function (super_) {
|
|
113
|
+
return function () {
|
|
114
|
+
var $el = super_.call(this);
|
|
115
|
+
if (this.enableMobileNav) {
|
|
116
|
+
var escapedTitle = BookReader.util.escapeHTML(this.bookTitle);
|
|
117
|
+
$el
|
|
118
|
+
.addClass('responsive')
|
|
119
|
+
.prepend($(
|
|
120
|
+
"<span class='BRmobileHamburgerWrapper'>"
|
|
121
|
+
+ "<button class=\"BRmobileHamburger\"></button>"
|
|
122
|
+
+ "<span class=\"BRtoolbarMobileTitle\" title=\""+escapedTitle+"\">" + this.bookTitle + "</span>"
|
|
123
|
+
+ "</span>"
|
|
124
|
+
));
|
|
125
|
+
}
|
|
126
|
+
return $el;
|
|
127
|
+
};
|
|
128
|
+
})(BookReader.prototype.buildToolbarElement);
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* This method builds the html for the mobile drawer. It can be decorated to
|
|
132
|
+
* extend the default drawer.
|
|
133
|
+
* @return {jqueryElement}
|
|
134
|
+
*/
|
|
135
|
+
BookReader.prototype.buildMobileDrawerElement = function() {
|
|
136
|
+
var experimentalHtml = '';
|
|
137
|
+
if (this.enableExperimentalControls) {
|
|
138
|
+
experimentalHtml += "<div class=\"DrawerSettingsTitle\">Experimental (may not work)</div>"
|
|
139
|
+
+" <button class='BRaction default high-contrast-button'>Toggle high contrast</button>";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var $el = $(
|
|
143
|
+
"<nav id=\"BRmobileMenu\" class=\"BRmobileMenu\">"
|
|
144
|
+
+" <ul>"
|
|
145
|
+
+" <li>"
|
|
146
|
+
+" <span>"
|
|
147
|
+
+" <span class=\"DrawerIconWrapper \"><img class=\"DrawerIcon\" src=\""+this.imagesBaseURL+"icon_gear.svg\" alt=\"settings-icon\"/></span>"
|
|
148
|
+
+" Settings"
|
|
149
|
+
+" </span>"
|
|
150
|
+
+" <div class=\"DrawerSettingsWrapper\">"
|
|
151
|
+
+" <div class=\"DrawerSettingsTitle\">Page Layout</div>"
|
|
152
|
+
+" <div class=\"DrawerSettingsLayoutWrapper\">"
|
|
153
|
+
+" <button class=\"DrawerLayoutButton one_page_mode\"><img class=\"\" src=\""+this.imagesBaseURL+"icon_one_page.svg\" alt=\"Single Page\"/><br>One Page</button>"
|
|
154
|
+
+" <button class=\"DrawerLayoutButton two_page_mode TwoPagesButton\"><img class=\"\" src=\""+this.imagesBaseURL+"icon_two_pages.svg\" alt=\"Two Pages\"/><br>Two Pages</button>"
|
|
155
|
+
+" <button class=\"DrawerLayoutButton thumbnail_mode\"><img class=\"\" src=\""+this.imagesBaseURL+"icon_thumbnails.svg\" alt=\"Thumbnails\"/><br>Thumbnails</button>"
|
|
156
|
+
+" </div>"
|
|
157
|
+
+" <br>"
|
|
158
|
+
+" <div class=\"DrawerSettingsTitle\">Zoom</div>"
|
|
159
|
+
+" <button class='BRicon zoom_out'></button>"
|
|
160
|
+
+" <button class='BRicon zoom_in'></button>"
|
|
161
|
+
+" <br style='clear:both'><br><br>"
|
|
162
|
+
+ experimentalHtml
|
|
163
|
+
+" </div>"
|
|
164
|
+
+" </li>"
|
|
165
|
+
+" <li class='BRmobileMenu__moreInfoRow'>"
|
|
166
|
+
+" <span>"
|
|
167
|
+
+" <span class=\"DrawerIconWrapper \"><img class=\"DrawerIcon\" src=\""+this.imagesBaseURL+"icon_info.svg\" alt=\"info-icon\"/></span>"
|
|
168
|
+
+" About This Book"
|
|
169
|
+
+" </span>"
|
|
170
|
+
+" <div class=\"BRmobileInfo\"></div>"
|
|
171
|
+
+" </li>"
|
|
172
|
+
+" <li>"
|
|
173
|
+
+" <span>"
|
|
174
|
+
+" <span class=\"DrawerIconWrapper \"><img class=\"DrawerIcon\" src=\""+this.imagesBaseURL+"icon_share.svg\" alt=\"info-share\"/></span>"
|
|
175
|
+
+" Share This Book"
|
|
176
|
+
+" </span>"
|
|
177
|
+
+" <div class=\"BRmobileShare\"></div>"
|
|
178
|
+
+" </li>"
|
|
179
|
+
+" </ul>"
|
|
180
|
+
+"</nav>"
|
|
181
|
+
);
|
|
182
|
+
return $el;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Mmenu moves itself out side of the root BookReader element, so we need to
|
|
187
|
+
* include it in the scoped $ function.
|
|
188
|
+
*/
|
|
189
|
+
BookReader.prototype.$ = (function (super_) {
|
|
190
|
+
return function (arg) {
|
|
191
|
+
var $results = super_.call(this, arg);
|
|
192
|
+
if (this.refs.$mmenu) {
|
|
193
|
+
$results = $results.add(this.refs.$mmenu.find(arg));
|
|
194
|
+
}
|
|
195
|
+
return $results;
|
|
196
|
+
};
|
|
197
|
+
})(BookReader.prototype.$);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds some print features to bookreader
|
|
3
|
+
*
|
|
4
|
+
* To bind it to a button, use code like this:
|
|
5
|
+
* jIcons.filter('.print').click(function(e) {
|
|
6
|
+
* self.printPage();
|
|
7
|
+
* return false;
|
|
8
|
+
* });
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
jQuery.extend(BookReader.defaultOptions, {
|
|
12
|
+
imageFormat: 'jp2',
|
|
13
|
+
subPrefix: '',
|
|
14
|
+
server: '',
|
|
15
|
+
zip: '',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Extend the constructor to add search properties
|
|
19
|
+
BookReader.prototype.setup = (function (super_) {
|
|
20
|
+
return function (options) {
|
|
21
|
+
super_.call(this, options);
|
|
22
|
+
|
|
23
|
+
this.imageFormat = options.imageFormat;
|
|
24
|
+
this.subPrefix = options.subPrefix;
|
|
25
|
+
this.server = options.server;
|
|
26
|
+
this.zip = options.zip;
|
|
27
|
+
};
|
|
28
|
+
})(BookReader.prototype.setup);
|
|
29
|
+
|
|
30
|
+
//______________________________________________________________________________
|
|
31
|
+
BookReader.prototype.printPage = function() {
|
|
32
|
+
window.open(this.getPrintURI(), 'printpage', 'width=400, height=500, resizable=yes, scrollbars=no, toolbar=no, location=no');
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Get print URI from current indices and mode
|
|
36
|
+
BookReader.prototype.getPrintURI = function() {
|
|
37
|
+
var indexToPrint;
|
|
38
|
+
if (this.constMode2up == this.mode) {
|
|
39
|
+
indexToPrint = this.twoPage.currentIndexL;
|
|
40
|
+
} else {
|
|
41
|
+
indexToPrint = this.firstIndex; // $$$ the index in the middle of the viewport would make more sense
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var options = 'id=' + this.subPrefix + '&server=' + this.server + '&zip=' + this.zip
|
|
45
|
+
+ '&format=' + this.imageFormat + '&file=' + this.getPageFile(indexToPrint)
|
|
46
|
+
+ '&width=' + this._getPageWidth(indexToPrint) + '&height=' + this._getPageHeight(indexToPrint);
|
|
47
|
+
|
|
48
|
+
if (this.constMode2up == this.mode) {
|
|
49
|
+
options += '&file2=' + this.getPageFile(this.twoPage.currentIndexR) + '&width2=' + this._getPageWidth(this.twoPage.currentIndexR);
|
|
50
|
+
options += '&height2=' + this._getPageHeight(this.twoPage.currentIndexR);
|
|
51
|
+
options += '&title=' + encodeURIComponent(this.shortTitle(50) + ' - Pages ' + this.getPageNum(this.twoPage.currentIndexL) + ', ' + this.getPageNum(this.twoPage.currentIndexR));
|
|
52
|
+
} else {
|
|
53
|
+
options += '&title=' + encodeURIComponent(this.shortTitle(50) + ' - Page ' + this.getPageNum(indexToPrint));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return '/bookreader/print.php?' + options;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
BookReader.prototype.getPageFile = function(index) {
|
|
60
|
+
if (index === null) {
|
|
61
|
+
return '';
|
|
62
|
+
}
|
|
63
|
+
var leafStr = '0000';
|
|
64
|
+
var imgStr = String(index); //String(this._leafMap[index]); // if index != leafNum
|
|
65
|
+
var re = new RegExp("0{"+imgStr.length+"}$");
|
|
66
|
+
var insideZipPrefix = this.subPrefix.match('[^/]+$');
|
|
67
|
+
var file = insideZipPrefix + '_' + this.imageFormat + '/' + insideZipPrefix +
|
|
68
|
+
'_' + leafStr.replace(re, imgStr) + '.' + this.imageFormat;
|
|
69
|
+
return file;
|
|
70
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin to remember the current page in a cookie
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
jQuery.extend(BookReader.defaultOptions, {
|
|
6
|
+
enablePageResume: true,
|
|
7
|
+
/**
|
|
8
|
+
* @var null|string eg '/', '/details/id'
|
|
9
|
+
*/
|
|
10
|
+
resumeCookiePath: null,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
BookReader.prototype.init = (function(super_) {
|
|
14
|
+
return function() {
|
|
15
|
+
super_.call(this);
|
|
16
|
+
if (this.options.enablePageResume) {
|
|
17
|
+
this.bind(BookReader.eventNames.fragmentChange, function() {
|
|
18
|
+
var params = this.paramsFromCurrent();
|
|
19
|
+
this.updateResumeValue(params.index);
|
|
20
|
+
}.bind(this));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
})(BookReader.prototype.init);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get's the page resume value, for remembering reader's page
|
|
27
|
+
* Can be overriden for different implementation
|
|
28
|
+
* @return {Number|null}
|
|
29
|
+
*/
|
|
30
|
+
BookReader.prototype.getResumeValue = function() {
|
|
31
|
+
var val = BookReader.docCookies.getItem('br-resume');
|
|
32
|
+
if (val !== null) return parseInt(val);
|
|
33
|
+
else return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Set's the page resume value, for remembering reader's page
|
|
38
|
+
* Can be overriden for different implementation
|
|
39
|
+
* @param {Number} the leaf index
|
|
40
|
+
*/
|
|
41
|
+
BookReader.prototype.updateResumeValue = function(index, cookieName) {
|
|
42
|
+
var ttl = new Date(+new Date + 12096e5); // 2 weeks
|
|
43
|
+
var path = this.options.resumeCookiePath || window.location.pathname;
|
|
44
|
+
cookieName = cookieName || 'br-resume';
|
|
45
|
+
BookReader.docCookies.setItem(cookieName, index, ttl, path, null, false);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/*\
|
|
49
|
+
|*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
|
|
50
|
+
|*| https://developer.mozilla.org/User:fusionchess
|
|
51
|
+
|*| https://github.com/madmurphy/cookies.js
|
|
52
|
+
|*| This framework is released under the GNU Public License, version 3 or later.
|
|
53
|
+
|*| http://www.gnu.org/licenses/gpl-3.0-standalone.html
|
|
54
|
+
\*/
|
|
55
|
+
BookReader.docCookies = {
|
|
56
|
+
getItem: function (sKey) {
|
|
57
|
+
if (!sKey) { return null; }
|
|
58
|
+
return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
|
|
59
|
+
},
|
|
60
|
+
setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
|
|
61
|
+
var sExpires = "";
|
|
62
|
+
if (vEnd) {
|
|
63
|
+
sExpires = "; expires=" + vEnd.toUTCString();
|
|
64
|
+
}
|
|
65
|
+
document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
|
|
66
|
+
return true;
|
|
67
|
+
},
|
|
68
|
+
removeItem: function (sKey, sPath, sDomain) {
|
|
69
|
+
if (!this.hasItem(sKey)) { return false; }
|
|
70
|
+
document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
|
|
71
|
+
return true;
|
|
72
|
+
},
|
|
73
|
+
};
|