index.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. var state = {
  2. compiler: '',
  3. options: {},
  4. content: {},
  5. theme: '',
  6. themes: {},
  7. _themes: [
  8. 'github',
  9. 'github-dark',
  10. 'almond',
  11. 'awsm',
  12. 'axist',
  13. 'bamboo',
  14. 'bullframe',
  15. 'holiday',
  16. 'kacit',
  17. 'latex',
  18. 'markdown-splendor',
  19. 'markdown-retro',
  20. 'markdown-air',
  21. 'markdown-modest',
  22. 'marx',
  23. 'minicss',
  24. 'new',
  25. 'no-class',
  26. 'pico',
  27. 'sakura',
  28. 'sakura-vader',
  29. 'semantic',
  30. 'simplecss',
  31. 'style-sans',
  32. 'style-serif',
  33. 'stylize',
  34. 'superstylin',
  35. 'tacit',
  36. 'vanilla',
  37. 'water',
  38. 'water-dark',
  39. 'writ',
  40. ],
  41. raw: false,
  42. tab: '',
  43. tabs: ['theme', 'compiler', 'content'],
  44. compilers: [],
  45. description: {
  46. themes: {
  47. wide: '100% width',
  48. },
  49. compiler: {},
  50. content: {
  51. autoreload: 'Auto reload on file change',
  52. emoji: 'Convert emoji :shortnames: into EmojiOne images',
  53. scroll: 'Remember scroll position',
  54. toc: 'Generate Table of Contents',
  55. mathjax: 'Render MathJax formulas',
  56. mermaid: 'Mermaid diagrams',
  57. }
  58. }
  59. }
  60. var events = {
  61. tab: (e) => {
  62. state.tab = e.target.hash.replace('#tab-', '')
  63. localStorage.setItem('tab', state.tab)
  64. return false
  65. },
  66. compiler: {
  67. name: (e) => {
  68. state.compiler = state.compilers[e.target.selectedIndex]
  69. chrome.runtime.sendMessage({
  70. message: 'popup.compiler.name',
  71. compiler: state.compiler,
  72. }, () => {
  73. chrome.runtime.sendMessage({message: 'popup'}, init)
  74. })
  75. },
  76. options: (e) => {
  77. state.options[e.target.name] = !state.options[e.target.name]
  78. chrome.runtime.sendMessage({
  79. message: 'popup.compiler.options',
  80. compiler: state.compiler,
  81. options: state.options,
  82. })
  83. }
  84. },
  85. content: (e) => {
  86. state.content[e.target.name] = !state.content[e.target.name]
  87. chrome.runtime.sendMessage({
  88. message: 'popup.content',
  89. content: state.content,
  90. })
  91. },
  92. themes: (e) => {
  93. state.themes[e.target.name] = !state.themes[e.target.name]
  94. chrome.runtime.sendMessage({
  95. message: 'popup.themes',
  96. themes: state.themes,
  97. })
  98. },
  99. theme: (e) => {
  100. state.theme = state._themes[e.target.selectedIndex]
  101. chrome.runtime.sendMessage({
  102. message: 'popup.theme',
  103. theme: state.theme
  104. })
  105. },
  106. raw: () => {
  107. state.raw = !state.raw
  108. chrome.runtime.sendMessage({
  109. message: 'popup.raw',
  110. raw: state.raw
  111. })
  112. },
  113. defaults: () => {
  114. chrome.runtime.sendMessage({
  115. message: 'popup.defaults'
  116. }, () => {
  117. chrome.runtime.sendMessage({message: 'popup'}, init)
  118. localStorage.removeItem('tab')
  119. state._tabs.activeTabIndex = 0
  120. })
  121. },
  122. advanced: () => {
  123. chrome.runtime.sendMessage({message: 'popup.advanced'})
  124. }
  125. }
  126. var init = (res) => {
  127. state.compiler = res.compiler
  128. state.options = res.options
  129. state.content = res.content
  130. state.theme = res.theme
  131. state.themes = res.themes
  132. state.raw = res.raw
  133. state.tab = localStorage.getItem('tab') || 'theme'
  134. state.compilers = res.compilers
  135. state.description.compiler = res.description
  136. m.redraw()
  137. }
  138. chrome.runtime.sendMessage({message: 'popup'}, init)
  139. var oncreate = {
  140. ripple: (vnode) => {
  141. mdc.ripple.MDCRipple.attachTo(vnode.dom)
  142. },
  143. tabs: (vnode) => {
  144. state._tabs = mdc.tabs.MDCTabBar.attachTo(vnode.dom)
  145. setTimeout(() => {
  146. state._tabs.activeTabIndex = state.tabs.indexOf(state.tab)
  147. }, 250)
  148. }
  149. }
  150. var onupdate = (tab, key) => (vnode) => {
  151. var value = tab === 'compiler' ? state.options[key]
  152. : tab === 'content' ? state.content[key]
  153. : null
  154. if (vnode.dom.classList.contains('is-checked') !== value) {
  155. vnode.dom.classList.toggle('is-checked')
  156. }
  157. }
  158. m.mount(document.querySelector('body'), {
  159. view: (vnode) =>
  160. m('#popup',
  161. // raw
  162. m('button.mdc-button mdc-button--raised m-button', {
  163. oncreate: oncreate.ripple,
  164. onclick: events.raw
  165. },
  166. (state.raw ? 'Html' : 'Markdown')
  167. ),
  168. // defaults
  169. m('button.mdc-button mdc-button--raised m-button', {
  170. oncreate: oncreate.ripple,
  171. onclick: events.defaults
  172. },
  173. 'Defaults'
  174. ),
  175. // tabs
  176. m('nav.mdc-tab-bar m-tabs', {
  177. oncreate: oncreate.tabs,
  178. onclick: events.tab
  179. },
  180. state.tabs.map((tab) =>
  181. m('a.mdc-tab', {
  182. href: '#tab-' + tab,
  183. },
  184. tab
  185. )),
  186. m('span.mdc-tab-bar__indicator')
  187. ),
  188. m('.m-panels',
  189. // theme
  190. m('.m-panel', {
  191. class: state.tab === 'theme' ? 'is-active' : ''
  192. },
  193. m('select.mdc-elevation--z2 m-select', {
  194. onchange: events.theme
  195. },
  196. state._themes.map((theme) =>
  197. m('option', {selected: state.theme === theme}, theme)
  198. )
  199. ),
  200. m('.scroll', Object.keys(state.themes).map((key) =>
  201. m('label.mdc-switch m-switch', {
  202. onupdate: onupdate('themes', key),
  203. title: state.description.themes[key]
  204. },
  205. m('input.mdc-switch__native-control', {
  206. type: 'checkbox',
  207. name: key,
  208. checked: state.themes[key],
  209. onchange: events.themes
  210. }),
  211. m('.mdc-switch__background', m('.mdc-switch__knob')),
  212. m('span.mdc-switch-label', key)
  213. ))
  214. )
  215. ),
  216. // compiler
  217. m('.m-panel', {
  218. class: state.tab === 'compiler' ? 'is-active' : ''
  219. },
  220. m('select.mdc-elevation--z2 m-select', {
  221. onchange: events.compiler.name
  222. },
  223. state.compilers.map((name) =>
  224. m('option', {selected: state.compiler === name}, name)
  225. )
  226. ),
  227. m('.scroll', {
  228. class: Object.keys(state.options)
  229. .filter((key) => typeof state.options[key] === 'boolean')
  230. .length > 8
  231. ? 'max' : ''
  232. },
  233. Object.keys(state.options)
  234. .filter((key) => typeof state.options[key] === 'boolean')
  235. .map((key) =>
  236. m('label.mdc-switch m-switch', {
  237. onupdate: onupdate('compiler', key),
  238. title: state.description.compiler[key]
  239. },
  240. m('input.mdc-switch__native-control', {
  241. type: 'checkbox',
  242. name: key,
  243. checked: state.options[key],
  244. onchange: events.compiler.options
  245. }),
  246. m('.mdc-switch__background', m('.mdc-switch__knob')),
  247. m('span.mdc-switch-label', key)
  248. )
  249. )
  250. )
  251. ),
  252. // content
  253. m('.m-panel', {
  254. class: state.tab === 'content' ? 'is-active' : ''
  255. },
  256. m('.scroll', Object.keys(state.content).map((key) =>
  257. m('label.mdc-switch m-switch', {
  258. onupdate: onupdate('content', key),
  259. title: state.description.content[key]
  260. },
  261. m('input.mdc-switch__native-control', {
  262. type: 'checkbox',
  263. name: key,
  264. checked: state.content[key],
  265. onchange: events.content
  266. }),
  267. m('.mdc-switch__background', m('.mdc-switch__knob')),
  268. m('span.mdc-switch-label', key)
  269. ))
  270. )
  271. )
  272. ),
  273. // advanced options
  274. m('button.mdc-button mdc-button--raised m-button', {
  275. oncreate: oncreate.ripple,
  276. onclick: events.advanced
  277. },
  278. 'Advanced Options'
  279. )
  280. )
  281. })