fcktools.js
上传用户:dbstep
上传日期:2022-08-06
资源大小:2803k
文件大小:19k
- /*
- * 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( /urls*(([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( /^([^|]+)|([sS]*)/ ) ;
- 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;' ;
- }