Insert Annotations

Change-Id: Ibc927730a668cdcea9c90fe4fc2cb3db4d20480e
This commit is contained in:
Christian Williams 2012-09-27 15:34:19 -07:00
parent 50ddba4d12
commit ffefe63063
5 changed files with 95 additions and 15 deletions

View file

@ -257,7 +257,11 @@ ve.ce.Surface.prototype.onKeyDown = function ( e ) {
if ( ve.ce.Surface.isShortcutKey( e ) ) {
// Ctrl+B / Cmd+B, annotate with bold
e.preventDefault();
annotations = this.documentView.model.getAnnotationsFromRange( this.model.getSelection() );
if ( this.model.getSelection().getLength() ) {
annotations = this.documentView.model.getAnnotationsFromRange( this.model.getSelection() );
} else {
annotations = this.model.documentModel.insertAnnotations;
}
annotation = { 'type': 'textStyle/bold' };
this.model.annotate( annotations.contains( annotation ) ? 'clear' : 'set', annotation );
@ -268,7 +272,11 @@ ve.ce.Surface.prototype.onKeyDown = function ( e ) {
if ( ve.ce.Surface.isShortcutKey( e ) ) {
// Ctrl+I / Cmd+I, annotate with italic
e.preventDefault();
annotations = this.documentView.model.getAnnotationsFromRange( this.model.getSelection() );
if ( this.model.getSelection().getLength() ) {
annotations = this.documentView.model.getAnnotationsFromRange( this.model.getSelection() );
} else {
annotations = this.model.documentModel.insertAnnotations;
}
annotation = { 'type': 'textStyle/italic' };
this.model.annotate( annotations.contains( annotation ) ? 'clear' : 'set', annotation );
@ -311,6 +319,50 @@ ve.ce.Surface.prototype.onKeyDown = function ( e ) {
}
};
ve.ce.Surface.prototype.handleInsertAnnotations = function () {
var selection = this.model.getSelection();
// compare annotation stack to annotation for offset - 1, do pawn trick if necessary
var leftAnnotations = this.model.documentModel.data[selection.start - 1][1];
var insertAnnotations = this.model.documentModel.insertAnnotations;
if ( leftAnnotations == undefined && insertAnnotations.getLength() == 0 ) {
// plain text for both, do nothing
} else if ( leftAnnotations != undefined && ve.compareObjects ( leftAnnotations, insertAnnotations ) ) {
// objects are the same, do nothing
} else {
this.model.insertingAnnotations = true;
// Add the pawn with annotation, re-render, select pawn
this.model.change(
ve.dm.Transaction.newFromInsertion(
this.documentView.model,
selection.start,
[['\u2659', this.model.documentModel.insertAnnotations]]
),
new ve.Range( selection.start, selection.start + 1 )
);
// Remove pawn from the model and do not re-render
this.render = false;
this.model.change(
ve.dm.Transaction.newFromRemoval(
this.documentView.model,
this.model.getSelection()
)
);
this.render = true;
// Reset the pawn trick when current event handling is done
var _this = this;
setTimeout(function() {
_this.model.insertingAnnotations = false;
_this.pollChanges();
}, 0);
}
};
/**
* Responds to copy events.
*
@ -477,6 +529,8 @@ ve.ce.Surface.prototype.onKeyPress = function ( e ) {
this.startPolling();
}
this.handleInsertAnnotations();
// Is there an expanded range and something other than keycodes 0 (nothing) or 27 (esc) were pressed?
if ( selection.getLength() > 0 && ( e.which !== 0 || e.which !== 27 ) ) {
this.stopPolling();
@ -699,16 +753,14 @@ ve.ce.Surface.prototype.onContentChange = function ( node, previous, next ) {
) {
// Something simple was added, figure out what it is and transact.
ve.log('simple addition');
data = next.text.substring(
previous.range.start - nodeOffset - 1,
next.range.start - nodeOffset - 1
).split( '' );
// Get annotations to the left of new content and apply
annotations = this.model.getDocument().getAnnotationsFromOffset( previous.range.start - 1 );
if ( !annotations.isEmpty() ) {
ve.dm.Document.addAnnotationsToData( data, annotations );
}
// Apply insertAnnotations
ve.dm.Document.addAnnotationsToData( data, this.model.getDocument().insertAnnotations );
// Prevent re-rendering and transact
this.render = false;

View file

@ -45,6 +45,7 @@ ve.dm.Document = function VeDmDocument( data, parentDocument ) {
currentStack = stack[1],
parentStack = stack[0],
currentNode = this.documentNode;
this.insertAnnotations = new ve.AnnotationSet();
this.documentNode.setDocument( doc );
this.documentNode.setRoot( root );
for ( i = 0, length = this.data.length; i < length; i++ ) {

View file

@ -117,6 +117,18 @@ ve.dm.Surface.prototype.change = function ( transactions, selection ) {
if ( transactions ) {
this.emit( 'transact', transactions );
}
// Clear and add annotations to stack if insertingAnnotations isn't happening
if (!this.insertingAnnotations) {
var annotations = this.documentModel.getAnnotationsFromOffset( this.getSelection().start - 1 );
// Reset insertAnnotations
this.documentModel.insertAnnotations = new ve.AnnotationSet();
this.documentModel.insertAnnotations.addSet( annotations );
this.emit( 'annotationChange' );
}
this.emit( 'change', transactions, selection );
};
@ -131,12 +143,21 @@ ve.dm.Surface.prototype.annotate = function ( method, annotation ) {
var tx,
selection = this.getSelection();
if ( selection.getLength() ) {
// Apply annotation immediately to selection
selection = this.getDocument().trimOuterSpaceFromRange( selection );
tx = ve.dm.Transaction.newFromAnnotation(
this.getDocument(), selection, method, annotation
);
this.change( tx, selection );
} else {
// Apply annotation to stack
if ( method == 'set' ) {
this.documentModel.insertAnnotations.push( annotation );
} else if ( method == 'clear' ) {
this.documentModel.insertAnnotations.remove( annotation );
}
}
this.emit( 'annotationChange' );
};
ve.dm.Surface.prototype.breakpoint = function ( selection ) {

View file

@ -47,10 +47,18 @@ ve.ui.AnnotationButtonTool.prototype.onClick = function () {
} else {
if ( this.active ) {
// Get all annotations by type.
annotations = documentModel
.getAnnotationsFromRange( surfaceModel.getSelection() )
.getAnnotationsOfType( this.annotation.type )
.get();
if ( surfaceModel.getSelection().getLength() ) {
annotations = documentModel
.getAnnotationsFromRange( surfaceModel.getSelection() )
.getAnnotationsOfType( this.annotation.type )
.get();
} else {
annotations = documentModel
.insertAnnotations
.getAnnotationsOfType( this.annotation.type )
.get();
}
// Clear each selected annotation.
for( i = 0; i < annotations.length; i++ ) {
surfaceModel.annotate( 'clear', annotations[i] );

View file

@ -39,7 +39,7 @@ ve.ui.Toolbar = function VeUiToolbar( $container, surfaceView, config ) {
this.$.prepend( this.$groups );
// Events
this.surfaceView.model.on( 'change', ve.bind( this.updateTools, this ) );
this.surfaceView.model.on( 'annotationChange', ve.bind( this.updateTools, this ) );
// Initialization
this.setup();
@ -99,9 +99,7 @@ ve.ui.Toolbar.prototype.updateTools = function () {
} else {
// Clear context
this.surfaceView.contextView.clear();
annotations = doc.getAnnotationsFromOffset(
doc.getNearestContentOffset( range.start - 1 )
);
annotations = doc.insertAnnotations;
}
// Normalize nodes returned from selectNodes and add to nodes list.
// Fire toolbar update state to update tools.