Bugfix : prendre le innerHTML du body du document n'est pas une bonne idée, dans...
[ckeditor.git] / skins / ckeditor / _source / plugins / xml / plugin.js
1 /*
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
4 */
5
6 /**
7 * @fileOverview Defines the {@link CKEDITOR.xml} class, which represents a
8 * loaded XML document.
9 */
10
11 (function()
12 {
13 CKEDITOR.plugins.add( 'xml', {});
14
15 /**
16 * Represents a loaded XML document.
17 * @constructor
18 * @param {object|string} xmlObjectOrData A native XML (DOM document) object or
19 * a string containing the XML definition to be loaded.
20 * @example
21 * var xml = <b>new CKEDITOR.xml( '<books><book title="My Book" /></books>' )</b>;
22 */
23 CKEDITOR.xml = function( xmlObjectOrData )
24 {
25 var baseXml = null;
26
27 if ( typeof xmlObjectOrData == 'object' )
28 baseXml = xmlObjectOrData;
29 else
30 {
31 var data = ( xmlObjectOrData || '' ).replace( /&nbsp;/g, '\xA0' );
32 if ( window.DOMParser )
33 baseXml = (new DOMParser()).parseFromString( data, 'text/xml' );
34 else if ( window.ActiveXObject )
35 {
36 try { baseXml = new ActiveXObject( 'MSXML2.DOMDocument' ); }
37 catch(e)
38 {
39 try { baseXml = new ActiveXObject( 'Microsoft.XmlDom' ); } catch(e) {}
40 }
41
42 if ( baseXml )
43 {
44 baseXml.async = false;
45 baseXml.resolveExternals = false;
46 baseXml.validateOnParse = false;
47 baseXml.loadXML( data );
48 }
49 }
50 }
51
52 /**
53 * The native XML (DOM document) used by the class instance.
54 * @type object
55 * @example
56 */
57 this.baseXml = baseXml;
58 };
59
60 CKEDITOR.xml.prototype =
61 {
62 /**
63 * Get a single node from the XML document, based on a XPath query.
64 * @param {String} xpath The XPath query to execute.
65 * @param {Object} [contextNode] The XML DOM node to be used as the context
66 * for the XPath query. The document root is used by default.
67 * @returns {Object} A XML node element or null if the query has no results.
68 * @example
69 * // Create the XML instance.
70 * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' );
71 * // Get the first <item> node.
72 * var itemNode = <b>xml.selectSingleNode( 'list/item' )</b>;
73 * // Alert "item".
74 * alert( itemNode.nodeName );
75 */
76 selectSingleNode : function( xpath, contextNode )
77 {
78 var baseXml = this.baseXml;
79
80 if ( contextNode || ( contextNode = baseXml ) )
81 {
82 if ( CKEDITOR.env.ie || contextNode.selectSingleNode ) // IE
83 return contextNode.selectSingleNode( xpath );
84 else if ( baseXml.evaluate ) // Others
85 {
86 var result = baseXml.evaluate( xpath, contextNode, null, 9, null);
87 return ( result && result.singleNodeValue ) || null;
88 }
89 }
90
91 return null;
92 },
93
94 /**
95 * Gets a list node from the XML document, based on a XPath query.
96 * @param {String} xpath The XPath query to execute.
97 * @param {Object} [contextNode] The XML DOM node to be used as the context
98 * for the XPath query. The document root is used by default.
99 * @returns {ArrayLike} An array containing all matched nodes. The array will
100 * be empty if the query has no results.
101 * @example
102 * // Create the XML instance.
103 * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' );
104 * // Get the first <item> node.
105 * var itemNodes = xml.selectSingleNode( 'list/item' );
106 * // Alert "item" twice, one for each <item>.
107 * for ( var i = 0 ; i < itemNodes.length ; i++ )
108 * alert( itemNodes[i].nodeName );
109 */
110 selectNodes : function( xpath, contextNode )
111 {
112 var baseXml = this.baseXml,
113 nodes = [];
114
115 if ( contextNode || ( contextNode = baseXml ) )
116 {
117 if ( CKEDITOR.env.ie || contextNode.selectNodes ) // IE
118 return contextNode.selectNodes( xpath );
119 else if ( baseXml.evaluate ) // Others
120 {
121 var result = baseXml.evaluate( xpath, contextNode, null, 5, null);
122
123 if ( result )
124 {
125 var node;
126 while ( ( node = result.iterateNext() ) )
127 nodes.push( node );
128 }
129 }
130 }
131
132 return nodes;
133 },
134
135 /**
136 * Gets the string representation of hte inner contents of a XML node,
137 * based on a XPath query.
138 * @param {String} xpath The XPath query to execute.
139 * @param {Object} [contextNode] The XML DOM node to be used as the context
140 * for the XPath query. The document root is used by default.
141 * @returns {String} The textual representation of the inner contents of
142 * the node or null if the query has no results.
143 * @example
144 * // Create the XML instance.
145 * var xml = new CKEDITOR.xml( '<list><item id="test1" /><item id="test2" /></list>' );
146 * // Alert "<item id="test1" /><item id="test2" />".
147 * alert( xml.getInnerXml( 'list' ) );
148 */
149 getInnerXml : function( xpath, contextNode )
150 {
151 var node = this.selectSingleNode( xpath, contextNode ),
152 xml = [];
153 if ( node )
154 {
155 node = node.firstChild;
156 while ( node )
157 {
158 if ( node.xml ) // IE
159 xml.push( node.xml );
160 else if ( window.XMLSerializer ) // Others
161 xml.push( ( new XMLSerializer() ).serializeToString( node ) );
162
163 node = node.nextSibling;
164 }
165 }
166
167 return xml.length ? xml.join( '' ) : null;
168 }
169 };
170 })();