mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-25 06:46:26 +00:00
Merge "Great Annotation Refactor of 2013"
This commit is contained in:
commit
5029ee29ea
|
@ -15,12 +15,17 @@
|
|||
"name": "General",
|
||||
"classes": [
|
||||
"ve.ce",
|
||||
"ve.ce.AnnotationFactory",
|
||||
"ve.ce.NodeFactory",
|
||||
"ve.ce.Surface",
|
||||
"ve.ce.SurfaceObserver",
|
||||
"ve.ce.DomRange"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Annotations",
|
||||
"classes": ["ve.ce.*Annotation"]
|
||||
},
|
||||
{
|
||||
"name": "Nodes",
|
||||
"classes": ["ve.ce.Document", "ve.ce.*Node"]
|
||||
|
|
|
@ -286,8 +286,10 @@ $wgResourceModules += array(
|
|||
// ce
|
||||
've/ce/ve.ce.js',
|
||||
've/ce/ve.ce.DomRange.js',
|
||||
've/ce/ve.ce.AnnotationFactory.js',
|
||||
've/ce/ve.ce.NodeFactory.js',
|
||||
've/ce/ve.ce.Document.js',
|
||||
've/ce/ve.ce.Annotation.js',
|
||||
've/ce/ve.ce.Node.js',
|
||||
've/ce/ve.ce.BranchNode.js',
|
||||
've/ce/ve.ce.ContentBranchNode.js',
|
||||
|
@ -319,6 +321,11 @@ $wgResourceModules += array(
|
|||
've/ce/nodes/ve.ce.MWPreformattedNode.js',
|
||||
've/ce/nodes/ve.ce.MWImageNode.js',
|
||||
|
||||
've/ce/annotations/ve.ce.LinkAnnotation.js',
|
||||
've/ce/annotations/ve.ce.MWExternalLinkAnnotation.js',
|
||||
've/ce/annotations/ve.ce.MWInternalLinkAnnotation.js',
|
||||
've/ce/annotations/ve.ce.TextStyleAnnotation.js',
|
||||
|
||||
// ui
|
||||
've/ui/ve.ui.js',
|
||||
've/ui/ve.ui.Context.js',
|
||||
|
|
|
@ -168,8 +168,10 @@ $html = file_get_contents( $page );
|
|||
<script src="../../modules/ve/dm/metaitems/ve.dm.MWLanguageMetaItem.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.DomRange.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.AnnotationFactory.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.NodeFactory.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.Document.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.Annotation.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.Node.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.BranchNode.js"></script>
|
||||
<script src="../../modules/ve/ce/ve.ce.ContentBranchNode.js"></script>
|
||||
|
@ -199,6 +201,10 @@ $html = file_get_contents( $page );
|
|||
<script src="../../modules/ve/ce/nodes/ve.ce.MWHeadingNode.js"></script>
|
||||
<script src="../../modules/ve/ce/nodes/ve.ce.MWPreformattedNode.js"></script>
|
||||
<script src="../../modules/ve/ce/nodes/ve.ce.MWImageNode.js"></script>
|
||||
<script src="../../modules/ve/ce/annotations/ve.ce.LinkAnnotation.js"></script>
|
||||
<script src="../../modules/ve/ce/annotations/ve.ce.MWExternalLinkAnnotation.js"></script>
|
||||
<script src="../../modules/ve/ce/annotations/ve.ce.MWInternalLinkAnnotation.js"></script>
|
||||
<script src="../../modules/ve/ce/annotations/ve.ce.TextStyleAnnotation.js"></script>
|
||||
<script src="../../modules/ve/ui/ve.ui.js"></script>
|
||||
<script src="../../modules/ve/ui/ve.ui.Context.js"></script>
|
||||
<script src="../../modules/ve/ui/ve.ui.Frame.js"></script>
|
||||
|
|
35
modules/ve/ce/annotations/ve.ce.LinkAnnotation.js
Normal file
35
modules/ve/ce/annotations/ve.ce.LinkAnnotation.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*!
|
||||
* VisualEditor ContentEditable LinkAnnotation class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentEditable link annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.Annotation
|
||||
* @constructor
|
||||
* @param {ve.dm.LinkAnnotation} model Model to observe
|
||||
*/
|
||||
ve.ce.LinkAnnotation = function VeCeLinkAnnotation( model ) {
|
||||
// Parent constructor
|
||||
ve.ce.Annotation.call( this, model, $( '<a>' ) );
|
||||
|
||||
// DOM changes
|
||||
this.$.addClass( 've-ce-LinkAnnotation' );
|
||||
this.$.attr( 'href', model.getAttribute( 'href' ) );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.inheritClass( ve.ce.LinkAnnotation, ve.ce.Annotation );
|
||||
|
||||
/* Static Properties */
|
||||
|
||||
ve.ce.LinkAnnotation.static.name = 'link';
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.ce.annotationFactory.register( ve.ce.LinkAnnotation );
|
35
modules/ve/ce/annotations/ve.ce.MWExternalLinkAnnotation.js
Normal file
35
modules/ve/ce/annotations/ve.ce.MWExternalLinkAnnotation.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*!
|
||||
* VisualEditor ContentEditable MWExternalLinkAnnotation class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentEditable MediaWiki external link annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.LinkAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.MWExternalLinkAnnotation} model Model to observe
|
||||
*/
|
||||
ve.ce.MWExternalLinkAnnotation = function VeCeMWExternalLinkAnnotation( model ) {
|
||||
// Parent constructor
|
||||
ve.ce.LinkAnnotation.call( this, model );
|
||||
|
||||
// DOM changes
|
||||
this.$.addClass( 've-ce-MWExternalLinkAnnotation' );
|
||||
this.$.attr( 'title', model.getAttribute( 'href' ) );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.inheritClass( ve.ce.MWExternalLinkAnnotation, ve.ce.LinkAnnotation );
|
||||
|
||||
/* Static Properties */
|
||||
|
||||
ve.ce.MWExternalLinkAnnotation.static.name = 'link/MWexternal';
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.ce.annotationFactory.register( ve.ce.MWExternalLinkAnnotation );
|
39
modules/ve/ce/annotations/ve.ce.MWInternalLinkAnnotation.js
Normal file
39
modules/ve/ce/annotations/ve.ce.MWInternalLinkAnnotation.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*!
|
||||
* VisualEditor ContentEditable MWInternalLinkAnnotation class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentEditable MediaWiki internal link annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.LinkAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.MWInternalLinkAnnotation} model Model to observe
|
||||
*/
|
||||
ve.ce.MWInternalLinkAnnotation = function VeCeMWInternalLinkAnnotation( model ) {
|
||||
var dmRendering;
|
||||
// Parent constructor
|
||||
ve.ce.LinkAnnotation.call( this, model );
|
||||
|
||||
// DOM changes
|
||||
this.$.addClass( 've-ce-MWInternalLinkAnnotation' );
|
||||
this.$.attr( 'title', model.getAttribute( 'title' ) );
|
||||
// Get href from DM rendering
|
||||
dmRendering = model.getDomElements()[0];
|
||||
this.$.attr( 'href', dmRendering.getAttribute( 'href' ) );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.inheritClass( ve.ce.MWInternalLinkAnnotation, ve.ce.LinkAnnotation );
|
||||
|
||||
/* Static Properties */
|
||||
|
||||
ve.ce.MWInternalLinkAnnotation.static.name = 'link/MWinternal';
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.ce.annotationFactory.register( ve.ce.MWInternalLinkAnnotation );
|
213
modules/ve/ce/annotations/ve.ce.TextStyleAnnotation.js
Normal file
213
modules/ve/ce/annotations/ve.ce.TextStyleAnnotation.js
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*!
|
||||
* VisualEditor ContentEditable TextStyleAnnotation class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentEditable text style annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.Annotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleAnnotation} model Model to observe
|
||||
* @param {jQuery} $element jQuery element (required!)
|
||||
*/
|
||||
ve.ce.TextStyleAnnotation = function VeCeTextStyleAnnotation( model, $element ) {
|
||||
// Parent constructor
|
||||
ve.ce.Annotation.call( this, model, $element );
|
||||
|
||||
// DOM changes
|
||||
this.$.addClass( 've-ce-TextStyleAnnotation' );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.inheritClass( ve.ce.TextStyleAnnotation, ve.ce.Annotation );
|
||||
|
||||
/* Static Properties */
|
||||
|
||||
ve.ce.TextStyleAnnotation.static.name = 'textStyle';
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleAnnotation );
|
||||
|
||||
/* Concrete Subclasses */
|
||||
|
||||
/**
|
||||
* ContentEditable bold annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleBoldAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleBoldAnnotation = function VeCeTextStyleBoldAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<b>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleBoldAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleBoldAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleBoldAnnotation.static.name = 'textStyle/bold';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleBoldAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable italic annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleItalicAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleItalicAnnotation = function VeCeTextStyleItalicAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<i>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleItalicAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleItalicAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleItalicAnnotation.static.name = 'textStyle/italic';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleItalicAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable underline annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleUnderlineAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleUnderlineAnnotation = function VeCeTextStyleUnderlineAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<u>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleUnderlineAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleUnderlineAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleUnderlineAnnotation.static.name = 'textStyle/underline';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleUnderlineAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable strike annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleStrikeAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleStrikeAnnotation = function VeCeTextStyleStrikeAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<s>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleStrikeAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleStrikeAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleStrikeAnnotation.static.name = 'textStyle/strike';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleStrikeAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable small annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleSmallAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleSmallAnnotation = function VeCeTextStyleSmallAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<small>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleSmallAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleSmallAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleSmallAnnotation.static.name = 'textStyle/small';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleSmallAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable big annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleBigAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleBigAnnotation = function VeCeTextStyleBigAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<big>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleBigAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleBigAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleBigAnnotation.static.name = 'textStyle/big';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleBigAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable span annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleSpanAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleSpanAnnotation = function VeCeTextStyleSpanAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<span>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleSpanAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleSpanAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleSpanAnnotation.static.name = 'textStyle/span';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleSpanAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable strong annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleStrongAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleStrongAnnotation = function VeCeTextStyleStrongAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<strong>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleStrongAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleStrongAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleStrongAnnotation.static.name = 'textStyle/strong';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleStrongAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable emphasize annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleEmphasizeAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleEmphasizeAnnotation = function VeCeTextStyleEmphasizeAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<em>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleEmphasizeAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleEmphasizeAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleEmphasizeAnnotation.static.name = 'textStyle/emphasize';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleEmphasizeAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable superScript annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleSuperScriptAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleSuperScriptAnnotation = function VeCeTextStyleSuperScriptAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<sup>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleSuperScriptAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleSuperScriptAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleSuperScriptAnnotation.static.name = 'textStyle/superScript';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleSuperScriptAnnotation );
|
||||
|
||||
/**
|
||||
* ContentEditable subScript annotation.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.ce.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {ve.dm.TextStyleSubScriptAnnotation} model
|
||||
*/
|
||||
ve.ce.TextStyleSubScriptAnnotation = function VeCeTextStyleSubScriptAnnotation( model ) {
|
||||
ve.ce.TextStyleAnnotation.call( this, model, $( '<sub>' ) );
|
||||
this.$.addClass( 've-ce-TextStyleSubScriptAnnotation' );
|
||||
};
|
||||
ve.inheritClass( ve.ce.TextStyleSubScriptAnnotation, ve.ce.TextStyleAnnotation );
|
||||
ve.ce.TextStyleSubScriptAnnotation.static.name = 'textStyle/subScript';
|
||||
ve.ce.annotationFactory.register( ve.ce.TextStyleSubScriptAnnotation );
|
|
@ -22,9 +22,6 @@ ve.ce.MWEntityNode = function VeCeMWEntityNode( model ) {
|
|||
// Need CE=false to prevent selection issues
|
||||
this.$.attr( 'contenteditable', false );
|
||||
|
||||
// Properties
|
||||
this.currentSource = null;
|
||||
|
||||
// Events
|
||||
this.model.addListenerMethod( this, 'update', 'onUpdate' );
|
||||
|
||||
|
|
105
modules/ve/ce/ve.ce.Annotation.js
Normal file
105
modules/ve/ce/ve.ce.Annotation.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*!
|
||||
* VisualEditor ContentEditable Annotation class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generic ContentEditable annotation.
|
||||
*
|
||||
* This is an abstract class, annotations should extend this and call this constructor from their
|
||||
* constructor. You should not instantiate this class directly.
|
||||
*
|
||||
* Subclasses of ve.dm.Annotation should have a corresponding subclass here that controls rendering.
|
||||
*
|
||||
* @class
|
||||
* @constructor
|
||||
* @param {ve.dm.Annotation} model Model to observe
|
||||
* @param {jQuery} [$element] Element to use as a container
|
||||
*/
|
||||
ve.ce.Annotation = function VeCeAnnotation( model, $element ) {
|
||||
// Properties
|
||||
this.model = model;
|
||||
this.$ = $element || $( '<span>' );
|
||||
this.parent = null;
|
||||
this.live = false;
|
||||
|
||||
// Initialization
|
||||
this.$.data( 'annotation', this );
|
||||
ve.setDomAttributes(
|
||||
this.$[0],
|
||||
this.model.getAttributes( 'html/0/' ),
|
||||
this.constructor.static.domAttributeWhitelist
|
||||
);
|
||||
};
|
||||
|
||||
/* Events */
|
||||
|
||||
/**
|
||||
* @event live
|
||||
*/
|
||||
|
||||
/* Static Members */
|
||||
|
||||
// TODO create a single base class for ce.Node and ce.Annotation
|
||||
|
||||
ve.ce.Annotation.static = {};
|
||||
|
||||
/**
|
||||
* Allowed attributes for DOM elements.
|
||||
*
|
||||
* This list includes attributes that are generally safe to include in HTML loaded from a
|
||||
* foreign source and displaying it inside the browser. It doesn't include any event attributes,
|
||||
* for instance, which would allow arbitrary JavaScript execution. This alone is not enough to
|
||||
* make HTML safe to display, but it helps.
|
||||
*
|
||||
* TODO: Rather than use a single global list, set these on a per-annotation basis to something that makes
|
||||
* sense for that annotation in particular.
|
||||
*
|
||||
* @static
|
||||
* @property static.domAttributeWhitelist
|
||||
* @inheritable
|
||||
*/
|
||||
ve.ce.Annotation.static.domAttributeWhitelist = [
|
||||
'abbr', 'about', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellpadding', 'cellspacing',
|
||||
'char', 'charoff', 'cite', 'class', 'clear', 'color', 'colspan', 'datatype', 'datetime',
|
||||
'dir', 'face', 'frame', 'headers', 'height', 'href', 'id', 'itemid', 'itemprop', 'itemref',
|
||||
'itemscope', 'itemtype', 'lang', 'noshade', 'nowrap', 'property', 'rbspan', 'rel',
|
||||
'resource', 'rev', 'rowspan', 'rules', 'scope', 'size', 'span', 'src', 'start', 'style',
|
||||
'summary', 'title', 'type', 'typeof', 'valign', 'value', 'width'
|
||||
];
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Get the model this CE annotation observes.
|
||||
*
|
||||
* @method
|
||||
* @returns {ve.ce.Annotation} Model
|
||||
*/
|
||||
ve.ce.Annotation.prototype.getModel = function () {
|
||||
return this.model;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the annotation is attached to the live DOM.
|
||||
*
|
||||
* @method
|
||||
* @returns {boolean} Annotation is attached to the live DOM
|
||||
*/
|
||||
ve.ce.Annotation.prototype.isLive = function () {
|
||||
return this.live;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set live state.
|
||||
*
|
||||
* @method
|
||||
* @param {boolean} live The annotation has been attached to the live DOM (use false on detach)
|
||||
* @emits live
|
||||
*/
|
||||
ve.ce.Annotation.prototype.setLive = function ( live ) {
|
||||
this.live = live;
|
||||
this.emit( 'live' );
|
||||
};
|
28
modules/ve/ce/ve.ce.AnnotationFactory.js
Normal file
28
modules/ve/ce/ve.ce.AnnotationFactory.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*!
|
||||
* VisualEditor ContentEditable AnnotationFactory class.
|
||||
*
|
||||
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* ContentEditable annotation factory.
|
||||
*
|
||||
* @class
|
||||
* @extends ve.NodeFactory
|
||||
* @constructor
|
||||
*/
|
||||
ve.ce.AnnotationFactory = function VeCeAnnotationFactory() {
|
||||
// Parent constructor
|
||||
// FIXME give ve.NodeFactory a more generic name
|
||||
ve.NodeFactory.call( this );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.inheritClass( ve.ce.AnnotationFactory, ve.NodeFactory );
|
||||
|
||||
/* Initialization */
|
||||
|
||||
// TODO: Move instantiation to a different file
|
||||
ve.ce.annotationFactory = new ve.ce.AnnotationFactory();
|
|
@ -49,40 +49,18 @@ ve.ce.ContentBranchNode.prototype.onSplice = function () {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get an HTML rendering of contents.
|
||||
* Get an HTML rendering of the contents.
|
||||
*
|
||||
* @method
|
||||
* @returns {string} HTML rendering
|
||||
* @returns {jQuery}
|
||||
*/
|
||||
ve.ce.ContentBranchNode.prototype.getRenderedContents = function () {
|
||||
var i, j, open, close, startedClosing, arr, annotation, itemAnnotations, itemHtml, $wrapper,
|
||||
store = this.model.doc.getStore(), html = '',
|
||||
annotationStack = new ve.dm.AnnotationSet( store ), annotatedHtml = [];
|
||||
|
||||
function openAnnotations( annotations ) {
|
||||
var out = '',
|
||||
annotation, i, arr, rendered;
|
||||
arr = annotations.get();
|
||||
for ( i = 0; i < arr.length; i++ ) {
|
||||
annotation = arr[i];
|
||||
rendered = annotation.renderHTML();
|
||||
out += ve.getOpeningHtmlTag( rendered.tag, rendered.attributes );
|
||||
annotationStack.push( annotation );
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function closeAnnotations( annotations ) {
|
||||
var out = '',
|
||||
annotation, i, arr;
|
||||
arr = annotations.get();
|
||||
for ( i = 0; i < arr.length; i++ ) {
|
||||
annotation = arr[i];
|
||||
out += '</' + annotation.renderHTML().tag + '>';
|
||||
annotationStack.remove( annotation );
|
||||
}
|
||||
return out;
|
||||
}
|
||||
var i, j, itemHtml, itemAnnotations, startClosingAt, arr, annotation, $ann,
|
||||
store = this.model.doc.getStore(),
|
||||
annotationStack = new ve.dm.AnnotationSet( store ),
|
||||
annotatedHtml = [],
|
||||
$wrapper = $( '<div>' ),
|
||||
$current = $wrapper;
|
||||
|
||||
// Gather annotated HTML from the child nodes
|
||||
for ( i = 0; i < this.children.length; i++ ) {
|
||||
|
@ -98,60 +76,51 @@ ve.ce.ContentBranchNode.prototype.getRenderedContents = function () {
|
|||
itemHtml = annotatedHtml[i];
|
||||
itemAnnotations = new ve.dm.AnnotationSet( store );
|
||||
}
|
||||
open = new ve.dm.AnnotationSet( store );
|
||||
close = new ve.dm.AnnotationSet( store );
|
||||
|
||||
// Go through annotationStack from bottom to top (left to right), and
|
||||
// close all annotations starting at the first one that's in annotationStack but
|
||||
// not in itemAnnotations. Then reopen the ones that are in itemAnnotations.
|
||||
startedClosing = false;
|
||||
// FIXME code largely copied from ve.dm.Converter
|
||||
// Close annotations as needed
|
||||
// Go through annotationStack from bottom to top (low to high),
|
||||
// and find the first annotation that's not in annotations.
|
||||
startClosingAt = undefined;
|
||||
arr = annotationStack.get();
|
||||
for ( j = 0; j < arr.length; j++ ) {
|
||||
annotation = arr[j];
|
||||
if (
|
||||
!startedClosing &&
|
||||
annotationStack.contains( annotation ) &&
|
||||
!itemAnnotations.contains( annotation )
|
||||
) {
|
||||
startedClosing = true;
|
||||
if ( !itemAnnotations.contains( annotation ) ) {
|
||||
startClosingAt = j;
|
||||
break;
|
||||
}
|
||||
if ( startedClosing ) {
|
||||
// Because we're processing these in reverse order, we need
|
||||
// to put these in close in reverse order
|
||||
close.add( annotation, 0 );
|
||||
if ( itemAnnotations.contains( annotation ) ) {
|
||||
// open needs to be reversed with respect to close
|
||||
open.push( annotation );
|
||||
}
|
||||
}
|
||||
if ( startClosingAt !== undefined ) {
|
||||
// Close all annotations from top to bottom (high to low)
|
||||
// until we reach startClosingAt
|
||||
for ( j = annotationStack.getLength() - 1; j >= startClosingAt; j-- ) {
|
||||
// Traverse up
|
||||
$current = $current.parent();
|
||||
// Remove from annotationStack
|
||||
annotationStack.removeAt( j );
|
||||
}
|
||||
}
|
||||
|
||||
// Open all annotations that are in right but not in left
|
||||
open.addSet( itemAnnotations.diffWith( annotationStack ) );
|
||||
// Open annotations as needed
|
||||
arr = itemAnnotations.get();
|
||||
for ( j = 0; j < arr.length; j++ ) {
|
||||
annotation = arr[j];
|
||||
if ( !annotationStack.contains( annotation ) ) {
|
||||
// Create new node and descend into it
|
||||
$ann = ve.ce.annotationFactory.create( annotation.getType(), annotation ).$;
|
||||
$current.append( $ann );
|
||||
$current = $ann;
|
||||
// Add to annotationStack
|
||||
annotationStack.push( annotation );
|
||||
}
|
||||
}
|
||||
|
||||
// Output the annotation closings and openings
|
||||
html += closeAnnotations( close );
|
||||
html += openAnnotations( open );
|
||||
// Output the actual HTML
|
||||
if ( typeof itemHtml === 'string' ) {
|
||||
// Output it directly
|
||||
html += itemHtml;
|
||||
} else {
|
||||
// itemHtml is a jQuery object, output a placeholder
|
||||
html += '<div class="ve-ce-contentBranch-placeholder" rel="' + i + '"></div>';
|
||||
}
|
||||
$current.append( itemHtml );
|
||||
}
|
||||
// Close all remaining open annotations
|
||||
html += closeAnnotations( annotationStack.reversed() );
|
||||
|
||||
$wrapper = $( '<div>' ).html( html );
|
||||
// Replace placeholders
|
||||
$wrapper.find( '.ve-ce-contentBranch-placeholder' ).each( function() {
|
||||
var $this = $( this ), item = annotatedHtml[$this.attr( 'rel' )];
|
||||
$this.replaceWith( ve.isArray( item ) ? item[0] : item );
|
||||
} );
|
||||
|
||||
return $wrapper.contents();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* @class
|
||||
* @extends ve.dm.Annotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.LinkAnnotation = function VeDmLinkAnnotation( element ) {
|
||||
ve.dm.LinkAnnotation = function VeDmLinkAnnotation( linmodAnnotation ) {
|
||||
// Parent constructor
|
||||
ve.dm.Annotation.call( this, element );
|
||||
ve.dm.Annotation.call( this, linmodAnnotation );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -40,55 +40,19 @@ ve.dm.LinkAnnotation.static.name = 'link';
|
|||
*/
|
||||
ve.dm.LinkAnnotation.static.matchTagNames = ['a'];
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Get annotation data, especially the href of the link.
|
||||
*
|
||||
* @method
|
||||
* @param {HTMLElement} element
|
||||
* @returns {Object} Annotation data, containing href property
|
||||
*/
|
||||
ve.dm.LinkAnnotation.prototype.getAnnotationData = function( element ) {
|
||||
return { 'href': element.getAttribute( 'href' ) };
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert to an object with HTML element information.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} HTML element information, including tag and attributes properties
|
||||
*/
|
||||
ve.dm.LinkAnnotation.prototype.toHTML = function () {
|
||||
var parentResult = ve.dm.Annotation.prototype.toHTML.call( this );
|
||||
parentResult.tag = 'a';
|
||||
parentResult.attributes.href = this.data.href;
|
||||
return parentResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the hash object of the link annotation.
|
||||
*
|
||||
* This extends the basic annotation hash by adding htmlAttributes.rel
|
||||
* if it present.
|
||||
*
|
||||
* This is a custom hash function for ve#getHash.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} Object to hash
|
||||
*/
|
||||
ve.dm.LinkAnnotation.prototype.getHashObject = function () {
|
||||
var keys = [ 'name', 'data' ], obj = {}, i;
|
||||
for ( i = 0; i < keys.length; i++ ) {
|
||||
if ( this[keys[i]] !== undefined ) {
|
||||
obj[keys[i]] = this[keys[i]];
|
||||
ve.dm.LinkAnnotation.static.toDataElement = function ( domElements ) {
|
||||
return {
|
||||
'type': 'link',
|
||||
'attributes': {
|
||||
'href': domElements[0].getAttribute( 'href' )
|
||||
}
|
||||
}
|
||||
if ( this.htmlAttributes && this.htmlAttributes.rel ) {
|
||||
obj.htmlAttributes = {};
|
||||
obj.htmlAttributes.rel = this.htmlAttributes.rel;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
};
|
||||
|
||||
ve.dm.LinkAnnotation.static.toDomElements = function ( dataElement ) {
|
||||
var domElement = document.createElement( 'a' );
|
||||
domElement.setAttribute( 'href', dataElement.attributes.href );
|
||||
return [ domElement ];
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
|
|
@ -13,16 +13,16 @@
|
|||
* <a rel="mw:ExtLink/Numbered">
|
||||
* <a rel="mw:ExtLink/URL">
|
||||
*
|
||||
* Each example is semantically slightly different, but don't need special treatment (yet).
|
||||
* Each example is semantically slightly different, but they don't need special treatment (yet).
|
||||
*
|
||||
* @class
|
||||
* @extends ve.dm.LinkAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.MWExternalLinkAnnotation = function VeDmMWExternalLinkAnnotation( element ) {
|
||||
ve.dm.MWExternalLinkAnnotation = function VeDmMWExternalLinkAnnotation( linmodAnnotation ) {
|
||||
// Parent constructor
|
||||
ve.dm.LinkAnnotation.call( this, element );
|
||||
ve.dm.LinkAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -47,22 +47,17 @@ ve.dm.MWExternalLinkAnnotation.static.matchRdfaTypes = [
|
|||
'mw:ExtLink', 'mw:ExtLink/Numbered', 'mw:ExtLink/URL'
|
||||
];
|
||||
|
||||
/**
|
||||
* Convert to an object with HTML element information.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} HTML element information, including tag and attributes properties
|
||||
*/
|
||||
ve.dm.MWExternalLinkAnnotation.prototype.toHTML = function () {
|
||||
var parentResult = ve.dm.LinkAnnotation.prototype.toHTML.call( this );
|
||||
parentResult.attributes.rel = parentResult.attributes.rel || 'mw:ExtLink';
|
||||
ve.dm.MWExternalLinkAnnotation.static.toDataElement = function ( domElements ) {
|
||||
var parentResult = ve.dm.LinkAnnotation.static.toDataElement.apply( this, arguments );
|
||||
parentResult.type = 'link/MWexternal';
|
||||
parentResult.attributes.rel = domElements[0].getAttribute( 'rel' );
|
||||
return parentResult;
|
||||
};
|
||||
|
||||
ve.dm.MWExternalLinkAnnotation.prototype.renderHTML = function () {
|
||||
var result = this.toHTML();
|
||||
result.attributes.title = this.data.href;
|
||||
return result;
|
||||
ve.dm.MWExternalLinkAnnotation.static.toDomElements = function ( dataElement ) {
|
||||
var parentResult = ve.dm.LinkAnnotation.static.toDomElements( dataElement );
|
||||
parentResult[0].setAttribute( 'rel', dataElement.attributes.rel || 'mw:ExtLink' );
|
||||
return parentResult;
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* @class
|
||||
* @extends ve.dm.LinkAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {HTMLElement|Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation = function VeDmMWInternalLinkAnnotation( element ) {
|
||||
ve.dm.MWInternalLinkAnnotation = function VeDmMWInternalLinkAnnotation( linmodAnnotation ) {
|
||||
// Parent constructor
|
||||
ve.dm.LinkAnnotation.call( this, element );
|
||||
ve.dm.LinkAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -41,60 +41,40 @@ ve.dm.MWInternalLinkAnnotation.static.name = 'link/MWinternal';
|
|||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.static.matchRdfaTypes = ['mw:WikiLink'];
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Get annotation data, especially the href of the link.
|
||||
*
|
||||
* @method
|
||||
* @param {HTMLElement} element
|
||||
* @returns {Object} Annotation data, containing 'hrefPrefix' and 'title' properties
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.prototype.getAnnotationData = function ( element ) {
|
||||
ve.dm.MWInternalLinkAnnotation.static.toDataElement = function ( domElements ) {
|
||||
// Get title from href
|
||||
// The href is simply the title, unless we're dealing with a page that has slashes in its name
|
||||
// in which case it's preceded by one or more instances of "./" or "../", so strip those
|
||||
/*jshint regexp:false */
|
||||
var matches = element.getAttribute( 'href' ).match( /^((?:\.\.?\/)*)(.*)$/ );
|
||||
var matches = domElements[0].getAttribute( 'href' ).match( /^((?:\.\.?\/)*)(.*)$/ );
|
||||
return {
|
||||
// Store the ./ and ../ prefixes so we can restore them on the way out
|
||||
'hrefPrefix': matches[1],
|
||||
'title': decodeURIComponent( matches[2] ).replace( /_/g, ' ' ),
|
||||
'origTitle': matches[2]
|
||||
'type': 'link/MWinternal',
|
||||
'attributes': {
|
||||
'hrefPrefix': matches[1],
|
||||
'title': decodeURIComponent( matches[2] ).replace( /_/g, ' ' ),
|
||||
'origTitle': matches[2]
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert to an object with HTML element information.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} HTML element information, including tag and attributes properties
|
||||
*/
|
||||
ve.dm.MWInternalLinkAnnotation.prototype.toHTML = function () {
|
||||
ve.dm.MWInternalLinkAnnotation.static.toDomElements = function ( dataElement ) {
|
||||
var href,
|
||||
parentResult = ve.dm.LinkAnnotation.prototype.toHTML.call( this );
|
||||
if (
|
||||
this.data.origTitle &&
|
||||
decodeURIComponent( this.data.origTitle ).replace( /_/g, ' ' ) === this.data.title
|
||||
) {
|
||||
domElement = document.createElement( 'a' ),
|
||||
title = dataElement.attributes.title,
|
||||
origTitle = dataElement.attributes.origTitle;
|
||||
if ( origTitle && decodeURIComponent( origTitle ).replace( /_/g, ' ' ) === title ) {
|
||||
// Restore href from origTitle
|
||||
href = this.data.origTitle;
|
||||
href = origTitle;
|
||||
// Only use hrefPrefix if restoring from origTitle
|
||||
if ( this.data.hrefPrefix ) {
|
||||
href = this.data.hrefPrefix + href;
|
||||
if ( dataElement.attributes.hrefPrefix ) {
|
||||
href = dataElement.attributes.hrefPrefix + href;
|
||||
}
|
||||
} else {
|
||||
href = encodeURIComponent( this.data.title );
|
||||
href = encodeURIComponent( title );
|
||||
}
|
||||
parentResult.attributes.href = href;
|
||||
parentResult.attributes.rel = 'mw:WikiLink';
|
||||
return parentResult;
|
||||
};
|
||||
|
||||
ve.dm.MWInternalLinkAnnotation.prototype.renderHTML = function () {
|
||||
var result = this.toHTML();
|
||||
result.attributes.title = this.data.title;
|
||||
return result;
|
||||
domElement.setAttribute( 'href', href );
|
||||
domElement.setAttribute( 'rel', 'mw:WikiLink' );
|
||||
return [ domElement ];
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* @class
|
||||
* @extends ve.dm.Annotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleAnnotation = function VeDmTextStyleAnnotation( element ) {
|
||||
ve.dm.Annotation.call( this, element );
|
||||
ve.dm.TextStyleAnnotation = function VeDmTextStyleAnnotation( linmodAnnotation ) {
|
||||
ve.dm.Annotation.call( this, linmodAnnotation );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
@ -39,18 +39,43 @@ ve.dm.TextStyleAnnotation.static.name = 'textStyle';
|
|||
*/
|
||||
ve.dm.TextStyleAnnotation.static.matchTagNames = [];
|
||||
|
||||
/**
|
||||
* Convert to an object with HTML element information.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} HTML element information, including tag and attributes properties
|
||||
*/
|
||||
ve.dm.TextStyleAnnotation.prototype.toHTML = function () {
|
||||
var parentResult = ve.dm.Annotation.prototype.toHTML.call( this );
|
||||
parentResult.tag = parentResult.tag || this.constructor.static.matchTagNames[0];
|
||||
return parentResult;
|
||||
ve.dm.TextStyleAnnotation.static.toDataElement = function ( domElements ) {
|
||||
var types = {
|
||||
'b': 'bold',
|
||||
'i': 'italic',
|
||||
'u': 'underline',
|
||||
's': 'strike',
|
||||
'small': 'small',
|
||||
'big': 'big',
|
||||
'span': 'span',
|
||||
'strong': 'strong',
|
||||
'em': 'emphasize',
|
||||
'sup': 'superScript',
|
||||
'sub': 'subScript'
|
||||
};
|
||||
return {
|
||||
'type': 'textStyle/' + types[domElements[0].nodeName.toLowerCase()]
|
||||
};
|
||||
};
|
||||
|
||||
ve.dm.TextStyleAnnotation.static.toDomElements = function ( dataElement ) {
|
||||
var nodeNames = {
|
||||
'bold': 'b',
|
||||
'italic': 'i',
|
||||
'underline': 'u',
|
||||
'strike': 's',
|
||||
'small': 'small',
|
||||
'big': 'big',
|
||||
'span': 'span',
|
||||
'strong': 'strong',
|
||||
'emphasize': 'em',
|
||||
'superScript': 'sup',
|
||||
'subScript': 'sub'
|
||||
};
|
||||
return [ document.createElement( nodeNames[dataElement.type.substring( 10 )] ) ];
|
||||
};
|
||||
|
||||
|
||||
/* Registration */
|
||||
|
||||
ve.dm.modelRegistry.register( ve.dm.TextStyleAnnotation );
|
||||
|
@ -63,10 +88,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleBoldAnnotation = function VeDmTextStyleBoldAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleBoldAnnotation = function VeDmTextStyleBoldAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleBoldAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleBoldAnnotation.static.name = 'textStyle/bold';
|
||||
|
@ -79,10 +104,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleBoldAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleItalicAnnotation = function VeDmTextStyleItalicAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleItalicAnnotation = function VeDmTextStyleItalicAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleItalicAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleItalicAnnotation.static.name = 'textStyle/italic';
|
||||
|
@ -95,10 +120,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleItalicAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleUnderlineAnnotation = function VeDmTextStyleUnderlineAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleUnderlineAnnotation = function VeDmTextStyleUnderlineAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleUnderlineAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleUnderlineAnnotation.static.name = 'textStyle/underline';
|
||||
|
@ -111,10 +136,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleUnderlineAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleStrikeAnnotation = function VeDmTextStyleStrikeAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleStrikeAnnotation = function VeDmTextStyleStrikeAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleStrikeAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleStrikeAnnotation.static.name = 'textStyle/strike';
|
||||
|
@ -127,10 +152,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleStrikeAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleSmallAnnotation = function VeDmTextStyleSmallAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleSmallAnnotation = function VeDmTextStyleSmallAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleSmallAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleSmallAnnotation.static.name = 'textStyle/small';
|
||||
|
@ -143,10 +168,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleSmallAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleBigAnnotation = function VeDmTextStyleBigAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleBigAnnotation = function VeDmTextStyleBigAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleBigAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleBigAnnotation.static.name = 'textStyle/big';
|
||||
|
@ -159,10 +184,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleBigAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleSpanAnnotation = function VeDmTextStyleSpanAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleSpanAnnotation = function VeDmTextStyleSpanAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleSpanAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleSpanAnnotation.static.name = 'textStyle/span';
|
||||
|
@ -175,10 +200,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleSpanAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleStrongAnnotation = function VeDmTextStyleStrongAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleStrongAnnotation = function VeDmTextStyleStrongAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleStrongAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleStrongAnnotation.static.name = 'textStyle/strong';
|
||||
|
@ -191,10 +216,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleStrongAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleEmphasizeAnnotation = function VeDmTextStyleEmphasizeAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleEmphasizeAnnotation = function VeDmTextStyleEmphasizeAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleEmphasizeAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleEmphasizeAnnotation.static.name = 'textStyle/emphasize';
|
||||
|
@ -207,10 +232,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleEmphasizeAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleSuperScriptAnnotation = function VeDmTextStyleSuperScriptAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleSuperScriptAnnotation = function VeDmTextStyleSuperScriptAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleSuperScriptAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleSuperScriptAnnotation.static.name = 'textStyle/superScript';
|
||||
|
@ -223,10 +248,10 @@ ve.dm.modelRegistry.register( ve.dm.TextStyleSuperScriptAnnotation );
|
|||
* @class
|
||||
* @extends ve.dm.TextStyleAnnotation
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} element
|
||||
* @param {Object} linmodAnnotation
|
||||
*/
|
||||
ve.dm.TextStyleSubScriptAnnotation = function VeDmTextStyleSubScriptAnnotation( element ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, element );
|
||||
ve.dm.TextStyleSubScriptAnnotation = function VeDmTextStyleSubScriptAnnotation( linmodAnnotation ) {
|
||||
ve.dm.TextStyleAnnotation.call( this, linmodAnnotation );
|
||||
};
|
||||
ve.inheritClass( ve.dm.TextStyleSubScriptAnnotation, ve.dm.TextStyleAnnotation );
|
||||
ve.dm.TextStyleSubScriptAnnotation.static.name = 'textStyle/subScript';
|
||||
|
|
|
@ -11,29 +11,16 @@
|
|||
* This is an abstract class, annotations should extend this and call this constructor from their
|
||||
* constructor. You should not instantiate this class directly.
|
||||
*
|
||||
* Annotations in the linear model are instances of subclasses of this class. Subclasses are
|
||||
* required to have a constructor with the same signature.
|
||||
*
|
||||
* this.htmlTagName and this.htmlAttributes are private to the base class, subclasses must not
|
||||
* use them. Any information from the HTML element that is needed later should be extracted into
|
||||
* this.data by overriding getAnnotationData(). Subclasses can read from this.data but must not
|
||||
* write to it directly.
|
||||
* Annotations in the linear model are instances of subclasses of this class. Subclasses should
|
||||
* only override static properties and functions.
|
||||
*
|
||||
* @class
|
||||
* @constructor
|
||||
* @param {HTMLElement|Object} [element] HTML element the annotation was converted from, if any, or
|
||||
* an object to copy into the annotation's data property
|
||||
* @param {Object} linmodAnnotation Linear model annotation
|
||||
*/
|
||||
ve.dm.Annotation = function VeDmAnnotation( element ) {
|
||||
this.name = this.constructor.static.name; // Needed for proper hashing
|
||||
this.data = {};
|
||||
if ( ve.isPlainObject( element ) ) {
|
||||
this.data = ve.copyObject( element );
|
||||
} else if ( element && element.nodeType === Node.ELEMENT_NODE ) {
|
||||
this.htmlTagName = element.nodeName.toLowerCase();
|
||||
this.htmlAttributes = ve.getDomAttributes( element );
|
||||
this.data = this.getAnnotationData( element );
|
||||
}
|
||||
ve.dm.Annotation = function VeDmAnnotation( linmodAnnotation ) {
|
||||
this.name = this.constructor.static.name;
|
||||
this.linmodAnnotation = linmodAnnotation;
|
||||
};
|
||||
|
||||
/* Static properties */
|
||||
|
@ -48,6 +35,8 @@ ve.dm.Annotation = function VeDmAnnotation( element ) {
|
|||
*/
|
||||
ve.dm.Annotation.static = {};
|
||||
|
||||
// TODO create a single base class for dm.Node, dm.Annotation and dm.MetaItem
|
||||
|
||||
/**
|
||||
* Symbolic name for the annotation class.
|
||||
*
|
||||
|
@ -105,74 +94,134 @@ ve.dm.Annotation.static.matchRdfaTypes = null;
|
|||
*/
|
||||
ve.dm.Annotation.static.matchFunction = null;
|
||||
|
||||
/**
|
||||
* Static function to convert a DOM element or set of sibling DOM elements to an annotation of
|
||||
* this type.
|
||||
*
|
||||
* This function is only called if this annotation "won" the matching for the first DOM element, so
|
||||
* domElements[0] will match this item's matching rule. For annotations, there is only one node in
|
||||
* domElements[].
|
||||
*
|
||||
* This function is allowed to return an annotation even if context.expectingContent is false.
|
||||
* If that happens, the annotation will be put in a wrapper paragraph. If this function returns
|
||||
* null, the DOM element will be converted to an alien node.
|
||||
*
|
||||
* The returned linear model annotation must have a type property set to a registered annotation
|
||||
* name (usually the annotations's .static.name, but that's not required). It may optionally have an
|
||||
* attributes property set to an object with key-value pairs. Any other properties are not allowed.
|
||||
*
|
||||
* @static
|
||||
* @method
|
||||
* @param {HTMLElement[]} domElements DOM elements to convert. Only one element
|
||||
* @param {Object} context Object describing the current state of the converter
|
||||
* @param {boolean} context.expectingContent Whether this function is expected to return a content element
|
||||
* @param {boolean} context.inWrapper Whether this element is in a wrapper paragraph generated by the converter;
|
||||
* can only be true if context.expectingContent is also true
|
||||
* @param {boolean} context.canCloseWrapper Whether the current wrapper paragraph can be closed;
|
||||
* can only be true if context.inWrapper is also true
|
||||
* @returns {Object|null} Linear model annotation, or null to alienate
|
||||
*/
|
||||
ve.dm.Annotation.static.toDataElement = function ( /*domElements, context*/ ) {
|
||||
throw new Error( 've.dm.Annotation subclass must implement toDataElement' );
|
||||
};
|
||||
|
||||
/**
|
||||
* Static function to convert a linear model annotation of this type back to a DOM element.
|
||||
*
|
||||
* This function returns an array of DOM elements for consistency, but annotations can only return
|
||||
* one DOM element, so any elements beyond the first are ignored.
|
||||
*
|
||||
* @static
|
||||
* @method
|
||||
* @param {Object} Linear model annotation with a type property and optionally an attributes property
|
||||
* @returns {HTMLElement[]} Array of one DOM element
|
||||
*/
|
||||
ve.dm.Annotation.static.toDomElements = function ( /*dataElement*/ ) {
|
||||
throw new Error( 've.dm.Annotation subclass must implement toDomElements' );
|
||||
};
|
||||
|
||||
/**
|
||||
* About grouping is not supported for annotations; setting this to true has no effect.
|
||||
*
|
||||
* @static
|
||||
* @property {boolean} static.enableAboutGrouping
|
||||
*/
|
||||
ve.dm.Annotation.static.enableAboutGrouping = false;
|
||||
|
||||
/**
|
||||
* Whether HTML attributes should be preserved for this annotation type. If true, the HTML attributes
|
||||
* of the DOM elements will be stored as attributes in the linear model annotation. The attribute
|
||||
* names will be html/i/attrName, where i is the index of the DOM element in the domElements array,
|
||||
* and attrName is the name of the attribute.
|
||||
*
|
||||
* This should generally be enabled, except for annotation types that store their entire HTML in an
|
||||
* attribute.
|
||||
*
|
||||
* @static
|
||||
* @property {boolean} static.storeHtmlAttributes
|
||||
* @inheritable
|
||||
*/
|
||||
ve.dm.Annotation.static.storeHtmlAttributes = true;
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Get annotation data for the linear model.
|
||||
*
|
||||
* Called when building a new annotation from an HTML element.
|
||||
*
|
||||
* This annotation data object is completely free-form. It's stored in the linear model, it can be
|
||||
* manipulated by UI widgets, and you access it as this.data in toHTML() on the way out and in
|
||||
* renderHTML() for rendering. It is also the ONLY data you can reliably use in those contexts, so
|
||||
* any information from the HTML element that you'll need later should be extracted into the data
|
||||
* object here.
|
||||
*
|
||||
* @method
|
||||
* @param {HTMLElement} element HTML element the annotation will represent
|
||||
* @returns {Object} Annotation data
|
||||
*/
|
||||
ve.dm.Annotation.prototype.getAnnotationData = function () {
|
||||
return {};
|
||||
ve.dm.Annotation.prototype.getType = function () {
|
||||
return this.name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert the annotation back to HTML for output purposes.
|
||||
*
|
||||
* You should only use this.data here, you cannot reliably use any of the other properties.
|
||||
* The default action is to restore the original HTML element's tag name and attributes (if this
|
||||
* annotation was created based on an element). If a subclass wants to do this too (this is common),
|
||||
* it should call its parent's implementation first, then manipulate the return value.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} Object with 'tag' (tag name) and 'attributes' (object with attribute key/values)
|
||||
* Get the linear model object for this annotation
|
||||
* @returns {Object} Linear model annotation
|
||||
*/
|
||||
ve.dm.Annotation.prototype.toHTML = function () {
|
||||
return {
|
||||
'tag': this.htmlTagName || '',
|
||||
'attributes': this.htmlAttributes || {}
|
||||
};
|
||||
ve.dm.Annotation.prototype.getLinmodAnnotation = function () {
|
||||
return this.linmodAnnotation;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert the annotation to HTML for rendering purposes.
|
||||
* Get the value of an attribute
|
||||
*
|
||||
* By default, this just calls #toHTML, but it may be customized if the rendering should be
|
||||
* different from the output.
|
||||
*
|
||||
* @see #toHTML
|
||||
* Return value is by reference if array or object
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} Object with 'tag' (tag name) and 'attributes' (object with attribute key/values)
|
||||
* @param {string} key Name of attribute to get
|
||||
* @returns {Mixed} Value of attribute, or undefined if no such attribute exists
|
||||
*/
|
||||
ve.dm.Annotation.prototype.renderHTML = function () {
|
||||
return this.toHTML();
|
||||
ve.dm.Annotation.prototype.getAttribute = function ( key ) {
|
||||
return this.linmodAnnotation && this.linmodAnnotation.attributes ?
|
||||
this.linmodAnnotation.attributes[key] : undefined;
|
||||
};
|
||||
|
||||
// FIXME code copied from ve.dm.Node
|
||||
/**
|
||||
* Get the hash object of the annotation.
|
||||
* Get a copy of all attributes.
|
||||
*
|
||||
* This is a custom hash function for ve#getHash.
|
||||
* Values are by reference if array or object, similar to using the getAttribute method.
|
||||
*
|
||||
* @method
|
||||
* @returns {Object} Object to hash
|
||||
* @param {string} prefix Only return attributes with this prefix, and remove the prefix from them
|
||||
* @returns {Object} Attributes
|
||||
*/
|
||||
ve.dm.Annotation.prototype.getHashObject = function () {
|
||||
var keys = [ 'name', 'data' ], obj = {}, i;
|
||||
for ( i = 0; i < keys.length; i++ ) {
|
||||
if ( this[keys[i]] !== undefined ) {
|
||||
obj[keys[i]] = this[keys[i]];
|
||||
ve.dm.Annotation.prototype.getAttributes = function ( prefix ) {
|
||||
var key, filtered,
|
||||
attributes = this.element && this.linmodAnnotation.attributes ?
|
||||
this.linmodAnnotation.attributes : {};
|
||||
if ( prefix ) {
|
||||
filtered = {};
|
||||
for ( key in attributes ) {
|
||||
if ( key.indexOf( prefix ) === 0 ) {
|
||||
filtered[key.substr( prefix.length )] = attributes[key];
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
return ve.extendObject( {}, attributes );
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience wrapper for .toDomElements() on the current annotation
|
||||
* @method
|
||||
* @see #toDomElements
|
||||
*/
|
||||
ve.dm.Annotation.prototype.getDomElements = function () {
|
||||
return this.constructor.static.toDomElements( this.linmodAnnotation );
|
||||
};
|
||||
|
|
|
@ -98,7 +98,7 @@ ve.dm.Converter.prototype.getDomElementsFromDataElement = function ( dataElement
|
|||
|
||||
/**
|
||||
* Create a data element from a DOM element.
|
||||
* @param {ve.dm.Node|ve.dm.MetaItem} modelClass Model class to use for conversion
|
||||
* @param {ve.dm.Node|ve.dm.MetaItem|ve.dm.Annotation} modelClass Model class to use for conversion
|
||||
* @param {HTMLElement[]} domElements DOM elements to convert
|
||||
* @param {Object} context Converter context to pass to toDataElement() (will be cloned)
|
||||
* @returns {Object} Data element
|
||||
|
@ -245,7 +245,7 @@ ve.dm.Converter.prototype.getDataFromDomRecursion = function ( store, domElement
|
|||
path = path || ['document'];
|
||||
var i, childDomElement, childDomElements, childDataElement, text, childTypes, matches,
|
||||
wrappingParagraph, prevElement, childAnnotations, modelName, modelClass,
|
||||
annotation, childIsContent, aboutGroup,
|
||||
annotation, annotationData, childIsContent, aboutGroup,
|
||||
data = [],
|
||||
branchType = path[path.length - 1],
|
||||
branchHasContent = this.nodeFactory.canNodeContainContent( branchType ),
|
||||
|
@ -270,7 +270,10 @@ ve.dm.Converter.prototype.getDataFromDomRecursion = function ( store, domElement
|
|||
modelName = this.modelRegistry.matchElement( childDomElement );
|
||||
modelClass = this.modelRegistry.lookup( modelName ) || ve.dm.AlienNode;
|
||||
if ( modelClass.prototype instanceof ve.dm.Annotation ) {
|
||||
annotation = this.annotationFactory.create( modelName, childDomElement );
|
||||
annotationData = this.createDataElement( modelClass, [ childDomElement ], context );
|
||||
}
|
||||
if ( modelClass.prototype instanceof ve.dm.Annotation && annotationData ) {
|
||||
annotation = this.annotationFactory.create( modelName, annotationData );
|
||||
// Start wrapping if needed
|
||||
if ( !context.inWrapper && !context.expectingContent ) {
|
||||
startWrapping();
|
||||
|
@ -627,7 +630,9 @@ ve.dm.Converter.prototype.getDomFromData = function ( store, data ) {
|
|||
text = '';
|
||||
}
|
||||
// Create new node and descend into it
|
||||
annotationElement = this.getDomElementFromDataAnnotation( annotation, doc );
|
||||
annotationElement = this.getDomElementsFromDataElement(
|
||||
annotation.getLinmodAnnotation(), doc
|
||||
)[0];
|
||||
domElement.appendChild( annotationElement );
|
||||
domElement = annotationElement;
|
||||
// Add to annotationStack
|
||||
|
|
|
@ -491,6 +491,7 @@ ve.dm.Node.prototype.getOffset = function () {
|
|||
* Return value is by reference if array or object.
|
||||
*
|
||||
* @method
|
||||
* @param {string} key Name of attribute to get
|
||||
* @returns {Mixed} Value of attribute, or undefined if no such attribute exists
|
||||
*/
|
||||
ve.dm.Node.prototype.getAttribute = function ( key ) {
|
||||
|
|
|
@ -10,9 +10,10 @@ QUnit.module( 've.ce.ContentBranchNode' );
|
|||
/* Tests */
|
||||
|
||||
QUnit.test( 'getRenderedContents', function ( assert ) {
|
||||
var i, len, doc, $rendered,
|
||||
var i, len, doc, $rendered, $wrapper,
|
||||
cases = [
|
||||
{
|
||||
'msg': 'Plain text without annotations',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
|
@ -23,6 +24,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': 'abc'
|
||||
},
|
||||
{
|
||||
'msg': 'Bold text',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
['a', [ { 'type': 'textStyle/bold' } ]],
|
||||
|
@ -33,6 +35,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': '<b>abc</b>'
|
||||
},
|
||||
{
|
||||
'msg': 'Bold character, plain character, italic character',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
['a', [ { 'type': 'textStyle/bold' } ]],
|
||||
|
@ -43,6 +46,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': '<b>a</b>b<i>c</i>'
|
||||
},
|
||||
{
|
||||
'msg': 'Bold, italic and underlined text (same order)',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
['a', [
|
||||
|
@ -65,6 +69,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': '<b><i><u>abc</u></i></b>'
|
||||
},
|
||||
{
|
||||
'msg': 'Varying order in consecutive range doesn\'t affect rendering',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
['a', [
|
||||
|
@ -87,6 +92,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': '<b><i><u>abc</u></i></b>'
|
||||
},
|
||||
{
|
||||
'msg': 'Varying order in non-consecutive range does affect rendering',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
['a', [
|
||||
|
@ -105,6 +111,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': '<b><i><u>a</u></i></b>b<u><b><i>c</i></b></u>'
|
||||
},
|
||||
{
|
||||
'msg': 'Text annotated in varying order, surrounded by plain text',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
|
@ -133,6 +140,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': 'abc<b><i><u>def</u></i></b>ghi'
|
||||
},
|
||||
{
|
||||
'msg': 'Out-of-order closings do not produce misnested tags',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
|
@ -160,6 +168,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': 'abc<b><i><u>d</u></i></b><i><u>e<b>f</b></u></i>ghi'
|
||||
},
|
||||
{
|
||||
'msg': 'Additional openings are added inline, even when out of order',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
|
@ -187,6 +196,7 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'html': 'abc<i><u><b>d</b>e<b>f</b></u></i>ghi'
|
||||
},
|
||||
{
|
||||
'msg': 'Out-of-order closings surrounded by plain text',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
|
@ -210,9 +220,10 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
'i',
|
||||
{ 'type': '/paragraph' }
|
||||
],
|
||||
'html': 'abc<i><u><b>d</b></u></i><u><b>ef</b></u>ghi'
|
||||
'html': 'abc<i><u><b>d</b></u></i><b><u>ef</u></b>ghi'
|
||||
},
|
||||
{
|
||||
'msg': 'Annotation spanning text and inline nodes',
|
||||
'data': [
|
||||
{ 'type': 'paragraph' },
|
||||
'a',
|
||||
|
@ -242,6 +253,9 @@ QUnit.test( 'getRenderedContents', function ( assert ) {
|
|||
for ( i = 0, len = cases.length; i < len; i++ ) {
|
||||
doc = new ve.dm.Document( ve.dm.example.preprocessAnnotations( cases[i].data ) );
|
||||
$rendered = ( new ve.ce.ParagraphNode( doc.documentNode.getChildren()[0] ) ).getRenderedContents();
|
||||
assert.deepEqual( $( '<div>' ).append( $rendered ).html(), cases[i].html );
|
||||
$wrapper = $( '<div>' ).append( $rendered );
|
||||
// HACK strip out all the class="ve-ce-TextStyleAnnotation ve-ce-TextStyleBoldAnnotation" crap
|
||||
$wrapper.find( '.ve-ce-TextStyleAnnotation' ).removeAttr( 'class' );
|
||||
assert.equalDomElement( $wrapper[0], $( '<div>' ).html( cases[i].html )[0], cases[i].msg );
|
||||
}
|
||||
} );
|
||||
|
|
|
@ -19,7 +19,7 @@ ve.dm.example = {};
|
|||
* annotation objects, and wraps the result in a ve.dm.ElementLinearData object.
|
||||
*
|
||||
* Shorthand notation for annotations is:
|
||||
* [ 'a', [ { 'type': 'link', 'data': { 'href': '...' }, 'htmlTagName': 'a', 'htmlAttributes': { ... } } ] ]
|
||||
* [ 'a', [ { 'type': 'link', 'attributes': { 'href': '...' } ] ]
|
||||
*
|
||||
* The actual storage format has an instance of ve.dm.LinkAnnotation instead of the plain object,
|
||||
* and an instance of ve.dm.AnnotationSet instead of the array.
|
||||
|
@ -55,18 +55,11 @@ ve.dm.example.preprocessAnnotations = function ( data, store ) {
|
|||
/**
|
||||
* Create an annotation object from shorthand notation.
|
||||
* @method
|
||||
* @param {Object} annotation Plain object with type, data, htmlTagName and htmlAttributes properties
|
||||
* @param {Object} annotation Plain object with type and attributes properties
|
||||
* @return {ve.dm.Annotation} Instance of the right ve.dm.Annotation subclass
|
||||
*/
|
||||
ve.dm.example.createAnnotation = function ( annotation ) {
|
||||
var ann, annKey;
|
||||
ann = ve.dm.annotationFactory.create( annotation.type );
|
||||
for ( annKey in annotation ) {
|
||||
if ( annKey !== 'type' ) {
|
||||
ann[annKey] = annotation[annKey];
|
||||
}
|
||||
}
|
||||
return ann;
|
||||
return ve.dm.annotationFactory.create( annotation.type, annotation );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,10 +81,10 @@ ve.dm.example.createAnnotationSet = function ( store, annotations ) {
|
|||
};
|
||||
|
||||
/* Some common annotations in shorthand format */
|
||||
ve.dm.example.bold = { 'type': 'textStyle/bold', 'htmlTagName': 'b', 'htmlAttributes': {} };
|
||||
ve.dm.example.italic = { 'type': 'textStyle/italic', 'htmlTagName': 'i', 'htmlAttributes': {} };
|
||||
ve.dm.example.underline = { 'type': 'textStyle/underline', 'htmlTagName': 'u', 'htmlAttributes': {} };
|
||||
ve.dm.example.span = { 'type': 'textStyle/span', 'htmlTagName': 'span', 'htmlAttributes': {} };
|
||||
ve.dm.example.bold = { 'type': 'textStyle/bold' };
|
||||
ve.dm.example.italic = { 'type': 'textStyle/italic' };
|
||||
ve.dm.example.underline = { 'type': 'textStyle/underline' };
|
||||
ve.dm.example.span = { 'type': 'textStyle/span' };
|
||||
|
||||
/**
|
||||
* Creates a document from example data.
|
||||
|
@ -1049,16 +1042,13 @@ ve.dm.example.domToDataCases = {
|
|||
'b',
|
||||
[ {
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'title': 'Foo bar',
|
||||
'origTitle': 'Foo_bar',
|
||||
'hrefPrefix': ''
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'data-rt': '{"sHref":"foo bar"}',
|
||||
'href': 'Foo_bar',
|
||||
'rel': 'mw:WikiLink'
|
||||
'hrefPrefix': '',
|
||||
'html/0/data-rt': '{"sHref":"foo bar"}',
|
||||
'html/0/href': 'Foo_bar',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1066,16 +1056,13 @@ ve.dm.example.domToDataCases = {
|
|||
'a',
|
||||
[ {
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'title': 'Foo bar',
|
||||
'origTitle': 'Foo_bar',
|
||||
'hrefPrefix': ''
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'data-rt': '{"sHref":"foo bar"}',
|
||||
'href': 'Foo_bar',
|
||||
'rel': 'mw:WikiLink'
|
||||
'hrefPrefix': '',
|
||||
'html/0/data-rt': '{"sHref":"foo bar"}',
|
||||
'html/0/href': 'Foo_bar',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1083,16 +1070,13 @@ ve.dm.example.domToDataCases = {
|
|||
'r',
|
||||
[ {
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'title': 'Foo bar',
|
||||
'origTitle': 'Foo_bar',
|
||||
'hrefPrefix': ''
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'data-rt': '{"sHref":"foo bar"}',
|
||||
'href': 'Foo_bar',
|
||||
'rel': 'mw:WikiLink'
|
||||
'hrefPrefix': '',
|
||||
'html/0/data-rt': '{"sHref":"foo bar"}',
|
||||
'html/0/href': 'Foo_bar',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1110,15 +1094,12 @@ ve.dm.example.domToDataCases = {
|
|||
'F',
|
||||
[ {
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'title': 'Foo/Bar',
|
||||
'origTitle': 'Foo/Bar',
|
||||
'hrefPrefix': './../../../'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': './../../../Foo/Bar',
|
||||
'rel': 'mw:WikiLink'
|
||||
'hrefPrefix': './../../../',
|
||||
'html/0/href': './../../../Foo/Bar',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1126,15 +1107,12 @@ ve.dm.example.domToDataCases = {
|
|||
'o',
|
||||
[ {
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'title': 'Foo/Bar',
|
||||
'origTitle': 'Foo/Bar',
|
||||
'hrefPrefix': './../../../'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': './../../../Foo/Bar',
|
||||
'rel': 'mw:WikiLink'
|
||||
'hrefPrefix': './../../../',
|
||||
'html/0/href': './../../../Foo/Bar',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1142,15 +1120,12 @@ ve.dm.example.domToDataCases = {
|
|||
'o',
|
||||
[ {
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'title': 'Foo/Bar',
|
||||
'origTitle': 'Foo/Bar',
|
||||
'hrefPrefix': './../../../'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': './../../../Foo/Bar',
|
||||
'rel': 'mw:WikiLink'
|
||||
'hrefPrefix': './../../../',
|
||||
'html/0/href': './../../../Foo/Bar',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1165,13 +1140,11 @@ ve.dm.example.domToDataCases = {
|
|||
'[',
|
||||
[ {
|
||||
'type': 'link/MWexternal',
|
||||
'data': {
|
||||
'href': 'http://www.mediawiki.org/'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'attributes': {
|
||||
'href': 'http://www.mediawiki.org/',
|
||||
'rel': 'mw:ExtLink/Numbered'
|
||||
'rel': 'mw:ExtLink/Numbered',
|
||||
'html/0/href': 'http://www.mediawiki.org/',
|
||||
'html/0/rel': 'mw:ExtLink/Numbered'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1179,13 +1152,11 @@ ve.dm.example.domToDataCases = {
|
|||
'1',
|
||||
[ {
|
||||
'type': 'link/MWexternal',
|
||||
'data': {
|
||||
'href': 'http://www.mediawiki.org/'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'attributes': {
|
||||
'href': 'http://www.mediawiki.org/',
|
||||
'rel': 'mw:ExtLink/Numbered'
|
||||
'rel': 'mw:ExtLink/Numbered',
|
||||
'html/0/href': 'http://www.mediawiki.org/',
|
||||
'html/0/rel': 'mw:ExtLink/Numbered'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1193,13 +1164,11 @@ ve.dm.example.domToDataCases = {
|
|||
']',
|
||||
[ {
|
||||
'type': 'link/MWexternal',
|
||||
'data': {
|
||||
'href': 'http://www.mediawiki.org/'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'attributes': {
|
||||
'href': 'http://www.mediawiki.org/',
|
||||
'rel': 'mw:ExtLink/Numbered'
|
||||
'rel': 'mw:ExtLink/Numbered',
|
||||
'html/0/href': 'http://www.mediawiki.org/',
|
||||
'html/0/rel': 'mw:ExtLink/Numbered'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1214,13 +1183,11 @@ ve.dm.example.domToDataCases = {
|
|||
'm',
|
||||
[ {
|
||||
'type': 'link/MWexternal',
|
||||
'data': {
|
||||
'href': 'http://www.mediawiki.org/'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'attributes': {
|
||||
'href': 'http://www.mediawiki.org/',
|
||||
'rel': 'mw:ExtLink/URL'
|
||||
'rel': 'mw:ExtLink/URL',
|
||||
'html/0/href': 'http://www.mediawiki.org/',
|
||||
'html/0/rel': 'mw:ExtLink/URL'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1228,13 +1195,11 @@ ve.dm.example.domToDataCases = {
|
|||
'w',
|
||||
[ {
|
||||
'type': 'link/MWexternal',
|
||||
'data': {
|
||||
'href': 'http://www.mediawiki.org/'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'attributes': {
|
||||
'href': 'http://www.mediawiki.org/',
|
||||
'rel': 'mw:ExtLink/URL'
|
||||
'rel': 'mw:ExtLink/URL',
|
||||
'html/0/href': 'http://www.mediawiki.org/',
|
||||
'html/0/rel': 'mw:ExtLink/URL'
|
||||
}
|
||||
} ]
|
||||
],
|
||||
|
@ -1634,15 +1599,12 @@ ve.dm.example.domToDataCases = {
|
|||
ve.dm.example.bold,
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
},
|
||||
ve.dm.example.italic
|
||||
|
@ -1654,15 +1616,12 @@ ve.dm.example.domToDataCases = {
|
|||
ve.dm.example.bold,
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
},
|
||||
ve.dm.example.italic
|
||||
|
@ -1674,15 +1633,12 @@ ve.dm.example.domToDataCases = {
|
|||
ve.dm.example.bold,
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
},
|
||||
ve.dm.example.italic
|
||||
|
@ -1700,15 +1656,12 @@ ve.dm.example.domToDataCases = {
|
|||
[
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1718,15 +1671,12 @@ ve.dm.example.domToDataCases = {
|
|||
[
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
},
|
||||
ve.dm.example.bold
|
||||
|
@ -1737,15 +1687,12 @@ ve.dm.example.domToDataCases = {
|
|||
[
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
},
|
||||
ve.dm.example.bold,
|
||||
|
@ -1757,15 +1704,12 @@ ve.dm.example.domToDataCases = {
|
|||
[
|
||||
{
|
||||
'type': 'link/MWinternal',
|
||||
'data': {
|
||||
'attributes': {
|
||||
'hrefPrefix': '',
|
||||
'origTitle': 'Foo',
|
||||
'title': 'Foo'
|
||||
},
|
||||
'htmlTagName': 'a',
|
||||
'htmlAttributes': {
|
||||
'href': 'Foo',
|
||||
'rel': 'mw:WikiLink'
|
||||
'title': 'Foo',
|
||||
'html/0/href': 'Foo',
|
||||
'html/0/rel': 'mw:WikiLink'
|
||||
}
|
||||
},
|
||||
ve.dm.example.italic
|
||||
|
|
|
@ -112,8 +112,10 @@
|
|||
<script src="../../ve/dm/metaitems/ve.dm.MWLanguageMetaItem.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.DomRange.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.AnnotationFactory.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.NodeFactory.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.Document.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.Annotation.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.Node.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.BranchNode.js"></script>
|
||||
<script src="../../ve/ce/ve.ce.ContentBranchNode.js"></script>
|
||||
|
@ -143,6 +145,10 @@
|
|||
<script src="../../ve/ce/nodes/ve.ce.MWHeadingNode.js"></script>
|
||||
<script src="../../ve/ce/nodes/ve.ce.MWPreformattedNode.js"></script>
|
||||
<script src="../../ve/ce/nodes/ve.ce.MWImageNode.js"></script>
|
||||
<script src="../../ve/ce/annotations/ve.ce.LinkAnnotation.js"></script>
|
||||
<script src="../../ve/ce/annotations/ve.ce.MWExternalLinkAnnotation.js"></script>
|
||||
<script src="../../ve/ce/annotations/ve.ce.MWInternalLinkAnnotation.js"></script>
|
||||
<script src="../../ve/ce/annotations/ve.ce.TextStyleAnnotation.js"></script>
|
||||
<script src="../../ve/ui/ve.ui.js"></script>
|
||||
<script src="../../ve/ui/ve.ui.Context.js"></script>
|
||||
<script src="../../ve/ui/ve.ui.Frame.js"></script>
|
||||
|
|
|
@ -195,7 +195,12 @@ ve.ui.LinkInspector.prototype.onClose = function ( remove ) {
|
|||
* @returns {ve.dm.LinkAnnotation}
|
||||
*/
|
||||
ve.ui.LinkInspector.prototype.getAnnotationFromTarget = function ( target ) {
|
||||
return new ve.dm.LinkAnnotation( { 'href': target } );
|
||||
return new ve.dm.LinkAnnotation( {
|
||||
'type': 'link',
|
||||
'attributes': {
|
||||
'href': target
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/* Registration */
|
||||
|
|
|
@ -47,7 +47,12 @@ ve.ui.MWLinkInspector.prototype.getAnnotationFromTarget = function ( target ) {
|
|||
// Figure out if this is an internal or external link
|
||||
if ( ve.init.platform.getExternalLinkUrlProtocolsRegExp().test( target ) ) {
|
||||
// External link
|
||||
return new ve.dm.MWExternalLinkAnnotation( { 'href': target } );
|
||||
return new ve.dm.MWExternalLinkAnnotation( {
|
||||
'type': 'link/MWexternal',
|
||||
'attributes': {
|
||||
'href': target
|
||||
}
|
||||
} );
|
||||
} else {
|
||||
// Internal link
|
||||
// TODO: In the longer term we'll want to have autocompletion and existence and validity
|
||||
|
@ -61,7 +66,12 @@ ve.ui.MWLinkInspector.prototype.getAnnotationFromTarget = function ( target ) {
|
|||
target = ':' + target;
|
||||
}
|
||||
} catch ( e ) { }
|
||||
return new ve.dm.MWInternalLinkAnnotation( { 'title': target } );
|
||||
return new ve.dm.MWInternalLinkAnnotation( {
|
||||
'type': 'link/MWinternal',
|
||||
'attributes': {
|
||||
'title': target
|
||||
}
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -45,7 +45,12 @@ ve.ui.LinkTargetInputWidget.prototype.setValue = function ( value ) {
|
|||
if ( value === '' ) {
|
||||
this.annotation = null;
|
||||
} else {
|
||||
this.setAnnotation( new ve.dm.LinkAnnotation( { 'href': value } ) );
|
||||
this.setAnnotation( new ve.dm.LinkAnnotation( {
|
||||
'type': 'link',
|
||||
'attributes': {
|
||||
'href': value
|
||||
}
|
||||
} ) );
|
||||
}
|
||||
|
||||
// Call parent method
|
||||
|
@ -92,7 +97,7 @@ ve.ui.LinkTargetInputWidget.prototype.getAnnotation = function () {
|
|||
*/
|
||||
ve.ui.LinkTargetInputWidget.prototype.getTargetFromAnnotation = function ( annotation ) {
|
||||
if ( annotation instanceof ve.dm.LinkAnnotation ) {
|
||||
return annotation.data.href;
|
||||
return annotation.getAttribute( 'href' );
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
|
|
@ -257,7 +257,12 @@ ve.ui.MWLinkTargetInputWidget.prototype.getInternalLinkAnnotationFromTitle = fun
|
|||
target = ':' + target;
|
||||
}
|
||||
} catch ( e ) { }
|
||||
return new ve.dm.MWInternalLinkAnnotation( { 'title': target } );
|
||||
return new ve.dm.MWInternalLinkAnnotation( {
|
||||
'type': 'link/MWinternal',
|
||||
'attributes': {
|
||||
'title': target
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -268,7 +273,12 @@ ve.ui.MWLinkTargetInputWidget.prototype.getInternalLinkAnnotationFromTitle = fun
|
|||
* @returns {ve.dm.MWExternalLinkAnnotation}
|
||||
*/
|
||||
ve.ui.MWLinkTargetInputWidget.prototype.getExternalLinkAnnotationFromUrl = function ( target ) {
|
||||
return new ve.dm.MWExternalLinkAnnotation( { 'href': target } );
|
||||
return new ve.dm.MWExternalLinkAnnotation( {
|
||||
'type': 'link/MWexternal',
|
||||
'attributes': {
|
||||
'href': target
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -280,9 +290,9 @@ ve.ui.MWLinkTargetInputWidget.prototype.getExternalLinkAnnotationFromUrl = funct
|
|||
*/
|
||||
ve.ui.MWLinkTargetInputWidget.prototype.getTargetFromAnnotation = function ( annotation ) {
|
||||
if ( annotation instanceof ve.dm.MWExternalLinkAnnotation ) {
|
||||
return annotation.data.href;
|
||||
return annotation.getAttribute( 'href' );
|
||||
} else if ( annotation instanceof ve.dm.MWInternalLinkAnnotation ) {
|
||||
return annotation.data.title;
|
||||
return annotation.getAttribute( 'title' );
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue