# Demo Scripts Documentation

Visual assistance demo scripts for DOM manipulation previews. Each script implements a specific type of UI enhancement with preview and undo capabilities.

## Architecture

### Core Pattern
All scripts follow this structure:
```javascript
window.VADemo[ScriptName] = (example, elementMap) => {
  // 1. Initialize tracking
  const overlays = new Set();
  const modifiedElements = new Set();

  // 2. Apply modifications
  // ...

  // 3. Return undo function
  return {
    undo: () => {
      // Clean up all changes
    }
  };
};
```

### Defensive Programming
All scripts use **fallback patterns** for backward compatibility:
```javascript
const useNewFeature = config.newProperty !== undefined;
if (useNewFeature) {
  // New behavior
} else {
  // Original behavior (fallback)
}
```

---

## Scripts Overview

### 1. demoInsertOverlayTip.js
**Purpose**: Display tooltip overlays on elements
**Type**: Insert

**Configuration**:
- `position`: 'top' | 'bottom' | 'left' | 'right' (default: 'top')
- `sequential`: boolean - if true, delegates to sequential script

**Payload**:
- `message`: string - tooltip text

**Behavior**:
- Shows all tooltips simultaneously
- Each tooltip has an 'X' close button
- Elements get blue outline + shine animation
- Ignores `payload.sequence` (non-sequential mode)

**Delegation**:
```javascript
if (config.sequential === true) {
  return window.VADemoInsertOverlayTipSequential(example, elementMap);
}
```

---

### 2. demoInsertOverlayTipSequential.js ⭐ NEW
**Purpose**: Display tooltips group-by-group with progression
**Type**: Insert (Sequential Mode)

**Configuration**:
- `position`: 'top' | 'bottom' | 'left' | 'right' (default: 'top')
- `sequential`: true (required for activation)

**Payload**:
- `message`: string - tooltip text
- `sequence`: number - sequence group number (default: 1)

**Features**:
- **Gold color scheme**: `rgba(251, 191, 36, ...)`
- **Transparent tooltips**: 15% opacity with backdrop blur
- **Tiny buttons**: 9px font, 1px×4px padding
- **Group display**: Shows only current sequence group
- **Next button**: Only on FIRST tooltip of each group
- **Auto-progression**: Fades out current, fades in next

**Visual Style**:
```css
background: rgba(251, 191, 36, 0.15);
backdrop-filter: blur(8px);
color: #92400e;
border: 1px solid rgba(251, 191, 36, 0.5);
```

**Button**:
```css
font-size: 9px;
padding: 1px 4px;
background: rgba(251, 191, 36, 0.9);
```

---

### 3. demoMutateReframe.js
**Purpose**: Change text content with crossfade animation
**Type**: Mutate

**Payload**:
- `newText`: string - replacement text

**Features**:
- **Crossfade animation**: 800ms fade old → new
- **Shine effect**: 2 seconds AFTER text changes
- **No border**: Removed old outline style
- **Purple shine**: Matches reframe theme

**Animation Timeline**:
```
0ms:    Create overlay with old + new text layers
50ms:   Start fade (old: 1→0, new: 0→1)
850ms:  Animation complete
900ms:  Update element.textContent, remove overlay
900ms:  Apply 2s purple shine effect
2900ms: Shine complete
```

---

### 4. demoMutateRepresentation.js
**Purpose**: Transform dropdown to button group
**Type**: Mutate

**Configuration**:
- `from`: 'dropdown'
- `to`: 'button-group'
- `spacing`: number (default: 8)

**Features**:
- **Compact buttons**: 4px×8px padding (was 6px×12px)
- **Smaller font**: 12px (was 13px)
- **Tight spacing**: `white-space: nowrap`, `line-height: 1.2`

**Button Style**:
```css
padding: 4px 8px;
font-size: 12px;
white-space: nowrap;
line-height: 1.2;
```

---

### 5. demoRecomposeGroup.js
**Purpose**: Group elements into colored panels
**Type**: Recompose

**Configuration**:
- `layout`: 'row' | 'column' | 'wrap' | 'grid' (default: 'wrap')
- `gap`: number (default: 8)
- `padding`: number (default: 8)
- `minItemWidth`: number (default: 150)

**Payload**:
- `group`: string - group name (default: 'default')

**Features**:
- **Multi-group support**: Creates separate wrapper per group
- **Color palette**: 6 colors (orange, green, blue, purple, red, cyan)
- **Group titles**: Badge with group name
- **Backward compatible**: Single 'default' group if no `payload.group`

**Defensive Logic**:
```javascript
const groupName = target.payload?.group || 'default';
const hasMultipleGroups = groupsMap.size > 1;
console.log(`[RecomposeGroup] Found ${groupsMap.size} group(s)`);
```

**Colors**:
```javascript
['#f59e0b', '#10b981', '#3b82f6', '#8b5cf6', '#ef4444', '#06b6d4']
```

---

### 6. demoRecomposeReorder.js
**Purpose**: Reorder elements by custom order or policy
**Type**: Recompose

**Configuration**:
- `customOrder`: number[] - explicit order by index
- `policy`: 'frequency' | 'custom' (default: 'custom')
- `layout`: 'row' | 'column' | 'wrap' (default: 'column')
- `direction`: 'top' | 'bottom' (default: 'top')

**Delegation**:
```javascript
if (config.policy === 'frequency') {
  return window.VADemoRecomposeReorderFrequency(example, elementMap);
}
```

**Features**:
- Staggered fade-in animation (100ms per element)
- Green wrapper with outline highlights
- Falls back to reverse order if no customOrder

---

### 7. demoRecomposeReorderFrequency.js ⭐ NEW
**Purpose**: Reorder elements by click/drag frequency
**Type**: Recompose (Frequency Policy)

**Configuration**:
- `policy`: 'frequency' (required for activation)

**Features**:
- **Click tracking**: Counts clicks on each element
- **Drag tracking**: Also counts dragstart events
- **Frequency badges**: Show click count (0-9+)
- **Dynamic backgrounds**: Deeper green for higher frequency
- **Real-time reordering**: Most-clicked elements move to top
- **Compact padding**: 8px (was 12px)

**Background Color Formula**:
```javascript
const opacity = Math.min(0.5, count * 0.05);
backgroundColor = `rgba(16, 185, 129, ${opacity})`;

// Examples:
// 1 click:  rgba(16, 185, 129, 0.05)  - very light
// 5 clicks: rgba(16, 185, 129, 0.25)  - medium
// 10 clicks: rgba(16, 185, 129, 0.5)  - deep (max)
```

**Event Handlers**:
```javascript
element.addEventListener('click', incrementCount);
element.addEventListener('dragstart', incrementCount);
```

**Enhanced Cleanup** (4-step process):
1. Remove badges first (before cloning)
2. Clone elements to remove listeners, restore styles
3. Restore original DOM positions
4. Clear all tracking maps

**Cleanup Steps**:
```javascript
// Step 1: Remove badges
badges.forEach(badge => badge.remove());

// Step 2: Clone with style restoration
const clone = element.cloneNode(true);
clone.style.backgroundColor = originalBg;
clone.style.position = originalPos;
element.parentNode?.replaceChild(clone, element);

// Step 3: Move to original position
original.parent.insertBefore(clone, original.nextSibling);

// Step 4: Clear maps
originalBackgrounds.clear();
clickCounts.clear();
originalPositions.clear();
```

---

## Common Patterns

### 1. Tracking Sets/Maps
```javascript
const overlays = new Set();        // DOM nodes to remove
const modifiedElements = new Set(); // Elements to restore
const originalPositions = new Map(); // element -> {parent, nextSibling}
const timeouts = new Set();         // setTimeout IDs to clear
```

### 2. Storing Original Styles
```javascript
element.dataset.demoOriginalOutline = element.style.outline || '';
element.dataset.demoOriginalBackground = element.style.backgroundColor || '';
```

### 3. Restoring Elements
```javascript
if (element.dataset.demoOriginalOutline !== undefined) {
  if (element.dataset.demoOriginalOutline === '') {
    element.style.removeProperty('outline');
  } else {
    element.style.outline = element.dataset.demoOriginalOutline;
  }
  delete element.dataset.demoOriginalOutline;
}
```

### 4. Restoring DOM Position
```javascript
const original = originalPositions.get(element);
if (original?.parent) {
  if (original.nextSibling?.parentNode) {
    original.parent.insertBefore(element, original.nextSibling);
  } else {
    original.parent.appendChild(element);
  }
}
```

### 5. Removing Event Listeners (Clone Technique)
```javascript
const clone = element.cloneNode(true);
element.parentNode?.replaceChild(clone, element);
delete clone.dataset.demoEventHandler;
```

---

## Animation Patterns

### Fade In
```javascript
element.style.opacity = '0';
element.style.transition = 'opacity 0.3s ease-in';
setTimeout(() => {
  element.style.opacity = '1';
}, 50);
```

### Staggered Animation
```javascript
elements.forEach((element, idx) => {
  setTimeout(() => {
    element.style.opacity = '1';
    element.style.transform = 'translateY(0)';
  }, idx * 100); // 100ms delay per element
});
```

### Crossfade
```javascript
// Two layers: old (opacity: 1) and new (opacity: 0)
setTimeout(() => {
  oldLayer.style.opacity = '0';
  newLayer.style.opacity = '1';
}, 50);
```

