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,115 @@
1
+ //
2
+ // This file shows the minimum you need to provide to BookReader to display a book
3
+ //
4
+ // Copyright(c)2008-2009 Internet Archive. Software license AGPL version 3.
5
+
6
+ // Create the BookReader object
7
+ var options = {
8
+ // Total number of leafs
9
+ getNumLeafs: function() {
10
+ return 15;
11
+ },
12
+
13
+ // Return the width of a given page. Here we assume all images are 800 pixels wide
14
+ getPageWidth: function(index) {
15
+ return 800;
16
+ },
17
+
18
+ // Return the height of a given page. Here we assume all images are 1200 pixels high
19
+ getPageHeight: function(index) {
20
+ return 1200;
21
+ },
22
+
23
+ // We load the images from archive.org -- you can modify this function to retrieve images
24
+ // using a different URL structure
25
+ getPageURI: function(index, reduce, rotate) {
26
+ // reduce and rotate are ignored in this simple implementation, but we
27
+ // could e.g. look at reduce and load images from a different directory
28
+ // or pass the information to an image server
29
+ var leafStr = '000';
30
+ var imgStr = (index+1).toString();
31
+ var re = new RegExp("0{"+imgStr.length+"}$");
32
+ var url = 'http://archive.org/download/BookReader/img/page'+leafStr.replace(re, imgStr) + '.jpg';
33
+ return url;
34
+ },
35
+
36
+ // Return which side, left or right, that a given page should be displayed on
37
+ getPageSide: function(index) {
38
+ if (0 == (index & 0x1)) {
39
+ return 'R';
40
+ } else {
41
+ return 'L';
42
+ }
43
+ },
44
+
45
+ // This function returns the left and right indices for the user-visible
46
+ // spread that contains the given index. The return values may be
47
+ // null if there is no facing page or the index is invalid.
48
+ getSpreadIndices: function(pindex) {
49
+ var spreadIndices = [null, null];
50
+ if ('rl' == this.pageProgression) {
51
+ // Right to Left
52
+ if (this.getPageSide(pindex) == 'R') {
53
+ spreadIndices[1] = pindex;
54
+ spreadIndices[0] = pindex + 1;
55
+ } else {
56
+ // Given index was LHS
57
+ spreadIndices[0] = pindex;
58
+ spreadIndices[1] = pindex - 1;
59
+ }
60
+ } else {
61
+ // Left to right
62
+ if (this.getPageSide(pindex) == 'L') {
63
+ spreadIndices[0] = pindex;
64
+ spreadIndices[1] = pindex + 1;
65
+ } else {
66
+ // Given index was RHS
67
+ spreadIndices[1] = pindex;
68
+ spreadIndices[0] = pindex - 1;
69
+ }
70
+ }
71
+ return spreadIndices;
72
+ },
73
+
74
+ // For a given "accessible page index" return the page number in the book.
75
+ //
76
+ // For example, index 5 might correspond to "Page 1" if there is front matter such
77
+ // as a title page and table of contents.
78
+ getPageNum: function(index) {
79
+ return index+1;
80
+ },
81
+
82
+ // Book title and the URL used for the book title link
83
+ bookTitle: 'BookReader Advanced Demo',
84
+ bookUrl: '/BookReaderDemo/index.html',
85
+ bookUrlText: 'Back to Demos',
86
+ bookUrlTitle: 'This is the book URL title',
87
+ // thumbnail is optional, but it is used in the info dialog
88
+ thumbnail: '//archive.org/download/BookReader/img/page014.jpg',
89
+ // Metadata is optional, but it is used in the info dialog
90
+ metadata: [
91
+ {label: 'Title', value: 'Open Library BookReader Presentation'},
92
+ {label: 'Author', value: 'Internet Archive'},
93
+ {label: 'Demo Info', value: 'This demo shows how one could use BookReader with their own content.'},
94
+ ],
95
+ // This toggles the mobile drawer (not shown in 'embed' mode)
96
+ enableMobileNav: false,
97
+ mobileNavTitle: 'BookReader demo',
98
+
99
+ // Override the path used to find UI images
100
+ imagesBaseURL: '../BookReader/images/',
101
+
102
+ getEmbedCode: function(frameWidth, frameHeight, viewParams) {
103
+ return "Embed code not supported in bookreader demo.";
104
+ },
105
+
106
+ // Note previously the UI param was used for mobile, but it's going to be responsive
107
+ // embed === iframe
108
+
109
+ ui: 'full', // embed, full (responsive)
110
+
111
+ };
112
+ var br = new BookReader(options);
113
+
114
+ // Let's go!
115
+ br.init();
@@ -0,0 +1,56 @@
1
+ //
2
+ // This file shows the minimum you need to provide to BookReader to display a book
3
+ //
4
+ // Copyright(c)2008-2009 Internet Archive. Software license AGPL version 3.
5
+
6
+ // Create the BookReader object
7
+ function instantiateBookReader(selector, extraOptions) {
8
+ selector = selector || '#BookReader';
9
+ extraOptions = extraOptions || {};
10
+ var options = {
11
+ data: [
12
+ [
13
+ { width: 800, height: 1200,
14
+ uri: '//archive.org/download/BookReader/img/page001.jpg' },
15
+ ],
16
+ [
17
+ { width: 800, height: 1200,
18
+ uri: '//archive.org/download/BookReader/img/page002.jpg' },
19
+ { width: 800, height: 1200,
20
+ uri: '//archive.org/download/BookReader/img/page003.jpg' },
21
+ ],
22
+ [
23
+ { width: 800, height: 1200,
24
+ uri: '//archive.org/download/BookReader/img/page004.jpg' },
25
+ { width: 800, height: 1200,
26
+ uri: '//archive.org/download/BookReader/img/page005.jpg' },
27
+ ]
28
+ ],
29
+
30
+ // Book title and the URL used for the book title link
31
+ bookTitle: 'BookReader Demo',
32
+ bookUrl: '/BookReaderDemo/index.html',
33
+ bookUrlText: 'Back to Demos',
34
+ bookUrlTitle: 'This is the book URL title',
35
+
36
+ // thumbnail is optional, but it is used in the info dialog
37
+ thumbnail: '//archive.org/download/BookReader/img/page014.jpg',
38
+ // Metadata is optional, but it is used in the info dialog
39
+ metadata: [
40
+ {label: 'Title', value: 'Open Library BookReader Presentation'},
41
+ {label: 'Author', value: 'Internet Archive'},
42
+ {label: 'Demo Info', value: 'This demo shows how one could use BookReader with their own content.'},
43
+ ],
44
+
45
+ // Override the path used to find UI images
46
+ imagesBaseURL: '../BookReader/images/',
47
+
48
+ ui: 'full', // embed, full (responsive)
49
+
50
+ el: selector,
51
+ };
52
+ Object.assign(options, extraOptions);
53
+ var br = new BookReader(options);
54
+ br.init();
55
+ }
56
+
@@ -0,0 +1,207 @@
1
+ // Bind to the BookReader object providing facilities to set the necessary
2
+ // BookReader functions from a IIIF endpoint URL.
3
+ // author: @aeschylus
4
+
5
+ // TODO enable passing in manifest and sequence id directly
6
+ // TODO convert this to be a v3 plugin. Use simplified options.data
7
+
8
+ (function(BR){
9
+
10
+ BR.prototype.IIIF = function (config) {
11
+ // config should have the url of a sequence
12
+ // within a passed-in manifest.
13
+ var brInstance = this;
14
+ brInstance.IIIFsequence = {
15
+ title: null,
16
+ imagesList: [],
17
+ numPages: null,
18
+ bookUrl: null
19
+ };
20
+ oldInit = brInstance.init;
21
+ oldMode = brInstance.mode;
22
+ brInstance.init = function() {
23
+ load(config);
24
+ };
25
+ brInstance.mode = 2;
26
+
27
+ function bindBRMethods(){
28
+ brInstance.getPageNum = function(index) {
29
+ return index+1;
30
+ };
31
+
32
+ brInstance.getSpreadIndices = function(pindex) {
33
+ var spreadIndices = [null, null];
34
+ if ('rl' == brInstance.pageProgression) {
35
+ // Right to Left
36
+ if (brInstance.getPageSide(pindex) == 'R') {
37
+ spreadIndices[1] = pindex;
38
+ spreadIndices[0] = pindex + 1;
39
+ } else {
40
+ // Given index was LHS
41
+ spreadIndices[0] = pindex;
42
+ spreadIndices[1] = pindex - 1;
43
+ }
44
+ } else {
45
+ // Left to right
46
+ if (brInstance.getPageSide(pindex) == 'L') {
47
+ spreadIndices[0] = pindex;
48
+ spreadIndices[1] = pindex + 1;
49
+ } else {
50
+ // Given index was RHS
51
+ spreadIndices[1] = pindex;
52
+ spreadIndices[0] = pindex - 1;
53
+ }
54
+ }
55
+
56
+ return spreadIndices;
57
+ };
58
+
59
+ brInstance.getPageSide = function(index) {
60
+ if (0 == (index & 0x1)) {
61
+ return 'R';
62
+ } else {
63
+ return 'L';
64
+ }
65
+ };
66
+
67
+ brInstance.getPageHeight = function(index) {
68
+ // console.log(index);
69
+ var fullWidth = brInstance.IIIFsequence.imagesList[index].width,
70
+ fullHeight = brInstance.IIIFsequence.imagesList[index].height,
71
+ scaleRatio = config.maxWidth/fullWidth;
72
+
73
+ return fullHeight*scaleRatio;
74
+ };
75
+
76
+ brInstance.getPageWidth = function(index) {
77
+ var fullWidth = brInstance.IIIFsequence.imagesList[index].width,
78
+ scaleRatio = config.maxWidth/fullWidth;
79
+
80
+ return fullWidth*scaleRatio;
81
+ };
82
+
83
+ brInstance.getPageURI = function(index) {
84
+ // Finds the image info.json url
85
+ // from the loaded sequence and returns the
86
+ // IIIF-formatted url for the page image
87
+ // based on the provided configuration object
88
+ // (adjusting for width, etc.).
89
+ var infoJsonUrl = brInstance.IIIFsequence.imagesList[index].imageUrl;
90
+ var url = infoJsonUrl + "/full/" + config.maxWidth + ",/0/native.jpg";
91
+ return url;
92
+ };
93
+
94
+ }
95
+
96
+ function load(config) {
97
+
98
+ endpointUrl = config.url,
99
+ sequenceId = config.sequenceId;
100
+
101
+ jQuery.ajax({
102
+ url: endpointUrl.replace(/^\s+|\s+$/g, ''),
103
+ dataType: 'json',
104
+ async: true,
105
+
106
+ success: function(jsonLd) {
107
+ brInstance.jsonLd = jsonLd;
108
+ brInstance.bookTitle = jsonLd.label;
109
+ brInstance.bookUrl = '#';
110
+ brInstance.thumbnail = jsonLd.thumbnail['@id'];
111
+ brInstance.metadata = jsonLd.metadata;
112
+ parseSequence(sequenceId);
113
+ bindBRMethods();
114
+
115
+ // Call the old initialisation after
116
+ // the urls are finished. A better implementation
117
+ // would be to employ promises (Likely by including
118
+ // the Q Promises/A+ implementation. See issue #1 at
119
+ // github.
120
+ oldInit.call(brInstance);
121
+
122
+ if (config.initCallback) {
123
+ config.initCallback.apply();
124
+ }
125
+
126
+ // // The following is an attrocious hack and must not
127
+ // // be allowed to persist. See issue #2 at github.com
128
+ // setTimeout(function() { jQuery(window).trigger('resize'); console.log("resize event fired")}, 2500);
129
+ },
130
+
131
+ error: function() {
132
+ console.log('Failed loading ' + brInstance.uri);
133
+ }
134
+
135
+ });
136
+
137
+ }
138
+
139
+ function parseSequence(sequenceId) {
140
+
141
+ jQuery.each(brInstance.jsonLd.sequences, function(index, sequence) {
142
+ if (sequence['@id'] === sequenceId) {
143
+ brInstance.IIIFsequence.title = "here's a sequence";
144
+ brInstance.IIIFsequence.bookUrl = "http://iiif.io";
145
+ brInstance.IIIFsequence.imagesList = getImagesList(sequence);
146
+ brInstance.numLeafs = brInstance.IIIFsequence.imagesList.length;
147
+ }
148
+ });
149
+
150
+ delete brInstance.jsonLd;
151
+
152
+ }
153
+
154
+ function getImagesList(sequence) {
155
+ var imagesList = [];
156
+
157
+ jQuery.each(sequence.canvases, function(index, canvas) {
158
+ var imageObj;
159
+
160
+ if (canvas['@type'] === 'sc:Canvas') {
161
+ var images = canvas.resources || canvas.images;
162
+
163
+ jQuery.each(images, function(index, image) {
164
+ if (image['@type'] === 'oa:Annotation') {
165
+ imageObj = getImageObject(image);
166
+ imageObj.canvasWidth = canvas.width;
167
+ imageObj.canvasHeight = canvas.height;
168
+
169
+ if (!(/#xywh/).test(image.on)) {
170
+ imagesList.push(imageObj);
171
+ }
172
+ }
173
+ });
174
+
175
+ }
176
+ });
177
+
178
+ return imagesList;
179
+ }
180
+
181
+ function getImageObject (image) {
182
+ var resource = image.resource;
183
+
184
+ if (resource.hasOwnProperty('@type') && resource['@type'] === 'oa:Choice') {
185
+ var imageObj = getImageProperties(resource.default);
186
+ } else {
187
+ imageObj = getImageProperties(resource);
188
+ }
189
+
190
+ return(imageObj);
191
+ }
192
+
193
+ function getImageProperties(image) {
194
+ var imageObj = {
195
+ height: image.height || 0,
196
+ width: image.width || 0,
197
+ imageUrl: image.service['@id'].replace(/\/$/, ''),
198
+ };
199
+
200
+ imageObj.aspectRatio = (imageObj.width / imageObj.height) || 1;
201
+
202
+ return imageObj;
203
+ }
204
+
205
+ };
206
+
207
+ })(BookReader);
@@ -0,0 +1,26 @@
1
+ // This demo uses a slightly modified version of
2
+ // https://github.com/aeschylus/IIIFBookReader
3
+ //
4
+ // It is intended as a rapid proof of concept.
5
+ // More development could be done.
6
+
7
+ var br = new BookReader({
8
+ // Book title and the URL used for the book title link
9
+ bookTitle: 'Open Library BookReader Presentation',
10
+ bookUrl: 'http://openlibrary.org',
11
+
12
+ // Override the path used to find UI images
13
+ imagesBaseURL: '../BookReader/images/',
14
+ enableMobileNav: false,
15
+ });
16
+
17
+ br.IIIF({
18
+ url: 'https://iiif.archivelab.org/iiif/platowithenglish04platuoft/manifest.json',
19
+ sequenceId : 'https://iiif.archivelab.org/iiif/platowithenglish04platuoft/canvas/default',
20
+ maxWidth: 800,
21
+ initCallback: function() {
22
+ }
23
+ });
24
+
25
+ // Let's go!
26
+ br.init();
@@ -0,0 +1,261 @@
1
+ /*
2
+ * jQuery dragscrollable Plugin
3
+ * version: 1.0 (25-Jun-2009)
4
+ * Copyright (c) 2009 Miquel Herrera
5
+ *
6
+ * Portions Copyright (c) 2010 Reg Braithwaite
7
+ * Copyright (c) 2010 Internet Archive / Michael Ang
8
+ * Copyright (c) 2016 Internet Archive / Richard Caceres
9
+ *
10
+ * Dual licensed under the MIT and GPL licenses:
11
+ * http://www.opensource.org/licenses/mit-license.php
12
+ * http://www.gnu.org/licenses/gpl.html
13
+ *
14
+ * Modified by richard@archive.org 2016
15
+ * - Added check to disable on touch enabled devices
16
+ * - Change dragend handler to bind using event "capturing" instead of "bubbling"
17
+ */
18
+ ;(function($){ // secure $ jQuery alias
19
+
20
+ /**
21
+ * Adds the ability to manage elements scroll by dragging
22
+ * one or more of its descendant elements. Options parameter
23
+ * allow to specifically select which inner elements will
24
+ * respond to the drag events.
25
+ *
26
+ * options properties:
27
+ * ------------------------------------------------------------------------
28
+ * dragSelector | jquery selector to apply to each wrapped element
29
+ * | to find which will be the dragging elements.
30
+ * | Defaults to '>:first' which is the first child of
31
+ * | scrollable element
32
+ * ------------------------------------------------------------------------
33
+ * acceptPropagatedEvent| Will the dragging element accept propagated
34
+ * | events? default is yes, a propagated mouse event
35
+ * | on a inner element will be accepted and processed.
36
+ * | If set to false, only events originated on the
37
+ * | draggable elements will be processed.
38
+ * ------------------------------------------------------------------------
39
+ * preventDefault | Prevents the event to propagate further effectivey
40
+ * | dissabling other default actions. Defaults to true
41
+ * ------------------------------------------------------------------------
42
+ * scrollWindow | Scroll the window rather than the element
43
+ * | Defaults to false
44
+ * ------------------------------------------------------------------------
45
+ *
46
+ * usage examples:
47
+ *
48
+ * To add the scroll by drag to the element id=viewport when dragging its
49
+ * first child accepting any propagated events
50
+ * $('#viewport').dragscrollable();
51
+ *
52
+ * To add the scroll by drag ability to any element div of class viewport
53
+ * when dragging its first descendant of class dragMe responding only to
54
+ * evcents originated on the '.dragMe' elements.
55
+ * $('div.viewport').dragscrollable({dragSelector:'.dragMe:first',
56
+ * acceptPropagatedEvent: false});
57
+ *
58
+ * Notice that some 'viewports' could be nested within others but events
59
+ * would not interfere as acceptPropagatedEvent is set to false.
60
+ *
61
+ */
62
+
63
+ var append_namespace = function (string_of_events, ns) {
64
+
65
+ /* IE doesn't have map
66
+ return string_of_events
67
+ .split(' ')
68
+ .map(function (name) { return name + ns; })
69
+ .join(' ');
70
+ */
71
+ var pieces = string_of_events.split(' ');
72
+ var ret = new Array();
73
+ for (var i = 0; i < pieces.length; i++) {
74
+ ret.push(pieces[i] + ns);
75
+ }
76
+ return ret.join(' ');
77
+ };
78
+
79
+ var left_top = function(event) {
80
+
81
+ var x;
82
+ var y;
83
+ if (typeof(event.clientX) != 'undefined') {
84
+ x = event.clientX;
85
+ y = event.clientY;
86
+ }
87
+ else if (typeof(event.screenX) != 'undefined') {
88
+ x = event.screenX;
89
+ y = event.screenY;
90
+ }
91
+ else if (typeof(event.targetTouches) != 'undefined') {
92
+ x = event.targetTouches[0].pageX;
93
+ y = event.targetTouches[0].pageY;
94
+ }
95
+ else if (typeof(event.originalEvent) == 'undefined') {
96
+ var str = '';
97
+ for (i in event) {
98
+ str += ', ' + i + ': ' + event[i];
99
+ }
100
+ console.error("don't understand x and y for " + event.type + ' event: ' + str);
101
+ }
102
+ else if (typeof(event.originalEvent.clientX) != 'undefined') {
103
+ x = event.originalEvent.clientX;
104
+ y = event.originalEvent.clientY;
105
+ }
106
+ else if (typeof(event.originalEvent.screenX) != 'undefined') {
107
+ x = event.originalEvent.screenX;
108
+ y = event.originalEvent.screenY;
109
+ }
110
+ else if (typeof(event.originalEvent.targetTouches) != 'undefined') {
111
+ x = event.originalEvent.targetTouches[0].pageX;
112
+ y = event.originalEvent.targetTouches[0].pageY;
113
+ }
114
+
115
+ return {left: x, top:y};
116
+ };
117
+
118
+ $.fn.dragscrollable = function( options ) {
119
+
120
+ var handling_element = $(this);
121
+
122
+ var settings = $.extend(
123
+ {
124
+ dragSelector:'>:first',
125
+ acceptPropagatedEvent: true,
126
+ preventDefault: true,
127
+ dragstart: 'mousedown touchstart',
128
+ dragcontinue: 'mousemove touchmove',
129
+ dragend: 'mouseup touchend', // mouseleave
130
+ dragMinDistance: 5,
131
+ namespace: '.ds',
132
+ scrollWindow: false,
133
+ },options || {});
134
+
135
+ settings.dragstart = append_namespace(settings.dragstart, settings.namespace);
136
+ settings.dragcontinue = append_namespace(settings.dragcontinue, settings.namespace);
137
+ //settings.dragend = append_namespace(settings.dragend, settings.namespace);
138
+
139
+ var shouldAbort = function() {
140
+ var isTouchDevice = !!('ontouchstart' in window) || !!('msmaxtouchpoints' in window.navigator);
141
+ return isTouchDevice;
142
+ };
143
+
144
+ var dragContinueHandlerProxy;
145
+
146
+ var dragscroll= {
147
+ dragStartHandler : function(event) {
148
+ if (shouldAbort()) { return true; }
149
+
150
+ // mousedown, left click, check propagation
151
+ if (event.which > 1 ||
152
+ (!event.data.acceptPropagatedEvent && event.target != this)){
153
+ return false;
154
+ }
155
+
156
+ event.data.firstCoord = left_top(event);
157
+ // Initial coordinates will be the last when dragging
158
+ event.data.lastCoord = event.data.firstCoord;
159
+
160
+ handling_element
161
+ .bind(settings.dragcontinue, event.data, dragscroll.dragContinueHandler)
162
+ //.bind(settings.dragend, event.data, dragscroll.dragEndHandler)
163
+ ;
164
+
165
+ // Note, we bind using addEventListener so we can use "capture" binding
166
+ // instead of "bubble" binding
167
+ dragContinueHandlerProxy = function(e){
168
+ e.data = event.data;
169
+ dragscroll.dragEndHandler(e);
170
+ };
171
+ $.each(settings.dragend.split(' '), function(idx, val) {
172
+ handling_element.get(0).addEventListener(val, dragContinueHandlerProxy, true);
173
+ });
174
+
175
+ if (event.data.preventDefault) {
176
+ event.preventDefault();
177
+ return false;
178
+ }
179
+ },
180
+ dragContinueHandler : function(event) { // User is dragging
181
+ // console.log('drag continue');
182
+ if (shouldAbort()) { return true; }
183
+
184
+ var lt = left_top(event);
185
+
186
+ // How much did the mouse move?
187
+ var delta = {left: (lt.left - event.data.lastCoord.left),
188
+ top: (lt.top - event.data.lastCoord.top)};
189
+
190
+ var scrollTarget = event.data.scrollable;
191
+ if (event.data.scrollWindow) {
192
+ scrollTarget = $(window);
193
+ }
194
+ // Set the scroll position relative to what ever the scroll is now
195
+ scrollTarget.scrollLeft( scrollTarget.scrollLeft() - delta.left );
196
+ scrollTarget.scrollTop( scrollTarget.scrollTop() - delta.top );
197
+
198
+ // Save where the cursor is
199
+ event.data.lastCoord = lt;
200
+
201
+ if (event.data.preventDefault) {
202
+ event.preventDefault();
203
+ return false;
204
+ }
205
+ },
206
+ dragEndHandler : function(event) { // Stop scrolling
207
+ //console.log('dragEndHandler');
208
+
209
+ if (shouldAbort()) { return true; }
210
+
211
+ handling_element
212
+ .unbind(settings.dragcontinue)
213
+ // Note, for some reason, even though I removeEventListener below,
214
+ // this call to unbind is still necessary. I don't know why.
215
+ .unbind(settings.dragend)
216
+ ;
217
+
218
+ // Note, we bind using addEventListener so we can use "capture" binding
219
+ // instead of "bubble" binding
220
+ $.each(settings.dragend.split(' '), function(idx, val) {
221
+ handling_element.get(0).removeEventListener(val, dragContinueHandlerProxy, true);
222
+ });
223
+
224
+ // How much did the mouse move total?
225
+ var delta = {left: Math.abs(event.data.lastCoord.left - event.data.firstCoord.left),
226
+ top: Math.abs(event.data.lastCoord.top - event.data.firstCoord.top)};
227
+ var distance = Math.max(delta.left, delta.top);
228
+
229
+ // Allow event to propage if min distance was not achieved
230
+ if (event.data.preventDefault && distance > settings.dragMinDistance) {
231
+ event.preventDefault();
232
+ event.stopImmediatePropagation();
233
+ event.stopPropagation();
234
+ return false;
235
+ }
236
+ }
237
+ };
238
+
239
+ // set up the initial events
240
+ return this.each(function() {
241
+ // closure object data for each scrollable element
242
+ var data = {scrollable : $(this),
243
+ acceptPropagatedEvent : settings.acceptPropagatedEvent,
244
+ preventDefault : settings.preventDefault,
245
+ scrollWindow : settings.scrollWindow };
246
+ // Set mouse initiating event on the desired descendant
247
+ $(this).find(settings.dragSelector).
248
+ bind(settings.dragstart, data, dragscroll.dragStartHandler);
249
+ });
250
+ }; //end plugin dragscrollable
251
+
252
+ // Note, this probably doesn't work anymore with our modifications - Nov/8/2016
253
+ $.fn.removedragscrollable = function (namespace) {
254
+ if (typeof(namespace) == 'undefined')
255
+ namespace = '.ds';
256
+ return this.each(function() {
257
+ var x = $(document).find('*').andSelf().unbind(namespace);
258
+ });
259
+ };
260
+
261
+ })( jQuery ); // confine scope