@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
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Media } from "../Media";
|
|
2
|
+
import Dom from "../../dom/Dom";
|
|
3
|
+
import { Language } from "../../language/Language";
|
|
4
|
+
|
|
5
|
+
/* Media.HtmlMedia
|
|
6
|
+
Shared implementation for the <audio> and <video> types. The two differ
|
|
7
|
+
only in the element name, the CSS class, the fallback text and the
|
|
8
|
+
file extension -> MIME map, so all of that is data here.
|
|
9
|
+
================================================== */
|
|
10
|
+
|
|
11
|
+
/** The element this media type plays. */
|
|
12
|
+
export type HtmlMediaKind = "audio" | "video";
|
|
13
|
+
|
|
14
|
+
interface HtmlMediaSpec {
|
|
15
|
+
/** The element to create. */
|
|
16
|
+
kind: HtmlMediaKind;
|
|
17
|
+
/** File extension (lowercase, no dot) -> MIME subtype. */
|
|
18
|
+
extensions: Record<string, string>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const AUDIO_DEFAULT: HtmlMediaSpec = { kind: "audio", extensions: { mp3: "mpeg" } };
|
|
22
|
+
|
|
23
|
+
/** MIME subtype for a file extension, or "" when it is not recognised. */
|
|
24
|
+
function mimeSubtype(ext: string, spec: HtmlMediaSpec): string {
|
|
25
|
+
return spec.extensions[ext.toLowerCase()] ?? "";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** The behaviour shared by the audio and video media types. */
|
|
29
|
+
export class HtmlMediaBase extends Media {
|
|
30
|
+
declare "player_element": HTMLMediaElement | null;
|
|
31
|
+
declare "_onCanPlay": (() => void) | null;
|
|
32
|
+
declare "_onEnded": (() => void) | null;
|
|
33
|
+
declare "_onSourceError": (() => void) | null;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The per-kind differences. Overridden by the Audio/Video subclasses; the
|
|
37
|
+
* base value is never used (an HtmlMediaBase is always subclassed).
|
|
38
|
+
*/
|
|
39
|
+
protected spec(): HtmlMediaSpec {
|
|
40
|
+
return AUDIO_DEFAULT;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_loadMedia() {
|
|
44
|
+
const spec = this.spec();
|
|
45
|
+
this.loadingMessage();
|
|
46
|
+
|
|
47
|
+
const media_item = Dom.create(
|
|
48
|
+
spec.kind,
|
|
49
|
+
`vco-media-item vco-media-${spec.kind} vco-media-shadow`,
|
|
50
|
+
this._el.content,
|
|
51
|
+
) as HTMLMediaElement;
|
|
52
|
+
this._el.content_item = media_item;
|
|
53
|
+
media_item.controls = true;
|
|
54
|
+
|
|
55
|
+
const source_item = Dom.create("source", "", media_item) as HTMLSourceElement;
|
|
56
|
+
this._el.source_item = source_item;
|
|
57
|
+
|
|
58
|
+
// Media Loaded Event. The references are kept so dispose() can detach
|
|
59
|
+
// them: an inline arrow function has no other handle.
|
|
60
|
+
this._onEnded = null;
|
|
61
|
+
this._onCanPlay = () => {
|
|
62
|
+
this.onLoaded();
|
|
63
|
+
};
|
|
64
|
+
media_item.addEventListener("canplay", this._onCanPlay);
|
|
65
|
+
|
|
66
|
+
// Load Error Event (the source element fires it, not the media element)
|
|
67
|
+
this._onSourceError = () => {
|
|
68
|
+
this.loadErrorDisplay(Language.messages.error + " " + this.options.media_name);
|
|
69
|
+
};
|
|
70
|
+
source_item.addEventListener("error", this._onSourceError);
|
|
71
|
+
|
|
72
|
+
const url = this._url();
|
|
73
|
+
source_item.src = url;
|
|
74
|
+
const media_type = this._getType(url, spec);
|
|
75
|
+
// An unrecognised extension leaves the type unset so the browser can
|
|
76
|
+
// work it out from the URL — setting a bare "audio/" (as this used to)
|
|
77
|
+
// is not a valid MIME type and makes the source fail outright.
|
|
78
|
+
if (media_type) {
|
|
79
|
+
source_item.type = media_type;
|
|
80
|
+
}
|
|
81
|
+
// Subtitles: a WebVTT track, opt-in via media.subtitles. The element
|
|
82
|
+
// is created before the fallback text node so the fallback stays last.
|
|
83
|
+
if (spec.kind === "video" || spec.kind === "audio") {
|
|
84
|
+
const subtitles = (this.data as { subtitles?: string | null }).subtitles;
|
|
85
|
+
if (typeof subtitles === "string" && subtitles !== "") {
|
|
86
|
+
const track = Dom.create(
|
|
87
|
+
"track",
|
|
88
|
+
"vco-media-track",
|
|
89
|
+
media_item,
|
|
90
|
+
) as HTMLTrackElement;
|
|
91
|
+
track.kind = "subtitles";
|
|
92
|
+
track.srclang = "en";
|
|
93
|
+
track.label = "Subtitles";
|
|
94
|
+
track.src = subtitles;
|
|
95
|
+
track.default = true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// append as a text node: re-serializing innerHTML would replace the
|
|
100
|
+
// source element and drop its error listener, leaving the loading
|
|
101
|
+
// message on screen forever
|
|
102
|
+
media_item.appendChild(
|
|
103
|
+
document.createTextNode(
|
|
104
|
+
`Your browser doesn't support HTML5 ${spec.kind} with ` + source_item.type,
|
|
105
|
+
),
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// `ended` is what autoplay_media waits for instead of its timer; the
|
|
109
|
+
// reference is kept so dispose() can detach it, like the two above
|
|
110
|
+
this._onEnded = () => {
|
|
111
|
+
this.fire("media_ended", this.data);
|
|
112
|
+
};
|
|
113
|
+
media_item.addEventListener("ended", this._onEnded);
|
|
114
|
+
|
|
115
|
+
this.player_element = media_item;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Update Media Display
|
|
119
|
+
_updateMediaDisplay() {
|
|
120
|
+
// the height is CSS-driven; nothing to compute here
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_stopMedia() {
|
|
124
|
+
this.player_element?.pause();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Detach the media listeners and release the source, so a disposed audio
|
|
129
|
+
* or video element stops buffering instead of playing into a detached
|
|
130
|
+
* tree. Pausing alone (what `stopMedia()` does per slide change) is not
|
|
131
|
+
* enough for a full teardown.
|
|
132
|
+
*/
|
|
133
|
+
_disposeMedia() {
|
|
134
|
+
if (this._onCanPlay) {
|
|
135
|
+
this.player_element?.removeEventListener("canplay", this._onCanPlay);
|
|
136
|
+
this._onCanPlay = null;
|
|
137
|
+
}
|
|
138
|
+
if (this._onEnded) {
|
|
139
|
+
this.player_element?.removeEventListener("ended", this._onEnded);
|
|
140
|
+
this._onEnded = null;
|
|
141
|
+
}
|
|
142
|
+
if (this._onSourceError) {
|
|
143
|
+
this._el.source_item?.removeEventListener("error", this._onSourceError);
|
|
144
|
+
this._onSourceError = null;
|
|
145
|
+
}
|
|
146
|
+
const el = this.player_element;
|
|
147
|
+
if (el) {
|
|
148
|
+
el.pause();
|
|
149
|
+
// dropping the source stops the network fetch immediately
|
|
150
|
+
el.removeAttribute("src");
|
|
151
|
+
el.load();
|
|
152
|
+
}
|
|
153
|
+
this.player_element = null;
|
|
154
|
+
|
|
155
|
+
this._onCanPlay = null;
|
|
156
|
+
|
|
157
|
+
this._onSourceError = null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_getType(url: string, spec: HtmlMediaSpec): string {
|
|
161
|
+
const ext = url.match((this.data.mediatype as { match_str: string | RegExp }).match_str);
|
|
162
|
+
if (!ext) {
|
|
163
|
+
return "";
|
|
164
|
+
}
|
|
165
|
+
return mimeSubtype(ext[1], spec);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Media } from "../Media";
|
|
2
|
+
import Dom from "../../dom/Dom";
|
|
3
|
+
import { buildIframe } from "../EmbedUtil";
|
|
4
|
+
|
|
5
|
+
/* Media.IFrame
|
|
6
|
+
================================================== */
|
|
7
|
+
|
|
8
|
+
export default class IFrame extends Media {
|
|
9
|
+
declare "media_id": string;
|
|
10
|
+
|
|
11
|
+
/* Load the media
|
|
12
|
+
================================================== */
|
|
13
|
+
_loadMedia() {
|
|
14
|
+
// Loading Message
|
|
15
|
+
this.loadingMessage();
|
|
16
|
+
|
|
17
|
+
// Create Dom element
|
|
18
|
+
this._el.content_item = Dom.create(
|
|
19
|
+
"div",
|
|
20
|
+
"vco-media-item vco-media-iframe",
|
|
21
|
+
this._el.content,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
// Get Media ID
|
|
25
|
+
this.media_id = this._url();
|
|
26
|
+
|
|
27
|
+
// The url field holds a user-pasted embed snippet. Rebuild a
|
|
28
|
+
// clean iframe from its src instead of injecting the raw markup,
|
|
29
|
+
// which would allow stored XSS via the storymap JSON.
|
|
30
|
+
const iframe = buildIframe(this.media_id);
|
|
31
|
+
|
|
32
|
+
if (!iframe) {
|
|
33
|
+
this.loadErrorDisplay(
|
|
34
|
+
"Invalid embed code. Paste an iframe embed code with an http(s) source URL.",
|
|
35
|
+
);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// API Call
|
|
40
|
+
this._el.content_item.appendChild(iframe);
|
|
41
|
+
|
|
42
|
+
// After Loaded
|
|
43
|
+
this.onLoaded();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Update Media Display
|
|
47
|
+
_updateMediaDisplay() {
|
|
48
|
+
this._sizeContentItemToOptionHeight();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Media } from "../Media";
|
|
2
|
+
import Dom from "../../dom/Dom";
|
|
3
|
+
import { validateWebURL } from "../EmbedUtil";
|
|
4
|
+
|
|
5
|
+
/* IIIF Image API 2/3 URL tail: .../region/size/rotation/quality.format
|
|
6
|
+
(optionally a query string). Used to request container-matched widths
|
|
7
|
+
instead of the full-size image (perf, backwards-compatible). */
|
|
8
|
+
const IIIF_TAIL =
|
|
9
|
+
/\/(full|max|pct:[\d.]+|\d+,?\d*)\/(full|max|pct:[\d.]+|\d+,?\d*)\/(\d+|full)\/(default|color|gray|bitonal)\.(jpg|jpeg|png|webp|gif)(\?.*)?$/i;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Rewrite an IIIF Image API URL to the given pixel width (`w,` size
|
|
13
|
+
* component, height unconstrained). Returns the URL unchanged when it is
|
|
14
|
+
* not a recognizable IIIF image URL.
|
|
15
|
+
*/
|
|
16
|
+
export function iiifSizedUrl(url: string | null, width: number): string | null {
|
|
17
|
+
if (!url || !(width > 0)) {
|
|
18
|
+
return url;
|
|
19
|
+
}
|
|
20
|
+
const match = url.match(IIIF_TAIL);
|
|
21
|
+
if (!match) {
|
|
22
|
+
return url;
|
|
23
|
+
}
|
|
24
|
+
return (
|
|
25
|
+
url.slice(0, match.index) +
|
|
26
|
+
`/${match[1]}/${width},/${match[3]}/${match[4]}.${match[5]}${match[6] ?? ""}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Media.Image
|
|
31
|
+
Produces image assets.
|
|
32
|
+
Takes a data object and populates a dom object
|
|
33
|
+
================================================== */
|
|
34
|
+
|
|
35
|
+
export default class Image extends Media {
|
|
36
|
+
/* Load the media
|
|
37
|
+
================================================== */
|
|
38
|
+
_loadMedia() {
|
|
39
|
+
// Loading Message
|
|
40
|
+
this.loadingMessage();
|
|
41
|
+
|
|
42
|
+
// Link — protocol-checked: a `javascript:` href in the storymap JSON
|
|
43
|
+
// would be a click-through XSS (see Media._initLayout)
|
|
44
|
+
const link_href = this.data.link ? validateWebURL(this.data.link) : null;
|
|
45
|
+
if (link_href) {
|
|
46
|
+
this._el.content_link = Dom.create("a", "", this._el.content);
|
|
47
|
+
const content_link = this._el.content_link as HTMLAnchorElement;
|
|
48
|
+
content_link.href = link_href;
|
|
49
|
+
content_link.target = "_blank";
|
|
50
|
+
content_link.rel = "noopener noreferrer";
|
|
51
|
+
this._el.content_item = Dom.create(
|
|
52
|
+
"img",
|
|
53
|
+
"vco-media-item vco-media-image vco-media-shadow",
|
|
54
|
+
this._el.content_link,
|
|
55
|
+
);
|
|
56
|
+
} else {
|
|
57
|
+
this._el.content_item = Dom.create(
|
|
58
|
+
"img",
|
|
59
|
+
"vco-media-item vco-media-image vco-media-shadow",
|
|
60
|
+
this._el.content,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Media Loaded Event
|
|
65
|
+
this._el.content_item.addEventListener("load", (e) => {
|
|
66
|
+
this.onMediaLoaded();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const img = this._el.content_item as HTMLImageElement;
|
|
70
|
+
// offscreen/preloaded slides stay lazy (the active slide is
|
|
71
|
+
// upgraded to eager on activation, see Slide.setActive); decoding
|
|
72
|
+
// is only a hint — old browsers ignore both attributes
|
|
73
|
+
img.decoding = "async";
|
|
74
|
+
img.loading = this._state.eager ? "eager" : "lazy";
|
|
75
|
+
// responsive sizes (perf): IIIF image URLs request a container-
|
|
76
|
+
// matched width; author-provided srcset/sizes pass through;
|
|
77
|
+
// everything else renders byte-identically
|
|
78
|
+
const media_width = Number(this.options.width) || 0;
|
|
79
|
+
const sized = iiifSizedUrl(this._url(), media_width);
|
|
80
|
+
img.src = sized ?? this._url();
|
|
81
|
+
// accessibility: explicit alt text, falling back to the caption as
|
|
82
|
+
// plain text; an empty string marks a decorative image
|
|
83
|
+
img.alt = this._altText();
|
|
84
|
+
if (this.data.srcset) {
|
|
85
|
+
img.srcset = this.data.srcset as string;
|
|
86
|
+
}
|
|
87
|
+
if (this.data.sizes) {
|
|
88
|
+
img.sizes = this.data.sizes as string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// the element is built and the src is set: hand over to Media so the
|
|
92
|
+
// loading overlay is hidden and credit/caption are rendered. The
|
|
93
|
+
// `load` listener above only fires the separate media_loaded event.
|
|
94
|
+
this.onLoaded();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_altText(): string {
|
|
98
|
+
const alt = this.data.alt as string | undefined;
|
|
99
|
+
if (alt !== undefined && alt !== "") {
|
|
100
|
+
return alt;
|
|
101
|
+
}
|
|
102
|
+
const caption = this.data.caption as string | null | undefined;
|
|
103
|
+
if (caption) {
|
|
104
|
+
return caption
|
|
105
|
+
.replace(/<[^>]*>/g, " ")
|
|
106
|
+
.replace(/\s+/g, " ")
|
|
107
|
+
.trim();
|
|
108
|
+
}
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
_updateMediaDisplay(layout?: string) {
|
|
113
|
+
// modern browsers size media correctly without engine-specific fixes
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Media } from "../Media";
|
|
2
|
+
import Dom from "../../dom/Dom";
|
|
3
|
+
import { buildIframe } from "../EmbedUtil";
|
|
4
|
+
|
|
5
|
+
/* Media.Juxtapose
|
|
6
|
+
Embeds a JuxtaposeJS before/after slider (issue #360)
|
|
7
|
+
================================================== */
|
|
8
|
+
|
|
9
|
+
export default class Juxtapose extends Media {
|
|
10
|
+
/* Load the media
|
|
11
|
+
================================================== */
|
|
12
|
+
_loadMedia() {
|
|
13
|
+
// Loading Message
|
|
14
|
+
this.loadingMessage();
|
|
15
|
+
|
|
16
|
+
// Create Dom element
|
|
17
|
+
this._el.content_item = Dom.create(
|
|
18
|
+
"div",
|
|
19
|
+
"vco-media-item vco-media-iframe vco-media-juxtapose",
|
|
20
|
+
this._el.content,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// Built through buildIframe rather than an `<iframe src="${url}">`
|
|
24
|
+
// template string: interpolating a storymap-JSON string into markup
|
|
25
|
+
// is a stored-XSS break-out (`"><img src=x onerror=...>`), and
|
|
26
|
+
// MediaType routes *any* URL containing "juxtapose" here.
|
|
27
|
+
const embed = buildIframe(`<iframe src="${String(this._url() ?? "")}"></iframe>`);
|
|
28
|
+
if (!embed) {
|
|
29
|
+
this.loadErrorDisplay("Invalid URL.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
embed.setAttribute("loading", "lazy");
|
|
33
|
+
this._el.content_item.appendChild(embed);
|
|
34
|
+
this.onLoaded();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Update Media Display
|
|
38
|
+
_updateMediaDisplay() {
|
|
39
|
+
this._sizeContentItemToOptionHeight();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Media } from "../Media";
|
|
2
|
+
import Dom from "../../dom/Dom";
|
|
3
|
+
import { sanitizeSlideText } from "../EmbedUtil";
|
|
4
|
+
|
|
5
|
+
/* Media.SoundCloud
|
|
6
|
+
================================================== */
|
|
7
|
+
|
|
8
|
+
/* Minimal surface of the SoundCloud widget API used here. */
|
|
9
|
+
interface SoundCloudWidget {
|
|
10
|
+
pause: () => void;
|
|
11
|
+
unbind?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default class SoundCloud extends Media {
|
|
15
|
+
declare "media_id": string;
|
|
16
|
+
declare "soundCloudCreated": boolean;
|
|
17
|
+
declare "widget": SoundCloudWidget | null;
|
|
18
|
+
|
|
19
|
+
/* Load the media
|
|
20
|
+
================================================== */
|
|
21
|
+
async _loadMedia() {
|
|
22
|
+
// Loading Message
|
|
23
|
+
this.loadingMessage();
|
|
24
|
+
|
|
25
|
+
// Create Dom element
|
|
26
|
+
this._el.content_item = Dom.create(
|
|
27
|
+
"div",
|
|
28
|
+
"vco-media-item vco-media-iframe vco-media-soundcloud vco-media-shadow",
|
|
29
|
+
this._el.content,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Get Media ID
|
|
33
|
+
this.media_id = this._url();
|
|
34
|
+
|
|
35
|
+
// API URL
|
|
36
|
+
const api_url = "https://soundcloud.com/oembed?url=" + this.media_id + "&format=json";
|
|
37
|
+
|
|
38
|
+
// API Call
|
|
39
|
+
try {
|
|
40
|
+
const r = await fetch(api_url);
|
|
41
|
+
const d = await r.json();
|
|
42
|
+
await this.loadScript("https://w.soundcloud.com/player/api.js");
|
|
43
|
+
//load soundcloud api for pausing.
|
|
44
|
+
this.createMedia(d);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
// aborted loads stay silent (the visitor navigated away);
|
|
47
|
+
// real failures show the media error display
|
|
48
|
+
if ((err as DOMException)?.name !== "AbortError") {
|
|
49
|
+
this.loadErrorDisplay("Unable to load this track.");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
createMedia(d: unknown) {
|
|
55
|
+
const data = d as { html: string };
|
|
56
|
+
if (!data?.html) {
|
|
57
|
+
this.loadErrorDisplay("Unable to load this track.");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// The oEmbed response is third-party HTML. It is sanitized like any
|
|
61
|
+
// other untrusted markup, which in practice keeps the provider's
|
|
62
|
+
// <iframe> (rebuilt by the sanitizer) and drops its inline script —
|
|
63
|
+
// the widget is created from the iframe below, so the script was never
|
|
64
|
+
// needed in the first place.
|
|
65
|
+
const content_item = this._el.content_item;
|
|
66
|
+
if (!content_item) {
|
|
67
|
+
this.loadErrorDisplay("Unable to load this track.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
content_item.appendChild(sanitizeSlideText(data.html));
|
|
71
|
+
|
|
72
|
+
this.soundCloudCreated = true;
|
|
73
|
+
|
|
74
|
+
const sc = SC as { Widget: (iframe: Element | null) => SoundCloudWidget };
|
|
75
|
+
// per-instance widget: a global would be overwritten by every
|
|
76
|
+
// SoundCloud slide and _stopMedia would pause the wrong one
|
|
77
|
+
this.widget = sc.Widget(content_item.querySelector("iframe"));
|
|
78
|
+
|
|
79
|
+
// After Loaded
|
|
80
|
+
this.onLoaded();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_stopMedia() {
|
|
84
|
+
if (this.soundCloudCreated) {
|
|
85
|
+
this.widget?.pause();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Unbind the widget so it stops playing once the slide is gone. */
|
|
90
|
+
_disposeMedia() {
|
|
91
|
+
try {
|
|
92
|
+
this.widget?.unbind?.();
|
|
93
|
+
} catch (err) {
|
|
94
|
+
console.log(err);
|
|
95
|
+
}
|
|
96
|
+
this.widget = null;
|
|
97
|
+
this.soundCloudCreated = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { mergeData, htmlify, convertUnixTime } from "../../core/Util";
|
|
2
|
+
import { Evented, type EventedInstance } from "../../core/mixins";
|
|
3
|
+
import Dom from "../../dom/Dom";
|
|
4
|
+
import { sanitizeSlideText } from "../EmbedUtil";
|
|
5
|
+
|
|
6
|
+
interface TextData {
|
|
7
|
+
uniqueid?: string | null;
|
|
8
|
+
headline?: string;
|
|
9
|
+
text?: string;
|
|
10
|
+
text_align?: string;
|
|
11
|
+
date?: { created_time?: string; [key: string]: unknown } | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface TextOptions {
|
|
15
|
+
title?: boolean;
|
|
16
|
+
text_align?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class TextBase {
|
|
20
|
+
declare "_el": Record<string, HTMLElement>;
|
|
21
|
+
declare "data": TextData;
|
|
22
|
+
declare "options": TextOptions;
|
|
23
|
+
declare "fire": EventedInstance["fire"];
|
|
24
|
+
|
|
25
|
+
/* Constructor
|
|
26
|
+
================================================== */
|
|
27
|
+
constructor(data: TextData, options?: TextOptions, add_to_container?: HTMLElement) {
|
|
28
|
+
// DOM ELEMENTS
|
|
29
|
+
this._el = {
|
|
30
|
+
container: {} as HTMLElement,
|
|
31
|
+
content_container: {} as HTMLElement,
|
|
32
|
+
content: {} as HTMLElement,
|
|
33
|
+
headline: {} as HTMLElement,
|
|
34
|
+
date: {} as HTMLElement,
|
|
35
|
+
start_btn: {} as HTMLElement,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Data. The placeholders were the literal strings "headline" and
|
|
39
|
+
// "text", which mergeData only overwrites when the key is present — so
|
|
40
|
+
// a slide with body text and no headline rendered an <h2>headline</h2>.
|
|
41
|
+
// The renderer guards both on `!== ""`, so empty is the real default.
|
|
42
|
+
this.data = {
|
|
43
|
+
uniqueid: "",
|
|
44
|
+
headline: "",
|
|
45
|
+
text: "",
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Options
|
|
49
|
+
this.options = {
|
|
50
|
+
title: false,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
mergeData(this.data, data);
|
|
54
|
+
|
|
55
|
+
// Merge Options
|
|
56
|
+
mergeData(this.options, options);
|
|
57
|
+
|
|
58
|
+
this._el.container = Dom.create("div", "vco-text");
|
|
59
|
+
this._el.container.id = this.data.uniqueid ?? "";
|
|
60
|
+
|
|
61
|
+
this._initLayout();
|
|
62
|
+
|
|
63
|
+
if (add_to_container) {
|
|
64
|
+
add_to_container.appendChild(this._el.container);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Adding, Hiding, Showing etc
|
|
69
|
+
================================================== */
|
|
70
|
+
show() {}
|
|
71
|
+
|
|
72
|
+
hide() {}
|
|
73
|
+
|
|
74
|
+
addTo(container: HTMLElement) {
|
|
75
|
+
container.appendChild(this._el.container);
|
|
76
|
+
//this.onAdd();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
removeFrom(container: HTMLElement) {
|
|
80
|
+
container.removeChild(this._el.container);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
headlineHeight() {
|
|
84
|
+
return this._el.headline.offsetHeight + 40;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
addDateText(str: string) {
|
|
88
|
+
if (this._el.date) {
|
|
89
|
+
this._el.date.innerHTML = str;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* Events
|
|
94
|
+
================================================== */
|
|
95
|
+
onLoaded() {
|
|
96
|
+
this.fire("loaded", this.data);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
onAdd() {
|
|
100
|
+
this.fire("added", this.data);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
onRemove() {
|
|
104
|
+
this.fire("removed", this.data);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Private Methods
|
|
108
|
+
================================================== */
|
|
109
|
+
_initLayout() {
|
|
110
|
+
// Create Layout
|
|
111
|
+
this._el.content_container = Dom.create(
|
|
112
|
+
"div",
|
|
113
|
+
"vco-text-content-container",
|
|
114
|
+
this._el.container,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// Text alignment: per-slide override wins, then the storymap option
|
|
118
|
+
// (issue #244)
|
|
119
|
+
const align =
|
|
120
|
+
(this.data.text_align as string | undefined) ??
|
|
121
|
+
(this.options.text_align as string | undefined) ??
|
|
122
|
+
"left";
|
|
123
|
+
if (align === "center" || align === "right") {
|
|
124
|
+
this._el.content_container.classList.add("vco-text-align-" + align);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Date (only rendered when the slide has one; issue #286)
|
|
128
|
+
if (this.data.date && this.data.date.created_time && this.data.date.created_time !== "") {
|
|
129
|
+
this._el.date = Dom.create("h3", "vco-headline-date", this._el.content_container);
|
|
130
|
+
this.addDateText(convertUnixTime(this.data.date.created_time));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Headline (sanitized; issue #358 keeps formatting but drops scripts)
|
|
134
|
+
const headline = this.data.headline ?? "";
|
|
135
|
+
if (headline !== "") {
|
|
136
|
+
let headline_class = "vco-headline";
|
|
137
|
+
if (this.options.title) {
|
|
138
|
+
headline_class = "vco-headline vco-headline-title";
|
|
139
|
+
}
|
|
140
|
+
this._el.headline = Dom.create("h2", headline_class, this._el.content_container);
|
|
141
|
+
this._el.headline.appendChild(sanitizeSlideText(headline));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Text (sanitized; issue #358 allows extra iframe media in the text field)
|
|
145
|
+
const text = this.data.text ?? "";
|
|
146
|
+
if (text !== "") {
|
|
147
|
+
let text_content = "";
|
|
148
|
+
|
|
149
|
+
text_content += htmlify(text);
|
|
150
|
+
|
|
151
|
+
// Date
|
|
152
|
+
if (
|
|
153
|
+
this.data.date &&
|
|
154
|
+
this.data.date.created_time &&
|
|
155
|
+
this.data.date.created_time !== ""
|
|
156
|
+
) {
|
|
157
|
+
if (this.data.date.created_time.length > 10) {
|
|
158
|
+
text_content +=
|
|
159
|
+
"<div class='vco-text-date'>" +
|
|
160
|
+
convertUnixTime(this.data.date.created_time) +
|
|
161
|
+
"</div>";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
this._el.content = Dom.create("div", "vco-text-content", this._el.content_container);
|
|
166
|
+
this._el.content.appendChild(sanitizeSlideText(text_content));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Fire event that the slide is loaded
|
|
170
|
+
this.onLoaded();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export default class Text extends Evented(TextBase) {
|
|
175
|
+
constructor(...args: ConstructorParameters<typeof TextBase>) {
|
|
176
|
+
super(...args);
|
|
177
|
+
}
|
|
178
|
+
}
|