Amire80 has uploaded a new change for review. https://gerrit.wikimedia.org/r/265766
Change subject: Update jquery.ime from upstream ...................................................................... Update jquery.ime from upstream * Digit fix in Southern Kurdish. * Or-Lekhani and OdiScript layouts. * Major updates for VisualEditor integration by David Chan. Change-Id: Ia7301bddb79c1fbce2af7190494bdd7bdd909862 --- M lib/jquery.ime/jquery.ime.js M lib/jquery.ime/rules/or/or-lekhani.js M lib/jquery.ime/rules/sdh/sdh-kbd.js M lib/jquery.ime/rules/si/si-singlish.js M lib/jquery.ime/rules/yo/yo-alt.js 5 files changed, 390 insertions(+), 370 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/UniversalLanguageSelector refs/changes/66/265766/1 diff --git a/lib/jquery.ime/jquery.ime.js b/lib/jquery.ime/jquery.ime.js index 8bb2d4f..283c51c 100644 --- a/lib/jquery.ime/jquery.ime.js +++ b/lib/jquery.ime/jquery.ime.js @@ -3,18 +3,51 @@ * Copyright (c) 2015 Santhosh Thottingal; Licensed GPL, MIT */ ( function ( $ ) { 'use strict'; + var TextEntryFactory, TextEntry, FormWidgetEntry, ContentEditableEntry, + defaultInputMethod; // rangy is defined in the rangy library /*global rangy */ /** + * Just initializes an empty static object. + * Similar to initClass in https://www.mediawiki.org/wiki/OOjs + * + * @param {Function} fn + */ + function initClass( fn ) { + fn.static = fn.static || {}; + } + + /** + * Inheritance. Uses pattern similar to OOjs (https://www.mediawiki.org/wiki/OOjs). + * Extend prototype and static methods and properties of child constructor from + * a parent constructor. + * + * @param {Function} targetFn + * @param {Function} originFn + */ + function inheritClass( targetFn, originFn ) { + targetFn.parent = originFn; + targetFn.prototype = $.extend( {}, originFn.prototype ); + targetFn.prototype.constructor = originFn.constructor; + targetFn.static = $.extend( {}, originFn.static ); + } + + /** * IME Class + * @class + * + * @constructor + * @param {HTMLElement} element Element on which to listen for events + * @param {TextEntry} textEntry Text entry object to use to get/set text * @param {Function} [options.helpHandler] Called for each input method row in the selector * @param {Object} options.helpHandler.imeSelector * @param {String} options.helpHandler.ime Id of the input method */ - function IME( element, options ) { + function IME( element, textEntry, options ) { this.$element = $( element ); + this.textEntry = textEntry; // This needs to be delayed here since extending language list happens at DOM ready $.ime.defaults.languages = arrayKeys( $.ime.languages ); this.options = $.extend( {}, $.ime.defaults, options ); @@ -127,7 +160,7 @@ */ keypress: function ( e ) { var altGr = false, - c, startPos, pos, endPos, divergingPos, input, replacement; + c, input, replacement; if ( !this.active ) { return true; @@ -160,24 +193,10 @@ c = String.fromCharCode( e.which ); - // Get the current caret position. The user may have selected text to overwrite, - // so get both the start and end position of the selection. If there is no selection, - // startPos and endPos will be equal. - pos = this.getCaretPosition( this.$element ); - startPos = pos[0]; - endPos = pos[1]; - - // Get the last few characters before the one the user just typed, + // Append the character being typed to the preceding few characters, // to provide context for the transliteration regexes. - // We need to append c because it hasn't been added to $this.val() yet - input = this.lastNChars( - this.$element.val() || this.$element.text(), - startPos, - this.inputmethod.maxKeyLength - ); - input += c; - - replacement = this.transliterate( input, this.context, altGr ); + input = this.textEntry.getTextBeforeSelection( this.inputmethod.maxKeyLength ); + replacement = this.transliterate( input + c, this.context, altGr ); // Update the context this.context += c; @@ -198,11 +217,7 @@ return true; } - // Drop a common prefix, if any - divergingPos = this.firstDivergence( input, replacement.output ); - input = input.substring( divergingPos ); - replacement.output = replacement.output.substring( divergingPos ); - replaceText( this.$element, replacement.output, startPos - input.length + 1, endPos ); + this.textEntry.replaceTextAtSelection( input.length, replacement.output ); e.stopPropagation(); @@ -332,121 +347,200 @@ return deferred.promise(); }, + }; - /** - * Returns an array [start, end] of the beginning - * and the end of the current selection in $element - * @returns {Array} - */ - getCaretPosition: function ( $element ) { - return getCaretPosition( $element ); - }, + /** + * TextEntry factory + * @class + * + * @constructor + */ + TextEntryFactory = function IMETextEntryFactory() { + this.TextEntryClasses = []; + }; - /** - * Set the caret position in the div. - * @param {jQuery} $element The content editable div element - * @param {Object} position An object with start and end properties. - * @return {Array} If the cursor could not be placed at given position, how - * many characters had to go back to place the cursor - */ - setCaretPosition: function ( $element, position ) { - return setCaretPosition( $element, position ); - }, + /* Inheritance */ - /** - * Find the point at which a and b diverge, i.e. the first position - * at which they don't have matching characters. - * - * @param a String - * @param b String - * @return Position at which a and b diverge, or -1 if a === b - */ - firstDivergence: function ( a, b ) { - return firstDivergence( a, b ); - }, + initClass( TextEntryFactory ); - /** - * Get the n characters in str that immediately precede pos - * Example: lastNChars( 'foobarbaz', 5, 2 ) === 'ba' - * - * @param str String to search in - * @param pos Position in str - * @param n Number of characters to go back from pos - * @return Substring of str, at most n characters long, immediately preceding pos - */ - lastNChars: function ( str, pos, n ) { - return lastNChars( str, pos, n ); + /* Methods */ + + /** + * Register a TextEntry class, with priority over previous registrations + * + * @param {TextEntry} Class to register + */ + TextEntryFactory.prototype.register = function ( TextEntryClass ) { + this.TextEntryClasses.unshift( TextEntryClass ); + }; + + /** + * Wrap an editable element with the appropriate TextEntry class + * + * @param {jQuery} $element The element to wrap + * @return {TextEntry|undefined} A TextEntry, or undefined if no match + */ + TextEntryFactory.prototype.wrap = function ( $element ) { + var i, len, TextEntryClass; + for ( i = 0, len = this.TextEntryClasses.length; i < len; i++ ) { + TextEntryClass = this.TextEntryClasses[ i ]; + if ( TextEntryClass.static.canWrap( $element ) ) { + return new TextEntryClass( $element ); + } + } + return undefined; + }; + + /* Initialization */ + + TextEntryFactory.static.singleton = new TextEntryFactory(); + + /** + * Generic text entry + * @class + * + * @abstract + */ + TextEntry = function IMETextEntry() { + }; + + /* Inheritance */ + + initClass( TextEntry ); + + /* Static methods */ + + /** + * Test whether can wrap this type of element + * + * @param {jQuery} $element The element to wrap + * @return {boolean} Whether the element can be wrapped + */ + TextEntry.static.canWrap = function () { + return false; + }; + + /* Abstract methods */ + + /** + * Get text immediately before the current selection start. + * + * This SHOULD return the empty string for non-collapsed selections. + * + * @param {number} maxLength Maximum number of chars (code units) to return + * @return {String} Up to maxLength of text + */ + TextEntry.prototype.getTextBeforeSelection = null; + + /** + * Replace the currently selected text and/or text before the selection + * + * @param {number} precedingCharCount Number of chars before selection to replace + * @param {String} newText Replacement text + */ + TextEntry.prototype.replaceTextAtSelection = null; + + /** + * TextEntry class for input/textarea widgets + * @class + * + * @constructor + * @param {jQuery} $element The element to wrap + */ + FormWidgetEntry = function IMEFormWidgetEntry( $element ) { + this.$element = $element; + }; + + /* Inheritance */ + + inheritClass( FormWidgetEntry, TextEntry ); + + /* Static methods */ + + /** + * @inheritdoc TextEntry + */ + FormWidgetEntry.static.canWrap = function ( $element ) { + return $element.is( 'input:not([type]), input[type=text], input[type=search], textarea' ) && + !$element.prop( 'readonly' ) && + !$element.prop( 'disabled' ) && + !$element.hasClass( 'noime' ); + }; + + /* Instance methods */ + + /** + * @inheritdoc TextEntry + */ + FormWidgetEntry.prototype.getTextBeforeSelection = function ( maxLength ) { + var pos = this.getCaretPosition(); + return this.$element.val().substring( + Math.max( 0, pos.start - maxLength ), + pos.start + ); + }; + + /** + * @inheritdoc TextEntry + */ + FormWidgetEntry.prototype.replaceTextAtSelection = function ( precedingCharCount, newText ) { + var selection, + length, + newLines, + start, + scrollTop, + pos, + element = this.$element.get( 0 ); + + if ( typeof element.selectionStart === 'number' && typeof element.selectionEnd === 'number' ) { + // IE9+ and all other browsers + start = element.selectionStart; + scrollTop = element.scrollTop; + + // Replace the whole text of the text area: + // text before + newText + text after. + // This could be made better if range selection worked on browsers. + // But for complex scripts, browsers place cursor in unexpected places + // and it's not possible to fix cursor programmatically. + // Ref Bug https://bugs.webkit.org/show_bug.cgi?id=66630 + element.value = element.value.substring( 0, start - precedingCharCount ) + + newText + + element.value.substring( element.selectionEnd, element.value.length ); + + // restore scroll + element.scrollTop = scrollTop; + // set selection + element.selectionStart = element.selectionEnd = start - precedingCharCount + newText.length; + } else { + // IE8 and lower + pos = this.getCaretPosition(); + selection = element.createTextRange(); + length = element.value.length; + // IE doesn't count \n when computing the offset, so we won't either + newLines = element.value.match( /\n/g ); + + if ( newLines ) { + length = length - newLines.length; + } + + selection.moveStart( 'character', pos.start - precedingCharCount ); + selection.moveEnd( 'character', pos.end - length ); + + selection.text = newText; + selection.collapse( false ); + selection.select(); } }; /** - * jQuery plugin ime - * @param {Object} option + * Get the current selection offsets inside the widget + * + * @return {Object} Offsets in chars (0 means first offset *or* no selection in widget) + * @return.start {number} Selection start + * @return.end {number} Selection end */ - $.fn.ime = function ( option ) { - return this.each( function () { - var data, - $this = $( this ), - options = typeof option === 'object' && option; - - // Some exclusions: IME shouldn't be applied to textareas with - // these properties. - if ( $this.prop( 'readonly' ) || - $this.prop( 'disabled' ) || - $this.hasClass( 'noime' ) ) { - return; - } - - data = $this.data( 'ime' ); - - if ( !data ) { - data = new IME( this, options ); - $this.data( 'ime', data ); - } - - if ( typeof option === 'string' ) { - data[option](); - } - } ); - }; - - $.ime = {}; - $.ime.inputmethods = {}; - $.ime.sources = {}; - $.ime.preferences = {}; - $.ime.languages = {}; - - var defaultInputMethod = { - contextLength: 0, - maxKeyLength: 1 - }; - - $.ime.register = function ( inputMethod ) { - $.ime.inputmethods[inputMethod.id] = $.extend( {}, defaultInputMethod, inputMethod ); - }; - - // default options - $.ime.defaults = { - imePath: '../', // Relative/Absolute path for the rules folder of jquery.ime - languages: [], // Languages to be used- by default all languages - helpHandler: null // Called for each ime option in the menu - }; - - /** - * private function for debugging - */ - function debug( $obj ) { - if ( window.console && window.console.log ) { - window.console.log( $obj ); - } - } - - /** - * Returns an array [start, end] of the beginning - * and the end of the current selection in $element - */ - function getCaretPosition( $element ) { - var el = $element.get( 0 ), + FormWidgetEntry.prototype.getCaretPosition = function () { + var el = this.$element.get( 0 ), start = 0, end = 0, normalizedValue, @@ -455,10 +549,6 @@ len, newLines, endRange; - - if ( $element.is( '[contenteditable]' ) ) { - return getDivCaretPosition( el ); - } if ( typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number' ) { start = el.selectionStart; @@ -499,264 +589,189 @@ } } } + return { start: start, end: end }; + }; - return [start, end]; - } + TextEntryFactory.static.singleton.register( FormWidgetEntry ); /** - * Helper function to get an IE TextRange object for an element + * TextEntry class for ContentEditable + * @class + * + * @constructor + * @param {jQuery} $element The element to wrap */ - function rangeForElementIE( element ) { - var selection; + ContentEditableEntry = function IMEContentEditableEntry( $element ) { + this.$element = $element; + }; - if ( element.nodeName.toLowerCase() === 'input' ) { - selection = element.createTextRange(); - } else { - selection = document.body.createTextRange(); - selection.moveToElementText( element ); + /* Inheritance */ + + inheritClass( ContentEditableEntry, TextEntry ); + + /* Static methods */ + + /** + * @inheritdoc TextEntry + */ + ContentEditableEntry.static.canWrap = function ( $element ) { + return $element.is( '[contenteditable]' ) && !$element.hasClass( 'noime' ); + }; + + /* Instance methods */ + + /** + * @inheritdoc TextEntry + */ + ContentEditableEntry.prototype.getTextBeforeSelection = function ( maxLength ) { + var range = this.getSelectedRange(); + if ( !range || !range.collapsed || range.startContainer.nodeType !== Node.TEXT_NODE ) { + return ''; } + return range.startContainer.nodeValue.substring( + Math.max( 0, range.startOffset - maxLength ), + range.startOffset + ); + }; - return selection; - } + /** + * @inheritdoc SelectionWrapper + */ + ContentEditableEntry.prototype.replaceTextAtSelection = function ( precedingCharCount, newText ) { + var range, textNode, textOffset, newOffset, newRange; - function replaceText( $element, replacement, start, end ) { - var selection, - length, - newLines, - scrollTop, - range, - correction, - textNode, - element = $element.get( 0 ); - - if ( $element.is( '[contenteditable]' ) ) { - correction = setCaretPosition( $element, { - start: start, - end: end - } ); - - rangy.init(); - selection = rangy.getSelection(); - range = selection.getRangeAt( 0 ); - - if ( correction[0] > 0 ) { - replacement = selection.toString().substring( 0, correction[0] ) + replacement; - } - - textNode = document.createTextNode( replacement ); - range.deleteContents(); - range.insertNode( textNode ); - range.commonAncestorContainer.normalize(); - start = end = start + replacement.length - correction[0]; - setCaretPosition( $element, { - start: start, - end: end - } ); - + if ( !this.getSelectedRange() ) { return; } - if ( typeof element.selectionStart === 'number' && typeof element.selectionEnd === 'number' ) { - // IE9+ and all other browsers - scrollTop = element.scrollTop; + // Trigger any externally registered jQuery compositionstart event listeners. + // TODO: Try node.dispatchEvent( new CompositionEvent(...) ) so listeners not + // registered using jQuery will also get triggered, then fallback gracefully for + // browsers that do not support it. + this.$element.trigger( 'compositionstart' ); - // Replace the whole text of the text area: - // text before + replacement + text after. - // This could be made better if range selection worked on browsers. - // But for complex scripts, browsers place cursor in unexpected places - // and it's not possible to fix cursor programmatically. - // Ref Bug https://bugs.webkit.org/show_bug.cgi?id=66630 - element.value = element.value.substring( 0, start ) + - replacement + - element.value.substring( end, element.value.length ); + range = this.getSelectedRange(); - // restore scroll - element.scrollTop = scrollTop; - // set selection - element.selectionStart = element.selectionEnd = start + replacement.length; - } else { - // IE8 and lower - selection = rangeForElementIE(element); - length = element.value.length; - // IE doesn't count \n when computing the offset, so we won't either - newLines = element.value.match( /\n/g ); - - if ( newLines ) { - length = length - newLines.length; - } - - selection.moveStart( 'character', start ); - selection.moveEnd( 'character', end - length ); - - selection.text = replacement; - selection.collapse( false ); - selection.select(); + if ( !range.collapsed ) { + range.deleteContents(); } - } - function getDivCaretPosition( element ) { - var charIndex = 0, - start = 0, - end = 0, - foundStart = false, - foundEnd = false, - sel; + if ( range.startContainer.nodeType === Node.TEXT_NODE ) { + // Alter this text node's content and move the cursor + textNode = range.startContainer; + textOffset = range.startOffset; + textNode.nodeValue = + textNode.nodeValue.substr( 0, textOffset - precedingCharCount ) + + newText + + textNode.nodeValue.substr( textOffset ); + newOffset = textOffset - precedingCharCount + newText.length; + newRange = rangy.createRange(); + newRange.setStart( range.startContainer, newOffset ); + newRange.setEnd( range.startContainer, newOffset ); + rangy.getSelection().setSingleRange( newRange ); + } else { + // XXX assert precedingCharCount === 0 + // Insert a new text node with the new text + textNode = document.createTextNode( newText ); + range.startContainer.insertBefore( + textNode, + range.startContainer.childNodes[ range.startOffset ] + ); + newRange = rangy.createRange(); + newRange.setStart( textNode, textNode.length ); + newRange.setEnd( textNode, textNode.length ); + rangy.getSelection().setSingleRange( newRange ); + } + // Trigger any externally registered jQuery compositionend / input event listeners. + // TODO: Try node.dispatchEvent( new CompositionEvent(...) ) so listeners not + // registered using jQuery will also get triggered, then fallback gracefully for + // browsers that do not support it. + this.$element.trigger( 'compositionend' ); + this.$element.trigger( 'input' ); + }; + + /** + * Get the selection range inside the wrapped element, or null + * + * @return {Range|null} The selection range + */ + ContentEditableEntry.prototype.getSelectedRange = function () { + var sel, range; rangy.init(); sel = rangy.getSelection(); - - function traverseTextNodes( node, range ) { - var i, childNodesCount; - - if ( node.nodeType === Node.TEXT_NODE ) { - if ( !foundStart && node === range.startContainer ) { - start = charIndex + range.startOffset; - foundStart = true; - } - - if ( foundStart && node === range.endContainer ) { - end = charIndex + range.endOffset; - foundEnd = true; - } - - charIndex += node.length; - } else { - childNodesCount = node.childNodes.length; - - for ( i = 0; i < childNodesCount; ++i ) { - traverseTextNodes( node.childNodes[i], range ); - if ( foundEnd ) { - break; - } - } - } + if ( sel.rangeCount === 0 ) { + return null; } - - if ( sel.rangeCount ) { - traverseTextNodes( element, sel.getRangeAt( 0 ) ); + range = sel.getRangeAt( 0 ); + if ( !this.$element[ 0 ].contains( range.commonAncestorContainer ) ) { + return null; } + return range; + }; - return [ start, end ]; - } + TextEntryFactory.static.singleton.register( ContentEditableEntry ); - function setCaretPosition( $element, position ) { - var currentPosition, - startCorrection = 0, - endCorrection = 0, - element = $element[0]; - - setDivCaretPosition( element, position ); - currentPosition = getDivCaretPosition( element ); - // see Bug https://bugs.webkit.org/show_bug.cgi?id=66630 - while ( position.start !== currentPosition[0] ) { - position.start -= 1; // go back one more position. - if ( position.start < 0 ) { - // never go beyond 0 - break; - } - setDivCaretPosition( element, position ); - currentPosition = getDivCaretPosition( element ); - startCorrection += 1; - } - - while ( position.end !== currentPosition[1] ) { - position.end += 1; // go forward one more position. - setDivCaretPosition( element, position ); - currentPosition = getDivCaretPosition( element ); - endCorrection += 1; - if ( endCorrection > 10 ) { - // XXX avoid rare case of infinite loop here. - break; - } - } - - return [startCorrection, endCorrection]; - } + /* Exports */ /** - * Set the caret position in the div. - * @param {Element} element The content editable div element - * @param position + * jQuery plugin ime + * @param {Object} option */ - function setDivCaretPosition( element, position ) { - var nextCharIndex, - charIndex = 0, - range = rangy.createRange(), - foundStart = false, - foundEnd = false; + $.fn.ime = function ( option ) { + return this.each( function () { + var data, textEntry, + $this = $( this ), + options = typeof option === 'object' && option; - range.collapseToPoint( element, 0 ); - - function traverseTextNodes( node ) { - var i, len; - - if ( node.nodeType === 3 ) { - nextCharIndex = charIndex + node.length; - - if ( !foundStart && position.start >= charIndex && position.start <= nextCharIndex ) { - range.setStart( node, position.start - charIndex ); - foundStart = true; + data = $this.data( 'ime' ); + if ( !data ) { + textEntry = TextEntryFactory.static.singleton.wrap( $this ); + if ( textEntry === undefined ) { + return; } - - if ( foundStart && position.end >= charIndex && position.end <= nextCharIndex ) { - range.setEnd( node, position.end - charIndex ); - foundEnd = true; - } - - charIndex = nextCharIndex; - } else { - for ( i = 0, len = node.childNodes.length; i < len; ++i ) { - traverseTextNodes( node.childNodes[i] ); - if ( foundEnd ) { - rangy.getSelection().setSingleRange( range ); - break; - } - } + data = new IME( this, textEntry, options ); + $this.data( 'ime', data ); } - } - traverseTextNodes( element ); + if ( typeof option === 'string' ) { + data[option](); + } + } ); + }; - } + $.ime = {}; + $.ime.inputmethods = {}; + $.ime.sources = {}; + $.ime.preferences = {}; + $.ime.languages = {}; + + $.ime.textEntryFactory = TextEntryFactory.static.singleton; + $.ime.TextEntry = TextEntry; + $.ime.inheritClass = inheritClass; + + defaultInputMethod = { + contextLength: 0, + maxKeyLength: 1 + }; + + $.ime.register = function ( inputMethod ) { + $.ime.inputmethods[inputMethod.id] = $.extend( {}, defaultInputMethod, inputMethod ); + }; + + // default options + $.ime.defaults = { + imePath: '../', // Relative/Absolute path for the rules folder of jquery.ime + languages: [], // Languages to be used- by default all languages + helpHandler: null // Called for each ime option in the menu + }; /** - * Find the point at which a and b diverge, i.e. the first position - * at which they don't have matching characters. - * - * @param a String - * @param b String - * @return Position at which a and b diverge, or -1 if a === b + * private function for debugging */ - function firstDivergence( a, b ) { - var minLength, i; - - minLength = a.length < b.length ? a.length : b.length; - - for ( i = 0; i < minLength; i++ ) { - if ( a.charCodeAt( i ) !== b.charCodeAt( i ) ) { - return i; - } - } - - return -1; - } - - /** - * Get the n characters in str that immediately precede pos - * Example: lastNChars( 'foobarbaz', 5, 2 ) === 'ba' - * - * @param str String to search in - * @param pos Position in str - * @param n Number of characters to go back from pos - * @return Substring of str, at most n characters long, immediately preceding pos - */ - function lastNChars( str, pos, n ) { - if ( n === 0 ) { - return ''; - } else if ( pos <= n ) { - return str.substr( 0, pos ); - } else { - return str.substr( pos - n, n ); + function debug( $obj ) { + if ( window.console && window.console.log ) { + window.console.log( $obj ); } } @@ -1601,6 +1616,10 @@ name: 'ফনেটিক', source: 'rules/as/as-phonetic.js' }, + 'as-rodali': { + name: 'ৰ\'দালি', + source: 'rules/as/as-rodali.js' + }, 'as-transliteration': { name: 'প্ৰতিৰূপান্তৰণ', source: 'rules/as/as-transliteration.js' @@ -2014,6 +2033,10 @@ 'or-transliteration': { name: 'ଟ୍ରାନ୍ସଲିଟରେସନ', source: 'rules/or/or-transliteration.js' + }, + 'or-OdiScript': { + name: 'ଓଡ଼ିସ୍କ୍ରିପ୍ଟ', + source: 'rules/or/or-OdiScript.js' }, 'or-inscript': { name: 'ଇନସ୍କ୍ରିପ୍ଟ', @@ -2435,7 +2458,7 @@ }, 'or': { autonym: 'ଓଡ଼ିଆ', - inputmethods: [ 'or-phonetic', 'or-transliteration', 'or-inscript', 'or-inscript2', 'or-lekhani' ] + inputmethods: [ 'or-phonetic', 'or-transliteration', 'or-inscript', 'or-inscript2', 'or-lekhani', 'or-OdiScript' ] }, 'pa': { autonym: 'ਪੰਜਾਬੀ', diff --git a/lib/jquery.ime/rules/or/or-lekhani.js b/lib/jquery.ime/rules/or/or-lekhani.js index eb36675..364890a 100644 --- a/lib/jquery.ime/rules/or/or-lekhani.js +++ b/lib/jquery.ime/rules/or/or-lekhani.js @@ -7,7 +7,7 @@ description: 'Odia Lekhani phonetic input method', date: '2012-10-14', URL: 'http://github.com/wikimedia/jquery.ime', - author: 'Junaid P V and Subhashish Panigrahi', + author: 'Junaid P V, Subhashish Panigrahi and Jnanaranjan Sahu', license: 'GPLv3', version: '1.0', contextLength: 4, @@ -15,7 +15,7 @@ patterns: [ ['\\\\([A-Za-z\\>_~\\.0-9])', '\\\\', '$1'], - ['([(କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])a', '$1ା'], + ['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])a', '$1ା'], ['([କ-ଳଲନ୍ଧଥଡ଼ଢ଼ହୟୱରକ୍ଷଶସଷଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])i', '$1\u0b3f'], ['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍])I', '$1ୀ'], ['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍])u', '$1\u0b41'], @@ -31,13 +31,13 @@ ['([କ-ହୟୱ])(w|v)', '$1୍ୱ'], ['([କ-ହୟୱ])~', '$1\u200C'], - ['([କ-ହୟୱ])y', '$1୍ୟ'], // <consonant>y + ['([କ-ହୱ])y', '$1୍ୟ'], // <consonant>y ['z', '୍'], // halanta ['\\.', '।'], //purnacheda ['ଅa', 'ଆ'], ['ଏe', 'ଐ'], - ['(ଅu|ଓo|ଓO)', 'ଔ'], + ['(ଅu|O)', 'ଔ'], ['ଋR', 'ୠ'], // RR ['ଳl', 'ଌ'], // Ll ['ଌl', 'ୡ'], // Lll @@ -45,8 +45,6 @@ ['ଞ୍ଜh', 'ଞ୍ଝ'], // njh ['ଙ୍କh', 'ଙ୍ଖ'], // nkh ['ଙ୍ଗh', 'ଙ୍ଘ'], // ngh - ['ହm', 'ହ୍ମ'], // mh - ['ହn', 'ହ୍ନ'], // nh ['ମ୍ବh', 'ମ୍ଭ'], // mbh or nbh ['ଣ୍ଡai', 'ଣ୍ଡାଇ'], // NDai ['ଜ୍ଜh', 'ଜ୍ଝ'], // jjh @@ -67,7 +65,6 @@ ['ନD|ଣD', 'ଣ୍ଡ'], // nd ['ଣDh', 'ଣ୍ଢ'], //ndh ['ନdh', 'ନ୍ଧ'], // ndht - ['ଷT', '$1୍ଟ'], // ST ['ଟh', 'ଠ'], // Th ['ଡh', 'ଢ'], // Dh ['ତh', 'ଥ'], // th diff --git a/lib/jquery.ime/rules/sdh/sdh-kbd.js b/lib/jquery.ime/rules/sdh/sdh-kbd.js index e1b7c2f..c76a14c 100644 --- a/lib/jquery.ime/rules/sdh/sdh-kbd.js +++ b/lib/jquery.ime/rules/sdh/sdh-kbd.js @@ -17,7 +17,7 @@ ['3', '٣'], ['4', '٤'], ['5', '٥'], - ['6', '٦'], + ['6', '۶'], ['7', '٧'], ['8', '٨'], ['9', '٩'], diff --git a/lib/jquery.ime/rules/si/si-singlish.js b/lib/jquery.ime/rules/si/si-singlish.js index 8ba93b1..d872015 100644 --- a/lib/jquery.ime/rules/si/si-singlish.js +++ b/lib/jquery.ime/rules/si/si-singlish.js @@ -11,7 +11,7 @@ license: 'GPLv3', version: '1.0', contextLength: 5, - maxKeyLength: 2, + maxKeyLength: 5, patterns: [ //['ඬ්හ්a', 'ඳ'], // nndha ['ඬ්h', 'ඳ්'], // nndh diff --git a/lib/jquery.ime/rules/yo/yo-alt.js b/lib/jquery.ime/rules/yo/yo-alt.js index 2e8c41b..b272472 100644 --- a/lib/jquery.ime/rules/yo/yo-alt.js +++ b/lib/jquery.ime/rules/yo/yo-alt.js @@ -16,7 +16,7 @@ // Combining grave tone mark ['\\\\', '\u0340'], // Combining acute tone mark - ["/", '\u0341'] + ['/', '\u0341'] ] }; -- To view, visit https://gerrit.wikimedia.org/r/265766 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia7301bddb79c1fbce2af7190494bdd7bdd909862 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/UniversalLanguageSelector Gerrit-Branch: master Gerrit-Owner: Amire80 <amir.ahar...@mail.huji.ac.il> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits