text: /*!
   * VisualEditor Node class.
   *
   * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
   * @license The MIT License (MIT); see LICENSE.txt
   */
  
  /**
   * Generic node.
   *
   * @abstract
   * @mixins OO.EventEmitter
   *
   * @constructor
   */
  ve.Node = function VeNode() {
  	// Properties
  	this.type = this.constructor.static.name;
  	this.parent = null;
  	this.root = null;
  	this.doc = null;
  };
  
  /**
   * @event attach
   * @param {ve.Node} parent
   */
  
  /**
   * @event detach
   * @param {ve.Node} parent
   */
  
  /**
   * @event root
   */
  
  /**
   * @event unroot
   */
  
  /* Abstract Methods */
  
  /**
   * Check if the node can have children.
   *
   * @method
   * @abstract
   * @returns {boolean} Node can have children
   * @throws {Error} if not overridden
   */
  ve.Node.prototype.canHaveChildren = function () {
  	throw new Error( 've.Node.canHaveChildren must be overridden in subclass' );
  };
  
  /**
   * Check if the node can have children but not content nor be content.
   *
   * @method
   * @abstract
   * @returns {boolean} Node can have children but not content nor be content
   * @throws {Error} if not overridden
   */
  ve.Node.prototype.canHaveChildrenNotContent = function () {
  	throw new Error( 've.Node.canHaveChildrenNotContent must be overridden in subclass' );
  };
  
  /**
   * Check if the node has a wrapped element in the document data.
   *
   * @method
   * @abstract
   * @returns {boolean} Node represents a wrapped element
   * @throws {Error} if not overridden
   */
  ve.Node.prototype.isWrapped = function () {
  	throw new Error( 've.Node.isWrapped must be overridden in subclass' );
  };
  
  /**
   * Get the length of the node.
   *
   * @method
   * @abstract
   * @returns {number} Node length
   * @throws {Error} if not overridden
   */
  ve.Node.prototype.getLength = function () {
  	throw new Error( 've.Node.getLength must be overridden in subclass' );
  };
  
  /**
   * Get the outer length of the node, which includes wrappers if present.
   *
   * @method
   * @abstract
   * @returns {number} Node outer length
   * @throws {Error} if not overridden
   */
  ve.Node.prototype.getOuterLength = function () {
  	throw new Error( 've.Node.getOuterLength must be overridden in subclass' );
  };
  
  /**
   * Get the outer range of the node, which includes wrappers if present.
   *
   * @method
   * @param {boolean} backwards Return a backwards range
   * @returns {ve.Range} Node outer range
   */
  ve.Node.prototype.getOuterRange = function ( backwards ) {
  	var range = new ve.Range( this.getOffset(), this.getOffset() + this.getOuterLength() );
  	if ( backwards ) {
  		return range.flip();
  	} else {
  		return range;
  	}
  };
  
  /* Methods */
  
  /**
   * Get the symbolic node type name.
   *
   * @method
   * @returns {string} Symbolic name of element type
   */
  ve.Node.prototype.getType = function () {
  	return this.type;
  };
  
  /**
   * Get a reference to the node's parent.
   *
   * @method
   * @returns {ve.Node} Reference to the node's parent
   */
  ve.Node.prototype.getParent = function () {
  	return this.parent;
  };
  
  /**
   * Get the root node of the tree the node is currently attached to.
   *
   * @method
   * @returns {ve.Node} Root node
   */
  ve.Node.prototype.getRoot = function () {
  	return this.root;
  };
  
  /**
   * Set the root node.
   *
   * This method is overridden by nodes with children.
   *
   * @method
   * @param {ve.Node} root Node to use as root
   * @fires root
   * @fires unroot
   */
  ve.Node.prototype.setRoot = function ( root ) {
  	if ( root !== this.root ) {
  		this.root = root;
  		if ( this.getRoot() ) {
  			this.emit( 'root' );
  		} else {
  			this.emit( 'unroot' );
  		}
  	}
  };
  
  /**
   * Get the document the node is a part of.
   *
   * @method
   * @returns {ve.Document} Document the node is a part of
   */
  ve.Node.prototype.getDocument = function () {
  	return this.doc;
  };
  
  /**
   * Set the document the node is a part of.
   *
   * This method is overridden by nodes with children.
   *
   * @method
   * @param {ve.Document} doc Document this node is a part of
   */
  ve.Node.prototype.setDocument = function ( doc ) {
  	this.doc = doc;
  };
  
  /**
   * Attach the node to another as a child.
   *
   * @method
   * @param {ve.Node} parent Node to attach to
   * @fires attach
   */
  ve.Node.prototype.attach = function ( parent ) {
  	this.parent = parent;
  	this.setRoot( parent.getRoot() );
  	this.setDocument( parent.getDocument() );
  	this.emit( 'attach', parent );
  };
  
  /**
   * Detach the node from its parent.
   *
   * @method
   * @fires detach
   */
  ve.Node.prototype.detach = function () {
  	var parent = this.parent;
  	this.parent = null;
  	this.setRoot( null );
  	this.setDocument( null );
  	this.emit( 'detach', parent );
  };
  
  /**
   * Traverse tree of nodes (model or view) upstream.
   *
   * For each traversed node, the callback function will be passed the traversed node as a parameter.
   *
   * @param {Function} callback Callback method to be called for every traversed node
   * @method
   */
  ve.Node.prototype.traverseUpstream = function ( callback ) {
  	var node = this;
  	while ( node ) {
  		if ( callback ( node ) === false ) {
  			break;
  		}
  		node = node.getParent();
  	}
  };
  