Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js |
— | — | @@ -146,75 +146,15 @@ |
147 | 147 | // gets called again we can pick up where we left off |
148 | 148 | var context = $(this).data( 'wikiEditor-context' ); |
149 | 149 | |
| 150 | +// This only gets run on the first call |
150 | 151 | if ( typeof context == 'undefined' ) { |
151 | 152 | |
152 | | - /* Base UI Construction */ |
153 | | - |
154 | 153 | var instance = $.wikiEditor.instances.length; |
155 | 154 | context = { '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance }; |
156 | 155 | $.wikiEditor.instances[instance] = $(this); |
157 | | - // Encapsulate the textarea with some containers for layout |
158 | | - $(this) |
159 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ) ) |
160 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-wikitext' ) ) |
161 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-left' ) ) |
162 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ) ) |
163 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ) ); |
164 | | - // Get a reference to the outer container |
165 | | - context.$ui = $(this).parent().parent().parent().parent(); |
166 | | - context.$ui.after( $( '<div style="clear:both;"></div>' ) ); |
167 | | - // Attach a right container |
168 | | - context.$ui.append( $( '<div></div>' ).addClass( 'wikiEditor-ui-right' ) ); |
169 | | - // Attach a top container to the left pane |
170 | | - context.$ui.find( '.wikiEditor-ui-left' ).prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ) ); |
171 | 156 | |
172 | | - /* Magic IFRAME Construction */ |
| 157 | + /* Externally Accessible API */ |
173 | 158 | |
174 | | - // Create an iframe in place of the text area |
175 | | - context.$iframe = $( '<iframe></iframe>' ) |
176 | | - .attr( 'frameborder', 0 ) |
177 | | - .css( { |
178 | | - 'backgroundColor': 'white', |
179 | | - 'width': '100%', |
180 | | - 'height': context.$textarea.height(), |
181 | | - 'display': 'none', |
182 | | - 'overflow-y': 'scroll', |
183 | | - 'overflow-x': 'hidden', |
184 | | - }) |
185 | | - .insertAfter( context.$textarea ); |
186 | | - |
187 | | - /* |
188 | | - * For whatever strange reason, this code needs to be within a timeout or it doesn't work - it seems to be that |
189 | | - * the DOM manipulation to add the iframe happens asynchronously and this code that depends on it actually being |
190 | | - * finished doesn't function on the right reference. |
191 | | - * FIXME: The fact that this calls a function that's defined below is ugly |
192 | | - */ |
193 | | - setTimeout( function() { context.fn.setup(); }, 1 ); |
194 | | - |
195 | | - // Attach a submit handler to the form so that when the form is submitted the content of the iframe gets decoded and |
196 | | - // copied over to the textarea |
197 | | - context.$textarea.closest( 'form' ).submit( function() { |
198 | | - context.$textarea.attr( 'disabled', false ); |
199 | | - context.$textarea.val( context.$textarea.textSelection( 'getContents' ) ); |
200 | | - } ); |
201 | | - |
202 | | - /* This is probably only a textarea issue, thus no longer needed |
203 | | - * |
204 | | - // Some browsers don't restore the cursor position on refocus properly |
205 | | - // Do it for them |
206 | | - $(this) |
207 | | - .focus( function() { |
208 | | - var pos = $(this).data( 'wikiEditor-cursor' ); |
209 | | - if ( pos ) |
210 | | - $(this).setSelection( pos[0], pos[1] ); |
211 | | - $(this).data( 'wikiEditor-cursor', false ); |
212 | | - }) |
213 | | - .blur( function() { |
214 | | - $(this).data( 'wikiEditor-cursor', $(this).getCaretPosition( true ) ); |
215 | | - }); |
216 | | - */ |
217 | | - |
218 | | - // Create a set of standard methods for internal and external use |
219 | 159 | context.api = { |
220 | 160 | /** |
221 | 161 | * Accepts either a string of the name of a module to add without any |
— | — | @@ -255,9 +195,7 @@ |
256 | 196 | } |
257 | 197 | } |
258 | 198 | } |
259 | | - /* |
260 | | - * Create a set of event handlers for the iframe to hook into |
261 | | - */ |
| 199 | + /* Event Handlers */ |
262 | 200 | context.evt = { |
263 | 201 | 'change': function( event ) { |
264 | 202 | // BTW: context is in event.data.context |
— | — | @@ -300,11 +238,11 @@ |
301 | 239 | context.$iframe[0].contentWindow.document.close(); |
302 | 240 | // Turn the document's design mode on |
303 | 241 | context.$iframe[0].contentWindow.document.designMode = 'on'; |
304 | | - |
305 | 242 | // Get a reference to the content area of the iframe |
306 | 243 | context.$content = $( context.$iframe[0].contentWindow.document.body ); |
307 | | - if ( $( 'body' ).is( '.rtl' ) ) |
| 244 | + if ( $( 'body' ).is( '.rtl' ) ) { |
308 | 245 | context.$content.addClass( 'rtl' ).attr( 'dir', 'rtl' ); |
| 246 | + } |
309 | 247 | |
310 | 248 | /* Magic IFRAME Activation */ |
311 | 249 | |
— | — | @@ -374,7 +312,6 @@ |
375 | 313 | selText = selText.substring( 0, selText.length - 1 ); |
376 | 314 | post += ' '; |
377 | 315 | } |
378 | | - |
379 | 316 | var range = context.$iframe[0].contentWindow.getSelection().getRangeAt( 0 ); |
380 | 317 | if ( options.ownline ) { |
381 | 318 | // TODO: This'll probably break with syntax highlighting |
— | — | @@ -384,10 +321,8 @@ |
385 | 322 | if ( range.endContainer == range.commonAncestorContainer ) |
386 | 323 | post += "\n"; |
387 | 324 | } |
388 | | - |
389 | 325 | var insertText = pre + selText + post; |
390 | 326 | var insertLines = insertText.split( "\n" ); |
391 | | - |
392 | 327 | range.extractContents(); |
393 | 328 | // Insert the contents one line at a time |
394 | 329 | // insertNode() inserts at the beginning, so this has |
— | — | @@ -395,12 +330,13 @@ |
396 | 331 | var lastNode; |
397 | 332 | for ( var i = insertLines.length - 1; i >= 0; i-- ) { |
398 | 333 | range.insertNode( document.createTextNode( insertLines[i] ) ); |
399 | | - if ( i > 0 ) |
| 334 | + if ( i > 0 ) { |
400 | 335 | lastNode = range.insertNode( document.createElement( 'br' ) ); |
| 336 | + } |
401 | 337 | } |
402 | | - if ( lastNode ) |
| 338 | + if ( lastNode ) { |
403 | 339 | context.fn.scrollToTop( lastNode ); |
404 | | - |
| 340 | + } |
405 | 341 | // Trigger the encapsulateSelection event (this might need to get named something else/done differently) |
406 | 342 | context.$content.trigger( 'encapsulateSelection', [ pre, peri, post, ownline, replace ] ); |
407 | 343 | return context.$textarea; |
— | — | @@ -443,10 +379,56 @@ |
444 | 380 | $element.trigger( 'scrollToTop' ); |
445 | 381 | } |
446 | 382 | }; |
| 383 | + |
| 384 | + /* Base UI Construction */ |
| 385 | + |
| 386 | + // Encapsulate the textarea with some containers for layout |
| 387 | + $(this) |
| 388 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ) ) |
| 389 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-wikitext' ) ) |
| 390 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-left' ) ) |
| 391 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ) ) |
| 392 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ) ); |
| 393 | + // Get a reference to the outer container |
| 394 | + context.$ui = $(this).parent().parent().parent().parent(); |
| 395 | + context.$ui.after( $( '<div style="clear:both;"></div>' ) ); |
| 396 | + // Attach a right container |
| 397 | + context.$ui.append( $( '<div></div>' ).addClass( 'wikiEditor-ui-right' ) ); |
| 398 | + // Attach a top container to the left pane |
| 399 | + context.$ui.find( '.wikiEditor-ui-left' ).prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ) ); |
| 400 | + |
| 401 | + /* Magic IFRAME Construction */ |
| 402 | + |
| 403 | + // Create an iframe in place of the text area |
| 404 | + context.$iframe = $( '<iframe></iframe>' ) |
| 405 | + .attr( 'frameborder', 0 ) |
| 406 | + .css( { |
| 407 | + 'backgroundColor': 'white', |
| 408 | + 'width': '100%', |
| 409 | + 'height': context.$textarea.height(), |
| 410 | + 'display': 'none', |
| 411 | + 'overflow-y': 'scroll', |
| 412 | + 'overflow-x': 'hidden', |
| 413 | + }) |
| 414 | + .insertAfter( context.$textarea ); |
| 415 | + |
| 416 | + /* |
| 417 | + * For whatever strange reason, this code needs to be within a timeout or it doesn't work - it seems to be that |
| 418 | + * the DOM manipulation to add the iframe happens asynchronously and this code that depends on it actually being |
| 419 | + * finished doesn't function on the right reference. |
| 420 | + * FIXME: The fact that this calls a function that's defined below is ugly |
| 421 | + */ |
| 422 | + setTimeout( function() { context.fn.setup(); }, 1 ); |
| 423 | + |
| 424 | + // Attach a submit handler to the form so that when the form is submitted the content of the iframe gets decoded and |
| 425 | + // copied over to the textarea |
| 426 | + context.$textarea.closest( 'form' ).submit( function() { |
| 427 | + context.$textarea.attr( 'disabled', false ); |
| 428 | + context.$textarea.val( context.$textarea.textSelection( 'getContents' ) ); |
| 429 | + } ); |
447 | 430 | } |
448 | 431 | |
449 | | -// If there was a configuration passed, it's assumed to be for the addModule |
450 | | -// API call |
| 432 | +// If there was a configuration passed, it's assumed to be for the addModule API call |
451 | 433 | if ( arguments.length > 0 && typeof arguments[0] == 'object' ) { |
452 | 434 | // If the iframe construction isn't ready yet, defer the call |
453 | 435 | if ( context.fn.isSetup() ) |
— | — | @@ -458,8 +440,7 @@ |
459 | 441 | }, 2 ); |
460 | 442 | } |
461 | 443 | } else { |
462 | | - // Since javascript gives arguments as an object, we need to convert them |
463 | | - // so they can be used more easily |
| 444 | + // Since javascript gives arguments as an object, we need to convert them so they can be used more easily |
464 | 445 | arguments = $.makeArray( arguments ); |
465 | 446 | if ( arguments.length > 0 ) { |
466 | 447 | // Handle API calls |