Skip to content

Commit ee5708f

Browse files
filiptronicekfelladringtsiolis
authored
Enable . keybind to open repositories in Gitpod (#54)
Co-authored-by: Victor Nogueira <[email protected]> Co-authored-by: George Tsiolis <[email protected]>
1 parent 16f301a commit ee5708f

File tree

7 files changed

+77
-6
lines changed

7 files changed

+77
-6
lines changed

src/config.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { EventEmitter } from "events";
44
export interface Config {
55
gitpodURL: string;
66
openAsPopup: boolean;
7+
rewritePeriodKeybind: boolean;
78
}
89

910
export const DEFAULT_CONFIG: Config = {
1011
gitpodURL: "https://gitpod.io",
11-
openAsPopup: false
12+
openAsPopup: false,
13+
rewritePeriodKeybind: false
1214
};
1315

1416
export interface ConfigListener {

src/injectors/github-injector.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as select from 'select-dom';
22
import * as ghInjection from 'github-injection';
33
import { ConfigProvider } from '../config';
4-
import { ButtonInjector, InjectorBase, checkIsBtnUpToDate } from './injector';
4+
import { ButtonInjector, InjectorBase, checkIsBtnUpToDate, rewritePeriodKeybindGitHub } from './injector';
55
import { renderGitpodUrl, makeOpenInPopup } from '../utils';
66

77
namespace Gitpodify {
@@ -52,6 +52,10 @@ export class GitHubInjector extends InjectorBase {
5252
if (!this.checkIsInjected()) {
5353
this.injectButtons();
5454
}
55+
56+
(async () => {
57+
await rewritePeriodKeybindGitHub();
58+
})();
5559
});
5660
}
5761

src/injectors/gitlab-injector.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as domloaded from 'dom-loaded';
22
import * as select from 'select-dom';
33
import { ConfigProvider } from '../config';
4-
import { ButtonInjector, InjectorBase, checkIsBtnUpToDate } from './injector';
4+
import { ButtonInjector, InjectorBase, checkIsBtnUpToDate, rewritePeriodKeybindGitLab } from './injector';
55
import { renderGitpodUrl, makeOpenInPopup } from '../utils';
66

77
namespace Gitpodify {
@@ -36,8 +36,10 @@ export class GitlabInjector extends InjectorBase {
3636

3737
async inject(): Promise<void> {
3838
await domloaded; // TODO(geropl) This is dead slow, improve.
39-
4039
this.injectButtons(false);
40+
if (this.canHandleCurrentPage() && this.checkIsInjected()) {
41+
await rewritePeriodKeybindGitLab();
42+
}
4143
}
4244

4345
async update(): Promise<void> {

src/injectors/injector.ts

+43
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ConfigProvider } from "../config";
22
import { renderGitpodUrl } from "../utils";
3+
import { isVisible } from "../utils";
34

45
export interface Injector {
56

@@ -67,6 +68,48 @@ export abstract class InjectorBase implements Injector {
6768
}
6869
}
6970

71+
function openInGitpod(e: MouseEvent | KeyboardEvent, inNewTab: boolean) {
72+
const currentUrl = window.location.href;
73+
window.open(`https://gitpod.io/#${currentUrl}`, inNewTab ? '_blank' : '_self');
74+
e.preventDefault();
75+
e.stopPropagation();
76+
}
77+
78+
export async function rewritePeriodKeybindGitHub() {
79+
const configProvider = await ConfigProvider.create();
80+
const config = configProvider.getConfig();
81+
82+
if (config.rewritePeriodKeybind) {
83+
document.querySelectorAll('.js-github-dev-shortcut, .js-github-dev-new-tab-shortcut').forEach((elem) => {
84+
const new_element = elem.cloneNode(true) as HTMLElement;
85+
elem.parentNode?.replaceChild(new_element, elem);
86+
new_element.addEventListener('click', (e) => {
87+
if (new_element && isVisible(new_element) && !confirm('Are you sure you want to open gitpod.io?')) {
88+
return;
89+
}
90+
openInGitpod(e, elem.classList.contains('js-github-dev-new-tab-shortcut') || config.openAsPopup);
91+
});
92+
});
93+
}
94+
}
95+
96+
export async function rewritePeriodKeybindGitLab() {
97+
const configProvider = await ConfigProvider.create();
98+
const config = configProvider.getConfig();
99+
100+
if (config.rewritePeriodKeybind) {
101+
const unbindMousetrapScript = document.createElement('script');
102+
unbindMousetrapScript.innerHTML='window.Mousetrap.unbind(".");';
103+
document.head.appendChild(unbindMousetrapScript);
104+
105+
document.onkeydown = (e: KeyboardEvent) => {
106+
if (e.code === 'Period') {
107+
openInGitpod(e, e.shiftKey || config.openAsPopup);
108+
}
109+
};
110+
}
111+
}
112+
70113
export const checkIsBtnUpToDate = (button: HTMLElement | null, currentUrl: string): boolean => {
71114
return !!button && button instanceof HTMLAnchorElement && button.href === currentUrl;
72115
};

src/options/options.html

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
<label>Open as popup:</label>
1515
<input id="gitpod-open-as-popup" type="checkbox"/>
1616
</div>
17+
<div class="row">
18+
<label>Enable <kbd>.</kbd> keybind to open repositories in Gitpod</label>
19+
<input id="gitpod-replace-keybind" type="checkbox"/>
20+
</div>
1721
<div class="row">
1822
<div style="min-width: 5em;"></div>
1923
<div><a href="https://www.gitpod.io/docs/browser-extension/">https://www.gitpod.io/docs/browser-extension/</a></div>

src/options/options.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ConfigProvider } from "../config";
22

33
const gitpodUrlInput = document.getElementById("gitpod-url-input")! as HTMLInputElement;
4+
const gitpodRewriteKeybind = document.getElementById("gitpod-replace-keybind")! as HTMLInputElement;
45
const gitpodPopupInput = document.getElementById("gitpod-open-as-popup")! as HTMLInputElement;
56
const messageElement = document.getElementById("message")! as HTMLDivElement;
67

@@ -12,6 +13,7 @@ const init = async () => {
1213
const initialConfig = configProvider.getConfig();
1314
gitpodUrlInput.value = initialConfig.gitpodURL;
1415
gitpodPopupInput.checked = initialConfig.openAsPopup;
16+
gitpodRewriteKeybind.checked = initialConfig.rewritePeriodKeybind;
1517

1618
let timeout: number | undefined = undefined;
1719

@@ -20,7 +22,8 @@ const init = async () => {
2022
// Update config (propagated internally)
2123
configProvider.setConfig({
2224
gitpodURL: gitpodUrlInput.value || undefined,
23-
openAsPopup: gitpodPopupInput.checked
25+
openAsPopup: gitpodPopupInput.checked,
26+
rewritePeriodKeybind: gitpodRewriteKeybind.checked
2427
});
2528
if (timeout) {
2629
window.clearTimeout(timeout);
@@ -35,7 +38,7 @@ const init = async () => {
3538
}
3639
save()
3740
});
38-
gitpodPopupInput.addEventListener('change', save);
41+
[gitpodPopupInput, gitpodRewriteKeybind].forEach((el) => el.addEventListener('change', save))
3942
};
4043

4144
init().catch(err => console.error(err));

src/utils.ts

+13
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@ export function renderGitpodUrl(gitpodURL: string): string {
33
return `${gitpodURL}/#${baseURL}` + window.location.pathname + window.location.search;
44
}
55

6+
export function isVisible(el: HTMLElement) {
7+
try {
8+
const rect = el.getBoundingClientRect();
9+
if (rect.height === 0 && rect.width === 0) {
10+
return false;
11+
}
12+
if (el.style.opacity === '0' || el.style.visibility === 'hidden') {
13+
return false;
14+
}
15+
} catch {}
16+
return true;
17+
}
18+
619
export function makeOpenInPopup(a: HTMLAnchorElement): void {
720
a.onclick = () => !window.open(a.href, a.target, 'menubar=no,toolbar=no,location=no,dependent');
821
}

0 commit comments

Comments
 (0)