@genexus/designer-common
Advanced tools
Comparing version 0.0.2-beta.8 to 0.0.2
@@ -156,3 +156,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
if (command) { | ||
let eventArgs = { undo: true, itemsAffected: command.itemsAffected }; | ||
let eventArgs = { undo: false, itemsAffected: command.itemsAffected }; | ||
yield this.onBeforeUndoRedo(eventArgs); | ||
@@ -159,0 +159,0 @@ yield command.redo(); |
@@ -13,2 +13,5 @@ import { MaybePromise } from "../types"; | ||
} | ||
export declare namespace CommandData { | ||
function is(arg: any): arg is CommandData; | ||
} | ||
export declare type CommandData = { | ||
@@ -15,0 +18,0 @@ id: string; |
@@ -20,2 +20,10 @@ export class Command { | ||
} | ||
export var CommandData; | ||
(function (CommandData) { | ||
function is(arg) { | ||
return !!arg | ||
&& 'id' in arg; | ||
} | ||
CommandData.is = is; | ||
})(CommandData || (CommandData = {})); | ||
//# sourceMappingURL=command.js.map |
@@ -1,4 +0,3 @@ | ||
import { Command } from "./command"; | ||
import { Command, CommandData } from "./command"; | ||
export declare class CompositeCommand extends Command { | ||
static ID: string; | ||
private _commands; | ||
@@ -12,7 +11,11 @@ constructor(description?: string); | ||
undo(): Promise<boolean>; | ||
getData(): Promise<{ | ||
id: string; | ||
data: import("./command").CommandData[]; | ||
}>; | ||
getData(): Promise<CompositeCommandData>; | ||
} | ||
export declare namespace CompositeCommandData { | ||
const ID = "Composite"; | ||
function is(arg: any): arg is CompositeCommandData; | ||
} | ||
export declare type CompositeCommandData = CommandData & { | ||
data: CommandData[]; | ||
}; | ||
//# sourceMappingURL=composite-command.d.ts.map |
@@ -10,3 +10,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
import { Command } from "./command"; | ||
import { Command, CommandData } from "./command"; | ||
export class CompositeCommand extends Command { | ||
@@ -18,3 +18,3 @@ constructor(description) { | ||
get id() { | ||
return CompositeCommand.ID; | ||
return CompositeCommandData.ID; | ||
} | ||
@@ -58,3 +58,13 @@ addCommand(command) { | ||
} | ||
CompositeCommand.ID = 'Composite'; | ||
export var CompositeCommandData; | ||
(function (CompositeCommandData) { | ||
CompositeCommandData.ID = 'Composite'; | ||
function is(arg) { | ||
return CommandData.is(arg) | ||
&& arg.id === CompositeCommandData.ID | ||
&& 'data' in arg | ||
&& Array.isArray(arg.data); | ||
} | ||
CompositeCommandData.is = is; | ||
})(CompositeCommandData || (CompositeCommandData = {})); | ||
//# sourceMappingURL=composite-command.js.map |
export declare namespace CommonServiceIds { | ||
const DesignerHost = "DesignerHost"; | ||
const HostContextMenu = "HostContextMenu"; | ||
const ContextMenu = "ContextMenu"; | ||
const Selection = "Selection"; | ||
const GxmlNodeFactory = "GxmlNodeFactory"; | ||
const InteropContextMenu = "InteropContextMenu"; | ||
const InteropContextMenuResolver = "InteropContextMenuResolver"; | ||
const InteropKeybinding = "InteropKeybinding"; | ||
const InteropSelection = "InteropSelection"; | ||
const InteropModel = "InteropModel"; | ||
const InteropDragDrop = "InteropDragDrop"; | ||
} | ||
//# sourceMappingURL=common-services-ids.d.ts.map |
export var CommonServiceIds; | ||
(function (CommonServiceIds) { | ||
CommonServiceIds.DesignerHost = 'DesignerHost'; | ||
CommonServiceIds.HostContextMenu = 'HostContextMenu'; | ||
CommonServiceIds.ContextMenu = 'ContextMenu'; | ||
CommonServiceIds.Selection = 'Selection'; | ||
CommonServiceIds.GxmlNodeFactory = 'GxmlNodeFactory'; | ||
CommonServiceIds.InteropContextMenu = 'InteropContextMenu'; | ||
CommonServiceIds.InteropContextMenuResolver = 'InteropContextMenuResolver'; | ||
CommonServiceIds.InteropKeybinding = 'InteropKeybinding'; | ||
CommonServiceIds.InteropSelection = 'InteropSelection'; | ||
CommonServiceIds.InteropModel = 'InteropModel'; | ||
CommonServiceIds.InteropDragDrop = 'InteropDragDrop'; | ||
})(CommonServiceIds || (CommonServiceIds = {})); | ||
//# sourceMappingURL=common-services-ids.js.map |
@@ -9,2 +9,3 @@ import { MaybePromise } from "../types"; | ||
subMenu?: MenuCommandData[]; | ||
iconName?: string; | ||
}; | ||
@@ -21,8 +22,26 @@ export declare type PointData = { | ||
subMenu?: MenuCommand[]; | ||
iconName?: string; | ||
action?: () => void; | ||
}; | ||
export interface IHostContextMenuSerivce { | ||
export interface IInteropContextMenuSerivce { | ||
show(anchor: PointData, commands: MenuCommandData[]): MaybePromise<string>; | ||
hide(): void; | ||
} | ||
export interface IInteropContextMenuResolverService { | ||
show(anchor: PointData, nodeId: string): void; | ||
} | ||
export declare type KeyboardEventData = { | ||
readonly altKey: boolean; | ||
readonly code: string; | ||
readonly ctrlKey: boolean; | ||
readonly isComposing: boolean; | ||
readonly key: string; | ||
readonly location: number; | ||
readonly metaKey: boolean; | ||
readonly repeat: boolean; | ||
readonly shiftKey: boolean; | ||
}; | ||
export interface IInteropKeybindingService { | ||
dispatch(key: KeyboardEventData): MaybePromise<boolean>; | ||
} | ||
export interface IContextMenuSerivce { | ||
@@ -29,0 +48,0 @@ show(anchor: Point, commands: MenuCommand[]): void; |
@@ -20,3 +20,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
try { | ||
let hostSrv = this._services.getService(CommonServiceIds.HostContextMenu); | ||
let hostSrv = this._services.getService(CommonServiceIds.InteropContextMenu); | ||
let cmdId = yield hostSrv.show(anchor, this._convertCommands(commands)); | ||
@@ -36,3 +36,3 @@ if (cmdId) { | ||
this._cleanup(); | ||
let hostSrv = this._services.getService(CommonServiceIds.HostContextMenu); | ||
let hostSrv = this._services.getService(CommonServiceIds.InteropContextMenu); | ||
hostSrv.hide(); | ||
@@ -47,3 +47,4 @@ } | ||
label: c.label, | ||
subMenu: c.subMenu ? this._convertCommands(c.subMenu) : [] | ||
subMenu: c.subMenu ? this._convertCommands(c.subMenu) : [], | ||
iconName: c.iconName | ||
}; | ||
@@ -50,0 +51,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
import { GxmlDocument } from "../gxml"; | ||
import { GxmlDocument, GxmlNode } from "../gxml"; | ||
import { IComponent } from "./icomponent"; | ||
@@ -18,2 +18,3 @@ import { DesignerFactoryRegistry, IDesigner } from "./idesigner"; | ||
getDesigner(component: IComponent): IDesigner; | ||
getComponentByNode(node: GxmlNode): IComponent; | ||
addService(name: string, service: any): void; | ||
@@ -23,4 +24,5 @@ removeService(name: string): void; | ||
protected updateDesigners(): void; | ||
private _disaposeDesigner; | ||
private _createDesigner; | ||
} | ||
//# sourceMappingURL=designer-host.d.ts.map |
@@ -15,2 +15,10 @@ import { GenericRegistry } from "../registry"; | ||
} | ||
getComponentByNode(node) { | ||
let component; | ||
this._designers.forEach((des, comp) => { | ||
if (des.model == node) | ||
component = comp; | ||
}); | ||
return component; | ||
} | ||
addService(name, service) { | ||
@@ -26,5 +34,11 @@ this._services.add(name, service); | ||
updateDesigners() { | ||
// this._designers.forEach((d) => d.dispose()); | ||
// this._designers.clear(); | ||
let visited = new Set(); | ||
for (let component of this.components) { | ||
let designer = this._designers.get(component); | ||
if (designer && designer.model !== this.document.getNodeById(component.site.id)) { | ||
this._disaposeDesigner(designer); | ||
designer = undefined; | ||
} | ||
if (!designer) { | ||
@@ -40,13 +54,16 @@ designer = this._createDesigner(component); | ||
let d = this._designers.get(c); | ||
try { | ||
d.dispose(); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
} | ||
finally { | ||
this._designers.delete(c); | ||
} | ||
this._disaposeDesigner(d); | ||
} | ||
} | ||
_disaposeDesigner(designer) { | ||
try { | ||
designer.dispose(); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
} | ||
finally { | ||
this._designers.delete(designer.component); | ||
} | ||
} | ||
_createDesigner(component) { | ||
@@ -53,0 +70,0 @@ let node = this.document.getNodeById(component.site.id); |
import { CompositeDisposable } from "../composite-disposable"; | ||
import { GxmlNode } from "../gxml/gxml-node"; | ||
import { MaybePromise } from "../types"; | ||
import { MenuCommand } from "./context-menu-service"; | ||
import { IComponent } from "./icomponent"; | ||
import { IDesigner } from "./idesigner"; | ||
import { CommandsRequest, IDesigner } from "./idesigner"; | ||
export declare class Designer implements IDesigner { | ||
@@ -17,6 +18,8 @@ readonly component: IComponent; | ||
canCopy(): boolean; | ||
canPaste(): boolean; | ||
canPropagateGetCommands(): boolean; | ||
doDefaultAction(): void; | ||
getCommands(event: MouseEvent): MenuCommand[]; | ||
getCommands(request: CommandsRequest): MaybePromise<MenuCommand[]>; | ||
dispose(): void; | ||
} | ||
//# sourceMappingURL=designer.d.ts.map |
@@ -9,6 +9,4 @@ import { CompositeDisposable } from "../composite-disposable"; | ||
initializeSurface(surface) { | ||
// console.log('Init Surface', surface); | ||
} | ||
onWillDestroySurface() { | ||
// console.log('Destroy surface', this); | ||
} | ||
@@ -27,5 +25,11 @@ canSelect() { | ||
} | ||
canPaste() { | ||
return false; | ||
} | ||
canPropagateGetCommands() { | ||
return true; | ||
} | ||
doDefaultAction() { | ||
} | ||
getCommands(event) { | ||
getCommands(request) { | ||
return []; | ||
@@ -32,0 +36,0 @@ } |
import { GxmlNode } from "../gxml"; | ||
import { Registry } from "../registry"; | ||
import { MaybePromise } from "../types"; | ||
import { MenuCommand } from "./context-menu-service"; | ||
@@ -9,2 +10,6 @@ import { IComponent } from "./icomponent"; | ||
} | ||
export declare type CommandsRequest = { | ||
event: MouseEvent; | ||
composedPath: HTMLElement[]; | ||
}; | ||
export interface IDesigner { | ||
@@ -19,6 +24,8 @@ readonly component: IComponent; | ||
canCopy(): boolean; | ||
canPaste(): boolean; | ||
canPropagateGetCommands(): boolean; | ||
doDefaultAction(): void; | ||
getCommands(event: MouseEvent): MenuCommand[]; | ||
getCommands(request: CommandsRequest): MaybePromise<MenuCommand[]>; | ||
dispose(): void; | ||
} | ||
//# sourceMappingURL=idesigner.d.ts.map |
@@ -0,1 +1,2 @@ | ||
export * from './common-flags'; | ||
export * from './common-services-ids'; | ||
@@ -5,2 +6,3 @@ export * from './context-menu-service'; | ||
export * from './designer-host'; | ||
export * from './drag-drop-service'; | ||
export * from './icomponent'; | ||
@@ -10,3 +12,5 @@ export * from './icontainer'; | ||
export * from './idesigner-host'; | ||
export * from './interop-context-menu-resolver-service'; | ||
export * from './imenu-command'; | ||
export * from './model-service'; | ||
export * from './selection-service'; | ||
@@ -13,0 +17,0 @@ export * from './iservice-container'; |
@@ -0,1 +1,2 @@ | ||
export * from './common-flags'; | ||
export * from './common-services-ids'; | ||
@@ -5,2 +6,3 @@ export * from './context-menu-service'; | ||
export * from './designer-host'; | ||
export * from './drag-drop-service'; | ||
export * from './icomponent'; | ||
@@ -10,3 +12,5 @@ export * from './icontainer'; | ||
export * from './idesigner-host'; | ||
export * from './interop-context-menu-resolver-service'; | ||
export * from './imenu-command'; | ||
export * from './model-service'; | ||
export * from './selection-service'; | ||
@@ -13,0 +17,0 @@ export * from './iservice-container'; |
@@ -1,3 +0,8 @@ | ||
import { IDisposable } from "../disposable"; | ||
import { IComponent } from "./icomponent"; | ||
import { IComponent } from './icomponent'; | ||
import { IDesignerHost } from './idesigner-host'; | ||
import { IDisposable } from '../disposable'; | ||
import { MaybePromise } from '../types'; | ||
export declare type SelectionChangedEventArgs = { | ||
selection: IComponent[]; | ||
}; | ||
export interface ISelectionService { | ||
@@ -11,3 +16,3 @@ readonly selection: IComponent[]; | ||
setSelection(components: IComponent[]): void; | ||
selectionChanged(callack: (selection: IComponent[]) => void): IDisposable; | ||
selectionChanged(callack: (args: SelectionChangedEventArgs) => void): IDisposable; | ||
isSelected(component: IComponent): boolean; | ||
@@ -28,6 +33,26 @@ } | ||
setSelection(components: IComponent[]): void; | ||
selectionChanged(callack: (selection: IComponent[]) => void): IDisposable; | ||
selectionChanged(callack: (args: SelectionChangedEventArgs) => void): IDisposable; | ||
isSelected(component: IComponent): boolean; | ||
private _onSelectionChanged; | ||
} | ||
export declare type InteropSelectionChangedEventArgs = { | ||
selection: string[]; | ||
}; | ||
export interface IInteropSelectionService { | ||
onChanged(args: InteropSelectionChangedEventArgs): MaybePromise<void>; | ||
} | ||
export declare class SelectionSynchronizer implements IDisposable { | ||
private _designerHost; | ||
private _disposables; | ||
private _interopService; | ||
private _ignoreHostChanges; | ||
private _ignoreDesignerChanges; | ||
constructor(designerHost: IDesignerHost); | ||
get interopService(): IInteropSelectionService; | ||
private _onHostSelectionChanged; | ||
private _onDesignerSelectionChanged; | ||
private _getSelectionService; | ||
private _getComponentById; | ||
dispose(): void; | ||
} | ||
//# sourceMappingURL=selection-service.d.ts.map |
@@ -1,2 +0,13 @@ | ||
import { Emitter } from "event-kit"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import { CommonServiceIds } from './common-services-ids'; | ||
import { CompositeDisposable } from '../composite-disposable'; | ||
import { Emitter } from '../emitter'; | ||
const EVT_SELECTION_CHANGED = 'selectionChanged'; | ||
@@ -50,5 +61,57 @@ export class SelectionService { | ||
_onSelectionChanged() { | ||
this._emitter.emit(EVT_SELECTION_CHANGED, this.selection); | ||
this._emitter.emit(EVT_SELECTION_CHANGED, { selection: this.selection }); | ||
} | ||
} | ||
export class SelectionSynchronizer { | ||
constructor(designerHost) { | ||
this._designerHost = designerHost; | ||
this._disposables = new CompositeDisposable(); | ||
this._disposables.add(this._getSelectionService().selectionChanged((args) => this._onDesignerSelectionChanged(args))); | ||
this._interopService = { | ||
onChanged: (args) => this._onHostSelectionChanged(args) | ||
}; | ||
} | ||
get interopService() { | ||
return this._interopService; | ||
} | ||
_onHostSelectionChanged(args) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this._ignoreHostChanges) | ||
return; | ||
this._ignoreDesignerChanges = true; | ||
try { | ||
let components = args.selection.map(id => this._getComponentById(id)); | ||
yield this._getSelectionService().setSelection(components); | ||
} | ||
finally { | ||
this._ignoreDesignerChanges = false; | ||
} | ||
}); | ||
} | ||
_onDesignerSelectionChanged(args) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this._ignoreDesignerChanges) | ||
return; | ||
this._ignoreHostChanges = true; | ||
try { | ||
let hostSelService = this._designerHost.getService(CommonServiceIds.InteropSelection); | ||
if (hostSelService) | ||
yield hostSelService.onChanged({ selection: args.selection.map(c => c.site.id) }); | ||
} | ||
finally { | ||
this._ignoreHostChanges = false; | ||
} | ||
}); | ||
} | ||
_getSelectionService() { | ||
return this._designerHost.getService(CommonServiceIds.Selection); | ||
} | ||
_getComponentById(id) { | ||
return this._designerHost.components.find(c => c.site.id === id); | ||
} | ||
//#region IDisposable | ||
dispose() { | ||
this._disposables.dispose(); | ||
} | ||
} | ||
//# sourceMappingURL=selection-service.js.map |
@@ -1,2 +0,3 @@ | ||
import { GxmlNode } from "../gxml-node"; | ||
import { CommandData } from "../../command"; | ||
import { GxmlNode, GxmlNodeData } from "../gxml-node"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
@@ -6,12 +7,22 @@ export declare class InsertNodeCommand extends GxmlCommand { | ||
private _child; | ||
private _index; | ||
constructor(parent: GxmlNode, child: GxmlNode, index: number); | ||
private _position; | ||
constructor(parent: GxmlNode, child: GxmlNode, position: number); | ||
get id(): string; | ||
get parent(): GxmlNode; | ||
get child(): GxmlNode; | ||
get index(): number; | ||
get position(): number; | ||
get changeRoot(): GxmlNode; | ||
do(): boolean; | ||
undo(): boolean; | ||
getData(): InsertNodeCommandData; | ||
} | ||
export declare namespace InsertNodeCommandData { | ||
const ID = "InsertNode"; | ||
function is(arg: any): arg is InsertNodeCommandData; | ||
} | ||
export declare type InsertNodeCommandData = CommandData & { | ||
parentId: string; | ||
child: GxmlNodeData | string; | ||
position: number; | ||
}; | ||
//# sourceMappingURL=insert-node-command.d.ts.map |
@@ -0,12 +1,12 @@ | ||
import { CommandData } from "../../command"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'AddNode'; | ||
export class InsertNodeCommand extends GxmlCommand { | ||
constructor(parent, child, index) { | ||
constructor(parent, child, position) { | ||
super(); | ||
this._parent = parent; | ||
this._child = child; | ||
this._index = index; | ||
this._position = position; | ||
} | ||
get id() { | ||
return ID; | ||
return InsertNodeCommandData.ID; | ||
} | ||
@@ -19,4 +19,4 @@ get parent() { | ||
} | ||
get index() { | ||
return this._index; | ||
get position() { | ||
return this._position; | ||
} | ||
@@ -27,3 +27,3 @@ get changeRoot() { | ||
do() { | ||
this._parent.insertNode(this._child, this._index); | ||
this._parent.insertNode(this._child, this._position); | ||
return true; | ||
@@ -34,3 +34,24 @@ } | ||
} | ||
getData() { | ||
let isNew = this._child.isNew; | ||
return { | ||
id: this.id, | ||
parentId: this._parent.id, | ||
child: isNew ? this._child.toData(false) : this._child.id, | ||
position: this._position | ||
}; | ||
} | ||
} | ||
export var InsertNodeCommandData; | ||
(function (InsertNodeCommandData) { | ||
InsertNodeCommandData.ID = 'InsertNode'; | ||
function is(arg) { | ||
return CommandData.is(arg) | ||
&& arg.id === InsertNodeCommandData.ID | ||
&& 'parentId' in arg | ||
&& 'child' in arg | ||
&& 'position' in arg; | ||
} | ||
InsertNodeCommandData.is = is; | ||
})(InsertNodeCommandData || (InsertNodeCommandData = {})); | ||
//# sourceMappingURL=insert-node-command.js.map |
@@ -0,1 +1,2 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlNode } from "../gxml-node"; | ||
@@ -6,12 +7,22 @@ import { GxmlCommand } from "./gxml-command"; | ||
private _child; | ||
private _index; | ||
constructor(parent: GxmlNode, child: GxmlNode, index: number); | ||
private _position; | ||
constructor(parent: GxmlNode, child: GxmlNode, position: number); | ||
get id(): string; | ||
get parent(): GxmlNode; | ||
get child(): GxmlNode; | ||
get index(): number; | ||
get position(): number; | ||
get changeRoot(): GxmlNode; | ||
do(): boolean; | ||
undo(): boolean; | ||
getData(): RemoveNodeCommandData; | ||
} | ||
export declare namespace RemoveNodeCommandData { | ||
const ID = "RemoveNode"; | ||
function is(arg: any): arg is RemoveNodeCommandData; | ||
} | ||
export declare type RemoveNodeCommandData = CommandData & { | ||
parentId: string; | ||
childId: string; | ||
position: number; | ||
}; | ||
//# sourceMappingURL=remove-node-command.d.ts.map |
@@ -0,12 +1,12 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'RemoveNode'; | ||
export class RemoveNodeCommand extends GxmlCommand { | ||
constructor(parent, child, index) { | ||
constructor(parent, child, position) { | ||
super(); | ||
this._parent = parent; | ||
this._child = child; | ||
this._index = index; | ||
this._position = position; | ||
} | ||
get id() { | ||
return ID; | ||
return RemoveNodeCommandData.ID; | ||
} | ||
@@ -19,4 +19,4 @@ get parent() { | ||
} | ||
get index() { | ||
return this._index; | ||
get position() { | ||
return this._position; | ||
} | ||
@@ -27,9 +27,30 @@ get changeRoot() { | ||
do() { | ||
console.log('Remove', this._parent, this._child); | ||
return this._parent.removeNode(this._child); | ||
} | ||
undo() { | ||
this._parent.insertNode(this._child, this._index); | ||
this._parent.insertNode(this._child, this._position); | ||
return true; | ||
} | ||
getData() { | ||
return { | ||
id: this.id, | ||
parentId: this._parent.id, | ||
childId: this._child.id, | ||
position: this._position | ||
}; | ||
} | ||
} | ||
export var RemoveNodeCommandData; | ||
(function (RemoveNodeCommandData) { | ||
RemoveNodeCommandData.ID = 'RemoveNode'; | ||
function is(arg) { | ||
return CommandData.is(arg) | ||
&& arg.id === RemoveNodeCommandData.ID | ||
&& 'parentId' in arg | ||
&& 'childId' in arg | ||
&& 'position' in arg; | ||
} | ||
RemoveNodeCommandData.is = is; | ||
})(RemoveNodeCommandData || (RemoveNodeCommandData = {})); | ||
//# sourceMappingURL=remove-node-command.js.map |
@@ -0,1 +1,2 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlNode } from "../gxml-node"; | ||
@@ -7,4 +8,4 @@ import { GxmlCommand } from "./gxml-command"; | ||
private _oldValue; | ||
private _newValue; | ||
constructor(node: GxmlNode, name: string, oldValue: string, newValue: string); | ||
private _value; | ||
constructor(node: GxmlNode, name: string, oldValue: string, value: string); | ||
get id(): string; | ||
@@ -14,3 +15,14 @@ get changeRoot(): GxmlNode; | ||
undo(): boolean; | ||
getData(): SetPropertyValueCommandData; | ||
} | ||
export declare namespace SetPropertyValueCommandData { | ||
const ID = "SetPropertyValue"; | ||
function is(arg: any): arg is SetPropertyValueCommandData; | ||
} | ||
export declare type SetPropertyValueCommandData = CommandData & { | ||
nodeId: string; | ||
name: string; | ||
oldValue: string; | ||
value: string; | ||
}; | ||
//# sourceMappingURL=set-property-value-command.d.ts.map |
@@ -0,5 +1,5 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'SetPropertyValue'; | ||
export class SetPropertyValueCommand extends GxmlCommand { | ||
constructor(node, name, oldValue, newValue) { | ||
constructor(node, name, oldValue, value) { | ||
super(); | ||
@@ -9,6 +9,6 @@ this._node = node; | ||
this._oldValue = oldValue; | ||
this._newValue = newValue; | ||
this._value = value; | ||
} | ||
get id() { | ||
return ID; | ||
return SetPropertyValueCommandData.ID; | ||
} | ||
@@ -19,3 +19,3 @@ get changeRoot() { | ||
do() { | ||
this._node.setPropertyValue(this._name, this._newValue); | ||
this._node.setPropertyValue(this._name, this._value); | ||
return true; | ||
@@ -27,3 +27,24 @@ } | ||
} | ||
getData() { | ||
return { | ||
id: this.id, | ||
nodeId: this._node.id, | ||
name: this._name, | ||
oldValue: this._oldValue, | ||
value: this._value | ||
}; | ||
} | ||
} | ||
export var SetPropertyValueCommandData; | ||
(function (SetPropertyValueCommandData) { | ||
SetPropertyValueCommandData.ID = 'SetPropertyValue'; | ||
function is(arg) { | ||
return CommandData.is(arg) | ||
&& arg.id === SetPropertyValueCommandData.ID | ||
&& 'nodeId' in arg | ||
&& 'oldValue' in arg | ||
&& 'value' in arg; | ||
} | ||
SetPropertyValueCommandData.is = is; | ||
})(SetPropertyValueCommandData || (SetPropertyValueCommandData = {})); | ||
//# sourceMappingURL=set-property-value-command.js.map |
@@ -0,3 +1,4 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlDocument } from "../gxml-document"; | ||
import { GxmlNode } from "../gxml-node"; | ||
import { GxmlNode, GxmlNodeData } from "../gxml-node"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
@@ -16,3 +17,12 @@ export declare class SetRootNodeCommand extends GxmlCommand { | ||
undo(): boolean; | ||
getData(): SetRootNodeCommandData; | ||
} | ||
export declare namespace SetRootNodeCommandData { | ||
const ID = "SetRootNode"; | ||
function is(arg: any): arg is SetRootNodeCommandData; | ||
} | ||
export declare type SetRootNodeCommandData = CommandData & { | ||
rootNode: GxmlNodeData; | ||
oldRootNodeId: string; | ||
}; | ||
//# sourceMappingURL=set-root-node-command.d.ts.map |
@@ -0,3 +1,3 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'SetRootNode'; | ||
export class SetRootNodeCommand extends GxmlCommand { | ||
@@ -11,3 +11,3 @@ constructor(document, rootNode, oldRootNode) { | ||
get id() { | ||
return ID; | ||
return SetRootNodeCommandData.ID; | ||
} | ||
@@ -34,3 +34,21 @@ get document() { | ||
} | ||
getData() { | ||
return { | ||
id: this.id, | ||
rootNode: this._rootNode.toData(), | ||
oldRootNodeId: this._oldRootNode.id | ||
}; | ||
} | ||
} | ||
export var SetRootNodeCommandData; | ||
(function (SetRootNodeCommandData) { | ||
SetRootNodeCommandData.ID = 'SetRootNode'; | ||
function is(arg) { | ||
return CommandData.is(arg) | ||
&& arg.id === SetRootNodeCommandData.ID | ||
&& 'rootNode' in arg | ||
&& 'oldRootNodeId' in arg; | ||
} | ||
SetRootNodeCommandData.is = is; | ||
})(SetRootNodeCommandData || (SetRootNodeCommandData = {})); | ||
//# sourceMappingURL=set-root-node-command.js.map |
@@ -1,9 +0,14 @@ | ||
import { Disposable } from "../disposable"; | ||
import { GxmlCommand } from "./commands/gxml-command"; | ||
import { GxmlCompositeCommand } from "./commands/gxml-composite-command"; | ||
import { GxmlNode } from "./gxml-node"; | ||
import { GxmlNodeDescriptor, GxmlNodeDescriptorRegistry } from "./gxml-node-descriptor"; | ||
import { Disposable } from '../disposable'; | ||
import { GxmlCommand } from './commands/gxml-command'; | ||
import { GxmlCompositeCommand } from './commands/gxml-composite-command'; | ||
import { GxmlNode, VisitNodeCallback } from './gxml-node'; | ||
import { GxmlNodeDescriptor, GxmlNodeDescriptorRegistry } from './gxml-node-descriptor'; | ||
import { MaybePromise } from '../types'; | ||
export declare type GxmlDocumentOptions = { | ||
registry: GxmlNodeDescriptorRegistry; | ||
}; | ||
export declare type DocumentChangedEventArgs = { | ||
document: GxmlDocument; | ||
command: GxmlCommand; | ||
}; | ||
export declare class GxmlDocument { | ||
@@ -16,2 +21,3 @@ private _emitter; | ||
private _updateCount; | ||
private _knownNodes; | ||
constructor(options: GxmlDocumentOptions); | ||
@@ -25,10 +31,11 @@ registerChanges: boolean; | ||
findNode(predicate: (n: GxmlNode) => boolean): GxmlNode; | ||
visitNodes(fn: (n: GxmlNode) => boolean): void; | ||
visitNodes(fn: VisitNodeCallback): void; | ||
getAllNodes(): GxmlNode[]; | ||
isNewNode(node: GxmlNode): boolean; | ||
get updating(): boolean; | ||
beginUpdate(): void; | ||
endUpdate(): Promise<void>; | ||
onChanged(command: GxmlCommand): void; | ||
changed(callback: (args: DocumentChangedEventArgs) => void): Disposable; | ||
updateFinished(callback: (args: DocumentChangedEventArgs) => void): Disposable; | ||
onChanged(command: GxmlCommand, notify?: boolean): void; | ||
changed(callback: (args: DocumentChangedEventArgs) => MaybePromise<void>): Disposable; | ||
updateFinished(callback: (args: DocumentChangedEventArgs) => MaybePromise<void>): Disposable; | ||
protected createCompositeCommand(): GxmlCompositeCommand; | ||
@@ -39,7 +46,4 @@ private _fireChangedEvent; | ||
private _calculateNewName; | ||
private _updateKnownNodes; | ||
} | ||
export declare type DocumentChangedEventArgs = { | ||
document: GxmlDocument; | ||
command: GxmlCommand; | ||
}; | ||
//# sourceMappingURL=gxml-document.d.ts.map |
@@ -10,9 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
import { Emitter } from "../emitter"; | ||
import { Guid } from "../guid"; | ||
import { GxmlCompositeCommand } from "./commands/gxml-composite-command"; | ||
import { SetRootNodeCommand } from "./commands/set-root-node-command"; | ||
import { Emitter } from '../emitter'; | ||
import { Guid } from '../guid'; | ||
import { GxmlCompositeCommand } from './commands/gxml-composite-command'; | ||
import { SetRootNodeCommand } from './commands/set-root-node-command'; | ||
const _EVT_CHANGED = 'Changed'; | ||
const _EVT_UPDATE_FINISHED = 'UpdateFinished'; | ||
const _NAME_REGEX = /([^\d]+)([\d]*)/g; | ||
export class GxmlDocument { | ||
@@ -25,2 +24,3 @@ constructor(options) { | ||
this._updateCount = 0; | ||
this._knownNodes = new Set(); | ||
} | ||
@@ -50,2 +50,5 @@ get rootNode() { | ||
} | ||
/// <summary> | ||
/// Visits the root node its descendant with function fn. If fn returns true, the visit is stopped. | ||
/// </summary> | ||
visitNodes(fn) { | ||
@@ -59,2 +62,9 @@ var _a; | ||
} | ||
/// <summary> | ||
/// Returns true if this node belongs to this document but it is the first time it is inserted into the document in the context of | ||
/// the current update operation. After the update operation is finished, the node is considered to be known and no longer a new one. | ||
/// </summary> | ||
isNewNode(node) { | ||
return !this._knownNodes.has(node.id); | ||
} | ||
get updating() { | ||
@@ -70,11 +80,11 @@ return !!this._compositeCommand; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
console.log('End udpate 1', this._updateCount); | ||
if (this._updateCount > 0) { | ||
this._updateCount--; | ||
console.log('End update', this._updateCount, this._compositeCommand); | ||
if (this._updateCount === 0) { | ||
let command = this._compositeCommand; | ||
this._compositeCommand = undefined; | ||
if (command && command.count > 0) | ||
if (command && command.count > 0) { | ||
yield this._fireUpdateFinishedEvent(command); | ||
this._updateKnownNodes(); | ||
} | ||
} | ||
@@ -84,11 +94,16 @@ } | ||
} | ||
onChanged(command) { | ||
//if (command instanceof InsertNodeCommand || command instanceof SetRootNodeCommand) | ||
onChanged(command, notify = true) { | ||
this._fixUniqueProperties(); | ||
if (this.registerChanges) | ||
this._executedCommands.push(command); | ||
// Do not wait for promise, this case is supposed to be used only in synchronous cases without beginUpdate and endUpdate | ||
this._fireChangedEvent(command); | ||
if (this._compositeCommand) | ||
this._compositeCommand.addCommand(command); | ||
if (notify) { | ||
// Do not wait for promise, this case is supposed to be used only in synchronous cases without beginUpdate and endUpdate | ||
this._fireChangedEvent(command); | ||
} | ||
if (this._compositeCommand) { | ||
if (notify) | ||
this._compositeCommand.addCommand(command); | ||
} | ||
else | ||
this._updateKnownNodes(); | ||
} | ||
@@ -120,7 +135,7 @@ changed(callback) { | ||
this.visitNodes(n => { | ||
if (n.descriptor.hasId) { | ||
if (!n.id || usedIds.has(n.id.toLowerCase())) | ||
n.id = Guid.newInstance().toString(); | ||
usedIds.add(n.id.toLowerCase()); | ||
if (!n.id || usedIds.has(n.id.toLowerCase())) { | ||
//debugger; | ||
n.id = Guid.newInstance().toString(); | ||
} | ||
usedIds.add(n.id.toLowerCase()); | ||
if (n.descriptor.nameProperty) { | ||
@@ -156,3 +171,6 @@ if (!n.name || (n.descriptor.hasUniqueName && usedNames.has(n.name.toLowerCase()))) { | ||
} | ||
_updateKnownNodes() { | ||
this.visitNodes(n => { this._knownNodes.add(n.id); }); | ||
} | ||
} | ||
//# sourceMappingURL=gxml-document.js.map |
@@ -1,5 +0,5 @@ | ||
import { Registry } from "../registry"; | ||
import { Registry } from '../registry'; | ||
export declare type GxmlNodeDescriptorOptions = { | ||
type: string; | ||
hasId?: boolean; | ||
flags?: number; | ||
nameProperty?: string; | ||
@@ -10,3 +10,3 @@ hasUniqueName?: boolean; | ||
private _type; | ||
private _hasId; | ||
private _flags; | ||
private _nameProperty?; | ||
@@ -16,5 +16,6 @@ private _hasUniqueName; | ||
get type(): string; | ||
get hasId(): boolean; | ||
get flags(): number; | ||
get nameProperty(): string; | ||
get hasUniqueName(): boolean; | ||
getData(): GxmlNodeDescriptorOptions; | ||
} | ||
@@ -21,0 +22,0 @@ export declare class GxmlNodeDescriptorRegistry extends Registry<GxmlNodeDescriptor> { |
@@ -1,6 +0,6 @@ | ||
import { Registry } from "../registry"; | ||
import { Registry } from '../registry'; | ||
export class GxmlNodeDescriptor { | ||
constructor(options) { | ||
this._type = options.type; | ||
this._hasId = options.hasId !== undefined ? options.hasId : true; | ||
this._flags = options.flags !== undefined ? options.flags : 0; | ||
this._nameProperty = options.nameProperty; | ||
@@ -12,4 +12,4 @@ this._hasUniqueName = options.hasUniqueName !== undefined ? options.hasUniqueName : true; | ||
} | ||
get hasId() { | ||
return this._hasId; | ||
get flags() { | ||
return this._flags; | ||
} | ||
@@ -22,2 +22,10 @@ get nameProperty() { | ||
} | ||
getData() { | ||
return { | ||
type: this._type, | ||
flags: this._flags, | ||
nameProperty: this._nameProperty, | ||
hasUniqueName: this._hasUniqueName | ||
}; | ||
} | ||
} | ||
@@ -30,4 +38,3 @@ export class GxmlNodeDescriptorRegistry extends Registry { | ||
return new GxmlNodeDescriptor({ | ||
type, | ||
hasId: true | ||
type | ||
}); | ||
@@ -34,0 +41,0 @@ } |
@@ -13,2 +13,3 @@ import { IDesignerHost } from "../component-model"; | ||
properties?: GxmlNodeProperties; | ||
isNew?: boolean; | ||
}; | ||
@@ -18,2 +19,3 @@ export declare type GxmlNodeData = GxmlNodeOptions & { | ||
}; | ||
export declare type VisitNodeCallback = (n: GxmlNode) => boolean | void; | ||
export declare class GxmlNode { | ||
@@ -33,2 +35,3 @@ private _document; | ||
set id(value: string | undefined); | ||
get isNew(): boolean; | ||
get name(): string | undefined; | ||
@@ -43,3 +46,3 @@ set name(value: string | undefined); | ||
findNode(predicate: (n: GxmlNode) => boolean): GxmlNode; | ||
visitNodes(fn: (n: GxmlNode) => boolean): void; | ||
visitNodes(fn: VisitNodeCallback): void; | ||
getAllNodes(includeSelf: boolean): GxmlNode[]; | ||
@@ -51,4 +54,5 @@ isAncestorOf(node: GxmlNode): boolean; | ||
addNode(child: GxmlNode): void; | ||
insertNode(child: GxmlNode, index: number): void; | ||
insertNode(child: GxmlNode, position: number): void; | ||
removeNode(child: GxmlNode): boolean; | ||
moveNode(child: GxmlNode, newPosition: number): boolean; | ||
remove(): boolean; | ||
@@ -55,0 +59,0 @@ copy(deep?: boolean): GxmlNode; |
import { Guid } from "../guid"; | ||
import { Registry } from "../registry"; | ||
import { InsertNodeCommand } from "./commands/insert-node-command"; | ||
import { MoveNodeCommand } from "./commands/move-command"; | ||
import { RemoveNodeCommand } from "./commands/remove-node-command"; | ||
@@ -12,3 +13,3 @@ import { SetPropertyValueCommand } from "./commands/set-property-value-command"; | ||
throw Error(`Unknown node type: '${options.type}'`); | ||
this._id = this._descriptor.hasId ? options.id || Guid.newInstance().toString() : undefined; | ||
this._id = options.id || Guid.newInstance().toString(); | ||
this._children = []; | ||
@@ -39,2 +40,5 @@ this._properties = new Map(); | ||
} | ||
get isNew() { | ||
return this._document.isNewNode(this); | ||
} | ||
get name() { | ||
@@ -60,3 +64,3 @@ if (this._descriptor.nameProperty) | ||
getNodeById(id) { | ||
return this.findNode(n => n.id === id); | ||
return this.findNode(n => n.id.toLowerCase() === id.toLocaleLowerCase()); | ||
} | ||
@@ -80,2 +84,5 @@ getNodeByName(name) { | ||
} | ||
/// <summary> | ||
/// Visits this node and its descendant with function fn. If fn returns true, the visit is stopped. | ||
/// </summary> | ||
visitNodes(fn) { | ||
@@ -85,3 +92,3 @@ let queue = [this]; | ||
let current = queue.shift(); | ||
if (fn(current)) | ||
if (!!fn(current)) | ||
break; | ||
@@ -106,3 +113,4 @@ current.children.map(c => queue.push(c)); | ||
this._properties.set(name, value); | ||
this._document.onChanged(new SetPropertyValueCommand(this, name, oldValue, value)); | ||
if (!this.isNew) | ||
this._document.onChanged(new SetPropertyValueCommand(this, name, oldValue, value)); | ||
} | ||
@@ -121,3 +129,3 @@ getPropertyValue(name) { | ||
} | ||
insertNode(child, index) { | ||
insertNode(child, position) { | ||
if (child.document !== this._document) | ||
@@ -129,5 +137,5 @@ throw Error('Node belongs to another document'); | ||
} | ||
this._children.splice(index, 0, child); | ||
this._children.splice(position, 0, child); | ||
child._parent = this; | ||
this._document.onChanged(new InsertNodeCommand(this, child, index)); | ||
this._document.onChanged(new InsertNodeCommand(this, child, position)); | ||
} | ||
@@ -137,2 +145,3 @@ removeNode(child) { | ||
if (index >= 0) { | ||
child._parent = undefined; | ||
this._children.splice(index, 1); | ||
@@ -144,5 +153,16 @@ this._document.onChanged(new RemoveNodeCommand(this, child, index)); | ||
} | ||
moveNode(child, newPosition) { | ||
let oldPosition = this._children.indexOf(child); | ||
if (oldPosition >= 0) { | ||
this._children.splice(oldPosition, 1); | ||
this._children.splice(newPosition, 0, child); | ||
this._document.onChanged(new MoveNodeCommand(child, oldPosition, newPosition)); | ||
return true; | ||
} | ||
return false; | ||
} | ||
remove() { | ||
var _a; | ||
return !!((_a = this._parent) === null || _a === void 0 ? void 0 : _a.removeNode(this)); | ||
if (!this._parent) | ||
throw Error('Node has no parent'); | ||
return !!this._parent.removeNode(this); | ||
} | ||
@@ -149,0 +169,0 @@ copy(deep = true) { |
export * from "./gxml-document"; | ||
export * from "./gxml-node"; | ||
export * from "./gxml-node-descriptor"; | ||
export * from "./commands"; | ||
//# sourceMappingURL=index.d.ts.map |
export * from "./gxml-document"; | ||
export * from "./gxml-node"; | ||
export * from "./gxml-node-descriptor"; | ||
export * from "./commands"; | ||
//# sourceMappingURL=index.js.map |
@@ -0,3 +1,5 @@ | ||
export * from './control-helper'; | ||
export * from './dynamic-assets-loader'; | ||
export * from './flag-set'; | ||
export * from './service-helper'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -0,3 +1,5 @@ | ||
export * from './control-helper'; | ||
export * from './dynamic-assets-loader'; | ||
export * from './flag-set'; | ||
export * from './service-helper'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,1 @@ | ||
import { IDisposable } from "../disposable"; | ||
export declare type ServiceProxy = { | ||
@@ -25,17 +24,22 @@ [key: string]: (...args: any[]) => Promise<any>; | ||
}; | ||
export declare class InterFrameServiceHelper { | ||
export declare class FrameBridge { | ||
private static readonly EXECUTE_OPERATION_EVENT_NAME; | ||
private static readonly OPERATION_RESULT_EVENT_NAME; | ||
private static _pendingOperations; | ||
private static _serviceMap; | ||
static initializeSourceEndpoint(source: Window): IDisposable; | ||
static initializeTargetEndpoint(target: Window, source: Window): IDisposable; | ||
static createProxy(target: Window, descriptor: ServiceDescriptorData): ServiceProxy; | ||
static registerServices(services: Map<string, any>): IDisposable; | ||
static registerService(name: string, service: any): IDisposable; | ||
static getServiceDescriptors(services: Map<string, any>): ServiceDescriptorData[]; | ||
static getServiceDescriptor(name: string, service: any): ServiceDescriptorData; | ||
private static _getAllFunctions; | ||
private static _getFunctions; | ||
private _local; | ||
private _remote; | ||
private _disposables; | ||
private _pendingOperations; | ||
private _serviceMap; | ||
constructor(local: Window, remote: Window); | ||
createProxy(descriptor: ServiceDescriptorData): ServiceProxy; | ||
registerServices(services: Map<string, any>): void; | ||
registerService(name: string, service: any): void; | ||
getServiceDescriptors(services: Map<string, any>): ServiceDescriptorData[]; | ||
getServiceDescriptor(name: string, service: any): ServiceDescriptorData; | ||
dispose(): void; | ||
private _getAllFunctions; | ||
private _getFunctions; | ||
private _initializeSource; | ||
private _initializeTarget; | ||
} | ||
//# sourceMappingURL=service-helper.d.ts.map |
@@ -11,48 +11,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { Disposable } from "event-kit"; | ||
import { CompositeDisposable } from "../composite-disposable"; | ||
import { Guid } from "../guid"; | ||
export class InterFrameServiceHelper { | ||
static initializeSourceEndpoint(source) { | ||
const listener = (e) => { | ||
var _a; | ||
if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.eventName) === InterFrameServiceHelper.OPERATION_RESULT_EVENT_NAME && e.data.data.guid) { | ||
let data = e.data.data; | ||
let pending = InterFrameServiceHelper._pendingOperations.get(data.guid); | ||
InterFrameServiceHelper._pendingOperations.delete(data.guid); | ||
if (pending) { | ||
if (data.success) | ||
pending.resolve(data.value); | ||
else | ||
pending.reject(data.errorMessage || 'Operation Failed'); | ||
} | ||
} | ||
}; | ||
source.addEventListener('message', listener); | ||
return new Disposable(() => source.removeEventListener('message', listener)); | ||
export class FrameBridge { | ||
constructor(local, remote) { | ||
this._local = local; | ||
this._remote = remote; | ||
this._disposables = new CompositeDisposable(); | ||
this._pendingOperations = new Map(); | ||
this._serviceMap = new Map(); | ||
this._initializeSource(); | ||
this._initializeTarget(); | ||
} | ||
static initializeTargetEndpoint(target, source) { | ||
const listener = (e) => __awaiter(this, void 0, void 0, function* () { | ||
var _a; | ||
if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.eventName) === InterFrameServiceHelper.EXECUTE_OPERATION_EVENT_NAME) { | ||
let data = e.data.data; | ||
let service = InterFrameServiceHelper._serviceMap.get(data.serviceName); | ||
let result = { guid: data.guid, success: false }; | ||
if (service) { | ||
try { | ||
result.value = yield service[data.operation](...data.args); | ||
result.success = true; | ||
} | ||
catch (ex) { | ||
result.errorMessage = ex.message; | ||
} | ||
} | ||
else { | ||
result.errorMessage = `Service '${data.serviceName}' does not exist`; | ||
} | ||
source.postMessage({ eventName: InterFrameServiceHelper.OPERATION_RESULT_EVENT_NAME, data: result }, '*'); | ||
} | ||
}); | ||
target.addEventListener('message', listener); | ||
return new Disposable(() => target.removeEventListener('message', listener)); | ||
} | ||
static createProxy(target, descriptor) { | ||
createProxy(descriptor) { | ||
let proxy = {}; | ||
@@ -62,5 +29,5 @@ for (let op of descriptor.operations) { | ||
let guid = Guid.newInstance().toString(); | ||
InterFrameServiceHelper._pendingOperations.set(guid, { resolve, reject }); | ||
target.postMessage({ | ||
eventName: InterFrameServiceHelper.EXECUTE_OPERATION_EVENT_NAME, | ||
this._pendingOperations.set(guid, { resolve, reject }); | ||
this._remote.postMessage({ | ||
eventName: FrameBridge.EXECUTE_OPERATION_EVENT_NAME, | ||
data: { | ||
@@ -77,15 +44,12 @@ guid, | ||
} | ||
static registerServices(services) { | ||
let disposables = []; | ||
registerServices(services) { | ||
for (let service of services.entries()) | ||
disposables.push(this.registerService(service[0], service[1])); | ||
return new Disposable(() => disposables.forEach(d => d.dispose())); | ||
this.registerService(service[0], service[1]); | ||
} | ||
static registerService(name, service) { | ||
if (InterFrameServiceHelper._serviceMap.has(name)) | ||
registerService(name, service) { | ||
if (this._serviceMap.has(name)) | ||
throw new Error(`Service '${name}' already registered`); | ||
InterFrameServiceHelper._serviceMap.set(name, service); | ||
return new Disposable(() => InterFrameServiceHelper._serviceMap.delete(name)); | ||
this._serviceMap.set(name, service); | ||
} | ||
static getServiceDescriptors(services) { | ||
getServiceDescriptors(services) { | ||
let data = []; | ||
@@ -96,3 +60,3 @@ for (let name of services.keys()) | ||
} | ||
static getServiceDescriptor(name, service) { | ||
getServiceDescriptor(name, service) { | ||
return { | ||
@@ -103,6 +67,9 @@ name, | ||
} | ||
static _getAllFunctions(target) { | ||
dispose() { | ||
this._disposables.dispose(); | ||
} | ||
_getAllFunctions(target) { | ||
return [...this._getFunctions(target), ...this._getFunctions(Object.getPrototypeOf(target))]; | ||
} | ||
static _getFunctions(target) { | ||
_getFunctions(target) { | ||
let fs = []; | ||
@@ -115,7 +82,48 @@ for (let p of Object.getOwnPropertyNames(target)) { | ||
} | ||
_initializeSource() { | ||
const listener = (e) => { | ||
var _a; | ||
if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.eventName) === FrameBridge.OPERATION_RESULT_EVENT_NAME && e.data.data.guid) { | ||
let data = e.data.data; | ||
let pending = this._pendingOperations.get(data.guid); | ||
this._pendingOperations.delete(data.guid); | ||
if (pending) { | ||
if (data.success) | ||
pending.resolve(data.value); | ||
else | ||
pending.reject(data.errorMessage || 'Operation Failed'); | ||
} | ||
} | ||
}; | ||
this._local.addEventListener('message', listener); | ||
this._disposables.add(new Disposable(() => { var _a; return ((_a = this._local) === null || _a === void 0 ? void 0 : _a.removeEventListener) && this._local.removeEventListener('message', listener); })); | ||
} | ||
_initializeTarget() { | ||
const listener = (e) => __awaiter(this, void 0, void 0, function* () { | ||
var _a; | ||
if (this._remote === e.source && ((_a = e.data) === null || _a === void 0 ? void 0 : _a.eventName) === FrameBridge.EXECUTE_OPERATION_EVENT_NAME) { | ||
let data = e.data.data; | ||
let service = this._serviceMap.get(data.serviceName); | ||
let result = { guid: data.guid, success: false }; | ||
if (service) { | ||
try { | ||
result.value = yield service[data.operation](...data.args); | ||
result.success = true; | ||
} | ||
catch (ex) { | ||
result.errorMessage = ex.message; | ||
} | ||
} | ||
else { | ||
result.errorMessage = `Service '${data.serviceName}' does not exist`; | ||
} | ||
this._remote.postMessage({ eventName: FrameBridge.OPERATION_RESULT_EVENT_NAME, data: result }, '*'); | ||
} | ||
}); | ||
this._local.addEventListener('message', listener); | ||
this._disposables.add(new Disposable(() => { var _a, _b; return ((_a = this._remote) === null || _a === void 0 ? void 0 : _a.removeEventListener) && ((_b = this._remote) === null || _b === void 0 ? void 0 : _b.removeEventListener('message', listener)); })); | ||
} | ||
} | ||
InterFrameServiceHelper.EXECUTE_OPERATION_EVENT_NAME = 'ExecuteServiceOperation'; | ||
InterFrameServiceHelper.OPERATION_RESULT_EVENT_NAME = 'ServiceOperationResult'; | ||
InterFrameServiceHelper._pendingOperations = new Map(); | ||
InterFrameServiceHelper._serviceMap = new Map(); | ||
FrameBridge.EXECUTE_OPERATION_EVENT_NAME = 'ExecuteServiceOperation'; | ||
FrameBridge.OPERATION_RESULT_EVENT_NAME = 'ServiceOperationResult'; | ||
//# sourceMappingURL=service-helper.js.map |
@@ -1,2 +0,2 @@ | ||
import { GxmlNodeData, GxmlNodeOptions } from "./gxml"; | ||
import { GxmlNodeOptions } from "./gxml"; | ||
import { AssetData, ServiceDescriptorData } from "./helpers"; | ||
@@ -10,3 +10,2 @@ export declare type MaybeArray<T> = T | T[]; | ||
export declare type DesignerOptionsData = { | ||
rootNode: GxmlNodeData; | ||
services?: ServiceDescriptorData[]; | ||
@@ -19,8 +18,3 @@ assets?: AssetData[]; | ||
const DESIGNER_READY = "designerReady"; | ||
const EXTERNAL_DRAG_START = "externalDragStart"; | ||
const EXTERNAL_DRAG_END = "externalDragEnd"; | ||
const EXTERNAL_DRAG_ENTER = "externalDragEnter"; | ||
const EXTERNAL_DRAG_LEAVE = "externalDragLeave"; | ||
const EXTERNAL_DRAG_OVER = "externalDragOver"; | ||
const EXTERNAL_DROP = "externalDrop"; | ||
const DESIGNER_FOCUS = "designerFocus"; | ||
} | ||
@@ -35,3 +29,3 @@ export declare namespace DragHelper { | ||
function hasDragData(win: Window): boolean; | ||
function setExternalDragData(win: Window, options: GxmlNodeOptions): void; | ||
function setExternalDragData(win: Window, options: GxmlNodeOptions | undefined): void; | ||
function setInternalDragData(win: Window, nodeIds: string[], isCopy: boolean): void; | ||
@@ -45,4 +39,6 @@ function getDragData(win: Window): DragData; | ||
readonly cellIndex: number; | ||
readonly column: number; | ||
readonly position: PlaceHolderPosition; | ||
readonly data: DragHelper.DragData; | ||
readonly isVirtual: boolean; | ||
}; | ||
@@ -58,2 +54,5 @@ type TableModel = { | ||
readonly isEmpty: boolean; | ||
readonly column: number; | ||
readonly cellIdx: number; | ||
readonly isVirtual: boolean; | ||
}; | ||
@@ -60,0 +59,0 @@ type Rect = { |
@@ -6,8 +6,3 @@ export var InterFrameMessageIds; | ||
InterFrameMessageIds.DESIGNER_READY = 'designerReady'; | ||
InterFrameMessageIds.EXTERNAL_DRAG_START = 'externalDragStart'; | ||
InterFrameMessageIds.EXTERNAL_DRAG_END = 'externalDragEnd'; | ||
InterFrameMessageIds.EXTERNAL_DRAG_ENTER = 'externalDragEnter'; | ||
InterFrameMessageIds.EXTERNAL_DRAG_LEAVE = 'externalDragLeave'; | ||
InterFrameMessageIds.EXTERNAL_DRAG_OVER = 'externalDragOver'; | ||
InterFrameMessageIds.EXTERNAL_DROP = 'externalDrop'; | ||
InterFrameMessageIds.DESIGNER_FOCUS = 'designerFocus'; | ||
})(InterFrameMessageIds || (InterFrameMessageIds = {})); | ||
@@ -14,0 +9,0 @@ export var DragHelper; |
@@ -21,4 +21,8 @@ import { Control } from "../component-model"; | ||
} | ||
export declare type DesignerViewControls = { | ||
root: Element; | ||
active?: Control[]; | ||
}; | ||
export interface IDesignerViewContainer { | ||
controls: Control[]; | ||
controls: DesignerViewControls; | ||
toolbarHidden: boolean; | ||
@@ -25,0 +29,0 @@ pointerEvents: boolean; |
{ | ||
"name": "@genexus/designer-common", | ||
"version": "0.0.2-beta.8+895024f", | ||
"version": "0.0.2", | ||
"main": "lib/index.js", | ||
@@ -30,3 +30,3 @@ "typings": "lib/index.d.ts", | ||
}, | ||
"gitHead": "895024f50f60f3e1e65a2bec6e89eaa1d6a65e18" | ||
"gitHead": "67892ac5ddc6b105aa9d3cf0aa81f88c18d56988" | ||
} |
@@ -18,3 +18,3 @@ import { Disposable } from "../disposable"; | ||
export class CommandManager { | ||
private _commands: Command[]; | ||
@@ -31,3 +31,3 @@ private _macroCommandStack: CompositeCommand[]; | ||
constructor() { | ||
constructor() { | ||
this._commands = []; | ||
@@ -47,3 +47,3 @@ this._macroCommandStack = []; | ||
return this._emitter; | ||
} | ||
} | ||
@@ -164,2 +164,3 @@ get maxDepth() { | ||
let command = this.nextUndo; | ||
if (command) { | ||
@@ -192,3 +193,3 @@ let eventArgs = { undo: true, itemsAffected: command.itemsAffected }; | ||
if (command) { | ||
let eventArgs = { undo: true, itemsAffected: command.itemsAffected }; | ||
let eventArgs = { undo: false, itemsAffected: command.itemsAffected }; | ||
await this.onBeforeUndoRedo(eventArgs); | ||
@@ -195,0 +196,0 @@ await command.redo(); |
@@ -36,2 +36,9 @@ import { MaybePromise } from "../types"; | ||
export namespace CommandData { | ||
export function is(arg: any): arg is CommandData { | ||
return !!arg | ||
&& 'id' in arg; | ||
} | ||
} | ||
export type CommandData = { | ||
@@ -38,0 +45,0 @@ id: string; |
@@ -1,7 +0,5 @@ | ||
import { Command } from "./command"; | ||
import { Command, CommandData } from "./command"; | ||
export class CompositeCommand extends Command { | ||
static ID = 'Composite'; | ||
private _commands: Command[]; | ||
@@ -16,3 +14,3 @@ | ||
get id() { | ||
return CompositeCommand.ID; | ||
return CompositeCommandData.ID; | ||
} | ||
@@ -48,3 +46,3 @@ | ||
async getData() { | ||
async getData(): Promise<CompositeCommandData> { | ||
let data = []; | ||
@@ -60,1 +58,17 @@ for (let command of this._commands) | ||
} | ||
export namespace CompositeCommandData { | ||
export const ID = 'Composite'; | ||
export function is(arg: any): arg is CompositeCommandData { | ||
return CommandData.is(arg) | ||
&& arg.id === ID | ||
&& 'data' in arg | ||
&& Array.isArray(arg.data) | ||
} | ||
} | ||
export type CompositeCommandData = CommandData & { | ||
data: CommandData[]; | ||
} |
export namespace CommonServiceIds { | ||
export const DesignerHost = 'DesignerHost'; | ||
export const HostContextMenu = 'HostContextMenu'; | ||
export const DesignerHost = 'DesignerHost'; | ||
export const ContextMenu = 'ContextMenu'; | ||
export const Selection = 'Selection'; | ||
export const GxmlNodeFactory = 'GxmlNodeFactory'; | ||
export const InteropContextMenu = 'InteropContextMenu'; | ||
export const InteropContextMenuResolver = 'InteropContextMenuResolver'; | ||
export const InteropKeybinding = 'InteropKeybinding'; | ||
export const InteropSelection = 'InteropSelection'; | ||
export const InteropModel = 'InteropModel'; | ||
export const InteropDragDrop = 'InteropDragDrop'; | ||
} |
@@ -10,3 +10,4 @@ import { MaybePromise } from "../types"; | ||
disabled?: boolean; | ||
subMenu?: MenuCommandData[]; | ||
subMenu?: MenuCommandData[]; | ||
iconName?: string; | ||
} | ||
@@ -26,6 +27,7 @@ | ||
subMenu?: MenuCommand[]; | ||
iconName?: string; | ||
action?: () => void; | ||
} | ||
export interface IHostContextMenuSerivce { | ||
export interface IInteropContextMenuSerivce { | ||
@@ -37,2 +39,22 @@ show(anchor: PointData, commands: MenuCommandData[]): MaybePromise<string>; | ||
export interface IInteropContextMenuResolverService { | ||
show(anchor: PointData, nodeId: string):void; | ||
} | ||
export type KeyboardEventData = { | ||
readonly altKey: boolean; | ||
readonly code: string; | ||
readonly ctrlKey: boolean; | ||
readonly isComposing: boolean; | ||
readonly key: string; | ||
readonly location: number; | ||
readonly metaKey: boolean; | ||
readonly repeat: boolean; | ||
readonly shiftKey: boolean; | ||
} | ||
export interface IInteropKeybindingService { | ||
dispatch(key: KeyboardEventData): MaybePromise<boolean>; | ||
} | ||
export interface IContextMenuSerivce { | ||
@@ -58,3 +80,3 @@ | ||
try { | ||
let hostSrv = this._services.getService(CommonServiceIds.HostContextMenu) as IHostContextMenuSerivce; | ||
let hostSrv = this._services.getService(CommonServiceIds.InteropContextMenu) as IInteropContextMenuSerivce; | ||
let cmdId = await hostSrv.show(anchor, this._convertCommands(commands)); | ||
@@ -74,3 +96,3 @@ if (cmdId) { | ||
this._cleanup(); | ||
let hostSrv = this._services.getService(CommonServiceIds.HostContextMenu) as IHostContextMenuSerivce; | ||
let hostSrv = this._services.getService(CommonServiceIds.InteropContextMenu) as IInteropContextMenuSerivce; | ||
hostSrv.hide(); | ||
@@ -87,3 +109,4 @@ } | ||
label: c.label, | ||
subMenu: c.subMenu ? this._convertCommands(c.subMenu) : [] | ||
subMenu: c.subMenu ? this._convertCommands(c.subMenu) : [], | ||
iconName: c.iconName | ||
} | ||
@@ -90,0 +113,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
import { GxmlDocument } from "../gxml"; | ||
import { GxmlDocument, GxmlNode } from "../gxml"; | ||
import { GenericRegistry } from "../registry"; | ||
@@ -37,2 +37,11 @@ import { CommonServiceIds } from "./common-services-ids"; | ||
getComponentByNode(node: GxmlNode): IComponent{ | ||
let component: IComponent; | ||
this._designers.forEach((des, comp) => { | ||
if (des.model == node) | ||
component = comp; | ||
}); | ||
return component; | ||
} | ||
addService(name: string, service: any): void { | ||
@@ -50,6 +59,14 @@ this._services.add(name, service); | ||
protected updateDesigners() { | ||
protected updateDesigners() { | ||
// this._designers.forEach((d) => d.dispose()); | ||
// this._designers.clear(); | ||
let visited: Set<IComponent> = new Set(); | ||
for (let component of this.components) { | ||
let designer = this._designers.get(component); | ||
if (designer && designer.model !== this.document.getNodeById(component.site.id)) { | ||
this._disaposeDesigner(designer); | ||
designer = undefined; | ||
} | ||
if (!designer) { | ||
@@ -63,18 +80,21 @@ designer = this._createDesigner(component); | ||
let removed: IComponent[] = [] | ||
let removed: IComponent[] = []; | ||
this._designers.forEach((_, c) => !visited.has(c) && removed.push(c)); | ||
for (let c of removed) { | ||
let d = this._designers.get(c); | ||
try { | ||
d.dispose(); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
} | ||
finally { | ||
this._designers.delete(c); | ||
} | ||
} | ||
this._disaposeDesigner(d); | ||
} | ||
} | ||
private _disaposeDesigner(designer: IDesigner) { | ||
try { | ||
designer.dispose(); | ||
} | ||
catch (e) { | ||
console.error(e); | ||
} finally { | ||
this._designers.delete(designer.component); | ||
} | ||
} | ||
private _createDesigner(component: IComponent): IDesigner { | ||
@@ -81,0 +101,0 @@ let node = this.document.getNodeById(component.site.id); |
import { CompositeDisposable } from "../composite-disposable"; | ||
import { GxmlNode } from "../gxml/gxml-node"; | ||
import { MaybePromise } from "../types"; | ||
import { MenuCommand } from "./context-menu-service"; | ||
import { IComponent } from "./icomponent"; | ||
import { IDesigner } from "./idesigner"; | ||
import { CommandsRequest, IDesigner } from "./idesigner"; | ||
@@ -21,8 +22,5 @@ export class Designer implements IDesigner { | ||
initializeSurface(surface: HTMLElement): void { | ||
// console.log('Init Surface', surface); | ||
} | ||
onWillDestroySurface(): void { | ||
// console.log('Destroy surface', this); | ||
} | ||
@@ -46,2 +44,10 @@ | ||
canPaste(): boolean { | ||
return false; | ||
} | ||
canPropagateGetCommands(): boolean { | ||
return true; | ||
} | ||
doDefaultAction(): void { | ||
@@ -51,3 +57,3 @@ | ||
getCommands(event: MouseEvent): MenuCommand[] { | ||
getCommands(request: CommandsRequest): MaybePromise<MenuCommand[]> { | ||
return []; | ||
@@ -54,0 +60,0 @@ } |
import { GxmlNode } from "../gxml"; | ||
import { Registry } from "../registry"; | ||
import { MaybePromise } from "../types"; | ||
import { MenuCommand } from "./context-menu-service"; | ||
@@ -16,2 +17,7 @@ import { Designer } from "./designer"; | ||
export type CommandsRequest = { | ||
event: MouseEvent; | ||
composedPath: HTMLElement[]; | ||
} | ||
export interface IDesigner { | ||
@@ -23,5 +29,4 @@ | ||
initializeSurface(surface: HTMLElement): void; | ||
onWillDestroySurface(): void; | ||
canSelect(): boolean; | ||
@@ -31,8 +36,10 @@ canDelete(): boolean; | ||
canCopy(): boolean; | ||
canPaste(): boolean; | ||
canPropagateGetCommands(): boolean; | ||
doDefaultAction(): void; | ||
getCommands(event: MouseEvent): MenuCommand[] ; | ||
getCommands(request: CommandsRequest): MaybePromise<MenuCommand[]> ; | ||
dispose(): void; | ||
} |
export * from './common-flags'; | ||
export * from './common-services-ids'; | ||
@@ -6,2 +7,3 @@ export * from './context-menu-service'; | ||
export * from './designer-host'; | ||
export * from './drag-drop-service'; | ||
export * from './icomponent'; | ||
@@ -11,3 +13,5 @@ export * from './icontainer'; | ||
export * from './idesigner-host'; | ||
export * from './interop-context-menu-resolver-service'; | ||
export * from './imenu-command'; | ||
export * from './model-service'; | ||
export * from './selection-service'; | ||
@@ -14,0 +18,0 @@ export * from './iservice-container'; |
@@ -1,5 +0,16 @@ | ||
import { Emitter } from "event-kit"; | ||
import { IDisposable } from "../disposable"; | ||
import { IComponent } from "./icomponent"; | ||
import { CommonServiceIds } from './common-services-ids'; | ||
import { CompositeDisposable } from '../composite-disposable'; | ||
import { Emitter } from '../emitter'; | ||
import { IComponent } from './icomponent'; | ||
import { IDesignerHost } from './idesigner-host'; | ||
import { IDisposable } from '../disposable'; | ||
import { MaybePromise } from '../types'; | ||
const EVT_SELECTION_CHANGED = 'selectionChanged'; | ||
export type SelectionChangedEventArgs = { | ||
selection: IComponent[]; | ||
} | ||
export interface ISelectionService { | ||
@@ -21,3 +32,3 @@ | ||
selectionChanged(callack: (selection: IComponent[]) => void): IDisposable; | ||
selectionChanged(callack: (args: SelectionChangedEventArgs) => void): IDisposable; | ||
@@ -27,4 +38,2 @@ isSelected(component: IComponent): boolean; | ||
const EVT_SELECTION_CHANGED = 'selectionChanged'; | ||
export class SelectionService implements ISelectionService { | ||
@@ -86,3 +95,3 @@ | ||
selectionChanged(callack: (selection: IComponent[]) => void): IDisposable { | ||
selectionChanged(callack: (args: SelectionChangedEventArgs) => void): IDisposable { | ||
return this._emitter.on(EVT_SELECTION_CHANGED, callack); | ||
@@ -95,5 +104,88 @@ } | ||
private _onSelectionChanged() { | ||
this._emitter.emit(EVT_SELECTION_CHANGED, this.selection); | ||
private _onSelectionChanged() { | ||
this._emitter.emit(EVT_SELECTION_CHANGED, { selection: this.selection }); | ||
} | ||
} | ||
} | ||
export type InteropSelectionChangedEventArgs = { | ||
selection: string[]; | ||
} | ||
export interface IInteropSelectionService { | ||
onChanged(args: InteropSelectionChangedEventArgs): MaybePromise<void>; | ||
} | ||
export class SelectionSynchronizer implements IDisposable { | ||
private _designerHost: IDesignerHost; | ||
private _disposables: CompositeDisposable; | ||
private _interopService: IInteropSelectionService; | ||
private _ignoreHostChanges: any; | ||
private _ignoreDesignerChanges: any; | ||
constructor(designerHost: IDesignerHost) { | ||
this._designerHost = designerHost; | ||
this._disposables = new CompositeDisposable(); | ||
this._disposables.add( | ||
this._getSelectionService().selectionChanged((args) => this._onDesignerSelectionChanged(args)) | ||
); | ||
this._interopService = { | ||
onChanged: (args: InteropSelectionChangedEventArgs) => this._onHostSelectionChanged(args) | ||
} | ||
} | ||
get interopService(): IInteropSelectionService { | ||
return this._interopService; | ||
} | ||
private async _onHostSelectionChanged(args: InteropSelectionChangedEventArgs) { | ||
if (this._ignoreHostChanges) | ||
return; | ||
this._ignoreDesignerChanges = true; | ||
try { | ||
let components = args.selection.map(id => this._getComponentById(id)); | ||
await this._getSelectionService().setSelection(components); | ||
} | ||
finally { | ||
this._ignoreDesignerChanges = false; | ||
} | ||
} | ||
private async _onDesignerSelectionChanged(args: SelectionChangedEventArgs) { | ||
if (this._ignoreDesignerChanges) | ||
return; | ||
this._ignoreHostChanges = true; | ||
try { | ||
let hostSelService = this._designerHost.getService(CommonServiceIds.InteropSelection) as IInteropSelectionService; | ||
if (hostSelService) | ||
await hostSelService.onChanged({ selection: args.selection.map(c => c.site.id) }); | ||
} | ||
finally { | ||
this._ignoreHostChanges = false; | ||
} | ||
} | ||
private _getSelectionService(): ISelectionService { | ||
return this._designerHost.getService(CommonServiceIds.Selection) as ISelectionService; | ||
} | ||
private _getComponentById(id: string): IComponent { | ||
return this._designerHost.components.find(c => c.site.id === id); | ||
} | ||
//#region IDisposable | ||
dispose(): void { | ||
this._disposables.dispose(); | ||
} | ||
//#endregion | ||
} | ||
@@ -16,4 +16,2 @@ import { CompositeCommand } from "../../command/composite-command"; | ||
} | ||
} |
@@ -1,6 +0,5 @@ | ||
import { GxmlNode } from "../gxml-node"; | ||
import { CommandData } from "../../command"; | ||
import { GxmlNode, GxmlNodeData } from "../gxml-node"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'AddNode'; | ||
export class InsertNodeCommand extends GxmlCommand { | ||
@@ -10,14 +9,13 @@ | ||
private _child: GxmlNode; | ||
private _index: number; | ||
private _position: number; | ||
constructor(parent: GxmlNode, child: GxmlNode, index: number) { | ||
constructor(parent: GxmlNode, child: GxmlNode, position: number) { | ||
super(); | ||
this._parent = parent; | ||
this._child = child; | ||
this._index = index; | ||
this._position = position; | ||
} | ||
get id(): string { | ||
return ID; | ||
return InsertNodeCommandData.ID; | ||
} | ||
@@ -33,4 +31,4 @@ | ||
public get index(): number { | ||
return this._index; | ||
public get position(): number { | ||
return this._position; | ||
} | ||
@@ -42,4 +40,4 @@ | ||
do(): boolean { | ||
this._parent.insertNode(this._child, this._index); | ||
do(): boolean { | ||
this._parent.insertNode(this._child, this._position); | ||
return true; | ||
@@ -50,6 +48,33 @@ } | ||
return this._parent.removeNode(this._child); | ||
} | ||
getData(): InsertNodeCommandData { | ||
let isNew = this._child.isNew; | ||
return { | ||
id: this.id, | ||
parentId: this._parent.id, | ||
child: isNew ? this._child.toData(false) : this._child.id, // do not include children if the node is new since children nodes will have their own command | ||
position: this._position | ||
} | ||
} | ||
} | ||
export namespace InsertNodeCommandData { | ||
export const ID = 'InsertNode'; | ||
export function is(arg: any): arg is InsertNodeCommandData { | ||
return CommandData.is(arg) | ||
&& arg.id === ID | ||
&& 'parentId' in arg | ||
&& 'child' in arg | ||
&& 'position' in arg; | ||
} | ||
} | ||
export type InsertNodeCommandData = CommandData & { | ||
parentId: string; | ||
child: GxmlNodeData | string; | ||
position: number; | ||
} |
@@ -1,6 +0,5 @@ | ||
import { GxmlNode } from "../gxml-node"; | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlNode, GxmlNodeData } from "../gxml-node"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'RemoveNode'; | ||
export class RemoveNodeCommand extends GxmlCommand { | ||
@@ -10,5 +9,5 @@ | ||
private _child: GxmlNode; | ||
private _index: number; | ||
private _position: number; | ||
constructor(parent: GxmlNode, child: GxmlNode, index: number) { | ||
constructor(parent: GxmlNode, child: GxmlNode, position: number) { | ||
super(); | ||
@@ -18,7 +17,7 @@ | ||
this._child = child; | ||
this._index = index; | ||
this._position = position; | ||
} | ||
get id(): string { | ||
return ID; | ||
return RemoveNodeCommandData.ID; | ||
} | ||
@@ -34,4 +33,4 @@ | ||
public get index(): number { | ||
return this._index; | ||
public get position(): number { | ||
return this._position; | ||
} | ||
@@ -44,2 +43,3 @@ | ||
do(): boolean { | ||
console.log('Remove', this._parent, this._child); | ||
return this._parent.removeNode(this._child); | ||
@@ -49,5 +49,33 @@ } | ||
undo(): boolean { | ||
this._parent.insertNode(this._child, this._index); | ||
this._parent.insertNode(this._child, this._position); | ||
return true; | ||
} | ||
getData(): RemoveNodeCommandData { | ||
return { | ||
id: this.id, | ||
parentId: this._parent.id, | ||
childId: this._child.id, | ||
position: this._position | ||
} | ||
} | ||
} | ||
export namespace RemoveNodeCommandData { | ||
export const ID = 'RemoveNode'; | ||
export function is(arg: any): arg is RemoveNodeCommandData { | ||
return CommandData.is(arg) | ||
&& arg.id === ID | ||
&& 'parentId' in arg | ||
&& 'childId' in arg | ||
&& 'position' in arg; | ||
} | ||
} | ||
export type RemoveNodeCommandData = CommandData & { | ||
parentId: string; | ||
childId: string; | ||
position: number; | ||
} |
@@ -0,6 +1,5 @@ | ||
import { CommandData } from "../../command/command"; | ||
import { GxmlNode } from "../gxml-node"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'SetPropertyValue'; | ||
export class SetPropertyValueCommand extends GxmlCommand { | ||
@@ -11,5 +10,5 @@ | ||
private _oldValue: string; | ||
private _newValue: string | ||
private _value: string | ||
constructor(node: GxmlNode, name: string, oldValue: string, newValue: string) { | ||
constructor(node: GxmlNode, name: string, oldValue: string, value: string) { | ||
super(); | ||
@@ -20,7 +19,7 @@ | ||
this._oldValue = oldValue; | ||
this._newValue = newValue; | ||
this._value = value; | ||
} | ||
get id(): string { | ||
return ID; | ||
return SetPropertyValueCommandData.ID; | ||
} | ||
@@ -33,3 +32,3 @@ | ||
do(): boolean { | ||
this._node.setPropertyValue(this._name, this._newValue); | ||
this._node.setPropertyValue(this._name, this._value); | ||
return true; | ||
@@ -42,2 +41,32 @@ } | ||
} | ||
getData(): SetPropertyValueCommandData { | ||
return { | ||
id: this.id, | ||
nodeId: this._node.id, | ||
name: this._name, | ||
oldValue: this._oldValue, | ||
value: this._value | ||
} | ||
} | ||
} | ||
export namespace SetPropertyValueCommandData { | ||
export const ID = 'SetPropertyValue'; | ||
export function is(arg: any): arg is SetPropertyValueCommandData { | ||
return CommandData.is(arg) | ||
&& arg.id === ID | ||
&& 'nodeId' in arg | ||
&& 'oldValue' in arg | ||
&& 'value' in arg; | ||
} | ||
} | ||
export type SetPropertyValueCommandData = CommandData & { | ||
nodeId: string; | ||
name: string; | ||
oldValue: string; | ||
value: string; | ||
} |
import { CommandData } from "../../command/command"; | ||
import { GxmlDocument } from "../gxml-document"; | ||
import { GxmlNode } from "../gxml-node"; | ||
import { GxmlNode, GxmlNodeData } from "../gxml-node"; | ||
import { GxmlCommand } from "./gxml-command"; | ||
const ID = 'SetRootNode'; | ||
export class SetRootNodeCommand extends GxmlCommand { | ||
@@ -23,3 +22,3 @@ | ||
get id(): string { | ||
return ID; | ||
return SetRootNodeCommandData.ID; | ||
} | ||
@@ -53,2 +52,26 @@ | ||
getData(): SetRootNodeCommandData { | ||
return { | ||
id: this.id, | ||
rootNode: this._rootNode.toData(), | ||
oldRootNodeId: this._oldRootNode.id | ||
} | ||
} | ||
} | ||
export namespace SetRootNodeCommandData { | ||
export const ID = 'SetRootNode'; | ||
export function is(arg: any): arg is SetRootNodeCommandData { | ||
return CommandData.is(arg) | ||
&& arg.id === ID | ||
&& 'rootNode' in arg | ||
&& 'oldRootNodeId' in arg; | ||
} | ||
} | ||
export type SetRootNodeCommandData = CommandData & { | ||
rootNode: GxmlNodeData; | ||
oldRootNodeId: string; | ||
} |
@@ -1,14 +0,15 @@ | ||
import { CompositeCommand } from "../command"; | ||
import { Disposable } from "../disposable"; | ||
import { Emitter } from "../emitter"; | ||
import { Guid } from "../guid"; | ||
import { GxmlCommand } from "./commands/gxml-command"; | ||
import { GxmlCompositeCommand } from "./commands/gxml-composite-command"; | ||
import { SetRootNodeCommand } from "./commands/set-root-node-command"; | ||
import { GxmlNode } from "./gxml-node"; | ||
import { GxmlNodeDescriptor, GxmlNodeDescriptorRegistry } from "./gxml-node-descriptor"; | ||
import { CompositeCommand } from '../command'; | ||
import { Disposable } from '../disposable'; | ||
import { Emitter } from '../emitter'; | ||
import { Guid } from '../guid'; | ||
import { GxmlCommand } from './commands/gxml-command'; | ||
import { GxmlCompositeCommand } from './commands/gxml-composite-command'; | ||
import { GxmlNode, VisitNodeCallback } from './gxml-node'; | ||
import { GxmlNodeDescriptor, GxmlNodeDescriptorRegistry } from './gxml-node-descriptor'; | ||
import { SetRootNodeCommand } from './commands/set-root-node-command'; | ||
import { MaybePromise } from '../types'; | ||
const _EVT_CHANGED = 'Changed'; | ||
const _EVT_UPDATE_FINISHED = 'UpdateFinished'; | ||
const _NAME_REGEX = /([^\d]+)([\d]*)/g; | ||
@@ -19,2 +20,7 @@ export type GxmlDocumentOptions = { | ||
export type DocumentChangedEventArgs = { | ||
document: GxmlDocument, | ||
command: GxmlCommand | ||
} | ||
export class GxmlDocument { | ||
@@ -28,2 +34,3 @@ | ||
private _updateCount: number; | ||
private _knownNodes: Set<string>; | ||
@@ -35,2 +42,3 @@ constructor(options: GxmlDocumentOptions) { | ||
this._updateCount = 0; | ||
this._knownNodes = new Set(); | ||
} | ||
@@ -66,4 +74,6 @@ | ||
visitNodes(fn: (n: GxmlNode) => boolean) { | ||
/// <summary> | ||
/// Visits the root node its descendant with function fn. If fn returns true, the visit is stopped. | ||
/// </summary> | ||
visitNodes(fn: VisitNodeCallback) { | ||
this._rootNode?.visitNodes(fn); | ||
@@ -76,2 +86,10 @@ } | ||
/// <summary> | ||
/// Returns true if this node belongs to this document but it is the first time it is inserted into the document in the context of | ||
/// the current update operation. After the update operation is finished, the node is considered to be known and no longer a new one. | ||
/// </summary> | ||
isNewNode(node: GxmlNode) { | ||
return !this._knownNodes.has(node.id); | ||
} | ||
get updating(): boolean { | ||
@@ -89,12 +107,5 @@ return !!this._compositeCommand; | ||
async endUpdate() { | ||
console.log('End udpate 1', this._updateCount); | ||
if (this._updateCount > 0) { | ||
this._updateCount--; | ||
console.log('End update', this._updateCount, this._compositeCommand); | ||
if (this._updateCount === 0) { | ||
@@ -104,4 +115,6 @@ let command = this._compositeCommand; | ||
if (command && command.count > 0) | ||
if (command && command.count > 0) { | ||
await this._fireUpdateFinishedEvent(command); | ||
this._updateKnownNodes(); | ||
} | ||
} | ||
@@ -111,4 +124,3 @@ } | ||
onChanged(command: GxmlCommand) { | ||
//if (command instanceof InsertNodeCommand || command instanceof SetRootNodeCommand) | ||
onChanged(command: GxmlCommand, notify: boolean = true) { | ||
this._fixUniqueProperties(); | ||
@@ -119,14 +131,20 @@ | ||
// Do not wait for promise, this case is supposed to be used only in synchronous cases without beginUpdate and endUpdate | ||
this._fireChangedEvent(command); | ||
if (notify) { | ||
// Do not wait for promise, this case is supposed to be used only in synchronous cases without beginUpdate and endUpdate | ||
this._fireChangedEvent(command); | ||
} | ||
if (this._compositeCommand) | ||
this._compositeCommand.addCommand(command); | ||
if (this._compositeCommand) { | ||
if (notify) | ||
this._compositeCommand.addCommand(command); | ||
} | ||
else | ||
this._updateKnownNodes(); | ||
} | ||
changed(callback: (args: DocumentChangedEventArgs) => void): Disposable { | ||
changed(callback: (args: DocumentChangedEventArgs) => MaybePromise<void>): Disposable { | ||
return this._emitter.on(_EVT_CHANGED, callback); | ||
} | ||
updateFinished(callback: (args: DocumentChangedEventArgs) => void): Disposable { | ||
updateFinished(callback: (args: DocumentChangedEventArgs) => MaybePromise<void>): Disposable { | ||
return this._emitter.on(_EVT_UPDATE_FINISHED, callback); | ||
@@ -158,9 +176,10 @@ } | ||
this.visitNodes(n => { | ||
if (n.descriptor.hasId) { | ||
if (!n.id || usedIds.has(n.id.toLowerCase())) | ||
n.id = Guid.newInstance().toString(); | ||
usedIds.add(n.id.toLowerCase()); | ||
if (!n.id || usedIds.has(n.id.toLowerCase())) { | ||
//debugger; | ||
n.id = Guid.newInstance().toString(); | ||
} | ||
usedIds.add(n.id.toLowerCase()); | ||
if (n.descriptor.nameProperty) { | ||
@@ -203,7 +222,7 @@ if (!n.name || (n.descriptor.hasUniqueName && usedNames.has(n.name.toLowerCase()))) { | ||
} | ||
private _updateKnownNodes() { | ||
this.visitNodes(n => { this._knownNodes.add(n.id) }); | ||
} | ||
} | ||
export type DocumentChangedEventArgs = { | ||
document: GxmlDocument, | ||
command: GxmlCommand | ||
} |
@@ -1,6 +0,7 @@ | ||
import { Registry } from "../registry"; | ||
import { Registry } from '../registry'; | ||
export type GxmlNodeDescriptorOptions = { | ||
type: string; | ||
hasId?: boolean; | ||
flags?: number; | ||
nameProperty?: string; | ||
@@ -13,3 +14,3 @@ hasUniqueName?: boolean; | ||
private _type: string; | ||
private _hasId: boolean; | ||
private _flags: number; | ||
private _nameProperty?: string; | ||
@@ -20,3 +21,3 @@ private _hasUniqueName: boolean; | ||
this._type = options.type; | ||
this._hasId = options.hasId !== undefined ? options.hasId : true; | ||
this._flags = options.flags !== undefined ? options.flags : 0; | ||
this._nameProperty = options.nameProperty; | ||
@@ -26,17 +27,26 @@ this._hasUniqueName = options.hasUniqueName !== undefined ? options.hasUniqueName : true; | ||
public get type(): string { | ||
get type(): string { | ||
return this._type; | ||
} | ||
public get hasId(): boolean { | ||
return this._hasId; | ||
get flags(): number { | ||
return this._flags; | ||
} | ||
public get nameProperty(): string { | ||
get nameProperty(): string { | ||
return this._nameProperty; | ||
} | ||
public get hasUniqueName(): boolean { | ||
get hasUniqueName(): boolean { | ||
return this._hasUniqueName; | ||
} | ||
getData(): GxmlNodeDescriptorOptions { | ||
return { | ||
type: this._type, | ||
flags: this._flags, | ||
nameProperty: this._nameProperty, | ||
hasUniqueName: this._hasUniqueName | ||
} | ||
} | ||
} | ||
@@ -51,6 +61,5 @@ | ||
return new GxmlNodeDescriptor({ | ||
type, | ||
hasId: true | ||
type | ||
}); | ||
} | ||
} |
@@ -0,1 +1,2 @@ | ||
import { IDesignerHost } from "../component-model"; | ||
@@ -6,2 +7,3 @@ import { Guid } from "../guid"; | ||
import { InsertNodeCommand } from "./commands/insert-node-command"; | ||
import { MoveNodeCommand } from "./commands/move-command"; | ||
import { RemoveNodeCommand } from "./commands/remove-node-command"; | ||
@@ -18,2 +20,3 @@ import { SetPropertyValueCommand } from "./commands/set-property-value-command"; | ||
properties?: GxmlNodeProperties; | ||
isNew?: boolean; | ||
} | ||
@@ -25,2 +28,4 @@ | ||
export type VisitNodeCallback = (n: GxmlNode) => boolean | void; | ||
export class GxmlNode { | ||
@@ -42,4 +47,3 @@ | ||
this._id = this._descriptor.hasId ? options.id || Guid.newInstance().toString() : undefined; | ||
this._id = options.id || Guid.newInstance().toString(); | ||
this._children = []; | ||
@@ -78,2 +82,6 @@ | ||
get isNew() { | ||
return this._document.isNewNode(this); | ||
} | ||
get name(): string | undefined { | ||
@@ -105,3 +113,3 @@ if (this._descriptor.nameProperty) | ||
getNodeById(id: string) { | ||
return this.findNode(n => n.id === id); | ||
return this.findNode(n => n.id.toLowerCase() === id.toLocaleLowerCase()); | ||
} | ||
@@ -131,7 +139,10 @@ | ||
visitNodes(fn: (n: GxmlNode) => boolean) { | ||
/// <summary> | ||
/// Visits this node and its descendant with function fn. If fn returns true, the visit is stopped. | ||
/// </summary> | ||
visitNodes(fn: VisitNodeCallback) { | ||
let queue: GxmlNode[] = [this]; | ||
while (queue.length > 0) { | ||
let current = queue.shift(); | ||
if (fn(current)) | ||
if (!!fn(current)) | ||
break; | ||
@@ -161,3 +172,5 @@ | ||
this._properties.set(name, value); | ||
this._document.onChanged(new SetPropertyValueCommand(this, name, oldValue, value)); | ||
if (!this.isNew) | ||
this._document.onChanged(new SetPropertyValueCommand(this, name, oldValue, value)); | ||
} | ||
@@ -181,3 +194,3 @@ | ||
insertNode(child: GxmlNode, index: number) { | ||
insertNode(child: GxmlNode, position: number) { | ||
if (child.document !== this._document) | ||
@@ -192,6 +205,6 @@ throw Error('Node belongs to another document'); | ||
this._children.splice(index, 0, child); | ||
this._children.splice(position, 0, child); | ||
child._parent = this; | ||
this._document.onChanged(new InsertNodeCommand(this, child, index)); | ||
this._document.onChanged(new InsertNodeCommand(this, child, position)); | ||
} | ||
@@ -202,2 +215,3 @@ | ||
if (index >= 0) { | ||
child._parent = undefined; | ||
this._children.splice(index, 1); | ||
@@ -212,4 +226,20 @@ this._document.onChanged(new RemoveNodeCommand(this, child, index)); | ||
moveNode(child: GxmlNode, newPosition: number): boolean { | ||
let oldPosition = this._children.indexOf(child); | ||
if (oldPosition >= 0) { | ||
this._children.splice(oldPosition, 1); | ||
this._children.splice(newPosition, 0, child); | ||
this._document.onChanged(new MoveNodeCommand(child, oldPosition, newPosition)); | ||
return true; | ||
} | ||
return false; | ||
} | ||
remove(): boolean { | ||
return !!this._parent?.removeNode(this); | ||
if (!this._parent) | ||
throw Error('Node has no parent'); | ||
return !!this._parent.removeNode(this); | ||
} | ||
@@ -216,0 +246,0 @@ |
export * from "./gxml-document"; | ||
export * from "./gxml-node"; | ||
export * from "./gxml-node-descriptor"; | ||
export * from "./commands"; |
@@ -0,2 +1,4 @@ | ||
export * from './control-helper'; | ||
export * from './dynamic-assets-loader'; | ||
export * from './flag-set'; | ||
export * from './service-helper'; |
import { Disposable } from "event-kit"; | ||
import { CompositeDisposable } from "../composite-disposable"; | ||
import { IDisposable } from "../disposable"; | ||
@@ -33,3 +34,3 @@ import { Guid } from "../guid"; | ||
export class InterFrameServiceHelper { | ||
export class FrameBridge { | ||
@@ -39,58 +40,19 @@ private static readonly EXECUTE_OPERATION_EVENT_NAME = 'ExecuteServiceOperation'; | ||
private static _pendingOperations: Map<string, {resolve: Function, reject: Function}> = new Map(); | ||
private static _serviceMap: Map<string, any> = new Map(); | ||
private _local: Window; | ||
private _remote: Window; | ||
private _disposables: CompositeDisposable; | ||
private _pendingOperations: Map<string, { resolve: Function, reject: Function }>; | ||
private _serviceMap: Map<string, any>; | ||
static initializeSourceEndpoint(source: Window): IDisposable { | ||
const listener = (e: MessageEvent<any>) => { | ||
if (e.data?.eventName === InterFrameServiceHelper.OPERATION_RESULT_EVENT_NAME && e.data.data.guid) { | ||
let data = e.data.data as ServiceOperationResultData; | ||
let pending = InterFrameServiceHelper._pendingOperations.get(data.guid); | ||
InterFrameServiceHelper._pendingOperations.delete(data.guid); | ||
if (pending) { | ||
if (data.success) | ||
pending.resolve(data.value); | ||
else | ||
pending.reject(data.errorMessage || 'Operation Failed'); | ||
} | ||
} | ||
} | ||
source.addEventListener('message', listener); | ||
return new Disposable(() => source.removeEventListener('message', listener)); | ||
constructor(local: Window, remote: Window) { | ||
this._local = local; | ||
this._remote = remote; | ||
this._disposables = new CompositeDisposable(); | ||
this._pendingOperations = new Map(); | ||
this._serviceMap = new Map(); | ||
this._initializeSource(); | ||
this._initializeTarget(); | ||
} | ||
static initializeTargetEndpoint(target: Window, source: Window): IDisposable { | ||
const listener = async (e: MessageEvent<any>) => { | ||
if (e.data?.eventName === InterFrameServiceHelper.EXECUTE_OPERATION_EVENT_NAME) { | ||
let data = e.data.data as ServiceOperationInvocationData; | ||
let service = InterFrameServiceHelper._serviceMap.get(data.serviceName); | ||
let result: ServiceOperationResultData = { guid: data.guid, success: false }; | ||
if (service) { | ||
try { | ||
result.value = await service[data.operation](...data.args); | ||
result.success = true; | ||
} | ||
catch (ex) { | ||
result.errorMessage = ex.message; | ||
} | ||
} | ||
else { | ||
result.errorMessage = `Service '${data.serviceName}' does not exist`; | ||
} | ||
source.postMessage({ eventName: InterFrameServiceHelper.OPERATION_RESULT_EVENT_NAME, data: result }, '*'); | ||
} | ||
} | ||
target.addEventListener('message', listener); | ||
return new Disposable(() => target.removeEventListener('message', listener)); | ||
} | ||
static createProxy(target: Window, descriptor: ServiceDescriptorData): ServiceProxy { | ||
createProxy(descriptor: ServiceDescriptorData): ServiceProxy { | ||
let proxy: ServiceProxy = {}; | ||
@@ -100,6 +62,6 @@ for (let op of descriptor.operations) { | ||
let guid = Guid.newInstance().toString(); | ||
InterFrameServiceHelper._pendingOperations.set(guid, {resolve, reject}); | ||
this._pendingOperations.set(guid, { resolve, reject }); | ||
target.postMessage({ | ||
eventName: InterFrameServiceHelper.EXECUTE_OPERATION_EVENT_NAME, | ||
this._remote.postMessage({ | ||
eventName: FrameBridge.EXECUTE_OPERATION_EVENT_NAME, | ||
data: { | ||
@@ -118,20 +80,15 @@ guid, | ||
static registerServices(services: Map<string, any>): IDisposable { | ||
let disposables: IDisposable[] = []; | ||
registerServices(services: Map<string, any>): void { | ||
for (let service of services.entries()) | ||
disposables.push(this.registerService(service[0], service[1])); | ||
return new Disposable(() => disposables.forEach(d => d.dispose())); | ||
this.registerService(service[0], service[1]); | ||
} | ||
static registerService(name: string, service: any): IDisposable { | ||
if (InterFrameServiceHelper._serviceMap.has(name)) | ||
registerService(name: string, service: any): void { | ||
if (this._serviceMap.has(name)) | ||
throw new Error(`Service '${name}' already registered`); | ||
InterFrameServiceHelper._serviceMap.set(name, service); | ||
return new Disposable(() => InterFrameServiceHelper._serviceMap.delete(name)) | ||
this._serviceMap.set(name, service); | ||
} | ||
static getServiceDescriptors(services: Map<string, any>): ServiceDescriptorData[] { | ||
getServiceDescriptors(services: Map<string, any>): ServiceDescriptorData[] { | ||
let data: ServiceDescriptorData[] = []; | ||
@@ -144,3 +101,3 @@ for (let name of services.keys()) | ||
static getServiceDescriptor(name: string, service: any): ServiceDescriptorData { | ||
getServiceDescriptor(name: string, service: any): ServiceDescriptorData { | ||
return { | ||
@@ -152,7 +109,11 @@ name, | ||
private static _getAllFunctions(target: any): string[] { | ||
dispose() { | ||
this._disposables.dispose(); | ||
} | ||
private _getAllFunctions(target: any): string[] { | ||
return [...this._getFunctions(target), ...this._getFunctions(Object.getPrototypeOf(target))]; | ||
} | ||
private static _getFunctions(target: any): string[] { | ||
private _getFunctions(target: any): string[] { | ||
let fs = []; | ||
@@ -166,3 +127,50 @@ for (let p of Object.getOwnPropertyNames(target)) { | ||
} | ||
private _initializeSource(): void { | ||
const listener = (e: MessageEvent<any>) => { | ||
if (e.data?.eventName === FrameBridge.OPERATION_RESULT_EVENT_NAME && e.data.data.guid) { | ||
let data = e.data.data as ServiceOperationResultData; | ||
let pending = this._pendingOperations.get(data.guid); | ||
this._pendingOperations.delete(data.guid); | ||
if (pending) { | ||
if (data.success) | ||
pending.resolve(data.value); | ||
else | ||
pending.reject(data.errorMessage || 'Operation Failed'); | ||
} | ||
} | ||
} | ||
this._local.addEventListener('message', listener); | ||
this._disposables.add(new Disposable(() => this._local?.removeEventListener && this._local.removeEventListener('message', listener))); | ||
} | ||
private _initializeTarget() { | ||
const listener = async (e: MessageEvent<any>) => { | ||
if (this._remote === e.source && e.data?.eventName === FrameBridge.EXECUTE_OPERATION_EVENT_NAME) { | ||
let data = e.data.data as ServiceOperationInvocationData; | ||
let service = this._serviceMap.get(data.serviceName); | ||
let result: ServiceOperationResultData = { guid: data.guid, success: false }; | ||
if (service) { | ||
try { | ||
result.value = await service[data.operation](...data.args); | ||
result.success = true; | ||
} | ||
catch (ex) { | ||
result.errorMessage = ex.message; | ||
} | ||
} | ||
else { | ||
result.errorMessage = `Service '${data.serviceName}' does not exist`; | ||
} | ||
this._remote.postMessage({ eventName: FrameBridge.OPERATION_RESULT_EVENT_NAME, data: result }, '*'); | ||
} | ||
} | ||
this._local.addEventListener('message', listener); | ||
this._disposables.add(new Disposable(() => this._remote?.removeEventListener && this._remote?.removeEventListener('message', listener))); | ||
} | ||
} | ||
@@ -1,2 +0,2 @@ | ||
import { GxmlNodeData, GxmlNodeOptions } from "./gxml"; | ||
import { GxmlNodeOptions } from "./gxml"; | ||
import { AssetData, ServiceDescriptorData } from "./helpers"; | ||
@@ -13,3 +13,2 @@ | ||
export type DesignerOptionsData = { | ||
rootNode: GxmlNodeData; | ||
services?: ServiceDescriptorData[]; | ||
@@ -23,9 +22,3 @@ assets?: AssetData[]; | ||
export const DESIGNER_READY = 'designerReady'; | ||
export const EXTERNAL_DRAG_START = 'externalDragStart'; | ||
export const EXTERNAL_DRAG_END = 'externalDragEnd'; | ||
export const EXTERNAL_DRAG_ENTER = 'externalDragEnter'; | ||
export const EXTERNAL_DRAG_LEAVE = 'externalDragLeave'; | ||
export const EXTERNAL_DRAG_OVER = 'externalDragOver'; | ||
export const EXTERNAL_DROP = 'externalDrop'; | ||
export const DESIGNER_FOCUS = 'designerFocus'; | ||
} | ||
@@ -50,3 +43,3 @@ | ||
export function setExternalDragData(win: Window, options: GxmlNodeOptions) { | ||
export function setExternalDragData(win: Window, options: GxmlNodeOptions | undefined) { | ||
(win as any)[SYM_DRAG_DATA] = options; | ||
@@ -83,4 +76,6 @@ //dt.setData(GX_DESIGNER_DRAG_FORMAT, JSON.stringify({ data: options, isCopy: false, isInternal: false } as DragData)); | ||
readonly cellIndex: number; | ||
readonly column: number; | ||
readonly position: PlaceHolderPosition; | ||
readonly data: DragHelper.DragData; | ||
readonly isVirtual: boolean; | ||
} | ||
@@ -99,2 +94,5 @@ | ||
readonly isEmpty: boolean; | ||
readonly column: number; | ||
readonly cellIdx: number; | ||
readonly isVirtual: boolean; | ||
} | ||
@@ -101,0 +99,0 @@ |
@@ -30,4 +30,9 @@ import { Control } from "../component-model"; | ||
export interface IDesignerViewContainer { | ||
controls: Control[]; | ||
export type DesignerViewControls = { | ||
root: Element; | ||
active?: Control[]; | ||
} | ||
export interface IDesignerViewContainer { | ||
controls: DesignerViewControls; | ||
toolbarHidden: boolean; | ||
@@ -34,0 +39,0 @@ pointerEvents: boolean; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
305518
237
5596
0