diva.js 6.0.2 → 7.2.3

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 (131) hide show
  1. package/.clang-format +7 -0
  2. package/.github/workflows/npm-publish.yml +45 -0
  3. package/LICENSE +55 -0
  4. package/Makefile +75 -0
  5. package/README.md +15 -114
  6. package/elm.json +32 -0
  7. package/package.json +12 -59
  8. package/review/elm.json +52 -0
  9. package/review/src/ReviewConfig.elm +87 -0
  10. package/scripts/elm-esm.sh +40 -0
  11. package/scripts/minify-css.mjs +31 -0
  12. package/src/Filters.elm +1044 -0
  13. package/src/Main.elm +1217 -0
  14. package/src/Model.elm +213 -0
  15. package/src/Msg.elm +59 -0
  16. package/src/Utilities.elm +46 -0
  17. package/src/View/CollectionExplorer.elm +172 -0
  18. package/src/View/Helpers.elm +86 -0
  19. package/src/View/HtmlRenderer.elm +136 -0
  20. package/src/View/Icons.elm +159 -0
  21. package/src/View/ManifestInfoModal.elm +363 -0
  22. package/src/View/PageViewModal.elm +1046 -0
  23. package/src/View/Sidebar.elm +786 -0
  24. package/src/View/Toolbar.elm +189 -0
  25. package/src/View.elm +244 -0
  26. package/src/diva.ts +802 -0
  27. package/src/filters.ts +1843 -0
  28. package/src/styles/app.css +328 -0
  29. package/src/styles/collection.css +75 -0
  30. package/src/styles/modal.css +388 -0
  31. package/src/styles/sidebar.css +215 -0
  32. package/src/styles/theme.css +39 -0
  33. package/src/styles/toolbar.css +154 -0
  34. package/src/viewer-element.ts +1307 -0
  35. package/testing/index.html +52 -0
  36. package/testing/testing.html +231 -0
  37. package/tsconfig.json +12 -0
  38. package/AUTHORS +0 -22
  39. package/build/diva.css +0 -554
  40. package/build/diva.css.map +0 -1
  41. package/build/diva.js +0 -9
  42. package/build/diva.js.map +0 -1
  43. package/build/plugins/download.js +0 -2
  44. package/build/plugins/download.js.map +0 -1
  45. package/build/plugins/manipulation.js +0 -2
  46. package/build/plugins/manipulation.js.map +0 -1
  47. package/build/plugins/metadata.js +0 -2
  48. package/build/plugins/metadata.js.map +0 -1
  49. package/index.html +0 -28
  50. package/karma.conf.js +0 -87
  51. package/source/css/_mixins.scss +0 -43
  52. package/source/css/_variables.scss +0 -50
  53. package/source/css/_viewer.scss +0 -462
  54. package/source/css/diva.scss +0 -15
  55. package/source/css/plugins/_manipulation.scss +0 -228
  56. package/source/css/plugins/_metadata.scss +0 -31
  57. package/source/img/adjust.svg +0 -11
  58. package/source/img/book-view.svg +0 -6
  59. package/source/img/close.svg +0 -6
  60. package/source/img/download.svg +0 -6
  61. package/source/img/from-fullscreen.svg +0 -8
  62. package/source/img/grid-fewer.svg +0 -6
  63. package/source/img/grid-more.svg +0 -6
  64. package/source/img/grid-view.svg +0 -6
  65. package/source/img/link.svg +0 -6
  66. package/source/img/metadata.svg +0 -9
  67. package/source/img/page-view.svg +0 -6
  68. package/source/img/to-fullscreen.svg +0 -11
  69. package/source/img/zoom-in.svg +0 -6
  70. package/source/img/zoom-out.svg +0 -7
  71. package/source/js/composite-image.js +0 -174
  72. package/source/js/diva-global.js +0 -7
  73. package/source/js/diva.js +0 -1543
  74. package/source/js/document-handler.js +0 -180
  75. package/source/js/document-layout.js +0 -286
  76. package/source/js/exceptions.js +0 -26
  77. package/source/js/gesture-events.js +0 -190
  78. package/source/js/grid-handler.js +0 -122
  79. package/source/js/iiif-source-adapter.js +0 -63
  80. package/source/js/image-cache.js +0 -113
  81. package/source/js/image-manifest.js +0 -157
  82. package/source/js/image-request-handler.js +0 -76
  83. package/source/js/interpolate-animation.js +0 -122
  84. package/source/js/page-layouts/book-layout.js +0 -161
  85. package/source/js/page-layouts/grid-layout.js +0 -97
  86. package/source/js/page-layouts/index.js +0 -38
  87. package/source/js/page-layouts/page-dimensions.js +0 -9
  88. package/source/js/page-layouts/singles-layout.js +0 -27
  89. package/source/js/page-overlay-manager.js +0 -102
  90. package/source/js/page-tools-overlay.js +0 -95
  91. package/source/js/parse-iiif-manifest.js +0 -302
  92. package/source/js/plugins/_filters.js +0 -679
  93. package/source/js/plugins/download.js +0 -83
  94. package/source/js/plugins/manipulation.js +0 -837
  95. package/source/js/plugins/metadata.js +0 -190
  96. package/source/js/renderer.js +0 -584
  97. package/source/js/settings-view.js +0 -30
  98. package/source/js/tile-coverage-map.js +0 -25
  99. package/source/js/toolbar.js +0 -573
  100. package/source/js/utils/dragscroll.js +0 -106
  101. package/source/js/utils/elt.js +0 -94
  102. package/source/js/utils/events.js +0 -190
  103. package/source/js/utils/get-scrollbar-width.js +0 -29
  104. package/source/js/utils/hash-params.js +0 -86
  105. package/source/js/utils/parse-label-value.js +0 -34
  106. package/source/js/utils/vanilla.kinetic.js +0 -527
  107. package/source/js/validation-runner.js +0 -177
  108. package/source/js/viewer-core.js +0 -1514
  109. package/source/js/viewport.js +0 -143
  110. package/test/_setup.js +0 -13
  111. package/test/composite-image_test.js +0 -94
  112. package/test/diva_test.js +0 -43
  113. package/test/hash-params_test.js +0 -221
  114. package/test/image-cache_test.js +0 -106
  115. package/test/main.js +0 -6
  116. package/test/manifests/beromunsterManifest.json +0 -15514
  117. package/test/manifests/iiifv2.json +0 -11032
  118. package/test/manifests/iiifv2pages.json +0 -30437
  119. package/test/manifests/iiifv3.json +0 -10965
  120. package/test/navigation_test.js +0 -355
  121. package/test/parse-iiif-manifest_test.js +0 -68
  122. package/test/public_test.js +0 -881
  123. package/test/settings_test.js +0 -487
  124. package/test/utils/book-layout_test.js +0 -148
  125. package/test/utils/elt_test.js +0 -102
  126. package/test/utils/events_test.js +0 -245
  127. package/test/utils/hash-params_test.js +0 -79
  128. package/test/utils/parse-label-value_test.js +0 -45
  129. package/test/z_plugins_test.js +0 -180
  130. package/webpack.config.js +0 -58
  131. package/webpack.config.test.js +0 -45
