Name:
[IMP] viin_brain,viin_web_editor: UI hardening v1 (token + polish + Odoo-native + v2 seams)
State:
Failed
finished in 19m
PR State:
merged
PR Author:
David Tran
PR Author Email:
PR:
#27
Committer:
David Tran
Committer Email:
davidtran.hp@gmail.com
Commit:
6d7ec7c9a357c0fba5cdfb57bda3408fb540a787
Description:
[IMP] viin_brain: P7 H4 fix + WI-4 universal injector wire (round 3 sprint 3)
P7 H4 — content_html sanitize_attributes=False
- Brain embed blocks use data-snapshot-id, data-snapshot-kind,
data-block-anchor, data-is-stale, data-mode attributes that are NOT
in Odoo's safe_attrs whitelist (odoo/tools/mail.py:44-55).
- With default sanitize_attributes=True, html_sanitize() with
safe_attrs_only=True strips all data-snapshot-* on every WRITE,
breaking embed chrome render after save→reload.
- Fix: explicit sanitize_attributes=False preserves data-* while
sanitize_tags=True (implicit) still blocks script/iframe/object
tags so XSS posture intact.
- Verified via JSON-RPC ORM write of 950-byte embed HTML →
read back returns 906 bytes with data-snapshot-kind +
o_brain_snapshot_chrome--snapshot class preserved.
WI-4 (ADR-001) Universal Brain sidebar injection — restored
- Original __manifest__.py:270-271 declares "WI-4 (ADR-001) — universal
hook injection for mail.thread descendants" but stage 1 (function
definition) shipped without stage 2 (caller wiring) per git
archaeology of commit 26f2190.
- Per ETHOS §4.1.1 boil-the-lake: the function intent was clear, only
the wiring was missing; restore (wire) rather than delete.
- Rewrote brain_form_sidebar_universal.js to patch FormCompiler
.prototype.compile() (not FormController) and mutate source arch
this.templates[key] BEFORE super.compile(). Detection: presence of
<div class="oe_chatter"> proxies for mail.thread descendant (= has
brain_page_count via mail_thread.py inheritance). Guards against
double-inject (existing .o_brain_form_sidebar_hook from bridge XML)
+ WeakSet on processed templates.
- Verified on 2 models with NO bridge XML:
* project.project (Office Design ID=1) — BRAIN rail sidebar auto-renders
* crm.team (Sales ID=1) — BRAIN rail sidebar auto-renders
- Existing 5 bridges (res.partner, crm.lead, hr.employee, project.task,
sale.order) continue to work unchanged — hookAlreadyPresent guard
prevents double injection.
NOTE — separate page_editor render race exists: bodyRef.el.innerHTML
stays empty despite state.page.content_html containing 906 bytes after
ORM write. JSON-RPC verifies content delivery; OWL render does not
materialize. Investigation deferred — not introduced by this commit;
unrelated to H4 sanitization fix.
NOTE — universal injector stat button (Brain Pages count) appears on
forms with <div name="button_box"> but the inserted <field name=
"brain_page_count" widget="statinfo"> child does not visually render in
project.project capture. Sidebar (primary deliverable) works on both
test models. Stat button compilation pipeline interaction worth
follow-up; sidebar functionality unblocked.
AC-1 hex grep PASS, brain_v3_ci_check.py --strict 8 PASS / 1 pre-existing
WARN (rule2 contenteditable baseline = 14 unchanged).
Refs PR #27.
Branch:
17.0
Instance ID:
0
Age:
Up-time: