fix(bricks): on_parent 等事件 params 为 widget 对象时不再撞循环 JSON
- buildEventHandler: event.params 经 bricks.event_params_data 过滤,widget/DOM/Event 不当数据用 - apply_data: 改用 bricks.safe_json_stringify,循环引用时降级序列化而不抛异常 - bump bricks.js 缓存版本 20260825a
This commit is contained in:
parent
91b3212f31
commit
7e0d5a1701
@ -128,11 +128,64 @@ bricks.str2data = function(s, d){
|
|||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* event.params 不一定是数据字典:add_widget 派发的 'on_parent' 事件把父 widget
|
||||||
|
* 对象作为 params 传入,widget 与 dom_element 互相引用
|
||||||
|
* (dom_element.bricks_widget -> widget.dom_element),直接 extend 进 handler 的
|
||||||
|
* params 会让 apply_data 里的 JSON.stringify 抛
|
||||||
|
* "Converting circular structure to JSON"。
|
||||||
|
* 这里只把「可当数据用」的 params 交给 handler;widget/DOM/Event 这类对象丢弃,
|
||||||
|
* script/method handler 仍可通过第二个参数 event(event.params) 拿到原始对象。
|
||||||
|
*/
|
||||||
|
bricks.event_params_data = function(p){
|
||||||
|
if (p === null || p === undefined){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (typeof FormData !== 'undefined' && p instanceof FormData){
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
if (p instanceof bricks.JsWidget){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (typeof Node !== 'undefined' && p instanceof Node){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (typeof Event !== 'undefined' && p instanceof Event){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* JSON.stringify 的安全版本:撞上循环引用时退化为跳过 widget/DOM/已见对象的序列化,
|
||||||
|
* 保证 apply_data 不会因为 params 里夹带 widget 对象而整个 handler 抛异常。
|
||||||
|
*/
|
||||||
|
bricks.safe_json_stringify = function(obj){
|
||||||
|
try {
|
||||||
|
return JSON.stringify(obj);
|
||||||
|
} catch (e) {
|
||||||
|
var seen = new WeakSet();
|
||||||
|
return JSON.stringify(obj, function(k, v){
|
||||||
|
if (v instanceof bricks.JsWidget){
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (typeof Node !== 'undefined' && v instanceof Node){
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (v && typeof v === 'object'){
|
||||||
|
if (seen.has(v)){
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
seen.add(v);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
bricks.apply_data = function(desc, data){
|
bricks.apply_data = function(desc, data){
|
||||||
if (bricks.is_empty(data)){
|
if (bricks.is_empty(data)){
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
var tmpl = JSON.stringify(desc);
|
var tmpl = bricks.safe_json_stringify(desc);
|
||||||
var s = bricks.obj_fmtstr(data, tmpl);
|
var s = bricks.obj_fmtstr(data, tmpl);
|
||||||
return JSON.parse(s);
|
return JSON.parse(s);
|
||||||
}
|
}
|
||||||
@ -265,7 +318,7 @@ bricks.buildEventHandler = async function(w, desc, event){
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
var rtdata = {};
|
var rtdata = {};
|
||||||
desc.event_params = event.params || {} ;
|
desc.event_params = bricks.event_params_data(event.params);
|
||||||
desc.event = event;
|
desc.event = event;
|
||||||
if (desc.rtdata) rtdata = desc.rtdata;
|
if (desc.rtdata) rtdata = desc.rtdata;
|
||||||
else if (desc.datawidget){
|
else if (desc.datawidget){
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
<script type="module"
|
<script type="module"
|
||||||
src="{{entire_url('/bricks/3parties/model-viewer.min.js')}}">
|
src="{{entire_url('/bricks/3parties/model-viewer.min.js')}}">
|
||||||
</script>
|
</script>
|
||||||
<script src="{{entire_url('/bricks/bricks.js')}}?v=20260820b"></script>
|
<script src="{{entire_url('/bricks/bricks.js')}}?v=20260825a"></script>
|
||||||
{% for myjs in jsfiles() %}
|
{% for myjs in jsfiles() %}
|
||||||
<script src="{{entire_url(myjs)}}"></script>
|
<script src="{{entire_url(myjs)}}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user