浏览代码

Remove custom themes implementation + add wide theme option

simov 4 年之前
父节点
当前提交
fe87b3450d
共有 14 个文件被更改,包括 80 次插入737 次删除
  1. 1 0
      background/inject.js
  2. 5 32
      background/messages.js
  3. 10 5
      background/storage.js
  4. 16 0
      content/index.css
  5. 9 2
      content/index.js
  6. 0 34
      options/index.css
  7. 0 1
      options/index.html
  8. 0 3
      options/index.js
  9. 0 207
      options/themes.js
  10. 35 19
      popup/index.js
  11. 0 429
      test/custom-themes.js
  12. 2 2
      test/defaults-popup.js
  13. 0 1
      test/index.js
  14. 2 2
      test/popup-options.js

+ 1 - 0
background/inject.js

@@ -6,6 +6,7 @@ md.inject = ({storage: {state}}) => (id) => {
       document.querySelector('pre').style.visibility = 'hidden'
       var theme = ${JSON.stringify(state.theme)}
       var raw = ${state.raw}
+      var themes = ${JSON.stringify(state.themes)}
       var content = ${JSON.stringify(state.content)}
       var compiler = '${state.compiler}'
     `,

+ 5 - 32
background/messages.js

@@ -45,6 +45,11 @@ md.messages = ({storage: {defaults, state, set}, compilers, mathjax, xhr, webreq
       notifyContent({message: 'raw', raw: req.raw})
       sendResponse()
     }
+    else if (req.message === 'popup.themes') {
+      set({themes: req.themes})
+      notifyContent({message: 'themes', themes: req.themes})
+      sendResponse()
+    }
     else if (req.message === 'popup.defaults') {
       var options = Object.assign({}, defaults)
       options.origins = state.origins
@@ -89,11 +94,6 @@ md.messages = ({storage: {defaults, state, set}, compilers, mathjax, xhr, webreq
         match: state.match,
       })
     }
-    else if (req.message === 'options.themes') {
-      sendResponse({
-        themes: state.themes,
-      })
-    }
     else if (req.message === 'options.header') {
       set({header: req.header})
       sendResponse()
@@ -122,33 +122,6 @@ md.messages = ({storage: {defaults, state, set}, compilers, mathjax, xhr, webreq
       sendResponse()
     }
 
-    // themes
-    else if (req.message === 'themes') {
-      set({themes: req.themes})
-
-      ;(() => {
-        var defaults = chrome.runtime.getManifest().web_accessible_resources
-          .filter((file) => file.indexOf('/themes/') === 0)
-          .map((file) => file.replace(/\/themes\/(.*)\.css/, '$1'))
-        var custom = state.themes.map(({name}) => name)
-        var all = custom.concat(defaults)
-
-        if (!all.includes(state.theme.name)) {
-          var theme = {
-            name: 'github',
-            url: chrome.runtime.getURL('/themes/github.css')
-          }
-          set({theme})
-        }
-        else if (custom.includes(state.theme.name)) {
-          var theme = state.themes.find(({name}) => state.theme.name === name)
-          set({theme})
-        }
-      })()
-
-      sendResponse()
-    }
-
     return true
   }
 

+ 10 - 5
background/storage.js

@@ -39,14 +39,14 @@ md.storage.defaults = (compilers) => {
   var match = '\\.(?:markdown|mdown|mkdn|md|mkd|mdwn|mdtxt|mdtext|text)(?:#.*|\\?.*)?$'
 
   var defaults = {
-    theme: {
-      name: 'github',
-      url: chrome.runtime.getURL('/themes/github.css')
-    },
+    theme: 'github',
     compiler: 'marked',
     raw: false,
     header: true,
     match,
+    themes: {
+      wide: false,
+    },
     content: {
       emoji: false,
       scroll: true,
@@ -62,7 +62,6 @@ md.storage.defaults = (compilers) => {
         encoding: '',
       }
     },
-    themes: [],
   }
 
   Object.keys(compilers).forEach((compiler) => {
@@ -110,4 +109,10 @@ md.storage.migrations = (state) => {
   if (state.content.mermaid === undefined) {
     state.content.mermaid = false
   }
+  if (state.themes === undefined || state.themes instanceof Array) {
+    state.themes = {wide: false}
+  }
+  if (typeof state.theme === 'object') {
+    state.theme = state.theme.name
+  }
 }

+ 16 - 0
content/index.css

@@ -53,6 +53,22 @@ pre#_markdown {
   .markdown-theme { width: 1145px !important; }
 }
 
+/*100% width*/
+.wide-theme {
+  box-sizing: border-box;
+  width: 100% !important;
+  max-width: 100% !important;
+  min-width: 100% !important;
+  border: none;
+  padding: 20px !important;
+  margin: 0 !important;
+}
+
+/*mermaid text bold effect*/
+svg[id^=mermaid] text {
+  stroke: none !important;
+}
+
 /*toc*/
 body {
   display: flex;

+ 9 - 2
content/index.js

@@ -4,6 +4,7 @@ var $ = document.querySelector.bind(document)
 var state = {
   theme,
   raw,
+  themes,
   content,
   compiler,
   html: '',
@@ -21,6 +22,10 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     state.theme = req.theme
     m.redraw()
   }
+  else if (req.message === 'themes') {
+    state.themes = req.themes
+    m.redraw()
+  }
   else if (req.message === 'raw') {
     state.raw = req.raw
     m.redraw()
@@ -78,12 +83,14 @@ function mount () {
         if (state.theme) {
           dom.push(m('link#_theme', {
             rel: 'stylesheet', type: 'text/css',
-            href: state.theme.url,
+            href: chrome.runtime.getURL(`/themes/${state.theme}.css`),
           }))
         }
         if (state.html) {
           dom.push(m('#_html', {oncreate: oncreate.html,
-            class: /github(-dark)?/.test(state.theme.name) ? 'markdown-body' : 'markdown-theme'},
+            class: (/github(-dark)?/.test(state.theme) ? 'markdown-body' : 'markdown-theme') +
+            (state.themes.wide ? ' wide-theme' : '')
+          },
             m.trust(state.html)
           ))
           if (state.content.toc && state.toc) {

+ 0 - 34
options/index.css

@@ -237,31 +237,6 @@ footer .icon-hidden {
 }
 
 
-/*add theme*/
-.m-add-theme:after { content: ''; display: block; clear: both; }
-.m-add-theme h4 {
-  float: left;
-  padding: 0 80px 0 0;
-}
-.m-add-theme .m-textfield {
-  height: auto !important;
-  padding: 0 !important;
-  margin: 0 10px !important;
-}
-.m-add-theme .m-textfield input {
-  padding-top: 3px;
-}
-.m-add-theme .m-name {
-  width: 270px;
-}
-.m-add-theme .m-url {
-  width: 500px;
-}
-.m-add-theme button {
-  float: right;
-}
-
-
 /*global*/
 .m-global {
   margin: 20px 0 0 0;
@@ -400,15 +375,6 @@ footer .icon-hidden {
   margin: 6px 0 0 25px;
 }
 
-/*list options - themes*/
-
-.m-list .m-content .m-option.m-theme .m-control {
-  width: 80%;
-  margin: 0 0 0 15px;
-}
-.m-list .m-content .m-option.m-theme .m-textfield {
-  width: 80%;
-}
 
 /*list footer*/
 

+ 0 - 1
options/index.html

@@ -30,6 +30,5 @@
   </footer>
 </body>
 <script src="/options/origins.js" type="text/javascript" charset="utf-8"></script>
-<script src="/options/themes.js" type="text/javascript" charset="utf-8"></script>
 <script src="/options/index.js" type="text/javascript" charset="utf-8"></script>
 </html>

+ 0 - 3
options/index.js

@@ -1,13 +1,10 @@
 
 var origins = Origins()
-var themes = Themes()
 
 m.mount(document.querySelector('main'), {
   view: () => [
     // allowed origins
     origins.render(),
-    // custom themes
-    // themes.render(),
   ]
 })
 

+ 0 - 207
options/themes.js

@@ -1,207 +0,0 @@
-
-var Themes = () => {
-  var defaults = {
-    // storage
-    themes: [],
-    // UI
-    timeout: null,
-    theme: {},
-    // static
-  }
-
-  var state = Object.assign({}, defaults)
-
-  chrome.runtime.sendMessage({message: 'options.themes'}, (res) => {
-    Object.assign(state, res)
-    m.redraw()
-  })
-
-  var events = {
-    name: (e) => {
-      state.theme.name = e.target.value
-    },
-
-    url: (e) => {
-      state.theme.url = e.target.value
-    },
-
-    add: () => {
-      if (!state.theme.name || !state.theme.url) {
-        return
-      }
-      var all = chrome.runtime.getManifest().web_accessible_resources
-        .filter((file) => file.indexOf('/themes/') === 0)
-        .map((file) => file.replace(/\/themes\/(.*)\.css/, '$1'))
-        .concat(state.themes.map(({name}) => name))
-      if (all.includes(state.theme.name)) {
-        return
-      }
-      state.themes.push({
-        name: state.theme.name,
-        url: state.theme.url,
-      })
-      chrome.runtime.sendMessage({
-        message: 'themes',
-        themes: state.themes.map(({name, url}) => ({name, url}))
-      })
-      state.theme.name = ''
-      state.theme.url = ''
-      m.redraw()
-    },
-
-    update: {
-      name: (theme) => (e) => {
-        theme.name = e.target.value
-        clearTimeout(state.timeout)
-        state.timeout = setTimeout(() => {
-          chrome.runtime.sendMessage({
-            message: 'themes',
-            themes: state.themes.map(({name, url}) => ({name, url}))
-          })
-          m.redraw()
-        }, 750)
-      },
-
-      url: (theme) => (e) => {
-        theme.url = e.target.value
-        clearTimeout(state.timeout)
-        state.timeout = setTimeout(() => {
-          chrome.runtime.sendMessage({
-            message: 'themes',
-            themes: state.themes.map(({name, url}) => ({name, url}))
-          })
-        }, 750)
-      }
-    },
-
-    remove: (theme) => () => {
-      var index = state.themes.findIndex(({name}) => name === theme.name)
-      state.themes.splice(index, 1)
-      chrome.runtime.sendMessage({
-        message: 'themes',
-        themes: state.themes.map(({name, url}) => ({name, url}))
-      })
-      m.redraw()
-    }
-  }
-
-  var oncreate = {
-    ripple: (vnode) => {
-      mdc.ripple.MDCRipple.attachTo(vnode.dom)
-    },
-    textfield: (vnode) => {
-      mdc.textfield.MDCTextField.attachTo(vnode.dom)
-    }
-  }
-
-  var onupdate = {
-    cache: (theme) => (vnode) => {
-      if (vnode.dom.classList.contains('is-checked') !== state.themes[theme.name].cache) {
-        vnode.dom.classList.toggle('is-checked')
-      }
-    }
-  }
-
-  var render = () =>
-    m('.bs-callout m-themes',
-
-      // add theme
-      m('.m-add-theme',
-        m('h4.mdc-typography--headline5', 'Custom Themes'),
-        // name
-        m('.mdc-text-field m-textfield m-name', {
-          oncreate: oncreate.textfield,
-          },
-          m('input.mdc-text-field__input', {
-            type: 'text',
-            value: state.theme.name,
-            onchange: events.name,
-            placeholder: 'Name'
-          }),
-          m('.mdc-line-ripple')
-        ),
-        // url
-        m('.mdc-text-field m-textfield m-url', {
-          oncreate: oncreate.textfield,
-          },
-          m('input.mdc-text-field__input', {
-            type: 'text',
-            value: state.theme.url,
-            onchange: events.url,
-            placeholder: 'URL - file:///home.. | http://localhost..'
-          }),
-          m('.mdc-line-ripple')
-        ),
-        m('button.mdc-button mdc-button--raised m-button', {
-          oncreate: oncreate.ripple,
-          onclick: events.add
-          },
-          'Add'
-        )
-      ),
-
-      // themes list
-      (state.themes.length || null) &&
-      m('ul.m-list', state.themes.map((theme) =>
-        m('li.mdc-elevation--z2', {
-          class: theme.expanded ? 'm-expanded' : null,
-          },
-          m('.m-summary', {
-            onclick: (e) => theme.expanded = !theme.expanded
-            },
-            m('.m-title', theme.name),
-            m('i.material-icons', {
-              class: theme.expanded ? 'icon-arrow-up' : 'icon-arrow-down'
-            })
-          ),
-          m('.m-content',
-            // name
-            m('.m-option m-theme',
-              m('.m-name', m('span', 'Name')),
-              m('.m-control',
-                m('.mdc-text-field m-textfield', {
-                  oncreate: oncreate.textfield
-                  },
-                  m('input.mdc-text-field__input', {
-                    type: 'text',
-                    onkeyup: events.update.name(theme),
-                    value: theme.name,
-                  }),
-                  m('.mdc-line-ripple')
-                )
-              )
-            ),
-            // url
-            m('.m-option m-theme',
-              m('.m-name', m('span', 'URL')),
-              m('.m-control',
-                m('.mdc-text-field m-textfield', {
-                  oncreate: oncreate.textfield
-                  },
-                  m('input.mdc-text-field__input', {
-                    type: 'text',
-                    onkeyup: events.update.url(theme),
-                    value: theme.url,
-                  }),
-                  m('.mdc-line-ripple')
-                )
-              )
-            ),
-            // update/remove
-            m('.m-footer',
-              m('span',
-                m('button.mdc-button mdc-button--raised m-button', {
-                  oncreate: oncreate.ripple,
-                  onclick: events.remove(theme)
-                  },
-                  'Remove'
-                )
-              )
-            )
-          )
-        )
-      ))
-    )
-
-  return {state, render}
-}

+ 35 - 19
popup/index.js

@@ -4,13 +4,16 @@ var state = {
   options: {},
   content: {},
   theme: '',
-  themes: [],
-  custom: [],
+  themes: {},
+  _themes: [],
   raw: false,
   tab: '',
   tabs: ['theme', 'compiler', 'content'],
   compilers: [],
   description: {
+    themes: {
+      wide: '100% width',
+    },
     compiler: {},
     content: {
       autoreload: 'Auto reload on file change',
@@ -58,17 +61,16 @@ var events = {
     })
   },
 
-  theme: (e) => {
-    var name = state.themes[e.target.selectedIndex]
-
-    var defaults = chrome.runtime.getManifest().web_accessible_resources
-      .filter((file) => file.indexOf('/themes/') === 0)
-      .map((file) => file.replace(/\/themes\/(.*)\.css/, '$1'))
-
-    state.theme = defaults.includes(name)
-      ? {name, url: chrome.runtime.getURL(`/themes/${name}.css`)}
-      : state.custom.find((theme) => theme.name === name)
+  themes: (e) => {
+    state.themes[e.target.name] = !state.themes[e.target.name]
+    chrome.runtime.sendMessage({
+      message: 'popup.themes',
+      themes: state.themes,
+    })
+  },
 
+  theme: (e) => {
+    state.theme = state._themes[e.target.selectedIndex]
     chrome.runtime.sendMessage({
       message: 'popup.theme',
       theme: state.theme
@@ -103,12 +105,11 @@ var init = (res) => {
   state.options = res.options
   state.content = res.content
   state.theme = res.theme
+  state.themes = res.themes
 
-  state.custom = res.themes
-  state.themes = res.themes.map(({name}) => name).concat(
-    chrome.runtime.getManifest().web_accessible_resources
-      .filter((file) => file.indexOf('/themes/') === 0)
-      .map((file) => file.replace(/\/themes\/(.*)\.css/, '$1')))
+  state._themes = chrome.runtime.getManifest().web_accessible_resources
+    .filter((file) => file.indexOf('/themes/') === 0)
+    .map((file) => file.replace(/\/themes\/(.*)\.css/, '$1'))
 
   state.raw = res.raw
   state.tab = localStorage.getItem('tab') || 'theme'
@@ -181,9 +182,24 @@ m.mount(document.querySelector('body'), {
           m('select.mdc-elevation--z2 m-select', {
             onchange: events.theme
             },
-            state.themes.map((theme) =>
-              m('option', {selected: state.theme.name === theme}, theme)
+            state._themes.map((theme) =>
+              m('option', {selected: state.theme === theme}, theme)
             )
+          ),
+          m('.scroll', Object.keys(state.themes).map((key) =>
+            m('label.mdc-switch m-switch', {
+              onupdate: onupdate('themes', key),
+              title: state.description.themes[key]
+              },
+              m('input.mdc-switch__native-control', {
+                type: 'checkbox',
+                name: key,
+                checked: state.themes[key],
+                onchange: events.themes
+              }),
+              m('.mdc-switch__background', m('.mdc-switch__knob')),
+              m('span.mdc-switch-label', key)
+            ))
           )
         ),
         // compiler

+ 0 - 429
test/custom-themes.js

@@ -1,429 +0,0 @@
-
-var t = require('assert')
-var defaults = require('./utils/defaults')
-
-
-module.exports = ({popup, advanced, content}) => {
-
-  before(async () => {
-    await defaults({popup, advanced, content})
-  })
-
-  describe('validate input', () => {
-    before(async () => {
-      // advanced
-      await advanced.bringToFront()
-    })
-
-    it('missing name and url', async () => {
-      // both empty
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = ''
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = ''
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      t.equal(
-        await advanced.evaluate(() => {
-          document.querySelector('.m-themes .m-list')
-        }),
-        null,
-        'should not add theme with missing name and url'
-      )
-    })
-
-    it('missing name', async () => {
-      // empty name
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = ''
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      t.equal(
-        await advanced.evaluate(() => {
-          document.querySelector('.m-themes .m-list')
-        }),
-        null,
-        'should not add theme with missing name'
-      )
-    })
-
-    it('missing url', async () => {
-      // empty url
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'hey'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = ''
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      t.equal(
-        await advanced.evaluate(() => {
-          document.querySelector('.m-themes .m-list')
-        }),
-        null,
-        'should not add theme with missing url'
-      )
-    })
-
-    it('duplicate name from the default themes', async () => {
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'github'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      t.equal(
-        await advanced.evaluate(() => {
-          document.querySelector('.m-themes .m-list')
-        }),
-        null,
-        'should not add theme with duplicate name'
-      )
-    })
-  })
-
-  describe('add', () => {
-
-    before(async () => {
-      await advanced.bringToFront()
-    })
-
-    it('add custom theme', async () => {
-      // add theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'a custom theme'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'file:///hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      await advanced.waitFor(300)
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelectorAll('.m-themes .m-list li').length
-        ),
-        1,
-        'the new theme should be added to the list of custom themes'
-      )
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-themes .m-list .m-title').innerText
-        ),
-        'a custom theme',
-        'the custom theme name should be set in the list'
-      )
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-add-theme [placeholder=Name]').innerText
-        ),
-        '',
-        'cleanup name input'
-      )
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-add-theme [placeholder~=URL]').innerText
-        ),
-        '',
-        'cleanup url input'
-      )
-    })
-
-    it('duplicate name from the custom themes', async () => {
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'a custom theme'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelectorAll('.m-themes .m-list').length
-        ),
-        1,
-        'should not add theme with duplicate name'
-      )
-    })
-
-    it('preserve state', async () => {
-      await advanced.reload()
-      await advanced.waitFor(300)
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelectorAll('.m-themes .m-list').length
-        ),
-        1,
-        'the new theme should be added to the list of custom themes'
-      )
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-themes .m-list .m-title').innerText
-        ),
-        'a custom theme',
-        'the custom theme name should be set in the list'
-      )
-    })
-  })
-
-  describe('choose', () => {
-
-    before(async () => {
-      // advanced
-      await advanced.bringToFront()
-      // add theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'a custom theme'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'file:///hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-    })
-
-    it('choose custom theme from the popup', async () => {
-      // popup
-      await popup.bringToFront()
-      await popup.reload()
-      // theme tab
-      await popup.click('.m-tabs a:nth-of-type(1)')
-
-      // select the first theme
-      await popup.select('.m-panel:nth-of-type(1) select', 'a custom theme')
-      t.equal(
-        await popup.evaluate(() =>
-          state.theme.name
-        ),
-        'a custom theme',
-        'custom theme should be selected'
-      )
-
-      await popup.reload()
-      await popup.waitFor(300)
-      t.equal(
-        await popup.evaluate(() =>
-          state.theme.name
-        ),
-        'a custom theme',
-        'custom theme should be selected'
-      )
-    })
-
-    it('theme should be added to the content', async () => {
-      await content.goto('http://localhost:3000/correct-content-type')
-      await content.bringToFront()
-      await content.waitFor(300)
-      t.equal(
-        await content.evaluate(() =>
-          document.querySelector('#_theme').getAttribute('href')
-        ),
-        'file:///hey',
-        'custom theme should be embedded'
-      )
-    })
-  })
-
-  describe('update url', () => {
-
-    before(async () => {
-      // advanced
-      await advanced.bringToFront()
-      // add theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'a custom theme'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'file:///hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-      // popup
-      await popup.bringToFront()
-      await popup.reload()
-      // theme tab
-      await popup.click('.m-tabs a:nth-of-type(1)')
-      // select the first theme
-      await popup.select('.m-panel:nth-of-type(1) select', 'a custom theme')
-    })
-
-    it('update custom theme url', async () => {
-      // advanced
-      await advanced.bringToFront()
-      // expand theme
-      if (!await advanced.evaluate(() => document.querySelector('.m-themes .m-list li:nth-of-type(1)').classList.contains('m-expanded'))) {
-        await advanced.click('.m-themes .m-list li:nth-of-type(1)')
-      }
-      // update theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-themes .m-option:nth-of-type(2) input').value = 'file:///hi'
-        document.querySelector('.m-themes .m-option:nth-of-type(2) input').dispatchEvent(new Event('keyup'))
-      })
-      // there is debounce timeout of 750ms in the options UI
-      await advanced.waitFor(800)
-
-      // reload
-      await advanced.reload()
-      await advanced.waitFor(300)
-
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-themes .m-option:nth-of-type(2) input').value
-        ),
-        'file:///hi',
-        'the custom theme URL should be updated'
-      )
-    })
-
-    it('check content', async () => {
-      await content.goto('http://localhost:3000/correct-content-type')
-      await content.bringToFront()
-      await content.waitFor(300)
-      t.equal(
-        await content.evaluate(() =>
-          document.querySelector('#_theme').getAttribute('href')
-        ),
-        'file:///hi',
-        'custom theme url should be updated'
-      )
-    })
-  })
-
-  describe('update name', () => {
-
-    before(async () => {
-      // advanced
-      await advanced.bringToFront()
-      // add theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'a custom theme'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'file:///hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-
-      // popup
-      await popup.bringToFront()
-      await popup.reload()
-      // theme tab
-      await popup.click('.m-tabs a:nth-of-type(1)')
-      // select the first theme
-      await popup.select('.m-panel:nth-of-type(1) select', 'a custom theme')
-
-      // advanced
-      await advanced.bringToFront()
-      // expand theme
-      if (!await advanced.evaluate(() => document.querySelector('.m-themes .m-list li:nth-of-type(1)').classList.contains('m-expanded'))) {
-        await advanced.click('.m-themes .m-list li:nth-of-type(1)')
-      }
-    })
-
-    it('update custom theme name', async () => {
-      // update theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-themes .m-option:nth-of-type(1) input').value = 'a very custom theme'
-        document.querySelector('.m-themes .m-option:nth-of-type(1) input').dispatchEvent(new Event('keyup'))
-      })
-      // there is debounce timeout of 750ms in the options UI
-      await advanced.waitFor(800)
-
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-themes .m-list .m-title').innerText
-        ),
-        'a very custom theme',
-        'the custom theme name should be updated in the list title'
-      )
-
-      // reload
-      await advanced.reload()
-      await advanced.waitFor(300)
-
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-themes .m-list .m-title').innerText
-        ),
-        'a very custom theme',
-        'the custom theme name should be updated in the list title'
-      )
-      t.equal(
-        await advanced.evaluate(() =>
-          document.querySelector('.m-themes .m-option:nth-of-type(1) input').value
-        ),
-        'a very custom theme',
-        'the custom theme name should be updated'
-      )
-    })
-
-    it('check popup', async () => {
-      // popup
-      await popup.bringToFront()
-      await popup.reload()
-      // theme tab
-      await popup.click('.m-tabs a:nth-of-type(1)')
-
-      t.equal(
-        await popup.evaluate(() =>
-          document.querySelector('.m-panel:nth-of-type(1) select option').innerText
-        ),
-        'a very custom theme',
-        'the custom theme should be updated'
-      )
-    })
-
-    it('check content', async () => {
-      await content.goto('http://localhost:3000/correct-content-type')
-      await content.bringToFront()
-      await content.waitFor(300)
-      t.ok(
-        /github\.css$/.test(
-          await content.evaluate(() =>
-            document.querySelector('#_theme').getAttribute('href')
-          )
-        ),
-        'defaults to github theme if the custom theme was active'
-      )
-    })
-  })
-
-  describe('remove', () => {
-
-    before(async () => {
-      // advanced
-      await advanced.bringToFront()
-      // add theme
-      await advanced.evaluate(() => {
-        document.querySelector('.m-add-theme [placeholder=Name]').value = 'a custom theme'
-        document.querySelector('.m-add-theme [placeholder=Name]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme [placeholder~=URL]').value = 'file:///hey'
-        document.querySelector('.m-add-theme [placeholder~=URL]').dispatchEvent(new Event('change'))
-        document.querySelector('.m-add-theme button').click()
-      })
-
-      // advanced
-      await advanced.bringToFront()
-      // expand theme
-      if (!await advanced.evaluate(() => document.querySelector('.m-themes .m-list li:nth-of-type(1)').classList.contains('m-expanded'))) {
-        await advanced.click('.m-themes .m-list li:nth-of-type(1)')
-      }
-    })
-
-    it('remove custom theme', async () => {
-      // remove
-      await advanced.evaluate(() => {
-        document.querySelector('.m-themes .m-list button').click()
-      })
-      t.equal(
-        await advanced.evaluate(() => {
-          document.querySelector('.m-themes .m-list')
-        }),
-        null,
-        'should not have any themes'
-      )
-    })
-  })
-
-}

+ 2 - 2
test/defaults-popup.js

@@ -55,10 +55,10 @@ module.exports = ({popup}) => {
   it('tab - theme', async () => {
     t.equal(
       await popup.evaluate(() =>
-        state.theme.name
+        state.theme
       ),
       'github',
-      'state.theme.name should equal github'
+      'state.theme should equal github'
     )
     t.strictEqual(
       await popup.evaluate(() =>

+ 0 - 1
test/index.js

@@ -17,7 +17,6 @@ var tests = [
   'defaults-options',
 
   'popup-options',
-  // 'custom-themes',
 
   'origin-add',
   'origin-match',

+ 2 - 2
test/popup-options.js

@@ -140,10 +140,10 @@ module.exports = ({popup, advanced, content}) => {
 
       t.equal(
         await popup.evaluate(() =>
-          state.theme.name
+          state.theme
         ),
         'github-dark',
-        'state.theme.name should equal github-dark'
+        'state.theme should equal github-dark'
       )
       t.equal(
         await popup.evaluate(() =>