Fix ShortcutsIssuable#replyWithSelectedText tests
This commit is contained in:
parent
72620ea1b7
commit
6089ece098
|
@ -231,20 +231,13 @@
|
||||||
let clipboardData = e.originalEvent.clipboardData;
|
let clipboardData = e.originalEvent.clipboardData;
|
||||||
if (!clipboardData) return;
|
if (!clipboardData) return;
|
||||||
|
|
||||||
if (!window.getSelection) return;
|
let documentFragment = CopyAsGFM.getSelectedFragment();
|
||||||
|
if (!documentFragment) 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;
|
|
||||||
|
|
||||||
e.preventDefault();
|
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);
|
clipboardData.setData('text/x-gfm', gfm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,11 +250,25 @@
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.insertText(e.target, gfm);
|
CopyAsGFM.insertText(e.target, gfm);
|
||||||
}
|
}
|
||||||
|
|
||||||
insertText(target, text) {
|
static getSelectedFragment() {
|
||||||
// Firefox doesn't support `document.execCommand('insertText', false, text);` on textareas
|
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 selectionStart = target.selectionStart;
|
||||||
let selectionEnd = target.selectionEnd;
|
let selectionEnd = target.selectionEnd;
|
||||||
|
@ -292,7 +299,7 @@
|
||||||
for (let selector in rules) {
|
for (let selector in rules) {
|
||||||
let func = rules[selector];
|
let func = rules[selector];
|
||||||
|
|
||||||
if (!node.matches(selector)) continue;
|
if (!CopyAsGFM.nodeMatchesSelector(node, selector)) continue;
|
||||||
|
|
||||||
let result = func(node, text);
|
let result = func(node, text);
|
||||||
if (result === false) continue;
|
if (result === false) continue;
|
||||||
|
@ -315,11 +322,38 @@
|
||||||
let clonedNode = clonedNodes[i];
|
let clonedNode = clonedNodes[i];
|
||||||
|
|
||||||
let text = this.nodeToGFM(node);
|
let text = this.nodeToGFM(node);
|
||||||
|
|
||||||
|
// `clonedNode.replaceWith(text)` is not yet widely supported
|
||||||
clonedNode.parentNode.replaceChild(document.createTextNode(text), clonedNode);
|
clonedNode.parentNode.replaceChild(document.createTextNode(text), clonedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clonedParentNode.innerText || clonedParentNode.textContent;
|
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 || {};
|
window.gl = window.gl || {};
|
||||||
|
|
|
@ -39,26 +39,22 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
ShortcutsIssuable.prototype.replyWithSelectedText = function() {
|
ShortcutsIssuable.prototype.replyWithSelectedText = function() {
|
||||||
var quote, replyField, selectedDocument, selected, selection, separator;
|
var quote, replyField, documentFragment, selected, separator;
|
||||||
if (!window.getSelection) return;
|
|
||||||
|
|
||||||
selection = window.getSelection();
|
documentFragment = window.gl.CopyAsGFM.getSelectedFragment();
|
||||||
if (!selection.rangeCount || selection.rangeCount === 0) return;
|
if (!documentFragment) return;
|
||||||
|
|
||||||
selectedDocument = selection.getRangeAt(0).cloneContents();
|
selected = window.gl.CopyAsGFM.nodeToGFM(documentFragment);
|
||||||
if (!selectedDocument) return;
|
|
||||||
|
|
||||||
selected = window.gl.CopyAsGFM.nodeToGFM(selectedDocument);
|
|
||||||
|
|
||||||
replyField = $('.js-main-target-form #note_note');
|
replyField = $('.js-main-target-form #note_note');
|
||||||
if (selected.trim() === "") {
|
if (selected.trim() === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
quote = _.map(selected.split("\n"), function(val) {
|
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
|
// 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) {
|
replyField.val(function(_, current) {
|
||||||
return current + separator + quote.join('') + "\n";
|
return current + separator + quote.join('') + "\n";
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* eslint-disable space-before-function-paren, no-return-assign, no-var, quotes, padded-blocks */
|
/* eslint-disable space-before-function-paren, no-return-assign, no-var, quotes, padded-blocks */
|
||||||
/* global ShortcutsIssuable */
|
/* global ShortcutsIssuable */
|
||||||
|
|
||||||
|
/*= require copy_as_gfm */
|
||||||
/*= require shortcuts_issuable */
|
/*= require shortcuts_issuable */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -14,10 +15,12 @@
|
||||||
});
|
});
|
||||||
return describe('#replyWithSelectedText', function() {
|
return describe('#replyWithSelectedText', function() {
|
||||||
var stubSelection;
|
var stubSelection;
|
||||||
// Stub window.getSelection to return the provided String.
|
// Stub window.gl.CopyAsGFM.getSelectedFragment to return a node with the provided HTML.
|
||||||
stubSelection = function(text) {
|
stubSelection = function(html) {
|
||||||
return window.getSelection = function() {
|
window.gl.CopyAsGFM.getSelectedFragment = function() {
|
||||||
return text;
|
var node = document.createElement('div');
|
||||||
|
node.innerHTML = html;
|
||||||
|
return node;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
@ -32,13 +35,13 @@
|
||||||
});
|
});
|
||||||
describe('with any selection', function() {
|
describe('with any selection', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return stubSelection('Selected text.');
|
return stubSelection('<p>Selected text.</p>');
|
||||||
});
|
});
|
||||||
it('leaves existing input intact', function() {
|
it('leaves existing input intact', function() {
|
||||||
$(this.selector).val('This text was already here.');
|
$(this.selector).val('This text was already here.');
|
||||||
expect($(this.selector).val()).toBe('This text was already here.');
|
expect($(this.selector).val()).toBe('This text was already here.');
|
||||||
this.shortcut.replyWithSelectedText();
|
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() {
|
it('triggers `input`', function() {
|
||||||
var triggered;
|
var triggered;
|
||||||
|
@ -61,16 +64,16 @@
|
||||||
});
|
});
|
||||||
describe('with a one-line selection', function() {
|
describe('with a one-line selection', function() {
|
||||||
return it('quotes the 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();
|
this.shortcut.replyWithSelectedText();
|
||||||
return expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
|
return expect($(this.selector).val()).toBe("> This text has been selected.\n\n");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return describe('with a multi-line selection', function() {
|
return describe('with a multi-line selection', function() {
|
||||||
return it('quotes the selected lines as a group', 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();
|
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