paginar 0.3.4 → 0.3.6

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 (60) hide show
  1. package/README.md +288 -236
  2. package/dist/index.es.js +684 -244
  3. package/dist/index.es.js.map +1 -1
  4. package/dist/style.css +63 -0
  5. package/package.json +6 -3
  6. package/.editorconfig +0 -13
  7. package/.env +0 -1
  8. package/.vscode/extensions.json +0 -3
  9. package/demo/slot/slot-chapter1.html +0 -384
  10. package/demo/slot/slot-chapter2.html +0 -366
  11. package/demo/slot/slot-chapter3.html +0 -265
  12. package/demo/summary/_content/1chapter.html +0 -100
  13. package/demo/summary/_content/2chapter.html +0 -311
  14. package/demo/summary/_content/3chapter.html +0 -211
  15. package/demo/summary/index.html +0 -134
  16. package/index.html +0 -18
  17. package/postcss.config.js +0 -7
  18. package/public/favicon.ico +0 -0
  19. package/src/App.ce.vue +0 -166
  20. package/src/assets/main.css +0 -392
  21. package/src/components/BookContent.vue +0 -23
  22. package/src/components/EngineWrapper.vue +0 -15
  23. package/src/components/FooterSlot.vue +0 -32
  24. package/src/components/FootnotesAside.vue +0 -123
  25. package/src/components/HeaderSlot/HeaderSlot.vue +0 -30
  26. package/src/components/HeaderSlot/OptionsButton/OptionsButton.vue +0 -67
  27. package/src/components/HeaderSlot/OptionsButton/OptionsColor.vue +0 -28
  28. package/src/components/HeaderSlot/OptionsButton/OptionsColumns.vue +0 -51
  29. package/src/components/HeaderSlot/OptionsButton/OptionsDropdown.vue +0 -59
  30. package/src/components/HeaderSlot/OptionsButton/OptionsFontFamily.vue +0 -17
  31. package/src/components/HeaderSlot/OptionsButton/OptionsFontSize.vue +0 -17
  32. package/src/components/HeaderSlot/SummaryButton/SummaryButton.vue +0 -74
  33. package/src/components/HeaderSlot/SummaryButton/SummaryDropdown.vue +0 -30
  34. package/src/components/NavigationButton.vue +0 -34
  35. package/src/components/ReaderWrapper.vue +0 -37
  36. package/src/components/ReferencePopup.vue +0 -36
  37. package/src/components/icons/Close.vue +0 -6
  38. package/src/components/icons/DoubleColumn.vue +0 -15
  39. package/src/components/icons/Expand.vue +0 -7
  40. package/src/components/icons/Eye.vue +0 -9
  41. package/src/components/icons/Footnote.vue +0 -5
  42. package/src/components/icons/Home.vue +0 -6
  43. package/src/components/icons/Moon.vue +0 -5
  44. package/src/components/icons/Notes.vue +0 -5
  45. package/src/components/icons/SingleColumn.vue +0 -3
  46. package/src/components/icons/Summary.vue +0 -10
  47. package/src/components/icons/Sun.vue +0 -5
  48. package/src/components/icons/ThreeDots.vue +0 -8
  49. package/src/composables/useBrowser.js +0 -16
  50. package/src/composables/useEstimatePages.js +0 -31
  51. package/src/composables/useFootnotes.js +0 -50
  52. package/src/composables/usePagination.js +0 -125
  53. package/src/composables/useReaderSettings.js +0 -174
  54. package/src/composables/useReferences.js +0 -67
  55. package/src/composables/useStyles.js +0 -60
  56. package/src/composables/useTextContent.js +0 -113
  57. package/src/main.js +0 -19
  58. package/src/tailwind.css +0 -1082
  59. package/tailwind.config.js +0 -16
  60. package/vite.config.js +0 -36
