1 /* 2 * phoneloc.js - Represent a phone locale object. 3 * 4 * Copyright © 2014-2015, 2018, JEDLSoft 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 // !data phoneloc 21 22 var ilib = require("../index.js"); 23 var Utils = require("./Utils.js"); 24 var Locale = require("./Locale.js"); 25 26 /** 27 * @class 28 * Extension of the locale class that has extra methods to map various numbers 29 * related to phone number parsing. 30 * 31 * @param {Object} options Options that govern how this phone locale works 32 * 33 * @private 34 * @constructor 35 * @extends Locale 36 */ 37 var PhoneLocale = function(options) { 38 var region, 39 mcc, 40 cc, 41 sync = true, 42 loadParams = {}, 43 locale; 44 45 locale = (options && options.locale) || ilib.getLocale(); 46 47 this.parent.call(this, locale); 48 49 region = this.region; 50 51 if (options) { 52 if (typeof(options.mcc) !== 'undefined') { 53 mcc = options.mcc; 54 } 55 56 if (typeof(options.countryCode) !== 'undefined') { 57 cc = options.countryCode; 58 } 59 60 if (typeof(options.sync) !== 'undefined') { 61 sync = !!options.sync; 62 } 63 64 if (options.loadParams) { 65 loadParams = options.loadParams; 66 } 67 } 68 69 Utils.loadData({ 70 name: "phoneloc.json", 71 object: "PhoneLocale", 72 nonlocale: true, 73 sync: sync, 74 loadParams: loadParams, 75 callback: ilib.bind(this, function (data) { 76 /** @type {{mcc2reg:Object.<string,string>,cc2reg:Object.<string,string>,reg2cc:Object.<string,string>,area2reg:Object.<string,string>}} */ 77 this.mappings = data; 78 79 if (typeof(mcc) !== 'undefined') { 80 region = this.mappings.mcc2reg[mcc]; 81 } 82 83 if (typeof(cc) !== 'undefined') { 84 region = this.mappings.cc2reg[cc]; 85 } 86 87 if (!region) { 88 region = "XX"; 89 } 90 91 this.region = this._normPhoneReg(region); 92 this._genSpec(); 93 94 if (options && typeof(options.onLoad) === 'function') { 95 options.onLoad(this); 96 } 97 }) 98 }); 99 }; 100 101 PhoneLocale.prototype = new Locale(); 102 PhoneLocale.prototype.parent = Locale; 103 PhoneLocale.prototype.constructor = PhoneLocale; 104 105 /** 106 * Map a mobile carrier code to a region code. 107 * 108 * @static 109 * @package 110 * @param {string|undefined} mcc the MCC to map 111 * @return {string|undefined} the region code 112 */ 113 114 PhoneLocale.prototype._mapMCCtoRegion = function(mcc) { 115 if (!mcc) { 116 return undefined; 117 } 118 return this.mappings.mcc2reg && this.mappings.mcc2reg[mcc] || "XX"; 119 }; 120 121 /** 122 * Map a country code to a region code. 123 * 124 * @static 125 * @package 126 * @param {string|undefined} cc the country code to map 127 * @return {string|undefined} the region code 128 */ 129 PhoneLocale.prototype._mapCCtoRegion = function(cc) { 130 if (!cc) { 131 return undefined; 132 } 133 return this.mappings.cc2reg && this.mappings.cc2reg[cc] || "XX"; 134 }; 135 136 /** 137 * Map a region code to a country code. 138 * 139 * @static 140 * @package 141 * @param {string|undefined} region the region code to map 142 * @return {string|undefined} the country code 143 */ 144 PhoneLocale.prototype._mapRegiontoCC = function(region) { 145 if (!region) { 146 return undefined; 147 } 148 return this.mappings.reg2cc && this.mappings.reg2cc[region] || "0"; 149 }; 150 151 /** 152 * Map a country code to a region code. 153 * 154 * @static 155 * @package 156 * @param {string|undefined} cc the country code to map 157 * @param {string|undefined} area the area code within the country code's numbering plan 158 * @return {string|undefined} the region code 159 */ 160 PhoneLocale.prototype._mapAreatoRegion = function(cc, area) { 161 if (!cc) { 162 return undefined; 163 } 164 if (cc in this.mappings.area2reg) { 165 return this.mappings.area2reg[cc][area] || this.mappings.area2reg[cc]["default"]; 166 } else { 167 return this.mappings.cc2reg[cc]; 168 } 169 }; 170 171 /** 172 * Return the region that controls the dialing plan in the given 173 * region. (ie. the "normalized phone region".) 174 * 175 * @static 176 * @package 177 * @param {string} region the region code to normalize 178 * @return {string} the normalized region code 179 */ 180 PhoneLocale.prototype._normPhoneReg = function(region) { 181 var norm; 182 183 /* 184 * Country list has been updated from metadata.json fro, libphonenumber-js library v1.7.20 185 * and Modified some countries based on Wikipedia 186 */ 187 188 // Map all NANP regions to the right region, so that they get parsed using the 189 // correct state table 190 switch (region) { 191 case "US": // usa 192 case "AG": // antigua and barbuda 193 case "AI": // anguilla 194 case "AS": // American Samoa 195 case "BB": // barbados 196 case "BM": // bermuda 197 case "BS": // bahamas 198 case "CA": // canada 199 case "DM": // dominica 200 case "DO": // dominican republic 201 case "GD": // grenada 202 case "GU": // Guam 203 case "JM": // jamaica 204 case "KN": // st. kitts and nevis 205 case "KY": // cayman islands 206 case "LC": // st. lucia 207 case "MP": // Northern Mariana Islands 208 case "MS": // montserrat 209 case "PR": // Puerto Rico 210 case "SX": // Sint Maarten 211 case "TC": // turks and caicos 212 case "TT": // trinidad and tobago 213 case "VC": // st. vincent and the grenadines 214 case "VG": // british virgin islands 215 case "VI": // Virgin Islands, U.S. 216 norm = "US"; 217 break; 218 219 /* all the French dependencies are on the French dialling plan 220 * Update manually following Wikipedia information 221 * https://en.wikipedia.org/wiki/Telephone_numbers_in_France#Others 222 */ 223 case "FR": // france 224 case "GF": // french guiana 225 case "MQ": // martinique 226 case "GP": // guadeloupe, 227 case "BL": // saint barthélemy 228 case "MF": // saint martin 229 case "RE": // réunion 230 case "YT": // mayotte 231 norm = "FR"; 232 break; 233 234 // these all use the Italian dialling plan 235 case "IT": // italy 236 case "SM": // san marino 237 case "VA": // vatican city // Update manually following Wikipedia information 238 norm = "IT"; 239 break; 240 241 // all the UK dependencies are on the UK dialling plan 242 case "GB": // United Kingdom 243 case "GG": // Guernsey 244 case "IM": // Isle of Man 245 case "JE": // Jersey 246 norm = "GB"; 247 break; 248 case "RU": // Russia 249 case "KZ": // Kazakhstan 250 norm = "RU"; 251 break; 252 case "NO": // Norway 253 case "SJ": // Svalbard and Jan Mayen 254 norm = "NO"; 255 break; 256 case "AU": // Australia 257 case "CC": // Cocos (Keeling) Islands 258 case "CX": // Christmas Island 259 norm = "AU"; 260 break; 261 case "MA": // Morocco 262 case "EH": // Western Sahara 263 norm = "MA"; 264 break; 265 case "SH": // Saint Helena 266 case "TA": // ? 267 norm = "SH"; 268 break; 269 case "FI": // Finland 270 case "AX": // Aland Islands 271 norm = "FI"; 272 break; 273 case "GP": // Guadeloupe 274 case "BL": // Saint-Barthélemy 275 case "MF": // Saint Martin (French part) 276 norm = "GP"; 277 break; 278 case "CW": // Curaçao 279 case "BQ": // Caribbean Netherlands 280 norm = "CW"; 281 break; 282 default: 283 norm = region; 284 break; 285 } 286 return norm; 287 }; 288 289 module.exports = PhoneLocale;