mediawiki-extensions-Visual.../modules/ve-mw/dm/nodes/ve.dm.MWGalleryNode.js
Bartosz Dziewoński 26062fd3a0 ve.dm.MWGalleryNode: Preserve 'class' attribute unchanged
By removing this line, we fall back to the default behavior,
which is to copy the attribute from the original DOM element.

The gallery is supposed to have a class indicating the type (packed,
traditional, etc.). However, Parsoid doesn't care about that and
instead reads the type from 'data-mw'. Instead, changing the attribute
is causing dirty diffs.

Bug: T214649
Change-Id: I96b5a21777046b1caf07a3b1def9fad81bb15939
2020-02-14 22:05:50 +01:00

130 lines
3.3 KiB
JavaScript

/*!
* VisualEditor DataModel MWGalleryNode class.
*
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* DataModel MediaWiki gallery node.
*
* @class
* @extends ve.dm.BranchNode
* @mixins ve.dm.FocusableNode
*
* @constructor
* @param {Object} [element] Reference to element in linear model
*/
ve.dm.MWGalleryNode = function VeDmMWGalleryNode() {
// Parent constructor
ve.dm.MWGalleryNode.super.apply( this, arguments );
// Mixin constructors
ve.dm.FocusableNode.call( this );
};
/* Inheritance */
OO.inheritClass( ve.dm.MWGalleryNode, ve.dm.BranchNode );
OO.mixinClass( ve.dm.MWGalleryNode, ve.dm.FocusableNode );
/* Static members */
ve.dm.MWGalleryNode.static.name = 'mwGallery';
ve.dm.MWGalleryNode.static.matchRdfaTypes = [ 'mw:Extension/gallery' ];
ve.dm.MWGalleryNode.static.matchTagNames = [ 'ul' ];
ve.dm.MWGalleryNode.static.childNodeTypes = [ 'mwGalleryCaption', 'mwGalleryImage' ];
ve.dm.MWGalleryNode.static.blacklistedAnnotationTypes = [ 'link' ];
ve.dm.MWGalleryNode.static.cloneElement = function () {
// Parent method
var clone = ve.dm.LeafNode.static.cloneElement.apply( this, arguments );
delete clone.attributes.originalMw;
return clone;
};
ve.dm.MWGalleryNode.static.getHashObject = function ( dataElement ) {
return {
type: dataElement.type,
mw: ve.copy( dataElement.attributes.mw )
};
};
ve.dm.MWGalleryNode.static.toDataElement = function ( domElements ) {
var mwDataJSON = domElements[ 0 ].getAttribute( 'data-mw' ),
mwData = mwDataJSON ? JSON.parse( mwDataJSON ) : {};
return {
type: this.name,
attributes: {
mw: mwData,
originalMw: mwDataJSON
}
};
};
ve.dm.MWGalleryNode.static.toDomElements = function ( data, doc ) {
var ul = doc.createElement( 'ul' );
// Build ul
ul.setAttribute( 'typeof', 'mw:Extension/gallery' );
ul.setAttribute( 'data-mw', JSON.stringify( data.attributes.mw ) );
return [ ul ];
};
ve.dm.MWGalleryNode.static.describeChanges = function ( attributeChanges, attributes, element ) {
// Only do a comparison on the 'mw.attrs' attribute
if ( attributeChanges.mw ) {
return ve.dm.MWGalleryNode.super.static.describeChanges.call(
this,
ve.ui.DiffElement.static.compareAttributes( attributeChanges.mw.from.attrs || {}, attributeChanges.mw.to.attrs || {} ),
attributes,
element
);
}
return [];
};
ve.dm.MWGalleryNode.static.describeChange = function ( key ) {
// Caption diff is shown in the DOM
if ( key === 'caption' ) {
return null;
}
// Parent method
return ve.dm.MWGalleryNode.super.static.describeChange.apply( this, arguments );
};
/* Methods */
/**
* Get the gallery's caption node.
*
* @return {ve.dm.MWImageCaptionNode|null} Caption node, if present
*/
ve.dm.MWGalleryNode.prototype.getCaptionNode = function () {
var node = this.children[ 0 ];
return node instanceof ve.dm.MWGalleryCaptionNode ? node : null;
};
/**
* Get the gallery's image nodes.
*
* @return {ve.dm.MWGalleryImageNode[]} Gallery image nodes (may be empty if none are present)
*/
ve.dm.MWGalleryNode.prototype.getImageNodes = function () {
var images = this.children.filter( function ( child ) {
return child instanceof ve.dm.MWGalleryImageNode;
} );
return images;
};
/* Registration */
ve.dm.modelRegistry.register( ve.dm.MWGalleryNode );