goog.provide("i18n.phonenumbers.demo"); // includes goog.require("i18n.phonenumbers.PhoneNumberFormat"); goog.require("i18n.phonenumbers.PhoneNumberUtil"); goog.require("i18n.phonenumbers.Error"); goog.require("i18n.phonenumbers.AsYouTypeFormatter"); //* Format the number as the user types. const formatNumberAsYouType = (number, countryCode) => { try { //* Have to clean it first, as AYTF stops formatting as soon as it hits any formatting char (even it's own) //* (it's designed to be fed one char at a time, as opposed to every char every time). const clean = number.replace(/[^+0-9]/g, ""); const formatter = new i18n.phonenumbers.AsYouTypeFormatter(countryCode); let result = ""; for (let i = 0; i < clean.length; i++) { result = formatter.inputDigit(clean.charAt(i)); } return result; } catch (e) { return number; } }; //* Format the given number to the given format. const formatNumber = (number, countryCode, formatArg) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); if (phoneUtil.isPossibleNumber(numberObj)) { const format = typeof formatArg === "undefined" ? i18n.phonenumbers.PhoneNumberFormat.E164 : formatArg; return phoneUtil.format(numberObj, format); } return number; } catch (e) { return number; } }; //* Get an example number for the given country code. const getExampleNumber = (countryCode, national, numberType, useE164) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.getExampleNumberForType( countryCode, numberType, ); let format; if (useE164) { format = i18n.phonenumbers.PhoneNumberFormat.E164; } else { format = national ? i18n.phonenumbers.PhoneNumberFormat.NATIONAL : i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL; } return phoneUtil.format(numberObj, format); } catch (e) { return ""; } }; //* Get the core number, without any international dial code, or national prefix. const getCoreNumber = (number, countryCode) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); return numberObj.getNationalNumber().toString(); } catch (e) { return ""; } }; //* Get the extension from the given number const getExtension = (number, countryCode) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); return numberObj.getExtension(); } catch (e) { return ""; } }; //* Get the type of the given number e.g. fixed-line/mobile. const getNumberType = (number, countryCode) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); return phoneUtil.getNumberType(numberObj); } catch (e) { //* Broken return -99; } }; //* Get more info if the validation has failed e.g. too long/too short. //* NOTE that isPossibleNumberWithReason returns a i18n.phonenumbers.PhoneNumberUtil.ValidationResult. const getValidationError = (number, countryCode) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); return phoneUtil.isPossibleNumberWithReason(numberObj); } catch (e) { //* Here I convert thrown errors into ValidationResult enums (if possible). //* errors are from i18n.phonenumbers.Error in the file https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js. if (e.message === i18n.phonenumbers.Error.INVALID_COUNTRY_CODE) { return i18n.phonenumbers.PhoneNumberUtil.ValidationResult .INVALID_COUNTRY_CODE; } if ( //* Hack to solve issue where parseAndKeepRawInput throws weird error for zero or 1-digit (national) numbers e.g. "3" or "+13" s number.length <= 3 || e.message === i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD || e.message === i18n.phonenumbers.Error.TOO_SHORT_NSN ) { return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_SHORT; } if (e.message === i18n.phonenumbers.Error.TOO_LONG) { return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_LONG; } //* Broken return -99; } }; //* Check if given number is valid. const isValidNumber = (number, countryCode) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); return phoneUtil.isValidNumber(numberObj); } catch (e) { return false; } }; //* Check if given number is possible. const isPossibleNumber = (number, countryCode, numberTypeName) => { try { const phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance(); const numberObj = phoneUtil.parseAndKeepRawInput(number, countryCode); if (numberTypeName) { const resultForType = phoneUtil.isPossibleNumberForTypeWithReason(numberObj, numberType[numberTypeName]); const isPossibleForType = resultForType === i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE; return isPossibleForType; } //* Can't use phoneUtil.isPossibleNumber directly as it accepts IS_POSSIBLE_LOCAL_ONLY numbers e.g. local numbers that are much shorter. const result = phoneUtil.isPossibleNumberWithReason(numberObj); const isPossible = result === i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE; return isPossible; } catch (e) { return false; } }; /******************** * NOTE: for following sections, keys must be in quotes to force closure compiler to preserve them ********************/ //* copied this from i18n.phonenumbers.PhoneNumberFormat in the file https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js. const numberFormat = { "E164": 0, "INTERNATIONAL": 1, "NATIONAL": 2, "RFC3966": 3, }; //* copied this from i18n.phonenumbers.PhoneNumberType in https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js and put the keys in quotes to force closure compiler to preserve the keys // TODO: There must be a way to just tell closure compiler to preserve the keys on i18n.phonenumbers.PhoneNumberType and just export that. const numberType = { "FIXED_LINE": 0, "MOBILE": 1, "FIXED_LINE_OR_MOBILE": 2, "TOLL_FREE": 3, "PREMIUM_RATE": 4, "SHARED_COST": 5, "VOIP": 6, "PERSONAL_NUMBER": 7, "PAGER": 8, "UAN": 9, "VOICEMAIL": 10, "UNKNOWN": -1, }; //* copied this from i18n.phonenumbers.PhoneNumberUtil.ValidationResult in https://github.com/googlei18n/libphonenumber/blob/master/javascript/i18n/phonenumbers/phonenumberutil.js and again put the keys in quotes. const validationError = { "IS_POSSIBLE": 0, "INVALID_COUNTRY_CODE": 1, "TOO_SHORT": 2, "TOO_LONG": 3, "IS_POSSIBLE_LOCAL_ONLY": 4, "INVALID_LENGTH": 5, }; //* Exports //* Note: the below code defines window.intlTelInputUtilsTemp, which is so-called because it will be exported (as an ES Module) and then deleted at the end of this file (see output_wrapper in grunt/closure-compiler.js). goog.exportSymbol("intlTelInputUtilsTemp", {}); goog.exportSymbol("intlTelInputUtilsTemp.formatNumberAsYouType", formatNumberAsYouType); goog.exportSymbol("intlTelInputUtilsTemp.formatNumber", formatNumber); goog.exportSymbol("intlTelInputUtilsTemp.getExampleNumber", getExampleNumber); goog.exportSymbol("intlTelInputUtilsTemp.getExtension", getExtension); goog.exportSymbol("intlTelInputUtilsTemp.getNumberType", getNumberType); goog.exportSymbol("intlTelInputUtilsTemp.getValidationError", getValidationError); goog.exportSymbol("intlTelInputUtilsTemp.isValidNumber", isValidNumber); goog.exportSymbol("intlTelInputUtilsTemp.isPossibleNumber", isPossibleNumber); goog.exportSymbol("intlTelInputUtilsTemp.getCoreNumber", getCoreNumber); //* Enums goog.exportSymbol("intlTelInputUtilsTemp.numberFormat", numberFormat); goog.exportSymbol("intlTelInputUtilsTemp.numberType", numberType); goog.exportSymbol("intlTelInputUtilsTemp.validationError", validationError);