提交 04706345 编写于 作者: J Johannes Rieken

Merge branch 'master' into joh/playwright

...@@ -17,6 +17,16 @@ ...@@ -17,6 +17,16 @@
"value": "# Preparation", "value": "# Preparation",
"editable": true "editable": true
}, },
{
"kind": 1,
"language": "markdown",
"value": "## Open Pull Requests on the Milestone"
},
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE is:pr is:open"
},
{ {
"kind": 1, "kind": 1,
"language": "markdown", "language": "markdown",
......
...@@ -17,6 +17,16 @@ ...@@ -17,6 +17,16 @@
"value": "# Preparation", "value": "# Preparation",
"editable": true "editable": true
}, },
{
"kind": 1,
"language": "markdown",
"value": "## Open Pull Requests on the Milestone"
},
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE $MINE is:pr is:open"
},
{ {
"kind": 1, "kind": 1,
"language": "markdown", "language": "markdown",
......
...@@ -197,7 +197,7 @@ suite('Comparers', () => { ...@@ -197,7 +197,7 @@ suite('Comparers', () => {
// name-only comparisons // name-only comparisons
assert(compareFileNamesDefault('a', 'A') === compareLocale('a', 'A'), 'the same letter sorts by locale'); assert(compareFileNamesDefault('a', 'A') === compareLocale('a', 'A'), 'the same letter sorts by locale');
assert(compareFileNamesDefault('â', 'Â') === compareLocale('â', 'Â'), 'the same accented letter sorts by locale'); assert(compareFileNamesDefault('â', 'Â') === compareLocale('â', 'Â'), 'the same accented letter sorts by locale');
assert.deepEqual(['artichoke', 'Artichoke', 'art', 'Art'].sort(compareFileNamesDefault), ['artichoke', 'Artichoke', 'art', 'Art'].sort(compareLocale), 'words with the same root and different cases sort in locale order'); // assert.deepEqual(['artichoke', 'Artichoke', 'art', 'Art'].sort(compareFileNamesDefault), ['artichoke', 'Artichoke', 'art', 'Art'].sort(compareLocale), 'words with the same root and different cases sort in locale order');
assert.deepEqual(['email', 'Email', 'émail', 'Émail'].sort(compareFileNamesDefault), ['email', 'Email', 'émail', 'Émail'].sort(compareLocale), 'the same base characters with different case or accents sort in locale order'); assert.deepEqual(['email', 'Email', 'émail', 'Émail'].sort(compareFileNamesDefault), ['email', 'Email', 'émail', 'Émail'].sort(compareLocale), 'the same base characters with different case or accents sort in locale order');
// numeric comparisons // numeric comparisons
...@@ -259,7 +259,7 @@ suite('Comparers', () => { ...@@ -259,7 +259,7 @@ suite('Comparers', () => {
// name-only comparisons // name-only comparisons
assert(compareFileExtensionsDefault('a', 'A') === compareLocale('a', 'A'), 'the same letter of different case sorts by locale'); assert(compareFileExtensionsDefault('a', 'A') === compareLocale('a', 'A'), 'the same letter of different case sorts by locale');
assert(compareFileExtensionsDefault('â', 'Â') === compareLocale('â', 'Â'), 'the same accented letter of different case sorts by locale'); assert(compareFileExtensionsDefault('â', 'Â') === compareLocale('â', 'Â'), 'the same accented letter of different case sorts by locale');
assert.deepEqual(['artichoke', 'Artichoke', 'art', 'Art'].sort(compareFileExtensionsDefault), ['artichoke', 'Artichoke', 'art', 'Art'].sort(compareLocale), 'words with the same root and different cases sort in locale order'); // assert.deepEqual(['artichoke', 'Artichoke', 'art', 'Art'].sort(compareFileExtensionsDefault), ['artichoke', 'Artichoke', 'art', 'Art'].sort(compareLocale), 'words with the same root and different cases sort in locale order');
assert.deepEqual(['email', 'Email', 'émail', 'Émail'].sort(compareFileExtensionsDefault), ['email', 'Email', 'émail', 'Émail'].sort((a, b) => a.localeCompare(b)), 'the same base characters with different case or accents sort in locale order'); assert.deepEqual(['email', 'Email', 'émail', 'Émail'].sort(compareFileExtensionsDefault), ['email', 'Email', 'émail', 'Émail'].sort((a, b) => a.localeCompare(b)), 'the same base characters with different case or accents sort in locale order');
// name plus extension comparisons // name plus extension comparisons
......
...@@ -107,17 +107,17 @@ export class ForwardedPortsView extends Disposable implements IWorkbenchContribu ...@@ -107,17 +107,17 @@ export class ForwardedPortsView extends Disposable implements IWorkbenchContribu
let tooltip: string; let tooltip: string;
const count = this.remoteExplorerService.tunnelModel.forwarded.size + this.remoteExplorerService.tunnelModel.detected.size; const count = this.remoteExplorerService.tunnelModel.forwarded.size + this.remoteExplorerService.tunnelModel.detected.size;
if (count === 0) { if (count === 0) {
text = nls.localize('remote.forwardedPorts.statusbarTextNone', "No Ports Available"); text = nls.localize('remote.forwardedPorts.statusbarTextNone', "No Ports Forwarded");
tooltip = text; tooltip = text;
} else { } else {
if (count === 1) { if (count === 1) {
text = nls.localize('remote.forwardedPorts.statusbarTextSingle', "1 Port Available"); text = nls.localize('remote.forwardedPorts.statusbarTextSingle', "1 Port Forwarded");
} else { } else {
text = nls.localize('remote.forwardedPorts.statusbarTextMultiple', "{0} Ports Available", count); text = nls.localize('remote.forwardedPorts.statusbarTextMultiple', "{0} Ports Forwarded", count);
} }
const allTunnels = Array.from(this.remoteExplorerService.tunnelModel.forwarded.values()); const allTunnels = Array.from(this.remoteExplorerService.tunnelModel.forwarded.values());
allTunnels.push(...Array.from(this.remoteExplorerService.tunnelModel.detected.values())); allTunnels.push(...Array.from(this.remoteExplorerService.tunnelModel.detected.values()));
tooltip = nls.localize('remote.forwardedPorts.statusbarTooltip', "Available Ports: {0}", tooltip = nls.localize('remote.forwardedPorts.statusbarTooltip', "Forwarded Ports: {0}",
allTunnels.map(forwarded => forwarded.remotePort).join(', ')); allTunnels.map(forwarded => forwarded.remotePort).join(', '));
} }
return { return {
...@@ -187,7 +187,7 @@ class ForwardedPortNotifier extends Disposable { ...@@ -187,7 +187,7 @@ class ForwardedPortNotifier extends Disposable {
tunnels = tunnels.sort((a, b) => a.tunnelRemotePort - b.tunnelRemotePort); tunnels = tunnels.sort((a, b) => a.tunnelRemotePort - b.tunnelRemotePort);
const firstTunnel = tunnels.shift()!; const firstTunnel = tunnels.shift()!;
const address = makeAddress(firstTunnel.tunnelRemoteHost, firstTunnel.tunnelRemotePort); const address = makeAddress(firstTunnel.tunnelRemoteHost, firstTunnel.tunnelRemotePort);
const message = nls.localize('remote.tunnelsView.automaticForward', "Your service running on port {0} is available. [See all available ports](command:{1}.focus)", const message = nls.localize('remote.tunnelsView.automaticForward', "Your service running on port {0} is available. [See all forwarded ports](command:{1}.focus)",
firstTunnel.tunnelRemotePort, TunnelPanel.ID); firstTunnel.tunnelRemotePort, TunnelPanel.ID);
const browserChoice: IPromptChoice = { const browserChoice: IPromptChoice = {
label: OpenPortInBrowserAction.LABEL, label: OpenPortInBrowserAction.LABEL,
......
...@@ -85,7 +85,8 @@ export class TunnelViewModel extends Disposable implements ITunnelViewModel { ...@@ -85,7 +85,8 @@ export class TunnelViewModel extends Disposable implements ITunnelViewModel {
tunnelType: TunnelType.Add, tunnelType: TunnelType.Add,
remoteHost: 'localhost', remoteHost: 'localhost',
remotePort: 0, remotePort: 0,
description: '' description: '',
iconClasses: undefined
}; };
} }
...@@ -176,6 +177,7 @@ interface ITunnelTemplateData { ...@@ -176,6 +177,7 @@ interface ITunnelTemplateData {
elementDisposable: IDisposable; elementDisposable: IDisposable;
container: HTMLElement; container: HTMLElement;
iconLabel: IconLabel; iconLabel: IconLabel;
icon: HTMLElement;
actionBar: ActionBar; actionBar: ActionBar;
} }
...@@ -208,6 +210,7 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou ...@@ -208,6 +210,7 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
renderTemplate(container: HTMLElement): ITunnelTemplateData { renderTemplate(container: HTMLElement): ITunnelTemplateData {
container.classList.add('custom-view-tree-node-item'); container.classList.add('custom-view-tree-node-item');
const icon = dom.append(container, dom.$('.custom-view-tree-node-item-icon'));
const iconLabel = new IconLabel(container, { supportHighlights: true }); const iconLabel = new IconLabel(container, { supportHighlights: true });
// dom.addClass(iconLabel.element, 'tunnel-view-label'); // dom.addClass(iconLabel.element, 'tunnel-view-label');
const actionsContainer = dom.append(iconLabel.element, dom.$('.actions')); const actionsContainer = dom.append(iconLabel.element, dom.$('.actions'));
...@@ -223,7 +226,7 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou ...@@ -223,7 +226,7 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
} }
}); });
return { iconLabel, actionBar, container, elementDisposable: Disposable.None }; return { icon, iconLabel, actionBar, container, elementDisposable: Disposable.None };
} }
private isTunnelItem(item: ITunnelGroup | ITunnelItem): item is ITunnelItem { private isTunnelItem(item: ITunnelGroup | ITunnelItem): item is ITunnelItem {
...@@ -236,6 +239,9 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou ...@@ -236,6 +239,9 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
// reset // reset
templateData.actionBar.clear(); templateData.actionBar.clear();
templateData.icon.className = 'custom-view-tree-node-item-icon';
templateData.icon.hidden = true;
let editableData: IEditableData | undefined; let editableData: IEditableData | undefined;
if (this.isTunnelItem(node)) { if (this.isTunnelItem(node)) {
editableData = this.remoteExplorerService.getEditableData(node); editableData = this.remoteExplorerService.getEditableData(node);
...@@ -258,6 +264,7 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou ...@@ -258,6 +264,7 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
private renderTunnel(node: ITunnelItem, templateData: ITunnelTemplateData) { private renderTunnel(node: ITunnelItem, templateData: ITunnelTemplateData) {
const label = node.label + (node.description ? (' - ' + node.description) : ''); const label = node.label + (node.description ? (' - ' + node.description) : '');
templateData.iconLabel.setLabel(node.label, node.description, { title: label, extraClasses: ['tunnel-view-label'] }); templateData.iconLabel.setLabel(node.label, node.description, { title: label, extraClasses: ['tunnel-view-label'] });
templateData.actionBar.context = node; templateData.actionBar.context = node;
const contextKeyService = this._register(this.contextKeyService.createScoped()); const contextKeyService = this._register(this.contextKeyService.createScoped());
contextKeyService.createKey('view', this.viewId); contextKeyService.createKey('view', this.viewId);
...@@ -274,6 +281,13 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou ...@@ -274,6 +281,13 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
templateData.actionBar.actionRunner = this._actionRunner; templateData.actionBar.actionRunner = this._actionRunner;
} }
} }
if (node.iconClasses) {
templateData.icon.className = `custom-view-tree-node-item-icon ${node.iconClasses}`;
templateData.icon.hidden = false;
} else {
templateData.icon.className = 'custom-view-tree-node-item-icon';
templateData.icon.hidden = true;
}
} }
private renderInputBox(container: HTMLElement, editableData: IEditableData): IDisposable { private renderInputBox(container: HTMLElement, editableData: IEditableData): IDisposable {
...@@ -456,6 +470,10 @@ class TunnelItem implements ITunnelItem { ...@@ -456,6 +470,10 @@ class TunnelItem implements ITunnelItem {
return undefined; return undefined;
} }
get iconClasses(): string | undefined {
return this.tunnelType === TunnelType.Detected || this.tunnelType === TunnelType.Forwarded ? Codicon.plug.classNames : undefined;
}
} }
export const TunnelTypeContextKey = new RawContextKey<TunnelType>('tunnelType', TunnelType.Add); export const TunnelTypeContextKey = new RawContextKey<TunnelType>('tunnelType', TunnelType.Add);
......
...@@ -36,6 +36,7 @@ export interface ITunnelItem { ...@@ -36,6 +36,7 @@ export interface ITunnelItem {
name?: string; name?: string;
closeable?: boolean; closeable?: boolean;
description?: string; description?: string;
readonly iconClasses?: string;
readonly label: string; readonly label: string;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册