提交 ae4472e2 编写于 作者: S Sandeep Somavarapu

Debt: Move viewlet views to views package

上级 9202b6a9
......@@ -8,23 +8,13 @@ import { TPromise } from 'vs/base/common/winjs.base';
import DOM = require('vs/base/browser/dom');
import errors = require('vs/base/common/errors');
import { Registry } from 'vs/platform/platform';
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
import { IAction, IActionRunner, Action } from 'vs/base/common/actions';
import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { Dimension, Builder } from 'vs/base/browser/builder';
import { Action } from 'vs/base/common/actions';
import { ITree, IFocusEvent, ISelectionEvent } from 'vs/base/parts/tree/browser/tree';
import { prepareActions } from 'vs/workbench/browser/actions';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { DelayedDragHandler } from 'vs/base/browser/dnd';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { CollapsibleView, CollapsibleState, FixedCollapsibleView, IView } from 'vs/base/browser/ui/splitview/splitview';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { Composite, CompositeDescriptor, CompositeRegistry } from 'vs/workbench/browser/composite';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IMessageService } from 'vs/platform/message/common/message';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IThemable } from 'vs/platform/theme/common/styler';
export abstract class Viewlet extends Composite implements IViewlet {
......@@ -287,327 +277,4 @@ export class CollapseAction extends Action {
return TPromise.as(null);
});
}
}
export interface IViewletView extends IView, IThemable {
id?: string;
create(): TPromise<void>;
setVisible(visible: boolean): TPromise<void>;
getActions(): IAction[];
getSecondaryActions(): IAction[];
getActionItem(action: IAction): IActionItem;
showHeader(): boolean;
hideHeader(): boolean;
shutdown(): void;
focusBody(): void;
isExpanded(): boolean;
expand(): void;
collapse(): void;
}
/**
* The AdaptiveCollapsibleViewletView can grow with the content inside dynamically.
*/
export abstract class AdaptiveCollapsibleViewletView extends FixedCollapsibleView implements IViewletView {
protected treeContainer: HTMLElement;
protected tree: ITree;
protected toDispose: IDisposable[];
protected isVisible: boolean;
protected toolBar: ToolBar;
protected actionRunner: IActionRunner;
protected isDisposed: boolean;
private dragHandler: DelayedDragHandler;
constructor(
actionRunner: IActionRunner,
initialBodySize: number,
collapsed: boolean,
private viewName: string,
protected keybindingService: IKeybindingService,
protected contextMenuService: IContextMenuService
) {
super({
expandedBodySize: initialBodySize,
initialState: collapsed ? CollapsibleState.COLLAPSED : CollapsibleState.EXPANDED,
ariaHeaderLabel: viewName,
headerSize: 22,
});
this.actionRunner = actionRunner;
this.toDispose = [];
}
protected changeState(state: CollapsibleState): void {
updateTreeVisibility(this.tree, state === CollapsibleState.EXPANDED);
super.changeState(state);
}
public create(): TPromise<void> {
return TPromise.as(null);
}
public renderHeader(container: HTMLElement): void {
// Tool bar
this.toolBar = new ToolBar($('div.actions').appendTo(container).getHTMLElement(), this.contextMenuService, {
orientation: ActionsOrientation.HORIZONTAL,
actionItemProvider: (action) => this.getActionItem(action),
ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.viewName),
getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id)
});
this.toolBar.actionRunner = this.actionRunner;
this.updateActions();
// Expand on drag over
this.dragHandler = new DelayedDragHandler(container, () => {
if (!this.isExpanded()) {
this.expand();
}
});
}
protected updateActions(): void {
this.toolBar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))();
}
protected renderViewTree(container: HTMLElement): HTMLElement {
return renderViewTree(container);
}
public getViewer(): ITree {
return this.tree;
}
public setVisible(visible: boolean): TPromise<void> {
this.isVisible = visible;
updateTreeVisibility(this.tree, visible && this.state === CollapsibleState.EXPANDED);
return TPromise.as(null);
}
public focusBody(): void {
focus(this.tree);
}
protected reveal(element: any, relativeTop?: number): TPromise<void> {
return reveal(this.tree, element, relativeTop);
}
protected layoutBody(size: number): void {
this.treeContainer.style.height = size + 'px';
this.tree.layout(size);
}
public getActions(): IAction[] {
return [];
}
public getSecondaryActions(): IAction[] {
return [];
}
public getActionItem(action: IAction): IActionItem {
return null;
}
public shutdown(): void {
// Subclass to implement
}
public dispose(): void {
this.isDisposed = true;
this.treeContainer = null;
this.tree.dispose();
this.dragHandler.dispose();
this.toDispose = dispose(this.toDispose);
if (this.toolBar) {
this.toolBar.dispose();
}
super.dispose();
}
}
export abstract class CollapsibleViewletView extends CollapsibleView implements IViewletView {
protected treeContainer: HTMLElement;
protected tree: ITree;
protected toDispose: IDisposable[];
protected isVisible: boolean;
protected toolBar: ToolBar;
protected actionRunner: IActionRunner;
protected isDisposed: boolean;
private dragHandler: DelayedDragHandler;
constructor(
actionRunner: IActionRunner,
collapsed: boolean,
private viewName: string,
protected messageService: IMessageService,
protected keybindingService: IKeybindingService,
protected contextMenuService: IContextMenuService,
headerSize?: number,
minimumSize?: number
) {
super({
minimumSize: minimumSize === void 0 ? 5 * 22 : minimumSize,
initialState: collapsed ? CollapsibleState.COLLAPSED : CollapsibleState.EXPANDED,
ariaHeaderLabel: viewName,
headerSize
});
this.actionRunner = actionRunner;
this.toDispose = [];
}
protected changeState(state: CollapsibleState): void {
updateTreeVisibility(this.tree, state === CollapsibleState.EXPANDED);
super.changeState(state);
}
public create(): TPromise<void> {
return TPromise.as(null);
}
public renderHeader(container: HTMLElement): void {
// Tool bar
this.toolBar = new ToolBar($('div.actions').appendTo(container).getHTMLElement(), this.contextMenuService, {
orientation: ActionsOrientation.HORIZONTAL,
actionItemProvider: (action) => this.getActionItem(action),
ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.viewName),
getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id)
});
this.toolBar.actionRunner = this.actionRunner;
this.updateActions();
// Expand on drag over
this.dragHandler = new DelayedDragHandler(container, () => {
if (!this.isExpanded()) {
this.expand();
}
});
}
protected updateActions(): void {
this.toolBar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))();
}
protected renderViewTree(container: HTMLElement): HTMLElement {
return renderViewTree(container);
}
public getViewer(): ITree {
return this.tree;
}
public setVisible(visible: boolean): TPromise<void> {
this.isVisible = visible;
updateTreeVisibility(this.tree, visible && this.state === CollapsibleState.EXPANDED);
return TPromise.as(null);
}
public focusBody(): void {
focus(this.tree);
}
protected reveal(element: any, relativeTop?: number): TPromise<void> {
return reveal(this.tree, element, relativeTop);
}
public layoutBody(size: number): void {
this.treeContainer.style.height = size + 'px';
this.tree.layout(size);
}
public getActions(): IAction[] {
return [];
}
public getSecondaryActions(): IAction[] {
return [];
}
public getActionItem(action: IAction): IActionItem {
return null;
}
public shutdown(): void {
// Subclass to implement
}
public dispose(): void {
this.isDisposed = true;
this.treeContainer = null;
this.tree.dispose();
if (this.dragHandler) {
this.dragHandler.dispose();
}
this.toDispose = dispose(this.toDispose);
if (this.toolBar) {
this.toolBar.dispose();
}
super.dispose();
}
}
function renderViewTree(container: HTMLElement): HTMLElement {
const treeContainer = document.createElement('div');
container.appendChild(treeContainer);
return treeContainer;
}
function updateTreeVisibility(tree: ITree, isVisible: boolean): void {
if (!tree) {
return;
}
if (isVisible) {
$(tree.getHTMLElement()).show();
} else {
$(tree.getHTMLElement()).hide(); // make sure the tree goes out of the tabindex world by hiding it
}
if (isVisible) {
tree.onVisible();
} else {
tree.onHidden();
}
}
function focus(tree: ITree): void {
if (!tree) {
return; // return early if viewlet has not yet been created
}
// Make sure the current selected element is revealed
const selection = tree.getSelection();
if (selection.length > 0) {
reveal(tree, selection[0], 0.5).done(null, errors.onUnexpectedError);
}
// Pass Focus to Viewer
tree.DOMFocus();
}
function reveal(tree: ITree, element: any, relativeTop?: number): TPromise<void> {
if (!tree) {
return TPromise.as(null); // return early if viewlet has not yet been created
}
return tree.reveal(element, relativeTop);
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IActionRunner } from 'vs/base/common/actions';
import { IViewletView } from 'vs/workbench/browser/viewlet';
import { IViewletView } from 'vs/workbench/parts/views/browser/views';
// Debug view registration
......
......@@ -12,7 +12,8 @@ import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { SplitView, HeaderView } from 'vs/base/browser/ui/splitview/splitview';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { Scope } from 'vs/workbench/common/memento';
import { IViewletView, Viewlet } from 'vs/workbench/browser/viewlet';
import { Viewlet } from 'vs/workbench/browser/viewlet';
import { IViewletView } from 'vs/workbench/parts/views/browser/views';
import { IDebugService, VIEWLET_ID, State } from 'vs/workbench/parts/debug/common/debug';
import { DebugViewRegistry } from 'vs/workbench/parts/debug/browser/debugViewRegistry';
import { StartAction, ToggleReplAction, ConfigureAction } from 'vs/workbench/parts/debug/browser/debugActions';
......
......@@ -16,7 +16,8 @@ import { prepareActions } from 'vs/workbench/browser/actions';
import { IHighlightEvent, ITree } from 'vs/base/parts/tree/browser/tree';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { CollapsibleState } from 'vs/base/browser/ui/splitview/splitview';
import { CollapsibleViewletView, AdaptiveCollapsibleViewletView, CollapseAction } from 'vs/workbench/browser/viewlet';
import { CollapseAction } from 'vs/workbench/browser/viewlet';
import { CollapsibleViewletView, AdaptiveCollapsibleViewletView } from 'vs/workbench/parts/views/browser/views';
import { IDebugService, State, IBreakpoint, IExpression, CONTEXT_BREAKPOINTS_FOCUSED, CONTEXT_WATCH_EXPRESSIONS_FOCUSED, CONTEXT_VARIABLES_FOCUSED } from 'vs/workbench/parts/debug/common/debug';
import { Expression, Variable, ExceptionBreakpoint, FunctionBreakpoint, Thread, StackFrame, Breakpoint, ThreadAndProcessIds } from 'vs/workbench/parts/debug/common/debugModel';
import * as viewer from 'vs/workbench/parts/debug/electron-browser/debugViewer';
......
......@@ -12,7 +12,8 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { Dimension, Builder } from 'vs/base/browser/builder';
import { Scope } from 'vs/workbench/common/memento';
import { VIEWLET_ID, ExplorerViewletVisibleContext, IFilesConfiguration } from 'vs/workbench/parts/files/common/files';
import { IViewletView, Viewlet } from 'vs/workbench/browser/viewlet';
import { Viewlet } from 'vs/workbench/browser/viewlet';
import { IViewletView } from 'vs/workbench/parts/views/browser/views';
import { SplitView } from 'vs/base/browser/ui/splitview/splitview';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ActionRunner, FileViewletState } from 'vs/workbench/parts/files/browser/views/explorerViewer';
......
......@@ -24,7 +24,8 @@ import { toResource } from 'vs/workbench/common/editor';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { IEditorGroupService } from 'vs/workbench/services/group/common/groupService';
import * as DOM from 'vs/base/browser/dom';
import { CollapseAction, CollapsibleViewletView } from 'vs/workbench/browser/viewlet';
import { CollapseAction } from 'vs/workbench/browser/viewlet';
import { CollapsibleViewletView } from 'vs/workbench/parts/views/browser/views';
import { FileStat } from 'vs/workbench/parts/files/common/explorerViewModel';
import { IListService } from 'vs/platform/list/browser/listService';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
......
......@@ -19,7 +19,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IEditorStacksModel, IStacksModelChangeEvent, IEditorGroup } from 'vs/workbench/common/editor';
import { SaveAllAction } from 'vs/workbench/parts/files/browser/fileActions';
import { AdaptiveCollapsibleViewletView } from 'vs/workbench/browser/viewlet';
import { AdaptiveCollapsibleViewletView } from 'vs/workbench/parts/views/browser/views';
import { IFilesConfiguration, VIEWLET_ID, OpenEditorsFocussedContext, ExplorerFocussedContext } from 'vs/workbench/parts/files/common/files';
import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
......
......@@ -6,7 +6,7 @@
import 'vs/css!./media/views';
import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable, dispose, empty as EmptyDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { CollapsibleViewletView } from 'vs/workbench/browser/viewlet';
import { CollapsibleViewletView } from 'vs/workbench/parts/views/browser/views';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TPromise } from 'vs/base/common/winjs.base';
import * as DOM from 'vs/base/browser/dom';
......
/*---------------------------------------------------------------------------------------------
* 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 { TPromise } from 'vs/base/common/winjs.base';
import { IThemable } from 'vs/platform/theme/common/styler';
import * as errors from 'vs/base/common/errors';
import { $ } from 'vs/base/browser/builder';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { IAction, IActionRunner } from 'vs/base/common/actions';
import { IActionItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { prepareActions } from 'vs/workbench/browser/actions';
import { ITree } from 'vs/base/parts/tree/browser/tree';
import { DelayedDragHandler } from 'vs/base/browser/dnd';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IMessageService } from 'vs/platform/message/common/message';
import { CollapsibleView, CollapsibleState, FixedCollapsibleView, IView } from 'vs/base/browser/ui/splitview/splitview';
export interface IViewletView extends IView, IThemable {
id?: string;
create(): TPromise<void>;
setVisible(visible: boolean): TPromise<void>;
getActions(): IAction[];
getSecondaryActions(): IAction[];
getActionItem(action: IAction): IActionItem;
showHeader(): boolean;
hideHeader(): boolean;
shutdown(): void;
focusBody(): void;
isExpanded(): boolean;
expand(): void;
collapse(): void;
}
/**
* The AdaptiveCollapsibleViewletView can grow with the content inside dynamically.
*/
export abstract class AdaptiveCollapsibleViewletView extends FixedCollapsibleView implements IViewletView {
protected treeContainer: HTMLElement;
protected tree: ITree;
protected toDispose: IDisposable[];
protected isVisible: boolean;
protected toolBar: ToolBar;
protected actionRunner: IActionRunner;
protected isDisposed: boolean;
private dragHandler: DelayedDragHandler;
constructor(
actionRunner: IActionRunner,
initialBodySize: number,
collapsed: boolean,
private viewName: string,
protected keybindingService: IKeybindingService,
protected contextMenuService: IContextMenuService
) {
super({
expandedBodySize: initialBodySize,
initialState: collapsed ? CollapsibleState.COLLAPSED : CollapsibleState.EXPANDED,
ariaHeaderLabel: viewName,
headerSize: 22,
});
this.actionRunner = actionRunner;
this.toDispose = [];
}
protected changeState(state: CollapsibleState): void {
updateTreeVisibility(this.tree, state === CollapsibleState.EXPANDED);
super.changeState(state);
}
public create(): TPromise<void> {
return TPromise.as(null);
}
public renderHeader(container: HTMLElement): void {
// Tool bar
this.toolBar = new ToolBar($('div.actions').appendTo(container).getHTMLElement(), this.contextMenuService, {
orientation: ActionsOrientation.HORIZONTAL,
actionItemProvider: (action) => this.getActionItem(action),
ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.viewName),
getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id)
});
this.toolBar.actionRunner = this.actionRunner;
this.updateActions();
// Expand on drag over
this.dragHandler = new DelayedDragHandler(container, () => {
if (!this.isExpanded()) {
this.expand();
}
});
}
protected updateActions(): void {
this.toolBar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))();
}
protected renderViewTree(container: HTMLElement): HTMLElement {
return renderViewTree(container);
}
public getViewer(): ITree {
return this.tree;
}
public setVisible(visible: boolean): TPromise<void> {
this.isVisible = visible;
updateTreeVisibility(this.tree, visible && this.state === CollapsibleState.EXPANDED);
return TPromise.as(null);
}
public focusBody(): void {
focus(this.tree);
}
protected reveal(element: any, relativeTop?: number): TPromise<void> {
return reveal(this.tree, element, relativeTop);
}
protected layoutBody(size: number): void {
this.treeContainer.style.height = size + 'px';
this.tree.layout(size);
}
public getActions(): IAction[] {
return [];
}
public getSecondaryActions(): IAction[] {
return [];
}
public getActionItem(action: IAction): IActionItem {
return null;
}
public shutdown(): void {
// Subclass to implement
}
public dispose(): void {
this.isDisposed = true;
this.treeContainer = null;
this.tree.dispose();
this.dragHandler.dispose();
this.toDispose = dispose(this.toDispose);
if (this.toolBar) {
this.toolBar.dispose();
}
super.dispose();
}
}
export abstract class CollapsibleViewletView extends CollapsibleView implements IViewletView {
protected treeContainer: HTMLElement;
protected tree: ITree;
protected toDispose: IDisposable[];
protected isVisible: boolean;
protected toolBar: ToolBar;
protected actionRunner: IActionRunner;
protected isDisposed: boolean;
private dragHandler: DelayedDragHandler;
constructor(
actionRunner: IActionRunner,
collapsed: boolean,
private viewName: string,
protected messageService: IMessageService,
protected keybindingService: IKeybindingService,
protected contextMenuService: IContextMenuService,
headerSize?: number,
minimumSize?: number
) {
super({
minimumSize: minimumSize === void 0 ? 5 * 22 : minimumSize,
initialState: collapsed ? CollapsibleState.COLLAPSED : CollapsibleState.EXPANDED,
ariaHeaderLabel: viewName,
headerSize
});
this.actionRunner = actionRunner;
this.toDispose = [];
}
protected changeState(state: CollapsibleState): void {
updateTreeVisibility(this.tree, state === CollapsibleState.EXPANDED);
super.changeState(state);
}
public create(): TPromise<void> {
return TPromise.as(null);
}
public renderHeader(container: HTMLElement): void {
// Tool bar
this.toolBar = new ToolBar($('div.actions').appendTo(container).getHTMLElement(), this.contextMenuService, {
orientation: ActionsOrientation.HORIZONTAL,
actionItemProvider: (action) => this.getActionItem(action),
ariaLabel: nls.localize('viewToolbarAriaLabel', "{0} actions", this.viewName),
getKeyBinding: (action) => this.keybindingService.lookupKeybinding(action.id)
});
this.toolBar.actionRunner = this.actionRunner;
this.updateActions();
// Expand on drag over
this.dragHandler = new DelayedDragHandler(container, () => {
if (!this.isExpanded()) {
this.expand();
}
});
}
protected updateActions(): void {
this.toolBar.setActions(prepareActions(this.getActions()), prepareActions(this.getSecondaryActions()))();
}
protected renderViewTree(container: HTMLElement): HTMLElement {
return renderViewTree(container);
}
public getViewer(): ITree {
return this.tree;
}
public setVisible(visible: boolean): TPromise<void> {
this.isVisible = visible;
updateTreeVisibility(this.tree, visible && this.state === CollapsibleState.EXPANDED);
return TPromise.as(null);
}
public focusBody(): void {
focus(this.tree);
}
protected reveal(element: any, relativeTop?: number): TPromise<void> {
return reveal(this.tree, element, relativeTop);
}
public layoutBody(size: number): void {
this.treeContainer.style.height = size + 'px';
this.tree.layout(size);
}
public getActions(): IAction[] {
return [];
}
public getSecondaryActions(): IAction[] {
return [];
}
public getActionItem(action: IAction): IActionItem {
return null;
}
public shutdown(): void {
// Subclass to implement
}
public dispose(): void {
this.isDisposed = true;
this.treeContainer = null;
this.tree.dispose();
if (this.dragHandler) {
this.dragHandler.dispose();
}
this.toDispose = dispose(this.toDispose);
if (this.toolBar) {
this.toolBar.dispose();
}
super.dispose();
}
}
function updateTreeVisibility(tree: ITree, isVisible: boolean): void {
if (!tree) {
return;
}
if (isVisible) {
$(tree.getHTMLElement()).show();
} else {
$(tree.getHTMLElement()).hide(); // make sure the tree goes out of the tabindex world by hiding it
}
if (isVisible) {
tree.onVisible();
} else {
tree.onHidden();
}
}
function focus(tree: ITree): void {
if (!tree) {
return; // return early if viewlet has not yet been created
}
// Make sure the current selected element is revealed
const selection = tree.getSelection();
if (selection.length > 0) {
reveal(tree, selection[0], 0.5).done(null, errors.onUnexpectedError);
}
// Pass Focus to Viewer
tree.DOMFocus();
}
function renderViewTree(container: HTMLElement): HTMLElement {
const treeContainer = document.createElement('div');
container.appendChild(treeContainer);
return treeContainer;
}
function reveal(tree: ITree, element: any, relativeTop?: number): TPromise<void> {
if (!tree) {
return TPromise.as(null); // return early if viewlet has not yet been created
}
return tree.reveal(element, relativeTop);
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
import Event, { Emitter } from 'vs/base/common/event';
import { IActionRunner } from 'vs/base/common/actions';
import { IViewletView as IView } from 'vs/workbench/browser/viewlet';
import { IViewletView as IView } from 'vs/workbench/parts/views/browser/views';
import { ITreeViewDataProvider } from 'vs/workbench/parts/views/common/views';
export class ViewLocation {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册