Skip to content

Commit ecb4865

Browse files
authored
Convert popup to React (#27)
* move popup code to its own folder * add React * convert signed out content to React * convert signed in content to React * convert Pemissions Request UI * lock dependency versions * unshadow variable names in Popup.tsx
1 parent d056c57 commit ecb4865

24 files changed

+369
-309
lines changed

.eslintrc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@
332332
],
333333
"@typescript-eslint/no-non-null-assertion": "off",
334334
"@typescript-eslint/no-redundant-type-constituents": "off",
335+
"@typescript-eslint/no-shadow": "warn",
335336
"@typescript-eslint/no-unnecessary-condition": "off",
336337
"@typescript-eslint/no-unnecessary-boolean-literal-compare": "off",
337338
"@typescript-eslint/no-unsafe-argument": "off",

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
18

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib"
3+
}

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,14 @@
4848
"watch:firefox": "yarn run set-manifest:firefox:force && yarn watch"
4949
},
5050
"dependencies": {
51+
"react": "18.2.0",
52+
"react-dom": "18.2.0",
5153
"webextension-polyfill": "0.10.0"
5254
},
5355
"devDependencies": {
54-
"@playwright/test": "^1.35.1",
55-
"@types/chrome": "^0.0.246",
56+
"@playwright/test": "1.35.1",
57+
"@types/chrome": "0.0.246",
58+
"@types/react-dom": "18.2.23",
5659
"@types/webextension-polyfill": "0.10.1",
5760
"@typescript-eslint/eslint-plugin": "6.0.0",
5861
"@typescript-eslint/parser": "6.0.0",

scripts/makeManifest.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ const getMakeManifest =
4646
},
4747
// Delete this in favor of optional_host_permissions when https://bugzilla.mozilla.org/show_bug.cgi?id=1766026
4848
// is resolved
49-
optional_permissions: [
50-
'*://*/*'
51-
]
49+
optional_permissions: ['*://*/*'],
5250
};
5351

5452
const chromiumKeys = {
@@ -57,8 +55,8 @@ const getMakeManifest =
5755
},
5856
optional_host_permissions: [
5957
// TODO: Move this to `manifestBase` when Firefox supports optional_host_permissions
60-
'*://*/*'
61-
]
58+
'*://*/*',
59+
],
6260
};
6361

6462
const manifest = {

src/background.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { WebNavigation } from 'webextension-polyfill';
2-
import { runtime, scripting , tabs, webNavigation } from 'webextension-polyfill';
2+
import { runtime, scripting, tabs, webNavigation } from 'webextension-polyfill';
33
import { fetchUser } from './gkApi';
44
import { injectionScope as inject_azureDevops } from './hosts/azureDevops';
55
import { injectionScope as inject_bitbucket } from './hosts/bitbucket';
@@ -21,7 +21,7 @@ const DefaultInjectionDomains: InjectionDomains = {
2121
github: ['github.com'],
2222
gitlab: ['gitlab.com'],
2323
bitbucket: ['bitbucket.org'],
24-
azureDevops: ['dev.azure.com']
24+
azureDevops: ['dev.azure.com'],
2525
};
2626

2727
webNavigation.onHistoryStateUpdated.addListener(details => {
@@ -35,7 +35,7 @@ webNavigation.onHistoryStateUpdated.addListener(details => {
3535
}
3636
});
3737

38-
runtime.onMessage.addListener(async (msg) => {
38+
runtime.onMessage.addListener(async msg => {
3939
if (msg === PopupInitMessage) {
4040
const context: CacheContext = {};
4141
return refreshPermissions(context);
@@ -79,12 +79,12 @@ async function addInjectionListener(context: CacheContext) {
7979
};
8080

8181
webNavigation.onDOMContentLoaded.addListener(injectScript, {
82-
url: allDomains.map((domain) => ({ hostContains: domain })),
82+
url: allDomains.map(domain => ({ hostContains: domain })),
8383
});
8484
}
8585

8686
function urlHostHasDomain(url: URL, domains: string[]): boolean {
87-
return domains.some((domain) => url.hostname.endsWith(domain));
87+
return domains.some(domain => url.hostname.endsWith(domain));
8888
}
8989

9090
function getInjectionFn(rawUrl: string, injectionDomains: InjectionDomains): (url: string) => void {
@@ -119,6 +119,6 @@ async function main() {
119119
// NOTE: This may request hosts that we may not have permissions for, which will log errors for the extension
120120
// This does not cause any issues, and eliminating the errors requires more logic
121121
await addInjectionListener(context);
122-
};
122+
}
123123

124124
void main();

src/domUtils.ts

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/gkApi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const accessTokenCookieName = MODE === 'production' ? 'accessToken' : 'devAccess
1111

1212
const getAccessToken = async () => {
1313
// Check if the user has granted permission to GitKraken.dev
14-
if (!await checkOrigins(['gitkraken.dev'])) {
14+
if (!(await checkOrigins(['gitkraken.dev']))) {
1515
// If not, just assume we're logged out
1616
return undefined;
1717
}

src/hosts/gitlab.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function injectionScope(url: string) {
2424
this.insertHTML(insertions);
2525
}
2626

27-
/*
27+
/*
2828
** PLEASE READ BEFORE TOUCHING ANY INJECTIONS **
2929
3030
GitLab supports up to two major versions behind the current version. See:
@@ -141,10 +141,8 @@ export function injectionScope(url: string) {
141141
);
142142

143143
// v16.8
144-
insertions.set(
145-
'.git-clone-holder .dropdown-menu .gl-dropdown-item:last-child',
146-
{
147-
html: /*html*/ `<li data-gk class="divider mt-2" role="presentation"></li>
144+
insertions.set('.git-clone-holder .dropdown-menu .gl-dropdown-item:last-child', {
145+
html: /*html*/ `<li data-gk class="divider mt-2" role="presentation"></li>
148146
<li data-gk class="gl-dropdown-item pt-2" role="menuitem">
149147
<label class="label-bold gl-px-4">GitKraken</label>
150148
<a class="dropdown-item open-with-link" href="${url}" style="align-items: center !important;" target="_blank">
@@ -154,9 +152,8 @@ export function injectionScope(url: string) {
154152
</div>
155153
</a>
156154
</li>`,
157-
position: 'afterend',
158-
},
159-
);
155+
position: 'afterend',
156+
});
160157

161158
// Drop this injection when support for <= v16.7 is dropped
162159
insertions.set(

src/permissions-helper.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function domainToMatchPattern(domain: string): string {
99

1010
const RequiredOriginPatterns = [
1111
// Without this permission, the extension cannot login
12-
'gitkraken.dev'
12+
'gitkraken.dev',
1313
].map(domainToMatchPattern);
1414
const CloudProviderOriginPatterns = CloudProviders.map(domainToMatchPattern);
1515

@@ -18,7 +18,7 @@ async function computeEnterpriseOriginPatterns(context: CacheContext): Promise<s
1818
if (!enterpriseConnections) {
1919
return;
2020
}
21-
return enterpriseConnections.map((x) => domainToMatchPattern(x.domain));
21+
return enterpriseConnections.map(x => domainToMatchPattern(x.domain));
2222
}
2323

2424
export type OriginTypes = 'required' | 'cloud' | 'enterprise';
@@ -38,11 +38,15 @@ export async function refreshPermissions(context: CacheContext): Promise<Permiss
3838
const newEnterpriseOrigins = arrayDifference(enterpriseOrigins, exitingPermissions.origins);
3939
const newCloudOrigins = arrayDifference(CloudProviderOriginPatterns, exitingPermissions.origins);
4040
const newOrigins = [...newRequiredOrigins, ...newEnterpriseOrigins, ...newCloudOrigins];
41-
const unusedOrigins = arrayDifference(exitingPermissions.origins, [...RequiredOriginPatterns, ...CloudProviderOriginPatterns, ...(enterpriseOrigins ?? [])]);
41+
const unusedOrigins = arrayDifference(exitingPermissions.origins, [
42+
...RequiredOriginPatterns,
43+
...CloudProviderOriginPatterns,
44+
...(enterpriseOrigins ?? []),
45+
]);
4246

4347
if (!unusedOrigins.length) {
4448
const unusedPermissions: Permissions.Permissions = {
45-
origins: unusedOrigins
49+
origins: unusedOrigins,
4650
};
4751
const result = await permissions.remove(unusedPermissions);
4852
if (!result) {
@@ -51,18 +55,18 @@ export async function refreshPermissions(context: CacheContext): Promise<Permiss
5155
}
5256
return newOrigins.length
5357
? {
54-
request: {
55-
origins: newOrigins,
56-
},
57-
hasRequired: Boolean(newRequiredOrigins.length),
58-
hasCloud: Boolean(newCloudOrigins.length),
59-
hasEnterprise: Boolean(newEnterpriseOrigins.length)
60-
}
58+
request: {
59+
origins: newOrigins,
60+
},
61+
hasRequired: Boolean(newRequiredOrigins.length),
62+
hasCloud: Boolean(newCloudOrigins.length),
63+
hasEnterprise: Boolean(newEnterpriseOrigins.length),
64+
}
6165
: undefined;
6266
}
6367

6468
export async function checkOrigins(origins: string[]): Promise<boolean> {
6569
return permissions.contains({
66-
origins: origins.map(domainToMatchPattern)
70+
origins: origins.map(domainToMatchPattern),
6771
});
6872
}

0 commit comments

Comments
 (0)