ve.dm.MWImageModel: Require parent document

Add a parentDoc parameter to the MWImageModel constructor and use
it to inherit language, direction and HTML document. Remove
getLang(), setLang(), getDir() and setDir() whose only purpose
was to propagate the language and direction from the parent document
in a hacky way.

Also add a parentDoc parameter to newFromImageAttributes(), replacing
the lang and dir parameters. Remove the unused and ill-conceived
caption parameter.

This causes caption documents to always have an HTML document
for URL resolution. Previously, this worked when editing existing
images because a document generated by cloneFromRange() (which
propagates the HTML document) was passed into setCaptionDocument(),
but it didn't work when creating new images.

Bug: T109599
Change-Id: Ida36862092cd779ffc2f04c0ecbc1164f8d71453
This commit is contained in:
Roan Kattouw 2015-08-26 23:49:26 -07:00
parent fc5ff16548
commit e4d2d4785e
3 changed files with 36 additions and 78 deletions

View file

@ -12,13 +12,14 @@
* @mixins OO.EventEmitter
*
* @constructor
* @param {ve.dm.Document} parentDoc Document that contains or will contain the image
* @param {Object} [config] Configuration options
* @cfg {string} [resourceName] The resource name of the given media file
* @cfg {Object} [currentDimensions] Current dimensions, width & height
* @cfg {Object} [minDimensions] Minimum dimensions, width & height
* @cfg {boolean} [isDefaultSize] Object is using its default size dimensions
*/
ve.dm.MWImageModel = function VeDmMWImageModel( config ) {
ve.dm.MWImageModel = function VeDmMWImageModel( parentDoc, config ) {
var scalable, currentDimensions, minDimensions;
config = config || {};
@ -30,6 +31,7 @@ ve.dm.MWImageModel = function VeDmMWImageModel( config ) {
this.attributesCache = null;
// Image properties
this.parentDoc = parentDoc;
this.captionDoc = null;
this.caption = null;
this.mediaType = null;
@ -40,8 +42,6 @@ ve.dm.MWImageModel = function VeDmMWImageModel( config ) {
this.sizeType = null;
this.border = false;
this.borderable = false;
this.dir = null;
this.lang = null;
this.defaultDimensions = null;
this.changedImageSource = false;
@ -157,21 +157,21 @@ ve.dm.MWImageModel.static.createImageNode = function ( attributes, imageType ) {
* Load from image data with scalable information.
*
* @param {Object} attrs Image node attributes
* @param {string} [dir] Document direction
* @param {string} [lang] Document language
* @param {string} [caption] Existing image caption HTML
* @param {ve.dm.Document} parentDoc Document that contains or will contain the image
* @return {ve.dm.MWImageModel} Image model
*/
ve.dm.MWImageModel.static.newFromImageAttributes = function ( attrs, dir, lang, caption ) {
var captionDomTree,
imgModel = new ve.dm.MWImageModel( {
resourceName: attrs.resource,
currentDimensions: {
width: attrs.width,
height: attrs.height
},
defaultSize: !!attrs.defaultSize
} );
ve.dm.MWImageModel.static.newFromImageAttributes = function ( attrs, parentDoc ) {
var imgModel = new ve.dm.MWImageModel(
parentDoc,
{
resourceName: attrs.resource,
currentDimensions: {
width: attrs.width,
height: attrs.height
},
defaultSize: !!attrs.defaultSize
}
);
// Cache the attributes so we can create a new image without
// losing any existing information
@ -191,9 +191,6 @@ ve.dm.MWImageModel.static.newFromImageAttributes = function ( attrs, dir, lang,
imgModel.toggleBorder( !!attrs.borderImage );
imgModel.setAltText( attrs.alt || '' );
imgModel.setDir( dir );
imgModel.setLang( lang );
imgModel.setType( attrs.type );
// Fix cases where alignment is undefined
@ -213,14 +210,19 @@ ve.dm.MWImageModel.static.newFromImageAttributes = function ( attrs, dir, lang,
'custom'
);
// If a caption is given, use it in the document
if ( caption ) {
captionDomTree = ve.createDocumentFromHtml( caption );
imgModel.setCaptionDocument( ve.dm.converter.getModelFromDom( captionDomTree ) );
}
return imgModel;
};
/**
* Load from existing image node.
*
* @param {ve.dm.MWImageNode} node Image node
* @return {ve.dm.MWImageModel} Image model
*/
ve.dm.MWImageModel.static.newFromImageNode = function ( node ) {
return ve.dm.MWImageModel.static.newFromImageAttributes( node.getAttributes(), node.getDocument() );
};
/* Methods */
/**
@ -686,7 +688,7 @@ ve.dm.MWImageModel.prototype.isAligned = function ( align ) {
*/
ve.dm.MWImageModel.prototype.isDefaultAligned = function ( imageType, align ) {
var alignment = align || this.getAlignment(),
defaultAlignment = ( this.getDir() === 'rtl' ) ? 'left' : 'right';
defaultAlignment = ( this.parentDoc.getDir() === 'rtl' ) ? 'left' : 'right';
imageType = imageType || this.getType();
// No alignment specified means defeault alignment always
@ -827,7 +829,7 @@ ve.dm.MWImageModel.prototype.getCaptionDocument = function () {
{ type: '/internalList' }
],
// htmlDocument
null,
this.parentDoc.getHtmlDocument(),
// parentDocument
null,
// internalList
@ -835,9 +837,9 @@ ve.dm.MWImageModel.prototype.getCaptionDocument = function () {
// innerWhitespace
null,
// lang
this.getLang(),
this.parentDoc.getLang(),
// dir
this.getDir()
this.parentDoc.getDir()
);
}
return this.captionDoc;
@ -1064,7 +1066,7 @@ ve.dm.MWImageModel.prototype.setVerticalAlignment = function ( valign ) {
ve.dm.MWImageModel.prototype.getDefaultDir = function ( imageNodeType ) {
imageNodeType = imageNodeType || this.getImageNodeType();
if ( this.getDir() === 'rtl' ) {
if ( this.parentDoc.getDir() === 'rtl' ) {
// Assume position is 'left'
return ( imageNodeType === 'mwBlockImage' ) ? 'left' : 'none';
} else {
@ -1073,46 +1075,6 @@ ve.dm.MWImageModel.prototype.getDefaultDir = function ( imageNodeType ) {
}
};
/**
* Get the directionality of the image, especially important for
* default alignment.
*
* @return {string} Current document direction 'rtl' or 'ltr'
*/
ve.dm.MWImageModel.prototype.getDir = function () {
return this.dir;
};
/**
* Set the directionality of the image, especially important for
* default alignment.
*
* @param {string} dir 'rtl' or 'ltr'
*/
ve.dm.MWImageModel.prototype.setDir = function ( dir ) {
this.dir = dir;
};
/**
* Get the language of the image document. Specifically relevant
* for the caption document.
*
* @return {string} Document language
*/
ve.dm.MWImageModel.prototype.getLang = function () {
return this.lang;
};
/**
* Set the language of the image document. Specifically relevant
* for the caption document.
*
* @param {string} lang Document language
*/
ve.dm.MWImageModel.prototype.setLang = function ( lang ) {
this.lang = lang;
};
/**
* Get the image file source
* The image file source that points to the location of the

View file

@ -10,7 +10,7 @@ QUnit.module( 've.dm.MWImageModel', ve.test.utils.mwEnvironment );
/* Tests */
QUnit.test( 'Create and manipulate image nodes', function ( assert ) {
var i, imageType, imageModel, value, result, expected, expectedAlignment, method, dir,
var i, imageType, imageModel, value, result, expected, expectedAlignment, method, dir, dummyDoc,
expect = 0,
imageNode = {},
images = {
@ -148,9 +148,10 @@ QUnit.test( 'Create and manipulate image nodes', function ( assert ) {
// Run tests
for ( i = 0; i < images[ imageType ].tests.length; i++ ) {
dir = images[ imageType ].dir;
dummyDoc = new ve.dm.Document( [], null, null, null, null, 'en', images[ imageType ].dir );
// Start from original details
imageModel = ve.dm.MWImageModel.static.newFromImageAttributes( images[ imageType ].attrs, dir );
imageModel = ve.dm.MWImageModel.static.newFromImageAttributes( images[ imageType ].attrs, dummyDoc );
// Run attributes
for ( method in images[ imageType ].tests[ i ].methods ) {

View file

@ -746,8 +746,7 @@ ve.ui.MWMediaDialog.prototype.confirmSelectedImage = function () {
align: 'default',
defaultSize: true
},
this.getFragment().getDocument().getDir(),
this.getFragment().getDocument().getLang()
this.getFragment().getDocument()
);
this.attachImageModel();
this.resetCaption();
@ -954,11 +953,7 @@ ve.ui.MWMediaDialog.prototype.getSetupProcess = function ( data ) {
if ( this.selectedNode ) {
this.isInsertion = false;
// Create image model
this.imageModel = ve.dm.MWImageModel.static.newFromImageAttributes(
this.selectedNode.getAttributes(),
this.selectedNode.getDocument().getDir(),
this.selectedNode.getDocument().getLang()
);
this.imageModel = ve.dm.MWImageModel.static.newFromImageNode( this.selectedNode );
this.attachImageModel();
if ( !this.imageModel.isDefaultSize() ) {