fckxhtml.js
上传用户:wlfwy2004
上传日期:2016-12-12
资源大小:33978k
文件大小:9k
源码类别:

Jsp/Servlet

开发平台:

Java

  1. /*
  2.  * FCKeditor - The text editor for internet
  3.  * Copyright (C) 2003-2005 Frederico Caldeira Knabben
  4.  * 
  5.  * Licensed under the terms of the GNU Lesser General Public License:
  6.  *  http://www.opensource.org/licenses/lgpl-license.php
  7.  * 
  8.  * For further information visit:
  9.  *  http://www.fckeditor.net/
  10.  * 
  11.  * File Name: fckxhtml.js
  12.  *  Defines the FCKXHtml object, responsible for the XHTML operations.
  13.  * 
  14.  * File Authors:
  15.  *  Frederico Caldeira Knabben (fredck@fckeditor.net)
  16.  */
  17. var FCKXHtml = new Object() ;
  18. FCKXHtml.CurrentJobNum = 0 ;
  19. FCKXHtml.GetXHTML = function( node, includeNode, format )
  20. {
  21. // Special blocks are blocks of content that remain untouched during the
  22. // process. It is used for SCRIPTs and STYLEs.
  23. FCKXHtml.SpecialBlocks = new Array() ;
  24. // Create the XML DOMDocument object.
  25. this.XML = FCKTools.CreateXmlObject( 'DOMDocument' ) ;
  26. // Add a root element that holds all child nodes.
  27. this.MainNode = this.XML.appendChild( this.XML.createElement( 'xhtml' ) ) ;
  28. FCKXHtml.CurrentJobNum++ ;
  29. if ( includeNode )
  30. this._AppendNode( this.MainNode, node ) ;
  31. else
  32. this._AppendChildNodes( this.MainNode, node, false ) ;
  33. // Get the resulting XHTML as a string.
  34. var sXHTML = this._GetMainXmlString() ;
  35. // Strip the "XHTML" root node.
  36. sXHTML = sXHTML.substr( 7, sXHTML.length - 15 ).trim() ;
  37. // Remove the trailing <br> added by Gecko.
  38. if ( FCKBrowserInfo.IsGecko )
  39. sXHTML = sXHTML.replace( /<br/>$/, '' ) ;
  40. // Add a space in the tags with no closing tags, like <br/> -> <br />
  41. sXHTML = sXHTML.replace( FCKRegexLib.SpaceNoClose, ' />');
  42. if ( FCKConfig.ForceSimpleAmpersand )
  43. sXHTML = sXHTML.replace( FCKRegexLib.ForceSimpleAmpersand, '&' ) ;
  44. if ( format )
  45. sXHTML = FCKCodeFormatter.Format( sXHTML ) ;
  46. // Now we put back the SpecialBlocks contents.
  47. for ( var i = 0 ; i < FCKXHtml.SpecialBlocks.length ; i++ )
  48. {
  49. var oRegex = new RegExp( '___FCKsi___' + i ) ;
  50. sXHTML = sXHTML.replace( oRegex, FCKXHtml.SpecialBlocks[i] ) ;
  51. }
  52. this.XML = null ;
  53. return sXHTML
  54. }
  55. FCKXHtml._AppendAttribute = function( xmlNode, attributeName, attributeValue )
  56. {
  57. try
  58. {
  59. // Create the attribute.
  60. var oXmlAtt = this.XML.createAttribute( attributeName ) ;
  61. oXmlAtt.value = attributeValue ? attributeValue : '' ;
  62. // Set the attribute in the node.
  63. xmlNode.attributes.setNamedItem( oXmlAtt ) ;
  64. }
  65. catch (e)
  66. {}
  67. }
  68. FCKXHtml._AppendChildNodes = function( xmlNode, htmlNode, isBlockElement )
  69. {
  70. var iCount = 0 ;
  71. if ( htmlNode.hasChildNodes() )
  72. {
  73. // Get all children nodes.
  74. var oChildren = htmlNode.childNodes ;
  75. for ( var i = 0 ; i < oChildren.length ; i++ )
  76. {
  77. if ( this._AppendNode( xmlNode, oChildren[i] ) )
  78. iCount++ ;
  79. }
  80. }
  81. if ( iCount == 0 )
  82. {
  83. if ( isBlockElement && FCKConfig.FillEmptyBlocks )
  84. {
  85. this._AppendEntity( xmlNode, 'nbsp' ) ;
  86. return ;
  87. }
  88. // We can't use short representation of empty elements that are not marked
  89. // as empty in th XHTML DTD.
  90. if ( !FCKRegexLib.EmptyElements.test( htmlNode.nodeName ) )
  91. xmlNode.appendChild( this.XML.createTextNode('') ) ;
  92. }
  93. }
  94. FCKXHtml._AppendNode = function( xmlNode, htmlNode )
  95. {
  96. switch ( htmlNode.nodeType )
  97. {
  98. // Element Node.
  99. case 1 :
  100. if ( htmlNode.getAttribute('_fckfakelement') )
  101. return FCKXHtml._AppendNode( xmlNode, FCK.GetRealElement( htmlNode ) ) ;
  102. // Mozilla insert custom nodes in the DOM.
  103. if ( FCKBrowserInfo.IsGecko && htmlNode.hasAttribute('_moz_editor_bogus_node') )
  104. return false ;
  105. if ( htmlNode.getAttribute('_fckdelete') )
  106. return false ;
  107. // Create the Element.
  108. var sNodeName = htmlNode.nodeName ;
  109. // Check if the node name is valid, otherwise ignore this tag.
  110. if ( !FCKRegexLib.ElementName.test( sNodeName ) )
  111. return false ;
  112. sNodeName = sNodeName.toLowerCase() ;
  113. if ( FCKBrowserInfo.IsGecko && sNodeName == 'br' && htmlNode.hasAttribute('type') && htmlNode.getAttribute( 'type', 2 ) == '_moz' )
  114. return false ;
  115. // The already processed nodes must be marked to avoid then to be duplicated (bad formatted HTML).
  116. // So here, the "mark" is checked... if the element is Ok, then mark it.
  117. if ( htmlNode._fckxhtmljob == FCKXHtml.CurrentJobNum )
  118. return false ;
  119. else
  120. htmlNode._fckxhtmljob = FCKXHtml.CurrentJobNum ;
  121. // If the nodeName starts with a slash, it is a orphan closing tag.
  122. // On some strange cases, the nodeName is empty, even if the node exists.
  123. // if ( sNodeName.length == 0 || sNodeName.substr(0,1) == '/' )
  124. // break ;
  125. var oNode = this.XML.createElement( sNodeName ) ;
  126. // Add all attributes.
  127. FCKXHtml._AppendAttributes( xmlNode, htmlNode, oNode, sNodeName ) ;
  128. // Tag specific processing.
  129. var oTagProcessor = FCKXHtml.TagProcessors[ sNodeName ] ;
  130. if ( oTagProcessor )
  131. {
  132. oNode = oTagProcessor( oNode, htmlNode ) ;
  133. if ( !oNode ) break ;
  134. }
  135. else
  136. this._AppendChildNodes( oNode, htmlNode, FCKRegexLib.BlockElements.test( sNodeName ) ) ;
  137. xmlNode.appendChild( oNode ) ;
  138. break ;
  139. // Text Node.
  140. case 3 :
  141. this._AppendTextNode( xmlNode, htmlNode.nodeValue.replaceNewLineChars(' ') ) ;
  142. break ;
  143. // Comment
  144. case 8 :
  145. xmlNode.appendChild( this.XML.createComment( htmlNode.nodeValue ) ) ;
  146. break ;
  147. // Unknown Node type.
  148. default :
  149. xmlNode.appendChild( this.XML.createComment( "Element not supported - Type: " + htmlNode.nodeType + " Name: " + htmlNode.nodeName ) ) ;
  150. break ;
  151. }
  152. return true ;
  153. }
  154. // Append an item to the SpecialBlocks array and returns the tag to be used.
  155. FCKXHtml._AppendSpecialItem = function( item )
  156. {
  157. return '___FCKsi___' + FCKXHtml.SpecialBlocks.addItem( item ) ;
  158. }
  159. if ( FCKConfig.ProcessHTMLEntities )
  160. {
  161. FCKXHtml._AppendTextNode = function( targetNode, textValue )
  162. {
  163. // We can't just replace the special chars with entities and create a
  164. // text node with it. We must split the text isolating the special chars
  165. // and add each piece a time.
  166. var asPieces = textValue.match( FCKXHtmlEntities.EntitiesRegex ) ;
  167. if ( asPieces )
  168. {
  169. for ( var i = 0 ; i < asPieces.length ; i++ )
  170. {
  171. if ( asPieces[i].length == 1 )
  172. {
  173. var sEntity = FCKXHtmlEntities.Entities[ asPieces[i] ] ;
  174. if ( sEntity != null )
  175. {
  176. this._AppendEntity( targetNode, sEntity ) ;
  177. continue ;
  178. }
  179. }
  180. targetNode.appendChild( this.XML.createTextNode( asPieces[i] ) ) ;
  181. }
  182. }
  183. }
  184. }
  185. else
  186. {
  187. FCKXHtml._AppendTextNode = function( targetNode, textValue )
  188. {
  189. targetNode.appendChild( this.XML.createTextNode( textValue ) ) ;
  190. }
  191. }
  192. // An object that hold tag specific operations.
  193. FCKXHtml.TagProcessors = new Object() ;
  194. FCKXHtml.TagProcessors['img'] = function( node )
  195. {
  196. // The "ALT" attribute is required in XHTML.
  197. if ( ! node.attributes.getNamedItem( 'alt' ) )
  198. FCKXHtml._AppendAttribute( node, 'alt', '' ) ;
  199. return node ;
  200. }
  201. FCKXHtml.TagProcessors['script'] = function( node, htmlNode )
  202. {
  203. // The "TYPE" attribute is required in XHTML.
  204. if ( ! node.attributes.getNamedItem( 'type' ) )
  205. FCKXHtml._AppendAttribute( node, 'type', 'text/javascript' ) ;
  206. node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( htmlNode.text ) ) ) ;
  207. return node ;
  208. }
  209. FCKXHtml.TagProcessors['style'] = function( node, htmlNode )
  210. {
  211. // The "_fcktemp" attribute is used to mark the <STYLE> used by the editor
  212. // to set some behaviors.
  213. if ( htmlNode.getAttribute( '_fcktemp' ) )
  214. return null ;
  215. // The "TYPE" attribute is required in XHTML.
  216. if ( ! node.attributes.getNamedItem( 'type' ) )
  217. FCKXHtml._AppendAttribute( node, 'type', 'text/css' ) ;
  218. node.appendChild( FCKXHtml.XML.createTextNode( FCKXHtml._AppendSpecialItem( htmlNode.innerHTML ) ) ) ;
  219. return node ;
  220. }
  221. FCKXHtml.TagProcessors['title'] = function( node, htmlNode )
  222. {
  223. node.appendChild( FCKXHtml.XML.createTextNode( FCK.EditorDocument.title ) ) ;
  224. return node ;
  225. }
  226. FCKXHtml.TagProcessors['base'] = function( node, htmlNode )
  227. {
  228. // The "_fcktemp" attribute is used to mark the <BASE> tag when the editor
  229. // automatically sets it using the FCKConfig.BaseHref configuration.
  230. if ( htmlNode.getAttribute( '_fcktemp' ) )
  231. return null ;
  232. // IE duplicates the BODY inside the <BASE /> tag (don't ask me why!).
  233. // This tag processor does nothing... in this way, no child nodes are added
  234. // (also because the BASE tag must be empty).
  235. return node ;
  236. }
  237. FCKXHtml.TagProcessors['link'] = function( node, htmlNode )
  238. {
  239. // The "_fcktemp" attribute is used to mark the fck_internal.css <LINK>
  240. // reference.
  241. if ( htmlNode.getAttribute( '_fcktemp' ) )
  242. return null ;
  243. return node ;
  244. }
  245. FCKXHtml.TagProcessors['table'] = function( node, htmlNode )
  246. {
  247. // There is a trick to show table borders when border=0. We add to the
  248. // table class the FCK__ShowTableBorders rule. So now we must remove it.
  249. var oClassAtt = node.attributes.getNamedItem( 'class' ) ;
  250. if ( oClassAtt && FCKRegexLib.TableBorderClass.test( oClassAtt.nodeValue ) )
  251. {
  252. var sClass = oClassAtt.nodeValue.replace( FCKRegexLib.TableBorderClass, '' ) ;
  253. if ( sClass.length == 0 )
  254. node.attributes.removeNamedItem( 'class' ) ;
  255. else
  256. FCKXHtml._AppendAttribute( node, 'class', sClass ) ;
  257. }
  258. FCKXHtml._AppendChildNodes( node, htmlNode, false ) ;
  259. return node ;
  260. }