import {Command, Session} from "../session"; import {randomid} from "../utils"; import {getWidgetElement} from "../models/output" import {CommandHandler} from "./base"; export class PopupHandler implements CommandHandler { session: Session; accept_command = ['popup', 'close_popup']; private body = $('body'); constructor(session: Session) { this.session = session; } static current_elem: JQuery = null; // 当前正在处于显示中的弹窗元素,表示页面的期望状态 handle_message(msg: Command) { if (PopupHandler.current_elem) { // @ts-ignore PopupHandler.current_elem.modal('hide'); PopupHandler.current_elem = null; } if (msg.command == 'popup') { // 显示弹窗前,先关闭其他弹窗 // @ts-ignore $('.modal').modal('hide'); let elem = PopupHandler.get_element(msg.spec); this.body.append(elem); // 弹窗关闭后就立即销毁 elem.on('hidden.bs.modal', function (e) { elem.remove(); }); elem.on('shown.bs.modal', function (e) { // 弹窗显示后,有新弹窗出现或当前弹窗被关闭,则立即关闭当前弹窗 if (elem != PopupHandler.current_elem || !PopupHandler.current_elem) { // @ts-ignore elem.modal('hide'); } }); // @ts-ignore elem.modal('show'); PopupHandler.current_elem = elem; } else if (msg.command == 'close_popup') { // @ts-ignore $('.modal').modal('hide'); PopupHandler.current_elem = null; } } static get_element(spec: { title: string, content: any[], closable: boolean, implicit_close: boolean, size: string }) { // https://v4.bootcss.com/docs/components/modal/#options const tpl = ``; let mid = randomid(10); let body_html = ''; for (let output_item of spec.content) { if (typeof output_item === 'object') { try { let nodes = getWidgetElement(output_item); for (let node of nodes) body_html += node.outerHTML || ''; } catch (e) { console.error('Get widget html error,', e, output_item); } } else { body_html += output_item; } } if (!spec.closable) spec.implicit_close = false; let html = Mustache.render(tpl, { ...spec, // 字段: content, title, size, implicit_close, closable large: spec.size == 'large', small: spec.size == 'small', mid: mid, content: body_html, }); return $(html as string); } }