Appearance
Dev Tools Improvements
Branch: improve-dev-tools (Application-Frontend + Creative-Engine) Issue: #1836 | AF PR: #1858 | CE PR: #733
Completed
DataTracker Rewrite
Replaced flat last-mutation display with a recursive collapsible tree view.
New files:
src/components/DevTools/DataTracker.vue— main panelsrc/components/DevTools/TreeNode.vue— recursive tree component
Features:
- Recursive collapsible tree showing all block properties
- Auto-expand and blue highlight on Vuex
updateBlockValuemutations - Sticky parent headers (VS Code-style scroll context) with correct stacking
- Sticky block-header bar showing block name, type badge, and expand/collapse toggle
- Click-to-select with orange highlight and scroll-into-view
- Color swatches for hex/rgba string values
- Expand all / Collapse all toggle button
- Deep-clone block data (
JSON.parse(JSON.stringify())) to strip Vue 2 reactivity wrappers blockKeycounter forces fresh TreeNodes on block switch (no stale expanded state)- i18n keys under
devToolssection inen.js
Key technical decisions:
- TreeNode must be a
.vueSFC file — Vue 2 runtime-only build (used by Vite) cannot compile inlinetemplatestrings - Block data deep-cloned because Vue 2 reactive objects don't always iterate correctly with
v-for changedPathwatcher usesimmediate: trueso newly rendered children (after parent expands) also auto-expand for deeply nested changes- Validation auto-expand:
FormConfigurationMixinemits entirevalidationobject at path'validation'(not'validation.required'), so TreeNode expands on both exact match and prefix match - Mutation path uses
indexOfinstead ofstartsWithto handle sub-blocks (e.g.formProperties.formSubmitButtonProperties.stateConfig.hover.x) - Sticky offset: block-header height (40px) + depth * 22px per level
DevToolPanel — Shared Wrapper
All three dev tool panels (DataTracker, JSON Viewer, JSON Provider) now use a shared DevToolPanel.vue wrapper component.
File: src/components/DevTools/DevToolPanel.vue
Features:
- Drag via panel header
- Resize from 8 handles (4 edges + 4 corners) with minimum size constraints (300×200)
- Pop-out to separate browser window (experimental — styles/reactivity incomplete)
- Fullscreen toggle (via scoped slot — children can provide custom button)
- Close button
scrollToTop()method exposed via refleft/topCSS positioning for natural drag/resize behavior
Scoped slot: header-actions provides { isFullscreen, toggleFullscreen } to children, so each tool can inject custom buttons (type toggle, validation badges, fullscreen) alongside the shared pop-out and close buttons.
JSON Tools Migration to DevToolPanel
Refactored CreativeJSONViewerV2.vue and CreativeJSONProviderV2.vue to use the shared DevToolPanel wrapper.
Changes:
- Removed all custom drag, resize, and positioning code from both components
- Removed fullscreen logic (now handled by DevToolPanel)
- Moved tool-specific buttons (type toggle, fullscreen, validation badges) to
header-actionsscoped slot - Content (search bar, JSON display/textarea, footer) rendered as default slot with flex layout
- Consistent dark aesthetic across all three dev tools
- Updated
JSONSearchBar.vuecolors to match DevToolPanel theme - Added i18n keys for all user-visible strings in JSON tools
Removed code per component: ~250 lines of drag/resize/position/fullscreen logic + CSS
V2 JSON Components
CreativeJSONProviderV2.vue— JSON input with validation, bracket auto-close, searchCreativeJSONViewerV2.vue— JSON display with syntax highlighting, search, type toggle (Plain/Composed), copy, double-click editJSONSearchBar.vue— reusable search component with match navigation
Analytics Monitor (new)
Real-time panel showing all analytics events from Creative-Engine via postMessage bridge.
File: src/components/DevTools/AnalyticsMonitor.vue
Features:
- Event feed with type badges (event / flow / count / metric / init / click)
- Live counters: elapsed, in view (from CE), actions, bg clicks, flow seq, events
- Milestone bar: loaded, viewable, 1st click, links, goal, end
- Click debug capture showing element selector, shortcode, innerText, and full CE handler chain
- Sub-type filter dropdown
- Glossary descriptions for headerClick and backgroundClick count metrics
- Baseline reset on creative rebuild so counters don't show negatives
- Accurate secondsToActive on preview refresh (CE resets loadTimestamp in devMode)
- Expandable event details with raw payload
- Refresh button that reloads creative and starts clean recording
CE integration (Creative-Engine PR #733)
- Analytics event bridge — forwards all analytics events to parent via postMessage in devMode
- Flow event enrichment with component name/text
- Click debug capture with full handler chain analysis and innerText fallback
- Live visibility postMessage (
cavai-devtools-visibility) with generation counter for accurate viewable tracking across rebuilds - Reset
loadTimestampandcreativeClickedOnceon rebuild in devMode for accurate metrics
Tool switching
- Dropdown in panel title to switch between all dev tools
- Position, size, and fullscreen state persist across switches
- Pop-out reuses existing popup when switching tools
- Click-outside closes the dropdown
DevTools.vue
- Updated to use V2 components, DataTracker, and Analytics Monitor
- Rounded corner styling
- Tool switching dropdown
Planned
Extract CE devtools code into its own module (from PR #733 review)
McSneaky flagged that the analytics bridge, click debug capture, and visibility tracking code in Creative.vue is a lot of inline code. Should be extracted to a separate module.
Goal: Move all devtools-related logic out of Creative.vue into a dedicated module (e.g. src/utils/devtools.ts or src/composables/useDevtools.ts).
Bonus: Dynamic import so the code is only loaded when devMode is active — keeps the production bundle clean. Could use import() to lazy-load the module when devMode is detected:
js
if (this.devMode) {
const { setupDevtools } = await import('./devtools')
setupDevtools(this)
}Scope:
- Click debug capture (click handler → structured debug info → postMessage)
- Analytics event bridge (all analytics events → postMessage with enrichment)
- Live visibility tracking (secondsInView / viewable state → postMessage with generation counter)
Operator/flow data inspection
- Extend DataTracker to inspect operator data, not just blocks
- Need to investigate how operators are stored in Vuex (getters, selection state)
- Would make DataTracker useful for debugging flow logic, not just visual block properties
Pop-out improvements
- Current approach re-mounts a new Vue instance in the popup — styles and reactivity break
- Better approach: DOM adoption (
appendChildto move real DOM node into popup window), preserving Vue reactivity and scoped styles - Would allow fullscreen dev tools on a second monitor
Performance profiling tool
- Show render times for blocks, reflow counts
- Monitor postMessage frequency between AF and CE
- Help identify performance bottlenecks in complex creatives
Console/log panel (started - see DOM Inspector below)
In Progress
DOM Inspector + Console (branch: dom-inspector)
Branch: dom-inspector (AF + CE)
Built-in iframe DOM inspector solving the browser DevTools focus-loss problem on iframe refresh. Three tabs:
Elements tab:
- Recursive DOM tree with Chrome DevTools-style attribute display (id, class, src, href, type)
- Click-to-inspect with pointer-blocking overlay (prevents creative interaction during inspect)
- Auto-expand ancestors and scroll-into-view on selection
- Layout badges: FLEX, GRID, ABS, FIXED, REL, STICKY, CLIP
- Shortcode badges mapping DOM classes to Cavai block names (t1 -> textProperties-1)
- Breadcrumb ancestor chain (clickable, hover-to-highlight)
- Element info: size, position, position context ("relative to ..."), flex/grid child info, stacking context detection
- MutationObserver auto-refresh (filters inspector overlay mutations to prevent tree collapse)
Console tab:
- Captured console.log/warn/error from CE via postMessage (consoleInterceptor.ts)
- Eval expressions in iframe scope
- Command history (up to 50), color-coded output, max 500 entries with auto-scroll
Styles tab:
- Box model diagram (margin/border/padding/content)
- Context insights: position info with offsets, z-index + stacking context, overflow clipping
- Flex/Grid parent context (direction, justify, align, self flex/order)
- Computed style groups filtered by non-default values
CE side: src/devtools/consoleInterceptor.ts - monkey-patches window.console in devMode, safe serialization (circular refs, DOM nodes, max depth 5)
Status: Functional, needs more testing and polish. Known areas to improve:
- Indent guide lines in tree (attempted, reverted due to recursive component CSS complexity)
- Pop-out support not yet tested with this tool
Ideas to explore
Search/filter in Elements tree
- Filter DOM tree by tag, class, attribute, or text content
- Use case: find all
<img>elements in the creative, or track a specific video element's class changes live as it transitions between states - Live filtering: tree updates in real-time as the creative DOM mutates, so you can watch attributes/classes change on filtered elements without manually navigating
Flow stepping from DOM Inspector
- Step forward/backward through flow steps directly from the inspector panel
- Navigate the creative's flow without clicking inside the iframe -- control flow progression purely from dev tools
- Watch the DOM tree update live as each step renders, see which elements appear/disappear/change
- Would need to send flow navigation commands to CE (postMessage or direct iframe access)
- Combines well with search/filter: filter to a specific element, then step through flow and watch it change
These need investigation -- not sure how CE exposes flow navigation, or whether we can trigger step transitions from AF side.