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

Change subject: Preserve data-mw verbatim if unchanged
......................................................................


Preserve data-mw verbatim if unchanged

Previously we would reserialize the JSON blob in data-mw even if we
didn't change it, which potentially reordered keys and caused a DOM
diff.

Bug: 50066
Change-Id: If0a5bcc67d3a172de0e8839cfda11efacfbf36ff
---
M modules/ve/dm/nodes/ve.dm.MWReferenceListNode.js
M modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
M modules/ve/dm/nodes/ve.dm.MWTransclusionNode.js
M modules/ve/test/dm/ve.dm.example.js
4 files changed, 49 insertions(+), 11 deletions(-)

Approvals:
  Krinkle: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/ve/dm/nodes/ve.dm.MWReferenceListNode.js 
b/modules/ve/dm/nodes/ve.dm.MWReferenceListNode.js
index 2e3a82c..c1698c8 100644
--- a/modules/ve/dm/nodes/ve.dm.MWReferenceListNode.js
+++ b/modules/ve/dm/nodes/ve.dm.MWReferenceListNode.js
@@ -43,6 +43,7 @@
                'type': this.name,
                'attributes': {
                        'mw': mwData,
+                       'origMw': mwDataJSON,
                        'about': domElements[0].getAttribute( 'about' ),
                        'domElements': ve.copyArray( domElements ),
                        'refGroup': refGroup,
@@ -52,7 +53,7 @@
 };
 
 ve.dm.MWReferenceListNode.static.toDomElements = function ( dataElement, doc ) 
{
-       var el, els, mwData,
+       var el, els, mwData, origMw,
                attribs = dataElement.attributes;
 
        if ( attribs.domElements ) {
@@ -78,7 +79,15 @@
                el.setAttribute( 'about', attribs.about );
        }
        el.setAttribute( 'typeof', 'mw:Extension/references' );
-       el.setAttribute( 'data-mw', JSON.stringify( mwData ) );
+
+       // If mwData and origMw are the same, use origMw to prevent 
reserialization.
+       // Reserialization has the potential to reorder keys and so change the 
DOM unnecessarily
+       origMw = attribs.origMw;
+       if ( origMw && ve.compare( mwData, JSON.parse( origMw ) ) ) {
+               el.setAttribute( 'data-mw', origMw );
+       } else {
+               el.setAttribute( 'data-mw', JSON.stringify( mwData ) );
+       }
 
        return els;
 };
diff --git a/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js 
b/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
index 36a25af..63b85f7 100644
--- a/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
+++ b/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
@@ -56,6 +56,7 @@
                'type': this.name,
                'attributes': {
                        'mw': mwData,
+                       'origMw': mwDataJSON,
                        'about': about,
                        'listIndex': listIndex,
                        'listGroup': listGroup,
@@ -68,7 +69,7 @@
 };
 
 ve.dm.MWReferenceNode.static.toDomElements = function ( dataElement, doc, 
converter ) {
-       var itemNodeHtml, mwAttr, i, iLen, keyedNodes, setContents,
+       var itemNodeHtml, mwAttr, i, iLen, keyedNodes, setContents, origMw,
                span = doc.createElement( 'span' ),
                itemNodeWrapper = doc.createElement( 'div' ),
                itemNode = converter.internalList.getItemNode( 
dataElement.attributes.listIndex ),
@@ -124,7 +125,14 @@
                delete mwAttr.attrs.refGroup;
        }
 
-       span.setAttribute( 'data-mw', JSON.stringify( mwAttr ) );
+       // If mwAttr and origMw are the same, use origMw to prevent 
reserialization.
+       // Reserialization has the potential to reorder keys and so change the 
DOM unnecessarily
+       origMw = dataElement.attributes.origMw;
+       if ( origMw && ve.compare( mwAttr, JSON.parse( origMw ) ) ) {
+               span.setAttribute( 'data-mw', origMw );
+       } else {
+               span.setAttribute( 'data-mw', JSON.stringify( mwAttr ) );
+       }
 
        return [ span ];
 };
