Set settings directly from the release notes (#204832)
* Set settings directly from the release notes Fixes #204338 * Fix buildpull/205024/head
parent
7ff2572a3e
commit
69fd227084
|
@ -62,6 +62,10 @@
|
|||
"name": "vs/workbench/contrib/mappedEdits",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/markdown",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/comments",
|
||||
"project": "vscode-workbench"
|
||||
|
|
|
@ -111,6 +111,11 @@ export namespace Schemas {
|
|||
* Scheme used for the Source Control commit input's text document
|
||||
*/
|
||||
export const vscodeSourceControl = 'vscode-scm';
|
||||
|
||||
/**
|
||||
* Scheme used for special rendering of settings in the release notes
|
||||
*/
|
||||
export const codeSetting = 'code-setting';
|
||||
}
|
||||
|
||||
export function matchesScheme(target: URI | string, scheme: string): boolean {
|
||||
|
|
|
@ -13,6 +13,7 @@ import { ILanguageService } from 'vs/editor/common/languages/language';
|
|||
import { tokenizeToString } from 'vs/editor/common/languages/textToHtmlTokenizer';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { SimpleSettingRenderer } from 'vs/workbench/contrib/markdown/browser/markdownSettingRenderer';
|
||||
|
||||
export const DEFAULT_MARKDOWN_STYLES = `
|
||||
body {
|
||||
|
@ -195,6 +196,7 @@ export async function renderMarkdownDocument(
|
|||
shouldSanitize: boolean = true,
|
||||
allowUnknownProtocols: boolean = false,
|
||||
token?: CancellationToken,
|
||||
settingRenderer?: SimpleSettingRenderer
|
||||
): Promise<string> {
|
||||
|
||||
const highlight = (code: string, lang: string | undefined, callback: ((error: any, code: string) => void) | undefined): any => {
|
||||
|
@ -220,8 +222,13 @@ export async function renderMarkdownDocument(
|
|||
return '';
|
||||
};
|
||||
|
||||
const renderer = new marked.Renderer();
|
||||
if (settingRenderer) {
|
||||
renderer.html = settingRenderer.getHtmlRenderer();
|
||||
}
|
||||
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
marked(text, { highlight }, (err, value) => err ? reject(err) : resolve(value));
|
||||
marked(text, { highlight, renderer }, (err, value) => err ? reject(err) : resolve(value));
|
||||
}).then(raw => {
|
||||
if (shouldSanitize) {
|
||||
return sanitize(raw, allowUnknownProtocols);
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { settingKeyToDisplayFormat } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { DefaultSettings } from 'vs/workbench/services/preferences/common/preferencesModels';
|
||||
|
||||
const codeSettingRegex = /^<span codesetting="([^\s"\:]+)(?::([^\s"]+))?">/;
|
||||
|
||||
export class SimpleSettingRenderer {
|
||||
private defaultSettings: DefaultSettings;
|
||||
private updatedSettings = new Map<string, any>(); // setting ID to user's original setting value
|
||||
private encounteredSettings = new Map<string, ISetting>(); // setting ID to setting
|
||||
|
||||
constructor(
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
this.defaultSettings = new DefaultSettings([], ConfigurationTarget.USER);
|
||||
}
|
||||
|
||||
getHtmlRenderer(): (html: string) => string {
|
||||
return (html): string => {
|
||||
const match = codeSettingRegex.exec(html);
|
||||
if (match && match.length === 3) {
|
||||
const settingId = match[1];
|
||||
const rendered = this.render(settingId, match[2]);
|
||||
if (rendered) {
|
||||
html = html.replace(codeSettingRegex, rendered);
|
||||
}
|
||||
}
|
||||
return html;
|
||||
};
|
||||
}
|
||||
|
||||
private settingsGroups: ISettingsGroup[] | undefined = undefined;
|
||||
private getSetting(settingId: string): ISetting | undefined {
|
||||
if (!this.settingsGroups) {
|
||||
this.settingsGroups = this.defaultSettings.getSettingsGroups();
|
||||
}
|
||||
if (this.encounteredSettings.has(settingId)) {
|
||||
return this.encounteredSettings.get(settingId);
|
||||
}
|
||||
for (const group of this.settingsGroups) {
|
||||
for (const section of group.sections) {
|
||||
for (const setting of section.settings) {
|
||||
if (setting.key === settingId) {
|
||||
this.encounteredSettings.set(settingId, setting);
|
||||
return setting;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
parseValue(settingId: string, value: string): any {
|
||||
if (value === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
const setting = this.getSetting(settingId);
|
||||
if (!setting) {
|
||||
return value;
|
||||
}
|
||||
|
||||
switch (setting.type) {
|
||||
case 'boolean':
|
||||
return value === 'true';
|
||||
case 'number':
|
||||
return parseInt(value, 10);
|
||||
case 'string':
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private render(settingId: string, newValue: string): string | undefined {
|
||||
const setting = this.getSetting(settingId);
|
||||
if (!setting) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return this.renderSetting(setting, newValue);
|
||||
}
|
||||
|
||||
private viewInSettings(settingId: string, alreadySet: boolean): string {
|
||||
let message: string;
|
||||
if (alreadySet) {
|
||||
const displayName = settingKeyToDisplayFormat(settingId);
|
||||
message = nls.localize('viewInSettingsDetailed', "View \"{0}: {1}\" in Settings", displayName.category, displayName.label);
|
||||
} else {
|
||||
message = nls.localize('viewInSettings', "View in Settings");
|
||||
}
|
||||
return `<a href="${URI.parse(`command:workbench.action.openSettings?${encodeURIComponent(JSON.stringify([`@id:${settingId}`]))}`)}">${message}</a>`;
|
||||
}
|
||||
|
||||
private renderRestorePreviousSetting(settingId: string): string {
|
||||
const displayName = settingKeyToDisplayFormat(settingId);
|
||||
const value = this.updatedSettings.get(settingId);
|
||||
const message = nls.localize('restorePreviousValue', "Restore value of \"{0}: {1}\"", displayName.category, displayName.label);
|
||||
return `<a href="${Schemas.codeSetting}://${settingId}/${value}">${message}</a>`;
|
||||
}
|
||||
|
||||
private renderBooleanSetting(setting: ISetting, value: string): string | undefined {
|
||||
const booleanValue: boolean = value === 'true' ? true : false;
|
||||
const currentValue = this.configurationService.getValue<boolean>(setting.key);
|
||||
if (currentValue === booleanValue || (currentValue === undefined && setting.value === booleanValue)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const displayName = settingKeyToDisplayFormat(setting.key);
|
||||
let message: string;
|
||||
if (booleanValue) {
|
||||
message = nls.localize('trueMessage', "Enable \"{0}: {1}\" now", displayName.category, displayName.label);
|
||||
} else {
|
||||
message = nls.localize('falseMessage', "Disable \"{0}: {1}\" now", displayName.category, displayName.label);
|
||||
}
|
||||
return `<a href="${Schemas.codeSetting}://${setting.key}/${value}">${message}</a>`;
|
||||
}
|
||||
|
||||
private renderStringSetting(setting: ISetting, value: string): string | undefined {
|
||||
const currentValue = this.configurationService.getValue<string>(setting.key);
|
||||
if (currentValue === value || (currentValue === undefined && setting.value === value)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const displayName = settingKeyToDisplayFormat(setting.key);
|
||||
const message = nls.localize('stringValue', "Set \"{0}: {1}\" to \"{2}\" now", displayName.category, displayName.label, value);
|
||||
return `<a href="${Schemas.codeSetting}://${setting.key}/${value}">${message}</a>`;
|
||||
}
|
||||
|
||||
private renderNumberSetting(setting: ISetting, value: string): string | undefined {
|
||||
const numberValue: number = parseInt(value, 10);
|
||||
const currentValue = this.configurationService.getValue<number>(setting.key);
|
||||
if (currentValue === numberValue || (currentValue === undefined && setting.value === numberValue)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const displayName = settingKeyToDisplayFormat(setting.key);
|
||||
const message = nls.localize('numberValue', "Set \"{0}: {1}\" to {2} now", displayName.category, displayName.label, numberValue);
|
||||
return `<a href="${Schemas.codeSetting}://${setting.key}/${value}">${message}</a>`;
|
||||
|
||||
}
|
||||
|
||||
private renderSetting(setting: ISetting, newValue: string | undefined): string | undefined {
|
||||
let renderedSetting: string | undefined;
|
||||
|
||||
if (newValue !== undefined) {
|
||||
if (this.updatedSettings.has(setting.key)) {
|
||||
renderedSetting = this.renderRestorePreviousSetting(setting.key);
|
||||
} else if (setting.type === 'boolean') {
|
||||
renderedSetting = this.renderBooleanSetting(setting, newValue);
|
||||
} else if (setting.type === 'string') {
|
||||
renderedSetting = this.renderStringSetting(setting, newValue);
|
||||
} else if (setting.type === 'number') {
|
||||
renderedSetting = this.renderNumberSetting(setting, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!renderedSetting) {
|
||||
return `(${this.viewInSettings(setting.key, true)})`;
|
||||
}
|
||||
|
||||
return nls.localize({ key: 'fullRenderedSetting', comment: ['A pair of already localized links. The first argument is a link to change a setting, the second is a link to view the setting.'] },
|
||||
"({0} | {1})", renderedSetting, this.viewInSettings(setting.key, false),);
|
||||
}
|
||||
|
||||
async updateSettingValue(uri: URI) {
|
||||
if (uri.scheme !== Schemas.codeSetting) {
|
||||
return;
|
||||
}
|
||||
const settingId = uri.authority;
|
||||
const newSettingValue = this.parseValue(uri.authority, uri.path.substring(1));
|
||||
const oldSettingValue = this.configurationService.inspect(settingId).userValue;
|
||||
if (newSettingValue === this.updatedSettings.get(settingId)) {
|
||||
this.updatedSettings.delete(settingId);
|
||||
} else {
|
||||
this.updatedSettings.set(settingId, oldSettingValue);
|
||||
}
|
||||
await this.configurationService.updateValue(settingId, newSettingValue, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SimpleSettingRenderer } from 'vs/workbench/contrib/markdown/browser/markdownSettingRenderer';
|
||||
|
||||
const configuration: IConfigurationNode = {
|
||||
'id': 'examples',
|
||||
'title': 'Examples',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'example.booleanSetting': {
|
||||
'type': 'boolean',
|
||||
'default': false,
|
||||
'scope': ConfigurationScope.APPLICATION
|
||||
},
|
||||
'example.booleanSetting2': {
|
||||
'type': 'boolean',
|
||||
'default': true,
|
||||
'scope': ConfigurationScope.APPLICATION
|
||||
},
|
||||
'example.stringSetting': {
|
||||
'type': 'string',
|
||||
'default': 'one',
|
||||
'scope': ConfigurationScope.APPLICATION
|
||||
},
|
||||
'example.numberSetting': {
|
||||
'type': 'number',
|
||||
'default': 3,
|
||||
'scope': ConfigurationScope.APPLICATION
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class MarkdownConfigurationService extends TestConfigurationService {
|
||||
override async updateValue(key: string, value: any): Promise<void> {
|
||||
const [section, setting] = key.split('.');
|
||||
return this.setUserConfiguration(section, { [setting]: value });
|
||||
}
|
||||
}
|
||||
|
||||
suite('Markdown Setting Renderer Test', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
let configurationService: TestConfigurationService;
|
||||
let settingRenderer: SimpleSettingRenderer;
|
||||
|
||||
suiteSetup(() => {
|
||||
configurationService = new MarkdownConfigurationService();
|
||||
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration(configuration);
|
||||
settingRenderer = new SimpleSettingRenderer(configurationService);
|
||||
});
|
||||
|
||||
suiteTeardown(() => {
|
||||
Registry.as<IConfigurationRegistry>(Extensions.Configuration).deregisterConfigurations([configuration]);
|
||||
});
|
||||
|
||||
test('render boolean setting', () => {
|
||||
const htmlRenderer = settingRenderer.getHtmlRenderer();
|
||||
const htmlNoValue = '<span codesetting="example.booleanSetting">';
|
||||
const renderedHtmlNoValue = htmlRenderer(htmlNoValue);
|
||||
assert.equal(renderedHtmlNoValue,
|
||||
`(<a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.booleanSetting%22%5D">View "Example: Boolean Setting" in Settings</a>)`);
|
||||
|
||||
const htmlWithValue = '<span codesetting="example.booleanSetting:true">';
|
||||
const renderedHtmlWithValue = htmlRenderer(htmlWithValue);
|
||||
assert.equal(renderedHtmlWithValue,
|
||||
`(<a href="code-setting://example.booleanSetting/true">Enable "Example: Boolean Setting" now</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.booleanSetting%22%5D">View in Settings</a>)`);
|
||||
|
||||
const htmlWithValueSetToFalse = '<span codesetting="example.booleanSetting2:false">';
|
||||
const renderedHtmlWithValueSetToFalse = htmlRenderer(htmlWithValueSetToFalse);
|
||||
assert.equal(renderedHtmlWithValueSetToFalse,
|
||||
`(<a href="code-setting://example.booleanSetting2/false">Disable "Example: Boolean Setting2" now</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.booleanSetting2%22%5D">View in Settings</a>)`);
|
||||
|
||||
const htmlSameValue = '<span codesetting="example.booleanSetting:false">';
|
||||
const renderedHtmlSameValue = htmlRenderer(htmlSameValue);
|
||||
assert.equal(renderedHtmlSameValue,
|
||||
`(<a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.booleanSetting%22%5D">View "Example: Boolean Setting" in Settings</a>)`);
|
||||
});
|
||||
|
||||
test('render string setting', () => {
|
||||
const htmlRenderer = settingRenderer.getHtmlRenderer();
|
||||
const htmlNoValue = '<span codesetting="example.stringSetting">';
|
||||
const renderedHtmlNoValue = htmlRenderer(htmlNoValue);
|
||||
assert.equal(renderedHtmlNoValue,
|
||||
`(<a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.stringSetting%22%5D">View "Example: String Setting" in Settings</a>)`);
|
||||
|
||||
const htmlWithValue = '<span codesetting="example.stringSetting:two">';
|
||||
const renderedHtmlWithValue = htmlRenderer(htmlWithValue);
|
||||
assert.equal(renderedHtmlWithValue,
|
||||
`(<a href="code-setting://example.stringSetting/two">Set "Example: String Setting" to "two" now</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.stringSetting%22%5D">View in Settings</a>)`);
|
||||
|
||||
const htmlSameValue = '<span codesetting="example.stringSetting:one">';
|
||||
const renderedHtmlSameValue = htmlRenderer(htmlSameValue);
|
||||
assert.equal(renderedHtmlSameValue,
|
||||
`(<a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.stringSetting%22%5D">View "Example: String Setting" in Settings</a>)`);
|
||||
});
|
||||
|
||||
test('render number setting', () => {
|
||||
const htmlRenderer = settingRenderer.getHtmlRenderer();
|
||||
const htmlNoValue = '<span codesetting="example.numberSetting">';
|
||||
const renderedHtmlNoValue = htmlRenderer(htmlNoValue);
|
||||
assert.equal(renderedHtmlNoValue,
|
||||
`(<a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.numberSetting%22%5D">View "Example: Number Setting" in Settings</a>)`);
|
||||
|
||||
const htmlWithValue = '<span codesetting="example.numberSetting:2">';
|
||||
const renderedHtmlWithValue = htmlRenderer(htmlWithValue);
|
||||
assert.equal(renderedHtmlWithValue,
|
||||
`(<a href="code-setting://example.numberSetting/2">Set "Example: Number Setting" to 2 now</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.numberSetting%22%5D">View in Settings</a>)`);
|
||||
|
||||
const htmlSameValue = '<span codesetting="example.numberSetting:3">';
|
||||
const renderedHtmlSameValue = htmlRenderer(htmlSameValue);
|
||||
assert.equal(renderedHtmlSameValue,
|
||||
`(<a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.numberSetting%22%5D">View "Example: Number Setting" in Settings</a>)`);
|
||||
});
|
||||
|
||||
test('updating and restoring the setting through the renderer changes what is rendered', async () => {
|
||||
await configurationService.setUserConfiguration('example', { stringSetting: 'two' });
|
||||
const htmlRenderer = settingRenderer.getHtmlRenderer();
|
||||
const htmlWithValue = '<span codesetting="example.stringSetting:three">';
|
||||
const renderedHtmlWithValue = htmlRenderer(htmlWithValue);
|
||||
assert.equal(renderedHtmlWithValue,
|
||||
`(<a href="code-setting://example.stringSetting/three">Set "Example: String Setting" to "three" now</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.stringSetting%22%5D">View in Settings</a>)`);
|
||||
assert.equal(configurationService.getValue('example.stringSetting'), 'two');
|
||||
|
||||
// Update the value
|
||||
await settingRenderer.updateSettingValue(URI.parse(`${Schemas.codeSetting}://example.stringSetting/three`));
|
||||
assert.equal(configurationService.getValue('example.stringSetting'), 'three');
|
||||
const renderedHtmlWithValueAfterUpdate = htmlRenderer(htmlWithValue);
|
||||
assert.equal(renderedHtmlWithValueAfterUpdate,
|
||||
`(<a href="code-setting://example.stringSetting/two">Restore value of "Example: String Setting"</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.stringSetting%22%5D">View in Settings</a>)`);
|
||||
|
||||
// Restore the value
|
||||
await settingRenderer.updateSettingValue(URI.parse(`${Schemas.codeSetting}://example.stringSetting/two`));
|
||||
assert.equal(configurationService.getValue('example.stringSetting'), 'two');
|
||||
const renderedHtmlWithValueAfterRestore = htmlRenderer(htmlWithValue);
|
||||
assert.equal(renderedHtmlWithValueAfterRestore,
|
||||
`(<a href="code-setting://example.stringSetting/three">Set "Example: String Setting" to "three" now</a> | <a href="command:workbench.action.openSettings?%5B%22%40id%3Aexample.stringSetting%22%5D">View in Settings</a>)`);
|
||||
});
|
||||
});
|
|
@ -30,10 +30,14 @@ import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/comm
|
|||
import { IConfigurationChangeEvent, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { SimpleSettingRenderer } from 'vs/workbench/contrib/markdown/browser/markdownSettingRenderer';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
export class ReleaseNotesManager {
|
||||
|
||||
private readonly _simpleSettingRenderer: SimpleSettingRenderer;
|
||||
private readonly _releaseNotesCache = new Map<string, Promise<string>>();
|
||||
private scrollPosition: { x: number; y: number } | undefined;
|
||||
|
||||
private _currentReleaseNotes: WebviewInput | undefined = undefined;
|
||||
private _lastText: string | undefined;
|
||||
|
@ -50,20 +54,28 @@ export class ReleaseNotesManager {
|
|||
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
|
||||
@IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService,
|
||||
@IExtensionService private readonly _extensionService: IExtensionService,
|
||||
@IProductService private readonly _productService: IProductService
|
||||
@IProductService private readonly _productService: IProductService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
TokenizationRegistry.onDidChange(async () => {
|
||||
if (!this._currentReleaseNotes || !this._lastText) {
|
||||
return;
|
||||
}
|
||||
const html = await this.renderBody(this._lastText);
|
||||
if (this._currentReleaseNotes) {
|
||||
this._currentReleaseNotes.webview.setHtml(html);
|
||||
}
|
||||
TokenizationRegistry.onDidChange(() => {
|
||||
return this.updateHtml();
|
||||
});
|
||||
|
||||
_configurationService.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
|
||||
_webviewWorkbenchService.onDidChangeActiveWebviewEditor(this.onDidChangeActiveWebviewEditor, this, this.disposables);
|
||||
this._simpleSettingRenderer = this._instantiationService.createInstance(SimpleSettingRenderer);
|
||||
}
|
||||
|
||||
private async updateHtml() {
|
||||
if (!this._currentReleaseNotes || !this._lastText) {
|
||||
return;
|
||||
}
|
||||
const captureScroll = this.scrollPosition;
|
||||
const html = await this.renderBody(this._lastText);
|
||||
if (this._currentReleaseNotes) {
|
||||
this._currentReleaseNotes.webview.setHtml(html);
|
||||
this._currentReleaseNotes.webview.postMessage({ type: 'setScroll', value: { scrollPosition: captureScroll } });
|
||||
}
|
||||
}
|
||||
|
||||
public async show(version: string): Promise<boolean> {
|
||||
|
@ -102,6 +114,8 @@ export class ReleaseNotesManager {
|
|||
disposables.add(this._currentReleaseNotes.webview.onMessage(e => {
|
||||
if (e.message.type === 'showReleaseNotes') {
|
||||
this._configurationService.updateValue('update.showReleaseNotes', e.message.value);
|
||||
} else if (e.message.type === 'scroll') {
|
||||
this.scrollPosition = e.message.value.scrollPosition;
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -204,10 +218,15 @@ export class ReleaseNotesManager {
|
|||
return this._releaseNotesCache.get(version)!;
|
||||
}
|
||||
|
||||
private onDidClickLink(uri: URI) {
|
||||
this.addGAParameters(uri, 'ReleaseNotes')
|
||||
.then(updated => this._openerService.open(updated))
|
||||
.then(undefined, onUnexpectedError);
|
||||
private async onDidClickLink(uri: URI) {
|
||||
if (uri.scheme === Schemas.codeSetting) {
|
||||
await this._simpleSettingRenderer.updateSettingValue(uri);
|
||||
this.updateHtml();
|
||||
} else {
|
||||
this.addGAParameters(uri, 'ReleaseNotes')
|
||||
.then(updated => this._openerService.open(updated, { allowCommands: ['workbench.action.openSettings'] }))
|
||||
.then(undefined, onUnexpectedError);
|
||||
}
|
||||
}
|
||||
|
||||
private async addGAParameters(uri: URI, origin: string, experiment = '1'): Promise<URI> {
|
||||
|
@ -221,7 +240,7 @@ export class ReleaseNotesManager {
|
|||
|
||||
private async renderBody(text: string) {
|
||||
const nonce = generateUuid();
|
||||
const content = await renderMarkdownDocument(text, this._extensionService, this._languageService, false);
|
||||
const content = await renderMarkdownDocument(text, this._extensionService, this._languageService, false, undefined, undefined, this._simpleSettingRenderer);
|
||||
const colorMap = TokenizationRegistry.getColorMap();
|
||||
const css = colorMap ? generateTokensCSSForColorMap(colorMap) : '';
|
||||
const showReleaseNotes = Boolean(this._configurationService.getValue<boolean>('update.showReleaseNotes'));
|
||||
|
@ -267,9 +286,23 @@ export class ReleaseNotesManager {
|
|||
window.addEventListener('message', event => {
|
||||
if (event.data.type === 'showReleaseNotes') {
|
||||
input.checked = event.data.value;
|
||||
} else if (event.data.type === 'setScroll') {
|
||||
window.scrollTo(event.data.value.scrollPosition.x, event.data.value.scrollPosition.y);
|
||||
}
|
||||
});
|
||||
|
||||
window.onscroll = () => {
|
||||
vscode.postMessage({
|
||||
type: 'scroll',
|
||||
value: {
|
||||
scrollPosition: {
|
||||
x: window.scrollX,
|
||||
y: window.scrollY
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
input.addEventListener('change', event => {
|
||||
vscode.postMessage({ type: 'showReleaseNotes', value: input.checked }, '*');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue