mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-15 18:39:52 +00:00
Merge "Preserve classes on media wrapper links"
This commit is contained in:
commit
beded65e85
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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>' );
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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' );
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue