import { GlobalConfig } from "../../config/GlobalConfig"; import { EventEmiter } from "../../event/EventEmiter"; import { PopsElementHandler } from "../../handler/PopsElementHandler"; import { PopsHandler } from "../../handler/PopsHandler"; import { PopsInstHandler } from "../../handler/PopsInstHandler"; import { PopsCSS } from "../../PopsCSS"; import { PopsInstData } from "../../PopsInst"; import type { PopsType } from "../../types/main"; import { popsDOMUtils } from "../../utils/PopsDOMUtils"; import { popsUtils } from "../../utils/PopsUtils"; import { PopsIframeDefaultConfig } from "./defaultConfig"; import type { PopsIframeClickEventConfig, PopsIframeConfig } from "./types"; export const PopsIframe = { init(__config__: PopsIframeConfig) { const guid = popsUtils.getRandomGUID(); // 设置当前类型 const popsType: PopsType = "iframe"; let config = PopsIframeDefaultConfig(); config = popsUtils.assign(config, GlobalConfig.getGlobalConfig()); config = popsUtils.assign(config, __config__); if (config.url == null) { throw new TypeError("config.url must not be null."); } config = PopsHandler.handleOnly(popsType, config); const emitter = config.emitter ?? new EventEmiter<{ "pops:iframe-min": (eventConfig: PopsIframeClickEventConfig, event: MouseEvent | PointerEvent) => void; "pops:iframe-mise": (eventConfig: PopsIframeClickEventConfig, event: MouseEvent | PointerEvent) => void; "pops:iframe-max": (eventConfig: PopsIframeClickEventConfig, event: MouseEvent | PointerEvent) => void; }>(popsType); const { $shadowContainer, $shadowRoot } = PopsHandler.handlerShadow(config); PopsHandler.handleInit($shadowRoot, [ { name: "index", css: PopsCSS.index, }, { name: "ninePalaceGridPosition", css: PopsCSS.ninePalaceGridPosition, }, { name: "scrollbar", css: PopsCSS.scrollbar, }, { name: "anim", css: PopsCSS.anim, }, { name: "common", css: PopsCSS.common, }, { name: "skeleton", css: PopsCSS.skeletonCSS, }, { name: "iframeCSS", css: PopsCSS.iframeCSS, }, ]); const maskExtraStyle = config.animation != null && config.animation != "" && config.animation ? "position:absolute;" : ""; // 先把z-index提取出来 const zIndex = PopsHandler.getTargerOrFunctionValue(config.zIndex); const maskHTML = PopsElementHandler.createMask(guid, zIndex, maskExtraStyle); const headerBtnHTML = PopsElementHandler.createHeader(popsType, config); const iframeLoadingHTML = /*html*/ '
'; const titleText = config.title!.text!.trim() !== "" ? config.title.text : config.url; const { headerStyle, headerPStyle } = PopsElementHandler.createHeaderStyle(popsType, config); const animHTML = PopsElementHandler.createAnim( guid, popsType, config, /*html*/ `
${ config.title.html ? titleText : `

${titleText}

` }${headerBtnHTML}
${config.loading.enable ? iframeLoadingHTML : ""}`, "", zIndex ); /** * 弹窗的主元素,包括动画层 */ const $anim = PopsElementHandler.parseElement(animHTML); const { $pops, $headerBtnClose, $headerControls, $title, $iframe, $loading, $contentLoading, $headerBtnMin, $headerBtnMax, $headerBtnMise, } = PopsHandler.handleQueryElement($anim, popsType); let $iframeContainer = popsDOMUtils.selector(".pops-iframe-container"); if (!$iframeContainer) { $iframeContainer = popsDOMUtils.createElement("div", { className: "pops-iframe-container", }); $iframeContainer.style.cssText = "display: flex;position: fixed;bottom: 0px;flex-flow: wrap-reverse;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;"; popsDOMUtils.appendBody($iframeContainer); } /** * 遮罩层元素 */ let $mask: HTMLDivElement | undefined = void 0; /** * 已创建的元素列表 */ const $elList: HTMLElement[] = [$anim]; if (config.mask.enable) { const handleMask = PopsHandler.handleMask({ type: popsType, guid: guid, config: config, animElement: $anim, maskHTML: maskHTML, }); $mask = handleMask.maskElement; $elList.push($mask); } const evtConfig = PopsHandler.handleEventConfig( config, guid, $shadowContainer, $shadowRoot, popsType, $anim, $pops, emitter, $mask ) as PopsIframeClickEventConfig; // 赋值额外的$iframe参数 evtConfig.$iframe = $iframe; const result = PopsHandler.handleResultConfig(evtConfig); popsDOMUtils.on($anim, popsDOMUtils.getAnimationEndNameList(), function () { // 动画加载完毕 $anim.style.width = "0%"; $anim.style.height = "0%"; }); popsDOMUtils.on($iframe, "load", () => { // iframe加载中... popsDOMUtils.remove($loading); $contentLoading!.style.animation = "iframeLoadingChange_85 0.3s forwards"; popsDOMUtils.on($contentLoading, popsDOMUtils.getAnimationEndNameList(), () => { // 动画加载完毕就移除 popsDOMUtils.remove($contentLoading); }); if (config.title!.text!.trim() === "" && $iframe!.contentDocument) { // 同域名下的才可以获取网页标题 $title!.querySelector("p")!.innerText = $iframe!.contentDocument.title; } config.loadEndCallBack(evtConfig); }); // 创建到页面中 popsDOMUtils.append($shadowRoot, $elList); emitter.emit("pops:before-append-to-page", $shadowRoot, $shadowContainer); $iframeContainer.appendChild($shadowContainer); if ($mask != null) { $anim.after($mask); } // 拖拽 if (config.drag) { PopsInstHandler.drag($pops!, { dragElement: $title!, limit: config.dragLimit, extraDistance: config.dragExtraDistance, moveCallBack: config.dragMoveCallBack, endCallBack: config.dragEndCallBack, }); } const TYPE_MODULE = "type-module"; // 最小化按钮点击事件 let origin_left = ""; let origin_top = ""; let origin_is_max = false; popsDOMUtils.on( $headerBtnMin, "click", (event) => { event.preventDefault(); event.stopPropagation(); origin_left = $pops.style.left; origin_top = $pops.style.top; popsDOMUtils.addClassName( $pops, "pops-iframe-unset-top", "pops-iframe-unset-left", "pops-iframe-unset-transform" ); $pops.style.transitionDuration = ""; $pops.setAttribute(TYPE_MODULE, "min"); $headerControls.setAttribute("type", "min"); // 隐藏放大图标 $headerBtnMax.style.setProperty("display", "none"); // 显示复位图标 $headerBtnMise.style.setProperty("display", ""); if (typeof config?.btn?.min?.callback === "function") { config.btn.min.callback(evtConfig, event); } emitter.emit("pops:iframe-min", evtConfig, event); }, { capture: true, } ); // 最大化按钮点击事件 popsDOMUtils.on( $headerBtnMax, "click", (event) => { event.preventDefault(); event.stopPropagation(); if ($pops.getAttribute(TYPE_MODULE) !== "min") { origin_left = $pops.style.left; origin_top = $pops.style.top; } origin_is_max = true; $pops.style.transitionDuration = ""; $pops.style.transform = ""; $pops.removeAttribute(TYPE_MODULE); popsDOMUtils.addClassName( $pops, "pops-iframe-unset-transition", "pops-iframe-unset-left", "pops-iframe-unset-top", "pops-iframe-unset-transform" ); popsDOMUtils.removeClassName($pops, "pops-iframe-unset-transition"); $pops.setAttribute(TYPE_MODULE, "max"); $headerControls.setAttribute("type", "max"); // 隐藏放大图标 $headerBtnMax.style.setProperty("display", "none"); // 显示复位图标 $headerBtnMise.style.setProperty("display", ""); if (typeof config?.btn?.max?.callback === "function") { config.btn.max.callback(evtConfig, event); } emitter.emit("pops:iframe-max", evtConfig, event); }, { capture: true, } ); // 先隐藏窗口化按钮 $headerBtnMise?.style?.setProperty("display", "none"); // 复位按钮点击事件 popsDOMUtils.on( $headerBtnMise, "click", (event) => { event.preventDefault(); event.stopPropagation(); if (origin_is_max && $pops.getAttribute(TYPE_MODULE) === "min") { popsDOMUtils.addClassName( $pops, "pops-iframe-unset-transition", "pops-iframe-unset-left", "pops-iframe-unset-top", "pops-iframe-unset-transform" ); popsDOMUtils.removeClassName($pops, "pops-iframe-unset-transition"); $pops.setAttribute(TYPE_MODULE, "max"); $headerControls.setAttribute("type", "max"); } else { origin_is_max = false; $pops.style.left = origin_left; $pops.style.top = origin_top; $pops.style.transitionDuration = ""; $pops.style.transform = ""; $headerControls.removeAttribute("type"); $pops.removeAttribute(TYPE_MODULE); popsDOMUtils.removeClassName( $pops, "pops-iframe-unset-top", "pops-iframe-unset-left", "pops-iframe-unset-transform" ); // 显示放大图标 $headerBtnMax.style.setProperty("display", ""); // 隐藏复位图标 $headerBtnMise.style.setProperty("display", "none"); } if (typeof config?.btn?.mise?.callback === "function") { config.btn.mise.callback(evtConfig, event); } emitter.emit("pops:iframe-mise", evtConfig, event); }, { capture: true, } ); // 关闭按钮点击事件 popsDOMUtils.on( $headerBtnClose, "click", async (event) => { event.preventDefault(); event.stopPropagation(); await PopsInstHandler.removeInstance([PopsInstData.iframe], guid, false); if (typeof config?.btn?.close?.callback === "function") { config.btn.close.callback(evtConfig, event); } }, { capture: true, } ); PopsHandler.handlePush(popsType, { guid: guid, $anim: $anim, $pops: $pops!, $mask: $mask!, $shadowContainer: $shadowContainer, $shadowRoot: $shadowRoot, config: config, emitter, }); return result; }, };