Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix
  • Loading branch information
wxiaoguang committed Jun 24, 2024
commit 8d45f2ebfde5109c9e69f21c6b5b22aef381365b
13 changes: 6 additions & 7 deletions web_src/js/features/comp/ComboMarkdownEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import '@github/text-expander-element';
import $ from 'jquery';
import {attachTribute} from '../tribute.js';
import {hideElem, showElem, autosize, isElemVisible} from '../../utils/dom.js';
import {initEasyMDEPaste, initTextareaPaste} from './Paste.js';
import {initEasyMDEPaste, initTextareaPaste} from './EditorUpload.js';
import {handleGlobalEnterQuickSubmit} from './QuickSubmit.js';
import {renderPreviewPanelContent} from '../repo-editor.js';
import {easyMDEToolbarActions} from './EasyMDEToolbarActions.js';
Expand Down Expand Up @@ -291,6 +291,11 @@ class ComboMarkdownEditor {
}
}

export function getComboMarkdownEditor(el) {
if (el instanceof $) el = el[0];
return el?._giteaComboMarkdownEditor;
}

export async function initComboMarkdownEditor(container, options = {}) {
if (container instanceof $) {
if (container.length !== 1) {
Expand All @@ -305,9 +310,3 @@ export async function initComboMarkdownEditor(container, options = {}) {
await editor.init();
return editor;
}

export function removeLinksInTextarea(editor, file) {
const fileName = file.name.slice(0, file.name.lastIndexOf('.'));
const fileText = `\\[${fileName}\\]\\(/attachments/${file.uuid}\\)`;
editor.value(editor.value().replace(new RegExp(`<img [\\s\\w"=]+ alt="${fileName}" src="/attachments/${file.uuid}">`, 'g'), '').replace(new RegExp(`\\!${fileText}`, 'g'), '').replace(new RegExp(fileText, 'g'), ''));
}
4 changes: 3 additions & 1 deletion web_src/js/features/comp/EditorMarkdown.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {triggerEditorContentChanged} from './Paste.js';
export function triggerEditorContentChanged(target) {
target.dispatchEvent(new CustomEvent('ce-editor-content-changed', {bubbles: true}));
}

function handleIndentSelection(textarea, e) {
const selStart = textarea.selectionStart;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {htmlEscape} from 'escape-goat';
import {POST} from '../../modules/fetch.js';
import {imageInfo} from '../../utils/image.js';
import {getPastedContent, replaceTextareaSelection} from '../../utils/dom.js';
import {replaceTextareaSelection} from '../../utils/dom.js';
import {isUrl} from '../../utils/url.js';
import {extname} from '../../utils.js';
import {triggerEditorContentChanged} from './EditorMarkdown.js';
import {getComboMarkdownEditor} from './ComboMarkdownEditor.js';

async function uploadFile(file, uploadUrl) {
const formData = new FormData();
Expand All @@ -12,10 +15,6 @@ async function uploadFile(file, uploadUrl) {
return await res.json();
}

export function triggerEditorContentChanged(target) {
target.dispatchEvent(new CustomEvent('ce-editor-content-changed', {bubbles: true}));
}

class TextareaEditor {
constructor(editor) {
this.editor = editor;
Expand Down Expand Up @@ -82,23 +81,21 @@ class CodeMirrorEditor {
}
}

// FIXME: handle non-image files
async function handleClipboardImages(editor, dropzone, images, e) {
const uploadUrl = dropzone.getAttribute('data-upload-url');
const filesContainer = dropzone.querySelector('.files');

if (!dropzone || !uploadUrl || !filesContainer || !images.length) return;

e.preventDefault();
e.stopPropagation();

for (const img of images) {
const name = img.name.slice(0, img.name.lastIndexOf('.'));

const {width, dppx} = await imageInfo(img);
const placeholder = `![${name}](uploading ...)`;
editor.insertPlaceholder(placeholder);

editor.insertPlaceholder(placeholder);
const {uuid} = await uploadFile(img, uploadUrl);
const {width, dppx} = await imageInfo(img);

let text;
if (width > 0 && dppx > 1) {
Expand Down Expand Up @@ -139,6 +136,18 @@ function handleClipboardText(textarea, e, {text, isShiftDown}) {
// else, let the browser handle it
}

// extract text and images from "paste" event
function getPastedContent(e) {
const images = [];
for (const item of e.clipboardData?.items ?? []) {
if (item.type?.startsWith('image/')) {
images.push(item.getAsFile());
}
}
const text = e.clipboardData?.getData?.('text') ?? '';
return {text, images};
}

export function initEasyMDEPaste(easyMDE, dropzone) {
easyMDE.codemirror.on('paste', (_, e) => {
const {images} = getPastedContent(e);
Expand All @@ -164,4 +173,17 @@ export function initTextareaPaste(textarea, dropzone) {
handleClipboardText(textarea, e, {text, isShiftDown});
}
});
textarea.addEventListener('drop', (e) => {
const acceptedFiles = getComboMarkdownEditor(textarea).dropzone.getAttribute('data-accepts');
const files = [];
for (const item of e.dataTransfer?.items ?? []) {
if (item?.kind !== 'file') continue;
const file = item.getAsFile();
if (acceptedFiles.includes(extname(file.name))) {
files.push(file);
}
}
// FIXME: handle upload files
handleClipboardImages(new TextareaEditor(textarea), dropzone, files, e);
});
}
1 change: 1 addition & 0 deletions web_src/js/features/dropzone.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export function initDropzone(el) {
data: new URLSearchParams({file: file.uuid}),
});
}
// TODO: remove the link from editor and maybe merge the duplicate code
});
this.on('error', function (file, message) {
showErrorToast(message);
Expand Down
1 change: 1 addition & 0 deletions web_src/js/features/repo-issue-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ async function onEditContent(event) {
console.error(error);
}
}
// TODO: remove the link from editor and maybe merge the duplicate code
});
this.on('submit', () => {
for (const fileUuid of Object.keys(fileUuidDict)) {
Expand Down
21 changes: 0 additions & 21 deletions web_src/js/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,27 +263,6 @@ export function isElemVisible(element) {
return Boolean(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
}

export function getComboMarkdownEditor(el) {
return el?._giteaComboMarkdownEditor;
}

// extract text and images from "paste" event
export function getPastedContent(e) {
const acceptedFiles = getComboMarkdownEditor(e.currentTarget).dropzone.getAttribute('data-accepts');
const files = [];
const data = e.clipboardData?.items || e.dataTransfer?.items;
for (const item of data ?? []) {
if (item?.kind === 'file') {
const file = item.getAsFile();
if (acceptedFiles.includes(extname(file.name))) {
files.push(file);
}
}
}
const text = e.clipboardData?.getData?.('text') ?? '';
return {text, files};
}

// replace selected text in a textarea while preserving editor history, e.g. CTRL-Z works after this
export function replaceTextareaSelection(textarea, text) {
const before = textarea.value.slice(0, textarea.selectionStart ?? undefined);
Expand Down