UNPKG

ares-ide

Version:

A browser-based code editor and UI designer for Enyo 2 projects

362 lines (321 loc) 8.69 kB
/*$ * @name utils.js * @fileOverview Utility functions for the entire phone library * */ /*globals G11n PhoneLoc enyo*/ //* @protected enyo.g11n.PhoneUtils = { // in what order should fields of the parsed phone model be formatted? fieldOrder: [ "vsc", "iddPrefix", "countryCode", "trunkAccess", "cic", "emergency", "mobilePrefix", "serviceCode", "areaCode", "subscriberNumber", "extension" ], // parsing states in the FSM tables. First state (none) is -1, "unknown" is -2, etc. states: [ "none", "unknown", "plus", "idd", "cic", "service", "cell", "area", "vsc", "country", "personal", "special", "trunk", "premium", "emergency", "service2", "service3", "service4", "cic2", "cic3", "start", "local" ], deepCopy: function _deepCopy(from, to) { var prop; for (prop in from) { if (prop) { if (typeof(from[prop]) === 'object') { to[prop] = {}; _deepCopy(from[prop], to[prop]); } else { to[prop] = from[prop]; } } } return to; }, /* * Returns the region that controls the dialing plan in the given region * (i.e., the "normalized phone region"). */ normPhoneReg: function (region) { var norm; // Map all NANP regions to the right region, so that they get parsed using the // correct state table switch (region) { case "us": // usa case "ca": // canada case "ag": // antigua and barbuda case "bs": // bahamas case "bb": // barbados case "dm": // dominica case "do": // dominican republic case "gd": // grenada case "jm": // jamaica case "kn": // st. kitts and nevis case "lc": // st. lucia case "vc": // st. vincent and the grenadines case "tt": // trinidad and tobago case "ai": // anguilla case "bm": // bermuda case "vg": // british virgin islands case "ky": // cayman islands case "ms": // montserrat case "tc": // turks and caicos case "as": // American Samoa case "vi": // Virgin Islands, U.S. case "pr": // Puerto Rico case "mp": // Northern Mariana Islands case "tl": // East Timor case "gu": // Guam norm = "us"; break; // these all use the Italian dialling plan case "it": // italy case "sm": // san marino case "va": // vatican city norm = "it"; break; // all the French dependencies are on the French dialling plan case "fr": // france case "gf": // french guiana case "mq": // martinique case "gp": // guadeloupe, case "bl": // saint barthélemy case "mf": // saint martin case "re": // réunion, mayotte norm = "fr"; break; default: norm = region; break; } return norm; }, //* @public /** Maps a passed-in mobile carrier code to a country dialing code. */ mapMCCtoCC: function (mcc) { if (!mcc) { return undefined; } if (!enyo.g11n.PhoneUtils.mcc2cc) { enyo.g11n.PhoneUtils.mcc2cc = enyo.g11n.Utils.getNonLocaleFile({ root: enyo.g11n.Utils._getEnyoRoot("../"), path: "phone/base/data/maps/mcc2cc.json" }); } return enyo.g11n.PhoneUtils.mcc2cc[mcc]; }, /** Maps a passed-in mobile carrier code to a region code. */ mapMCCtoRegion: function (mcc) { if (!mcc) { return undefined; } if (!enyo.g11n.PhoneUtils.mcc2reg) { enyo.g11n.PhoneUtils.mcc2reg = enyo.g11n.Utils.getNonLocaleFile({ root: enyo.g11n.Utils._getEnyoRoot("../"), path: "phone/base/data/maps/mcc2reg.json" }); } return enyo.g11n.PhoneUtils.normPhoneReg(enyo.g11n.PhoneUtils.mcc2reg[mcc]) || "unknown"; }, /** Maps a passed-in country dialing code to a region code. */ mapCCtoRegion: function (cc) { if (!cc) { return undefined; } if (!enyo.g11n.PhoneUtils.cc2reg) { enyo.g11n.PhoneUtils.cc2reg = enyo.g11n.Utils.getNonLocaleFile({ root: enyo.g11n.Utils._getEnyoRoot("../"), path: "phone/base/data/maps/cc2reg.json" }); } return enyo.g11n.PhoneUtils.cc2reg[cc] || "unknown"; }, /** Maps a passed-in region code to a country dialing code. */ mapRegiontoCC: function(region) { if (!region) { return undefined; } if (!enyo.g11n.PhoneUtils.reg2cc) { enyo.g11n.PhoneUtils.reg2cc = enyo.g11n.Utils.getNonLocaleFile({ root: enyo.g11n.Utils._getEnyoRoot("../"), path: "phone/base/data/maps/reg2cc.json" }); } return enyo.g11n.PhoneUtils.reg2cc[region] || "0"; }, /** Maps an area code within a dialing plan (cc) to a region code. Some dialing plans (notably the North American Numbering Plan) encompass multiple countries, and have particular area codes assigned to those countries. This function maps back to the actual country code. */ mapAreaToRegion: function (cc, area) { if (!cc) { return undefined; } if (!enyo.g11n.PhoneUtils.area2reg) { enyo.g11n.PhoneUtils.area2reg = enyo.g11n.Utils.getNonLocaleFile({ root: enyo.g11n.Utils._getEnyoRoot("../"), path: "phone/base/data/maps/area2reg.json" }); } if (cc in enyo.g11n.PhoneUtils.area2reg) { return enyo.g11n.PhoneUtils.area2reg[cc][area] || enyo.g11n.PhoneUtils.area2reg[cc]["default"]; } else { return enyo.g11n.PhoneUtils.mapCCtoRegion(cc); } }, //* @protected // Returns a code for each dialable digit in a phone number. _getCharacterCode: function _getCharacterCode(ch) { if (ch >= '0' && ch <= '9') { return ch - '0'; } switch (ch) { case '+': return 10; case '*': return 11; case '#': return 12; case '^': return 13; case 'p': // pause chars case 'P': case 't': case 'T': case 'w': case 'W': return -1; case 'x': case 'X': // extension char return -1; } return -2; }, //* @public /** Takes an IMSI number as a string, parses out the parts, and returns them as fields of a JavaScript object. The parts are: * mcc: The Mobile Country Code * mnc: The Mobile Network Code (identifies the carrier) * msin: The Mobile Service Identification Number (usually the person's subscriber number) Returns undefined if the IMSI cannot be parsed. */ parseImsi: function(imsi) { var ch, i, stateTable, end, handlerMethod, state = 0, newState, fields = {}; // enyo.log("parseImsi: parsing imsi " + imsi); if (!imsi) { return undefined; } i = 0; stateTable = new enyo.g11n.StatesData({ path: "phone/base/data/states", locale: new enyo.g11n.Locale("_mnc") }); if (!stateTable) { // can't parse anything return undefined; } while ( i < imsi.length ) { ch = enyo.g11n.PhoneUtils._getCharacterCode(imsi.charAt(i)); // enyo.log("parsing char " + imsi.charAt(i) + " code: " + ch); if (ch >= 0) { newState = stateTable.get(state)[ch]; if (newState < 0) { // reached a final state. First convert the state to a positive array index // in order to look up the name of the handler function name in the array state = newState; newState = -newState - 1; handlerMethod = enyo.g11n.PhoneUtils.states[newState]; // enyo.log("reached final state " + newState + " handler method is " + handlerMethod + " and i is " + i); // deal with syntactic ambiguity by using the "special" end state instead of "area" if ( handlerMethod === "area" ) { end = i+1; } else if ( handlerMethod === "special" ) { end = i; } else { // unrecognized imsi, so just assume the mnc is 3 digits end = 6; } fields.mcc = imsi.substring(0,3); fields.mnc = imsi.substring(3,end); fields.msin = imsi.substring(end); break; } else { // enyo.log("recognized digit " + optionalch + " continuing..."); // recognized digit, so continue parsing state = newState; i++; } } else if ( ch === -1 ) { // non-transition character, continue parsing in the same state i++; } else { // should not happen // enyo.log("skipping character " + ch); // not a digit, plus, pound, or star, so this is probably a formatting char. Skip it. i++; } } if ( state > 0 ) { if ( i >= imsi.length && i >= 6 ) { // we reached the end of the imsi, but did not finish recognizing anything. // Default to last resort and assume 3 digit mnc fields.mcc = imsi.substring(0,3); fields.mnc = imsi.substring(3,6); fields.msin = imsi.substring(6); } else { // unknown or not enough characters for a real imsi fields = undefined; } } // enyo.log("Globalization.Phone.parseImsi: final result is: " + JSON.stringify(fields)); enyo.g11n.Utils.releaseAllJsonFiles(); return fields; } };