web-mikul-news/components/editor/fixed-editor.js

159 lines
9.6 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// components/fixed-editor.js
import React, { useRef, useEffect } from "react";
import { Editor } from "@tinymce/tinymce-react";
function FixedEditor(props) {
const editorRef = useRef(null);
const contentRef = useRef(props.initialData || '');
const onChangeRef = useRef(props.onChange);
// Update refs when props change
useEffect(() => {
onChangeRef.current = props.onChange;
}, [props.onChange]);
useEffect(() => {
if (props.initialData !== undefined && editorRef.current) {
contentRef.current = props.initialData;
editorRef.current.setContent(props.initialData);
}
}, [props.initialData]);
const handleInit = (evt, editor) => {
editorRef.current = editor;
// Set initial content
if (props.initialData) {
editor.setContent(props.initialData);
contentRef.current = props.initialData;
}
// Create a debounced onChange handler
let timeoutId = null;
const debouncedOnChange = (content) => {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
if (onChangeRef.current && content !== contentRef.current) {
contentRef.current = content;
onChangeRef.current(content);
}
}, 100);
};
// Handle all content changes
editor.on('change keyup input paste', (e) => {
const content = editor.getContent();
debouncedOnChange(content);
});
// Handle undo/redo
editor.on('Undo Redo', (e) => {
setTimeout(() => {
const content = editor.getContent();
debouncedOnChange(content);
}, 0);
});
// Prevent cursor jumping by handling focus events
editor.on('focus', (e) => {
// Save current selection
editor.lastSelection = editor.selection.getBookmark();
});
editor.on('blur', (e) => {
// Restore selection if available
if (editor.lastSelection) {
try {
editor.selection.moveToBookmark(editor.lastSelection);
} catch (error) {
// Ignore bookmark errors
}
}
});
// Handle key events to prevent jumping
editor.on('keydown', (e) => {
// Save selection before any key operation
editor.lastSelection = editor.selection.getBookmark();
});
editor.on('keyup', (e) => {
// Restore selection after key operation
if (editor.lastSelection) {
try {
editor.selection.moveToBookmark(editor.lastSelection);
} catch (error) {
// Ignore bookmark errors
}
}
});
};
return (
<Editor
onInit={handleInit}
apiKey={process.env.NEXT_PUBLIC_TINYMCE_API_KEY}
init={{
height: 400,
menubar: false,
plugins: [
'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount'
],
toolbar: 'undo redo | blocks | ' +
'bold italic forecolor | alignleft aligncenter ' +
'alignright alignjustify | bullist numlist outdent indent | ' +
'removeformat | table | code | help',
content_style: `
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px;
line-height: 1.6;
color: #333;
}
.mce-content-body {
padding: 16px;
min-height: 368px;
}
`,
placeholder: 'Start typing...',
branding: false,
elementpath: false,
resize: false,
statusbar: false,
// Critical settings for stability
auto_focus: false,
forced_root_block: 'p',
entity_encoding: 'raw',
keep_styles: true,
// Disable all problematic features
verify_html: false,
cleanup: false,
cleanup_on_startup: false,
auto_resize: false,
// Content handling
paste_as_text: false,
paste_enable_default_filters: true,
paste_word_valid_elements: 'b,strong,i,em,h1,h2,h3,h4,h5,h6',
paste_retain_style_properties: 'color background-color font-size font-weight',
// Prevent automatic updates
element_format: 'html',
valid_children: '+body[style]',
extended_valid_elements: 'span[*]',
custom_elements: '~span',
// Mobile support
mobile: {
theme: 'silver',
plugins: ['lists', 'autolink', 'link', 'image', 'table'],
toolbar: 'bold italic | bullist numlist | link image'
}
}}
/>
);
}
export default FixedEditor;