| Current File : /home/omtekel/wiki/extensions/VisualEditor/lib/ve/src/ce/nodes/ve.ce.ActiveNode.js |
/*!
* VisualEditor ContentEditable ActiveNode class.
*
* @copyright 2011-2020 VisualEditor Team and others; see http://ve.mit-license.org
*/
/**
* Active nodes are editable sections that are nested inside
* uneditable sections.
*
* @class
* @mixins ve.ce.ContentEditableNode
* @abstract
*
* @constructor
*/
ve.ce.ActiveNode = function VeCeActiveNode() {
// Mixin constructor
ve.ce.ContentEditableNode.call( this );
// Properties
this.activeNodeSurface = null;
this.isActiveNodeSetup = false;
// Events
this.connect( this, {
setup: 'onActiveNodeSetup',
teardown: 'onActiveNodeTeardown'
} );
// DOM changes
this.$element.addClass( 've-ce-activeNode' );
};
/* Inheritance */
OO.mixinClass( ve.ce.ActiveNode, ve.ce.ContentEditableNode );
/* Methods */
/**
* Handle node setup
*/
ve.ce.ActiveNode.prototype.onActiveNodeSetup = function () {
// Exit if already setup or not attached
if ( this.isActiveNodeSetup || !this.root ) {
return;
}
this.activeNodeSurface = this.getRoot().getSurface();
// Events
this.activeNodeSurface.getModel().connect( this, { select: 'onActiveNodeSurfaceModelSelect' } );
this.isActiveNodeSetup = true;
};
/**
* Handle node teardown
*/
ve.ce.ActiveNode.prototype.onActiveNodeTeardown = function () {
if ( !this.isActiveNodeSetup ) {
return;
}
var surface = this.activeNodeSurface;
// Events
surface.getModel().disconnect( this );
if ( surface.getActiveNode() === this ) {
surface.setActiveNode( null );
}
this.isActiveNodeSetup = false;
};
/**
* Handle select events from the surface model.
*
* @param {ve.dm.Selection} selection
*/
ve.ce.ActiveNode.prototype.onActiveNodeSurfaceModelSelect = function ( selection ) {
var coveringRange = selection.getCoveringRange(),
surface = this.activeNodeSurface,
activeNode = this;
if ( coveringRange && this.model.getRange().containsRange( new ve.Range( coveringRange.from ) ) ) {
// Only set this as the active node if active node is empty, or not a
// descendant of this node.
if (
!surface.getActiveNode() ||
!surface.getActiveNode().traverseUpstream( function ( node ) {
return node !== activeNode;
} )
) {
surface.setActiveNode( this );
}
this.$element.addClass( 've-ce-activeNode-active' );
} else {
if ( surface.getActiveNode() === this ) {
surface.setActiveNode( null );
}
if ( !selection.isNull() ) {
this.$element.removeClass( 've-ce-activeNode-active' );
}
}
};