# Quill.js Emitter Error Fix

## Issue
```
Uncaught TypeError: can't access property "emit", this.emitter is undefined
```

This error occurred in `CustomRichEditor.tsx` when Quill.js tried to initialize or perform operations before its internal emitter was ready.

## Root Cause
1. **Unstable module configuration** - The `handleImageUpload` callback was included in `quillModules` dependencies, causing the modules object to recreate on every render
2. **Missing initialization guards** - Code attempted to access Quill editor methods before the editor was fully initialized
3. **Concurrent DOM mutations** - MutationObserver showed Quill was initializing while DOM was being modified

## Solution Applied

### 1. Stabilized Image Upload Handler
**Before:**
```typescript
const handleImageUpload = useCallback(() => { ... }, []);

const quillModules = useMemo(() => ({
  toolbar: {
    handlers: {
      image: onImageUpload ? handleImageUpload : undefined,
    },
  },
}), [toolbarConfig, onImageUpload, handleImageUpload]); // handleImageUpload caused recreation
```

**After:**
```typescript
const handleImageUploadRef = useRef<() => void>();
  
useEffect(() => {
  handleImageUploadRef.current = () => { ... };
});

const quillModules = useMemo(() => ({
  toolbar: {
    handlers: {
      image: onImageUpload ? () => handleImageUploadRef.current?.() : undefined,
    },
  },
}), [toolbarConfig, onImageUpload]); // Only stable dependencies
```

### 2. Added Emitter Safety Checks
**Before:**
```typescript
const quill = quillRef.current?.getEditor();
if (quill) {
  quill.focus();
  // ... operations
}
```

**After:**
```typescript
const quill = quillRef.current?.getEditor();
if (quill && quill.root && quill.emitter) {
  setTimeout(() => {
    // Double-check Quill is still valid
    if (!quill || !quill.emitter) {
      toast({ title: 'Editor není připraven', ... });
      return;
    }
    // ... operations
  }, 100);
} else {
  toast({ title: 'Editor není připraven', ... });
}
```

### 3. Added Stable Key to ReactQuill
```typescript
<ReactQuill
  key={`quill-${readOnly ? 'readonly' : 'edit'}`}
  // ... other props
/>
```

This prevents unnecessary remounting while allowing controlled reinitialization when mode changes.

### 4. Protected Image Manipulation Effect
```typescript
useEffect(() => {
  const editor = quillRef.current?.getEditor();
  if (!editor || !editor.root || !editor.emitter || readOnly) return;
  // ... event handlers
}, [readOnly, toast]);
```

## Benefits
- ✅ Prevents Quill from reinitializing on every render
- ✅ Ensures operations only happen when editor is fully ready
- ✅ Provides user feedback when editor isn't ready
- ✅ Maintains stable component lifecycle
- ✅ Fixes the "this.emitter is undefined" error

## Testing
1. Create a new article in admin panel
2. Click "Vložit obrázek" or use toolbar image button
3. Select and crop an image
4. Verify image inserts without errors
5. Test image editing features (resize, filters, alignment)
6. Check browser console for absence of Quill errors

## Files Modified
- `frontend/src/components/common/CustomRichEditor.tsx`

## Related
- React Quill: https://github.com/zenoamaro/react-quill
- Quill.js: https://quilljs.com/
