Skip to content

Commit

Permalink
feat: 增加degradeAttrs参数用于控制降级时的Iframe属性 (#272)
Browse files Browse the repository at this point in the history
* feat: 增加渲染iframe的样式参数

* fix: 销毁时清除iframeStyle属性

* fix: 改为degrateAttrs参数以适配更多属性

* fix: 修正参数名为degradeAttrs

close #271
  • Loading branch information
Xusenbiao authored Nov 25, 2022
1 parent 9d657ee commit 16adfd4
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 15 deletions.
8 changes: 7 additions & 1 deletion packages/wujie-core/src/iframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
execHooks,
getCurUrl,
getAbsolutePath,
mergeAttrsToElement,
} from "./utils";
import {
documentProxyProperties,
Expand Down Expand Up @@ -743,10 +744,15 @@ export function insertScriptToIframe(
* @param src 地址
* @param shadowRoot
*/
export function renderIframeReplaceApp(src: string, element: HTMLElement): void {
export function renderIframeReplaceApp(
src: string,
element: HTMLElement,
degradeAttrs: { [key: string]: any } = {}
): void {
const iframe = window.document.createElement("iframe");
iframe.setAttribute("src", src);
iframe.setAttribute("style", "height:100%;width:100%");
mergeAttrsToElement(iframe, degradeAttrs);
renderElementToContainer(iframe, element);
}

Expand Down
25 changes: 21 additions & 4 deletions packages/wujie-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ type baseOptions = {
props?: { [key: string]: any };
/** 自定义iframe属性 */
attrs?: { [key: string]: any };
/** 降级时渲染iframe的属性 */
degradeAttrs?: { [key: string]: any };
/** 子应用采用fiber模式执行 */
fiber?: boolean;
/** 子应用保活,state不会丢失 */
Expand Down Expand Up @@ -179,6 +181,7 @@ export async function startApp(startOptions: startOptions): Promise<Function | v
fetch,
props,
attrs,
degradeAttrs,
fiber,
alive,
degrade,
Expand Down Expand Up @@ -235,7 +238,7 @@ export async function startApp(startOptions: startOptions): Promise<Function | v

// 设置loading
addLoading(el, loading);
const newSandbox = new WuJie({ name, url, attrs, fiber, degrade, plugins, lifecycles });
const newSandbox = new WuJie({ name, url, attrs, degradeAttrs, fiber, degrade, plugins, lifecycles });
newSandbox.lifecycles?.beforeLoad?.(newSandbox.iframe.contentWindow);
const { template, getExternalScripts, getExternalStyleSheets } = await importHTML(url, {
fetch: fetch || window.fetch,
Expand Down Expand Up @@ -263,10 +266,24 @@ export function preloadApp(preOptions: preOptions): void {
const cacheOptions = getOptionsById(preOptions.name);
// 合并缓存配置
const options = mergeOptions({ ...preOptions }, cacheOptions);
const { name, url, props, alive, replace, fetch, exec, attrs, fiber, degrade, prefix, plugins, lifecycles } =
options;
const {
name,
url,
props,
alive,
replace,
fetch,
exec,
attrs,
degradeAttrs,
fiber,
degrade,
prefix,
plugins,
lifecycles,
} = options;

const sandbox = new WuJie({ name, url, attrs, fiber, degrade, plugins, lifecycles });
const sandbox = new WuJie({ name, url, attrs, degradeAttrs, fiber, degrade, plugins, lifecycles });
if (sandbox.preload) return sandbox.preload;
const runPreload = async () => {
sandbox.lifecycles?.beforeLoad?.(sandbox.iframe.contentWindow);
Expand Down
6 changes: 3 additions & 3 deletions packages/wujie-core/src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
* location href 的set劫持操作
*/
function locationHrefSet(iframe: HTMLIFrameElement, value: string, appHostPath: string): boolean {
const { shadowRoot, id, degrade, document } = iframe.contentWindow.__WUJIE;
const { shadowRoot, id, degrade, document, degradeAttrs } = iframe.contentWindow.__WUJIE;
let url = value;
if (!/^http/.test(url)) {
let hrefElement = anchorElementGenerator(url);
Expand All @@ -27,8 +27,8 @@ function locationHrefSet(iframe: HTMLIFrameElement, value: string, appHostPath:
if (degrade) {
const iframeBody = rawDocumentQuerySelector.call(iframe.contentDocument, "body");
renderElementToContainer(document.documentElement, iframeBody);
renderIframeReplaceApp(window.decodeURIComponent(url), getDegradeIframe(id).parentElement);
} else renderIframeReplaceApp(url, shadowRoot.host.parentElement);
renderIframeReplaceApp(window.decodeURIComponent(url), getDegradeIframe(id).parentElement, degradeAttrs);
} else renderIframeReplaceApp(url, shadowRoot.host.parentElement, degradeAttrs);
pushUrlToWindow(id, url);
return true;
}
Expand Down
9 changes: 7 additions & 2 deletions packages/wujie-core/src/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export default class Wujie {
public iframeReady: Promise<void>;
/** 子应用预加载态 */
public preload: Promise<void>;
/** 降级时渲染iframe的属性 */
public degradeAttrs: { [key: string]: any };
/** 子应用js执行队列 */
public execQueue: Array<Function>;
/** 子应用执行标志 */
Expand Down Expand Up @@ -181,7 +183,7 @@ export default class Wujie {

/* 降级处理 */
if (this.degrade) {
const iframe = createIframeContainer(this.id);
const iframe = createIframeContainer(this.id, this.degradeAttrs);
const iframeBody = rawDocumentQuerySelector.call(iframeWindow.document, "body") as HTMLElement;
this.el = renderElementToContainer(iframe, el ?? iframeBody);
clearChild(iframe.contentDocument);
Expand Down Expand Up @@ -385,6 +387,7 @@ export default class Wujie {
this.proxyLocation = null;
this.execQueue = null;
this.provide = null;
this.degradeAttrs = null;
this.styleSheetElements = null;
this.bus = null;
this.replace = null;
Expand Down Expand Up @@ -456,6 +459,7 @@ export default class Wujie {
name: string;
url: string;
attrs: { [key: string]: any };
degradeAttrs: { [key: string]: any };
fiber: boolean;
degrade;
plugins: Array<plugin>;
Expand All @@ -470,12 +474,13 @@ export default class Wujie {
mainHostPath: window.location.protocol + "//" + window.location.host,
};
}
const { name, url, attrs, fiber, degrade, lifecycles, plugins } = options;
const { name, url, attrs, fiber, degradeAttrs, degrade, lifecycles, plugins } = options;
this.id = name;
this.fiber = fiber;
this.degrade = degrade || !wujieSupport;
this.bus = new EventBus(this.id);
this.url = url;
this.degradeAttrs = degradeAttrs;
this.provide = { bus: this.bus };
this.styleSheetElements = [];
this.execQueue = [];
Expand Down
5 changes: 3 additions & 2 deletions packages/wujie-core/src/shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Wujie from "./sandbox";
import { patchElementEffect } from "./iframe";
import { patchRenderEffect } from "./effect";
import { getCssLoader, getPresetLoaders } from "./plugin";
import { getAbsolutePath, getContainer, getCurUrl } from "./utils";
import { getAbsolutePath, getContainer, getCurUrl, mergeAttrsToElement } from "./utils";

const cssSelectorMap = {
":root": ":host",
Expand Down Expand Up @@ -218,10 +218,11 @@ export async function renderTemplateToShadowRoot(
patchRenderEffect(shadowRoot, iframeWindow.__WUJIE.id, false);
}

export function createIframeContainer(id: string): HTMLIFrameElement {
export function createIframeContainer(id: string, degradeAttrs: { [key: string]: any } = {}): HTMLIFrameElement {
const iframe = document.createElement("iframe");
iframe.setAttribute("style", "width: 100%; height:100%");
iframe.setAttribute(WUJIE_DATA_ID, id);
mergeAttrsToElement(iframe, degradeAttrs);
return iframe;
}

Expand Down
15 changes: 12 additions & 3 deletions packages/wujie-core/src/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,23 @@ export function processAppForHrefJump(): void {
if (/http/.test(url)) {
if (sandbox.degrade) {
renderElementToContainer(sandbox.document.documentElement, iframeBody);
renderIframeReplaceApp(window.decodeURIComponent(url), getDegradeIframe(sandbox.id).parentElement);
} else renderIframeReplaceApp(window.decodeURIComponent(url), sandbox.shadowRoot.host.parentElement);
renderIframeReplaceApp(
window.decodeURIComponent(url),
getDegradeIframe(sandbox.id).parentElement,
sandbox.degradeAttrs
);
} else
renderIframeReplaceApp(
window.decodeURIComponent(url),
sandbox.shadowRoot.host.parentElement,
sandbox.degradeAttrs
);
sandbox.hrefFlag = true;
// href后退
} else if (sandbox.hrefFlag) {
if (sandbox.degrade) {
// 走全套流程,但是事件恢复不需要
const iframe = createIframeContainer(sandbox.id);
const iframe = createIframeContainer(sandbox.id, sandbox.degradeAttrs);
renderElementToContainer(iframe, sandbox.el);
clearChild(iframe.contentDocument);
patchEventTimeStamp(iframe.contentWindow, sandbox.iframe.contentWindow);
Expand Down
19 changes: 19 additions & 0 deletions packages/wujie-core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,24 @@ export function getDegradeIframe(id: string): HTMLIFrameElement {
return window.document.querySelector(`iframe[${WUJIE_DATA_ID}="${id}"]`);
}

export function mergeAttrsToElement(element: HTMLElement, attrs: { [key: string]: any }) {
Object.keys(attrs).forEach((name) => {
if (name === "style") {
const style: { [key: string]: string } = {};
const styleAttrs = attrs[name].split(";");
styleAttrs.forEach((styleAttr) => {
if (styleAttr && styleAttr.length) {
const [key, value] = styleAttr.split(":");
style[key.trim()] = value.trim();
}
});
Object.assign(element.style, style);
} else {
element.setAttribute(name, attrs[name]);
}
});
}

export function appRouteParse(url: string): {
urlElement: HTMLAnchorElement;
appHostPath: string;
Expand Down Expand Up @@ -292,6 +310,7 @@ export function mergeOptions(options: cacheOptions, cacheOptions: cacheOptions)
loading: options.loading || cacheOptions?.loading,
// 默认 {}
attrs: options.attrs !== undefined ? options.attrs : cacheOptions?.attrs || {},
degradeAttrs: options.degradeAttrs !== undefined ? options.degradeAttrs : cacheOptions?.degradeAttrs || {},
// 默认 true
fiber: options.fiber !== undefined ? options.fiber : cacheOptions?.fiber !== undefined ? cacheOptions?.fiber : true,
alive: options.alive !== undefined ? options.alive : cacheOptions?.alive,
Expand Down

0 comments on commit 16adfd4

Please sign in to comment.