ACC SHELL
/*
* FCKeditor - The text editor for internet
* Copyright (C) 2003-2005 Frederico Caldeira Knabben
*
* Licensed under the terms of the GNU Lesser General Public License:
* http://www.opensource.org/licenses/lgpl-license.php
*
* For further information visit:
* http://www.fckeditor.net/
*
* "Support Open Source software. What about a donation today?"
*
* File Name: fck_2_gecko.js
* This is the second part of the "FCK" object creation. This is the main
* object that represents an editor instance.
* (Gecko specific implementations)
*
* File Authors:
* Frederico Caldeira Knabben (fredck@fckeditor.net)
*/
// GetNamedCommandState overload for Gecko.
FCK._BaseGetNamedCommandState = FCK.GetNamedCommandState ;
FCK.GetNamedCommandState = function( commandName )
{
switch ( commandName )
{
case 'Unlink' :
return FCKSelection.HasAncestorNode('A') ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
default :
return FCK._BaseGetNamedCommandState( commandName ) ;
}
}
// Named commands to be handled by this browsers specific implementation.
FCK.RedirectNamedCommands =
{
Print : true,
Paste : true,
Cut : true,
Copy : true
// START iCM MODIFICATIONS
// Include list functions so we can ensure content is wrapped
// with P tags if not using BRs on carriage return, etc
/*
InsertOrderedList : true,
InsertUnorderedList : true
*/
// END iCM MODIFICATIONS
}
// ExecuteNamedCommand overload for Gecko.
FCK.ExecuteRedirectedNamedCommand = function( commandName, commandParameter )
{
switch ( commandName )
{
case 'Print' :
FCK.EditorWindow.print() ;
break ;
case 'Paste' :
try { if ( FCK.Paste() ) FCK.ExecuteNamedCommand( 'Paste', null, true ) ; }
catch (e) { alert(FCKLang.PasteErrorPaste) ; }
break ;
case 'Cut' :
try { FCK.ExecuteNamedCommand( 'Cut', null, true ) ; }
catch (e) { alert(FCKLang.PasteErrorCut) ; }
break ;
case 'Copy' :
try { FCK.ExecuteNamedCommand( 'Copy', null, true ) ; }
catch (e) { alert(FCKLang.PasteErrorCopy) ; }
break ;
// START iCM MODIFICATIONS
/*
case 'InsertOrderedList' :
case 'InsertUnorderedList' :
if ( !FCKConfig.UseBROnCarriageReturn && FCK.EditorDocument.queryCommandState( commandName ) )
{
// We're in a list item which is in the same type of list as the toolbar button clicked
// Therefore, move the selected list item out of the list as is done on an ENTER key within
// an empty list item.
var oSel = FCK.EditorWindow.getSelection() ;
var oSelNode = oSel.focusNode ;
var oLINode = FCKTools.GetElementAscensor( oSelNode, "LI" ) ;
FCK.ToggleListItem( oLINode, oSelNode ) ;
}
else
{
// Let the default handler do its stuff
FCK.Focus() ;
FCK.EditorDocument.execCommand( commandName, false, commandParameter ) ;
}
FCK.Events.FireEvent( 'OnSelectionChange' ) ;
break ;
*/
// END iCM MODIFICATIONS
default :
FCK.ExecuteNamedCommand( commandName, commandParameter ) ;
}
}
FCK.AttachToOnSelectionChange = function( functionPointer )
{
this.Events.AttachEvent( 'OnSelectionChange', functionPointer ) ;
}
FCK.Paste = function()
{
if ( FCKConfig.ForcePasteAsPlainText )
{
FCK.PasteAsPlainText() ;
return false ;
}
/* For now, the AutoDetectPasteFromWord feature is IE only.
else if ( FCKConfig.AutoDetectPasteFromWord )
{
var sHTML = FCK.GetClipboardHTML() ;
var re = /<\w[^>]* class="?MsoNormal"?/gi ;
if ( re.test( sHTML ) )
{
if ( confirm( FCKLang["PasteWordConfirm"] ) )
{
FCK.PasteFromWord() ;
return false ;
}
}
}
*/
else
return true ;
}
//**
// FCK.InsertHtml: Inserts HTML at the current cursor location. Deletes the
// selected content if any.
FCK.InsertHtml = function( html )
{
html = FCKConfig.ProtectedSource.Protect( html ) ;
html = FCK.ProtectUrls( html ) ;
// Delete the actual selection.
var oSel = FCKSelection.Delete() ;
// Get the first available range.
var oRange = oSel.getRangeAt(0) ;
// Create a fragment with the input HTML.
var oFragment = oRange.createContextualFragment( html ) ;
// Get the last available node.
var oLastNode = oFragment.lastChild ;
// Insert the fragment in the range.
oRange.insertNode(oFragment) ;
// Set the cursor after the inserted fragment.
FCKSelection.SelectNode( oLastNode ) ;
FCKSelection.Collapse( false ) ;
this.Focus() ;
}
FCK.InsertElement = function( element )
{
// Deletes the actual selection.
var oSel = FCKSelection.Delete() ;
// Gets the first available range.
var oRange = oSel.getRangeAt(0) ;
// Inserts the element in the range.
oRange.insertNode( element ) ;
// Set the cursor after the inserted fragment.
FCKSelection.SelectNode( element ) ;
FCKSelection.Collapse( false ) ;
this.Focus() ;
}
FCK.PasteAsPlainText = function()
{
// TODO: Implement the "Paste as Plain Text" code.
FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteAsText, 'dialog/fck_paste.html', 400, 330, 'PlainText' ) ;
/*
var sText = FCKTools.HTMLEncode( clipboardData.getData("Text") ) ;
sText = sText.replace( /\n/g, '<BR>' ) ;
this.InsertHtml( sText ) ;
*/
}
/*
FCK.PasteFromWord = function()
{
// TODO: Implement the "Paste as Plain Text" code.
FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteFromWord, 'dialog/fck_paste.html', 400, 330, 'Word' ) ;
// FCK.CleanAndPaste( FCK.GetClipboardHTML() ) ;
}
*/
FCK.GetClipboardHTML = function()
{
return '' ;
}
FCK.CreateLink = function( url )
{
FCK.ExecuteNamedCommand( 'Unlink' ) ;
if ( url.length > 0 )
{
// Generate a temporary name for the link.
var sTempUrl = 'javascript:void(0);/*' + ( new Date().getTime() ) + '*/' ;
// Use the internal "CreateLink" command to create the link.
FCK.ExecuteNamedCommand( 'CreateLink', sTempUrl ) ;
// Retrieve the just created link using XPath.
var oLink = document.evaluate("//a[@href='" + sTempUrl + "']", this.EditorDocument.body, null, 9, null).singleNodeValue ;
if ( oLink )
{
oLink.href = url ;
return oLink ;
}
}
}
// START iCM Modifications
/*
// Ensure that behaviour of the ENTER key or the list toolbar button works correctly for a list item.
// ENTER in empty list item at top of list should result in the empty list item being
// removed and selection being moved out of the list into a P tag above it.
// ENTER in empty list item at bottom of list should result in the empty list item being
// removed and selection being moved out of the list into a P tag below it.
// ENTER in empty list item in middle of the list should result in the list being split
// into two and the selection being moved into a P tag between the two resulting lists.
// Clicking the list toolbar button in a list item at top of list should result in the list item's contents being
// moved out of the list into a P tag above it.
// Clicking the list toolbar button in a list item at the bottom of list should result in the list item's contents being
// moved out of the list into a P tag below it.
// Clicking the list toolbar button in a list item in the middle of the list should result in the list being split
// into two and the list item's contents being moved into a P tag between the two resulting lists.
FCK.ToggleListItem = function( oLINode, oSelNode )
{
var oListNode = FCKTools.GetElementAscensor( oLINode, "UL,OL" ) ;
var oRange = FCK.EditorDocument.createRange() ;
// Create a new block element
var oBlockNode = FCK.EditorDocument.createElement( "P" ) ;
oBlockNode.innerHTML = oLINode.innerHTML ; // Transfer any list item contents
if ( FCKTools.NodeIsEmpty( oBlockNode ) )
oBlockNode.innerHTML = GECKO_BOGUS ; // Ensure it has some content, required for Gecko
if ( oLINode.className && oLINode.className != '' )
oBlockNode.className = oLINode.className ; // Transfer across any class attribute
var oCursorNode = oBlockNode ;
// Then, perform list processing and locate the point at which the new P tag is to be inserted
if ( oListNode.childNodes[0] == oLINode )
{
// First LI was empty so want to leave list and insert P above it
oListNode.removeChild( oLINode );
// Need to insert a new P tag (or other suitable block element) just before the list
oRange.setStartBefore( oListNode ) ;
oRange.setEndBefore( oListNode ) ;
}
else if ( oListNode.childNodes[oListNode.childNodes.length-1] == oLINode )
{
// Last LI was empty so want to leave list and insert new block element in the parent
oListNode.removeChild( oLINode );
// Need to insert a new P tag (or other suitable block element) just after the list
oRange.setEndAfter( oListNode ) ;
oRange.setStartAfter( oListNode ) ;
}
else
{
// A middle LI was empty so want to break list into two and insert the new block/text node in between them
oListNode = FCKTools.SplitNode( oListNode, oSelNode, 0 ) ;
oListNode.removeChild( oListNode.childNodes[0] ) ;
oRange.setStartBefore( oListNode ) ;
oRange.setEndBefore( oListNode ) ;
}
// Insert new block/text node
oRange.insertNode( oBlockNode ) ;
// Ensure that we don't leave empty UL/OL tags behind
if ( oListNode.childNodes.length == 0 )
oListNode.parentNode.removeChild( oListNode ) ;
// Reset cursor position to start of the new P tag's contents ready for typing
FCK.Selection.SetCursorPosition( oCursorNode ) ;
}
FCK.ListItemEnter = function( oLINode, oSelNode, nSelOffset )
{
// Ensure that behaviour of ENTER key within an empty list element works correctly.
// ENTER in empty list item at top of list should result in the empty list item being
// removed and selection being moved out of the list into a P tag above it.
// ENTER in empty list item at bottom of list should result in the empty list item being
// removed and selection being moved out of the list into a P tag below it.
// ENTER in empty list item in middle of the list should result in the list being split
// into two and the selection being moved into a P tag between the two resulting lists.
if ( FCKTools.NodeIsEmpty( oLINode ) )
{
FCK.ToggleListItem( oLINode, oSelNode ) ;
return false ; // Job done, perform no default handling
}
return true ; // If non-empty list item, let default handler do its stuff
}
FCK.ListItemBackSpace = function( oSelNode, nSelOffset )
{
// Ensure that behaviour of BACKSPACE key within an empty list element works correctly.
// BACKSPACE in empty list item at top of list should result in the empty list item being
// removed and selection being moved out of the list into a P tag above it.
// Allow the default handler to do its stuff for backspace in other list elements.
var oListNode = oSelNode.parentNode ;
if ( FCKTools.NodeIsEmpty( oSelNode ) && ( oListNode.childNodes[0] == oSelNode ) )
{
var oRange = FCK.EditorDocument.createRange() ;
// Create a new P element
var oBlockNode = FCK.EditorDocument.createElement( "P" ) ;
if ( FCKTools.NodeIsEmpty( oBlockNode ) )
oBlockNode.innerHTML = GECKO_BOGUS ; // Ensure it has some content, required for Gecko
// First LI was empty so want to leave list and insert P above it
oListNode.removeChild( oSelNode );
oRange.setStartBefore( oListNode ) ;
oRange.setEndBefore( oListNode ) ;
// Insert new P tag
oRange.insertNode( oBlockNode ) ;
// Ensure that we don't leave empty UL/OL tags behind
if ( oListNode.childNodes.length == 0 )
oListNode.parentNode.removeChild( oListNode ) ;
// Reset cursor position to start of the new P tag's contents ready for typing
FCK.Selection.SetCursorPosition( oBlockNode ) ;
return false ; // Job done, perform no default handling
}
return true ; // Let default handler do its stuff if not backspacing in an empty first LI
}
FCK.Enter = function()
{
// Remove any selected content before we begin so we end up with a single selection point
FCK.Selection.Delete() ;
// Determine the current cursor (selection) point, the node it's within and the offset
// position of the cursor within that node
var oSel = FCK.EditorWindow.getSelection() ;
var nSelOffset = oSel.focusOffset;
var oSelNode = oSel.focusNode ;
// Guard against a null focus node.
if ( !oSelNode )
return false ;
var oLINode = FCKTools.GetElementAscensor( oSelNode, "LI" ) ;
if ( oLINode ) // An LI element is selected
{
// Handle list items separately as need to handle termination of the list, etc
return FCK.ListItemEnter( oLINode, oSelNode, nSelOffset ) ;
}
else if ( oSelNode.nodeType == 3 ) // A TEXT node is selected
{
// Split it at the selection point and ensure both halves have a suitable enclosing block element
var oParentBlockNode = FCKTools.GetParentBlockNode( oSelNode ) ;
var oBlockNode2 = FCKTools.SplitNode( oParentBlockNode ? oParentBlockNode : FCK.EditorDocument.body, oSelNode, nSelOffset ) ;
FCK.Selection.SetCursorPosition( oBlockNode2 );
return false ;
}
else // An ELEMENT node is selected
{
// Cater for ENTER being pressed after very last element in the editor e.g. pressing ENTER after table element at very end of the editor's content
if ( nSelOffset >= oSelNode.childNodes.length )
{
var oBlockNode = FCK.EditorDocument.createElement( "P" ) ;
if ( FCKTools.NodeIsEmpty( oBlockNode ) )
oBlockNode.innerHTML = GECKO_BOGUS ; // Ensure it has some content, required for Gecko
oSelNode.appendChild( oBlockNode ) ;
FCK.Selection.SetCursorPosition( oBlockNode ) ;
return false ;
}
var oBlockNode2 = FCKTools.SplitNode( oSelNode, oSelNode.childNodes[nSelOffset] ) ;
FCK.Selection.SetCursorPosition( oBlockNode2 );
return false ;
}
return true ;
}
FCK.BackSpace = function()
{
var oSel = FCK.EditorWindow.getSelection() ;
var oSelNode = oSel.focusNode ;
var nSelOffset = oSel.focusOffset;
var oParentNode = null ;
// Guard against a null focus node.
if ( !oSelNode )
return false ;
if ( oSelNode.nodeName.toUpperCase() == "LI" ) // An LI element is selected
{
// Handle list items separately as need to handle termination of the list, etc
return FCK.ListItemBackSpace( oSelNode, nSelOffset ) ;
}
else
{
// If we are anything other than a TEXT node, move to the child indicated by the selection offset
if ( oSelNode.nodeType != 3 )
{
oSelNode = oSelNode.childNodes[nSelOffset] ;
nSelOffset = 0 ;
}
// If we are the first child and the previous sibling of the parent is an empty block element (containing nothing or just the filler element)
// want the backspace to completely remove the empty block element
if ( !oSelNode.previousSibling && nSelOffset <= 0 )
{
oParentNode = oSelNode.parentNode ;
if ( oParentNode && oParentNode.previousSibling && FCKRegexLib.BlockElements.test( oParentNode.previousSibling.nodeName ) )
{
if ( FCKTools.NodeIsEmpty( oParentNode.previousSibling ) )
{
var oRange = FCK.EditorDocument.createRange() ;
oRange.selectNode ( oParentNode.previousSibling );
oRange.deleteContents() ;
// Don't do any default processing
return false ;
}
}
}
}
return true ; // Let default processing do its stuff
}
*/
// END iCM Modifications
ACC SHELL 2018