|
1 /** |
|
2 * plugin.js |
|
3 * |
|
4 * Copyright, Moxiecode Systems AB |
|
5 * Released under LGPL License. |
|
6 * |
|
7 * License: http://www.tinymce.com/license |
|
8 * Contributing: http://www.tinymce.com/contributing |
|
9 */ |
|
10 |
|
11 // Forked for WordPress so it can be turned on/off after loading. |
|
12 |
|
13 /*global tinymce:true */ |
|
14 /*eslint no-nested-ternary:0 */ |
|
15 |
|
16 /** |
|
17 * Auto Resize |
|
18 * |
|
19 * This plugin automatically resizes the content area to fit its content height. |
|
20 * It will retain a minimum height, which is the height of the content area when |
|
21 * it's initialized. |
|
22 */ |
|
23 tinymce.PluginManager.add( 'wpautoresize', function( editor ) { |
|
24 var settings = editor.settings, |
|
25 oldSize = 300, |
|
26 isActive = false; |
|
27 |
|
28 if ( editor.settings.inline || tinymce.Env.iOS ) { |
|
29 return; |
|
30 } |
|
31 |
|
32 function isFullscreen() { |
|
33 return editor.plugins.fullscreen && editor.plugins.fullscreen.isFullscreen(); |
|
34 } |
|
35 |
|
36 function getInt( n ) { |
|
37 return parseInt( n, 10 ) || 0; |
|
38 } |
|
39 |
|
40 /** |
|
41 * This method gets executed each time the editor needs to resize. |
|
42 */ |
|
43 function resize( e ) { |
|
44 var deltaSize, doc, body, docElm, DOM = tinymce.DOM, resizeHeight, myHeight, |
|
45 marginTop, marginBottom, paddingTop, paddingBottom, borderTop, borderBottom; |
|
46 |
|
47 if ( ! isActive ) { |
|
48 return; |
|
49 } |
|
50 |
|
51 doc = editor.getDoc(); |
|
52 if ( ! doc ) { |
|
53 return; |
|
54 } |
|
55 |
|
56 e = e || {}; |
|
57 body = doc.body; |
|
58 docElm = doc.documentElement; |
|
59 resizeHeight = settings.autoresize_min_height; |
|
60 |
|
61 if ( ! body || ( e && e.type === 'setcontent' && e.initial ) || isFullscreen() ) { |
|
62 if ( body && docElm ) { |
|
63 body.style.overflowY = 'auto'; |
|
64 docElm.style.overflowY = 'auto'; // Old IE |
|
65 } |
|
66 |
|
67 return; |
|
68 } |
|
69 |
|
70 // Calculate outer height of the body element using CSS styles |
|
71 marginTop = editor.dom.getStyle( body, 'margin-top', true ); |
|
72 marginBottom = editor.dom.getStyle( body, 'margin-bottom', true ); |
|
73 paddingTop = editor.dom.getStyle( body, 'padding-top', true ); |
|
74 paddingBottom = editor.dom.getStyle( body, 'padding-bottom', true ); |
|
75 borderTop = editor.dom.getStyle( body, 'border-top-width', true ); |
|
76 borderBottom = editor.dom.getStyle( body, 'border-bottom-width', true ); |
|
77 myHeight = body.offsetHeight + getInt( marginTop ) + getInt( marginBottom ) + |
|
78 getInt( paddingTop ) + getInt( paddingBottom ) + |
|
79 getInt( borderTop ) + getInt( borderBottom ); |
|
80 |
|
81 // IE < 11, other? |
|
82 if ( myHeight && myHeight < docElm.offsetHeight ) { |
|
83 myHeight = docElm.offsetHeight; |
|
84 } |
|
85 |
|
86 // Make sure we have a valid height |
|
87 if ( isNaN( myHeight ) || myHeight <= 0 ) { |
|
88 // Get height differently depending on the browser used |
|
89 myHeight = tinymce.Env.ie ? body.scrollHeight : ( tinymce.Env.webkit && body.clientHeight === 0 ? 0 : body.offsetHeight ); |
|
90 } |
|
91 |
|
92 // Don't make it smaller than the minimum height |
|
93 if ( myHeight > settings.autoresize_min_height ) { |
|
94 resizeHeight = myHeight; |
|
95 } |
|
96 |
|
97 // If a maximum height has been defined don't exceed this height |
|
98 if ( settings.autoresize_max_height && myHeight > settings.autoresize_max_height ) { |
|
99 resizeHeight = settings.autoresize_max_height; |
|
100 body.style.overflowY = 'auto'; |
|
101 docElm.style.overflowY = 'auto'; // Old IE |
|
102 } else { |
|
103 body.style.overflowY = 'hidden'; |
|
104 docElm.style.overflowY = 'hidden'; // Old IE |
|
105 body.scrollTop = 0; |
|
106 } |
|
107 |
|
108 // Resize content element |
|
109 if (resizeHeight !== oldSize) { |
|
110 deltaSize = resizeHeight - oldSize; |
|
111 DOM.setStyle( editor.iframeElement, 'height', resizeHeight + 'px' ); |
|
112 oldSize = resizeHeight; |
|
113 |
|
114 // WebKit doesn't decrease the size of the body element until the iframe gets resized |
|
115 // So we need to continue to resize the iframe down until the size gets fixed |
|
116 if ( tinymce.isWebKit && deltaSize < 0 ) { |
|
117 resize( e ); |
|
118 } |
|
119 |
|
120 editor.fire( 'wp-autoresize', { height: resizeHeight, deltaHeight: e.type === 'nodechange' ? deltaSize : null } ); |
|
121 } |
|
122 } |
|
123 |
|
124 /** |
|
125 * Calls the resize x times in 100ms intervals. We can't wait for load events since |
|
126 * the CSS files might load async. |
|
127 */ |
|
128 function wait( times, interval, callback ) { |
|
129 setTimeout( function() { |
|
130 resize(); |
|
131 |
|
132 if ( times-- ) { |
|
133 wait( times, interval, callback ); |
|
134 } else if ( callback ) { |
|
135 callback(); |
|
136 } |
|
137 }, interval ); |
|
138 } |
|
139 |
|
140 // Define minimum height |
|
141 settings.autoresize_min_height = parseInt(editor.getParam( 'autoresize_min_height', editor.getElement().offsetHeight), 10 ); |
|
142 |
|
143 // Define maximum height |
|
144 settings.autoresize_max_height = parseInt(editor.getParam( 'autoresize_max_height', 0), 10 ); |
|
145 |
|
146 function on() { |
|
147 if ( ! editor.dom.hasClass( editor.getBody(), 'wp-autoresize' ) ) { |
|
148 isActive = true; |
|
149 editor.dom.addClass( editor.getBody(), 'wp-autoresize' ); |
|
150 // Add appropriate listeners for resizing the content area |
|
151 editor.on( 'nodechange setcontent keyup FullscreenStateChanged', resize ); |
|
152 resize(); |
|
153 } |
|
154 } |
|
155 |
|
156 function off() { |
|
157 var doc; |
|
158 |
|
159 // Don't turn off if the setting is 'on' |
|
160 if ( ! settings.wp_autoresize_on ) { |
|
161 isActive = false; |
|
162 doc = editor.getDoc(); |
|
163 editor.dom.removeClass( editor.getBody(), 'wp-autoresize' ); |
|
164 editor.off( 'nodechange setcontent keyup FullscreenStateChanged', resize ); |
|
165 doc.body.style.overflowY = 'auto'; |
|
166 doc.documentElement.style.overflowY = 'auto'; // Old IE |
|
167 oldSize = 0; |
|
168 } |
|
169 } |
|
170 |
|
171 if ( settings.wp_autoresize_on ) { |
|
172 // Turn resizing on when the editor loads |
|
173 isActive = true; |
|
174 |
|
175 editor.on( 'init', function() { |
|
176 editor.dom.addClass( editor.getBody(), 'wp-autoresize' ); |
|
177 }); |
|
178 |
|
179 editor.on( 'nodechange keyup FullscreenStateChanged', resize ); |
|
180 |
|
181 editor.on( 'setcontent', function() { |
|
182 wait( 3, 100 ); |
|
183 }); |
|
184 |
|
185 if ( editor.getParam( 'autoresize_on_init', true ) ) { |
|
186 editor.on( 'init', function() { |
|
187 // Hit it 10 times in 200 ms intervals |
|
188 wait( 10, 200, function() { |
|
189 // Hit it 5 times in 1 sec intervals |
|
190 wait( 5, 1000 ); |
|
191 }); |
|
192 }); |
|
193 } |
|
194 } |
|
195 |
|
196 // Reset the stored size |
|
197 editor.on( 'show', function() { |
|
198 oldSize = 0; |
|
199 }); |
|
200 |
|
201 // Register the command |
|
202 editor.addCommand( 'wpAutoResize', resize ); |
|
203 |
|
204 // On/off |
|
205 editor.addCommand( 'wpAutoResizeOn', on ); |
|
206 editor.addCommand( 'wpAutoResizeOff', off ); |
|
207 }); |