Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)

* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c

* remove files we don't want

* fix hygiene

* update distro

* update distro

* fix hygiene

* fix strict nulls

* distro

* distro

* fix tests

* fix tests

* add another edit

* fix viewlet icon

* fix azure dialog

* fix some padding

* fix more padding issues
This commit is contained in:
Anthony Dresser
2019-12-04 19:28:22 -08:00
committed by GitHub
parent a8818ab0df
commit f5ce7fb2a5
1507 changed files with 42813 additions and 27370 deletions

View File

@@ -21,6 +21,7 @@ body img {
.container {
padding: 5px 0 0 10px;
box-sizing: border-box;
-webkit-user-select: none;
user-select: none;
}

View File

@@ -70,7 +70,8 @@
let ctrlPressed = false;
let altPressed = false;
let hasLoadedImage = false;
let consumeClick = false;
let consumeClick = true;
let isActive = false;
// Elements
const container = document.body;
@@ -117,10 +118,16 @@
});
}
function changeActive(value) {
function setActive(value) {
isActive = value;
if (value) {
container.classList.add('zoom-in');
consumeClick = true;
if (isMac ? altPressed : ctrlPressed) {
container.classList.remove('zoom-in');
container.classList.add('zoom-out');
} else {
container.classList.remove('zoom-out');
container.classList.add('zoom-in');
}
} else {
ctrlPressed = false;
altPressed = false;
@@ -202,7 +209,10 @@
return;
}
consumeClick = false;
ctrlPressed = e.ctrlKey;
altPressed = e.altKey;
consumeClick = !isActive;
});
container.addEventListener('click', (/** @type {MouseEvent} */ e) => {
@@ -214,14 +224,6 @@
return;
}
ctrlPressed = e.ctrlKey;
altPressed = e.altKey;
if (isMac ? altPressed : ctrlPressed) {
container.classList.remove('zoom-in');
container.classList.add('zoom-out');
}
if (consumeClick) {
consumeClick = false;
return;
@@ -239,6 +241,11 @@
});
container.addEventListener('wheel', (/** @type {WheelEvent} */ e) => {
// Prevent pinch to zoom
if (e.ctrlKey) {
e.preventDefault();
}
if (!image || !hasLoadedImage) {
return;
}
@@ -254,9 +261,9 @@
let delta = e.deltaY > 0 ? 1 : -1;
updateScale(scale * (1 - delta * SCALE_PINCH_FACTOR));
});
}, { passive: false });
window.addEventListener('scroll', () => {
window.addEventListener('scroll', e => {
if (!image || !hasLoadedImage || !image.parentElement || scale === 'fit') {
return;
}
@@ -265,7 +272,7 @@
if (entry) {
vscode.setState({ scale: entry.scale, offsetX: window.scrollX, offsetY: window.scrollY });
}
});
}, { passive: true });
container.classList.add('image');
@@ -296,7 +303,7 @@
document.body.classList.remove('loading');
});
image.src = decodeURI(settings.src);
image.src = settings.src;
window.addEventListener('message', e => {
switch (e.data.type) {
@@ -305,7 +312,7 @@
break;
case 'setActive':
changeActive(e.data.value);
setActive(e.data.value);
break;
case 'zoomIn':

View File

@@ -29,8 +29,7 @@
"priority": "builtin",
"selector": [
{
"filenamePattern": "*.{jpg,jpe,jpeg,png,bmp,gif,ico,tga,webp}",
"mime": "image/*"
"filenamePattern": "*.{jpg,jpe,jpeg,png,bmp,gif,ico,webp}"
}
]
}

View File

@@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { PreviewStatusBarEntry } from './ownedStatusBarEntry';
const localize = nls.loadMessageBundle();
class BinarySize {
static readonly KB = 1024;
static readonly MB = BinarySize.KB * BinarySize.KB;
static readonly GB = BinarySize.MB * BinarySize.KB;
static readonly TB = BinarySize.GB * BinarySize.KB;
static formatSize(size: number): string {
if (size < BinarySize.KB) {
return localize('sizeB', "{0}B", size);
}
if (size < BinarySize.MB) {
return localize('sizeKB', "{0}KB", (size / BinarySize.KB).toFixed(2));
}
if (size < BinarySize.GB) {
return localize('sizeMB', "{0}MB", (size / BinarySize.MB).toFixed(2));
}
if (size < BinarySize.TB) {
return localize('sizeGB', "{0}GB", (size / BinarySize.GB).toFixed(2));
}
return localize('sizeTB', "{0}TB", (size / BinarySize.TB).toFixed(2));
}
}
export class BinarySizeStatusBarEntry extends PreviewStatusBarEntry {
constructor() {
super({
id: 'imagePreview.binarySize',
name: localize('sizeStatusBar.name', "Image Binary Size"),
alignment: vscode.StatusBarAlignment.Right,
priority: 100,
});
}
public show(owner: string, size: number | undefined) {
if (typeof size === 'number') {
super.showItem(owner, BinarySize.formatSize(size));
} else {
this.hide(owner);
}
}
}

View File

@@ -6,6 +6,7 @@
import * as vscode from 'vscode';
import { PreviewManager } from './preview';
import { SizeStatusBarEntry } from './sizeStatusBarEntry';
import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
import { ZoomStatusBarEntry } from './zoomStatusBarEntry';
export function activate(context: vscode.ExtensionContext) {
@@ -14,18 +15,15 @@ export function activate(context: vscode.ExtensionContext) {
const sizeStatusBarEntry = new SizeStatusBarEntry();
context.subscriptions.push(sizeStatusBarEntry);
const binarySizeStatusBarEntry = new BinarySizeStatusBarEntry();
context.subscriptions.push(binarySizeStatusBarEntry);
const zoomStatusBarEntry = new ZoomStatusBarEntry();
context.subscriptions.push(zoomStatusBarEntry);
const previewManager = new PreviewManager(extensionRoot, sizeStatusBarEntry, zoomStatusBarEntry);
const previewManager = new PreviewManager(extensionRoot, sizeStatusBarEntry, binarySizeStatusBarEntry, zoomStatusBarEntry);
context.subscriptions.push(vscode.window.registerWebviewEditorProvider(
PreviewManager.viewType,
{
async resolveWebviewEditor(resource: vscode.Uri, editor: vscode.WebviewEditor): Promise<void> {
previewManager.resolve(resource, editor);
}
}));
context.subscriptions.push(vscode.window.registerWebviewEditorProvider(PreviewManager.viewType, previewManager));
context.subscriptions.push(vscode.commands.registerCommand('imagePreview.zoomIn', () => {
previewManager.activePreview?.zoomIn();

View File

@@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Disposable } from './dispose';
export abstract class PreviewStatusBarEntry extends Disposable {
private _showOwner: string | undefined;
protected readonly entry: vscode.StatusBarItem;
constructor(options: vscode.window.StatusBarItemOptions) {
super();
this.entry = this._register(vscode.window.createStatusBarItem(options));
}
protected showItem(owner: string, text: string) {
this._showOwner = owner;
this.entry.text = text;
this.entry.show();
}
public hide(owner: string) {
if (owner === this._showOwner) {
this.entry.hide();
this._showOwner = undefined;
}
}
}

View File

@@ -8,11 +8,12 @@ import * as nls from 'vscode-nls';
import { Disposable } from './dispose';
import { SizeStatusBarEntry } from './sizeStatusBarEntry';
import { Scale, ZoomStatusBarEntry } from './zoomStatusBarEntry';
import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
const localize = nls.loadMessageBundle();
export class PreviewManager {
export class PreviewManager implements vscode.WebviewEditorProvider {
public static readonly viewType = 'imagePreview.previewEditor';
@@ -22,14 +23,15 @@ export class PreviewManager {
constructor(
private readonly extensionRoot: vscode.Uri,
private readonly sizeStatusBarEntry: SizeStatusBarEntry,
private readonly binarySizeStatusBarEntry: BinarySizeStatusBarEntry,
private readonly zoomStatusBarEntry: ZoomStatusBarEntry,
) { }
public resolve(
resource: vscode.Uri,
webviewEditor: vscode.WebviewEditor,
) {
const preview = new Preview(this.extensionRoot, resource, webviewEditor, this.sizeStatusBarEntry, this.zoomStatusBarEntry);
public async resolveWebviewEditor(
input: { readonly resource: vscode.Uri, },
webviewEditor: vscode.WebviewPanel,
): Promise<vscode.WebviewEditorCapabilities> {
const preview = new Preview(this.extensionRoot, input.resource, webviewEditor, this.sizeStatusBarEntry, this.binarySizeStatusBarEntry, this.zoomStatusBarEntry);
this._previews.add(preview);
this.setActivePreview(preview);
@@ -42,6 +44,8 @@ export class PreviewManager {
this.setActivePreview(undefined);
}
});
return {};
}
public get activePreview() { return this._activePreview; }
@@ -68,13 +72,15 @@ class Preview extends Disposable {
private _previewState = PreviewState.Visible;
private _imageSize: string | undefined;
private _imageBinarySize: number | undefined;
private _imageZoom: Scale | undefined;
constructor(
private readonly extensionRoot: vscode.Uri,
private readonly resource: vscode.Uri,
private readonly webviewEditor: vscode.WebviewEditor,
private readonly webviewEditor: vscode.WebviewPanel,
private readonly sizeStatusBarEntry: SizeStatusBarEntry,
private readonly binarySizeStatusBarEntry: BinarySizeStatusBarEntry,
private readonly zoomStatusBarEntry: ZoomStatusBarEntry,
) {
super();
@@ -115,11 +121,13 @@ class Preview extends Disposable {
this._register(webviewEditor.onDidChangeViewState(() => {
this.update();
this.webviewEditor.webview.postMessage({ type: 'setActive', value: this.webviewEditor.active });
}));
this._register(webviewEditor.onDidDispose(() => {
if (this._previewState === PreviewState.Active) {
this.sizeStatusBarEntry.hide(this.id);
this.binarySizeStatusBarEntry.hide(this.id);
this.zoomStatusBarEntry.hide(this.id);
}
this._previewState = PreviewState.Disposed;
@@ -137,8 +145,14 @@ class Preview extends Disposable {
}
}));
vscode.workspace.fs.stat(resource).then(({ size }) => {
this._imageBinarySize = size;
this.update();
});
this.render();
this.update();
this.webviewEditor.webview.postMessage({ type: 'setActive', value: this.webviewEditor.active });
}
public zoomIn() {
@@ -167,15 +181,16 @@ class Preview extends Disposable {
if (this.webviewEditor.active) {
this._previewState = PreviewState.Active;
this.sizeStatusBarEntry.show(this.id, this._imageSize || '');
this.binarySizeStatusBarEntry.show(this.id, this._imageBinarySize);
this.zoomStatusBarEntry.show(this.id, this._imageZoom || 'fit');
} else {
if (this._previewState === PreviewState.Active) {
this.sizeStatusBarEntry.hide(this.id);
this.binarySizeStatusBarEntry.hide(this.id);
this.zoomStatusBarEntry.hide(this.id);
}
this._previewState = PreviewState.Visible;
}
this.webviewEditor.webview.postMessage({ type: 'setActive', value: this.webviewEditor.active });
}
private getWebiewContents(): string {
@@ -191,8 +206,11 @@ class Preview extends Disposable {
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- Disable pinch zooming -->
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<title>Image Preview</title>
<link rel="stylesheet" href="${escapeAttribute(this.extensionResource('/media/main.css'))}" type="text/css" media="screen" nonce="${nonce}">
@@ -208,18 +226,21 @@ class Preview extends Disposable {
</html>`;
}
private getResourcePath(webviewEditor: vscode.WebviewEditor, resource: vscode.Uri, version: string) {
private getResourcePath(webviewEditor: vscode.WebviewPanel, resource: vscode.Uri, version: string) {
switch (resource.scheme) {
case 'data':
return encodeURI(resource.toString(true));
return resource.toString(true);
case 'git':
// Show blank image
return encodeURI('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg==');
return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR42gEFAPr/AP///wAI/AL+Sr4t6gAAAABJRU5ErkJggg==';
default:
return encodeURI(webviewEditor.webview.asWebviewUri(resource).toString(true) + `?version=${version}`);
// Avoid adding cache busting if there is already a query string
if (resource.query) {
return webviewEditor.webview.asWebviewUri(resource).toString(true);
}
return webviewEditor.webview.asWebviewUri(resource).with({ query: `version=${version}` }).toString(true);
}
}

View File

@@ -4,36 +4,23 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Disposable } from './dispose';
import * as nls from 'vscode-nls';
import { PreviewStatusBarEntry } from './ownedStatusBarEntry';
const localize = nls.loadMessageBundle();
export class SizeStatusBarEntry extends Disposable {
private readonly _entry: vscode.StatusBarItem;
private _showingOwner: string | undefined;
export class SizeStatusBarEntry extends PreviewStatusBarEntry {
constructor() {
super();
this._entry = this._register(vscode.window.createStatusBarItem({
super({
id: 'imagePreview.size',
name: localize('sizeStatusBar.name', "Image Size"),
alignment: vscode.StatusBarAlignment.Right,
priority: 101 /* to the left of editor status (100) */,
}));
});
}
public show(owner: string, text: string) {
this._showingOwner = owner;
this._entry.text = text;
this._entry.show();
}
public hide(owner: string) {
if (owner === this._showingOwner) {
this._entry.hide();
this._showingOwner = undefined;
}
this.showItem(owner, text);
}
}

View File

@@ -5,7 +5,7 @@
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Disposable } from './dispose';
import { PreviewStatusBarEntry as OwnedStatusBarEntry } from './ownedStatusBarEntry';
const localize = nls.loadMessageBundle();
@@ -13,22 +13,18 @@ const selectZoomLevelCommandId = '_imagePreview.selectZoomLevel';
export type Scale = number | 'fit';
export class ZoomStatusBarEntry extends Disposable {
private readonly _entry: vscode.StatusBarItem;
export class ZoomStatusBarEntry extends OwnedStatusBarEntry {
private readonly _onDidChangeScale = this._register(new vscode.EventEmitter<{ scale: Scale }>());
public readonly onDidChangeScale = this._onDidChangeScale.event;
private _showOwner: string | undefined;
constructor() {
super();
this._entry = this._register(vscode.window.createStatusBarItem({
super({
id: 'imagePreview.zoom',
name: localize('zoomStatusBar.name', "Image Zoom"),
alignment: vscode.StatusBarAlignment.Right,
priority: 102 /* to the left of editor size entry (101) */,
}));
});
this._register(vscode.commands.registerCommand(selectZoomLevelCommandId, async () => {
type MyPickItem = vscode.QuickPickItem & { scale: Scale };
@@ -47,20 +43,11 @@ export class ZoomStatusBarEntry extends Disposable {
}
}));
this._entry.command = selectZoomLevelCommandId;
this.entry.command = selectZoomLevelCommandId;
}
public show(owner: string, scale: Scale) {
this._showOwner = owner;
this._entry.text = this.zoomLabel(scale);
this._entry.show();
}
public hide(owner: string) {
if (owner === this._showOwner) {
this._entry.hide();
this._showOwner = undefined;
}
this.showItem(owner, this.zoomLabel(scale));
}
private zoomLabel(scale: Scale): string {