diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/copy_as_gfm.js.es6 | 64 | ||||
-rw-r--r-- | app/assets/javascripts/shortcuts_issuable.js | 16 |
2 files changed, 55 insertions, 25 deletions
diff --git a/app/assets/javascripts/copy_as_gfm.js.es6 b/app/assets/javascripts/copy_as_gfm.js.es6 index 0d1e9b0a952..63291853548 100644 --- a/app/assets/javascripts/copy_as_gfm.js.es6 +++ b/app/assets/javascripts/copy_as_gfm.js.es6 @@ -231,20 +231,13 @@ let clipboardData = e.originalEvent.clipboardData; if (!clipboardData) return; - if (!window.getSelection) return; - - let selection = window.getSelection(); - if (!selection.rangeCount || selection.rangeCount === 0) return; - - let selectedDocument = selection.getRangeAt(0).cloneContents(); - if (!selectedDocument) return; - - if (selectedDocument.textContent.length === 0) return; + let documentFragment = CopyAsGFM.getSelectedFragment(); + if (!documentFragment) return; e.preventDefault(); - clipboardData.setData('text/plain', selectedDocument.textContent); + clipboardData.setData('text/plain', documentFragment.textContent); - let gfm = CopyAsGFM.nodeToGFM(selectedDocument); + let gfm = CopyAsGFM.nodeToGFM(documentFragment); clipboardData.setData('text/x-gfm', gfm); } @@ -257,11 +250,25 @@ e.preventDefault(); - this.insertText(e.target, gfm); + CopyAsGFM.insertText(e.target, gfm); } - insertText(target, text) { - // Firefox doesn't support `document.execCommand('insertText', false, text);` on textareas + static getSelectedFragment() { + if (!window.getSelection) return null; + + let selection = window.getSelection(); + if (!selection.rangeCount || selection.rangeCount === 0) return null; + + let documentFragment = selection.getRangeAt(0).cloneContents(); + if (!documentFragment) return null; + + if (documentFragment.textContent.length === 0) return null; + + return documentFragment; + } + + static insertText(target, text) { + // Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas let selectionStart = target.selectionStart; let selectionEnd = target.selectionEnd; @@ -292,7 +299,7 @@ for (let selector in rules) { let func = rules[selector]; - if (!node.matches(selector)) continue; + if (!CopyAsGFM.nodeMatchesSelector(node, selector)) continue; let result = func(node, text); if (result === false) continue; @@ -315,11 +322,38 @@ let clonedNode = clonedNodes[i]; let text = this.nodeToGFM(node); + + // `clonedNode.replaceWith(text)` is not yet widely supported clonedNode.parentNode.replaceChild(document.createTextNode(text), clonedNode); } return clonedParentNode.innerText || clonedParentNode.textContent; } + + static nodeMatchesSelector(node, selector) { + let matches = Element.prototype.matches || + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector; + + if (matches) { + return matches.call(node, selector); + } + + // IE11 doesn't support `node.matches(selector)` + + let parentNode = node.parentNode; + if (!parentNode) { + parentNode = document.createElement('div'); + node = node.cloneNode(true); + parentNode.appendChild(node); + } + + let matchingNodes = parentNode.querySelectorAll(selector); + return Array.prototype.indexOf.call(matchingNodes, node) !== -1; + } } window.gl = window.gl || {}; diff --git a/app/assets/javascripts/shortcuts_issuable.js b/app/assets/javascripts/shortcuts_issuable.js index 426821873d7..e9ede122ab7 100644 --- a/app/assets/javascripts/shortcuts_issuable.js +++ b/app/assets/javascripts/shortcuts_issuable.js @@ -39,26 +39,22 @@ } ShortcutsIssuable.prototype.replyWithSelectedText = function() { - var quote, replyField, selectedDocument, selected, selection, separator; - if (!window.getSelection) return; + var quote, replyField, documentFragment, selected, separator; - selection = window.getSelection(); - if (!selection.rangeCount || selection.rangeCount === 0) return; + documentFragment = window.gl.CopyAsGFM.getSelectedFragment(); + if (!documentFragment) return; - selectedDocument = selection.getRangeAt(0).cloneContents(); - if (!selectedDocument) return; - - selected = window.gl.CopyAsGFM.nodeToGFM(selectedDocument); + selected = window.gl.CopyAsGFM.nodeToGFM(documentFragment); replyField = $('.js-main-target-form #note_note'); if (selected.trim() === "") { return; } quote = _.map(selected.split("\n"), function(val) { - return "> " + val + "\n"; + return ("> " + val).trim() + "\n"; }); // If replyField already has some content, add a newline before our quote - separator = replyField.val().trim() !== "" && "\n" || ''; + separator = replyField.val().trim() !== "" && "\n\n" || ''; replyField.val(function(_, current) { return current + separator + quote.join('') + "\n"; }); |