/*! * VisualEditor ContentEditable ContentBranchNode class. * * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt * @license The MIT License (MIT); see LICENSE.txt */ /** * ContentEditable content branch node. * * Content branch nodes can only have content nodes as children. * * @abstract * @extends ve.ce.BranchNode * @constructor * @param {ve.dm.BranchNode} model Model to observe * @param {jQuery} [$element] Element to use as a container */ ve.ce.ContentBranchNode = function VeCeContentBranchNode( model, $element ) { // Parent constructor ve.ce.BranchNode.call( this, model, $element ); // Properties this.surfaceModelState = null; // Events this.connect( this, { 'childUpdate': 'onChildUpdate' } ); // Initialization this.renderContents(); }; /* Inheritance */ ve.inheritClass( ve.ce.ContentBranchNode, ve.ce.BranchNode ); /* Methods */ /** * Handle splice events. * * Rendering is only done once per transaction. If a paragraph has multiple nodes in it then it's * possible to receive multiple `childUpdate` events for a single transaction such as annotating * across them. State is tracked by storing and comparing the length of the surface model's complete * history. * * This is used to automatically render contents. * @see ve.ce.BranchNode#onSplice * * @method */ ve.ce.ContentBranchNode.prototype.onChildUpdate = function ( transaction ) { var surfaceModel = this.getRoot().getSurface().getModel(), surfaceModelState = surfaceModel.getCompleteHistoryLength(); if ( transaction instanceof ve.dm.Transaction ) { if ( surfaceModelState === this.surfaceModelState ) { return; } this.surfaceModelState = surfaceModelState; } this.renderContents(); }; /** * Handle splice events. * * This is used to automatically render contents. * @see ve.ce.BranchNode#onSplice * * @method */ ve.ce.ContentBranchNode.prototype.onSplice = function () { // Call parent implementation ve.ce.BranchNode.prototype.onSplice.apply( this, arguments ); // Rerender to make sure annotations are applied correctly this.renderContents(); }; /** * Get an HTML rendering of the contents. * * @method * @returns {jQuery} */ ve.ce.ContentBranchNode.prototype.getRenderedContents = function () { var i, itemHtml, itemAnnotations, $ann, store = this.model.doc.getStore(), annotationStack = new ve.dm.AnnotationSet( store ), annotatedHtml = [], $wrapper = $( '