jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/327774 )

Change subject: Unwrap single pasted content branch nodes
......................................................................


Unwrap single pasted content branch nodes

This usually means the user selected just text, but
the browser added the surrounding node (e.g. header) to the
paste context.

Bug: T153249
Change-Id: Icd3bb68bb072883eb408c0fb1e754f0f0e49d860
---
M src/ce/ve.ce.Surface.js
M tests/ce/ve.ce.Surface.test.js
2 files changed, 84 insertions(+), 7 deletions(-)

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



diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index e24a747..ec04f41 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -1889,7 +1889,7 @@
                $elements, pasteData, slice, internalListRange,
                data, pastedDocumentModel, htmlDoc, $body, $images, i,
                context, left, right, contextRange, pastedText, handled,
-               tableAction, htmlBlacklist,
+               tableAction, htmlBlacklist, pastedNodes,
                items = [],
                metadataIdRegExp = ve.init.platform.getMetadataIdRegExp(),
                importantElement = '[id],[typeof],[rel]',
@@ -2162,9 +2162,10 @@
                        targetFragment.removeContent();
                }
 
+               internalListRange = 
pastedDocumentModel.getInternalList().getListNode().getOuterRange();
+
                // If the paste was given context, calculate the range of the 
inserted data
                if ( beforePasteData.context ) {
-                       internalListRange = 
pastedDocumentModel.getInternalList().getListNode().getOuterRange();
                        context = new ve.dm.ElementLinearData(
                                pastedDocumentModel.getStore(),
                                ve.copy( beforePasteData.context )
@@ -2204,6 +2205,23 @@
                                right--;
                        }
                        contextRange = new ve.Range( left, right );
+               } else {
+                       contextRange = new ve.Range( 0, internalListRange.start 
);
+               }
+               pastedNodes = pastedDocumentModel.selectNodes( contextRange, 
'siblings' ).filter( function ( node ) {
+                       // Ignore nodes where nothing is selected
+                       return !( node.range && node.range.isCollapsed() );
+               } );
+
+               // Unwrap single content branch nodes to match internal 
copy/paste behaviour
+               // (which wouldn't put the open and close tags in the clipboard 
to begin with).
+               if (
+                       pastedNodes.length === 1 &&
+                       pastedNodes[ 0 ].node instanceof ve.dm.ContentBranchNode
+               ) {
+                       if ( contextRange.containsRange( pastedNodes[ 0 
].nodeRange ) ) {
+                               contextRange = pastedNodes[ 0 ].nodeRange;
+                       }
                }
 
                // If the external HTML turned out to be plain text after
diff --git a/tests/ce/ve.ce.Surface.test.js b/tests/ce/ve.ce.Surface.test.js
index 7b9fbbe..9f27080 100644
--- a/tests/ce/ve.ce.Surface.test.js
+++ b/tests/ce/ve.ce.Surface.test.js
@@ -2003,19 +2003,21 @@
                                expectedOps: [
                                        [
                                                {
+                                                       type: 'retain',
+                                                       length: 1
+                                               },
+                                               {
                                                        type: 'replace',
                                                        insert: [
-                                                               { type: 
'paragraph', internal: { generated: 'wrapper' } },
                                                                { type: 
'alienInline' },
-                                                               { type: 
'/alienInline' },
-                                                               { type: 
'/paragraph' }
+                                                               { type: 
'/alienInline' }
                                                        ],
                                                        remove: []
                                                },
-                                               { type: 'retain', length: 
docLen }
+                                               { type: 'retain', length: 
docLen - 1 }
                                        ]
                                ],
-                               expectedRangeOrSelection: new ve.Range( 4 ),
+                               expectedRangeOrSelection: new ve.Range( 3 ),
                                msg: 'Paste API HTML used if important 
attributes dropped'
                        },
                        {
@@ -2720,6 +2722,63 @@
                                        ]
                                ],
                                msg: 'Empty paragraph kept in internal paste'
+                       },
+                       {
+                               rangeOrSelection: new ve.Range( 0 ),
+                               pasteTargetHtml: '<h3>A</h3>',
+                               expectedOps: [
+                                       [
+                                               {
+                                                       type: 'replace',
+                                                       insert: [
+                                                               { type: 
'paragraph' },
+                                                               'A',
+                                                               { type: 
'/paragraph' }
+                                                       ],
+                                                       remove: []
+                                               },
+                                               { type: 'retain', length: 
docLen }
+                                       ]
+                               ],
+                               msg: 'Non-paragraph content branch node 
converted to paragraph'
+                       },
+                       {
+                               rangeOrSelection: new ve.Range( 5 ),
+                               pasteHtml: '<h3>A</h3>',
+                               expectedOps: [
+                                       [
+                                               {
+                                                       type: 'retain',
+                                                       length: 5
+                                               },
+                                               {
+                                                       type: 'replace',
+                                                       insert: [ 'A' ],
+                                                       remove: []
+                                               },
+                                               { type: 'retain', length: 
docLen - 5 }
+                                       ]
+                               ],
+                               msg: 'Non-paragraph content branch node 
converted to paragraph when in paragraph'
+                       },
+                       {
+                               rangeOrSelection: new ve.Range( 6 ),
+                               pasteHtml: '<h3>A</h3>',
+                               expectedOps: [
+                                       [
+                                               {
+                                                       type: 'retain',
+                                                       length: 6
+                                               },
+                                               {
+                                                       type: 'replace',
+                                                       insert: [ 'A' ],
+                                                       remove: []
+                                               },
+                                               { type: 'retain', length: 
docLen - 6 }
+                                       ]
+                               ],
+                               msg: 'Non-paragraph content branch node 
converted to paragraph at end of paragraph'
                        }
                ];
 

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Icd3bb68bb072883eb408c0fb1e754f0f0e49d860
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <esand...@wikimedia.org>
Gerrit-Reviewer: DLynch <dly...@wikimedia.org>
Gerrit-Reviewer: Divec <da...@troi.org>
Gerrit-Reviewer: Jforrester <jforres...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to