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,523 @@
1
+ /**
2
+ * Plugin for Archive.org book search
3
+ */
4
+
5
+ jQuery.extend(BookReader.defaultOptions, {
6
+ server: 'ia600609.us.archive.org',
7
+ bookId: '',
8
+ subPrefix: '',
9
+ bookPath: '',
10
+ enableSearch: true,
11
+ searchInsideUrl: '/fulltext/inside.php',
12
+ initialSearchTerm: null,
13
+ });
14
+
15
+ // Extend the constructor to add search properties
16
+ BookReader.prototype.setup = (function (super_) {
17
+ return function (options) {
18
+ super_.call(this, options);
19
+
20
+ this.searchTerm = '';
21
+ this.searchResults = null;
22
+ this.searchInsideUrl = options.searchInsideUrl;
23
+ this.enableSearch = options.enableSearch;
24
+
25
+ // Base server used by some api calls
26
+ this.bookId = options.bookId;
27
+ this.server = options.server;
28
+ this.subPrefix = options.subPrefix;
29
+ this.bookPath = options.bookPath;
30
+ };
31
+ })(BookReader.prototype.setup);
32
+
33
+ BookReader.prototype.init = (function (super_) {
34
+ return function () {
35
+ super_.call(this);
36
+
37
+ if (this.options.enableSearch
38
+ && this.options.initialSearchTerm) {
39
+ this.$('.BRsearchInput').val(this.options.initialSearchTerm);
40
+ this.search(this.options.initialSearchTerm, {
41
+ goToFirstResult: true
42
+ });
43
+ }
44
+ };
45
+ })(BookReader.prototype.init);
46
+
47
+
48
+ // Extend buildMobileDrawerElement
49
+ BookReader.prototype.buildMobileDrawerElement = (function (super_) {
50
+ return function () {
51
+ var $el = super_.call(this);
52
+ if (this.enableSearch) {
53
+ $el.find('.BRmobileMenu__moreInfoRow').after($(
54
+ "<li>"
55
+ +" <span>"
56
+ +" <span class=\"DrawerIconWrapper \"><img class=\"DrawerIcon\" src=\""+this.imagesBaseURL+"icon_search_button_blue.svg\" alt=\"info-speaker\"/></span>"
57
+ +" Search"
58
+ +" </span>"
59
+ +" <div>"
60
+ + "<form class='BRbooksearch mobile'>"
61
+ + "<input type='search' class='BRsearchInput' val='' placeholder='Search inside'/>"
62
+ + "<button type='submit' class='BRsearchSubmit'></button>"
63
+ + "</form>"
64
+ + "<div class='BRmobileSearchResultWrapper'>Enter your search above.</div>"
65
+ +" </div>"
66
+ +" </li>"
67
+ ));
68
+ };
69
+ return $el;
70
+ };
71
+ })(BookReader.prototype.buildMobileDrawerElement);
72
+
73
+
74
+ // Extend buildToolbarElement
75
+ BookReader.prototype.buildToolbarElement = (function (super_) {
76
+ return function () {
77
+ var $el = super_.call(this);
78
+ if (this.enableSearch) {
79
+ var $BRtoolbarSectionSearch = $("<span class='BRtoolbarSection BRtoolbarSectionSearch'>"
80
+ + "<form class='BRbooksearch desktop'>"
81
+ + "<input type='search' class='BRsearchInput' val='' placeholder='Search inside'/>"
82
+ + "<button type='submit' class='BRsearchSubmit'>"
83
+ + "<img src=\""+this.imagesBaseURL+"icon_search_button.svg\" />"
84
+ + "</button>"
85
+ + "</form>"
86
+ + "</span>");
87
+ $BRtoolbarSectionSearch.insertAfter($el.find('.BRtoolbarSectionInfo'));
88
+ }
89
+ return $el;
90
+ };
91
+ })(BookReader.prototype.buildToolbarElement);
92
+
93
+
94
+ // Extend initToolbar
95
+ BookReader.prototype.initToolbar = (function (super_) {
96
+ return function (mode, ui) {
97
+ super_.apply(this, arguments);
98
+
99
+ var self = this;
100
+
101
+ // Bind search forms
102
+ this.$('.BRbooksearch.desktop').submit(function(e) {
103
+ e.preventDefault();
104
+ var val = $(this).find('.BRsearchInput').val();
105
+ if (!val.length) return false;
106
+ self.search(val);
107
+ return false;
108
+ });
109
+ this.$('.BRbooksearch.mobile').submit(function(e) {
110
+ e.preventDefault();
111
+ var val = $(this).find('.BRsearchInput').val();
112
+ if (!val.length) return false;
113
+ self.search(val, {
114
+ disablePopup:true,
115
+ error: self.BRSearchCallbackErrorMobile,
116
+ });
117
+ self.$('.BRmobileSearchResultWrapper').append(
118
+ '<div>Your search results will appear below.</div>'
119
+ + '<div class="loader tc mt20"></div>'
120
+ );
121
+ return false;
122
+ });
123
+ // Handle clearing the search results
124
+ this.$(".BRsearchInput").bind('input propertychange', function() {
125
+ if (this.value == "") self.removeSearchResults();
126
+ });
127
+ };
128
+ })(BookReader.prototype.initToolbar);
129
+
130
+
131
+
132
+ // search()
133
+ // @param {string} term
134
+ // @param {object} options
135
+ //______________________________________________________________________________
136
+ BookReader.prototype.search = function(term, options) {
137
+ options = options !== undefined ? options : {};
138
+ var defaultOptions = {
139
+ // {bool} (default=false) goToFirstResult - jump to the first result
140
+ goToFirstResult: false,
141
+ // {bool} (default=false) disablePopup - don't show the modal progress
142
+ disablePopup: false,
143
+ error: this.BRSearchCallbackErrorDesktop.bind(this),
144
+ success: this.BRSearchCallback.bind(this),
145
+ };
146
+ options = jQuery.extend({}, defaultOptions, options);
147
+
148
+ this.$('.BRsearchInput').blur(); //cause mobile safari to hide the keyboard
149
+
150
+ this.removeSearchResults();
151
+
152
+ this.searchTerm = term;
153
+ // strip slashes, since this goes in the url
154
+ this.searchTerm = this.searchTerm.replace(/\//g, ' ');
155
+
156
+ this.trigger(BookReader.eventNames.fragmentChange);
157
+
158
+ // Add quotes to the term. This is to compenstate for the backends default OR query
159
+ // term = term.replace(/['"]+/g, '');
160
+ // term = '"' + term + '"';
161
+
162
+ // Remove the port and userdir
163
+ var url = 'https://' + this.server.replace(/:.+/, '') + this.searchInsideUrl + '?';
164
+
165
+ // Remove subPrefix from end of path
166
+ var path = this.bookPath;
167
+ var subPrefixWithSlash = '/' + this.subPrefix;
168
+ if (this.bookPath.length - this.bookPath.lastIndexOf(subPrefixWithSlash) == subPrefixWithSlash.length) {
169
+ path = this.bookPath.substr(0, this.bookPath.length - subPrefixWithSlash.length);
170
+ }
171
+
172
+ var urlParams = {
173
+ 'item_id': this.bookId,
174
+ 'doc': this.subPrefix,
175
+ 'path': path,
176
+ 'q': term,
177
+ };
178
+
179
+ var paramStr = $.param(urlParams);
180
+
181
+ // NOTE that the API does not expect / (slashes) to be encoded. (%2F) won't work
182
+ paramStr = paramStr.replace(/%2F/g, '/');
183
+
184
+ url += paramStr;
185
+
186
+ if (!options.disablePopup) {
187
+ this.showProgressPopup('<img class="searchmarker" src="'+this.imagesBaseURL + 'marker_srch-on.svg'+'"> Search results will appear below...');
188
+ }
189
+ $.ajax({
190
+ url:url,
191
+ dataType:'jsonp',
192
+ success: function(data) {
193
+ if (data.error || 0 == data.matches.length) {
194
+ options.error.call(br, data, options);
195
+ } else {
196
+ options.success.call(br, data, options);
197
+ }
198
+ },
199
+ });
200
+ };
201
+
202
+
203
+
204
+ // BRSearchCallback()
205
+ //______________________________________________________________________________
206
+ BookReader.prototype.BRSearchCallback = function(results, options) {
207
+ this.searchResults = results;
208
+ this.$('.BRnavpos .search').remove();
209
+ this.$('.BRmobileSearchResultWrapper').empty(); // Empty mobile results
210
+
211
+ // Update Mobile count
212
+ var mobileResultsText = results.matches.length == 1 ? "1 match" : results.matches.length + " matches";
213
+ this.$('.BRmobileSearchResultWrapper').append("<div class='BRmobileNumResults'>"+mobileResultsText+" for &quot;"+this.searchTerm+"&quot;</div>");
214
+
215
+ var i, firstResultIndex = null;
216
+ for (i=0; i < results.matches.length; i++) {
217
+ this.addSearchResult(results.matches[i].text, this.leafNumToIndex(results.matches[i].par[0].page));
218
+ if (i === 0 && options.goToFirstResult === true) {
219
+ firstResultIndex = this.leafNumToIndex(results.matches[i].par[0].page);
220
+ }
221
+ }
222
+ this.updateSearchHilites();
223
+ this.removeProgressPopup();
224
+ if (firstResultIndex !== null) {
225
+ this.jumpToIndex(firstResultIndex);
226
+ }
227
+ }
228
+
229
+ // BRSearchCallbackErrorDesktop()
230
+ //______________________________________________________________________________
231
+ BookReader.prototype.BRSearchCallbackErrorDesktop = function(results, options) {
232
+ var $el = $(this.popup);
233
+ this._BRSearchCallbackError(results, $el, true);
234
+ };
235
+
236
+ // BRSearchCallbackErrorMobile()
237
+ //______________________________________________________________________________
238
+ BookReader.prototype.BRSearchCallbackErrorMobile = function(results, options) {
239
+ var $el = this.$('.BRmobileSearchResultWrapper');
240
+ this._BRSearchCallbackError(results, $el);
241
+ };
242
+ BookReader.prototype._BRSearchCallbackError = function(results, $el, fade, options) {
243
+ var self = this;
244
+ this.$('.BRnavpos .search').remove();
245
+ this.$('.BRmobileSearchResultWrapper').empty(); // Empty mobile results
246
+
247
+ this.searchResults = results;
248
+ var timeout = 2000;
249
+ if (results.error) {
250
+ if (/debug/.test(window.location.href)) {
251
+ $el.html(results.error);
252
+ } else {
253
+ timeout = 4000;
254
+ $el.html('Sorry, there was an error with your search.<br />The text may still be processing.');
255
+
256
+ }
257
+ } else if (0 == results.matches.length) {
258
+ var errStr = 'No matches were found.';
259
+ timeout = 2000;
260
+ if (false === results.indexed) {
261
+ errStr = "<p>This book hasn't been indexed for searching yet. We've just started indexing it, so search should be available soon. Please try again later. Thanks!</p>";
262
+ timeout = 5000;
263
+ }
264
+ $el.html(errStr);
265
+ }
266
+ if (fade) {
267
+ setTimeout(function(){
268
+ $el.fadeOut('slow', function() {
269
+ self.removeProgressPopup();
270
+ })
271
+ }, timeout);
272
+ }
273
+ };
274
+
275
+
276
+ // updateSearchHilites()
277
+ //______________________________________________________________________________
278
+ BookReader.prototype.updateSearchHilites = function() {
279
+ if (this.constMode2up == this.mode) {
280
+ this.updateSearchHilites2UP();
281
+ } else {
282
+ this.updateSearchHilites1UP();
283
+ }
284
+ };
285
+
286
+ // showSearchHilites1UP()
287
+ //______________________________________________________________________________
288
+ BookReader.prototype.updateSearchHilites1UP = function() {
289
+ var results = this.searchResults;
290
+ if (null == results) return;
291
+ var i, j;
292
+ for (i=0; i<results.matches.length; i++) {
293
+ for (j=0; j<results.matches[i].par[0].boxes.length; j++) {
294
+ var box = results.matches[i].par[0].boxes[j];
295
+ var pageIndex = this.leafNumToIndex(box.page);
296
+ if (jQuery.inArray(pageIndex, this.displayedIndices) >= 0) {
297
+ if (null == box.div) {
298
+ //create a div for the search highlight, and stash it in the box object
299
+ box.div = document.createElement('div');
300
+ $(box.div).prop('className', 'BookReaderSearchHilite').appendTo(this.$('.pagediv'+pageIndex));
301
+ }
302
+ $(box.div).css({
303
+ width: (box.r-box.l)/this.reduce + 'px',
304
+ height: (box.b-box.t)/this.reduce + 'px',
305
+ left: (box.l)/this.reduce + 'px',
306
+ top: (box.t)/this.reduce +'px'
307
+ });
308
+ } else {
309
+ if (null != box.div) {
310
+ $(box.div).remove();
311
+ box.div=null;
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ };
318
+
319
+ // showSearchHilites2UPNew()
320
+ //______________________________________________________________________________
321
+ BookReader.prototype.updateSearchHilites2UP = function() {
322
+ var results = this.searchResults;
323
+ if (null == results) return;
324
+ var i, j;
325
+ for (i=0; i<results.matches.length; i++) {
326
+ //TODO: loop over all par objects
327
+ var pageIndex = this.leafNumToIndex(results.matches[i].par[0].page);
328
+ for (j=0; j<results.matches[i].par[0].boxes.length; j++) {
329
+ var box = results.matches[i].par[0].boxes[j];
330
+ if (jQuery.inArray(pageIndex, this.displayedIndices) >= 0) {
331
+ if (null == box.div) {
332
+ //create a div for the search highlight, and stash it in the box object
333
+ box.div = document.createElement('div');
334
+ $(box.div).addClass('BookReaderSearchHilite')
335
+ .appendTo(this.refs.$brTwoPageView)
336
+ ;
337
+ }
338
+ this.setHilightCss2UP(box.div, pageIndex, box.l, box.r, box.t, box.b);
339
+ } else {
340
+ if (null != box.div) {
341
+ $(box.div).remove();
342
+ box.div=null;
343
+ }
344
+ }
345
+ }
346
+ }
347
+ };
348
+
349
+
350
+ // removeSearchHilites()
351
+ //______________________________________________________________________________
352
+ BookReader.prototype.removeSearchHilites = function() {
353
+ var results = this.searchResults;
354
+ if (null == results) return;
355
+ var i, j;
356
+ for (i=0; i<results.matches.length; i++) {
357
+ for (j=0; j<results.matches[i].par[0].boxes.length; j++) {
358
+ var box = results.matches[i].par[0].boxes[j];
359
+ if (null != box.div) {
360
+ $(box.div).remove();
361
+ box.div=null;
362
+ }
363
+ }
364
+ }
365
+ };
366
+
367
+
368
+ BookReader.prototype.addSearchResult = function(queryString, pageIndex) {
369
+ var self = this;
370
+
371
+ var pageNumber = this.getPageNum(pageIndex);
372
+ var uiStringSearch = "Search result"; // i18n
373
+ var uiStringPage = "Page"; // i18n
374
+
375
+ var percentThrough = BookReader.util.cssPercentage(pageIndex, this.getNumLeafs() - 1);
376
+ var pageDisplayString = uiStringPage + ' ' + this.getNavPageNumString(pageIndex, true);
377
+
378
+ var searchBtSettings = {
379
+ contentSelector: '$(this).find(".BRquery")',
380
+ trigger: 'hover',
381
+ closeWhenOthersOpen: true,
382
+ cssStyles: {
383
+ padding: '12px 14px',
384
+ backgroundColor: '#fff',
385
+ border: '4px solid rgb(216,216,216)',
386
+ color: 'rgb(52,52,52)'
387
+ },
388
+ shrinkToFit: false,
389
+ width: '230px',
390
+ padding: 0,
391
+ spikeGirth: 0,
392
+ spikeLength: 0,
393
+ overlap: '0px',
394
+ overlay: false,
395
+ killTitle: false,
396
+ offsetParent: null,
397
+ positions: ['top'],
398
+ fill: 'white',
399
+ windowMargin: 10,
400
+ strokeWidth: 0,
401
+ cornerRadius: 0,
402
+ centerPointX: 0,
403
+ centerPointY: 0,
404
+ shadow: false
405
+ };
406
+
407
+ var re = new RegExp('{{{(.+?)}}}', 'g');
408
+ var queryStringWithB = queryString.replace(re, '<b>$1</b>');
409
+
410
+ var queryStringWithBTruncated;
411
+
412
+ if (queryString.length > 100) {
413
+ queryStringWithBTruncated = queryString
414
+ .replace(/^(.{100}[^\s]*).*/, "$1")
415
+ .replace(re, '<b>$1</b>')
416
+ + '...';
417
+ } else {
418
+ queryStringWithBTruncated = queryString.replace(re, '<b>$1</b>');
419
+ }
420
+
421
+ var $marker = $('<div>')
422
+ .addClass('BRsearch')
423
+ .css({
424
+ top: (-this.refs.$brContainer.height())+'px',
425
+ left: percentThrough,
426
+ })
427
+ .attr('title', uiStringSearch)
428
+ .append(
429
+ $('<div>')
430
+ .addClass('BRquery')
431
+ .append(
432
+ $('<div>').html(queryStringWithB),
433
+ $('<div>').html(uiStringPage + ' ' + pageNumber)
434
+ )
435
+ )
436
+ .data({'self': this, 'pageIndex': pageIndex})
437
+ .appendTo(this.$('.BRnavline'))
438
+ .bt(searchBtSettings)
439
+ .hover(function() {
440
+ // remove from other markers then turn on just for this
441
+ // XXX should be done when nav slider moves
442
+ self.$('.BRsearch,.BRchapter').removeClass('front');
443
+ $(this).addClass('front');
444
+ }, function() {
445
+ $(this).removeClass('front');
446
+ }
447
+ )
448
+ .bind('click', function() {
449
+ $(this).data('self').jumpToIndex($(this).data('pageIndex'));
450
+ })
451
+ .animate({top:'-25px'}, 'slow')
452
+ ;
453
+
454
+ // Add Mobile Search Results
455
+ var imgPreviewUrl = this.getPageURI(pageIndex, 16, 0); // scale 16 is small
456
+ var $mobileSearchResultWrapper = self.$('.BRmobileSearchResultWrapper');
457
+ if ($mobileSearchResultWrapper.length) {
458
+ $('<a class="BRmobileSearchResult">'
459
+ +"<table>"
460
+ +" <tr>"
461
+ +" <span class='pageDisplay'>"+pageDisplayString+"</span>"
462
+ +" </tr>"
463
+ +" <tr>"
464
+ +" <td>"
465
+ +" <img class='searchImgPreview' src=\""+imgPreviewUrl+"\" />"
466
+ +" </td>"
467
+ +" <td>"
468
+ +" <span>"+queryStringWithBTruncated+"</span>"
469
+ +" </td>"
470
+ +" </tr>"
471
+ +"</table>"
472
+ +'</a>')
473
+ .attr('href', '#search/' + this.searchTerm)
474
+ .click(function(e){
475
+ e.preventDefault();
476
+ self.switchMode(self.constMode1up);
477
+ self.jumpToIndex(pageIndex);
478
+ self.refs.$mmenu.data('mmenu').close();
479
+ })
480
+ .appendTo($mobileSearchResultWrapper)
481
+ ;
482
+ }
483
+ };
484
+
485
+ BookReader.prototype.removeSearchResults = function() {
486
+ this.removeSearchHilites(); //be sure to set all box.divs to null
487
+ this.searchTerm = null;
488
+ this.searchResults = null;
489
+ this.trigger(BookReader.eventNames.fragmentChange);
490
+ this.$('.BRnavpos .BRsearch').remove();
491
+ this.$('.BRmobileSearchResultWrapper').empty(); // Empty mobile results
492
+ };
493
+
494
+
495
+ // searchHighlightVisible
496
+ //________
497
+ // Returns true if a search highlight is currently being displayed
498
+ BookReader.prototype.searchHighlightVisible = function() {
499
+ var results = this.searchResults;
500
+ if (null == results) return false;
501
+
502
+ if (this.constMode2up == this.mode) {
503
+ var visiblePages = Array(this.twoPage.currentIndexL, this.twoPage.currentIndexR);
504
+ } else if (this.constMode1up == this.mode) {
505
+ var visiblePages = Array();
506
+ visiblePages[0] = this.currentIndex();
507
+ } else {
508
+ return false;
509
+ }
510
+
511
+ var i, j;
512
+ for (i=0; i<results.matches.length; i++) {
513
+ for (j=0; j<results.matches[i].par[0].boxes.length; j++) {
514
+ var box = results.matches[i].par[0].boxes[j];
515
+ var pageIndex = this.leafNumToIndex(box.page);
516
+ if (jQuery.inArray(pageIndex, visiblePages) >= 0) {
517
+ return true;
518
+ }
519
+ }
520
+ }
521
+
522
+ return false;
523
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Deprecated theming functionality
3
+ */
4
+
5
+ jQuery.extend(BookReader.defaultOptions, {
6
+ enableThemesPlugin: true,
7
+ });
8
+
9
+ BookReader.prototype.setup = (function(super_) {
10
+ return function (options) {
11
+ super_.call(this, options);
12
+
13
+ this.enableThemesPlugin = options.enableThemesPlugin;
14
+
15
+ // Themes
16
+ this.themes = { ol: null };
17
+ this.default_theme = 'ol';
18
+ this.theme = 'ol';
19
+ };
20
+ })(BookReader.prototype.setup);
21
+
22
+
23
+ // updateTheme
24
+ //______________________________________________________________________________
25
+ BookReader.prototype.updateTheme = function(theme) {
26
+ if (!(theme in this.themes)) return;
27
+ var main_style = $('#BRCSS');
28
+ if (main_style.length == 0) return;
29
+ if (theme == this.theme) return;
30
+ this.theme = theme;
31
+
32
+ if (theme == this.default_theme) {
33
+ $('#BRCSSTheme').attr('disabled', true);
34
+ return;
35
+ }
36
+
37
+ var stylesheet = $('#BRCSSTheme');
38
+ if (stylesheet.length == 0) {
39
+ stylesheet = $('<link rel="stylesheet" type="text/css">').attr('id', 'BRCSSTheme');
40
+ $('head').append(stylesheet);
41
+ }
42
+
43
+ var main_href = $('#BRCSS').attr('href');
44
+ var index = main_href.indexOf('BookReader.css');
45
+ var css_prefix = main_href.substr(0, index);
46
+ var theme_href = css_prefix + this.themes[theme];
47
+
48
+ stylesheet.attr({disabled: false, href: theme_href});
49
+ };