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