1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-18 11:30:55 +01:00

Simplify oncopy behavior

Summary:
Firefox has supported clipboardData since version 22 (Jul 2013), and even IE8 supports it if you look at `window.clipboardData` instead of `e.clipboardData`. As a result, we can simplify this code significantly.

I also used (or at least, attempted to) Javelin so that we can get the event object and preventDefault more easily. Plus, this way we don't assign to document.body.oncopy.

Test Plan: Copied a selection including a line number in Chrome, Firefox, and IE8. The line number didn't get copied.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: epriestley, Korvin

Differential Revision: https://secure.phabricator.com/D8688
This commit is contained in:
Ben Alpert 2014-04-03 09:20:55 -07:00 committed by epriestley
parent 3e6bfda0ca
commit 26c836e1e1
2 changed files with 46 additions and 61 deletions

View file

@ -8,7 +8,7 @@ return array(
'names' =>
array(
'core.pkg.css' => 'fb144113',
'core.pkg.js' => 'd3fecc57',
'core.pkg.js' => 'e39d336b',
'darkconsole.pkg.js' => 'ca8671ce',
'differential.pkg.css' => 'cc216438',
'differential.pkg.js' => '11a5b750',
@ -463,7 +463,7 @@ return array(
'rsrc/js/core/behavior-line-linker.js' => 'bc778103',
'rsrc/js/core/behavior-more.js' => '9b9197be',
'rsrc/js/core/behavior-object-selector.js' => 'b4eef37b',
'rsrc/js/core/behavior-oncopy.js' => 'dab9253e',
'rsrc/js/core/behavior-oncopy.js' => 'c3e218fe',
'rsrc/js/core/behavior-phabricator-nav.js' => 'b5842a5e',
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a',
'rsrc/js/core/behavior-refresh-csrf.js' => 'c4b31646',
@ -596,7 +596,7 @@ return array(
'javelin-behavior-phabricator-nav' => 'b5842a5e',
'javelin-behavior-phabricator-notification-example' => 'c51a6616',
'javelin-behavior-phabricator-object-selector' => 'b4eef37b',
'javelin-behavior-phabricator-oncopy' => 'dab9253e',
'javelin-behavior-phabricator-oncopy' => 'c3e218fe',
'javelin-behavior-phabricator-remarkup-assist' => 'c021950a',
'javelin-behavior-phabricator-reveal-content' => '8f24abfc',
'javelin-behavior-phabricator-search-typeahead' => 'f6b56f7a',
@ -1634,6 +1634,11 @@ return array(
2 => 'javelin-util',
3 => 'javelin-magical-init',
),
'c3e218fe' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'c4b31646' =>
array(
0 => 'javelin-request',
@ -1768,11 +1773,6 @@ return array(
1 => 'javelin-util',
2 => 'javelin-stratcom',
),
'dab9253e' =>
array(
0 => 'javelin-behavior',
1 => 'javelin-dom',
),
'dd7e8ef5' =>
array(
0 => 'javelin-behavior',

View file

@ -18,63 +18,48 @@ JX.behavior('phabricator-oncopy', function() {
var zws = "\u200B"; // Unicode Zero-Width Space
document.body.oncopy = function(e) {
JX.enableDispatch(document.body, 'copy');
JX.Stratcom.listen(
['copy'],
null,
function(e) {
var selection = window.getSelection();
var text = selection.toString();
if (text.indexOf(zws) == -1) {
// If there's no marker in the text, just let it copy normally.
return;
}
var result = [];
// Strip everything before the marker (and the marker itself) out of the
// text. If a line doesn't have the marker, throw it away (the assumption
// is that it's a line number or part of some other meta-text).
var lines = text.split("\n");
var pos;
for (var ii = 0; ii < lines.length; ii++) {
pos = lines[ii].indexOf(zws);
if (pos == -1 && ii !== 0) {
continue;
var selection;
var text;
if (window.getSelection) {
selection = window.getSelection();
text = selection.toString();
} else {
selection = document.selection;
text = selection.createRange().text;
}
result.push(lines[ii].substring(pos + 1));
}
result = result.join("\n");
if (e.clipboardData) {
// Safari and Chrome support this easy, straightforward mechanism.
e.clipboardData.setData('Text', result);
e.preventDefault();
} else {
if (text.indexOf(zws) == -1) {
// If there's no marker in the text, just let it copy normally.
return;
}
// In Firefox, we have to create a <pre> and select the text in it, then
// let the copy event fire. It has to be a <pre> because Firefox won't
// copy returns properly out of a div, even if it has 'whitespace: pre'.
// There's been a bug open for 10 (!) years:
//
// https://bugzilla.mozilla.org/show_bug.cgi?id=116083
var result = [];
var style = {
position: 'absolute',
left: '-10000px'
};
var pre = JX.$N('pre', {style: style}, result);
document.body.appendChild(pre);
// Strip everything before the marker (and the marker itself) out of the
// text. If a line doesn't have the marker, throw it away (the assumption
// is that it's a line number or part of some other meta-text).
var lines = text.split("\n");
var pos;
for (var ii = 0; ii < lines.length; ii++) {
pos = lines[ii].indexOf(zws);
if (pos == -1 && ii !== 0) {
continue;
}
result.push(lines[ii].substring(pos + 1));
}
result = result.join("\n");
// Select the text in the <pre>.
var range = document.createRange();
range.selectNodeContents(pre);
selection.removeAllRanges();
selection.addRange(range);
setTimeout(function() { JX.DOM.remove(pre); }, 0);
// TODO: I tried to restore the old selection range but it doesn't seem
// to work or give me any errors. So you lose your selection when you
// copy. Oh well?
}
};
var rawEvent = e.getRawEvent();
var clipboardData = 'clipboardData' in rawEvent ?
rawEvent.clipboardData :
window.clipboardData;
clipboardData.setData('Text', result);
e.prevent();
});
});