Esanders has uploaded a new change for review.
https://gerrit.wikimedia.org/r/169517
Change subject: Factor out class <-> attribute mappings from BlockImageNode
......................................................................
Factor out class <-> attribute mappings from BlockImageNode
Create a mixin with functionality to extract attributes from classes
and vice-versa.
Change-Id: I4fc42e1468a9f0860c7c13e73967204bdf5ad78d
---
M VisualEditor.php
M modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js
A modules/ve-mw/dm/nodes/ve.dm.MWClassAttributeNode.js
3 files changed, 123 insertions(+), 72 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/17/169517/1
diff --git a/VisualEditor.php b/VisualEditor.php
index bc2c6c4..d21b244 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -699,6 +699,8 @@
// dm
'modules/ve-mw/dm/ve.dm.MW.js',
+ 'modules/ve-mw/dm/nodes/ve.dm.MWClassAttributeNode.js',
+
'modules/ve-mw/dm/nodes/ve.dm.MWEntityNode.js',
'modules/ve-mw/dm/nodes/ve.dm.MWExtensionNode.js',
diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js
b/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js
index f86cb8c..4a2ae65 100644
--- a/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js
+++ b/modules/ve-mw/dm/nodes/ve.dm.MWBlockImageNode.js
@@ -11,6 +11,7 @@
* @class
* @extends ve.dm.BranchNode
* @mixins ve.dm.MWImageNode
+ * @mixins ve.dm.MWClassAttributeNode
*
* @constructor
* @param {Object} [element] Reference to element in linear model
@@ -22,6 +23,7 @@
// Mixin constructors
ve.dm.MWImageNode.call( this );
+ ve.dm.MWClassAttributeNode.call( this );
};
/* Inheritance */
@@ -32,6 +34,8 @@
OO.mixinClass( ve.dm.MWBlockImageNode, ve.dm.GeneratedContentNode );
OO.mixinClass( ve.dm.MWBlockImageNode, ve.dm.MWImageNode );
+
+OO.mixinClass( ve.dm.MWBlockImageNode, ve.dm.MWClassAttributeNode );
/* Static Properties */
@@ -60,6 +64,15 @@
return ve.getObjectKeys( this.rdfaToType );
};
+ve.dm.MWBlockImageNode.static.classAttributes = {
+ 'mw-image-border': { borderImage: true },
+ 'mw-halign-left': { align: 'left' },
+ 'mw-halign-right': { align: 'right' },
+ 'mw-halign-center': { align: 'center' },
+ 'mw-halign-none': { align: 'none' },
+ 'mw-default-size': { defaultSize: true }
+};
+
ve.dm.MWBlockImageNode.static.toDataElement = function ( domElements,
converter ) {
var dataElement, newDimensions,
$figure = $( domElements[0] ),
@@ -67,15 +80,13 @@
$imgWrapper = $figure.children( 'a, span' ).eq( 0 ),
$img = $imgWrapper.children( 'img' ).eq( 0 ),
$caption = $figure.children( 'figcaption' ).eq( 0 ),
+ classAttr = $figure.attr( 'class' ),
typeofAttr = $figure.attr( 'typeof' ),
- classes = $figure.attr( 'class' ),
- recognizedClasses = [],
attributes = {
type: this.rdfaToType[typeofAttr],
href: $imgWrapper.attr( 'href' ) || '',
src: $img.attr( 'src' ),
- resource: $img.attr( 'resource' ),
- originalClasses: classes
+ resource: $img.attr( 'resource' )
},
width = $img.attr( 'width' ),
height = $img.attr( 'height' ),
@@ -85,40 +96,15 @@
attributes.alt = altText;
}
- // Extract individual classes
- classes = typeof classes === 'string' ? classes.trim().split( /\s+/ ) :
[];
+ this.setClassAttributes( attributes, classAttr );
- // Deal with border flag
- if ( classes.indexOf( 'mw-image-border' ) !== -1 ) {
- attributes.borderImage = true;
- recognizedClasses.push( 'mw-image-border' );
- }
-
- // Horizontal alignment
- if ( classes.indexOf( 'mw-halign-left' ) !== -1 ) {
- attributes.align = 'left';
- recognizedClasses.push( 'mw-halign-left' );
- } else if ( classes.indexOf( 'mw-halign-right' ) !== -1 ) {
- attributes.align = 'right';
- recognizedClasses.push( 'mw-halign-right' );
- } else if ( classes.indexOf( 'mw-halign-center' ) !== -1 ) {
- attributes.align = 'center';
- recognizedClasses.push( 'mw-halign-center' );
- } else if ( classes.indexOf( 'mw-halign-none' ) !== -1 ) {
- attributes.align = 'none';
- recognizedClasses.push( 'mw-halign-none' );
- } else {
- attributes.align = 'default';
- }
+ attributes.align = attributes.align || 'default';
attributes.width = width !== undefined && width !== '' ? Number( width
) : null;
attributes.height = height !== undefined && height !== '' ? Number(
height ) : null;
// Default-size
- if ( classes.indexOf( 'mw-default-size' ) !== -1 ) {
- // Flag as default size
- attributes.defaultSize = true;
- recognizedClasses.push( 'mw-default-size' );
+ if ( attributes.defaultSize ) {
// Force wiki-default size for thumb and frameless
if (
attributes.type === 'thumb' ||
@@ -140,9 +126,6 @@
}
}
}
-
- // Store unrecognized classes so we can restore them on the way out
- attributes.unrecognizedClasses = OO.simpleArrayDifference( classes,
recognizedClasses );
dataElement = { type: this.name, attributes: attributes };
@@ -172,8 +155,7 @@
imgWrapper = doc.createElement( dataElement.attributes.href !==
'' ? 'a' : 'span' ),
img = doc.createElement( 'img' ),
wrapper = doc.createElement( 'div' ),
- classes = [],
- originalClasses = dataElement.attributes.originalClasses,
+ classAttr = this.getClassAttrFromAttributes(
dataElement.attributes ),
captionData = data.slice( 1, -1 );
if ( !this.typeToRdfa ) {
@@ -185,43 +167,11 @@
// Type
figure.setAttribute( 'typeof',
this.typeToRdfa[dataElement.attributes.type] );
- if ( dataElement.attributes.borderImage === true ) {
- classes.push( 'mw-image-border' );
+
+ if ( classAttr ) {
+ figure.className = classAttr;
}
- // Apply classes if size is default
- if ( dataElement.attributes.defaultSize === true ) {
- classes.push( 'mw-default-size' );
- }
-
- // Horizontal alignment
- switch ( dataElement.attributes.align ) {
- case 'left':
- classes.push( 'mw-halign-left' );
- break;
- case 'right':
- classes.push( 'mw-halign-right' );
- break;
- case 'center':
- classes.push( 'mw-halign-center' );
- break;
- case 'none':
- classes.push( 'mw-halign-none' );
- break;
- }
-
- if ( dataElement.attributes.unrecognizedClasses ) {
- classes = OO.simpleArrayUnion( classes,
dataElement.attributes.unrecognizedClasses );
- }
-
- if (
- originalClasses &&
- ve.compare( originalClasses.trim().split( /\s+/ ).sort(),
classes.sort() )
- ) {
- figure.className = originalClasses;
- } else if ( classes.length > 0 ) {
- figure.className = classes.join( ' ' );
- }
if ( dataElement.attributes.href !== '' ) {
imgWrapper.setAttribute( 'href', dataElement.attributes.href );
}
diff --git a/modules/ve-mw/dm/nodes/ve.dm.MWClassAttributeNode.js
b/modules/ve-mw/dm/nodes/ve.dm.MWClassAttributeNode.js
new file mode 100644
index 0000000..6ca247f
--- /dev/null
+++ b/modules/ve-mw/dm/nodes/ve.dm.MWClassAttributeNode.js
@@ -0,0 +1,99 @@
+/*!
+ * VisualEditor DataModel MWClassAttribute class.
+ *
+ * @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/**
+ * DataModel MediaWiki class-attribute node.
+ *
+ * Used for nodes which use classes to store attributes.
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ */
+ve.dm.MWClassAttributeNode = function VeDmMWImageNode() {
+};
+
+/* Inheritance */
+
+OO.initClass( ve.dm.MWClassAttributeNode );
+
+/* Static methods */
+
+/**
+ * Mapping from class names to attributes
+ *
+ * e.g. { alignLeft: { align: 'left' } } sets the align attribute to 'left'
+ * if the element has the class 'alignLeft'
+ *
+ * @type {Object}
+ */
+ve.dm.MWClassAttributeNode.static.classAttributes = {};
+
+/**
+ * Set attributes from a class attribute
+ *
+ * Unrecognized classes are also preserved.
+ *
+ * @param {Object} attributes Attributes object to modify
+ * @param {string|null} classAttr Class attribute from an element
+ */
+ve.dm.MWClassAttributeNode.static.setClassAttributes = function ( attributes,
classAttr ) {
+ var className,
+ recognizedClasses = [],
+ classes = classAttr ? classAttr.trim().split( /\s+/ ) : [];
+
+ for ( className in this.classAttributes ) {
+ if ( ve.indexOf( className, classes ) !== -1 ) {
+ attributes = ve.extendObject( attributes,
this.classAttributes[className] );
+ recognizedClasses.push( className );
+ }
+ }
+ attributes.originalClasses = classAttr;
+ attributes.unrecognizedClasses = OO.simpleArrayDifference( classes,
recognizedClasses );
+};
+
+/**
+ * Get class attribute from element attributes
+ *
+ * @param {Object} elementAttributes Element attributes
+ * @return {string|null} Class name, or null if no classes to set
+ */
+ve.dm.MWClassAttributeNode.static.getClassAttrFromAttributes = function (
attributes ) {
+ var className, key, classAttributeSet, hasClass,
+ classes = [];
+
+ for ( className in this.classAttributes ) {
+ classAttributeSet = this.classAttributes[className];
+ hasClass = true;
+ for ( key in classAttributeSet ) {
+ if ( attributes[key] !== classAttributeSet[key] ) {
+ hasClass = false;
+ break;
+ }
+ }
+ if ( hasClass ) {
+ classes.push( className );
+ }
+ }
+
+ if ( attributes.unrecognizedClasses ) {
+ classes = OO.simpleArrayUnion( classes,
attributes.unrecognizedClasses );
+ }
+
+ // If no meaningful change in classes, preserve order
+ if (
+ attributes.originalClasses &&
+ ve.compare( attributes.originalClasses.trim().split( /\s+/
).sort(), classes.sort() )
+ ) {
+ return attributes.originalClasses;
+ } else if ( classes.length > 0 ) {
+ return classes.join( ' ' );
+ }
+
+ return null;
+};
--
To view, visit https://gerrit.wikimedia.org/r/169517
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4fc42e1468a9f0860c7c13e73967204bdf5ad78d
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits