2011-11-03 18:15:24 +00:00
|
|
|
/**
|
|
|
|
* Serializes a WikiDom plain object into an HTML string.
|
|
|
|
*
|
|
|
|
* @class
|
|
|
|
* @constructor
|
|
|
|
* @param {Object} options List of options for serialization
|
|
|
|
*/
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer = function( options ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
this.options = $.extend( {
|
|
|
|
// defaults
|
|
|
|
}, options || {} );
|
|
|
|
};
|
|
|
|
|
2012-04-05 21:31:59 +00:00
|
|
|
/* Static Members */
|
|
|
|
|
|
|
|
ve.dm.HtmlSerializer.headingTags = {
|
|
|
|
'1': 'h1',
|
|
|
|
'2': 'h2',
|
|
|
|
'3': 'h3',
|
|
|
|
'4': 'h4',
|
|
|
|
'5': 'h5',
|
|
|
|
'6': 'h6'
|
|
|
|
};
|
|
|
|
|
|
|
|
ve.dm.HtmlSerializer.listTags = {
|
|
|
|
'bullet': 'ul',
|
|
|
|
'number': 'ol',
|
|
|
|
'definition': 'dl'
|
|
|
|
};
|
|
|
|
|
|
|
|
ve.dm.HtmlSerializer.listItemTags = {
|
|
|
|
'item': 'li',
|
|
|
|
'term': 'dt',
|
|
|
|
'definition': 'dd'
|
|
|
|
};
|
|
|
|
|
|
|
|
ve.dm.HtmlSerializer.tableCellTags = {
|
|
|
|
'tableHeading': 'th',
|
|
|
|
'tableCell': 'td'
|
|
|
|
};
|
|
|
|
|
2011-11-03 18:15:24 +00:00
|
|
|
/* Static Methods */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a serialized version of data.
|
|
|
|
*
|
|
|
|
* @static
|
|
|
|
* @method
|
|
|
|
* @param {Object} data Data to serialize
|
2012-02-06 23:50:56 +00:00
|
|
|
* @param {Object} options Options to use, @see {ve.dm.WikitextSerializer} for details
|
2011-11-03 18:15:24 +00:00
|
|
|
* @returns {String} Serialized version of data
|
|
|
|
*/
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.stringify = function( data, options ) {
|
|
|
|
return ( new ve.dm.HtmlSerializer( options ) ).document( data );
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.getHtmlAttributes = function( attributes ) {
|
2011-11-03 19:39:12 +00:00
|
|
|
var htmlAttributes = {},
|
|
|
|
count = 0;
|
|
|
|
for ( var key in attributes ) {
|
|
|
|
if ( key.indexOf( 'html/' ) === 0 ) {
|
|
|
|
htmlAttributes[key.substr( 5 )] = attributes[key];
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count ? htmlAttributes : null;
|
|
|
|
};
|
|
|
|
|
2011-11-03 18:15:24 +00:00
|
|
|
/* Methods */
|
|
|
|
|
2012-04-05 21:31:59 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.document = function( node, wrapWith, rawFirstParagraph ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
var lines = [];
|
2012-04-05 21:31:59 +00:00
|
|
|
if ( wrapWith ) {
|
|
|
|
var htmlAttributes = ve.dm.HtmlSerializer.getHtmlAttributes( node.attributes );
|
|
|
|
lines.push( ve.Html.makeOpeningTag( wrapWith, htmlAttributes ) );
|
|
|
|
}
|
2011-11-03 18:15:24 +00:00
|
|
|
for ( var i = 0, length = node.children.length; i < length; i++ ) {
|
2012-04-05 21:31:59 +00:00
|
|
|
var child = node.children[i];
|
|
|
|
if ( child.type in this ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
// Special case for paragraphs which have particular wrapping needs
|
2012-04-05 21:31:59 +00:00
|
|
|
if ( child.type === 'paragraph' ) {
|
|
|
|
lines.push( this.paragraph( child, rawFirstParagraph && i === 0 ) );
|
2011-11-03 18:15:24 +00:00
|
|
|
} else {
|
2012-04-05 21:31:59 +00:00
|
|
|
lines.push( this[child.type].call( this, child ) );
|
2011-11-03 18:15:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-05 21:31:59 +00:00
|
|
|
if ( wrapWith ) {
|
|
|
|
lines.push( ve.Html.makeClosingTag( wrapWith ) );
|
|
|
|
}
|
2011-11-03 18:15:24 +00:00
|
|
|
return lines.join( '\n' );
|
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.comment = function( node ) {
|
2011-11-07 14:39:12 +00:00
|
|
|
return '<!--(' + node.text + ')-->';
|
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.pre = function( node ) {
|
|
|
|
return ve.Html.makeTag(
|
2011-11-08 16:08:05 +00:00
|
|
|
'pre', {}, this.content( node.content, true )
|
2011-11-07 14:39:12 +00:00
|
|
|
);
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.horizontalRule = function( node ) {
|
|
|
|
return ve.Html.makeTag( 'hr', {}, false );
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.heading = function( node ) {
|
|
|
|
return ve.Html.makeTag(
|
2012-04-05 21:31:59 +00:00
|
|
|
ve.dm.HtmlSerializer.headingTags[node.attributes.level], {}, this.content( node.content )
|
2011-11-03 18:15:24 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.paragraph = function( node, raw ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
if ( raw ) {
|
|
|
|
return this.content( node.content );
|
|
|
|
} else {
|
2012-02-06 23:50:56 +00:00
|
|
|
return ve.Html.makeTag( 'p', {}, this.content( node.content ) );
|
2011-11-03 18:15:24 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.list = function( node ) {
|
2012-04-05 21:31:59 +00:00
|
|
|
return this.document(
|
|
|
|
node, ve.dm.HtmlSerializer.listTags[node.attributes.style]
|
|
|
|
);
|
|
|
|
};
|
2011-11-04 10:02:59 +00:00
|
|
|
|
2012-04-05 21:31:59 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.listItem = function( node ) {
|
|
|
|
return this.document(
|
|
|
|
node, ve.dm.HtmlSerializer.listItemTags[node.attributes.style]
|
|
|
|
);
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.table = function( node ) {
|
2012-04-05 21:31:59 +00:00
|
|
|
return this.document( node, 'table' );
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.tableRow = function( node ) {
|
2012-04-05 21:31:59 +00:00
|
|
|
return this.document( node, 'tr' );
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.tableCell = function( node ) {
|
2012-04-05 21:31:59 +00:00
|
|
|
return this.document(
|
|
|
|
node, ve.dm.HtmlSerializer.tableCellTags[node.attributes.type], true
|
|
|
|
);
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.tableCaption = function( node ) {
|
2012-04-05 21:31:59 +00:00
|
|
|
return ve.Html.makeTag(
|
|
|
|
'caption',
|
|
|
|
ve.dm.HtmlSerializer.getHtmlAttributes( node.attributes ),
|
|
|
|
this.content( node.content )
|
|
|
|
);
|
2011-11-04 12:06:49 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.transclusion = function( node ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
var title = [];
|
|
|
|
if ( node.namespace !== 'Main' ) {
|
|
|
|
title.push( node.namespace );
|
|
|
|
}
|
|
|
|
title.push( node.title );
|
|
|
|
title = title.join( ':' );
|
2012-02-06 23:50:56 +00:00
|
|
|
return ve.Html.makeTag( 'a', { 'href': '/wiki/' + title }, title );
|
2011-11-03 18:15:24 +00:00
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.parameter = function( node ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
return '{{{' + node.name + '}}}';
|
|
|
|
};
|
|
|
|
|
2012-02-06 23:50:56 +00:00
|
|
|
ve.dm.HtmlSerializer.prototype.content = function( node ) {
|
2011-11-03 18:15:24 +00:00
|
|
|
if ( 'annotations' in node && node.annotations.length ) {
|
2012-02-06 23:50:56 +00:00
|
|
|
var annotationSerializer = new ve.dm.AnnotationSerializer(),
|
2011-11-03 18:15:24 +00:00
|
|
|
tagTable = {
|
|
|
|
'textStyle/bold': 'b',
|
|
|
|
'textStyle/italic': 'i',
|
|
|
|
'textStyle/strong': 'strong',
|
2011-11-07 19:28:47 +00:00
|
|
|
'textStyle/emphasize': 'em',
|
2011-11-03 18:15:24 +00:00
|
|
|
'textStyle/big': 'big',
|
|
|
|
'textStyle/small': 'small',
|
|
|
|
'textStyle/superScript': 'sup',
|
|
|
|
'textStyle/subScript': 'sub'
|
|
|
|
};
|
|
|
|
for ( var i = 0, length = node.annotations.length; i < length; i++ ) {
|
|
|
|
var annotation = node.annotations[i];
|
|
|
|
if ( annotation.type in tagTable ) {
|
|
|
|
annotationSerializer.addTags( annotation.range, tagTable[annotation.type] );
|
|
|
|
} else {
|
|
|
|
switch ( annotation.type ) {
|
|
|
|
case 'link/external':
|
|
|
|
annotationSerializer.addTags(
|
|
|
|
annotation.range, 'a', { 'href': annotation.data.url }
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case 'link/internal':
|
|
|
|
annotationSerializer.addTags(
|
|
|
|
annotation.range, 'a', { 'href': '/wiki/' + annotation.data.title }
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case 'object/template':
|
|
|
|
case 'object/hook':
|
|
|
|
annotationSerializer.add( annotation.range, annotation.data.html, '' );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return annotationSerializer.render( node.text );
|
|
|
|
} else {
|
|
|
|
return node.text;
|
|
|
|
}
|
|
|
|
};
|