diva.js 6.0.2 → 7.2.4

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
@@ -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
- }