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,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
|