diff --git a/modules/ve/dm/nodes/ve.dm.MWTransclusionNode.js 
b/modules/ve/dm/nodes/ve.dm.MWTransclusionNode.js
index 5661320..e3b6746 100644
--- a/modules/ve/dm/nodes/ve.dm.MWTransclusionNode.js
+++ b/modules/ve/dm/nodes/ve.dm.MWTransclusionNode.js
@@ -60,14 +60,16 @@
 
 ve.dm.MWTransclusionNode.static.toDataElement = function ( domElements, 
converter ) {
        var dataElement, index,
-               mw = JSON.parse( domElements[0].getAttribute( 'data-mw' ) ),
+               mwDataJSON = domElements[0].getAttribute( 'data-mw' ),
+               mwData = mwDataJSON ? JSON.parse( mwDataJSON ) : {},
                isInline = this.isHybridInline( domElements, converter ),
                type = isInline ? 'mwTransclusionInline' : 
'mwTransclusionBlock';
 
        dataElement = {
                'type': type,
                'attributes': {
-                       'mw': mw
+                       'mw': mwData,
+                       'origMw': mwDataJSON
                }
        };
 
@@ -79,13 +81,17 @@
 
 ve.dm.MWTransclusionNode.static.toDomElements = function ( dataElement, doc, 
converter ) {
        var span,
-               index = converter.getStore().indexOfHash( ve.getHash( 
this.getHashObject( dataElement ) ) );
+               index = converter.getStore().indexOfHash( ve.getHash( 
this.getHashObject( dataElement ) ) ),
+               origMw = dataElement.attributes.origMw;
 
        // If the transclusion is unchanged just send back the
        // original DOM elements so selser can skip over it
-       if ( index === dataElement.attributes.originalIndex ) {
+       if (
+               index === dataElement.attributes.originalIndex ||
+               ( origMw && ve.compare( dataElement.attributes.mw, JSON.parse( 
origMw ) ) )
+       ) {
                // The object in the store is also used for CE rendering so 
return a copy
-               return ve.copyArray( converter.getStore().value( index ) );
+               return ve.copyDomElements( converter.getStore().value( index ), 
doc );
        } else {
                span = doc.createElement( 'span' );
                // All we need to send back to Parsoid is the original 
transclusion marker, with a
diff --git a/modules/ve/test/dm/ve.dm.example.js 
b/modules/ve/test/dm/ve.dm.example.js
index 83278d1..e5c30c7 100644
--- a/modules/ve/test/dm/ve.dm.example.js
+++ b/modules/ve/test/dm/ve.dm.example.js
@@ -857,7 +857,7 @@
 
 ve.dm.example.MWInlineImageHtml = '<span typeof="mw:Image" 
data-parsoid="{&quot;tsr&quot;:[0,24],&quot;optList&quot;:[{&quot;ck&quot;:&quot;width&quot;,&quot;ak&quot;:&quot;500px&quot;}],&quot;cacheKey&quot;:&quot;[[Image:Wiki.png|500px]]&quot;,&quot;img&quot;:{&quot;h&quot;:155,&quot;w&quot;:135,&quot;wdset&quot;:true},&quot;dsr&quot;:[0,24,null,null]}"><a
 href="./File:Wiki.png" 
data-parsoid="{&quot;a&quot;:{&quot;href&quot;:&quot;./File:Wiki.png&quot;}}"><img
 resource="./File:Wiki.png" 
src="http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png"; height="155" 
width="135" 
data-parsoid="{&quot;a&quot;:{&quot;resource&quot;:&quot;./File:Wiki.png&quot;,&quot;width&quot;:&quot;135&quot;},&quot;sa&quot;:{&quot;resource&quot;:&quot;Image:Wiki.png&quot;,&quot;width&quot;:&quot;500&quot;}}"></a></span>';
 ve.dm.example.MWTransclusion = {
-       'blockSpan':         '<span about="#mwt1" typeof="mw:Transclusion" 
data-mw="{&quot;id&quot;:&quot;mwt1&quot;,&quot;target&quot;:{&quot;wt&quot;:&quot;Test&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Hello,
 world!&quot;}}}" 
data-parsoid="{&quot;tsr&quot;:[18,40],&quot;src&quot;:&quot;{{Test|Hello, 
world!}}&quot;,&quot;dsr&quot;:[18,40,null,null]}"></span>',
+       'blockSpan':         '<span about="#mwt1" typeof="mw:Transclusion" 
data-mw="{&quot;target&quot;:{&quot;wt&quot;:&quot;Test&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Hello,
 world!&quot;}},&quot;id&quot;:&quot;mwt1&quot;}" 