package/source/js/diva.js DELETED
@@ -1,1543 +0,0 @@
1
- import './utils/vanilla.kinetic';
2
- import './utils/dragscroll';
3
- import { elt } from "./utils/elt";
4
- import {
5
- DivaParentElementNotFoundException,
6
- NotAnIIIFManifestException,
7
- ObjectDataNotSuppliedException
8
- } from "./exceptions";
9
- import diva from "./diva-global";
10
- import ViewerCore from "./viewer-core";
11
- import ImageManifest from "./image-manifest";
12
- import Toolbar from "./toolbar";
13
- import HashParams from "./utils/hash-params";
14
-
15
-
16
- /**
17
- * The top-level class for Diva objects. This is instantiated by passing in an HTML element
18
- * ID or HTML Element node and an object containing a list of options, of which the 'objectData'
19
- * option is required and which must point to a IIIF Presentation API Manifest:
20
- *
21
- * var diva = new Diva('element-id', {
22
- * objectData: "http://example.com/iiif-manifest.json"
23
- * });
24
- *
25
- * This class also serves as the entry point for the Events system, in which applications can subscribe
26
- * to notifications sent from Diva instances:
27
- *
28
- * Diva.Events.subscribe('VisiblePageDidChange', function () { console.log("Visible Page Changed"); });
29
- *
30
- *
31
- *
32
- **/
33
- class Diva
34
- {
35
- constructor (element, options)
36
- {
37
- /*
38
- * If a string is passed in, convert that to an element.
39
- * */
40
- if (!(element instanceof HTMLElement))
41
- {
42
- this.element = document.getElementById(element);
43
-
44
- if (this.element === null)
45
- {
46
- throw new DivaParentElementNotFoundException();
47
- }
48
- }
49
-
50
- if (!options.objectData)
51
- {
52
- throw new ObjectDataNotSuppliedException('You must supply either a URL or a literal object to the `objectData` key.');
53
- }
54
-
55
- this.options = Object.assign({
56
- acceptHeader: "application/json", // The header to send off to the server in content negotiation
57
- adaptivePadding: 0.05, // The ratio of padding to the page dimension
58
- arrowScrollAmount: 40, // The amount (in pixels) to scroll by when using arrow keys
59
- blockMobileMove: false, // Prevent moving or scrolling the page on mobile devices
60
- objectData: '', // A IIIF Manifest or a JSON file generated by process.py that provides the object dimension data, or a URL pointing to such data - *REQUIRED*
61
- enableAutoTitle: true, // Shows the title within a div of id diva-title
62
- enableFilename: true, // Uses filenames and not page numbers for links (i=bm_001.tif, not p=1)
63
- enableFullscreen: true, // Enable or disable fullscreen icon (mode still available)
64
- enableGotoPage: true, // A "go to page" jump box
65
- enableGotoSuggestions: true, // Controls whether suggestions are shown under the input field when the user is typing in the 'go to page' form
66
- enableGridIcon: true, // A grid view of all the pages
67
- enableGridControls: 'buttons', // Specify control of pages per grid row in Grid view. Possible values: 'buttons' (+/-), 'slider'. Any other value disables the controls.
68
- enableImageTitles: true, // Adds "Page {n}" title to page images if true
69
- enableIndexAsLabel: false, // Use index numbers instead of page labels in the page n-m display.
70
- enableKeyScroll: true, // Captures scrolling using the arrow and page up/down keys regardless of page focus. When off, defers to default browser scrolling behavior.
71
- enableLinkIcon: true, // Controls the visibility of the link icon
72
- enableNonPagedVisibilityIcon: true, // Controls the visibility of the icon to toggle the visibility of non-paged pages. (Automatically hidden if no 'non-paged' pages).
73
- enableSpaceScroll: false, // Scrolling down by pressing the space key
74
- enableToolbar: true, // Enables the toolbar. Note that disabling this means you have to handle all controls yourself.
75
- enableZoomControls: 'buttons', // Specify controls for zooming in and out. Possible values: 'buttons' (+/-), 'slider'. Any other value disables the controls.
76
- fillParentHeight: true, // Use a flexbox layout to allow Diva to fill its parent's height
77
- fixedPadding: 10, // Fallback if adaptive padding is set to 0
78
- fixedHeightGrid: true, // So each page in grid view has the same height (only widths differ)
79
- goDirectlyTo: 0, // Default initial page to show (0-indexed)
80
- hashParamSuffix: null, // Used when there are multiple document viewers on a page
81
- inFullscreen: false, // Set to true to load fullscreen mode initially
82
- inBookLayout: false, // Set to true to view the document with facing pages in document mode
83
- inGrid: false, // Set to true to load grid view initially
84
- maxPagesPerRow: 8, // Maximum number of pages per row in grid view
85
- maxZoomLevel: -1, // Optional; defaults to the max zoom returned in the JSON response
86
- minPagesPerRow: 2, // Minimum pages per row in grid view. Recommended default.
87
- minZoomLevel: 0, // Defaults to 0 (the minimum zoom)
88
- onGotoSubmit: null, // When set to a function that takes a string and returns a page index, this will override the default behaviour of the 'go to page' form submission
89
- pageAliases: {}, // An object mapping specific page indices to aliases (has priority over 'pageAliasFunction'
90
- pageAliasFunction: function(){return false;}, // A function mapping page indices to an alias. If false is returned, default page number is displayed
91
- pageLoadTimeout: 200, // Number of milliseconds to wait before loading pages
92
- pagesPerRow: 5, // The default number of pages per row in grid view
93
- showNonPagedPages: false, // Whether pages tagged as 'non-paged' (in IIIF manifests only) should be visible after initial load
94
- throbberTimeout: 100, // Number of milliseconds to wait before showing throbber
95
- tileHeight: 256, // The height of each tile, in pixels; usually 256
96
- tileWidth: 256, // The width of each tile, in pixels; usually 256
97
- toolbarParentObject: null, // The toolbar parent object.
98
- verticallyOriented: true, // Determines vertical vs. horizontal orientation
99
- viewportMargin: 200, // Pretend tiles +/- 200px away from viewport are in
100
- zoomLevel: 2 // The initial zoom level (used to store the current zoom level)
101
- }, options);
102
-
103
- // In order to fill the height, use a wrapper div displayed using a flexbox layout
104
- const wrapperElement = elt('div', {
105
- class: `diva-wrapper${this.options.fillParentHeight ? " diva-wrapper-flexbox" : ""}`
106
- });
107
-
108
- this.element.appendChild(wrapperElement);
109
-
110
- this.options.toolbarParentObject = this.options.toolbarParentObject || wrapperElement;
111
-
112
- const viewerCore = new ViewerCore(wrapperElement, this.options, this);
113
-
114
- this.viewerState = viewerCore.getInternalState();
115
- this.settings = viewerCore.getSettings();
116
- this.toolbar = this.settings.enableToolbar ? new Toolbar(this) : null;
117
-
118
- wrapperElement.id = this.settings.ID + 'wrapper';
119
-
120
- this.divaState = {
121
- viewerCore: viewerCore,
122
- toolbar: this.toolbar
123
- };
124
-
125
- // only render the toolbar after the object has been loaded
126
- let handle = diva.Events.subscribe('ObjectDidLoad', () =>
127
- {
128
- if (this.toolbar !== null)
129
- {
130
- this.toolbar.render();
131
- }
132
-
133
- diva.Events.unsubscribe(handle);
134
- });
135
-
136
- this.hashState = this._getHashParamState();
137
-
138
- this._loadOrFetchObjectData();
139
- }
140
-
141
- /**
142
- * @private
143
- **/
144
- _loadOrFetchObjectData ()
145
- {
146
- if (typeof this.settings.objectData === 'object')
147
- {
148
- // Defer execution until initialization has completed
149
- setTimeout(() =>
150
- {
151
- this._loadObjectData(this.settings.objectData, this.hashState);
152
- }, 0);
153
- }
154
- else
155
- {
156
- const pendingManifestRequest = fetch(this.settings.objectData, {
157
- headers: {
158
- "Accept": this.settings.acceptHeader
159
- }
160
- }).then( (response) =>
161
- {
162
- if (!response.ok)
163
- {
164
- this._ajaxError(response);
165
-
166
- let error = new Error(response.statusText);
167
- error.response = response;
168
- throw error;
169
- }
170
- return response.json();
171
-
172
- }).then( (data) =>
173
- {
174
- this._loadObjectData(data, this.hashState);
175
- });
176
-
177
- // Store the pending request so that it can be cancelled in the event that Diva needs to be destroyed
178
- this.divaState.viewerCore.setPendingManifestRequest(pendingManifestRequest);
179
- }
180
- }
181
-
182
- /**
183
- * @private
184
- **/
185
- _showError (message)
186
- {
187
- this.divaState.viewerCore.showError(message);
188
- }
189
-
190
- /**
191
- * @private
192
- * */
193
- _ajaxError (response)
194
- {
195
- // Show a basic error message within the document viewer pane
196
- const errorMessage = ['Invalid objectData setting. Error code: ' + response.status + ' ' + response.statusText];
197
-
198
- // Detect and handle CORS errors
199
- const dataHasAbsolutePath = this.settings.objectData.lastIndexOf('http', 0) === 0;
200
-
201
- if (dataHasAbsolutePath)
202
- {
203
- const jsonHost = this.settings.objectData.replace(/https?:\/\//i, "").split(/[/?#]/)[0];
204
-
205
- if (window.location.hostname !== jsonHost)
206
- {
207
- errorMessage.push(
208
- elt('p', 'Attempted to access cross-origin data without CORS.'),
209
- elt('p',
210
- 'You may need to update your server configuration to support CORS. For help, see the ',
211
- elt('a', {
212
- href: 'https://github.com/DDMAL/diva.js/wiki/Installation#a-note-about-cross-site-requests',
213
- target: '_blank'
214
- }, 'cross-site request documentation.')
215
- )
216
- );
217
- }
218
- }
219
-
220
- this._showError(errorMessage);
221
- }
222
-
223
- /**
224
- * @private
225
- **/
226
- _loadObjectData (responseData, hashState)
227
- {
228
- let manifest;
229
-
230
- // TODO improve IIIF detection method
231
- if (!responseData.hasOwnProperty('@context') && (responseData['@context'].indexOf('iiif') === -1 || responseData['@context'].indexOf('shared-canvas') === -1))
232
- {
233
- throw new NotAnIIIFManifestException('This does not appear to be a IIIF Manifest.');
234
- }
235
-
236
- // trigger ManifestDidLoad event
237
- diva.Events.publish('ManifestDidLoad', [responseData], this);
238
- manifest = ImageManifest.fromIIIF(responseData);
239
- const loadOptions = hashState ? this._getLoadOptionsForState(hashState, manifest) : {};
240
-
241
- this.divaState.viewerCore.setManifest(manifest, loadOptions);
242
- }
243
-
244
- /**
245
- * Parse the hash parameters into the format used by getState and setState
246
- *
247
- * @private
248
- **/
249
- _getHashParamState ()
250
- {
251
- const state = {};
252
-
253
- ['f', 'v', 'z', 'n', 'i', 'p', 'y', 'x'].forEach( (param) =>
254
- {
255
- const value = HashParams.get(param + this.settings.hashParamSuffix);
256
-
257
- // `false` is returned if the value is missing
258
- if (value !== false)
259
- state[param] = value;
260
- });
261
-
262
- // Do some awkward special-casing, since this format is kind of weird.
263
-
264
- // For inFullscreen (f), true and false strings should be interpreted
265
- // as booleans.
266
- if (state.f === 'true')
267
- state.f = true;
268
- else if (state.f === 'false')
269
- state.f = false;
270
-
271
- // Convert numerical values to integers, if provided
272
- ['z', 'n', 'p', 'x', 'y'].forEach( (param) =>
273
- {
274
- if (param in state)
275
- state[param] = parseInt(state[param], 10);
276
- });
277
-
278
- return state;
279
- }
280
-
281
- /**
282
- * @private
283
- **/
284
- _getLoadOptionsForState (state, manifest)
285
- {
286
- manifest = manifest || this.settings.manifest;
287
-
288
- const options = ('v' in state) ? this._getViewState(state.v) : {};
289
-
290
- if ('f' in state)
291
- options.inFullscreen = state.f;
292
-
293
- if ('z' in state)
294
- options.zoomLevel = state.z;
295
-
296
- if ('n' in state)
297
- options.pagesPerRow = state.n;
298
-
299
- // Only change specify the page if state.i or state.p is valid
300
- let pageIndex = this._getPageIndexForManifest(manifest, state.i);
301
-
302
- if (!(pageIndex >= 0 && pageIndex < manifest.pages.length))
303
- {
304
- pageIndex = state.p - 1;
305
-
306
- // Possibly NaN
307
- if (!(pageIndex >= 0 && pageIndex < manifest.pages.length))
308
- pageIndex = null;
309
- }
310
-
311
- if (pageIndex !== null)
312
- {
313
- const horizontalOffset = parseInt(state.x, 10);
314
- const verticalOffset = parseInt(state.y, 10);
315
-
316
- options.goDirectlyTo = pageIndex;
317
- options.horizontalOffset = horizontalOffset;
318
- options.verticalOffset = verticalOffset;
319
- }
320
-
321
- return options;
322
- }
323
-
324
- /**
325
- * @private
326
- * */
327
- _getViewState (view)
328
- {
329
- switch (view)
330
- {
331
- case 'd':
332
- return {
333
- inGrid: false,
334
- inBookLayout: false
335
- };
336
-
337
- case 'b':
338
- return {
339
- inGrid: false,
340
- inBookLayout: true
341
- };
342
-
343
- case 'g':
344
- return {
345
- inGrid: true,
346
- inBookLayout: false
347
- };
348
-
349
- default:
350
- return {};
351
- }
352
- }
353
-
354
- /**
355
- * @private
356
- * */
357
- _getPageIndexForManifest (manifest, filename)
358
- {
359
- let i;
360
- const np = manifest.pages.length;
361
-
362
- for (i = 0; i < np; i++)
363
- {
364
- if (manifest.pages[i].f === filename)
365
- {
366
- return i;
367
- }
368
- }
369
-
370
- return -1;
371
- }
372
-
373
- /**
374
- * @private
375
- * */
376
- _getState ()
377
- {
378
- let view;
379
-
380
- if (this.settings.inGrid)
381
- {
382
- view = 'g';
383
- }
384
- else if (this.settings.inBookLayout)
385
- {
386
- view = 'b';
387
- }
388
- else
389
- {
390
- view = 'd';
391
- }
392
-
393
- const layout = this.divaState.viewerCore.getCurrentLayout();
394
- const pageOffset = layout.getPageToViewportCenterOffset(this.settings.activePageIndex, this.viewerState.viewport);
395
-
396
- return {
397
- 'f': this.settings.inFullscreen,
398
- 'v': view,
399
- 'z': this.settings.zoomLevel,
400
- 'n': this.settings.pagesPerRow,
401
- 'i': this.settings.enableFilename ? this.settings.manifest.pages[this.settings.activePageIndex].f : false,
402
- 'p': this.settings.enableFilename ? false : this.settings.activePageIndex + 1,
403
- 'y': pageOffset ? pageOffset.y : false,
404
- 'x': pageOffset ? pageOffset.x : false
405
- };
406
- }
407
-
408
- /**
409
- * @private
410
- **/
411
- _getURLHash ()
412
- {
413
- const hashParams = this._getState();
414
- const hashStringBuilder = [];
415
- let param;
416
-
417
- for (param in hashParams)
418
- {
419
- if (hashParams[param] !== false)
420
- hashStringBuilder.push(param + this.settings.hashParamSuffix + '=' + encodeURIComponent(hashParams[param]));
421
- }
422
-
423
- return hashStringBuilder.join('&');
424
- }
425
-
426
- /**
427
- * Returns the page index associated with the given filename; must called after setting settings.manifest
428
- *
429
- * @private
430
- **/
431
- _getPageIndex (filename)
432
- {
433
- return this._getPageIndexForManifest(this.settings.manifest, filename);
434
- }
435
-
436
- /**
437
- * @private
438
- * */
439
- _checkLoaded ()
440
- {
441
- if (!this.viewerState.loaded)
442
- {
443
- console.warn("The viewer is not completely initialized. This is likely because it is still downloading data. To fix this, only call this function if the isReady() method returns true.");
444
- return false;
445
- }
446
- return true;
447
- }
448
-
449
- /**
450
- * Called when the fullscreen icon is clicked
451
- *
452
- * @private
453
- **/
454
- _toggleFullscreen ()
455
- {
456
- this._reloadViewer({
457
- inFullscreen: !this.settings.inFullscreen
458
- });
459
-
460
- // handle toolbar opacity in fullscreen
461
- let t;
462
- let hover = false;
463
- let tools = document.getElementById(this.settings.selector + 'tools');
464
- const TIMEOUT = 2000;
465
-
466
- if (this.settings.inFullscreen)
467
- {
468
- tools.classList.add("diva-fullscreen-tools");
469
-
470
- document.addEventListener('mousemove', toggleOpacity.bind(this));
471
- document.getElementsByClassName('diva-viewport')[0].addEventListener('scroll', toggleOpacity.bind(this));
472
- tools.addEventListener('mouseenter', function () {
473
- hover = true;
474
- });
475
- tools.addEventListener('mouseleave', function () {
476
- hover = false;
477
- });
478
- }
479
- else
480
- {
481
- tools.classList.remove("diva-fullscreen-tools");
482
- }
483
-
484
- function toggleOpacity ()
485
- {
486
- tools.style.opacity = 1;
487
- clearTimeout(t);
488
- if (!hover && this.settings.inFullscreen) {
489
- t = setTimeout(function ()
490
- {
491
- tools.style.opacity = 0;
492
- }, TIMEOUT);
493
- }
494
- }
495
- }
496
-
497
- /**
498
- * Toggles between orientations
499
- *
500
- * @private
501
- * */
502
- _togglePageLayoutOrientation ()
503
- {
504
- const verticallyOriented = !this.settings.verticallyOriented;
505
-
506
- //if in grid, switch out of grid
507
- this._reloadViewer({
508
- inGrid: false,
509
- verticallyOriented: verticallyOriented,
510
- goDirectlyTo: this.settings.activePageIndex,
511
- verticalOffset: this.divaState.viewerCore.getYOffset(),
512
- horizontalOffset: this.divaState.viewerCore.getXOffset()
513
- });
514
-
515
- return verticallyOriented;
516
- }
517
-
518
- /**
519
- * Called when the change view icon is clicked
520
- *
521
- * @private
522
- **/
523
- _changeView (destinationView)
524
- {
525
- switch (destinationView)
526
- {
527
- case 'document':
528
- return this._reloadViewer({
529
- inGrid: false,
530
- inBookLayout: false
531
- });
532
-
533
- case 'book':
534
- return this._reloadViewer({
535
- inGrid: false,
536
- inBookLayout: true
537
- });
538
-
539
- case 'grid':
540
- return this._reloadViewer({
541
- inGrid: true
542
- });
543
-
544
- default:
545
- return false;
546
- }
547
- }
548
-
549
- /**
550
- * @private
551
- *
552
- * @param {Number} pageIndex - 0-based page index.
553
- * @param {Number} xAnchor - x coordinate to jump to on resulting page.
554
- * @param {Number} yAnchor - y coordinate to jump to on resulting page.
555
- * @returns {Boolean} - Whether the jump was successful.
556
- **/
557
- _gotoPageByIndex (pageIndex, xAnchor, yAnchor)
558
- {
559
- let pidx = parseInt(pageIndex, 10);
560
-
561
- if (this._isPageIndexValid(pidx))
562
- {
563
- const xOffset = this.divaState.viewerCore.getXOffset(pidx, xAnchor);
564
- const yOffset = this.divaState.viewerCore.getYOffset(pidx, yAnchor);
565
-
566
- this.viewerState.renderer.goto(pidx, yOffset, xOffset);
567
- return true;
568
- }
569
-
570
- return false;
571
- }
572
-
573
- /**
574
- * Check if a page index is valid
575
- *
576
- * @private
577
- * @param {Number} pageIndex - Numeric (0-based) page index
578
- * @return {Boolean} whether the page index is valid or not.
579
- */
580
- _isPageIndexValid (pageIndex)
581
- {
582
- return this.settings.manifest.isPageValid(pageIndex, this.settings.showNonPagedPages);
583
- }
584
-
585
- /**
586
- * Given a pageX and pageY value, returns either the page visible at that (x,y)
587
- * position or -1 if no page is.
588
- *
589
- * @private
590
- */
591
- _getPageIndexForPageXYValues (pageX, pageY)
592
- {
593
- //get the four edges of the outer element
594
- const outerOffset = this.viewerState.outerElement.getBoundingClientRect();
595
- const outerTop = outerOffset.top;
596
- const outerLeft = outerOffset.left;
597
- const outerBottom = outerOffset.bottom;
598
- const outerRight = outerOffset.right;
599
-
600
- //if the clicked position was outside the diva-outer object, it was not on a visible portion of a page
601
- if (pageX < outerLeft || pageX > outerRight)
602
- return -1;
603
-
604
- if (pageY < outerTop || pageY > outerBottom)
605
- return -1;
606
-
607
- //navigate through all diva page objects
608
- const pages = document.getElementsByClassName('diva-page');
609
- let curPageIdx = pages.length;
610
- while (curPageIdx--)
611
- {
612
- //get the offset for each page
613
- const curPage = pages[curPageIdx];
614
- const curOffset = curPage.getBoundingClientRect();
615
-
616
- //if this point is outside the horizontal boundaries of the page, continue
617
- if (pageX < curOffset.left || pageX > curOffset.right)
618
- continue;
619
-
620
- //same with vertical boundaries
621
- if (pageY < curOffset.top || pageY > curOffset.bottom)
622
- continue;
623
-
624
- //if we made it through the above two, we found the page we're looking for
625
- return curPage.getAttribute('data-index');
626
- }
627
-
628
- //if we made it through that entire while loop, we didn't click on a page
629
- return -1;
630
- }
631
-
632
- /**
633
- * @private
634
- **/
635
- _reloadViewer (newOptions)
636
- {
637
- return this.divaState.viewerCore.reload(newOptions);
638
- }
639
-
640
- /**
641
- * @private
642
- */
643
- _getCurrentURL ()
644
- {
645
- return location.protocol + '//' + location.host + location.pathname + location.search + '#' + this._getURLHash();
646
- }
647
-
648
- /**
649
- * ===============================================
650
- * PUBLIC FUNCTIONS
651
- * ===============================================
652
- **/
653
-
654
- /**
655
- * Activate this instance of diva via the active Diva controller.
656
- *
657
- * @public
658
- */
659
- activate ()
660
- {
661
- this.viewerState.isActiveDiva = true;
662
- }
663
-
664
- /**
665
- * Change the object (objectData) parameter currently being rendered by Diva.
666
- *
667
- * @public
668
- * @params {object} objectData - An IIIF Manifest object OR a URL to a IIIF manifest.
669
- */
670
- changeObject (objectData)
671
- {
672
- this.viewerState.loaded = false;
673
- this.divaState.viewerCore.clear();
674
-
675
- if (this.viewerState.renderer)
676
- this.viewerState.renderer.destroy();
677
-
678
- this.viewerState.options.objectData = objectData;
679
-
680
- this._loadOrFetchObjectData();
681
- }
682
-
683
- /**
684
- * Change views. Takes 'document', 'book', or 'grid' to specify which view to switch into
685
- *
686
- * @public
687
- * @params {string} destinationView - the destination view to change to.
688
- */
689
- changeView (destinationView)
690
- {
691
- this._changeView(destinationView);
692
- }
693
-
694
- /**
695
- * Deactivate this diva instance through the active Diva controller.
696
- *
697
- * @public
698
- **/
699
- deactivate ()
700
- {
701
- this.viewerState.isActiveDiva = false;
702
- }
703
-
704
- /**
705
- * Destroys this instance, tells plugins to do the same
706
- *
707
- * @public
708
- **/
709
- destroy ()
710
- {
711
- this.divaState.viewerCore.destroy();
712
- }
713
-
714
- /**
715
- * Disables document dragging, scrolling (by keyboard if set), and zooming by double-clicking
716
- *
717
- * @public
718
- **/
719
- disableScrollable ()
720
- {
721
- this.divaState.viewerCore.disableScrollable();
722
- }
723
-
724
- /**
725
- * Re-enables document dragging, scrolling (by keyboard if set), and zooming by double-clicking
726
- *
727
- * @public
728
- **/
729
- enableScrollable ()
730
- {
731
- this.divaState.viewerCore.enableScrollable();
732
- }
733
-
734
- /**
735
- * Disables document drag scrolling
736
- *
737
- * @public
738
- */
739
- disableDragScrollable ()
740
- {
741
- this.divaState.viewerCore.disableDragScrollable();
742
- }
743
-
744
- /**
745
- * Enables document drag scrolling
746
- *
747
- * @public
748
- */
749
- enableDragScrollable ()
750
- {
751
- this.divaState.viewerCore.enableDragScrollable();
752
- }
753
-
754
- /**
755
- * Enter fullscreen mode if currently not in fullscreen mode. If currently in fullscreen
756
- * mode this will have no effect.
757
- *
758
- * This function will work even if enableFullscreen is set to false in the options.
759
- *
760
- * @public
761
- * @returns {boolean} - Whether the switch to fullscreen was successful or not.
762
- **/
763
- enterFullscreenMode ()
764
- {
765
- if (!this.settings.inFullscreen)
766
- {
767
- this._toggleFullscreen();
768
- return true;
769
- }
770
-
771
- return false;
772
- }
773
-
774
- /**
775
- * Enter grid view if currently not in grid view. If currently in grid view mode
776
- * this will have no effect.
777
- *
778
- * @public
779
- * @returns {boolean} - Whether the switch to grid view was successful or not.
780
- **/
781
- enterGridView ()
782
- {
783
- if (!this.settings.inGrid)
784
- {
785
- this._changeView('grid');
786
- return true;
787
- }
788
-
789
- return false;
790
- }
791
-
792
- /**
793
- * Returns an array of all page image URIs in the document.
794
- *
795
- * @public
796
- * @returns {Array} - An array of all the URIs in the document.
797
- * */
798
- getAllPageURIs ()
799
- {
800
- return this.settings.manifest.pages.map( (pg) =>
801
- {
802
- return pg.f;
803
- });
804
- }
805
-
806
- /**
807
- * Get the canvas identifier for the currently visible page.
808
- *
809
- * @public
810
- * @returns {string} - The URI of the currently visible canvas.
811
- **/
812
- getCurrentCanvas ()
813
- {
814
- return this.settings.manifest.pages[this.settings.activePageIndex].canvas;
815
- }
816
-
817
- /**
818
- * Returns the dimensions of the current page at the current zoom level. Also works in
819
- * grid view.
820
- *
821
- * @public
822
- * @returns {object} - An object containing the current page dimensions at the current zoom level.
823
- **/
824
- getCurrentPageDimensionsAtCurrentZoomLevel ()
825
- {
826
- return this.getPageDimensionsAtCurrentZoomLevel(this.settings.activePageIndex);
827
- }
828
-
829
- /**
830
- * Returns the current filename (deprecated). Returns the URI for current page.
831
- *
832
- * @public
833
- * @deprecated
834
- * @returns {string} - The URI for the current page image.
835
- **/
836
- getCurrentPageFilename ()
837
- {
838
- console.warn('This method will be deprecated in the next version of Diva. Please use getCurrentPageURI instead.');
839
- return this.settings.manifest.pages[this.settings.activePageIndex].f;
840
- }
841
-
842
- /**
843
- * Returns an array of page indices that are visible in the viewport.
844
- *
845
- * @public
846
- * @returns {array} - The 0-based indices array for the currently visible pages.
847
- **/
848
- getCurrentPageIndices ()
849
- {
850
- return this.settings.currentPageIndices;
851
- }
852
-
853
- /**
854
- * Returns the 0-based index for the current page.
855
- *
856
- * @public
857
- * @returns {number} - The 0-based index for the currently visible page.
858
- **/
859
- getActivePageIndex ()
860
- {
861
- return this.settings.activePageIndex;
862
- }
863
-
864
- /**
865
- * Shortcut to getPageOffset for current page.
866
- *
867
- * @public
868
- * @returns {} -
869
- * */
870
- getCurrentPageOffset ()
871
- {
872
- return this.getPageOffset(this.settings.activePageIndex);
873
- }
874
-
875
- /**
876
- * Returns the current URI for the visible page.
877
- *
878
- * @public
879
- * @returns {string} - The URI for the current page image.
880
- **/
881
- getCurrentPageURI ()
882
- {
883
- return this.settings.manifest.pages[this.settings.activePageIndex].f;
884
- }
885
-
886
- /**
887
- * Return the current URL for the viewer, including the hash parameters reflecting
888
- * the current state of the viewer.
889
- *
890
- * @public
891
- * @returns {string} - The URL for the current view state.
892
- * */
893
- getCurrentURL ()
894
- {
895
- return this._getCurrentURL();
896
- }
897
-
898
- /**
899
- * Returns an array of all filenames in the document. Deprecated.
900
- *
901
- * @public
902
- * @deprecated
903
- * @returns {Array} - An array of all the URIs in the document.
904
- * */
905
- getFilenames ()
906
- {
907
- console.warn('This will be removed in the next version of Diva. Use getAllPageURIs instead.');
908
-
909
- return this.settings.manifest.pages.map( (pg) =>
910
- {
911
- return pg.f;
912
- });
913
- }
914
-
915
- /**
916
- * Get the number of grid pages per row.
917
- *
918
- * @public
919
- * @returns {number} - The number of grid pages per row.
920
- **/
921
- getGridPagesPerRow ()
922
- {
923
- // TODO(wabain): Add test case
924
- return this.settings.pagesPerRow;
925
- }
926
-
927
- /**
928
- * Get the instance ID number.
929
- *
930
- * @public
931
- * @returns {number} - The instance ID.
932
- * */
933
- //
934
- getInstanceId ()
935
- {
936
- return this.settings.ID;
937
- }
938
-
939
- /**
940
- * Get the instance selector for this instance. This is the selector for the parent
941
- * div.
942
- *
943
- * @public
944
- * @returns {string} - The viewport selector.
945
- * */
946
- getInstanceSelector ()
947
- {
948
- return this.divaState.viewerCore.selector;
949
- }
950
-
951
- /**
952
- * Returns the title of the document, based on the label in the IIIF manifest.
953
- *
954
- * @public
955
- * @returns {string} - The current title of the object from the label key in the IIIF Manifest.
956
- **/
957
- getItemTitle ()
958
- {
959
- return this.settings.manifest.itemTitle;
960
- }
961
-
962
- /**
963
- * Gets the maximum zoom level for the entire document.
964
- *
965
- * @public
966
- * @returns {number} - The maximum zoom level for the document
967
- * */
968
- getMaxZoomLevel ()
969
- {
970
- return this.settings.maxZoomLevel;
971
- }
972
-
973
- /**
974
- * Gets the max zoom level for a given page.
975
- *
976
- * @public
977
- * @param {number} pageIdx - The 0-based index number for the page.
978
- * @returns {number} - The maximum zoom level for that page.
979
- * */
980
- getMaxZoomLevelForPage (pageIdx)
981
- {
982
- if (!this._checkLoaded())
983
- return false;
984
-
985
- return this.settings.manifest.pages[pageIdx].m;
986
- }
987
-
988
- /**
989
- * Gets the minimum zoom level for the entire document.
990
- *
991
- * @public
992
- * @returns {number} - The minimum zoom level for the document
993
- * */
994
- getMinZoomLevel ()
995
- {
996
- return this.settings.minZoomLevel;
997
- }
998
-
999
- /**
1000
- * Gets the number of pages in the document.
1001
- *
1002
- * @public
1003
- * @returns {number} - The number of pages in the document.
1004
- * */
1005
- getNumberOfPages ()
1006
- {
1007
- if (!this._checkLoaded())
1008
- return false;
1009
-
1010
- return this.settings.numPages;
1011
- }
1012
-
1013
- /**
1014
- * If a canvas has multiple images defined, returns the non-primary image.
1015
- *
1016
- * @public
1017
- * @params {number} pageIndex - The page index for which to return the other images.
1018
- * @returns {object} An object containing the other images.
1019
- **/
1020
- getOtherImages (pageIndex)
1021
- {
1022
- return this.settings.manifest.pages[pageIndex].otherImages;
1023
- }
1024
-
1025
- /**
1026
- * Get page dimensions in the current view and zoom level
1027
- *
1028
- * @public
1029
- * @params {number} pageIndex - A valid 0-based page index
1030
- * @returns {object} - An object containing the dimensions of the page
1031
- * */
1032
- getPageDimensions (pageIndex)
1033
- {
1034
- if (!this._checkLoaded())
1035
- return null;
1036
-
1037
- return this.divaState.viewerCore.getCurrentLayout().getPageDimensions(pageIndex);
1038
- }
1039
-
1040
- /**
1041
- * Returns the dimensions of a given page at the current zoom level.
1042
- * Also works in Grid view
1043
- *
1044
- * @public
1045
- * @param {number} pageIndex - The 0-based page index
1046
- * @returns {object} - An object containing the page dimensions at the current zoom level.
1047
- * */
1048
- getPageDimensionsAtCurrentZoomLevel (pageIndex)
1049
- {
1050
- let pidx = parseInt(pageIndex, 10);
1051
-
1052
- if (!this._isPageIndexValid(pidx))
1053
- throw new Error('Invalid Page Index');
1054
-
1055
- return this.divaState.viewerCore.getCurrentLayout().getPageDimensions(pidx);
1056
- }
1057
-
1058
- /**
1059
- * Get page dimensions at a given zoom level
1060
- *
1061
- * @public
1062
- * @params {number} pageIdx - A valid 0-based page index
1063
- * @params {number} zoomLevel - A candidate zoom level.
1064
- * @returns {object} - An object containing the dimensions of the page at the given zoom level.
1065
- **/
1066
- getPageDimensionsAtZoomLevel (pageIdx, zoomLevel)
1067
- {
1068
- if (!this._checkLoaded())
1069
- return false;
1070
-
1071
- if (zoomLevel > this.settings.maxZoomLevel)
1072
- zoomLevel = this.settings.maxZoomLevel;
1073
-
1074
- const pg = this.settings.manifest.pages[parseInt(pageIdx, 10)];
1075
- const pgAtZoom = pg.d[parseInt(zoomLevel, 10)];
1076
-
1077
- return {
1078
- width: pgAtZoom.w,
1079
- height: pgAtZoom.h
1080
- };
1081
- }
1082
-
1083
- /**
1084
- * Returns a URL for the image of the page at the given index. The
1085
- * optional size parameter supports setting the image width or height
1086
- * (default is full-sized).
1087
- *
1088
- * @public
1089
- * @params {number} pageIndex - 0-based page index
1090
- * @params {?object} size - an object containing width and height information
1091
- * @returns {string} - The IIIF URL for a given page at an optional size
1092
- */
1093
- getPageImageURL (pageIndex, size)
1094
- {
1095
- return this.settings.manifest.getPageImageURL(pageIndex, size);
1096
- }
1097
-
1098
- /**
1099
- * Given a set of co-ordinates (e.g., from a mouse click), return the 0-based page index
1100
- * for which it matches.
1101
- *
1102
- * @public
1103
- * @params {number} pageX - The x co-ordinate
1104
- * @params {number} pageY - The y co-ordinate
1105
- * @returns {number} - The page index matching the co-ordinates.
1106
- * */
1107
- getPageIndexForPageXYValues (pageX, pageY)
1108
- {
1109
- return this._getPageIndexForPageXYValues(pageX, pageY);
1110
- }
1111
-
1112
- /**
1113
- * Returns distance between the northwest corners of diva-inner and page index.
1114
- *
1115
- * @public
1116
- * @params {number} pageIndex - The 0-based page index
1117
- * @params {?options} options - A set of options to pass in.
1118
- * @returns {object} - The offset between the upper left corner and the page.
1119
- *
1120
- * */
1121
- getPageOffset (pageIndex, options)
1122
- {
1123
- const region = this.divaState.viewerCore.getPageRegion(pageIndex, options);
1124
-
1125
- return {
1126
- top: region.top,
1127
- left: region.left
1128
- };
1129
- }
1130
-
1131
- /**
1132
- * Get the instance settings.
1133
- *
1134
- * @public
1135
- * @returns {object} - The current instance settings.
1136
- * */
1137
- getSettings ()
1138
- {
1139
- return this.settings;
1140
- }
1141
-
1142
- /**
1143
- * Get an object representing the complete state of the viewer.
1144
- *
1145
- * @public
1146
- * @returns {object} - The current instance state.
1147
- * */
1148
- getState ()
1149
- {
1150
- return this._getState();
1151
- }
1152
-
1153
- /**
1154
- * Get the current zoom level.
1155
- *
1156
- * @public
1157
- * @returns {number} - The current zoom level.
1158
- * */
1159
- getZoomLevel ()
1160
- {
1161
- return this.settings.zoomLevel;
1162
- }
1163
-
1164
- /**
1165
- * Go to a particular page (with indexing starting at 0).
1166
- * The (xAnchor) side of the page will be anchored to the (xAnchor) side of the diva-outer element
1167
- *
1168
- * @public
1169
- * @params {number} pageIndex - 0-based page index.
1170
- * @params {?string} xAnchor - may either be "left", "right", or default "center"
1171
- * @params {?string} yAnchor - may either be "top", "bottom", or default "center"; same process as xAnchor.
1172
- * @returns {boolean} - True if the page index is valid; false if it is not.
1173
- * */
1174
- gotoPageByIndex (pageIndex, xAnchor, yAnchor)
1175
- {
1176
- return this._gotoPageByIndex(pageIndex, xAnchor, yAnchor);
1177
- }
1178
-
1179
- /**
1180
- * Given a canvas label, attempt to go to that page. If no label was found.
1181
- * the label will be attempted to match against the page index.
1182
- *
1183
- * @public
1184
- * @params {string} label - The label to search on.
1185
- * @params {?string} xAnchor - may either be "left", "right", or default "center"
1186
- * @params {?string} yAnchor - may either be "top", "bottom", or default "center"
1187
- * @returns {boolean} - True if the page index is valid; false if it is not.
1188
- * */
1189
- gotoPageByLabel (label, xAnchor, yAnchor)
1190
- {
1191
- const pages = this.settings.manifest.pages;
1192
- let llc = label.toLowerCase();
1193
-
1194
- for (let i = 0, len = pages.length; i < len; i++)
1195
- {
1196
- if (pages[i].l.toLowerCase().indexOf(llc) > -1)
1197
- return this._gotoPageByIndex(i, xAnchor, yAnchor);
1198
- }
1199
-
1200
- const pageIndex = parseInt(label, 10) - 1;
1201
- return this._gotoPageByIndex(pageIndex, xAnchor, yAnchor);
1202
- }
1203
-
1204
- /**
1205
- * Jump to a page based on its filename. Deprecated. Use gotoPageByURI instead.
1206
- *
1207
- * @public
1208
- * @params {string} filename - The filename of the image to jump to.
1209
- * @params {?string} xAnchor - may either be "left", "right", or default "center"
1210
- * @params {?string} yAnchor - may either be "top", "bottom", or default "center"
1211
- * @returns {boolean} true if successful and false if the filename is not found.
1212
- */
1213
- gotoPageByName (filename, xAnchor, yAnchor)
1214
- {
1215
- console.warn('This method will be removed in the next version of Diva.js. Use gotoPageByURI instead.');
1216
- const pageIndex = this._getPageIndex(filename);
1217
- return this._gotoPageByIndex(pageIndex, xAnchor, yAnchor);
1218
- }
1219
-
1220
- /**
1221
- * Jump to a page based on its URI.
1222
- *
1223
- * @public
1224
- * @params {string} uri - The URI of the image to jump to.
1225
- * @params {?string} xAnchor - may either be "left", "right", or default "center"
1226
- * @params {?string} yAnchor - may either be "top", "bottom", or default "center"
1227
- * @returns {boolean} true if successful and false if the URI is not found.
1228
- */
1229
- gotoPageByURI (uri, xAnchor, yAnchor)
1230
- {
1231
- const pageIndex = this._getPageIndex(uri);
1232
- return this._gotoPageByIndex(pageIndex, xAnchor, yAnchor);
1233
- }
1234
-
1235
- /**
1236
- * Whether the page has other images to display.
1237
- *
1238
- * @public
1239
- * @params {number} pageIndex - The 0-based page index
1240
- * @returns {boolean} Whether the page has other images to display.
1241
- **/
1242
- hasOtherImages (pageIndex)
1243
- {
1244
- return this.settings.manifest.pages[pageIndex].otherImages === true;
1245
- }
1246
-
1247
- /**
1248
- * Hides the pages that are marked "non-paged" in the IIIF manifest.
1249
- *
1250
- * @public
1251
- **/
1252
- hideNonPagedPages ()
1253
- {
1254
- this._reloadViewer({ showNonPagedPages: false });
1255
- }
1256
-
1257
- /**
1258
- * Is the viewer currently in full-screen mode?
1259
- *
1260
- * @public
1261
- * @returns {boolean} - Whether the viewer is in fullscreen mode.
1262
- **/
1263
- isInFullscreen ()
1264
- {
1265
- return this.settings.inFullscreen;
1266
- }
1267
-
1268
- /**
1269
- * Check if a page index is within the range of the document
1270
- *
1271
- * @public
1272
- * @returns {boolean} - Whether the page index is valid.
1273
- **/
1274
- isPageIndexValid (pageIndex)
1275
- {
1276
- return this._isPageIndexValid(pageIndex);
1277
- }
1278
-
1279
- /**
1280
- * Determines if a page is currently in the viewport
1281
- *
1282
- * @public
1283
- * @params {number} pageIndex - The 0-based page index
1284
- * @returns {boolean} - Whether the page is currently in the viewport.
1285
- **/
1286
- isPageInViewport (pageIndex)
1287
- {
1288
- return this.viewerState.renderer.isPageVisible(pageIndex);
1289
- }
1290
-
1291
- /**
1292
- * Whether the Diva viewer has been fully initialized.
1293
- *
1294
- * @public
1295
- * @returns {boolean} - True if the viewer is initialized; false otherwise.
1296
- **/
1297
- isReady ()
1298
- {
1299
- return this.viewerState.loaded;
1300
- }
1301
-
1302
- /**
1303
- * Check if something (e.g. a highlight box on a particular page) is visible
1304
- *
1305
- * @public
1306
- * @params {number} pageIndex - The 0-based page index
1307
- * @params {number} leftOffset - The distance of the region from the left of the viewport
1308
- * @params {number} topOffset - The distance of the region from the top of the viewport
1309
- * @params {number} width - The width of the region
1310
- * @params {number} height - The height of the region
1311
- * @returns {boolean} - Whether the region is in the viewport.
1312
- **/
1313
- isRegionInViewport (pageIndex, leftOffset, topOffset, width, height)
1314
- {
1315
- const layout = this.divaState.viewerCore.getCurrentLayout();
1316
-
1317
- if (!layout)
1318
- return false;
1319
-
1320
- const offset = layout.getPageOffset(pageIndex);
1321
-
1322
- const top = offset.top + topOffset;
1323
- const left = offset.left + leftOffset;
1324
-
1325
- return this.viewerState.viewport.intersectsRegion({
1326
- top: top,
1327
- bottom: top + height,
1328
- left: left,
1329
- right: left + width
1330
- });
1331
- }
1332
-
1333
- /**
1334
- * Whether the page layout is vertically or horizontally oriented.
1335
- *
1336
- * @public
1337
- * @returns {boolean} - True if vertical; false if horizontal.
1338
- **/
1339
- isVerticallyOriented ()
1340
- {
1341
- return this.settings.verticallyOriented;
1342
- }
1343
-
1344
- /**
1345
- * Leave fullscreen mode if currently in fullscreen mode.
1346
- *
1347
- * @public
1348
- * @returns {boolean} - true if in fullscreen mode intitially, false otherwise
1349
- **/
1350
- leaveFullscreenMode ()
1351
- {
1352
- if (this.settings.inFullscreen)
1353
- {
1354
- this._toggleFullscreen();
1355
- return true;
1356
- }
1357
-
1358
- return false;
1359
- }
1360
-
1361
- /**
1362
- * Leave grid view if currently in grid view.
1363
- *
1364
- * @public
1365
- * @returns {boolean} - true if in grid view initially, false otherwise
1366
- **/
1367
- leaveGridView ()
1368
- {
1369
- if (this.settings.inGrid)
1370
- {
1371
- this._reloadViewer({ inGrid: false });
1372
- return true;
1373
- }
1374
-
1375
- return false;
1376
- }
1377
-
1378
- /**
1379
- * Set the number of grid pages per row.
1380
- *
1381
- * @public
1382
- * @params {number} pagesPerRow - The number of pages per row
1383
- * @returns {boolean} - True if the operation was successful.
1384
- **/
1385
- setGridPagesPerRow (pagesPerRow)
1386
- {
1387
- // TODO(wabain): Add test case
1388
- if (!this.divaState.viewerCore.isValidOption('pagesPerRow', pagesPerRow))
1389
- return false;
1390
-
1391
- return this._reloadViewer({
1392
- inGrid: true,
1393
- pagesPerRow: pagesPerRow
1394
- });
1395
- }
1396
-
1397
- /**
1398
- * Align this diva instance with a state object (as returned by getState)
1399
- *
1400
- * @public
1401
- * @params {object} state - A Diva state object.
1402
- * @returns {boolean} - True if the operation was successful.
1403
- **/
1404
- setState (state)
1405
- {
1406
- this._reloadViewer(this._getLoadOptionsForState(state));
1407
- }
1408
-
1409
- /**
1410
- * Sets the zoom level.
1411
- *
1412
- * @public
1413
- * @returns {boolean} - True if the operation was successful.
1414
- **/
1415
- setZoomLevel (zoomLevel)
1416
- {
1417
- if (this.settings.inGrid)
1418
- {
1419
- this._reloadViewer({
1420
- inGrid: false
1421
- });
1422
- }
1423
-
1424
- return this.divaState.viewerCore.zoom(zoomLevel);
1425
- }
1426
-
1427
- /**
1428
- * Show non-paged pages.
1429
- *
1430
- * @public
1431
- * @returns {boolean} - True if the operation was successful.
1432
- **/
1433
- showNonPagedPages ()
1434
- {
1435
- this._reloadViewer({ showNonPagedPages: true });
1436
- }
1437
-
1438
- /**
1439
- * Toggle fullscreen mode.
1440
- *
1441
- * @public
1442
- * @returns {boolean} - True if the operation was successful.
1443
- **/
1444
- toggleFullscreenMode ()
1445
- {
1446
- this._toggleFullscreen();
1447
- }
1448
-
1449
- /**
1450
- * Show/Hide non-paged pages
1451
- *
1452
- * @public
1453
- * @returns {boolean} - True if the operation was successful.
1454
- **/
1455
- toggleNonPagedPagesVisibility ()
1456
- {
1457
- this._reloadViewer({
1458
- showNonPagedPages: !this.settings.showNonPagedPages
1459
- });
1460
- }
1461
-
1462
- //Changes between horizontal layout and vertical layout. Returns true if document is now vertically oriented, false otherwise.
1463
- toggleOrientation ()
1464
- {
1465
- return this._togglePageLayoutOrientation();
1466
- }
1467
-
1468
- /**
1469
- * Translates a measurement from the zoom level on the largest size
1470
- * to one on the current zoom level.
1471
- *
1472
- * For example, a point 1000 on an image that is on zoom level 2 of 5
1473
- * translates to a position of 111.111... (1000 / (5 - 2)^2).
1474
- *
1475
- * Works for a single pixel co-ordinate or a dimension (e.g., translates a box
1476
- * that is 1000 pixels wide on the original to one that is 111.111 pixels wide
1477
- * on the current zoom level).
1478
- *
1479
- * @public
1480
- * @params {number} position - A point on the max zoom level
1481
- * @returns {number} - The same point on the current zoom level.
1482
- */
1483
- translateFromMaxZoomLevel (position)
1484
- {
1485
- const zoomDifference = this.settings.maxZoomLevel - this.settings.zoomLevel;
1486
- return position / Math.pow(2, zoomDifference);
1487
- }
1488
-
1489
- /**
1490
- * Translates a measurement from the current zoom level to the position on the
1491
- * largest zoom level.
1492
- *
1493
- * Works for a single pixel co-ordinate or a dimension (e.g., translates a box
1494
- * that is 111.111 pixels wide on the current image to one that is 1000 pixels wide
1495
- * on the current zoom level).
1496
- *
1497
- * @public
1498
- * @params {number} position - A point on the current zoom level
1499
- * @returns {number} - The same point on the max zoom level.
1500
- */
1501
- translateToMaxZoomLevel (position)
1502
- {
1503
- const zoomDifference = this.settings.maxZoomLevel - this.settings.zoomLevel;
1504
-
1505
- // if there is no difference, it's a box on the max zoom level and
1506
- // we can just return the position.
1507
- if (zoomDifference === 0)
1508
- return position;
1509
-
1510
- return position * Math.pow(2, zoomDifference);
1511
- }
1512
-
1513
- /**
1514
- * Zoom in.
1515
- *
1516
- * @public
1517
- * @returns {boolean} - false if it's at the maximum zoom
1518
- **/
1519
- zoomIn ()
1520
- {
1521
- return this.setZoomLevel(this.settings.zoomLevel + 1);
1522
- }
1523
-
1524
- /**
1525
- * Zoom out.
1526
- * @returns {boolean} - false if it's at the minimum zoom
1527
- **/
1528
- zoomOut ()
1529
- {
1530
- return this.setZoomLevel(this.settings.zoomLevel - 1);
1531
- }
1532
- }
1533
-
1534
- export default Diva;
1535
-
1536
- /**
1537
- * Make `Diva` available in the global context.
1538
- * */
1539
- (function (global)
1540
- {
1541
- global.Diva = global.Diva || Diva;
1542
- global.Diva.Events = diva.Events;
1543
- })(window);