in src/vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor.ts [239:440]
protected createEditor(parent: HTMLElement): void {
addClass(parent, 'runtime-extensions-editor');
const TEMPLATE_ID = 'runtimeExtensionElementTemplate';
const delegate = new class implements IListVirtualDelegate<IRuntimeExtension>{
getHeight(element: IRuntimeExtension): number {
return 62;
}
getTemplateId(element: IRuntimeExtension): string {
return TEMPLATE_ID;
}
};
interface IRuntimeExtensionTemplateData {
root: HTMLElement;
element: HTMLElement;
name: HTMLElement;
msgContainer: HTMLElement;
actionbar: ActionBar;
activationTime: HTMLElement;
profileTime: HTMLElement;
disposables: IDisposable[];
elementDisposables: IDisposable[];
}
const renderer: IListRenderer<IRuntimeExtension, IRuntimeExtensionTemplateData> = {
templateId: TEMPLATE_ID,
renderTemplate: (root: HTMLElement): IRuntimeExtensionTemplateData => {
const element = append(root, $('.extension'));
const desc = append(element, $('div.desc'));
const name = append(desc, $('div.name'));
const msgContainer = append(desc, $('div.msg'));
const actionbar = new ActionBar(desc, { animated: false });
actionbar.onDidRun(({ error }) => error && this._notificationService.error(error));
const timeContainer = append(element, $('.time'));
const activationTime = append(timeContainer, $('div.activation-time'));
const profileTime = append(timeContainer, $('div.profile-time'));
const disposables = [actionbar];
return {
root,
element,
name,
actionbar,
activationTime,
profileTime,
msgContainer,
disposables,
elementDisposables: []
};
},
renderElement: (element: IRuntimeExtension, index: number, data: IRuntimeExtensionTemplateData): void => {
data.elementDisposables = dispose(data.elementDisposables);
toggleClass(data.root, 'odd', index % 2 === 1);
data.name.textContent = element.marketplaceInfo ? element.marketplaceInfo.displayName : element.description.displayName || '';
const activationTimes = element.status.activationTimes!;
let syncTime = activationTimes.codeLoadingTime + activationTimes.activateCallTime;
data.activationTime.textContent = activationTimes.startup ? `Startup Activation: ${syncTime}ms` : `Activation: ${syncTime}ms`;
data.actionbar.clear();
if (element.unresponsiveProfile) {
data.actionbar.push(this._instantiationService.createInstance(SlowExtensionAction, element.description, element.unresponsiveProfile), { icon: true, label: true });
}
if (isNonEmptyArray(element.status.runtimeErrors)) {
data.actionbar.push(new ReportExtensionIssueAction(element), { icon: true, label: true });
}
let title: string;
if (activationTimes.activationEvent === '*') {
title = nls.localize('starActivation', "Activated on start-up");
} else if (/^workspaceContains:/.test(activationTimes.activationEvent)) {
let fileNameOrGlob = activationTimes.activationEvent.substr('workspaceContains:'.length);
if (fileNameOrGlob.indexOf('*') >= 0 || fileNameOrGlob.indexOf('?') >= 0) {
title = nls.localize({
key: 'workspaceContainsGlobActivation',
comment: [
'{0} will be a glob pattern'
]
}, "Activated because a file matching {0} exists in your workspace", fileNameOrGlob);
} else {
title = nls.localize({
key: 'workspaceContainsFileActivation',
comment: [
'{0} will be a file name'
]
}, "Activated because file {0} exists in your workspace", fileNameOrGlob);
}
} else if (/^workspaceContainsTimeout:/.test(activationTimes.activationEvent)) {
const glob = activationTimes.activationEvent.substr('workspaceContainsTimeout:'.length);
title = nls.localize({
key: 'workspaceContainsTimeout',
comment: [
'{0} will be a glob pattern'
]
}, "Activated because searching for {0} took too long", glob);
} else if (/^onLanguage:/.test(activationTimes.activationEvent)) {
let language = activationTimes.activationEvent.substr('onLanguage:'.length);
title = nls.localize('languageActivation', "Activated because you opened a {0} file", language);
} else {
title = nls.localize({
key: 'workspaceGenericActivation',
comment: [
'The {0} placeholder will be an activation event, like e.g. \'language:typescript\', \'debug\', etc.'
]
}, "Activated on {0}", activationTimes.activationEvent);
}
data.activationTime.title = title;
clearNode(data.msgContainer);
if (this._extensionHostProfileService.getUnresponsiveProfile(element.description.identifier)) {
const el = $('span');
el.innerHTML = renderOcticons(` $(alert) Unresponsive`);
el.title = nls.localize('unresponsive.title', "Extension has caused the extension host to freeze.");
data.msgContainer.appendChild(el);
}
if (isNonEmptyArray(element.status.runtimeErrors)) {
const el = $('span');
el.innerHTML = renderOcticons(`$(bug) ${nls.localize('errors', "{0} uncaught errors", element.status.runtimeErrors.length)}`);
data.msgContainer.appendChild(el);
}
if (element.status.messages && element.status.messages.length > 0) {
const el = $('span');
el.innerHTML = renderOcticons(`$(alert) ${element.status.messages[0].message}`);
data.msgContainer.appendChild(el);
}
if (element.description.extensionLocation.scheme !== 'file') {
const el = $('span');
el.innerHTML = renderOcticons(`$(remote) ${element.description.extensionLocation.authority}`);
data.msgContainer.appendChild(el);
const hostLabel = this._labelService.getHostLabel(REMOTE_HOST_SCHEME, this._environmentService.configuration.remoteAuthority);
if (hostLabel) {
el.innerHTML = renderOcticons(`$(remote) ${hostLabel}`);
}
}
if (this._profileInfo && element.profileInfo) {
data.profileTime.textContent = `Profile: ${(element.profileInfo.totalTime / 1000).toFixed(2)}ms`;
} else {
data.profileTime.textContent = '';
}
},
disposeTemplate: (data: IRuntimeExtensionTemplateData): void => {
data.disposables = dispose(data.disposables);
}
};
this._list = this._instantiationService.createInstance(WorkbenchList, parent, delegate, [renderer], {
multipleSelectionSupport: false,
setRowLineHeight: false,
horizontalScrolling: false
}) as WorkbenchList<IRuntimeExtension>;
this._list.splice(0, this._list.length, this._elements || undefined);
this._list.onContextMenu((e) => {
if (!e.element) {
return;
}
const actions: IAction[] = [];
actions.push(new ReportExtensionIssueAction(e.element));
actions.push(new Separator());
if (e.element.marketplaceInfo) {
actions.push(new Action('runtimeExtensionsEditor.action.disableWorkspace', nls.localize('disable workspace', "Disable (Workspace)"), undefined, true, () => this._extensionsWorkbenchService.setEnablement(e.element!.marketplaceInfo, EnablementState.DisabledWorkspace)));
actions.push(new Action('runtimeExtensionsEditor.action.disable', nls.localize('disable', "Disable"), undefined, true, () => this._extensionsWorkbenchService.setEnablement(e.element!.marketplaceInfo, EnablementState.DisabledGlobally)));
actions.push(new Separator());
}
const state = this._extensionHostProfileService.state;
if (state === ProfileSessionState.Running) {
actions.push(this._instantiationService.createInstance(StopExtensionHostProfileAction, StopExtensionHostProfileAction.ID, StopExtensionHostProfileAction.LABEL));
} else {
actions.push(this._instantiationService.createInstance(StartExtensionHostProfileAction, StartExtensionHostProfileAction.ID, StartExtensionHostProfileAction.LABEL));
}
actions.push(this.saveExtensionHostProfileAction);
this._contextMenuService.showContextMenu({
getAnchor: () => e.anchor,
getActions: () => actions
});
});
}