web/drupal/modules/fckeditor/plugins/drupalbreak/fckplugin.js
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 // $Id: fckplugin.js,v 1.2.2.3 2009/01/28 14:52:26 wwalc Exp $
       
     2 /*
       
     3  * FCKeditor - The text editor for Internet - http://www.fckeditor.net
       
     4  * Copyright (C) 2003-2007 Frederico Caldeira Knabben
       
     5  *
       
     6  * == BEGIN LICENSE ==
       
     7  *
       
     8  * Licensed under the terms of any of the following licenses at your
       
     9  * choice:
       
    10  *
       
    11  *  - GNU General Public License Version 2 or later (the "GPL")
       
    12  *    http://www.gnu.org/licenses/gpl.html
       
    13  *
       
    14  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
       
    15  *    http://www.gnu.org/licenses/lgpl.html
       
    16  *
       
    17  *  - Mozilla Public License Version 1.1 or later (the "MPL")
       
    18  *    http://www.mozilla.org/MPL/MPL-1.1.html
       
    19  *
       
    20  * == END LICENSE ==
       
    21  *
       
    22  * Plugin: add support for <!--break--> tag inside Drupal
       
    23  * Source: http://drupal.org/node/81893
       
    24  */
       
    25 
       
    26 var pBreakBorderStyle = "#FF0000 1px dotted" ;
       
    27 
       
    28 // Define the command.
       
    29 var FCKDrupalBreak = function( name )
       
    30 {
       
    31 	this.Name = name ;
       
    32 	this.EditMode = FCK.EditMode ;
       
    33 }
       
    34 
       
    35 FCKDrupalBreak.prototype.Execute = function()
       
    36 {
       
    37 	if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG ) 
       
    38 		return ;
       
    39 	
       
    40 	FCKUndo.SaveUndoStep() ;
       
    41 		
       
    42 	switch ( this.Name )
       
    43 	{
       
    44 		case 'Break' :
       
    45 			this.RemoveOldBreaks();
       
    46 			var e = FCK.EditorDocument.createComment( 'break' ) ;
       
    47 			oFakeImage = FCK.InsertElement( FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', e ) ) ;
       
    48 			oFakeImage.setAttribute( "_drupalbreak", "true" ) ;
       
    49 			oFakeImage.style.borderTop = oFakeImage.style.borderBottom = pBreakBorderStyle ;
       
    50 			this.MoveBreakOutsideElement();
       
    51 		break;
       
    52 		default :
       
    53 		break;
       
    54 	}	
       
    55 }
       
    56 
       
    57 FCKDrupalBreak.prototype.RemoveOldBreaks = function()
       
    58 {	
       
    59 	// get all elements in FCK document
       
    60 	var elements = FCK.EditorDocument.getElementsByTagName( 'img' ) ;
       
    61 
       
    62 	// check every element for childNodes
       
    63 	var i = 0;
       
    64 	var next ;
       
    65 	while ( element = elements[i++] )
       
    66 	{
       
    67 		if ( element.getAttribute( '_drupalbreak' ) == "true" )
       
    68 		{
       
    69 			element.parentNode.removeChild( element ) ;
       
    70 		}
       
    71 	}
       
    72 }
       
    73 
       
    74 FCKDrupalBreak.prototype.MoveBreakOutsideElement = function()
       
    75 {
       
    76   FCK.FixBody();
       
    77 	// get all elements in FCK document
       
    78 	var elements = FCK.EditorDocument.getElementsByTagName( 'img' ) ;
       
    79 
       
    80 	// check every element for childNodes
       
    81 	var i = 0;
       
    82 	var next ;
       
    83 	while ( element = elements[i++] )
       
    84 	{
       
    85 		if ( element.getAttribute( '_drupalbreak' ) == "true" )
       
    86 		{
       
    87 			while( ( next = element.parentNode.nodeName.toLowerCase() ) != 'body' ) 
       
    88 			{
       
    89 				//if we are inside p or div, close immediately this tag, insert break tag, 
       
    90 				//create new element and move remaining siblings to the next element
       
    91 				if ( ( next == 'div' || next == 'p' ) && ( element.parentNode.parentNode.nodeName.toLowerCase() == 'body' ) )
       
    92 				{
       
    93 					var oParent = element.parentNode ;
       
    94 					var oDiv = FCK.EditorDocument.createElement( next.toUpperCase() ) ;
       
    95 					var bDivEmpty = true ;
       
    96 					var sibling ;
       
    97 
       
    98 					while( sibling = element.nextSibling )
       
    99 					{
       
   100 						if (!((sibling.nodeType == 3 && !sibling.nodeValue.length) || (sibling.nodeType == 1 && sibling.nodeName.toLowerCase() == 'br' && sibling.getAttribute( 'type' ) == '_moz'))) {
       
   101 						bDivEmpty = false ;
       
   102 						}
       
   103 
       
   104 						oDiv.appendChild( sibling ) ;
       
   105 					}
       
   106 
       
   107 					if ( oDiv.childNodes.length )
       
   108 					{
       
   109 						if ( oParent.nextSibling )
       
   110 							FCK.EditorDocument.body.insertBefore( oDiv, oParent.nextSibling ) ;
       
   111 						else
       
   112 							FCK.EditorDocument.body.appendChild( oDiv ) ;
       
   113 					}
       
   114 
       
   115 					if ( element.parentNode.nextSibling )
       
   116 						element.parentNode.parentNode.insertBefore( element, element.parentNode.nextSibling ) ;
       
   117 					else
       
   118 						element.parentNode.parentNode.appendChild( element ) ;
       
   119 						
       
   120 					if ( !oParent.childNodes.length )
       
   121 						FCK.EditorDocument.body.removeChild( oParent ) ;
       
   122 						
       
   123 					//we must be sure the bogus node is available to make cursor blinking
       
   124 					if ( FCKBrowserInfo.IsGeckoLike )
       
   125 						FCKTools.AppendBogusBr( oParent ) ;
       
   126 						
       
   127 					if ( bDivEmpty )
       
   128 						oDiv.parentNode.removeChild( oDiv );
       
   129 						
       
   130 					break ;
       
   131 				}
       
   132 				else
       
   133 				{
       
   134 					if ( element.parentNode.nextSibling )
       
   135 						element.parentNode.parentNode.insertBefore( element, element.parentNode.nextSibling ) ;
       
   136 					else
       
   137 						element.parentNode.parentNode.appendChild( element ) ;
       
   138 				}
       
   139 			}
       
   140 		}
       
   141 	}
       
   142 }
       
   143 
       
   144 FCKDrupalBreak.prototype.GetState = function()
       
   145 {
       
   146 	return ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
       
   147 }
       
   148 
       
   149 // Register the Drupal tag commands.
       
   150 FCKCommands.RegisterCommand( 'DrupalBreak', new FCKDrupalBreak( 'Break' ) ) ;
       
   151 // Create the Drupal tag buttons.
       
   152 var oDrupalItem = new FCKToolbarButton( 'DrupalBreak', FCKLang.DrupalBreakTitle, FCKLang.DrupalBreakTooltip, FCK_TOOLBARITEM_ICONTEXT, true, true ) ;
       
   153 oDrupalItem.IconPath = FCKConfig.PluginsPath + 'drupalbreak/drupalbreak.gif';
       
   154 FCKToolbarItems.RegisterItem( 'DrupalBreak', oDrupalItem ) ;
       
   155 
       
   156 // after switch in to source mode and back proccess page and insert fake
       
   157 // image for break again
       
   158 // Drupal Page Breaks Processor
       
   159 
       
   160 var FCKDrupalBreaksProcessor = FCKDocumentProcessor.AppendNew() ;
       
   161 FCKDrupalBreaksProcessor.ProcessDocument = function( document )
       
   162 {
       
   163 	// get all elements in FCK document
       
   164 	var elements = document.getElementsByTagName( '*' ) ;
       
   165 
       
   166 	// check every element for childNodes
       
   167 	var i = 0;
       
   168 	while (element = elements[i++]) {
       
   169 		var nodes = element.childNodes;
       
   170 
       
   171 		var j = 0;
       
   172 		while (node = nodes[j++]) {
       
   173 			if (node.nodeName == '#comment') {
       
   174 				var re = /\{\d+\}/ ;
       
   175 				var PContent;
       
   176 				if (re.test(node.nodeValue))
       
   177 					PContent = FCKConfig.ProtectedSource.Revert('<!--' + node.nodeValue + '-->', false);
       
   178 				if (node.nodeValue == 'break' || PContent == '<!--break-->') {
       
   179 					var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', node.cloneNode(true) ) ;
       
   180 					oFakeImage.setAttribute( "_drupalbreak", "true" ) ;
       
   181 					oFakeImage.style.borderTop = oFakeImage.style.borderBottom = pBreakBorderStyle ;
       
   182 					node.parentNode.insertBefore( oFakeImage, node ) ;
       
   183 					node.parentNode.removeChild( node ) ;
       
   184 				}
       
   185 			}
       
   186 		}
       
   187 	}
       
   188 	FCKDrupalBreak.prototype.MoveBreakOutsideElement();
       
   189 }
       
   190 
       
   191 if ( !FCK.Config.ProtectedSource._RevertOld )
       
   192 	FCK.Config.ProtectedSource._RevertOld = FCK.Config.ProtectedSource.Revert ;
       
   193 
       
   194 FCK.Config.ProtectedSource.Revert = function( html, clearBin )
       
   195 {
       
   196 	// Call the original code.
       
   197 	var result = FCK.Config.ProtectedSource._RevertOld ( html, clearBin ) ;
       
   198 	
       
   199 	if ( typeof FCKDrupalPageBreak !="undefined" && typeof FCKDrupalBreak !="undefined" )
       
   200 		var re = /<(p|div)>((?:<!--pagebreak-->|<!--break-->)+)<\/\1>/gi ;
       
   201 	else if ( typeof FCKDrupalBreak !="undefined" )
       
   202 		var re = /<(p|div)>(<!--break-->)+<\/\1>/gi ;
       
   203 	else if ( typeof FCKDrupalPageBreak !="undefined" )
       
   204 		var re = /<(p|div)>(<!--pagebreak-->)+<\/\1>/gi ;
       
   205 		
       
   206 	result = result.replace( re, '$2' );
       
   207 	return result ;
       
   208 }