EdText.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <script>
  2. import Vue from 'vue'
  3. export default {
  4. name: 'EdText',
  5. props: {
  6. tei: String,
  7. uuid: String,
  8. textid: String
  9. },
  10. data: () => ({
  11. template: null,
  12. html: null,
  13. pages: []
  14. }),
  15. watch: {
  16. tei: function (newtei, oldtei) {
  17. // console.log('tei watcher', oldtei, newtei)
  18. // we need this watcher to update display as route is changing
  19. this.buildTemplate()
  20. }
  21. },
  22. beforeMount () {
  23. // console.log('EdText beforeMount')
  24. if (this.tei) {
  25. this.buildTemplate()
  26. }
  27. },
  28. // mounted () {
  29. // this.$emit('onNewPageBreaks', this.pages)
  30. // },
  31. methods: {
  32. buildTemplate () {
  33. // console.log('EdText buildTemplate: tei', this.tei)
  34. // to get Vue.compile working we have to use the full build of vuejs
  35. // https://vuejs.org/v2/guide/installation.html#Explanation-of-Different-Builds
  36. // in /build/webpack.config.base.js alias -> 'vue': 'vue/dist/vue.js',
  37. this.buildHtml()
  38. this.template = Vue.compile(this.html)
  39. this.$options.staticRenderFns = []
  40. this._staticTrees = []
  41. this.template.staticRenderFns.map(fn => (this.$options.staticRenderFns.push(fn)))
  42. },
  43. buildHtml () {
  44. this.html = `<div` +
  45. ` class="tei${this.uuid === this.textid ? ' active' : ''}"` +
  46. ` data-uuid="${this.uuid}"` +
  47. `>` +
  48. `<a` +
  49. ` href="http://${window.apipath}/items/${this.uuid}"` +
  50. ` title="Copy to clipboard ${this.uuid}"` +
  51. ` class="text-item-link"` +
  52. ` @click.prevent="onClickCopyClipboard"` +
  53. `>` +
  54. `<span class="mdi mdi-open-in-new" />` +
  55. `</a>` +
  56. `${this.tei}</div>`
  57. this.parseLinks()
  58. this.parseFigures()
  59. // this.parsePageBreaks()
  60. // console.log('EdText: builded html', this.html)
  61. },
  62. parseLinks () {
  63. let links = this.html.match(/<a[^<]+<\/a>/g)
  64. // console.log('links', links)
  65. if (links) {
  66. // let domparser = new DOMParser()
  67. // let domlink
  68. let linkparts, newlink, uuid
  69. let index = null
  70. for (var i = 0; i < links.length; i++) {
  71. // console.log(`link ${i}:`, links[i])
  72. linkparts = RegExp(/<a class="(.+)" href="(.+)" data-index="(.+)">(.+)<\/a>/g).exec(links[i], 'g')
  73. // console.log('linkparts', linkparts)
  74. if (!linkparts) {
  75. console.warn(`link ${i} malformed:`, links[i])
  76. } else {
  77. index = linkparts[3]
  78. uuid = linkparts[2].replace('#', '')
  79. newlink = `<a` +
  80. ` class="${linkparts[1]} active-link"` +
  81. ` data-index="${index}"` +
  82. ` data-uuid="${uuid}"` +
  83. ` href="/${index}/${uuid}"` +
  84. ` @click.prevent="onClickRef"` +
  85. ` @keyup.enter="onClickRef"` +
  86. ` @mouseover="onHoverLink"` +
  87. ` @mouseleave="onLeaveLink"` +
  88. // prevent click on this one
  89. ` v-touch:tap.prevent="onTapLink"` +
  90. ` v-touch-class="'tapped'"` +
  91. `>${linkparts[4]}` +
  92. `<sup class="mdi mdi-message-text-outline" />` +
  93. `</a>`
  94. // console.log('newlink', newlink)
  95. this.html = this.html.replace(links[i], newlink)
  96. }
  97. }
  98. // console.log('this.html', this.html)
  99. }
  100. },
  101. parseFigures () {
  102. console.log('parseFigures this.html', this.html)
  103. let imgs = this.html.match(/<img[^>]*>/g)
  104. console.log('imgs', imgs)
  105. if (imgs) {
  106. let imgparts, newsrc, newimg
  107. for (var i = 0; i < imgs.length; i++) {
  108. // console.log(`link ${i}:`, links[i])
  109. imgparts = RegExp(/<img src="(.+)" alt="(.+)">/g).exec(imgs[i], 'g')
  110. console.log('imgparts', imgparts)
  111. if (!imgparts) {
  112. console.warn(`img ${i} malformed:`, imgs[i])
  113. } else {
  114. newsrc = `${imgparts[1]}/full/1000,/0/native.jpg`
  115. newimg = `<img` +
  116. ` src="${newsrc}"` +
  117. ` alt="${imgparts[2]}"` +
  118. `/>`
  119. // console.log('newlink', newlink)
  120. this.html = this.html.replace(imgs[i], newimg)
  121. }
  122. }
  123. }
  124. },
  125. // parsePageBreaks () {
  126. // let pbs = this.html.match(/<span role="pageBreak"[^>]+><\/span>/g)
  127. // console.log('pagebreaks', pbs)
  128. // if (pbs) {
  129. // let pbparts, newpb, num
  130. // for (var i = 0; i < pbs.length; i++) {
  131. // pbparts = RegExp(/<span role="pageBreak" data-num="(.+)"><\/span>/).exec(pbs[i], 'g')
  132. // if (!pbparts) {
  133. // console.warn(`pageBreak ${i} maformed`, pbs[i])
  134. // } else {
  135. // // console.log('pbparts', pbparts)
  136. // num = pbparts[1]
  137. // this.pages.push(num)
  138. // newpb = `<span` +
  139. // // ` id="page-break-${num}"` +
  140. // ` role="pageBreak"` +
  141. // ` data-num="${num}"` +
  142. // ` data-num-prev="${num - 1}"` +
  143. // ` />`
  144. // // console.log('newpb', newpb)
  145. // this.html = this.html.replace(pbs[i], newpb)
  146. // }
  147. // }
  148. // }
  149. // },
  150. onClickRef (e) {
  151. console.log('onClickRef(e)', e)
  152. if (e.target.classList.contains('tapped')) {
  153. this.$router.push({
  154. name: e.target.dataset.index,
  155. params: { id: e.target.dataset.uuid }
  156. })
  157. }
  158. },
  159. onHoverLink (e) {
  160. console.log('EdText onHoverLink(e)', e)
  161. this.$emit('onHoverLink', {
  162. uuid: e.target.dataset.uuid,
  163. index: e.target.dataset.index,
  164. rect: e.target.getBoundingClientRect()
  165. })
  166. },
  167. onTapLink (e) {
  168. console.log('EdText onTapLink(e)', e)
  169. this.$emit('onHoverLink', {
  170. uuid: e.target.dataset.uuid,
  171. index: e.target.dataset.index,
  172. rect: e.target.getBoundingClientRect()
  173. })
  174. },
  175. onLeaveLink (e) {
  176. // console.log('EdText onLeaveLink(e)', e)
  177. this.$emit('onLeaveLink')
  178. },
  179. onClickCopyClipboard (e) {
  180. e.preventDefault()
  181. console.log('onClickCopyClipboard', e)
  182. // navigator.clipboard.writeText(e.target.getAttribute('href'))
  183. this.$copyText(e.target.getAttribute('href'))
  184. return false
  185. }
  186. },
  187. render (h) {
  188. // console.log('EdText render()')
  189. if (!this.template) {
  190. return h('span', 'Loading ...')
  191. } else {
  192. return this.template.render.call(this)
  193. }
  194. }
  195. }
  196. </script>
  197. <style lang="scss" scoped>
  198. </style>