core: Prevent pasting empty string when the clipboard is empty
This commit is contained in:
parent
a2751c3c0f
commit
c23ec0782a
|
@ -73,6 +73,11 @@ pub trait UiBackend: Downcast {
|
|||
/// Get the clipboard content
|
||||
fn clipboard_content(&mut self) -> String;
|
||||
|
||||
/// Check if the clipboard is available and not empty
|
||||
fn clipboard_available(&mut self) -> bool {
|
||||
!self.clipboard_content().is_empty()
|
||||
}
|
||||
|
||||
/// Sets the clipboard to the given content.
|
||||
fn set_clipboard_content(&mut self, content: String);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ impl<'gc> ContextMenuState<'gc> {
|
|||
let language = &context.ui.language();
|
||||
self.push(
|
||||
ContextMenuItem {
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Cut),
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Cut, context),
|
||||
separator_before: true,
|
||||
caption: core_text(language, "context-menu-cut"),
|
||||
checked: false,
|
||||
|
@ -154,7 +154,7 @@ impl<'gc> ContextMenuState<'gc> {
|
|||
);
|
||||
self.push(
|
||||
ContextMenuItem {
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Copy),
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Copy, context),
|
||||
separator_before: false,
|
||||
caption: core_text(language, "context-menu-copy"),
|
||||
checked: false,
|
||||
|
@ -166,7 +166,7 @@ impl<'gc> ContextMenuState<'gc> {
|
|||
);
|
||||
self.push(
|
||||
ContextMenuItem {
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Paste),
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Paste, context),
|
||||
separator_before: false,
|
||||
caption: core_text(language, "context-menu-paste"),
|
||||
checked: false,
|
||||
|
@ -178,7 +178,7 @@ impl<'gc> ContextMenuState<'gc> {
|
|||
);
|
||||
self.push(
|
||||
ContextMenuItem {
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Delete),
|
||||
enabled: text.is_text_control_applicable(TextControlCode::Delete, context),
|
||||
separator_before: false,
|
||||
caption: core_text(language, "context-menu-delete"),
|
||||
checked: false,
|
||||
|
@ -190,7 +190,7 @@ impl<'gc> ContextMenuState<'gc> {
|
|||
);
|
||||
self.push(
|
||||
ContextMenuItem {
|
||||
enabled: text.is_text_control_applicable(TextControlCode::SelectAll),
|
||||
enabled: text.is_text_control_applicable(TextControlCode::SelectAll, context),
|
||||
separator_before: true,
|
||||
caption: core_text(language, "context-menu-select-all"),
|
||||
checked: false,
|
||||
|
|
|
@ -1420,7 +1420,11 @@ impl<'gc> EditText<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_text_control_applicable(self, control_code: TextControlCode) -> bool {
|
||||
pub fn is_text_control_applicable(
|
||||
self,
|
||||
control_code: TextControlCode,
|
||||
context: &mut UpdateContext<'_, 'gc>,
|
||||
) -> bool {
|
||||
if !self.is_editable() && control_code.is_edit_input() {
|
||||
return false;
|
||||
}
|
||||
|
@ -1439,7 +1443,10 @@ impl<'gc> EditText<'gc> {
|
|||
| TextControlCode::SelectRightLine
|
||||
| TextControlCode::SelectRightDocument
|
||||
| TextControlCode::SelectAll => self.is_selectable(),
|
||||
TextControlCode::Copy | TextControlCode::Cut => !selection.is_caret(),
|
||||
TextControlCode::Copy | TextControlCode::Cut => {
|
||||
!selection.is_caret()
|
||||
}
|
||||
TextControlCode::Paste => context.ui.clipboard_available(),
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
@ -1449,7 +1456,7 @@ impl<'gc> EditText<'gc> {
|
|||
control_code: TextControlCode,
|
||||
context: &mut UpdateContext<'_, 'gc>,
|
||||
) {
|
||||
if !self.is_text_control_applicable(control_code) {
|
||||
if !self.is_text_control_applicable(control_code, context) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1525,8 +1532,15 @@ impl<'gc> EditText<'gc> {
|
|||
let text = &self.text()[selection.start()..selection.end()];
|
||||
context.ui.set_clipboard_content(text.to_string());
|
||||
}
|
||||
TextControlCode::Paste => {
|
||||
TextControlCode::Paste => 'paste: {
|
||||
let text = context.ui.clipboard_content();
|
||||
if text.is_empty() {
|
||||
// When the clipboard is empty, nothing is pasted
|
||||
// and the already selected text is not removed.
|
||||
// Note that if the clipboard is not empty, but does not have
|
||||
// any allowed characters, the selected text is removed.
|
||||
break 'paste;
|
||||
}
|
||||
|
||||
let mut text = self.0.read().restrict.filter_allowed(&text);
|
||||
|
||||
|
|
|
@ -222,6 +222,12 @@ impl UiBackend for WebUiBackend {
|
|||
self.clipboard_content.to_owned()
|
||||
}
|
||||
|
||||
fn clipboard_available(&mut self) -> bool {
|
||||
// On web, we have to assume that the clipboard
|
||||
// is available due to the JS `paste` event.
|
||||
true
|
||||
}
|
||||
|
||||
fn set_clipboard_content(&mut self, content: String) {
|
||||
self.clipboard_content = content.to_owned();
|
||||
// We use `document.execCommand("copy")` as `navigator.clipboard.writeText("string")`
|
||||
|
|
Loading…
Reference in New Issue