Skip to content

Commit 9f90941

Browse files
committed
fix: send extra message and error occur & migrate
1 parent 88400f6 commit 9f90941

14 files changed

+114
-63
lines changed

src/background.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import migrate from './common/migrate'
88
import boss from './common/service/boss'
99
import listManager from './common/listManager'
1010
import browser from 'webextension-polyfill'
11+
import {sendMessage} from './common/utils'
1112

1213
/* eslint-disable-next-line */
1314
if (DEBUG && !MOZ) import(
@@ -27,6 +28,10 @@ if (DEBUG) {
2728
window.listManager = listManager
2829
window.boss = boss
2930
browser.browserAction.setBadgeText({text: 'dev'})
31+
import(
32+
/* webpackChunkName: "helper", webpackMode: "lazy" */
33+
'@/common/helper'
34+
).then(helper => { window.helper = helper })
3035
}
3136

3237
const getBrowserActionHandler = action => {
@@ -225,7 +230,7 @@ const init = async () => {
225230
Object.assign(window.opts, changes)
226231
if (changes.browserAction) updateBrowserAction(changes.browserAction)
227232
if (['pageContext', 'allContext', 'disableDynamicMenu'].some(k => k in changes)) await setupContextMenus(changes)
228-
await browser.runtime.sendMessage({optionsChangeHandledStatus: 'success'})
233+
await sendMessage({optionsChangeHandledStatus: 'success'})
229234
if (PRODUCTION) Object.keys(changes).map(key => ga('send', 'event', 'Options changed', key, changes[key]))
230235
}
231236
if (msg.restoreList) {

src/common/helper.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import browser from 'webextension-polyfill'
2+
3+
export const clearStorage = () => browser.storage.local.get()
4+
.then(Object.keys).then(browser.storage.local.remove)

src/common/listManager.js

+8-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
REMOVE_LIST_BY_ID,
1010
CHANGE_LIST_ORDER,
1111
} from './constants'
12-
import {isBackground} from './utils'
12+
import {isBackground, sendMessage} from './utils'
1313

1414
const cache = { lists: null, ops: null }
1515
let _readingStorage = false
@@ -75,7 +75,7 @@ const saveStorage = _.debounce(async () => {
7575
cache.ops = compressOps(cache.ops)
7676
await browser.storage.local.set(cache)
7777
cache.lists = cache.ops = null
78-
await browser.runtime.sendMessage({refresh: true})
78+
await sendMessage({refresh: true})
7979
}, 5000)
8080
const manager = {}
8181
// lists modifier (return true if need to add ops)
@@ -136,10 +136,10 @@ const genMethods = isBackground => {
136136
manager[method] = isBackground ? async (...args) => { // for background
137137
console.debug('[list manager] modify list:', method, ...args)
138138
await applyChangesToStorage(method, args)
139-
await browser.runtime.sendMessage({listModifed: {method, args}, from: END_BACKGROUND})
139+
await sendMessage({listModifed: {method, args}, from: END_BACKGROUND})
140140
} : async (...args) => { // for front end
141141
console.debug('[list manager] call to modify list:', name, ...args)
142-
await browser.runtime.sendMessage({listModifed: {method, args}, from: END_FRONT})
142+
await sendMessage({listModifed: {method, args}, from: END_FRONT})
143143
}
144144
})
145145
}
@@ -150,22 +150,19 @@ manager.init = async () => {
150150
if (_isBackground) await addEventListener(END_FRONT, applyChangesToStorage)
151151
genMethods(_isBackground)
152152
}
153-
const receiver = []
154-
manager.receiveBackgroundModified = async lists => {
155-
if (receiver.includes(lists)) return
156-
receiver.push(lists)
157-
await addEventListener(END_BACKGROUND, (method, args) => manager.modifiers[method](lists, args))
158-
}
159153
manager.mapMutations = () => {
160154
const mutations = {}
161155
Object.entries(manager.modifiers).forEach(([method, fn]) => {
162156
mutations[method] = (state, payload) => fn(state.lists, payload)
163157
})
158+
mutations.receiveData = (state, {method, args}) => {
159+
manager.modifiers[method](state.lists, args)
160+
}
164161
return mutations
165162
}
166163
manager.createVuexPlugin = () => store => {
167164
addEventListener(END_BACKGROUND, (method, args) => {
168-
store.commit(method, args)
165+
store.commit('receiveData', {method, args})
169166
})
170167
browser.runtime.onMessage.addListener(({refreshed}) => {
171168
if (refreshed && refreshed.success) store.dispatch('getLists')

src/common/migrate.js

+35-21
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,47 @@
11
import _ from 'lodash'
22
import {normalizeList} from './list'
3-
import options from './options'
4-
import {genObjectId} from './utils'
3+
import logger from './logger'
4+
import {genObjectId, compareVersion} from './utils'
55
import listManager from './listManager'
66
import browser from 'webextension-polyfill'
77
listManager.init()
8-
const migrate = async () => {
9-
const {version} = await browser.storage.local.get('version')
10-
const {version: currentVersion} = browser.runtime.getManifest()
11-
if (version !== currentVersion) await browser.storage.local.set({version: currentVersion})
12-
if (version >= '1.4.0') return
13-
// every list need an ID
14-
const {lists} = await browser.storage.local.get('lists')
15-
if (lists) {
16-
const {0: listsWithoutId, 1: listsWithId} = _.groupBy(lists.map(normalizeList), list => +!!list._id)
17-
if (listsWithId) await browser.storage.local.set({lists: listsWithId})
188

19-
for (const list of listsWithoutId.reverse()) {
20-
list._id = genObjectId()
21-
await listManager.addList(list)
9+
const migrations = {
10+
'1.4.0': async () => {
11+
// every list need an ID
12+
const {lists} = await browser.storage.local.get('lists')
13+
if (lists) {
14+
const {0: listsWithoutId, 1: listsWithId} = _.groupBy(lists.map(normalizeList), list => +!!list._id)
15+
if (listsWithId) await browser.storage.local.set({lists: listsWithId})
16+
17+
for (const list of listsWithoutId.reverse()) {
18+
list._id = genObjectId()
19+
await listManager.addList(list)
20+
}
2221
}
22+
// remove deprecated storage keys
23+
await browser.storage.local.remove(['conflict'])
2324
}
24-
// remove depracated options
25-
const {opts} = await browser.storage.local.get('opts')
26-
if (opts) {
27-
await browser.storage.local.set({opts: _.pick(opts, _.keys(options.getDefaultOptions()))})
25+
}
26+
27+
const migrate = async () => {
28+
const {version: dataVersion} = await browser.storage.local.get('version')
29+
const {version: currentVersion} = browser.runtime.getManifest()
30+
if (dataVersion === currentVersion) return
31+
const sorted = Object.keys(migrations).sort(compareVersion)
32+
for (const v of sorted) {
33+
if (compareVersion(currentVersion, v) > 0) continue
34+
try {
35+
console.debug('[migrate] migrating:', v)
36+
await migrations[v]()
37+
await browser.storage.local.set({version: v})
38+
console.debug('[migrate] migrated to:', v)
39+
} catch (err) {
40+
logger.error('[migrate] migrate failed')
41+
logger.error(err)
42+
throw err
43+
}
2844
}
29-
// remove deprecated storage keys
30-
await browser.storage.local.remove(['conflict'])
3145
}
3246

3347
export default migrate

src/common/options.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ if (DEBUG) {
293293
window.printOptionsMap = () => console.debug(availableOptionsList.map(i => i.name + ': ' + i.type.name + ',').join('\n'))
294294
}
295295

296-
297-
const getDefaultOptions = () => _.mapValues(_.keyBy(availableOptionsList, 'name'), i => i.default)
296+
const _defaultOptions = _.mapValues(_.keyBy(availableOptionsList, 'name'), i => i.default)
297+
const getDefaultOptions = () => _defaultOptions
298298

299299
export default {getDefaultOptions, optionsList: availableOptionsList}

src/common/service/boss.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
import _ from 'lodash'
99
import storage from '../storage'
1010
import listManager from '../listManager'
11-
import {isBackground, timeout} from '../utils'
11+
import {isBackground, timeout, sendMessage} from '../utils'
1212
import browser from 'webextension-polyfill'
1313
import io from 'socket.io-client'
1414
import logger from '../logger'
@@ -202,13 +202,13 @@ const refresh = async () => {
202202
if (_refreshing || !(await hasToken())) return
203203

204204
_refreshing = true
205-
await browser.runtime.sendMessage({refreshing: true})
205+
await sendMessage({refreshing: true})
206206
try {
207207
await timeout(Promise.all([syncOptions(), syncLists()]), 20000)
208-
await browser.runtime.sendMessage({refreshed: {success: true}})
208+
await sendMessage({refreshed: {success: true}})
209209
} catch (err) {
210210
logger.error(err)
211-
await browser.runtime.sendMessage({refreshed: {success: false}})
211+
await sendMessage({refreshed: {success: false}})
212212
} finally {
213213
_refreshing = false
214214
}
@@ -218,7 +218,7 @@ const login = async token => {
218218
if (await hasToken()) return
219219
await setToken(token)
220220
const {uid} = await getInfo()
221-
browser.runtime.sendMessage({logged: {uid}})
221+
await sendMessage({logged: {uid}})
222222
const loginNotificationId = 'login'
223223
browser.notifications.create(loginNotificationId, {
224224
type: 'basic',

src/common/storage.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import _ from 'lodash'
22
import {normalizeList} from '@/common/list'
33
import browser from 'webextension-polyfill'
4+
import options from './options'
45

56
const get = key => browser.storage.local.get(key)
67

@@ -24,7 +25,10 @@ const setLists = async lists => {
2425
const getOptions = () => get('opts')
2526
.then(({opts}) => opts)
2627

27-
const setOptions = opts => set({opts, optsUpdatedAt: Date.now()})
28+
const setOptions = opts => set({
29+
opts: _.pick(opts, _.keys(options.getDefaultOptions())),
30+
optsUpdatedAt: Date.now(),
31+
})
2832

2933
export default {
3034
getLists,

src/common/utils.js

+21
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,24 @@ export const timeout = (promise, ms) => Promise.race([
6464
reject(new Error('promise timeout'))
6565
}, ms))
6666
])
67+
68+
export const compareVersion = (a, b) => {
69+
if (a === b) return 0
70+
const [ap, bp] = [a, b].map(i => i || '0').map(i => i.split('.').map(j => +j))
71+
const len = Math.min(ap.length, bp.length)
72+
for (let i = 0; i < len; i += 1) {
73+
if (ap[i] !== bp[i]) return ap[i] - bp[i]
74+
}
75+
return ap.length - bp.length
76+
}
77+
78+
export const sendMessage = async msg => {
79+
try {
80+
await browser.runtime.sendMessage(msg)
81+
} catch (err) {
82+
if (err.message === 'Could not establish connection. Receiving end does not exist.') {
83+
return console.warn('error ignored', err.message)
84+
}
85+
throw err
86+
}
87+
}

src/component/main/Drawer.vue

+9-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
{{ __('ui_export_import') }}
5858
</v-list-tile-content>
5959
</v-list-tile>
60-
<v-list-tile @click="openShortcutPage" :disabled="isFirefox">
60+
<v-list-tile @click="openShortcutPage" :disabled="isLowFirefox">
6161
<v-list-tile-action>
6262
<v-icon>keyboard</v-icon>
6363
</v-list-tile-action>
@@ -104,6 +104,7 @@ export default {
104104
data() {
105105
return {
106106
isFirefox: false,
107+
isLowFirefox: false,
107108
}
108109
},
109110
computed: {
@@ -120,15 +121,19 @@ export default {
120121
__,
121122
async init() {
122123
try {
123-
const {name} = await browser.runtime.getBrowserInfo()
124-
if (name === 'Firefox') this.isFirefox = true
124+
const {name, version} = await browser.runtime.getBrowserInfo()
125+
if (name === 'Firefox') {
126+
this.isFirefox = true
127+
if (version < '66') this.isLowFirefox = true
128+
}
125129
} catch (e) {
126130
// ignored
127131
}
128132
this.preloadLists()
129133
},
130134
async openShortcutPage() {
131-
await browser.tabs.create({url: 'chrome://extensions/shortcuts'})
135+
if (this.isFirefox) await browser.tabs.create({url: 'about:addons'})
136+
else await browser.tabs.create({url: 'chrome://extensions/shortcuts'})
132137
},
133138
}
134139
}

src/component/main/Toolbar.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import dynamicTime from '@/component/DynamicTime'
2929
import browser from 'webextension-polyfill'
3030
import {SYNC_SERVICE_URL} from '@/common/constants'
3131
import {mapState, mapActions, mapMutations} from 'vuex'
32+
import {sendMessage} from '@/common/utils'
3233
3334
export default {
3435
data() {
@@ -88,7 +89,7 @@ export default {
8889
syncBtnClicked() {
8990
if (this.uploadSuccess) return
9091
if (!this.hasToken) return browser.tabs.create({url: SYNC_SERVICE_URL + '/login'})
91-
return browser.runtime.sendMessage({refresh: true})
92+
return sendMessage({refresh: true})
9293
},
9394
}
9495
}

src/content.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import browser from 'webextension-polyfill'
21
import {SYNC_SERVICE_URL} from './common/constants'
2+
import {sendMessage} from './common/utils'
3+
34
console.debug('content_script loaded')
45
const main = async () => {
56
if (!document.URL.startsWith(SYNC_SERVICE_URL)) return
67
const token = localStorage._BOSS_TOKEN
78
console.debug('token', token)
89
if (!token) return
9-
await browser.runtime.sendMessage({login: {token}})
10+
await sendMessage({login: {token}})
1011
}
1112

1213
main()

src/page/Popup.vue

+7-9
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
<script>
4747
import __ from '@/common/i18n'
4848
import storage from '@/common/storage'
49-
import {formatTime} from '@/common/utils'
49+
import {formatTime, sendMessage} from '@/common/utils'
5050
import browser from 'webextension-polyfill'
5151
5252
export default {
@@ -88,17 +88,15 @@ export default {
8888
this.processed = true
8989
},
9090
clicked(index) {
91-
if (['restore', 'restore-new-window'].includes(this.action)) {
92-
chrome.runtime.sendMessage({restoreList: {
93-
index,
94-
newWindow: this.action === 'restore-new-window',
95-
}})
96-
} else return
91+
if (!['restore', 'restore-new-window'].includes(this.action)) return
9792
98-
if (!this.lists[index].pinned) this.lists.splice(index, 1)
93+
sendMessage({restoreList: {
94+
index,
95+
newWindow: this.action === 'restore-new-window',
96+
}})
9997
},
10098
storeInto(index) {
101-
browser.runtime.sendMessage({storeInto: {index}})
99+
sendMessage({storeInto: {index}})
102100
},
103101
}
104102
}

src/page/main/DetailList.vue

+5-4
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ export default {
382382
},
383383
watch: {
384384
// '$route.query.p': 'updateExpandStatus',
385-
'listsToDisplay': 'updateExpandStatus',
385+
listsToDisplay: 'updateExpandStatus',
386386
// '$route.params.tag': 'setTagInView'
387387
},
388388
computed: {
@@ -460,10 +460,11 @@ export default {
460460
},
461461
async updateExpandStatus() {
462462
await this.$nextTick()
463-
if (this.opts.disableExpansion)
464-
this.expandStatus = this.listsToDisplay.map(_ => true)
465-
else
463+
if (this.opts.disableExpansion) {
464+
this.expandStatus = this.listsToDisplay.map(() => true)
465+
} else {
466466
this.expandStatus = this.getExpandStatus()
467+
}
467468
},
468469
openTab(listIndex, tabIndex) {
469470
tabs.openTab(this.lists[listIndex].tabs[tabIndex])

src/page/main/Options.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ import options from '@/common/options'
9999
import __ from '@/common/i18n'
100100
import _ from 'lodash'
101101
import browser from 'webextension-polyfill'
102-
import {formatTime} from '@/common/utils'
102+
import {formatTime, sendMessage} from '@/common/utils'
103103
import {mapState, mapMutations} from 'vuex'
104104
105105
const currentVersion = browser.runtime.getManifest().version
@@ -131,7 +131,7 @@ export default {
131131
await storage.setOptions(this.opts) // eslint-disable-line
132132
await storage.setOptions(this.opts) // eslint-disable-line
133133
console.log(2)
134-
chrome.runtime.sendMessage({optionsChanged: {[key]: value}})
134+
await sendMessage({optionsChanged: {[key]: value}})
135135
}, 100),
136136
optionsChanged(key, value) {
137137
this.setOption({[key]: value})

0 commit comments

Comments
 (0)