PageView.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <template lang="html">
  2. <div class="page" :class="'page-' + slug">
  3. <div v-if="!noClose" class="btn-close-wrapper">
  4. <button-close @click="$emit('close')" />
  5. </div>
  6. <div class="page-wrapper" v-html="page.content" />
  7. <div class="page-footnotes" v-if="page.notes">
  8. <div
  9. v-for="note in page.notes" :key="`note-${note.number}`"
  10. :id="`note-${note.number}`"
  11. >
  12. <div v-if="note.content" class="footnote-content" v-html="note.content" />
  13. <div
  14. v-if="note.links"
  15. class="footnote-child-list"
  16. >
  17. <node-view-title
  18. v-for="link in note.links" :key="link.id"
  19. :node="getLinkObj(link)"
  20. link
  21. @open-node="onFootnoteLinkClick(link)"
  22. >
  23. <dot-button
  24. :variant="link.variant"
  25. class="mr-2"
  26. active hovered
  27. >
  28. {{ $t('variants.' + link.variant) }}
  29. </dot-button>
  30. </node-view-title>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. </template>
  36. <script>
  37. import { getRelation } from '@/store/utils'
  38. import { NodeViewTitle } from '@/components/nodes'
  39. export default {
  40. name: 'PageView',
  41. components: {
  42. NodeViewTitle
  43. },
  44. props: {
  45. page: { type: Object, default: undefined },
  46. slug: { type: String, required: true },
  47. noClose: { type: Boolean, default: false }
  48. },
  49. methods: {
  50. getLinkObj (link) {
  51. if (link.preTitle || link.italTitle) return link
  52. if (link.type === 'prod' && link.parents && link.parents.length) return link.parents[0]
  53. return link
  54. },
  55. addFootnotes () {
  56. const links = this.$el.querySelectorAll('.page-wrapper a')
  57. links.forEach((link, i) => {
  58. const number = parseInt(link.hash.replace('#', ''))
  59. if (!isNaN(number) && this.page.notes.find(note => note.number === number)) {
  60. link.classList.add('page-footnote-link')
  61. link.id = `footnote-${this.slug}-${number}`
  62. link.setAttribute('href', 'javascript:;')
  63. link.dataset.number = number
  64. link.textContent = i + 1
  65. if (link.parentElement.nodeName === 'SUP') {
  66. link.parentElement.replaceWith(link)
  67. }
  68. link.onclick = this.onFootnoteClick
  69. this.addFootnoteContent(link, number)
  70. }
  71. })
  72. },
  73. addFootnoteContent (link, i) {
  74. const note = document.getElementById(`note-${i}`)
  75. const noteContainer = document.createElement('DIV')
  76. noteContainer.classList.add('footnote')
  77. noteContainer.id = link.id + '-content'
  78. noteContainer.appendChild(note)
  79. // noteContainer.innerHTML = this.page.notes.find(note => note.number === i).content
  80. link.insertAdjacentElement('afterend', noteContainer)
  81. },
  82. onFootnoteClick (e) {
  83. const container = document.getElementById(e.target.id + '-content')
  84. if (container) {
  85. container.classList.toggle('show')
  86. }
  87. },
  88. onFootnoteLinkClick (node) {
  89. this.$store.dispatch('OPEN_NODE', getRelation(node))
  90. }
  91. },
  92. mounted () {
  93. if (this.page.notes) {
  94. const ids = this.page.notes.filter(note => (note.links)).reduce((ids, note) => {
  95. note.links.forEach((link) => {
  96. ids.push(link.id)
  97. if (link.parents && link.parents.length) {
  98. ids.push(link.parents[0].id)
  99. }
  100. })
  101. return ids
  102. }, [])
  103. this.$store.dispatch('GET_NODES', { ids, dataLevel: 'initial' })
  104. this.addFootnotes()
  105. }
  106. }
  107. }
  108. </script>
  109. <style lang="scss">
  110. .page {
  111. font-size: 1rem;
  112. position: relative;
  113. .btn-close-wrapper {
  114. position: sticky;
  115. z-index: 2;
  116. float: right;
  117. height: 0;
  118. right: 0;
  119. top: $node-view-spacer-sm-y;
  120. @include media-breakpoint-up($size-bp) {
  121. top: $node-view-spacer-y;
  122. }
  123. .btn-close {
  124. position: absolute;
  125. padding: 0.5rem;
  126. width: 2.25rem;
  127. height: 2.25rem;
  128. top: -.5rem;
  129. right: -.5rem;
  130. background-color: $white;
  131. }
  132. }
  133. @include media-breakpoint-up($size-bp) {
  134. font-size: 1.5rem;
  135. }
  136. padding: $node-view-spacer-sm-y $node-view-spacer-sm-x;
  137. @include media-breakpoint-up($size-bp) {
  138. padding: $node-view-spacer-y $node-view-spacer-x;
  139. }
  140. p {
  141. margin-bottom: 1em;
  142. }
  143. blockquote {
  144. margin: 0 0 50px 50px;
  145. @include media-breakpoint-up($size-bp) {
  146. margin: 50px 0 110px 180px;
  147. }
  148. }
  149. img {
  150. display: block;
  151. max-width: 100%;
  152. max-height: 90vh;
  153. }
  154. .page-footnotes {
  155. display: none;
  156. }
  157. &-footnote-link {
  158. display: inline-block;
  159. text-align: center;
  160. background-color: $black;
  161. color: $white;
  162. font-weight: $font-weight-bold;
  163. font-size: 0.8em;
  164. font-style: normal;
  165. text-decoration: none;
  166. border-radius: 1em;
  167. padding: 0 .5em;
  168. min-width: 1.25em;
  169. max-height: 1.5em;
  170. margin: 0 .2em;
  171. &:hover,
  172. &:active {
  173. color: $white;
  174. text-decoration: none;
  175. }
  176. }
  177. .footnote {
  178. background-color: $black;
  179. color: $white;
  180. font-size: 1.5rem;
  181. font-style: normal;
  182. padding: $node-view-spacer-sm-y $node-view-spacer-sm-x;
  183. margin: $node-view-spacer-sm-y 0;
  184. @include media-breakpoint-up($size-bp) {
  185. padding: $node-view-spacer-y $node-view-spacer-x;
  186. margin: $node-view-spacer-y 0;
  187. }
  188. // @include media-breakpoint-up(lg) {
  189. // max-width: 50%;
  190. // }
  191. &-child-list {
  192. margin-top: 0;
  193. }
  194. &-content + .footnote-child-list {
  195. margin-top: 1rem;
  196. }
  197. &:not(.show) {
  198. display: none;
  199. }
  200. p:last-of-type {
  201. margin-bottom: 0;
  202. }
  203. blockquote {
  204. margin: 0 0 1em 2em;
  205. }
  206. }
  207. &.small {
  208. font-size: 1rem;
  209. padding: 0;
  210. .footnote {
  211. font-size: 1rem;
  212. padding: $node-card-spacer-y $node-card-spacer-x;
  213. }
  214. }
  215. }
  216. </style>