# Anchor Point Visibility Implementation

## Summary

Anchor points are now properly handled across all three modes:

1. **Editor Mode**: Visible with visual indicator
2. **Preview Mode**: Hidden from view
3. **Export/Deployed**: Completely removed from HTML

---

## Implementation Details

### 1. Editor Mode (js/editor.js, lines 247-280)

Anchors are visible in the editor with a dashed border, light blue background, an anchor icon, and an **editable text field** showing the anchor name:

```html
<div data-anchor="true" id="anchor-1" class="editor-anchor">
    <span class="anchor-icon">⚓</span>
    <input type="text" class="anchor-name-input" value="anchor-1" />
</div>
```

```css
.editor-anchor {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 28px;
    border: 1px dashed #9ca3af;
    padding: 4px 8px;
    background: rgba(59,130,246,0.05);
    border-radius: 4px;
}

.editor-anchor .anchor-name-input {
    border: none;
    background: transparent;
    color: #374151;
    font-size: 12px;
    font-weight: 500;
    min-width: 80px;
}

.editor-anchor .anchor-name-input:focus {
    background: rgba(255,255,255,0.5);
    border-radius: 2px;
}
```

**Editable Name**: Users can click directly on the text field to edit the anchor name. Changes are automatically synced to the anchor's ID attribute.

This styling is part of the GrapesJS canvas styles, which only apply in the editor.

### 2. Preview Mode (preview.html, lines 35-40)

When previewing the site, anchor elements and their children (icon + input) exist in the DOM but are hidden:

```css
/* Hide editor-only elements in preview */
.editor-anchor,
.editor-anchor .anchor-icon,
.editor-anchor .anchor-name-input {
    display: none !important;
}
```

This ensures that when users preview their site, anchors and their editable fields are invisible (as they would be on the deployed site).

### 3. Export Mode (js/editor.js, lines 3826-3828)

When exporting to ZIP or deploying, anchor elements (with all nested content) are **completely removed** from the HTML:

```javascript
// Remove editor-only anchor elements completely (with nested content)
html = html.replace(/<div[^>]*data-anchor="true"[^>]*>[\s\S]*?<\/div>/g, '');
html = html.replace(/<div[^>]*class="editor-anchor"[^>]*>[\s\S]*?<\/div>/g, '');
```

The `[\s\S]*?` pattern matches any content (including newlines) inside the anchor div, ensuring the icon, input field, and any whitespace are all removed.

Additional CSS cleanup (line 3839):

```javascript
// Remove editor-anchor CSS rules from page CSS
css = css.replace(/\.editor-anchor[^}]*}/g, '');
```

---

## Testing

### Manual Testing Steps

1. **Test Editor Visibility**:
   - Open the site builder at http://localhost:8081
   - Add an "Anchor Point" block from the Blocks panel
   - Verify you see:
     - Dashed gray border with light blue background
     - ⚓ anchor icon on the left
     - Editable text field showing "anchor-1" on the right
   - Click directly on the text field and change the name (e.g., "pricing")
   - Verify the anchor's ID updates automatically (check in Settings panel)
   - Try spaces and special characters - should auto-sanitize to lowercase with hyphens

2. **Test Preview Mode**:
   - Add some content and an anchor point
   - Click the "Preview" button in the top toolbar
   - Verify the anchor point is NOT visible in the preview window
   - Check browser DevTools: element should exist but have `display: none`

3. **Test Export**:
   - Add an anchor point to your page
   - Click "Export" → "Export ZIP"
   - Extract the ZIP and open `index.html` in a text editor
   - Search for "anchor" - should find NO instances of:
     - `data-anchor="true"`
     - `class="editor-anchor"`
     - `.editor-anchor` CSS rules

### Automated Testing

The anchor visibility tests are in `tests/anchor-visibility.spec.js`. Note: These tests require proper block dragging implementation to work reliably with Playwright.

---

## Use Cases

### Why Anchors?

Anchor points let users create jump links within a page. For example:

```html
<!-- Anchor point (invisible on deployed site) -->
<div id="pricing"></div>

<!-- Link that jumps to the anchor -->
<a href="#pricing">Jump to Pricing</a>
```

### Editor Experience

Users can:
- See where anchors are placed (visual indicator)
- Select and configure anchor IDs
- Move anchors around the page
- Preview how the site works without seeing anchor markers

### Deployed Site

On the live site:
- Anchors are invisible (completely removed from HTML)
- Jump links still work (browser looks for matching `id` attributes)
- No extra elements cluttering the DOM
- Clean, semantic HTML

---

## Technical Notes

### Why Three Separate Approaches?

1. **Editor**: Canvas styles are injected by GrapesJS and only apply to the editor frame
2. **Preview**: Loads the page HTML/CSS in a new window; canvas styles don't apply here
3. **Export**: Generates standalone HTML files that should have no editor artifacts

### Regex Patterns

The export function uses two regex patterns to catch both possible element formats:

- `/<div[^>]*data-anchor="true"[^>]*><\/div>/g` - Matches by data attribute
- `/<div[^>]*class="editor-anchor"[^>]*><\/div>/g` - Matches by class name

This ensures complete removal regardless of attribute order.

### CSS Specificity

Preview.html uses `!important` on `display: none` to ensure the rule takes precedence over any user-added CSS that might target `.editor-anchor`.

---

## Files Modified

| File | Lines | Change |
|------|-------|--------|
| `js/editor.js` | 3744-3746 | Updated anchor removal regex (export) |
| `preview.html` | 35-38 | Added `.editor-anchor { display: none }` |

Files with existing anchor styling (unchanged):

| File | Lines | Purpose |
|------|-------|---------|
| `js/editor.js` | 247-260 | Canvas styles for editor visibility |
| `js/editor.js` | 943 | Anchor block definition |

---

## Future Enhancements

Potential improvements:

1. **Drag-and-Drop Visual**: Show a target line when dragging anchors
2. **Anchor Link Helper**: Auto-suggest anchor IDs when creating links
3. **Jump Preview**: In preview mode, clicking anchor links should scroll smoothly
4. **Anchor List Panel**: Show all anchors in a dedicated panel for easy navigation
5. **Export Warning**: Warn users if they have links pointing to non-existent anchors

---

## Troubleshooting

### "I can't see the anchor in the editor"

- Make sure you're viewing the editor, not preview mode
- Click the anchor element to select it
- Check that canvas styles are loaded (inspect element in browser DevTools)

### "The anchor still shows in preview"

- Hard refresh the preview page (Ctrl+Shift+R)
- Check browser console for CSS loading errors
- Verify `preview.html` has the `.editor-anchor` display rule

### "The anchor appears in exported HTML"

- Check the `generatePageHtml` function has the updated regex
- Verify you're using the latest version of `js/editor.js`
- Try re-exporting after a hard refresh of the editor

---

**Last Updated**: 2026-02-25  
**Author**: Jarvis (AI Assistant)

---

## Known Issues & Fixes

### Issue 1: Backspace Deleting Component (Fixed)
**Problem**: Pressing backspace in the input field deleted the entire anchor.  
**Fix**: Added event propagation stoppers to prevent GrapesJS from intercepting keyboard events.  
**Location**: `js/editor.js` lines 3079-3092

### Issue 2: Child Elements Separately Selectable (Fixed)
**Problem**: Users could click on the icon or input field and select/delete them individually.  
**Fix**: Set child components to `selectable: false` in anchor-point component type's `init()` method.  
**Location**: `js/editor.js` lines 1481-1497  
**Result**: Entire anchor acts as a single unit; clicking anywhere selects the container.