### Shine Effect
```javascript
@keyframes demo-shine {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.7),
                0 0 0 4px rgba(251, 191, 36, 0.4),
                0 0 0 8px rgba(251, 191, 36, 0.2);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(251, 191, 36, 0.9),
                0 0 0 8px rgba(251, 191, 36, 0.6),
                0 0 0 12px rgba(251, 191, 36, 0.3);
  }
}
```

---

## Color Schemes

### Blue (Original Overlay)
- Primary: `rgba(59, 130, 246, ...)`
- Outline: `#3b82f6`
- Use: Standard tooltips

### Gold (Sequential Overlay)
- Primary: `rgba(251, 191, 36, ...)`
- Dark text: `#92400e`
- Darker text: `#78350f`
- Use: Sequential tooltips, premium feel

### Green (Reorder/Frequency)
- Primary: `rgba(16, 185, 129, ...)`
- Solid: `#10b981`
- Use: Reordering, frequency tracking

### Purple (Reframe)
- Primary: `rgba(139, 92, 246, ...)`
- Solid: `#8b5cf6`
- Use: Text reframing

### Orange (Group)
- Primary: `#f59e0b`
- Use: First group color

---

## Script Injection Order

In `background/index.ts`:
```javascript
files: [
  'demo/demoInsertOverlayTip.js',
  'demo/demoInsertOverlayTipSequential.js',  // Must be after base
  'demo/demoInsertWidget.js',
  'demo/demoInsertInlineControl.js',
  'demo/demoMutateHighlight.js',
  'demo/demoMutateReframe.js',
  'demo/demoMutateVisibility.js',
  'demo/demoMutateRepresentation.js',
  'demo/demoRecomposeReorder.js',
  'demo/demoRecomposeReorderFrequency.js',   // Must be after base
  'demo/demoRecomposeGroup.js',
  'demo/demoRecomposeLayout.js',
  'demo/demoPreview.js',                     // Must be last
]
```

**Important**: Delegated scripts (Sequential, Frequency) must load AFTER their base scripts.

---

## Testing Checklist

### Per Script
- [ ] Preview displays correctly
- [ ] Undo removes all changes
- [ ] No console errors
- [ ] No lingering DOM nodes
- [ ] No memory leaks (clear all maps)
- [ ] Styles restored properly
- [ ] Event listeners removed

### Integration
- [ ] Multiple previews in sequence
- [ ] Rapid preview→undo→preview cycles
- [ ] Concurrent previews on different elements
- [ ] Script delegation works correctly

### Backward Compatibility
- [ ] Old examples (no new properties) work
- [ ] Falls back to original behavior
- [ ] Console logs show correct mode

---

## Debug Logging

All scripts log their mode:
```javascript
console.log('[InsertOverlayTip] Sequential mode: false');
console.log('[RecomposeGroup] Found 1 group(s)');  // Backward compatible
console.log('[RecomposeGroup] Found 3 group(s)');  // Multi-group
console.log('[RecomposeReorder] Frequency policy detected');
```

Use these logs to verify:
1. Script is loaded
2. Correct mode is activated
3. Delegation happens as expected
4. Cleanup completes successfully

---

## Common Issues & Solutions

### Issue: Element Not Found
**Symptom**: `No element found for index: X`
**Solution**: Check elementMap is populated correctly

### Issue: Undo Doesn't Restore
**Symptom**: Styles remain after undo
**Solution**: Ensure original values are stored BEFORE modification

### Issue: Event Listeners Remain
**Symptom**: Clicks still trigger after undo
**Solution**: Use clone technique to remove listeners

### Issue: DOM Position Wrong
**Symptom**: Elements in wrong order after undo
**Solution**: Store nextSibling, not the element itself

### Issue: Memory Leak
**Symptom**: Maps/sets keep growing
**Solution**: Clear all tracking structures in undo

---

## Future Enhancements

### Potential Features
- [ ] Configurable animation durations
- [ ] Custom color schemes per script
- [ ] Accessibility improvements (ARIA labels)
- [ ] Keyboard navigation for sequential tooltips
- [ ] Pause/resume frequency tracking
- [ ] Export frequency data

### API Improvements
- [ ] Unified configuration schema
- [ ] Validation for configuration objects
- [ ] Better error messages
- [ ] Progress callbacks for animations

---

## Version History

### v1.3 (Current)
- ✨ Added sequential overlay tooltips with gold style
- ✨ Added frequency-based reordering with drag support
- ✨ Enhanced cleanup logic with 4-step process
- 🎨 Compact button styling
- 🎨 Crossfade + shine animation for reframe
- 🐛 Fixed background color restoration
- 📝 Comprehensive documentation

### v1.2
- ✨ Multi-group support
- ✨ Defensive programming patterns
- 🎨 Staggered animations

### v1.1
- ✨ Basic reorder and group scripts
- 🎨 Tooltip and highlight scripts

### v1.0
- 🎉 Initial release
- ✨ Core mutation and insert scripts
