jenkins-bot has submitted this change and it was merged.

Change subject: Allow right click copy on focusable nodes
......................................................................


Allow right click copy on focusable nodes

Right click copy only works when there is a real text
(not image) selection underneath the mouse.

On right click:
* Hide drag drop markers with CSS.
* Select the focusable node highlight, which has a nbsp-
  containing span for selectability, and is made ce=true.
* Undo both of these things on the next tick after the
  menu has been shown.

Bug: T98589
Bug: T98650
Change-Id: I23609cdbe2762bdbe103fc3f010dd6ebaf7e9be1
---
M src/ce/styles/nodes/ve.ce.FocusableNode.css
M src/ce/ve.ce.FocusableNode.js
M src/ce/ve.ce.Surface.js
3 files changed, 43 insertions(+), 13 deletions(-)

Approvals:
  Jforrester: Looks good to me, but someone else must approve
  Trevor Parscal: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/src/ce/styles/nodes/ve.ce.FocusableNode.css 
b/src/ce/styles/nodes/ve.ce.FocusableNode.css
index a359702..ed70be7 100644
--- a/src/ce/styles/nodes/ve.ce.FocusableNode.css
+++ b/src/ce/styles/nodes/ve.ce.FocusableNode.css
@@ -39,6 +39,8 @@
        background: #6da9f7;
        box-shadow: inset 0 0 0 1px #4C76ac;
        position: absolute;
+       /* Clip extra span added for selectability */
+       overflow: hidden;
 }
 
 .ve-ce-focusableNode-highlight-relocatable-marker {
@@ -50,3 +52,13 @@
        background: #000;
        background: rgba(0, 0, 0, 1);
 }
+
+/* Prevent 'copy image' appearing in context menu */
+.ve-ce-focusableNode-highlights-contextOpen 
.ve-ce-focusableNode-highlight-relocatable-marker {
+       display: none;
+}
+
+.ve-ce-focusableNode-highlight-selectable {
+       position: absolute;
+       top: -1000px;
+}
diff --git a/src/ce/ve.ce.FocusableNode.js b/src/ce/ve.ce.FocusableNode.js
index b4a2f67..2384400 100644
--- a/src/ce/ve.ce.FocusableNode.js
+++ b/src/ce/ve.ce.FocusableNode.js
@@ -90,6 +90,7 @@
                        .addClass( 
've-ce-focusableNode-highlight-relocatable-marker' )
                        .attr( 'src', 
'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' )
                        .on( {
+                               mousedown: this.onFocusableMouseDown.bind( this 
),
                                dragstart: this.onFocusableDragStart.bind( this 
),
                                dragend: this.onFocusableDragEnd.bind( this )
                        } )
@@ -167,6 +168,7 @@
  */
 ve.ce.FocusableNode.prototype.onFocusableMouseDown = function ( e ) {
        var range,
+               node = this,
                surfaceModel = this.focusableSurface.getModel(),
                selection = surfaceModel.getSelection(),
                nodeRange = this.model.getOuterRange();
@@ -174,6 +176,20 @@
        if ( !this.isInContentEditable() ) {
                return;
        }
+       if ( e.which === 3 ) {
+               // Hide images, and select spans so context menu shows 'copy', 
but not 'copy image'
+               this.$highlights.addClass( 
've-ce-focusableNode-highlights-contextOpen' );
+               // Make ce=true so we get cut/paste options in context menu
+               this.$highlights.prop( 'contentEditable', 'true' );
+               ve.selectElement( this.$highlights[0] );
+               setTimeout( function () {
+                       // Undo everything as soon as the context menu is show
+                       node.$highlights.removeClass( 
've-ce-focusableNode-highlights-contextOpen' );
+                       node.$highlights.prop( 'contentEditable', 'true' );
+                       node.focusableSurface.preparePasteTargetForCopy();
+               } );
+       }
+
        // Wait for native selection to change before correcting
        setTimeout( function () {
                range = selection instanceof ve.dm.LinearSelection && 
selection.getRange();
@@ -545,7 +561,9 @@
        var i, l;
 
        this.calculateHighlights();
-       this.$highlights.empty();
+       this.$highlights.empty()
+               // Append something selectable for right-click copy
+               .append( $( '<span>' ).addClass( 
've-ce-focusableNode-highlight-selectable' ).html( '&nbsp;' ) );
 
        for ( i = 0, l = this.rects.length; i < l; i++ ) {
                this.$highlights.append(
diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index 89a1b2d..e2dd6f1 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -120,7 +120,7 @@
        this.debounceFocusChange = ve.debounce( this.onFocusChange ).bind( this 
);
        this.$document.on( 'mousedown', this.debounceFocusChange );
 
-       this.$pasteTarget.on( {
+       this.$pasteTarget.add( this.$highlights ).on( {
                cut: this.onCut.bind( this ),
                copy: this.onCopy.bind( this ),
                paste: this.onPaste.bind( this )
@@ -653,7 +653,8 @@
        hasFocus = OO.ui.contains(
                [
                        this.$documentNode[0],
-                       this.$pasteTarget[0]
+                       this.$pasteTarget[0],
+                       this.$highlights[0]
                ],
                this.nativeSelection.anchorNode,
                true
@@ -1681,12 +1682,15 @@
                        this.$window.scrollTop( scrollTop );
 
                        setTimeout( function () {
-                               // Change focus back
-                               view.$documentNode[0].focus();
-                               view.nativeSelection.removeAllRanges();
-                               view.nativeSelection.addRange( 
originalRange.cloneRange() );
-                               // Restore scroll position
-                               view.$window.scrollTop( scrollTop );
+                               // If the range was in $highlights (right-click 
copy), don't restore it
+                               if ( !OO.ui.contains( view.$highlights[0], 
originalRange.startContainer, true ) ) {
+                                       // Change focus back
+                                       view.$documentNode[0].focus();
+                                       view.nativeSelection.removeAllRanges();
+                                       view.nativeSelection.addRange( 
originalRange.cloneRange() );
+                                       // Restore scroll position
+                                       view.$window.scrollTop( scrollTop );
+                               }
                                view.surfaceObserver.clear();
                                view.surfaceObserver.enable();
                        } );
@@ -2803,7 +2807,6 @@
  *
  * @see ve.ce.FocusableNode
  *
- * @method
  * @param {ve.ce.Node} node Node being relocated
  */
 ve.ce.Surface.prototype.startRelocation = function ( node ) {
@@ -2815,9 +2818,6 @@
  * Complete a relocation action.
  *
  * @see ve.ce.FocusableNode
- *
- * @method
- * @param {ve.ce.Node} node Node being relocated
  */
 ve.ce.Surface.prototype.endRelocation = function () {
        if ( this.relocatingNode ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/209970
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I23609cdbe2762bdbe103fc3f010dd6ebaf7e9be1
Gerrit-PatchSet: 6
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Divec <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to