wujie-event-scope 1.0.8 → 1.0.10
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 +63 -2
- package/dist/index.cjs.js +134 -44
- package/dist/index.es.js +134 -44
- package/dist/types/babelParse.d.ts +9 -0
- package/dist/types/babelParse.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/babelParse.ts +113 -34
- package/src/index.ts +23 -12
package/README.md
CHANGED
|
@@ -1,2 +1,63 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# wujie-event-scope
|
|
2
|
+
|
|
3
|
+
在无界(wujie)子应用沙箱中,内联 HTML 事件(如 `onclick`)里的代码往往默认指向**宿主全局 `window`**,访问子应用里挂载的变量或 API 时容易出现 **`undefined` 或跑错环境**。本库在**不改业务写法**的前提下,把事件函数字符串改写为在**子应用代理 `window`** 上执行。
|
|
4
|
+
|
|
5
|
+
## 目标
|
|
6
|
+
|
|
7
|
+
- 让 **`onclick` 属性** 与 **`element.onclick` 函数 toString** 两类来源的事件逻辑,在运行时使用的 `window` 与无界子应用一致。
|
|
8
|
+
- 通过 **IIFE 形参遮蔽**:`(function(window) { … })(window.__WUJIE_xxx)`,使补丁里出现的 `window.xxx` 指向传入的代理,而不是宿主全局。
|
|
9
|
+
- 对**函数声明、变量声明、以及裸标识符的简单赋值**(如 `obj = {}`)等会在全局产生「名字」的写法,额外生成 **`window.名字 = 名字`**,把这些绑定同步到形参 `window`(子应用代理)上,避免只在局部存在、代理上读不到的问题。
|
|
10
|
+
|
|
11
|
+
## 工作原理(简要)
|
|
12
|
+
|
|
13
|
+
1. **表达式侧改写**(`findIdentifiers`)
|
|
14
|
+
用 [Acorn](https://github.com/acornjs/acorn) 遍历代码,收集**调用 callee**、**赋值左侧**等位置;对未包含 `window` 子串的片段前缀 `window.`,把对全局的访问改写成 `window.xxx`,与 IIFE 内形参 `window` 一致。
|
|
15
|
+
|
|
16
|
+
2. **声明 / 隐式全局绑定同步**(`findDeclarationIdentifiers`)
|
|
17
|
+
单独扫描**函数声明**、**变量声明**(含解构左侧)、以及 **`id = …` 且左侧为裸标识符**的简单赋值(脚本语义下会挂到全局对象上的名字)。
|
|
18
|
+
对每个收集到的名字 `x`,生成一段 **`window.x = x;`** 拼接进最终可执行字符串。这样在 `(function(window) { … })` 里,先执行用户逻辑产生绑定,再把同名属性挂到**形参 `window`**(无界子应用代理)上,后续通过 `window.xxx` 的读写才能落在同一对象上。
|
|
19
|
+
|
|
20
|
+
3. **子应用 `window` 注入**
|
|
21
|
+
- 首次处理某个子应用 `Window` 时,读取 `targetWindow.__WUJIE.id`,生成宿主上的全局路径 `__WUJIE_<规范化后的 id>`(字母数字大写,见 `targetToLNU`),并执行 `window[路径] = targetWindow`。
|
|
22
|
+
- 路径缓存在 `WeakMap<Window, string>`(`elementDataStore`),同一子应用只注册一次。
|
|
23
|
+
|
|
24
|
+
4. **回写**
|
|
25
|
+
`patchElementHook` 会把改写后的函数体包进:
|
|
26
|
+
`(function(window) { … })(window.__WUJIE_xxx)`。
|
|
27
|
+
若还需要**声明同步**,请把 `findDeclarationIdentifiers` 返回的 `window.x=x;…` 串在函数体**前部**与经 `findIdentifiers` 处理后的正文拼在一起,再包进同一 IIFE(与无界注入路径一致)。
|
|
28
|
+
|
|
29
|
+
## 使用
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import wujieEventScope from "wujie-event-scope";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
通过 [WUJIE](https://wujie-micro.github.io/doc/api/preloadApp.html#plugins)提供的Plugins扩展使用
|
|
36
|
+
|
|
37
|
+
源码中可直接使用:
|
|
38
|
+
|
|
39
|
+
- `findIdentifiers`:表达式侧改写(`window.xxx` 前缀)。
|
|
40
|
+
- `findDeclarationIdentifiers`:返回 `window.x=x;` 形式的声明同步片段(见 `src/babelParse.ts`)。二者可按需组合
|
|
41
|
+
|
|
42
|
+
**前提**:子应用 `Window` 上存在无界提供的 `__WUJIE.id`,用于生成稳定的全局路径名。
|
|
43
|
+
|
|
44
|
+
## 构建
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm install
|
|
48
|
+
npm run build
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
产物:`dist/index.cjs.js`、`dist/index.es.js` 及类型声明。
|
|
52
|
+
|
|
53
|
+
## 限制与注意
|
|
54
|
+
|
|
55
|
+
- **覆盖范围**:`findIdentifiers` 只处理扫描到的调用/赋值等位置,并非任意标识符;`!ast.includes('window')` 为启发式判断,极端写法可能漏改或误跳过。
|
|
56
|
+
- **`findDeclarationIdentifiers`**:不包含成员赋值 `a.b =`、复合赋值、普通表达式里的标识符等;与「声明 / 裸 `x =`」语义对齐,复杂场景需自行扩展。
|
|
57
|
+
- **`element.onclick` 路径**:从 `function … () { … }` 字符串中用正则抽取函数体(`fnBody`),复杂嵌套或非 `function` 声明可能不稳定。
|
|
58
|
+
- **安全**:本质仍是执行字符串化后的用户代码;不可信输入场景需配合 CSP、白名单等治理,不能单靠本库视为「安全沙箱」。
|
|
59
|
+
- **多子应用**:通过 `__WUJIE.id` 区分,每个子应用对应宿主上一个 `window.__WUJIE_<…>` 槽位。
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
ISC
|
package/dist/index.cjs.js
CHANGED
|
@@ -6284,6 +6284,26 @@ function simple(node, visitors, baseVisitor, state, override) {
|
|
|
6284
6284
|
})(node, state, override);
|
|
6285
6285
|
}
|
|
6286
6286
|
|
|
6287
|
+
// A recursive walk is one where your functions override the default
|
|
6288
|
+
// walkers. They can modify and replace the state parameter that's
|
|
6289
|
+
// threaded through the walk, and can opt how and whether to walk
|
|
6290
|
+
// their child nodes (by calling their third argument on these
|
|
6291
|
+
// nodes).
|
|
6292
|
+
function recursive(node, state, funcs, baseVisitor, override) {
|
|
6293
|
+
var visitor = funcs ? make(funcs, undefined) : baseVisitor
|
|
6294
|
+
;(function c(node, st, override) {
|
|
6295
|
+
visitor[override || node.type](node, st, c);
|
|
6296
|
+
})(node, state, override);
|
|
6297
|
+
}
|
|
6298
|
+
|
|
6299
|
+
// Used to create a custom walker. Will fill in all missing node
|
|
6300
|
+
// type properties with the defaults.
|
|
6301
|
+
function make(funcs, baseVisitor) {
|
|
6302
|
+
var visitor = Object.create(baseVisitor || base);
|
|
6303
|
+
for (var type in funcs) { visitor[type] = funcs[type]; }
|
|
6304
|
+
return visitor
|
|
6305
|
+
}
|
|
6306
|
+
|
|
6287
6307
|
function skipThrough(node, st, c) { c(node, st); }
|
|
6288
6308
|
function ignore(_node, _st, _c) {}
|
|
6289
6309
|
|
|
@@ -6619,39 +6639,6 @@ function findIdentifiers(code) {
|
|
|
6619
6639
|
if (!callee)
|
|
6620
6640
|
return;
|
|
6621
6641
|
getCallExpression(callee, node.arguments, results);
|
|
6622
|
-
// if (callee.type === "Identifier") {
|
|
6623
|
-
// results.add({
|
|
6624
|
-
// ast: callee.name,
|
|
6625
|
-
// start: callee.start,
|
|
6626
|
-
// end: callee.end,
|
|
6627
|
-
// });
|
|
6628
|
-
// if (Array.isArray(node.arguments) && node.arguments.length > 0) {
|
|
6629
|
-
// node.arguments.forEach((node: any) => {
|
|
6630
|
-
// if (node.type === 'Identifier') {
|
|
6631
|
-
// results.add({
|
|
6632
|
-
// ast: node.name,
|
|
6633
|
-
// start: node.start,
|
|
6634
|
-
// end: node.end,
|
|
6635
|
-
// });
|
|
6636
|
-
// } else if (node.type === 'MemberExpression') {
|
|
6637
|
-
// const memberName = getMemberExpressionPath(callee);
|
|
6638
|
-
// results.add({
|
|
6639
|
-
// ast: memberName,
|
|
6640
|
-
// start: node.start,
|
|
6641
|
-
// end: node.end,
|
|
6642
|
-
// });
|
|
6643
|
-
// }
|
|
6644
|
-
// })
|
|
6645
|
-
// }
|
|
6646
|
-
// }
|
|
6647
|
-
// if (callee.type === "MemberExpression") {
|
|
6648
|
-
// const memberName = getMemberExpressionPath(callee);
|
|
6649
|
-
// results.add({
|
|
6650
|
-
// ast: memberName,
|
|
6651
|
-
// start: callee.start,
|
|
6652
|
-
// end: callee.end,
|
|
6653
|
-
// });
|
|
6654
|
-
// }
|
|
6655
6642
|
},
|
|
6656
6643
|
AssignmentExpression(node) {
|
|
6657
6644
|
const left = node.left;
|
|
@@ -6676,6 +6663,103 @@ function findIdentifiers(code) {
|
|
|
6676
6663
|
});
|
|
6677
6664
|
return Array.from(results).sort((a, b) => a.start - b.start);
|
|
6678
6665
|
}
|
|
6666
|
+
/** 从解构等 Pattern 中收集绑定名(仅用于变量声明左侧) */
|
|
6667
|
+
function collectPatternBindingIds(id, results) {
|
|
6668
|
+
if (!id)
|
|
6669
|
+
return;
|
|
6670
|
+
// 普通声明:let a、const foo = 1、var bar
|
|
6671
|
+
if (id.type === "Identifier") {
|
|
6672
|
+
results.push({ ast: id.name, start: id.start, end: id.end });
|
|
6673
|
+
return;
|
|
6674
|
+
}
|
|
6675
|
+
// 对象解构左侧:const { x, y: z, ...rest } = obj
|
|
6676
|
+
if (id.type === "ObjectPattern") {
|
|
6677
|
+
for (const prop of id.properties) {
|
|
6678
|
+
if (prop.type === "Property") {
|
|
6679
|
+
collectPatternBindingIds(prop.value, results);
|
|
6680
|
+
}
|
|
6681
|
+
else if (prop.type === "RestElement") {
|
|
6682
|
+
collectPatternBindingIds(prop.argument, results);
|
|
6683
|
+
}
|
|
6684
|
+
}
|
|
6685
|
+
return;
|
|
6686
|
+
}
|
|
6687
|
+
// 数组解构左侧:const [a, b, , c] = arr
|
|
6688
|
+
if (id.type === "ArrayPattern") {
|
|
6689
|
+
for (const elt of id.elements) {
|
|
6690
|
+
if (elt)
|
|
6691
|
+
collectPatternBindingIds(elt, results);
|
|
6692
|
+
}
|
|
6693
|
+
return;
|
|
6694
|
+
}
|
|
6695
|
+
// 带默认值的解构项:const { x = 1 } = o 或 const [a = 0] = arr
|
|
6696
|
+
if (id.type === "AssignmentPattern") {
|
|
6697
|
+
collectPatternBindingIds(id.left, results);
|
|
6698
|
+
}
|
|
6699
|
+
// 剩余合并项解构赋值:const { ...rest } = o、const [a, ...tail] = arr
|
|
6700
|
+
if (id.type === "RestElement") {
|
|
6701
|
+
collectPatternBindingIds(id.argument, results);
|
|
6702
|
+
}
|
|
6703
|
+
}
|
|
6704
|
+
/**
|
|
6705
|
+
* 匹配会在全局(如浏览器 window)上产生「命名绑定」的写法(仅**脚本顶层**,不含嵌套函数体内):
|
|
6706
|
+
* - 顶层函数声明名(如 `function onclick`)
|
|
6707
|
+
* - 顶层 var/let/const(含解构左侧)
|
|
6708
|
+
* - 顶层对裸标识符的简单赋值 `id = ...`
|
|
6709
|
+
*
|
|
6710
|
+
* 不包含:函数体内的声明、成员赋值 `a.b =`、复合赋值等。
|
|
6711
|
+
*/
|
|
6712
|
+
function findDeclarationIdentifiers(code) {
|
|
6713
|
+
const state = {
|
|
6714
|
+
functionDepth: 0,
|
|
6715
|
+
results: [],
|
|
6716
|
+
};
|
|
6717
|
+
const ast = parse(code, {
|
|
6718
|
+
ecmaVersion: "latest",
|
|
6719
|
+
sourceType: "module",
|
|
6720
|
+
ranges: true,
|
|
6721
|
+
});
|
|
6722
|
+
const visitors = make({
|
|
6723
|
+
Function(node, st, c) {
|
|
6724
|
+
if (node.type === "FunctionDeclaration" &&
|
|
6725
|
+
node.id &&
|
|
6726
|
+
st.functionDepth === 0) {
|
|
6727
|
+
st.results.push({
|
|
6728
|
+
ast: node.id.name,
|
|
6729
|
+
start: node.id.start,
|
|
6730
|
+
end: node.id.end,
|
|
6731
|
+
});
|
|
6732
|
+
}
|
|
6733
|
+
st.functionDepth++;
|
|
6734
|
+
base.Function(node, st, c);
|
|
6735
|
+
st.functionDepth--;
|
|
6736
|
+
},
|
|
6737
|
+
VariableDeclaration(node, st, c) {
|
|
6738
|
+
if (st.functionDepth === 0) {
|
|
6739
|
+
for (const decl of node.declarations) {
|
|
6740
|
+
collectPatternBindingIds(decl.id, st.results);
|
|
6741
|
+
}
|
|
6742
|
+
}
|
|
6743
|
+
base.VariableDeclaration(node, st, c);
|
|
6744
|
+
},
|
|
6745
|
+
AssignmentExpression(node, st, c) {
|
|
6746
|
+
if (st.functionDepth === 0 &&
|
|
6747
|
+
node.operator === "=" &&
|
|
6748
|
+
node.left?.type === "Identifier") {
|
|
6749
|
+
st.results.push({
|
|
6750
|
+
ast: node.left.name,
|
|
6751
|
+
start: node.left.start,
|
|
6752
|
+
end: node.left.end,
|
|
6753
|
+
});
|
|
6754
|
+
}
|
|
6755
|
+
base.AssignmentExpression(node, st, c);
|
|
6756
|
+
},
|
|
6757
|
+
}, base);
|
|
6758
|
+
recursive(ast, state, visitors);
|
|
6759
|
+
return state.results.reduce((pv, { ast }) => {
|
|
6760
|
+
return `${pv}window.${ast}=${ast};`;
|
|
6761
|
+
}, "");
|
|
6762
|
+
}
|
|
6679
6763
|
|
|
6680
6764
|
const store = new WeakMap();
|
|
6681
6765
|
function setStoreData(window, path) {
|
|
@@ -6706,11 +6790,11 @@ function dealAttributesOCPatch(targetString) {
|
|
|
6706
6790
|
}
|
|
6707
6791
|
});
|
|
6708
6792
|
replaceAttributeEventStr += `${targetString.slice(lastSliceEnd)}`;
|
|
6709
|
-
console.log("====事件函数处理后字符", replaceAttributeEventStr)
|
|
6793
|
+
// console.log("====事件函数处理后字符", replaceAttributeEventStr)
|
|
6710
6794
|
return replaceAttributeEventStr;
|
|
6711
6795
|
}
|
|
6712
6796
|
function dealHTMLOCPatch(targetString) {
|
|
6713
|
-
console.log("====事件函数原字符", targetString)
|
|
6797
|
+
// console.log("====事件函数原字符", targetString)
|
|
6714
6798
|
const targetAttrLists = findIdentifiers(targetString);
|
|
6715
6799
|
let lastSliceEnd = 0;
|
|
6716
6800
|
let replaceHTMLClickEventStr = '';
|
|
@@ -6722,7 +6806,7 @@ function dealHTMLOCPatch(targetString) {
|
|
|
6722
6806
|
}
|
|
6723
6807
|
});
|
|
6724
6808
|
replaceHTMLClickEventStr += `${targetString.slice(lastSliceEnd)}`;
|
|
6725
|
-
console.log("====事件函数处理后字符", replaceHTMLClickEventStr)
|
|
6809
|
+
// console.log("====事件函数处理后字符", replaceHTMLClickEventStr)
|
|
6726
6810
|
const fnBodyStr = replaceHTMLClickEventStr.match(fnBody)?.[1];
|
|
6727
6811
|
return fnBodyStr || '';
|
|
6728
6812
|
}
|
|
@@ -6730,10 +6814,10 @@ function patchElementHook(element, targetWindow) {
|
|
|
6730
6814
|
const targetHaveGetAttribute = typeof element.getAttribute === 'function';
|
|
6731
6815
|
const originHTMLClickEvent = element.onclick;
|
|
6732
6816
|
const originAttributeEventStr = targetHaveGetAttribute ? element.getAttribute('onclick') : '';
|
|
6733
|
-
if (targetHaveGetAttribute && element.getAttribute('data-test-scope')) {
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
}
|
|
6817
|
+
// if (targetHaveGetAttribute && element.getAttribute('data-test-scope')) {
|
|
6818
|
+
// console.log('===HTML事件绑定', originHTMLClickEvent)
|
|
6819
|
+
// console.log('===attribute获取事件', originAttributeEventStr)
|
|
6820
|
+
// }
|
|
6737
6821
|
let result = '';
|
|
6738
6822
|
if (originAttributeEventStr) {
|
|
6739
6823
|
result = dealAttributesOCPatch(originAttributeEventStr);
|
|
@@ -6742,13 +6826,13 @@ function patchElementHook(element, targetWindow) {
|
|
|
6742
6826
|
result = dealHTMLOCPatch(originHTMLClickEvent.toString());
|
|
6743
6827
|
}
|
|
6744
6828
|
if (result) {
|
|
6745
|
-
console.log("====执行字符串", result)
|
|
6829
|
+
// console.log("====执行字符串", result)
|
|
6746
6830
|
const haveRegister = elementDataStore.hasStoreData(targetWindow);
|
|
6747
6831
|
if (!haveRegister) {
|
|
6748
6832
|
// @ts-ignore
|
|
6749
6833
|
const currentWujieName = targetWindow.__WUJIE.id;
|
|
6750
6834
|
const targetWindowPath = `__WUJIE_${targetToLNU(currentWujieName)}`;
|
|
6751
|
-
console.log("===存储路径", targetWindowPath)
|
|
6835
|
+
// console.log("===存储路径", targetWindowPath)
|
|
6752
6836
|
// @ts-ignore
|
|
6753
6837
|
window[targetWindowPath] = targetWindow;
|
|
6754
6838
|
elementDataStore.setStoreData(targetWindow, targetWindowPath);
|
|
@@ -6757,11 +6841,17 @@ function patchElementHook(element, targetWindow) {
|
|
|
6757
6841
|
element.setAttribute('onclick', `(function(window) {
|
|
6758
6842
|
${result}
|
|
6759
6843
|
})(window.${targetWindowPath})`);
|
|
6760
|
-
console.log("===替换之后的结果", element.getAttribute('onclick'))
|
|
6844
|
+
// console.log("===替换之后的结果", element.getAttribute('onclick'))
|
|
6761
6845
|
}
|
|
6762
6846
|
}
|
|
6847
|
+
function patchInlineCodeHook(target, targetWindow) {
|
|
6848
|
+
const result = findDeclarationIdentifiers(target.code);
|
|
6849
|
+
console.log("===处理后的信息", result);
|
|
6850
|
+
target.code = result;
|
|
6851
|
+
}
|
|
6763
6852
|
var index = {
|
|
6764
|
-
patchElementHook
|
|
6853
|
+
patchElementHook,
|
|
6854
|
+
patchInlineCodeHook
|
|
6765
6855
|
};
|
|
6766
6856
|
|
|
6767
6857
|
module.exports = index;
|
package/dist/index.es.js
CHANGED
|
@@ -6282,6 +6282,26 @@ function simple(node, visitors, baseVisitor, state, override) {
|
|
|
6282
6282
|
})(node, state, override);
|
|
6283
6283
|
}
|
|
6284
6284
|
|
|
6285
|
+
// A recursive walk is one where your functions override the default
|
|
6286
|
+
// walkers. They can modify and replace the state parameter that's
|
|
6287
|
+
// threaded through the walk, and can opt how and whether to walk
|
|
6288
|
+
// their child nodes (by calling their third argument on these
|
|
6289
|
+
// nodes).
|
|
6290
|
+
function recursive(node, state, funcs, baseVisitor, override) {
|
|
6291
|
+
var visitor = funcs ? make(funcs, undefined) : baseVisitor
|
|
6292
|
+
;(function c(node, st, override) {
|
|
6293
|
+
visitor[override || node.type](node, st, c);
|
|
6294
|
+
})(node, state, override);
|
|
6295
|
+
}
|
|
6296
|
+
|
|
6297
|
+
// Used to create a custom walker. Will fill in all missing node
|
|
6298
|
+
// type properties with the defaults.
|
|
6299
|
+
function make(funcs, baseVisitor) {
|
|
6300
|
+
var visitor = Object.create(baseVisitor || base);
|
|
6301
|
+
for (var type in funcs) { visitor[type] = funcs[type]; }
|
|
6302
|
+
return visitor
|
|
6303
|
+
}
|
|
6304
|
+
|
|
6285
6305
|
function skipThrough(node, st, c) { c(node, st); }
|
|
6286
6306
|
function ignore(_node, _st, _c) {}
|
|
6287
6307
|
|
|
@@ -6617,39 +6637,6 @@ function findIdentifiers(code) {
|
|
|
6617
6637
|
if (!callee)
|
|
6618
6638
|
return;
|
|
6619
6639
|
getCallExpression(callee, node.arguments, results);
|
|
6620
|
-
// if (callee.type === "Identifier") {
|
|
6621
|
-
// results.add({
|
|
6622
|
-
// ast: callee.name,
|
|
6623
|
-
// start: callee.start,
|
|
6624
|
-
// end: callee.end,
|
|
6625
|
-
// });
|
|
6626
|
-
// if (Array.isArray(node.arguments) && node.arguments.length > 0) {
|
|
6627
|
-
// node.arguments.forEach((node: any) => {
|
|
6628
|
-
// if (node.type === 'Identifier') {
|
|
6629
|
-
// results.add({
|
|
6630
|
-
// ast: node.name,
|
|
6631
|
-
// start: node.start,
|
|
6632
|
-
// end: node.end,
|
|
6633
|
-
// });
|
|
6634
|
-
// } else if (node.type === 'MemberExpression') {
|
|
6635
|
-
// const memberName = getMemberExpressionPath(callee);
|
|
6636
|
-
// results.add({
|
|
6637
|
-
// ast: memberName,
|
|
6638
|
-
// start: node.start,
|
|
6639
|
-
// end: node.end,
|
|
6640
|
-
// });
|
|
6641
|
-
// }
|
|
6642
|
-
// })
|
|
6643
|
-
// }
|
|
6644
|
-
// }
|
|
6645
|
-
// if (callee.type === "MemberExpression") {
|
|
6646
|
-
// const memberName = getMemberExpressionPath(callee);
|
|
6647
|
-
// results.add({
|
|
6648
|
-
// ast: memberName,
|
|
6649
|
-
// start: callee.start,
|
|
6650
|
-
// end: callee.end,
|
|
6651
|
-
// });
|
|
6652
|
-
// }
|
|
6653
6640
|
},
|
|
6654
6641
|
AssignmentExpression(node) {
|
|
6655
6642
|
const left = node.left;
|
|
@@ -6674,6 +6661,103 @@ function findIdentifiers(code) {
|
|
|
6674
6661
|
});
|
|
6675
6662
|
return Array.from(results).sort((a, b) => a.start - b.start);
|
|
6676
6663
|
}
|
|
6664
|
+
/** 从解构等 Pattern 中收集绑定名(仅用于变量声明左侧) */
|
|
6665
|
+
function collectPatternBindingIds(id, results) {
|
|
6666
|
+
if (!id)
|
|
6667
|
+
return;
|
|
6668
|
+
// 普通声明:let a、const foo = 1、var bar
|
|
6669
|
+
if (id.type === "Identifier") {
|
|
6670
|
+
results.push({ ast: id.name, start: id.start, end: id.end });
|
|
6671
|
+
return;
|
|
6672
|
+
}
|
|
6673
|
+
// 对象解构左侧:const { x, y: z, ...rest } = obj
|
|
6674
|
+
if (id.type === "ObjectPattern") {
|
|
6675
|
+
for (const prop of id.properties) {
|
|
6676
|
+
if (prop.type === "Property") {
|
|
6677
|
+
collectPatternBindingIds(prop.value, results);
|
|
6678
|
+
}
|
|
6679
|
+
else if (prop.type === "RestElement") {
|
|
6680
|
+
collectPatternBindingIds(prop.argument, results);
|
|
6681
|
+
}
|
|
6682
|
+
}
|
|
6683
|
+
return;
|
|
6684
|
+
}
|
|
6685
|
+
// 数组解构左侧:const [a, b, , c] = arr
|
|
6686
|
+
if (id.type === "ArrayPattern") {
|
|
6687
|
+
for (const elt of id.elements) {
|
|
6688
|
+
if (elt)
|
|
6689
|
+
collectPatternBindingIds(elt, results);
|
|
6690
|
+
}
|
|
6691
|
+
return;
|
|
6692
|
+
}
|
|
6693
|
+
// 带默认值的解构项:const { x = 1 } = o 或 const [a = 0] = arr
|
|
6694
|
+
if (id.type === "AssignmentPattern") {
|
|
6695
|
+
collectPatternBindingIds(id.left, results);
|
|
6696
|
+
}
|
|
6697
|
+
// 剩余合并项解构赋值:const { ...rest } = o、const [a, ...tail] = arr
|
|
6698
|
+
if (id.type === "RestElement") {
|
|
6699
|
+
collectPatternBindingIds(id.argument, results);
|
|
6700
|
+
}
|
|
6701
|
+
}
|
|
6702
|
+
/**
|
|
6703
|
+
* 匹配会在全局(如浏览器 window)上产生「命名绑定」的写法(仅**脚本顶层**,不含嵌套函数体内):
|
|
6704
|
+
* - 顶层函数声明名(如 `function onclick`)
|
|
6705
|
+
* - 顶层 var/let/const(含解构左侧)
|
|
6706
|
+
* - 顶层对裸标识符的简单赋值 `id = ...`
|
|
6707
|
+
*
|
|
6708
|
+
* 不包含:函数体内的声明、成员赋值 `a.b =`、复合赋值等。
|
|
6709
|
+
*/
|
|
6710
|
+
function findDeclarationIdentifiers(code) {
|
|
6711
|
+
const state = {
|
|
6712
|
+
functionDepth: 0,
|
|
6713
|
+
results: [],
|
|
6714
|
+
};
|
|
6715
|
+
const ast = parse(code, {
|
|
6716
|
+
ecmaVersion: "latest",
|
|
6717
|
+
sourceType: "module",
|
|
6718
|
+
ranges: true,
|
|
6719
|
+
});
|
|
6720
|
+
const visitors = make({
|
|
6721
|
+
Function(node, st, c) {
|
|
6722
|
+
if (node.type === "FunctionDeclaration" &&
|
|
6723
|
+
node.id &&
|
|
6724
|
+
st.functionDepth === 0) {
|
|
6725
|
+
st.results.push({
|
|
6726
|
+
ast: node.id.name,
|
|
6727
|
+
start: node.id.start,
|
|
6728
|
+
end: node.id.end,
|
|
6729
|
+
});
|
|
6730
|
+
}
|
|
6731
|
+
st.functionDepth++;
|
|
6732
|
+
base.Function(node, st, c);
|
|
6733
|
+
st.functionDepth--;
|
|
6734
|
+
},
|
|
6735
|
+
VariableDeclaration(node, st, c) {
|
|
6736
|
+
if (st.functionDepth === 0) {
|
|
6737
|
+
for (const decl of node.declarations) {
|
|
6738
|
+
collectPatternBindingIds(decl.id, st.results);
|
|
6739
|
+
}
|
|
6740
|
+
}
|
|
6741
|
+
base.VariableDeclaration(node, st, c);
|
|
6742
|
+
},
|
|
6743
|
+
AssignmentExpression(node, st, c) {
|
|
6744
|
+
if (st.functionDepth === 0 &&
|
|
6745
|
+
node.operator === "=" &&
|
|
6746
|
+
node.left?.type === "Identifier") {
|
|
6747
|
+
st.results.push({
|
|
6748
|
+
ast: node.left.name,
|
|
6749
|
+
start: node.left.start,
|
|
6750
|
+
end: node.left.end,
|
|
6751
|
+
});
|
|
6752
|
+
}
|
|
6753
|
+
base.AssignmentExpression(node, st, c);
|
|
6754
|
+
},
|
|
6755
|
+
}, base);
|
|
6756
|
+
recursive(ast, state, visitors);
|
|
6757
|
+
return state.results.reduce((pv, { ast }) => {
|
|
6758
|
+
return `${pv}window.${ast}=${ast};`;
|
|
6759
|
+
}, "");
|
|
6760
|
+
}
|
|
6677
6761
|
|
|
6678
6762
|
const store = new WeakMap();
|
|
6679
6763
|
function setStoreData(window, path) {
|
|
@@ -6704,11 +6788,11 @@ function dealAttributesOCPatch(targetString) {
|
|
|
6704
6788
|
}
|
|
6705
6789
|
});
|
|
6706
6790
|
replaceAttributeEventStr += `${targetString.slice(lastSliceEnd)}`;
|
|
6707
|
-
console.log("====事件函数处理后字符", replaceAttributeEventStr)
|
|
6791
|
+
// console.log("====事件函数处理后字符", replaceAttributeEventStr)
|
|
6708
6792
|
return replaceAttributeEventStr;
|
|
6709
6793
|
}
|
|
6710
6794
|
function dealHTMLOCPatch(targetString) {
|
|
6711
|
-
console.log("====事件函数原字符", targetString)
|
|
6795
|
+
// console.log("====事件函数原字符", targetString)
|
|
6712
6796
|
const targetAttrLists = findIdentifiers(targetString);
|
|
6713
6797
|
let lastSliceEnd = 0;
|
|
6714
6798
|
let replaceHTMLClickEventStr = '';
|
|
@@ -6720,7 +6804,7 @@ function dealHTMLOCPatch(targetString) {
|
|
|
6720
6804
|
}
|
|
6721
6805
|
});
|
|
6722
6806
|
replaceHTMLClickEventStr += `${targetString.slice(lastSliceEnd)}`;
|
|
6723
|
-
console.log("====事件函数处理后字符", replaceHTMLClickEventStr)
|
|
6807
|
+
// console.log("====事件函数处理后字符", replaceHTMLClickEventStr)
|
|
6724
6808
|
const fnBodyStr = replaceHTMLClickEventStr.match(fnBody)?.[1];
|
|
6725
6809
|
return fnBodyStr || '';
|
|
6726
6810
|
}
|
|
@@ -6728,10 +6812,10 @@ function patchElementHook(element, targetWindow) {
|
|
|
6728
6812
|
const targetHaveGetAttribute = typeof element.getAttribute === 'function';
|
|
6729
6813
|
const originHTMLClickEvent = element.onclick;
|
|
6730
6814
|
const originAttributeEventStr = targetHaveGetAttribute ? element.getAttribute('onclick') : '';
|
|
6731
|
-
if (targetHaveGetAttribute && element.getAttribute('data-test-scope')) {
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
}
|
|
6815
|
+
// if (targetHaveGetAttribute && element.getAttribute('data-test-scope')) {
|
|
6816
|
+
// console.log('===HTML事件绑定', originHTMLClickEvent)
|
|
6817
|
+
// console.log('===attribute获取事件', originAttributeEventStr)
|
|
6818
|
+
// }
|
|
6735
6819
|
let result = '';
|
|
6736
6820
|
if (originAttributeEventStr) {
|
|
6737
6821
|
result = dealAttributesOCPatch(originAttributeEventStr);
|
|
@@ -6740,13 +6824,13 @@ function patchElementHook(element, targetWindow) {
|
|
|
6740
6824
|
result = dealHTMLOCPatch(originHTMLClickEvent.toString());
|
|
6741
6825
|
}
|
|
6742
6826
|
if (result) {
|
|
6743
|
-
console.log("====执行字符串", result)
|
|
6827
|
+
// console.log("====执行字符串", result)
|
|
6744
6828
|
const haveRegister = elementDataStore.hasStoreData(targetWindow);
|
|
6745
6829
|
if (!haveRegister) {
|
|
6746
6830
|
// @ts-ignore
|
|
6747
6831
|
const currentWujieName = targetWindow.__WUJIE.id;
|
|
6748
6832
|
const targetWindowPath = `__WUJIE_${targetToLNU(currentWujieName)}`;
|
|
6749
|
-
console.log("===存储路径", targetWindowPath)
|
|
6833
|
+
// console.log("===存储路径", targetWindowPath)
|
|
6750
6834
|
// @ts-ignore
|
|
6751
6835
|
window[targetWindowPath] = targetWindow;
|
|
6752
6836
|
elementDataStore.setStoreData(targetWindow, targetWindowPath);
|
|
@@ -6755,11 +6839,17 @@ function patchElementHook(element, targetWindow) {
|
|
|
6755
6839
|
element.setAttribute('onclick', `(function(window) {
|
|
6756
6840
|
${result}
|
|
6757
6841
|
})(window.${targetWindowPath})`);
|
|
6758
|
-
console.log("===替换之后的结果", element.getAttribute('onclick'))
|
|
6842
|
+
// console.log("===替换之后的结果", element.getAttribute('onclick'))
|
|
6759
6843
|
}
|
|
6760
6844
|
}
|
|
6845
|
+
function patchInlineCodeHook(target, targetWindow) {
|
|
6846
|
+
const result = findDeclarationIdentifiers(target.code);
|
|
6847
|
+
console.log("===处理后的信息", result);
|
|
6848
|
+
target.code = result;
|
|
6849
|
+
}
|
|
6761
6850
|
var index = {
|
|
6762
|
-
patchElementHook
|
|
6851
|
+
patchElementHook,
|
|
6852
|
+
patchInlineCodeHook
|
|
6763
6853
|
};
|
|
6764
6854
|
|
|
6765
6855
|
export { index as default };
|
|
@@ -4,4 +4,13 @@ export interface AstInfo {
|
|
|
4
4
|
end: number;
|
|
5
5
|
}
|
|
6
6
|
export declare function findIdentifiers(code: string): AstInfo[];
|
|
7
|
+
/**
|
|
8
|
+
* 匹配会在全局(如浏览器 window)上产生「命名绑定」的写法(仅**脚本顶层**,不含嵌套函数体内):
|
|
9
|
+
* - 顶层函数声明名(如 `function onclick`)
|
|
10
|
+
* - 顶层 var/let/const(含解构左侧)
|
|
11
|
+
* - 顶层对裸标识符的简单赋值 `id = ...`
|
|
12
|
+
*
|
|
13
|
+
* 不包含:函数体内的声明、成员赋值 `a.b =`、复合赋值等。
|
|
14
|
+
*/
|
|
15
|
+
export declare function findDeclarationIdentifiers(code: string): string;
|
|
7
16
|
//# sourceMappingURL=babelParse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babelParse.d.ts","sourceRoot":"","sources":["../../src/babelParse.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AA0CD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"babelParse.d.ts","sourceRoot":"","sources":["../../src/babelParse.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AA0CD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,aA2C3C;AA4CD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA6D/D"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
interface IpatchInlineCodeHook {
|
|
2
|
+
code: string;
|
|
3
|
+
}
|
|
1
4
|
declare function patchElementHook(element: HTMLElement, targetWindow: Window): void;
|
|
5
|
+
declare function patchInlineCodeHook(target: IpatchInlineCodeHook, targetWindow: Window): void;
|
|
2
6
|
declare const _default: {
|
|
3
7
|
patchElementHook: typeof patchElementHook;
|
|
8
|
+
patchInlineCodeHook: typeof patchInlineCodeHook;
|
|
4
9
|
};
|
|
5
10
|
export default _default;
|
|
6
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAKA,UAAU,oBAAoB;IAC1B,IAAI,EAAE,MAAM,CAAA;CACf;AAoCD,iBAAS,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,QAgCnE;AAED,iBAAS,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,QAI9E;;;;;AAED,wBAGE"}
|
package/package.json
CHANGED
package/src/babelParse.ts
CHANGED
|
@@ -64,40 +64,6 @@ export function findIdentifiers(code: string) {
|
|
|
64
64
|
if (!callee) return;
|
|
65
65
|
|
|
66
66
|
getCallExpression(callee, node.arguments, results)
|
|
67
|
-
// if (callee.type === "Identifier") {
|
|
68
|
-
// results.add({
|
|
69
|
-
// ast: callee.name,
|
|
70
|
-
// start: callee.start,
|
|
71
|
-
// end: callee.end,
|
|
72
|
-
// });
|
|
73
|
-
// if (Array.isArray(node.arguments) && node.arguments.length > 0) {
|
|
74
|
-
// node.arguments.forEach((node: any) => {
|
|
75
|
-
// if (node.type === 'Identifier') {
|
|
76
|
-
// results.add({
|
|
77
|
-
// ast: node.name,
|
|
78
|
-
// start: node.start,
|
|
79
|
-
// end: node.end,
|
|
80
|
-
// });
|
|
81
|
-
// } else if (node.type === 'MemberExpression') {
|
|
82
|
-
// const memberName = getMemberExpressionPath(callee);
|
|
83
|
-
// results.add({
|
|
84
|
-
// ast: memberName,
|
|
85
|
-
// start: node.start,
|
|
86
|
-
// end: node.end,
|
|
87
|
-
// });
|
|
88
|
-
// }
|
|
89
|
-
// })
|
|
90
|
-
// }
|
|
91
|
-
// }
|
|
92
|
-
|
|
93
|
-
// if (callee.type === "MemberExpression") {
|
|
94
|
-
// const memberName = getMemberExpressionPath(callee);
|
|
95
|
-
// results.add({
|
|
96
|
-
// ast: memberName,
|
|
97
|
-
// start: callee.start,
|
|
98
|
-
// end: callee.end,
|
|
99
|
-
// });
|
|
100
|
-
// }
|
|
101
67
|
},
|
|
102
68
|
AssignmentExpression(node: any) {
|
|
103
69
|
const left = node.left;
|
|
@@ -124,4 +90,117 @@ export function findIdentifiers(code: string) {
|
|
|
124
90
|
});
|
|
125
91
|
|
|
126
92
|
return Array.from(results).sort((a, b) => a.start - b.start);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** 从解构等 Pattern 中收集绑定名(仅用于变量声明左侧) */
|
|
96
|
+
function collectPatternBindingIds(id: any, results: AstInfo[]): void {
|
|
97
|
+
if (!id) return;
|
|
98
|
+
// 普通声明:let a、const foo = 1、var bar
|
|
99
|
+
if (id.type === "Identifier") {
|
|
100
|
+
results.push({ ast: id.name, start: id.start, end: id.end });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// 对象解构左侧:const { x, y: z, ...rest } = obj
|
|
104
|
+
if (id.type === "ObjectPattern") {
|
|
105
|
+
for (const prop of id.properties) {
|
|
106
|
+
if (prop.type === "Property") {
|
|
107
|
+
collectPatternBindingIds(prop.value, results);
|
|
108
|
+
} else if (prop.type === "RestElement") {
|
|
109
|
+
collectPatternBindingIds(prop.argument, results);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// 数组解构左侧:const [a, b, , c] = arr
|
|
115
|
+
if (id.type === "ArrayPattern") {
|
|
116
|
+
for (const elt of id.elements) {
|
|
117
|
+
if (elt) collectPatternBindingIds(elt, results);
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// 带默认值的解构项:const { x = 1 } = o 或 const [a = 0] = arr
|
|
122
|
+
if (id.type === "AssignmentPattern") {
|
|
123
|
+
collectPatternBindingIds(id.left, results);
|
|
124
|
+
}
|
|
125
|
+
// 剩余合并项解构赋值:const { ...rest } = o、const [a, ...tail] = arr
|
|
126
|
+
if (id.type === "RestElement") {
|
|
127
|
+
collectPatternBindingIds(id.argument, results);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface DeclarationWalkState {
|
|
132
|
+
/** >0 表示在任意函数/箭头函数体内,其中的 var/赋值不会挂到 window */
|
|
133
|
+
functionDepth: number;
|
|
134
|
+
results: AstInfo[];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 匹配会在全局(如浏览器 window)上产生「命名绑定」的写法(仅**脚本顶层**,不含嵌套函数体内):
|
|
139
|
+
* - 顶层函数声明名(如 `function onclick`)
|
|
140
|
+
* - 顶层 var/let/const(含解构左侧)
|
|
141
|
+
* - 顶层对裸标识符的简单赋值 `id = ...`
|
|
142
|
+
*
|
|
143
|
+
* 不包含:函数体内的声明、成员赋值 `a.b =`、复合赋值等。
|
|
144
|
+
*/
|
|
145
|
+
export function findDeclarationIdentifiers(code: string): string {
|
|
146
|
+
const state: DeclarationWalkState = {
|
|
147
|
+
functionDepth: 0,
|
|
148
|
+
results: [],
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
const ast = acorn.parse(code, {
|
|
152
|
+
ecmaVersion: "latest",
|
|
153
|
+
sourceType: "module",
|
|
154
|
+
ranges: true,
|
|
155
|
+
}) as any;
|
|
156
|
+
|
|
157
|
+
const visitors = walk.make(
|
|
158
|
+
{
|
|
159
|
+
Function(node: any, st: DeclarationWalkState, c) {
|
|
160
|
+
if (
|
|
161
|
+
node.type === "FunctionDeclaration" &&
|
|
162
|
+
node.id &&
|
|
163
|
+
st.functionDepth === 0
|
|
164
|
+
) {
|
|
165
|
+
st.results.push({
|
|
166
|
+
ast: node.id.name,
|
|
167
|
+
start: node.id.start,
|
|
168
|
+
end: node.id.end,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
st.functionDepth++;
|
|
172
|
+
walk.base.Function!(node, st, c);
|
|
173
|
+
st.functionDepth--;
|
|
174
|
+
},
|
|
175
|
+
VariableDeclaration(node: any, st: DeclarationWalkState, c) {
|
|
176
|
+
if (st.functionDepth === 0) {
|
|
177
|
+
for (const decl of node.declarations) {
|
|
178
|
+
collectPatternBindingIds(decl.id, st.results);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
walk.base.VariableDeclaration!(node, st, c);
|
|
182
|
+
},
|
|
183
|
+
AssignmentExpression(node: any, st: DeclarationWalkState, c) {
|
|
184
|
+
if (
|
|
185
|
+
st.functionDepth === 0 &&
|
|
186
|
+
node.operator === "=" &&
|
|
187
|
+
node.left?.type === "Identifier"
|
|
188
|
+
) {
|
|
189
|
+
st.results.push({
|
|
190
|
+
ast: node.left.name,
|
|
191
|
+
start: node.left.start,
|
|
192
|
+
end: node.left.end,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
walk.base.AssignmentExpression!(node, st, c);
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
walk.base,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
walk.recursive(ast, state, visitors);
|
|
202
|
+
|
|
203
|
+
return state.results.reduce((pv, { ast }) => {
|
|
204
|
+
return `${pv}window.${ast}=${ast};`;
|
|
205
|
+
}, "");
|
|
127
206
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { fnBody } from "./regx"
|
|
2
2
|
import { targetToLNU } from "./utils"
|
|
3
|
-
import { findIdentifiers } from "./babelParse"
|
|
3
|
+
import { findIdentifiers, findDeclarationIdentifiers } from "./babelParse"
|
|
4
4
|
import elementDataStore from "./elementDataStore"
|
|
5
5
|
|
|
6
|
+
interface IpatchInlineCodeHook {
|
|
7
|
+
code: string
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
function dealAttributesOCPatch(targetString: string) {
|
|
7
11
|
const targetAttrLists = findIdentifiers(targetString);
|
|
8
12
|
let lastSliceEnd = 0;
|
|
@@ -15,12 +19,12 @@ function dealAttributesOCPatch(targetString: string) {
|
|
|
15
19
|
}
|
|
16
20
|
})
|
|
17
21
|
replaceAttributeEventStr += `${targetString.slice(lastSliceEnd)}`
|
|
18
|
-
console.log("====事件函数处理后字符", replaceAttributeEventStr)
|
|
22
|
+
// console.log("====事件函数处理后字符", replaceAttributeEventStr)
|
|
19
23
|
return replaceAttributeEventStr
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
function dealHTMLOCPatch(targetString: string) {
|
|
23
|
-
console.log("====事件函数原字符", targetString)
|
|
27
|
+
// console.log("====事件函数原字符", targetString)
|
|
24
28
|
const targetAttrLists = findIdentifiers(targetString);
|
|
25
29
|
let lastSliceEnd = 0;
|
|
26
30
|
let replaceHTMLClickEventStr: string = '';
|
|
@@ -32,7 +36,7 @@ function dealHTMLOCPatch(targetString: string) {
|
|
|
32
36
|
}
|
|
33
37
|
})
|
|
34
38
|
replaceHTMLClickEventStr += `${targetString.slice(lastSliceEnd)}`
|
|
35
|
-
console.log("====事件函数处理后字符", replaceHTMLClickEventStr)
|
|
39
|
+
// console.log("====事件函数处理后字符", replaceHTMLClickEventStr)
|
|
36
40
|
const fnBodyStr = replaceHTMLClickEventStr.match(fnBody)?.[1];
|
|
37
41
|
return fnBodyStr || ''
|
|
38
42
|
}
|
|
@@ -41,10 +45,10 @@ function patchElementHook(element: HTMLElement, targetWindow: Window) {
|
|
|
41
45
|
const targetHaveGetAttribute = typeof element.getAttribute === 'function'
|
|
42
46
|
const originHTMLClickEvent = element.onclick;
|
|
43
47
|
const originAttributeEventStr = targetHaveGetAttribute ? element.getAttribute('onclick') : ''
|
|
44
|
-
if (targetHaveGetAttribute && element.getAttribute('data-test-scope')) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
+
// if (targetHaveGetAttribute && element.getAttribute('data-test-scope')) {
|
|
49
|
+
// console.log('===HTML事件绑定', originHTMLClickEvent)
|
|
50
|
+
// console.log('===attribute获取事件', originAttributeEventStr)
|
|
51
|
+
// }
|
|
48
52
|
let result = '';
|
|
49
53
|
if (originAttributeEventStr) {
|
|
50
54
|
result = dealAttributesOCPatch(originAttributeEventStr)
|
|
@@ -52,13 +56,13 @@ function patchElementHook(element: HTMLElement, targetWindow: Window) {
|
|
|
52
56
|
result = dealHTMLOCPatch(originHTMLClickEvent.toString())
|
|
53
57
|
}
|
|
54
58
|
if (result) {
|
|
55
|
-
console.log("====执行字符串", result)
|
|
59
|
+
// console.log("====执行字符串", result)
|
|
56
60
|
const haveRegister = elementDataStore.hasStoreData(targetWindow)
|
|
57
61
|
if(!haveRegister) {
|
|
58
62
|
// @ts-ignore
|
|
59
63
|
const currentWujieName = targetWindow.__WUJIE.id
|
|
60
64
|
const targetWindowPath = `__WUJIE_${targetToLNU(currentWujieName)}`
|
|
61
|
-
console.log("===存储路径", targetWindowPath)
|
|
65
|
+
// console.log("===存储路径", targetWindowPath)
|
|
62
66
|
// @ts-ignore
|
|
63
67
|
window[targetWindowPath] = targetWindow
|
|
64
68
|
elementDataStore.setStoreData(targetWindow, targetWindowPath)
|
|
@@ -67,10 +71,17 @@ function patchElementHook(element: HTMLElement, targetWindow: Window) {
|
|
|
67
71
|
element.setAttribute('onclick', `(function(window) {
|
|
68
72
|
${result}
|
|
69
73
|
})(window.${targetWindowPath})`)
|
|
70
|
-
console.log("===替换之后的结果", element.getAttribute('onclick'))
|
|
74
|
+
// console.log("===替换之后的结果", element.getAttribute('onclick'))
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
|
|
78
|
+
function patchInlineCodeHook(target: IpatchInlineCodeHook, targetWindow: Window) {
|
|
79
|
+
const result = findDeclarationIdentifiers(target.code)
|
|
80
|
+
console.log("===处理后的信息", result)
|
|
81
|
+
target.code = result
|
|
82
|
+
}
|
|
83
|
+
|
|
74
84
|
export default {
|
|
75
|
-
patchElementHook
|
|
85
|
+
patchElementHook,
|
|
86
|
+
patchInlineCodeHook
|
|
76
87
|
};
|