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