From 8887be9e914be166d3b7f7740a406d31257c5be0 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sun, 8 May 2016 08:31:56 +0200 Subject: [PATCH] Improve copying of element text Slack uses markdown-style backtick syntax for code spans. Example: one `code` two This is the rendered HTML for the above: one `code` two Previously, `.textContent` was used to copy element text. Because those backticks actually are there in the DOM, they get copied too. However, that's unexpected because they're not visible. The `yv` command is supposed to be equivalent to `zvy`, but this meant that it wasn't. This commit instead creates an actual selection and then invokes Firefox's `cmd_copy` command (which is exactly what `zv` followed by `y` does). A difference is that now you can see the created selection flash for a split second, but I actually like that visual feedback. This fix also has a positive effect on the `yf` command when copying `contenteditable` elements. Take this markup:
T
Then type `onetwo` in it. Finally, copy the element using `yf`. Before, you'd get this: ``` onetwo ``` Now, you get the expected result: ``` one two ``` --- extension/lib/commands-frame.coffee | 10 +++++----- extension/lib/commands.coffee | 25 ++++++++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/extension/lib/commands-frame.coffee b/extension/lib/commands-frame.coffee index fb6113e..7707bab 100644 --- a/extension/lib/commands-frame.coffee +++ b/extension/lib/commands-frame.coffee @@ -334,16 +334,14 @@ commands.copy_marker_element = ({vim, elementIndex, property}) -> {element} = vim.state.markerElements[elementIndex] utils.writeToClipboard(element[property]) -commands.element_text_select = ({vim, elementIndex, full}) -> +commands.element_text_select = ({vim, elementIndex, full, scroll = false}) -> {element} = vim.state.markerElements[elementIndex] window = element.ownerGlobal selection = window.getSelection() range = window.document.createRange() - if full - range.selectNodeContents(element) - - # Try to scroll the element into view, but keep the caret visible. + # Try to scroll the element into view, but keep the caret visible. + if scroll viewport = viewportUtils.getWindowViewport(window) rect = element.getBoundingClientRect() block = switch @@ -363,6 +361,8 @@ commands.element_text_select = ({vim, elementIndex, full}) -> behavior: if smooth then 'smooth' else 'instant' }) + if full + range.selectNodeContents(element) else result = viewportUtils.getFirstNonWhitespace(element) if result diff --git a/extension/lib/commands.coffee b/extension/lib/commands.coffee index 0f7cfb8..323036a 100644 --- a/extension/lib/commands.coffee +++ b/extension/lib/commands.coffee @@ -517,15 +517,14 @@ commands.follow_multiple = (args) -> commands.follow_copy = ({vim}) -> callback = (marker) -> - {elementIndex} = marker.wrapper property = switch marker.wrapper.type when 'link' 'href' when 'text' 'value' when 'contenteditable', 'other' - 'textContent' - vim._run('copy_marker_element', {elementIndex, property}) + '_selection' + helper_copy_marker_element(vim, marker.wrapper.elementIndex, property) helper_follow('follow_copy', vim, callback) commands.follow_focus = ({vim}) -> @@ -612,6 +611,7 @@ helper_follow_selectable = ({select}, {vim}) -> vim._run('element_text_select', { elementIndex: marker.wrapper.elementIndex full: select + scroll: select }) vim.enterMode('caret', select) helper_follow('follow_selectable', vim, callback) @@ -624,12 +624,23 @@ commands.element_text_select = commands.element_text_copy = ({vim}) -> callback = (marker) -> - vim._run('copy_marker_element', { - elementIndex: marker.wrapper.elementIndex - property: 'textContent' - }) + helper_copy_marker_element(vim, marker.wrapper.elementIndex, '_selection') helper_follow('follow_selectable', vim, callback) +helper_copy_marker_element = (vim, elementIndex, property) -> + if property == '_selection' + # Selecting the text and then copying that selection is better than copying + # `.textContent`. Slack uses markdown-style backtick syntax for code spans + # and then includes those backticks in the compiled output (!), in hidden + # ``s, so `.textContent` would copy those too. In `contenteditable` + # elements, text selection gives better whitespace than `.textContent`. + vim._run('element_text_select', {elementIndex, full: true}, -> + vim.window.goDoCommand('cmd_copy') # See `caret.copy_selection_and_exit`. + vim._run('clear_selection') + ) + else + vim._run('copy_marker_element', {elementIndex, property}) + findStorage = {lastSearchString: ''} -- 2.39.3