diva.js 6.0.1 → 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 (133) 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 -108
  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/_site/diva.iml +0 -11
  40. package/build/diva.css +0 -554
  41. package/build/diva.css.map +0 -1
  42. package/build/diva.js +0 -9
  43. package/build/diva.js.map +0 -1
  44. package/build/plugins/download.js +0 -2
  45. package/build/plugins/download.js.map +0 -1
  46. package/build/plugins/manipulation.js +0 -2
  47. package/build/plugins/manipulation.js.map +0 -1
  48. package/build/plugins/metadata.js +0 -2
  49. package/build/plugins/metadata.js.map +0 -1
  50. package/diva.iml +0 -11
  51. package/index.html +0 -28
  52. package/karma.conf.js +0 -87
  53. package/source/css/_mixins.scss +0 -43
  54. package/source/css/_variables.scss +0 -50
  55. package/source/css/_viewer.scss +0 -462
  56. package/source/css/diva.scss +0 -15
  57. package/source/css/plugins/_manipulation.scss +0 -228
  58. package/source/css/plugins/_metadata.scss +0 -31
  59. package/source/img/adjust.svg +0 -11
  60. package/source/img/book-view.svg +0 -6
  61. package/source/img/close.svg +0 -6
  62. package/source/img/download.svg +0 -6
  63. package/source/img/from-fullscreen.svg +0 -8
  64. package/source/img/grid-fewer.svg +0 -6
  65. package/source/img/grid-more.svg +0 -6
  66. package/source/img/grid-view.svg +0 -6
  67. package/source/img/link.svg +0 -6
  68. package/source/img/metadata.svg +0 -9
  69. package/source/img/page-view.svg +0 -6
  70. package/source/img/to-fullscreen.svg +0 -11
  71. package/source/img/zoom-in.svg +0 -6
  72. package/source/img/zoom-out.svg +0 -7
  73. package/source/js/composite-image.js +0 -174
  74. package/source/js/diva-global.js +0 -7
  75. package/source/js/diva.js +0 -1543
  76. package/source/js/document-handler.js +0 -180
  77. package/source/js/document-layout.js +0 -286
  78. package/source/js/exceptions.js +0 -26
  79. package/source/js/gesture-events.js +0 -190
  80. package/source/js/grid-handler.js +0 -122
  81. package/source/js/iiif-source-adapter.js +0 -63
  82. package/source/js/image-cache.js +0 -113
  83. package/source/js/image-manifest.js +0 -157
  84. package/source/js/image-request-handler.js +0 -76
  85. package/source/js/interpolate-animation.js +0 -122
  86. package/source/js/page-layouts/book-layout.js +0 -161
  87. package/source/js/page-layouts/grid-layout.js +0 -97
  88. package/source/js/page-layouts/index.js +0 -38
  89. package/source/js/page-layouts/page-dimensions.js +0 -9
  90. package/source/js/page-layouts/singles-layout.js +0 -27
  91. package/source/js/page-overlay-manager.js +0 -102
  92. package/source/js/page-tools-overlay.js +0 -95
  93. package/source/js/parse-iiif-manifest.js +0 -302
  94. package/source/js/plugins/_filters.js +0 -679
  95. package/source/js/plugins/download.js +0 -83
  96. package/source/js/plugins/manipulation.js +0 -837
  97. package/source/js/plugins/metadata.js +0 -190
  98. package/source/js/renderer.js +0 -584
  99. package/source/js/settings-view.js +0 -30
  100. package/source/js/tile-coverage-map.js +0 -25
  101. package/source/js/toolbar.js +0 -572
  102. package/source/js/utils/dragscroll.js +0 -106
  103. package/source/js/utils/elt.js +0 -94
  104. package/source/js/utils/events.js +0 -190
  105. package/source/js/utils/get-scrollbar-width.js +0 -29
  106. package/source/js/utils/hash-params.js +0 -86
  107. package/source/js/utils/parse-label-value.js +0 -34
  108. package/source/js/utils/vanilla.kinetic.js +0 -527
  109. package/source/js/validation-runner.js +0 -177
  110. package/source/js/viewer-core.js +0 -1505
  111. package/source/js/viewport.js +0 -143
  112. package/test/_setup.js +0 -13
  113. package/test/composite-image_test.js +0 -94
  114. package/test/diva_test.js +0 -43
  115. package/test/hash-params_test.js +0 -221
  116. package/test/image-cache_test.js +0 -106
  117. package/test/main.js +0 -6
  118. package/test/manifests/beromunsterManifest.json +0 -15514
  119. package/test/manifests/iiifv2.json +0 -11032
  120. package/test/manifests/iiifv2pages.json +0 -30437
  121. package/test/manifests/iiifv3.json +0 -10965
  122. package/test/navigation_test.js +0 -355
  123. package/test/parse-iiif-manifest_test.js +0 -68
  124. package/test/public_test.js +0 -881
  125. package/test/settings_test.js +0 -487
  126. package/test/utils/book-layout_test.js +0 -148
  127. package/test/utils/elt_test.js +0 -102
  128. package/test/utils/events_test.js +0 -245
  129. package/test/utils/hash-params_test.js +0 -79
  130. package/test/utils/parse-label-value_test.js +0 -45
  131. package/test/z_plugins_test.js +0 -180
  132. package/webpack.config.js +0 -58
  133. package/webpack.config.test.js +0 -45
