Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
VCCI-News
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Văn Hoàng
VCCI-News
Commits
8e61c773
Commit
8e61c773
authored
Aug 24, 2026
by
Lê Bảo Hồng Đức
☄
Browse files
Options
Browse Files
Download
Plain Diff
[tag]0.1-vcci
parents
79e4483e
d75b3139
Pipeline
#52794
passed with stages
in 4 minutes and 43 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
35 additions
and
20 deletions
+35
-20
.gitignore
.gitignore
+4
-1
rich-text-editor.tsx
src/components/admin/rich-text-editor.tsx
+31
-19
No files found.
.gitignore
View file @
8e61c773
...
...
@@ -41,4 +41,7 @@ yarn-error.log*
next-env.d.ts
#vscode
.vscode/
\ No newline at end of file
.vscode/
# Windows reserved device name files (cannot be deleted normally)
nul
\ No newline at end of file
src/components/admin/rich-text-editor.tsx
View file @
8e61c773
...
...
@@ -239,6 +239,36 @@ export function AdminRichTextEditor({
const
recentlyFormattedRef
=
useRef
(
false
);
// Flag set by the native paste handler — only true right after a real paste event
const
pasteDetectedRef
=
useRef
(
false
);
// Holds the cleanup function for the paste listener so we can remove it
// when the editor instance is replaced or the component unmounts.
const
pasteCleanupRef
=
useRef
<
(()
=>
void
)
|
null
>
(
null
);
// Called by JoditEditor once the IJodit instance is ready. We use this to
// attach a native paste listener to the editor's editable DOM element.
const
handleEditorRef
=
React
.
useCallback
((
jodit
:
{
editor
?:
HTMLElement
})
=>
{
// Clean up any previous listener
pasteCleanupRef
.
current
?.();
pasteCleanupRef
.
current
=
null
;
const
editorEl
=
jodit
?.
editor
;
if
(
!
editorEl
)
return
;
const
handlePaste
=
()
=>
{
pasteDetectedRef
.
current
=
true
;
};
editorEl
.
addEventListener
(
"paste"
,
handlePaste
);
pasteCleanupRef
.
current
=
()
=>
{
editorEl
.
removeEventListener
(
"paste"
,
handlePaste
);
};
},
[]);
React
.
useEffect
(()
=>
{
return
()
=>
{
pasteCleanupRef
.
current
?.();
pasteCleanupRef
.
current
=
null
;
};
},
[]);
const
handleFormat
=
React
.
useCallback
((
html
:
string
)
=>
{
setIsFormatting
(
true
);
...
...
@@ -287,25 +317,6 @@ export function AdminRichTextEditor({
onChange
(
html
);
},
[
handleFormat
,
onChange
]);
// Attach a native paste listener to the editor container so we can detect
// real clipboard paste events instead of guessing from HTML content.
React
.
useEffect
(()
=>
{
const
container
=
editor
.
current
as
unknown
as
HTMLElement
|
null
;
if
(
!
container
)
return
;
const
editorEl
=
container
.
querySelector
?.(
".jodit-wysiwyg"
)
as
HTMLElement
|
null
;
const
target
=
editorEl
??
container
;
const
handlePaste
=
()
=>
{
pasteDetectedRef
.
current
=
true
;
};
target
.
addEventListener
(
"paste"
,
handlePaste
);
return
()
=>
{
target
.
removeEventListener
(
"paste"
,
handlePaste
);
};
},
[
localValue
]);
const
config
:
JoditEditorProps
[
"config"
]
=
useMemo
(
()
=>
({
readonly
:
readOnly
,
...
...
@@ -565,6 +576,7 @@ export function AdminRichTextEditor({
<
div
className=
"editor-wrapper"
>
<
JoditEditor
ref=
{
editor
}
editorRef=
{
handleEditorRef
}
value=
{
localValue
}
config=
{
config
}
onBlur=
{
(
nextContent
)
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment