@projektemacher/storymapjs 0.10.6 → 0.10.8
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.
- package/CHANGELOG +358 -16
- package/README.md +43 -9
- package/dist/assets/demo-DBpeF31K.js +1 -0
- package/dist/assets/harness-Cr0rYpvt.js +1 -0
- package/dist/assets/harness-multi-CYHgI0a9.js +1 -0
- package/dist/assets/harness-support-Do7sIp2j.js +1 -0
- package/dist/assets/index-wHPqGrBS.js +1 -0
- package/dist/assets/main-DXalctuR.js +17 -0
- package/dist/context.json +12 -9
- package/dist/css/fonts/files/amatic-sc-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/amatic-sc-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/amatic-sc-hebrew-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/amatic-sc-hebrew-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/amatic-sc-vietnamese-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/amatic-sc-vietnamese-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-100-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-100-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-200-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-200-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-600-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-600-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-800-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-800-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-900-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-100-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-100-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-200-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-200-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-600-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-600-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-800-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-800-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-900-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-100-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-100-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-200-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-200-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-600-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-600-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-800-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-800-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-900-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/bitter-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-200-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-600-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-800-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-arabic-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-200-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-600-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-800-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-200-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-600-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-800-normal.woff2 +0 -0
- package/dist/css/fonts/files/cairo-latin-ext-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/dancing-script-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-cyrillic-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-cyrillic-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-greek-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-greek-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-greek-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-greek-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-vietnamese-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/eb-garamond-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-greek-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-vietnamese-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-vietnamese-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-vietnamese-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/gentium-book-plus-vietnamese-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-vietnamese-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-vietnamese-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/old-standard-tt-vietnamese-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-cyrillic-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-cyrillic-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-greek-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-greek-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-greek-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-greek-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-hebrew-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-hebrew-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-vietnamese-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/open-sans-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-cyrillic-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-cyrillic-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-cyrillic-900-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-cyrillic-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-vietnamese-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-vietnamese-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-vietnamese-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-vietnamese-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-vietnamese-900-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-sc-vietnamese-900-normal.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-vietnamese-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/playfair-display-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-narrow-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-narrow-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-narrow-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-sans-narrow-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/pt-serif-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/raleway-cyrillic-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/raleway-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/raleway-cyrillic-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/raleway-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/raleway-vietnamese-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/raleway-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/roboto-slab-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/roboto-slab-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/roboto-slab-greek-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/roboto-slab-greek-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/roboto-slab-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-300-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-300-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-400-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-500-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-500-normal.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-700-italic.woff2 +0 -0
- package/dist/css/fonts/files/ubuntu-greek-ext-700-normal.woff2 +0 -0
- package/dist/css/fonts/files/unica-one-vietnamese-400-normal.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-cyrillic-ext-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-cyrillic-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-cyrillic-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-greek-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-greek-wght-normal.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-vietnamese-wght-italic.woff2 +0 -0
- package/dist/css/fonts/files/vollkorn-vietnamese-wght-normal.woff2 +0 -0
- package/dist/css/fonts/font.abril-droidsans.css +3 -0
- package/dist/css/fonts/font.amatic-andika.css +57 -0
- package/dist/css/fonts/font.bitter-raleway.css +111 -0
- package/dist/css/fonts/font.cairo.css +312 -0
- package/dist/css/fonts/font.clicker-garamond.css +93 -0
- package/dist/css/fonts/font.dancing-ledger.css +12 -0
- package/dist/css/fonts/font.default.css +183 -0
- package/dist/css/fonts/font.fjalla-average.css +3 -0
- package/dist/css/fonts/font.georgia-helvetica.css +3 -0
- package/dist/css/fonts/font.knightlab.css +642 -0
- package/dist/css/fonts/font.lustria-lato.css +3 -0
- package/dist/css/fonts/font.medula-lato.css +3 -0
- package/dist/css/fonts/font.oldstandard.css +101 -21
- package/dist/css/fonts/font.opensans-gentiumbook.css +183 -0
- package/dist/css/fonts/font.playfair-faunaone.css +39 -0
- package/dist/css/fonts/font.playfair.css +147 -0
- package/dist/css/fonts/font.pt.css +183 -0
- package/dist/css/fonts/font.roboto-megrim.css +3 -0
- package/dist/css/fonts/font.rufina-sintony.css +3 -0
- package/dist/css/fonts/font.ubuntu.css +291 -0
- package/dist/css/fonts/font.unicaone-vollkorn.css +84 -0
- package/dist/css/storymap.css +1 -1
- package/dist/demo.html +2 -2
- package/dist/docs/api/.nojekyll +1 -0
- package/dist/docs/api/assets/custom.css +47 -0
- package/dist/docs/api/assets/hierarchy.js +1 -0
- package/dist/docs/api/assets/highlight.css +57 -0
- package/dist/docs/api/assets/icons.js +18 -0
- package/dist/docs/api/assets/icons.svg +1 -0
- package/dist/docs/api/assets/main.js +60 -0
- package/dist/docs/api/assets/navigation.js +1 -0
- package/dist/docs/api/assets/search.js +1 -0
- package/dist/docs/api/assets/style.css +1648 -0
- package/dist/docs/api/classes/StoryMap.html +1604 -0
- package/dist/docs/api/functions/MediaType.html +51 -0
- package/dist/docs/api/functions/isPresentation3Collection.html +47 -0
- package/dist/docs/api/functions/isPresentation3Manifest.html +53 -0
- package/dist/docs/api/functions/loadCSS.html +63 -0
- package/dist/docs/api/functions/manifestToStorymapData.html +49 -0
- package/dist/docs/api/functions/setLanguage.html +54 -0
- package/dist/docs/api/functions/storymapToManifest.html +57 -0
- package/dist/docs/api/functions/validateStorymap.html +53 -0
- package/dist/docs/api/functions/validateStorymapAndReport.html +54 -0
- package/dist/docs/api/hierarchy.html +28 -0
- package/dist/docs/api/index.html +197 -0
- package/dist/docs/api/interfaces/AnimationHandle.html +60 -0
- package/dist/docs/api/interfaces/ImagereadyPayload.html +71 -0
- package/dist/docs/api/interfaces/LanguageEntry.html +102 -0
- package/dist/docs/api/interfaces/LatLngLiteral.html +73 -0
- package/dist/docs/api/interfaces/LoadOptions.html +59 -0
- package/dist/docs/api/interfaces/OlLayer.html +1400 -0
- package/dist/docs/api/interfaces/OlMap.html +1656 -0
- package/dist/docs/api/interfaces/OlProjection.html +332 -0
- package/dist/docs/api/interfaces/OlSource.html +784 -0
- package/dist/docs/api/interfaces/OlTileLayer.html +1497 -0
- package/dist/docs/api/interfaces/OlVectorLayer.html +1559 -0
- package/dist/docs/api/interfaces/OlView.html +1958 -0
- package/dist/docs/api/interfaces/StorymapData.html +71 -0
- package/dist/docs/api/interfaces/StorymapDataWrapper.html +60 -0
- package/dist/docs/api/interfaces/StorymapDocument.html +68 -0
- package/dist/docs/api/interfaces/StorymapError.html +63 -0
- package/dist/docs/api/interfaces/StorymapGeoreference.html +93 -0
- package/dist/docs/api/interfaces/StorymapGeoreferenceBody.html +74 -0
- package/dist/docs/api/interfaces/StorymapGroundControlPoint.html +69 -0
- package/dist/docs/api/interfaces/StorymapLanguageMap.html +57 -0
- package/dist/docs/api/interfaces/StorymapManifest.html +118 -0
- package/dist/docs/api/interfaces/StorymapManifestAnnotation.html +105 -0
- package/dist/docs/api/interfaces/StorymapManifestBackground.html +81 -0
- package/dist/docs/api/interfaces/StorymapManifestCanvas.html +140 -0
- package/dist/docs/api/interfaces/StorymapManifestContentResource.html +97 -0
- package/dist/docs/api/interfaces/StorymapManifestFeatureCollection.html +82 -0
- package/dist/docs/api/interfaces/StorymapManifestGeoreferencing.html +87 -0
- package/dist/docs/api/interfaces/StorymapManifestImageService.html +69 -0
- package/dist/docs/api/interfaces/StorymapManifestRange.html +75 -0
- package/dist/docs/api/interfaces/StorymapManifestService.html +77 -0
- package/dist/docs/api/interfaces/StorymapManifestSpecificResource.html +69 -0
- package/dist/docs/api/interfaces/StorymapManifestStatement.html +63 -0
- package/dist/docs/api/interfaces/StorymapMapOptions.html +92 -0
- package/dist/docs/api/interfaces/StorymapOptions.html +532 -0
- package/dist/docs/api/interfaces/StorymapOverlayLayer.html +126 -0
- package/dist/docs/api/interfaces/StorymapSlide.html +132 -0
- package/dist/docs/api/interfaces/StorymapSlideBackground.html +72 -0
- package/dist/docs/api/interfaces/StorymapSlideLocation.html +117 -0
- package/dist/docs/api/interfaces/StorymapSlideMarker.html +104 -0
- package/dist/docs/api/interfaces/StorymapSlideMedia.html +110 -0
- package/dist/docs/api/interfaces/StorymapSlideNarration.html +65 -0
- package/dist/docs/api/interfaces/StorymapSlideText.html +72 -0
- package/dist/docs/api/interfaces/StorymapTilejson.html +105 -0
- package/dist/docs/api/media/es.json +31 -0
- package/dist/docs/api/media/migration-from-knightlab.md +359 -0
- package/dist/docs/api/modules.html +50 -0
- package/dist/docs/api/types/ContentState.html +70 -0
- package/dist/docs/api/types/ImagereadyKind.html +34 -0
- package/dist/docs/api/types/MediaTypeMatch.html +78 -0
- package/dist/docs/api/types/TileSourceFactory.html +53 -0
- package/dist/docs/authoring.html +293 -0
- package/dist/docs/iiif.html +617 -62
- package/dist/docs/migration.html +314 -12
- package/dist/docs/readme.html +40 -9
- package/dist/embed/index.html +130 -5
- package/dist/examples/issue-242-nonlatin.json +55 -0
- package/dist/examples/issue-305-start-at-slide-data.json +96 -0
- package/dist/examples/issue-358-iframe.json +57 -0
- package/dist/examples/issue-iiif-geo.json +32 -0
- package/dist/examples/issue-image-alt.json +23 -0
- package/dist/examples/issue-image-region.json +42 -0
- package/dist/examples/issue-image-srcset.json +24 -0
- package/dist/examples/map-area-overlays.json +68 -0
- package/dist/examples/no-map.json +44 -0
- package/dist/examples-iiif/annotated-image.json +188 -0
- package/dist/examples-iiif/bob-boilen.json +11 -5
- package/dist/examples-iiif/courbet.json +9 -6
- package/dist/examples-iiif/empty.json +8 -4
- package/dist/examples-iiif/flickr-drewvigal.json +248 -24
- package/dist/examples-iiif/flickr-zach.wise.json +8 -4
- package/dist/examples-iiif/georeferenced-layer-unsupported.json +153 -0
- package/dist/examples-iiif/georeferenced-layer.json +318 -0
- package/dist/examples-iiif/iiif-wellcome.json +9 -6
- package/dist/examples-iiif/instagram-chenpamela.json +381 -36
- package/dist/examples-iiif/instagram_brentfoster.json +429 -40
- package/dist/examples-iiif/instagram_couch.json +261 -26
- package/dist/examples-iiif/instagram_joegermuska.json +441 -41
- package/dist/examples-iiif/instagram_matteich.json +261 -26
- package/dist/examples-iiif/instagram_mirandamulligan.json +261 -26
- package/dist/examples-iiif/instagram_raymondmccrea.json +261 -26
- package/dist/examples-iiif/instagram_test.json +261 -26
- package/dist/examples-iiif/issue-134-no-lines.json +9 -5
- package/dist/examples-iiif/issue-177-color-vars.json +9 -5
- package/dist/examples-iiif/issue-211-rtl.json +9 -5
- package/dist/examples-iiif/issue-242-nonlatin.json +239 -0
- package/dist/examples-iiif/issue-272-facebook.json +9 -5
- package/dist/examples-iiif/issue-305-start-at-slide-data.json +305 -0
- package/dist/examples-iiif/issue-305-start-at-slide.json +9 -5
- package/dist/examples-iiif/issue-341-distance.json +9 -5
- package/dist/examples-iiif/issue-358-iframe.json +190 -0
- package/dist/examples-iiif/issue-360-juxtapose.json +22 -7
- package/dist/examples-iiif/issue-368-null-fields.json +9 -5
- package/dist/examples-iiif/issue-375-code-lists.json +9 -5
- package/dist/examples-iiif/issue-381-dateline.json +9 -5
- package/dist/examples-iiif/issue-405-custom-icon.json +203 -0
- package/dist/examples-iiif/issue-425-many-slides.json +9 -5
- package/dist/examples-iiif/issue-428-background.json +20 -8
- package/dist/examples-iiif/issue-435-googlemaps.json +9 -5
- package/dist/examples-iiif/issue-437-documentcloud.json +22 -7
- package/dist/examples-iiif/issue-451-webp.json +9 -5
- package/dist/examples-iiif/issue-455-audio.json +9 -5
- package/dist/examples-iiif/issue-480-shorts.json +9 -5
- package/dist/examples-iiif/issue-506-marker-sync.json +9 -5
- package/dist/examples-iiif/issue-iiif-geo.json +200 -0
- package/dist/examples-iiif/issue-image-alt.json +90 -0
- package/dist/examples-iiif/issue-image-region.json +203 -0
- package/dist/examples-iiif/issue-image-srcset.json +87 -0
- package/dist/examples-iiif/jansteen.json +9 -6
- package/dist/examples-iiif/katrina.json +197 -41
- package/dist/examples-iiif/map-area-overlays.json +289 -0
- package/dist/examples-iiif/marktwain.json +255 -58
- package/dist/examples-iiif/no-map.json +148 -0
- package/dist/examples-iiif/population.json +440 -76
- package/dist/examples-iiif/president.json +456 -83
- package/dist/examples-iiif/scroll-hint.json +190 -0
- package/dist/examples-iiif/seurat.json +113 -22
- package/dist/examples-iiif/zoomify-clamp.json +153 -0
- package/dist/harness-multi.html +17 -0
- package/dist/harness.html +3 -2
- package/dist/index.html +33 -10
- package/dist/js/storymap.d.ts +1558 -114
- package/dist/js/storymap.js +10113 -6490
- package/dist/js/storymap.js.map +1 -1
- package/dist/navplace-properties.json +40 -0
- package/docs/migration-from-knightlab.md +359 -0
- package/docs/storymap-as-iiif-manifest.md +934 -0
- package/package.json +16 -10
- package/schema/storymap.schema.json +431 -78
- package/src/animation/easings.ts +25 -0
- package/src/animation/tween.ts +186 -0
- package/src/core/Browser.ts +20 -0
- package/src/core/Load.ts +232 -0
- package/src/core/Util.ts +416 -0
- package/src/core/mixins.ts +188 -0
- package/src/core/viewers.ts +94 -0
- package/src/dom/Dom.ts +31 -0
- package/src/dom/DomEvent.ts +80 -0
- package/src/globals.d.ts +24 -0
- package/src/language/Language.ts +281 -0
- package/src/language/locale/.expected-gaps.json +86 -0
- package/src/language/locale/be.json +31 -0
- package/src/language/locale/bg.json +31 -0
- package/src/language/locale/cs.json +31 -0
- package/src/language/locale/de.json +31 -0
- package/src/language/locale/el.json +31 -0
- package/src/language/locale/en.json +32 -0
- package/src/language/locale/es.json +31 -0
- package/src/language/locale/et.json +22 -0
- package/src/language/locale/fr.json +31 -0
- package/src/language/locale/he.json +31 -0
- package/src/language/locale/hu.json +31 -0
- package/src/language/locale/is.json +22 -0
- package/src/language/locale/it.json +31 -0
- package/src/language/locale/jp.json +31 -0
- package/src/language/locale/ko.json +31 -0
- package/src/language/locale/nl.json +31 -0
- package/src/language/locale/nn.json +22 -0
- package/src/language/locale/no.json +31 -0
- package/src/language/locale/pl.json +31 -0
- package/src/language/locale/pt.json +31 -0
- package/src/language/locale/ru.json +31 -0
- package/src/language/locale/sk.json +31 -0
- package/src/language/locale/sr.json +21 -0
- package/src/language/locale/sv.json +31 -0
- package/src/language/locale/tr.json +31 -0
- package/src/language/locale/uk.json +31 -0
- package/src/language/locale/ur.json +22 -0
- package/src/language/locale/zh-cn.json +31 -0
- package/src/language/locale/zh-tw.json +31 -0
- package/src/main.ts +143 -0
- package/src/map/Map.ts +794 -0
- package/src/map/MapMarker.ts +172 -0
- package/src/map/georeference.ts +325 -0
- package/src/map/openlayers/Map.OpenLayers.ts +2492 -0
- package/src/map/openlayers/MapMarker.OpenLayers.ts +400 -0
- package/src/map/openlayers/zoomifyTiles.ts +25 -0
- package/src/map/types.ts +17 -0
- package/src/media/EmbedUtil.ts +452 -0
- package/src/media/Media.ts +597 -0
- package/src/media/MediaType.ts +163 -0
- package/src/media/embedId.ts +104 -0
- package/src/media/types/Audio.ts +14 -0
- package/src/media/types/Blockquote.ts +39 -0
- package/src/media/types/DailyMotion.ts +53 -0
- package/src/media/types/DocumentCloud.ts +12 -0
- package/src/media/types/Facebook.ts +40 -0
- package/src/media/types/Flickr.ts +115 -0
- package/src/media/types/GoogleDoc.ts +58 -0
- package/src/media/types/HtmlMedia.ts +167 -0
- package/src/media/types/IFrame.ts +50 -0
- package/src/media/types/Image.ts +115 -0
- package/src/media/types/Juxtapose.ts +41 -0
- package/src/media/types/SoundCloud.ts +99 -0
- package/src/media/types/Text.ts +178 -0
- package/src/media/types/Twitter.ts +109 -0
- package/src/media/types/Video.ts +14 -0
- package/src/media/types/Vimeo.ts +65 -0
- package/src/media/types/Website.ts +46 -0
- package/src/media/types/Wikipedia.ts +134 -0
- package/src/media/types/YouTube.ts +224 -0
- package/src/scss/Typography.scss +235 -0
- package/src/scss/VCO.StoryMap.Dark.scss +150 -0
- package/src/scss/VCO.StoryMap.scss +195 -0
- package/src/scss/Variables.Dark.scss +57 -0
- package/src/scss/Variables.scss +48 -0
- package/src/scss/core/Mixins.scss +54 -0
- package/src/scss/core/Reset.scss +206 -0
- package/src/scss/fonts/_font.base.scss +113 -0
- package/src/scss/fonts/font.abril-droidsans.scss +75 -0
- package/src/scss/fonts/font.amatic-andika.scss +76 -0
- package/src/scss/fonts/font.bitter-raleway.scss +92 -0
- package/src/scss/fonts/font.cairo.scss +79 -0
- package/src/scss/fonts/font.clicker-garamond.scss +97 -0
- package/src/scss/fonts/font.dancing-ledger.scss +75 -0
- package/src/scss/fonts/font.default.scss +9 -0
- package/src/scss/fonts/font.fjalla-average.scss +80 -0
- package/src/scss/fonts/font.georgia-helvetica.scss +58 -0
- package/src/scss/fonts/font.knightlab.scss +111 -0
- package/src/scss/fonts/font.lustria-lato.scss +80 -0
- package/src/scss/fonts/font.medula-lato.scss +73 -0
- package/src/scss/fonts/font.oldstandard.scss +94 -0
- package/src/scss/fonts/font.opensans-gentiumbook.scss +85 -0
- package/src/scss/fonts/font.playfair-faunaone.scss +88 -0
- package/src/scss/fonts/font.playfair.scss +89 -0
- package/src/scss/fonts/font.pt.scss +96 -0
- package/src/scss/fonts/font.roboto-megrim.scss +73 -0
- package/src/scss/fonts/font.rufina-sintony.scss +73 -0
- package/src/scss/fonts/font.ubuntu.scss +82 -0
- package/src/scss/fonts/font.unicaone-vollkorn.scss +90 -0
- package/src/scss/icons/Icons.scss +239 -0
- package/src/scss/map/VCO.ImageMarker.scss +23 -0
- package/src/scss/map/VCO.Map.scss +21 -0
- package/src/scss/map/VCO.MapMarker.scss +242 -0
- package/src/scss/map/openlayers/VCO.Map.OpenLayers.scss +126 -0
- package/src/scss/media/VCO.Media.scss +219 -0
- package/src/scss/media/types/VCO.Media.Blockquote.scss +76 -0
- package/src/scss/media/types/VCO.Media.IFrame.scss +11 -0
- package/src/scss/media/types/VCO.Media.Image.scss +13 -0
- package/src/scss/media/types/VCO.Media.Text.scss +98 -0
- package/src/scss/media/types/VCO.Media.Twitter.scss +87 -0
- package/src/scss/media/types/VCO.Media.Wikipedia.scss +65 -0
- package/src/scss/site/site.scss +748 -0
- package/src/scss/slider/VCO.Slide.scss +457 -0
- package/src/scss/slider/VCO.SlideNav.scss +332 -0
- package/src/scss/slider/VCO.StorySlider.scss +66 -0
- package/src/scss/snapmap/VCO.SnapMap.scss +103 -0
- package/src/scss/ui/VCO.Consent.scss +121 -0
- package/src/scss/ui/VCO.MenuBar.Button.scss +107 -0
- package/src/scss/ui/VCO.MenuBar.scss +20 -0
- package/src/scss/ui/VCO.Message.scss +101 -0
- package/src/site/site.ts +88 -0
- package/src/slider/Slide.ts +554 -0
- package/src/slider/SlideNav.ts +246 -0
- package/src/slider/StorySlider.ts +833 -0
- package/src/storymap/Consent.ts +471 -0
- package/src/storymap/StoryMap.ts +2118 -0
- package/src/storymap/content-state.ts +185 -0
- package/src/storymap/iiif.ts +1844 -0
- package/src/storymap/to-iiif.ts +921 -0
- package/src/storymap/validate.ts +257 -0
- package/src/types.ts +494 -0
- package/src/ui/MenuBar.ts +376 -0
- package/src/ui/Message.ts +127 -0
- package/src/ui/Swipable.ts +455 -0
- package/dist/assets/demo-CVQ7kFek.js +0 -1
- package/dist/assets/harness-C-VZV-ou.js +0 -1
- package/dist/assets/index-DDsPBPZA.js +0 -1
- package/dist/assets/main-DwbXrrYn.js +0 -17
package/CHANGELOG
CHANGED
|
@@ -1,10 +1,304 @@
|
|
|
1
|
-
|
|
1
|
+
0.10.8 (2026-09-29)
|
|
2
2
|
------------------------
|
|
3
|
-
|
|
3
|
+
Code audit: one regression, a set of latent bugs, seven stored-XSS sinks, a
|
|
4
|
+
disabled type check that had been hiding them, and a dependency swap.
|
|
5
|
+
|
|
6
|
+
Added
|
|
7
|
+
-----
|
|
8
|
+
- **`map_type: "none"`: a storymap with no map.** The text and the media are
|
|
9
|
+
the whole story, which the map's unconditional construction used to make
|
|
10
|
+
impossible. No `ol/Map` is built, so there is no tile request to consent to
|
|
11
|
+
and the consent dialog omits its tile row; the overview control is hidden;
|
|
12
|
+
the slider panel takes the full width, since there is no map to fade over;
|
|
13
|
+
and `loaded` fires without waiting for a map that will never load. The
|
|
14
|
+
accessors return their neutral values and the map setters are no-ops.
|
|
15
|
+
`map_type: ""` and an absent key still mean OpenStreetMap, and `map_type:
|
|
16
|
+
null` is normalised to that default instead of throwing out of the
|
|
17
|
+
constructor (the schema already allowed the key to be missing)
|
|
18
|
+
- **`storymapToManifest()` is now a library export**, promoted out of the
|
|
19
|
+
`convert:iiif` script, so one function both writes and reads the IIIF format
|
|
20
|
+
and a host can produce a manifest in the browser. The CLI delegates to it
|
|
21
|
+
(via Node's own type stripping, so no new dependency and no build step), and
|
|
22
|
+
its output is unchanged byte for byte across all 50 fixtures
|
|
23
|
+
- **Annotation-driven tour stops.** A IIIF manifest whose commenting,
|
|
24
|
+
tagging, classifying or describing annotations carry a fragment target
|
|
25
|
+
becomes one slide per annotation, each fitting the region it points at —
|
|
26
|
+
the Storiiies/Micrio shape. `text/plain` bodies become one paragraph per
|
|
27
|
+
block (escaped), `text/html` keeps its markup, and a `Sound` body becomes
|
|
28
|
+
the slide's media. A `PointSelector` becomes a square of 5% of the
|
|
29
|
+
canvas's smaller side, centred and clamped. New `docs/iiif-authoring.md`
|
|
30
|
+
(published as `authoring.html`) and a four-stop example,
|
|
31
|
+
`public/examples-iiif/annotated-image.json`
|
|
32
|
+
- A normalized selector reader: `FragmentSelector`/`ImageApiSelector`
|
|
33
|
+
(`xywh=`, including `xywh=pixel:`), `PointSelector`, `TextQuoteSelector`,
|
|
34
|
+
`TimeState` and `SvgSelector` are all read, one level of `refinedBy` is
|
|
35
|
+
followed, and a string target's `#xywh=` fragment counts. Quote and SVG
|
|
36
|
+
selectors are preserved but not yet resolved or drawn — the guide says so
|
|
37
|
+
- The painting body's standard fields are the only source for the slide
|
|
38
|
+
media record: `body.label` (caption), `body.requiredStatement` /
|
|
39
|
+
`body.provider` (credit), `body.accessibilitySummary` (alt),
|
|
40
|
+
`body.thumbnail` (thumb), and a `TextualBody` with `format: text/vtt`
|
|
41
|
+
(subtitles). The `storymap:mediaCaption` / `mediaCredit` / `mediaAlt`
|
|
42
|
+
extension terms are dropped; a manifest still using them loads, but the
|
|
43
|
+
strings are no longer read
|
|
44
|
+
(subtitles)
|
|
45
|
+
- `media.subtitles`: a WebVTT file rendered as a `<track kind="subtitles">`
|
|
46
|
+
on the audio or video element
|
|
47
|
+
- Per-slide `narration: {url}`, played through one reused audio element
|
|
48
|
+
rather than the slide's media frame, so switching slides cannot leave a
|
|
49
|
+
recording playing. Gated by browser autoplay policy (it starts after the
|
|
50
|
+
first gesture) and by a new `media:narration` consent service, so the GDPR
|
|
51
|
+
mode has no hole for it
|
|
52
|
+
- `autoplay_media`: with autoplay on, a slide whose media is audio or video
|
|
53
|
+
advances when it ends instead of on the millisecond timer. The timer stays
|
|
54
|
+
armed as a fallback, so a media element that never fires `ended` cannot
|
|
55
|
+
stall the story
|
|
56
|
+
- Per-slide `marker: { icon, iconSize, image, label, popup, audioBadge }`,
|
|
57
|
+
with `location.*` kept as the legacy spelling and `marker.*` winning. No
|
|
58
|
+
new `storymap:` term: in a manifest all of it arrives in the `navPlace`
|
|
59
|
+
Feature `properties` bag, which is a GeoJSON foreign-member bag and needs
|
|
60
|
+
no vocabulary registration
|
|
61
|
+
- `marker.popup`: the active marker's card toggles on click, with a sanitized
|
|
62
|
+
headline and excerpt, the media thumb and a real close button. Escape and
|
|
63
|
+
navigating away both close it, and the marker releases it (and its keydown
|
|
64
|
+
listener) in `dispose()`. Inactive markers still navigate on click
|
|
65
|
+
- `marker.audioBadge`: a dot on markers whose slide has narration or audio
|
|
66
|
+
media
|
|
67
|
+
- Browser coverage for the surfaces jsdom cannot reach, and for the changes
|
|
68
|
+
that came with replacing the map engine: `imageready` against a real
|
|
69
|
+
asynchronously-attached IIIF source, `dispose()` proving no tile requests
|
|
70
|
+
happen after teardown, `addTo()`/`removeFrom()` re-measuring a moved map,
|
|
71
|
+
the `isImageSpace()` contract, runtime option and language changes,
|
|
72
|
+
per-viewer consent, `tile_source_factory`, and network-level proof that
|
|
73
|
+
imagery actually reaches the map (the fixture sweep only checked that a
|
|
74
|
+
container existed, so a grey map used to pass everything)
|
|
75
|
+
- `npm run test:e2e:all` runs the whole suite on Chromium, Firefox and WebKit
|
|
76
|
+
(`E2E_ALL_BROWSERS=1`). Chromium-only stays the default, so the main CI job is
|
|
77
|
+
unaffected; a separate, currently non-blocking CI job runs the matrix
|
|
78
|
+
- A typed OpenLayers surface: all OL types (`Map`, `View`, `Layer`,
|
|
79
|
+
`Source`, ...) plus the StoryMapJS extension types are re-exported, so a
|
|
80
|
+
consumer can build and type its own layers without depending on `ol`
|
|
81
|
+
separately. `storymap.map` is the raw `ol/Map` and is now honestly nullable
|
|
82
|
+
(`OlMap | null`) instead of an `{} as Map` placeholder
|
|
83
|
+
- Accessors for everything the viewer kept private:
|
|
84
|
+
`getBaseLayer()`, `getOverlayLayers()`/`getOverlayLayer(i)`,
|
|
85
|
+
`getOverlayCount()`, `setOverlayVisible()`/`setOverlayOpacity()`,
|
|
86
|
+
`getMinimap()`, `getLine()`/`getLineActive()`, `getMarker(n)`/`getMarkers()`
|
|
87
|
+
and `setExtraAttributions()`; underscore internals are no longer needed
|
|
88
|
+
- `tile_source_factory` may return a full `ol/layer/Layer`, not only a source,
|
|
89
|
+
so a custom layer can carry its own opacity, z-index and events. A layer
|
|
90
|
+
without a source (Allmaps' `WarpedMapLayer`) passes through untouched —
|
|
91
|
+
the engine fields are `Layer`-typed and source reads go through a
|
|
92
|
+
capability check instead of assuming a tile source
|
|
93
|
+
- `imageready` event (`{ source, kind, layer }`, now a typed
|
|
94
|
+
`ImagereadyPayload` export with `kind: "iiif" | "zoomify" | "tiles"`)
|
|
95
|
+
fired once an image source is actually ready, and re-fired on the
|
|
96
|
+
storymap: `loaded` can fire before the imagery exists. The zoomify base
|
|
97
|
+
layer never announced itself — only its minimap did — so a host waiting
|
|
98
|
+
on the event hung on legacy stories; it fires now
|
|
99
|
+
- `storymap.dispose()` releases timers, the resize observer, window/document
|
|
100
|
+
listeners, running slide animations, the slider and the OpenLayers map
|
|
101
|
+
- `isImageSpace()` tells an IIIF image presented as a picture of the world
|
|
102
|
+
(`map_as_image`) from a georeferenced IIIF map; the five places that tested
|
|
103
|
+
`map_type === "iiif" && map_as_image` inline now share it
|
|
104
|
+
- The no-op `show()`/`hide()` methods (map and marker) are marked deprecated
|
|
105
|
+
with the reason, and the surviving map/marker methods are documented as
|
|
106
|
+
aliases over the OpenLayers map
|
|
107
|
+
- `marker.createPopup()` is back as a deprecated no-op, so pre-0.10 code that
|
|
108
|
+
calls it keeps working. It never did anything upstream either: the base
|
|
109
|
+
`MapMarker._createPopup` had an empty body and the Leaflet override's body
|
|
110
|
+
was commented out, so the `map_popup` option that called it never had an
|
|
111
|
+
effect
|
|
112
|
+
- `map.addTo(container)` / `map.removeFrom(container)` keep their original
|
|
113
|
+
`DomMixed` behaviour (append/remove the map container, fire
|
|
114
|
+
`added`/`removed`) and are now OpenLayers-aware: `addTo` re-attaches the map
|
|
115
|
+
target and calls `updateSize()` after the move, `removeFrom` untargets the
|
|
116
|
+
map so it does not render into a detached node
|
|
117
|
+
|
|
118
|
+
Fixed
|
|
119
|
+
-----
|
|
120
|
+
- A IIIF `requiredStatement`'s `label` was discarded, so a manifest that labels
|
|
121
|
+
its statement — "Credit", "Rights holder", "Photographer" — showed the bare
|
|
122
|
+
value. The label is now kept ("Attribution: …") where there is one, and an
|
|
123
|
+
unlabelled statement is still the bare value, unchanged
|
|
124
|
+
- An IIIF `Collection` was accepted as a Manifest and its member Manifests were
|
|
125
|
+
read as if they were Canvases, producing text-only slides with no media, no
|
|
126
|
+
locations and no warning. A Collection is now detected and reported by name
|
|
127
|
+
with its members instead
|
|
128
|
+
- A IIIF manifest's canonical ids were dropped, so a stop could not be
|
|
129
|
+
addressed by its own id even though the viewer already resolves deep links by
|
|
130
|
+
`uniqueid`. Canvas `id` (falling back to the Manifest's) now lands on the
|
|
131
|
+
slide, and an annotation-driven stop gets `<canvasId>#<index>` so it is
|
|
132
|
+
addressable without colliding with the canvas it annotates
|
|
133
|
+
- A slide with body text and no headline rendered a literal "headline" as an
|
|
134
|
+
`<h2>`: `Text`'s constructor seeded its data with the placeholder strings
|
|
135
|
+
"headline"/"text", which `mergeData` only overwrites when the key is
|
|
136
|
+
present. The empty strings its render guards already expect
|
|
137
|
+
- `e2e/known-issues/issue-288` tested neither half of what it claimed: without
|
|
138
|
+
`hasTouch` the browser still reports `pointer: fine`, so `Browser.touch` and
|
|
139
|
+
`Browser.mobile` were false and the desktop branch rendered, and the click
|
|
140
|
+
landed on `.vco-slidenav-next`, which is `display: none` on mobile. It now
|
|
141
|
+
enables touch, asserts the mobile branch is the one under test, checks the
|
|
142
|
+
`touch-action: pan-y` rule the fix is actually about, and drives a real
|
|
143
|
+
touch drag (via CDP) to show a vertical swipe scrolls the page past the
|
|
144
|
+
storymap
|
|
145
|
+
- `e2e/known-issues/issue-452` reported a `zoom` declaration that exists in no
|
|
146
|
+
stylesheet. OpenLayers ships `.ol-viewport canvas { all: unset }`, and Firefox
|
|
147
|
+
and WebKit enumerate `zoom` as a *declared* property once `all` has reset it
|
|
148
|
+
while Chromium does not. It now asserts against the stylesheet's source text
|
|
149
|
+
- The touch-scrollbar assertion in `e2e/scroll-hint` compared
|
|
150
|
+
`getComputedStyle().scrollbarWidth` against `"thin"`/`"auto"`, which is not
|
|
151
|
+
comparable across engines: Chromium computes `auto`, Firefox computes `none`
|
|
152
|
+
for the same declaration. The declaration is now checked in the stylesheet
|
|
153
|
+
source, and the runtime half is skipped where Playwright does not report
|
|
154
|
+
touch (WebKit)
|
|
155
|
+
- A new georeferenced-IIIF fixture (`issue-iiif-geo`), because the negative
|
|
156
|
+
`isImageSpace()` case could not be reached from the existing ones: the
|
|
157
|
+
document sets `map_as_image`, and the document wins over a constructor option
|
|
158
|
+
- The consent registry keyed its stored decisions on a *localized* label, so
|
|
159
|
+
the same service hashed differently in German than in English and renaming a
|
|
160
|
+
label orphaned every saved decision. Keys are now stable and namespaced
|
|
161
|
+
(`map:tiles`, `fonts:web`, `media:<type>`) with the localized name carried
|
|
162
|
+
alongside, and existing decisions are migrated on read. The per-slide dialog
|
|
163
|
+
also asked "Load content from youtube?" — it now shows the media's display
|
|
164
|
+
name, matching the start-of-story dialog
|
|
165
|
+
- 27 of the 29 bundled locales had no `consent_*` strings at all and silently
|
|
166
|
+
fell back to English, including the whole start-of-story dialog. The 9
|
|
167
|
+
missing keys are translated in 23 locales; `npm run check:locales` now fails
|
|
168
|
+
on a new gap (its `--strict` flag was documented but never implemented, and
|
|
169
|
+
the check was not in CI) instead of only reporting
|
|
170
|
+
- Removing a map marker did not renumber the ones behind it, even though
|
|
171
|
+
`marker_number` is the index a click hands to `goTo()`: a click on the third
|
|
172
|
+
pin after removing the second navigated to the wrong slide
|
|
173
|
+
- Every slide got an empty element id. The generated `uniqueid` was only
|
|
174
|
+
created when the field was the empty string, but it is optional in the
|
|
175
|
+
schema and absent from 47 of the 48 bundled fixtures
|
|
176
|
+
- `dispose()` released the timers and the OpenLayers map but nothing they
|
|
177
|
+
owned, so a torn-down storymap left its slider, slides, media players,
|
|
178
|
+
markers and buttons in the document. Each class now releases what it owns,
|
|
179
|
+
and three listeners that could not be removed at all (registered as inline
|
|
180
|
+
arrows or a throwaway `.bind()`) keep a reference
|
|
181
|
+
- A preload was tracked in one `preloadTimer` that held either a
|
|
182
|
+
`setTimeout` or a `requestIdleCallback` handle. Both are numbers, so
|
|
183
|
+
cancelling one with the other's API appeared to work while leaking it
|
|
184
|
+
- map_bbox was ignored for every IIIF map: the runtime test was "map_type is
|
|
185
|
+
iiif", so a *georeferenced* IIIF map was treated as image space and its view
|
|
186
|
+
was fitted to the image extent instead of the bbox
|
|
187
|
+
- 12 tile/vector source sites declared `attributions: []`, so the OSM, Stadia,
|
|
188
|
+
Mapbox, Esri, Carto, OpenTopo, Esri Ocean, NASA, overlay and mini-map
|
|
189
|
+
credits never reached the attribution control. They are now credited from
|
|
190
|
+
the source; custom `.vco-map-attribution` lines are unchanged
|
|
191
|
+
- Navigating mutated the caller's document: the computed marker zoom was
|
|
192
|
+
written back onto `slides[i].location.zoom`, and `StoryMap.data` is that very
|
|
193
|
+
object. The zoom ladder now lives in an internal store; the authored value is
|
|
194
|
+
left alone and is still used for the min/max bounds
|
|
195
|
+
- `map_options.interactions` was documented as replacing the defaults; it is
|
|
196
|
+
additive (the viewer's own pan/zoom set is always installed)
|
|
197
|
+
- Image media never called onLoaded(): the call had drifted into a dead
|
|
198
|
+
position after a `return` in _altText(), so every image slide kept a
|
|
199
|
+
permanent "Loading Image" overlay painted over it and never rendered its
|
|
200
|
+
credit or caption
|
|
201
|
+
- Consent-denied media threw a TypeError on desktop: updateMediaDisplay()
|
|
202
|
+
dereferenced `content_item.style` on the empty placeholder
|
|
203
|
+
- Map.goTo() fired its change event twice for a slide with no location
|
|
204
|
+
- start_at_slide supplied by the storymap *data* was ignored: the field was
|
|
205
|
+
read before the data merge and the slider's opening goTo() fires before the
|
|
206
|
+
change listener is attached
|
|
207
|
+
- The menubar collapse toggle was a no-op: the portrait branch it only
|
|
208
|
+
appears in unconditionally overwrote the map height it asked for
|
|
209
|
+
- map_type "stadia" with no style resolved to a non-Stadia style name, so
|
|
210
|
+
every tile 404'd; setMapOption("map_bbox") rebuilt the View without the
|
|
211
|
+
deliberate constraints
|
|
212
|
+
- The start-of-story consent dialog listed services the visitor had already
|
|
213
|
+
answered, and left answered rows greyed out rather than removing them
|
|
214
|
+
(two consent e2e tests were failing because of this)
|
|
215
|
+
- The YouTube IFrame API poll retried forever; Vimeo's embed URL used &
|
|
216
|
+
separators that are not decoded in a URL property; the horizontal swipe
|
|
217
|
+
constraint clamp was inverted; slide positions were computed from the
|
|
218
|
+
previous width; goToId() with an unknown id jumped to slide 0
|
|
219
|
+
- 7 of the 18 media types had no icon glyph, so their error boxes were blank
|
|
220
|
+
- he.json carried a UTF-8 BOM that made it unparseable by standard JSON tools
|
|
221
|
+
|
|
222
|
+
Security
|
|
223
|
+
--------
|
|
224
|
+
- The slide-text sanitizer was a denylist that copied every attribute
|
|
225
|
+
verbatim. `style` came through untouched, which allowed a pasted
|
|
226
|
+
full-viewport opaque overlay over the map and controls (chrome spoofing and
|
|
227
|
+
clickjacking from one attribute). It is now an allowlist; `target` is always
|
|
228
|
+
forced to `_blank`, `id`/`name` are dropped, `srcset` is validated per
|
|
229
|
+
candidate, and rebuilt embeds are sandboxed with a no-referrer policy
|
|
230
|
+
- Seven innerHTML sinks that bypassed the sanitizer are routed through it:
|
|
231
|
+
media credit, media caption, the navigation headline, the call-to-action
|
|
232
|
+
text, the Juxtapose iframe, and the map attribution line
|
|
233
|
+
- media and image link hrefs are protocol-checked, so a `javascript:` href in
|
|
234
|
+
the storymap JSON is no longer a click-through XSS
|
|
235
|
+
- a crafted `stock:` font name resolved to an arbitrary same-origin file
|
|
236
|
+
- the schema validator did not implement `anyOf`, so map_bbox,
|
|
237
|
+
map_overview_center and the zoomify block were accepted completely
|
|
238
|
+
unvalidated; `format` and `maxLength` are now honoured
|
|
239
|
+
|
|
240
|
+
Removed
|
|
241
|
+
-------
|
|
242
|
+
- The inert option keys `less_bounce`, `map_subdomains`, `map_popup`,
|
|
243
|
+
`zoom_distance`, `dragging` and `path_gfx`: documented and accepted, but read
|
|
244
|
+
by nothing. They are gone from the schema, the types and the defaults, and
|
|
245
|
+
documents carrying them still validate, because the schema does not close
|
|
246
|
+
`additionalProperties`
|
|
247
|
+
|
|
248
|
+
Changed
|
|
249
|
+
-------
|
|
250
|
+
- The map engine is genuinely optional. `StoryMap._map` is `null` rather than a
|
|
251
|
+
`{}` stub, so the accessors' `this._map ? … : neutral` guards mean what they
|
|
252
|
+
say instead of passing on a truthy object and then calling a method on it,
|
|
253
|
+
and the paths that only make sense with a map now throw a named error if they
|
|
254
|
+
are reached without one
|
|
255
|
+
- `StoryMap._el.map` is `HTMLElement | null` rather than `HTMLElement`
|
|
256
|
+
- A second viewer on a page asking for a different `language` now **throws**
|
|
257
|
+
instead of silently repainting the first one. The UI strings are a single
|
|
258
|
+
page-wide binding read while a viewer is constructed, so a conflict was
|
|
259
|
+
never survivable; the claim is released by `dispose()`. Only an explicit
|
|
260
|
+
`language` — the constructor option or the document's — counts as a request:
|
|
261
|
+
a viewer that was not given one adopts the page's current locale, so calling
|
|
262
|
+
the public `setLanguage()` and then building viewers without a `language`
|
|
263
|
+
option keeps the locale instead of resetting the page to English. The
|
|
264
|
+
trade-off is that such a viewer follows a previous viewer's
|
|
265
|
+
`refreshLanguage()`
|
|
266
|
+
- Several viewers on a page no longer overwrite each other's consent
|
|
267
|
+
decisions: each manager merges into the shared record and re-reads it on
|
|
268
|
+
every ask, instead of writing its whole set back
|
|
269
|
+
- With `keyboard: true` on more than one viewer, an arrow keypress goes to the
|
|
270
|
+
viewer that holds focus, or else the one interacted with most recently
|
|
271
|
+
- External scripts and stylesheets are injected once per URL for the page, so
|
|
272
|
+
two viewers no longer both load the YouTube/SoundCloud APIs and the font
|
|
273
|
+
theme
|
|
274
|
+
- `dispose()` empties the host container and turns the public methods and
|
|
275
|
+
accessors into no-ops; there is no re-init path (build a new StoryMap)
|
|
276
|
+
- strictNullChecks is enabled. The `{} as HTMLElement` placeholders it was
|
|
277
|
+
masking are now honestly nullable, which is what the consent-denied crash
|
|
278
|
+
came from
|
|
279
|
+
- morpheus (an inlined UMD build that shipped no types) is replaced by a
|
|
280
|
+
~130 line Web Animations API wrapper with the same call signature: one
|
|
281
|
+
dependency and one hand-maintained .d.ts removed, -5 kB raw and no
|
|
282
|
+
measurable change over the wire. morpheus gzipped well, so most of the raw
|
|
283
|
+
saving is offset by the new code; the win here is the dependency and the
|
|
284
|
+
type stub, not the bytes
|
|
285
|
+
- npm run check:locales reports which locales are missing which strings.
|
|
286
|
+
28 of 29 are missing 8-10, mostly the per-service consent labels
|
|
287
|
+
- Docs corrected: DEVELOPMENT.md described a CommonJS/UMD build with a
|
|
288
|
+
KLStoryMap global (it is ESM-only), the CHANGELOG claimed consent labels
|
|
289
|
+
were fully translated and that zoomify was removed (both false), and
|
|
290
|
+
README/index.html said slide text is rendered raw (it is sanitized)
|
|
291
|
+
|
|
292
|
+
0.10.0 - 0.10.7 (2026-09-22 to 2026-09-25)
|
|
293
|
+
------------------------
|
|
294
|
+
Released as eight patches without individual changelog entries; this is the
|
|
295
|
+
consolidated list. Viewer-only restructure of the repository:
|
|
4
296
|
- Removed the editor Flask backend, CDN staging and all legacy build artifacts
|
|
5
297
|
- Replaced webpack with Vite (dev/build/preview), default Vite project layout
|
|
6
298
|
- Converted the source to strict TypeScript (target ES2022, noImplicitAny, no explicit any)
|
|
7
|
-
- Replaced Leaflet with OpenLayers
|
|
299
|
+
- Replaced Leaflet with OpenLayers. IIIF Image API ("map_type": "iiif") is the
|
|
300
|
+
recommended image basemap; the legacy Zoomify pyramid ("map_type": "zoomify")
|
|
301
|
+
is retained as a deprecated basemap and warns when it loads
|
|
8
302
|
- Converted Less to SASS with zero deprecation warnings (@use only, no @import, no vendor prefixes, no postcss-scss)
|
|
9
303
|
- Fonts bundled via @fontsource + @fontsource-utils/scss mixins (woff2, latin subsets); no runtime font CDN requests
|
|
10
304
|
- New exchange format: IIIF Presentation API 3.0 manifests (docs/storymap-as-iiif-manifest.md) with navPlace geo +
|
|
@@ -16,6 +310,67 @@ Viewer-only restructure of the repository:
|
|
|
16
310
|
- Dropped code for pre-2022 browsers: XHR -> fetch, removed vendor detection, engine workarounds, pollers,
|
|
17
311
|
minEmoji sprite polyfill and Knight Lab tracking
|
|
18
312
|
- Bug fixes: null-offset crashes, IIIF source races, unique-id generation, swipe direction check, empty-block cleanup
|
|
313
|
+
- Stacked raster overlays with per-layer presentation (opacity, visibility,
|
|
314
|
+
attribution, className, blendMode, lon/lat extent), runtime setters and
|
|
315
|
+
setMapOption rebuild; minimap overview constraint via overview_extent
|
|
316
|
+
- Slide transition events (transitionstart/transitionend), guaranteed goTo
|
|
317
|
+
change events, opt-in global keyboard navigation
|
|
318
|
+
- Runtime language switching without reload (MenuBar.refreshLabels,
|
|
319
|
+
StoryMap.refreshLanguage); locale fallback no longer mutates English;
|
|
320
|
+
German fullscreen labels
|
|
321
|
+
- Attribution refresh on basemap switch (+setExtraAttributions); identical
|
|
322
|
+
credits collapse to one entry; route lines pinned above rebuilt tile
|
|
323
|
+
layers; font_css resolves page-relative; slide colors accept any CSS color
|
|
324
|
+
- Consent: decisions persist in localStorage (storymapjs-consent, no expiry)
|
|
325
|
+
instead of a 90-day cookie; a start-of-story dialog lists the external
|
|
326
|
+
services the story uses (map tiles, media services, external fonts) and
|
|
327
|
+
offers allow all, decline all or a decision per service, with per-service
|
|
328
|
+
panels as the fallback for services discovered later. Only en.json
|
|
329
|
+
translates every label: the other 28 bundled locales are each missing the
|
|
330
|
+
per-service consent strings and fall back to English (npm run check:locales)
|
|
331
|
+
- Mobile gestures: iOS swipe navigation fixed — signed gesture deltas (a
|
|
332
|
+
rightward swipe on the left half no longer counts as "next"), touchcancel
|
|
333
|
+
handled without leaking touchmove/mouseleave listeners (swipes used to stop
|
|
334
|
+
working after the first slide), touchend reads changedTouches, and
|
|
335
|
+
touch-action: pan-y on the slider keeps vertical page scrolling
|
|
336
|
+
- Accessibility: image alt text end-to-end (schema, IIIF storymap:mediaAlt,
|
|
337
|
+
caption-as-plain-text fallback), aria-live slide announcements, real <button>
|
|
338
|
+
menubar actions with :focus-visible styling, keyboard-operable slider nav
|
|
339
|
+
arrows (role/tabindex/Enter/Space), prefers-reduced-motion honored
|
|
340
|
+
(instant slide changes, no autoplay), embed page allows pinch-zoom
|
|
341
|
+
- Image performance: offscreen slide images are lazy-loaded and
|
|
342
|
+
async-decoded (upgraded to eager when their slide becomes active), IIIF
|
|
343
|
+
image URLs request container-matched widths, optional srcset/sizes pass
|
|
344
|
+
through for plain images
|
|
345
|
+
- Fonts: non-latin subsets (cyrillic, greek, hebrew, vietnamese) shipped
|
|
346
|
+
from the installed Fontsource packages where a family provides them, plus a
|
|
347
|
+
new stock:cairo theme with arabic coverage
|
|
348
|
+
- IIIF: per-slide image regions (location.region as IIIF xywh in image
|
|
349
|
+
pixels) fit the view on navigation for image-map stories, encoded in
|
|
350
|
+
manifests as storymap:imageRegion
|
|
351
|
+
- Storymap JSON: schema entries for map_area, overlays (with per-layer
|
|
352
|
+
opacity, visibility, attribution, className, blendMode and lon/lat extent),
|
|
353
|
+
overview_extent and keyboard — plus the slide fields location.region and
|
|
354
|
+
media.alt/srcset/sizes, and a fix for overlays and overview_extent being
|
|
355
|
+
silently dropped when they came from the data file instead of the options
|
|
356
|
+
- IIIF manifests: the same options as storymap:mapArea, storymap:overlays,
|
|
357
|
+
storymap:overviewExtent and storymap:keyboard terms on the map
|
|
358
|
+
configuration service, storymap:mediaSrcset / storymap:mediaSizes on the
|
|
359
|
+
canvas, and the native geospatial vocabulary where IIIF has it — a navPlace
|
|
360
|
+
Polygon as the story extent (map_bbox), an IIIF Image API Selector as
|
|
361
|
+
location.region
|
|
362
|
+
- IIIF manifests: storymap:georeferencedLayers places a IIIF image on the
|
|
363
|
+
geographic map from a Georeference Extension annotation body (affine
|
|
364
|
+
placement of its ground control points); placements needing a
|
|
365
|
+
non-affine transform or a rotated sheet are reported and skipped, so
|
|
366
|
+
warped layers stay a tile_source_factory/Allmaps concern
|
|
367
|
+
- Map providers: tile_source_factory option injects custom OpenLayers tile
|
|
368
|
+
layers/sources (e.g. WMS) for the base map, overlays and minimap, with
|
|
369
|
+
recipes in the migration guide
|
|
370
|
+
- Embed: &autoplay=<ms> URL parameter for automatic slide playback
|
|
371
|
+
- Upstream audit: docs/KNOWN_ISSUES.md reconciled with the implementation
|
|
372
|
+
(60 of 109 triaged issues verified fixed, one-by-one verdicts and
|
|
373
|
+
regression specs for each)
|
|
19
374
|
|
|
20
375
|
0.9.5 (2025-11-05)
|
|
21
376
|
* Implement basic Audio and Video media types
|
|
@@ -106,16 +461,3 @@ Viewer-only restructure of the repository:
|
|
|
106
461
|
* PR #302 Media fixes including pause of video types when navigating away from slide
|
|
107
462
|
* PR #303 Adds custom map marker upload in editor
|
|
108
463
|
* PR #312 Adds Greek translation to StoryMap editor
|
|
109
|
-
|
|
110
|
-
## 1.0.0 (unreleased)
|
|
111
|
-
|
|
112
|
-
Viewer-only restructure of the repository:
|
|
113
|
-
- Removed the editor Flask backend, staging and legacy build artifacts
|
|
114
|
-
- Replaced webpack with Vite (dev/build/preview), default project layout
|
|
115
|
-
- Converted the source to strict TypeScript (target ES2022)
|
|
116
|
-
- Replaced Leaflet with OpenLayers; IIIF Image API replaces Zoomify (breaking)
|
|
117
|
-
- Converted Less to SASS; fonts bundled from npm (@fontsource) instead of runtime CDN requests
|
|
118
|
-
- Added a JSON Schema for storymap data, runtime validation with console reporting, and a CLI validator
|
|
119
|
-
- Added ESLint + Stylelint and GitHub Actions for linting/tests and release packaging
|
|
120
|
-
- Playwright e2e suite over all examples, Vitest for units
|
|
121
|
-
- Dropped code paths for pre-2022 browsers (legacy vendor prefixes, IE/old-engine fallbacks)
|
package/README.md
CHANGED
|
@@ -10,7 +10,9 @@ This fork is a **viewer-only library**: it renders existing StoryMap JSON
|
|
|
10
10
|
files (or IIIF Presentation manifests) with TypeScript + Vite + OpenLayers.
|
|
11
11
|
There is no authoring tool — create your storymap JSON by hand or with your
|
|
12
12
|
own code, and see `docs/` for the migration notes from the original
|
|
13
|
-
Knight Lab release.
|
|
13
|
+
Knight Lab release. The library also exports `storymapToManifest()`, which
|
|
14
|
+
produces a IIIF manifest from a storymap document (`npm run convert:iiif`
|
|
15
|
+
does the same from the command line; see `docs/storymap-as-iiif-manifest.md`).
|
|
14
16
|
|
|
15
17
|
## Development
|
|
16
18
|
|
|
@@ -40,6 +42,14 @@ Points are set to only display on mouseover in image mode, but you can set map_a
|
|
|
40
42
|
To disable connecting lines on maps set `map_as_image: true` in the storymap
|
|
41
43
|
options (the default `false` renders cartography).
|
|
42
44
|
|
|
45
|
+
`storymap.map` is the raw OpenLayers map, typed with the re-exported `ol`
|
|
46
|
+
types, and `getBaseLayer()`, `getOverlayLayers()`, `getMinimap()`,
|
|
47
|
+
`getMarkers()` and friends hand out the layers the viewer built. Listen for
|
|
48
|
+
`imageready` to run code against the real imagery, and call
|
|
49
|
+
`storymap.dispose()` when the embedding view goes away — see
|
|
50
|
+
[docs/migration-from-knightlab.md](docs/migration-from-knightlab.md#reaching-the-map-layers-and-markers)
|
|
51
|
+
for the full surface.
|
|
52
|
+
|
|
43
53
|
The menubar buttons can be disabled individually:
|
|
44
54
|
|
|
45
55
|
show_overview: false, // map overview button
|
|
@@ -92,7 +102,8 @@ an opaque slide panel instead of the gradient over the map), set
|
|
|
92
102
|
|
|
93
103
|
Any value containing `{z}` renders as a raster XYZ layer; a path without `{z}`
|
|
94
104
|
that looks like a URL/path renders as a vector style layer; anything else falls
|
|
95
|
-
back to classic OSM raster
|
|
105
|
+
back to classic OSM raster — except `"none"`, which builds no map at all and
|
|
106
|
+
runs the story as text and media only.
|
|
96
107
|
|
|
97
108
|
### Switching the basemap at runtime
|
|
98
109
|
|
|
@@ -123,14 +134,22 @@ images, lists, emphasis and spans in your slides, e.g.:
|
|
|
123
134
|
|
|
124
135
|
The `vco-note` span renders as a small grey note, like the built-in credits.
|
|
125
136
|
|
|
126
|
-
**Caution:** the text is
|
|
127
|
-
|
|
137
|
+
**Caution:** the text is sanitized, but sanitizing is a mitigation rather
|
|
138
|
+
than a guarantee. Prose and media formatting survive (`class`, `alt`, `width`,
|
|
139
|
+
table attributes, and so on), scripts and other executable tags are dropped
|
|
140
|
+
with their contents, event-handler attributes are stripped, every URL
|
|
141
|
+
attribute is checked to be `http(s)`, and `<iframe>` embeds are rebuilt into
|
|
142
|
+
a sandboxed, `no-referrer` element. `style`, `id` and `name` are _not_ allowed,
|
|
143
|
+
and a link's `target` is always forced to `_blank`. The same sanitizer covers
|
|
144
|
+
media credit, media caption, the navigation headline and the map attribution
|
|
145
|
+
line. Still: only load storymaps from sources you trust.
|
|
128
146
|
|
|
129
147
|
## GDPR consent for external services
|
|
130
148
|
|
|
131
149
|
Set the `consent_required` option to `true` to ask for permission before
|
|
132
150
|
anything is loaded from external services (media embeds such as YouTube,
|
|
133
|
-
Twitter or SoundCloud, map tiles, and external font
|
|
151
|
+
Twitter or SoundCloud, slide narration audio, map tiles, and external font
|
|
152
|
+
CSS):
|
|
134
153
|
|
|
135
154
|
{
|
|
136
155
|
"consent_required": true,
|
|
@@ -138,11 +157,26 @@ Twitter or SoundCloud, map tiles, and external font CSS):
|
|
|
138
157
|
}
|
|
139
158
|
|
|
140
159
|
Each service asks with an Allow/Deny panel; answering one panel resolves every
|
|
141
|
-
pending panel of the same service.
|
|
142
|
-
cookie, the panel is skipped entirely. Denied services show a placeholder
|
|
160
|
+
pending panel of the same service. Denied services show a placeholder
|
|
143
161
|
instead of the media, and the map renders without tiles until they are
|
|
144
|
-
allowed.
|
|
145
|
-
|
|
162
|
+
allowed.
|
|
163
|
+
|
|
164
|
+
Before the story loads, one dialog lists every external service it uses (map
|
|
165
|
+
tiles, media services including slide narration, external fonts) with three
|
|
166
|
+
choices: **Allow all**, **Decline all**, or a decision per service. A story
|
|
167
|
+
with no map (`map_type: "none"`) has no tile row to answer. The dialog is
|
|
168
|
+
skipped once every service has a stored decision; per-service panels still
|
|
169
|
+
appear for services discovered later (e.g. a preloaded slide).
|
|
170
|
+
|
|
171
|
+
Decisions are stored in `localStorage` under `storymapjs-consent` and have no
|
|
172
|
+
expiry — clearing site data asks again.
|
|
173
|
+
|
|
174
|
+
The consent labels are **not** fully translated. `src/language/locale/en.json`
|
|
175
|
+
defines every string; 28 bundled locales fall back to English for the keys
|
|
176
|
+
they lack — most are missing one, a handful are missing around ten (the
|
|
177
|
+
per-service consent prompts and the fullscreen button labels). Run
|
|
178
|
+
`npm run check:locales` to see the current state — it reports the gap per
|
|
179
|
+
locale and is expected to be runnable without failing.
|
|
146
180
|
|
|
147
181
|
## Troubleshooting
|
|
148
182
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./modulepreload-polyfill-P2Xu9kJm.js";import{t as e}from"./main-DXalctuR.js";function t(e){document.title=`StoryMapJS: `+e.title}window.storymap=new e(`storymap-embed`,`./demo.json`,{},{title:t});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./modulepreload-polyfill-P2Xu9kJm.js";import{t as e}from"./main-DXalctuR.js";import{n as t,t as n}from"./harness-support-Do7sIp2j.js";window.__smErrors=[],window.__smReady=!1,window.addEventListener(`error`,e=>{window.__smErrors.push(String(e.message||e))});var r=new URLSearchParams(window.location.search),i=r.get(`manifest`),a=r.get(`url`),o=i===null?r.get(`example`):i,s=i===null?`/examples/`:`/examples-iiif/`,c={};if(r.get(`options`))try{c=JSON.parse(r.get(`options`))}catch(e){window.__smErrors.push(`harness: bad options param: `+e)}var l=t(window);l&&(c.tile_source_factory=l);var u=a??s+o+`.json`;fetch(u).then(e=>e.json()).then(t=>{let i=new e(`storymap-embed`,t,c,{});window.__sm=i,n(i,r.get(`record`),window),window.__smReady=!0}).catch(e=>{window.__smErrors.push(`harness: `+(e&&e.message?e.message:String(e))),window.__smReady=!0});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./modulepreload-polyfill-P2Xu9kJm.js";import{t as e}from"./main-DXalctuR.js";import{n as t,t as n}from"./harness-support-Do7sIp2j.js";window.__smErrors=[],window.__smReady=!1,window.addEventListener(`error`,e=>{window.__smErrors.push(String(e.message||e))});var r=new URLSearchParams(window.location.search),i={a:r.get(`a`)??`katrina`,b:r.get(`b`)??`seurat`},a={a:o(r.get(`aopts`)),b:o(r.get(`bopts`))};for(let[e,n]of Object.entries(a)){let r=t(window);r&&(n.tile_source_factory=r),a[e]=n}function o(e){if(!e)return{};try{return JSON.parse(e)}catch(e){return window.__smErrors.push(`harness-multi: bad options: `+e),{}}}async function s(e){let t=await fetch(`/examples/`+i[e]+`.json`);if(!t.ok)throw Error(`no example `+i[e]);return t.json()}var c=r.get(`shared`)===`1`?await s(`a`):null;try{let t=c??await s(`a`);window.__smA=new e(`sm-a`,t,a.a,{}),n(window.__smA,r.get(`record`),window,`A`);let i=c??await s(`b`);window.__smB=new e(`sm-b`,i,a.b,{}),n(window.__smB,r.get(`record`),window,`B`)}catch(e){window.__smErrors.push(`harness-multi: `+(e?.message??e))}window.__smReady=!0;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t,r,i=``){let a=(t??``).split(`,`).map(e=>e.trim()).filter(Boolean);if(a.length!==0){r.__events=r.__events??[];for(let t of a)e.on(t,e=>{r.__events.push({type:t,viewer:i,payload:n(e)})})}}function t(e){return typeof e.__tileSourceFactory==`function`?e.__tileSourceFactory:void 0}function n(e){if(typeof e!=`object`||!e)return e;let t={};for(let[a,o]of Object.entries(e))if(typeof o!=`object`||!o)t[a]=typeof o==`function`?`[fn]`:o;else if(a===`source`||a===`layer`)t[a]={type:o.constructor?.name??null,state:typeof o.getState==`function`?o.getState():void 0,url:o.url_??o.href_??r(o,`url`)};else if(a===`target`)t[a]=i(o);else if(Array.isArray(o))t[a]=o.map(e=>n(e));else{let e=Object.getPrototypeOf(o);t[a]=e===Object.prototype||e===null?n(o):{type:o.constructor?.name??null}}return t}function r(e,t){try{return e.get?.(t)}catch{return}}function i(e){let t=a(e)?e:a(e?._map)?e._map:null;if(!t)return{type:e?.constructor?.name??null};let n=t.getView(),r=t.getSize();return{type:e?.constructor?.name??null,size:r?[r[0],r[1]]:null,center:n?.getCenter?.()??null,resolution:n?.getResolution?.()??null,projection:n?.getProjection?.()?.getCode?.()??null}}function a(e){return!!e&&typeof e.getSize==`function`&&typeof e.getView==`function`}export{t as n,e as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./modulepreload-polyfill-P2Xu9kJm.js";var e=[{id:`katrina`,title:`Hurricane Katrina`,kind:`Map`},{id:`population`,title:`US Population Shifts`,kind:`Map`},{id:`marktwain`,title:`Mark Twain's Travels`,kind:`Map`},{id:`seurat`,title:`A Sunday on La Grande Jatte`,kind:`Large image (legacy)`},{id:`iiif-wellcome`,title:`Wellcome Collection (IIIF)`,kind:`IIIF`},{id:`president`,title:`A Month in the Life of President Obama`,kind:`Map`},{url:`https://s3.amazonaws.com/uploads.knightlab.com/storymapjs/a1a349b51799ee49e96bed10cc235e7f/garden-of-earthly-delights/published.json`,thumb:`bosch-garden`,title:`The Garden of Earthly Delights – Hieronymus Bosch`,kind:`Knight Lab example`},{url:`https://uploads.knightlab.com/storymapjs/3df56e350378e51781746bfb2a2ea428/test/published.json`,thumb:`southern-literary-trail`,title:`Southern Literary Trail`,kind:`Georgia Humanities`}];function t(e){let t=e.url??`examples/`+e.id+`.json`,n=e.thumb??e.id??``,r=document.createElement(`a`);r.className=`card`,r.href=`./embed/index.html?url=${encodeURIComponent(t)}`;let i=document.createElement(`span`);i.className=`header-image`;let a=document.createElement(`span`);a.className=`header-image-background bw`,a.style.backgroundImage=`url('./thumbs/${n}.jpg'), linear-gradient(135deg, #b8b8b8, #646464)`,a.setAttribute(`role`,`img`),a.setAttribute(`aria-label`,e.title),i.append(a);let o=document.createElement(`article`);o.className=`card-content`;let s=document.createElement(`h3`);s.textContent=e.title,o.append(s);let c=document.createElement(`footer`);return c.textContent=e.kind,r.append(i,o,c),r}var n=document.getElementById(`examples-cards`);if(n){n.classList.add(`cards-link`);for(let r of e)n.append(t(r))}var r=document.getElementById(`demo-frame`);if(r){let e=()=>{r.style.height=window.innerHeight-20+`px`};e(),window.addEventListener(`resize`,e)}
|