Index: trunk/extensions/Narayam/css/ext.narayam.core.css |
— | — | @@ -4,10 +4,135 @@ |
5 | 5 | * about styling this nicely |
6 | 6 | */ |
7 | 7 | background-color: #EAF3F8 !important; |
8 | | - border: 2px inset #FDBBBB !important; |
9 | 8 | } |
10 | 9 | |
11 | 10 | .narayam-wrapper { |
12 | 11 | padding: 0; |
13 | 12 | margin: 0; |
14 | 13 | } |
| 14 | + |
| 15 | + |
| 16 | +li#pt-narayam{ |
| 17 | + padding-left: 15px !important; |
| 18 | +} |
| 19 | + |
| 20 | +/* Variants and Actions */ |
| 21 | +/* @noflip */ |
| 22 | +div#narayam-menu { |
| 23 | + direction: ltr; |
| 24 | + float: left; |
| 25 | + cursor: pointer; |
| 26 | +} |
| 27 | +div.narayam-menuFocus { |
| 28 | + background-position: -22px 60%; |
| 29 | +} |
| 30 | +/* @noflip */ |
| 31 | +body.rtl div#narayam-menu { |
| 32 | + direction: rtl; |
| 33 | +} |
| 34 | +div#narayam-menu div.menu-items { |
| 35 | + position: relative; |
| 36 | + display: none; |
| 37 | + clear: both; |
| 38 | + text-align: left; |
| 39 | + z-index: 99999; |
| 40 | +} |
| 41 | + |
| 42 | +div#narayam-menu-items li{ |
| 43 | + margin: 0; |
| 44 | + padding: 5px; |
| 45 | + font-size: 100%; |
| 46 | + float: none; |
| 47 | + z-index: 99999; |
| 48 | + |
| 49 | +} |
| 50 | +ul#imelist{ |
| 51 | + padding: 5px; |
| 52 | +} |
| 53 | +/* OVERRIDDEN BY COMPLIANT BROWSERS */ |
| 54 | +/* @noflip */ |
| 55 | +body.rtl div#narayam-menu div.menu-items { |
| 56 | + margin-left: 24px; |
| 57 | +} |
| 58 | +/* IGNORED BY IE6 */ |
| 59 | +/* @noflip */ |
| 60 | +body.rtl div#narayam-menu > div.menu-items { |
| 61 | + margin-left: auto; |
| 62 | +} |
| 63 | +/* IGNORED BY IE6 */ |
| 64 | +/* Also fixes old versions of FireFox */ |
| 65 | +/* @noflip */ |
| 66 | +body.rtl div#narayam-menu > div.menu-items, |
| 67 | +x:-moz-any-link { |
| 68 | + margin-left: 23px; |
| 69 | +} |
| 70 | +/* Enable forcing showing of the menu for accessibility */ |
| 71 | +div#narayam-menu:hover div.menu-items, div#narayam-menu div.menuForceShow { |
| 72 | + display: block; |
| 73 | +} |
| 74 | +div#narayam-menu ul { |
| 75 | + position: absolute; |
| 76 | + background-color: white; |
| 77 | + border: solid 1px silver; |
| 78 | + border-top-width: 0; |
| 79 | + list-style: none; |
| 80 | + list-style-image: none; |
| 81 | + list-style-type: none; |
| 82 | + padding: 0; |
| 83 | + margin: 0; |
| 84 | + margin-left: -1px; |
| 85 | + text-align: left; |
| 86 | +} |
| 87 | +/* Fixes old versions of FireFox */ |
| 88 | +div#narayam-menu ul, |
| 89 | +x:-moz-any-link { |
| 90 | + min-width: 5em; |
| 91 | +} |
| 92 | +/* Returns things back to normal in modern versions of FireFox */ |
| 93 | +div#narayam-menu ul, |
| 94 | +x:-moz-any-link, |
| 95 | +x:default { |
| 96 | + min-width: 0; |
| 97 | +} |
| 98 | +div#narayam-menu li { |
| 99 | +/* padding: 0;*/ |
| 100 | + margin: 0; |
| 101 | + text-align: left; |
| 102 | + line-height: 1em; |
| 103 | +} |
| 104 | +/* OVERRIDDEN BY COMPLIANT BROWSERS */ |
| 105 | +div#narayam-menu li a { |
| 106 | + display: inline-block; |
| 107 | + padding: 0.5em; |
| 108 | + white-space: nowrap; |
| 109 | + color: #0645ad; |
| 110 | + cursor: pointer; |
| 111 | +/* font-size: 0.8em;*/ |
| 112 | +} |
| 113 | +/* IGNORED BY IE6 */ |
| 114 | +div#narayam-menu li > a { |
| 115 | + display: block; |
| 116 | +} |
| 117 | +div#narayam-menu li.selected a, |
| 118 | +div#narayam-menu li.selected a:visited { |
| 119 | + color: #333333; |
| 120 | + text-decoration: none; |
| 121 | +} |
| 122 | +div#narayam-menu a { |
| 123 | + display: block; |
| 124 | + padding-left:5px; |
| 125 | + padding-right:5px; |
| 126 | +} |
| 127 | + |
| 128 | +div#narayam-menu-items li.narayam-help-link a { |
| 129 | + background: url('../images/help.png') no-repeat scroll left center transparent; |
| 130 | + padding-left: 15px; |
| 131 | +} |
| 132 | + |
| 133 | +li.narayam-active { |
| 134 | + background: url('../images/narayam-active.png') no-repeat scroll left top transparent; |
| 135 | +} |
| 136 | + |
| 137 | +li.narayam-inactive { |
| 138 | + background: url('../images/narayam-inactive.png') no-repeat scroll left top transparent; |
| 139 | +} |
\ No newline at end of file |
Index: trunk/extensions/Narayam/Narayam.i18n.php |
— | — | @@ -15,7 +15,10 @@ |
16 | 16 | */ |
17 | 17 | $messages['en'] = array( |
18 | 18 | 'narayam-desc' => 'Allows to add custom input methods for input fields', |
19 | | - 'narayam-toggle-ime' => 'To toggle IM ($1)', // FIXME: better message |
| 19 | + 'narayam-toggle-ime' => 'Enable ($1)', |
| 20 | + 'narayam-menu' => 'Input Method', |
| 21 | + 'narayam-menu-tooltip' => 'Control Narayam Input Method Editor (IME)', |
| 22 | + 'narayam-help' => 'Help', |
20 | 23 | 'narayam-help-page' => 'Help:Typing', |
21 | 24 | 'narayam-checkbox-tooltip' => 'To toggle input method on and off', // FIXME: better message |
22 | 25 | 'narayam-disable-preference' => 'Disable Narayam Input Method Editor (IME)', |
Index: trunk/extensions/Narayam/js/ext.narayam.core.js |
— | — | @@ -16,13 +16,11 @@ |
17 | 17 | ( function( $ ) { |
18 | 18 | $.narayam = new ( function() { |
19 | 19 | /* Private members */ |
20 | | - |
| 20 | + |
21 | 21 | // Reference to this object |
22 | 22 | var that = this; |
23 | 23 | // jQuery array holding all text inputs Narayam applies to |
24 | 24 | var $inputs = $( [] ); |
25 | | - // Input method dropdown |
26 | | - var $select = $( [] ); |
27 | 25 | // Whether Narayam is enabled |
28 | 26 | var enabled = false; |
29 | 27 | // Registered schemes |
— | — | @@ -41,9 +39,9 @@ |
42 | 40 | shiftKey: false, |
43 | 41 | key: null |
44 | 42 | }; |
45 | | - |
| 43 | + |
46 | 44 | /* Private functions */ |
47 | | - |
| 45 | + |
48 | 46 | /** |
49 | 47 | * Transliterate a string using the current scheme |
50 | 48 | * @param str String to transliterate |
— | — | @@ -68,7 +66,7 @@ |
69 | 67 | // No matches, return the input |
70 | 68 | return str; |
71 | 69 | } |
72 | | - |
| 70 | + |
73 | 71 | /** |
74 | 72 | * Get the n characters in str that immediately precede pos |
75 | 73 | * Example: lastNChars( "foobarbaz", 5, 2 ) == "ba" |
— | — | @@ -87,7 +85,7 @@ |
88 | 86 | return str.substr( pos - n, n); |
89 | 87 | } |
90 | 88 | } |
91 | | - |
| 89 | + |
92 | 90 | /** |
93 | 91 | * Find the point at which a and b diverge, i.e. the first position |
94 | 92 | * at which they don't have matching characters. |
— | — | @@ -104,7 +102,7 @@ |
105 | 103 | } |
106 | 104 | return -1; |
107 | 105 | } |
108 | | - |
| 106 | + |
109 | 107 | /** |
110 | 108 | * Check whether a keypress event corresponds to the shortcut key |
111 | 109 | * @param e Event object |
— | — | @@ -116,7 +114,7 @@ |
117 | 115 | e.shiftKey == shortcutKey.shiftKey && |
118 | 116 | String.fromCharCode( e.which ).toLowerCase() == shortcutKey.key.toLowerCase(); |
119 | 117 | } |
120 | | - |
| 118 | + |
121 | 119 | /** |
122 | 120 | * Get a description of the shortcut key, e.g. "Ctrl-M" |
123 | 121 | * @return string |
— | — | @@ -136,7 +134,7 @@ |
137 | 135 | text += shortcutKey.key.toUpperCase(); |
138 | 136 | return text; |
139 | 137 | } |
140 | | - |
| 138 | + |
141 | 139 | /** |
142 | 140 | * Change visual appearance of element (text input, textarea) according |
143 | 141 | * current state of Narayam |
— | — | @@ -150,7 +148,7 @@ |
151 | 149 | $element.removeClass( 'narayam-input' ); |
152 | 150 | } |
153 | 151 | } |
154 | | - |
| 152 | + |
155 | 153 | /** |
156 | 154 | * Keydown event handler. Handles shortcut key presses |
157 | 155 | * @param e Event object |
— | — | @@ -168,7 +166,7 @@ |
169 | 167 | } |
170 | 168 | return true; |
171 | 169 | } |
172 | | - |
| 170 | + |
173 | 171 | /** |
174 | 172 | * Keypress event handler. This is where the real work happens |
175 | 173 | * @param e Event object |
— | — | @@ -177,19 +175,19 @@ |
178 | 176 | if ( !enabled ) { |
179 | 177 | return true; |
180 | 178 | } |
181 | | - |
| 179 | + |
182 | 180 | if ( e.which == 8 ) { // Backspace |
183 | 181 | // Blank the keybuffer |
184 | 182 | $( this ).data( 'narayamKeyBuffer', '' ); |
185 | 183 | return true; |
186 | 184 | } |
187 | | - |
| 185 | + |
188 | 186 | // Leave non-ASCII stuff alone, as well as anything involving |
189 | 187 | // Alt (except for extended keymaps), Ctrl and Meta |
190 | 188 | if ( e.which < 32 || ( e.altKey && !currentScheme.extended_keyboard ) || e.ctrlKey || e.metaKey ) { |
191 | 189 | return true; |
192 | 190 | } |
193 | | - |
| 191 | + |
194 | 192 | var $this = $( this ); |
195 | 193 | var c = String.fromCharCode( e.which ); |
196 | 194 | // Get the current caret position. The user may have selected text to overwrite, |
— | — | @@ -204,7 +202,7 @@ |
205 | 203 | var input = lastNChars( $this.val(), startPos, currentScheme.lookbackLength ) + c; |
206 | 204 | var keyBuffer = $this.data( 'narayamKeyBuffer' ); |
207 | 205 | var replacement = transliterate( input, keyBuffer, e.altKey ); |
208 | | - |
| 206 | + |
209 | 207 | // Update the key buffer |
210 | 208 | keyBuffer += c; |
211 | 209 | if ( keyBuffer.length > currentScheme.keyBufferLength ) { |
— | — | @@ -212,7 +210,7 @@ |
213 | 211 | keyBuffer = keyBuffer.substring( keyBuffer.length - currentScheme.keyBufferLength ); |
214 | 212 | } |
215 | 213 | $this.data( 'narayamKeyBuffer', keyBuffer ); |
216 | | - |
| 214 | + |
217 | 215 | // textSelection() magic is expensive, so we avoid it as much as we can |
218 | 216 | if ( replacement == input ) { |
219 | 217 | return true; |
— | — | @@ -222,7 +220,7 @@ |
223 | 221 | var divergingPos = firstDivergence( input, replacement ); |
224 | 222 | input = input.substring( divergingPos ); |
225 | 223 | replacement = replacement.substring( divergingPos ); |
226 | | - |
| 224 | + |
227 | 225 | // Select and replace the text |
228 | 226 | $this.textSelection( 'setSelection', { |
229 | 227 | 'start': startPos - input.length + 1, |
— | — | @@ -233,11 +231,11 @@ |
234 | 232 | 'replace': true, |
235 | 233 | 'selectPeri': false |
236 | 234 | } ); |
237 | | - |
| 235 | + |
238 | 236 | e.stopPropagation(); |
239 | 237 | return false; |
240 | 238 | } |
241 | | - |
| 239 | + |
242 | 240 | /** |
243 | 241 | * Focus event handler. |
244 | 242 | * @param e Event object |
— | — | @@ -246,7 +244,7 @@ |
247 | 245 | $( this ).data( 'narayamKeyBuffer', '' ); |
248 | 246 | changeVisual( $( this ) ); |
249 | 247 | } |
250 | | - |
| 248 | + |
251 | 249 | /** |
252 | 250 | * Blur event handler. |
253 | 251 | * @param e Event object |
— | — | @@ -254,16 +252,8 @@ |
255 | 253 | function onblur( e ) { |
256 | 254 | $( this ).removeClass( 'narayam-input' ); |
257 | 255 | } |
258 | | - |
259 | | - /** |
260 | | - * Change handler for the scheme dropdown. Updates the current scheme |
261 | | - * based on the new selection in the dropdown. |
262 | | - */ |
263 | | - function updateSchemeFromSelect() { |
264 | | - var scheme = $( this ).val(); |
265 | | - that.setScheme( scheme ); |
266 | | - } |
267 | | - |
| 256 | + |
| 257 | + |
268 | 258 | /* Public functions */ |
269 | 259 | |
270 | 260 | /** |
— | — | @@ -291,7 +281,7 @@ |
292 | 282 | .bind( 'blur', onblur); |
293 | 283 | } |
294 | 284 | }; |
295 | | - |
| 285 | + |
296 | 286 | /** |
297 | 287 | * Enable Narayam |
298 | 288 | */ |
— | — | @@ -299,10 +289,12 @@ |
300 | 290 | if ( !enabled && currentScheme !== null ) { |
301 | 291 | $.cookie( 'narayam-enabled', '1', { 'path': '/', 'expires': 30 } ); |
302 | 292 | $( '#narayam-toggle' ).attr( 'checked', true ); |
| 293 | + $( 'li#pt-narayam').removeClass( 'narayam-inactive' ); |
| 294 | + $( 'li#pt-narayam').addClass( 'narayam-active' ); |
303 | 295 | enabled = true; |
304 | 296 | } |
305 | 297 | }; |
306 | | - |
| 298 | + |
307 | 299 | /** |
308 | 300 | * Disable Narayam |
309 | 301 | */ |
— | — | @@ -310,10 +302,12 @@ |
311 | 303 | if ( enabled ) { |
312 | 304 | $.cookie( 'narayam-enabled', '0', { 'path': '/', 'expires': 30 } ); |
313 | 305 | $( '#narayam-toggle' ).attr( 'checked', false ); |
| 306 | + $( 'li#pt-narayam').removeClass( 'narayam-active' ); |
| 307 | + $( 'li#pt-narayam').addClass( 'narayam-inactive' ); |
314 | 308 | enabled = false; |
315 | 309 | } |
316 | 310 | }; |
317 | | - |
| 311 | + |
318 | 312 | /** |
319 | 313 | * Toggle the enabled/disabled state |
320 | 314 | */ |
— | — | @@ -324,7 +318,7 @@ |
325 | 319 | that.enable(); |
326 | 320 | } |
327 | 321 | }; |
328 | | - |
| 322 | + |
329 | 323 | /** |
330 | 324 | * Add a transliteration scheme. Schemes whose name is not in |
331 | 325 | * wgNarayamAvailableSchemes will be ignored. |
— | — | @@ -373,7 +367,7 @@ |
374 | 368 | return false; |
375 | 369 | } |
376 | 370 | }; |
377 | | - |
| 371 | + |
378 | 372 | /** |
379 | 373 | * Change the current transliteration scheme |
380 | 374 | * @param name String |
— | — | @@ -382,80 +376,121 @@ |
383 | 377 | if ( name in schemes ) { |
384 | 378 | currentScheme = schemes[name]; |
385 | 379 | $.cookie( 'narayam-scheme', name, { 'path': '/', 'expires': 30 } ); |
386 | | - $select.val( name ); |
387 | 380 | } |
388 | 381 | }; |
389 | | - |
| 382 | + |
390 | 383 | /** |
391 | 384 | * Set up Narayam. This adds the scheme dropdown, binds the handlers |
392 | 385 | * and initializes the enabled/disabled state and selected scheme |
393 | 386 | * from a cookie or wgNarayamEnableByDefault |
394 | 387 | */ |
395 | 388 | this.setup = function() { |
396 | | - // Build scheme dropdown |
397 | | - $select = $( '<select />' ); |
398 | 389 | var haveSchemes = false; |
399 | | - for ( var scheme in schemes ) { |
400 | | - $( '<option />' ) |
401 | | - .val( scheme ) |
402 | | - .text( mw.msg( schemes[scheme].namemsg ) ) |
403 | | - .appendTo( $select ); |
| 390 | + // Build schemes option list |
| 391 | + var $ul = $( '<ul/>' ); |
| 392 | + for ( scheme in schemes ) { |
| 393 | + $input = $( '<input type="radio" name="narayam-input-method" class="narayam-scheme" />' ); |
| 394 | + $input |
| 395 | + .attr( 'id', 'narayam-' + scheme ) |
| 396 | + .val( scheme ); |
| 397 | + |
| 398 | + $( '<li/>' ) |
| 399 | + .append( $input ) |
| 400 | + .append( mw.msg( schemes[scheme].namemsg ) ) |
| 401 | + .appendTo( $ul ); |
404 | 402 | haveSchemes = true; |
405 | 403 | } |
406 | | - $select.change( updateSchemeFromSelect ); |
407 | | - |
| 404 | + |
408 | 405 | if ( !haveSchemes ) { |
409 | 406 | // No schemes available, don't show the tool |
410 | 407 | return; |
411 | 408 | } |
412 | | - |
| 409 | + |
| 410 | + // Event listener for scheme selection. |
| 411 | + // There is a plan to add a feature that allow dynamic loading of schemes. |
| 412 | + // So .live will be useful |
| 413 | + $( '.narayam-scheme', $( '#narayam-menu-items > ul')[0] ).live( 'click', function(){ |
| 414 | + that.setScheme( $(this).val() ); |
| 415 | + } ); |
| 416 | + |
413 | 417 | // Build enable/disable checkbox and label |
414 | 418 | var $checkbox = $( '<input type="checkbox" id="narayam-toggle" />' ); |
415 | 419 | $checkbox |
416 | 420 | .attr( 'title', mw.msg( 'narayam-checkbox-tooltip' ) ) |
417 | 421 | .click( that.toggle ); |
418 | | - |
419 | | - var helppage = mw.msg( 'narayam-help-page' ); |
| 422 | + |
420 | 423 | var $label = $( '<label for="narayam-toggle" />' ); |
421 | 424 | $label |
422 | 425 | .text( mw.msg( 'narayam-toggle-ime', shortcutText() ) ) |
| 426 | + .prepend( $checkbox ) |
423 | 427 | .attr( 'title', mw.msg( 'narayam-checkbox-tooltip' ) ); |
| 428 | + |
| 429 | + var helppage = mw.msg( 'narayam-help-page' ); |
424 | 430 | if ( helppage ) { |
425 | | - // Link to the help page |
426 | | - $label.wrapInner( $( '<a />' ).attr( 'href', mw.util.wikiGetlink( helppage ) ) ); |
| 431 | + $ul.append( $( '<li class="narayam-help-link" />') |
| 432 | + .append( |
| 433 | + $( '<a/>' ) |
| 434 | + .text( mw.msg( 'narayam-help' ) ) |
| 435 | + .attr( 'href', mw.util.wikiGetlink( mw.msg( 'narayam-help-page' ) )) |
| 436 | + ) |
| 437 | + ); |
427 | 438 | } |
428 | | - |
429 | | - var $checkboxAndLabel = $( '<span />' ) |
430 | | - .addClass( 'narayam-toggle-wrapper' ) |
431 | | - .append( $checkbox ) |
432 | | - .append( $label ); |
433 | | - var $spanWithEverything = $( '<span />' ) |
434 | | - .addClass( 'narayam-wrapper' ) |
435 | | - .append( $select ) |
436 | | - .append( $checkboxAndLabel ); |
437 | | - |
438 | | - // Put the dropdown and the checkbox at the beginning of the |
439 | | - // search form. This seems to be the most reliable way across skins. |
440 | | - $( '#searchform' ).prepend( $spanWithEverything ); |
441 | | - |
| 439 | + |
| 440 | + $ul.prepend( $( '<li/>' ).append( $label ) ); |
| 441 | + |
| 442 | + var $menuItems = $( '<div id="narayam-menu-items" class="menu-items" />' ); |
| 443 | + $menuItems |
| 444 | + .append( $ul ); |
| 445 | + |
| 446 | + var $menu = $( '<div id="narayam-menu" class="narayam-menu" />'); |
| 447 | + $menu |
| 448 | + .append( |
| 449 | + $( '<a href="#" />' ) |
| 450 | + .text( mw.msg( 'narayam-menu' ) ) |
| 451 | + .attr( 'title', mw.msg( 'narayam-menu-tooltip' ) ) |
| 452 | + ) |
| 453 | + .append( $menuItems ); |
| 454 | + |
| 455 | + var $li = $( '<li id="pt-narayam" />'); |
| 456 | + $li |
| 457 | + .append( $menu ); |
| 458 | + |
| 459 | + // If rtl, add to the right of top personal links, else, to the left |
| 460 | + if($('body').is( '.rtl' ) ){ |
| 461 | + $($('#p-personal ul')[0]).append( $li ); |
| 462 | + } |
| 463 | + else{ |
| 464 | + $($('#p-personal ul')[0]).prepend( $li ); |
| 465 | + } |
| 466 | + |
| 467 | + // Build enable/disable checkbox and label |
| 468 | + $checkbox = $( '<input type="checkbox" id="narayam-toggle" />' ); |
| 469 | + $checkbox |
| 470 | + .attr( 'title', mw.msg( 'narayam-checkbox-tooltip' ) ) |
| 471 | + .click( that.toggle ); |
| 472 | + |
442 | 473 | // Restore state from cookies |
443 | 474 | var savedScheme = $.cookie( 'narayam-scheme' ); |
444 | 475 | if ( savedScheme && savedScheme in schemes ) { |
445 | 476 | that.setScheme( savedScheme ); |
| 477 | + $( '#narayam-' + savedScheme ).attr( 'checked', 'checked' ); |
446 | 478 | } else { |
447 | | - $select.change(); |
| 479 | + $('input.narayam-scheme')[0].attr( 'checked', 'checked' ); |
448 | 480 | } |
449 | 481 | var enabledCookie = $.cookie( 'narayam-enabled' ); |
450 | 482 | if ( enabledCookie == '1' || ( mw.config.get( 'wgNarayamEnabledByDefault' ) && enabledCookie !== '0' ) ) { |
451 | 483 | that.enable(); |
452 | 484 | } |
| 485 | + else { |
| 486 | + $( 'li#pt-narayam').addClass( 'narayam-inactive' ); |
| 487 | + } |
453 | 488 | // Renew the narayam-enabled cookie. naraym-scheme is renewed by setScheme() |
454 | 489 | if ( enabledCookie ) { |
455 | 490 | $.cookie( 'narayam-enabled', enabledCookie, { 'path': '/', 'expires': 30 } ); |
456 | 491 | } |
457 | | - |
| 492 | + |
458 | 493 | }; |
459 | | - |
| 494 | + |
460 | 495 | } )(); |
461 | 496 | |
462 | 497 | } )( jQuery ); |
Index: trunk/extensions/Narayam/Narayam.php |
— | — | @@ -132,6 +132,9 @@ |
133 | 133 | ), |
134 | 134 | 'messages' => array( |
135 | 135 | 'narayam-checkbox-tooltip', |
| 136 | + 'narayam-menu', |
| 137 | + 'narayam-menu-tooltip', |
| 138 | + 'narayam-help', |
136 | 139 | 'narayam-help-page', |
137 | 140 | 'narayam-toggle-ime', |
138 | 141 | ), |