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

Reply via email to