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:
yumoqing 2026-08-25 13:56:20 +08:00
parent 91b3212f31
commit 7e0d5a1701
2 changed files with 56 additions and 3 deletions

View File

@ -128,11 +128,64 @@ bricks.str2data = function(s, d){
}
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 交给 handlerwidget/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){
if (bricks.is_empty(data)){
return desc;
}
var tmpl = JSON.stringify(desc);
var tmpl = bricks.safe_json_stringify(desc);
var s = bricks.obj_fmtstr(data, tmpl);
return JSON.parse(s);
}
@ -265,7 +318,7 @@ bricks.buildEventHandler = async function(w, desc, event){
return null
}
var rtdata = {};
desc.event_params = event.params || {} ;
desc.event_params = bricks.event_params_data(event.params);
desc.event = event;
if (desc.rtdata) rtdata = desc.rtdata;
else if (desc.datawidget){

View File

@ -37,7 +37,7 @@
<script type="module"
src="{{entire_url('/bricks/3parties/model-viewer.min.js')}}">
</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() %}
<script src="{{entire_url(myjs)}}"></script>
{% endfor %}