JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
253cb57732771655adf6782a77bf84875981d57e
[ckeditor.git] / _source / plugins / autogrow / plugin.js
1 /*\r
2 Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r
3 For licensing, see LICENSE.html or http://ckeditor.com/license\r
4 */\r
5 \r
6 /**\r
7  * @file AutoGrow plugin\r
8  */\r
9 (function(){\r
10 \r
11         // Actual content height, figured out by appending check the last element's document position.\r
12         function contentHeight( scrollable )\r
13         {\r
14                 var overflowY = scrollable.getStyle( 'overflow-y' );\r
15 \r
16                 var doc = scrollable.getDocument();\r
17                 // Create a temporary marker element.\r
18                 var marker = CKEDITOR.dom.element.createFromHtml( '<span style="margin:0;padding:0;border:0;clear:both;width:1px;height:1px;display:block;">' + ( CKEDITOR.env.webkit ? '&nbsp;' : '' ) + '</span>', doc );\r
19                 doc[ CKEDITOR.env.ie? 'getBody' : 'getDocumentElement']().append( marker );\r
20 \r
21                 var height = marker.getDocumentPosition( doc ).y + marker.$.offsetHeight;\r
22                 marker.remove();\r
23                 scrollable.setStyle( 'overflow-y', overflowY );\r
24                 return height;\r
25         }\r
26 \r
27         function getScrollable( editor )\r
28         {\r
29                 var doc = editor.document,\r
30                         body = doc.getBody(),\r
31                         htmlElement = doc.getDocumentElement();\r
32 \r
33                 // Quirks mode overflows body, standards overflows document element\r
34                 return doc.$.compatMode == 'BackCompat' ? body : htmlElement;\r
35         }\r
36 \r
37         var resizeEditor = function( editor )\r
38         {\r
39                 if ( !editor.window )\r
40                         return;\r
41 \r
42                 var scrollable = getScrollable( editor ),\r
43                         currentHeight = editor.window.getViewPaneSize().height,\r
44                         newHeight = contentHeight( scrollable );\r
45 \r
46                 // Additional space specified by user.\r
47                 newHeight += ( editor.config.autoGrow_bottomSpace || 0 );\r
48 \r
49                 var min = editor.config.autoGrow_minHeight != undefined ? editor.config.autoGrow_minHeight : 200,\r
50                         max = editor.config.autoGrow_maxHeight || Infinity;\r
51 \r
52                 newHeight = Math.max( newHeight, min );\r
53                 newHeight = Math.min( newHeight, max );\r
54 \r
55                 if ( newHeight != currentHeight )\r
56                 {\r
57                         newHeight = editor.fire( 'autoGrow', { currentHeight : currentHeight, newHeight : newHeight } ).newHeight;\r
58                         editor.resize( editor.container.getStyle( 'width' ), newHeight, true );\r
59                 }\r
60 \r
61                 if ( scrollable.$.scrollHeight > scrollable.$.clientHeight && newHeight < max )\r
62                         scrollable.setStyle( 'overflow-y', 'hidden' );\r
63                 else\r
64                         scrollable.removeStyle( 'overflow-y' );\r
65 \r
66 \r
67         };\r
68 \r
69         CKEDITOR.plugins.add( 'autogrow',\r
70         {\r
71                 init : function( editor )\r
72                 {\r
73                         editor.addCommand( 'autogrow', { exec : resizeEditor, modes : { wysiwyg:1 }, readOnly: 1, canUndo: false, editorFocus: false } );\r
74 \r
75                         var eventsList = { contentDom:1, key:1, selectionChange:1, insertElement:1, mode:1 };\r
76                         editor.config.autoGrow_onStartup && ( eventsList[ 'instanceReady' ] = 1 );\r
77                         for ( var eventName in eventsList )\r
78                         {\r
79                                 editor.on( eventName, function( evt )\r
80                                 {\r
81                                         var maximize = editor.getCommand( 'maximize' );\r
82                                         // Some time is required for insertHtml, and it gives other events better performance as well.\r
83                                         if ( evt.editor.mode == 'wysiwyg' &&\r
84                                                 // Disable autogrow when the editor is maximized .(#6339)\r
85                                                 ( !maximize || maximize.state != CKEDITOR.TRISTATE_ON ) )\r
86                                         {\r
87                                                 setTimeout( function()\r
88                                                 {\r
89                                                         resizeEditor( evt.editor );\r
90                                                         // Second pass to make correction upon\r
91                                                         // the first resize, e.g. scrollbar.\r
92                                                         resizeEditor( evt.editor );\r
93                                                 }, 100 );\r
94                                         }\r
95                                 });\r
96                         }\r
97 \r
98                         // Coordinate with the "maximize" plugin. (#9311)\r
99                         editor.on( 'beforeCommandExec', function( evt )\r
100                         {\r
101                                 if ( evt.data.name == 'maximize' && evt.editor.mode == 'wysiwyg' )\r
102                                 {\r
103                                         if ( evt.data.command.state == CKEDITOR.TRISTATE_OFF )\r
104                                         {\r
105                                                 var scrollable = getScrollable( editor );\r
106                                                 scrollable.removeStyle( 'overflow' );\r
107                                         }\r
108                                         else\r
109                                                 resizeEditor( editor );\r
110                                 }\r
111                         });\r
112                 }\r
113         });\r
114 })();\r
115 /**\r
116  * The minimum height that the editor can reach using the AutoGrow feature.\r
117  * @name CKEDITOR.config.autoGrow_minHeight\r
118  * @type Number\r
119  * @default <code>200</code>\r
120  * @since 3.4\r
121  * @example\r
122  * config.autoGrow_minHeight = 300;\r
123  */\r
124 \r
125 /**\r
126  * The maximum height that the editor can reach using the AutoGrow feature. Zero means unlimited.\r
127  * @name CKEDITOR.config.autoGrow_maxHeight\r
128  * @type Number\r
129  * @default <code>0</code>\r
130  * @since 3.4\r
131  * @example\r
132  * config.autoGrow_maxHeight = 400;\r
133  */\r
134 \r
135  /**\r
136  * Whether to have the auto grow happen on editor creation.\r
137  * @name CKEDITOR.config.autoGrow_onStartup\r
138  * @type Boolean\r
139  * @default false\r
140  * @since 3.6.2\r
141  * @example\r
142  * config.autoGrow_onStartup = true;\r
143  */\r
144 \r
145 /**\r
146  * Fired when the AutoGrow plugin is about to change the size of the editor.\r
147  * @name CKEDITOR.editor#autogrow\r
148  * @event\r
149  * @param {Number} data.currentHeight The current height of the editor (before resizing).\r
150  * @param {Number} data.newHeight The new height of the editor (after resizing). It can be changed\r
151  *                              to determine a different height value to be used instead.\r
152  */\r
153 \r
154 \r
155 /**\r
156  *  Extra height in pixel to leave between the bottom boundary of content with document size when auto resizing.\r
157  * @name CKEDITOR.config.autoGrow_bottomSpace\r
158  * @type Number\r
159  * @default 0\r
160  * @since 3.6.2\r
161  */\r