Skip to content

Commit fed50bb

Browse files
committed
Support GitLab
1 parent afcf34a commit fed50bb

File tree

1 file changed

+102
-19
lines changed

1 file changed

+102
-19
lines changed

src/injectors/gitlab-injector.ts

Lines changed: 102 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@ import * as domloaded from 'dom-loaded';
22
import * as select from 'select-dom';
33
import { ConfigProvider } from '../config';
44
import { ButtonInjector, InjectorBase, checkIsBtnUpToDate, rewritePeriodKeybindGitLab } from './injector';
5-
import { renderGitpodUrl, makeOpenInPopup, UrlInfo } from '../utils';
5+
import { renderGitpodUrl, makeOpenInPopup, UrlInfo, renderGitpodCustomEditor, createElementFromHTML, ideOptions } from '../utils';
6+
import { IDEOptions } from '@gitpod/gitpod-protocol/lib/ide-protocol';
67

78
namespace Gitpodify {
89
export const BTN_ID = "gitpod-btn-nav";
910
export const BTN_CLASS = "gitpod-nav-btn";
1011
}
1112

13+
14+
const DropdownID = "gitpod-dropdown"
15+
const DropdownTriggerID = "gitpod-dropdown-trigger"
16+
1217
export class GitlabInjector extends InjectorBase {
1318

1419
constructor(protected readonly configProvider: ConfigProvider) {
@@ -49,6 +54,7 @@ export class GitlabInjector extends InjectorBase {
4954

5055
class RepositoryInjector implements ButtonInjector {
5156
static readonly PARENT_SELECTOR = ".tree-controls";
57+
protected showDropdown: boolean = false;
5258

5359
isApplicableToCurrentPage(): boolean {
5460
const result = !!select.exists(RepositoryInjector.PARENT_SELECTOR)
@@ -71,8 +77,9 @@ class RepositoryInjector implements ButtonInjector {
7177
return;
7278
}
7379

74-
const btn = this.renderButton(currentUrl, openAsPopup);
80+
const btn = this.renderButton(urlInfo, openAsPopup, useLatest);
7581
parent.firstElementChild.appendChild(btn);
82+
this.bindDropdown()
7683

7784
const primaryButtons = parent.firstElementChild.getElementsByClassName("btn-primary");
7885
if (primaryButtons && primaryButtons.length > 1) {
@@ -85,27 +92,103 @@ class RepositoryInjector implements ButtonInjector {
8592
}
8693
}
8794

88-
protected renderButton(url: string, openAsPopup: boolean): HTMLElement {
89-
const container = document.createElement('div');
90-
container.className = "project-clone-holder d-none d-md-inline-block";
95+
genOptionsString(ideOptions: IDEOptions, urlInfo: UrlInfo, useLatest: boolean) {
96+
if (!ideOptions.clients) {
97+
return []
98+
}
99+
return Object.entries(ideOptions.options ?? {}).map(([ide, ideOption]) => {
100+
const url = renderGitpodCustomEditor(urlInfo.host, urlInfo.originUrl, ide, useLatest);
101+
const title = ideOption.title + (ideOption.type === "desktop" ? "" : (" - " + ideOption.type.toUpperCase()));
102+
const logo = ideOption.logo
103+
return `<li role="presentation" class="gl-new-dropdown-item"><button data-qa-selector="webide_menu_item"
104+
data-testid="action_webide" role="menuitem" type="button" class="dropdown-item">
105+
<img class="gl-icon s16 gl-new-dropdown-item-check-icon gl-mt-3 gl-align-self-start" height="14" width="14" class="octicon octicon-check select-menu-item-icon" src="${logo}" alt="logo">
106+
<a class="dropdown-item dropdown-item open-with-link" style="padding: 0;" href="${url}">
107+
<div class="gl-new-dropdown-item-text-wrapper">
108+
<p class="gl-new-dropdown-item-text-primary"><span
109+
class="gl-font-weight-bold">${title}</span></p>
110+
</div>
111+
</a>
112+
</button></li>`
113+
})
114+
}
91115

92-
const container2ndLevel = document.createElement('div');
93-
container2ndLevel.className = "git-clone-holder js-git-clone-holder";
116+
bindDropdown() {
117+
const element = document.querySelector('#' + DropdownTriggerID) as HTMLButtonElement
118+
if (element == null) {
119+
return
120+
}
121+
element.onblur = () => { this.triggerDropdown() }
122+
element.onfocus = () => { this.triggerDropdown() }
123+
}
94124

95-
const a = document.createElement('a');
96-
a.id = Gitpodify.BTN_ID;
97-
a.title = "Gitpod";
98-
a.text = "Gitpod"
99-
a.href = url;
100-
a.target = "_blank";
101-
a.className = "gl-button btn btn-info";
125+
triggerDropdown() {
126+
const element = document.querySelector('#' + DropdownID)
127+
const show = !element?.classList.contains("show")
128+
if (show) {
129+
element?.classList.add("show")
130+
} else {
131+
element?.classList.remove("show")
132+
}
133+
this.showDropdown = show
134+
}
135+
136+
protected renderButton(urlInfo: UrlInfo, openAsPopup: boolean, useLatest: boolean) {
137+
const element = createElementFromHTML(`
138+
<div class="dropdown b-dropdown gl-new-dropdown btn-group" data-qa-selector="action_dropdown" id="GP_DROPDOWN">
139+
<a id="GP_DROPDOWN__BV_button_" type="button" href="${urlInfo.gitpodUrl}"
140+
class="btn btn-default btn-md gl-button split-content-button btn-default-secondary">
141+
<span
142+
data-qa-selector="gitpod_button" class="gl-new-dropdown-button-text">
143+
Gitpod
144+
</span>
145+
</a>
146+
<button id="${DropdownTriggerID}" aria-haspopup="true" aria-expanded="true" type="button"
147+
class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-secondary dropdown-toggle-split"
148+
id="GP_DROPDOWN__BV_toggle_">
149+
<span class="sr-only">Toggle dropdown</span>
150+
</button>
151+
<ul id="${DropdownID}" role="menu" tabindex="-1" class="dropdown-menu" aria-labelledby="GP_DROPDOWN__BV_button_"
152+
style="position: absolute; transform: translate3d(-144px, 32px, 0px); top: 0px; left: 0px; will-change: transform;"
153+
x-placement="bottom-start">
154+
<div class="gl-new-dropdown-inner">
155+
<label class="px-2 label-bold">Open with</label>
156+
<div class="gl-new-dropdown-contents">
157+
${this.genOptionsString(ideOptions, urlInfo, useLatest).join("\n")}
158+
</div>
159+
</div>
160+
</ul>
161+
</div>`)
102162

103163
if (openAsPopup) {
104-
makeOpenInPopup(a);
164+
element.querySelectorAll('a').forEach(e => {
165+
makeOpenInPopup(e);
166+
});
105167
}
106-
107-
container2ndLevel.appendChild(a);
108-
container.appendChild(container2ndLevel);
109-
return container;
168+
return element
110169
}
170+
171+
// protected renderButton(url: string, openAsPopup: boolean): HTMLElement {
172+
// const container = document.createElement('div');
173+
// container.className = "project-clone-holder d-none d-md-inline-block";
174+
175+
// const container2ndLevel = document.createElement('div');
176+
// container2ndLevel.className = "git-clone-holder js-git-clone-holder";
177+
178+
// const a = document.createElement('a');
179+
// a.id = Gitpodify.BTN_ID;
180+
// a.title = "Gitpod";
181+
// a.text = "Gitpod"
182+
// a.href = url;
183+
// a.target = "_blank";
184+
// a.className = "gl-button btn btn-info";
185+
186+
// if (openAsPopup) {
187+
// makeOpenInPopup(a);
188+
// }
189+
190+
// container2ndLevel.appendChild(a);
191+
// container.appendChild(container2ndLevel);
192+
// return container;
193+
// }
111194
}

0 commit comments

Comments
 (0)