# IIFE Capture-Phase Handler Kills Save Button

## Pattern

A page has an inline IIFE `<script>` block (not `type="module"`) that registers a capture-phase click handler on `document`:

```javascript
document.addEventListener('click', function(e) {
    var closeBtn = e.target.closest('[aria-label="Close"],[data-close-modal]');
    if (closeBtn) {
        e.preventDefault();
        e.stopPropagation();  // ← THIS IS THE KILLER
        var id = closeBtn.getAttribute('data-close-modal');
        if (id) { closeModal(id); return; }
        // ... fallback close logic ...
    }
    // ... backdrop click handling ...
}, true);  // ← capture phase
```

Some JS module (e.g., `settings.js`) sets `data-close-modal` on close, cancel, AND save buttons:

```javascript
saveSiteSettings.setAttribute('data-close-modal', 'site-settings-modal');
```

## Symptom

- Close (X) and Cancel buttons work correctly — modal closes
- Save button closes the modal but **settings are never persisted**
- No console errors
- The save function is defined and reachable (inline `onclick` or `addEventListener` exists)

## Root Cause

When the user clicks Save:

1. **Capture phase** — IIFE handler on `document` fires FIRST. Matches `[data-close-modal]` on the save button. Calls `closeModal()` immediately. Calls `e.stopPropagation()` which **prevents the event from ever reaching the target phase or bubble phase**.
2. **Target phase** — NEVER REACHED. The inline `onclick="saveSiteSettings()"` never fires.
3. **Bubble phase** — NEVER REACHED. Any `addEventListener('click', handler)` on the button never fires.

The modal closes (step 1 did that), but the save logic never executes.

## Why Close/Cancel Still Work

For close and cancel buttons, closing the modal IS the correct action. The IIFE intercepting and closing is fine — no additional behavior was needed.

## Fix (Three Options)

### Option A: Remove `data-close-modal` from save button (cleanest)

In the code that sets attributes (`ensureSiteSettingsCloseAttributes` or dashboard init):

```javascript
// BEFORE (broken)
setAttr(closeId);   // ✓ fine
setAttr(cancelId);  // ✓ fine
setAttr(saveId);    // ✗ kills save handler

// AFTER (fixed)
setAttr(closeId);   // ✓
setAttr(cancelId);  // ✓
// Do NOT set on saveId — let addEventListener handle it
```

Then wire the save button via `addEventListener` (non-capture) so it fires after the IIFE ignores it:

```javascript
saveBtn.addEventListener('click', async function() {
    // read form, save settings
    await saveAllSettings();
    closeModal('site-settings-modal');
});
```

The IIFE no longer matches the save button → capture phase passes through → target/bubble handlers fire normally.

### Option B: Add save handling to the IIFE itself

Insert a save-button check BEFORE the close-button check in the capture handler:

```javascript
document.addEventListener('click', function(e) {
    // Check save button FIRST
    var saveBtn = e.target.closest('#save-site-settings');
    if (saveBtn) {
        e.stopPropagation();
        // Save directly or call window.saveSiteSettings()
        window.saveSiteSettings();
        window.closeModal('site-settings-modal');
        return;
    }
    // Then check close/cancel as before
    var closeBtn = e.target.closest('[aria-label="Close"],[data-close-modal]');
    // ...
}, true);
```

This works but couples the IIFE to specific button IDs. Option A is cleaner.

### Option C: Direct onclick property override (nuclear option)

Set `saveBtn.onclick` from the IIFE (firing in target phase, before bubbling):

```javascript
var btn = document.getElementById('save-site-settings');
if (btn) {
    btn.onclick = function(e) {
        e.stopImmediatePropagation();
        // save logic
        window.closeModal('site-settings-modal');
        return false;
    };
}
```

`stopImmediatePropagation()` prevents other listeners (from JS modules) on the same element from firing, avoiding duplicate saves.

## Diagnosis Checklist

1. Does the page have a capture-phase IIFE? Search for `addEventListener('click', ..., true)` or `},true)` in inline `<script>` blocks.
2. Does the save button have `data-close-modal`? Check the HTML and any JS that sets attributes.
3. Does the save button have an inline `onclick` or an `addEventListener` handler?
4. If yes to all three → this is the bug.

## Related Pitfalls

- **Double save:** If you remove `data-close-modal` from save but BOTH the IIFE's new save handler AND the JS module's addEventListener fire, you get duplicate saves and duplicate notifications. Use `stopImmediatePropagation()` or check `hasAttribute('onclick')` to gate one of them.
- **Module timing:** If the save handler is defined in a JS module (e.g., `window.saveSiteSettings` in `settings.js`), and the module loads after the IIFE, the IIFE may call it before it exists. Always check `typeof window.saveSiteSettings === 'function'` before calling.
- **`stopPropagation()` vs `stopImmediatePropagation()`:** `stopPropagation()` in the target phase prevents bubbling but NOT other target-phase handlers on the same element. `stopImmediatePropagation()` prevents ALL remaining handlers on the element regardless of phase.
