qlfy-postmate 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- ### 子系统认证通信插件使用文档1.2.0
1
+ ### 子系统认证通信插件使用文档1.2.3
2
2
 
3
- ### 【1.2.0优化升级说明】
3
+ ### 【1.2.3优化升级说明】
4
4
 
5
5
  ```txt
6
6
  1、优化了同IP链接切换时的系统资源重复加载问题
@@ -14,7 +14,7 @@
14
14
  3、建议
15
15
  已完成集成系统也建议使用最新版本,使用变化极小
16
16
  仅需以下两步操作:
17
- (1)下载新版本插件:npm i qlfy-postmate@1.2.0
17
+ (1)下载新版本插件:npm i qlfy-postmate@1.2.3
18
18
  (2)使用处添加新参数:router
19
19
  new ChildPostmate({...保持不变}, router)
20
20
  ```
@@ -128,7 +128,7 @@ new ChildPostmate({
128
128
  按下面链接格式在浏览器中访问,该链接支持前端的本地调试
129
129
 
130
130
  ```js
131
- http://10.76.91.80:28084/test?url=本地前端服务地址
131
+ http://10.76.91.80:28084/#/test?url=本地前端服务地址
132
132
  ```
133
133
 
134
134
  url后配置本地所启用的前端服务
@@ -136,6 +136,6 @@ url后配置本地所启用的前端服务
136
136
  例:
137
137
 
138
138
  ```js
139
- http://10.76.91.80:28084/test?url=http://192.168.3.136:8080/
139
+ http://10.76.91.80:28084/#/test?url=http://192.168.3.136:8080/
140
140
  ```
141
141
 
package/lib/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
- const c = "application/x-postmate-v1+json";
2
- let m = 0;
3
- const f = {
1
+ const u = "application/x-postmate-v1+json";
2
+ let g = 0;
3
+ const P = {
4
4
  handshake: 1,
5
5
  "handshake-reply": 1,
6
6
  call: 1,
@@ -8,358 +8,397 @@ const f = {
8
8
  reply: 1,
9
9
  request: 1
10
10
  };
11
- function u(n, t) {
12
- return (typeof t != "string" || n.origin === t) && !!n.data && (typeof n.data != "object" || "postmate" in n.data) && n.data.type === c && !!f[n.data.postmate];
11
+ function m(i, e) {
12
+ return (typeof e != "string" || i.origin === e) && !!i.data && (typeof i.data != "object" || "postmate" in i.data) && i.data.type === u && !!P[i.data.postmate];
13
13
  }
14
- class g {
15
- constructor(t) {
16
- this.parent = t.parent, this.frame = t.frame, this.child = t.child, this.childOrigin = t.childOrigin, this.events = {}, this.listener = (e) => {
17
- if (!u(e, this.childOrigin)) return;
18
- const { value: s = {} } = e.data, { name: a, data: r } = s;
19
- e.data.postmate === "emit" && a in this.events && this.events[a].call(this, r);
14
+ class R {
15
+ constructor(e) {
16
+ this.parent = e.parent, this.frame = e.frame, this.child = e.child, this.childOrigin = e.childOrigin, this.events = {}, this.listener = (t) => {
17
+ if (!m(t, this.childOrigin)) return;
18
+ const { value: s = {} } = t.data, { name: r, data: a } = s;
19
+ t.data.postmate === "emit" && r in this.events && this.events[r].call(this, a);
20
20
  }, this.parent.addEventListener("message", this.listener, !1);
21
21
  }
22
- get(t) {
23
- return new o.Promise((e) => {
24
- const s = ++m, a = (r) => {
25
- r.data.uid === s && r.data.postmate === "reply" && (this.parent.removeEventListener("message", a, !1), e(r.data.value));
22
+ get(e) {
23
+ return new l.Promise((t) => {
24
+ const s = ++g, r = (a) => {
25
+ a.data.uid === s && a.data.postmate === "reply" && (this.parent.removeEventListener("message", r, !1), t(a.data.value));
26
26
  };
27
- this.parent.addEventListener("message", a, !1), this.child.postMessage(
27
+ this.parent.addEventListener("message", r, !1), this.child.postMessage(
28
28
  {
29
29
  postmate: "request",
30
- type: c,
31
- property: t,
30
+ type: u,
31
+ property: e,
32
32
  uid: s
33
33
  },
34
34
  this.childOrigin
35
35
  );
36
36
  });
37
37
  }
38
- call(t, e) {
38
+ call(e, t) {
39
39
  this.child.postMessage(
40
40
  {
41
41
  postmate: "call",
42
- type: c,
43
- property: t,
44
- data: e
42
+ type: u,
43
+ property: e,
44
+ data: t
45
45
  },
46
46
  this.childOrigin
47
47
  );
48
48
  }
49
- on(t, e) {
50
- this.events[t] = e;
49
+ on(e, t) {
50
+ this.events[e] = t;
51
51
  }
52
52
  destroy() {
53
53
  window.removeEventListener("message", this.listener, !1), this.frame.parentNode.removeChild(this.frame);
54
54
  }
55
55
  }
56
- class w {
57
- constructor(t) {
58
- this.model = t.model, this.parent = t.parent, this.parentOrigin = t.parentOrigin, this.child = t.child, this.child.addEventListener("message", (e) => {
59
- if (!u(e, this.parentOrigin)) return;
60
- const { postmate: s, property: a, uid: r, data: h } = e.data, i = this.model[a];
56
+ class y {
57
+ constructor(e) {
58
+ this.model = e.model, this.parent = e.parent, this.parentOrigin = e.parentOrigin, this.child = e.child, this.child.addEventListener("message", (t) => {
59
+ if (!m(t, this.parentOrigin)) return;
60
+ const { postmate: s, property: r, uid: a, data: n } = t.data, o = this.model[r];
61
61
  if (s !== "call") {
62
- const l = typeof i == "function" ? i() : i;
63
- o.Promise.resolve(l).then((d) => {
64
- e.source.postMessage(
62
+ const h = typeof o == "function" ? o() : o;
63
+ l.Promise.resolve(h).then((c) => {
64
+ t.source.postMessage(
65
65
  {
66
- property: a,
66
+ property: r,
67
67
  postmate: "reply",
68
- type: c,
69
- uid: r,
70
- value: d
68
+ type: u,
69
+ uid: a,
70
+ value: c
71
71
  },
72
- e.origin
72
+ t.origin
73
73
  );
74
74
  });
75
- } else a in this.model && typeof i == "function" && i(h);
75
+ } else r in this.model && typeof o == "function" && o(n);
76
76
  });
77
77
  }
78
- emit(t, e) {
78
+ emit(e, t) {
79
79
  this.parent.postMessage(
80
80
  {
81
81
  postmate: "emit",
82
- type: c,
83
- value: { name: t, data: e }
82
+ type: u,
83
+ value: { name: e, data: t }
84
84
  },
85
85
  this.parentOrigin
86
86
  );
87
87
  }
88
88
  }
89
- class o {
90
- constructor({ container: t = document.body, model: e, url: s, name: a, classListArray: r = [] }) {
91
- return this.parent = window, this.frame = document.createElement("iframe"), this.frame.name = a || "", this.frame.classList.add(...r), t.appendChild(this.frame), this.child = this.frame.contentWindow, this.model = e || {}, this.sendHandshake(s);
89
+ class l {
90
+ constructor({ container: e = document.body, model: t, url: s, name: r, classListArray: a = [] }) {
91
+ return this.parent = window, this.frame = document.createElement("iframe"), this.frame.name = r || "", this.frame.classList.add(...a), e.appendChild(this.frame), this.child = this.frame.contentWindow, this.model = t || {}, this.sendHandshake(s);
92
92
  }
93
- sendHandshake(t) {
94
- const e = (() => {
95
- const r = document.createElement("a");
96
- r.href = t;
97
- const h = r.protocol.length > 4 ? r.protocol : window.location.protocol, i = r.host.length ? r.port === "80" || r.port === "443" ? r.hostname : r.host : window.location.host;
98
- return r.origin || `${h}//${i}`;
93
+ sendHandshake(e) {
94
+ const t = (() => {
95
+ const a = document.createElement("a");
96
+ a.href = e;
97
+ const n = a.protocol.length > 4 ? a.protocol : window.location.protocol, o = a.host.length ? a.port === "80" || a.port === "443" ? a.hostname : a.host : window.location.host;
98
+ return a.origin || `${n}//${o}`;
99
99
  })();
100
- let s = 0, a;
101
- return new o.Promise((r, h) => {
102
- const i = (p) => {
103
- if (!u(p, e)) return !1;
104
- p.data.postmate === "handshake-reply" ? (clearInterval(a), this.parent.removeEventListener("message", i, !1), this.childOrigin = p.origin, r(new g(this))) : h("Failed handshake");
100
+ let s = 0, r;
101
+ return new l.Promise((a, n) => {
102
+ const o = (d) => {
103
+ if (!m(d, t)) return !1;
104
+ d.data.postmate === "handshake-reply" ? (clearInterval(r), this.parent.removeEventListener("message", o, !1), this.childOrigin = d.origin, a(new R(this))) : n("Failed handshake");
105
105
  };
106
- this.parent.addEventListener("message", i, !1);
107
- const l = () => {
106
+ this.parent.addEventListener("message", o, !1);
107
+ const h = () => {
108
108
  s++, this.child.postMessage(
109
109
  {
110
110
  postmate: "handshake",
111
- type: c,
111
+ type: u,
112
112
  model: this.model
113
113
  },
114
- e
115
- ), s === 5 && clearInterval(a);
116
- }, d = () => {
117
- l(), a = setInterval(l, 500);
114
+ t
115
+ ), s === 5 && clearInterval(r);
116
+ }, c = () => {
117
+ h(), r = setInterval(h, 500);
118
118
  };
119
- this.frame.onload = d, this.frame.attachEvent && this.frame.attachEvent("onload", d), this.frame.src = t;
119
+ this.frame.onload = c, this.frame.attachEvent && this.frame.attachEvent("onload", c), this.frame.src = e;
120
120
  });
121
121
  }
122
122
  }
123
- class P {
124
- constructor(t) {
125
- return this.child = window, this.model = t, this.parent = window.parent, this.sendHandshakeReply();
123
+ class U {
124
+ constructor(e) {
125
+ return this.child = window, this.model = e, this.parent = window.parent, this.sendHandshakeReply();
126
126
  }
127
127
  sendHandshakeReply() {
128
- return new o.Promise((t, e) => {
128
+ return new l.Promise((e, t) => {
129
129
  this.child.addEventListener("message", (s) => {
130
130
  if (s.data.postmate) {
131
- if (s.data.postmate !== "handshake") return e("Handshake Reply Failed");
131
+ if (s.data.postmate !== "handshake") return t("Handshake Reply Failed");
132
132
  this.child.removeEventListener("message", this, !1), s.source.postMessage(
133
133
  {
134
134
  postmate: "handshake-reply",
135
- type: c
135
+ type: u
136
136
  },
137
137
  s.origin
138
138
  ), this.parentOrigin = s.origin;
139
- const a = s.data.model;
140
- a && Object.keys(a).forEach((r) => {
141
- this.model[r] = a[r];
142
- }), t(new w(this));
139
+ const r = s.data.model;
140
+ r && Object.keys(r).forEach((a) => {
141
+ this.model[a] = r[a];
142
+ }), e(new y(this));
143
143
  }
144
144
  }, !1);
145
145
  });
146
146
  }
147
147
  }
148
- o.debug = !1;
149
- o.Promise = (() => {
148
+ l.debug = !1;
149
+ l.Promise = (() => {
150
150
  try {
151
151
  return typeof window < "u" ? window.Promise : Promise;
152
152
  } catch {
153
153
  return Promise;
154
154
  }
155
155
  })();
156
- o.Model = P;
157
- class y {
158
- constructor(t, e, s) {
159
- this.childPostmate = null, this.parentPostmate = null, this.isGetData = !1, this.getDataCllBack = null, this.router = null, this.routeUpdateCallback = null, this.router = e, this.routeUpdateCallback = s, window.top !== window.self ? this.init(t) : t.error({ status: 500, data: null, message: "未在一体化平台中运行" });
156
+ l.Model = U;
157
+ function f(i, e) {
158
+ for (const t of i)
159
+ if (t.path === e || t.children && Array.isArray(t.children) && t.children.length > 0 && f(t.children, e))
160
+ return !0;
161
+ return !1;
162
+ }
163
+ function w(i, e) {
164
+ e.includes("?") && (e = e.split("?")[0]);
165
+ const t = p(i);
166
+ return !t || t.length === 0 ? !1 : f(t, e);
167
+ }
168
+ function p(i) {
169
+ let e = [];
170
+ return typeof i.getRoutes == "function" ? e = i.getRoutes() : i.options && Array.isArray(i.options.routes) && (e = i.options.routes), e || [];
171
+ }
172
+ function E(i, e) {
173
+ try {
174
+ const t = new URL(i), s = new URL(e), r = t.protocol.toLowerCase() === s.protocol.toLowerCase(), a = t.hostname === s.hostname, n = t.port === s.port;
175
+ return r && a && n;
176
+ } catch (t) {
177
+ return console.error("URL解析错误:", t), !1;
160
178
  }
161
- init(t) {
162
- const e = this;
163
- this.childPostmate = new o.Model({
179
+ }
180
+ class I {
181
+ constructor(e, t, s) {
182
+ this.childPostmate = null, this.parentPostmate = null, this.isGetData = !1, this.getDataCllBack = null, this.router = null, this.routeUpdateCallback = void 0, this.router = t, this.routeUpdateCallback = s, window.top !== window.self ? this.init(e) : e.error({ status: 500, data: null, message: "未在一体化平台中运行" });
183
+ }
184
+ init(e) {
185
+ const t = this;
186
+ this.childPostmate = new l.Model({
164
187
  // 定义子页面可以暴露给父页面的方法
165
188
  baseData(s) {
166
- s = JSON.parse(s), e.isGetData ? e.getDataCllBack && e.getDataCllBack({
189
+ s = JSON.parse(s), t.isGetData ? t.getDataCllBack && t.getDataCllBack({
167
190
  status: 200,
168
191
  message: "success",
169
192
  data: s
170
- }) : t.receive({
193
+ }) : e.receive({
171
194
  status: 200,
172
195
  message: "success",
173
196
  data: s
174
- }), e.isGetData = !1;
197
+ }), t.isGetData = !1;
198
+ },
199
+ // 提供当前系统的路由
200
+ getRoutes: () => {
201
+ if (t.router) {
202
+ let s = p(t.router);
203
+ t.parentPostmate.emit("pushRoutes", JSON.stringify(s));
204
+ } else t.parentPostmate.emit("pushRoutes");
205
+ },
206
+ // 检查路由是否存在
207
+ isRouteExists(s) {
208
+ t.router ? t.parentPostmate.emit("routeExists", w(t.router, s)) : t.parentPostmate.emit("routeExists", !1);
175
209
  },
176
210
  // 处理路由更新
177
211
  routeUpdate(s) {
178
212
  try {
179
- window.parent.postMessage(JSON.stringify({
180
- type: "route_update_support",
181
- supported: !0
182
- }), "*");
183
- const a = JSON.parse(s);
184
- if (e.routeUpdateCallback) {
185
- e.routeUpdateCallback(a);
213
+ const r = JSON.parse(s);
214
+ if (t.routeUpdateCallback) {
215
+ t.routeUpdateCallback(r);
186
216
  return;
187
217
  }
188
- e.router ? e.router.replace(a.fullPath) : console.warn("未提供router实例,无法进行路由更新");
189
- } catch (a) {
190
- console.error("路由更新失败:", a);
218
+ t.router ? (t.router.replace(r.fullPath), t.parentPostmate.emit("route_update_result", !0), console.log("----------------- 【ChildPastMate】路由更新完成 -----------------")) : (t.parentPostmate.emit("route_update_result", !1), console.warn("【ChildPastMate】未提供router实例,无法进行路由更新"));
219
+ } catch (r) {
220
+ console.error("【ChildPastMate】路由更新失败:", r), t.parentPostmate.emit("route_update_result", !1);
191
221
  }
192
222
  }
193
223
  }).then((s) => {
194
- e.parentPostmate = s, e.getData(), t.success({
224
+ t.parentPostmate = s, t.getData(), e.success({
195
225
  status: 200,
196
226
  message: "success",
197
227
  data: {
198
228
  ChildPostmate: s
199
229
  }
200
- });
230
+ }), t.parentPostmate.emit("route_update_support", !!t.router), t.router && t.parentPostmate.emit("pushRoutes", JSON.stringify(p(t.router)));
201
231
  }).catch((s) => {
202
- t.error({ status: 500, data: null, message: s });
232
+ e.error({ status: 500, data: null, message: s });
203
233
  });
204
234
  }
205
235
  // 获取数据
206
- getData(t) {
236
+ getData(e) {
207
237
  if (!this.parentPostmate) {
208
- t({
238
+ e({
209
239
  status: 500,
210
240
  message: "父页面未连接",
211
241
  data: null
212
242
  });
213
243
  return;
214
244
  }
215
- t ? (this.isGetData = !0, this.getDataCllBack = t) : (this.isGetData = !1, this.getDataCllBack = null), this.parentPostmate.emit("requestBaseData");
245
+ e ? (this.isGetData = !0, this.getDataCllBack = e) : (this.isGetData = !1, this.getDataCllBack = null), this.parentPostmate.emit("requestBaseData");
216
246
  }
217
247
  /**
218
248
  * 设置路由实例和路由更新回调
219
249
  * @param router Vue Router实例
220
250
  * @param routeUpdateCallback 自定义路由更新回调函数
221
251
  */
222
- setRouter(t, e) {
223
- this.router = t, e && (this.routeUpdateCallback = e);
252
+ setRouter(e, t) {
253
+ this.router = e, t && (this.routeUpdateCallback = t);
224
254
  }
225
255
  /**
226
256
  * 向父页面发送其他请求
227
257
  * @param params 请求参数
228
258
  */
229
- sendOtherRequest(t) {
230
- this.parentPostmate && this.parentPostmate.emit("otherRequest", t);
259
+ sendOtherRequest(e) {
260
+ this.parentPostmate && this.parentPostmate.emit("otherRequest", e);
231
261
  }
232
262
  }
233
- class U {
234
- constructor(t, e, s = "", a) {
263
+ class k {
264
+ constructor(e, t, s = "", r) {
235
265
  this.postmateParent = null, this.dataInfo = {
236
266
  loginInfo: {},
237
267
  token: "",
238
268
  isHideHeader: !0
239
- }, this.iframeEle = null, this.currentUrl = "", this.currentIframe = null, this.loadFunction = null, this.handleOtherRequest = null, this.parsedCurrentUrl = null, this.childSupportsRouteUpdate = !0, this.dataInfo = t || this.dataInfo, this.iframeEle = e, this.setIframeUrl(s), a && (this.handleOtherRequest = a);
269
+ }, this.iframeEle = null, this.currentUrl = "", this.currentBaseUrl = "", this.currentRouterPath = "", this.currentIframe = null, this.loadFunction = null, this.handleOtherRequest = null, this.parsedCurrentUrl = null, this.childSupportsRouteUpdate = !0, this.childRoutes = [], this.eventBus = {
270
+ getRoutes: null,
271
+ route_update_resultL: null
272
+ }, this.dataInfo = e || this.dataInfo, this.iframeEle = t, this.setIframeUrl(s), r && (this.handleOtherRequest = r);
240
273
  }
241
274
  /** 解析URL */
242
- parseUrl(t) {
243
- const e = document.createElement("a");
244
- e.href = t;
245
- const s = e.protocol.length > 4 ? e.protocol : window.location.protocol, a = e.hostname, r = e.port || (s === "https:" ? "443" : s === "http:" ? "80" : ""), h = e.pathname.startsWith("/") ? e.pathname : `/${e.pathname}`, i = e.search, l = e.hash, d = e.origin || `${s}//${a}${r ? `:${r}` : ""}`, p = `${h}${i}${l}`;
275
+ parseUrl(e) {
276
+ const t = document.createElement("a");
277
+ t.href = e;
278
+ const s = t.protocol.length > 4 ? t.protocol : window.location.protocol, r = t.hostname, a = t.port || (s === "https:" ? "443" : s === "http:" ? "80" : ""), n = t.pathname.startsWith("/") ? t.pathname : `/${t.pathname}`, o = t.search, h = t.hash.slice(2, t.hash.length), c = t.origin || `${s}//${r}${a ? `:${a}` : ""}`, d = `${n}${h}`;
246
279
  return {
247
280
  protocol: s,
248
- host: a,
249
- port: r,
250
- pathname: h,
251
- search: i,
252
- hash: l,
253
- origin: d,
254
- fullPath: p
281
+ host: r,
282
+ port: a,
283
+ pathname: n,
284
+ search: o,
285
+ hash: h,
286
+ origin: c,
287
+ fullPath: d
255
288
  };
256
289
  }
257
- /** 比较两个URL是否相同(协议、主机、端口) */
258
- compareUrlBase(t, e) {
259
- if (!t || !e) return !1;
260
- const s = this.parseUrl(t), a = this.parseUrl(e);
261
- return s.protocol === a.protocol && s.host === a.host && s.port === a.port;
290
+ /** 比较两个URL是否相同*/
291
+ compareUrlBase(e, t) {
292
+ const s = e.endsWith("/"), r = t.endsWith("/");
293
+ return s && r || !s && !r || (s && (t += "/"), r && (e += "/")), e === t;
262
294
  }
263
295
  /** 比较两个URL的路径是否相同(不包含查询参数和哈希) */
264
- compareUrlPath(t, e) {
265
- if (!t || !e) return !1;
266
- const s = this.parseUrl(t), a = this.parseUrl(e);
267
- return s.pathname === a.pathname;
296
+ compareUrlPath(e, t) {
297
+ if (!e || !t) return !1;
298
+ const s = this.parseUrl(e), r = this.parseUrl(t);
299
+ return s.pathname === r.pathname;
268
300
  }
269
301
  /** 比较两个URL是否完全相同(包括查询参数和哈希) */
270
- compareUrlFull(t, e) {
271
- if (!t || !e) return !1;
272
- const s = this.parseUrl(t), a = this.parseUrl(e);
273
- return s.fullPath === a.fullPath;
302
+ compareUrlFull(e, t) {
303
+ if (!e || !t) return !1;
304
+ const s = this.parseUrl(e), r = this.parseUrl(t);
305
+ return s.fullPath === r.fullPath;
274
306
  }
275
307
  /** 清除当前的 iframe 和 postmate 实例 */
276
308
  clear() {
277
309
  this.postmateParent && (this.postmateParent.destroy(), this.postmateParent = null), this.currentIframe && this.currentIframe.parentNode && this.currentIframe.parentNode.removeChild(this.currentIframe), this.currentIframe = null;
278
310
  }
279
311
  /** 初始化 */
280
- async init(t = null) {
281
- if (this.clear(), this.childSupportsRouteUpdate = !0, !this.iframeEle || !this.currentUrl) {
282
- console.warn("iframeEle currentUrl 是必需的");
283
- return;
284
- }
285
- const e = typeof this.iframeEle == "function" ? this.iframeEle() : this.iframeEle;
286
- if (!e) {
287
- console.warn("无法获取 iframe 容器");
312
+ async init(e = null) {
313
+ this.clear(), this.childSupportsRouteUpdate = !1, (!this.iframeEle || !this.currentUrl) && this.destroy();
314
+ const t = typeof this.iframeEle == "function" ? this.iframeEle() : this.iframeEle;
315
+ if (!t) {
316
+ console.warn("【ParentPostmate】无法获取 iframe 容器");
288
317
  return;
289
318
  }
290
- const s = new o({
291
- container: e,
319
+ const s = new l({
320
+ container: t,
292
321
  url: this.currentUrl,
293
322
  name: "",
294
323
  model: ""
295
324
  });
296
- this.currentIframe = e.querySelector("iframe"), this.currentIframe.setAttribute("frameborder", "0"), this.currentIframe.setAttribute("allow", "fullscreen"), this.currentIframe.addEventListener("load", () => {
325
+ this.currentIframe = t.querySelector("iframe"), this.currentIframe.setAttribute("frameborder", "0"), this.currentIframe.setAttribute("allow", "fullscreen"), this.currentIframe.addEventListener("load", () => {
297
326
  this.loadFunction && this.loadFunction();
298
- }), s.then((a) => {
299
- this.postmateParent = a, a.on("requestBaseData", () => {
327
+ }), s.then((r) => {
328
+ this.postmateParent = r, r.on("requestBaseData", () => {
300
329
  this.sendData();
301
- }), a.on("otherRequest", (r) => {
302
- this.handleOtherRequest && this.handleOtherRequest(r);
303
- }), typeof t == "function" && t();
304
- }).catch((a) => {
305
- console.error("Postmate 连接失败:", a);
330
+ }), r.on("pushRoutes", (a) => {
331
+ a ? this.childRoutes = JSON.parse(a) : this.childRoutes = [], this.eventBus.getRoutes && this.eventBus.getRoutes();
332
+ }), r.on("routeExists", (a) => {
333
+ }), r.on("route_update_support", (a) => {
334
+ this.childSupportsRouteUpdate = a;
335
+ }), r.on("route_update_result", (a) => {
336
+ this.eventBus.route_update_result && this.eventBus.route_update_result(a);
337
+ }), r.on("otherRequest", (a) => {
338
+ this.handleOtherRequest && this.handleOtherRequest(a);
339
+ }), typeof e == "function" && e();
340
+ }).catch((r) => {
341
+ console.error("【ParentPostmate】Postmate 连接失败:", r);
306
342
  });
307
343
  }
308
344
  /** 设置load执行事件 */
309
- setLoadFunction(t) {
310
- this.loadFunction = t;
345
+ setLoadFunction(e) {
346
+ this.loadFunction = e;
311
347
  }
312
348
  /** 设置 iframe url */
313
- setIframeUrl(t) {
314
- if (this.currentUrl === t) return;
315
- if (!this.currentUrl) {
316
- this.currentUrl = t, this.parsedCurrentUrl = this.parseUrl(t), this.iframeEle && this.init();
349
+ setIframeUrl(e, t = "") {
350
+ var r;
351
+ if (t && !t.startsWith("/") && (t = "/" + t), !e) {
352
+ this.currentUrl = "", this.currentRouterPath = "", this.destroy(), console.error("【ParentPostmate】无加载地址,无法初始化");
317
353
  return;
318
354
  }
319
- const e = this.parseUrl(t);
320
- if (this.postmateParent && this.compareUrlBase(this.currentUrl, t) && this.childSupportsRouteUpdate)
321
- if (this.compareUrlPath(this.currentUrl, t)) {
322
- if (this.compareUrlFull(this.currentUrl, t))
323
- return;
324
- this.currentUrl = t, this.parsedCurrentUrl = e, this.sendRouteUpdate(e);
325
- return;
326
- } else {
327
- this.currentUrl = t, this.parsedCurrentUrl = e, this.sendRouteUpdate(e);
355
+ if (!this.postmateParent || !this.currentUrl) {
356
+ this.currentUrl = e, this.currentRouterPath = t, this.iframeEle ? this.init() : console.error("【ParentPostmate】无 iframe 容器,无法初始化");
357
+ return;
358
+ }
359
+ if (!this.childSupportsRouteUpdate || !((r = this.childRoutes) != null && r.length) || !E(this.currentUrl, e)) {
360
+ this.currentUrl = e, this.currentRouterPath = t, this.init();
361
+ return;
362
+ }
363
+ let s = !1;
364
+ this.eventBus.getRoutes = () => {
365
+ s = !0, this.handleSimilarUrl(e, t);
366
+ }, this.postmateParent.call("getRoutes"), setTimeout(() => {
367
+ s || this.handleSimilarUrl(e, t);
368
+ }, 1e3);
369
+ }
370
+ // 处理相似地址
371
+ handleSimilarUrl(e, t) {
372
+ if (this.currentUrl = e, this.currentRouterPath = t || "", t && f(this.childRoutes, t)) {
373
+ this.sendRouteUpdate({
374
+ fullPath: t
375
+ });
376
+ return;
377
+ }
378
+ let s = !1, r = e.split("?")[0];
379
+ this.childRoutes.forEach((a) => {
380
+ if (r.endsWith(a.path)) {
381
+ this.sendRouteUpdate({
382
+ fullPath: t
383
+ }), s = !0;
328
384
  return;
329
385
  }
330
- this.currentUrl = t, this.parsedCurrentUrl = e, this.iframeEle && this.init();
386
+ }), !s && this.init();
331
387
  }
332
388
  /** 向子页面发送路由更新消息 */
333
- sendRouteUpdate(t) {
334
- if (this.postmateParent) {
335
- if (!this.childSupportsRouteUpdate) {
336
- console.warn("子页面不支持路由更新,直接重新初始化iframe"), this.init();
337
- return;
338
- }
339
- try {
340
- this.postmateParent.call(
341
- "routeUpdate",
342
- JSON.stringify({
343
- fullPath: t.fullPath,
344
- pathname: t.pathname,
345
- search: t.search,
346
- hash: t.hash
347
- })
348
- );
349
- let e = !1;
350
- const s = (a) => {
351
- try {
352
- const r = JSON.parse(a.data);
353
- r && r.type === "route_update_support" && r.supported === !0 && (e = !0, window.removeEventListener("message", s));
354
- } catch {
355
- }
356
- };
357
- window.addEventListener("message", s), setTimeout(() => {
358
- window.removeEventListener("message", s), e || (console.warn("子页面不支持路由更新,将在下次更新时重新初始化iframe"), this.childSupportsRouteUpdate = !1, this.init());
359
- }, 1e3);
360
- } catch (e) {
361
- console.warn("发送路由更新消息失败,将重新初始化iframe:", e), this.childSupportsRouteUpdate = !1, this.init();
362
- }
389
+ sendRouteUpdate(e) {
390
+ try {
391
+ let t = !1;
392
+ this.eventBus.route_update_result = (s) => {
393
+ t = s, this.loadFunction && this.loadFunction();
394
+ }, this.postmateParent.call(
395
+ "routeUpdate",
396
+ JSON.stringify(e)
397
+ ), console.log("---------------------- 【ParentPostmate】推送路由更新 ----------------------"), setTimeout(() => {
398
+ t || (console.warn("【ParentPostmate】推送路由更新失败,将重新初始化iframe"), this.childSupportsRouteUpdate = !1, this.init());
399
+ }, 1e3);
400
+ } catch (t) {
401
+ console.warn("【ParentPostmate】发送路由更新消息失败,将重新初始化iframe:", t), this.childSupportsRouteUpdate = !1, this.init();
363
402
  }
364
403
  }
365
404
  /** 向子页面发送消息 */
@@ -372,6 +411,6 @@ class U {
372
411
  }
373
412
  }
374
413
  export {
375
- y as ChildPostmate,
376
- U as ParentPostmate
414
+ I as ChildPostmate,
415
+ k as ParentPostmate
377
416
  };
package/lib/index.mjs.gz CHANGED
Binary file
package/lib/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(d,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(d=typeof globalThis<"u"?globalThis:d||self,n(d["qlfy-postmate"]={}))})(this,function(d){"use strict";const n="application/x-postmate-v1+json";let f=0;const g={handshake:1,"handshake-reply":1,call:1,emit:1,reply:1,request:1};function m(o,t){return(typeof t!="string"||o.origin===t)&&!!o.data&&(typeof o.data!="object"||"postmate"in o.data)&&o.data.type===n&&!!g[o.data.postmate]}class P{constructor(t){this.parent=t.parent,this.frame=t.frame,this.child=t.child,this.childOrigin=t.childOrigin,this.events={},this.listener=e=>{if(!m(e,this.childOrigin))return;const{value:s={}}=e.data,{name:a,data:r}=s;e.data.postmate==="emit"&&a in this.events&&this.events[a].call(this,r)},this.parent.addEventListener("message",this.listener,!1)}get(t){return new h.Promise(e=>{const s=++f,a=r=>{r.data.uid===s&&r.data.postmate==="reply"&&(this.parent.removeEventListener("message",a,!1),e(r.data.value))};this.parent.addEventListener("message",a,!1),this.child.postMessage({postmate:"request",type:n,property:t,uid:s},this.childOrigin)})}call(t,e){this.child.postMessage({postmate:"call",type:n,property:t,data:e},this.childOrigin)}on(t,e){this.events[t]=e}destroy(){window.removeEventListener("message",this.listener,!1),this.frame.parentNode.removeChild(this.frame)}}class w{constructor(t){this.model=t.model,this.parent=t.parent,this.parentOrigin=t.parentOrigin,this.child=t.child,this.child.addEventListener("message",e=>{if(!m(e,this.parentOrigin))return;const{postmate:s,property:a,uid:r,data:l}=e.data,i=this.model[a];if(s!=="call"){const c=typeof i=="function"?i():i;h.Promise.resolve(c).then(u=>{e.source.postMessage({property:a,postmate:"reply",type:n,uid:r,value:u},e.origin)})}else a in this.model&&typeof i=="function"&&i(l)})}emit(t,e){this.parent.postMessage({postmate:"emit",type:n,value:{name:t,data:e}},this.parentOrigin)}}class h{constructor({container:t=document.body,model:e,url:s,name:a,classListArray:r=[]}){return this.parent=window,this.frame=document.createElement("iframe"),this.frame.name=a||"",this.frame.classList.add(...r),t.appendChild(this.frame),this.child=this.frame.contentWindow,this.model=e||{},this.sendHandshake(s)}sendHandshake(t){const e=(()=>{const r=document.createElement("a");r.href=t;const l=r.protocol.length>4?r.protocol:window.location.protocol,i=r.host.length?r.port==="80"||r.port==="443"?r.hostname:r.host:window.location.host;return r.origin||`${l}//${i}`})();let s=0,a;return new h.Promise((r,l)=>{const i=p=>{if(!m(p,e))return!1;p.data.postmate==="handshake-reply"?(clearInterval(a),this.parent.removeEventListener("message",i,!1),this.childOrigin=p.origin,r(new P(this))):l("Failed handshake")};this.parent.addEventListener("message",i,!1);const c=()=>{s++,this.child.postMessage({postmate:"handshake",type:n,model:this.model},e),s===5&&clearInterval(a)},u=()=>{c(),a=setInterval(c,500)};this.frame.onload=u,this.frame.attachEvent&&this.frame.attachEvent("onload",u),this.frame.src=t})}}class y{constructor(t){return this.child=window,this.model=t,this.parent=window.parent,this.sendHandshakeReply()}sendHandshakeReply(){return new h.Promise((t,e)=>{this.child.addEventListener("message",s=>{if(s.data.postmate){if(s.data.postmate!=="handshake")return e("Handshake Reply Failed");this.child.removeEventListener("message",this,!1),s.source.postMessage({postmate:"handshake-reply",type:n},s.origin),this.parentOrigin=s.origin;const a=s.data.model;a&&Object.keys(a).forEach(r=>{this.model[r]=a[r]}),t(new w(this))}},!1)})}}h.debug=!1,h.Promise=(()=>{try{return typeof window<"u"?window.Promise:Promise}catch{return Promise}})(),h.Model=y;class U{constructor(t,e,s){this.childPostmate=null,this.parentPostmate=null,this.isGetData=!1,this.getDataCllBack=null,this.router=null,this.routeUpdateCallback=null,this.router=e,this.routeUpdateCallback=s,window.top!==window.self?this.init(t):t.error({status:500,data:null,message:"未在一体化平台中运行"})}init(t){const e=this;this.childPostmate=new h.Model({baseData(s){s=JSON.parse(s),e.isGetData?e.getDataCllBack&&e.getDataCllBack({status:200,message:"success",data:s}):t.receive({status:200,message:"success",data:s}),e.isGetData=!1},routeUpdate(s){try{window.parent.postMessage(JSON.stringify({type:"route_update_support",supported:!0}),"*");const a=JSON.parse(s);if(e.routeUpdateCallback){e.routeUpdateCallback(a);return}e.router?e.router.replace(a.fullPath):console.warn("未提供router实例,无法进行路由更新")}catch(a){console.error("路由更新失败:",a)}}}).then(s=>{e.parentPostmate=s,e.getData(),t.success({status:200,message:"success",data:{ChildPostmate:s}})}).catch(s=>{t.error({status:500,data:null,message:s})})}getData(t){if(!this.parentPostmate){t({status:500,message:"父页面未连接",data:null});return}t?(this.isGetData=!0,this.getDataCllBack=t):(this.isGetData=!1,this.getDataCllBack=null),this.parentPostmate.emit("requestBaseData")}setRouter(t,e){this.router=t,e&&(this.routeUpdateCallback=e)}sendOtherRequest(t){this.parentPostmate&&this.parentPostmate.emit("otherRequest",t)}}class E{constructor(t,e,s="",a){this.postmateParent=null,this.dataInfo={loginInfo:{},token:"",isHideHeader:!0},this.iframeEle=null,this.currentUrl="",this.currentIframe=null,this.loadFunction=null,this.handleOtherRequest=null,this.parsedCurrentUrl=null,this.childSupportsRouteUpdate=!0,this.dataInfo=t||this.dataInfo,this.iframeEle=e,this.setIframeUrl(s),a&&(this.handleOtherRequest=a)}parseUrl(t){const e=document.createElement("a");e.href=t;const s=e.protocol.length>4?e.protocol:window.location.protocol,a=e.hostname,r=e.port||(s==="https:"?"443":s==="http:"?"80":""),l=e.pathname.startsWith("/")?e.pathname:`/${e.pathname}`,i=e.search,c=e.hash,u=e.origin||`${s}//${a}${r?`:${r}`:""}`,p=`${l}${i}${c}`;return{protocol:s,host:a,port:r,pathname:l,search:i,hash:c,origin:u,fullPath:p}}compareUrlBase(t,e){if(!t||!e)return!1;const s=this.parseUrl(t),a=this.parseUrl(e);return s.protocol===a.protocol&&s.host===a.host&&s.port===a.port}compareUrlPath(t,e){if(!t||!e)return!1;const s=this.parseUrl(t),a=this.parseUrl(e);return s.pathname===a.pathname}compareUrlFull(t,e){if(!t||!e)return!1;const s=this.parseUrl(t),a=this.parseUrl(e);return s.fullPath===a.fullPath}clear(){this.postmateParent&&(this.postmateParent.destroy(),this.postmateParent=null),this.currentIframe&&this.currentIframe.parentNode&&this.currentIframe.parentNode.removeChild(this.currentIframe),this.currentIframe=null}async init(t=null){if(this.clear(),this.childSupportsRouteUpdate=!0,!this.iframeEle||!this.currentUrl){console.warn("iframeEle 和 currentUrl 是必需的");return}const e=typeof this.iframeEle=="function"?this.iframeEle():this.iframeEle;if(!e){console.warn("无法获取 iframe 容器");return}const s=new h({container:e,url:this.currentUrl,name:"",model:""});this.currentIframe=e.querySelector("iframe"),this.currentIframe.setAttribute("frameborder","0"),this.currentIframe.setAttribute("allow","fullscreen"),this.currentIframe.addEventListener("load",()=>{this.loadFunction&&this.loadFunction()}),s.then(a=>{this.postmateParent=a,a.on("requestBaseData",()=>{this.sendData()}),a.on("otherRequest",r=>{this.handleOtherRequest&&this.handleOtherRequest(r)}),typeof t=="function"&&t()}).catch(a=>{console.error("Postmate 连接失败:",a)})}setLoadFunction(t){this.loadFunction=t}setIframeUrl(t){if(this.currentUrl===t)return;if(!this.currentUrl){this.currentUrl=t,this.parsedCurrentUrl=this.parseUrl(t),this.iframeEle&&this.init();return}const e=this.parseUrl(t);if(this.postmateParent&&this.compareUrlBase(this.currentUrl,t)&&this.childSupportsRouteUpdate)if(this.compareUrlPath(this.currentUrl,t)){if(this.compareUrlFull(this.currentUrl,t))return;this.currentUrl=t,this.parsedCurrentUrl=e,this.sendRouteUpdate(e);return}else{this.currentUrl=t,this.parsedCurrentUrl=e,this.sendRouteUpdate(e);return}this.currentUrl=t,this.parsedCurrentUrl=e,this.iframeEle&&this.init()}sendRouteUpdate(t){if(this.postmateParent){if(!this.childSupportsRouteUpdate){console.warn("子页面不支持路由更新,直接重新初始化iframe"),this.init();return}try{this.postmateParent.call("routeUpdate",JSON.stringify({fullPath:t.fullPath,pathname:t.pathname,search:t.search,hash:t.hash}));let e=!1;const s=a=>{try{const r=JSON.parse(a.data);r&&r.type==="route_update_support"&&r.supported===!0&&(e=!0,window.removeEventListener("message",s))}catch{}};window.addEventListener("message",s),setTimeout(()=>{window.removeEventListener("message",s),e||(console.warn("子页面不支持路由更新,将在下次更新时重新初始化iframe"),this.childSupportsRouteUpdate=!1,this.init())},1e3)}catch(e){console.warn("发送路由更新消息失败,将重新初始化iframe:",e),this.childSupportsRouteUpdate=!1,this.init()}}}sendData(){this.postmateParent&&this.postmateParent.call("baseData",JSON.stringify(this.dataInfo))}destroy(){this.clear()}}d.ChildPostmate=U,d.ParentPostmate=E,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
1
+ (function(u,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(u=typeof globalThis<"u"?globalThis:u||self,n(u["qlfy-postmate"]={}))})(this,function(u){"use strict";const n="application/x-postmate-v1+json";let P=0;const y={handshake:1,"handshake-reply":1,call:1,emit:1,reply:1,request:1};function m(i,e){return(typeof e!="string"||i.origin===e)&&!!i.data&&(typeof i.data!="object"||"postmate"in i.data)&&i.data.type===n&&!!y[i.data.postmate]}class R{constructor(e){this.parent=e.parent,this.frame=e.frame,this.child=e.child,this.childOrigin=e.childOrigin,this.events={},this.listener=t=>{if(!m(t,this.childOrigin))return;const{value:s={}}=t.data,{name:r,data:a}=s;t.data.postmate==="emit"&&r in this.events&&this.events[r].call(this,a)},this.parent.addEventListener("message",this.listener,!1)}get(e){return new l.Promise(t=>{const s=++P,r=a=>{a.data.uid===s&&a.data.postmate==="reply"&&(this.parent.removeEventListener("message",r,!1),t(a.data.value))};this.parent.addEventListener("message",r,!1),this.child.postMessage({postmate:"request",type:n,property:e,uid:s},this.childOrigin)})}call(e,t){this.child.postMessage({postmate:"call",type:n,property:e,data:t},this.childOrigin)}on(e,t){this.events[e]=t}destroy(){window.removeEventListener("message",this.listener,!1),this.frame.parentNode.removeChild(this.frame)}}class U{constructor(e){this.model=e.model,this.parent=e.parent,this.parentOrigin=e.parentOrigin,this.child=e.child,this.child.addEventListener("message",t=>{if(!m(t,this.parentOrigin))return;const{postmate:s,property:r,uid:a,data:h}=t.data,o=this.model[r];if(s!=="call"){const c=typeof o=="function"?o():o;l.Promise.resolve(c).then(d=>{t.source.postMessage({property:r,postmate:"reply",type:n,uid:a,value:d},t.origin)})}else r in this.model&&typeof o=="function"&&o(h)})}emit(e,t){this.parent.postMessage({postmate:"emit",type:n,value:{name:e,data:t}},this.parentOrigin)}}class l{constructor({container:e=document.body,model:t,url:s,name:r,classListArray:a=[]}){return this.parent=window,this.frame=document.createElement("iframe"),this.frame.name=r||"",this.frame.classList.add(...a),e.appendChild(this.frame),this.child=this.frame.contentWindow,this.model=t||{},this.sendHandshake(s)}sendHandshake(e){const t=(()=>{const a=document.createElement("a");a.href=e;const h=a.protocol.length>4?a.protocol:window.location.protocol,o=a.host.length?a.port==="80"||a.port==="443"?a.hostname:a.host:window.location.host;return a.origin||`${h}//${o}`})();let s=0,r;return new l.Promise((a,h)=>{const o=p=>{if(!m(p,t))return!1;p.data.postmate==="handshake-reply"?(clearInterval(r),this.parent.removeEventListener("message",o,!1),this.childOrigin=p.origin,a(new R(this))):h("Failed handshake")};this.parent.addEventListener("message",o,!1);const c=()=>{s++,this.child.postMessage({postmate:"handshake",type:n,model:this.model},t),s===5&&clearInterval(r)},d=()=>{c(),r=setInterval(c,500)};this.frame.onload=d,this.frame.attachEvent&&this.frame.attachEvent("onload",d),this.frame.src=e})}}class w{constructor(e){return this.child=window,this.model=e,this.parent=window.parent,this.sendHandshakeReply()}sendHandshakeReply(){return new l.Promise((e,t)=>{this.child.addEventListener("message",s=>{if(s.data.postmate){if(s.data.postmate!=="handshake")return t("Handshake Reply Failed");this.child.removeEventListener("message",this,!1),s.source.postMessage({postmate:"handshake-reply",type:n},s.origin),this.parentOrigin=s.origin;const r=s.data.model;r&&Object.keys(r).forEach(a=>{this.model[a]=r[a]}),e(new U(this))}},!1)})}}l.debug=!1,l.Promise=(()=>{try{return typeof window<"u"?window.Promise:Promise}catch{return Promise}})(),l.Model=w;function f(i,e){for(const t of i)if(t.path===e||t.children&&Array.isArray(t.children)&&t.children.length>0&&f(t.children,e))return!0;return!1}function E(i,e){e.includes("?")&&(e=e.split("?")[0]);const t=g(i);return!t||t.length===0?!1:f(t,e)}function g(i){let e=[];return typeof i.getRoutes=="function"?e=i.getRoutes():i.options&&Array.isArray(i.options.routes)&&(e=i.options.routes),e||[]}function I(i,e){try{const t=new URL(i),s=new URL(e),r=t.protocol.toLowerCase()===s.protocol.toLowerCase(),a=t.hostname===s.hostname,h=t.port===s.port;return r&&a&&h}catch(t){return console.error("URL解析错误:",t),!1}}class k{constructor(e,t,s){this.childPostmate=null,this.parentPostmate=null,this.isGetData=!1,this.getDataCllBack=null,this.router=null,this.routeUpdateCallback=void 0,this.router=t,this.routeUpdateCallback=s,window.top!==window.self?this.init(e):e.error({status:500,data:null,message:"未在一体化平台中运行"})}init(e){const t=this;this.childPostmate=new l.Model({baseData(s){s=JSON.parse(s),t.isGetData?t.getDataCllBack&&t.getDataCllBack({status:200,message:"success",data:s}):e.receive({status:200,message:"success",data:s}),t.isGetData=!1},getRoutes:()=>{if(t.router){let s=g(t.router);t.parentPostmate.emit("pushRoutes",JSON.stringify(s))}else t.parentPostmate.emit("pushRoutes")},isRouteExists(s){t.router?t.parentPostmate.emit("routeExists",E(t.router,s)):t.parentPostmate.emit("routeExists",!1)},routeUpdate(s){try{const r=JSON.parse(s);if(t.routeUpdateCallback){t.routeUpdateCallback(r);return}t.router?(t.router.replace(r.fullPath),t.parentPostmate.emit("route_update_result",!0),console.log("----------------- 【ChildPastMate】路由更新完成 -----------------")):(t.parentPostmate.emit("route_update_result",!1),console.warn("【ChildPastMate】未提供router实例,无法进行路由更新"))}catch(r){console.error("【ChildPastMate】路由更新失败:",r),t.parentPostmate.emit("route_update_result",!1)}}}).then(s=>{t.parentPostmate=s,t.getData(),e.success({status:200,message:"success",data:{ChildPostmate:s}}),t.parentPostmate.emit("route_update_support",!!t.router),t.router&&t.parentPostmate.emit("pushRoutes",JSON.stringify(g(t.router)))}).catch(s=>{e.error({status:500,data:null,message:s})})}getData(e){if(!this.parentPostmate){e({status:500,message:"父页面未连接",data:null});return}e?(this.isGetData=!0,this.getDataCllBack=e):(this.isGetData=!1,this.getDataCllBack=null),this.parentPostmate.emit("requestBaseData")}setRouter(e,t){this.router=e,t&&(this.routeUpdateCallback=t)}sendOtherRequest(e){this.parentPostmate&&this.parentPostmate.emit("otherRequest",e)}}class C{constructor(e,t,s="",r){this.postmateParent=null,this.dataInfo={loginInfo:{},token:"",isHideHeader:!0},this.iframeEle=null,this.currentUrl="",this.currentBaseUrl="",this.currentRouterPath="",this.currentIframe=null,this.loadFunction=null,this.handleOtherRequest=null,this.parsedCurrentUrl=null,this.childSupportsRouteUpdate=!0,this.childRoutes=[],this.eventBus={getRoutes:null,route_update_resultL:null},this.dataInfo=e||this.dataInfo,this.iframeEle=t,this.setIframeUrl(s),r&&(this.handleOtherRequest=r)}parseUrl(e){const t=document.createElement("a");t.href=e;const s=t.protocol.length>4?t.protocol:window.location.protocol,r=t.hostname,a=t.port||(s==="https:"?"443":s==="http:"?"80":""),h=t.pathname.startsWith("/")?t.pathname:`/${t.pathname}`,o=t.search,c=t.hash.slice(2,t.hash.length),d=t.origin||`${s}//${r}${a?`:${a}`:""}`,p=`${h}${c}`;return{protocol:s,host:r,port:a,pathname:h,search:o,hash:c,origin:d,fullPath:p}}compareUrlBase(e,t){const s=e.endsWith("/"),r=t.endsWith("/");return s&&r||!s&&!r||(s&&(t+="/"),r&&(e+="/")),e===t}compareUrlPath(e,t){if(!e||!t)return!1;const s=this.parseUrl(e),r=this.parseUrl(t);return s.pathname===r.pathname}compareUrlFull(e,t){if(!e||!t)return!1;const s=this.parseUrl(e),r=this.parseUrl(t);return s.fullPath===r.fullPath}clear(){this.postmateParent&&(this.postmateParent.destroy(),this.postmateParent=null),this.currentIframe&&this.currentIframe.parentNode&&this.currentIframe.parentNode.removeChild(this.currentIframe),this.currentIframe=null}async init(e=null){this.clear(),this.childSupportsRouteUpdate=!1,(!this.iframeEle||!this.currentUrl)&&this.destroy();const t=typeof this.iframeEle=="function"?this.iframeEle():this.iframeEle;if(!t){console.warn("【ParentPostmate】无法获取 iframe 容器");return}const s=new l({container:t,url:this.currentUrl,name:"",model:""});this.currentIframe=t.querySelector("iframe"),this.currentIframe.setAttribute("frameborder","0"),this.currentIframe.setAttribute("allow","fullscreen"),this.currentIframe.addEventListener("load",()=>{this.loadFunction&&this.loadFunction()}),s.then(r=>{this.postmateParent=r,r.on("requestBaseData",()=>{this.sendData()}),r.on("pushRoutes",a=>{a?this.childRoutes=JSON.parse(a):this.childRoutes=[],this.eventBus.getRoutes&&this.eventBus.getRoutes()}),r.on("routeExists",a=>{}),r.on("route_update_support",a=>{this.childSupportsRouteUpdate=a}),r.on("route_update_result",a=>{this.eventBus.route_update_result&&this.eventBus.route_update_result(a)}),r.on("otherRequest",a=>{this.handleOtherRequest&&this.handleOtherRequest(a)}),typeof e=="function"&&e()}).catch(r=>{console.error("【ParentPostmate】Postmate 连接失败:",r)})}setLoadFunction(e){this.loadFunction=e}setIframeUrl(e,t=""){var r;if(t&&!t.startsWith("/")&&(t="/"+t),!e){this.currentUrl="",this.currentRouterPath="",this.destroy(),console.error("【ParentPostmate】无加载地址,无法初始化");return}if(!this.postmateParent||!this.currentUrl){this.currentUrl=e,this.currentRouterPath=t,this.iframeEle?this.init():console.error("【ParentPostmate】无 iframe 容器,无法初始化");return}if(!this.childSupportsRouteUpdate||!((r=this.childRoutes)!=null&&r.length)||!I(this.currentUrl,e)){this.currentUrl=e,this.currentRouterPath=t,this.init();return}let s=!1;this.eventBus.getRoutes=()=>{s=!0,this.handleSimilarUrl(e,t)},this.postmateParent.call("getRoutes"),setTimeout(()=>{s||this.handleSimilarUrl(e,t)},1e3)}handleSimilarUrl(e,t){if(this.currentUrl=e,this.currentRouterPath=t||"",t&&f(this.childRoutes,t)){this.sendRouteUpdate({fullPath:t});return}let s=!1,r=e.split("?")[0];this.childRoutes.forEach(a=>{if(r.endsWith(a.path)){this.sendRouteUpdate({fullPath:t}),s=!0;return}}),!s&&this.init()}sendRouteUpdate(e){try{let t=!1;this.eventBus.route_update_result=s=>{t=s,this.loadFunction&&this.loadFunction()},this.postmateParent.call("routeUpdate",JSON.stringify(e)),console.log("---------------------- 【ParentPostmate】推送路由更新 ----------------------"),setTimeout(()=>{t||(console.warn("【ParentPostmate】推送路由更新失败,将重新初始化iframe"),this.childSupportsRouteUpdate=!1,this.init())},1e3)}catch(t){console.warn("【ParentPostmate】发送路由更新消息失败,将重新初始化iframe:",t),this.childSupportsRouteUpdate=!1,this.init()}}sendData(){this.postmateParent&&this.postmateParent.call("baseData",JSON.stringify(this.dataInfo))}destroy(){this.clear()}}u.ChildPostmate=k,u.ParentPostmate=C,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
Binary file
@@ -5,9 +5,6 @@ interface EventObj {
5
5
  }
6
6
  interface RouteUpdateInfo {
7
7
  fullPath: string;
8
- pathname: string;
9
- search: string;
10
- hash: string;
11
8
  }
12
9
  export default class ChildPostmate {
13
10
  childPostmate: any;
@@ -15,7 +12,7 @@ export default class ChildPostmate {
15
12
  isGetData: boolean;
16
13
  getDataCllBack: Function | null;
17
14
  router: any;
18
- routeUpdateCallback: ((routeInfo: RouteUpdateInfo) => void) | null;
15
+ routeUpdateCallback: ((routeInfo: RouteUpdateInfo) => void) | undefined;
19
16
  constructor(eventObj: EventObj, router: any, routeUpdateCallback?: (routeInfo: RouteUpdateInfo) => void);
20
17
  init(eventObj: EventObj): void;
21
18
  getData(callback?: any): void;
@@ -0,0 +1,61 @@
1
+ interface DataInfo {
2
+ loginInfo: {
3
+ [x: string]: any;
4
+ };
5
+ token: string;
6
+ isHideHeader: boolean;
7
+ }
8
+ interface ParsedUrl {
9
+ protocol: string;
10
+ host: string;
11
+ port: string;
12
+ pathname: string;
13
+ search: string;
14
+ hash: string;
15
+ origin: string;
16
+ fullPath: string;
17
+ }
18
+ export default class ParentPostmate {
19
+ /** 连接到的子 postmate 实例 */
20
+ postmateParent: any;
21
+ /** 通讯数据 */
22
+ dataInfo: DataInfo;
23
+ /** iframe Dom 容器 */
24
+ iframeEle: any;
25
+ /** 当前 iframe url */
26
+ currentUrl: string;
27
+ /** 存储当前的 iframe 元素 */
28
+ currentIframe: any;
29
+ /** iframe 加载完成执行函数 */
30
+ loadFunction: (() => void) | null;
31
+ /** 处理子类的其他请求方法 */
32
+ handleOtherRequest: ((params: any) => void) | null;
33
+ /** 当前URL解析结果 */
34
+ parsedCurrentUrl: ParsedUrl | null;
35
+ /** 子页面是否支持路由更新 */
36
+ childSupportsRouteUpdate: boolean;
37
+ constructor(dataInfo: DataInfo, iframeEle: HTMLElement | (() => HTMLElement), iframeUrl?: string, handleOtherRequest?: (params: any) => void);
38
+ /** 解析URL */
39
+ parseUrl(url: string): ParsedUrl;
40
+ /** 比较两个URL是否相同(协议、主机、端口) */
41
+ compareUrlBase(url1: string, url2: string): boolean;
42
+ /** 比较两个URL的路径是否相同(不包含查询参数和哈希) */
43
+ compareUrlPath(url1: string, url2: string): boolean;
44
+ /** 比较两个URL是否完全相同(包括查询参数和哈希) */
45
+ compareUrlFull(url1: string, url2: string): boolean;
46
+ /** 清除当前的 iframe 和 postmate 实例 */
47
+ clear(): void;
48
+ /** 初始化 */
49
+ init(callback?: any): Promise<void>;
50
+ /** 设置load执行事件 */
51
+ setLoadFunction(loadFunction: any): void;
52
+ /** 设置 iframe url */
53
+ setIframeUrl(iframeUrl: string): void;
54
+ /** 向子页面发送路由更新消息 */
55
+ sendRouteUpdate(parsedUrl: ParsedUrl): void;
56
+ /** 向子页面发送消息 */
57
+ sendData(): void;
58
+ /** 销毁实例 */
59
+ destroy(): void;
60
+ }
61
+ export {};
@@ -24,6 +24,10 @@ export default class ParentPostmate {
24
24
  iframeEle: any;
25
25
  /** 当前 iframe url */
26
26
  currentUrl: string;
27
+ /** 当前url基础地址 */
28
+ currentBaseUrl: string;
29
+ /** 当前路由地址 */
30
+ currentRouterPath: string;
27
31
  /** 存储当前的 iframe 元素 */
28
32
  currentIframe: any;
29
33
  /** iframe 加载完成执行函数 */
@@ -34,10 +38,13 @@ export default class ParentPostmate {
34
38
  parsedCurrentUrl: ParsedUrl | null;
35
39
  /** 子页面是否支持路由更新 */
36
40
  childSupportsRouteUpdate: boolean;
41
+ /** 子系统的路由列表 */
42
+ childRoutes: any[];
43
+ eventBus: any;
37
44
  constructor(dataInfo: DataInfo, iframeEle: HTMLElement | (() => HTMLElement), iframeUrl?: string, handleOtherRequest?: (params: any) => void);
38
45
  /** 解析URL */
39
46
  parseUrl(url: string): ParsedUrl;
40
- /** 比较两个URL是否相同(协议、主机、端口) */
47
+ /** 比较两个URL是否相同*/
41
48
  compareUrlBase(url1: string, url2: string): boolean;
42
49
  /** 比较两个URL的路径是否相同(不包含查询参数和哈希) */
43
50
  compareUrlPath(url1: string, url2: string): boolean;
@@ -48,11 +55,12 @@ export default class ParentPostmate {
48
55
  /** 初始化 */
49
56
  init(callback?: any): Promise<void>;
50
57
  /** 设置load执行事件 */
51
- setLoadFunction(loadFunction: any): void;
58
+ setLoadFunction(loadFunction: () => void): void;
52
59
  /** 设置 iframe url */
53
- setIframeUrl(iframeUrl: string): void;
60
+ setIframeUrl(iframeUrl: string, routerPath?: string): void;
61
+ handleSimilarUrl(iframeUrl: string, routerPath?: string): void;
54
62
  /** 向子页面发送路由更新消息 */
55
- sendRouteUpdate(parsedUrl: ParsedUrl): void;
63
+ sendRouteUpdate(parsedUrl: any): void;
56
64
  /** 向子页面发送消息 */
57
65
  sendData(): void;
58
66
  /** 销毁实例 */
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 检查路径是否存在于路由配置中(递归检查所有层级)
3
+ * @param routes 路由配置数组
4
+ * @param path 需要检查的路径
5
+ * @returns 是否存在
6
+ */
7
+ export declare function checkPathInRoutes(routes: any[], path: string): boolean;
8
+ /**
9
+ * 判断路径是否存在于vue-router对象中(兼容Vue2和Vue3)
10
+ * @param router vue-router实例
11
+ * @param path 需要检查的页面路径
12
+ * @returns 路径是否存在
13
+ */
14
+ export declare function isRouteExists(router: any, path: string): boolean;
15
+ /**
16
+ * 获取路由路径
17
+ *
18
+ */
19
+ export declare function getRouterPaths(router: any): any[];
20
+ /**
21
+ * 比较两个URL的协议、IP(或域名)和端口是否完全相同
22
+ * @param url1 第一个URL字符串
23
+ * @param url2 第二个URL字符串
24
+ * @returns 如果协议、IP(或域名)和端口都相同则返回true,否则返回false;解析失败时返回false
25
+ */
26
+ export declare function areUrlsSameProtocolIpPort(url1: string, url2: string): boolean;
@@ -0,0 +1,34 @@
1
+ interface EventObj {
2
+ error: (error: any) => void;
3
+ success: (success: any) => void;
4
+ receive: (receive: any) => void;
5
+ }
6
+ interface RouteUpdateInfo {
7
+ fullPath: string;
8
+ pathname: string;
9
+ search: string;
10
+ hash: string;
11
+ }
12
+ export default class ChildPostmate {
13
+ childPostmate: any;
14
+ parentPostmate: any;
15
+ isGetData: boolean;
16
+ getDataCllBack: Function | null;
17
+ router: any;
18
+ routeUpdateCallback: ((routeInfo: RouteUpdateInfo) => void) | null;
19
+ constructor(eventObj: EventObj, router: any, routeUpdateCallback?: (routeInfo: RouteUpdateInfo) => void);
20
+ init(eventObj: EventObj): void;
21
+ getData(callback?: any): void;
22
+ /**
23
+ * 设置路由实例和路由更新回调
24
+ * @param router Vue Router实例
25
+ * @param routeUpdateCallback 自定义路由更新回调函数
26
+ */
27
+ setRouter(router: any, routeUpdateCallback?: (routeInfo: RouteUpdateInfo) => void): void;
28
+ /**
29
+ * 向父页面发送其他请求
30
+ * @param params 请求参数
31
+ */
32
+ sendOtherRequest(params: any): void;
33
+ }
34
+ export {};
@@ -0,0 +1,61 @@
1
+ interface DataInfo {
2
+ loginInfo: {
3
+ [x: string]: any;
4
+ };
5
+ token: string;
6
+ isHideHeader: boolean;
7
+ }
8
+ interface ParsedUrl {
9
+ protocol: string;
10
+ host: string;
11
+ port: string;
12
+ pathname: string;
13
+ search: string;
14
+ hash: string;
15
+ origin: string;
16
+ fullPath: string;
17
+ }
18
+ export default class ParentPostmate {
19
+ /** 连接到的子 postmate 实例 */
20
+ postmateParent: any;
21
+ /** 通讯数据 */
22
+ dataInfo: DataInfo;
23
+ /** iframe Dom 容器 */
24
+ iframeEle: any;
25
+ /** 当前 iframe url */
26
+ currentUrl: string;
27
+ /** 存储当前的 iframe 元素 */
28
+ currentIframe: any;
29
+ /** iframe 加载完成执行函数 */
30
+ loadFunction: (() => void) | null;
31
+ /** 处理子类的其他请求方法 */
32
+ handleOtherRequest: ((params: any) => void) | null;
33
+ /** 当前URL解析结果 */
34
+ parsedCurrentUrl: ParsedUrl | null;
35
+ /** 子页面是否支持路由更新 */
36
+ childSupportsRouteUpdate: boolean;
37
+ constructor(dataInfo: DataInfo, iframeEle: HTMLElement | (() => HTMLElement), iframeUrl?: string, handleOtherRequest?: (params: any) => void);
38
+ /** 解析URL */
39
+ parseUrl(url: string): ParsedUrl;
40
+ /** 比较两个URL是否相同(协议、主机、端口) */
41
+ compareUrlBase(url1: string, url2: string): boolean;
42
+ /** 比较两个URL的路径是否相同(不包含查询参数和哈希) */
43
+ compareUrlPath(url1: string, url2: string): boolean;
44
+ /** 比较两个URL是否完全相同(包括查询参数和哈希) */
45
+ compareUrlFull(url1: string, url2: string): boolean;
46
+ /** 清除当前的 iframe 和 postmate 实例 */
47
+ clear(): void;
48
+ /** 初始化 */
49
+ init(callback?: any): Promise<void>;
50
+ /** 设置load执行事件 */
51
+ setLoadFunction(loadFunction: any): void;
52
+ /** 设置 iframe url */
53
+ setIframeUrl(iframeUrl: string): void;
54
+ /** 向子页面发送路由更新消息 */
55
+ sendRouteUpdate(parsedUrl: ParsedUrl): void;
56
+ /** 向子页面发送消息 */
57
+ sendData(): void;
58
+ /** 销毁实例 */
59
+ destroy(): void;
60
+ }
61
+ export {};
@@ -0,0 +1,3 @@
1
+ import { default as ChildPostmate } from './ChildPostmate';
2
+ import { default as ParentPostmate } from './ParentPostmate';
3
+ export { ChildPostmate, ParentPostmate };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlfy-postmate",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "",
5
5
  "types": "lib/index.d.ts",
6
6
  "module": "lib/index.umd.js",