diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-01-25 17:45:33 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2016-01-25 18:00:33 +0100 |
commit | 7adcb81e4f83f98c468889aaa5a85558ba88c770 (patch) | |
tree | 0d6ede733777b29060b48df4afaa2c64bfbae276 /sources/core/dom/domobject.js | |
download | connexionswing-ckeditor-component-7adcb81e4f83f98c468889aaa5a85558ba88c770.tar.gz connexionswing-ckeditor-component-7adcb81e4f83f98c468889aaa5a85558ba88c770.tar.zst connexionswing-ckeditor-component-7adcb81e4f83f98c468889aaa5a85558ba88c770.zip |
Initial commit4.5.6
Diffstat (limited to 'sources/core/dom/domobject.js')
-rw-r--r-- | sources/core/dom/domobject.js | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/sources/core/dom/domobject.js b/sources/core/dom/domobject.js new file mode 100644 index 00000000..21a351d7 --- /dev/null +++ b/sources/core/dom/domobject.js | |||
@@ -0,0 +1,266 @@ | |||
1 | /** | ||
2 | * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. | ||
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license | ||
4 | */ | ||
5 | |||
6 | /** | ||
7 | * @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base | ||
8 | * for other classes representing DOM objects. | ||
9 | */ | ||
10 | |||
11 | /** | ||
12 | * Represents a DOM object. This class is not intended to be used directly. It | ||
13 | * serves as the base class for other classes representing specific DOM | ||
14 | * objects. | ||
15 | * | ||
16 | * @class | ||
17 | * @mixins CKEDITOR.event | ||
18 | * @constructor Creates a domObject class instance. | ||
19 | * @param {Object} nativeDomObject A native DOM object. | ||
20 | */ | ||
21 | CKEDITOR.dom.domObject = function( nativeDomObject ) { | ||
22 | if ( nativeDomObject ) { | ||
23 | /** | ||
24 | * The native DOM object represented by this class instance. | ||
25 | * | ||
26 | * var element = new CKEDITOR.dom.element( 'span' ); | ||
27 | * alert( element.$.nodeType ); // '1' | ||
28 | * | ||
29 | * @readonly | ||
30 | * @property {Object} | ||
31 | */ | ||
32 | this.$ = nativeDomObject; | ||
33 | } | ||
34 | }; | ||
35 | |||
36 | CKEDITOR.dom.domObject.prototype = ( function() { | ||
37 | // Do not define other local variables here. We want to keep the native | ||
38 | // listener closures as clean as possible. | ||
39 | |||
40 | var getNativeListener = function( domObject, eventName ) { | ||
41 | return function( domEvent ) { | ||
42 | // In FF, when reloading the page with the editor focused, it may | ||
43 | // throw an error because the CKEDITOR global is not anymore | ||
44 | // available. So, we check it here first. (#2923) | ||
45 | if ( typeof CKEDITOR != 'undefined' ) | ||
46 | domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) ); | ||
47 | }; | ||
48 | }; | ||
49 | |||
50 | return { | ||
51 | |||
52 | /** | ||
53 | * Gets the private `_` object which is bound to the native | ||
54 | * DOM object using {@link #getCustomData}. | ||
55 | * | ||
56 | * var elementA = new CKEDITOR.dom.element( nativeElement ); | ||
57 | * elementA.getPrivate().value = 1; | ||
58 | * ... | ||
59 | * var elementB = new CKEDITOR.dom.element( nativeElement ); | ||
60 | * elementB.getPrivate().value; // 1 | ||
61 | * | ||
62 | * @returns {Object} The private object. | ||
63 | */ | ||
64 | getPrivate: function() { | ||
65 | var priv; | ||
66 | |||
67 | // Get the main private object from the custom data. Create it if not defined. | ||
68 | if ( !( priv = this.getCustomData( '_' ) ) ) | ||
69 | this.setCustomData( '_', ( priv = {} ) ); | ||
70 | |||
71 | return priv; | ||
72 | }, | ||
73 | |||
74 | // Docs inherited from event. | ||
75 | on: function( eventName ) { | ||
76 | // We customize the "on" function here. The basic idea is that we'll have | ||
77 | // only one listener for a native event, which will then call all listeners | ||
78 | // set to the event. | ||
79 | |||
80 | // Get the listeners holder object. | ||
81 | var nativeListeners = this.getCustomData( '_cke_nativeListeners' ); | ||
82 | |||
83 | if ( !nativeListeners ) { | ||
84 | nativeListeners = {}; | ||
85 | this.setCustomData( '_cke_nativeListeners', nativeListeners ); | ||
86 | } | ||
87 | |||
88 | // Check if we have a listener for that event. | ||
89 | if ( !nativeListeners[ eventName ] ) { | ||
90 | var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName ); | ||
91 | |||
92 | if ( this.$.addEventListener ) | ||
93 | this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture ); | ||
94 | else if ( this.$.attachEvent ) | ||
95 | this.$.attachEvent( 'on' + eventName, listener ); | ||
96 | } | ||
97 | |||
98 | // Call the original implementation. | ||
99 | return CKEDITOR.event.prototype.on.apply( this, arguments ); | ||
100 | }, | ||
101 | |||
102 | // Docs inherited from event. | ||
103 | removeListener: function( eventName ) { | ||
104 | // Call the original implementation. | ||
105 | CKEDITOR.event.prototype.removeListener.apply( this, arguments ); | ||
106 | |||
107 | // If we don't have listeners for this event, clean the DOM up. | ||
108 | if ( !this.hasListeners( eventName ) ) { | ||
109 | var nativeListeners = this.getCustomData( '_cke_nativeListeners' ); | ||
110 | var listener = nativeListeners && nativeListeners[ eventName ]; | ||
111 | if ( listener ) { | ||
112 | if ( this.$.removeEventListener ) | ||
113 | this.$.removeEventListener( eventName, listener, false ); | ||
114 | else if ( this.$.detachEvent ) | ||
115 | this.$.detachEvent( 'on' + eventName, listener ); | ||
116 | |||
117 | delete nativeListeners[ eventName ]; | ||
118 | } | ||
119 | } | ||
120 | }, | ||
121 | |||
122 | /** | ||
123 | * Removes any listener set on this object. | ||
124 | * | ||
125 | * To avoid memory leaks we must assure that there are no | ||
126 | * references left after the object is no longer needed. | ||
127 | */ | ||
128 | removeAllListeners: function() { | ||
129 | var nativeListeners = this.getCustomData( '_cke_nativeListeners' ); | ||
130 | for ( var eventName in nativeListeners ) { | ||
131 | var listener = nativeListeners[ eventName ]; | ||
132 | if ( this.$.detachEvent ) | ||
133 | this.$.detachEvent( 'on' + eventName, listener ); | ||
134 | else if ( this.$.removeEventListener ) | ||
135 | this.$.removeEventListener( eventName, listener, false ); | ||
136 | |||
137 | delete nativeListeners[ eventName ]; | ||
138 | } | ||
139 | |||
140 | // Remove events from events object so fire() method will not call | ||
141 | // listeners (#11400). | ||
142 | CKEDITOR.event.prototype.removeAllListeners.call( this ); | ||
143 | } | ||
144 | }; | ||
145 | } )(); | ||
146 | |||
147 | ( function( domObjectProto ) { | ||
148 | var customData = {}; | ||
149 | |||
150 | CKEDITOR.on( 'reset', function() { | ||
151 | customData = {}; | ||
152 | } ); | ||
153 | |||
154 | /** | ||
155 | * Determines whether the specified object is equal to the current object. | ||
156 | * | ||
157 | * var doc = new CKEDITOR.dom.document( document ); | ||
158 | * alert( doc.equals( CKEDITOR.document ) ); // true | ||
159 | * alert( doc == CKEDITOR.document ); // false | ||
160 | * | ||
161 | * @param {Object} object The object to compare with the current object. | ||
162 | * @returns {Boolean} `true` if the object is equal. | ||
163 | */ | ||
164 | domObjectProto.equals = function( object ) { | ||
165 | // Try/Catch to avoid IE permission error when object is from different document. | ||
166 | try { | ||
167 | return ( object && object.$ === this.$ ); | ||
168 | } catch ( er ) { | ||
169 | return false; | ||
170 | } | ||
171 | }; | ||
172 | |||
173 | /** | ||
174 | * Sets a data slot value for this object. These values are shared by all | ||
175 | * instances pointing to that same DOM object. | ||
176 | * | ||
177 | * **Note:** The created data slot is only guaranteed to be available on this unique DOM node, | ||
178 | * thus any wish to continue access to it from other element clones (either created by | ||
179 | * clone node or from `innerHtml`) will fail. For such usage please use | ||
180 | * {@link CKEDITOR.dom.element#setAttribute} instead. | ||
181 | * | ||
182 | * **Note**: This method does not work on text nodes prior to Internet Explorer 9. | ||
183 | * | ||
184 | * var element = new CKEDITOR.dom.element( 'span' ); | ||
185 | * element.setCustomData( 'hasCustomData', true ); | ||
186 | * | ||
187 | * @param {String} key A key used to identify the data slot. | ||
188 | * @param {Object} value The value to set to the data slot. | ||
189 | * @returns {CKEDITOR.dom.domObject} This DOM object instance. | ||
190 | * @chainable | ||
191 | */ | ||
192 | domObjectProto.setCustomData = function( key, value ) { | ||
193 | var expandoNumber = this.getUniqueId(), | ||
194 | dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} ); | ||
195 | |||
196 | dataSlot[ key ] = value; | ||
197 | |||
198 | return this; | ||
199 | }; | ||
200 | |||
201 | /** | ||
202 | * Gets the value set to a data slot in this object. | ||
203 | * | ||
204 | * var element = new CKEDITOR.dom.element( 'span' ); | ||
205 | * alert( element.getCustomData( 'hasCustomData' ) ); // e.g. 'true' | ||
206 | * alert( element.getCustomData( 'nonExistingKey' ) ); // null | ||
207 | * | ||
208 | * @param {String} key The key used to identify the data slot. | ||
209 | * @returns {Object} This value set to the data slot. | ||
210 | */ | ||
211 | domObjectProto.getCustomData = function( key ) { | ||
212 | var expandoNumber = this.$[ 'data-cke-expando' ], | ||
213 | dataSlot = expandoNumber && customData[ expandoNumber ]; | ||
214 | |||
215 | return ( dataSlot && key in dataSlot ) ? dataSlot[ key ] : null; | ||
216 | }; | ||
217 | |||
218 | /** | ||
219 | * Removes the value in the data slot under the given `key`. | ||
220 | * | ||
221 | * @param {String} key | ||
222 | * @returns {Object} Removed value or `null` if not found. | ||
223 | */ | ||
224 | domObjectProto.removeCustomData = function( key ) { | ||
225 | var expandoNumber = this.$[ 'data-cke-expando' ], | ||
226 | dataSlot = expandoNumber && customData[ expandoNumber ], | ||
227 | retval, hadKey; | ||
228 | |||
229 | if ( dataSlot ) { | ||
230 | retval = dataSlot[ key ]; | ||
231 | hadKey = key in dataSlot; | ||
232 | delete dataSlot[ key ]; | ||
233 | } | ||
234 | |||
235 | return hadKey ? retval : null; | ||
236 | }; | ||
237 | |||
238 | /** | ||
239 | * Removes any data stored in this object. | ||
240 | * To avoid memory leaks we must assure that there are no | ||
241 | * references left after the object is no longer needed. | ||
242 | */ | ||
243 | domObjectProto.clearCustomData = function() { | ||
244 | // Clear all event listeners | ||
245 | this.removeAllListeners(); | ||
246 | |||
247 | var expandoNumber = this.$[ 'data-cke-expando' ]; | ||
248 | expandoNumber && delete customData[ expandoNumber ]; | ||
249 | }; | ||
250 | |||
251 | /** | ||
252 | * Gets an ID that can be used to identify this DOM object in | ||
253 | * the running session. | ||
254 | * | ||
255 | * **Note**: This method does not work on text nodes prior to Internet Explorer 9. | ||
256 | * | ||
257 | * @returns {Number} A unique ID. | ||
258 | */ | ||
259 | domObjectProto.getUniqueId = function() { | ||
260 | return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() ); | ||
261 | }; | ||
262 | |||
263 | // Implement CKEDITOR.event. | ||
264 | CKEDITOR.event.implementOn( domObjectProto ); | ||
265 | |||
266 | } )( CKEDITOR.dom.domObject.prototype ); | ||