Set alt in data-mw for non-img media

Follow up to I02ea8421e468635ba6297bb5cda488a5a79c9a1d the depends on
I7a5c24f6ffc15ff0455adf5b025b695ee71501b6 in Parsoid.

Note that the mediaTag isn't currently being passed around for gallery
image nodes so, for example, a <video> becomes an <img> as is.  But,
that's independent of this patch, and a follow up will fix it.
Noted in T348703#9278332

Bug: T348703
Bug: T214603
Change-Id: I5f7d3dfe0a41fac1568c97dccc41209c14e741d0
This commit is contained in:
Arlo Breault 2023-10-24 19:12:22 -04:00
parent c599481ad9
commit 2497a5254e
4 changed files with 49 additions and 13 deletions

View file

@ -41,7 +41,7 @@ ve.dm.MWGalleryImageNode.static.matchFunction = function ( element ) {
ve.dm.MWGalleryImageNode.static.parentNodeTypes = [ 'mwGallery' ];
ve.dm.MWGalleryImageNode.static.preserveHtmlAttributes = function ( attribute ) {
var attributes = [ 'typeof', 'class', 'src', 'resource', 'width', 'height', 'href', 'rel', 'alt' ];
var attributes = [ 'typeof', 'class', 'src', 'resource', 'width', 'height', 'href', 'rel', 'alt', 'data-mw' ];
return attributes.indexOf( attribute ) === -1;
};
// By handling our own children we ensure that original DOM attributes
@ -152,6 +152,7 @@ ve.dm.MWGalleryImageNode.static.toDataElement = function ( domElements, converte
height: height !== null && height !== '' ? +height : null,
isError: isError,
errorText: errorText,
mw: mwData,
imageClassAttr: img.getAttribute( 'class' ),
imgWrapperClassAttr: a.getAttribute( 'class' )
}
@ -176,7 +177,8 @@ ve.dm.MWGalleryImageNode.static.toDomElements = function ( data, doc, converter
container = doc.createElement( 'span' ),
a = doc.createElement( 'a' ),
img = doc.createElement( attributes.isError ? 'span' : ( attributes.mediaTag || 'img' ) ),
alt = attributes.altText;
alt = attributes.altText,
mwData = ve.copy( attributes.mw ) || {};
// FIXME: attributes.mediaTag and attributes.mediaClass aren't set after edit
@ -225,10 +227,30 @@ ve.dm.MWGalleryImageNode.static.toDomElements = function ( data, doc, converter
li.appendChild( captionWrapper.firstChild );
}
if ( attributes.altTextSame ) {
img.setAttribute( 'alt', ve.dm.MWGalleryImageNode.static.textContentFromCaption( li ).trim() );
} else if ( typeof alt === 'string' ) {
img.setAttribute( 'alt', alt );
// Meh, see the FIXME above about the mediaTag not being set
if ( img.nodeName.toLowerCase() === 'img' ) {
if ( attributes.altTextSame ) {
img.setAttribute( 'alt', ve.dm.MWGalleryImageNode.static.textContentFromCaption( li ).trim() );
} else if ( typeof alt === 'string' ) {
img.setAttribute( 'alt', alt );
}
} else {
var mwAttribs = mwData.attribs || [];
mwAttribs = mwAttribs.filter(
function ( attr ) { return attr[ 0 ] !== 'alt'; }
);
// Parsoid only sets an alt in the data-mw.attribs if it's explicit
// in the source
if ( !attributes.altTextSame && typeof alt === 'string' ) {
mwAttribs.push( [ 'alt', { txt: alt } ] );
}
if ( mwData.attribs || mwAttribs.length ) {
mwData.attribs = mwAttribs;
}
}
if ( !ve.isEmptyObject( mwData ) ) {
container.setAttribute( 'data-mw', JSON.stringify( mwData ) );
}
return [ li ];

View file

@ -946,7 +946,15 @@ ve.dm.mwExample.domToDataCases = {
imgWrapperClassAttr: null,
src: null,
isError: true,
errorText: 'File:!Example.jpg'
errorText: 'File:!Example.jpg',
mw: {
errors: [
{
key: 'apierror-filedoesnotexist',
message: 'This image does not exist.'
}
]
}
}
},
{ type: 'mwGalleryImageCaption' },
@ -967,7 +975,7 @@ ve.dm.mwExample.domToDataCases = {
<ul typeof="mw:Extension/gallery" about="#mwt2" data-mw='{"name":"gallery","attrs":{},"body":{}}'>
<li class="gallerybox">
<div class="thumb">
<span typeof="mw:Error mw:File">
<span typeof="mw:Error mw:File" data-mw='{"errors":[{"key":"apierror-filedoesnotexist","message":"This image does not exist."}]}'>
<a href="./Special:FilePath/!Example.jpg">
<span class="mw-file-element mw-broken-media" resource="./File:!Example.jpg" data-width="120" data-height="120">File:!Example.jpg</span>
</a>
@ -1023,7 +1031,8 @@ ve.dm.mwExample.domToDataCases = {
imgWrapperClassAttr: 'mw-file-description',
src: ve.ce.minImgDataUri,
isError: false,
errorText: null
errorText: null,
mw: {}
}
},
{ type: 'mwGalleryImageCaption' },
@ -1099,7 +1108,8 @@ ve.dm.mwExample.domToDataCases = {
imgWrapperClassAttr: 'mw-file-description',
src: ve.ce.minImgDataUri,
isError: false,
errorText: null
errorText: null,
mw: {}
}
},
{ type: 'mwGalleryImageCaption' },

View file

@ -428,7 +428,8 @@ ve.ui.MWGalleryDialog.prototype.getSetupProcess = function ( data ) {
isError: image.getAttribute( 'isError' ),
errorText: image.getAttribute( 'errorText' ),
imageClassAttr: image.getAttribute( 'imageClassAttr' ),
imgWrapperClassAttr: image.getAttribute( 'imgWrapperClassAttr' )
imgWrapperClassAttr: image.getAttribute( 'imgWrapperClassAttr' ),
mw: image.getAttribute( 'mw' )
} );
}
@ -676,7 +677,8 @@ ve.ui.MWGalleryDialog.prototype.onRequestImagesSuccess = function ( response ) {
captionDocument: this.createCaptionDocument( null ),
isError: false,
errorText: null,
imageClassAttr: 'mw-file-element'
imageClassAttr: 'mw-file-element',
mw: {}
}, config ) );
delete this.selectedFilenames[ title ];
}
@ -1040,7 +1042,8 @@ ve.ui.MWGalleryDialog.prototype.insertOrUpdateNode = function () {
isError: galleryItem.isError,
errorText: galleryItem.errorText,
imageClassAttr: galleryItem.imageClassAttr,
imgWrapperClassAttr: galleryItem.imgWrapperClassAttr
imgWrapperClassAttr: galleryItem.imgWrapperClassAttr,
mw: galleryItem.mw
};
return [

View file

@ -35,6 +35,7 @@ ve.ui.MWGalleryItemWidget = function VeUiMWGalleryItemWidget( imageInfo, config
this.isError = imageInfo.isError;
this.imageClassAttr = imageInfo.imageClassAttr;
this.imgWrapperClassAttr = imageInfo.imgWrapperClassAttr;
this.mw = imageInfo.mw;
// Configuration initialization
config = config || {};