⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fckdomrange.js

📁 1602液晶的GPS 信号显示 单片机接收gps芯片的信号 进行显示
💻 JS
📖 第 1 页 / 共 2 页
字号:
/*
 * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 * Copyright (C) 2003-2007 Frederico Caldeira Knabben
 *
 * == BEGIN LICENSE ==
 *
 * Licensed under the terms of any of the following licenses at your
 * choice:
 *
 *  - GNU General Public License Version 2 or later (the "GPL")
 *    http://www.gnu.org/licenses/gpl.html
 *
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 *    http://www.gnu.org/licenses/lgpl.html
 *
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 *    http://www.mozilla.org/MPL/MPL-1.1.html
 *
 * == END LICENSE ==
 *
 * Class for working with a selection range, much like the W3C DOM Range, but
 * it is not intended to be an implementation of the W3C interface.
 */

var FCKDomRange = function( sourceWindow )
{
	this.Window = sourceWindow ;
	this._Cache = {} ;
}

FCKDomRange.prototype =
{

	_UpdateElementInfo : function()
	{
		var innerRange = this._Range ;

		if ( !innerRange )
			this.Release( true ) ;
		else
		{
			// For text nodes, the node itself is the StartNode.
			var eStart	= innerRange.startContainer ;
			var eEnd	= innerRange.endContainer ;

			var oElementPath = new FCKElementPath( eStart ) ;
			this.StartNode			= eStart.nodeType == 3 ? eStart : eStart.childNodes[ innerRange.startOffset ] ;
			this.StartContainer		= eStart ;
			this.StartBlock			= oElementPath.Block ;
			this.StartBlockLimit	= oElementPath.BlockLimit ;

			if ( eStart != eEnd )
				oElementPath = new FCKElementPath( eEnd ) ;

			// The innerRange.endContainer[ innerRange.endOffset ] is not
			// usually part of the range, but the marker for the range end. So,
			// let's get the previous available node as the real end.
			var eEndNode = eEnd ;
			if ( innerRange.endOffset == 0 )
			{
				while ( eEndNode && !eEndNode.previousSibling )
					eEndNode = eEndNode.parentNode ;

				if ( eEndNode )
					eEndNode = eEndNode.previousSibling ;
			}
			else if ( eEndNode.nodeType == 1 )
				eEndNode = eEndNode.childNodes[ innerRange.endOffset - 1 ] ;

			this.EndNode			= eEndNode ;
			this.EndContainer		= eEnd ;
			this.EndBlock			= oElementPath.Block ;
			this.EndBlockLimit		= oElementPath.BlockLimit ;
		}

		this._Cache = {} ;
	},

	CreateRange : function()
	{
		return new FCKW3CRange( this.Window.document ) ;
	},

	DeleteContents : function()
	{
		if ( this._Range )
		{
			this._Range.deleteContents() ;
			this._UpdateElementInfo() ;
		}
	},

	ExtractContents : function()
	{
		if ( this._Range )
		{
			var docFrag = this._Range.extractContents() ;
			this._UpdateElementInfo() ;
			return docFrag ;
		}
	},

	CheckIsCollapsed : function()
	{
		if ( this._Range )
			return this._Range.collapsed ;
	},

	Collapse : function( toStart )
	{
		if ( this._Range )
			this._Range.collapse( toStart ) ;

		this._UpdateElementInfo() ;
	},

	Clone : function()
	{
		var oClone = FCKTools.CloneObject( this ) ;

		if ( this._Range )
			oClone._Range = this._Range.cloneRange() ;

		return oClone ;
	},

	MoveToNodeContents : function( targetNode )
	{
		if ( !this._Range )
			this._Range = this.CreateRange() ;

		this._Range.selectNodeContents( targetNode ) ;

		this._UpdateElementInfo() ;
	},

	MoveToElementStart : function( targetElement )
	{
		this.SetStart(targetElement,1) ;
		this.SetEnd(targetElement,1) ;
	},

	// Moves to the first editing point inside a element. For example, in a
	// element tree like "<p><b><i></i></b> Text</p>", the start editing point
	// is "<p><b><i>^</i></b> Text</p>" (inside <i>).
	MoveToElementEditStart : function( targetElement )
	{
		var child ;

		while ( ( child = targetElement.firstChild ) && child.nodeType == 1 && FCKListsLib.EmptyElements[ child.nodeName.toLowerCase() ] == null )
			targetElement = child ;

		this.MoveToElementStart( targetElement ) ;
	},

	InsertNode : function( node )
	{
		if ( this._Range )
			this._Range.insertNode( node ) ;
	},

	CheckIsEmpty : function()
	{
		if ( this.CheckIsCollapsed() )
			return true ;

		// Inserts the contents of the range in a div tag.
		var eToolDiv = this.Window.document.createElement( 'div' ) ;
		this._Range.cloneContents().AppendTo( eToolDiv ) ;

		FCKDomTools.TrimNode( eToolDiv ) ;

		return ( eToolDiv.innerHTML.length == 0 ) ;
	},

	CheckStartOfBlock : function()
	{
		var bIsStartOfBlock = this._Cache.IsStartOfBlock ;

		if ( bIsStartOfBlock != undefined )
			return bIsStartOfBlock ;

		// Create a clone of the current range.
		var oTestRange = this.Clone() ;

		// Collapse it to its start point.
		oTestRange.Collapse( true ) ;

		// Move the start boundary to the start of the block.
		oTestRange.SetStart( oTestRange.StartBlock || oTestRange.StartBlockLimit, 1 ) ;

		if ( oTestRange.CheckIsCollapsed() )
			bIsStartOfBlock = true ;
		else
		{
			// Inserts the contents of the range in a div tag.
			var eToolDiv = oTestRange.Window.document.createElement( 'div' ) ;
			oTestRange._Range.cloneContents().AppendTo( eToolDiv ) ;

			// This line is why we don't use CheckIsEmpty() here...
			// Because using RTrimNode() or TrimNode() would be incorrect - 
			// TrimNode() and RTrimNode() would delete <br> nodes at the end of the div node,
			// but for checking start of block they are actually meaningful. (Bug #1350)
			FCKDomTools.LTrimNode( eToolDiv ) ;

			bIsStartOfBlock = ( eToolDiv.innerHTML.length == 0 ) ;
		}

		oTestRange.Release() ;

		return ( this._Cache.IsStartOfBlock = bIsStartOfBlock ) ;
	},

	CheckEndOfBlock : function( refreshSelection )
	{
		var bIsEndOfBlock = this._Cache.IsEndOfBlock ;

		if ( bIsEndOfBlock != undefined )
			return bIsEndOfBlock ;

		// Create a clone of the current range.
		var oTestRange = this.Clone() ;

		// Collapse it to its end point.
		oTestRange.Collapse( false ) ;

		// Move the end boundary to the end of the block.
		oTestRange.SetEnd( oTestRange.EndBlock || oTestRange.EndBlockLimit, 2 ) ;

		bIsEndOfBlock = oTestRange.CheckIsCollapsed() ;

		if ( !bIsEndOfBlock )
		{
			// Inserts the contents of the range in a div tag.
			var eToolDiv = this.Window.document.createElement( 'div' ) ;
			oTestRange._Range.cloneContents().AppendTo( eToolDiv ) ;
			FCKDomTools.TrimNode( eToolDiv ) ;

			// Find out if we are in an empty tree of inline elements, like <b><i><span></span></i></b>
			bIsEndOfBlock = true ;
			var eLastChild = eToolDiv ;
			while ( ( eLastChild = eLastChild.lastChild ) )
			{
				// Check the following:
				//		1. Is there more than one node in the parents children?
				//		2. Is the node not an element node?
				//		3. Is it not a inline element.
				if ( eLastChild.previousSibling || eLastChild.nodeType != 1 || FCKListsLib.InlineChildReqElements[ eLastChild.nodeName.toLowerCase() ] == null )
				{
					// So we are not in the end of the range.
					bIsEndOfBlock = false ;
					break ;
				}
			}
		}

		oTestRange.Release() ;

		if ( refreshSelection )
			this.Select() ;

		return this._Cache.IsEndOfBlock = bIsEndOfBlock ;
	},

	// This is an "intrusive" way to create a bookmark. It includes <span> tags
	// in the range boundaries. The advantage of it is that it is possible to
	// handle DOM mutations when moving back to the bookmark.
	// Attention: the inclusion of nodes in the DOM is a design choice and
	// should not be changed as there are other points in the code that may be
	// using those nodes to perform operations. See GetBookmarkNode.
	// For performance, includeNodes=true if intended to SelectBookmark.
	CreateBookmark : function( includeNodes )
	{
		// Create the bookmark info (random IDs).
		var oBookmark =
		{
			StartId	: (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'S',
			EndId	: (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'E'
		} ;

		var oDoc = this.Window.document ;
		var eStartSpan ;
		var eEndSpan ;
		var oClone ;

		// For collapsed ranges, add just the start marker.
		if ( !this.CheckIsCollapsed() )
		{
			eEndSpan = oDoc.createElement( 'span' ) ;
			eEndSpan.style.display = 'none' ;
			eEndSpan.id = oBookmark.EndId ;
			eEndSpan.setAttribute( '_fck_bookmark', true ) ;

			// For IE, it must have something inside, otherwise it may be
			// removed during DOM operations.
//			if ( FCKBrowserInfo.IsIE )
				eEndSpan.innerHTML = '&nbsp;' ;

			oClone = this.Clone() ;
			oClone.Collapse( false ) ;
			oClone.InsertNode( eEndSpan ) ;
		}

		eStartSpan = oDoc.createElement( 'span' ) ;
		eStartSpan.style.display = 'none' ;
		eStartSpan.id = oBookmark.StartId ;
		eStartSpan.setAttribute( '_fck_bookmark', true ) ;

		// For IE, it must have something inside, otherwise it may be removed
		// during DOM operations.
//		if ( FCKBrowserInfo.IsIE )
			eStartSpan.innerHTML = '&nbsp;' ;

		oClone = this.Clone() ;
		oClone.Collapse( true ) ;
		oClone.InsertNode( eStartSpan ) ;

		if ( includeNodes )
		{
			oBookmark.StartNode = eStartSpan ;
			oBookmark.EndNode = eEndSpan ;
		}
		
		// Update the range position.
		if ( eEndSpan )
		{
			this.SetStart( eStartSpan, 4 ) ;
			this.SetEnd( eEndSpan, 3 ) ;
		}
		else
			this.MoveToPosition( eStartSpan, 4 ) ;
		
		return oBookmark ;
	},

	// This one should be a part of a hypothetic "bookmark" object.
	GetBookmarkNode : function( bookmark, start )
	{
		var doc = this.Window.document ;

		if ( start )
			return bookmark.StartNode || doc.getElementById( bookmark.StartId ) ;
		else
			return bookmark.EndNode || doc.getElementById( bookmark.EndId ) ;
	},

	MoveToBookmark : function( bookmark, preserveBookmark )
	{
		var eStartSpan	= this.GetBookmarkNode( bookmark, true ) ;
		var eEndSpan	= this.GetBookmarkNode( bookmark, false ) ;

		this.SetStart( eStartSpan, 3 ) ;

		if ( !preserveBookmark )
			FCKDomTools.RemoveNode( eStartSpan ) ;

		// If collapsed, the end span will not be available.
		if ( eEndSpan )
		{
			this.SetEnd( eEndSpan, 3 ) ;

			if ( !preserveBookmark )
				FCKDomTools.RemoveNode( eEndSpan ) ;
		}
		else
			this.Collapse( true ) ;

		this._UpdateElementInfo() ;
	},

	// Non-intrusive bookmark algorithm
	CreateBookmark2 : function()
	{
		// If there is no range then get out of here.
		// It happens on initial load in Safari #962 and if the editor it's hidden also in Firefox
		if ( ! this._Range )
			return { "Start" : 0, "End" : 0 } ;

		// First, we record down the offset values
		var bookmark =
		{
			"Start" : [ this._Range.startOffset ],
			"End" : [ this._Range.endOffset ]
		} ;
		var curStart = this._Range.startContainer.previousSibling ;
		var curEnd = this._Range.endContainer.previousSibling ;
		while ( curStart && curStart.nodeType == 3 )
		{
			bookmark.Start[0] += curStart.length ;
			curStart = curStart.previousSibling ;
		}
		while ( curEnd && curEnd.nodeType == 3 )
		{
			bookmark.End[0] += curEnd.length ;
			curEnd = curEnd.previousSibling ;
		}
		// Then, we record down the precise position of the container nodes
		// by walking up the DOM tree and counting their childNode index
		bookmark.Start = FCKDomTools.GetNodeAddress( this._Range.startContainer, true ).concat( bookmark.Start ) ;
		bookmark.End = FCKDomTools.GetNodeAddress( this._Range.endContainer, true ).concat( bookmark.End ) ;
		return bookmark;
	},

	MoveToBookmark2 : function( bookmark )
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -