1
- import { IS_CHROME , IS_FIREFOX , isSupportExecutionVersion } from './utils'
2
- const browser = require ( 'webextension-polyfill' )
1
+ import { IS_CHROME , IS_FIREFOX , isSupportExecutionVersion } from '../utils'
2
+ import browser from 'webextension-polyfill'
3
+ import TabsStateService from './TabsStateService'
3
4
4
- const tabsStorage = { }
5
+ const tabsState = new TabsStateService ( )
5
6
6
7
if ( IS_CHROME && isSupportExecutionVersion ) {
7
8
/**
@@ -30,39 +31,75 @@ if (IS_CHROME && isSupportExecutionVersion) {
30
31
)
31
32
}
32
33
33
- browser . tabs . onActivated . addListener ( handleActivated )
34
34
browser . tabs . onUpdated . addListener ( handleUpdated )
35
+ browser . runtime . onStartup . addListener ( ( ) => {
36
+ // clear state on startup.
37
+ // note: chrome allows to use 'browser.storage.session' but it is available in chrome only.
38
+ // for firefox a 'window.session' can be considered as alternative.
39
+ // TODO: create polyfill for session store.
40
+ tabsState . clear ( )
41
+ } )
35
42
36
- function setIcon ( details ) {
43
+ async function setIcon ( details ) {
37
44
// because manifest version is different
38
45
if ( IS_FIREFOX ) {
39
- browser . browserAction . setIcon ( details )
46
+ await browser . browserAction . setIcon ( details )
40
47
} else {
41
- browser . action . setIcon ( details )
48
+ await browser . action . setIcon ( details )
42
49
}
43
50
}
44
51
52
+ const setIconForTab = async ( tabId ) => {
53
+ const tabs = await tabsState . get ( )
54
+ const tab = tabs [ tabId ] ;
55
+ if ( tab ?. framework ?. slug ) {
56
+ const slug = tab . framework . slug
57
+ const iconPath = `icons/${ slug } .png`
58
+ try {
59
+ await setIcon ( { tabId, path : iconPath } ) ;
60
+ } catch ( e ) {
61
+ await setIcon ( {
62
+ tabId,
63
+ path : 'icons/icon-128.png'
64
+ } )
65
+ }
66
+ } else {
67
+ await setIcon ( {
68
+ tabId,
69
+ path : tab ?. hasVue ? 'icons/icon-128.png' : 'icons/icon-grey-128.png'
70
+ } )
71
+ }
72
+ }
73
+
74
+ browser . storage . local . onChanged . addListener ( async ( payload ) => {
75
+ if ( payload . settings ) {
76
+ const tabs = await browser . tabs . query ( { } ) ;
77
+ tabs . forEach ( tab => {
78
+ if ( tab . id ) {
79
+ setIconForTab ( tab . id )
80
+ }
81
+ } )
82
+ }
83
+ } )
84
+
45
85
browser . runtime . onMessage . addListener (
46
86
async function ( message , sender , sendResponse ) {
47
87
if ( message . action === 'analyze' ) {
48
88
// when sending message from popup.js there's no sender.tab, so need to pass tabId
49
89
const tabId = ( sender . tab && sender . tab . id ) || message . payload . tabId
50
- setIcon ( {
51
- tabId : tabId ,
52
- path : message . payload . hasVue ? 'icons/icon-128.png' : 'icons/icon-grey-128.png'
53
- } )
54
90
55
- if ( ! tabsStorage [ tabId ] ) {
56
- tabsStorage [ tabId ] = message . payload
91
+ const tabs = await tabsState . get ( )
92
+ if ( ! tabs [ tabId ] ) {
93
+ tabs [ tabId ] = message . payload
57
94
} else {
58
95
// temporary fix when hit CSP
59
96
if ( ! message . payload . modules . length ) delete message . payload . modules
60
97
if ( ! message . payload . plugins . length ) delete message . payload . plugins
61
98
62
- tabsStorage [ tabId ] = { ...tabsStorage [ tabId ] , ...message . payload }
99
+ tabs [ tabId ] = { ...tabs [ tabId ] , ...message . payload }
63
100
}
64
101
65
- const showcase = tabsStorage [ tabId ]
102
+ const showcase = tabs [ tabId ]
66
103
if ( showcase . hasVue && ! showcase . slug ) {
67
104
try {
68
105
if ( typeof EventSource === 'undefined' ) {
@@ -72,7 +109,7 @@ browser.runtime.onMessage.addListener(
72
109
const sse = new EventSource (
73
110
`https://service.vuetelescope.com?url=${ message . payload . url } `
74
111
)
75
- sse . addEventListener ( 'message' , ( event ) => {
112
+ sse . addEventListener ( 'message' , async ( event ) => {
76
113
try {
77
114
const res = JSON . parse ( event . data )
78
115
if ( ! res . error && ! res . isAdultContent ) {
@@ -87,6 +124,7 @@ browser.runtime.onMessage.addListener(
87
124
if ( ! showcase . plugins . length && res . plugins . length ) {
88
125
showcase . plugins = res . plugins
89
126
}
127
+ await tabsState . updateData ( tabId , tabs [ tabId ] )
90
128
} else {
91
129
throw new Error ( 'API call to VT failed' )
92
130
}
@@ -96,48 +134,28 @@ browser.runtime.onMessage.addListener(
96
134
} )
97
135
} catch ( err ) { }
98
136
}
99
- // tabsStorage[tabId] = message.payload
137
+ await tabsState . updateData ( tabId , tabs [ tabId ] )
138
+ await setIconForTab ( tabId ) ;
100
139
} else if ( ! sender . tab ) {
101
140
if ( message . action === 'getShowcase' ) {
102
- // this is likely popup requesting
103
- // sendResponse doesn't work in Firefox 👀
104
- // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage#Sending_a_synchronous_response
105
- return Promise . resolve ( { payload : tabsStorage [ message . payload . tabId ] } )
106
- // sendResponse({ payload: tabsStorage[message.payload.tabId] })
141
+ const tabs = await tabsState . get ( )
142
+ return { payload : tabs [ message . payload . tabId ] }
107
143
}
108
144
}
109
145
}
110
146
)
111
147
112
- // when tab clicked
113
- async function handleActivated ( { tabId, windowId } ) {
114
- setIcon ( {
115
- tabId,
116
- path : tabsStorage [ tabId ] && tabsStorage [ tabId ] && tabsStorage [ tabId ] . hasVue ? 'icons/icon-128.png' : 'icons/icon-grey-128.png'
117
- } )
118
- // chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
119
- // const { id, url, status } = tabs[0]
120
- // if (status === 'complete') {
121
- // // tabsStorage[id].url = url
122
- // }
123
- // })
124
- }
125
-
126
148
// when tab updated
127
149
async function handleUpdated ( tabId , changeInfo , tabInfo ) {
128
150
if ( changeInfo . status === 'complete' ) {
129
- if ( ! tabsStorage [ tabId ] ) return
151
+ const tabs = await tabsState . get ( )
152
+ if ( ! tabs [ tabId ] ) return
130
153
// tabsStorage[tabId].url = tabInfo.url
131
154
browser . tabs . sendMessage ( tabId , {
132
155
from : 'background' ,
133
156
to : 'injected' ,
134
157
action : 'analyze' ,
135
158
payload : { }
136
159
} )
137
- // chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
138
- // // send message to content script
139
- // chrome.tabs.sendMessage(tabs[0].id, { from: 'background', to: 'injected', payload: { message: 'hello from background with sendMessage' } })
140
- // })
141
- // console.log('tabsStorage', tabsStorage)
142
160
}
143
161
}
0 commit comments