popup.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. var state = {
  2. compiler: '',
  3. options: {},
  4. content: {},
  5. theme: '',
  6. themes: [],
  7. raw: false,
  8. tab: '',
  9. tabs: ['theme', 'compiler', 'content'],
  10. compilers: [],
  11. description: {
  12. compiler: {},
  13. content: {
  14. emoji: 'Convert emoji :shortnames: into EmojiOne images',
  15. scroll: 'Remember scroll position',
  16. toc: 'Generate Table of Contents'
  17. }
  18. }
  19. }
  20. var events = {
  21. tab: (e) => {
  22. state.tab = e.target.parentNode.hash.replace('#tab-', '')
  23. localStorage.setItem('tab', state.tab)
  24. },
  25. compiler: {
  26. name: (e) => {
  27. state.compiler = state.compilers[e.target.selectedIndex]
  28. chrome.runtime.sendMessage({
  29. message: 'compiler.name',
  30. compiler: state.compiler
  31. }, () => {
  32. chrome.runtime.sendMessage({message: 'settings'}, init)
  33. })
  34. },
  35. options: (e) => {
  36. state.options[e.target.name] = !state.options[e.target.name]
  37. chrome.runtime.sendMessage({
  38. message: 'compiler.options',
  39. compiler: state.compiler,
  40. options: state.options
  41. })
  42. }
  43. },
  44. content: (e) => {
  45. state.content[e.target.name] = !state.content[e.target.name]
  46. chrome.runtime.sendMessage({
  47. message: 'content',
  48. content: state.content
  49. })
  50. },
  51. theme: (e) => {
  52. state.theme = state.themes[e.target.selectedIndex]
  53. chrome.runtime.sendMessage({
  54. message: 'theme',
  55. theme: state.theme
  56. })
  57. },
  58. raw: () => {
  59. state.raw = !state.raw
  60. chrome.runtime.sendMessage({
  61. message: 'raw',
  62. raw: state.raw
  63. })
  64. },
  65. defaults: () => {
  66. chrome.runtime.sendMessage({
  67. message: 'defaults'
  68. }, () => {
  69. chrome.runtime.sendMessage({message: 'settings'}, init)
  70. localStorage.removeItem('tab')
  71. })
  72. },
  73. advanced: () => {
  74. chrome.runtime.sendMessage({message: 'advanced'})
  75. }
  76. }
  77. var init = (res) => {
  78. state.compiler = res.compiler
  79. state.options = res.options
  80. state.content = res.content
  81. state.theme = res.theme
  82. state.themes = chrome.runtime.getManifest().web_accessible_resources
  83. .filter((file) => (file.indexOf('/themes/') === 0))
  84. .map((file) => (file.replace(/\/themes\/(.*)\.css/, '$1')))
  85. state.raw = res.raw
  86. state.tab = localStorage.getItem('tab') || 'theme'
  87. state.compilers = res.compilers
  88. state.description.compiler = res.description
  89. m.redraw()
  90. }
  91. chrome.runtime.sendMessage({message: 'settings'}, init)
  92. var oncreate = (vnode) => {
  93. componentHandler.upgradeElements(vnode.dom)
  94. }
  95. var onupdate = (tab, key) => (vnode) => {
  96. var value = tab === 'compiler' ? state.options[key]
  97. : tab === 'content' ? state.content[key]
  98. : null
  99. if (vnode.dom.classList.contains('is-checked') !== value) {
  100. vnode.dom.classList.toggle('is-checked')
  101. }
  102. }
  103. m.mount(document.querySelector('body'), {
  104. view: (vnode) =>
  105. m('#popup',
  106. // defaults
  107. m('button.mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect',
  108. {oncreate, onclick: events.raw},
  109. (state.raw ? 'Html' : 'Markdown')),
  110. m('button.mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect',
  111. {oncreate, onclick: events.defaults},
  112. 'Defaults'),
  113. // tabs
  114. m('.mdl-tabs mdl-js-tabs mdl-js-ripple-effect', {oncreate},
  115. m('.mdl-tabs__tab-bar', {onclick: events.tab}, state.tabs.map((tab) =>
  116. m('a.mdl-tabs__tab', {
  117. href: '#tab-' + tab,
  118. class: state.tab === tab ? 'is-active' : ''
  119. }, tab))
  120. ),
  121. // theme
  122. m('.mdl-tabs__panel #tab-theme', {class: state.tab === 'theme' ? 'is-active' : ''},
  123. m('select.mdl-shadow--2dp', {onchange: events.theme}, state.themes.map((theme) =>
  124. m('option', {selected: state.theme === theme}, theme)
  125. ))
  126. ),
  127. // compiler
  128. m('.mdl-tabs__panel #tab-compiler', {class: state.tab === 'compiler' ? 'is-active' : ''},
  129. m('select.mdl-shadow--2dp', {onchange: events.compiler.name}, state.compilers.map((name) =>
  130. m('option', {selected: state.compiler === name}, name)
  131. )),
  132. m('.scroll', {class: Object.keys(state.options).length > 8 ? 'max' : ''},
  133. m('.mdl-grid', Object.keys(state.options || [])
  134. .filter((key) => typeof state.options[key] === 'boolean')
  135. .map((key) =>
  136. m('.mdl-cell',
  137. m('label.mdl-switch mdl-js-switch mdl-js-ripple-effect',
  138. {oncreate, onupdate: onupdate('compiler', key),
  139. title: state.description.compiler[key]},
  140. m('input[type="checkbox"].mdl-switch__input', {
  141. name: key,
  142. checked: state.options[key],
  143. onchange: events.compiler.options
  144. }),
  145. m('span.mdl-switch__label', key)
  146. )
  147. ))
  148. )
  149. )
  150. ),
  151. // content
  152. m('.mdl-tabs__panel #tab-content',
  153. {class: state.tab === 'content' ? 'is-active' : ''},
  154. m('.scroll',
  155. m('.mdl-grid', Object.keys(state.content).map((key) =>
  156. m('.mdl-cell',
  157. m('label.mdl-switch mdl-js-switch mdl-js-ripple-effect',
  158. {oncreate, onupdate: onupdate('content', key), title: state.description.content[key]},
  159. m('input[type="checkbox"].mdl-switch__input', {
  160. name: key,
  161. checked: state.content[key],
  162. onchange: events.content
  163. }),
  164. m('span.mdl-switch__label', key)
  165. )
  166. )
  167. ))
  168. )
  169. )
  170. ),
  171. // advanced options
  172. m('button.mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect',
  173. {oncreate, onclick: events.advanced},
  174. 'Advanced Options')
  175. )
  176. })