mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40: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:
parent
3e6bfda0ca
commit
26c836e1e1
2 changed files with 46 additions and 61 deletions
|
@ -8,7 +8,7 @@ return array(
|
||||||
'names' =>
|
'names' =>
|
||||||
array(
|
array(
|
||||||
'core.pkg.css' => 'fb144113',
|
'core.pkg.css' => 'fb144113',
|
||||||
'core.pkg.js' => 'd3fecc57',
|
'core.pkg.js' => 'e39d336b',
|
||||||
'darkconsole.pkg.js' => 'ca8671ce',
|
'darkconsole.pkg.js' => 'ca8671ce',
|
||||||
'differential.pkg.css' => 'cc216438',
|
'differential.pkg.css' => 'cc216438',
|
||||||
'differential.pkg.js' => '11a5b750',
|
'differential.pkg.js' => '11a5b750',
|
||||||
|
@ -463,7 +463,7 @@ return array(
|
||||||
'rsrc/js/core/behavior-line-linker.js' => 'bc778103',
|
'rsrc/js/core/behavior-line-linker.js' => 'bc778103',
|
||||||
'rsrc/js/core/behavior-more.js' => '9b9197be',
|
'rsrc/js/core/behavior-more.js' => '9b9197be',
|
||||||
'rsrc/js/core/behavior-object-selector.js' => 'b4eef37b',
|
'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-nav.js' => 'b5842a5e',
|
||||||
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a',
|
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a',
|
||||||
'rsrc/js/core/behavior-refresh-csrf.js' => 'c4b31646',
|
'rsrc/js/core/behavior-refresh-csrf.js' => 'c4b31646',
|
||||||
|
@ -596,7 +596,7 @@ return array(
|
||||||
'javelin-behavior-phabricator-nav' => 'b5842a5e',
|
'javelin-behavior-phabricator-nav' => 'b5842a5e',
|
||||||
'javelin-behavior-phabricator-notification-example' => 'c51a6616',
|
'javelin-behavior-phabricator-notification-example' => 'c51a6616',
|
||||||
'javelin-behavior-phabricator-object-selector' => 'b4eef37b',
|
'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-remarkup-assist' => 'c021950a',
|
||||||
'javelin-behavior-phabricator-reveal-content' => '8f24abfc',
|
'javelin-behavior-phabricator-reveal-content' => '8f24abfc',
|
||||||
'javelin-behavior-phabricator-search-typeahead' => 'f6b56f7a',
|
'javelin-behavior-phabricator-search-typeahead' => 'f6b56f7a',
|
||||||
|
@ -1634,6 +1634,11 @@ return array(
|
||||||
2 => 'javelin-util',
|
2 => 'javelin-util',
|
||||||
3 => 'javelin-magical-init',
|
3 => 'javelin-magical-init',
|
||||||
),
|
),
|
||||||
|
'c3e218fe' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-dom',
|
||||||
|
),
|
||||||
'c4b31646' =>
|
'c4b31646' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-request',
|
0 => 'javelin-request',
|
||||||
|
@ -1768,11 +1773,6 @@ return array(
|
||||||
1 => 'javelin-util',
|
1 => 'javelin-util',
|
||||||
2 => 'javelin-stratcom',
|
2 => 'javelin-stratcom',
|
||||||
),
|
),
|
||||||
'dab9253e' =>
|
|
||||||
array(
|
|
||||||
0 => 'javelin-behavior',
|
|
||||||
1 => 'javelin-dom',
|
|
||||||
),
|
|
||||||
'dd7e8ef5' =>
|
'dd7e8ef5' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
|
|
|
@ -18,63 +18,48 @@ JX.behavior('phabricator-oncopy', function() {
|
||||||
|
|
||||||
var zws = "\u200B"; // Unicode Zero-Width Space
|
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 selection;
|
||||||
var text = selection.toString();
|
var text;
|
||||||
|
if (window.getSelection) {
|
||||||
if (text.indexOf(zws) == -1) {
|
selection = window.getSelection();
|
||||||
// If there's no marker in the text, just let it copy normally.
|
text = selection.toString();
|
||||||
return;
|
} else {
|
||||||
}
|
selection = document.selection;
|
||||||
|
text = selection.createRange().text;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
result.push(lines[ii].substring(pos + 1));
|
|
||||||
}
|
|
||||||
result = result.join("\n");
|
|
||||||
|
|
||||||
if (e.clipboardData) {
|
if (text.indexOf(zws) == -1) {
|
||||||
// Safari and Chrome support this easy, straightforward mechanism.
|
// If there's no marker in the text, just let it copy normally.
|
||||||
e.clipboardData.setData('Text', result);
|
return;
|
||||||
e.preventDefault();
|
}
|
||||||
} else {
|
|
||||||
|
|
||||||
// In Firefox, we have to create a <pre> and select the text in it, then
|
var result = [];
|
||||||
// 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 style = {
|
// Strip everything before the marker (and the marker itself) out of the
|
||||||
position: 'absolute',
|
// text. If a line doesn't have the marker, throw it away (the assumption
|
||||||
left: '-10000px'
|
// is that it's a line number or part of some other meta-text).
|
||||||
};
|
var lines = text.split("\n");
|
||||||
var pre = JX.$N('pre', {style: style}, result);
|
var pos;
|
||||||
document.body.appendChild(pre);
|
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 rawEvent = e.getRawEvent();
|
||||||
var range = document.createRange();
|
var clipboardData = 'clipboardData' in rawEvent ?
|
||||||
range.selectNodeContents(pre);
|
rawEvent.clipboardData :
|
||||||
selection.removeAllRanges();
|
window.clipboardData;
|
||||||
selection.addRange(range);
|
clipboardData.setData('Text', result);
|
||||||
|
e.prevent();
|
||||||
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?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue