From 6bfa91f7adf0e65e6d210c040d347b13ace9389d Mon Sep 17 00:00:00 2001 From: Paul Pestov <10750176+paulpestov@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:53:25 +0200 Subject: [PATCH] refactor: add linting fixes --- .eslintrc | 20 + .eslintrc.cjs | 50 - .stylelintrc | 20 + cypress.config.cjs | 1 + examples/gfl-local.html | 2 - examples/style.css | 5 +- package-lock.json | 2361 ++++++++--------- package.json | 27 +- src/App.vue | 17 +- src/components/ContentView.vue | 15 +- src/components/ImageView.vue | 19 +- src/components/Loading.vue | 14 - src/components/LoadingSpinner.vue | 39 + .../{Notification.vue => MessageBox.vue} | 5 +- src/components/TreeView.vue | 63 +- src/components/annotations/AnnotationIcon.vue | 4 - .../annotations/AnnotationsList.vue | 15 +- .../annotations/AnnotationsView.vue | 8 +- src/components/base/BaseButton.vue | 25 +- src/components/base/BaseCheckbox.vue | 18 +- src/components/base/BaseDialog.vue | 19 +- src/components/base/BaseDropdown.vue | 5 +- src/components/base/BaseIcon.vue | 2 +- src/components/header/DarkModeToggle.vue | 2 +- src/components/header/GlobalHeader.vue | 22 +- .../{Language.vue => LanguageSwitch.vue} | 0 .../header/{Navbar.vue => NavBar.vue} | 4 +- src/components/header/PanelsToggle.vue | 23 +- src/components/header/SoftwareInfo.vue | 44 +- src/components/header/TitleBar.vue | 22 +- .../header/{Tools.vue => ToolBar.vue} | 6 +- src/components/metadata/Actor.vue | 14 +- .../metadata/CollectionMetadata.vue | 29 +- src/components/metadata/ItemMetadata.vue | 18 +- src/components/metadata/ManifestMetadata.vue | 25 +- src/components/metadata/MetadataItem.vue | 23 +- src/components/metadata/MetadataValue.vue | 19 - src/components/panels/Panel.vue | 139 +- src/components/panels/PanelsWrapper.vue | 2 +- .../panels/actions/PanelImageAction.vue | 5 +- .../panels/actions/PanelToggleAction.vue | 11 +- .../panels/actions/PanelZoomAction.vue | 6 +- src/css/_global.scss | 8 +- src/css/_scrollbar.scss | 1 - src/css/_tooltip.scss | 2 +- src/css/preflight.scss | 13 +- src/services/bookmark.js | 2 +- src/stores/contents.ts | 220 +- src/types.d.ts | 10 +- src/utils/annotations.js | 2 + src/utils/icons/index.js | 1 - tests/mocks/ahiqar/content/ahiqar.css | 12 +- 52 files changed, 1700 insertions(+), 1739 deletions(-) create mode 100644 .eslintrc delete mode 100644 .eslintrc.cjs create mode 100644 .stylelintrc delete mode 100644 src/components/Loading.vue create mode 100644 src/components/LoadingSpinner.vue rename src/components/{Notification.vue => MessageBox.vue} (92%) rename src/components/header/{Language.vue => LanguageSwitch.vue} (100%) rename src/components/header/{Navbar.vue => NavBar.vue} (100%) rename src/components/header/{Tools.vue => ToolBar.vue} (81%) diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..b72b9895 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,20 @@ +{ + "root": true, + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:vue/vue3-recommended" + ], + "parser": "vue-eslint-parser", + "parserOptions": { + "parser": "@typescript-eslint/parser" + }, + "rules": { + "no-undef": "off", + "vue/multi-word-component-names": "off", + "vue/no-v-html": "off" + } +} diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index f67fb027..00000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = { - root: true, - - env: { - browser: true, - }, - - extends: [ - 'airbnb-base', - 'plugin:vue/vue3-essential', - '@vue/eslint-config-typescript' - ], - globals: { - ga: true, // Google Analytics - cordova: true, - __statics: true, - process: true, - Capacitor: true, - chrome: true, - }, - - // add your custom rules here - rules: { - 'no-param-reassign': 'off', - 'import/first': 'off', - 'import/named': 'error', - 'import/namespace': 'error', - 'import/default': 'error', - 'import/export': 'error', - 'import/extensions': 'off', - 'import/no-unresolved': 'off', - 'import/no-extraneous-dependencies': 'off', - 'import/prefer-default-export': 'off', - 'import/no-mutable-exports': 'off', - 'prefer-promise-reject-errors': 'off', - 'no-use-before-define': 'off', - 'no-return-assign': 'off', - 'vue/multi-word-component-names': 'off', - 'no-promise-executor-return': 'off', - 'vue/no-deprecated-slot-attribute': 'off', - 'no-throw-literal': 'off', - 'class-methods-use-this': 'off', - - // allow debugger during development only - 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', - 'max-len': 0, - 'allow-parens': 'off', - 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], - }, -}; diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 00000000..20a117c1 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,20 @@ +{ + "extends": ["stylelint-config-standard"], + "overrides": [ + { + "files": ["*.scss", "**/*.scss"], + "extends": ["stylelint-config-standard-scss"] + }, + { + "files": ["*.vue", "**/*.vue"], + "extends": [ + "stylelint-config-standard-scss", + "stylelint-config-standard-vue/scss" + ] + } + ], + "rules": { + "at-rule-no-unknown": null, + "no-descending-specificity": null + } +} diff --git a/cypress.config.cjs b/cypress.config.cjs index 5757b74c..13c1e355 100644 --- a/cypress.config.cjs +++ b/cypress.config.cjs @@ -4,6 +4,7 @@ module.exports = defineConfig({ viewportWidth: 1400, viewportHeight: 800, experimentalSourceRewriting: true, + chromeWebSecurity: false, screenshotsFolder: 'tests/cypress/screenshots', downloadsFolder: 'tests/cypress/downloads', fixturesFolder: 'tests/cypress/fixtures', diff --git a/examples/gfl-local.html b/examples/gfl-local.html index a5bcd7a9..ec4adf50 100644 --- a/examples/gfl-local.html +++ b/examples/gfl-local.html @@ -21,9 +21,7 @@
-
- diff --git a/src/components/LoadingSpinner.vue b/src/components/LoadingSpinner.vue new file mode 100644 index 00000000..a4f05644 --- /dev/null +++ b/src/components/LoadingSpinner.vue @@ -0,0 +1,39 @@ + + + diff --git a/src/components/Notification.vue b/src/components/MessageBox.vue similarity index 92% rename from src/components/Notification.vue rename to src/components/MessageBox.vue index ef5d3a73..a691d6fc 100644 --- a/src/components/Notification.vue +++ b/src/components/MessageBox.vue @@ -8,7 +8,10 @@ /> {{ title || message }} -
+
diff --git a/src/components/TreeView.vue b/src/components/TreeView.vue index a080caa9..8a0b9622 100644 --- a/src/components/TreeView.vue +++ b/src/components/TreeView.vue @@ -1,42 +1,47 @@ diff --git a/src/components/annotations/AnnotationIcon.vue b/src/components/annotations/AnnotationIcon.vue index aa341a30..37199625 100644 --- a/src/components/annotations/AnnotationIcon.vue +++ b/src/components/annotations/AnnotationIcon.vue @@ -16,7 +16,3 @@ interface Props { defineProps(); - - diff --git a/src/components/annotations/AnnotationsList.vue b/src/components/annotations/AnnotationsList.vue index 44551136..f117f4d2 100644 --- a/src/components/annotations/AnnotationsList.vue +++ b/src/components/annotations/AnnotationsList.vue @@ -2,8 +2,8 @@
{} : toggle(annotation)" >
- +
@@ -22,7 +25,7 @@ diff --git a/src/components/annotations/AnnotationsView.vue b/src/components/annotations/AnnotationsView.vue index 72c3ff3b..777e3ba2 100644 --- a/src/components/annotations/AnnotationsView.vue +++ b/src/components/annotations/AnnotationsView.vue @@ -9,7 +9,7 @@ :toggle="toggle" :types="types" /> - - - diff --git a/src/components/base/BaseButton.vue b/src/components/base/BaseButton.vue index 59823575..abb040ec 100644 --- a/src/components/base/BaseButton.vue +++ b/src/components/base/BaseButton.vue @@ -92,16 +92,31 @@ classes['t-bg-transparent hover:t-bg-gray-300/30 dark:hover:t-bg-gray-600 ' diff --git a/src/components/base/BaseCheckbox.vue b/src/components/base/BaseCheckbox.vue index c38a8d4e..edfe722a 100644 --- a/src/components/base/BaseCheckbox.vue +++ b/src/components/base/BaseCheckbox.vue @@ -57,16 +57,24 @@ function getAriaChecked(): AriaChecked { diff --git a/src/components/base/BaseIcon.vue b/src/components/base/BaseIcon.vue index cad20299..87bd124b 100644 --- a/src/components/base/BaseIcon.vue +++ b/src/components/base/BaseIcon.vue @@ -9,7 +9,7 @@ defineProps(); diff --git a/src/components/header/TitleBar.vue b/src/components/header/TitleBar.vue index 8b43bd34..d8307cbe 100644 --- a/src/components/header/TitleBar.vue +++ b/src/components/header/TitleBar.vue @@ -2,10 +2,16 @@
-

+

TIDO Viewer

@@ -44,7 +56,7 @@ export interface Props { item: Item } -const props = withDefaults(defineProps(), { +withDefaults(defineProps(), { item: () => {} }) diff --git a/src/components/header/Tools.vue b/src/components/header/ToolBar.vue similarity index 81% rename from src/components/header/Tools.vue rename to src/components/header/ToolBar.vue index ccc67562..d6c54afb 100644 --- a/src/components/header/Tools.vue +++ b/src/components/header/ToolBar.vue @@ -1,7 +1,7 @@ @@ -10,7 +10,7 @@ import { computed } from 'vue'; import { useConfigStore } from '@/stores/config'; import SoftwareInfo from '@/components/header/SoftwareInfo.vue'; -import Language from '@/components/header/Language.vue'; +import LanguageSwitch from '@/components/header/LanguageSwitch.vue'; import DarkModeToggle from '@/components/header/DarkModeToggle.vue'; const configStore = useConfigStore(); diff --git a/src/components/metadata/Actor.vue b/src/components/metadata/Actor.vue index f63e9251..7491ab0a 100644 --- a/src/components/metadata/Actor.vue +++ b/src/components/metadata/Actor.vue @@ -1,9 +1,13 @@ @@ -17,7 +21,7 @@ export interface Props { data: Actor[] } -const props = withDefaults(defineProps(), { +withDefaults(defineProps(), { data: () => [], }); @@ -28,7 +32,3 @@ function getRole(actorItem: Actor) : string { return role[0]; } - - diff --git a/src/components/metadata/CollectionMetadata.vue b/src/components/metadata/CollectionMetadata.vue index beda728d..898f8b16 100644 --- a/src/components/metadata/CollectionMetadata.vue +++ b/src/components/metadata/CollectionMetadata.vue @@ -1,8 +1,17 @@ @@ -37,17 +46,13 @@ const metadata = computed(() => { return [ ...collectionTitle - .filter((collection) => collection) - .map((collectionTitle) => ({ - key: mappings[collectionTitle.type] || 'title', - value: collectionTitle.title, + .filter((c) => c) + .map((title) => ({ + key: mappings[title.type] || 'title', + value: title.title, })), ...(collectorName ? [{ key: 'collector', value: collectorName }] : []), ...(description ? [{ key: 'description', value: description }] : []), ]; }); - - diff --git a/src/components/metadata/ItemMetadata.vue b/src/components/metadata/ItemMetadata.vue index ea1ff4bc..469d278f 100644 --- a/src/components/metadata/ItemMetadata.vue +++ b/src/components/metadata/ItemMetadata.vue @@ -1,8 +1,14 @@ @@ -31,10 +37,6 @@ const metadata = computed(() => ( { key: 'language', value: item.value?.lang?.join(',') }, { key: 'image_license', value: item.value?.image?.license?.id }, { key: 'image_notes', value: item.value?.image?.license?.notes }, - ].filter((item) => item.value) + ].filter((i) => i.value) )); - - diff --git a/src/components/metadata/ManifestMetadata.vue b/src/components/metadata/ManifestMetadata.vue index 06efb1aa..7c688df8 100644 --- a/src/components/metadata/ManifestMetadata.vue +++ b/src/components/metadata/ManifestMetadata.vue @@ -1,10 +1,19 @@ @@ -36,9 +45,5 @@ const metadata = computed(() => { ...(manifest.value.metadata || []), ]; }); -const actor = computed(() => manifest.value?.actor); +const actor = computed(() => manifest.value?.actor); - - diff --git a/src/components/metadata/MetadataItem.vue b/src/components/metadata/MetadataItem.vue index 74636743..62bd1147 100644 --- a/src/components/metadata/MetadataItem.vue +++ b/src/components/metadata/MetadataItem.vue @@ -1,11 +1,26 @@ diff --git a/src/components/metadata/MetadataValue.vue b/src/components/metadata/MetadataValue.vue index b66c2f59..0b3a90fa 100644 --- a/src/components/metadata/MetadataValue.vue +++ b/src/components/metadata/MetadataValue.vue @@ -22,25 +22,6 @@ withDefaults(defineProps(), { flex-wrap: wrap; } -.content__link { - display: flex; - align-items: center; - border-bottom: 1px var(--q-primary) dotted; - text-decoration: none; - - @media (prefers-color-scheme: dark) { - border-color: var(--q-white); - } -} - -.content__link { - &:focus, - &:hover, - &:active { - border-bottom-style: solid; - } -} - .url-text { display: flex; padding-right: 4px; diff --git a/src/components/panels/Panel.vue b/src/components/panels/Panel.vue index e10f5218..72da4e7d 100644 --- a/src/components/panels/Panel.vue +++ b/src/components/panels/Panel.vue @@ -4,82 +4,113 @@
{{ $t(panel.label) }} - {{$t(tabs[0].label)}} + {{ $t(tabs[0].label) }}
- diff --git a/src/components/panels/actions/PanelToggleAction.vue b/src/components/panels/actions/PanelToggleAction.vue index 86342946..a71492b1 100644 --- a/src/components/panels/actions/PanelToggleAction.vue +++ b/src/components/panels/actions/PanelToggleAction.vue @@ -1,7 +1,14 @@ diff --git a/src/components/panels/actions/PanelZoomAction.vue b/src/components/panels/actions/PanelZoomAction.vue index 31852753..8c3f9c79 100644 --- a/src/components/panels/actions/PanelZoomAction.vue +++ b/src/components/panels/actions/PanelZoomAction.vue @@ -9,8 +9,7 @@ :title="$t('increase')" class="t-text-primary dark:t-text-gray-400" @click="increase()" - > - + /> - + />
diff --git a/src/css/_global.scss b/src/css/_global.scss index 33151388..eca70ee9 100644 --- a/src/css/_global.scss +++ b/src/css/_global.scss @@ -2,6 +2,7 @@ display: flex; width: 100%; height: 100%; + @media (min-width: $breakpoint-lg-min) { min-height: 400px; min-width: 400px; @@ -13,9 +14,6 @@ z-index: 1; width: 100%; height: 100%; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0,0,0,0.04); + inset: 0; + background: rgb(0 0 0 / 4%); } diff --git a/src/css/_scrollbar.scss b/src/css/_scrollbar.scss index 2d04a925..f8a52cc9 100644 --- a/src/css/_scrollbar.scss +++ b/src/css/_scrollbar.scss @@ -1,6 +1,5 @@ $foreground: #cacaca; $background: #eee; - $foreground-dark: #555; $background-dark: #1c1c1c; diff --git a/src/css/_tooltip.scss b/src/css/_tooltip.scss index fea55985..55c43fff 100644 --- a/src/css/_tooltip.scss +++ b/src/css/_tooltip.scss @@ -16,7 +16,7 @@ border: 1px solid #ddd; -webkit-touch-callout: none; - .body--dark & { + [color-scheme="dark"] & { background-color: $dark; border: 1px solid #424242; } diff --git a/src/css/preflight.scss b/src/css/preflight.scss index a9e943f1..f883497e 100644 --- a/src/css/preflight.scss +++ b/src/css/preflight.scss @@ -10,7 +10,7 @@ box-sizing: border-box; /* 1 */ border-width: 0; /* 2 */ border-style: solid; /* 2 */ - border-color: theme('borderColor.DEFAULT', currentColor); /* 2 */ + border-color: theme('borderColor.DEFAULT', currentcolor); /* 2 */ } *::before, @@ -29,8 +29,7 @@ */ line-height: 1.5; /* 1 */ - -webkit-text-size-adjust: 100%; /* 2 */ - -moz-tab-size: 4; /* 3 */ + text-size-adjust: 100%; /* 2 */ /* 3 */ tab-size: 4; /* 3 */ font-family: theme('fontFamily.sans', ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"); /* 4 */ font-feature-settings: theme('fontFamily.sans[1].fontFeatureSettings', normal); /* 5 */ @@ -195,7 +194,7 @@ [type='button'], [type='reset'], [type='submit'] { - -webkit-appearance: button; /* 1 */ + appearance: button; /* 1 */ background-color: transparent; /* 2 */ background-image: none; /* 2 */ } @@ -239,7 +238,7 @@ */ [type='search'] { - -webkit-appearance: textfield; /* 1 */ + appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } @@ -248,7 +247,7 @@ */ &::-webkit-search-decoration { - -webkit-appearance: none; + appearance: none; } /* @@ -257,7 +256,7 @@ */ &::-webkit-file-upload-button { - -webkit-appearance: button; /* 1 */ + appearance: button; /* 1 */ font: inherit; /* 2 */ } diff --git a/src/services/bookmark.js b/src/services/bookmark.js index b126d3ac..94e6a74f 100644 --- a/src/services/bookmark.js +++ b/src/services/bookmark.js @@ -11,7 +11,7 @@ class BookmarkService { getValueInOldQuery(oldQueryValue, key) { const oldQueryArray = oldQueryValue.split('_'); let numbersPart = ''; - oldQueryArray.forEach((part, index) => { + oldQueryArray.forEach((part) => { if (part.includes(key)) { numbersPart = part.slice(1); } diff --git a/src/stores/contents.ts b/src/stores/contents.ts index 54fd4360..3e3a41b3 100644 --- a/src/stores/contents.ts +++ b/src/stores/contents.ts @@ -1,91 +1,85 @@ -import { defineStore } from 'pinia' +import { defineStore } from 'pinia'; import { - computed, ref, - } from 'vue'; + computed, ref, +} from 'vue'; import { request } from '@/utils/http'; import { i18n } from '@/i18n'; import BookmarkService from '@/services/bookmark'; import { loadCss, loadFont } from '../utils'; -import { c } from 'vite/dist/node/types.d-aGj9QkWt'; import { useConfigStore } from '@/stores/config'; import { useAnnotationsStore } from '@/stores/annotations'; +export const useContentsStore = defineStore('contents', () => { + const activeContentUrl = ref(null); + const collection = ref(null); + const item = ref(null); + const itemUrl = ref(null); + const manifests = ref(null); + const manifest = ref(null); - export const useContentsStore = defineStore('contents', () => { - - const activeContentUrl = ref(null) - const collection = ref(null) - const item = ref(null) - const itemUrl = ref(null) - const manifests = ref(null) - const manifest = ref(null) - - const collectionTitle = computed(() => { - if (!collection.value) return null; - - if (Object.keys(collection.value).length) { - return collection.value.title[0].title - ? collection.value.title[0].title - : 'Undefined collection title'; - } - - return 'Manifest (No label available)' + const collectionTitle = computed(() => { + if (!collection.value) return null; + + if (Object.keys(collection.value).length) { + return collection.value.title[0].title + ? collection.value.title[0].title + : 'Undefined collection title'; + } + + return 'Manifest (No label available)'; }); - const itemIndex = computed (() => { + const itemIndex = computed(() => { if (!manifest.value) return -1; return manifest.value.sequence.findIndex((item) => item.id === itemUrl.value); }); - function setCollection(payload: Collection) { - collection.value = { ...payload } + collection.value = { ...payload }; } - function setItem (payload: Item) { - item.value = payload + function setItem(payload: Item) { + item.value = payload; } - function setItemUrl (payload: string) { - itemUrl.value = payload + function setItemUrl(payload: string) { + itemUrl.value = payload; } function setManifests(payload: Manifest[]) { - manifests.value = payload + manifests.value = payload; } - + function setManifest(payload: Manifest) { if (!Array.isArray(payload.sequence)) payload.sequence = [payload.sequence]; manifest.value = { ...payload }; - } + } function setActiveContentUrl(payload: string) { - activeContentUrl.value = payload + activeContentUrl.value = payload; } - function findActiveManifestIndex(manifests: Manifest[] = [], itemUrl: string | null): number { if (manifests === null) return -1; if (manifests.length === 0) return -1; if (!itemUrl) return 0; - + itemUrl = encodeURI(decodeURI(itemUrl)); - + return manifests.findIndex(({ sequence }) => { sequence = Array.isArray(sequence) ? sequence : [sequence]; return sequence.find(({ id }) => encodeURI(decodeURI(id)) === itemUrl); }); } - + function findManifestIndexOfManifestInConfig(resultConfig) { // Url of manifest is given in resultConfig as 'manifest' const manifestUrl = resultConfig.manifest; return manifests.value.findIndex((element) => element.id === manifestUrl); } - - async function getManifest(url: string): Promise{ + async function getManifest(url: string): Promise { const data: Manifest = await request(url); return data; } @@ -93,31 +87,30 @@ import { useAnnotationsStore } from '@/stores/annotations'; function isManifestPartInsideRangeValue(m: number, numberManifests: number) { return (m >= 0 && m < numberManifests); } - + function isItemPartInsideRangeValue(i: number, numberItems: number) { return (i >= 0 && i < numberItems); } - - const initCollection = async (url: string) => { - const configStore = useConfigStore() - const contentStore = useContentsStore() - const resultConfig = configStore.config + const initCollection = async (url: string) => { + const configStore = useConfigStore(); + const contentStore = useContentsStore(); + const resultConfig = configStore.config; let { item: itemUrl } = resultConfig; let collection: Collection; let activeManifest: Manifest; let manifestIndex: number; let itemIndex: number; - + try { collection = await request(url); } catch (err) { throw new Error(i18n.global.t('error_collection_url')); } - contentStore.setCollection(collection) - + contentStore.setCollection(collection); + const numberManifests: number = Object.keys(collection).length > 0 ? collection.sequence.length : 0; - + if (numberManifests === 0) { throw new Error(i18n.global.t('error_no_manifests_in_initCollection')); } @@ -126,13 +119,13 @@ import { useAnnotationsStore } from '@/stores/annotations'; throw new Error(`Please enter 'm' as integer in this range [0,${numberManifests})`); } } - + if (Array.isArray(collection.sequence) && collection.sequence.length > 0) { const promises = []; collection.sequence.forEach((seq) => promises.push(getManifest(seq.id))); const manifests: Manifest[] = await Promise.all(promises); - contentStore.setManifests(manifests) - + contentStore.setManifests(manifests); + if ('m' in resultConfig && 'i' in resultConfig) { // Check if manifestIndex or item Index are part of the result config manifestIndex = resultConfig.m; @@ -154,32 +147,31 @@ import { useAnnotationsStore } from '@/stores/annotations'; } else { [manifestIndex, itemIndex] = [0, 0]; } - + const numberItems = manifests[manifestIndex].sequence.length; if (!isItemPartInsideRangeValue(itemIndex, numberItems)) { throw new Error(`Please enter 'i' as integer in this range [0,${numberItems})`); } - + activeManifest = manifests[manifestIndex]; itemUrl = activeManifest.sequence[itemIndex].id; const { support } = activeManifest; - + if (support && support.length > 0) { - await contentStore.getSupport(support) + await contentStore.getSupport(support); } - contentStore.setManifest(activeManifest) - - if (item) contentStore.initItem(itemUrl) + contentStore.setManifest(activeManifest); + contentStore.initItem(itemUrl); } }; const initManifest = async (url: string) => { - const contentStore = useContentsStore() + const contentStore = useContentsStore(); let manifest: Manifest; let itemUrl: string; let itemIndex: number; - const configStore = useConfigStore() + const configStore = useConfigStore(); try { manifest = await request(url); @@ -189,12 +181,12 @@ import { useAnnotationsStore } from '@/stores/annotations'; if (Array.isArray(manifest.sequence) && manifest.sequence.length <= 0) { throw new Error(i18n.global.t('error_no_items_in_manifest')); } - + const numberItems: number = manifest.sequence.length; - contentStore.setManifest(manifest) + contentStore.setManifest(manifest); const resultConfig = configStore.config; itemUrl = resultConfig.item; - + if ('collection' in resultConfig && resultConfig.collection === '') { // we make sure that this error doesn't occur when switching manifest (the condition 'm' & 'i' in resultConfig) if (('m' in resultConfig && 'i' in resultConfig) || 'm' in resultConfig) { @@ -214,67 +206,83 @@ import { useAnnotationsStore } from '@/stores/annotations'; } else if (resultConfig.manifest !== '') { itemIndex = 0; } - + const { support } = manifest; if (support && support.length > 0) { - await contentStore.getSupport(support) + await contentStore.getSupport(support); } - + if (itemIndex !== undefined) { if (!isItemPartInsideRangeValue(itemIndex, numberItems)) { throw new Error(`Please enter 'i' as integer in this range [0,${numberItems})`); } itemUrl = manifest.sequence[itemIndex].id; - await contentStore.initItem(itemUrl) + await contentStore.initItem(itemUrl); } }; + const initItem = async (url: string) => { + const annotationStore = useAnnotationsStore(); + const contentStore = useContentsStore(); + let item: Item; - const initItem = async (url: string) => { - const annotationStore = useAnnotationsStore() - const contentStore = useContentsStore() - let item: Item; - - try { - item = await request(url); - } catch (err) { - throw new Error(i18n.global.t('error_item_url')); - } - contentStore.setItem(item) - contentStore.setItemUrl(url) + try { + item = await request(url); + } catch (err) { + throw new Error(i18n.global.t('error_item_url')); + } + contentStore.setItem(item); + contentStore.setItemUrl(url); - if (item.annotationCollection) { - await annotationStore.initAnnotations(item.annotationCollection) - } - // here we have item query -> we should extract the manifest index and the item index from the query and then give it as a parameter to updateItemQuery() + if (item.annotationCollection) { + await annotationStore.initAnnotations(item.annotationCollection); + } + // here we have item query -> we should extract the manifest index and the item index from the query and then give it as a parameter to updateItemQuery() - const i = itemIndex.value; - const m = contentStore.findActiveManifestIndex(manifests.value, url) - - const query = (manifests.value && manifests.value.length > 0) ? { - m, - i, - } : { i }; - await BookmarkService.updateQuery(query); -}; + const i = itemIndex.value; + const m = contentStore.findActiveManifestIndex(manifests.value, url); + const query = (manifests.value && manifests.value.length > 0) ? { + m, + i, + } : { i }; + await BookmarkService.updateQuery(query); + }; -const getSupport = (support) => { - const configStore = useConfigStore() + const getSupport = (support) => { + const configStore = useConfigStore(); const { container } = configStore.config; - + support.forEach((s) => { const hasElement = document.getElementById(s.url); if (s.type === 'font' && !hasElement) loadFont(s.url, container); if (s.type !== 'font' && !hasElement) loadCss(s.url); }); }; - - -return { activeContentUrl, collection, item, itemUrl, manifests, manifest, // states - collectionTitle, itemIndex, // computed - setCollection, setItem, setItemUrl, setManifests, setManifest, setActiveContentUrl, //mutations as functions - findActiveManifestIndex, findManifestIndexOfManifestInConfig, getManifest, isManifestPartInsideRangeValue, // actions as functions - isItemPartInsideRangeValue, initCollection, initManifest, initItem, getSupport - } -}) \ No newline at end of file + + return { + activeContentUrl, + collection, + item, + itemUrl, + manifests, + manifest, // states + collectionTitle, + itemIndex, // computed + setCollection, + setItem, + setItemUrl, + setManifests, + setManifest, + setActiveContentUrl, // mutations as functions + findActiveManifestIndex, + findManifestIndexOfManifestInConfig, + getManifest, + isManifestPartInsideRangeValue, // actions as functions + isItemPartInsideRangeValue, + initCollection, + initManifest, + initItem, + getSupport, + }; +}); diff --git a/src/types.d.ts b/src/types.d.ts index 60e3172c..3c86071c 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,5 +1,5 @@ declare global { - + interface ActiveAnnotation { [key: string]: Annotation } @@ -103,7 +103,7 @@ declare global { manifest?: string, license: License } - + interface Item { '@context': string, @@ -164,7 +164,7 @@ declare global { editionPrints?: boolean } - interface NotificationColors { + interface MessageBoxColors { info: string, warning: string } @@ -199,7 +199,7 @@ declare global { } type SequenceType = 'collection' | 'manifest' | 'item' - type SupportType = 'font' | 'css' + type SupportType = 'font' | 'css' interface Title { '@context': string, @@ -209,4 +209,4 @@ declare global { type TitleType = 'main' | 'sub'; } -export {} \ No newline at end of file +export {} diff --git a/src/utils/annotations.js b/src/utils/annotations.js index fdc3ed07..634b12d4 100644 --- a/src/utils/annotations.js +++ b/src/utils/annotations.js @@ -167,6 +167,7 @@ export function handleRangeSelector(selector) { let started = false; let ended = false; + // eslint-disable-next-line no-inner-declarations function findElementsInRangeRecursive(element) { if (element === start) started = true; if (element === end) { @@ -187,6 +188,7 @@ export function handleRangeSelector(selector) { } }); } + findElementsInRangeRecursive(document.getElementById('text-content')); return elementsInRange.map((el) => Utils.elemToSelector(el)).join(','); diff --git a/src/utils/icons/index.js b/src/utils/icons/index.js index ad3869f3..8116a51d 100644 --- a/src/utils/icons/index.js +++ b/src/utils/icons/index.js @@ -1,4 +1,3 @@ import * as icons from './icons'; -// eslint-disable-next-line import/namespace export const getIcon = (name) => icons[name] || icons.pencil; diff --git a/tests/mocks/ahiqar/content/ahiqar.css b/tests/mocks/ahiqar/content/ahiqar.css index ac47c34a..9a32570a 100644 --- a/tests/mocks/ahiqar/content/ahiqar.css +++ b/tests/mocks/ahiqar/content/ahiqar.css @@ -27,6 +27,7 @@ h1 { font-weight: normal; font-style: normal; } + @font-face { font-family: "Serto Jerusalem"; font-weight: normal; @@ -34,6 +35,7 @@ h1 { src: local("Serto Jerusalem"), url("syrcomjerusalem.woff") format("woff"); } + @font-face { font-family: "Serto Jerusalem"; font-weight: bold; @@ -41,6 +43,7 @@ h1 { src: local("Serto Jerusalem"), url("syrcomjerusalembold.woff") format("woff"); } + @font-face { font-family: "Serto Jerusalem"; font-weight: normal; @@ -125,6 +128,7 @@ h1 { font-weight: normal; font-style: normal; } + @font-face { font-family: "Estrangelo Edessa"; font-weight: normal; @@ -145,18 +149,24 @@ h1 { @media (prefers-color-scheme: dark) { .gap { color: #D5F72B; } + .hi.red { color: #F23A3A; } + .note { background: none; color: #619EFF; text-decoration: none; } + .ref { color: #5895F9; } + .seg { - color: #FFFFFF; } + color: #FFF; } + .quote.colophon { color: #FF6161; } + .tei-lg.colophon { color: #1F9AFF; } }