@@ -1,302 +0,0 @@
1
- import parseLabelValue from './utils/parse-label-value';
2
-
3
- const getMaxZoomLevel = (width, height) =>
4
- {
5
- const largestDimension = Math.max(width, height);
6
- if (largestDimension < 128)
7
- return 0;
8
- return Math.ceil(Math.log((largestDimension + 1) / (256 + 1)) / Math.log(2));
9
- };
10
-
11
- const incorporateZoom = (imageDimension, zoomDifference) => imageDimension / (Math.pow(2, zoomDifference));
12
-
13
- const getOtherImageData = (otherImages, lowestMaxZoom) =>
14
- {
15
- return otherImages.map( (itm) =>
16
- {
17
- const w = itm.width;
18
- const h = itm.height;
19
- const info = parseImageInfo(itm);
20
- const url = info.url.slice(-1) !== '/' ? info.url + '/' : info.url; // append trailing slash to url if it's not there.
21
-
22
- const dims = new Array(lowestMaxZoom + 1);
23
- for (let j = 0; j < lowestMaxZoom + 1; j++)
24
- {
25
- dims[j] = {
26
- h: Math.floor(incorporateZoom(h, lowestMaxZoom - j)),
27
- w: Math.floor(incorporateZoom(w, lowestMaxZoom - j))
28
- };
29
- }
30
-
31
- return {
32
- f: info.url,
33
- url: url,
34
- il: itm.label || "",
35
- d: dims
36
- };
37
- });
38
- };
39
-
40
- const getIIIFPresentationVersion = (context) =>
41
- {
42
- if (context === "http://iiif.io/api/presentation/2/context.json")
43
- return 2;
44
- else if (Array.isArray(context) && context.includes("http://iiif.io/api/presentation/2/context.json"))
45
- return 2;
46
- else if (Array.isArray(context) && context.includes("http://iiif.io/api/presentation/3/context.json"))
47
- return 3;
48
- else
49
- return 2; // Assume a v2 manifest.
50
- };
51
-
52
- /**
53
- * Parses an IIIF Presentation API Manifest and converts it into a Diva.js-format object
54
- * (See https://github.com/DDMAL/diva.js/wiki/Development-notes#data-received-through-ajax-request)
55
- *
56
- * @param {Object} manifest - an object that represents a valid IIIF manifest
57
- * @returns {Object} divaServiceBlock - the data needed by Diva to show a view of a single document
58
- */
59
- export default function parseIIIFManifest (manifest)
60
- {
61
- let ctx = manifest["@context"];
62
-
63
- if (!ctx)
64
- {
65
- console.error("Invalid IIIF Manifest; No @context found.");
66
- return null;
67
- }
68
-
69
- const version = getIIIFPresentationVersion(ctx);
70
- const sequence = manifest.sequences ? manifest.sequences[0] : null;
71
- const canvases = sequence ? sequence.canvases : manifest.items;
72
- const numCanvases = canvases.length;
73
-
74
- const pages = new Array(canvases.length);
75
-
76
- let thisCanvas,
77
- thisResource,
78
- thisImage,
79
- secondaryImages,
80
- otherImages = [],
81
- context,
82
- url,
83
- info,
84
- imageAPIVersion,
85
- width,
86
- height,
87
- maxZoom,
88
- canvas,
89
- label,
90
- imageLabel,
91
- zoomDimensions,
92
- widthAtCurrentZoomLevel,
93
- heightAtCurrentZoomLevel;
94
-
95
- let lowestMaxZoom = 100;
96
- let maxRatio = 0;
97
- let minRatio = 100;
98
-
99
- // quickly determine the lowest possible max zoom level (i.e., the upper bound for images) across all canvases.
100
- // while we're here, compute the global ratios as well.
101
- for (let z = 0; z < numCanvases; z++)
102
- {
103
- const c = canvases[z];
104
- const w = c.width;
105
- const h = c.height;
106
- const mz = getMaxZoomLevel(w, h);
107
- const ratio = h / w;
108
- maxRatio = Math.max(ratio, maxRatio);
109
- minRatio = Math.min(ratio, minRatio);
110
-
111
- lowestMaxZoom = Math.min(lowestMaxZoom, mz);
112
- }
113
-
114
- /*
115
- These arrays need to be pre-initialized since we will do arithmetic and value checking on them
116
- */
117
- const totalWidths = new Array(lowestMaxZoom + 1).fill(0);
118
- const totalHeights = new Array(lowestMaxZoom + 1).fill(0);
119
- const maxWidths = new Array(lowestMaxZoom + 1).fill(0);
120
- const maxHeights = new Array(lowestMaxZoom + 1).fill(0);
121
-
122
- for (let i = 0; i < numCanvases; i++)
123
- {
124
- thisCanvas = canvases[i];
125
- canvas = thisCanvas['@id'] || thisCanvas.id;
126
- label = thisCanvas.label;
127
- thisResource = thisCanvas.images ? thisCanvas.images[0].resource : thisCanvas.items[0].items[0].body;
128
-
129
- /*
130
- * If a canvas has multiple images it will be encoded
131
- * with a resource type of "oa:Choice" (v2) or "Choice" (v3).
132
- **/
133
- otherImages = []; // reset array
134
- if (thisResource['@type'] === "oa:Choice" || thisResource.type === "Choice")
135
- {
136
- thisImage = thisResource.default || thisResource.items[0];
137
- secondaryImages = thisResource.item || thisResource.items.slice(1);
138
- otherImages = getOtherImageData(secondaryImages, lowestMaxZoom);
139
- }
140
- else
141
- {
142
- thisImage = thisResource;
143
- }
144
-
145
- // Prioritize the canvas height / width first, since images may not have h/w
146
- width = thisCanvas.width || thisImage.width;
147
- height = thisCanvas.height || thisImage.height;
148
-
149
- if (width <= 0 || height <= 0)
150
- {
151
- console.warn('Invalid width or height for canvas ' + label + '. Skipping');
152
- continue;
153
- }
154
-
155
- maxZoom = getMaxZoomLevel(width, height);
156
-
157
- imageLabel = thisImage.label || null;
158
-
159
- info = parseImageInfo(thisImage);
160
- url = info.url.slice(-1) !== '/' ? info.url + '/' : info.url; // append trailing slash to url if it's not there.
161
-
162
- context = thisImage.service['@context'] || thisImage.service.type;
163
-
164
- if (context === 'http://iiif.io/api/image/2/context.json' || context === "ImageService2")
165
- {
166
- imageAPIVersion = 2;
167
- }
168
- else if (context === 'http://library.stanford.edu/iiif/image-api/1.1/context.json')
169
- {
170
- imageAPIVersion = 1.1;
171
- }
172
- else
173
- {
174
- imageAPIVersion = 1.0;
175
- }
176
-
177
- zoomDimensions = new Array(lowestMaxZoom + 1);
178
-
179
- for (let k = 0; k < lowestMaxZoom + 1; k++)
180
- {
181
- widthAtCurrentZoomLevel = Math.floor(incorporateZoom(width, lowestMaxZoom - k));
182
- heightAtCurrentZoomLevel = Math.floor(incorporateZoom(height, lowestMaxZoom - k));
183
- zoomDimensions[k] = {
184
- h: heightAtCurrentZoomLevel,
185
- w: widthAtCurrentZoomLevel
186
- };
187
-
188
- totalWidths[k] += widthAtCurrentZoomLevel;
189
- totalHeights[k] += heightAtCurrentZoomLevel;
190
- maxWidths[k] = Math.max(widthAtCurrentZoomLevel, maxWidths[k]);
191
- maxHeights[k] = Math.max(heightAtCurrentZoomLevel, maxHeights[k]);
192
- }
193
-
194
- let isPaged = thisCanvas.viewingHint !== 'non-paged' || (thisCanvas.behavior ? thisCanvas.behavior[0] !== 'non-paged' : false);
195
- let isFacing = thisCanvas.viewingHint === 'facing-pages' || (thisCanvas.behavior ? thisCanvas.behavior[0] === 'facing-pages' : false);
196
-
197
- pages[i] = {
198
- d: zoomDimensions,
199
- m: maxZoom,
200
- l: label, // canvas label ('page 1, page 2', etc.)
201
- il: imageLabel, // default image label ('primary image', 'UV light', etc.)
202
- f: info.url,
203
- url: url,
204
- api: imageAPIVersion,
205
- paged: isPaged,
206
- facingPages: isFacing,
207
- canvas: canvas,
208
- otherImages: otherImages,
209
- xoffset: info.x || null,
210
- yoffset: info.y || null
211
- };
212
- }
213
-
214
- const averageWidths = new Array(lowestMaxZoom + 1);
215
- const averageHeights = new Array(lowestMaxZoom + 1);
216
-
217
- for (let a = 0; a < lowestMaxZoom + 1; a++)
218
- {
219
- averageWidths[a] = totalWidths[a] / numCanvases;
220
- averageHeights[a] = totalHeights[a] / numCanvases;
221
- }
222
-
223
- const dims = {
224
- a_wid: averageWidths,
225
- a_hei: averageHeights,
226
- max_w: maxWidths,
227
- max_h: maxHeights,
228
- max_ratio: maxRatio,
229
- min_ratio: minRatio,
230
- t_hei: totalHeights,
231
- t_wid: totalWidths
232
- };
233
-
234
- // assumes paged is false for non-paged values
235
- return {
236
- version: version,
237
- item_title: parseLabelValue(manifest).label,
238
- metadata: manifest.metadata || null,
239
- dims: dims,
240
- max_zoom: lowestMaxZoom,
241
- pgs: pages,
242
- paged: manifest.viewingHint === 'paged' || (manifest.behaviour ? manifest.behaviour[0] === 'paged' : false) || (sequence ? sequence.viewingHint === 'paged' : false)
243
- };
244
- }
245
-
246
- /**
247
- * Takes in a resource block from a canvas and outputs the following information associated with that resource:
248
- * - Image URL
249
- * - Image region to be displayed
250
- *
251
- * @param {Object} resource - an object representing the resource block of a canvas section in a IIIF manifest
252
- * @returns {Object} imageInfo - an object containing image URL and region
253
- */
254
- function parseImageInfo (resource)
255
- {
256
- let url = resource['@id'] || resource.id;
257
- const fragmentRegex = /#xywh=([0-9]+,[0-9]+,[0-9]+,[0-9]+)/;
258
- let xywh = '';
259
- let stripURL = true;
260
-
261
- if (/\/([0-9]+,[0-9]+,[0-9]+,[0-9]+)\//.test(url))
262
- {
263
- // if resource in image API format, extract region x,y,w,h from URL (after 4th slash from last)
264
- // matches coordinates in URLs of the form http://www.example.org/iiif/book1-page1/40,50,1200,1800/full/0/default.jpg
265
- const urlArray = url.split('/');
266
- xywh = urlArray[urlArray.length - 4];
267
- }
268
- else if (fragmentRegex.test(url))
269
- {
270
- // matches coordinates of the style http://www.example.org/iiif/book1/canvas/p1#xywh=50,50,320,240
271
- const result = fragmentRegex.exec(url);
272
- xywh = result[1];
273
- }
274
- else if (resource.service && (resource.service['@id'] || resource.service.id))
275
- {
276
- // this URL excludes region parameters so we don't need to remove them
277
- url = resource.service['@id'] || resource.service.id;
278
- stripURL = false;
279
- }
280
-
281
- if (stripURL)
282
- {
283
- // extract URL up to identifier (we eliminate the last 5 parameters: /region/size/rotation/quality.format)
284
- url = url.split('/').slice(0, -4).join('/');
285
- }
286
-
287
- const imageInfo = {
288
- url: url
289
- };
290
-
291
- if (xywh.length)
292
- {
293
- // parse into separate components
294
- const dimensions = xywh.split(',');
295
- imageInfo.x = parseInt(dimensions[0], 10);
296
- imageInfo.y = parseInt(dimensions[1], 10);
297
- imageInfo.w = parseInt(dimensions[2], 10);
298
- imageInfo.h = parseInt(dimensions[3], 10);
299
- }
300
-
301
- return imageInfo;
302
- }