提交 9dfc48fd 编写于 作者: A Alex Dima

Clean up some base/browser files

上级 70297de1
......@@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import Lifecycle = require('vs/base/common/lifecycle');
import DomUtils = require('vs/base/browser/dom');
import Mouse = require('vs/base/browser/mouseEvent');
import IframeUtils = require('vs/base/browser/iframe');
import * as DomUtils from 'vs/base/browser/dom';
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {StandardMouseEvent} from 'vs/base/browser/mouseEvent';
import {IframeUtils} from 'vs/base/browser/iframe';
export interface IStandardMouseMoveEventData {
leftButton:boolean;
......@@ -28,7 +28,7 @@ export interface IOnStopCallback {
}
export function standardMouseMoveMerger(lastEvent:IStandardMouseMoveEventData, currentEvent:MouseEvent):IStandardMouseMoveEventData {
var ev = new Mouse.StandardMouseEvent(currentEvent);
let ev = new StandardMouseEvent(currentEvent);
ev.preventDefault();
return {
leftButton: ev.leftButton,
......@@ -37,9 +37,9 @@ export function standardMouseMoveMerger(lastEvent:IStandardMouseMoveEventData, c
};
}
export class GlobalMouseMoveMonitor<R> implements Lifecycle.IDisposable {
export class GlobalMouseMoveMonitor<R> implements IDisposable {
private hooks:Lifecycle.IDisposable[];
private hooks:IDisposable[];
private mouseMoveEventMerger:IEventMerger<R>;
private mouseMoveCallback:IMouseMoveCallback<R>;
private onStopCallback:IOnStopCallback;
......@@ -62,10 +62,10 @@ export class GlobalMouseMoveMonitor<R> implements Lifecycle.IDisposable {
}
// Unhook
this.hooks = Lifecycle.disposeAll(this.hooks);
this.hooks = disposeAll(this.hooks);
this.mouseMoveEventMerger = null;
this.mouseMoveCallback = null;
var onStopCallback = this.onStopCallback;
let onStopCallback = this.onStopCallback;
this.onStopCallback = null;
if (invokeStopCallback) {
......@@ -90,9 +90,9 @@ export class GlobalMouseMoveMonitor<R> implements Lifecycle.IDisposable {
this.mouseMoveCallback = mouseMoveCallback;
this.onStopCallback = onStopCallback;
var windowChain = IframeUtils.getSameOriginWindowChain();
for (var i = 0; i < windowChain.length; i++) {
this.hooks.push(DomUtils.addDisposableThrottledListener(windowChain[i].window.document, 'mousemove',
let windowChain = IframeUtils.getSameOriginWindowChain();
for (let i = 0; i < windowChain.length; i++) {
this.hooks.push(DomUtils.addDisposableThrottledListener(windowChain[i].window.document, 'mousemove',
(data:R) => this.mouseMoveCallback(data),
(lastEvent:R, currentEvent:MouseEvent) => this.mouseMoveEventMerger(lastEvent, currentEvent)
));
......@@ -100,18 +100,18 @@ export class GlobalMouseMoveMonitor<R> implements Lifecycle.IDisposable {
}
if (IframeUtils.hasDifferentOriginAncestor()) {
var lastSameOriginAncestor = windowChain[windowChain.length - 1];
let lastSameOriginAncestor = windowChain[windowChain.length - 1];
// We might miss a mouse up if it happens outside the iframe
// This one is for Chrome
this.hooks.push(DomUtils.addDisposableListener(lastSameOriginAncestor.window.document, 'mouseout', (browserEvent:MouseEvent) => {
var e = new Mouse.StandardMouseEvent(browserEvent);
let e = new StandardMouseEvent(browserEvent);
if (e.target.tagName.toLowerCase() === 'html') {
this.stopMonitoring(true);
}
}));
// This one is for FF
this.hooks.push(DomUtils.addDisposableListener(lastSameOriginAncestor.window.document, 'mouseover', (browserEvent:MouseEvent) => {
var e = new Mouse.StandardMouseEvent(browserEvent);
let e = new StandardMouseEvent(browserEvent);
if (e.target.tagName.toLowerCase() === 'html') {
this.stopMonitoring(true);
}
......@@ -122,4 +122,4 @@ export class GlobalMouseMoveMonitor<R> implements Lifecycle.IDisposable {
}));
}
}
}
\ No newline at end of file
}
......@@ -4,10 +4,11 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import DomUtils = require('vs/base/browser/dom');
import {IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import * as DomUtils from 'vs/base/browser/dom';
import {Disposable, IDisposable, disposeAll} from 'vs/base/common/lifecycle';
import {EventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter';
import {getService} from 'vs/base/browser/browserService';
import {TimeoutTimer} from 'vs/base/common/async';
export enum UserStatus {
Idle,
......@@ -16,151 +17,73 @@ export enum UserStatus {
export const DEFAULT_IDLE_TIME = 60 * 60 * 1000; // 60 minutes
export class IdleMonitor {
export class IdleMonitor extends Disposable {
private toDispose: IDisposable[];
private lastActiveTime: number;
private idleCheckTimeout: number;
private status: UserStatus;
private eventEmitter: EventEmitter;
private instance: ReferenceCountedIdleMonitor;
private idleTime: number;
private _lastActiveTime: number;
private _idleCheckTimeout: TimeoutTimer;
private _status: UserStatus;
private _eventEmitter: EventEmitter;
private _idleTime: number;
constructor(idleTime: number = DEFAULT_IDLE_TIME) {
this.instance = ReferenceCountedIdleMonitor.INSTANCE;
this.instance.increment();
this.status = null;
this.idleCheckTimeout = -1;
this.lastActiveTime = -1;
this.idleTime = idleTime;
this.toDispose = [];
this.eventEmitter = new EventEmitter();
this.toDispose.push(this.eventEmitter);
this.toDispose.push({ dispose: this.instance.addListener(() => this.onUserActive()) });
this.onUserActive();
}
super();
public addOneTimeActiveListener(callback: () => void): IDisposable {
return this.eventEmitter.addOneTimeDisposableListener('onActive', callback);
}
public addOneTimeIdleListener(callback: () => void): IDisposable {
return this.eventEmitter.addOneTimeDisposableListener('onIdle', callback);
}
this._status = null;
this._idleCheckTimeout = this._register(new TimeoutTimer());
this._lastActiveTime = -1;
this._idleTime = idleTime;
public getStatus(): UserStatus {
return this.status;
this._eventEmitter = this._register(new EventEmitter());
this._register(DomUtils.addDisposableListener(getService().document, 'mousemove', () => this._onUserActive()));
this._register(DomUtils.addDisposableListener(getService().document, 'keydown', () => this._onUserActive()));
this._onUserActive();
}
public dispose(): void {
this.cancelIdleCheck();
this.toDispose = disposeAll(this.toDispose);
this.instance.decrement();
super.dispose();
}
private onUserActive(): void {
this.lastActiveTime = (new Date()).getTime();
if (this.status !== UserStatus.Active) {
this.status = UserStatus.Active;
this.scheduleIdleCheck();
this.eventEmitter.emit('onActive');
}
public addOneTimeActiveListener(callback: () => void): IDisposable {
return this._eventEmitter.addOneTimeDisposableListener('onActive', callback);
}
private onUserIdle(): void {
if (this.status !== UserStatus.Idle) {
this.status = UserStatus.Idle;
this.eventEmitter.emit('onIdle');
}
public addOneTimeIdleListener(callback: () => void): IDisposable {
return this._eventEmitter.addOneTimeDisposableListener('onIdle', callback);
}
private scheduleIdleCheck(): void {
if (this.idleCheckTimeout === -1) {
let minimumTimeWhenUserCanBecomeIdle = this.lastActiveTime + this.idleTime;
this.idleCheckTimeout = setTimeout(() => {
this.idleCheckTimeout = -1;
this.checkIfUserIsIdle();
}, minimumTimeWhenUserCanBecomeIdle - (new Date()).getTime());
}
public getStatus(): UserStatus {
return this._status;
}
private cancelIdleCheck(): void {
if (this.idleCheckTimeout !== -1) {
clearTimeout(this.idleCheckTimeout);
this.idleCheckTimeout = -1;
private _onUserActive(): void {
this._lastActiveTime = (new Date()).getTime();
if (this._status !== UserStatus.Active) {
this._status = UserStatus.Active;
this._scheduleIdleCheck();
this._eventEmitter.emit('onActive');
}
}
private checkIfUserIsIdle(): void {
let actualIdleTime = (new Date()).getTime() - this.lastActiveTime;
if (actualIdleTime >= this.idleTime) {
this.onUserIdle();
} else {
this.scheduleIdleCheck();
private _onUserIdle(): void {
if (this._status !== UserStatus.Idle) {
this._status = UserStatus.Idle;
this._eventEmitter.emit('onIdle');
}
}
}
class ReferenceCountedObject {
private referenceCount: number;
constructor() {
this.referenceCount = 0;
}
public increment(): void {
if (this.referenceCount === 0) {
this.construct();
}
this.referenceCount++;
private _scheduleIdleCheck(): void {
let minimumTimeWhenUserCanBecomeIdle = this._lastActiveTime + this._idleTime;
this._idleCheckTimeout.setIfNotSet(() => {
this._checkIfUserIsIdle();
}, minimumTimeWhenUserCanBecomeIdle - (new Date()).getTime());
}
public decrement(): void {
if (this.referenceCount > 0) {
this.referenceCount--;
if (this.referenceCount === 0) {
this.dispose();
}
private _checkIfUserIsIdle(): void {
let actualIdleTime = (new Date()).getTime() - this._lastActiveTime;
if (actualIdleTime >= this._idleTime) {
this._onUserIdle();
} else {
this._scheduleIdleCheck();
}
}
public construct(): void {
throw new Error('Implement me');
}
public dispose(): void {
throw new Error('Implement me');
}
}
class ReferenceCountedIdleMonitor extends ReferenceCountedObject {
public static INSTANCE: ReferenceCountedIdleMonitor = new ReferenceCountedIdleMonitor();
private toDispose: IDisposable[];
private eventEmitter: EventEmitter;
public construct(): void {
this.toDispose = [];
this.eventEmitter = new EventEmitter();
this.toDispose.push(this.eventEmitter);
this.toDispose.push(DomUtils.addDisposableListener(getService().document, 'mousemove', () => this.onUserActive()));
this.toDispose.push(DomUtils.addDisposableListener(getService().document, 'keydown', () => this.onUserActive()));
this.onUserActive();
}
public dispose(): void {
this.toDispose = disposeAll(this.toDispose);
}
private onUserActive(): void {
this.eventEmitter.emit('onActive');
}
public addListener(callback: () => void): ListenerUnbind {
return this.eventEmitter.addListener('onActive', callback);
}
}
\ No newline at end of file
......@@ -54,79 +54,82 @@ function findIframeElementInParentWindow(parentWindow: Window, childWindow: Wind
return null;
}
/**
* Returns a chain of embedded windows with the same origin (which can be accessed programmatically).
* Having a chain of length 1 might mean that the current execution environment is running outside of an iframe or inside an iframe embedded in a window with a different origin.
* To distinguish if at one point the current execution environment is running inside a window with a different origin, see hasDifferentOriginAncestor()
*/
export function getSameOriginWindowChain(): IWindowChainElement[] {
if (!sameOriginWindowChainCache) {
sameOriginWindowChainCache = [];
let w = window, parent: Window;
do {
parent = getParentWindowIfSameOrigin(w);
if (parent) {
sameOriginWindowChainCache.push({
window: w,
iframeElement: findIframeElementInParentWindow(parent, w)
});
} else {
sameOriginWindowChainCache.push({
window: w,
iframeElement: null
});
}
w = parent;
} while (w);
export class IframeUtils {
/**
* Returns a chain of embedded windows with the same origin (which can be accessed programmatically).
* Having a chain of length 1 might mean that the current execution environment is running outside of an iframe or inside an iframe embedded in a window with a different origin.
* To distinguish if at one point the current execution environment is running inside a window with a different origin, see hasDifferentOriginAncestor()
*/
public static getSameOriginWindowChain(): IWindowChainElement[] {
if (!sameOriginWindowChainCache) {
sameOriginWindowChainCache = [];
let w = window, parent: Window;
do {
parent = getParentWindowIfSameOrigin(w);
if (parent) {
sameOriginWindowChainCache.push({
window: w,
iframeElement: findIframeElementInParentWindow(parent, w)
});
} else {
sameOriginWindowChainCache.push({
window: w,
iframeElement: null
});
}
w = parent;
} while (w);
}
return sameOriginWindowChainCache.slice(0);
}
return sameOriginWindowChainCache.slice(0);
}
/**
* Returns true if the current execution environment is chained in a list of iframes which at one point ends in a window with a different origin.
* Returns false if the current execution environment is not running inside an iframe or if the entire chain of iframes have the same origin.
*/
export function hasDifferentOriginAncestor(): boolean {
if (!sameOriginWindowChainCache) {
getSameOriginWindowChain();
/**
* Returns true if the current execution environment is chained in a list of iframes which at one point ends in a window with a different origin.
* Returns false if the current execution environment is not running inside an iframe or if the entire chain of iframes have the same origin.
*/
public static hasDifferentOriginAncestor(): boolean {
if (!sameOriginWindowChainCache) {
this.getSameOriginWindowChain();
}
return hasDifferentOriginAncestorFlag;
}
return hasDifferentOriginAncestorFlag;
}
/**
* Returns the position of `childWindow` relative to `ancestorWindow`
*/
export function getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: any) {
/**
* Returns the position of `childWindow` relative to `ancestorWindow`
*/
public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: any) {
if (!ancestorWindow || childWindow === ancestorWindow) {
return {
top: 0,
left: 0
};
}
if (!ancestorWindow || childWindow === ancestorWindow) {
return {
top: 0,
left: 0
};
}
let top = 0, left = 0;
let top = 0, left = 0;
let windowChain = getSameOriginWindowChain();
let windowChain = this.getSameOriginWindowChain();
for (let i = 0; i < windowChain.length; i++) {
let windowChainEl = windowChain[i];
for (let i = 0; i < windowChain.length; i++) {
let windowChainEl = windowChain[i];
if (windowChainEl.window === ancestorWindow) {
break;
}
if (windowChainEl.window === ancestorWindow) {
break;
}
if (!windowChainEl.iframeElement) {
break;
}
if (!windowChainEl.iframeElement) {
break;
let boundingRect = windowChainEl.iframeElement.getBoundingClientRect();
top += boundingRect.top;
left += boundingRect.left;
}
let boundingRect = windowChainEl.iframeElement.getBoundingClientRect();
top += boundingRect.top;
left += boundingRect.left;
return {
top: top,
left: left
};
}
return {
top: top,
left: left
};
}
\ No newline at end of file
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import DomUtils = require('vs/base/browser/dom');
import Lifecycle = require('vs/base/common/lifecycle');
export interface IKeyboardController {
addListener(type:'keydown', callback:(event:DomUtils.IKeyboardEvent)=>void): ()=>void;
addListener(type:'keypress', callback:(event:DomUtils.IKeyboardEvent)=>void): ()=>void;
addListener(type:'keyup', callback:(event:DomUtils.IKeyboardEvent)=>void): ()=>void;
addListener(type:'input', callback:(event:Event)=>void): ()=>void;
addListener(type:string, callback:(event:any)=>void): ()=>void;
addListener2(type:'keydown', callback:(event:DomUtils.IKeyboardEvent)=>void): Lifecycle.IDisposable;
addListener2(type:'keypress', callback:(event:DomUtils.IKeyboardEvent)=>void): Lifecycle.IDisposable;
addListener2(type:'keyup', callback:(event:DomUtils.IKeyboardEvent)=>void): Lifecycle.IDisposable;
addListener2(type:'input', callback:(event:Event)=>void): Lifecycle.IDisposable;
addListener2(type:string, callback:(event:any)=>void): Lifecycle.IDisposable;
dispose(): void;
}
export class KeyboardController implements IKeyboardController, Lifecycle.IDisposable {
private _listeners:{ [type:string]:(e:any)=>void; };
private _previousKeyDown:DomUtils.IKeyboardEvent;
private _previousEventType:string;
private _toDispose:Lifecycle.IDisposable[];
constructor(domNode:HTMLElement) {
this._listeners = {};
this._previousKeyDown = null;
this._previousEventType = null;
this._toDispose = [];
this._toDispose.push(DomUtils.addStandardDisposableListener(domNode, 'keydown', (e) => this._onKeyDown(e)));
this._toDispose.push(DomUtils.addStandardDisposableListener(domNode, 'keypress', (e) => this._onKeyPress(e)));
this._toDispose.push(DomUtils.addStandardDisposableListener(domNode, 'keyup', (e) => this._onKeyUp(e)));
this._toDispose.push(DomUtils.addDisposableListener(domNode, 'input', (e) => this._onInput(e)));
}
public dispose(): void {
this._toDispose = Lifecycle.disposeAll(this._toDispose);
this._listeners = null;
this._previousKeyDown = null;
this._previousEventType = null;
}
public addListener(type:string, callback:(event:DomUtils.IKeyboardEvent)=>void):()=>void {
this._listeners[type] = callback;
return () => {
if (!this._listeners) {
// disposed
return;
}
this._listeners[type] = null;
};
}
public addListener2(type:string, callback:(event:DomUtils.IKeyboardEvent)=>void): Lifecycle.IDisposable {
let unbind = this.addListener(type, callback);
return {
dispose: () => {
unbind();
}
};
}
private _fire(type:string, event:any): void {
if (this._listeners.hasOwnProperty(type)) {
this._listeners[type](event);
}
}
private _onKeyDown(e:DomUtils.IKeyboardEvent): void {
this._previousKeyDown = e.clone();
this._previousEventType = 'keydown';
this._fire('keydown', e);
}
private _onKeyPress(e:DomUtils.IKeyboardEvent): void {
if (this._previousKeyDown) {
if (e.shiftKey && this._previousKeyDown.asKeybinding() !== e.asKeybinding()) {
// Looks like Shift changed the resulting character, so eat it up!
e.shiftKey = false;
}
if (this._previousEventType === 'keypress') {
// Ensure a keydown is alwas fired before a keypress
this._fire('keydown', this._previousKeyDown);
}
}
this._previousEventType = 'keypress';
this._fire('keypress', e);
}
private _onInput(e:Event): void {
this._fire('input', e);
}
private _onKeyUp(e:DomUtils.IKeyboardEvent): void {
this._fire('keyup', e);
}
}
......@@ -5,8 +5,8 @@
"use strict";
import Platform = require('vs/base/common/platform');
import Browser = require('vs/base/browser/browser');
import * as Platform from 'vs/base/common/platform';
import * as Browser from 'vs/base/browser/browser';
import {KeyMod, KeyCode, BinaryKeybindings} from 'vs/base/common/keyCodes';
let KEY_CODE_MAP: {[keyCode:number]:KeyCode} = {};
......
......@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import Platform = require('vs/base/common/platform');
import Browser = require('vs/base/browser/browser');
import IframeUtils = require('vs/base/browser/iframe');
import * as Platform from 'vs/base/common/platform';
import * as Browser from 'vs/base/browser/browser';
import {IframeUtils} from 'vs/base/browser/iframe';
export interface IMouseEvent {
browserEvent:MouseEvent;
......@@ -63,7 +63,7 @@ export class StandardMouseEvent implements IMouseEvent {
this.altKey = e.altKey;
this.metaKey = e.metaKey;
var readClientCoords = () => {
let readClientCoords = () => {
if (e.clientX || e.clientY) {
this.posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
this.posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
......@@ -72,7 +72,7 @@ export class StandardMouseEvent implements IMouseEvent {
return false;
};
var readPageCoords = () => {
let readPageCoords = () => {
if (e.pageX || e.pageY) {
this.posx = e.pageX;
this.posy = e.pageY;
......@@ -81,7 +81,7 @@ export class StandardMouseEvent implements IMouseEvent {
return false;
};
var test1 = readPageCoords, test2 = readClientCoords;
let test1 = readPageCoords, test2 = readClientCoords;
if (Browser.isIE10) {
// The if A elseif B logic here is inversed in IE10 due to an IE10 issue
test1 = readClientCoords;
......@@ -93,7 +93,7 @@ export class StandardMouseEvent implements IMouseEvent {
}
// Find the position of the iframe this code is executing in relative to the iframe where the event was captured.
var iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(self, e.view);
let iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(self, e.view);
this.posx -= iframeOffsets.left;
this.posy -= iframeOffsets.top;
}
......@@ -171,8 +171,8 @@ export class StandardMouseWheelEvent {
this.deltaX = deltaX;
if (e) {
var e1 = <IWebKitMouseWheelEvent><any>e;
var e2 = <IGeckoMouseWheelEvent><any>e;
let e1 = <IWebKitMouseWheelEvent><any>e;
let e2 = <IGeckoMouseWheelEvent><any>e;
// vertical delta scroll
if (typeof e1.wheelDeltaY !== 'undefined') {
......
......@@ -5,7 +5,6 @@
'use strict';
import EditorCommon = require('vs/editor/common/editorCommon');
import keyboardController = require('vs/base/browser/keyboardController');
import DomUtils = require('vs/base/browser/dom');
import Platform = require('vs/base/common/platform');
import Browser = require('vs/base/browser/browser');
......@@ -132,11 +131,9 @@ class TextAreaWrapper extends Lifecycle.Disposable implements ITextAreaWrapper {
super();
this._textArea = textArea;
let kbController = this._register(new keyboardController.KeyboardController(this._textArea));
this._register(kbController.addListener2('keydown', (e) => this._onKeyDown.fire(new KeyboardEventWrapper(e))));
this._register(kbController.addListener2('keyup', (e) => this._onKeyUp.fire(new KeyboardEventWrapper(e))));
this._register(kbController.addListener2('keypress', (e) => this._onKeyPress.fire(new KeyboardEventWrapper(e))));
this._register(DomUtils.addStandardDisposableListener(this._textArea, 'keydown', (e) => this._onKeyDown.fire(new KeyboardEventWrapper(e))));
this._register(DomUtils.addStandardDisposableListener(this._textArea, 'keyup', (e) => this._onKeyUp.fire(new KeyboardEventWrapper(e))));
this._register(DomUtils.addStandardDisposableListener(this._textArea, 'keypress', (e) => this._onKeyPress.fire(new KeyboardEventWrapper(e))));
this._register(DomUtils.addDisposableListener(this._textArea, 'compositionstart', (e) => this._onCompositionStart.fire()));
this._register(DomUtils.addDisposableListener(this._textArea, 'compositionend', (e) => this._onCompositionEnd.fire()));
this._register(DomUtils.addDisposableListener(this._textArea, 'input', (e) => this._onInput.fire()));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册