{"version":3,"sources":["../../../packages/core/frame/frame-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,UAAU,EAAY,MAAM,MAAM,CAAC;AAIzD,OAAO,EACH,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,4BAA4B,EAC5B,6BAA6B,EAE7B,uBAAuB,EACvB,wBAAwB,EAI3B,MAAM,gCAAgC,CAAC;AAIxC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAE1E;;GAEG;AACH,qBAAa,eAAe;IAoBZ,OAAO,CAAC,GAAG;IAnBvB,OAAO,CAAC,uBAAuB,CAA4B;IAE3D;;OAEG;IACI,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEzD;;OAEG;IACH,IAAW,UAAU,IAAI,yBAAyB,CAEjD;IAED;;;;OAIG;gBACiB,GAAG,EAAE,GAAG;IAK5B;;;;;OAKG;IACI,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG,UAAU,CAAC,uBAAuB,CAAC;IAI7F;;;;;OAKG;IACI,iBAAiB,CAAC,OAAO,EAAE,uBAAuB,GAAG,UAAU,CAAC,wBAAwB,CAAC;IAKhG;;;;;OAKG;IACI,sBAAsB,CAAC,OAAO,EAAE,4BAA4B,GAAG,UAAU,CAAC,6BAA6B,CAAC;IAK/G;;;;;OAKG;IACI,0BAA0B,CAAC,OAAO,EAAE,gCAAgC,GAAG,UAAU,CAAC,6BAA6B,CAAC;IAKvH;;;;OAIG;IACI,WAAW,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC;IAQtE;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD;;;;;;;OAOG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpF;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA6ClB,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,aAAa;CAGxB","file":"frame-connection.d.ts","sourcesContent":["import { EMPTY, from, Observable, Observer } from 'rxjs';\r\nimport { expand, filter, map } from 'rxjs/operators';\r\nimport { Dom } from '../dom/dom';\r\nimport { RpcDialogClient } from '../rpc/dialog/rpc-dialog-client';\r\nimport {\r\n    RpcDialogChoiceRequest,\r\n    RpcDialogChoiceResponse,\r\n    RpcDialogConfirmationListRequest,\r\n    RpcDialogConfirmationRequest,\r\n    RpcDialogConfirmationResponse,\r\n    RpcDialogData,\r\n    RpcDialogMessageRequest,\r\n    RpcDialogMessageResponse,\r\n    RpcDialogResult,\r\n    RpcDialogState,\r\n    RpcDialogType\r\n} from '../rpc/dialog/rpc-dialog-model';\r\nimport { RpcDialogOverlayData } from '../rpc/overlay/rpc-overlay-model';\r\nimport { RpcOverlayOpenClient } from '../rpc/overlay/rpc-overlay-open-client';\r\nimport { RpcReportClient } from '../rpc/report/rpc-report-client';\r\nimport { RpcReportData } from '../rpc/report/rpc-report-model';\r\nimport { Rpc } from '../rpc/rpc';\r\nimport { RpcUpdateDataClient } from '../rpc/update-data/rpc-update-data-client';\r\nimport { RpcUpdateData } from '../rpc/update-data/rpc-update-data-model';\r\nimport { ShellNavigationConnection } from './shell-navigation-connection';\r\n\r\n/**\r\n * Frame connection class.\r\n */\r\nexport class FrameConnection {\r\n    private shellNavigationInternal: ShellNavigationConnection;\r\n\r\n    /**\r\n     * Active dialog origina data.\r\n     */\r\n    public activeRpcDialogsOrigins: Map<string, HTMLElement>;\r\n\r\n    /**\r\n     * Gets the shell navigation functions.\r\n     */\r\n    public get navigation(): ShellNavigationConnection {\r\n        return this.shellNavigationInternal;\r\n    }\r\n\r\n    /**\r\n     * Initializes a new instance of the FrameConnection class.\r\n     *\r\n     * @param rpc the RPC object.\r\n     */\r\n    constructor(private rpc: Rpc) {\r\n        this.activeRpcDialogsOrigins = new Map<string, HTMLElement>();\r\n        this.shellNavigationInternal = new ShellNavigationConnection(this.rpc);\r\n    }\r\n\r\n    /**\r\n     * Open a choice dialog and wait for completion through RPC.\r\n     * To close the dialog before user input, unsubscribe the observable.\r\n     *\r\n     * @param request the request object of rpc based dialog message.\r\n     */\r\n    public showDialogChoice(request: RpcDialogChoiceRequest): Observable<RpcDialogChoiceResponse> {\r\n        return this.showDialog<RpcDialogChoiceRequest, RpcDialogChoiceResponse>(request, RpcDialogType.OpenChoiceDialog);\r\n    }\r\n\r\n    /**\r\n     * Open a message dialog and wait for completion through RPC.\r\n     * To close the dialog before user input, unsubscribe the observable.\r\n     *\r\n     * @param request the request object of rpc based dialog message.\r\n     */\r\n    public showDialogMessage(request: RpcDialogMessageRequest): Observable<RpcDialogMessageResponse> {\r\n        return this.showDialog<RpcDialogMessageRequest, RpcDialogMessageResponse>(\r\n            request, RpcDialogType.OpenMessageDialog);\r\n    }\r\n\r\n    /**\r\n     * Open a confirmation dialog and wait for completion through RPC.\r\n     * To close the dialog before user input, unsubscribe the observable.\r\n     *\r\n     * @param request the request object of rpc based dialog confirmation.\r\n     */\r\n    public showDialogConfirmation(request: RpcDialogConfirmationRequest): Observable<RpcDialogConfirmationResponse> {\r\n        return this.showDialog<RpcDialogConfirmationRequest, RpcDialogConfirmationResponse>(\r\n            request, RpcDialogType.OpenConfirmationDialog);\r\n    }\r\n\r\n    /**\r\n     * Open a confirmation list dialog and wait for completion through RPC.\r\n     * To close the dialog before user input, unsubscribe the observable.\r\n     *\r\n     * @param request the request object of rpc based dialog confirmation list.\r\n     */\r\n    public showDialogConfirmationList(request: RpcDialogConfirmationListRequest): Observable<RpcDialogConfirmationResponse> {\r\n        return this.showDialog<RpcDialogConfirmationListRequest, RpcDialogConfirmationResponse>(\r\n            request, RpcDialogType.OpenConfirmationListDialog);\r\n    }\r\n\r\n    /**\r\n     * Call rpc for overlay command and create an observable\r\n     * @param overlayData true add overlay, false remove\r\n     * @param id id of dialog\r\n     */\r\n    public overlayOpen(overlayData: boolean, id: string): Observable<void> {\r\n        const data: RpcDialogOverlayData = {\r\n            overlay: overlayData,\r\n            dialogId: id\r\n        };\r\n        return from(RpcOverlayOpenClient.overlayOpen(this.rpc, data));\r\n    }\r\n\r\n    /**\r\n     * Report location change of module to shell.\r\n     */\r\n    public report(data: RpcReportData): Promise<void> {\r\n        return RpcReportClient.report(this.rpc, data);\r\n    }\r\n\r\n    /**\r\n     * Update data of new connection information to shell.\r\n     *\r\n     * @param name the module name.\r\n     * @param subName the sub name of module.\r\n     * @param data the update data object.\r\n     * @return Promise<void> the promise object.\r\n     */\r\n    public updateData(name: string, subName: string, data: RpcUpdateData): Promise<void> {\r\n        return RpcUpdateDataClient.updateData(this.rpc, name, subName, data);\r\n    }\r\n\r\n    /**\r\n     * Open a message dialog and wait for completion through RPC.\r\n     *\r\n     * @param request the request object of rpc based dialog message.\r\n     */\r\n    private showDialog<\r\n        TRequest extends RpcDialogMessageRequest | RpcDialogConfirmationRequest | RpcDialogConfirmationListRequest,\r\n        TResult extends RpcDialogMessageResponse | RpcDialogConfirmationResponse>\r\n        (request: TRequest, type: RpcDialogType): Observable<TResult> {\r\n        const data: RpcDialogData = {\r\n            dialogId: MsftSme.getUniqueId(),\r\n            type: type,\r\n            request\r\n        };\r\n        this.activeRpcDialogsOrigins.set(data.dialogId, document.activeElement as HTMLElement);\r\n\r\n        return new Observable((observer: Observer<TResult>) => {\r\n            const subscription = this.openAndLongPolling(data)\r\n                .pipe(\r\n                    map((value: RpcDialogResult) => {\r\n                        switch (value.state) {\r\n                            case RpcDialogState.Closed:\r\n                                this.removeActiveDialog(data.dialogId);\r\n                                observer.next(<TResult>value.response);\r\n                                observer.complete();\r\n                                break;\r\n                            case RpcDialogState.Failed:\r\n                                this.removeActiveDialog(data.dialogId);\r\n                                observer.error(new Error(value.failedMessage));\r\n                                break;\r\n                            case RpcDialogState.ForcedTerminated:\r\n                                this.removeActiveDialog(data.dialogId);\r\n                                observer.error(new Error('forced terminated'));\r\n                                break;\r\n                        }\r\n                    }))\r\n                .subscribe();\r\n            return () => {\r\n                if (!subscription.closed) {\r\n                    // sending close request to the shell/dialog if not closed yet.\r\n                    subscription.unsubscribe();\r\n                    data.request = null;\r\n                    data.type = RpcDialogType.Close;\r\n                    RpcDialogClient.dialog(this.rpc, data);\r\n                    this.removeActiveDialog(data.dialogId);\r\n                }\r\n            };\r\n        });\r\n    }\r\n\r\n    private removeActiveDialog(dialogId: string): void {\r\n        if (this.activeRpcDialogsOrigins.has(dialogId)) {\r\n            const focusOn = this.activeRpcDialogsOrigins.get(dialogId);\r\n            if (focusOn) {\r\n                // setTimeout to give the button elements time to update either as disabled or not\r\n                setTimeout(() => {\r\n                    if ((focusOn as HTMLButtonElement).disabled) {\r\n                        const nextZoneElement = Dom.getNextZoneElement(focusOn);\r\n                        if (nextZoneElement) {\r\n                            nextZoneElement.focus();\r\n                        }\r\n                    } else {\r\n                        focusOn.focus();\r\n                    }\r\n                });\r\n            }\r\n            this.activeRpcDialogsOrigins.delete(dialogId);\r\n        }\r\n    }\r\n\r\n    private openAndLongPolling(data: RpcDialogData): Observable<RpcDialogResult> {\r\n        return this.requestDialog(data)\r\n            .pipe(\r\n                expand((result) => {\r\n                    if (result.state === RpcDialogState.Opened) {\r\n                        // status polling...\r\n                        const newData: RpcDialogData = {\r\n                            dialogId: data.dialogId,\r\n                            type: RpcDialogType.PollingStatus\r\n                        };\r\n                        return this.requestDialog(newData);\r\n                    }\r\n\r\n                    return EMPTY;\r\n                }),\r\n                filter(result => result.state !== RpcDialogState.Opened));\r\n    }\r\n\r\n    private requestDialog(data: RpcDialogData): Observable<RpcDialogResult> {\r\n        return from(RpcDialogClient.dialog(this.rpc, data));\r\n    }\r\n}\r\n"]}