@@ -1,125 +0,0 @@
1
- import { reactive, computed, watch } from 'vue'
2
- import { onKeyStroke } from '@vueuse/core'
3
-
4
- import useReaderSettings from './useReaderSettings'
5
- import useEstimatePages from './useEstimatePages'
6
- import useTextContent from './useTextContent'
7
- import useBrowser from './useBrowser'
8
-
9
- const state = reactive({
10
- currentPage: 1,
11
- nextTry: 0,
12
- prevTry: 0,
13
- willRedirect: false
14
- })
15
-
16
- const currentPage = computed(() => state.currentPage)
17
- const totalPages = computed(() => useEstimatePages.totalPages.value)
18
-
19
- function init(viewport, content) {
20
- useEstimatePages.estimate(viewport, content)
21
-
22
- // check if there is a query string for oring, and
23
- // if previews chapter was the next one. If so,
24
- // start from the end, as we are coming backwards
25
- const urlParams = new URLSearchParams(window.location.search)
26
- const origin = urlParams.get('origin')
27
- if (origin && origin === 'next') {
28
- setTimeout(() => {
29
- state.currentPage = totalPages.value
30
- }, 200)
31
- }
32
-
33
- if (!useBrowser.isApple && !useBrowser.isSafari) {
34
- addEventListener('wheel', onWheel)
35
- }
36
-
37
- setInterval(() => {
38
- useEstimatePages.estimate(viewport, content)
39
- }, 5000)
40
- }
41
-
42
- // when resizing the viewport, totalPages change
43
- // this watch is to currentPage inside totalPages range
44
- watch(totalPages, () => {
45
- if (totalPages.value < currentPage.value) {
46
- set(totalPages.value)
47
- }
48
- })
49
-
50
- // navigate by increase/decrease value
51
- function next(usingScroll = false) {
52
- if (!useReaderSettings.blocked.value) {
53
- if ((state.currentPage + 1) <= totalPages.value) {
54
- state.currentPage = state.currentPage + 1
55
- } else {
56
- // prevent going too fast to next chapter on
57
- // stronger scroll
58
- if (usingScroll && state.nextTry < 4) {
59
- state.nextTry += 1
60
- return
61
- }
62
-
63
- if (state.willRedirect === false) {
64
- const context = useTextContent.context.value
65
- if (context.surround?.after) {
66
- window.location.href = context.surround.after.link + (`?origin=prev`)
67
- state.willRedirect = true
68
- }
69
- }
70
- }
71
- }
72
- }
73
- onKeyStroke('ArrowRight', (e) => {
74
- e.preventDefault()
75
- next()
76
- })
77
-
78
- function onWheel(event) {
79
- if (event.wheelDelta < 0) {
80
- next(true)
81
- } else {
82
- prev(true)
83
- }
84
- };
85
-
86
- function prev(usingScroll = false) {
87
- if (!useReaderSettings.blocked.value) {
88
- if ((state.currentPage - 1) > 0) {
89
- state.currentPage = state.currentPage - 1
90
- } else {
91
- // prevent going too fast to prev chapter on
92
- // stronger scroll
93
- if (usingScroll && state.prevTry < 4) {
94
- state.prevTry += 1
95
- return
96
- }
97
-
98
- if (state.willRedirect === false) {
99
- const context = useTextContent.context.value
100
- if (context.surround?.before) {
101
- window.location.href = context.surround.before.link + (`?origin=next`)
102
- }
103
- state.willRedirect = true
104
- }
105
- }
106
- }
107
- }
108
- onKeyStroke('ArrowLeft', (e) => {
109
- e.preventDefault()
110
- prev()
111
- })
112
-
113
- // navigate to specific page
114
- function set(val) {
115
- state.currentPage = val
116
- }
117
-
118
- export default {
119
- currentPage,
120
- totalPages,
121
- next,
122
- prev,
123
- init,
124
- set
125
- }
@@ -1,174 +0,0 @@
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 +0,0 @@
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,60 +0,0 @@
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
- }
@@ -1,113 +0,0 @@
1
- import { computed, reactive } from 'vue'
2
- import { useEventListener } from '@vueuse/core'
3
-
4
- import useReferences from './useReferences'
5
- import useFootnotes from './useFootnotes'
6
-
7
- const state = reactive({
8
- summary: null,
9
- content: null
10
- })
11
-
12
- const content = computed(() => state.content)
13
- const summary = computed(() => state.summary)
14
- const context = computed(() => {
15
- const current = state.summary.findIndex(
16
- chapter => window.location.href.includes(chapter.link)
17
- )
18
- return {
19
- chapter: state.summary[current],
20
- surround: {
21
- before: current - 1 >= 0
22
- ? state.summary[current - 1]
23
- : null,
24
- after: current + 1 <= state.summary.length
25
- ? state.summary[current + 1]
26
- : null,
27
- }
28
- }
29
- })
30
-
31
- async function initContent(contentString, contentWrapper) {
32
- const { setReferences, applyReferences } = useReferences
33
- const { setFootnotes } = useFootnotes
34
-
35
- const content = contentString
36
- ? JSON.parse(contentString)
37
- : null
38
-
39
- if (content?.summary)
40
- state.summary = content.summary
41
-
42
- if (content?.references)
43
- setReferences(content.references)
44
-
45
- if (content?.footnotes)
46
- setFootnotes(content.footnotes)
47
-
48
- // if content comes from file, apply references to file
49
- if (content?.summary?.[0]?.file) {
50
- const text = await getContent(content.summary?.[0]?.file)
51
- const newContent = content.applyReferences
52
- ? applyReferences(text)
53
- : text
54
- state.content = newContent
55
-
56
- // else if content comes from slot, apply references to slot
57
- } else {
58
- const content = document.querySelectorAll('[slot="content"]')
59
-
60
- if (content && content?.[0]?.innerHTML && content.applyReferences) {
61
- const newContent = applyReferences(content?.[0]?.innerHTML)
62
- if (newContent) {
63
- content[0].innerHTML = newContent
64
- }
65
- }
66
- }
67
-
68
- // after applying references above, now we start to listen to its clicks
69
- listenToClicks(contentWrapper)
70
- }
71
-
72
- async function getContent(location) {
73
- try {
74
- const dataRef = await fetch(location)
75
- const text = await dataRef.text()
76
- return text
77
- } catch (err) {
78
- console.log({ err })
79
- state.content = 'Ops, não foi possível carregar o arquivo solicitado.'
80
- }
81
- }
82
-
83
- function applyContent(text) {
84
- const { applyReferences } = useReferences
85
- const newContent = applyReferences(text)
86
- state.content = newContent
87
- }
88
-
89
- function listenToClicks(contentWrapper) {
90
- setTimeout(() => {
91
- useEventListener(contentWrapper, 'click', getClickedReferenceData)
92
- }, 100)
93
- }
94
-
95
- function getClickedReferenceData(event) {
96
- if (event.target.closest('.reference')) {
97
- useReferences.applyReference(event)
98
- }
99
-
100
- if (event.target.closest('.footnote')) {
101
- useFootnotes.applyFootnote(event)
102
- }
103
- }
104
-
105
- export default {
106
- content,
107
- summary,
108
- initContent,
109
- getContent,
110
- applyContent,
111
- listenToClicks,
112
- context
113
- }
package/src/main.js DELETED
@@ -1,19 +0,0 @@
1
- // https://maximomussini.com/posts/vue-custom-elements
2
- import { defineCustomElement } from 'vue'
3
-
4
- import App from './App.ce.vue'
5
-
6
- import tailwindStyles from './tailwind.css'
7
-
8
- const styles = [
9
- ...[tailwindStyles],
10
- ...App.styles
11
- ]
12
-
13
- customElements.define(
14
- 'paginate-content',
15
- defineCustomElement({
16
- ...App,
17
- styles
18
- })
19
- )