Skip to content

Commit eb36ba4

Browse files
GODrumsStep7750
andauthored
Fix: Compatibility issues for Firefox (#287)
* Fixes Support for Setting Net Rules on Firefox Firefox has random IDs, so we have to make a dynamic rule instead. * Add simple permission popup * Restyle popup * Make sure to reload extension * chore: run format * chore: update Chrome types * Update button style for disabled state * Update button text * Adjust offer tracking banner for Firefox * chore: run formatting * Update alert text Co-authored-by: Step7750 <Step7750@gmail.com> * Require optional host permission on Firefox --------- Co-authored-by: Step7750 <step7750@gmail.com>
1 parent b651874 commit eb36ba4

File tree

10 files changed

+187
-15
lines changed

10 files changed

+187
-15
lines changed

package-lock.json

Lines changed: 8 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
},
2727
"homepage": "https://github.com/csfloat/extension#readme",
2828
"devDependencies": {
29-
"@types/chrome": "^0.0.193",
29+
"@types/chrome": "^0.0.300",
3030
"@types/firefox-webext-browser": "^111.0.1",
3131
"@types/jquery": "^3.5.14",
3232
"@types/lodash": "^4.14.195",

src/background.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {alarmListener, registerTradeAlarmIfPossible} from './lib/alarms/setup';
55
import {pingTradeStatus} from './lib/alarms/csfloat_trade_pings';
66
import {gStore} from './lib/storage/store';
77
import {StorageKey} from './lib/storage/keys';
8+
import {isFirefox} from './lib/utils/detect';
89

910
function unifiedHandler(request: any, sender: MessageSender, sendResponse: (response?: any) => void) {
1011
Handle(request, sender)
@@ -24,7 +25,7 @@ function unifiedHandler(request: any, sender: MessageSender, sendResponse: (resp
2425
});
2526
}
2627

27-
function requestPermissions(permissions: string[], origins: string[], sendResponse: any) {
28+
function requestPermissions(permissions: chrome.runtime.ManifestPermissions[], origins: string[], sendResponse: any) {
2829
chrome.permissions.request({permissions, origins}, (granted) => sendResponse(granted));
2930

3031
return true;
@@ -66,3 +67,39 @@ async function checkTradeStatus() {
6667
}
6768
}
6869
checkTradeStatus();
70+
71+
if (isFirefox()) {
72+
// Need to manually update the rule to allow the extension to send trade offers
73+
// Since Firefox IDs are random and we still want to scope it to only this extension
74+
browser.declarativeNetRequest
75+
.updateDynamicRules({
76+
removeRuleIds: [1738196326],
77+
addRules: [
78+
{
79+
id: 1738196326,
80+
priority: 2,
81+
action: {
82+
type: 'modifyHeaders',
83+
requestHeaders: [
84+
{
85+
header: 'referer',
86+
operation: 'set',
87+
value: 'https://steamcommunity.com/tradeoffer/new',
88+
},
89+
],
90+
},
91+
condition: {
92+
urlFilter: 'https://steamcommunity.com/tradeoffer/new/send',
93+
resourceTypes: ['xmlhttprequest'],
94+
initiatorDomains: [new URL(browser.runtime.getURL('')).hostname],
95+
},
96+
},
97+
],
98+
})
99+
.then(() => {
100+
console.log('[INFO] Successfully updated ruleset');
101+
})
102+
.catch((e) => {
103+
console.error('[ERROR] Failed to update ruleset for Firefox');
104+
});
105+
}

src/lib/bridge/handlers/has_permissions.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {SimpleHandler} from './main';
22
import {RequestType} from './types';
33

44
export interface HasPermissionsRequest {
5-
permissions: string[];
5+
permissions: chrome.runtime.ManifestPermissions[];
66
origins: string[];
77
}
88

@@ -13,11 +13,10 @@ export interface HasPermissionsResponse {
1313
export const HasPermissions = new SimpleHandler<HasPermissionsRequest, HasPermissionsResponse>(
1414
RequestType.HAS_PERMISSIONS,
1515
async (req) => {
16-
// @ts-ignore
17-
const granted = (await chrome.permissions.contains({
16+
const granted = await chrome.permissions.contains({
1817
permissions: req.permissions,
1918
origins: req.origins,
20-
})) as boolean;
19+
});
2120

2221
return {
2322
granted,

src/lib/components/common/ui/steam-button.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export class SteamButton extends FloatElement {
1818
@property({type: String})
1919
private type: ButtonType = ButtonType.GreenWhite;
2020

21+
@property({type: Boolean})
22+
private disabled: boolean = false;
23+
2124
static styles = [
2225
...FloatElement.styles,
2326
css`
@@ -102,6 +105,10 @@ export class SteamButton extends FloatElement {
102105
font-size: 12px;
103106
line-height: 20px;
104107
}
108+
109+
.btn_disabled {
110+
cursor: default;
111+
}
105112
`,
106113
];
107114

@@ -112,6 +119,9 @@ export class SteamButton extends FloatElement {
112119
btnClass() {
113120
const r: {[key: string]: boolean} = {btn_small: true};
114121
r[`btn_${this.type}_innerfade`] = true;
122+
if (this.disabled) {
123+
r.btn_disabled = true;
124+
}
115125
return classMap(r);
116126
}
117127

src/lib/components/trade_offers/better_tracking.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {state} from 'lit/decorators.js';
88
import {FetchPendingTrades} from '../../bridge/handlers/fetch_pending_trades';
99
import {HasPermissions} from '../../bridge/handlers/has_permissions';
1010
import {PingSetupExtension} from '../../bridge/handlers/ping_setup_extension';
11+
import {isFirefox} from '../../utils/detect';
1112

1213
@CustomElement()
1314
@InjectAfter(
@@ -18,6 +19,9 @@ export class BetterTrackingWidget extends FloatElement {
1819
@state()
1920
show = false;
2021

22+
@state()
23+
isFirefox = isFirefox();
24+
2125
static styles = [
2226
...FloatElement.styles,
2327
css`
@@ -50,6 +54,14 @@ export class BetterTrackingWidget extends FloatElement {
5054
`,
5155
];
5256

57+
steamButton() {
58+
return {
59+
text: this.isFirefox ? 'Enable in the Extension Popup' : 'Enable',
60+
type: this.isFirefox ? 'grey_white' : 'green_white',
61+
disabled: this.isFirefox,
62+
};
63+
}
64+
5365
async connectedCallback() {
5466
super.connectedCallback();
5567

@@ -92,7 +104,12 @@ export class BetterTrackingWidget extends FloatElement {
92104
<span class="item-name">Setup Offer Tracking on CSFloat</span>
93105
<div class="sale-info">Verify trades while preserving your privacy.</div>
94106
</div>
95-
<csfloat-steam-button id="csfloat-enable-enhanced" .text="${'Enable'}"></csfloat-steam-button>
107+
<csfloat-steam-button
108+
id="csfloat-enable-enhanced"
109+
.text="${this.steamButton().text}"
110+
.type="${this.steamButton().type}"
111+
.disabled=${this.steamButton().disabled}
112+
></csfloat-steam-button>
96113
</div>
97114
`
98115
: html``;

src/lib/page_scripts/trade_offers.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {PingSetupExtension} from '../bridge/handlers/ping_setup_extension';
77
import {PingExtensionStatus} from '../bridge/handlers/ping_extension_status';
88
import {FetchSteamTrades, FetchSteamTradesResponse} from '../bridge/handlers/fetch_steam_trades';
99
import {convertSteamID32To64, getUserSteamID} from '../utils/userinfo';
10+
import {isFirefox} from '../utils/detect';
1011

1112
init('src/lib/page_scripts/trade_offers.js', main);
1213

@@ -112,6 +113,10 @@ if (!inPageContext()) {
112113
}
113114

114115
btn.addEventListener('click', async () => {
116+
if (isFirefox()) {
117+
alert('Please enable the feature in the extension popup in the top right of your browser');
118+
return;
119+
}
115120
chrome.runtime.sendMessage(
116121
{
117122
message: 'requestPermissions',

src/popup/popup.html

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="preconnect" href="https://fonts.googleapis.com" />
6+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
7+
<link
8+
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
9+
rel="stylesheet"
10+
/>
11+
<style>
12+
body {
13+
width: 300px;
14+
padding: 16px;
15+
background-color: #15171c;
16+
}
17+
button {
18+
width: 100%;
19+
padding: 10px;
20+
background-color: rgba(35, 123, 255, 0.15);
21+
color: #237bff;
22+
border: none;
23+
border-radius: 8px;
24+
cursor: pointer;
25+
font-family: 'Roboto', serif;
26+
font-size: 14px;
27+
font-weight: 500;
28+
display: flex;
29+
justify-content: center;
30+
align-items: center;
31+
gap: 8px;
32+
}
33+
button:hover {
34+
background-color: #2a374d;
35+
}
36+
button:disabled {
37+
cursor: not-allowed;
38+
background-color: rgba(255, 255, 255, .12);
39+
color: rgba(255, 255, 255, .5);
40+
}
41+
</style>
42+
</head>
43+
<body>
44+
<button id="requestPermissions">
45+
<svg
46+
xmlns="http://www.w3.org/2000/svg"
47+
width="24"
48+
height="24"
49+
viewBox="0 0 24 24"
50+
fill="none"
51+
stroke="currentColor"
52+
stroke-width="3"
53+
stroke-linecap="round"
54+
stroke-linejoin="round"
55+
>
56+
<path
57+
d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"
58+
/>
59+
<path d="M12 8v4" />
60+
<path d="M12 16h.01" />
61+
</svg>
62+
<span>Enable Offer Tracking</span>
63+
</button>
64+
<script src="popup/popup.js"></script>
65+
</body>
66+
</html>

src/popup/popup.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
window.addEventListener('DOMContentLoaded', async () => {
2+
const requestButton = document.getElementById('requestPermissions');
3+
if (!requestButton) {
4+
return;
5+
}
6+
7+
const hasPermissions = await chrome.permissions.contains({
8+
origins: ['*://*.steampowered.com/*'],
9+
});
10+
11+
if (hasPermissions) {
12+
// If permissions are already granted, disable the button
13+
requestButton.children[1].textContent = 'Offer Tracking Enabled';
14+
requestButton.setAttribute('disabled', 'true');
15+
} else {
16+
requestButton.addEventListener('click', async () => {
17+
try {
18+
const success = await chrome.permissions.request({
19+
origins: ['*://*.steampowered.com/*'],
20+
});
21+
if (success) {
22+
// extension requires reload to apply permissions
23+
browser.runtime.reload();
24+
}
25+
} catch (error) {
26+
console.error('Error requesting permissions:', error);
27+
}
28+
});
29+
}
30+
});

webpack.config.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,16 @@ function getPathEntries(path) {
2121

2222
function convertToFirefoxManifest(manifest) {
2323
const cp = Object.assign({}, manifest);
24+
cp.action = {
25+
default_popup: "src/popup.html"
26+
}
2427
cp.background = {
2528
page: 'src/background_ff.html',
2629
};
2730
cp.browser_specific_settings = {
2831
gecko: {
2932
id: '{194d0dc6-7ada-41c6-88b8-95d7636fe43c}',
30-
strict_min_version: '109.0',
33+
strict_min_version: '127.0',
3134
},
3235
};
3336
// Allow getting the extension version from CSFloat page in Firefox
@@ -36,6 +39,8 @@ function convertToFirefoxManifest(manifest) {
3639
js: ['src/lib/page_scripts/csfloat.js'],
3740
});
3841
cp.host_permissions.push('*://*.csfloat.com/*');
42+
// Force optional host permissions to be required
43+
cp.host_permissions = cp.host_permissions.concat(cp.optional_host_permissions);
3944
return cp;
4045
}
4146

@@ -48,6 +53,7 @@ module.exports = (env) => {
4853
getPathEntries('./src/lib/page_scripts/*.ts'),
4954
getPathEntries('./src/lib/types/*.d.ts'),
5055
getPathEntries('./src/background.ts'),
56+
getPathEntries('./src/popup/popup.ts'),
5157
getPathEntries('./src/**/*.js')
5258
),
5359
output: {
@@ -97,6 +103,7 @@ module.exports = (env) => {
97103
{from: 'src/steamcommunity_ruleset.json', to: 'src/', context: '.'},
98104
{from: 'src', to: 'raw/', context: '.'},
99105
{from: 'README.md', to: '', context: '.'},
106+
{from: 'src/popup/popup.html', to: 'src/', context: '.'},
100107
{
101108
from: 'manifest.json',
102109
to: 'manifest.json',

0 commit comments

Comments
 (0)