paginar 0.2.8 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.editorconfig +13 -13
  2. package/.env +1 -1
  3. package/.vscode/extensions.json +3 -3
  4. package/LICENSE.md +21 -0
  5. package/README.md +244 -14
  6. package/demo/slot/slot-chapter1.html +384 -357
  7. package/demo/slot/slot-chapter2.html +366 -366
  8. package/demo/slot/slot-chapter3.html +265 -265
  9. package/demo/summary/_content/1chapter.html +100 -97
  10. package/demo/summary/_content/2chapter.html +311 -311
  11. package/demo/summary/_content/3chapter.html +211 -211
  12. package/demo/summary/index.html +134 -123
  13. package/dist/index.es.js +991 -920
  14. package/dist/index.es.js.map +1 -1
  15. package/dist/style.css +14 -17
  16. package/index.html +18 -18
  17. package/package.json +1 -1
  18. package/src/App.ce.vue +148 -153
  19. package/src/assets/main.css +392 -392
  20. package/src/components/BookContent.vue +23 -23
  21. package/src/components/FooterSlot.vue +32 -32
  22. package/src/components/FootnotesAside.vue +123 -123
  23. package/src/components/HeaderSlot/HeaderSlot.vue +30 -30
  24. package/src/components/HeaderSlot/OptionsButton/OptionsButton.vue +67 -67
  25. package/src/components/HeaderSlot/OptionsButton/OptionsColor.vue +28 -28
  26. package/src/components/HeaderSlot/OptionsButton/OptionsColumns.vue +51 -49
  27. package/src/components/HeaderSlot/OptionsButton/OptionsDropdown.vue +59 -55
  28. package/src/components/HeaderSlot/OptionsButton/OptionsFontFamily.vue +17 -17
  29. package/src/components/HeaderSlot/OptionsButton/OptionsFontSize.vue +17 -17
  30. package/src/components/HeaderSlot/SummaryButton/SummaryButton.vue +70 -65
  31. package/src/components/HeaderSlot/SummaryButton/SummaryDropdown.vue +8 -7
  32. package/src/components/ReaderWrapper.vue +37 -37
  33. package/src/components/ReferencePopup.vue +36 -36
  34. package/src/components/icons/Close.vue +6 -6
  35. package/src/components/icons/DoubleColumn.vue +15 -15
  36. package/src/components/icons/Expand.vue +7 -7
  37. package/src/components/icons/Eye.vue +9 -9
  38. package/src/components/icons/Footnote.vue +5 -5
  39. package/src/components/icons/Home.vue +6 -6
  40. package/src/components/icons/Moon.vue +5 -5
  41. package/src/components/icons/Notes.vue +5 -5
  42. package/src/components/icons/SingleColumn.vue +3 -3
  43. package/src/components/icons/Summary.vue +10 -10
  44. package/src/components/icons/Sun.vue +5 -5
  45. package/src/components/icons/ThreeDots.vue +8 -8
  46. package/src/composables/useBrowser.js +16 -16
  47. package/src/composables/useFootnotes.js +50 -50
  48. package/src/composables/usePagination.js +125 -125
  49. package/src/composables/useReaderSettings.js +174 -153
  50. package/src/composables/useReferences.js +67 -67
  51. package/src/composables/useStyles.js +60 -43
  52. package/src/composables/useTextContent.js +113 -113
  53. package/src/main.js +19 -19
  54. package/src/tailwind.css +5 -8
  55. package/tailwind.config.js +16 -16
  56. package/vite.config.js +36 -36