data-parsoid="{&quot;tsr&quot;:[18,40],&quot;src&quot;:&quot;{{Test|Hello, 
world!}}&quot;,&quot;dsr&quot;:[18,40,null,null]}"></span>',
        'blockSpanModified': '<span about="#mwt1" typeof="mw:Transclusion" 
data-mw="{&quot;id&quot;:&quot;mwt1&quot;,&quot;target&quot;:{&quot;wt&quot;:&quot;Test&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Hello,
 globe!&quot;}}}" 
data-parsoid="{&quot;tsr&quot;:[18,40],&quot;src&quot;:&quot;{{Test|Hello, 
world!}}&quot;,&quot;dsr&quot;:[18,40,null,null]}"></span>',
        'blockContent': '<p about="#mwt1" data-parsoid="{}">Hello, world!</p>',
        'blockData': {
@@ -870,12 +870,13 @@
                                        '1': { 'wt': 'Hello, world!' }
                                }
                        },
+                       'origMw': 
'{\"target\":{\"wt\":\"Test\"},\"params\":{\"1\":{\"wt\":\"Hello, 
world!\"}},\"id\":\"mwt1\"}',
                        'originalIndex': 0
                },
                'htmlAttributes': [
                        { 'values': {
                                'about': '#mwt1',
-                               'data-mw': 
'{\"id\":\"mwt1\",\"target\":{\"wt\":\"Test\"},\"params\":{\"1\":{\"wt\":\"Hello,
 world!\"}}}',
+                               'data-mw': 
'{\"target\":{\"wt\":\"Test\"},\"params\":{\"1\":{\"wt\":\"Hello, 
world!\"}},\"id\":\"mwt1\"}',
                                'data-parsoid': 
'{\"tsr\":[18,40],\"src\":\"{{Test|Hello, 
world!}}\",\"dsr\":[18,40,null,null]}',
                                'typeof': 'mw:Transclusion'
                        } },
@@ -899,6 +900,7 @@
                                        '1': { 'wt': '1,234' }
                                }
                        },
