X-Git-Url: https://scm.cri.minesparis.psl.eu/git/ckeditor.git/blobdiff_plain/256592bf803e851aa7fc953e08a6e9e58d970f8c..871bad8291b6dbc29d489d95d185458caab25158:/skins/ckeditor/_source/adapters/jquery.js diff --git a/skins/ckeditor/_source/adapters/jquery.js b/skins/ckeditor/_source/adapters/jquery.js new file mode 100644 index 0000000..1b0a994 --- /dev/null +++ b/skins/ckeditor/_source/adapters/jquery.js @@ -0,0 +1,306 @@ +/* +Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +/** + * @fileOverview jQuery adapter provides easy use of basic CKEditor functions + * and access to internal API. It also integrates some aspects of CKEditor with + * jQuery framework. + * + * Every TEXTAREA, DIV and P elements can be converted to working editor. + * + * Plugin exposes some of editor's event to jQuery event system. All of those are namespaces inside + * ".ckeditor" namespace and can be binded/listened on supported textarea, div and p nodes. + * + * Available jQuery events: + * - instanceReady.ckeditor( editor, rootNode ) + * Triggered when new instance is ready. + * - destroy.ckeditor( editor ) + * Triggered when instance is destroyed. + * - getData.ckeditor( editor, eventData ) + * Triggered when getData event is fired inside editor. It can change returned data using eventData reference. + * - setData.ckeditor( editor ) + * Triggered when getData event is fired inside editor. + * + * @example + * + * + * + */ + +(function() +{ + /** + * Allows CKEditor to override jQuery.fn.val(), making it possible to use the val() + * function on textareas, as usual, having it synchronized with CKEditor.
+ *
+ * This configuration option is global and executed during the jQuery Adapter loading. + * It can't be customized across editor instances. + * @type Boolean + * @example + * <script> + * CKEDITOR.config.jqueryOverrideVal = true; + * </script> + * <!-- Important: The JQuery adapter is loaded *after* setting jqueryOverrideVal --> + * <script src="/ckeditor/adapters/jquery.js"></script> + * @example + * // ... then later in the code ... + * + * $( 'textarea' ).ckeditor(); + * // ... + * $( 'textarea' ).val( 'New content' ); + */ + CKEDITOR.config.jqueryOverrideVal = typeof CKEDITOR.config.jqueryOverrideVal == 'undefined' + ? true : CKEDITOR.config.jqueryOverrideVal; + + var jQuery = window.jQuery; + + if ( typeof jQuery == 'undefined' ) + return; + + // jQuery object methods. + jQuery.extend( jQuery.fn, + /** @lends jQuery.fn */ + { + /** + * Return existing CKEditor instance for first matched element. + * Allows to easily use internal API. Doesn't return jQuery object. + * + * Raised exception if editor doesn't exist or isn't ready yet. + * + * @name jQuery.ckeditorGet + * @return CKEDITOR.editor + * @see CKEDITOR.editor + */ + ckeditorGet: function() + { + var instance = this.eq( 0 ).data( 'ckeditorInstance' ); + if ( !instance ) + throw "CKEditor not yet initialized, use ckeditor() with callback."; + return instance; + }, + /** + * Triggers creation of CKEditor in all matched elements (reduced to DIV, P and TEXTAREAs). + * Binds callback to instanceReady event of all instances. If editor is already created, than + * callback is fired right away. + * + * Mixed parameter order allowed. + * + * @param callback Function to be run on editor instance. Passed parameters: [ textarea ]. + * Callback is fiered in "this" scope being ckeditor instance and having source textarea as first param. + * + * @param config Configuration options for new instance(s) if not already created. + * See URL + * + * @example + * $( 'textarea' ).ckeditor( function( textarea ) { + * $( textarea ).val( this.getData() ) + * } ); + * + * @name jQuery.fn.ckeditor + * @return jQuery.fn + */ + ckeditor: function( callback, config ) + { + if ( !CKEDITOR.env.isCompatible ) + return this; + + if ( !jQuery.isFunction( callback )) + { + var tmp = config; + config = callback; + callback = tmp; + } + config = config || {}; + + this.filter( 'textarea, div, p' ).each( function() + { + var $element = jQuery( this ), + editor = $element.data( 'ckeditorInstance' ), + instanceLock = $element.data( '_ckeditorInstanceLock' ), + element = this; + + if ( editor && !instanceLock ) + { + if ( callback ) + callback.apply( editor, [ this ] ); + } + else if ( !instanceLock ) + { + // CREATE NEW INSTANCE + + // Handle config.autoUpdateElement inside this plugin if desired. + if ( config.autoUpdateElement + || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) ) + { + config.autoUpdateElementJquery = true; + } + + // Always disable config.autoUpdateElement. + config.autoUpdateElement = false; + $element.data( '_ckeditorInstanceLock', true ); + + // Set instance reference in element's data. + editor = CKEDITOR.replace( element, config ); + $element.data( 'ckeditorInstance', editor ); + + // Register callback. + editor.on( 'instanceReady', function( event ) + { + var editor = event.editor; + setTimeout( function() + { + // Delay bit more if editor is still not ready. + if ( !editor.element ) + { + setTimeout( arguments.callee, 100 ); + return; + } + + // Remove this listener. + event.removeListener( 'instanceReady', this.callee ); + + // Forward setData on dataReady. + editor.on( 'dataReady', function() + { + $element.trigger( 'setData' + '.ckeditor', [ editor ] ); + }); + + // Forward getData. + editor.on( 'getData', function( event ) { + $element.trigger( 'getData' + '.ckeditor', [ editor, event.data ] ); + }, 999 ); + + // Forward destroy event. + editor.on( 'destroy', function() + { + $element.trigger( 'destroy.ckeditor', [ editor ] ); + }); + + // Integrate with form submit. + if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $element.parents( 'form' ).length ) + { + var onSubmit = function() + { + $element.ckeditor( function() + { + editor.updateElement(); + }); + }; + + // Bind to submit event. + $element.parents( 'form' ).submit( onSubmit ); + + // Bind to form-pre-serialize from jQuery Forms plugin. + $element.parents( 'form' ).bind( 'form-pre-serialize', onSubmit ); + + // Unbind when editor destroyed. + $element.bind( 'destroy.ckeditor', function() + { + $element.parents( 'form' ).unbind( 'submit', onSubmit ); + $element.parents( 'form' ).unbind( 'form-pre-serialize', onSubmit ); + }); + } + + // Garbage collect on destroy. + editor.on( 'destroy', function() + { + $element.data( 'ckeditorInstance', null ); + }); + + // Remove lock. + $element.data( '_ckeditorInstanceLock', null ); + + // Fire instanceReady event. + $element.trigger( 'instanceReady.ckeditor', [ editor ] ); + + // Run given (first) code. + if ( callback ) + callback.apply( editor, [ element ] ); + }, 0 ); + }, null, null, 9999); + } + else + { + // Editor is already during creation process, bind our code to the event. + CKEDITOR.on( 'instanceReady', function( event ) + { + var editor = event.editor; + setTimeout( function() + { + // Delay bit more if editor is still not ready. + if ( !editor.element ) + { + setTimeout( arguments.callee, 100 ); + return; + } + + if ( editor.element.$ == element ) + { + // Run given code. + if ( callback ) + callback.apply( editor, [ element ] ); + } + }, 0 ); + }, null, null, 9999); + } + }); + return this; + } + }); + + // New val() method for objects. + if ( CKEDITOR.config.jqueryOverrideVal ) + { + jQuery.fn.val = CKEDITOR.tools.override( jQuery.fn.val, function( oldValMethod ) + { + /** + * CKEditor-aware val() method. + * + * Acts same as original jQuery val(), but for textareas which have CKEditor instances binded to them, method + * returns editor's content. It also works for settings values. + * + * @param oldValMethod + * @name jQuery.fn.val + */ + return function( newValue, forceNative ) + { + var isSetter = typeof newValue != 'undefined', + result; + + this.each( function() + { + var $this = jQuery( this ), + editor = $this.data( 'ckeditorInstance' ); + + if ( !forceNative && $this.is( 'textarea' ) && editor ) + { + if ( isSetter ) + editor.setData( newValue ); + else + { + result = editor.getData(); + // break; + return null; + } + } + else + { + if ( isSetter ) + oldValMethod.call( $this, newValue ); + else + { + result = oldValMethod.call( $this ); + // break; + return null; + } + } + + return true; + }); + return isSetter ? this : result; + }; + }); + } +})();