import ViewController from './ViewController'; import shim from 'lib/shim'; import { ButtonId, ButtonSpec } from './api/types'; const { toSystemSlashes } = require('lib/path-utils'); export enum ContainerType { Panel = 'panel', Dialog = 'dialog', } export interface Options { containerType: ContainerType, } interface CloseResponse { resolve: Function; reject: Function; } export default class WebviewController extends ViewController { private baseDir_:string; private messageListener_:Function = null; private closeResponse_:CloseResponse = null; constructor(id:string, pluginId:string, store:any, baseDir:string) { super(id, pluginId, store); this.baseDir_ = toSystemSlashes(baseDir, 'linux'); this.store.dispatch({ type: 'PLUGIN_VIEW_ADD', pluginId: pluginId, view: { id: this.handle, type: this.type, containerType: ContainerType.Panel, html: '', scripts: [], opened: false, buttons: null, }, }); } public get type():string { return 'webview'; } private setStoreProp(name:string, value:any) { this.store.dispatch({ type: 'PLUGIN_VIEW_PROP_SET', pluginId: this.pluginId, id: this.handle, name: name, value: value, }); } public get html():string { return this.storeView.html; } public set html(html:string) { this.setStoreProp('html', html); } public get containerType():ContainerType { return this.storeView.containerType; } public set containerType(containerType:ContainerType) { this.setStoreProp('containerType', containerType); } public async addScript(path:string) { const fullPath = toSystemSlashes(shim.fsDriver().resolve(`${this.baseDir_}/${path}`), 'linux'); if (fullPath.indexOf(this.baseDir_) !== 0) throw new Error(`Script appears to be outside of plugin base directory: ${fullPath} (Base dir: ${this.baseDir_})`); this.store.dispatch({ type: 'PLUGIN_VIEW_PROP_PUSH', pluginId: this.pluginId, id: this.handle, name: 'scripts', value: fullPath, }); } public emitMessage(event:any) { if (!this.messageListener_) return; this.messageListener_(event.message); } public onMessage(callback:any) { this.messageListener_ = callback; } // --------------------------------------------- // Specific to dialogs // --------------------------------------------- public async open():Promise { this.setStoreProp('opened', true); return new Promise((resolve:Function, reject:Function) => { this.closeResponse_ = { resolve, reject }; }); } public async close() { this.setStoreProp('opened', false); } public closeWithResponse(result:ButtonId) { this.close(); this.closeResponse_.resolve(result); } public get buttons():ButtonSpec[] { return this.storeView.buttons; } public set buttons(buttons:ButtonSpec[]) { this.setStoreProp('buttons', buttons); } }