Esanders has uploaded a new change for review.
https://gerrit.wikimedia.org/r/71716
Change subject: Allow annotations to be additive
......................................................................
Allow annotations to be additive
Set a static property on big, small, sup, sub to allow them
to be added multiple times to an annotationSet.
Fix the converter to count out annotations when opening/closing.
Bug: 49755
Change-Id: Ifbede9345a66434022dbd681eada447ab81ab025
---
M modules/ve/dm/annotations/ve.dm.TextStyleAnnotation.js
M modules/ve/dm/ve.dm.Annotation.js
M modules/ve/dm/ve.dm.AnnotationSet.js
M modules/ve/dm/ve.dm.Converter.js
M modules/ve/test/dm/ve.dm.example.js
5 files changed, 53 insertions(+), 5 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor
refs/changes/16/71716/1
diff --git a/modules/ve/dm/annotations/ve.dm.TextStyleAnnotation.js
b/modules/ve/dm/annotations/ve.dm.TextStyleAnnotation.js
index 67d22ba..e94e19a 100644
--- a/modules/ve/dm/annotations/ve.dm.TextStyleAnnotation.js
+++ b/modules/ve/dm/annotations/ve.dm.TextStyleAnnotation.js
@@ -157,6 +157,7 @@
ve.inheritClass( ve.dm.TextStyleSmallAnnotation, ve.dm.TextStyleAnnotation );
ve.dm.TextStyleSmallAnnotation.static.name = 'textStyle/small';
ve.dm.TextStyleSmallAnnotation.static.matchTagNames = ['small'];
+ve.dm.TextStyleSmallAnnotation.static.isAdditive = true;
ve.dm.modelRegistry.register( ve.dm.TextStyleSmallAnnotation );
/**
@@ -173,6 +174,7 @@
ve.inheritClass( ve.dm.TextStyleBigAnnotation, ve.dm.TextStyleAnnotation );
ve.dm.TextStyleBigAnnotation.static.name = 'textStyle/big';
ve.dm.TextStyleBigAnnotation.static.matchTagNames = ['big'];
+ve.dm.TextStyleBigAnnotation.static.isAdditive = true;
ve.dm.modelRegistry.register( ve.dm.TextStyleBigAnnotation );
/**
@@ -237,6 +239,7 @@
ve.inheritClass( ve.dm.TextStyleSuperScriptAnnotation,
ve.dm.TextStyleAnnotation );
ve.dm.TextStyleSuperScriptAnnotation.static.name = 'textStyle/superScript';
ve.dm.TextStyleSuperScriptAnnotation.static.matchTagNames = ['sup'];
+ve.dm.TextStyleSuperScriptAnnotation.static.isAdditive = true;
ve.dm.modelRegistry.register( ve.dm.TextStyleSuperScriptAnnotation );
/**
@@ -253,4 +256,5 @@
ve.inheritClass( ve.dm.TextStyleSubScriptAnnotation, ve.dm.TextStyleAnnotation
);
ve.dm.TextStyleSubScriptAnnotation.static.name = 'textStyle/subScript';
ve.dm.TextStyleSubScriptAnnotation.static.matchTagNames = ['sub'];
+ve.dm.TextStyleSubScriptAnnotation.static.isAdditive = true;
ve.dm.modelRegistry.register( ve.dm.TextStyleSubScriptAnnotation );
diff --git a/modules/ve/dm/ve.dm.Annotation.js
b/modules/ve/dm/ve.dm.Annotation.js
index 305b3a9..c2d220d 100644
--- a/modules/ve/dm/ve.dm.Annotation.js
+++ b/modules/ve/dm/ve.dm.Annotation.js
@@ -33,6 +33,15 @@
/* Static properties */
/**
+ * Allow annotation to be applied additively, e.g. <big><big>Foo</big></big>
+ *
+ * @static
+ * @type {boolean}
+ * @inheritable
+ */
+ve.dm.Annotation.static.isAdditive = false;
+
+/**
* About grouping is not supported for annotations; setting this to true has
no effect.
*
* @static
diff --git a/modules/ve/dm/ve.dm.AnnotationSet.js
b/modules/ve/dm/ve.dm.AnnotationSet.js
index 3bd70fd..80d2440 100644
--- a/modules/ve/dm/ve.dm.AnnotationSet.js
+++ b/modules/ve/dm/ve.dm.AnnotationSet.js
@@ -366,7 +366,7 @@
*/
ve.dm.AnnotationSet.prototype.push = function ( annotation ) {
var storeIndex = this.getStore().index( annotation );
- if ( !this.containsIndex( storeIndex ) ) {
+ if ( annotation.constructor.static.isAdditive || !this.containsIndex(
storeIndex ) ) {
this.storeIndexes.push( storeIndex );
}
};
diff --git a/modules/ve/dm/ve.dm.Converter.js b/modules/ve/dm/ve.dm.Converter.js
index 091ac58..a866153 100644
--- a/modules/ve/dm/ve.dm.Converter.js
+++ b/modules/ve/dm/ve.dm.Converter.js
@@ -68,15 +68,19 @@
* @param {Function} close Callback called when an annotation is closed.
*/
ve.dm.Converter.openAndCloseAnnotations = function ( currentSet, targetSet,
open, close ) {
- var i, len, annotation, startClosingAt;
+ var i, len, annotation, startClosingAt, currentSetOpen, targetSetOpen;
// Close annotations as needed
// Go through annotationStack from bottom to top (low to high),
// and find the first annotation that's not in annotations.
+ targetSetOpen = targetSet.clone();
for ( i = 0, len = currentSet.getLength(); i < len; i++ ) {
- if ( !targetSet.containsComparableForSerialization(
currentSet.get( i ) ) ) {
+ annotation = currentSet.get( i );
+ if ( !targetSetOpen.containsComparableForSerialization(
annotation ) ) {
startClosingAt = i;
break;
+ } else {
+ targetSetOpen.remove( annotation );
}
}
if ( startClosingAt !== undefined ) {
@@ -89,13 +93,19 @@
}
}
+ currentSetOpen = currentSet.clone();
// Open annotations as needed
for ( i = 0, len = targetSet.getLength(); i < len; i++ ) {
annotation = targetSet.get( i );
- if ( !currentSet.containsComparableForSerialization( annotation
) ) {
+ if ( !currentSetOpen.containsComparableForSerialization(
annotation ) ) {
open( annotation );
// Add to currentClone
currentSet.push( annotation );
+ } else {
+ // If an annotation is already open remove it from the
currentSetOpen list
+ // as it may exist multiple times in the targetSet, and
so may need to be
+ // opened again
+ currentSetOpen.remove( annotation );
}
}
};
@@ -384,7 +394,7 @@
* @param {ve.dm.AnnotationSet} [annotationSet] Override the set of
annotations to use
* @returns {Array} Linear model data
*/
-ve.dm.Converter.prototype.getDataFromDomRecursionClean = function (
domElement, wrapperElement, annotationSet ) {
+ve.dm.Converter.prototype.getDataFromDomRecursionClean = function (
domElement, wrapperElement, annotationSet ) {
var result, contextStack = this.contextStack;
this.contextStack = [];
result = this.getDataFromDomRecursion( domElement, wrapperElement,
annotationSet );
diff --git a/modules/ve/test/dm/ve.dm.example.js
b/modules/ve/test/dm/ve.dm.example.js
index d154796..e5f27ca 100644
--- a/modules/ve/test/dm/ve.dm.example.js
+++ b/modules/ve/test/dm/ve.dm.example.js
@@ -85,6 +85,7 @@
ve.dm.example.italic = { 'type': 'textStyle/italic' };
ve.dm.example.underline = { 'type': 'textStyle/underline' };
ve.dm.example.span = { 'type': 'textStyle/span' };
+ve.dm.example.big = { 'type': 'textStyle/big' };
/**
* Creates a document from example data.
@@ -880,6 +881,30 @@
{ 'type': '/internalList' }
]
},
+ 'additive annotations': {
+ 'html': '<body><p><big>a<big>b</big>c</big></p></body>',
+ 'data': [
+ { 'type': 'paragraph' },
+ ['a', [ ve.dm.example.big ]],
+ ['b', [ ve.dm.example.big, ve.dm.example.big ]],
+ ['c', [ ve.dm.example.big ]],
+ { 'type': '/paragraph' },
+ { 'type': 'internalList' },
+ { 'type': '/internalList' }
+ ]
+ },
+ 'additive annotations overlapping basic annotations': {
+ 'html':
'<body><p><i><big>a<big><b>b</big></i>c</big></b></p></body>',
+ 'data': [
+ { 'type': 'paragraph' },
+ ['a', [ ve.dm.example.italic, ve.dm.example.big ]],
+ ['b', [ ve.dm.example.italic, ve.dm.example.big,
ve.dm.example.big, ve.dm.example.bold ]],
+ ['c', [ ve.dm.example.big, ve.dm.example.bold ]],
+ { 'type': '/paragraph' },
+ { 'type': 'internalList' },
+ { 'type': '/internalList' }
+ ]
+ },
'image': {
'html': '<body><img src="' + ve.dm.example.imgSrc + '"></body>',
'data': [
--
To view, visit https://gerrit.wikimedia.org/r/71716
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifbede9345a66434022dbd681eada447ab81ab025
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