@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Ben Alpert and committed by
epriestley
26c836e1 3e6bfda0

+46 -61
+8 -8
resources/celerity/map.php
··· 8 8 'names' => 9 9 array( 10 10 'core.pkg.css' => 'fb144113', 11 - 'core.pkg.js' => 'd3fecc57', 11 + 'core.pkg.js' => 'e39d336b', 12 12 'darkconsole.pkg.js' => 'ca8671ce', 13 13 'differential.pkg.css' => 'cc216438', 14 14 'differential.pkg.js' => '11a5b750', ··· 463 463 'rsrc/js/core/behavior-line-linker.js' => 'bc778103', 464 464 'rsrc/js/core/behavior-more.js' => '9b9197be', 465 465 'rsrc/js/core/behavior-object-selector.js' => 'b4eef37b', 466 - 'rsrc/js/core/behavior-oncopy.js' => 'dab9253e', 466 + 'rsrc/js/core/behavior-oncopy.js' => 'c3e218fe', 467 467 'rsrc/js/core/behavior-phabricator-nav.js' => 'b5842a5e', 468 468 'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a', 469 469 'rsrc/js/core/behavior-refresh-csrf.js' => 'c4b31646', ··· 596 596 'javelin-behavior-phabricator-nav' => 'b5842a5e', 597 597 'javelin-behavior-phabricator-notification-example' => 'c51a6616', 598 598 'javelin-behavior-phabricator-object-selector' => 'b4eef37b', 599 - 'javelin-behavior-phabricator-oncopy' => 'dab9253e', 599 + 'javelin-behavior-phabricator-oncopy' => 'c3e218fe', 600 600 'javelin-behavior-phabricator-remarkup-assist' => 'c021950a', 601 601 'javelin-behavior-phabricator-reveal-content' => '8f24abfc', 602 602 'javelin-behavior-phabricator-search-typeahead' => 'f6b56f7a', ··· 1634 1634 2 => 'javelin-util', 1635 1635 3 => 'javelin-magical-init', 1636 1636 ), 1637 + 'c3e218fe' => 1638 + array( 1639 + 0 => 'javelin-behavior', 1640 + 1 => 'javelin-dom', 1641 + ), 1637 1642 'c4b31646' => 1638 1643 array( 1639 1644 0 => 'javelin-request', ··· 1767 1772 0 => 'javelin-install', 1768 1773 1 => 'javelin-util', 1769 1774 2 => 'javelin-stratcom', 1770 - ), 1771 - 'dab9253e' => 1772 - array( 1773 - 0 => 'javelin-behavior', 1774 - 1 => 'javelin-dom', 1775 1775 ), 1776 1776 'dd7e8ef5' => 1777 1777 array(
+38 -53
webroot/rsrc/js/core/behavior-oncopy.js
··· 18 18 19 19 var zws = "\u200B"; // Unicode Zero-Width Space 20 20 21 - document.body.oncopy = function(e) { 21 + JX.enableDispatch(document.body, 'copy'); 22 + JX.Stratcom.listen( 23 + ['copy'], 24 + null, 25 + function(e) { 22 26 23 - var selection = window.getSelection(); 24 - var text = selection.toString(); 27 + var selection; 28 + var text; 29 + if (window.getSelection) { 30 + selection = window.getSelection(); 31 + text = selection.toString(); 32 + } else { 33 + selection = document.selection; 34 + text = selection.createRange().text; 35 + } 25 36 26 - if (text.indexOf(zws) == -1) { 27 - // If there's no marker in the text, just let it copy normally. 28 - return; 29 - } 37 + if (text.indexOf(zws) == -1) { 38 + // If there's no marker in the text, just let it copy normally. 39 + return; 40 + } 30 41 31 - var result = []; 42 + var result = []; 32 43 33 - // Strip everything before the marker (and the marker itself) out of the 34 - // text. If a line doesn't have the marker, throw it away (the assumption 35 - // is that it's a line number or part of some other meta-text). 36 - var lines = text.split("\n"); 37 - var pos; 38 - for (var ii = 0; ii < lines.length; ii++) { 39 - pos = lines[ii].indexOf(zws); 40 - if (pos == -1 && ii !== 0) { 41 - continue; 44 + // Strip everything before the marker (and the marker itself) out of the 45 + // text. If a line doesn't have the marker, throw it away (the assumption 46 + // is that it's a line number or part of some other meta-text). 47 + var lines = text.split("\n"); 48 + var pos; 49 + for (var ii = 0; ii < lines.length; ii++) { 50 + pos = lines[ii].indexOf(zws); 51 + if (pos == -1 && ii !== 0) { 52 + continue; 53 + } 54 + result.push(lines[ii].substring(pos + 1)); 42 55 } 43 - result.push(lines[ii].substring(pos + 1)); 44 - } 45 - result = result.join("\n"); 56 + result = result.join("\n"); 46 57 47 - if (e.clipboardData) { 48 - // Safari and Chrome support this easy, straightforward mechanism. 49 - e.clipboardData.setData('Text', result); 50 - e.preventDefault(); 51 - } else { 52 - 53 - // In Firefox, we have to create a <pre> and select the text in it, then 54 - // let the copy event fire. It has to be a <pre> because Firefox won't 55 - // copy returns properly out of a div, even if it has 'whitespace: pre'. 56 - // There's been a bug open for 10 (!) years: 57 - // 58 - // https://bugzilla.mozilla.org/show_bug.cgi?id=116083 59 - 60 - var style = { 61 - position: 'absolute', 62 - left: '-10000px' 63 - }; 64 - var pre = JX.$N('pre', {style: style}, result); 65 - document.body.appendChild(pre); 66 - 67 - // Select the text in the <pre>. 68 - var range = document.createRange(); 69 - range.selectNodeContents(pre); 70 - selection.removeAllRanges(); 71 - selection.addRange(range); 72 - 73 - setTimeout(function() { JX.DOM.remove(pre); }, 0); 74 - 75 - // TODO: I tried to restore the old selection range but it doesn't seem 76 - // to work or give me any errors. So you lose your selection when you 77 - // copy. Oh well? 78 - } 79 - }; 58 + var rawEvent = e.getRawEvent(); 59 + var clipboardData = 'clipboardData' in rawEvent ? 60 + rawEvent.clipboardData : 61 + window.clipboardData; 62 + clipboardData.setData('Text', result); 63 + e.prevent(); 64 + }); 80 65 });