background.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // chrome.storage.sync.clear()
  2. // chrome.permissions.getAll((p) => chrome.permissions.remove({origins: p.origins}))
  3. chrome.storage.sync.get((res) => {
  4. var match = '\\.(?:markdown|mdown|mkdn|md|mkd|mdwn|mdtxt|mdtext|text)(?:#.*)?$'
  5. var defaults = {
  6. compiler: md.defaults,
  7. content: {
  8. toc: false,
  9. scroll: true
  10. },
  11. theme: 'github',
  12. raw: false,
  13. match,
  14. origins: {
  15. 'file://': match
  16. }
  17. }
  18. var options = !Object.keys(res).length ? defaults : res
  19. // v2.2 -> v2.3
  20. if (!options.match || !options.origins) {
  21. options.match = match
  22. options.origins = {
  23. 'file://': match
  24. }
  25. }
  26. // v2.3 -> v2.4
  27. else if (!options.origins['file://']) {
  28. options.origins['file://'] = match
  29. }
  30. // v2.4 -> v2.5
  31. if (!options.compiler) {
  32. options.compiler = options.options
  33. }
  34. if (!options.content) {
  35. options.content = defaults.content
  36. }
  37. chrome.storage.sync.set(options)
  38. // reload extension bug
  39. chrome.permissions.getAll((permissions) => {
  40. var origins = Object.keys(res.origins || {})
  41. chrome.permissions.remove({
  42. origins: permissions.origins
  43. .filter((origin) => (origins.indexOf(origin.slice(0, -2)) === -1))
  44. })
  45. })
  46. })
  47. function parallel (tasks, done) {
  48. var complete = 0, error, result = {}
  49. tasks.forEach((task) => task((err, res) => {
  50. if (error) {
  51. return
  52. }
  53. if (err) {
  54. error = err
  55. done(err)
  56. return
  57. }
  58. if (res) {
  59. Object.keys(res).forEach((key) => {
  60. result[key] = res[key]
  61. })
  62. }
  63. if (++complete === tasks.length) {
  64. done(null, result)
  65. }
  66. }))
  67. }
  68. chrome.tabs.onUpdated.addListener((id, info, tab) => {
  69. if (info.status === 'loading') {
  70. parallel([
  71. (done) => {
  72. chrome.tabs.executeScript(id, {
  73. code: 'JSON.stringify({location, state: window.state})',
  74. runAt: 'document_start'
  75. }, (res) => {
  76. if (chrome.runtime.lastError) {
  77. done(new Error('Origin not allowed'))
  78. return
  79. }
  80. try {
  81. res = JSON.parse(res)
  82. }
  83. catch (err) {
  84. done(new Error('JSON parse error'))
  85. return
  86. }
  87. done(null, res)
  88. })
  89. },
  90. (done) => {
  91. chrome.storage.sync.get((res) => done(null, res))
  92. }
  93. ], (err, res) => {
  94. if (err) {
  95. return
  96. }
  97. var path =
  98. res.origins[res.location.origin] ||
  99. res.origins['*://' + res.location.host] ||
  100. res.origins['*://*']
  101. if (!path) { // v2.2 -> v2.3
  102. return
  103. }
  104. if (!res.state && new RegExp(path).test(res.location.href)) {
  105. chrome.tabs.executeScript(id, {
  106. code: [
  107. 'document.querySelector("pre").style.visibility = "hidden"',
  108. 'var theme = "' + res.theme + '"',
  109. 'var raw = ' + res.raw,
  110. 'var content = ' + JSON.stringify(res.content)
  111. ].join(';'), runAt: 'document_start'})
  112. chrome.tabs.insertCSS(id, {file: 'css/content.css', runAt: 'document_start'})
  113. chrome.tabs.insertCSS(id, {file: 'vendor/prism.css', runAt: 'document_start'})
  114. chrome.tabs.executeScript(id, {file: 'vendor/mithril.min.js', runAt: 'document_start'})
  115. chrome.tabs.executeScript(id, {file: 'vendor/prism.js', runAt: 'document_start'})
  116. chrome.tabs.executeScript(id, {file: 'content/content.js', runAt: 'document_start'})
  117. chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
  118. chrome.pageAction.show(tabs[0].id)
  119. })
  120. }
  121. })
  122. }
  123. })
  124. chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
  125. if (req.message === 'markdown') {
  126. md.compile(req.markdown, sendResponse)
  127. }
  128. else if (req.message === 'settings') {
  129. chrome.storage.sync.get(['compiler', 'content', 'theme', 'raw'], (res) => {
  130. delete res.compiler.langPrefix
  131. sendResponse(res)
  132. })
  133. }
  134. else if (req.message === 'compiler') {
  135. req.compiler.langPrefix = 'language-' // prism
  136. chrome.storage.sync.set({compiler: req.compiler}, sendResponse)
  137. sendMessage({message: 'reload'})
  138. }
  139. else if (req.message === 'content') {
  140. chrome.storage.sync.set({content: req.content}, sendResponse)
  141. sendMessage({message: 'reload'})
  142. }
  143. else if (req.message === 'defaults') {
  144. chrome.storage.sync.set({
  145. compiler: md.defaults,
  146. content: {toc: false, scroll: true},
  147. theme: 'github', raw: false
  148. }, sendResponse)
  149. sendMessage({message: 'reload'})
  150. }
  151. else if (req.message === 'theme') {
  152. chrome.storage.sync.set({theme: req.theme}, sendResponse)
  153. sendMessage({message: 'theme', theme: req.theme})
  154. }
  155. else if (req.message === 'raw') {
  156. chrome.storage.sync.set({raw: req.raw}, sendResponse)
  157. sendMessage({message: 'raw', raw: req.raw})
  158. }
  159. else if (req.message === 'advanced') {
  160. chrome.management.getSelf((extension) => {
  161. chrome.tabs.create({url: extension.optionsUrl}, sendResponse)
  162. })
  163. }
  164. else if (req.message === 'origins') {
  165. chrome.storage.sync.get('origins', sendResponse)
  166. }
  167. else if (req.message === 'add') {
  168. chrome.storage.sync.get(['match', 'origins'], (res) => {
  169. res.origins[req.origin] = res.match
  170. chrome.storage.sync.set({origins: res.origins}, sendResponse)
  171. })
  172. }
  173. else if (req.message === 'remove') {
  174. chrome.storage.sync.get('origins', (res) => {
  175. delete res.origins[req.origin]
  176. chrome.storage.sync.set({origins: res.origins}, sendResponse)
  177. })
  178. }
  179. else if (req.message === 'update') {
  180. chrome.storage.sync.get('origins', (res) => {
  181. res.origins[req.origin] = req.match
  182. chrome.storage.sync.set({origins: res.origins}, sendResponse)
  183. })
  184. }
  185. return true
  186. })
  187. function sendMessage (req) {
  188. chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
  189. chrome.tabs.sendMessage(tabs[0].id, req)
  190. })
  191. }