PageSourceSearch

https://belial.fr/libs/ckeditor/adapters/jquery.js?4.5.7

js belial.fr collected 2026-10-02 06:00:11 UTC 12,223 bytes, 379 lines download raw bytes

1/**
2 * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3 * CKEditor 4 LTS ("Long Term Support") is available under the terms of the Extended Support Model.
4 */
5
6/**
7 * @fileOverview Defines the {@link CKEDITOR_Adapters.jQuery jQuery Adapter}.
8 */
9
10/**
11 * @class CKEDITOR_Adapters.jQuery
12 * @singleton
13 *
14 * The jQuery Adapter allows for easy use of basic CKEditor functions and access to the internal API.
15 * To find more information about the jQuery Adapter, go to the {@glink guide/dev_jquery jQuery Adapter section}
16 * of the Developer's Guide or see the "Create Editors with jQuery" sample.
17 *
18 * @aside guide dev_jquery
19 */
20
21( function( $ ) {
22	if ( typeof $ == 'undefined' ) {
23		throw new Error( 'jQuery should be loaded before CKEditor jQuery adapter.' );
24	}
25
26	if ( typeof CKEDITOR == 'undefined' ) {
27		throw new Error( 'CKEditor should be loaded before CKEditor jQuery adapter.' );
28	}
29
30	/**
31	 * Allows CKEditor to override `jQuery.fn.val()`. When set to `true`, the `val()` function
32	 * used on textarea elements replaced with CKEditor uses the CKEditor API.
33	 *
34	 * This configuration option is global and is executed during the loading of the jQuery Adapter.
35	 * It cannot be customized across editor instances.
36	 *
37	 * Read more in the {@glink guide/dev_jquery documentation}.
38	 *
39	 *		<script>
40	 *			CKEDITOR.config.jqueryOverrideVal = true;
41	 *		</script>
42	 *
43	 *		<!-- Important: The jQuery Adapter is loaded *after* setting jqueryOverrideVal. -->
44	 *		<script src="/ckeditor/adapters/jquery.js"></script>
45	 *
46	 *		<script>
47	 *			$( 'textarea' ).ckeditor();
48	 *			// ...
49	 *			$( 'textarea' ).val( 'New content' );
50	 *		</script>
51	 *
52	 * @cfg {Boolean} [jqueryOverrideVal=true]
53	 * @member CKEDITOR.config
54	 */
55	CKEDITOR.config.jqueryOverrideVal =
56		typeof CKEDITOR.config.jqueryOverrideVal == 'undefined' ? true : CKEDITOR.config.jqueryOverrideVal;
57
58	// jQuery object methods.
59	$.extend( $.fn, {
60		/**
61		 * Returns an existing CKEditor instance for the first matched element.
62		 * Allows to easily use the internal API. Does not return a jQuery object.
63		 *
64		 * Raises an exception if the editor does not exist or is not ready yet.
65		 *
66		 * @returns CKEDITOR.editor
67		 * @deprecated Use {@link #editor editor property} instead.
68		 */
69		ckeditorGet: function() {
70			var instance = this.eq( 0 ).data( 'ckeditorInstance' );
71
72			if ( !instance )
73				throw 'CKEditor is not initialized yet, use ckeditor() with a callback.';
74
75			return instance;
76		},
77
78		/**
79		 * A jQuery function which triggers the creation of CKEditor with `<textarea>` and
80		 * {@link CKEDITOR.dtd#$editable editable} elements.
81		 * Every `<textarea>` element will be converted to a classic (`iframe`-based) editor,
82		 * while any other supported element will be converted to an inline editor.
83		 * This method binds the callback to the `instanceReady` event of all instances.
84		 * If the editor has already been created, the callback is fired straightaway.
85		 * You can also create multiple editors at once by using `$( '.className' ).ckeditor();`.
86		 *
87		 * **Note**: jQuery chaining and mixed parameter order is allowed.
88		 *
89		 * @param {Function} callback
90		 * Function to be run on the editor instance. Callback takes the source element as a parameter.
91		 *
92		 *		$( 'textarea' ).ckeditor( function( textarea ) {
93		 *			// Callback function code.
94		 *		} );
95		 *
96		 * @param {Object} config
97		 * Configuration options for new instance(s) if not already created.
98		 *
99		 *		$( 'textarea' ).ckeditor( {
100		 *			uiColor: '#9AB8F3'
101		 *		} );
102		 *
103		 * @returns jQuery.fn
104		 */
105		ckeditor: function( callback, config ) {
106			if ( !CKEDITOR.env.isCompatible )
107				throw new Error( 'The environment is incompatible.' );
108
109			// Reverse the order of arguments if the first one isn't a function.
110			if ( typeof callback !== 'function' ) {
111				var tmp = config;
112				config = callback;
113				callback = tmp;
114			}
115
116			// An array of instanceReady callback promises.
117			var promises = [];
118
119			config = config || {};
120
121			// Iterate over the collection.
122			this.each( function() {
123				var $element = $( this ),
124					editor = $element.data( 'ckeditorInstance' ),
125					instanceLock = $element.data( '_ckeditorInstanceLock' ),
126					element = this,
127					dfd = new $.Deferred();
128
129				promises.push( dfd.promise() );
130
131				if ( editor && !instanceLock ) {
132					if ( callback )
133						callback.apply( editor, [ this ] );
134
135					dfd.resolve();
136				} else if ( !instanceLock ) {
137					// CREATE NEW INSTANCE
138
139					// Handle config.autoUpdateElement inside this plugin if desired.
140					if ( config.autoUpdateElement || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) ) {
141						config.autoUpdateElementJquery = true;
142					}
143
144					// Always disable config.autoUpdateElement.
145					config.autoUpdateElement = false;
146					$element.data( '_ckeditorInstanceLock', true );
147
148					// Set instance reference in element's data.
149					if ( $( this ).is( 'textarea' ) )
150						editor = CKEDITOR.replace( element, config );
151					else
152						editor = CKEDITOR.inline( element, config );
153
154					$element.data( 'ckeditorInstance', editor );
155
156					// Register callback.
157					editor.on( 'instanceReady', function( evt ) {
158						var editor = evt.editor;
159
160						setTimeout( function waitForEditor() {
161							// Delay bit more if editor is still not ready.
162							if ( !editor.element ) {
163								setTimeout( waitForEditor, 100 );
164								return;
165							}
166
167							// Remove this listener. Triggered when new instance is ready.
168							evt.removeListener();
169
170							/**
171							 * Forwards the CKEditor {@link CKEDITOR.editor#event-dataReady dataReady event} as a jQuery event.
172							 *
173							 * @event dataReady
174							 * @param {CKEDITOR.editor} editor Editor instance.
175							 */
176							editor.on( 'dataReady', function() {
177								$element.trigger( 'dataReady.ckeditor', [ editor ] );
178							} );
179
180							/**
181							 * Forwards the CKEditor {@link CKEDITOR.editor#event-setData setData event} as a jQuery event.
182							 *
183							 * @event setData
184							 * @param {CKEDITOR.editor} editor Editor instance.
185							 * @param data
186							 * @param {String} data.dataValue The data that will be used.
187							 */
188							editor.on( 'setData', function( evt ) {
189								$element.trigger( 'setData.ckeditor', [ editor, evt.data ] );
190							} );
191
192							/**
193							 * Forwards the CKEditor {@link CKEDITOR.editor#event-getData getData event} as a jQuery event.
194							 *
195							 * @event getData
196							 * @param {CKEDITOR.editor} editor Editor instance.
197							 * @param data
198							 * @param {String} data.dataValue The data that will be returned.
199							 */
200							editor.on( 'getData', function( evt ) {
201								$element.trigger( 'getData.ckeditor', [ editor, evt.data ] );
202							}, 999 );
203
204							/**
205							 * Forwards the CKEditor {@link CKEDITOR.editor#event-destroy destroy event} as a jQuery event.
206							 *
207							 * @event destroy
208							 * @param {CKEDITOR.editor} editor Editor instance.
209							 */
210							editor.on( 'destroy', function() {
211								$element.trigger( 'destroy.ckeditor', [ editor ] );
212							} );
213
214							// Overwrite save button to call jQuery submit instead of javascript submit.
215							// Otherwise jQuery.forms does not work properly
216							editor.on( 'save', function() {
217								$( element.form ).trigger('submit');
218								return false;
219							}, null, null, 20 );
220
221							// Integrate with form submit.
222							if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $( element.form ).length ) {
223								var onSubmit = function() {
224									$element.ckeditor( function() {
225										editor.updateElement();
226									} );
227								};
228
229								// Bind to submit event.
230								$( element.form ).on( 'submit', onSubmit );
231
232								// Bind to form-pre-serialize from jQuery Forms plugin.
233								$( element.form ).on( 'form-pre-serialize', onSubmit );
234
235								// Unbind when editor destroyed.
236								$element.on( 'destroy.ckeditor', function() {
237									$( element.form ).off( 'submit', onSubmit );
238									$( element.form ).off( 'form-pre-serialize', onSubmit );
239								} );
240							}
241
242							// Garbage collect on destroy.
243							editor.on( 'destroy', function() {
244								$element.removeData( 'ckeditorInstance' );
245							} );
246
247							// Remove lock.
248							$element.removeData( '_ckeditorInstanceLock' );
249
250							/**
251							 * Forwards the CKEditor {@link CKEDITOR.editor#event-instanceReady instanceReady event} as a jQuery event.
252							 *
253							 * @event instanceReady
254							 * @param {CKEDITOR.editor} editor Editor instance.
255							 */
256							$element.trigger( 'instanceReady.ckeditor', [ editor ] );
257
258							// Run given (first) code.
259							if ( callback )
260								callback.apply( editor, [ element ] );
261
262							dfd.resolve();
263						}, 0 );
264					}, null, null, 9999 );
265				} else {
266					// Editor is already during creation process, bind our code to the event.
267					editor.once( 'instanceReady', function() {
268						setTimeout( function waitForEditor() {
269							// Delay bit more if editor is still not ready.
270							if ( !editor.element ) {
271								setTimeout( waitForEditor, 100 );
272								return;
273							}
274
275							// Run given code.
276							if ( editor.element.$ == element && callback )
277								callback.apply( editor, [ element ] );
278
279							dfd.resolve();
280						}, 0 );
281					}, null, null, 9999 );
282				}
283			} );
284
285			/**
286			 * The [jQuery Promise object](http://api.jquery.com/promise/) that handles the asynchronous constructor.
287			 * This promise will be resolved after **all** of the constructors.
288			 *
289			 * @property {Function} promise
290			 */
291			var dfd = new $.Deferred();
292
293			this.promise = dfd.promise();
294
295			$.when.apply( this, promises ).then( function() {
296				dfd.resolve();
297			} );
298
299			/**
300			 * Existing CKEditor instance. Allows to easily use the internal API.
301			 *
302			 * **Note**: This is not a jQuery object.
303			 *
304			 *		var editor = $( 'textarea' ).ckeditor().editor;
305			 *
306			 * @property {CKEDITOR.editor} editor
307			 */
308			this.editor = this.eq( 0 ).data( 'ckeditorInstance' );
309
310			return this;
311		}
312	} );
313
314	/**
315	 * Overwritten jQuery `val()` method for `<textarea>` elements that have bound CKEditor instances.
316	 * This method gets or sets editor content by using the {@link CKEDITOR.editor#method-getData editor.getData()}
317	 * or {@link CKEDITOR.editor#method-setData editor.setData()} methods. To handle
318	 * the {@link CKEDITOR.editor#method-setData editor.setData()} callback (as `setData` is asynchronous),
319	 * `val( 'some data' )` will return a [jQuery Promise object](http://api.jquery.com/promise/).
320	 *
321	 * @method val
322	 * @returns String|Number|Array|jQuery.fn|function(jQuery Promise)
323	 */
324	if ( CKEDITOR.config.jqueryOverrideVal ) {
325		$.fn.val = CKEDITOR.tools.override( $.fn.val, function( oldValMethod ) {
326			return function( value ) {
327				// Setter, i.e. .val( "some data" );
328				if ( arguments.length ) {
329					var _this = this,
330						promises = [], //use promise to handle setData callback
331
332						result = this.each( function() {
333							var $elem = $( this ),
334								editor = $elem.data( 'ckeditorInstance' );
335
336							// Handle .val for CKEditor.
337							if ( $elem.is( 'textarea' ) && editor ) {
338								var dfd = new $.Deferred();
339
340								editor.setData( value, function() {
341									dfd.resolve();
342								} );
343
344								promises.push( dfd.promise() );
345								return true;
346								// Call default .val function for rest of elements
347							} else {
348								return oldValMethod.call( $elem, value );
349							}
350						} );
351
352					// If there is no promise return default result (jQuery object of chaining).
353					if ( !promises.length )
354						return result;
355					// Create one promise which will be resolved when all of promises will be done.
356					else {
357						var dfd = new $.Deferred();
358
359						$.when.apply( this, promises ).done( function() {
360							dfd.resolveWith( _this );
361						} );
362
363						return dfd.promise();
364					}
365				}
366				// Getter .val();
367				else {
368					var $elem = $( this ).eq( 0 ),
369						editor = $elem.data( 'ckeditorInstance' );
370
371					if ( $elem.is( 'textarea' ) && editor )
372						return editor.getData();
373					else
374						return oldValMethod.call( $elem );
375				}
376			};
377		} );
378	}
379} )( window.jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.