/* * FCKeditor - The text editor for Internet - http://www.fckeditor.net * Copyright (C) 2003-2008 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 == * * Defines the FCKToolbarSet object that is used to load and draw the * toolbar. */ function FCKToolbarSet_Create( overhideLocation ) { var oToolbarSet ; var sLocation = overhideLocation || FCKConfig.ToolbarLocation ; switch ( sLocation ) { case 'In' : document.getElementById( 'xToolbarRow' ).style.display = '' ; oToolbarSet = new FCKToolbarSet( document ) ; break ; case 'None' : oToolbarSet = new FCKToolbarSet( document ) ; break ; // case 'OutTop' : // Not supported. default : FCK.Events.AttachEvent( 'OnBlur', FCK_OnBlur ) ; FCK.Events.AttachEvent( 'OnFocus', FCK_OnFocus ) ; var eToolbarTarget ; // Out:[TargetWindow]([TargetId]) var oOutMatch = sLocation.match( /^Out:(.+)\((\w+)\)$/ ) ; if ( oOutMatch ) { if ( FCKBrowserInfo.IsAIR ) FCKAdobeAIR.ToolbarSet_GetOutElement( window, oOutMatch ) ; else eToolbarTarget = eval( 'parent.' + oOutMatch[1] ).document.getElementById( oOutMatch[2] ) ; } else { // Out:[TargetId] oOutMatch = sLocation.match( /^Out:(\w+)$/ ) ; if ( oOutMatch ) eToolbarTarget = parent.document.getElementById( oOutMatch[1] ) ; } if ( !eToolbarTarget ) { alert( 'Invalid value for "ToolbarLocation"' ) ; return arguments.callee( 'In' ); } // If it is a shared toolbar, it may be already available in the target element. oToolbarSet = eToolbarTarget.__FCKToolbarSet ; if ( oToolbarSet ) break ; // Create the IFRAME that will hold the toolbar inside the target element. var eToolbarIFrame = FCKTools.GetElementDocument( eToolbarTarget ).createElement( 'iframe' ) ; eToolbarIFrame.src = 'javascript:void(0)' ; eToolbarIFrame.frameBorder = 0 ; eToolbarIFrame.width = '100%' ; eToolbarIFrame.height = '10' ; eToolbarTarget.appendChild( eToolbarIFrame ) ; eToolbarIFrame.unselectable = 'on' ; // Write the basic HTML for the toolbar (copy from the editor main page). var eTargetDocument = eToolbarIFrame.contentWindow.document ; // Workaround for Safari 12256. Ticket #63 var sBase = '' ; if ( FCKBrowserInfo.IsSafari ) sBase = '' ; // Initialize the IFRAME document body. eTargetDocument.open() ; eTargetDocument.write( '' + sBase + '' + document.getElementById( 'xToolbarSpace' ).innerHTML + '' ) ; eTargetDocument.close() ; if( FCKBrowserInfo.IsAIR ) FCKAdobeAIR.ToolbarSet_InitOutFrame( eTargetDocument ) ; FCKTools.AddEventListener/* * FCKeditor - The text editor for Internet - http://www.fckeditor.net * Copyright (C) 2003-2008 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 == */ var FCKUndo = new Object() ; FCKUndo.SavedData = new Array() ; FCKUndo.CurrentIndex = -1 ; FCKUndo.TypesCount = 0 ; FCKUndo.Changed = false ; // Is the document changed in respect to its initial image? FCKUndo.MaxTypes = 25 ; FCKUndo.Typing = false ; FCKUndo.SaveLocked = false ; FCKUndo._GetBookmark = function() { FCKSelection.Restore() ; var range = new FCKDomRange( FCK.EditorWindow ) ; try { // There are some tricky cases where this might fail (e.g. having a lone empty table in IE) range.MoveToSelection() ; } catch ( e ) { return null ; } if ( FCKBrowserInfo.IsIE ) { var bookmark = range.CreateBookmark() ; var dirtyHtml = FCK.EditorDocument.body.innerHTML ; range.MoveToBookmark( bookmark ) ; return [ bookmark, dirtyHtml ] ; } return range.CreateBookmark2() ; } FCKUndo._SelectBookmark = function( bookmark ) { if ( ! bookmark ) return ; var range = new FCKDomRange( FCK.EditorWindow ) ; if ( bookmark instanceof Object ) { if ( FCKBrowserInfo.IsIE ) range.MoveToBookmark( bookmark[0] ) ; else range.MoveToBookmark2( bookmark ) ; try { // this does not always succeed, there are still some tricky cases where it fails // e.g. add a special character at end of document, undo, redo -> error range.Select() ; } catch ( e ) { // if select restore fails, put the caret at the end of the document range.MoveToPosition( FCK.EditorDocument.body, 4 ) ; range.Select() ; } } } FCKUndo._CompareCursors = function( cursor1, cursor2 ) { for ( var i = 0 ; i < Math.min( cursor1.length, cursor2.length ) ; i++ ) { if ( cursor1[i] < cursor2[i] ) return -1; else if (cursor1[i] > cursor2[i] ) return 1; } if ( cursor1.length < cursor2.length ) return -1; else if (cursor1.length > cursor2.length ) return 1; return 0; } FCKUndo._CheckIsBookmarksEqual = function( bookmark1, bookmark2 ) { if ( ! ( bookmark1 && bookmark2 ) ) return false ; if ( FCKBrowserInfo.IsIE ) { var startOffset1 = bookmark1[1].search( bookmark1[0].StartId ) ; var startOffset2 = bookmark2[1].search( bookmark2[0].StartId ) ; var endOffset1 = bookmark1[1].search( bookmark1[0].EndId ) ; var endOffset2 = bookmark2[1].search( bookmark2[0].EndId ) ; return startOffset1 == startOffset2 && endOffset1 == endOffset2 ; } else { return this._CompareCursors( bookmark1.Start, bookmark2.Start ) == 0 && this._CompareCursors( bookmark1.End, bookmark2.End ) == 0 ; } } FCKUndo.SaveUndoStep = function() { if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || this.SaveLocked ) return ; // Assume the editor content is changed when SaveUndoStep() is called after the first time. // This also enables the undo button in toolbar. if ( this.SavedData.length ) this.Changed = true ; // Get the HTML content. var sHtml = FCK.EditorDocument.body.innerHTML ; var bookmark = this._GetBookmark() ; // Shrink the array to the current level. this.SavedData = this.SavedData.slice( 0, this.CurrentIndex + 1 ) ; // Cancel operation if the new step is identical to the previous one. if ( this.CurrentIndex > 0 && sHtml == this.SavedData[ this.CurrentIndex ][0] && this._CheckIsBookmarksEqual( bookmark, this.SavedData[ this.CurrentIndex ][1] ) ) return ; // Save the selection and caret position in the first undo level for the first change. else if ( this.CurrentIndex == 0 && this.SavedData.length && sHtml == this.SavedData[0][0] ) { this.SavedData[0][1] = bookmark ; return ; } // If we reach the Maximum number of undo levels, we must remove the first // entry of the list shifting all elements. if ( this.CurrentIndex + 1 >= FCKConfig.MaxUndoLevels ) this.SavedData.shift() ; else this.CurrentIndex++ ; // Save the new level in front of the actual position. this.SavedData[ this.CurrentIndex ] = [ sHtml, bookmark ] ; FCK.Events.FireEvent( "OnSelectionChange" ) ; } FCKUndo.CheckUndoState = function() { return ( this.Changed || this.CurrentIndex > 0 ) ; } FCKUndo.CheckRedoState = function() { return ( this.CurrentIndex < ( this.SavedData.length - 1 ) ) ; } FCKUndo.Undo = function() { if ( this.CheckUndoState() ) { // If it is the first step. if ( this.CurrentIndex == ( this.SavedData.length - 1 ) ) { // Save the actual state for a possible "Redo" call. this.SaveUndoSte