PageView.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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
  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. return [...ids, ...note.links.map(link => link.id)]
  96. }, [])
  97. this.$store.dispatch('GET_NODES', { ids, dataLevel: 'initial' })
  98. this.addFootnotes()
  99. }
  100. }
  101. }
  102. </script>
  103. <style lang="scss">
  104. .page {
  105. font-size: 1rem;
  106. position: relative;
  107. .btn-close-wrapper {
  108. position: sticky;
  109. z-index: 2;
  110. float: right;
  111. height: 0;
  112. right: 0;
  113. top: $node-view-spacer-sm-y;
  114. @include media-breakpoint-up($size-bp) {
  115. top: $node-view-spacer-y;
  116. }
  117. .btn-close {
  118. position: absolute;
  119. padding: 0.5rem;
  120. width: 2.25rem;
  121. height: 2.25rem;
  122. top: -.5rem;
  123. right: -.5rem;
  124. background-color: $white;
  125. }
  126. }
  127. @include media-breakpoint-up($size-bp) {
  128. font-size: 1.5rem;
  129. }
  130. padding: $node-view-spacer-sm-y $node-view-spacer-sm-x;
  131. @include media-breakpoint-up($size-bp) {
  132. padding: $node-view-spacer-y $node-view-spacer-x;
  133. }
  134. p {
  135. margin-bottom: 1em;
  136. }
  137. blockquote {
  138. margin: 0 0 50px 50px;
  139. @include media-breakpoint-up($size-bp) {
  140. margin: 50px 0 110px 180px;
  141. }
  142. }
  143. img {
  144. display: block;
  145. max-width: 100%;
  146. max-height: 90vh;
  147. }
  148. .page-footnotes {
  149. display: none;
  150. }
  151. &-footnote-link {
  152. display: inline-block;
  153. text-align: center;
  154. background-color: $black;
  155. color: $white;
  156. font-weight: $font-weight-bold;
  157. font-size: 0.8em;
  158. font-style: normal;
  159. text-decoration: none;
  160. border-radius: 1em;
  161. padding: 0 .5em;
  162. min-width: 1.25em;
  163. max-height: 1.5em;
  164. margin: 0 .2em;
  165. &:hover,
  166. &:active {
  167. color: $white;
  168. text-decoration: none;
  169. }
  170. }
  171. .footnote {
  172. background-color: $black;
  173. color: $white;
  174. font-size: 1.5rem;
  175. font-style: normal;
  176. padding: $node-view-spacer-sm-y $node-view-spacer-sm-x;
  177. margin: $node-view-spacer-sm-y 0;
  178. @include media-breakpoint-up($size-bp) {
  179. padding: $node-view-spacer-y $node-view-spacer-x;
  180. margin: $node-view-spacer-y 0;
  181. }
  182. // @include media-breakpoint-up(lg) {
  183. // max-width: 50%;
  184. // }
  185. &-child-list {
  186. margin-top: 0;
  187. }
  188. &-content + .footnote-child-list {
  189. margin-top: 1rem;
  190. }
  191. &:not(.show) {
  192. display: none;
  193. }
  194. p:last-of-type {
  195. margin-bottom: 0;
  196. }
  197. blockquote {
  198. margin: 0 0 1em 2em;
  199. }
  200. }
  201. &.small {
  202. font-size: 1rem;
  203. padding: 0;
  204. .footnote {
  205. font-size: 1rem;
  206. padding: $node-card-spacer-y $node-card-spacer-x;
  207. }
  208. }
  209. }
  210. </style>