+                       'origMw': 
'{\"id\":\"mwt1\",\"target\":{\"wt\":\"Inline\"},\"params\":{\"1\":{\"wt\":\"1,234\"}}}',
                        'originalIndex': 0
                },
                'htmlAttributes': [ { 'values': {
@@ -919,6 +921,7 @@
                                        '1': { 'wt': '5,678' }
                                }
                        },
+                       'origMw': 
'{\"id\":\"mwt1\",\"target\":{\"wt\":\"Inline\"},\"params\":{\"1\":{\"wt\":\"5,678\"}}}',
                        'originalIndex': 0
                },
                'htmlAttributes': [
@@ -1148,6 +1151,7 @@
                                        'listKey': 'bar',
                                        'refGroup': '',
                                        'mw': { 'body': { 'html': '' }, 
'attrs': { 'name': 'bar' } },
+                                       'origMw': 
'{"body":{"html":""},"attrs":{"name":"bar"}}',
                                        'contentsUsed': false
                                },
                                'htmlAttributes': [
@@ -1182,6 +1186,7 @@
                                        'listKey': 'quux',
                                        'refGroup': '',
                                        'mw': { 'body': { 'html': 'Quux' }, 
'attrs': { 'name': 'quux' } },
+                                       'origMw': 
'{"body":{"html":"Quux"},"attrs":{"name":"quux"}}',
                                        'contentsUsed': true
                                },
                                'htmlAttributes': [
@@ -1216,6 +1221,7 @@
                                        'listKey': 'bar',
                                        'refGroup': '',
                                        'mw': { 'body': { 'html': 'Bar' }, 
'attrs': { 'name': 'bar' } },
+                                       'origMw': 
'{"body":{"html":"Bar"},"attrs":{"name":"bar"}}',
                                        'contentsUsed': true
                                },
                                'htmlAttributes': [
@@ -1250,6 +1256,7 @@
                                        'listKey': null,
                                        'refGroup': 'g1',
                                        'mw': { 'body': { 'html': 'No name' }, 
'attrs': { 'group': 'g1' } },
+                                       'origMw': '{"body":{"html":"No 
name"},"attrs":{"group":"g1"}}',
                                        'contentsUsed': true
                                },
                                'htmlAttributes': [
@@ -1283,6 +1290,7 @@
                                                'name': 'references',
                                                'attrs': {}
                                        },
+                                       'origMw': 
'{"name":"references","attrs":{}}',
                                        'domElements': $(
                                                '<ol class="references" 
about="#mwt12" typeof="mw:Extension/references" '+
                                                        
'data-mw="{&quot;name&quot;:&quot;references&quot;,&quot;attrs&quot;:{}}" ' +
@@ -3449,6 +3457,7 @@
                                'body': { 'html': 'No name 1' },
                                'name': 'ref'
                        },
+                       'origMw': '{"name":"ref","body":{"html":"No name 
1"},"attrs":{}}',
                        'refGroup': ''
                },
                'htmlAttributes': [ { 'values': {
@@ -3478,6 +3487,7 @@
                                'body': { 'html': 'Bar' },
                                'name': 'ref'
                        },
+                       'origMw': '{"body":{"html":""},"attrs":{"name":"bar"}}',
                        'refGroup': ''
                },
                'htmlAttributes': [ { 'values': {
@@ -3505,6 +3515,7 @@
                                'body': { 'html': 'Quux' },
                                'name': 'ref'
                        },
+                       'origMw': 
'{"name":"ref","body":{"html":"Quux"},"attrs":{"name":"quux"}}',
                        'refGroup': ''
                },
                'htmlAttributes': [ { 'values': {
@@ -3531,6 +3542,7 @@
                                'attrs': { 'name': 'bar' },
                                'name': 'ref'
                        },
+                       'origMw': '{"body":{"html":""},"attrs":{"name":"bar"}}',
                        'refGroup': ''
                },
                'htmlAttributes': [ { 'values': {
@@ -3560,6 +3572,7 @@
                                'body': { 'html': 'No name 2' },
                                'name': 'ref'
                        },
+                       'origMw': '{"name":"ref","body":{"html":"No name 
2"},"attrs":{}}',
                        'refGroup': ''
                        },
                'htmlAttributes': [ { 'values': {
@@ -3586,6 +3599,7 @@
                                'body': { 'html': 'No name 3' },
                                'name': 'ref'
                        },
+                       'origMw': '{"name":"ref","body":{"html":"No name 
3"},"attrs":{}}',
                        'refGroup': ''
                },
                'htmlAttributes': [ { 'values': {
@@ -3608,6 +3622,7 @@
                                'name': 'references',
                                'attrs': {}
                        },
+                       'origMw': '{"name":"references","attrs":{}"}',
                        //'domElements': HTML,
                        'listGroup': 'mwReference/',
                        'refGroup': ''

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

Gerrit-MessageType: merged
Gerrit-Change-Id: If0a5bcc67d3a172de0e8839cfda11efacfbf36ff
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: jenkins-bot

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

Reply via email to