Skip to content

Commit 9331690

Browse files
committed
fix: When copying text and images, can the images only appear at the end of the article
1 parent c6189e5 commit 9331690

File tree

2 files changed

+64
-20
lines changed

2 files changed

+64
-20
lines changed

ui/src/components/Editor/ToolBars/image.tsx

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -228,30 +228,64 @@ const Image = ({ editorInstance }) => {
228228
return;
229229
}
230230
event.preventDefault();
231-
232-
let innerText = '';
233-
const allPTag = new DOMParser()
234-
.parseFromString(
235-
htmlStr.replace(
236-
/<img([\s\S]*?) src\s*=\s*(['"])([\s\S]*?)\2([^>]*)>/gi,
237-
`<p>![${t('image.text')}]($3)\n\n</p>`,
238-
),
239-
'text/html',
240-
)
241-
.querySelectorAll('body p');
242-
243-
allPTag.forEach((p, index) => {
244-
const text = p.textContent || '';
245-
if (text !== '') {
246-
if (index === allPTag.length - 1) {
247-
innerText += `${p.textContent}`;
231+
const parser = new DOMParser();
232+
const doc = parser.parseFromString(htmlStr, 'text/html');
233+
const { body } = doc;
234+
235+
let markdownText = '';
236+
237+
function traverse(node) {
238+
if (node.nodeType === Node.TEXT_NODE) {
239+
// text node
240+
markdownText += node.textContent;
241+
} else if (node.nodeType === Node.ELEMENT_NODE) {
242+
// element node
243+
const tagName = node.tagName.toLowerCase();
244+
245+
if (tagName === 'img') {
246+
// img node
247+
const src = node.getAttribute('src');
248+
const alt = node.getAttribute('alt') || t('image.text');
249+
markdownText += `![${alt}](${src})`;
250+
} else if (tagName === 'br') {
251+
// br node
252+
markdownText += '\n';
248253
} else {
249-
innerText += `${p.textContent}${text.endsWith('\n') ? '' : '\n\n'}`;
254+
for (let i = 0; i < node.childNodes.length; i += 1) {
255+
traverse(node.childNodes[i]);
256+
}
257+
}
258+
259+
const blockLevelElements = [
260+
'p',
261+
'div',
262+
'h1',
263+
'h2',
264+
'h3',
265+
'h4',
266+
'h5',
267+
'h6',
268+
'ul',
269+
'ol',
270+
'li',
271+
'blockquote',
272+
'pre',
273+
'table',
274+
'thead',
275+
'tbody',
276+
'tr',
277+
'th',
278+
'td',
279+
];
280+
if (blockLevelElements.includes(tagName)) {
281+
markdownText += '\n\n';
250282
}
251283
}
252-
});
284+
}
285+
286+
traverse(body);
253287

254-
editor.replaceSelection(innerText);
288+
editor.replaceSelection(markdownText);
255289
};
256290
const handleClick = () => {
257291
if (!link.value) {

ui/src/components/Editor/utils/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ export const useEditor = ({
172172
placeholder(placeholderText),
173173
EditorView.lineWrapping,
174174
editableCompartment.of(EditorView.editable.of(true)),
175+
EditorView.domEventHandlers({
176+
paste(event) {
177+
const clipboard = event.clipboardData as DataTransfer;
178+
const htmlStr = clipboard.getData('text/html');
179+
const imgRegex =
180+
/<img([\s\S]*?) src\s*=\s*(['"])([\s\S]*?)\2([^>]*)>/;
181+
182+
return Boolean(htmlStr.match(imgRegex));
183+
},
184+
}),
175185
],
176186
});
177187

0 commit comments

Comments
 (0)