1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-19 16:58:48 +02:00

Use pseudoelements, not Zero Width Space, to implement copy/paste behavior in Paste/Diffusion

Summary:
Depends on D19348. Ref T13105. When copying text from Paste or Diffusion, we'd like to copy only source, not line numbers.

We currently accomplish this with zero-width spaces plus a trigger that fires on "copy" in Paste and Diffusion. This is quite gross.

In the new-style Harbormaster logs, we use an approach that seems slightly better: CSS psuedoelements.

This isn't a complete solution (see also PHI504 / T5032) but puts us in a slightly better place.

Use it in Paste/Files/Diffusion too.

This gives us good behavior in all browsers in Files and Paste.

This gives us good behavior in Chrome and Firefox in Diffusion. Safari will copy (but not visually select) blame information in Diffusion. I think we can live with that for now.

Test Plan: Selected and copy/pasted stuff in Diffusion, Files, and Paste. Got good behavior everywhere except Safari + Diffusion.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13105

Differential Revision: https://secure.phabricator.com/D19349
This commit is contained in:
epriestley 2018-04-11 14:23:25 -07:00
parent c5c53e277a
commit 5b3a351852
4 changed files with 23 additions and 32 deletions

View file

@ -119,7 +119,7 @@ return array(
'rsrc/css/font/font-lato.css' => 'c7ccd872', 'rsrc/css/font/font-lato.css' => 'c7ccd872',
'rsrc/css/font/phui-font-icon-base.css' => '870a7360', 'rsrc/css/font/phui-font-icon-base.css' => '870a7360',
'rsrc/css/layout/phabricator-filetree-view.css' => 'b912ad97', 'rsrc/css/layout/phabricator-filetree-view.css' => 'b912ad97',
'rsrc/css/layout/phabricator-source-code-view.css' => 'c5edc888', 'rsrc/css/layout/phabricator-source-code-view.css' => '09368218',
'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494', 'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494',
'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68', 'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68',
'rsrc/css/phui/button/phui-button.css' => '1863cc6e', 'rsrc/css/phui/button/phui-button.css' => '1863cc6e',
@ -471,7 +471,7 @@ return array(
'rsrc/js/core/behavior-keyboard-pager.js' => 'a8da01f0', 'rsrc/js/core/behavior-keyboard-pager.js' => 'a8da01f0',
'rsrc/js/core/behavior-keyboard-shortcuts.js' => '01fca1f0', 'rsrc/js/core/behavior-keyboard-shortcuts.js' => '01fca1f0',
'rsrc/js/core/behavior-lightbox-attachments.js' => '6b31879a', 'rsrc/js/core/behavior-lightbox-attachments.js' => '6b31879a',
'rsrc/js/core/behavior-line-linker.js' => '69837bed', 'rsrc/js/core/behavior-line-linker.js' => '36165eb1',
'rsrc/js/core/behavior-more.js' => 'a80d0378', 'rsrc/js/core/behavior-more.js' => 'a80d0378',
'rsrc/js/core/behavior-object-selector.js' => '77c1f0b0', 'rsrc/js/core/behavior-object-selector.js' => '77c1f0b0',
'rsrc/js/core/behavior-oncopy.js' => '2926fff2', 'rsrc/js/core/behavior-oncopy.js' => '2926fff2',
@ -634,7 +634,7 @@ return array(
'javelin-behavior-phabricator-gesture-example' => '558829c2', 'javelin-behavior-phabricator-gesture-example' => '558829c2',
'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0', 'javelin-behavior-phabricator-keyboard-pager' => 'a8da01f0',
'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0', 'javelin-behavior-phabricator-keyboard-shortcuts' => '01fca1f0',
'javelin-behavior-phabricator-line-linker' => '69837bed', 'javelin-behavior-phabricator-line-linker' => '36165eb1',
'javelin-behavior-phabricator-nav' => '94b7c320', 'javelin-behavior-phabricator-nav' => '94b7c320',
'javelin-behavior-phabricator-notification-example' => '8ce821c5', 'javelin-behavior-phabricator-notification-example' => '8ce821c5',
'javelin-behavior-phabricator-object-selector' => '77c1f0b0', 'javelin-behavior-phabricator-object-selector' => '77c1f0b0',
@ -780,7 +780,7 @@ return array(
'phabricator-search-results-css' => '505dd8cf', 'phabricator-search-results-css' => '505dd8cf',
'phabricator-shaped-request' => '7cbe244b', 'phabricator-shaped-request' => '7cbe244b',
'phabricator-slowvote-css' => 'a94b7230', 'phabricator-slowvote-css' => 'a94b7230',
'phabricator-source-code-view-css' => 'c5edc888', 'phabricator-source-code-view-css' => '09368218',
'phabricator-standard-page-view' => '34ee718b', 'phabricator-standard-page-view' => '34ee718b',
'phabricator-textareautils' => '320810c8', 'phabricator-textareautils' => '320810c8',
'phabricator-title' => '485aaa6c', 'phabricator-title' => '485aaa6c',
@ -1098,6 +1098,12 @@ return array(
'javelin-dom', 'javelin-dom',
'javelin-vector', 'javelin-vector',
), ),
'36165eb1' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-history',
),
'3ab51e2c' => array( '3ab51e2c' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-behavior-device', 'javelin-behavior-device',
@ -1407,12 +1413,6 @@ return array(
'javelin-dom', 'javelin-dom',
'phuix-button-view', 'phuix-button-view',
), ),
'69837bed' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-dom',
'javelin-history',
),
'69adf288' => array( '69adf288' => array(
'javelin-install', 'javelin-install',
), ),

View file

@ -66,7 +66,6 @@ final class PhabricatorSourceCodeView extends AphrontView {
require_celerity_resource('phabricator-source-code-view-css'); require_celerity_resource('phabricator-source-code-view-css');
require_celerity_resource('syntax-highlighting-css'); require_celerity_resource('syntax-highlighting-css');
Javelin::initBehavior('phabricator-oncopy', array());
if ($this->canClickHighlight) { if ($this->canClickHighlight) {
Javelin::initBehavior('phabricator-line-linker'); Javelin::initBehavior('phabricator-line-linker');
} }
@ -78,11 +77,11 @@ final class PhabricatorSourceCodeView extends AphrontView {
$lines = $this->lines; $lines = $this->lines;
if ($this->truncatedFirstLines) { if ($this->truncatedFirstLines) {
$lines[] = phutil_tag( $lines[] = phutil_tag(
'span', 'span',
array( array(
'class' => 'c', 'class' => 'c',
), ),
pht('...')); pht('...'));
} else if ($this->truncatedFirstBytes) { } else if ($this->truncatedFirstBytes) {
$last_key = last_key($lines); $last_key = last_key($lines);
$lines[$last_key] = hsprintf( $lines[$last_key] = hsprintf(
@ -98,9 +97,6 @@ final class PhabricatorSourceCodeView extends AphrontView {
$base_uri = (string)$this->uri; $base_uri = (string)$this->uri;
foreach ($lines as $line) { foreach ($lines as $line) {
// NOTE: See phabricator-oncopy behavior.
$content_line = hsprintf("\xE2\x80\x8B%s", $line);
$row_attributes = array(); $row_attributes = array();
if (isset($this->highlights[$line_number])) { if (isset($this->highlights[$line_number])) {
$row_attributes['class'] = 'phabricator-source-highlight'; $row_attributes['class'] = 'phabricator-source-highlight';
@ -117,8 +113,8 @@ final class PhabricatorSourceCodeView extends AphrontView {
'a', 'a',
array( array(
'href' => $line_href, 'href' => $line_href,
), 'data-n' => $line_number,
$line_number); ));
} else { } else {
$tag_number = phutil_tag( $tag_number = phutil_tag(
'span', 'span',
@ -172,7 +168,7 @@ final class PhabricatorSourceCodeView extends AphrontView {
array( array(
'class' => 'phabricator-source-code', 'class' => 'phabricator-source-code',
), ),
$content_line), $line),
)); ));
$line_number++; $line_number++;

View file

@ -25,16 +25,11 @@
text-align: right; text-align: right;
border-right: 1px solid {$paste.border}; border-right: 1px solid {$paste.border};
color: {$sh-yellowtext}; color: {$sh-yellowtext};
}
/* When the user selects rows of source, don't visibly select the line .phabricator-source-line > a::before {
numbers beside them. We use JS to strip the line numbers out when the user /* Render the line numbers as a pseudo-element so they don't get copied. */
copies the text. */ content: attr(data-n);
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
} }
th.phabricator-source-line a, th.phabricator-source-line a,

View file

@ -29,7 +29,7 @@ JX.behavior('phabricator-line-linker', function() {
} }
} }
return +(th.textContent || th.innerText); return null;
} }
JX.Stratcom.listen( JX.Stratcom.listen(