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.
Files changed (142) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +43 -0
  9. data/Rakefile +10 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/bookreader.gemspec +42 -0
  13. data/lib/bookreader/engine.rb +6 -0
  14. data/lib/bookreader/version.rb +3 -0
  15. data/lib/bookreader.rb +8 -0
  16. data/vendor/assets/images/BRicons.png +0 -0
  17. data/vendor/assets/images/BRicons.svg +94 -0
  18. data/vendor/assets/images/BRicons_ia.png +0 -0
  19. data/vendor/assets/images/back_pages.png +0 -0
  20. data/vendor/assets/images/book_bottom_icon.png +0 -0
  21. data/vendor/assets/images/book_down_icon.png +0 -0
  22. data/vendor/assets/images/book_left_icon.png +0 -0
  23. data/vendor/assets/images/book_leftmost_icon.png +0 -0
  24. data/vendor/assets/images/book_right_icon.png +0 -0
  25. data/vendor/assets/images/book_rightmost_icon.png +0 -0
  26. data/vendor/assets/images/book_top_icon.png +0 -0
  27. data/vendor/assets/images/book_up_icon.png +0 -0
  28. data/vendor/assets/images/books_graphic.svg +177 -0
  29. data/vendor/assets/images/booksplit.png +0 -0
  30. data/vendor/assets/images/control_pause_icon.png +0 -0
  31. data/vendor/assets/images/control_play_icon.png +0 -0
  32. data/vendor/assets/images/embed_icon.png +0 -0
  33. data/vendor/assets/images/icon-home-ia.png +0 -0
  34. data/vendor/assets/images/icon_OL-logo-xs.png +0 -0
  35. data/vendor/assets/images/icon_alert-xs.png +0 -0
  36. data/vendor/assets/images/icon_book.svg +12 -0
  37. data/vendor/assets/images/icon_bookmark.svg +12 -0
  38. data/vendor/assets/images/icon_close-pop.png +0 -0
  39. data/vendor/assets/images/icon_download.png +0 -0
  40. data/vendor/assets/images/icon_gear.svg +17 -0
  41. data/vendor/assets/images/icon_hamburger.svg +20 -0
  42. data/vendor/assets/images/icon_home.png +0 -0
  43. data/vendor/assets/images/icon_home.svg +21 -0
  44. data/vendor/assets/images/icon_home_ia.png +0 -0
  45. data/vendor/assets/images/icon_indicator.png +0 -0
  46. data/vendor/assets/images/icon_info.svg +12 -0
  47. data/vendor/assets/images/icon_one_page.svg +16 -0
  48. data/vendor/assets/images/icon_return.png +0 -0
  49. data/vendor/assets/images/icon_search_button.svg +14 -0
  50. data/vendor/assets/images/icon_search_button_blue.svg +18 -0
  51. data/vendor/assets/images/icon_share.svg +17 -0
  52. data/vendor/assets/images/icon_speaker.svg +18 -0
  53. data/vendor/assets/images/icon_speaker_open.svg +26 -0
  54. data/vendor/assets/images/icon_thumbnails.svg +19 -0
  55. data/vendor/assets/images/icon_two_pages.svg +17 -0
  56. data/vendor/assets/images/icon_zoomer.png +0 -0
  57. data/vendor/assets/images/left_edges.png +0 -0
  58. data/vendor/assets/images/loading.gif +0 -0
  59. data/vendor/assets/images/logo_icon.png +0 -0
  60. data/vendor/assets/images/marker_chap-off.png +0 -0
  61. data/vendor/assets/images/marker_chap-off.svg +11 -0
  62. data/vendor/assets/images/marker_chap-off_ia.png +0 -0
  63. data/vendor/assets/images/marker_chap-on.png +0 -0
  64. data/vendor/assets/images/marker_chap-on.svg +11 -0
  65. data/vendor/assets/images/marker_srch-off.png +0 -0
  66. data/vendor/assets/images/marker_srch-off.svg +11 -0
  67. data/vendor/assets/images/marker_srch-on.png +0 -0
  68. data/vendor/assets/images/marker_srch-on.svg +11 -0
  69. data/vendor/assets/images/marker_srchchap-off.png +0 -0
  70. data/vendor/assets/images/marker_srchchap-on.png +0 -0
  71. data/vendor/assets/images/nav_control-dn.png +0 -0
  72. data/vendor/assets/images/nav_control-dn_ia.png +0 -0
  73. data/vendor/assets/images/nav_control-up.png +0 -0
  74. data/vendor/assets/images/nav_control-up_ia.png +0 -0
  75. data/vendor/assets/images/nav_control.png +0 -0
  76. data/vendor/assets/images/one_page_mode_icon.png +0 -0
  77. data/vendor/assets/images/paper-badge.png +0 -0
  78. data/vendor/assets/images/print_icon.png +0 -0
  79. data/vendor/assets/images/progressbar.gif +0 -0
  80. data/vendor/assets/images/right_edges.png +0 -0
  81. data/vendor/assets/images/slider.png +0 -0
  82. data/vendor/assets/images/slider_ia.png +0 -0
  83. data/vendor/assets/images/thumbnail_mode_icon.png +0 -0
  84. data/vendor/assets/images/transparent.png +0 -0
  85. data/vendor/assets/images/two_page_mode_icon.png +0 -0
  86. data/vendor/assets/images/zoom_in_icon.png +0 -0
  87. data/vendor/assets/images/zoom_out_icon.png +0 -0
  88. data/vendor/assets/javascripts/BookReader.js +4849 -0
  89. data/vendor/assets/javascripts/BookReaderJSAdvanced.js +115 -0
  90. data/vendor/assets/javascripts/BookReaderJSSimple.js +56 -0
  91. data/vendor/assets/javascripts/IIIFBookReader.js +207 -0
  92. data/vendor/assets/javascripts/demo-iiif.js +26 -0
  93. data/vendor/assets/javascripts/dragscrollable-br.js +261 -0
  94. data/vendor/assets/javascripts/excanvas.compiled.js +35 -0
  95. data/vendor/assets/javascripts/jquery-1.10.1.js +9807 -0
  96. data/vendor/assets/javascripts/jquery-ui-1.12.0.min.js +18686 -0
  97. data/vendor/assets/javascripts/jquery.browser.min.js +14 -0
  98. data/vendor/assets/javascripts/jquery.bt.min.js +8 -0
  99. data/vendor/assets/javascripts/jquery.colorbox-min.js +6 -0
  100. data/vendor/assets/javascripts/jquery.ui.touch-punch.min.js +11 -0
  101. data/vendor/assets/javascripts/mmenu/dist/addons/navbars/jquery.mmenu.navbars.min.js +43 -0
  102. data/vendor/assets/javascripts/mmenu/dist/addons/offcanvas/jquery.mmenu.offcanvas.min.js +7 -0
  103. data/vendor/assets/javascripts/mmenu/dist/addons/screenreader/jquery.mmenu.screenreader.min.js +7 -0
  104. data/vendor/assets/javascripts/mmenu/dist/addons/searchfield/jquery.mmenu.searchfield.min.js +7 -0
  105. data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.all.min.js +151 -0
  106. data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.all.min.umd.js +162 -0
  107. data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.min.js +25 -0
  108. data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.min.umd.js +36 -0
  109. data/vendor/assets/javascripts/mmenu/dist/js/jquery.mmenu.oncanvas.min.js +13 -0
  110. data/vendor/assets/javascripts/mmenu/jquery.mmenu.searchfield.js +510 -0
  111. data/vendor/assets/javascripts/plugins/plugin.archive_analytics.js +67 -0
  112. data/vendor/assets/javascripts/plugins/plugin.chapters.js +197 -0
  113. data/vendor/assets/javascripts/plugins/plugin.iframe.js +73 -0
  114. data/vendor/assets/javascripts/plugins/plugin.mobile_nav.js +197 -0
  115. data/vendor/assets/javascripts/plugins/plugin.print.js +70 -0
  116. data/vendor/assets/javascripts/plugins/plugin.resume.js +73 -0
  117. data/vendor/assets/javascripts/plugins/plugin.search.js +523 -0
  118. data/vendor/assets/javascripts/plugins/plugin.themes.js +49 -0
  119. data/vendor/assets/javascripts/plugins/plugin.tts.js +523 -0
  120. data/vendor/assets/javascripts/plugins/plugin.url.js +168 -0
  121. data/vendor/assets/javascripts/soundmanager/license.txt +29 -0
  122. data/vendor/assets/javascripts/soundmanager/script/soundmanager2-jsmin.js +113 -0
  123. data/vendor/assets/javascripts/soundmanager/script/soundmanager2-nodebug-jsmin.js +83 -0
  124. data/vendor/assets/javascripts/soundmanager/script/soundmanager2-nodebug.js +2765 -0
  125. data/vendor/assets/javascripts/soundmanager/script/soundmanager2.js +6325 -0
  126. data/vendor/assets/javascripts/soundmanager/swf/soundmanager2.swf +0 -0
  127. data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_debug.swf +0 -0
  128. data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_flash9.swf +0 -0
  129. data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_flash9_debug.swf +0 -0
  130. data/vendor/assets/javascripts/soundmanager/swf/soundmanager2_flash_xdomain.zip +0 -0
  131. data/vendor/assets/stylesheets/BookReader.css +1887 -0
  132. data/vendor/assets/stylesheets/BookReaderDemo.css +18 -0
  133. data/vendor/assets/stylesheets/BookReaderEmbed.css +0 -0
  134. data/vendor/assets/stylesheets/demo.css +0 -0
  135. data/vendor/assets/stylesheets/dist/addons/navbars/jquery.mmenu.navbars.css +29 -0
  136. data/vendor/assets/stylesheets/dist/addons/offcanvas/jquery.mmenu.offcanvas.css +14 -0
  137. data/vendor/assets/stylesheets/dist/addons/screenreader/jquery.mmenu.screenreader.css +1 -0
  138. data/vendor/assets/stylesheets/dist/addons/searchfield/jquery.mmenu.searchfield.css +16 -0
  139. data/vendor/assets/stylesheets/dist/css/jquery.mmenu.all.css +413 -0
  140. data/vendor/assets/stylesheets/dist/css/jquery.mmenu.css +80 -0
  141. data/vendor/assets/stylesheets/dist/css/jquery.mmenu.oncanvas.css +66 -0
  142. 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
+ };