wikimedia/mediawiki-extensions-VisualEditor

View on GitHub
modules/ve-mw/dm/nodes/ve.dm.MWGalleryNode.js

Summary

Maintainability
B
5 hrs
Test Coverage
/*!
 * VisualEditor DataModel MWGalleryNode class.
 *
 * @copyright See AUTHORS.txt
 * @license The MIT License (MIT); see LICENSE.txt
 */

/**
 * DataModel MediaWiki gallery node.
 *
 * @class
 * @extends ve.dm.BranchNode
 * @mixes 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.disallowedAnnotationTypes = [ 'link' ];

ve.dm.MWGalleryNode.static.cloneElement = function () {
    // Parent method
    const 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 ) {
    const 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 ) {
    const 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 */

ve.dm.MWGalleryNode.prototype.isDiffedAsDocument = function () {
    return true;
};

/**
 * Get the gallery's caption node.
 *
 * @return {ve.dm.MWImageCaptionNode|null} Caption node, if present
 */
ve.dm.MWGalleryNode.prototype.getCaptionNode = function () {
    const 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 () {
    const images = this.children.filter( ( child ) => child instanceof ve.dm.MWGalleryImageNode );
    return images;
};

/* Registration */

ve.dm.modelRegistry.register( ve.dm.MWGalleryNode );