mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
Merge pull request #8532 from penpot/superalex-fix-cut-copy-paste
🐛 Fix cut copy paste
This commit is contained in:
commit
208b3329fd
@ -111,6 +111,21 @@
|
|||||||
(let [text (text-editor/text-editor-export-selection)]
|
(let [text (text-editor/text-editor-export-selection)]
|
||||||
(.setData (.-clipboardData event) "text/plain" text))))))
|
(.setData (.-clipboardData event) "text/plain" text))))))
|
||||||
|
|
||||||
|
on-cut
|
||||||
|
(mf/use-fn
|
||||||
|
(fn [^js event]
|
||||||
|
(when (text-editor/text-editor-is-active?)
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(when (text-editor/text-editor-get-selection)
|
||||||
|
(let [text (text-editor/text-editor-export-selection)]
|
||||||
|
(.setData (.-clipboardData event) "text/plain" (or text ""))
|
||||||
|
(when (and text (seq text))
|
||||||
|
(text-editor/text-editor-delete-backward)
|
||||||
|
(sync-wasm-text-editor-content!)
|
||||||
|
(wasm.api/request-render "text-cut"))))
|
||||||
|
(when-let [node (mf/ref-val contenteditable-ref)]
|
||||||
|
(set! (.-textContent node) "")))))
|
||||||
|
|
||||||
on-key-down
|
on-key-down
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [^js event]
|
(fn [^js event]
|
||||||
@ -303,6 +318,7 @@
|
|||||||
:on-input on-input
|
:on-input on-input
|
||||||
:on-paste on-paste
|
:on-paste on-paste
|
||||||
:on-copy on-copy
|
:on-copy on-copy
|
||||||
|
:on-cut on-cut
|
||||||
:on-focus on-focus
|
:on-focus on-focus
|
||||||
:on-blur on-blur
|
:on-blur on-blur
|
||||||
;; FIXME on-click
|
;; FIXME on-click
|
||||||
|
|||||||
@ -576,6 +576,7 @@ impl TextContent {
|
|||||||
for paragraph in self.paragraphs() {
|
for paragraph in self.paragraphs() {
|
||||||
let paragraph_style = paragraph.paragraph_to_style();
|
let paragraph_style = paragraph.paragraph_to_style();
|
||||||
let mut builder = ParagraphBuilder::new(¶graph_style, fonts);
|
let mut builder = ParagraphBuilder::new(¶graph_style, fonts);
|
||||||
|
let mut has_text = false;
|
||||||
for span in paragraph.children() {
|
for span in paragraph.children() {
|
||||||
let remove_alpha = use_shadow.unwrap_or(false) && !span.is_transparent();
|
let remove_alpha = use_shadow.unwrap_or(false) && !span.is_transparent();
|
||||||
let text_style = span.to_style(
|
let text_style = span.to_style(
|
||||||
@ -585,9 +586,15 @@ impl TextContent {
|
|||||||
paragraph.line_height(),
|
paragraph.line_height(),
|
||||||
);
|
);
|
||||||
let text: String = span.apply_text_transform();
|
let text: String = span.apply_text_transform();
|
||||||
|
if !text.is_empty() {
|
||||||
|
has_text = true;
|
||||||
|
}
|
||||||
builder.push_style(&text_style);
|
builder.push_style(&text_style);
|
||||||
builder.add_text(&text);
|
builder.add_text(&text);
|
||||||
}
|
}
|
||||||
|
if !has_text {
|
||||||
|
builder.add_text(" ");
|
||||||
|
}
|
||||||
paragraph_group.push(vec![builder]);
|
paragraph_group.push(vec![builder]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -298,9 +298,7 @@ pub extern "C" fn text_editor_insert_text() {
|
|||||||
|
|
||||||
let cursor = state.text_editor_state.selection.focus;
|
let cursor = state.text_editor_state.selection.focus;
|
||||||
|
|
||||||
if let Some(new_offset) = insert_text_at_cursor(text_content, &cursor, &text) {
|
if let Some(new_cursor) = insert_text_with_newlines(text_content, &cursor, &text) {
|
||||||
let new_cursor =
|
|
||||||
TextPositionWithAffinity::new_without_affinity(cursor.paragraph, new_offset);
|
|
||||||
state.text_editor_state.selection.set_caret(new_cursor);
|
state.text_editor_state.selection.set_caret(new_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,12 +765,10 @@ pub extern "C" fn text_editor_export_selection() -> *mut u8 {
|
|||||||
char_pos += span_len;
|
char_pos += span_len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !para_text.is_empty() {
|
if para_idx > start.paragraph {
|
||||||
if !result.is_empty() {
|
result.push('\n');
|
||||||
result.push('\n');
|
|
||||||
}
|
|
||||||
result.push_str(¶_text);
|
|
||||||
}
|
}
|
||||||
|
result.push_str(¶_text);
|
||||||
}
|
}
|
||||||
let mut bytes = result.into_bytes();
|
let mut bytes = result.into_bytes();
|
||||||
bytes.push(0);
|
bytes.push(0);
|
||||||
@ -1069,6 +1065,45 @@ fn find_span_at_offset(para: &Paragraph, char_offset: usize) -> Option<(usize, u
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert text at a cursor position, splitting on newlines into multiple paragraphs.
|
||||||
|
/// Returns the final cursor position after insertion.
|
||||||
|
fn insert_text_with_newlines(
|
||||||
|
text_content: &mut TextContent,
|
||||||
|
cursor: &TextPositionWithAffinity,
|
||||||
|
text: &str,
|
||||||
|
) -> Option<TextPositionWithAffinity> {
|
||||||
|
let normalized = text.replace("\r\n", "\n").replace('\r', "\n");
|
||||||
|
let lines: Vec<&str> = normalized.split('\n').collect();
|
||||||
|
if lines.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut current_cursor = *cursor;
|
||||||
|
|
||||||
|
if let Some(new_offset) = insert_text_at_cursor(text_content, ¤t_cursor, lines[0]) {
|
||||||
|
current_cursor =
|
||||||
|
TextPositionWithAffinity::new_without_affinity(current_cursor.paragraph, new_offset);
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
for line in lines.iter().skip(1) {
|
||||||
|
if !split_paragraph_at_cursor(text_content, ¤t_cursor) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
current_cursor =
|
||||||
|
TextPositionWithAffinity::new_without_affinity(current_cursor.paragraph + 1, 0);
|
||||||
|
if let Some(new_offset) = insert_text_at_cursor(text_content, ¤t_cursor, line) {
|
||||||
|
current_cursor = TextPositionWithAffinity::new_without_affinity(
|
||||||
|
current_cursor.paragraph,
|
||||||
|
new_offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(current_cursor)
|
||||||
|
}
|
||||||
|
|
||||||
/// Insert text at a cursor position. Returns the new character offset after insertion.
|
/// Insert text at a cursor position. Returns the new character offset after insertion.
|
||||||
fn insert_text_at_cursor(
|
fn insert_text_at_cursor(
|
||||||
text_content: &mut TextContent,
|
text_content: &mut TextContent,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user