Update jquery.ime from upstream
* Digit fix in Southern Kurdish. * Rodali, Or-Lekhani and OdiScript layouts. * Major updates for VisualEditor integration by David Chan. Change-Id: Ia7301bddb79c1fbce2af7190494bdd7bdd909862
This commit is contained in:
@@ -3,18 +3,51 @@
|
|||||||
* Copyright (c) 2015 Santhosh Thottingal; Licensed GPL, MIT */
|
* Copyright (c) 2015 Santhosh Thottingal; Licensed GPL, MIT */
|
||||||
( function ( $ ) {
|
( function ( $ ) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
var TextEntryFactory, TextEntry, FormWidgetEntry, ContentEditableEntry,
|
||||||
|
defaultInputMethod;
|
||||||
|
|
||||||
// rangy is defined in the rangy library
|
// rangy is defined in the rangy library
|
||||||
/*global rangy */
|
/*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
|
* 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 {Function} [options.helpHandler] Called for each input method row in the selector
|
||||||
* @param {Object} options.helpHandler.imeSelector
|
* @param {Object} options.helpHandler.imeSelector
|
||||||
* @param {String} options.helpHandler.ime Id of the input method
|
* @param {String} options.helpHandler.ime Id of the input method
|
||||||
*/
|
*/
|
||||||
function IME( element, options ) {
|
function IME( element, textEntry, options ) {
|
||||||
this.$element = $( element );
|
this.$element = $( element );
|
||||||
|
this.textEntry = textEntry;
|
||||||
// This needs to be delayed here since extending language list happens at DOM ready
|
// This needs to be delayed here since extending language list happens at DOM ready
|
||||||
$.ime.defaults.languages = arrayKeys( $.ime.languages );
|
$.ime.defaults.languages = arrayKeys( $.ime.languages );
|
||||||
this.options = $.extend( {}, $.ime.defaults, options );
|
this.options = $.extend( {}, $.ime.defaults, options );
|
||||||
@@ -127,7 +160,7 @@
|
|||||||
*/
|
*/
|
||||||
keypress: function ( e ) {
|
keypress: function ( e ) {
|
||||||
var altGr = false,
|
var altGr = false,
|
||||||
c, startPos, pos, endPos, divergingPos, input, replacement;
|
c, input, replacement;
|
||||||
|
|
||||||
if ( !this.active ) {
|
if ( !this.active ) {
|
||||||
return true;
|
return true;
|
||||||
@@ -160,24 +193,10 @@
|
|||||||
|
|
||||||
c = String.fromCharCode( e.which );
|
c = String.fromCharCode( e.which );
|
||||||
|
|
||||||
// Get the current caret position. The user may have selected text to overwrite,
|
// Append the character being typed to the preceding few characters,
|
||||||
// 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,
|
|
||||||
// to provide context for the transliteration regexes.
|
// to provide context for the transliteration regexes.
|
||||||
// We need to append c because it hasn't been added to $this.val() yet
|
input = this.textEntry.getTextBeforeSelection( this.inputmethod.maxKeyLength );
|
||||||
input = this.lastNChars(
|
replacement = this.transliterate( input + c, this.context, altGr );
|
||||||
this.$element.val() || this.$element.text(),
|
|
||||||
startPos,
|
|
||||||
this.inputmethod.maxKeyLength
|
|
||||||
);
|
|
||||||
input += c;
|
|
||||||
|
|
||||||
replacement = this.transliterate( input, this.context, altGr );
|
|
||||||
|
|
||||||
// Update the context
|
// Update the context
|
||||||
this.context += c;
|
this.context += c;
|
||||||
@@ -198,11 +217,7 @@
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop a common prefix, if any
|
this.textEntry.replaceTextAtSelection( input.length, replacement.output );
|
||||||
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 );
|
|
||||||
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
@@ -332,121 +347,200 @@
|
|||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array [start, end] of the beginning
|
* TextEntry factory
|
||||||
* and the end of the current selection in $element
|
* @class
|
||||||
* @returns {Array}
|
*
|
||||||
*/
|
* @constructor
|
||||||
getCaretPosition: function ( $element ) {
|
*/
|
||||||
return getCaretPosition( $element );
|
TextEntryFactory = function IMETextEntryFactory() {
|
||||||
},
|
this.TextEntryClasses = [];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/* Inheritance */
|
||||||
* 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 );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
initClass( TextEntryFactory );
|
||||||
* 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 );
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/* Methods */
|
||||||
* Get the n characters in str that immediately precede pos
|
|
||||||
* Example: lastNChars( 'foobarbaz', 5, 2 ) === 'ba'
|
/**
|
||||||
*
|
* Register a TextEntry class, with priority over previous registrations
|
||||||
* @param str String to search in
|
*
|
||||||
* @param pos Position in str
|
* @param {TextEntry} Class to register
|
||||||
* @param n Number of characters to go back from pos
|
*/
|
||||||
* @return Substring of str, at most n characters long, immediately preceding pos
|
TextEntryFactory.prototype.register = function ( TextEntryClass ) {
|
||||||
*/
|
this.TextEntryClasses.unshift( TextEntryClass );
|
||||||
lastNChars: function ( str, pos, n ) {
|
};
|
||||||
return lastNChars( str, pos, n );
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Get the current selection offsets inside the widget
|
||||||
* @param {Object} option
|
*
|
||||||
|
* @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 ) {
|
FormWidgetEntry.prototype.getCaretPosition = function () {
|
||||||
return this.each( function () {
|
var el = this.$element.get( 0 ),
|
||||||
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 ),
|
|
||||||
start = 0,
|
start = 0,
|
||||||
end = 0,
|
end = 0,
|
||||||
normalizedValue,
|
normalizedValue,
|
||||||
@@ -456,10 +550,6 @@
|
|||||||
newLines,
|
newLines,
|
||||||
endRange;
|
endRange;
|
||||||
|
|
||||||
if ( $element.is( '[contenteditable]' ) ) {
|
|
||||||
return getDivCaretPosition( el );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number' ) {
|
if ( typeof el.selectionStart === 'number' && typeof el.selectionEnd === 'number' ) {
|
||||||
start = el.selectionStart;
|
start = el.selectionStart;
|
||||||
end = el.selectionEnd;
|
end = el.selectionEnd;
|
||||||
@@ -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 ) {
|
ContentEditableEntry = function IMEContentEditableEntry( $element ) {
|
||||||
var selection;
|
this.$element = $element;
|
||||||
|
};
|
||||||
|
|
||||||
if ( element.nodeName.toLowerCase() === 'input' ) {
|
/* Inheritance */
|
||||||
selection = element.createTextRange();
|
|
||||||
} else {
|
inheritClass( ContentEditableEntry, TextEntry );
|
||||||
selection = document.body.createTextRange();
|
|
||||||
selection.moveToElementText( element );
|
/* 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
|
||||||
|
*/
|
||||||
function replaceText( $element, replacement, start, end ) {
|
ContentEditableEntry.prototype.replaceTextAtSelection = function ( precedingCharCount, newText ) {
|
||||||
var selection,
|
var range, textNode, textOffset, newOffset, newRange;
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( typeof element.selectionStart === 'number' && typeof element.selectionEnd === 'number' ) {
|
// Trigger any externally registered jQuery compositionstart event listeners.
|
||||||
// IE9+ and all other browsers
|
// TODO: Try node.dispatchEvent( new CompositionEvent(...) ) so listeners not
|
||||||
scrollTop = element.scrollTop;
|
// 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:
|
range = this.getSelectedRange();
|
||||||
// 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 );
|
|
||||||
|
|
||||||
// restore scroll
|
if ( !range.collapsed ) {
|
||||||
element.scrollTop = scrollTop;
|
range.deleteContents();
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getDivCaretPosition( element ) {
|
if ( range.startContainer.nodeType === Node.TEXT_NODE ) {
|
||||||
var charIndex = 0,
|
// Alter this text node's content and move the cursor
|
||||||
start = 0,
|
textNode = range.startContainer;
|
||||||
end = 0,
|
textOffset = range.startOffset;
|
||||||
foundStart = false,
|
textNode.nodeValue =
|
||||||
foundEnd = false,
|
textNode.nodeValue.substr( 0, textOffset - precedingCharCount ) +
|
||||||
sel;
|
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();
|
rangy.init();
|
||||||
sel = rangy.getSelection();
|
sel = rangy.getSelection();
|
||||||
|
if ( sel.rangeCount === 0 ) {
|
||||||
function traverseTextNodes( node, range ) {
|
return null;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
range = sel.getRangeAt( 0 );
|
||||||
if ( sel.rangeCount ) {
|
if ( !this.$element[ 0 ].contains( range.commonAncestorContainer ) ) {
|
||||||
traverseTextNodes( element, sel.getRangeAt( 0 ) );
|
return null;
|
||||||
}
|
}
|
||||||
|
return range;
|
||||||
|
};
|
||||||
|
|
||||||
return [ start, end ];
|
TextEntryFactory.static.singleton.register( ContentEditableEntry );
|
||||||
}
|
|
||||||
|
|
||||||
function setCaretPosition( $element, position ) {
|
/* Exports */
|
||||||
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];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the caret position in the div.
|
* jQuery plugin ime
|
||||||
* @param {Element} element The content editable div element
|
* @param {Object} option
|
||||||
* @param position
|
|
||||||
*/
|
*/
|
||||||
function setDivCaretPosition( element, position ) {
|
$.fn.ime = function ( option ) {
|
||||||
var nextCharIndex,
|
return this.each( function () {
|
||||||
charIndex = 0,
|
var data, textEntry,
|
||||||
range = rangy.createRange(),
|
$this = $( this ),
|
||||||
foundStart = false,
|
options = typeof option === 'object' && option;
|
||||||
foundEnd = false;
|
|
||||||
|
|
||||||
range.collapseToPoint( element, 0 );
|
data = $this.data( 'ime' );
|
||||||
|
if ( !data ) {
|
||||||
function traverseTextNodes( node ) {
|
textEntry = TextEntryFactory.static.singleton.wrap( $this );
|
||||||
var i, len;
|
if ( textEntry === undefined ) {
|
||||||
|
return;
|
||||||
if ( node.nodeType === 3 ) {
|
|
||||||
nextCharIndex = charIndex + node.length;
|
|
||||||
|
|
||||||
if ( !foundStart && position.start >= charIndex && position.start <= nextCharIndex ) {
|
|
||||||
range.setStart( node, position.start - charIndex );
|
|
||||||
foundStart = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
* private function for debugging
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
function firstDivergence( a, b ) {
|
function debug( $obj ) {
|
||||||
var minLength, i;
|
if ( window.console && window.console.log ) {
|
||||||
|
window.console.log( $obj );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1601,6 +1616,10 @@
|
|||||||
name: 'ফনেটিক',
|
name: 'ফনেটিক',
|
||||||
source: 'rules/as/as-phonetic.js'
|
source: 'rules/as/as-phonetic.js'
|
||||||
},
|
},
|
||||||
|
'as-rodali': {
|
||||||
|
name: 'ৰ\'দালি',
|
||||||
|
source: 'rules/as/as-rodali.js'
|
||||||
|
},
|
||||||
'as-transliteration': {
|
'as-transliteration': {
|
||||||
name: 'প্ৰতিৰূপান্তৰণ',
|
name: 'প্ৰতিৰূপান্তৰণ',
|
||||||
source: 'rules/as/as-transliteration.js'
|
source: 'rules/as/as-transliteration.js'
|
||||||
@@ -2015,6 +2034,10 @@
|
|||||||
name: 'ଟ୍ରାନ୍ସଲିଟରେସନ',
|
name: 'ଟ୍ରାନ୍ସଲିଟରେସନ',
|
||||||
source: 'rules/or/or-transliteration.js'
|
source: 'rules/or/or-transliteration.js'
|
||||||
},
|
},
|
||||||
|
'or-OdiScript': {
|
||||||
|
name: 'ଓଡ଼ିସ୍କ୍ରିପ୍ଟ',
|
||||||
|
source: 'rules/or/or-OdiScript.js'
|
||||||
|
},
|
||||||
'or-inscript': {
|
'or-inscript': {
|
||||||
name: 'ଇନସ୍କ୍ରିପ୍ଟ',
|
name: 'ଇନସ୍କ୍ରିପ୍ଟ',
|
||||||
source: 'rules/or/or-inscript.js'
|
source: 'rules/or/or-inscript.js'
|
||||||
@@ -2435,7 +2458,7 @@
|
|||||||
},
|
},
|
||||||
'or': {
|
'or': {
|
||||||
autonym: 'ଓଡ଼ିଆ',
|
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': {
|
'pa': {
|
||||||
autonym: 'ਪੰਜਾਬੀ',
|
autonym: 'ਪੰਜਾਬੀ',
|
||||||
|
|||||||
147
lib/jquery.ime/rules/as/as-rodali.js
Normal file
147
lib/jquery.ime/rules/as/as-rodali.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
( function ( $ ) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var asRodali = {
|
||||||
|
id: 'as-rodali',
|
||||||
|
name: 'ৰ\'দালি',
|
||||||
|
description: 'Rodali Keyboard',
|
||||||
|
date: '2015-07-26',
|
||||||
|
URL: 'http://github.com/wikimedia/jquery.ime',
|
||||||
|
author: 'Gunadeep Chetia, Subhashish Panigrahi',
|
||||||
|
license: 'GPLv3',
|
||||||
|
version: '1.0',
|
||||||
|
contextLength: 4,
|
||||||
|
maxKeyLength: 5,
|
||||||
|
patterns: [
|
||||||
|
['([ক-হড়ঢ়য়])্?ৰৰi','[^a`]', '$1ৃ'],
|
||||||
|
['ৰৰi','[^a`]', 'ঋ'],
|
||||||
|
['(([ক-হড়ঢ়ৰৱয়]))a','[^a`]', '$1'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])a','a', '$1া'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])i','[^a`]', '$1ি'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])(িi|েe)','[^a`]', '$1ী'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])u','[^a`]', '$1ু'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])ুu','[^a`]', '$1ূ'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])o','[^a`]', '$1ো'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])e','[^a`]', '$1ে'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])োi','[^a`]', '$1ৈ'],
|
||||||
|
['([ক-হড়ঢ়ৰৱয়])োu','[^a`]', '$1ৌ'],
|
||||||
|
['([কঙলষস])(k|K)','[^a`]','$1্ক'],
|
||||||
|
['([গঙদল])(g)','[^a`]','$1্গ'],
|
||||||
|
['([চশ])c','[^a`]','$1্চ'],
|
||||||
|
['([জঞব])j','[^a`]','$1্জ'],
|
||||||
|
['নj','[^a`]','ঞ্জ'],
|
||||||
|
['([কটণনপলষস])T','[^a`]','$1্ট'],
|
||||||
|
['([ডণনল])D','[^a`]','$1্ড'],
|
||||||
|
['([গষহ])N','[^a`]','$1্ণ'],
|
||||||
|
['([কতনপশসহ])t','[^a`]','$1্ত'],
|
||||||
|
['([গদনব])d','[^a`]','$1্দ'],
|
||||||
|
['([গঘণতধনপমশসহ])n','[^a`]','$1্ন'],
|
||||||
|
['([পমলষস])p','[^a`]','$1্প'],
|
||||||
|
['([মস])f', '[^a`]', '$1্ফ'],
|
||||||
|
['([বমল])b','[^a`]','$1্ব'],
|
||||||
|
['([কগঙটণতদধনমলশষসহ])m','[^a`]','$1্ম'],
|
||||||
|
['([ক-ঘচ-ঝট-যলশ-হড়ঢ়য়])r','[^a`]','$1্ৰ'],
|
||||||
|
['([কগপ-বমলশসহ])l','[^a`]','$1্ল'],
|
||||||
|
['([কনপ])s','[^a`]','$1্স'],
|
||||||
|
['([ক-হড়ঢ়য়])(w|b|v)','[^a`]','$1্ব'],
|
||||||
|
['([ক-হড়ঢ়য়])y','[^a`]','$1্য'],
|
||||||
|
['নc','[^a`]','ঞ্চ'],
|
||||||
|
['ৰk','r','ৰ্ক'],
|
||||||
|
['ৰg','r','ৰ্গ'],
|
||||||
|
['ৰc','r','ৰ্চ'],
|
||||||
|
['ৰj','r','ৰ্জ'],
|
||||||
|
['ৰT','r','ৰ্ট'],
|
||||||
|
['ৰD','r','ৰ্ড'],
|
||||||
|
['ৰN','r','ৰ্ণ'],
|
||||||
|
['ৰt','r','ৰ্ত'],
|
||||||
|
['ৰd','r','ৰ্দ'],
|
||||||
|
['ৰn','r','ৰ্ন'],
|
||||||
|
['ৰp','r','ৰ্প'],
|
||||||
|
['ৰf','r','ৰ্ফ'],
|
||||||
|
['ৰb','r','ৰ্ব'],
|
||||||
|
['ৰv','r','ৰ্ভ'],
|
||||||
|
['ৰm','r','ৰ্ম'],
|
||||||
|
['ৰz','r','ৰ্য'],
|
||||||
|
['ৰl','r','ৰ্ল'],
|
||||||
|
['ৰx','r','ৰ্শ'],
|
||||||
|
['ৰS','r','ৰ্ষ'],
|
||||||
|
['ৰs','r','ৰ্স'],
|
||||||
|
['ৰh','r','ৰ্হ'],
|
||||||
|
['ৰR','r','ৰ্ড়'],
|
||||||
|
['ৰy','r','ৰ্য়'],
|
||||||
|
['ত~','t','ৎ'],
|
||||||
|
['অa','a', 'আ'],
|
||||||
|
['কh','k', 'খ'],
|
||||||
|
['গh','g', 'ঘ'],
|
||||||
|
['ণg','N', 'ঙ'],
|
||||||
|
['চh','c', 'ছ'],
|
||||||
|
['জh','j', 'ঝ'],
|
||||||
|
['নG','n', 'ঞ'],
|
||||||
|
['টh','T', 'ঠ'],
|
||||||
|
['ডh','D', 'ঢ'],
|
||||||
|
['তh','t', 'থ'],
|
||||||
|
['দh','d', 'ধ'],
|
||||||
|
['পh','p', 'ফ'],
|
||||||
|
['বh','b', 'ভ'],
|
||||||
|
['সh','s', 'শ'],
|
||||||
|
['ড়h','R', 'ঢ়'],
|
||||||
|
['নg','n', 'ং'],
|
||||||
|
['ওi','o', 'ঐ'],
|
||||||
|
['ওu','o', 'ঔ'],
|
||||||
|
['ইi','i', 'ঈ'],
|
||||||
|
['উu','u', 'ঊ'],
|
||||||
|
['([kK])', 'ক'],
|
||||||
|
['g', 'গ'],
|
||||||
|
['G', 'জ্ঞ'],
|
||||||
|
['(c|C)', 'চ'],
|
||||||
|
['(j|J)', 'জ'],
|
||||||
|
['T', 'ট'],
|
||||||
|
['D', 'ড'],
|
||||||
|
['N', 'ণ'],
|
||||||
|
['t', 'ত'],
|
||||||
|
['d', 'দ'],
|
||||||
|
['n', 'ন'],
|
||||||
|
['(p|P)', 'প'],
|
||||||
|
['f', 'ফ'],
|
||||||
|
['(b|B)', 'ব'],
|
||||||
|
['(v|V)', 'ৱ'],
|
||||||
|
['(m|M)', 'ম'],
|
||||||
|
['z|Z', 'য'],
|
||||||
|
['r', 'ৰ'],
|
||||||
|
['(l|L)', 'ল'],
|
||||||
|
['S', 'ষ'],
|
||||||
|
['s', 'স'],
|
||||||
|
['h', 'হ'],
|
||||||
|
['H', 'ঃ'],
|
||||||
|
['R', 'ড়'],
|
||||||
|
['(w|W)', 'ৱ'],
|
||||||
|
['x', 'শ'],
|
||||||
|
['X', 'ক্ষ'],
|
||||||
|
['y', 'য়'],
|
||||||
|
['a', 'অ'],
|
||||||
|
['i', 'ই'],
|
||||||
|
['u', 'উ'],
|
||||||
|
['e', 'এ'],
|
||||||
|
['o', 'ও'],
|
||||||
|
['0', '০'],
|
||||||
|
['1', '১'],
|
||||||
|
['2', '২'],
|
||||||
|
['3', '৩'],
|
||||||
|
['4', '৪'],
|
||||||
|
['5', '৫'],
|
||||||
|
['6', '৬'],
|
||||||
|
['7', '৭'],
|
||||||
|
['8', '৮'],
|
||||||
|
['9', '৯'],
|
||||||
|
['<','ৃ'],
|
||||||
|
['`', '্'],
|
||||||
|
['\\^', 'ঁ'],
|
||||||
|
['\\.', '।'],
|
||||||
|
['~', '্'],
|
||||||
|
['&', '°'],
|
||||||
|
['\\*', '৺']
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ime.register( asRodali );
|
||||||
|
}( jQuery ) );
|
||||||
116
lib/jquery.ime/rules/or/or-OdiScript.js
Normal file
116
lib/jquery.ime/rules/or/or-OdiScript.js
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
( function ( $ ) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var orOdiScript = {
|
||||||
|
id: 'or-OdiScript',
|
||||||
|
name: 'ଓଡ଼ିସ୍କ୍ରିପ୍ଟ',
|
||||||
|
description: 'Odia OdiScript input method',
|
||||||
|
date: '2015-7-28',
|
||||||
|
URL: 'http://github.com/wikimedia/jquery.ime',
|
||||||
|
author: 'Manoj Sahukar and Subhashish Panigrahi',
|
||||||
|
license: 'GPLv3',
|
||||||
|
version: '1.0',
|
||||||
|
contextLength: 6,
|
||||||
|
maxKeyLength: 4,
|
||||||
|
patterns: [
|
||||||
|
['/([A-Za-z\\>_\\-\\!@#\\$\\^\\&\\%\\*\\~\\.\\|\\\\0-9])', '$1'],
|
||||||
|
['\'([\'])','\"'], //'' to "
|
||||||
|
['\"([\'])','\'\'\''], //'''
|
||||||
|
['([କ-ହ]୍[କ-ହ])@@', 'ର୍\$1'], //reph
|
||||||
|
['([କ-ହ])@@', 'ର୍\$1'], //reph
|
||||||
|
['%%', 'ଙ୍କ' ], // Anka
|
||||||
|
['"', 'ଁ' ], //chanda bindu
|
||||||
|
['([ର])}', 'ର୍ୟ'], // special case: Ja phala (ର + ZWJ + ୍ୟ)
|
||||||
|
['\\}', '୍ୟ' ], // Ja phala
|
||||||
|
['୍\ ', '୍ '], // ending with halant+zwnj
|
||||||
|
['{', 'ୃ' ], // Ru kara
|
||||||
|
['େk', 'ୋ' ], // l= ekar, lk = okar
|
||||||
|
['ାl', 'ୋ' ], // l= ekar, kl = okar
|
||||||
|
['େp', 'ୈ' ], //
|
||||||
|
['ୈk', 'ୌ' ], //
|
||||||
|
['\\]', '୍ର'], // Ra phala
|
||||||
|
['\\[', 'ଅ'], // Type ଅ
|
||||||
|
['ଅk','ଆ'], // ଅ + ା = ଆ
|
||||||
|
['ଓ##','ୱ'],
|
||||||
|
['([ର])##', 'ର୍ୱ'], // special case ର + ZWJ + ୍ୱ
|
||||||
|
['([କ-ହ])##', '$1୍ୱ'], //
|
||||||
|
['ଦQ', 'ହ'],
|
||||||
|
['([କନପସମ])Q', 'ତ୍\$1' ],
|
||||||
|
['([ଖଥଧ])Q', '$1ି' ],
|
||||||
|
['([ନସ])_', '$1୍ତ୍ର' ], //ନ୍ତ୍ର , ସ୍ତ୍ର
|
||||||
|
['\\$', 'କ୍ଷ'],
|
||||||
|
['\\&&','ଏବଂ'],
|
||||||
|
['\\^', 'ଋ'],
|
||||||
|
['\\|', 'ଞ'],
|
||||||
|
['\\\\', 'ୟ'],
|
||||||
|
['<', 'ଏ'],
|
||||||
|
['>', 'ଐ'],
|
||||||
|
['0', '୦'],
|
||||||
|
['1', '୧'],
|
||||||
|
['2', '୨'],
|
||||||
|
['3', '୩'],
|
||||||
|
['4', '୪'],
|
||||||
|
['5', '୫'],
|
||||||
|
['6', '୬'],
|
||||||
|
['7', '୭'],
|
||||||
|
['8', '୮'],
|
||||||
|
['9', '୯'],
|
||||||
|
['a', 'ମ'],
|
||||||
|
['A', 'ଢ଼'],
|
||||||
|
['b', 'ୁ'],
|
||||||
|
['B', 'ଉ'],
|
||||||
|
['c', 'ଜ'],
|
||||||
|
['C', 'ଝ'],
|
||||||
|
['d', '୍'],
|
||||||
|
['D', ''], //zwnj
|
||||||
|
['e', 'ନ'],
|
||||||
|
['E', 'ଡ଼'],
|
||||||
|
['f', 'ତ'],
|
||||||
|
['F', 'ଥ'],
|
||||||
|
['G', 'ଇ'],
|
||||||
|
['g', 'ି'],
|
||||||
|
['H', 'ଈ'],
|
||||||
|
['h', 'ୀ'],
|
||||||
|
['i', 'ଂ'],
|
||||||
|
['I', 'ଠ'],
|
||||||
|
['j', 'ର'],
|
||||||
|
['J', 'ଣ'],
|
||||||
|
['k', 'ା'],
|
||||||
|
['K', 'ଶ'],
|
||||||
|
['l', 'େ'],
|
||||||
|
['L', 'ଷ'],
|
||||||
|
['m', 'ଳ'],
|
||||||
|
['M', 'ଲ'],
|
||||||
|
['n', 'ୂ'],
|
||||||
|
['N', 'ଊ'],
|
||||||
|
['o', 'ହ'],
|
||||||
|
['O', 'ଡ'],
|
||||||
|
['p', 'ୈ'],
|
||||||
|
['P', 'ଢ'],
|
||||||
|
['q', 'ବ'],
|
||||||
|
['r', 'ଦ'],
|
||||||
|
['R', 'ଧ'],
|
||||||
|
['s', 'କ'],
|
||||||
|
['S', 'ଖ'],
|
||||||
|
['t', 'ସ'],
|
||||||
|
['T', 'ଓ'],
|
||||||
|
['u', 'ଯ'],
|
||||||
|
['U', 'ଟ'],
|
||||||
|
['v', 'ଚ'],
|
||||||
|
['V', 'ଛ'],
|
||||||
|
['w', 'ପ'],
|
||||||
|
['W', 'ଫ'],
|
||||||
|
['x', 'ଗ'],
|
||||||
|
['X', 'ଘ'],
|
||||||
|
['y', 'ୌ'],
|
||||||
|
['Y', 'ଔ'],
|
||||||
|
['z', 'ଭ'],
|
||||||
|
['Z', 'ଙ'],
|
||||||
|
['`', '।'],
|
||||||
|
['~', 'ଃ'],
|
||||||
|
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ime.register( orOdiScript );
|
||||||
|
}( jQuery ) );
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
description: 'Odia Lekhani phonetic input method',
|
description: 'Odia Lekhani phonetic input method',
|
||||||
date: '2012-10-14',
|
date: '2012-10-14',
|
||||||
URL: 'http://github.com/wikimedia/jquery.ime',
|
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',
|
license: 'GPLv3',
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
contextLength: 4,
|
contextLength: 4,
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
patterns: [
|
patterns: [
|
||||||
['\\\\([A-Za-z\\>_~\\.0-9])', '\\\\', '$1'],
|
['\\\\([A-Za-z\\>_~\\.0-9])', '\\\\', '$1'],
|
||||||
|
|
||||||
['([(କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])a', '$1ା'],
|
['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])a', '$1ା'],
|
||||||
['([କ-ଳଲନ୍ଧଥଡ଼ଢ଼ହୟୱରକ୍ଷଶସଷଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])i', '$1\u0b3f'],
|
['([କ-ଳଲନ୍ଧଥଡ଼ଢ଼ହୟୱରକ୍ଷଶସଷଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍ଜ])i', '$1\u0b3f'],
|
||||||
['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍])I', '$1ୀ'],
|
['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍])I', '$1ୀ'],
|
||||||
['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍])u', '$1\u0b41'],
|
['([କ-ହୟୱଡ଼ଢ଼ଙ୍କଙ୍ଖଙ୍ଗଙ୍ଘଞ୍ଚଞ୍ଛଞ୍ଝଣ୍ଟଣ୍ଠଣ୍ଡଣ୍ଢନ୍ତନ୍ଥନ୍ଦନ୍ଧମ୍ପମ୍ଫମ୍ବମ୍ଭଞ୍])u', '$1\u0b41'],
|
||||||
@@ -31,13 +31,13 @@
|
|||||||
['([କ-ହୟୱ])(w|v)', '$1୍ୱ'],
|
['([କ-ହୟୱ])(w|v)', '$1୍ୱ'],
|
||||||
['([କ-ହୟୱ])~', '$1\u200C'],
|
['([କ-ହୟୱ])~', '$1\u200C'],
|
||||||
|
|
||||||
['([କ-ହୟୱ])y', '$1୍ୟ'], // <consonant>y
|
['([କ-ହୱ])y', '$1୍ୟ'], // <consonant>y
|
||||||
|
|
||||||
['z', '୍'], // halanta
|
['z', '୍'], // halanta
|
||||||
['\\.', '।'], //purnacheda
|
['\\.', '।'], //purnacheda
|
||||||
['ଅa', 'ଆ'],
|
['ଅa', 'ଆ'],
|
||||||
['ଏe', 'ଐ'],
|
['ଏe', 'ଐ'],
|
||||||
['(ଅu|ଓo|ଓO)', 'ଔ'],
|
['(ଅu|O)', 'ଔ'],
|
||||||
['ଋR', 'ୠ'], // RR
|
['ଋR', 'ୠ'], // RR
|
||||||
['ଳl', 'ଌ'], // Ll
|
['ଳl', 'ଌ'], // Ll
|
||||||
['ଌl', 'ୡ'], // Lll
|
['ଌl', 'ୡ'], // Lll
|
||||||
@@ -45,8 +45,6 @@
|
|||||||
['ଞ୍ଜh', 'ଞ୍ଝ'], // njh
|
['ଞ୍ଜh', 'ଞ୍ଝ'], // njh
|
||||||
['ଙ୍କh', 'ଙ୍ଖ'], // nkh
|
['ଙ୍କh', 'ଙ୍ଖ'], // nkh
|
||||||
['ଙ୍ଗh', 'ଙ୍ଘ'], // ngh
|
['ଙ୍ଗh', 'ଙ୍ଘ'], // ngh
|
||||||
['ହm', 'ହ୍ମ'], // mh
|
|
||||||
['ହn', 'ହ୍ନ'], // nh
|
|
||||||
['ମ୍ବh', 'ମ୍ଭ'], // mbh or nbh
|
['ମ୍ବh', 'ମ୍ଭ'], // mbh or nbh
|
||||||
['ଣ୍ଡai', 'ଣ୍ଡାଇ'], // NDai
|
['ଣ୍ଡai', 'ଣ୍ଡାଇ'], // NDai
|
||||||
['ଜ୍ଜh', 'ଜ୍ଝ'], // jjh
|
['ଜ୍ଜh', 'ଜ୍ଝ'], // jjh
|
||||||
@@ -67,7 +65,6 @@
|
|||||||
['ନD|ଣD', 'ଣ୍ଡ'], // nd
|
['ନD|ଣD', 'ଣ୍ଡ'], // nd
|
||||||
['ଣDh', 'ଣ୍ଢ'], //ndh
|
['ଣDh', 'ଣ୍ଢ'], //ndh
|
||||||
['ନdh', 'ନ୍ଧ'], // ndht
|
['ନdh', 'ନ୍ଧ'], // ndht
|
||||||
['ଷT', '$1୍ଟ'], // ST
|
|
||||||
['ଟh', 'ଠ'], // Th
|
['ଟh', 'ଠ'], // Th
|
||||||
['ଡh', 'ଢ'], // Dh
|
['ଡh', 'ଢ'], // Dh
|
||||||
['ତh', 'ଥ'], // th
|
['ତh', 'ଥ'], // th
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
['3', '٣'],
|
['3', '٣'],
|
||||||
['4', '٤'],
|
['4', '٤'],
|
||||||
['5', '٥'],
|
['5', '٥'],
|
||||||
['6', '٦'],
|
['6', '۶'],
|
||||||
['7', '٧'],
|
['7', '٧'],
|
||||||
['8', '٨'],
|
['8', '٨'],
|
||||||
['9', '٩'],
|
['9', '٩'],
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
contextLength: 5,
|
contextLength: 5,
|
||||||
maxKeyLength: 2,
|
maxKeyLength: 5,
|
||||||
patterns: [
|
patterns: [
|
||||||
//['ඬ්හ්a', 'ඳ'], // nndha
|
//['ඬ්හ්a', 'ඳ'], // nndha
|
||||||
['ඬ්h', 'ඳ්'], // nndh
|
['ඬ්h', 'ඳ්'], // nndh
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
// Combining grave tone mark
|
// Combining grave tone mark
|
||||||
['\\\\', '\u0340'],
|
['\\\\', '\u0340'],
|
||||||
// Combining acute tone mark
|
// Combining acute tone mark
|
||||||
["/", '\u0341']
|
['/', '\u0341']
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user