mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-31 17:23:31 -05:00
Merge from master
This commit is contained in:
@@ -2,26 +2,25 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { ClientCoordinates, EditorMouseEvent, EditorPagePosition, PageCoordinates } from 'vs/editor/browser/editorDom';
|
||||
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range as EditorRange } from 'vs/editor/common/core/range';
|
||||
import { MouseTargetType, IMouseTarget } from 'vs/editor/browser/editorBrowser';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { IPointerHandlerHelper } from 'vs/editor/browser/controller/mouseHandler';
|
||||
import { EditorMouseEvent, PageCoordinates, ClientCoordinates, EditorPagePosition } from 'vs/editor/browser/editorDom';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions';
|
||||
import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine';
|
||||
import { HorizontalRange } from 'vs/editor/common/view/renderingContext';
|
||||
import { ViewContext } from 'vs/editor/common/view/viewContext';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
|
||||
export interface IViewZoneData {
|
||||
viewZoneId: number;
|
||||
positionBefore: Position;
|
||||
positionAfter: Position;
|
||||
positionBefore: Position | null;
|
||||
positionAfter: Position | null;
|
||||
position: Position;
|
||||
afterLineNumber: number;
|
||||
}
|
||||
@@ -85,20 +84,20 @@ declare var IETextRange: {
|
||||
};
|
||||
|
||||
interface IHitTestResult {
|
||||
position: Position;
|
||||
hitTarget: Element;
|
||||
position: Position | null;
|
||||
hitTarget: Element | null;
|
||||
}
|
||||
|
||||
export class MouseTarget implements IMouseTarget {
|
||||
|
||||
public readonly element: Element;
|
||||
public readonly element: Element | null;
|
||||
public readonly type: MouseTargetType;
|
||||
public readonly mouseColumn: number;
|
||||
public readonly position: Position;
|
||||
public readonly range: EditorRange;
|
||||
public readonly position: Position | null;
|
||||
public readonly range: EditorRange | null;
|
||||
public readonly detail: any;
|
||||
|
||||
constructor(element: Element, type: MouseTargetType, mouseColumn: number = 0, position: Position = null, range: EditorRange = null, detail: any = null) {
|
||||
constructor(element: Element | null, type: MouseTargetType, mouseColumn: number = 0, position: Position | null = null, range: EditorRange | null = null, detail: any = null) {
|
||||
this.element = element;
|
||||
this.type = type;
|
||||
this.mouseColumn = mouseColumn;
|
||||
@@ -248,20 +247,20 @@ export class HitTestContext {
|
||||
this._viewHelper = viewHelper;
|
||||
}
|
||||
|
||||
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData {
|
||||
public getZoneAtCoord(mouseVerticalOffset: number): IViewZoneData | null {
|
||||
return HitTestContext.getZoneAtCoord(this._context, mouseVerticalOffset);
|
||||
}
|
||||
|
||||
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData {
|
||||
public static getZoneAtCoord(context: ViewContext, mouseVerticalOffset: number): IViewZoneData | null {
|
||||
// The target is either a view zone or the empty space after the last view-line
|
||||
let viewZoneWhitespace = context.viewLayout.getWhitespaceAtVerticalOffset(mouseVerticalOffset);
|
||||
|
||||
if (viewZoneWhitespace) {
|
||||
let viewZoneMiddle = viewZoneWhitespace.verticalOffset + viewZoneWhitespace.height / 2,
|
||||
lineCount = context.model.getLineCount(),
|
||||
positionBefore: Position = null,
|
||||
position: Position,
|
||||
positionAfter: Position = null;
|
||||
positionBefore: Position | null = null,
|
||||
position: Position | null,
|
||||
positionAfter: Position | null = null;
|
||||
|
||||
if (viewZoneWhitespace.afterLineNumber !== lineCount) {
|
||||
// There are more lines after this view zone
|
||||
@@ -287,7 +286,7 @@ export class HitTestContext {
|
||||
afterLineNumber: viewZoneWhitespace.afterLineNumber,
|
||||
positionBefore: positionBefore,
|
||||
positionAfter: positionAfter,
|
||||
position: position
|
||||
position: position!
|
||||
};
|
||||
}
|
||||
return null;
|
||||
@@ -324,11 +323,11 @@ export class HitTestContext {
|
||||
return this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber);
|
||||
}
|
||||
|
||||
public findAttribute(element: Element, attr: string): string {
|
||||
public findAttribute(element: Element, attr: string): string | null {
|
||||
return HitTestContext._findAttribute(element, attr, this._viewHelper.viewDomNode);
|
||||
}
|
||||
|
||||
private static _findAttribute(element: Element, attr: string, stopAt: Element): string {
|
||||
private static _findAttribute(element: Element, attr: string, stopAt: Element): string | null {
|
||||
while (element && element !== document.body) {
|
||||
if (element.hasAttribute && element.hasAttribute(attr)) {
|
||||
return element.getAttribute(attr);
|
||||
@@ -345,11 +344,11 @@ export class HitTestContext {
|
||||
return this._viewHelper.getLineWidth(lineNumber);
|
||||
}
|
||||
|
||||
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange {
|
||||
public visibleRangeForPosition2(lineNumber: number, column: number): HorizontalRange | null {
|
||||
return this._viewHelper.visibleRangeForPosition2(lineNumber, column);
|
||||
}
|
||||
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position {
|
||||
public getPositionFromDOMInfo(spanNode: HTMLElement, offset: number): Position | null {
|
||||
return this._viewHelper.getPositionFromDOMInfo(spanNode, offset);
|
||||
}
|
||||
|
||||
@@ -387,10 +386,10 @@ abstract class BareHitTestRequest {
|
||||
|
||||
class HitTestRequest extends BareHitTestRequest {
|
||||
private readonly _ctx: HitTestContext;
|
||||
public readonly target: Element;
|
||||
public readonly target: Element | null;
|
||||
public readonly targetPath: Uint8Array;
|
||||
|
||||
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element) {
|
||||
constructor(ctx: HitTestContext, editorPos: EditorPagePosition, pos: PageCoordinates, target: Element | null) {
|
||||
super(ctx, editorPos, pos);
|
||||
this._ctx = ctx;
|
||||
|
||||
@@ -407,15 +406,19 @@ class HitTestRequest extends BareHitTestRequest {
|
||||
return `pos(${this.pos.x},${this.pos.y}), editorPos(${this.editorPos.x},${this.editorPos.y}), mouseVerticalOffset: ${this.mouseVerticalOffset}, mouseContentHorizontalOffset: ${this.mouseContentHorizontalOffset}\n\ttarget: ${this.target ? (<HTMLElement>this.target).outerHTML : null}`;
|
||||
}
|
||||
|
||||
public fulfill(type: MouseTargetType, position: Position = null, range: EditorRange = null, detail: any = null): MouseTarget {
|
||||
public fulfill(type: MouseTargetType, position: Position | null = null, range: EditorRange | null = null, detail: any = null): MouseTarget {
|
||||
return new MouseTarget(this.target, type, this.mouseColumn, position, range, detail);
|
||||
}
|
||||
|
||||
public withTarget(target: Element): HitTestRequest {
|
||||
public withTarget(target: Element | null): HitTestRequest {
|
||||
return new HitTestRequest(this._ctx, this.editorPos, this.pos, target);
|
||||
}
|
||||
}
|
||||
|
||||
interface ResolvedHitTestRequest extends HitTestRequest {
|
||||
readonly target: Element;
|
||||
}
|
||||
|
||||
const EMPTY_CONTENT_AFTER_LINES: IEmptyContentData = { isAfterLines: true };
|
||||
|
||||
function createEmptyContentDataInLines(horizontalDistanceToText: number): IEmptyContentData {
|
||||
@@ -452,7 +455,7 @@ export class MouseTargetFactory {
|
||||
return false;
|
||||
}
|
||||
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement): IMouseTarget {
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement | null): IMouseTarget {
|
||||
const ctx = new HitTestContext(this._context, this._viewHelper, lastViewCursorsRenderData);
|
||||
const request = new HitTestRequest(ctx, editorPos, pos, target);
|
||||
try {
|
||||
@@ -485,23 +488,26 @@ export class MouseTargetFactory {
|
||||
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
|
||||
}
|
||||
|
||||
let result: MouseTarget = null;
|
||||
// we know for a fact that request.target is not null
|
||||
const resolvedRequest = <ResolvedHitTestRequest>request;
|
||||
|
||||
result = result || MouseTargetFactory._hitTestContentWidget(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestMinimap(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewZone(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestMargin(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewCursor(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestTextArea(ctx, request);
|
||||
result = result || MouseTargetFactory._hitTestViewLines(ctx, request, domHitTestExecuted);
|
||||
result = result || MouseTargetFactory._hitTestScrollbar(ctx, request);
|
||||
let result: MouseTarget | null = null;
|
||||
|
||||
result = result || MouseTargetFactory._hitTestContentWidget(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestOverlayWidget(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestMinimap(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestScrollbarSlider(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewZone(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestMargin(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewCursor(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestTextArea(ctx, resolvedRequest);
|
||||
result = result || MouseTargetFactory._hitTestViewLines(ctx, resolvedRequest, domHitTestExecuted);
|
||||
result = result || MouseTargetFactory._hitTestScrollbar(ctx, resolvedRequest);
|
||||
|
||||
return (result || request.fulfill(MouseTargetType.UNKNOWN));
|
||||
}
|
||||
|
||||
private static _hitTestContentWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestContentWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it a content widget?
|
||||
if (ElementPath.isChildOfContentWidgets(request.targetPath) || ElementPath.isChildOfOverflowingContentWidgets(request.targetPath)) {
|
||||
let widgetId = ctx.findAttribute(request.target, 'widgetId');
|
||||
@@ -514,7 +520,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestOverlayWidget(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestOverlayWidget(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it an overlay widget?
|
||||
if (ElementPath.isChildOfOverlayWidgets(request.targetPath)) {
|
||||
let widgetId = ctx.findAttribute(request.target, 'widgetId');
|
||||
@@ -527,7 +533,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewCursor(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestViewCursor(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
|
||||
if (request.target) {
|
||||
// Check if we've hit a painted cursor
|
||||
@@ -578,7 +584,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewZone(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestViewZone(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
let viewZoneData = ctx.getZoneAtCoord(request.mouseVerticalOffset);
|
||||
if (viewZoneData) {
|
||||
let mouseTargetType = (request.isInContentArea ? MouseTargetType.CONTENT_VIEW_ZONE : MouseTargetType.GUTTER_VIEW_ZONE);
|
||||
@@ -588,7 +594,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the textarea?
|
||||
if (ElementPath.isTextArea(request.targetPath)) {
|
||||
return request.fulfill(MouseTargetType.TEXTAREA);
|
||||
@@ -596,7 +602,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestMargin(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestMargin(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (request.isInMarginArea) {
|
||||
let res = ctx.getFullLineRangeAtCoord(request.mouseVerticalOffset);
|
||||
let pos = res.range.getStartPosition();
|
||||
@@ -629,7 +635,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestViewLines(ctx: HitTestContext, request: HitTestRequest, domHitTestExecuted: boolean): MouseTarget {
|
||||
private static _hitTestViewLines(ctx: HitTestContext, request: ResolvedHitTestRequest, domHitTestExecuted: boolean): MouseTarget | null {
|
||||
if (!ElementPath.isChildOfViewLines(request.targetPath)) {
|
||||
return null;
|
||||
}
|
||||
@@ -667,7 +673,7 @@ export class MouseTargetFactory {
|
||||
return this._createMouseTarget(ctx, request.withTarget(hitTestResult.hitTarget), true);
|
||||
}
|
||||
|
||||
private static _hitTestMinimap(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestMinimap(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (ElementPath.isChildOfMinimap(request.targetPath)) {
|
||||
const possibleLineNumber = ctx.getLineNumberAtVerticalOffset(request.mouseVerticalOffset);
|
||||
const maxColumn = ctx.model.getLineMaxColumn(possibleLineNumber);
|
||||
@@ -676,7 +682,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestScrollbarSlider(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
|
||||
if (request.target && request.target.nodeType === 1) {
|
||||
let className = request.target.className;
|
||||
@@ -690,7 +696,7 @@ export class MouseTargetFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static _hitTestScrollbar(ctx: HitTestContext, request: HitTestRequest): MouseTarget {
|
||||
private static _hitTestScrollbar(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the overview ruler?
|
||||
// Is it a child of the scrollable element?
|
||||
if (ElementPath.isChildOfScrollableElement(request.targetPath)) {
|
||||
@@ -818,7 +824,7 @@ export class MouseTargetFactory {
|
||||
|
||||
// Chrome always hits a TEXT_NODE, while Edge sometimes hits a token span
|
||||
let startContainer = range.startContainer;
|
||||
let hitTarget: HTMLElement;
|
||||
let hitTarget: HTMLElement | null = null;
|
||||
|
||||
if (startContainer.nodeType === startContainer.TEXT_NODE) {
|
||||
// startContainer is expected to be the token text
|
||||
@@ -843,7 +849,7 @@ export class MouseTargetFactory {
|
||||
let parent2ClassName = parent2 && parent2.nodeType === parent2.ELEMENT_NODE ? (<HTMLElement>parent2).className : null;
|
||||
|
||||
if (parent2ClassName === ViewLine.CLASS_NAME) {
|
||||
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent.length);
|
||||
let p = ctx.getPositionFromDOMInfo(<HTMLElement>startContainer, (<HTMLElement>startContainer).textContent!.length);
|
||||
return {
|
||||
position: p,
|
||||
hitTarget: null
|
||||
@@ -896,8 +902,8 @@ export class MouseTargetFactory {
|
||||
* Most probably IE
|
||||
*/
|
||||
private static _doHitTestWithMoveToPoint(ctx: HitTestContext, coords: ClientCoordinates): IHitTestResult {
|
||||
let resultPosition: Position = null;
|
||||
let resultHitTarget: Element = null;
|
||||
let resultPosition: Position | null = null;
|
||||
let resultHitTarget: Element | null = null;
|
||||
|
||||
let textRange: IETextRange = (<any>document.body).createTextRange();
|
||||
try {
|
||||
@@ -920,7 +926,7 @@ export class MouseTargetFactory {
|
||||
|
||||
if (parent2ClassName === ViewLine.CLASS_NAME) {
|
||||
let rangeToContainEntireSpan = textRange.duplicate();
|
||||
rangeToContainEntireSpan.moveToElementText(parentElement);
|
||||
rangeToContainEntireSpan.moveToElementText(parentElement!);
|
||||
rangeToContainEntireSpan.setEndPoint('EndToStart', textRange);
|
||||
|
||||
resultPosition = ctx.getPositionFromDOMInfo(<HTMLElement>parentElement, rangeToContainEntireSpan.text.length);
|
||||
|
||||
Reference in New Issue
Block a user