Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toolbar.js |
— | — | @@ -388,7 +388,7 @@ |
389 | 389 | ) |
390 | 390 | ); |
391 | 391 | } else { |
392 | | - sectionQueue[sectionQueue.length] = { |
| 392 | + s = { |
393 | 393 | 'context': context, |
394 | 394 | '$sections': $sections, |
395 | 395 | '$tabs': $tabs, |
— | — | @@ -396,23 +396,7 @@ |
397 | 397 | 'config': config[section], |
398 | 398 | 'selected': ( selected == section ) |
399 | 399 | }; |
400 | | - } |
401 | | - } |
402 | | - $.eachAsync( sectionQueue, { |
403 | | - 'bulk': 0, |
404 | | - 'end': function() { |
405 | | - // HACK: Opera doesn't seem to want to redraw after these bits |
406 | | - // are added to the DOM, so we can just FORCE it! |
407 | | - $( 'body' ).css( 'position', 'static' ); |
408 | | - $( 'body' ).css( 'position', 'relative' ); |
409 | | - }, |
410 | | - 'loop': function( i, s ) { |
411 | | - s.$sections.append( |
412 | | - $.wikiEditor.modules.toolbar.fn.buildSection( |
413 | | - s.context, s.section, s.config |
414 | | - ) |
415 | | - .css( 'display', s.selected ? 'block' : 'none' ) |
416 | | - ); |
| 400 | + sectionQueue[sectionQueue.length] = s; |
417 | 401 | s.$tabs.append( |
418 | 402 | $( '<span></span>' ) |
419 | 403 | .attr( { |
— | — | @@ -458,6 +442,24 @@ |
459 | 443 | ) |
460 | 444 | ); |
461 | 445 | } |
| 446 | + } |
| 447 | + $.eachAsync( sectionQueue, { |
| 448 | + 'bulk': 0, |
| 449 | + 'end': function() { |
| 450 | + // HACK: Opera doesn't seem to want to redraw after these bits |
| 451 | + // are added to the DOM, so we can just FORCE it! |
| 452 | + $( 'body' ).css( 'position', 'static' ); |
| 453 | + $( 'body' ).css( 'position', 'relative' ); |
| 454 | + }, |
| 455 | + 'loop': function( i, s ) { |
| 456 | + s.$sections.append( |
| 457 | + $.wikiEditor.modules.toolbar.fn.buildSection( |
| 458 | + s.context, s.section, s.config |
| 459 | + ) |
| 460 | + .css( 'display', s.selected ? 'block' : 'none' ) |
| 461 | + ); |
| 462 | + |
| 463 | + } |
462 | 464 | } ); |
463 | 465 | } |
464 | 466 | } |
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js |
— | — | @@ -1,638 +1,638 @@ |
2 | | -/* |
3 | | - * jQuery Asynchronous Plugin 1.0 |
4 | | - * |
5 | | - * Copyright (c) 2008 Vincent Robert (genezys.net) |
6 | | - * Dual licensed under the MIT (MIT-LICENSE.txt) |
7 | | - * and GPL (GPL-LICENSE.txt) licenses. |
8 | | - * |
9 | | - */ |
10 | | -(function($){ |
11 | | - |
12 | | -// opts.delay : (default 10) delay between async call in ms |
13 | | -// opts.bulk : (default 500) delay during which the loop can continue synchronously without yielding the CPU |
14 | | -// opts.test : (default true) function to test in the while test part |
15 | | -// opts.loop : (default empty) function to call in the while loop part |
16 | | -// opts.end : (default empty) function to call at the end of the while loop |
17 | | -$.whileAsync = function(opts) |
18 | | -{ |
19 | | - var delay = Math.abs(opts.delay) || 10, |
20 | | - bulk = isNaN(opts.bulk) ? 500 : Math.abs(opts.bulk), |
21 | | - test = opts.test || function(){ return true; }, |
22 | | - loop = opts.loop || function(){}, |
23 | | - end = opts.end || function(){}; |
24 | | - |
25 | | - (function(){ |
26 | | - |
27 | | - var t = false, |
28 | | - begin = new Date(); |
29 | | - |
30 | | - while( t = test() ) |
31 | | - { |
32 | | - loop(); |
33 | | - if( bulk === 0 || (new Date() - begin) > bulk ) |
34 | | - { |
35 | | - break; |
36 | | - } |
37 | | - } |
38 | | - if( t ) |
39 | | - { |
40 | | - setTimeout(arguments.callee, delay); |
41 | | - } |
42 | | - else |
43 | | - { |
44 | | - end(); |
45 | | - } |
46 | | - |
47 | | - })(); |
48 | | -} |
49 | | - |
50 | | -// opts.delay : (default 10) delay between async call in ms |
51 | | -// opts.bulk : (default 500) delay during which the loop can continue synchronously without yielding the CPU |
52 | | -// opts.loop : (default empty) function to call in the each loop part, signature: function(index, value) this = value |
53 | | -// opts.end : (default empty) function to call at the end of the each loop |
54 | | -$.eachAsync = function(array, opts) |
55 | | -{ |
56 | | - var i = 0, |
57 | | - l = array.length, |
58 | | - loop = opts.loop || function(){}; |
59 | | - |
60 | | - $.whileAsync( |
61 | | - $.extend(opts, { |
62 | | - test: function(){ return i < l; }, |
63 | | - loop: function() |
64 | | - { |
65 | | - var val = array[i]; |
66 | | - return loop.call(val, i++, val); |
67 | | - } |
68 | | - }) |
69 | | - ); |
70 | | -} |
71 | | - |
72 | | -$.fn.eachAsync = function(opts) |
73 | | -{ |
74 | | - $.eachAsync(this, opts); |
75 | | - return this; |
76 | | -} |
77 | | - |
78 | | -})(jQuery); |
79 | | - |
80 | | -/* |
81 | | - |
82 | | -jQuery Browser Plugin |
83 | | - * Version 2.3 |
84 | | - * 2008-09-17 19:27:05 |
85 | | - * URL: http://jquery.thewikies.com/browser |
86 | | - * Description: jQuery Browser Plugin extends browser detection capabilities and can assign browser selectors to CSS classes. |
87 | | - * Author: Nate Cavanaugh, Minhchau Dang, & Jonathan Neal |
88 | | - * Copyright: Copyright (c) 2008 Jonathan Neal under dual MIT/GPL license. |
89 | | - * JSLint: This javascript file passes JSLint verification. |
90 | | -*//*jslint |
91 | | - bitwise: true, |
92 | | - browser: true, |
93 | | - eqeqeq: true, |
94 | | - forin: true, |
95 | | - nomen: true, |
96 | | - plusplus: true, |
97 | | - undef: true, |
98 | | - white: true |
99 | | -*//*global |
100 | | - jQuery |
101 | | -*/ |
102 | | - |
103 | | -(function ($) { |
104 | | - $.browserTest = function (a, z) { |
105 | | - var u = 'unknown', x = 'X', m = function (r, h) { |
106 | | - for (var i = 0; i < h.length; i = i + 1) { |
107 | | - r = r.replace(h[i][0], h[i][1]); |
108 | | - } |
109 | | - |
110 | | - return r; |
111 | | - }, c = function (i, a, b, c) { |
112 | | - var r = { |
113 | | - name: m((a.exec(i) || [u, u])[1], b) |
114 | | - }; |
115 | | - |
116 | | - r[r.name] = true; |
117 | | - |
118 | | - r.version = (c.exec(i) || [x, x, x, x])[3]; |
119 | | - |
120 | | - if (r.name.match(/safari/) && r.version > 400) { |
121 | | - r.version = '2.0'; |
122 | | - } |
123 | | - |
124 | | - if (r.name === 'presto') { |
125 | | - r.version = ($.browser.version > 9.27) ? 'futhark' : 'linear_b'; |
126 | | - } |
127 | | - r.versionNumber = parseFloat(r.version, 10) || 0; |
128 | | - r.versionX = (r.version !== x) ? (r.version + '').substr(0, 1) : x; |
129 | | - r.className = r.name + r.versionX; |
130 | | - |
131 | | - return r; |
132 | | - }; |
133 | | - |
134 | | - a = (a.match(/Opera|Navigator|Minefield|KHTML|Chrome/) ? m(a, [ |
135 | | - [/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ''], |
136 | | - ['Chrome Safari', 'Chrome'], |
137 | | - ['KHTML', 'Konqueror'], |
138 | | - ['Minefield', 'Firefox'], |
139 | | - ['Navigator', 'Netscape'] |
140 | | - ]) : a).toLowerCase(); |
141 | | - |
142 | | - $.browser = $.extend((!z) ? $.browser : {}, c(a, /(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari)/, [], /(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/)); |
143 | | - |
144 | | - $.layout = c(a, /(gecko|konqueror|msie|opera|webkit)/, [ |
145 | | - ['konqueror', 'khtml'], |
146 | | - ['msie', 'trident'], |
147 | | - ['opera', 'presto'] |
148 | | - ], /(applewebkit|rv|konqueror|msie)(\:|\/|\s)([a-z0-9\.]*?)(\;|\)|\s)/); |
149 | | - |
150 | | - $.os = { |
151 | | - name: (/(win|mac|linux|sunos|solaris|iphone)/.exec(navigator.platform.toLowerCase()) || [u])[0].replace('sunos', 'solaris') |
152 | | - }; |
153 | | - |
154 | | - if (!z) { |
155 | | - $('html').addClass([$.os.name, $.browser.name, $.browser.className, $.layout.name, $.layout.className].join(' ')); |
156 | | - } |
157 | | - }; |
158 | | - |
159 | | - $.browserTest(navigator.userAgent); |
160 | | -})(jQuery); |
161 | | - |
162 | | -/** |
163 | | - * Cookie plugin |
164 | | - * |
165 | | - * Copyright (c) 2006 Klaus Hartl (stilbuero.de) |
166 | | - * Dual licensed under the MIT and GPL licenses: |
167 | | - * http://www.opensource.org/licenses/mit-license.php |
168 | | - * http://www.gnu.org/licenses/gpl.html |
169 | | - * |
170 | | - */ |
171 | | - |
172 | | -/** |
173 | | - * Create a cookie with the given name and value and other optional parameters. |
174 | | - * |
175 | | - * @example $.cookie('the_cookie', 'the_value'); |
176 | | - * @desc Set the value of a cookie. |
177 | | - * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); |
178 | | - * @desc Create a cookie with all available options. |
179 | | - * @example $.cookie('the_cookie', 'the_value'); |
180 | | - * @desc Create a session cookie. |
181 | | - * @example $.cookie('the_cookie', null); |
182 | | - * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain |
183 | | - * used when the cookie was set. |
184 | | - * |
185 | | - * @param String name The name of the cookie. |
186 | | - * @param String value The value of the cookie. |
187 | | - * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. |
188 | | - * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. |
189 | | - * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. |
190 | | - * If set to null or omitted, the cookie will be a session cookie and will not be retained |
191 | | - * when the the browser exits. |
192 | | - * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). |
193 | | - * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). |
194 | | - * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will |
195 | | - * require a secure protocol (like HTTPS). |
196 | | - * @type undefined |
197 | | - * |
198 | | - * @name $.cookie |
199 | | - * @cat Plugins/Cookie |
200 | | - * @author Klaus Hartl/klaus.hartl@stilbuero.de |
201 | | - */ |
202 | | - |
203 | | -/** |
204 | | - * Get the value of a cookie with the given name. |
205 | | - * |
206 | | - * @example $.cookie('the_cookie'); |
207 | | - * @desc Get the value of a cookie. |
208 | | - * |
209 | | - * @param String name The name of the cookie. |
210 | | - * @return The value of the cookie. |
211 | | - * @type String |
212 | | - * |
213 | | - * @name $.cookie |
214 | | - * @cat Plugins/Cookie |
215 | | - * @author Klaus Hartl/klaus.hartl@stilbuero.de |
216 | | - */ |
217 | | -jQuery.cookie = function(name, value, options) { |
218 | | - if (typeof value != 'undefined') { // name and value given, set cookie |
219 | | - options = options || {}; |
220 | | - if (value === null) { |
221 | | - value = ''; |
222 | | - options.expires = -1; |
223 | | - } |
224 | | - var expires = ''; |
225 | | - if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { |
226 | | - var date; |
227 | | - if (typeof options.expires == 'number') { |
228 | | - date = new Date(); |
229 | | - date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); |
230 | | - } else { |
231 | | - date = options.expires; |
232 | | - } |
233 | | - expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE |
234 | | - } |
235 | | - // CAUTION: Needed to parenthesize options.path and options.domain |
236 | | - // in the following expressions, otherwise they evaluate to undefined |
237 | | - // in the packed version for some reason... |
238 | | - var path = options.path ? '; path=' + (options.path) : ''; |
239 | | - var domain = options.domain ? '; domain=' + (options.domain) : ''; |
240 | | - var secure = options.secure ? '; secure' : ''; |
241 | | - document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); |
242 | | - } else { // only name given, get cookie |
243 | | - var cookieValue = null; |
244 | | - if (document.cookie && document.cookie != '') { |
245 | | - var cookies = document.cookie.split(';'); |
246 | | - for (var i = 0; i < cookies.length; i++) { |
247 | | - var cookie = jQuery.trim(cookies[i]); |
248 | | - // Does this cookie string begin with the name we want? |
249 | | - if (cookie.substring(0, name.length + 1) == (name + '=')) { |
250 | | - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); |
251 | | - break; |
252 | | - } |
253 | | - } |
254 | | - } |
255 | | - return cookieValue; |
256 | | - } |
257 | | -}; |
258 | | - |
259 | | -/** |
260 | | - * These plugins provide extra functionality for interaction with textareas. |
261 | | - */ |
262 | | -( function( $ ) { $.fn.extend( { |
263 | | -/** |
264 | | - * Ported from skins/common/edit.js by Trevor Parscal |
265 | | - * (c) 2009 Wikimedia Foundation (GPLv2) - http://www.wikimedia.org |
266 | | - * |
267 | | - * Inserts text at the begining and end of a text selection, optionally |
268 | | - * inserting text at the caret when selection is empty. |
269 | | - * |
270 | | - * @param pre Text to insert before selection |
271 | | - * @param peri Text to insert at caret if selection is empty |
272 | | - * @param post Text to insert after selection |
273 | | - */ |
274 | | -encapsulateSelection: function( pre, peri, post ) { |
275 | | - /** |
276 | | - * Check if the selected text is the same as the insert text |
277 | | - */ |
278 | | - function checkSelectedText() { |
279 | | - if ( !selText ) { |
280 | | - selText = peri; |
281 | | - isSample = true; |
282 | | - } else if ( selText.charAt( selText.length - 1 ) == ' ' ) { |
283 | | - // Exclude ending space char |
284 | | - selText = selText.substring(0, selText.length - 1); |
285 | | - post += ' ' |
286 | | - } |
287 | | - } |
288 | | - var e = this.jquery ? this[0] : this; |
289 | | - var selText; |
290 | | - var isSample = false; |
291 | | - if ( document.selection && document.selection.createRange ) { |
292 | | - // IE/Opera |
293 | | - if ( document.documentElement && document.documentElement.scrollTop ) { |
294 | | - var winScroll = document.documentElement.scrollTop; |
295 | | - } else if ( document.body ) { |
296 | | - var winScroll = document.body.scrollTop; |
297 | | - } |
298 | | - $(this).focus(); |
299 | | - var range = document.selection.createRange(); |
300 | | - selText = range.text; |
301 | | - checkSelectedText(); |
302 | | - range.text = pre + selText + post; |
303 | | - if ( isSample && range.moveStart ) { |
304 | | - if ( window.opera ) { |
305 | | - post = post.replace( /\n/g, '' ); |
306 | | - } |
307 | | - range.moveStart( 'character', - post.length - selText.length ); |
308 | | - range.moveEnd( 'character', - post.length ); |
309 | | - } |
310 | | - range.select(); |
311 | | - if ( document.documentElement && document.documentElement.scrollTop ) { |
312 | | - document.documentElement.scrollTop = winScroll |
313 | | - } else if ( document.body ) { |
314 | | - document.body.scrollTop = winScroll; |
315 | | - } |
316 | | - } else if ( e.selectionStart || e.selectionStart == '0' ) { |
317 | | - // Mozilla |
318 | | - var textScroll = e.scrollTop; |
319 | | - $(this).focus(); |
320 | | - var startPos = e.selectionStart; |
321 | | - var endPos = e.selectionEnd; |
322 | | - selText = e.value.substring( startPos, endPos ); |
323 | | - checkSelectedText(); |
324 | | - e.value = e.value.substring( 0, startPos ) + pre + selText + post + |
325 | | - e.value.substring( endPos, e.value.length ); |
326 | | - if ( isSample ) { |
327 | | - e.selectionStart = startPos + pre.length; |
328 | | - e.selectionEnd = startPos + pre.length + selText.length; |
329 | | - } else { |
330 | | - e.selectionStart = |
331 | | - startPos + pre.length + selText.length + post.length; |
332 | | - e.selectionEnd = e.selectionStart; |
333 | | - } |
334 | | - e.scrollTop = textScroll; |
335 | | - } |
336 | | - $(this).trigger( 'encapsulateSelection' ); |
337 | | -}, |
338 | | -/** |
339 | | - * Ported from Wikia's LinkSuggest extension |
340 | | - * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest |
341 | | - * Some code copied from |
342 | | - * http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/ |
343 | | - * |
344 | | - * Get the position (in resolution of bytes not nessecarily characters) |
345 | | - * in a textarea |
346 | | - */ |
347 | | - getCaretPosition: function() { |
348 | | - function getCaret( e ) { |
349 | | - var caretPos = 0; |
350 | | - if($.browser.msie) { |
351 | | - // IE Support |
352 | | - var postFinished = false; |
353 | | - var periFinished = false; |
354 | | - var postFinished = false; |
355 | | - var preText, rawPreText, periText; |
356 | | - var rawPeriText, postText, rawPostText; |
357 | | - // Create range containing text in the selection |
358 | | - var periRange = document.selection.createRange().duplicate(); |
359 | | - // Create range containing text before the selection |
360 | | - var preRange = document.body.createTextRange(); |
361 | | - // Select all the text |
362 | | - preRange.moveToElementText(e); |
363 | | - // Move the end where we need it |
364 | | - preRange.setEndPoint("EndToStart", periRange); |
365 | | - // Create range containing text after the selection |
366 | | - var postRange = document.body.createTextRange(); |
367 | | - // Select all the text |
368 | | - postRange.moveToElementText(e); |
369 | | - // Move the start where we need it |
370 | | - postRange.setEndPoint("StartToEnd", periRange); |
371 | | - // Load the text values we need to compare |
372 | | - preText = rawPreText = preRange.text; |
373 | | - periText = rawPeriText = periRange.text; |
374 | | - postText = rawPostText = postRange.text; |
375 | | - /* |
376 | | - * Check each range for trimmed newlines by shrinking the range by 1 |
377 | | - * character and seeing if the text property has changed. If it has |
378 | | - * not changed then we know that IE has trimmed a \r\n from the end. |
379 | | - */ |
380 | | - do { |
381 | | - if ( !postFinished ) { |
382 | | - if ( preRange. |
383 | | - compareEndPoints( "StartToEnd", preRange ) == 0 ) { |
384 | | - postFinished = true; |
385 | | - } else { |
386 | | - preRange.moveEnd( "character", -1 ) |
387 | | - if ( preRange.text == preText ) { |
388 | | - rawPreText += "\r\n"; |
389 | | - } else { |
390 | | - postFinished = true; |
391 | | - } |
392 | | - } |
393 | | - } |
394 | | - if ( !periFinished ) { |
395 | | - if ( periRange. |
396 | | - compareEndPoints( "StartToEnd", periRange ) == 0 ) { |
397 | | - periFinished = true; |
398 | | - } else { |
399 | | - periRange.moveEnd( "character", -1 ) |
400 | | - if ( periRange.text == periText ) { |
401 | | - rawPeriText += "\r\n"; |
402 | | - } else { |
403 | | - periFinished = true; |
404 | | - } |
405 | | - } |
406 | | - } |
407 | | - if ( !postFinished ) { |
408 | | - if ( postRange. |
409 | | - compareEndPoints("StartToEnd", postRange) == 0 ) { |
410 | | - postFinished = true; |
411 | | - } else { |
412 | | - postRange.moveEnd( "character", -1 ) |
413 | | - if ( postRange.text == postText ) { |
414 | | - rawPostText += "\r\n"; |
415 | | - } else { |
416 | | - postFinished = true; |
417 | | - } |
418 | | - } |
419 | | - } |
420 | | - } while ( ( !postFinished || !periFinished || !postFinished ) ); |
421 | | - caretPos = rawPreText.replace( /\r\n/g, "\n" ).length; |
422 | | - } else if ( e.selectionStart || e.selectionStart == '0' ) { |
423 | | - // Firefox support |
424 | | - caretPos = e.selectionStart; |
425 | | - } |
426 | | - return caretPos; |
427 | | - } |
428 | | - return getCaret( this.get( 0 ) ); |
429 | | -}, |
430 | | -/** |
431 | | - * Ported from Wikia's LinkSuggest extension |
432 | | - * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest |
433 | | - * |
434 | | - * Scroll a textarea to a certain offset |
435 | | - * @param pos Byte offset |
436 | | - */ |
437 | | -scrollToCaretPosition: function( pos ) { |
438 | | - function getLineLength( e ) { |
439 | | - return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) ); |
440 | | - } |
441 | | - function getCaretScrollPosition( e ) { |
442 | | - var text = e.value.replace( /\r/g, "" ); |
443 | | - var caret = $( e ).getCaretPosition(); |
444 | | - var lineLength = getLineLength( e ); |
445 | | - var row = 0; |
446 | | - var charInLine = 0; |
447 | | - var lastSpaceInLine = 0; |
448 | | - for ( i = 0; i < caret; i++ ) { |
449 | | - charInLine++; |
450 | | - if ( text.charAt( i ) == " " ) { |
451 | | - lastSpaceInLine = charInLine; |
452 | | - } else if ( text.charAt( i ) == "\n" ) { |
453 | | - lastSpaceInLine = 0; |
454 | | - charInLine = 0; |
455 | | - row++; |
456 | | - } |
457 | | - if ( charInLine > lineLength ) { |
458 | | - if ( lastSpaceInLine > 0 ) { |
459 | | - charInLine = charInLine - lastSpaceInLine; |
460 | | - lastSpaceInLine = 0; |
461 | | - row++; |
462 | | - } |
463 | | - } |
464 | | - } |
465 | | - var nextSpace = 0; |
466 | | - for ( j = caret; j < caret + lineLength; j++ ) { |
467 | | - if ( |
468 | | - text.charAt( j ) == " " || |
469 | | - text.charAt( j ) == "\n" || |
470 | | - caret == text.length |
471 | | - ) { |
472 | | - nextSpace = j; |
473 | | - break; |
474 | | - } |
475 | | - } |
476 | | - if( nextSpace > lineLength && caret <= lineLength ) { |
477 | | - charInLine = caret - lastSpaceInLine; |
478 | | - row++; |
479 | | - } |
480 | | - return ( |
481 | | - $.os.name == 'mac' ? 13 : ( $.os.name == 'linux' ? 15 : 16 ) |
482 | | - ) * row; |
483 | | - } |
484 | | - return this.each(function() { |
485 | | - $(this).focus(); |
486 | | - if ( this.selectionStart || this.selectionStart == '0' ) { |
487 | | - // Mozilla |
488 | | - this.selectionStart = pos; |
489 | | - this.selectionEnd = pos; |
490 | | - $(this).scrollTop( getCaretScrollPosition( this ) ); |
491 | | - } else if ( document.selection && document.selection.createRange ) { |
492 | | - // IE / Opera |
493 | | - /* |
494 | | - * IE automatically scrolls the section to the bottom of the page, |
495 | | - * except if it's already in view and the cursor position hasn't |
496 | | - * changed, in which case it does nothing. In that case we'll force |
497 | | - * it to act by moving one character back and forth. |
498 | | - */ |
499 | | - var range = document.selection.createRange(); |
500 | | - var oldPos = $(this).getCaretPosition(); |
501 | | - var goBack = false; |
502 | | - if ( oldPos == pos ) { |
503 | | - pos++; |
504 | | - goBack = true; |
505 | | - } |
506 | | - range.moveToElementText( this ); |
507 | | - range.collapse(); |
508 | | - range.move( 'character', pos ); |
509 | | - range.select(); |
510 | | - this.scrollTop += range.offsetTop; |
511 | | - if ( goBack ) { |
512 | | - range.move( 'character', -1 ); |
513 | | - range.select(); |
514 | | - } |
515 | | - } |
516 | | - $(this).trigger( 'scrollToPosition' ); |
517 | | - }); |
518 | | -} |
519 | | - |
520 | | -} ); } )( jQuery );/** |
521 | | - * This plugin provides a way to build a user interface around a textarea. You |
522 | | - * can build the UI from a confguration.. |
523 | | - * $j( 'div#edittoolbar' ).wikiEditor( |
524 | | - * { 'modules': { 'toolbar': { ... config ... } } } |
525 | | - * ); |
526 | | - * ...and add modules after it's already been initialized... |
527 | | - * $j( 'textarea#wpTextbox1' ).wikiEditor( |
528 | | - * 'addModule', 'toc', { ... config ... } |
529 | | - * ); |
530 | | - * ...using the API, which is still be finished. |
531 | | - */ |
532 | | -(function($) { |
533 | | -$.wikiEditor = { 'modules': {}, 'instances': [] }; |
534 | | -$.fn.wikiEditor = function() { |
535 | | - |
536 | | -/* Initialization */ |
537 | | - |
538 | | -// The wikiEditor context is stored in the element, so when this function |
539 | | -// gets called again we can pick up where we left off |
540 | | -var context = $(this).data( 'context' ); |
541 | | - |
542 | | -/* API */ |
543 | | - |
544 | | -// The first time this is called, we expect context to be undefined, meaning |
545 | | -// the editing ui has not yet been, and still needs to be built, however each |
546 | | -// additional call after that is expected to be an API call, which contains a |
547 | | -// string as the first argument which corrosponds to a supported api call |
548 | | -if ( typeof context !== 'undefined' ) { |
549 | | - // Since javascript gives arugments as an object, we need to convert them |
550 | | - // so they can be used more easily |
551 | | - arguments = $.makeArray( arguments ); |
552 | | - if ( arguments.length > 0 ) { |
553 | | - // Handle API calls |
554 | | - var call = arguments.shift(); |
555 | | - if ( call in context.api ) { |
556 | | - context.api[call]( |
557 | | - context, arguments[0] == undefined ? {} : arguments[0] |
558 | | - ); |
559 | | - } |
560 | | - // Store the context for next time and return |
561 | | - return $(this).data( 'context', context ); |
562 | | - } |
563 | | - // Nothing to do, just return |
564 | | - return $(this); |
565 | | -} |
566 | | - |
567 | | -/* Construction */ |
568 | | - |
569 | | -var instance = $.wikiEditor.instances.length; |
570 | | -context = { |
571 | | - '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance |
572 | | -}; |
573 | | -$.wikiEditor.instances[instance] = $(this); |
574 | | - |
575 | | -// Encapsulate the textarea with some containers for layout |
576 | | -$(this) |
577 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ) ) |
578 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ) ) |
579 | | - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ) ); |
580 | | -// Get a refrence to the outter container |
581 | | -context.$ui = $(this).parent().parent().parent(); |
582 | | -context.$ui.after( $( '<div style="clear:both;"></div>' ) ); |
583 | | -// Attach a container in the top |
584 | | -context.$ui.prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ) ); |
585 | | -// Create a set of standard methods for internal and external use |
586 | | -context.api = { |
587 | | - /** |
588 | | - * Accepts either a string of the name of a module to add without any |
589 | | - * additional configuration parameters, or an object with members keyed with |
590 | | - * module names and valued with configuration objects |
591 | | - */ |
592 | | - addModule: function( context, data ) { |
593 | | - // A safe way of calling an API function on a module |
594 | | - function callModuleApi( module, call, data ) { |
595 | | - if ( |
596 | | - module in $.wikiEditor.modules && |
597 | | - 'fn' in $.wikiEditor.modules[module] && |
598 | | - call in $.wikiEditor.modules[module].fn |
599 | | - ) { |
600 | | - $.wikiEditor.modules[module].fn[call]( context, data ); |
601 | | - } |
602 | | - } |
603 | | - if ( typeof data == 'string' ) { |
604 | | - callModuleApi( data, 'create', {} ); |
605 | | - } else if ( typeof data == 'object' ) { |
606 | | - for ( module in data ) { |
607 | | - if ( typeof module == 'string' ) { |
608 | | - callModuleApi( module, 'create', data[module] ); |
609 | | - } |
610 | | - } |
611 | | - } |
612 | | - } |
613 | | -}; |
614 | | -// Allow modules to extend the API |
615 | | -for ( module in $.wikiEditor.modules ) { |
616 | | - if ( 'api' in $.wikiEditor.modules[module] ) { |
617 | | - for ( call in $.wikiEditor.modules[module].api ) { |
618 | | - // Modules may not overwrite existing API functions - first come, |
619 | | - // first serve |
620 | | - if ( !( call in context.api ) ) { |
621 | | - context.api[call] = $.wikiEditor.modules[module].api[call]; |
622 | | - } |
623 | | - } |
624 | | - } |
625 | | -} |
626 | | -// Each browser seems to do this differently, so let's keep our editor |
627 | | -// consistent by allways starting at the begining |
628 | | -context.$textarea.scrollToCaretPosition( 0 ); |
629 | | -// If there was a configuration passed, it's assumed to be for the addModule |
630 | | -// API call, so we can just send it on it's way right now |
631 | | -if ( arguments.length > 0 && typeof arguments[0] == 'object' ) { |
632 | | - context.api.addModule( context, arguments[0] ); |
633 | | -} |
634 | | -// Store the context for next time, and support chaining |
635 | | -return $(this).data( 'context', context );; |
636 | | - |
| 2 | +/*
|
| 3 | + * jQuery Asynchronous Plugin 1.0
|
| 4 | + *
|
| 5 | + * Copyright (c) 2008 Vincent Robert (genezys.net)
|
| 6 | + * Dual licensed under the MIT (MIT-LICENSE.txt)
|
| 7 | + * and GPL (GPL-LICENSE.txt) licenses.
|
| 8 | + *
|
| 9 | + */
|
| 10 | +(function($){
|
| 11 | +
|
| 12 | +// opts.delay : (default 10) delay between async call in ms
|
| 13 | +// opts.bulk : (default 500) delay during which the loop can continue synchronously without yielding the CPU
|
| 14 | +// opts.test : (default true) function to test in the while test part
|
| 15 | +// opts.loop : (default empty) function to call in the while loop part
|
| 16 | +// opts.end : (default empty) function to call at the end of the while loop
|
| 17 | +$.whileAsync = function(opts)
|
| 18 | +{
|
| 19 | + var delay = Math.abs(opts.delay) || 10,
|
| 20 | + bulk = isNaN(opts.bulk) ? 500 : Math.abs(opts.bulk),
|
| 21 | + test = opts.test || function(){ return true; },
|
| 22 | + loop = opts.loop || function(){},
|
| 23 | + end = opts.end || function(){};
|
| 24 | +
|
| 25 | + (function(){
|
| 26 | +
|
| 27 | + var t = false,
|
| 28 | + begin = new Date();
|
| 29 | +
|
| 30 | + while( t = test() )
|
| 31 | + {
|
| 32 | + loop();
|
| 33 | + if( bulk === 0 || (new Date() - begin) > bulk )
|
| 34 | + {
|
| 35 | + break;
|
| 36 | + }
|
| 37 | + }
|
| 38 | + if( t )
|
| 39 | + {
|
| 40 | + setTimeout(arguments.callee, delay);
|
| 41 | + }
|
| 42 | + else
|
| 43 | + {
|
| 44 | + end();
|
| 45 | + }
|
| 46 | +
|
| 47 | + })();
|
| 48 | +}
|
| 49 | +
|
| 50 | +// opts.delay : (default 10) delay between async call in ms
|
| 51 | +// opts.bulk : (default 500) delay during which the loop can continue synchronously without yielding the CPU
|
| 52 | +// opts.loop : (default empty) function to call in the each loop part, signature: function(index, value) this = value
|
| 53 | +// opts.end : (default empty) function to call at the end of the each loop
|
| 54 | +$.eachAsync = function(array, opts)
|
| 55 | +{
|
| 56 | + var i = 0,
|
| 57 | + l = array.length,
|
| 58 | + loop = opts.loop || function(){};
|
| 59 | +
|
| 60 | + $.whileAsync(
|
| 61 | + $.extend(opts, {
|
| 62 | + test: function(){ return i < l; },
|
| 63 | + loop: function()
|
| 64 | + {
|
| 65 | + var val = array[i];
|
| 66 | + return loop.call(val, i++, val);
|
| 67 | + }
|
| 68 | + })
|
| 69 | + );
|
| 70 | +}
|
| 71 | +
|
| 72 | +$.fn.eachAsync = function(opts)
|
| 73 | +{
|
| 74 | + $.eachAsync(this, opts);
|
| 75 | + return this;
|
| 76 | +}
|
| 77 | +
|
| 78 | +})(jQuery);
|
| 79 | +
|
| 80 | +/*
|
| 81 | +
|
| 82 | +jQuery Browser Plugin
|
| 83 | + * Version 2.3
|
| 84 | + * 2008-09-17 19:27:05
|
| 85 | + * URL: http://jquery.thewikies.com/browser
|
| 86 | + * Description: jQuery Browser Plugin extends browser detection capabilities and can assign browser selectors to CSS classes.
|
| 87 | + * Author: Nate Cavanaugh, Minhchau Dang, & Jonathan Neal
|
| 88 | + * Copyright: Copyright (c) 2008 Jonathan Neal under dual MIT/GPL license.
|
| 89 | + * JSLint: This javascript file passes JSLint verification.
|
| 90 | +*//*jslint
|
| 91 | + bitwise: true,
|
| 92 | + browser: true,
|
| 93 | + eqeqeq: true,
|
| 94 | + forin: true,
|
| 95 | + nomen: true,
|
| 96 | + plusplus: true,
|
| 97 | + undef: true,
|
| 98 | + white: true
|
| 99 | +*//*global
|
| 100 | + jQuery
|
| 101 | +*/
|
| 102 | +
|
| 103 | +(function ($) {
|
| 104 | + $.browserTest = function (a, z) {
|
| 105 | + var u = 'unknown', x = 'X', m = function (r, h) {
|
| 106 | + for (var i = 0; i < h.length; i = i + 1) {
|
| 107 | + r = r.replace(h[i][0], h[i][1]);
|
| 108 | + }
|
| 109 | +
|
| 110 | + return r;
|
| 111 | + }, c = function (i, a, b, c) {
|
| 112 | + var r = {
|
| 113 | + name: m((a.exec(i) || [u, u])[1], b)
|
| 114 | + };
|
| 115 | +
|
| 116 | + r[r.name] = true;
|
| 117 | +
|
| 118 | + r.version = (c.exec(i) || [x, x, x, x])[3];
|
| 119 | +
|
| 120 | + if (r.name.match(/safari/) && r.version > 400) {
|
| 121 | + r.version = '2.0';
|
| 122 | + }
|
| 123 | +
|
| 124 | + if (r.name === 'presto') {
|
| 125 | + r.version = ($.browser.version > 9.27) ? 'futhark' : 'linear_b';
|
| 126 | + }
|
| 127 | + r.versionNumber = parseFloat(r.version, 10) || 0;
|
| 128 | + r.versionX = (r.version !== x) ? (r.version + '').substr(0, 1) : x;
|
| 129 | + r.className = r.name + r.versionX;
|
| 130 | +
|
| 131 | + return r;
|
| 132 | + };
|
| 133 | +
|
| 134 | + a = (a.match(/Opera|Navigator|Minefield|KHTML|Chrome/) ? m(a, [
|
| 135 | + [/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/, ''],
|
| 136 | + ['Chrome Safari', 'Chrome'],
|
| 137 | + ['KHTML', 'Konqueror'],
|
| 138 | + ['Minefield', 'Firefox'],
|
| 139 | + ['Navigator', 'Netscape']
|
| 140 | + ]) : a).toLowerCase();
|
| 141 | +
|
| 142 | + $.browser = $.extend((!z) ? $.browser : {}, c(a, /(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari)/, [], /(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/));
|
| 143 | +
|
| 144 | + $.layout = c(a, /(gecko|konqueror|msie|opera|webkit)/, [
|
| 145 | + ['konqueror', 'khtml'],
|
| 146 | + ['msie', 'trident'],
|
| 147 | + ['opera', 'presto']
|
| 148 | + ], /(applewebkit|rv|konqueror|msie)(\:|\/|\s)([a-z0-9\.]*?)(\;|\)|\s)/);
|
| 149 | +
|
| 150 | + $.os = {
|
| 151 | + name: (/(win|mac|linux|sunos|solaris|iphone)/.exec(navigator.platform.toLowerCase()) || [u])[0].replace('sunos', 'solaris')
|
| 152 | + };
|
| 153 | +
|
| 154 | + if (!z) {
|
| 155 | + $('html').addClass([$.os.name, $.browser.name, $.browser.className, $.layout.name, $.layout.className].join(' '));
|
| 156 | + }
|
| 157 | + };
|
| 158 | +
|
| 159 | + $.browserTest(navigator.userAgent);
|
| 160 | +})(jQuery);
|
| 161 | +
|
| 162 | +/**
|
| 163 | + * Cookie plugin
|
| 164 | + *
|
| 165 | + * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
| 166 | + * Dual licensed under the MIT and GPL licenses:
|
| 167 | + * http://www.opensource.org/licenses/mit-license.php
|
| 168 | + * http://www.gnu.org/licenses/gpl.html
|
| 169 | + *
|
| 170 | + */
|
| 171 | +
|
| 172 | +/**
|
| 173 | + * Create a cookie with the given name and value and other optional parameters.
|
| 174 | + *
|
| 175 | + * @example $.cookie('the_cookie', 'the_value');
|
| 176 | + * @desc Set the value of a cookie.
|
| 177 | + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
| 178 | + * @desc Create a cookie with all available options.
|
| 179 | + * @example $.cookie('the_cookie', 'the_value');
|
| 180 | + * @desc Create a session cookie.
|
| 181 | + * @example $.cookie('the_cookie', null);
|
| 182 | + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
| 183 | + * used when the cookie was set.
|
| 184 | + *
|
| 185 | + * @param String name The name of the cookie.
|
| 186 | + * @param String value The value of the cookie.
|
| 187 | + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
| 188 | + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
| 189 | + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
| 190 | + * If set to null or omitted, the cookie will be a session cookie and will not be retained
|
| 191 | + * when the the browser exits.
|
| 192 | + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
| 193 | + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
| 194 | + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
| 195 | + * require a secure protocol (like HTTPS).
|
| 196 | + * @type undefined
|
| 197 | + *
|
| 198 | + * @name $.cookie
|
| 199 | + * @cat Plugins/Cookie
|
| 200 | + * @author Klaus Hartl/klaus.hartl@stilbuero.de
|
| 201 | + */
|
| 202 | +
|
| 203 | +/**
|
| 204 | + * Get the value of a cookie with the given name.
|
| 205 | + *
|
| 206 | + * @example $.cookie('the_cookie');
|
| 207 | + * @desc Get the value of a cookie.
|
| 208 | + *
|
| 209 | + * @param String name The name of the cookie.
|
| 210 | + * @return The value of the cookie.
|
| 211 | + * @type String
|
| 212 | + *
|
| 213 | + * @name $.cookie
|
| 214 | + * @cat Plugins/Cookie
|
| 215 | + * @author Klaus Hartl/klaus.hartl@stilbuero.de
|
| 216 | + */
|
| 217 | +jQuery.cookie = function(name, value, options) {
|
| 218 | + if (typeof value != 'undefined') { // name and value given, set cookie
|
| 219 | + options = options || {};
|
| 220 | + if (value === null) {
|
| 221 | + value = '';
|
| 222 | + options.expires = -1;
|
| 223 | + }
|
| 224 | + var expires = '';
|
| 225 | + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
| 226 | + var date;
|
| 227 | + if (typeof options.expires == 'number') {
|
| 228 | + date = new Date();
|
| 229 | + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
| 230 | + } else {
|
| 231 | + date = options.expires;
|
| 232 | + }
|
| 233 | + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
| 234 | + }
|
| 235 | + // CAUTION: Needed to parenthesize options.path and options.domain
|
| 236 | + // in the following expressions, otherwise they evaluate to undefined
|
| 237 | + // in the packed version for some reason...
|
| 238 | + var path = options.path ? '; path=' + (options.path) : '';
|
| 239 | + var domain = options.domain ? '; domain=' + (options.domain) : '';
|
| 240 | + var secure = options.secure ? '; secure' : '';
|
| 241 | + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
| 242 | + } else { // only name given, get cookie
|
| 243 | + var cookieValue = null;
|
| 244 | + if (document.cookie && document.cookie != '') {
|
| 245 | + var cookies = document.cookie.split(';');
|
| 246 | + for (var i = 0; i < cookies.length; i++) {
|
| 247 | + var cookie = jQuery.trim(cookies[i]);
|
| 248 | + // Does this cookie string begin with the name we want?
|
| 249 | + if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
| 250 | + cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
| 251 | + break;
|
| 252 | + }
|
| 253 | + }
|
| 254 | + }
|
| 255 | + return cookieValue;
|
| 256 | + }
|
| 257 | +};
|
| 258 | +
|
| 259 | +/**
|
| 260 | + * These plugins provide extra functionality for interaction with textareas.
|
| 261 | + */
|
| 262 | +( function( $ ) { $.fn.extend( {
|
| 263 | +/**
|
| 264 | + * Ported from skins/common/edit.js by Trevor Parscal
|
| 265 | + * (c) 2009 Wikimedia Foundation (GPLv2) - http://www.wikimedia.org
|
| 266 | + *
|
| 267 | + * Inserts text at the begining and end of a text selection, optionally
|
| 268 | + * inserting text at the caret when selection is empty.
|
| 269 | + *
|
| 270 | + * @param pre Text to insert before selection
|
| 271 | + * @param peri Text to insert at caret if selection is empty
|
| 272 | + * @param post Text to insert after selection
|
| 273 | + */
|
| 274 | +encapsulateSelection: function( pre, peri, post ) {
|
| 275 | + /**
|
| 276 | + * Check if the selected text is the same as the insert text
|
| 277 | + */
|
| 278 | + function checkSelectedText() {
|
| 279 | + if ( !selText ) {
|
| 280 | + selText = peri;
|
| 281 | + isSample = true;
|
| 282 | + } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
|
| 283 | + // Exclude ending space char
|
| 284 | + selText = selText.substring(0, selText.length - 1);
|
| 285 | + post += ' '
|
| 286 | + }
|
| 287 | + }
|
| 288 | + var e = this.jquery ? this[0] : this;
|
| 289 | + var selText;
|
| 290 | + var isSample = false;
|
| 291 | + if ( document.selection && document.selection.createRange ) {
|
| 292 | + // IE/Opera
|
| 293 | + if ( document.documentElement && document.documentElement.scrollTop ) {
|
| 294 | + var winScroll = document.documentElement.scrollTop;
|
| 295 | + } else if ( document.body ) {
|
| 296 | + var winScroll = document.body.scrollTop;
|
| 297 | + }
|
| 298 | + $(this).focus();
|
| 299 | + var range = document.selection.createRange();
|
| 300 | + selText = range.text;
|
| 301 | + checkSelectedText();
|
| 302 | + range.text = pre + selText + post;
|
| 303 | + if ( isSample && range.moveStart ) {
|
| 304 | + if ( window.opera ) {
|
| 305 | + post = post.replace( /\n/g, '' );
|
| 306 | + }
|
| 307 | + range.moveStart( 'character', - post.length - selText.length );
|
| 308 | + range.moveEnd( 'character', - post.length );
|
| 309 | + }
|
| 310 | + range.select();
|
| 311 | + if ( document.documentElement && document.documentElement.scrollTop ) {
|
| 312 | + document.documentElement.scrollTop = winScroll
|
| 313 | + } else if ( document.body ) {
|
| 314 | + document.body.scrollTop = winScroll;
|
| 315 | + }
|
| 316 | + } else if ( e.selectionStart || e.selectionStart == '0' ) {
|
| 317 | + // Mozilla
|
| 318 | + var textScroll = e.scrollTop;
|
| 319 | + $(this).focus();
|
| 320 | + var startPos = e.selectionStart;
|
| 321 | + var endPos = e.selectionEnd;
|
| 322 | + selText = e.value.substring( startPos, endPos );
|
| 323 | + checkSelectedText();
|
| 324 | + e.value = e.value.substring( 0, startPos ) + pre + selText + post +
|
| 325 | + e.value.substring( endPos, e.value.length );
|
| 326 | + if ( isSample ) {
|
| 327 | + e.selectionStart = startPos + pre.length;
|
| 328 | + e.selectionEnd = startPos + pre.length + selText.length;
|
| 329 | + } else {
|
| 330 | + e.selectionStart =
|
| 331 | + startPos + pre.length + selText.length + post.length;
|
| 332 | + e.selectionEnd = e.selectionStart;
|
| 333 | + }
|
| 334 | + e.scrollTop = textScroll;
|
| 335 | + }
|
| 336 | + $(this).trigger( 'encapsulateSelection' );
|
| 337 | +},
|
| 338 | +/**
|
| 339 | + * Ported from Wikia's LinkSuggest extension
|
| 340 | + * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest
|
| 341 | + * Some code copied from
|
| 342 | + * http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/
|
| 343 | + *
|
| 344 | + * Get the position (in resolution of bytes not nessecarily characters)
|
| 345 | + * in a textarea
|
| 346 | + */
|
| 347 | + getCaretPosition: function() {
|
| 348 | + function getCaret( e ) {
|
| 349 | + var caretPos = 0;
|
| 350 | + if($.browser.msie) {
|
| 351 | + // IE Support
|
| 352 | + var postFinished = false;
|
| 353 | + var periFinished = false;
|
| 354 | + var postFinished = false;
|
| 355 | + var preText, rawPreText, periText;
|
| 356 | + var rawPeriText, postText, rawPostText;
|
| 357 | + // Create range containing text in the selection
|
| 358 | + var periRange = document.selection.createRange().duplicate();
|
| 359 | + // Create range containing text before the selection
|
| 360 | + var preRange = document.body.createTextRange();
|
| 361 | + // Select all the text
|
| 362 | + preRange.moveToElementText(e);
|
| 363 | + // Move the end where we need it
|
| 364 | + preRange.setEndPoint("EndToStart", periRange);
|
| 365 | + // Create range containing text after the selection
|
| 366 | + var postRange = document.body.createTextRange();
|
| 367 | + // Select all the text
|
| 368 | + postRange.moveToElementText(e);
|
| 369 | + // Move the start where we need it
|
| 370 | + postRange.setEndPoint("StartToEnd", periRange);
|
| 371 | + // Load the text values we need to compare
|
| 372 | + preText = rawPreText = preRange.text;
|
| 373 | + periText = rawPeriText = periRange.text;
|
| 374 | + postText = rawPostText = postRange.text;
|
| 375 | + /*
|
| 376 | + * Check each range for trimmed newlines by shrinking the range by 1
|
| 377 | + * character and seeing if the text property has changed. If it has
|
| 378 | + * not changed then we know that IE has trimmed a \r\n from the end.
|
| 379 | + */
|
| 380 | + do {
|
| 381 | + if ( !postFinished ) {
|
| 382 | + if ( preRange.
|
| 383 | + compareEndPoints( "StartToEnd", preRange ) == 0 ) {
|
| 384 | + postFinished = true;
|
| 385 | + } else {
|
| 386 | + preRange.moveEnd( "character", -1 )
|
| 387 | + if ( preRange.text == preText ) {
|
| 388 | + rawPreText += "\r\n";
|
| 389 | + } else {
|
| 390 | + postFinished = true;
|
| 391 | + }
|
| 392 | + }
|
| 393 | + }
|
| 394 | + if ( !periFinished ) {
|
| 395 | + if ( periRange.
|
| 396 | + compareEndPoints( "StartToEnd", periRange ) == 0 ) {
|
| 397 | + periFinished = true;
|
| 398 | + } else {
|
| 399 | + periRange.moveEnd( "character", -1 )
|
| 400 | + if ( periRange.text == periText ) {
|
| 401 | + rawPeriText += "\r\n";
|
| 402 | + } else {
|
| 403 | + periFinished = true;
|
| 404 | + }
|
| 405 | + }
|
| 406 | + }
|
| 407 | + if ( !postFinished ) {
|
| 408 | + if ( postRange.
|
| 409 | + compareEndPoints("StartToEnd", postRange) == 0 ) {
|
| 410 | + postFinished = true;
|
| 411 | + } else {
|
| 412 | + postRange.moveEnd( "character", -1 )
|
| 413 | + if ( postRange.text == postText ) {
|
| 414 | + rawPostText += "\r\n";
|
| 415 | + } else {
|
| 416 | + postFinished = true;
|
| 417 | + }
|
| 418 | + }
|
| 419 | + }
|
| 420 | + } while ( ( !postFinished || !periFinished || !postFinished ) );
|
| 421 | + caretPos = rawPreText.replace( /\r\n/g, "\n" ).length;
|
| 422 | + } else if ( e.selectionStart || e.selectionStart == '0' ) {
|
| 423 | + // Firefox support
|
| 424 | + caretPos = e.selectionStart;
|
| 425 | + }
|
| 426 | + return caretPos;
|
| 427 | + }
|
| 428 | + return getCaret( this.get( 0 ) );
|
| 429 | +},
|
| 430 | +/**
|
| 431 | + * Ported from Wikia's LinkSuggest extension
|
| 432 | + * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest
|
| 433 | + *
|
| 434 | + * Scroll a textarea to a certain offset
|
| 435 | + * @param pos Byte offset
|
| 436 | + */
|
| 437 | +scrollToCaretPosition: function( pos ) {
|
| 438 | + function getLineLength( e ) {
|
| 439 | + return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) );
|
| 440 | + }
|
| 441 | + function getCaretScrollPosition( e ) {
|
| 442 | + var text = e.value.replace( /\r/g, "" );
|
| 443 | + var caret = $( e ).getCaretPosition();
|
| 444 | + var lineLength = getLineLength( e );
|
| 445 | + var row = 0;
|
| 446 | + var charInLine = 0;
|
| 447 | + var lastSpaceInLine = 0;
|
| 448 | + for ( i = 0; i < caret; i++ ) {
|
| 449 | + charInLine++;
|
| 450 | + if ( text.charAt( i ) == " " ) {
|
| 451 | + lastSpaceInLine = charInLine;
|
| 452 | + } else if ( text.charAt( i ) == "\n" ) {
|
| 453 | + lastSpaceInLine = 0;
|
| 454 | + charInLine = 0;
|
| 455 | + row++;
|
| 456 | + }
|
| 457 | + if ( charInLine > lineLength ) {
|
| 458 | + if ( lastSpaceInLine > 0 ) {
|
| 459 | + charInLine = charInLine - lastSpaceInLine;
|
| 460 | + lastSpaceInLine = 0;
|
| 461 | + row++;
|
| 462 | + }
|
| 463 | + }
|
| 464 | + }
|
| 465 | + var nextSpace = 0;
|
| 466 | + for ( j = caret; j < caret + lineLength; j++ ) {
|
| 467 | + if (
|
| 468 | + text.charAt( j ) == " " ||
|
| 469 | + text.charAt( j ) == "\n" ||
|
| 470 | + caret == text.length
|
| 471 | + ) {
|
| 472 | + nextSpace = j;
|
| 473 | + break;
|
| 474 | + }
|
| 475 | + }
|
| 476 | + if( nextSpace > lineLength && caret <= lineLength ) {
|
| 477 | + charInLine = caret - lastSpaceInLine;
|
| 478 | + row++;
|
| 479 | + }
|
| 480 | + return (
|
| 481 | + $.os.name == 'mac' ? 13 : ( $.os.name == 'linux' ? 15 : 16 )
|
| 482 | + ) * row;
|
| 483 | + }
|
| 484 | + return this.each(function() {
|
| 485 | + $(this).focus();
|
| 486 | + if ( this.selectionStart || this.selectionStart == '0' ) {
|
| 487 | + // Mozilla
|
| 488 | + this.selectionStart = pos;
|
| 489 | + this.selectionEnd = pos;
|
| 490 | + $(this).scrollTop( getCaretScrollPosition( this ) );
|
| 491 | + } else if ( document.selection && document.selection.createRange ) {
|
| 492 | + // IE / Opera
|
| 493 | + /*
|
| 494 | + * IE automatically scrolls the section to the bottom of the page,
|
| 495 | + * except if it's already in view and the cursor position hasn't
|
| 496 | + * changed, in which case it does nothing. In that case we'll force
|
| 497 | + * it to act by moving one character back and forth.
|
| 498 | + */
|
| 499 | + var range = document.selection.createRange();
|
| 500 | + var oldPos = $(this).getCaretPosition();
|
| 501 | + var goBack = false;
|
| 502 | + if ( oldPos == pos ) {
|
| 503 | + pos++;
|
| 504 | + goBack = true;
|
| 505 | + }
|
| 506 | + range.moveToElementText( this );
|
| 507 | + range.collapse();
|
| 508 | + range.move( 'character', pos );
|
| 509 | + range.select();
|
| 510 | + this.scrollTop += range.offsetTop;
|
| 511 | + if ( goBack ) {
|
| 512 | + range.move( 'character', -1 );
|
| 513 | + range.select();
|
| 514 | + }
|
| 515 | + }
|
| 516 | + $(this).trigger( 'scrollToPosition' );
|
| 517 | + });
|
| 518 | +}
|
| 519 | +
|
| 520 | +} ); } )( jQuery );/**
|
| 521 | + * This plugin provides a way to build a user interface around a textarea. You
|
| 522 | + * can build the UI from a confguration..
|
| 523 | + * $j( 'div#edittoolbar' ).wikiEditor(
|
| 524 | + * { 'modules': { 'toolbar': { ... config ... } } }
|
| 525 | + * );
|
| 526 | + * ...and add modules after it's already been initialized...
|
| 527 | + * $j( 'textarea#wpTextbox1' ).wikiEditor(
|
| 528 | + * 'addModule', 'toc', { ... config ... }
|
| 529 | + * );
|
| 530 | + * ...using the API, which is still be finished.
|
| 531 | + */
|
| 532 | +(function($) {
|
| 533 | +$.wikiEditor = { 'modules': {}, 'instances': [] };
|
| 534 | +$.fn.wikiEditor = function() {
|
| 535 | +
|
| 536 | +/* Initialization */
|
| 537 | +
|
| 538 | +// The wikiEditor context is stored in the element, so when this function
|
| 539 | +// gets called again we can pick up where we left off
|
| 540 | +var context = $(this).data( 'context' );
|
| 541 | +
|
| 542 | +/* API */
|
| 543 | +
|
| 544 | +// The first time this is called, we expect context to be undefined, meaning
|
| 545 | +// the editing ui has not yet been, and still needs to be built, however each
|
| 546 | +// additional call after that is expected to be an API call, which contains a
|
| 547 | +// string as the first argument which corrosponds to a supported api call
|
| 548 | +if ( typeof context !== 'undefined' ) {
|
| 549 | + // Since javascript gives arugments as an object, we need to convert them
|
| 550 | + // so they can be used more easily
|
| 551 | + arguments = $.makeArray( arguments );
|
| 552 | + if ( arguments.length > 0 ) {
|
| 553 | + // Handle API calls
|
| 554 | + var call = arguments.shift();
|
| 555 | + if ( call in context.api ) {
|
| 556 | + context.api[call](
|
| 557 | + context, arguments[0] == undefined ? {} : arguments[0]
|
| 558 | + );
|
| 559 | + }
|
| 560 | + // Store the context for next time and return
|
| 561 | + return $(this).data( 'context', context );
|
| 562 | + }
|
| 563 | + // Nothing to do, just return
|
| 564 | + return $(this);
|
| 565 | +}
|
| 566 | +
|
| 567 | +/* Construction */
|
| 568 | +
|
| 569 | +var instance = $.wikiEditor.instances.length;
|
| 570 | +context = {
|
| 571 | + '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance
|
| 572 | +};
|
| 573 | +$.wikiEditor.instances[instance] = $(this);
|
| 574 | +
|
| 575 | +// Encapsulate the textarea with some containers for layout
|
| 576 | +$(this)
|
| 577 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ) )
|
| 578 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ) )
|
| 579 | + .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ) );
|
| 580 | +// Get a refrence to the outter container
|
| 581 | +context.$ui = $(this).parent().parent().parent();
|
| 582 | +context.$ui.after( $( '<div style="clear:both;"></div>' ) );
|
| 583 | +// Attach a container in the top
|
| 584 | +context.$ui.prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ) );
|
| 585 | +// Create a set of standard methods for internal and external use
|
| 586 | +context.api = {
|
| 587 | + /**
|
| 588 | + * Accepts either a string of the name of a module to add without any
|
| 589 | + * additional configuration parameters, or an object with members keyed with
|
| 590 | + * module names and valued with configuration objects
|
| 591 | + */
|
| 592 | + addModule: function( context, data ) {
|
| 593 | + // A safe way of calling an API function on a module
|
| 594 | + function callModuleApi( module, call, data ) {
|
| 595 | + if (
|
| 596 | + module in $.wikiEditor.modules &&
|
| 597 | + 'fn' in $.wikiEditor.modules[module] &&
|
| 598 | + call in $.wikiEditor.modules[module].fn
|
| 599 | + ) {
|
| 600 | + $.wikiEditor.modules[module].fn[call]( context, data );
|
| 601 | + }
|
| 602 | + }
|
| 603 | + if ( typeof data == 'string' ) {
|
| 604 | + callModuleApi( data, 'create', {} );
|
| 605 | + } else if ( typeof data == 'object' ) {
|
| 606 | + for ( module in data ) {
|
| 607 | + if ( typeof module == 'string' ) {
|
| 608 | + callModuleApi( module, 'create', data[module] );
|
| 609 | + }
|
| 610 | + }
|
| 611 | + }
|
| 612 | + }
|
| 613 | +};
|
| 614 | +// Allow modules to extend the API
|
| 615 | +for ( module in $.wikiEditor.modules ) {
|
| 616 | + if ( 'api' in $.wikiEditor.modules[module] ) {
|
| 617 | + for ( call in $.wikiEditor.modules[module].api ) {
|
| 618 | + // Modules may not overwrite existing API functions - first come,
|
| 619 | + // first serve
|
| 620 | + if ( !( call in context.api ) ) {
|
| 621 | + context.api[call] = $.wikiEditor.modules[module].api[call];
|
| 622 | + }
|
| 623 | + }
|
| 624 | + }
|
| 625 | +}
|
| 626 | +// Each browser seems to do this differently, so let's keep our editor
|
| 627 | +// consistent by allways starting at the begining
|
| 628 | +context.$textarea.scrollToCaretPosition( 0 );
|
| 629 | +// If there was a configuration passed, it's assumed to be for the addModule
|
| 630 | +// API call, so we can just send it on it's way right now
|
| 631 | +if ( arguments.length > 0 && typeof arguments[0] == 'object' ) {
|
| 632 | + context.api.addModule( context, arguments[0] );
|
| 633 | +}
|
| 634 | +// Store the context for next time, and support chaining
|
| 635 | +return $(this).data( 'context', context );;
|
| 636 | +
|
637 | 637 | };})(jQuery);/** |
638 | 638 | * TOC Module for wikiEditor |
639 | 639 | */ |
— | — | @@ -1249,7 +1249,7 @@ |
1250 | 1250 | ) |
1251 | 1251 | ); |
1252 | 1252 | } else { |
1253 | | - sectionQueue[sectionQueue.length] = { |
| 1253 | + s = { |
1254 | 1254 | 'context': context, |
1255 | 1255 | '$sections': $sections, |
1256 | 1256 | '$tabs': $tabs, |
— | — | @@ -1257,23 +1257,7 @@ |
1258 | 1258 | 'config': config[section], |
1259 | 1259 | 'selected': ( selected == section ) |
1260 | 1260 | }; |
1261 | | - } |
1262 | | - } |
1263 | | - $.eachAsync( sectionQueue, { |
1264 | | - 'bulk': 0, |
1265 | | - 'end': function() { |
1266 | | - // HACK: Opera doesn't seem to want to redraw after these bits |
1267 | | - // are added to the DOM, so we can just FORCE it! |
1268 | | - $( 'body' ).css( 'position', 'static' ); |
1269 | | - $( 'body' ).css( 'position', 'relative' ); |
1270 | | - }, |
1271 | | - 'loop': function( i, s ) { |
1272 | | - s.$sections.append( |
1273 | | - $.wikiEditor.modules.toolbar.fn.buildSection( |
1274 | | - s.context, s.section, s.config |
1275 | | - ) |
1276 | | - .css( 'display', s.selected ? 'block' : 'none' ) |
1277 | | - ); |
| 1261 | + sectionQueue[sectionQueue.length] = s; |
1278 | 1262 | s.$tabs.append( |
1279 | 1263 | $( '<span></span>' ) |
1280 | 1264 | .attr( { |
— | — | @@ -1319,6 +1303,24 @@ |
1320 | 1304 | ) |
1321 | 1305 | ); |
1322 | 1306 | } |
| 1307 | + } |
| 1308 | + $.eachAsync( sectionQueue, { |
| 1309 | + 'bulk': 0, |
| 1310 | + 'end': function() { |
| 1311 | + // HACK: Opera doesn't seem to want to redraw after these bits |
| 1312 | + // are added to the DOM, so we can just FORCE it! |
| 1313 | + $( 'body' ).css( 'position', 'static' ); |
| 1314 | + $( 'body' ).css( 'position', 'relative' ); |
| 1315 | + }, |
| 1316 | + 'loop': function( i, s ) { |
| 1317 | + s.$sections.append( |
| 1318 | + $.wikiEditor.modules.toolbar.fn.buildSection( |
| 1319 | + s.context, s.section, s.config |
| 1320 | + ) |
| 1321 | + .css( 'display', s.selected ? 'block' : 'none' ) |
| 1322 | + ); |
| 1323 | + |
| 1324 | + } |
1323 | 1325 | } ); |
1324 | 1326 | } |
1325 | 1327 | } |
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js |
— | — | @@ -1,94 +1,94 @@ |
2 | | - |
3 | | -(function($){$.whileAsync=function(opts) |
4 | | -{var delay=Math.abs(opts.delay)||10,bulk=isNaN(opts.bulk)?500:Math.abs(opts.bulk),test=opts.test||function(){return true;},loop=opts.loop||function(){},end=opts.end||function(){};(function(){var t=false,begin=new Date();while(t=test()) |
5 | | -{loop();if(bulk===0||(new Date()-begin)>bulk) |
6 | | -{break;}} |
7 | | -if(t) |
8 | | -{setTimeout(arguments.callee,delay);} |
9 | | -else |
10 | | -{end();}})();} |
11 | | -$.eachAsync=function(array,opts) |
12 | | -{var i=0,l=array.length,loop=opts.loop||function(){};$.whileAsync($.extend(opts,{test:function(){return i<l;},loop:function() |
13 | | -{var val=array[i];return loop.call(val,i++,val);}}));} |
14 | | -$.fn.eachAsync=function(opts) |
15 | | -{$.eachAsync(this,opts);return this;}})(jQuery);(function($){$.browserTest=function(a,z){var u='unknown',x='X',m=function(r,h){for(var i=0;i<h.length;i=i+1){r=r.replace(h[i][0],h[i][1]);} |
16 | | -return r;},c=function(i,a,b,c){var r={name:m((a.exec(i)||[u,u])[1],b)};r[r.name]=true;r.version=(c.exec(i)||[x,x,x,x])[3];if(r.name.match(/safari/)&&r.version>400){r.version='2.0';} |
17 | | -if(r.name==='presto'){r.version=($.browser.version>9.27)?'futhark':'linear_b';} |
18 | | -r.versionNumber=parseFloat(r.version,10)||0;r.versionX=(r.version!==x)?(r.version+'').substr(0,1):x;r.className=r.name+r.versionX;return r;};a=(a.match(/Opera|Navigator|Minefield|KHTML|Chrome/)?m(a,[[/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/,''],['Chrome Safari','Chrome'],['KHTML','Konqueror'],['Minefield','Firefox'],['Navigator','Netscape']]):a).toLowerCase();$.browser=$.extend((!z)?$.browser:{},c(a,/(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari)/,[],/(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/));$.layout=c(a,/(gecko|konqueror|msie|opera|webkit)/,[['konqueror','khtml'],['msie','trident'],['opera','presto']],/(applewebkit|rv|konqueror|msie)(\:|\/|\s)([a-z0-9\.]*?)(\;|\)|\s)/);$.os={name:(/(win|mac|linux|sunos|solaris|iphone)/.exec(navigator.platform.toLowerCase())||[u])[0].replace('sunos','solaris')};if(!z){$('html').addClass([$.os.name,$.browser.name,$.browser.className,$.layout.name,$.layout.className].join(' '));}};$.browserTest(navigator.userAgent);})(jQuery);jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options.expires=-1;} |
19 | | -var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;} |
20 | | -expires='; expires='+date.toUTCString();} |
21 | | -var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i]);if(cookie.substring(0,name.length+1)==(name+'=')){cookieValue=decodeURIComponent(cookie.substring(name.length+1));break;}}} |
22 | | -return cookieValue;}};(function($){$.fn.extend({encapsulateSelection:function(pre,peri,post){function checkSelectedText(){if(!selText){selText=peri;isSample=true;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' '}} |
23 | | -var e=this.jquery?this[0]:this;var selText;var isSample=false;if(document.selection&&document.selection.createRange){if(document.documentElement&&document.documentElement.scrollTop){var winScroll=document.documentElement.scrollTop;}else if(document.body){var winScroll=document.body.scrollTop;} |
24 | | -$(this).focus();var range=document.selection.createRange();selText=range.text;checkSelectedText();range.text=pre+selText+post;if(isSample&&range.moveStart){if(window.opera){post=post.replace(/\n/g,'');} |
25 | | -range.moveStart('character',-post.length-selText.length);range.moveEnd('character',-post.length);} |
26 | | -range.select();if(document.documentElement&&document.documentElement.scrollTop){document.documentElement.scrollTop=winScroll}else if(document.body){document.body.scrollTop=winScroll;}}else if(e.selectionStart||e.selectionStart=='0'){var textScroll=e.scrollTop;$(this).focus();var startPos=e.selectionStart;var endPos=e.selectionEnd;selText=e.value.substring(startPos,endPos);checkSelectedText();e.value=e.value.substring(0,startPos)+pre+selText+post+ |
27 | | -e.value.substring(endPos,e.value.length);if(isSample){e.selectionStart=startPos+pre.length;e.selectionEnd=startPos+pre.length+selText.length;}else{e.selectionStart=startPos+pre.length+selText.length+post.length;e.selectionEnd=e.selectionStart;} |
28 | | -e.scrollTop=textScroll;} |
29 | | -$(this).trigger('encapsulateSelection');},getCaretPosition:function(){function getCaret(e){var caretPos=0;if($.browser.msie){var postFinished=false;var periFinished=false;var postFinished=false;var preText,rawPreText,periText;var rawPeriText,postText,rawPostText;var periRange=document.selection.createRange().duplicate();var preRange=document.body.createTextRange();preRange.moveToElementText(e);preRange.setEndPoint("EndToStart",periRange);var postRange=document.body.createTextRange();postRange.moveToElementText(e);postRange.setEndPoint("StartToEnd",periRange);preText=rawPreText=preRange.text;periText=rawPeriText=periRange.text;postText=rawPostText=postRange.text;do{if(!postFinished){if(preRange.compareEndPoints("StartToEnd",preRange)==0){postFinished=true;}else{preRange.moveEnd("character",-1) |
30 | | -if(preRange.text==preText){rawPreText+="\r\n";}else{postFinished=true;}}} |
31 | | -if(!periFinished){if(periRange.compareEndPoints("StartToEnd",periRange)==0){periFinished=true;}else{periRange.moveEnd("character",-1) |
32 | | -if(periRange.text==periText){rawPeriText+="\r\n";}else{periFinished=true;}}} |
33 | | -if(!postFinished){if(postRange.compareEndPoints("StartToEnd",postRange)==0){postFinished=true;}else{postRange.moveEnd("character",-1) |
34 | | -if(postRange.text==postText){rawPostText+="\r\n";}else{postFinished=true;}}}}while((!postFinished||!periFinished||!postFinished));caretPos=rawPreText.replace(/\r\n/g,"\n").length;}else if(e.selectionStart||e.selectionStart=='0'){caretPos=e.selectionStart;} |
35 | | -return caretPos;} |
36 | | -return getCaret(this.get(0));},scrollToCaretPosition:function(pos){function getLineLength(e){return Math.floor(e.scrollWidth/($.os.name=='linux'?7:8));} |
37 | | -function getCaretScrollPosition(e){var text=e.value.replace(/\r/g,"");var caret=$(e).getCaretPosition();var lineLength=getLineLength(e);var row=0;var charInLine=0;var lastSpaceInLine=0;for(i=0;i<caret;i++){charInLine++;if(text.charAt(i)==" "){lastSpaceInLine=charInLine;}else if(text.charAt(i)=="\n"){lastSpaceInLine=0;charInLine=0;row++;} |
38 | | -if(charInLine>lineLength){if(lastSpaceInLine>0){charInLine=charInLine-lastSpaceInLine;lastSpaceInLine=0;row++;}}} |
39 | | -var nextSpace=0;for(j=caret;j<caret+lineLength;j++){if(text.charAt(j)==" "||text.charAt(j)=="\n"||caret==text.length){nextSpace=j;break;}} |
40 | | -if(nextSpace>lineLength&&caret<=lineLength){charInLine=caret-lastSpaceInLine;row++;} |
41 | | -return($.os.name=='mac'?13:($.os.name=='linux'?15:16))*row;} |
42 | | -return this.each(function(){$(this).focus();if(this.selectionStart||this.selectionStart=='0'){this.selectionStart=pos;this.selectionEnd=pos;$(this).scrollTop(getCaretScrollPosition(this));}else if(document.selection&&document.selection.createRange){var range=document.selection.createRange();var oldPos=$(this).getCaretPosition();var goBack=false;if(oldPos==pos){pos++;goBack=true;} |
43 | | -range.moveToElementText(this);range.collapse();range.move('character',pos);range.select();this.scrollTop+=range.offsetTop;if(goBack){range.move('character',-1);range.select();}} |
44 | | -$(this).trigger('scrollToPosition');});}});})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[]};$.fn.wikiEditor=function(){var context=$(this).data('context');if(typeof context!=='undefined'){arguments=$.makeArray(arguments);if(arguments.length>0){var call=arguments.shift();if(call in context.api){context.api[call](context,arguments[0]==undefined?{}:arguments[0]);} |
45 | | -return $(this).data('context',context);} |
46 | | -return $(this);} |
47 | | -var instance=$.wikiEditor.instances.length;context={'$textarea':$(this),'modules':{},'data':{},'instance':instance};$.wikiEditor.instances[instance]=$(this);$(this).wrap($('<div></div>').addClass('wikiEditor-ui')).wrap($('<div></div>').addClass('wikiEditor-ui-bottom')).wrap($('<div></div>').addClass('wikiEditor-ui-text'));context.$ui=$(this).parent().parent().parent();context.$ui.after($('<div style="clear:both;"></div>'));context.$ui.prepend($('<div></div>').addClass('wikiEditor-ui-top'));context.api={addModule:function(context,data){function callModuleApi(module,call,data){if(module in $.wikiEditor.modules&&'fn'in $.wikiEditor.modules[module]&&call in $.wikiEditor.modules[module].fn){$.wikiEditor.modules[module].fn[call](context,data);}} |
48 | | -if(typeof data=='string'){callModuleApi(data,'create',{});}else if(typeof data=='object'){for(module in data){if(typeof module=='string'){callModuleApi(module,'create',data[module]);}}}}};for(module in $.wikiEditor.modules){if('api'in $.wikiEditor.modules[module]){for(call in $.wikiEditor.modules[module].api){if(!(call in context.api)){context.api[call]=$.wikiEditor.modules[module].api[call];}}}} |
49 | | -context.$textarea.scrollToCaretPosition(0);if(arguments.length>0&&typeof arguments[0]=='object'){context.api.addModule(context,arguments[0]);} |
50 | | -return $(this).data('context',context);;};})(jQuery);(function($){$.wikiEditor.modules.toc={api:{},fn:{create:function(context,config){if('$toc'in context.modules){return;} |
51 | | -context.modules.$toc=$('<div></div>').addClass('wikiEditor-ui-toc');$.wikiEditor.modules.toc.fn.build(context,config);context.$ui.find('.wikiEditor-ui-bottom').append(context.modules.$toc);context.modules.$toc.height(context.$ui.find('.wikiEditor-ui-bottom').height());context.modules.$toc.css('width','12em');context.$ui.find('.wikiEditor-ui-text').css(($('body.rtl').size()?'marginLeft':'marginRight'),'12em');$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);context.$textarea.bind('keyup encapsulateSelection',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);}});}).bind('mouseup scrollToPosition',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.update(context);}});});},update:function(context){context.modules.$toc.find('a').removeClass('currentSelection');var position=context.$textarea.getCaretPosition();var section=0;if(context.data.outline.length>0){if(!(position<context.data.outline[0].position-1)){while(section<context.data.outline.length&&context.data.outline[section].position-1<position){section++;} |
52 | | -section=Math.max(0,section);} |
53 | | -context.modules.$toc.find('a.section-'+section).addClass('currentSelection');}},build:function(context){function buildStructure(outline,offset,level){if(offset==undefined)offset=0;if(level==undefined)level=1;var sections=[];for(var i=offset;i<outline.length;i++){if(outline[i].nLevel==level){var sub=buildStructure(outline,i+1,level+1);if(sub.length){outline[i].sections=sub;} |
54 | | -sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}} |
55 | | -return sections;} |
56 | | -function buildList(structure){var list=$('<ul></ul>');for(i in structure){var item=$('<li></li>').append($('<a></a>').attr('href','#').addClass('section-'+structure[i].index).data('textbox',context.$textarea).data('position',structure[i].position).click(function(event){$(this).data('textbox').scrollToCaretPosition($(this).data('position'));event.preventDefault();}).text(structure[i].text));if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));} |
57 | | -list.append(item);} |
58 | | -return list;} |
59 | | -var outline=[];var wikitext='\n'+context.$textarea.val()+'\n';var headings=wikitext.match(/\n={1,5}.*={1,5}(?=\n)/g);var offset=0;headings=$.makeArray(headings);for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position;}else if(position==-1){continue;} |
60 | | -text=$.trim(text);var startLevel=0;for(var c=0;c<text.length;c++){if(text.charAt(c)=='='){startLevel++;}else{break;}} |
61 | | -var endLevel=0;for(var c=text.length-1;c>=0;c--){if(text.charAt(c)=='='){endLevel++;}else{break;}} |
62 | | -var level=Math.min(startLevel,endLevel);text=$.trim(text.substr(level,text.length-(level*2)));outline[h]={'text':text,'position':position,'level':level,'index':h+1};} |
63 | | -var lastLevel=0;var nLevel=0;for(var i=0;i<outline.length;i++){if(outline[i].level>lastLevel){nLevel++;} |
64 | | -else if(outline[i].level<lastLevel){nLevel-=Math.max(1,lastLevel-outline[i].level);} |
65 | | -outline[i].nLevel=nLevel;lastLevel=nLevel;} |
66 | | -var structure=buildStructure(outline);structure.unshift({'text':wgTitle,'level':1,'index':0,'position':0});context.modules.$toc.html(buildList(structure));context.data.outline=outline;}}};})(jQuery);(function($){$.wikiEditor.modules.toolbar={imgPath:wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/toolbar/',api:{addToToolbar:function(context,data){},modifyToolbar:function(context,data){},removeFromToolbar:function(context,data){if(typeof data.section=='string'){var selector='div[rel='+data.section+'].section';if(typeof data.group=='string'){selector+=' div[rel='+data.group+'].group';if(typeof data.tool=='string'){selector+=' div[rel='+data.tool+'].tool';}} |
67 | | -context.modules.$toolbar.find(selector).remove();}}},fn:{autoMsg:function(object,property){if(property in object){return object[property];}else if(property+'Msg'in object){return gM(object[property+'Msg']);}else{return'';}},create:function(context,config){if('$toolbar'in context.modules){return;} |
68 | | -context.modules.$toolbar=$('<div></div>').addClass('wikiEditor-ui-toolbar');$.wikiEditor.modules.toolbar.fn.build(context,config);context.$ui.find('.wikiEditor-ui-top').append(context.modules.$toolbar);},doAction:function(context,action){switch(action.type){case'encapsulate':var parts={'pre':'','peri':'','post':''};for(part in parts){if(part+'Msg'in action.options){parts[part]=gM(action.options[part+'Msg'],(action.options[part]||null));}else{parts[part]=(action.options[part]||'')}} |
69 | | -context.$textarea.encapsulateSelection(parts.pre,parts.peri,parts.post);break;default:break;}},buildSection:function(context,id,section){switch(section.type){case'toolbar':return $.wikiEditor.modules.toolbar.fn.buildToolbar(context,id,section);case'booklet':return $.wikiEditor.modules.toolbar.fn.buildBooklet(context,id,section);default:return null;}},buildToolbar:function(context,id,toolbar){var $toolbar=$('<div></div>').attr({'class':'toolbar section section-'+id,'rel':id});if('groups'in toolbar){for(group in toolbar.groups){$toolbar.append($.wikiEditor.modules.toolbar.fn.buildGroup(context,group,toolbar.groups[group]));}} |
70 | | -return $toolbar;},buildGroup:function(context,id,group){var $group=$('<div></div>').attr({'class':'group group-'+id,'rel':id});var label=$.wikiEditor.modules.toolbar.fn.autoMsg(group,'label');if(label){$group.append($('<div></div>').text(label).addClass('label'))} |
71 | | -if('tools'in group){for(tool in group.tools){$group.append($.wikiEditor.modules.toolbar.fn.buildTool(context,tool,group.tools[tool]));}} |
72 | | -return $group;},buildTool:function(context,id,tool){if('filters'in tool){for(filter in tool.filters){if($(tool.filters[filter]).size()==0){return null;}}} |
73 | | -var label=$.wikiEditor.modules.toolbar.fn.autoMsg(tool,'label');switch(tool.type){case'button':$button=$('<img />').attr({'src':$.wikiEditor.modules.toolbar.imgPath+tool.icon,'alt':label,'title':label,'rel':id,'class':'tool tool-'+id});if('action'in tool){$button.data('action',tool.action).data('context',context).click(function(){$.wikiEditor.modules.toolbar.fn.doAction($(this).data('context'),$(this).data('action'));return false;});} |
74 | | -return $button;case'select':var $select=$('<select></select>').attr({'rel':id,'class':'tool tool-'+id});$select.append($('<option></option>').text(label)) |
75 | | -if('list'in tool){$select.data('list',tool.list).data('context',context).click(function(){var list=$(this).data('list');var val=$(this).val();if(val in list&&'action'in list[val]){$.wikiEditor.modules.toolbar.fn.doAction($(this).data('context'),list[val].action);} |
76 | | -$(this).find(":selected").attr('selected',false).find(":first").attr('selected',true);return false;});for(option in tool.list){var optionLabel=$.wikiEditor.modules.toolbar.fn.autoMsg(tool.list[option],'label');$select.append($('<option></option>').text(optionLabel).attr('value',option));}} |
77 | | -return $select;default:return null;}},buildBooklet:function(context,id,booklet){var selected=$.cookie('wikiEditor-'+context.instance+'-booklet-'+id+'-page');var $booklet=$('<div></div>').attr({'class':'booklet section section-'+id,'rel':id});var $pages=$('<div></div>').attr('class','pages');var $index=$('<div></div>').attr('class','index');if('pages'in booklet){if(!(selected in booklet.pages)){selected=null;} |
78 | | -for(page in booklet.pages){if(selected===null){selected=page;} |
79 | | -var $page=$.wikiEditor.modules.toolbar.fn.buildPage(context,page,booklet.pages[page]);var $bookmark=$.wikiEditor.modules.toolbar.fn.buildBookmark(context,page,booklet.pages[page]);if(selected==page){$page.show();$bookmark.addClass('current');}else{$page.hide();} |
80 | | -$pages.append($page);$index.append($bookmark);}} |
81 | | -return $booklet.append($index).append($pages);},buildBookmark:function(context,id,page){var label=$.wikiEditor.modules.toolbar.fn.autoMsg(page,'label');return $('<div></div>').text(label).attr('rel',id).data('context',context).click(function(){$(this).parent().parent().find('.page').hide();$(this).parent().parent().find('.page-'+$(this).attr('rel')).show();$(this).siblings().removeClass('current');$(this).addClass('current');var section=$(this).parent().parent().attr('rel');$.cookie('wikiEditor-'+$(this).data('context').instance+'-booklet-'+section+'-page',$(this).attr('rel'));});},buildPage:function(context,id,page){var $page=$('<div></div>').attr({'class':'page page-'+id,'rel':id});switch(page.layout){case'table':$page.addClass('page-table');var $table=$('<table></table>').attr({'cellpadding':'0','cellspacing':'0','border':'0','width':'100%','class':'table table-'+id});if('headings'in page){var $headings=$('<tr></tr>');for(heading in page.headings){var content=$.wikiEditor.modules.toolbar.fn.autoMsg(page.headings[heading],'content');$headings.append($('<th></th>').text(content));} |
82 | | -$table.append($headings);} |
83 | | -if('rows'in page){for(row in page.rows){var $row=$('<tr></tr>');for(cell in page.rows[row]){var $cell=$('<td></td>').attr({'class':'cell cell-'+cell,'valign':'top'});var content=$.wikiEditor.modules.toolbar.fn.autoMsg(page.rows[row][cell],'content');$cell.append($('<span></span>').html(content));$row.append($cell);} |
84 | | -$table.append($row);}} |
85 | | -$page.append($table);break;case'characters':$page.addClass('page-characters');$characters=$('<div></div>');if('language'in page){$characters.attr('lang',page.language);} |
86 | | -if('direction'in page){$characters.attr('dir',page.direction);} |
87 | | -if('characters'in page){for(character in page.characters){var tool=page.characters[character];if(typeof tool=='string'){tool={'label':tool,'action':{'type':'encapsulate','options':{'pre':tool}}};} |
88 | | -if('action'in tool&&'label'in tool){var $character=$('<a></a>').attr('href','#').text(tool.label).data('context',context).data('action',tool.action).click(function(){$.wikiEditor.modules.toolbar.fn.doAction($(this).data('context'),$(this).data('action'));return false;});$characters.append($character);}} |
89 | | -$page.append($characters);} |
90 | | -break;} |
91 | | -return $page;},build:function(context,config){var $tabs=$('<div></div>').addClass('tabs').appendTo(context.modules.$toolbar);var $sections=$('<div></div>').addClass('sections').appendTo(context.modules.$toolbar);context.modules.$toolbar.append($('<div></div>').addClass('break'));var selected=$.cookie('wikiEditor-'+context.instance+'-toolbar-section');var sectionQueue=[];for(section in config){if(section=='main'){context.modules.$toolbar.prepend($.wikiEditor.modules.toolbar.fn.buildSection(context,section,config[section]));}else{sectionQueue[sectionQueue.length]={'context':context,'$sections':$sections,'$tabs':$tabs,'section':section,'config':config[section],'selected':(selected==section)};}} |
92 | | -$.eachAsync(sectionQueue,{'bulk':0,'end':function(){$('body').css('position','static');$('body').css('position','relative');},'loop':function(i,s){s.$sections.append($.wikiEditor.modules.toolbar.fn.buildSection(s.context,s.section,s.config).css('display',s.selected?'block':'none'));s.$tabs.append($('<span></span>').attr({'class':'tab tab-'+s.section,'rel':s.section}).append($('<a></a>').addClass(s.selected?'current':null).attr('href','#').text($.wikiEditor.modules.toolbar.fn.autoMsg(s.config,'label')).data('context',s.context).click(function(){var $section=$(this).data('context').$ui.find('.section-'+ |
93 | | -$(this).parent().attr('rel'));$(this).blur();var show=$section.css('display')=='none';$section.parent().children().hide();$(this).parent().parent().find('a').removeClass('current');if(show){$section.show();$(this).addClass('current');} |
94 | | -$.cookie('wikiEditor-'+ |
95 | | -$(this).data('context').instance+'-toolbar-section',show?$section.attr('rel'):null);return false;})));}});}}};})(jQuery); |
\ No newline at end of file |
| 2 | +
|
| 3 | +(function($){$.whileAsync=function(opts)
|
| 4 | +{var delay=Math.abs(opts.delay)||10,bulk=isNaN(opts.bulk)?500:Math.abs(opts.bulk),test=opts.test||function(){return true;},loop=opts.loop||function(){},end=opts.end||function(){};(function(){var t=false,begin=new Date();while(t=test())
|
| 5 | +{loop();if(bulk===0||(new Date()-begin)>bulk)
|
| 6 | +{break;}}
|
| 7 | +if(t)
|
| 8 | +{setTimeout(arguments.callee,delay);}
|
| 9 | +else
|
| 10 | +{end();}})();}
|
| 11 | +$.eachAsync=function(array,opts)
|
| 12 | +{var i=0,l=array.length,loop=opts.loop||function(){};$.whileAsync($.extend(opts,{test:function(){return i<l;},loop:function()
|
| 13 | +{var val=array[i];return loop.call(val,i++,val);}}));}
|
| 14 | +$.fn.eachAsync=function(opts)
|
| 15 | +{$.eachAsync(this,opts);return this;}})(jQuery);(function($){$.browserTest=function(a,z){var u='unknown',x='X',m=function(r,h){for(var i=0;i<h.length;i=i+1){r=r.replace(h[i][0],h[i][1]);}
|
| 16 | +return r;},c=function(i,a,b,c){var r={name:m((a.exec(i)||[u,u])[1],b)};r[r.name]=true;r.version=(c.exec(i)||[x,x,x,x])[3];if(r.name.match(/safari/)&&r.version>400){r.version='2.0';}
|
| 17 | +if(r.name==='presto'){r.version=($.browser.version>9.27)?'futhark':'linear_b';}
|
| 18 | +r.versionNumber=parseFloat(r.version,10)||0;r.versionX=(r.version!==x)?(r.version+'').substr(0,1):x;r.className=r.name+r.versionX;return r;};a=(a.match(/Opera|Navigator|Minefield|KHTML|Chrome/)?m(a,[[/(Firefox|MSIE|KHTML,\slike\sGecko|Konqueror)/,''],['Chrome Safari','Chrome'],['KHTML','Konqueror'],['Minefield','Firefox'],['Navigator','Netscape']]):a).toLowerCase();$.browser=$.extend((!z)?$.browser:{},c(a,/(camino|chrome|firefox|netscape|konqueror|lynx|msie|opera|safari)/,[],/(camino|chrome|firefox|netscape|netscape6|opera|version|konqueror|lynx|msie|safari)(\/|\s)([a-z0-9\.\+]*?)(\;|dev|rel|\s|$)/));$.layout=c(a,/(gecko|konqueror|msie|opera|webkit)/,[['konqueror','khtml'],['msie','trident'],['opera','presto']],/(applewebkit|rv|konqueror|msie)(\:|\/|\s)([a-z0-9\.]*?)(\;|\)|\s)/);$.os={name:(/(win|mac|linux|sunos|solaris|iphone)/.exec(navigator.platform.toLowerCase())||[u])[0].replace('sunos','solaris')};if(!z){$('html').addClass([$.os.name,$.browser.name,$.browser.className,$.layout.name,$.layout.className].join(' '));}};$.browserTest(navigator.userAgent);})(jQuery);jQuery.cookie=function(name,value,options){if(typeof value!='undefined'){options=options||{};if(value===null){value='';options.expires=-1;}
|
| 19 | +var expires='';if(options.expires&&(typeof options.expires=='number'||options.expires.toUTCString)){var date;if(typeof options.expires=='number'){date=new Date();date.setTime(date.getTime()+(options.expires*24*60*60*1000));}else{date=options.expires;}
|
| 20 | +expires='; expires='+date.toUTCString();}
|
| 21 | +var path=options.path?'; path='+(options.path):'';var domain=options.domain?'; domain='+(options.domain):'';var secure=options.secure?'; secure':'';document.cookie=[name,'=',encodeURIComponent(value),expires,path,domain,secure].join('');}else{var cookieValue=null;if(document.cookie&&document.cookie!=''){var cookies=document.cookie.split(';');for(var i=0;i<cookies.length;i++){var cookie=jQuery.trim(cookies[i]);if(cookie.substring(0,name.length+1)==(name+'=')){cookieValue=decodeURIComponent(cookie.substring(name.length+1));break;}}}
|
| 22 | +return cookieValue;}};(function($){$.fn.extend({encapsulateSelection:function(pre,peri,post){function checkSelectedText(){if(!selText){selText=peri;isSample=true;}else if(selText.charAt(selText.length-1)==' '){selText=selText.substring(0,selText.length-1);post+=' '}}
|
| 23 | +var e=this.jquery?this[0]:this;var selText;var isSample=false;if(document.selection&&document.selection.createRange){if(document.documentElement&&document.documentElement.scrollTop){var winScroll=document.documentElement.scrollTop;}else if(document.body){var winScroll=document.body.scrollTop;}
|
| 24 | +$(this).focus();var range=document.selection.createRange();selText=range.text;checkSelectedText();range.text=pre+selText+post;if(isSample&&range.moveStart){if(window.opera){post=post.replace(/\n/g,'');}
|
| 25 | +range.moveStart('character',-post.length-selText.length);range.moveEnd('character',-post.length);}
|
| 26 | +range.select();if(document.documentElement&&document.documentElement.scrollTop){document.documentElement.scrollTop=winScroll}else if(document.body){document.body.scrollTop=winScroll;}}else if(e.selectionStart||e.selectionStart=='0'){var textScroll=e.scrollTop;$(this).focus();var startPos=e.selectionStart;var endPos=e.selectionEnd;selText=e.value.substring(startPos,endPos);checkSelectedText();e.value=e.value.substring(0,startPos)+pre+selText+post+
|
| 27 | +e.value.substring(endPos,e.value.length);if(isSample){e.selectionStart=startPos+pre.length;e.selectionEnd=startPos+pre.length+selText.length;}else{e.selectionStart=startPos+pre.length+selText.length+post.length;e.selectionEnd=e.selectionStart;}
|
| 28 | +e.scrollTop=textScroll;}
|
| 29 | +$(this).trigger('encapsulateSelection');},getCaretPosition:function(){function getCaret(e){var caretPos=0;if($.browser.msie){var postFinished=false;var periFinished=false;var postFinished=false;var preText,rawPreText,periText;var rawPeriText,postText,rawPostText;var periRange=document.selection.createRange().duplicate();var preRange=document.body.createTextRange();preRange.moveToElementText(e);preRange.setEndPoint("EndToStart",periRange);var postRange=document.body.createTextRange();postRange.moveToElementText(e);postRange.setEndPoint("StartToEnd",periRange);preText=rawPreText=preRange.text;periText=rawPeriText=periRange.text;postText=rawPostText=postRange.text;do{if(!postFinished){if(preRange.compareEndPoints("StartToEnd",preRange)==0){postFinished=true;}else{preRange.moveEnd("character",-1)
|
| 30 | +if(preRange.text==preText){rawPreText+="\r\n";}else{postFinished=true;}}}
|
| 31 | +if(!periFinished){if(periRange.compareEndPoints("StartToEnd",periRange)==0){periFinished=true;}else{periRange.moveEnd("character",-1)
|
| 32 | +if(periRange.text==periText){rawPeriText+="\r\n";}else{periFinished=true;}}}
|
| 33 | +if(!postFinished){if(postRange.compareEndPoints("StartToEnd",postRange)==0){postFinished=true;}else{postRange.moveEnd("character",-1)
|
| 34 | +if(postRange.text==postText){rawPostText+="\r\n";}else{postFinished=true;}}}}while((!postFinished||!periFinished||!postFinished));caretPos=rawPreText.replace(/\r\n/g,"\n").length;}else if(e.selectionStart||e.selectionStart=='0'){caretPos=e.selectionStart;}
|
| 35 | +return caretPos;}
|
| 36 | +return getCaret(this.get(0));},scrollToCaretPosition:function(pos){function getLineLength(e){return Math.floor(e.scrollWidth/($.os.name=='linux'?7:8));}
|
| 37 | +function getCaretScrollPosition(e){var text=e.value.replace(/\r/g,"");var caret=$(e).getCaretPosition();var lineLength=getLineLength(e);var row=0;var charInLine=0;var lastSpaceInLine=0;for(i=0;i<caret;i++){charInLine++;if(text.charAt(i)==" "){lastSpaceInLine=charInLine;}else if(text.charAt(i)=="\n"){lastSpaceInLine=0;charInLine=0;row++;}
|
| 38 | +if(charInLine>lineLength){if(lastSpaceInLine>0){charInLine=charInLine-lastSpaceInLine;lastSpaceInLine=0;row++;}}}
|
| 39 | +var nextSpace=0;for(j=caret;j<caret+lineLength;j++){if(text.charAt(j)==" "||text.charAt(j)=="\n"||caret==text.length){nextSpace=j;break;}}
|
| 40 | +if(nextSpace>lineLength&&caret<=lineLength){charInLine=caret-lastSpaceInLine;row++;}
|
| 41 | +return($.os.name=='mac'?13:($.os.name=='linux'?15:16))*row;}
|
| 42 | +return this.each(function(){$(this).focus();if(this.selectionStart||this.selectionStart=='0'){this.selectionStart=pos;this.selectionEnd=pos;$(this).scrollTop(getCaretScrollPosition(this));}else if(document.selection&&document.selection.createRange){var range=document.selection.createRange();var oldPos=$(this).getCaretPosition();var goBack=false;if(oldPos==pos){pos++;goBack=true;}
|
| 43 | +range.moveToElementText(this);range.collapse();range.move('character',pos);range.select();this.scrollTop+=range.offsetTop;if(goBack){range.move('character',-1);range.select();}}
|
| 44 | +$(this).trigger('scrollToPosition');});}});})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[]};$.fn.wikiEditor=function(){var context=$(this).data('context');if(typeof context!=='undefined'){arguments=$.makeArray(arguments);if(arguments.length>0){var call=arguments.shift();if(call in context.api){context.api[call](context,arguments[0]==undefined?{}:arguments[0]);}
|
| 45 | +return $(this).data('context',context);}
|
| 46 | +return $(this);}
|
| 47 | +var instance=$.wikiEditor.instances.length;context={'$textarea':$(this),'modules':{},'data':{},'instance':instance};$.wikiEditor.instances[instance]=$(this);$(this).wrap($('<div></div>').addClass('wikiEditor-ui')).wrap($('<div></div>').addClass('wikiEditor-ui-bottom')).wrap($('<div></div>').addClass('wikiEditor-ui-text'));context.$ui=$(this).parent().parent().parent();context.$ui.after($('<div style="clear:both;"></div>'));context.$ui.prepend($('<div></div>').addClass('wikiEditor-ui-top'));context.api={addModule:function(context,data){function callModuleApi(module,call,data){if(module in $.wikiEditor.modules&&'fn'in $.wikiEditor.modules[module]&&call in $.wikiEditor.modules[module].fn){$.wikiEditor.modules[module].fn[call](context,data);}}
|
| 48 | +if(typeof data=='string'){callModuleApi(data,'create',{});}else if(typeof data=='object'){for(module in data){if(typeof module=='string'){callModuleApi(module,'create',data[module]);}}}}};for(module in $.wikiEditor.modules){if('api'in $.wikiEditor.modules[module]){for(call in $.wikiEditor.modules[module].api){if(!(call in context.api)){context.api[call]=$.wikiEditor.modules[module].api[call];}}}}
|
| 49 | +context.$textarea.scrollToCaretPosition(0);if(arguments.length>0&&typeof arguments[0]=='object'){context.api.addModule(context,arguments[0]);}
|
| 50 | +return $(this).data('context',context);;};})(jQuery);(function($){$.wikiEditor.modules.toc={api:{},fn:{create:function(context,config){if('$toc'in context.modules){return;}
|
| 51 | +context.modules.$toc=$('<div></div>').addClass('wikiEditor-ui-toc');$.wikiEditor.modules.toc.fn.build(context,config);context.$ui.find('.wikiEditor-ui-bottom').append(context.modules.$toc);context.modules.$toc.height(context.$ui.find('.wikiEditor-ui-bottom').height());context.modules.$toc.css('width','12em');context.$ui.find('.wikiEditor-ui-text').css(($('body.rtl').size()?'marginLeft':'marginRight'),'12em');$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);context.$textarea.bind('keyup encapsulateSelection',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);}});}).bind('mouseup scrollToPosition',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.update(context);}});});},update:function(context){context.modules.$toc.find('a').removeClass('currentSelection');var position=context.$textarea.getCaretPosition();var section=0;if(context.data.outline.length>0){if(!(position<context.data.outline[0].position-1)){while(section<context.data.outline.length&&context.data.outline[section].position-1<position){section++;}
|
| 52 | +section=Math.max(0,section);}
|
| 53 | +context.modules.$toc.find('a.section-'+section).addClass('currentSelection');}},build:function(context){function buildStructure(outline,offset,level){if(offset==undefined)offset=0;if(level==undefined)level=1;var sections=[];for(var i=offset;i<outline.length;i++){if(outline[i].nLevel==level){var sub=buildStructure(outline,i+1,level+1);if(sub.length){outline[i].sections=sub;}
|
| 54 | +sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}}
|
| 55 | +return sections;}
|
| 56 | +function buildList(structure){var list=$('<ul></ul>');for(i in structure){var item=$('<li></li>').append($('<a></a>').attr('href','#').addClass('section-'+structure[i].index).data('textbox',context.$textarea).data('position',structure[i].position).click(function(event){$(this).data('textbox').scrollToCaretPosition($(this).data('position'));event.preventDefault();}).text(structure[i].text));if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));}
|
| 57 | +list.append(item);}
|
| 58 | +return list;}
|
| 59 | +var outline=[];var wikitext='\n'+context.$textarea.val()+'\n';var headings=wikitext.match(/\n={1,5}.*={1,5}(?=\n)/g);var offset=0;headings=$.makeArray(headings);for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position;}else if(position==-1){continue;}
|
| 60 | +text=$.trim(text);var startLevel=0;for(var c=0;c<text.length;c++){if(text.charAt(c)=='='){startLevel++;}else{break;}}
|
| 61 | +var endLevel=0;for(var c=text.length-1;c>=0;c--){if(text.charAt(c)=='='){endLevel++;}else{break;}}
|
| 62 | +var level=Math.min(startLevel,endLevel);text=$.trim(text.substr(level,text.length-(level*2)));outline[h]={'text':text,'position':position,'level':level,'index':h+1};}
|
| 63 | +var lastLevel=0;var nLevel=0;for(var i=0;i<outline.length;i++){if(outline[i].level>lastLevel){nLevel++;}
|
| 64 | +else if(outline[i].level<lastLevel){nLevel-=Math.max(1,lastLevel-outline[i].level);}
|
| 65 | +outline[i].nLevel=nLevel;lastLevel=nLevel;}
|
| 66 | +var structure=buildStructure(outline);structure.unshift({'text':wgTitle,'level':1,'index':0,'position':0});context.modules.$toc.html(buildList(structure));context.data.outline=outline;}}};})(jQuery);(function($){$.wikiEditor.modules.toolbar={imgPath:wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/toolbar/',api:{addToToolbar:function(context,data){},modifyToolbar:function(context,data){},removeFromToolbar:function(context,data){if(typeof data.section=='string'){var selector='div[rel='+data.section+'].section';if(typeof data.group=='string'){selector+=' div[rel='+data.group+'].group';if(typeof data.tool=='string'){selector+=' div[rel='+data.tool+'].tool';}}
|
| 67 | +context.modules.$toolbar.find(selector).remove();}}},fn:{autoMsg:function(object,property){if(property in object){return object[property];}else if(property+'Msg'in object){return gM(object[property+'Msg']);}else{return'';}},create:function(context,config){if('$toolbar'in context.modules){return;}
|
| 68 | +context.modules.$toolbar=$('<div></div>').addClass('wikiEditor-ui-toolbar');$.wikiEditor.modules.toolbar.fn.build(context,config);context.$ui.find('.wikiEditor-ui-top').append(context.modules.$toolbar);},doAction:function(context,action){switch(action.type){case'encapsulate':var parts={'pre':'','peri':'','post':''};for(part in parts){if(part+'Msg'in action.options){parts[part]=gM(action.options[part+'Msg'],(action.options[part]||null));}else{parts[part]=(action.options[part]||'')}}
|
| 69 | +context.$textarea.encapsulateSelection(parts.pre,parts.peri,parts.post);break;default:break;}},buildSection:function(context,id,section){switch(section.type){case'toolbar':return $.wikiEditor.modules.toolbar.fn.buildToolbar(context,id,section);case'booklet':return $.wikiEditor.modules.toolbar.fn.buildBooklet(context,id,section);default:return null;}},buildToolbar:function(context,id,toolbar){var $toolbar=$('<div></div>').attr({'class':'toolbar section section-'+id,'rel':id});if('groups'in toolbar){for(group in toolbar.groups){$toolbar.append($.wikiEditor.modules.toolbar.fn.buildGroup(context,group,toolbar.groups[group]));}}
|
| 70 | +return $toolbar;},buildGroup:function(context,id,group){var $group=$('<div></div>').attr({'class':'group group-'+id,'rel':id});var label=$.wikiEditor.modules.toolbar.fn.autoMsg(group,'label');if(label){$group.append($('<div></div>').text(label).addClass('label'))}
|
| 71 | +if('tools'in group){for(tool in group.tools){$group.append($.wikiEditor.modules.toolbar.fn.buildTool(context,tool,group.tools[tool]));}}
|
| 72 | +return $group;},buildTool:function(context,id,tool){if('filters'in tool){for(filter in tool.filters){if($(tool.filters[filter]).size()==0){return null;}}}
|
| 73 | +var label=$.wikiEditor.modules.toolbar.fn.autoMsg(tool,'label');switch(tool.type){case'button':$button=$('<img />').attr({'src':$.wikiEditor.modules.toolbar.imgPath+tool.icon,'alt':label,'title':label,'rel':id,'class':'tool tool-'+id});if('action'in tool){$button.data('action',tool.action).data('context',context).click(function(){$.wikiEditor.modules.toolbar.fn.doAction($(this).data('context'),$(this).data('action'));return false;});}
|
| 74 | +return $button;case'select':var $select=$('<select></select>').attr({'rel':id,'class':'tool tool-'+id});$select.append($('<option></option>').text(label))
|
| 75 | +if('list'in tool){$select.data('list',tool.list).data('context',context).click(function(){var list=$(this).data('list');var val=$(this).val();if(val in list&&'action'in list[val]){$.wikiEditor.modules.toolbar.fn.doAction($(this).data('context'),list[val].action);}
|
| 76 | +$(this).find(":selected").attr('selected',false).find(":first").attr('selected',true);return false;});for(option in tool.list){var optionLabel=$.wikiEditor.modules.toolbar.fn.autoMsg(tool.list[option],'label');$select.append($('<option></option>').text(optionLabel).attr('value',option));}}
|
| 77 | +return $select;default:return null;}},buildBooklet:function(context,id,booklet){var selected=$.cookie('wikiEditor-'+context.instance+'-booklet-'+id+'-page');var $booklet=$('<div></div>').attr({'class':'booklet section section-'+id,'rel':id});var $pages=$('<div></div>').attr('class','pages');var $index=$('<div></div>').attr('class','index');if('pages'in booklet){if(!(selected in booklet.pages)){selected=null;}
|
| 78 | +for(page in booklet.pages){if(selected===null){selected=page;}
|
| 79 | +var $page=$.wikiEditor.modules.toolbar.fn.buildPage(context,page,booklet.pages[page]);var $bookmark=$.wikiEditor.modules.toolbar.fn.buildBookmark(context,page,booklet.pages[page]);if(selected==page){$page.show();$bookmark.addClass('current');}else{$page.hide();}
|
| 80 | +$pages.append($page);$index.append($bookmark);}}
|
| 81 | +return $booklet.append($index).append($pages);},buildBookmark:function(context,id,page){var label=$.wikiEditor.modules.toolbar.fn.autoMsg(page,'label');return $('<div></div>').text(label).attr('rel',id).data('context',context).click(function(){$(this).parent().parent().find('.page').hide();$(this).parent().parent().find('.page-'+$(this).attr('rel')).show();$(this).siblings().removeClass('current');$(this).addClass('current');var section=$(this).parent().parent().attr('rel');$.cookie('wikiEditor-'+$(this).data('context').instance+'-booklet-'+section+'-page',$(this).attr('rel'));});},buildPage:function(context,id,page){var $page=$('<div></div>').attr({'class':'page page-'+id,'rel':id});switch(page.layout){case'table':$page.addClass('page-table');var $table=$('<table></table>').attr({'cellpadding':'0','cellspacing':'0','border':'0','width':'100%','class':'table table-'+id});if('headings'in page){var $headings=$('<tr></tr>');for(heading in page.headings){var content=$.wikiEditor.modules.toolbar.fn.autoMsg(page.headings[heading],'content');$headings.append($('<th></th>').text(content));}
|
| 82 | +$table.append($headings);}
|
| 83 | +if('rows'in page){for(row in page.rows){var $row=$('<tr></tr>');for(cell in page.rows[row]){var $cell=$('<td></td>').attr({'class':'cell cell-'+cell,'valign':'top'});var content=$.wikiEditor.modules.toolbar.fn.autoMsg(page.rows[row][cell],'content');$cell.append($('<span></span>').html(content));$row.append($cell);}
|
| 84 | +$table.append($row);}}
|
| 85 | +$page.append($table);break;case'characters':$page.addClass('page-characters');$characters=$('<div></div>');if('language'in page){$characters.attr('lang',page.language);}
|
| 86 | +if('direction'in page){$characters.attr('dir',page.direction);}
|
| 87 | +if('characters'in page){for(character in page.characters){var tool=page.characters[character];if(typeof tool=='string'){tool={'label':tool,'action':{'type':'encapsulate','options':{'pre':tool}}};}
|
| 88 | +if('action'in tool&&'label'in tool){var $character=$('<a></a>').attr('href','#').text(tool.label).data('context',context).data('action',tool.action).click(function(){$.wikiEditor.modules.toolbar.fn.doAction($(this).data('context'),$(this).data('action'));return false;});$characters.append($character);}}
|
| 89 | +$page.append($characters);}
|
| 90 | +break;}
|
| 91 | +return $page;},build:function(context,config){var $tabs=$('<div></div>').addClass('tabs').appendTo(context.modules.$toolbar);var $sections=$('<div></div>').addClass('sections').appendTo(context.modules.$toolbar);context.modules.$toolbar.append($('<div></div>').addClass('break'));var selected=$.cookie('wikiEditor-'+context.instance+'-toolbar-section');var sectionQueue=[];for(section in config){if(section=='main'){context.modules.$toolbar.prepend($.wikiEditor.modules.toolbar.fn.buildSection(context,section,config[section]));}else{s={'context':context,'$sections':$sections,'$tabs':$tabs,'section':section,'config':config[section],'selected':(selected==section)};sectionQueue[sectionQueue.length]=s;s.$tabs.append($('<span></span>').attr({'class':'tab tab-'+s.section,'rel':s.section}).append($('<a></a>').addClass(s.selected?'current':null).attr('href','#').text($.wikiEditor.modules.toolbar.fn.autoMsg(s.config,'label')).data('context',s.context).click(function(){var $section=$(this).data('context').$ui.find('.section-'+
|
| 92 | +$(this).parent().attr('rel'));$(this).blur();var show=$section.css('display')=='none';$section.parent().children().hide();$(this).parent().parent().find('a').removeClass('current');if(show){$section.show();$(this).addClass('current');}
|
| 93 | +$.cookie('wikiEditor-'+
|
| 94 | +$(this).data('context').instance+'-toolbar-section',show?$section.attr('rel'):null);return false;})));}}
|
| 95 | +$.eachAsync(sectionQueue,{'bulk':0,'end':function(){$('body').css('position','static');$('body').css('position','relative');},'loop':function(i,s){s.$sections.append($.wikiEditor.modules.toolbar.fn.buildSection(s.context,s.section,s.config).css('display',s.selected?'block':'none'));}});}}};})(jQuery); |
\ No newline at end of file |