+++ /dev/null
-/*\r
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net\r
- * Copyright (C) 2003-2009 Frederico Caldeira Knabben\r
- *\r
- * == BEGIN LICENSE ==\r
- *\r
- * Licensed under the terms of any of the following licenses at your\r
- * choice:\r
- *\r
- * - GNU General Public License Version 2 or later (the "GPL")\r
- * http://www.gnu.org/licenses/gpl.html\r
- *\r
- * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")\r
- * http://www.gnu.org/licenses/lgpl.html\r
- *\r
- * - Mozilla Public License Version 1.1 or later (the "MPL")\r
- * http://www.mozilla.org/MPL/MPL-1.1.html\r
- *\r
- * == END LICENSE ==\r
- *\r
- * FCKBlockQuoteCommand Class: adds or removes blockquote tags.\r
- */\r
-\r
-var FCKBlockQuoteCommand = function()\r
-{\r
-}\r
-\r
-FCKBlockQuoteCommand.prototype =\r
-{\r
- Execute : function()\r
- {\r
- FCKUndo.SaveUndoStep() ;\r
-\r
- var state = this.GetState() ;\r
-\r
- var range = new FCKDomRange( FCK.EditorWindow ) ;\r
- range.MoveToSelection() ;\r
-\r
- var bookmark = range.CreateBookmark() ;\r
-\r
- // Kludge for #1592: if the bookmark nodes are in the beginning of\r
- // blockquote, then move them to the nearest block element in the\r
- // blockquote.\r
- if ( FCKBrowserInfo.IsIE )\r
- {\r
- var bStart = range.GetBookmarkNode( bookmark, true ) ;\r
- var bEnd = range.GetBookmarkNode( bookmark, false ) ;\r
-\r
- var cursor ;\r
-\r
- if ( bStart\r
- && bStart.parentNode.nodeName.IEquals( 'blockquote' )\r
- && !bStart.previousSibling )\r
- {\r
- cursor = bStart ;\r
- while ( ( cursor = cursor.nextSibling ) )\r
- {\r
- if ( FCKListsLib.BlockElements[ cursor.nodeName.toLowerCase() ] )\r
- FCKDomTools.MoveNode( bStart, cursor, true ) ;\r
- }\r
- }\r
-\r
- if ( bEnd\r
- && bEnd.parentNode.nodeName.IEquals( 'blockquote' )\r
- && !bEnd.previousSibling )\r
- {\r
- cursor = bEnd ;\r
- while ( ( cursor = cursor.nextSibling ) )\r
- {\r
- if ( FCKListsLib.BlockElements[ cursor.nodeName.toLowerCase() ] )\r
- {\r
- if ( cursor.firstChild == bStart )\r
- FCKDomTools.InsertAfterNode( bStart, bEnd ) ;\r
- else\r
- FCKDomTools.MoveNode( bEnd, cursor, true ) ;\r
- }\r
- }\r
- }\r
- }\r
-\r
- var iterator = new FCKDomRangeIterator( range ) ;\r
- var block ;\r
-\r
- if ( state == FCK_TRISTATE_OFF )\r
- {\r
- var paragraphs = [] ;\r
- while ( ( block = iterator.GetNextParagraph() ) )\r
- paragraphs.push( block ) ;\r
-\r
- // If no paragraphs, create one from the current selection position.\r
- if ( paragraphs.length < 1 )\r
- {\r
- para = range.Window.document.createElement( FCKConfig.EnterMode.IEquals( 'p' ) ? 'p' : 'div' ) ;\r
- range.InsertNode( para ) ;\r
- para.appendChild( range.Window.document.createTextNode( '\ufeff' ) ) ;\r
- range.MoveToBookmark( bookmark ) ;\r
- range.MoveToNodeContents( para ) ;\r
- range.Collapse( true ) ;\r
- bookmark = range.CreateBookmark() ;\r
- paragraphs.push( para ) ;\r
- }\r
-\r
- // Make sure all paragraphs have the same parent.\r
- var commonParent = paragraphs[0].parentNode ;\r
- var tmp = [] ;\r
- for ( var i = 0 ; i < paragraphs.length ; i++ )\r
- {\r
- block = paragraphs[i] ;\r
- commonParent = FCKDomTools.GetCommonParents( block.parentNode, commonParent ).pop() ;\r
- }\r
-\r
- // The common parent must not be the following tags: table, tbody, tr, ol, ul.\r
- while ( commonParent.nodeName.IEquals( 'table', 'tbody', 'tr', 'ol', 'ul' ) )\r
- commonParent = commonParent.parentNode ;\r
-\r
- // Reconstruct the block list to be processed such that all resulting blocks\r
- // satisfy parentNode == commonParent.\r
- var lastBlock = null ;\r
- while ( paragraphs.length > 0 )\r
- {\r
- block = paragraphs.shift() ;\r
- while ( block.parentNode != commonParent )\r
- block = block.parentNode ;\r
- if ( block != lastBlock )\r
- tmp.push( block ) ;\r
- lastBlock = block ;\r
- }\r
-\r
- // If any of the selected blocks is a blockquote, remove it to prevent nested blockquotes.\r
- while ( tmp.length > 0 )\r
- {\r
- block = tmp.shift() ;\r
- if ( block.nodeName.IEquals( 'blockquote' ) )\r
- {\r
- var docFrag = FCKTools.GetElementDocument( block ).createDocumentFragment() ;\r
- while ( block.firstChild )\r
- {\r
- docFrag.appendChild( block.removeChild( block.firstChild ) ) ;\r
- paragraphs.push( docFrag.lastChild ) ;\r
- }\r
- block.parentNode.replaceChild( docFrag, block ) ;\r
- }\r
- else\r
- paragraphs.push( block ) ;\r
- }\r
-\r
- // Now we have all the blocks to be included in a new blockquote node.\r
- var bqBlock = range.Window.document.createElement( 'blockquote' ) ;\r
- commonParent.insertBefore( bqBlock, paragraphs[0] ) ;\r
- while ( paragraphs.length > 0 )\r
- {\r
- block = paragraphs.shift() ;\r
- bqBlock.appendChild( block ) ;\r
- }\r
- }\r
- else if ( state == FCK_TRISTATE_ON )\r
- {\r
- var moveOutNodes = [] ;\r
- var elementMarkers = {} ;\r
- while ( ( block = iterator.GetNextParagraph() ) )\r
- {\r
- var bqParent = null ;\r
- var bqChild = null ;\r
- while ( block.parentNode )\r
- {\r
- if ( block.parentNode.nodeName.IEquals( 'blockquote' ) )\r
- {\r
- bqParent = block.parentNode ;\r
- bqChild = block ;\r
- break ;\r
- }\r
- block = block.parentNode ;\r
- }\r
-\r
- // Remember the blocks that were recorded down in the moveOutNodes array\r
- // to prevent duplicates.\r
- if ( bqParent && bqChild && !bqChild._fckblockquotemoveout )\r
- {\r
- moveOutNodes.push( bqChild ) ;\r
- FCKDomTools.SetElementMarker( elementMarkers, bqChild, '_fckblockquotemoveout', true ) ;\r
- }\r
- }\r
- FCKDomTools.ClearAllMarkers( elementMarkers ) ;\r
-\r
- var movedNodes = [] ;\r
- var processedBlockquoteBlocks = [], elementMarkers = {} ;\r
- var noBlockLeft = function( bqBlock )\r
- {\r
- for ( var i = 0 ; i < bqBlock.childNodes.length ; i++ )\r
- {\r
- if ( FCKListsLib.BlockElements[ bqBlock.childNodes[i].nodeName.toLowerCase() ] )\r
- return false ;\r
- }\r
- return true ;\r
- } ;\r
- while ( moveOutNodes.length > 0 )\r
- {\r
- var node = moveOutNodes.shift() ;\r
- var bqBlock = node.parentNode ;\r
-\r
- // If the node is located at the beginning or the end, just take it out without splitting.\r
- // Otherwise, split the blockquote node and move the paragraph in between the two blockquote nodes.\r
- if ( node == node.parentNode.firstChild )\r
- bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock ) ;\r
- else if ( node == node.parentNode.lastChild )\r
- bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock.nextSibling ) ;\r
- else\r
- FCKDomTools.BreakParent( node, node.parentNode, range ) ;\r
-\r
- // Remember the blockquote node so we can clear it later (if it becomes empty).\r
- if ( !bqBlock._fckbqprocessed )\r
- {\r
- processedBlockquoteBlocks.push( bqBlock ) ;\r
- FCKDomTools.SetElementMarker( elementMarkers, bqBlock, '_fckbqprocessed', true );\r
- }\r
-\r
- movedNodes.push( node ) ;\r
- }\r
-\r
- // Clear blockquote nodes that have become empty.\r
- for ( var i = processedBlockquoteBlocks.length - 1 ; i >= 0 ; i-- )\r
- {\r
- var bqBlock = processedBlockquoteBlocks[i] ;\r
- if ( noBlockLeft( bqBlock ) )\r
- FCKDomTools.RemoveNode( bqBlock ) ;\r
- }\r
- FCKDomTools.ClearAllMarkers( elementMarkers ) ;\r
-\r
- if ( FCKConfig.EnterMode.IEquals( 'br' ) )\r
- {\r
- while ( movedNodes.length )\r
- {\r
- var node = movedNodes.shift() ;\r
- var firstTime = true ;\r
- if ( node.nodeName.IEquals( 'div' ) )\r
- {\r
- var docFrag = FCKTools.GetElementDocument( node ).createDocumentFragment() ;\r
- var needBeginBr = firstTime && node.previousSibling &&\r
- !FCKListsLib.BlockBoundaries[node.previousSibling.nodeName.toLowerCase()] ;\r
- if ( firstTime && needBeginBr )\r
- docFrag.appendChild( FCKTools.GetElementDocument( node ).createElement( 'br' ) ) ;\r
- var needEndBr = node.nextSibling &&\r
- !FCKListsLib.BlockBoundaries[node.nextSibling.nodeName.toLowerCase()] ;\r
- while ( node.firstChild )\r
- docFrag.appendChild( node.removeChild( node.firstChild ) ) ;\r
- if ( needEndBr )\r
- docFrag.appendChild( FCKTools.GetElementDocument( node ).createElement( 'br' ) ) ;\r
- node.parentNode.replaceChild( docFrag, node ) ;\r
- firstTime = false ;\r
- }\r
- }\r
- }\r
- }\r
- range.MoveToBookmark( bookmark ) ;\r
- range.Select() ;\r
-\r
- FCK.Focus() ;\r
- FCK.Events.FireEvent( 'OnSelectionChange' ) ;\r
- },\r
-\r
- GetState : function()\r
- {\r
- // Disabled if not WYSIWYG.\r
- if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )\r
- return FCK_TRISTATE_DISABLED ;\r
-\r
- var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ;\r
- var firstBlock = path.Block || path.BlockLimit ;\r
-\r
- if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' )\r
- return FCK_TRISTATE_OFF ;\r
-\r
- // See if the first block has a blockquote parent.\r
- for ( var i = 0 ; i < path.Elements.length ; i++ )\r
- {\r
- if ( path.Elements[i].nodeName.IEquals( 'blockquote' ) )\r
- return FCK_TRISTATE_ON ;\r
- }\r
- return FCK_TRISTATE_OFF ;\r
- }\r
-} ;\r