You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Accessibility.vue 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <template>
  2. <div id="accessibility" class="section">
  3. <h2>{{ t('accessibility', 'Accessibility') }}</h2>
  4. <p v-html="description" />
  5. <p v-html="descriptionDetail" />
  6. <div class="preview-list">
  7. <ItemPreview :key="highcontrast.id"
  8. :preview="highcontrast"
  9. :selected="selected.highcontrast"
  10. @select="selectHighContrast" />
  11. <ItemPreview v-for="preview in themes"
  12. :key="preview.id"
  13. :preview="preview"
  14. :selected="selected.theme"
  15. @select="selectTheme" />
  16. <ItemPreview v-for="preview in fonts"
  17. :key="preview.id"
  18. :preview="preview"
  19. :selected="selected.font"
  20. @select="selectFont" />
  21. </div>
  22. </div>
  23. </template>
  24. <script>
  25. import ItemPreview from './components/ItemPreview'
  26. import axios from 'nextcloud-axios'
  27. export default {
  28. name: 'Accessibility',
  29. components: { ItemPreview },
  30. data() {
  31. return {
  32. serverData: []
  33. }
  34. },
  35. computed: {
  36. themes() {
  37. return this.serverData.themes
  38. },
  39. highcontrast() {
  40. return this.serverData.highcontrast
  41. },
  42. fonts() {
  43. return this.serverData.fonts
  44. },
  45. selected() {
  46. return {
  47. theme: this.serverData.selected.theme,
  48. highcontrast: this.serverData.selected.highcontrast,
  49. font: this.serverData.selected.font
  50. }
  51. },
  52. description() {
  53. // using the `t` replace method escape html, we have to do it manually :/
  54. return t(
  55. 'accessibility',
  56. `Universal access is very important to us. We follow web standards
  57. and check to make everything usable also without mouse,
  58. and assistive software such as screenreaders.
  59. We aim to be compliant with the {guidelines} 2.1 on AA level,
  60. with the high contrast theme even on AAA level.`
  61. )
  62. .replace('{guidelines}', this.guidelinesLink)
  63. },
  64. guidelinesLink() {
  65. return `<a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/wcag/" rel="noreferrer nofollow">${t('accessibility', 'Web Content Accessibility Guidelines')}</a>`
  66. },
  67. descriptionDetail() {
  68. return t(
  69. 'accessibility',
  70. `If you find any issues, don’t hesitate to report them on {issuetracker}.
  71. And if you want to get involved, come join {designteam}!`
  72. )
  73. .replace('{issuetracker}', this.issuetrackerLink)
  74. .replace('{designteam}', this.designteamLink)
  75. },
  76. issuetrackerLink() {
  77. return `<a target="_blank" href="https://github.com/nextcloud/server/issues/" rel="noreferrer nofollow">${t('accessibility', 'our issue tracker')}</a>`
  78. },
  79. designteamLink() {
  80. return `<a target="_blank" href="https://nextcloud.com/design" rel="noreferrer nofollow">${t('accessibility', 'our design team')}</a>`
  81. }
  82. },
  83. beforeMount() {
  84. // importing server data into the app
  85. const serverDataElmt = document.getElementById('serverData')
  86. if (serverDataElmt !== null) {
  87. this.serverData = JSON.parse(
  88. document.getElementById('serverData').dataset.server
  89. )
  90. }
  91. },
  92. methods: {
  93. selectHighContrast(id) {
  94. this.selectItem('highcontrast', id)
  95. },
  96. selectTheme(id, idSelectedBefore) {
  97. this.selectItem('theme', id)
  98. document.body.classList.remove(idSelectedBefore)
  99. if (id) {
  100. document.body.classList.add(id)
  101. }
  102. },
  103. selectFont(id) {
  104. this.selectItem('font', id)
  105. },
  106. /**
  107. * Commit a change and force reload css
  108. * Fetching the file again will trigger the server update
  109. *
  110. * @param {string} type type of the change (font, highcontrast or theme)
  111. * @param {string} id the data of the change
  112. */
  113. selectItem(type, id) {
  114. axios.post(OC.linkToOCS('apps/accessibility/api/v1/config', 2) + type, { value: id })
  115. .then(response => {
  116. this.serverData.selected[type] = id
  117. // Remove old link
  118. let link = document.querySelector('link[rel=stylesheet][href*=accessibility][href*=user-]')
  119. if (!link) {
  120. // insert new css
  121. let link = document.createElement('link')
  122. link.rel = 'stylesheet'
  123. link.href = OC.generateUrl('/apps/accessibility/css/user-style.css') + '?v=' + new Date().getTime()
  124. document.head.appendChild(link)
  125. } else {
  126. // compare arrays
  127. if (
  128. JSON.stringify(Object.values(this.selected))
  129. === JSON.stringify([false, false])
  130. ) {
  131. // if nothing is selected, blindly remove the css
  132. link.remove()
  133. } else {
  134. // force update
  135. link.href
  136. = link.href.split('?')[0]
  137. + '?v='
  138. + new Date().getTime()
  139. }
  140. }
  141. })
  142. .catch(err => {
  143. console.error(err, err.response)
  144. OC.Notification.showTemporary(t('accessibility', err.response.data.ocs.meta.message + '. Unable to apply the setting.'))
  145. })
  146. }
  147. }
  148. }
  149. </script>