From 7e0d5a17011751b7244af6176b081f8f3361a759 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 25 Aug 2026 13:56:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(bricks):=20on=5Fparent=20=E7=AD=89=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=20params=20=E4=B8=BA=20widget=20=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E6=97=B6=E4=B8=8D=E5=86=8D=E6=92=9E=E5=BE=AA=E7=8E=AF=20JSON?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - buildEventHandler: event.params 经 bricks.event_params_data 过滤,widget/DOM/Event 不当数据用 - apply_data: 改用 bricks.safe_json_stringify,循环引用时降级序列化而不抛异常 - bump bricks.js 缓存版本 20260825a --- bricks/bricks.js | 57 ++++++++++++++++++++++++++++++++++++++++++++-- bricks/header.tmpl | 2 +- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/bricks/bricks.js b/bricks/bricks.js index 9d04c7f..5ab7fcd 100644 --- a/bricks/bricks.js +++ b/bricks/bricks.js @@ -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 交给 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){ 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){ diff --git a/bricks/header.tmpl b/bricks/header.tmpl index 9699cf6..d11233a 100644 --- a/bricks/header.tmpl +++ b/bricks/header.tmpl @@ -37,7 +37,7 @@ - + {% for myjs in jsfiles() %} {% endfor %}