Merge "Preserve classes on media wrapper links"

This commit is contained in:
jenkins-bot 2022-03-10 20:35:59 +00:00 committed by Gerrit Code Review
commit beded65e85
8 changed files with 102 additions and 5 deletions

View file

@ -42,7 +42,6 @@ ve.ce.MWBlockImageNode = function VeCeMWBlockImageNode() {
$image = $( '<img>' )
.attr( 'src', this.getResolvedAttribute( 'src' ) );
this.$a = $( '<a>' )
.addClass( 'image' )
.attr( 'href', this.getResolvedAttribute( 'href' ) )
.append( $image );
$focusable = $image;

View file

@ -68,8 +68,7 @@ ve.ce.MWGalleryImageNode = function VeCeMWGalleryImageNode( model ) {
.css( 'height', innerDivHeight + 'px' );
var $innerDiv = $( '<span>' )
.css( 'margin', innerDivMargin );
var $a = $( '<a>' )
.addClass( 'image' );
var $a = $( '<a>' );
var $img = $( '<img>' )
.attr( 'resource', attributes.resource )
.attr( 'alt', attributes.altText )

View file

@ -26,7 +26,7 @@ ve.ce.MWInlineImageNode = function VeCeMWInlineImageNode( model, config ) {
$image = $( [] );
} else {
if ( model.getAttribute( 'href' ) ) {
this.$element = $( '<a>' ).addClass( 'image' );
this.$element = $( '<a>' );
$image = $( '<img>' ).appendTo( this.$element );
} else {
this.$element = $image = $( '<img>' );

View file

@ -47,6 +47,11 @@ ve.dm.MWImageModel = function VeDmMWImageModel( parentDoc, config ) {
this.imageResourceName = '';
this.imageHref = '';
// FIXME: This is blindly being preserved but may not apply if, say,
// a link is no longer pointing to a file description page. When support
// for editing the |link= media option is added, take it into account.
this.imgWrapperClassAttr = null;
this.boundingBox = null;
this.initialHash = {};
@ -179,6 +184,7 @@ ve.dm.MWImageModel.static.newFromImageAttributes = function ( attrs, parentDoc )
imgModel.setImageSource( attrs.src );
imgModel.setFilename( new mw.Title( mw.libs.ve.normalizeParsoidResourceName( attrs.resource ) ).getMainText() );
imgModel.setImageHref( attrs.href );
imgModel.setImgWrapperClassAttr( attrs.imgWrapperClassAttr );
// Set bounding box
imgModel.setBoundingBox( {
@ -279,6 +285,11 @@ ve.dm.MWImageModel.prototype.changeImageSource = function ( attrs, APIinfo ) {
if ( attrs.href ) {
this.setImageHref( attrs.href );
}
if ( attrs.imgWrapperClassAttr ) {
this.setImgWrapperClassAttr( attrs.imgWrapperClassAttr );
}
if ( attrs.resource ) {
this.setImageResourceName( attrs.resource );
this.setFilename( new mw.Title( mw.libs.ve.normalizeParsoidResourceName( attrs.resource ) ).getMainText() );
@ -565,6 +576,7 @@ ve.dm.MWImageModel.prototype.getUpdatedAttributes = function () {
attrs.src = this.getImageSource();
attrs.href = this.getImageHref();
attrs.imgWrapperClassAttr = this.getImgWrapperClassAttr();
attrs.resource = this.getImageResourceName();
return attrs;
@ -1122,6 +1134,20 @@ ve.dm.MWImageModel.prototype.getImageHref = function () {
return this.imageHref;
};
/**
* @param {string|null} classAttr
*/
ve.dm.MWImageModel.prototype.setImgWrapperClassAttr = function ( classAttr ) {
this.imgWrapperClassAttr = classAttr;
};
/**
* @return {string|null}
*/
ve.dm.MWImageModel.prototype.getImgWrapperClassAttr = function () {
return this.imgWrapperClassAttr;
};
/**
* Attach a new scalable object to the model and request the
* information from the API.

View file

@ -98,6 +98,7 @@ ve.dm.MWBlockImageNode.static.toDataElement = function ( domElements, converter
type: types.frameType,
src: img.getAttribute( 'src' ) || img.getAttribute( 'poster' ),
href: href,
imgWrapperClassAttr: imgWrapper.getAttribute( 'class' ),
resource: img.getAttribute( 'resource' ),
width: width !== null && width !== '' ? +width : null,
height: height !== null && height !== '' ? +height : null,
@ -183,6 +184,11 @@ ve.dm.MWBlockImageNode.static.toDomElements = function ( data, doc, converter )
imgWrapper.setAttribute( 'href', attributes.href );
}
if ( attributes.imgWrapperClassAttr ) {
// eslint-disable-next-line mediawiki/class-doc
imgWrapper.className = attributes.imgWrapperClassAttr;
}
var width = attributes.width;
var height = attributes.height;
// If defaultSize is set, and was set on the way in, use the original width and height

View file

@ -107,6 +107,10 @@ ve.dm.MWGalleryImageNode.static.toDomElements = function ( data, doc ) {
innerDiv.setAttribute( 'typeof', 'mw:Image' );
// TODO: Support editing the link
// FIXME: Dropping the href causes Parsoid to mark the node as wrapper modified,
// making the whole gallery subtree edited, preventing selser. When fixing,
// preserving the imgWrapperClassAttr, as in the MW*ImageNodes, will also be
// necessary.
// a.setAttribute( 'href', model.attributes.src );
img.setAttribute( 'resource', model.attributes.resource );

View file

@ -88,6 +88,7 @@ ve.dm.MWInlineImageNode.static.toDataElement = function ( domElements, converter
type: types.frameType,
src: img.getAttribute( 'src' ) || img.getAttribute( 'poster' ),
href: href,
imgWrapperClassAttr: imgWrapper.getAttribute( 'class' ),
resource: img.getAttribute( 'resource' ),
originalClasses: classes,
width: width !== null && width !== '' ? +width : null,
@ -206,6 +207,10 @@ ve.dm.MWInlineImageNode.static.toDomElements = function ( dataElement, doc, conv
if ( attributes.href ) {
firstChild = doc.createElement( 'a' );
firstChild.setAttribute( 'href', attributes.href );
if ( attributes.imgWrapperClassAttr ) {
// eslint-disable-next-line mediawiki/class-doc
firstChild.className = attributes.imgWrapperClassAttr;
}
} else {
firstChild = doc.createElement( 'span' );
}

View file

@ -280,6 +280,7 @@ ve.dm.mwExample.MWBlockImage = {
type: 'thumb',
align: 'right',
href: './Foo',
imgWrapperClassAttr: null,
mediaClass: 'Image',
src: ve.ce.minImgDataUri,
width: 1,
@ -316,6 +317,7 @@ ve.dm.mwExample.MWInlineImage = {
attributes: {
src: 'http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png',
href: './File:Wiki.png',
imgWrapperClassAttr: null,
mediaClass: 'Image',
width: 135,
height: 155,
@ -335,6 +337,35 @@ ve.dm.mwExample.MWInlineImage = {
}
};
ve.dm.mwExample.MWInlineImageWithWrapperClass = {
html:
'<span typeof="mw:Image" class="foo mw-valign-text-top">' +
'<a href="./File:Wiki.png" class="mw-file-description">' +
'<img resource="./File:Wiki.png" src="http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png" height="155" width="135" alt="alt text">' +
'</a>' +
'</span>',
data: {
type: 'mwInlineImage',
attributes: {
src: 'http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png',
href: './File:Wiki.png',
imgWrapperClassAttr: 'mw-file-description',
mediaClass: 'Image',
width: 135,
height: 155,
alt: 'alt text',
isError: false,
valign: 'text-top',
resource: './File:Wiki.png',
mw: {},
type: 'none',
originalClasses: 'foo mw-valign-text-top',
unrecognizedClasses: [ 'foo' ],
tagName: 'span'
}
}
};
ve.dm.mwExample.mwNowikiAnnotation = {
type: 'mwNowiki'
};
@ -746,7 +777,26 @@ ve.dm.mwExample.domToDataCases = {
],
ceHtml: '<p class="ve-ce-branchNode ve-ce-contentBranchNode ve-ce-paragraphNode">' +
'<span class="ve-ce-branchNode-slug ve-ce-branchNode-inlineSlug"></span>' +
'<a class="image ve-ce-leafNode ve-ce-focusableNode ve-ce-mwInlineImageNode" contenteditable="false">' +
'<a class="ve-ce-leafNode ve-ce-focusableNode ve-ce-mwInlineImageNode" contenteditable="false">' +
'<img src="http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png" width="135" height="155" style="vertical-align: text-top;">' +
'</a>' +
ve.dm.example.inlineSlug +
'</p>',
storeItems: ve.dm.mwExample.MWInlineImage.storeItems
},
mwImageWithWrapperClass: {
body: '<p>' + ve.dm.mwExample.MWInlineImageWithWrapperClass.html + '</p>',
data: [
{ type: 'paragraph' },
ve.dm.mwExample.MWInlineImageWithWrapperClass.data,
{ type: '/mwInlineImage' },
{ type: '/paragraph' },
{ type: 'internalList' },
{ type: '/internalList' }
],
ceHtml: '<p class="ve-ce-branchNode ve-ce-contentBranchNode ve-ce-paragraphNode">' +
'<span class="ve-ce-branchNode-slug ve-ce-branchNode-inlineSlug"></span>' +
'<a class="ve-ce-leafNode ve-ce-focusableNode ve-ce-mwInlineImageNode" contenteditable="false">' +
'<img src="http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png" width="135" height="155" style="vertical-align: text-top;">' +
'</a>' +
ve.dm.example.inlineSlug +
@ -1025,6 +1075,7 @@ ve.dm.mwExample.domToDataCases = {
alt: null,
height: 300,
href: './Foo',
imgWrapperClassAttr: null,
isError: false,
mediaClass: 'Image',
mw: {},
@ -1059,6 +1110,7 @@ ve.dm.mwExample.domToDataCases = {
alt: null,
height: 300,
href: './Foo',
imgWrapperClassAttr: null,
isError: false,
mediaClass: 'Image',
mw: {},
@ -1092,6 +1144,7 @@ ve.dm.mwExample.domToDataCases = {
alt: null,
height: 300,
href: './Foo',
imgWrapperClassAttr: null,
isError: false,
mediaClass: 'Image',
mw: {},
@ -1125,6 +1178,7 @@ ve.dm.mwExample.domToDataCases = {
alt: null,
height: 300,
href: './Foo',
imgWrapperClassAttr: null,
isError: false,
mediaClass: 'Image',
mw: {},
@ -1149,6 +1203,7 @@ ve.dm.mwExample.domToDataCases = {
alt: null,
height: 300,
href: './Foo',
imgWrapperClassAttr: null,
isError: false,
mediaClass: 'Image',
mw: {},
@ -1905,6 +1960,7 @@ ve.dm.mwExample.domToDataCases = {
type: 'thumb',
align: 'default',
href: './Special:FilePath/Missing_image.jpg',
imgWrapperClassAttr: null,
mediaClass: 'Image',
src: null,
defaultSize: true,
@ -1958,6 +2014,7 @@ ve.dm.mwExample.domToDataCases = {
attributes: {
type: 'none',
href: './Special:FilePath/Missing_image.jpg',
imgWrapperClassAttr: null,
mediaClass: 'Image',
src: null,
tagName: 'span',
@ -2018,6 +2075,7 @@ ve.dm.mwExample.domToDataCases = {
type: 'thumb',
align: 'default',
href: './Foo',
imgWrapperClassAttr: null,
mediaClass: 'Image',
src: ve.ce.minImgDataUri,
width: 1,