750 lines
19 KiB
JavaScript
750 lines
19 KiB
JavaScript
/*
|
|
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
|
|
* Copyright (C) 2003-2009 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 ==
|
|
*
|
|
* Utility functions.
|
|
*/
|
|
|
|
var FCKTools = new Object() ;
|
|
|
|
FCKTools.CreateBogusBR = function( targetDocument )
|
|
{
|
|
var eBR = targetDocument.createElement( 'br' ) ;
|
|
// eBR.setAttribute( '_moz_editor_bogus_node', 'TRUE' ) ;
|
|
eBR.setAttribute( 'type', '_moz' ) ;
|
|
return eBR ;
|
|
}
|
|
|
|
/**
|
|
* Fixes relative URL entries defined inside CSS styles by appending a prefix
|
|
* to them.
|
|
* @param (String) cssStyles The CSS styles definition possibly containing url()
|
|
* paths.
|
|
* @param (String) urlFixPrefix The prefix to append to relative URLs.
|
|
*/
|
|
FCKTools.FixCssUrls = function( urlFixPrefix, cssStyles )
|
|
{
|
|
if ( !urlFixPrefix || urlFixPrefix.length == 0 )
|
|
return cssStyles ;
|
|
|
|
return cssStyles.replace( /url\s*\(([\s'"]*)(.*?)([\s"']*)\)/g, function( match, opener, path, closer )
|
|
{
|
|
if ( /^\/|^\w?:/.test( path ) )
|
|
return match ;
|
|
else
|
|
return 'url(' + opener + urlFixPrefix + path + closer + ')' ;
|
|
} ) ;
|
|
}
|
|
|
|
FCKTools._GetUrlFixedCss = function( cssStyles, urlFixPrefix )
|
|
{
|
|
var match = cssStyles.match( /^([^|]+)\|([\s\S]*)/ ) ;
|
|
|
|
if ( match )
|
|
return FCKTools.FixCssUrls( match[1], match[2] ) ;
|
|
else
|
|
return cssStyles ;
|
|
}
|
|
|
|
/**
|
|
* Appends a <link css> or <style> element to the document.
|
|
* @param (Object) documentElement The DOM document object to which append the
|
|
* stylesheet.
|
|
* @param (Variant) cssFileOrDef A String pointing to the CSS file URL or an
|
|
* Array with many CSS file URLs or the CSS definitions for the <style>
|
|
* element.
|
|
* @return {Array} An array containing all elements created in the target
|
|
* document. It may include <link> or <style> elements, depending on the
|
|
* value passed with cssFileOrDef.
|
|
*/
|
|
FCKTools.AppendStyleSheet = function( domDocument, cssFileOrArrayOrDef )
|
|
{
|
|
if ( !cssFileOrArrayOrDef )
|
|
return [] ;
|
|
|
|
if ( typeof( cssFileOrArrayOrDef ) == 'string' )
|
|
{
|
|
// Test if the passed argument is an URL.
|
|
if ( /[\\\/\.][^{}]*$/.test( cssFileOrArrayOrDef ) )
|
|
{
|
|
// The string may have several URLs separated by comma.
|
|
return this.AppendStyleSheet( domDocument, cssFileOrArrayOrDef.split(',') ) ;
|
|
}
|
|
else
|
|
return [ this.AppendStyleString( domDocument, FCKTools._GetUrlFixedCss( cssFileOrArrayOrDef ) ) ] ;
|
|
}
|
|
else
|
|
{
|
|
var styles = [] ;
|
|
for ( var i = 0 ; i < cssFileOrArrayOrDef.length ; i++ )
|
|
styles.push( this._AppendStyleSheet( domDocument, cssFileOrArrayOrDef[i] ) ) ;
|
|
return styles ;
|
|
}
|
|
}
|
|
|
|
FCKTools.GetStyleHtml = (function()
|
|
{
|
|
var getStyle = function( styleDef, markTemp )
|
|
{
|
|
if ( styleDef.length == 0 )
|
|
return '' ;
|
|
|
|
var temp = markTemp ? ' _fcktemp="true"' : '' ;
|
|
return '<' + 'style type="text/css"' + temp + '>' + styleDef + '<' + '/style>' ;
|
|
}
|
|
|
|
var getLink = function( cssFileUrl, markTemp )
|
|
{
|
|
if ( cssFileUrl.length == 0 )
|
|
return '' ;
|
|
|
|
var temp = markTemp ? ' _fcktemp="true"' : '' ;
|
|
return '<' + 'link href="' + cssFileUrl + '" type="text/css" rel="stylesheet" ' + temp + '/>' ;
|
|
}
|
|
|
|
return function( cssFileOrArrayOrDef, markTemp )
|
|
{
|
|
if ( !cssFileOrArrayOrDef )
|
|
return '' ;
|
|
|
|
if ( typeof( cssFileOrArrayOrDef ) == 'string' )
|
|
{
|
|
// Test if the passed argument is an URL.
|
|
if ( /[\\\/\.][^{}]*$/.test( cssFileOrArrayOrDef ) )
|
|
{
|
|
// The string may have several URLs separated by comma.
|
|
return this.GetStyleHtml( cssFileOrArrayOrDef.split(','), markTemp ) ;
|
|
}
|
|
else
|
|
return getStyle( this._GetUrlFixedCss( cssFileOrArrayOrDef ), markTemp ) ;
|
|
}
|
|
else
|
|
{
|
|
var html = '' ;
|
|
|
|
for ( var i = 0 ; i < cssFileOrArrayOrDef.length ; i++ )
|
|
html += getLink( cssFileOrArrayOrDef[i], markTemp ) ;
|
|
|
|
return html ;
|
|
}
|
|
}
|
|
})() ;
|
|
|
|
FCKTools.GetElementDocument = function ( element )
|
|
{
|
|
return element.ownerDocument || element.document ;
|
|
}
|
|
|
|
// Get the window object where the element is placed in.
|
|
FCKTools.GetElementWindow = function( element )
|
|
{
|
|
return this.GetDocumentWindow( this.GetElementDocument( element ) ) ;
|
|
}
|
|
|
|
FCKTools.GetDocumentWindow = function( document )
|
|
{
|
|
// With Safari, there is not way to retrieve the window from the document, so we must fix it.
|
|
if ( FCKBrowserInfo.IsSafari && !document.parentWindow )
|
|
this.FixDocumentParentWindow( window.top ) ;
|
|
|
|
return document.parentWindow || document.defaultView ;
|
|
}
|
|
|
|
/*
|
|
This is a Safari specific function that fix the reference to the parent
|
|
window from the document object.
|
|
*/
|
|
FCKTools.FixDocumentParentWindow = function( targetWindow )
|
|
{
|
|
if ( targetWindow.document )
|
|
targetWindow.document.parentWindow = targetWindow ;
|
|
|
|
for ( var i = 0 ; i < targetWindow.frames.length ; i++ )
|
|
FCKTools.FixDocumentParentWindow( targetWindow.frames[i] ) ;
|
|
}
|
|
|
|
FCKTools.HTMLEncode = function( text )
|
|
{
|
|
if ( !text )
|
|
return '' ;
|
|
|
|
text = text.replace( /&/g, '&' ) ;
|
|
text = text.replace( /</g, '<' ) ;
|
|
text = text.replace( />/g, '>' ) ;
|
|
|
|
return text ;
|
|
}
|
|
|
|
FCKTools.HTMLDecode = function( text )
|
|
{
|
|
if ( !text )
|
|
return '' ;
|
|
|
|
text = text.replace( />/g, '>' ) ;
|
|
text = text.replace( /</g, '<' ) ;
|
|
text = text.replace( /&/g, '&' ) ;
|
|
|
|
return text ;
|
|
}
|
|
|
|
FCKTools._ProcessLineBreaksForPMode = function( oEditor, text, liState, node, strArray )
|
|
{
|
|
var closeState = 0 ;
|
|
var blockStartTag = "<p>" ;
|
|
var blockEndTag = "</p>" ;
|
|
var lineBreakTag = "<br />" ;
|
|
if ( liState )
|
|
{
|
|
blockStartTag = "<li>" ;
|
|
blockEndTag = "</li>" ;
|
|
closeState = 1 ;
|
|
}
|
|
|
|
// Are we currently inside a <p> tag now?
|
|
// If yes, close it at the next double line break.
|
|
while ( node && node != oEditor.FCK.EditorDocument.body )
|
|
{
|
|
if ( node.tagName.toLowerCase() == 'p' )
|
|
{
|
|
closeState = 1 ;
|
|
break;
|
|
}
|
|
node = node.parentNode ;
|
|
}
|
|
|
|
for ( var i = 0 ; i < text.length ; i++ )
|
|
{
|
|
var c = text.charAt( i ) ;
|
|
if ( c == '\r' )
|
|
continue ;
|
|
|
|
if ( c != '\n' )
|
|
{
|
|
strArray.push( c ) ;
|
|
continue ;
|
|
}
|
|
|
|
// Now we have encountered a line break.
|
|
// Check if the next character is also a line break.
|
|
var n = text.charAt( i + 1 ) ;
|
|
if ( n == '\r' )
|
|
{
|
|
i++ ;
|
|
n = text.charAt( i + 1 ) ;
|
|
}
|
|
if ( n == '\n' )
|
|
{
|
|
i++ ; // ignore next character - we have already processed it.
|
|
if ( closeState )
|
|
strArray.push( blockEndTag ) ;
|
|
strArray.push( blockStartTag ) ;
|
|
closeState = 1 ;
|
|
}
|
|
else
|
|
strArray.push( lineBreakTag ) ;
|
|
}
|
|
}
|
|
|
|
FCKTools._ProcessLineBreaksForDivMode = function( oEditor, text, liState, node, strArray )
|
|
{
|
|
var closeState = 0 ;
|
|
var blockStartTag = "<div>" ;
|
|
var blockEndTag = "</div>" ;
|
|
if ( liState )
|
|
{
|
|
blockStartTag = "<li>" ;
|
|
blockEndTag = "</li>" ;
|
|
closeState = 1 ;
|
|
}
|
|
|
|
// Are we currently inside a <div> tag now?
|
|
// If yes, close it at the next double line break.
|
|
while ( node && node != oEditor.FCK.EditorDocument.body )
|
|
{
|
|
if ( node.tagName.toLowerCase() == 'div' )
|
|
{
|
|
closeState = 1 ;
|
|
break ;
|
|
}
|
|
node = node.parentNode ;
|
|
}
|
|
|
|
for ( var i = 0 ; i < text.length ; i++ )
|
|
{
|
|
var c = text.charAt( i ) ;
|
|
if ( c == '\r' )
|
|
continue ;
|
|
|
|
if ( c != '\n' )
|
|
{
|
|
strArray.push( c ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( closeState )
|
|
{
|
|
if ( strArray[ strArray.length - 1 ] == blockStartTag )
|
|
{
|
|
// A div tag must have some contents inside for it to be visible.
|
|
strArray.push( " " ) ;
|
|
}
|
|
strArray.push( blockEndTag ) ;
|
|
}
|
|
strArray.push( blockStartTag ) ;
|
|
closeState = 1 ;
|
|
}
|
|
if ( closeState )
|
|
strArray.push( blockEndTag ) ;
|
|
}
|
|
|
|
FCKTools._ProcessLineBreaksForBrMode = function( oEditor, text, liState, node, strArray )
|
|
{
|
|
var closeState = 0 ;
|
|
var blockStartTag = "<br />" ;
|
|
var blockEndTag = "" ;
|
|
if ( liState )
|
|
{
|
|
blockStartTag = "<li>" ;
|
|
blockEndTag = "</li>" ;
|
|
closeState = 1 ;
|
|
}
|
|
|
|
for ( var i = 0 ; i < text.length ; i++ )
|
|
{
|
|
var c = text.charAt( i ) ;
|
|
if ( c == '\r' )
|
|
continue ;
|
|
|
|
if ( c != '\n' )
|
|
{
|
|
strArray.push( c ) ;
|
|
continue ;
|
|
}
|
|
|
|
if ( closeState && blockEndTag.length )
|
|
strArray.push ( blockEndTag ) ;
|
|
strArray.push( blockStartTag ) ;
|
|
closeState = 1 ;
|
|
}
|
|
}
|
|
|
|
FCKTools.ProcessLineBreaks = function( oEditor, oConfig, text )
|
|
{
|
|
var enterMode = oConfig.EnterMode.toLowerCase() ;
|
|
var strArray = [] ;
|
|
|
|
// Is the caret or selection inside an <li> tag now?
|
|
var liState = 0 ;
|
|
var range = new oEditor.FCKDomRange( oEditor.FCK.EditorWindow ) ;
|
|
range.MoveToSelection() ;
|
|
var node = range._Range.startContainer ;
|
|
while ( node && node.nodeType != 1 )
|
|
node = node.parentNode ;
|
|
if ( node && node.tagName.toLowerCase() == 'li' )
|
|
liState = 1 ;
|
|
|
|
if ( enterMode == 'p' )
|
|
this._ProcessLineBreaksForPMode( oEditor, text, liState, node, strArray ) ;
|
|
else if ( enterMode == 'div' )
|
|
this._ProcessLineBreaksForDivMode( oEditor, text, liState, node, strArray ) ;
|
|
else if ( enterMode == 'br' )
|
|
this._ProcessLineBreaksForBrMode( oEditor, text, liState, node, strArray ) ;
|
|
return strArray.join( "" ) ;
|
|
}
|
|
|
|
/**
|
|
* Adds an option to a SELECT element.
|
|
*/
|
|
FCKTools.AddSelectOption = function( selectElement, optionText, optionValue )
|
|
{
|
|
var oOption = FCKTools.GetElementDocument( selectElement ).createElement( "OPTION" ) ;
|
|
|
|
oOption.text = optionText ;
|
|
oOption.value = optionValue ;
|
|
|
|
selectElement.options.add(oOption) ;
|
|
|
|
return oOption ;
|
|
}
|
|
|
|
FCKTools.RunFunction = function( func, thisObject, paramsArray, timerWindow )
|
|
{
|
|
if ( func )
|
|
this.SetTimeout( func, 0, thisObject, paramsArray, timerWindow ) ;
|
|
}
|
|
|
|
FCKTools.SetTimeout = function( func, milliseconds, thisObject, paramsArray, timerWindow )
|
|
{
|
|
return ( timerWindow || window ).setTimeout(
|
|
function()
|
|
{
|
|
if ( paramsArray )
|
|
func.apply( thisObject, [].concat( paramsArray ) ) ;
|
|
else
|
|
func.apply( thisObject ) ;
|
|
},
|
|
milliseconds ) ;
|
|
}
|
|
|
|
FCKTools.SetInterval = function( func, milliseconds, thisObject, paramsArray, timerWindow )
|
|
{
|
|
return ( timerWindow || window ).setInterval(
|
|
function()
|
|
{
|
|
func.apply( thisObject, paramsArray || [] ) ;
|
|
},
|
|
milliseconds ) ;
|
|
}
|
|
|
|
FCKTools.ConvertStyleSizeToHtml = function( size )
|
|
{
|
|
return size.EndsWith( '%' ) ? size : parseInt( size, 10 ) ;
|
|
}
|
|
|
|
FCKTools.ConvertHtmlSizeToStyle = function( size )
|
|
{
|
|
return size.EndsWith( '%' ) ? size : ( size + 'px' ) ;
|
|
}
|
|
|
|
// START iCM MODIFICATIONS
|
|
// Amended to accept a list of one or more ascensor tag names
|
|
// Amended to check the element itself before working back up through the parent hierarchy
|
|
FCKTools.GetElementAscensor = function( element, ascensorTagNames )
|
|
{
|
|
// var e = element.parentNode ;
|
|
var e = element ;
|
|
var lstTags = "," + ascensorTagNames.toUpperCase() + "," ;
|
|
|
|
while ( e )
|
|
{
|
|
if ( lstTags.indexOf( "," + e.nodeName.toUpperCase() + "," ) != -1 )
|
|
return e ;
|
|
|
|
e = e.parentNode ;
|
|
}
|
|
return null ;
|
|
}
|
|
// END iCM MODIFICATIONS
|
|
|
|
FCKTools.CreateEventListener = function( func, params )
|
|
{
|
|
var f = function()
|
|
{
|
|
var aAllParams = [] ;
|
|
|
|
for ( var i = 0 ; i < arguments.length ; i++ )
|
|
aAllParams.push( arguments[i] ) ;
|
|
|
|
func.apply( this, aAllParams.concat( params ) ) ;
|
|
}
|
|
|
|
return f ;
|
|
}
|
|
|
|
FCKTools.IsStrictMode = function( document )
|
|
{
|
|
// There is no compatMode in Safari, but it seams that it always behave as
|
|
// CSS1Compat, so let's assume it as the default for that browser.
|
|
return ( 'CSS1Compat' == ( document.compatMode || ( FCKBrowserInfo.IsSafari ? 'CSS1Compat' : null ) ) ) ;
|
|
}
|
|
|
|
// Transforms a "arguments" object to an array.
|
|
FCKTools.ArgumentsToArray = function( args, startIndex, maxLength )
|
|
{
|
|
startIndex = startIndex || 0 ;
|
|
maxLength = maxLength || args.length ;
|
|
|
|
var argsArray = new Array() ;
|
|
|
|
for ( var i = startIndex ; i < startIndex + maxLength && i < args.length ; i++ )
|
|
argsArray.push( args[i] ) ;
|
|
|
|
return argsArray ;
|
|
}
|
|
|
|
FCKTools.CloneObject = function( sourceObject )
|
|
{
|
|
var fCloneCreator = function() {} ;
|
|
fCloneCreator.prototype = sourceObject ;
|
|
return new fCloneCreator ;
|
|
}
|
|
|
|
// Appends a bogus <br> at the end of the element, if not yet available.
|
|
FCKTools.AppendBogusBr = function( element )
|
|
{
|
|
if ( !element )
|
|
return ;
|
|
|
|
var eLastChild = this.GetLastItem( element.getElementsByTagName('br') ) ;
|
|
|
|
if ( !eLastChild || ( eLastChild.getAttribute( 'type', 2 ) != '_moz' && eLastChild.getAttribute( '_moz_dirty' ) == null ) )
|
|
{
|
|
var doc = this.GetElementDocument( element ) ;
|
|
|
|
if ( FCKBrowserInfo.IsOpera )
|
|
element.appendChild( doc.createTextNode('') ) ;
|
|
else
|
|
element.appendChild( this.CreateBogusBR( doc ) ) ;
|
|
}
|
|
}
|
|
|
|
FCKTools.GetLastItem = function( list )
|
|
{
|
|
if ( list.length > 0 )
|
|
return list[ list.length - 1 ] ;
|
|
|
|
return null ;
|
|
}
|
|
|
|
FCKTools.GetDocumentPosition = function( w, node )
|
|
{
|
|
var x = 0 ;
|
|
var y = 0 ;
|
|
var curNode = node ;
|
|
var prevNode = null ;
|
|
var curWindow = FCKTools.GetElementWindow( curNode ) ;
|
|
while ( curNode && !( curWindow == w && ( curNode == w.document.body || curNode == w.document.documentElement ) ) )
|
|
{
|
|
x += curNode.offsetLeft - curNode.scrollLeft ;
|
|
y += curNode.offsetTop - curNode.scrollTop ;
|
|
|
|
if ( ! FCKBrowserInfo.IsOpera )
|
|
{
|
|
var scrollNode = prevNode ;
|
|
while ( scrollNode && scrollNode != curNode )
|
|
{
|
|
x -= scrollNode.scrollLeft ;
|
|
y -= scrollNode.scrollTop ;
|
|
scrollNode = scrollNode.parentNode ;
|
|
}
|
|
}
|
|
|
|
prevNode = curNode ;
|
|
if ( curNode.offsetParent )
|
|
curNode = curNode.offsetParent ;
|
|
else
|
|
{
|
|
if ( curWindow != w )
|
|
{
|
|
curNode = curWindow.frameElement ;
|
|
prevNode = null ;
|
|
if ( curNode )
|
|
curWindow = curNode.contentWindow.parent ;
|
|
}
|
|
else
|
|
curNode = null ;
|
|
}
|
|
}
|
|
|
|
// document.body is a special case when it comes to offsetTop and offsetLeft values.
|
|
// 1. It matters if document.body itself is a positioned element;
|
|
// 2. It matters is when we're in IE and the element has no positioned ancestor.
|
|
// Otherwise the values should be ignored.
|
|
if ( FCKDomTools.GetCurrentElementStyle( w.document.body, 'position') != 'static'
|
|
|| ( FCKBrowserInfo.IsIE && FCKDomTools.GetPositionedAncestor( node ) == null ) )
|
|
{
|
|
x += w.document.body.offsetLeft ;
|
|
y += w.document.body.offsetTop ;
|
|
}
|
|
|
|
return { "x" : x, "y" : y } ;
|
|
}
|
|
|
|
FCKTools.GetWindowPosition = function( w, node )
|
|
{
|
|
var pos = this.GetDocumentPosition( w, node ) ;
|
|
var scroll = FCKTools.GetScrollPosition( w ) ;
|
|
pos.x -= scroll.X ;
|
|
pos.y -= scroll.Y ;
|
|
return pos ;
|
|
}
|
|
|
|
FCKTools.ProtectFormStyles = function( formNode )
|
|
{
|
|
if ( !formNode || formNode.nodeType != 1 || formNode.tagName.toLowerCase() != 'form' )
|
|
return [] ;
|
|
var hijackRecord = [] ;
|
|
var hijackNames = [ 'style', 'className' ] ;
|
|
for ( var i = 0 ; i < hijackNames.length ; i++ )
|
|
{
|
|
var name = hijackNames[i] ;
|
|
if ( formNode.elements.namedItem( name ) )
|
|
{
|
|
var hijackNode = formNode.elements.namedItem( name ) ;
|
|
hijackRecord.push( [ hijackNode, hijackNode.nextSibling ] ) ;
|
|
formNode.removeChild( hijackNode ) ;
|
|
}
|
|
}
|
|
return hijackRecord ;
|
|
}
|
|
|
|
FCKTools.RestoreFormStyles = function( formNode, hijackRecord )
|
|
{
|
|
if ( !formNode || formNode.nodeType != 1 || formNode.tagName.toLowerCase() != 'form' )
|
|
return ;
|
|
if ( hijackRecord.length > 0 )
|
|
{
|
|
for ( var i = hijackRecord.length - 1 ; i >= 0 ; i-- )
|
|
{
|
|
var node = hijackRecord[i][0] ;
|
|
var sibling = hijackRecord[i][1] ;
|
|
if ( sibling )
|
|
formNode.insertBefore( node, sibling ) ;
|
|
else
|
|
formNode.appendChild( node ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Perform a one-step DFS walk.
|
|
FCKTools.GetNextNode = function( node, limitNode )
|
|
{
|
|
if ( node.firstChild )
|
|
return node.firstChild ;
|
|
else if ( node.nextSibling )
|
|
return node.nextSibling ;
|
|
else
|
|
{
|
|
var ancestor = node.parentNode ;
|
|
while ( ancestor )
|
|
{
|
|
if ( ancestor == limitNode )
|
|
return null ;
|
|
if ( ancestor.nextSibling )
|
|
return ancestor.nextSibling ;
|
|
else
|
|
ancestor = ancestor.parentNode ;
|
|
}
|
|
}
|
|
return null ;
|
|
}
|
|
|
|
FCKTools.GetNextTextNode = function( textnode, limitNode, checkStop )
|
|
{
|
|
node = this.GetNextNode( textnode, limitNode ) ;
|
|
if ( checkStop && node && checkStop( node ) )
|
|
return null ;
|
|
while ( node && node.nodeType != 3 )
|
|
{
|
|
node = this.GetNextNode( node, limitNode ) ;
|
|
if ( checkStop && node && checkStop( node ) )
|
|
return null ;
|
|
}
|
|
return node ;
|
|
}
|
|
|
|
/**
|
|
* Merge all objects passed by argument into a single object.
|
|
*/
|
|
FCKTools.Merge = function()
|
|
{
|
|
var args = arguments ;
|
|
var o = args[0] ;
|
|
|
|
for ( var i = 1 ; i < args.length ; i++ )
|
|
{
|
|
var arg = args[i] ;
|
|
for ( var p in arg )
|
|
o[p] = arg[p] ;
|
|
}
|
|
|
|
return o ;
|
|
}
|
|
|
|
/**
|
|
* Check if the passed argument is a real Array. It may not working when
|
|
* calling it cross windows.
|
|
*/
|
|
FCKTools.IsArray = function( it )
|
|
{
|
|
return ( it instanceof Array ) ;
|
|
}
|
|
|
|
/**
|
|
* Appends a "length" property to an object, containing the number of
|
|
* properties available on it, excluded the append property itself.
|
|
*/
|
|
FCKTools.AppendLengthProperty = function( targetObject, propertyName )
|
|
{
|
|
var counter = 0 ;
|
|
|
|
for ( var n in targetObject )
|
|
counter++ ;
|
|
|
|
return targetObject[ propertyName || 'length' ] = counter ;
|
|
}
|
|
|
|
/**
|
|
* Gets the browser parsed version of a css text (style attribute value). On
|
|
* some cases, the browser makes changes to the css text, returning a different
|
|
* value. For example, hexadecimal colors get transformed to rgb().
|
|
*/
|
|
FCKTools.NormalizeCssText = function( unparsedCssText )
|
|
{
|
|
// Injects the style in a temporary span object, so the browser parses it,
|
|
// retrieving its final format.
|
|
var tempSpan = document.createElement( 'span' ) ;
|
|
tempSpan.style.cssText = unparsedCssText ;
|
|
return tempSpan.style.cssText ;
|
|
}
|
|
|
|
/**
|
|
* Binding the "this" reference to an object for a function.
|
|
*/
|
|
FCKTools.Bind = function( subject, func )
|
|
{
|
|
return function(){ return func.apply( subject, arguments ) ; } ;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the correct "empty iframe" URL for the current browser, which
|
|
* causes the minimum fuzz (e.g. security warnings in HTTPS, DNS error in
|
|
* IE5.5, etc.) for that browser, making the iframe ready to DOM use whithout
|
|
* having to loading an external file.
|
|
*/
|
|
FCKTools.GetVoidUrl = function()
|
|
{
|
|
if ( FCK_IS_CUSTOM_DOMAIN )
|
|
return "javascript: void( function(){" +
|
|
"document.open();" +
|
|
"document.write('<html><head><title></title></head><body></body></html>');" +
|
|
"document.domain = '" + FCK_RUNTIME_DOMAIN + "';" +
|
|
"document.close();" +
|
|
"}() ) ;";
|
|
|
|
if ( FCKBrowserInfo.IsIE )
|
|
{
|
|
if ( FCKBrowserInfo.IsIE7 || !FCKBrowserInfo.IsIE6 )
|
|
return "" ; // IE7+ / IE5.5
|
|
else
|
|
return "javascript: '';" ; // IE6+
|
|
}
|
|
|
|
return "javascript: void(0);" ; // All other browsers.
|
|
}
|
|
|
|
FCKTools.ResetStyles = function( element )
|
|
{
|
|
element.style.cssText = 'margin:0;' +
|
|
'padding:0;' +
|
|
'border:0;' +
|
|
'background-color:transparent;' +
|
|
'background-image:none;' ;
|
|
}
|