1 | /*
|
---|
2 | Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
|
---|
3 | For licensing, see LICENSE.html or http://ckeditor.com/license
|
---|
4 | */
|
---|
5 |
|
---|
6 | /**
|
---|
7 | * @fileOverview jQuery adapter provides easy use of basic CKEditor functions
|
---|
8 | * and access to internal API. It also integrates some aspects of CKEditor with
|
---|
9 | * jQuery framework.
|
---|
10 | *
|
---|
11 | * Every TEXTAREA, DIV and P elements can be converted to working editor.
|
---|
12 | *
|
---|
13 | * Plugin exposes some of editor's event to jQuery event system. All of those are namespaces inside
|
---|
14 | * ".ckeditor" namespace and can be binded/listened on supported textarea, div and p nodes.
|
---|
15 | *
|
---|
16 | * Available jQuery events:
|
---|
17 | * - instanceReady.ckeditor( editor, rootNode )
|
---|
18 | * Triggered when new instance is ready.
|
---|
19 | * - destroy.ckeditor( editor )
|
---|
20 | * Triggered when instance is destroyed.
|
---|
21 | * - getData.ckeditor( editor, eventData )
|
---|
22 | * Triggered when getData event is fired inside editor. It can change returned data using eventData reference.
|
---|
23 | * - setData.ckeditor( editor )
|
---|
24 | * Triggered when getData event is fired inside editor.
|
---|
25 | *
|
---|
26 | * @example
|
---|
27 | * <script src="jquery.js"></script>
|
---|
28 | * <script src="ckeditor.js"></script>
|
---|
29 | * <script src="adapters/jquery/adapter.js"></script>
|
---|
30 | */
|
---|
31 |
|
---|
32 | (function()
|
---|
33 | {
|
---|
34 | /**
|
---|
35 | * Allow CKEditor to override jQuery.fn.val(). This results in ability to use val()
|
---|
36 | * function on textareas as usual and having those calls synchronized with CKEditor
|
---|
37 | * Rich Text Editor component.
|
---|
38 | *
|
---|
39 | * This config option is global and executed during plugin load.
|
---|
40 | * Can't be customized across editor instances.
|
---|
41 | *
|
---|
42 | * @type Boolean
|
---|
43 | * @example
|
---|
44 | * $( 'textarea' ).ckeditor();
|
---|
45 | * // ...
|
---|
46 | * $( 'textarea' ).val( 'New content' );
|
---|
47 | */
|
---|
48 | CKEDITOR.config.jqueryOverrideVal = typeof CKEDITOR.config.jqueryOverrideVal == 'undefined'
|
---|
49 | ? true : CKEDITOR.config.jqueryOverrideVal;
|
---|
50 |
|
---|
51 | var jQuery = window.jQuery;
|
---|
52 |
|
---|
53 | if ( typeof jQuery == 'undefined' )
|
---|
54 | return;
|
---|
55 |
|
---|
56 | // jQuery object methods.
|
---|
57 | jQuery.extend( jQuery.fn,
|
---|
58 | /** @lends jQuery.fn */
|
---|
59 | {
|
---|
60 | /**
|
---|
61 | * Return existing CKEditor instance for first matched element.
|
---|
62 | * Allows to easily use internal API. Doesn't return jQuery object.
|
---|
63 | *
|
---|
64 | * Raised exception if editor doesn't exist or isn't ready yet.
|
---|
65 | *
|
---|
66 | * @name jQuery.ckeditorGet
|
---|
67 | * @return CKEDITOR.editor
|
---|
68 | * @see CKEDITOR.editor
|
---|
69 | */
|
---|
70 | ckeditorGet: function()
|
---|
71 | {
|
---|
72 | var instance = this.eq( 0 ).data( 'ckeditorInstance' );
|
---|
73 | if ( !instance )
|
---|
74 | throw "CKEditor not yet initialized, use ckeditor() with callback.";
|
---|
75 | return instance;
|
---|
76 | },
|
---|
77 | /**
|
---|
78 | * Triggers creation of CKEditor in all matched elements (reduced to DIV, P and TEXTAREAs).
|
---|
79 | * Binds callback to instanceReady event of all instances. If editor is already created, than
|
---|
80 | * callback is fired right away.
|
---|
81 | *
|
---|
82 | * Mixed parameter order allowed.
|
---|
83 | *
|
---|
84 | * @param callback Function to be run on editor instance. Passed parameters: [ textarea ].
|
---|
85 | * Callback is fiered in "this" scope being ckeditor instance and having source textarea as first param.
|
---|
86 | *
|
---|
87 | * @param config Configuration options for new instance(s) if not already created.
|
---|
88 | * See URL
|
---|
89 | *
|
---|
90 | * @example
|
---|
91 | * $( 'textarea' ).ckeditor( function( textarea ) {
|
---|
92 | * $( textarea ).val( this.getData() )
|
---|
93 | * } );
|
---|
94 | *
|
---|
95 | * @name jQuery.fn.ckeditor
|
---|
96 | * @return jQuery.fn
|
---|
97 | */
|
---|
98 | ckeditor: function( callback, config )
|
---|
99 | {
|
---|
100 | if ( !jQuery.isFunction( callback ))
|
---|
101 | {
|
---|
102 | var tmp = config;
|
---|
103 | config = callback;
|
---|
104 | callback = tmp;
|
---|
105 | }
|
---|
106 | config = config || {};
|
---|
107 |
|
---|
108 | this.filter( 'textarea, div, p' ).each( function()
|
---|
109 | {
|
---|
110 | var $element = jQuery( this ),
|
---|
111 | editor = $element.data( 'ckeditorInstance' ),
|
---|
112 | instanceLock = $element.data( '_ckeditorInstanceLock' ),
|
---|
113 | element = this;
|
---|
114 |
|
---|
115 | if ( editor && !instanceLock )
|
---|
116 | {
|
---|
117 | if ( callback )
|
---|
118 | callback.apply( editor, [ this ] );
|
---|
119 | }
|
---|
120 | else if ( !instanceLock )
|
---|
121 | {
|
---|
122 | // CREATE NEW INSTANCE
|
---|
123 |
|
---|
124 | // Handle config.autoUpdateElement inside this plugin if desired.
|
---|
125 | if ( config.autoUpdateElement
|
---|
126 | || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) )
|
---|
127 | {
|
---|
128 | config.autoUpdateElementJquery = true;
|
---|
129 | }
|
---|
130 |
|
---|
131 | // Always disable config.autoUpdateElement.
|
---|
132 | config.autoUpdateElement = false;
|
---|
133 | $element.data( '_ckeditorInstanceLock', true );
|
---|
134 |
|
---|
135 | // Set instance reference in element's data.
|
---|
136 | editor = CKEDITOR.replace( element, config );
|
---|
137 | $element.data( 'ckeditorInstance', editor );
|
---|
138 |
|
---|
139 | // Register callback.
|
---|
140 | editor.on( 'instanceReady', function( event )
|
---|
141 | {
|
---|
142 | var editor = event.editor;
|
---|
143 | setTimeout( function()
|
---|
144 | {
|
---|
145 | // Delay bit more if editor is still not ready.
|
---|
146 | if ( !editor.element )
|
---|
147 | {
|
---|
148 | setTimeout( arguments.callee, 100 );
|
---|
149 | return;
|
---|
150 | }
|
---|
151 |
|
---|
152 | // Remove this listener.
|
---|
153 | event.removeListener( 'instanceReady', this.callee );
|
---|
154 |
|
---|
155 | // Forward setData on dataReady.
|
---|
156 | editor.on( 'dataReady', function()
|
---|
157 | {
|
---|
158 | $element.trigger( 'setData' + '.ckeditor', [ editor ] );
|
---|
159 | });
|
---|
160 |
|
---|
161 | // Forward getData.
|
---|
162 | editor.on( 'getData', function( event ) {
|
---|
163 | $element.trigger( 'getData' + '.ckeditor', [ editor, event.data ] );
|
---|
164 | }, 999 );
|
---|
165 |
|
---|
166 | // Forward destroy event.
|
---|
167 | editor.on( 'destroy', function()
|
---|
168 | {
|
---|
169 | $element.trigger( 'destroy.ckeditor', [ editor ] );
|
---|
170 | });
|
---|
171 |
|
---|
172 | // Integrate with form submit.
|
---|
173 | if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $element.parents( 'form' ).length )
|
---|
174 | {
|
---|
175 | var onSubmit = function()
|
---|
176 | {
|
---|
177 | $element.ckeditor( function()
|
---|
178 | {
|
---|
179 | editor.updateElement();
|
---|
180 | });
|
---|
181 | };
|
---|
182 |
|
---|
183 | // Bind to submit event.
|
---|
184 | $element.parents( 'form' ).submit( onSubmit );
|
---|
185 |
|
---|
186 | // Bind to form-pre-serialize from jQuery Forms plugin.
|
---|
187 | $element.parents( 'form' ).bind( 'form-pre-serialize', onSubmit );
|
---|
188 |
|
---|
189 | // Unbind when editor destroyed.
|
---|
190 | $element.bind( 'destroy.ckeditor', function()
|
---|
191 | {
|
---|
192 | $element.parents( 'form' ).unbind( 'submit', onSubmit );
|
---|
193 | $element.parents( 'form' ).unbind( 'form-pre-serialize', onSubmit );
|
---|
194 | });
|
---|
195 | }
|
---|
196 |
|
---|
197 | // Garbage collect on destroy.
|
---|
198 | editor.on( 'destroy', function()
|
---|
199 | {
|
---|
200 | $element.data( 'ckeditorInstance', null );
|
---|
201 | });
|
---|
202 |
|
---|
203 | // Remove lock.
|
---|
204 | $element.data( '_ckeditorInstanceLock', null );
|
---|
205 |
|
---|
206 | // Fire instanceReady event.
|
---|
207 | $element.trigger( 'instanceReady.ckeditor', [ editor ] );
|
---|
208 |
|
---|
209 | // Run given (first) code.
|
---|
210 | if ( callback )
|
---|
211 | callback.apply( editor, [ element ] );
|
---|
212 | }, 0 );
|
---|
213 | }, null, null, 9999);
|
---|
214 | }
|
---|
215 | else
|
---|
216 | {
|
---|
217 | // Editor is already during creation process, bind our code to the event.
|
---|
218 | CKEDITOR.on( 'instanceReady', function( event )
|
---|
219 | {
|
---|
220 | var editor = event.editor;
|
---|
221 | setTimeout( function()
|
---|
222 | {
|
---|
223 | // Delay bit more if editor is still not ready.
|
---|
224 | if ( !editor.element )
|
---|
225 | {
|
---|
226 | setTimeout( arguments.callee, 100 );
|
---|
227 | return;
|
---|
228 | }
|
---|
229 |
|
---|
230 | if ( editor.element.$ == element )
|
---|
231 | {
|
---|
232 | // Run given code.
|
---|
233 | if ( callback )
|
---|
234 | callback.apply( editor, [ element ] );
|
---|
235 | }
|
---|
236 | }, 0 );
|
---|
237 | }, null, null, 9999);
|
---|
238 | }
|
---|
239 | });
|
---|
240 | return this;
|
---|
241 | }
|
---|
242 | });
|
---|
243 |
|
---|
244 | // New val() method for objects.
|
---|
245 | if ( CKEDITOR.config.jqueryOverrideVal )
|
---|
246 | {
|
---|
247 | jQuery.fn.val = CKEDITOR.tools.override( jQuery.fn.val, function( oldValMethod )
|
---|
248 | {
|
---|
249 | /**
|
---|
250 | * CKEditor-aware val() method.
|
---|
251 | *
|
---|
252 | * Acts same as original jQuery val(), but for textareas which have CKEditor instances binded to them, method
|
---|
253 | * returns editor's content. It also works for settings values.
|
---|
254 | *
|
---|
255 | * @param oldValMethod
|
---|
256 | * @name jQuery.fn.val
|
---|
257 | */
|
---|
258 | return function( newValue, forceNative )
|
---|
259 | {
|
---|
260 | var isSetter = typeof newValue != 'undefined',
|
---|
261 | result;
|
---|
262 |
|
---|
263 | this.each( function()
|
---|
264 | {
|
---|
265 | var $this = jQuery( this ),
|
---|
266 | editor = $this.data( 'ckeditorInstance' );
|
---|
267 |
|
---|
268 | if ( !forceNative && $this.is( 'textarea' ) && editor )
|
---|
269 | {
|
---|
270 | if ( isSetter )
|
---|
271 | editor.setData( newValue );
|
---|
272 | else
|
---|
273 | {
|
---|
274 | result = editor.getData();
|
---|
275 | // break;
|
---|
276 | return null;
|
---|
277 | }
|
---|
278 | }
|
---|
279 | else
|
---|
280 | {
|
---|
281 | if ( isSetter )
|
---|
282 | oldValMethod.call( $this, newValue );
|
---|
283 | else
|
---|
284 | {
|
---|
285 | result = oldValMethod.call( $this );
|
---|
286 | // break;
|
---|
287 | return null;
|
---|
288 | }
|
---|
289 | }
|
---|
290 |
|
---|
291 | return true;
|
---|
292 | });
|
---|
293 | return isSetter ? this : result;
|
---|
294 | };
|
---|
295 | });
|
---|
296 | }
|
---|
297 | })();
|
---|