Skip to content

Commit

Permalink
fix: Chat input: can't send html text from the clipboard
Browse files Browse the repository at this point in the history
We always take the plain text from the clipboard but even the plaintext
can contain HTML tags, so escape those and wrap the result in a `<div
style='white-space: pre-wrap'>foo</div>` container. That way we preserve
not only the linebreaks but also any whitespace or tags.

Fixes #8919
  • Loading branch information
caybro committed Jan 5, 2023
1 parent 63104bb commit e947f81
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 15 deletions.
3 changes: 3 additions & 0 deletions src/app/global/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ QtObject:
proc plainText*(self: Utils, text: string): string {.slot.} =
result = plain_text(text)

proc escapeHtml*(self: Utils, text: string): string {.slot.} =
result = escape_html(text)

proc getEmojiHashAsJson*(self: Utils, publicKey: string): string {.slot.} =
procs_from_visual_identity_service.getEmojiHashAsJson(publicKey)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ StatusModal {
root.close()
}

d.senderPublicKey = request.from,
d.senderPublicKey = request.from
d.senderDisplayName = request.displayName
d.senderIcon = request.icon
d.challengeText = request.challenge
Expand Down
15 changes: 7 additions & 8 deletions ui/imports/shared/status/StatusChatInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,10 @@ Rectangle {
} else if (event.key === Qt.Key_Escape && control.isReply) {
control.isReply = false
event.accepted = true
} else if (event.key === Qt.Key_Up && getPlainText() == "") {
} else if (event.key === Qt.Key_Up && messageInputField.length === 0) {
event.accepted = true
control.keyUpPress()
return
return
}

const symbolPressed = event.text.length > 0 &&
Expand Down Expand Up @@ -458,8 +458,8 @@ Rectangle {
d.copyTextStart = messageInputField.cursorPosition
messageInputField.readOnly = true

const clipboardText = globalUtils.plainText(QClipboardProxy.text)
const copiedText = globalUtils.plainText(d.copiedTextPlain)
const clipboardText = Utils.plainText(QClipboardProxy.text)
const copiedText = Utils.plainText(d.copiedTextPlain)
if (copiedText === clipboardText) {
d.internalPaste = true
} else {
Expand Down Expand Up @@ -574,7 +574,7 @@ Rectangle {

const deparsedEmoji = StatusQUtils.Emoji.deparse(textWithoutMention);

return globalUtils.plainText(deparsedEmoji)
return Utils.plainText(deparsedEmoji)
}

function removeMentions(currentText) {
Expand Down Expand Up @@ -717,9 +717,8 @@ Rectangle {
insertInTextInput(d.copyTextStart, d.copiedTextFormatted)
messageInputField.cursorPosition = d.copyTextStart + messageInputField.length - prevLength
d.internalPaste = false
} else if (event.matches(StandardKey.Paste)) {
insertInTextInput(d.copyTextStart, QClipboardProxy.text)
messageInputField.cursorPosition = d.copyTextStart + QClipboardProxy.text.length
} else if (event.matches(StandardKey.Paste) && QClipboardProxy.hasText) {
messageInputField.insert(d.copyTextStart, "<div style='white-space: pre-wrap'>" + Utils.escapeHtml(QClipboardProxy.text) + "</div>") // preserve formatting
}

if (event.key !== Qt.Key_Escape) {
Expand Down
11 changes: 5 additions & 6 deletions ui/imports/utils/Utils.qml
Original file line number Diff line number Diff line change
Expand Up @@ -731,12 +731,11 @@ QtObject {
}

function escapeHtml(unsafeStr) {
return unsafeStr
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
return globalUtilsInst.escapeHtml(unsafeStr)
}

function plainText(text) {
return globalUtilsInst.plainText(text)
}

function isInvalidPasswordMessage(msg) {
Expand Down

0 comments on commit e947f81

Please sign in to comment.