Skip to content

Commit 6dedad3

Browse files
committed
fix(utils): avoid recursion in browser polyfill
1 parent fcdd28b commit 6dedad3

File tree

1 file changed

+59
-46
lines changed

1 file changed

+59
-46
lines changed

utils/browser-polyfill.js

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,28 @@ const browserAPI = {};
2121
browserAPI.storage = {
2222
sync: {
2323
get: function(keys) {
24-
if (isFirefox) {
25-
return browser.storage.sync.get(keys);
26-
} else {
27-
return new Promise((resolve) => {
28-
chrome.storage.sync.get(keys, resolve);
29-
});
24+
const nativeGet = isFirefox
25+
? nativeBrowser?.storage?.sync?.get
26+
: nativeChrome?.storage?.sync?.get;
27+
if (nativeGet && nativeGet !== browserAPI.storage.sync.get) {
28+
if (isFirefox) {
29+
return nativeGet.call(nativeBrowser.storage.sync, keys);
30+
}
31+
return new Promise(resolve => nativeGet.call(nativeChrome.storage.sync, keys, resolve));
3032
}
33+
return Promise.resolve({});
3134
},
3235
set: function(items) {
33-
if (isFirefox) {
34-
return browser.storage.sync.set(items);
35-
} else {
36-
return new Promise((resolve) => {
37-
chrome.storage.sync.set(items, resolve);
38-
});
36+
const nativeSet = isFirefox
37+
? nativeBrowser?.storage?.sync?.set
38+
: nativeChrome?.storage?.sync?.set;
39+
if (nativeSet && nativeSet !== browserAPI.storage.sync.set) {
40+
if (isFirefox) {
41+
return nativeSet.call(nativeBrowser.storage.sync, items);
42+
}
43+
return new Promise(resolve => nativeSet.call(nativeChrome.storage.sync, items, resolve));
3944
}
45+
return Promise.resolve();
4046
}
4147
}
4248
};
@@ -57,54 +63,61 @@ browserAPI.i18n = {
5763
// Tabs API
5864
browserAPI.tabs = {
5965
query: function(queryInfo) {
60-
if (isFirefox) {
61-
return browser.tabs.query(queryInfo);
62-
} else {
63-
return new Promise((resolve) => {
64-
chrome.tabs.query(queryInfo, resolve);
65-
});
66+
const nativeQuery = isFirefox
67+
? nativeBrowser?.tabs?.query
68+
: nativeChrome?.tabs?.query;
69+
if (nativeQuery && nativeQuery !== browserAPI.tabs.query) {
70+
if (isFirefox) {
71+
return nativeQuery.call(nativeBrowser.tabs, queryInfo);
72+
}
73+
return new Promise(resolve => nativeQuery.call(nativeChrome.tabs, queryInfo, resolve));
6674
}
75+
return Promise.resolve([]);
6776
}
6877
};
6978

7079
// Runtime API
7180
browserAPI.runtime = {
7281
getBrowserInfo: function() {
73-
if (isFirefox && browser.runtime.getBrowserInfo) {
74-
return browser.runtime.getBrowserInfo();
75-
} else {
76-
// Chrome doesn't have getBrowserInfo, so we'll return a basic object
77-
return Promise.resolve({
78-
name: 'Chrome',
79-
vendor: 'Google',
80-
version: navigator.userAgent.match(/Chrome\/([0-9.]+)/)[1] || '',
81-
buildID: ''
82-
});
82+
const nativeGetInfo = nativeBrowser?.runtime?.getBrowserInfo;
83+
if (isFirefox && nativeGetInfo && nativeGetInfo !== browserAPI.runtime.getBrowserInfo) {
84+
return nativeGetInfo.call(nativeBrowser.runtime);
8385
}
86+
// Chrome doesn't have getBrowserInfo, so we'll return a basic object
87+
return Promise.resolve({
88+
name: 'Chrome',
89+
vendor: 'Google',
90+
version: navigator.userAgent.match(/Chrome\/([0-9.]+)/)[1] || '',
91+
buildID: ''
92+
});
8493
},
8594
getPlatformInfo: function() {
86-
if (isFirefox && browser.runtime.getPlatformInfo) {
87-
return browser.runtime.getPlatformInfo();
88-
} else if (chrome.runtime.getPlatformInfo) {
89-
return new Promise((resolve) => {
90-
chrome.runtime.getPlatformInfo(resolve);
91-
});
92-
} else {
93-
// Fallback if neither API is available
94-
return Promise.resolve({
95-
os: navigator.platform,
96-
arch: navigator.userAgent.includes('x64') ? 'x86-64' : 'x86-32'
97-
});
95+
const nativeGetPlatform = isFirefox
96+
? nativeBrowser?.runtime?.getPlatformInfo
97+
: nativeChrome?.runtime?.getPlatformInfo;
98+
if (nativeGetPlatform && nativeGetPlatform !== browserAPI.runtime.getPlatformInfo) {
99+
if (isFirefox) {
100+
return nativeGetPlatform.call(nativeBrowser.runtime);
101+
}
102+
return new Promise(resolve => nativeGetPlatform.call(nativeChrome.runtime, resolve));
98103
}
104+
// Fallback if neither API is available
105+
return Promise.resolve({
106+
os: navigator.platform,
107+
arch: navigator.userAgent.includes('x64') ? 'x86-64' : 'x86-32'
108+
});
99109
},
100110
openOptionsPage: function() {
101-
if (isFirefox) {
102-
return browser.runtime.openOptionsPage();
103-
} else {
104-
return new Promise((resolve) => {
105-
chrome.runtime.openOptionsPage(resolve);
106-
});
111+
const nativeOpen = isFirefox
112+
? nativeBrowser?.runtime?.openOptionsPage
113+
: nativeChrome?.runtime?.openOptionsPage;
114+
if (nativeOpen && nativeOpen !== browserAPI.runtime.openOptionsPage) {
115+
if (isFirefox) {
116+
return nativeOpen.call(nativeBrowser.runtime);
117+
}
118+
return new Promise(resolve => nativeOpen.call(nativeChrome.runtime, resolve));
107119
}
120+
return Promise.resolve();
108121
}
109122
};
110123

0 commit comments

Comments
 (0)