@@ -1,153 +1,174 @@
1
- import { reactive, computed, watch } from 'vue'
2
- import useStyles from './useStyles'
3
-
4
- const state = reactive({
5
- baseFont: 'Arial, sans-serif',
6
- textFont: 'Times New Roman, serif',
7
- fontsOptions: [
8
- { name: 'Times New Roman, serif' },
9
- { name: 'Georgia, serif' },
10
- { name: 'Arial, sans-serif' },
11
- { name: 'Verdana, sans-serif' },
12
- ],
13
- fontSize: 16,
14
- columns: 'double',
15
- mode: 'light',
16
- blocked: false
17
- })
18
-
19
- const baseFont = computed(() => state.baseFont)
20
- const textFont = computed(() => state.textFont)
21
- const fontSize = computed(() => state.fontSize)
22
- const fontsOptions = computed(() => state.fontsOptions)
23
- const columns = computed(() => state.columns)
24
- const mode = computed(() => state.mode)
25
- const blocked = computed(() => state.blocked)
26
-
27
- watch(
28
- [baseFont, textFont, fontSize, columns, mode],
29
- () => saveSettings()
30
- )
31
-
32
- async function initSettings(settingsString) {
33
- const settings = settingsString
34
- ? JSON.parse(settingsString)
35
- : null
36
-
37
- if (settings?.baseFont)
38
- state.baseFont = settings.baseFont
39
-
40
- if (settings?.textFont)
41
- state.textFont = settings.textFont
42
-
43
- if (settings?.fontSize)
44
- state.fontSize = Number(settings.fontSize)
45
-
46
- if (settings?.fontsOptions) {
47
- state.fontsOptions = settings.fontsOptions
48
- useStyles.fontLoader(settings.fontsOptions)
49
-
50
- // baseFont
51
- const defaultBaseFont = settings.fontsOptions.find(
52
- item => item.defaultBaseFont
53
- )
54
- if (defaultBaseFont)
55
- state.baseFont = defaultBaseFont.name
56
-
57
- // textFont
58
- const defaultTextFont = settings.fontsOptions.find(
59
- item => item.defaultTextFont
60
- )
61
- if (defaultTextFont)
62
- state.textFont = defaultTextFont.name
63
- }
64
-
65
- loadSavedSettings(settings)
66
- }
67
-
68
- function loadSavedSettings(settings) {
69
- const hasSettings = localStorage.getItem('readerSettings')
70
-
71
- if (hasSettings) {
72
- const savedSettings = JSON.parse(hasSettings)
73
-
74
- state.fontSize = savedSettings.fontSize
75
- state.columns = savedSettings.columns
76
- state.mode = savedSettings.mode
77
-
78
- if (settings?.fontsOptions &&
79
- settings?.fontsOptions?.find(item => item.name === savedSettings.textFont)
80
- ) {
81
- state.textFont = savedSettings.textFont
82
- }
83
-
84
- if (savedSettings.mode === 'dark') {
85
- const htmlRoot = document.querySelector('html')
86
- if (htmlRoot) {
87
- htmlRoot.classList.remove("light")
88
- htmlRoot.classList.add("dark")
89
- }
90
- }
91
- }
92
- }
93
-
94
- function setColumns(value) {
95
- state.columns = value
96
- }
97
-
98
- function setTextFont(value) {
99
- state.textFont = value
100
- }
101
-
102
- function setFontSize(value) {
103
- state.fontSize = value
104
- }
105
-
106
- function setBlocked(value) {
107
- state.blocked = value
108
- }
109
-
110
- function setMode(value) {
111
- state.mode = value
112
-
113
- const htmlRoot = document.querySelector('html')
114
- if (htmlRoot) {
115
- if (htmlRoot.classList.contains("dark")) {
116
- htmlRoot.classList.remove("dark")
117
- htmlRoot.classList.add("light")
118
-
119
- } else {
120
- htmlRoot.classList.remove("light")
121
- htmlRoot.classList.add("dark")
122
- }
123
- }
124
- }
125
-
126
- function saveSettings() {
127
- localStorage.setItem(
128
- 'readerSettings',
129
- JSON.stringify({
130
- textFont: textFont.value,
131
- fontSize: fontSize.value,
132
- columns: columns.value,
133
- mode: mode.value
134
- })
135
- )
136
- }
137
-
138
- export default {
139
- baseFont,
140
- textFont,
141
- fontSize,
142
- fontsOptions,
143
- columns,
144
- initSettings,
145
- setColumns,
146
- setTextFont,
147
- setFontSize,
148
- setBlocked,
149
- mode,
150
- blocked,
151
- setMode,
152
- saveSettings
153
- }
1
+ import { reactive, computed, watch } from 'vue'
2
+ import useStyles from './useStyles'
3
+
4
+ const state = reactive({
5
+ baseFont: 'Arial, sans-serif',
6
+ textFont: 'Times New Roman, serif',
7
+ fontsOptions: [
8
+ { name: 'Times New Roman, serif' },
9
+ { name: 'Georgia, serif' },
10
+ { name: 'Arial, sans-serif' },
11
+ { name: 'Verdana, sans-serif' },
12
+ ],
13
+ fontSize: 16,
14
+ columns: 'double',
15
+ mode: 'light',
16
+ blocked: false,
17
+
18
+ bookTitle: null,
19
+ chapterTitle: null,
20
+ homeUrl: null,
21
+ })
22
+
23
+ const baseFont = computed(() => state.baseFont)
24
+ const textFont = computed(() => state.textFont)
25
+ const fontSize = computed(() => state.fontSize)
26
+ const fontsOptions = computed(() => state.fontsOptions)
27
+ const columns = computed(() => state.columns)
28
+ const mode = computed(() => state.mode)
29
+ const blocked = computed(() => state.blocked)
30
+
31
+ const bookTitle = computed(() => state.bookTitle)
32
+ const chapterTitle = computed(() => state.chapterTitle)
33
+ const homeUrl = computed(() => state.homeUrl)
34
+
35
+ watch(
36
+ [baseFont, textFont, fontSize, columns, mode],
37
+ () => saveSettings()
38
+ )
39
+
40
+ async function initSettings(settingsString) {
41
+ const settings = settingsString
42
+ ? JSON.parse(settingsString)
43
+ : null
44
+
45
+ if (settings?.baseFont)
46
+ state.baseFont = settings.baseFont
47
+
48
+ if (settings?.textFont)
49
+ state.textFont = settings.textFont
50
+
51
+ if (settings?.fontSize)
52
+ state.fontSize = Number(settings.fontSize)
53
+
54
+ if (settings?.fontsOptions) {
55
+ state.fontsOptions = settings.fontsOptions
56
+ useStyles.fontLoader(settings.fontsOptions)
57
+
58
+ // baseFont
59
+ const defaultBaseFont = settings.fontsOptions.find(
60
+ item => item.defaultBaseFont
61
+ )
62
+ if (defaultBaseFont)
63
+ state.baseFont = defaultBaseFont.name
64
+
65
+ // textFont
66
+ const defaultTextFont = settings.fontsOptions.find(
67
+ item => item.defaultTextFont
68
+ )
69
+ if (defaultTextFont)
70
+ state.textFont = defaultTextFont.name
71
+ }
72
+
73
+ if (settings?.bookTitle)
74
+ state.bookTitle = settings.bookTitle
75
+
76
+ if (settings?.chapterTitle)
77
+ state.chapterTitle = settings.chapterTitle
78
+
79
+ if (settings?.homeUrl)
80
+ state.homeUrl = settings.homeUrl
81
+
82
+ loadSavedSettings(settings)
83
+ }
84
+
85
+ function loadSavedSettings(settings) {
86
+ const hasSettings = localStorage.getItem('readerSettings')
87
+
88
+ if (hasSettings) {
89
+ const savedSettings = JSON.parse(hasSettings)
90
+
91
+ state.fontSize = savedSettings.fontSize
92
+ state.columns = savedSettings.columns
93
+ state.mode = savedSettings.mode
94
+
95
+ if (settings?.fontsOptions &&
96
+ settings?.fontsOptions?.find(item => item.name === savedSettings.textFont)
97
+ ) {
98
+ state.textFont = savedSettings.textFont
99
+ }
100
+
101
+ if (savedSettings.mode === 'dark') {
102
+ const htmlRoot = document.querySelector('html')
103
+ if (htmlRoot) {
104
+ htmlRoot.classList.remove("light")
105
+ htmlRoot.classList.add("dark")
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ function setColumns(value) {
112
+ state.columns = value
113
+ }
114
+
115
+ function setTextFont(value) {
116
+ state.textFont = value
117
+ }
118
+
119
+ function setFontSize(value) {
120
+ state.fontSize = value
121
+ }
122
+
123
+ function setBlocked(value) {
124
+ state.blocked = value
125
+ }
126
+
127
+ function setMode(value) {
128
+ state.mode = value
129
+
130
+ const htmlRoot = document.querySelector('html')
131
+ if (htmlRoot) {
132
+ if (htmlRoot.classList.contains("dark")) {
133
+ htmlRoot.classList.remove("dark")
134
+ htmlRoot.classList.add("light")
135
+
136
+ } else {
137
+ htmlRoot.classList.remove("light")
138
+ htmlRoot.classList.add("dark")
139
+ }
140
+ }
141
+ }
142
+
143
+ function saveSettings() {
144
+ localStorage.setItem(
145
+ 'readerSettings',
146
+ JSON.stringify({
147
+ textFont: textFont.value,
148
+ fontSize: fontSize.value,
149
+ columns: columns.value,
150
+ mode: mode.value
151
+ })
152
+ )
153
+ }
154
+
155
+ export default {
156
+ baseFont,
157
+ textFont,
158
+ fontSize,
159
+ fontsOptions,
160
+ columns,
161
+ initSettings,
162
+ setColumns,
163
+ setTextFont,
164
+ setFontSize,
165
+ setBlocked,
166
+ mode,
167
+ blocked,
168
+ setMode,
169
+ saveSettings,
170
+
171
+ bookTitle,
172
+ chapterTitle,
173
+ homeUrl
174
+ }
@@ -1,67 +1,67 @@
1
- import { computed, reactive } from 'vue'
2
-
3
- const state = reactive({
4
- references: [],
5
- reference: null
6
- })
7
-
8
- const references = computed(() => state.references)
9
-
10
- function setReferences(references) {
11
- state.references = references
12
- }
13
-
14
- const reference = computed(() => state.reference)
15
-
16
- function setHighlightedReference(reference) {
17
- state.reference = reference
18
- }
19
-
20
- function applyReferences(contentRaw) {
21
- if (state.references.length === 0 || !contentRaw)
22
- return contentRaw
23
-
24
- return state.references.reduce((content, reference) => {
25
- if (!content) return content
26
-
27
- if (content.includes(reference.cit)) {
28
- const regex = new RegExp(reference.cit, 'g');
29
- const newContent = content.replace(
30
- regex,
31
- `<span class='reference reference-${reference.cit.replaceAll(' ', '')}'>
32
- ${reference.cit}
33
- </span>`
34
- )
35
- return newContent
36
- }
37
- return content
38
- }, contentRaw)
39
- }
40
-
41
- function applyReference(event) {
42
- const classList = event.target.closest('.reference')?.classList.value.split(' ')
43
-
44
- if (classList.length === 0)
45
- return
46
-
47
- const target = classList.find(item => item.startsWith('reference-'))
48
-
49
- if (target) {
50
- const ref = state.references.find(
51
- item => target && item.cit.replaceAll(' ', '') === target.replace('reference-', '')
52
- )
53
- if (ref) {
54
- state.reference = ref
55
- }
56
- }
57
-
58
- }
59
-
60
- export default {
61
- references,
62
- reference,
63
- applyReference,
64
- setReferences,
65
- setHighlightedReference,
66
- applyReferences,
67
- }
1
+ import { computed, reactive } from 'vue'
2
+
3
+ const state = reactive({
4
+ references: [],
5
+ reference: null
6
+ })
7
+
8
+ const references = computed(() => state.references)
9
+
10
+ function setReferences(references) {
11
+ state.references = references
12
+ }
13
+
14
+ const reference = computed(() => state.reference)
15
+
16
+ function setHighlightedReference(reference) {
17
+ state.reference = reference
18
+ }
19
+
20
+ function applyReferences(contentRaw) {
21
+ if (state.references.length === 0 || !contentRaw)
22
+ return contentRaw
23
+
24
+ return state.references.reduce((content, reference) => {
25
+ if (!content) return content
26
+
27
+ if (content.includes(reference.cit)) {
28
+ const regex = new RegExp(reference.cit, 'g');
29
+ const newContent = content.replace(
30
+ regex,
31
+ `<span class='reference reference-${reference.cit.replaceAll(' ', '')}'>
32
+ ${reference.cit}
33
+ </span>`
34
+ )
35
+ return newContent
36
+ }
37
+ return content
38
+ }, contentRaw)
39
+ }
40
+
41
+ function applyReference(event) {
42
+ const classList = event.target.closest('.reference')?.classList.value.split(' ')
43
+
44
+ if (classList.length === 0)
45
+ return
46
+
47
+ const target = classList.find(item => item.startsWith('reference-'))
48
+
49
+ if (target) {
50
+ const ref = state.references.find(
51
+ item => target && item.cit.replaceAll(' ', '') === target.replace('reference-', '')
52
+ )
53
+ if (ref) {
54
+ state.reference = ref
55
+ }
56
+ }
57
+
58
+ }
59
+
60
+ export default {
61
+ references,
62
+ reference,
63
+ applyReference,
64
+ setReferences,
65
+ setHighlightedReference,
66
+ applyReferences,
67
+ }
@@ -1,43 +1,60 @@
1
- function fontLoader(fontsOptions) {
2
- const fontsToLoad = fontsOptions.filter(item => item.link)
3
-
4
- if (fontsToLoad.length > 0) {
5
- const style = document.createElement('style')
6
- const head = document.head || document.getElementsByTagName('head')[0]
7
- head.appendChild(style)
8
-
9
- style.type = 'text/css'
10
- let css = ''
11
- fontsToLoad.forEach(
12
- item => css = css + `@import url(${item.link}); \n`
13
- )
14
- style.appendChild(document.createTextNode(css))
15
- }
16
- }
17
-
18
- async function stylesheetLoader(stylesheet, ref) {
19
- if (stylesheet) {
20
- try {
21
- const dataRef = await fetch(stylesheet)
22
- const cssText = await dataRef.text()
23
-
24
- applyStylesheet(cssText, ref)
25
-
26
- } catch (err) {
27
- console.log({ err })
28
- }
29
- }
30
- }
31
-
32
- async function applyStylesheet(stylesheet, ref) {
33
- const style = document.createElement('style')
34
- ref.value.appendChild(style)
35
- style.type = 'text/css'
36
- style.appendChild(document.createTextNode(stylesheet))
37
- }
38
-
39
- export default {
40
- fontLoader,
41
- stylesheetLoader,
42
- applyStylesheet
43
- }
1
+ function initStyles(props, rootComponent) {
2
+ const settings = props.readerSettings
3
+ ? JSON.parse(props.readerSettings)
4
+ : null
5
+
6
+ if (props.cssFile) {
7
+ stylesheetLoader(props.cssFile, rootComponent)
8
+ }
9
+
10
+ if (props.cssString) {
11
+ applyStylesheet(props.cssString, rootComponent)
12
+ }
13
+
14
+ if (settings?.cssString) {
15
+ applyStylesheet(settings.cssString, rootComponent)
16
+ }
17
+ }
18
+
19
+ function fontLoader(fontsOptions) {
20
+ const fontsToLoad = fontsOptions.filter(item => item.link)
21
+
22
+ if (fontsToLoad.length > 0) {
23
+ const style = document.createElement('style')
24
+ const head = document.head || document.getElementsByTagName('head')[0]
25
+ head.appendChild(style)
26
+
27
+ style.type = 'text/css'
28
+ let css = ''
29
+ fontsToLoad.forEach(
30
+ item => css = css + `@import url(${item.link}); \n`
31
+ )
32
+ style.appendChild(document.createTextNode(css))
33
+ }
34
+ }
35
+
36
+ async function stylesheetLoader(stylesheet, ref) {
37
+ if (stylesheet) {
38
+ try {
39
+ const dataRef = await fetch(stylesheet)
40
+ const cssText = await dataRef.text()
41
+
42
+ applyStylesheet(cssText, ref)
43
+
44
+ } catch (_) {}
45
+ }
46
+ }
47
+
48
+ async function applyStylesheet(stylesheet, ref) {
49
+ const style = document.createElement('style')
50
+ ref.value.appendChild(style)
51
+ style.type = 'text/css'
52
+ style.appendChild(document.createTextNode(stylesheet))
53
+ }
54
+
55
+ export default {
56
+ initStyles,
57
+ fontLoader,
58
+ stylesheetLoader,
59
+ applyStylesheet
60
+ }