/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* jshint moz:true */ /* jshint unused:true */ /* global InputMethods */ (function() { 'use strict'; var keyboard; var buffer = ''; var BACKSPACE = 8; var M = { consoTT: new RegExp('^(' + '\u1000|\u1001|\u1002|\u1003|\u1005|\u1006|\u1007|\u1008|' + '\u1009|\u100A|\u100B|\u100C|\u100D|\u100E|\u100F|\u1010|' + '\u1011|\u1012|\u1013|\u1014|\u1015|\u1016|\u1017|\u1018|' + '\u1019|\u101A|\u101B|\u101C|\u101D|\u101E|\u101F|\u1020|' + '\u1021' + ')$'), consoSA: new RegExp('^(' + '\u101E' + ')$'), vowelIA: new RegExp('^(' + '\u102D|\u102E|\u1032|\u1036|\u102F|\u1030|\u102B|\u102C' + ')$'), vowelIU: new RegExp('^(' + '\u102D|\u102E|\u102F|\u1030' + ')$'), vowelSI: new RegExp('^(' + '\u102D|\u102E' + ')$'), vowelIN: new RegExp('^(' + '\u1032|\u1036' + ')$'), vowelUU: new RegExp('^(' + '\u102F|\u1030' + ')$'), vowelAA: new RegExp('^(' + '\u102B|\u102C' + ')$'), vowelSU: new RegExp('^(' + '\u1025' + ')$'), vowelDU: new RegExp('^(' + '\u1026' + ')$'), vowelSO: new RegExp('^(' + '\u1029' + ')$'), vowelSA: new RegExp('^(' + '\u102C' + ')$'), vowelDI: new RegExp('^(' + '\u102E' + ')$'), vowelSE: new RegExp('^(' + '\u1031' + ')$'), vowelAI: new RegExp('^(' + '\u1032' + ')$'), vowelAN: new RegExp('^(' + '\u1036' + ')$'), vowelAU: new RegExp('^(' + '\u1037' + ')$'), vowelVT: new RegExp('^(' + '\u1038|\u103A' + ')$'), vowelVS: new RegExp('^(' + '\u1038' + ')$'), vowelVR: new RegExp('^(' + '\u1039' + ')$'), vowelAT: new RegExp('^(' + '\u103A' + ')$'), mediaYH: new RegExp('^(' + '\u103B|\u103C|\u103D|\u103E' + ')$'), mediaYW: new RegExp('^(' + '\u103B|\u103C|\u103D' + ')$'), mediaYR: new RegExp('^(' + '\u103B|\u103C' + ')$'), mediaYA: new RegExp('^(' + '\u103B' + ')$'), mediaRA: new RegExp('^(' + '\u103C' + ')$'), mediaWA: new RegExp('^(' + '\u103D' + ')$'), mediaHA: new RegExp('^(' + '\u103E' + ')$'), zeroLEN: new RegExp('^(' + '\u200B' + ')$') }; //================================================================== // \u103D + \u103E + \u1031 + \u103B => $4 + $1 + $2 + $3 // \u103D + \u103E + \u1031 + \u103C => $4 + $1 + $2 + $3 // \u103D + \u1031 + \u103B => $3 + $1 + $2 // \u103D + \u1031 + \u103C => $3 + $1 + $2 // \u103D + \u103E + \u103B => $3 + $1 + $2 // \u103D + \u103E + \u103C => $3 + $1 + $2 // \u103E + \u1031 + \u103B => $3 + $1 + $2 // \u103E + \u1031 + \u103C => $3 + $1 + $2 // \u103E + \u1031 + \u103D => $3 + $1 + $2 // \u1031 + \u1039 + consoTT[*] => $2 + $3 + $1 // \u200B + \u1031 + consoTT[*] => $3 + $2 // \u1031 + mediaYH[*] => $2 + $1 // \u1036 + \u1032 => $2 +$1 // \u1037 + vowelSI[*] => $2 + $1 // \u1037 + vowelIN[*] => $2 + $1 // \u1037 + vowelAA[*] => $2 + $1 // \u1037 + vowelUU[*] => $2 + $1 // \u1038 + \u1037 => $2 + $1 // \u103A + \u1037 => $2 + $1 // \u103D + \u103B => $2 + $1 // \u103D + \u103C => $2 + $1 // \u103E + \u103B => $2 + $1 // \u103E + \u103C => $2 + $1 // \u103E + \u103D => $2 + $1 // vowelUU[*] + vowelSI[*] => $2 + $1 // vowelIN[*] + vowelUU[*] => $2 + $1 // vowelIN[*] + vowelSI[*] => $2 + $1 //================================================================== var SWAP_RULE = [ // p1 + p2 + p3 + p4 => p4 + p1 + p2 + p3 { num: 4, out: 4, t:1, p1: M.mediaWA, p2: M.mediaHA, p3: M.vowelSE, p4: M.mediaYR }, // p1 + p2 + p3 => p3 + p2 { num: 3, out: 2, t:1, p1: M.zeroLEN, p2: M.vowelSE, p3: M.consoTT }, // p1 + p2 + p3 => p3 + p1 + p2 { num: 3, out: 3, t:1, p1: M.mediaWA, p2: M.vowelSE, p3: M.mediaYR }, { num: 3, out: 3, t:1, p1: M.mediaWA, p2: M.mediaHA, p3: M.mediaYR }, { num: 3, out: 3, t:1, p1: M.mediaHA, p2: M.vowelSE, p3: M.mediaYW }, // p1 + p2 + p3 => p2 + p3 + p1 { num: 3, out: 3, t:2, p1: M.vowelSE, p2: M.vowelVR, p3: M.consoTT }, // p1 + p2 => p2 + p1 { num: 2, out: 2, t:1, p1: M.vowelSE, p2: M.mediaYH }, { num: 2, out: 2, t:1, p1: M.vowelAN, p2: M.vowelAI }, { num: 2, out: 2, t:1, p1: M.vowelAU, p2: M.vowelIA }, { num: 2, out: 2, t:1, p1: M.vowelVT, p2: M.vowelAU }, { num: 2, out: 2, t:1, p1: M.vowelUU, p2: M.vowelSI }, { num: 2, out: 2, t:1, p1: M.vowelIN, p2: M.vowelIU }, { num: 2, out: 2, t:1, p1: M.mediaWA, p2: M.mediaYR }, { num: 2, out: 2, t:1, p1: M.mediaHA, p2: M.mediaYW } ]; //================================================================== // \u1025 + \u102E => \u1026 // \u1025 + \u103A => \u1009 + \u103A // \u101E + \u103C + \u1031 + \u102C + \u103A => \u102A //================================================================== var ADD_RULE = [ { num: 2, out: '\u1026', p1: M.vowelSU, p2: M.vowelDI }, { num: 2, out: '\u1009\u103A', p1: M.vowelSU, p2: M.vowelAT }, { num: 5, out: '\u102A', p1: M.consoSA, p2: M.mediaRA, p3: M.vowelSE, p4: M.vowelSA, p5: M.vowelAT } ]; //================================================================== // \u1039 + consoTT[*] + \u1031 + < VK_BACK > => \u1039 + $filler + \u1031 // \u200B + consoTT[*] + \u1031 + < VK_BACK > => $filler + \u1031 // mediaYH[*] + \u1031 + < VK_BACK > => \u1031 // \u1039 + consoTT[*] + < VK_BACK > => NULL // \u200B + \u1031 + < VK_BACK > => NULL //================================================================== var DEL_RULE = [ {num: 3, out: '\u1031\u1039', p1: M.vowelVR, p2: M.consoTT, p3: M.vowelSE}, {num: 2, out: '\u200B\u1031', p1: M.consoTT, p2: M.vowelSE}, {num: 2, out: '\u1031', p1: M.mediaYH, p2: M.vowelSE}, {num: 2, out: '', p1: M.vowelVR, p2: M.consoTT}, {num: 2, out: '', p1: M.zeroLEN, p2: M.vowelSE} ]; function myanParser(rule, callback) { var idx = ['p0', 'p1', 'p2', 'p3', 'p4', 'p5']; var len = buffer.length; if (len < 2) { return null; } for (var i = 0; i < rule.length; i++) { if (len < rule[i].num) { continue; } var c = len - 1; for (var j = rule[i].num; j > 0; j--) { if (!buffer[c--].match( rule[i][idx[j]] )) { break; } } if (j === 0) { return callback(rule[i]); } } return null; } function processBuffer(callback) { var swap = myanParser(SWAP_RULE, function(entry) { if (!entry) { return null; } var len = buffer.length; var tail = entry.t; var out = entry.out; var s = {}; s.num = entry.num; s.str = buffer.substr(len-tail, tail) + buffer.substr(len-out, out-tail); return s; }); // After process swap, check if the string need to be merged. var adds = myanParser(ADD_RULE, function(entry) { if (!entry) { return null; } var s = {}; s.num = entry.num; s.str = entry.out; return s; }); return (adds) ? callback(adds) : callback(swap); } function doDelete(callback) { var dels = myanParser(DEL_RULE, function(entry) { if (!entry) { return null; } var s = {}; s.num = entry.num; s.str = entry.out; return s; }); return (dels) ? callback(dels) : false; } function overrideInput(s) { if(s) { keyboard.replaceSurroundingText(s.str, -s.num, s.num); return true; } return false; } InputMethods.myanmar = { init: function(interfaceObject) { keyboard = interfaceObject; }, click: function(keycode) { keyboard.setUpperCase({ isUpperCase: false }); if (keycode == BACKSPACE) { if(!doDelete(overrideInput)) { keyboard.sendKey(keycode); } } else { if (String.fromCharCode(keycode) == '\u1031') { // Send an extra zero length space on click of vowel sign E. keyboard.sendKey('\u200B'.charCodeAt(0)); } keyboard.sendKey(keycode); } }, surroundingtextChange: function(detail) { buffer = detail.beforeString; processBuffer(overrideInput); } }; })();