Fix ShortcutsIssuable#replyWithSelectedText tests
This commit is contained in:
parent
72620ea1b7
commit
6089ece098
|
@ -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 || {};
|
||||
|
|
|
@ -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";
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable space-before-function-paren, no-return-assign, no-var, quotes, padded-blocks */
|
||||
/* global ShortcutsIssuable */
|
||||
|
||||
/*= require copy_as_gfm */
|
||||
/*= require shortcuts_issuable */
|
||||
|
||||
(function() {
|
||||
|
@ -14,10 +15,12 @@
|
|||
});
|
||||
return describe('#replyWithSelectedText', function() {
|
||||
var stubSelection;
|
||||
// Stub window.getSelection to return the provided String.
|
||||
stubSelection = function(text) {
|
||||
return window.getSelection = function() {
|
||||
return text;
|
||||
// Stub window.gl.CopyAsGFM.getSelectedFragment to return a node with the provided HTML.
|
||||
stubSelection = function(html) {
|
||||
window.gl.CopyAsGFM.getSelectedFragment = function() {
|
||||
var node = document.createElement('div');
|
||||
node.innerHTML = html;
|
||||
return node;
|
||||
};
|
||||
};
|
||||
beforeEach(function() {
|
||||
|
@ -32,13 +35,13 @@
|
|||
});
|
||||
describe('with any selection', function() {
|
||||
beforeEach(function() {
|
||||
return stubSelection('Selected text.');
|
||||
return stubSelection('<p>Selected text.</p>');
|
||||
});
|
||||
it('leaves existing input intact', function() {
|
||||
$(this.selector).val('This text was already here.');
|
||||
expect($(this.selector).val()).toBe('This text was already here.');
|
||||
this.shortcut.replyWithSelectedText();
|
||||
return expect($(this.selector).val()).toBe("This text was already here.\n> Selected text.\n\n");
|
||||
return expect($(this.selector).val()).toBe("This text was already here.\n\n> Selected text.\n\n");
|
||||
});
|
||||
it('triggers `input`', function() {
|
||||
var triggered;
|
||||
|
@ -61,16 +64,16 @@
|
|||
});
|
||||
describe('with a one-line selection', function() {
|
||||
return it('quotes the selection', function() {
|
||||
stubSelection('This text has been selected.');
|
||||
stubSelection('<p>This text has been selected.</p>');
|
||||
this.shortcut.replyWithSelectedText();
|
||||
return expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
|
||||
});
|
||||
});
|
||||
return describe('with a multi-line selection', function() {
|
||||
return it('quotes the selected lines as a group', function() {
|
||||
stubSelection("Selected line one.\n\nSelected line two.\nSelected line three.\n");
|
||||
stubSelection("<p>Selected line one.</p>\n\n<p>Selected line two.</p>\n\n<p>Selected line three.</p>");
|
||||
this.shortcut.replyWithSelectedText();
|
||||
return expect($(this.selector).val()).toBe("> Selected line one.\n> Selected line two.\n> Selected line three.\n\n");
|
||||
return expect($(this.selector).val()).toBe("> Selected line one.\n>\n> Selected line two.\n>\n> Selected line three.\n\n");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue