UNPKG

ares-ide

Version:

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

449 lines (372 loc) 15.6 kB
/*$ * @name handler.js * @fileOverview class to handle phone number parse states * * */ /*globals G11n PhoneLoc */ //* @protected enyo.g11n.StateHandler = function _StateHandler () { return this; }; enyo.g11n.StateHandler.prototype = { processSubscriberNumber: function(number, fields, regionSettings) { var last; last = number.search(/[xwtp]/i); // last digit of the local number if ( last > -1 ) { if ( last > 0 ) { fields.subscriberNumber = number.substring(0, last); } // strip x's which are there to indicate a break between the local subscriber number and the extension, but // are not themselves a dialable character fields.extension = number.substring(last).replace('x', ''); } else { fields.subscriberNumber = number; } if (regionSettings.plan.fieldLengths && regionSettings.plan.fieldLengths.maxLocalLength && fields.subscriberNumber && fields.subscriberNumber.length > regionSettings.plan.fieldLengths.maxLocalLength) { fields.invalid = true; } }, processFieldWithSubscriberNumber: function(fieldName, length, number, currentChar, fields, regionSettings, noExtractTrunk) { var ret, end, last; last = number.search(/[xwtp]/i); // last digit of the local number if ( length !== undefined && length > 0 ) { // fixed length end = length; if ( regionSettings.plan.trunkCode === "0" && number.charAt(0) === "0" ) { end += regionSettings.plan.trunkCode.length; // also extract the trunk access code } } else { // variable length // the setting is the negative of the length to add, so subtract to make it positive end = currentChar + 1 - length; } if ( fields[fieldName] !== undefined ) { // we have a spurious recognition, because this number already contains that field! So, just put // everything into the subscriberNumber as the default this.processSubscriberNumber(number, fields, regionSettings); } else { // substring() extracts the part of the string up to but not including the end character, // so add one to compensate if ( !noExtractTrunk && regionSettings.plan.trunkCode === "0" && number.charAt(0) === "0" ) { fields.trunkAccess = number.charAt(0); fields[fieldName] = number.substring(1, end); } else { fields[fieldName] = number.substring(0, end); } if ( number.length > end ) { this.processSubscriberNumber(number.substring(end), fields, regionSettings); } } ret = { number: "" }; return ret; }, processField: function(fieldName, length, number, currentChar, fields, regionSettings) { var ret = {}, end; if ( length !== undefined && length > 0 ) { // fixed length end = length; if ( regionSettings.plan.trunkCode === "0" && number.charAt(0) === "0" ) { end += regionSettings.plan.trunkCode.length; // also extract the trunk access code } } else { // variable length // the setting is the negative of the length to add, so subtract to make it positive end = currentChar + 1 - length; } if ( fields[fieldName] !== undefined ) { // we have a spurious recognition, because this number already contains that field! So, just put // everything into the subscriberNumber as the default this.processSubscriberNumber(number, fields, regionSettings); ret.number = ""; } else { // substring() extracts the part of the string up to but not including the end character, // so add one to compensate if ( regionSettings.plan.trunkCode === "0" && number.charAt(0) === "0" ) { fields.trunkAccess = number.charAt(0); fields[fieldName] = number.substring(1, end); ret.skipTrunk = true; } else { fields[fieldName] = number.substring(0, end); } ret.number = (number.length > end) ? number.substring(end) : ""; } return ret; }, trunk: function(number, currentChar, fields, regionSettings) { var ret, trunkLength; if ( fields.trunkAccess !== undefined ) { // What? We already have one? Okay, put the rest of this in the subscriber number as the default behaviour then. this.processSubscriberNumber(number, fields, regionSettings); number = ""; } else { trunkLength = regionSettings.plan.trunkCode.length; fields.trunkAccess = number.substring(0, trunkLength); number = (number.length > trunkLength) ? number.substring(trunkLength) : ""; } ret = { number: number }; return ret; }, plus: function(number, currentChar, fields, regionSettings) { var ret = {}; if ( fields.iddPrefix !== undefined ) { // What? We already have one? Okay, put the rest of this in the subscriber number as the default behaviour then. this.processSubscriberNumber(number, fields, regionSettings); ret.number = ""; } else { // found the idd prefix, so save it and cause the function to parse the next part // of the number with the idd table fields.iddPrefix = number.substring(0, 1); ret = { number: number.substring(1), push: new enyo.g11n.Locale('_idd') // shared subtable that parses the country code }; } return ret; }, idd: function(number, currentChar, fields, regionSettings) { var ret = {}; if ( fields.iddPrefix !== undefined ) { // What? We already have one? Okay, put the rest of this in the subscriber number as the default behaviour then. this.processSubscriberNumber(number, fields, regionSettings); ret.number = ""; } else { // found the idd prefix, so save it and cause the function to parse the next part // of the number with the idd table fields.iddPrefix = number.substring(0, currentChar+1); ret = { number: number.substring(currentChar+1), push: new enyo.g11n.Locale('_idd') // shared subtable that parses the country code }; } return ret; }, country: function(number, currentChar, fields, regionSettings) { var ret, cc, locale; // found the country code of an IDD number, so save it and cause the function to // parse the rest of the number with the regular table for this locale fields.countryCode = number.substring(0, currentChar+1); cc = fields.countryCode.replace(/[wWpPtT\+#\*]/g, ''); // fix for NOV-108200 locale = new enyo.g11n.PhoneLoc({countryCode: cc}); // enyo.log("Found country code " + fields.countryCode + ". Switching to country " + locale.region + " to parse the rest of the number"); ret = { number: number.substring(currentChar+1), push: locale }; return ret; }, cic: function(number, currentChar, fields, regionSettings) { return this.processField('cic', regionSettings.plan.fieldLengths.cic, number, currentChar, fields, regionSettings); }, service: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.serviceCode, number, currentChar, fields, regionSettings); }, area: function(number, currentChar, fields, regionSettings) { var ret, last, end, localLength; last = number.search(/[xwtp]/i); // last digit of the local number localLength = (last > -1) ? last : number.length; if ( regionSettings.plan.fieldLengths.areaCode > 0 ) { // fixed length end = regionSettings.plan.fieldLengths.areaCode; if ( regionSettings.plan.trunkCode === number.charAt(0) ) { end += regionSettings.plan.trunkCode.length; // also extract the trunk access code localLength -= regionSettings.plan.trunkCode.length; } } else { // variable length // the setting is the negative of the length to add, so subtract to make it positive end = currentChar + 1 - regionSettings.plan.fieldLengths.areaCode; } // substring() extracts the part of the string up to but not including the end character, // so add one to compensate if ( regionSettings.plan.trunkCode === number.charAt(0) ) { fields.trunkAccess = number.charAt(0); if ( number.length > 1 ) { fields.areaCode = number.substring(1, end); } if ( number.length > end ) { this.processSubscriberNumber(number.substring(end), fields, regionSettings); } } else if ( regionSettings.plan.fieldLengths.maxLocalLength !== undefined ) { if ( fields.trunkAccess !== undefined || fields.mobilePrefix !== undefined || fields.countryCode !== undefined || localLength > regionSettings.plan.fieldLengths.maxLocalLength ) { // too long for a local number by itself, or a different final state already parsed out the trunk // or mobile prefix, then consider the rest of this number to be an area code + part of the subscriber number fields.areaCode = number.substring(0, end); if ( number.length > end ) { this.processSubscriberNumber(number.substring(end), fields, regionSettings); } } else { // shorter than the length needed for a local number, so just consider it a local number this.processSubscriberNumber(number, fields, regionSettings); } } else { fields.areaCode = number.substring(0, end); if ( number.length > end ) { this.processSubscriberNumber(number.substring(end), fields, regionSettings); } } // extensions are separated from the number by a dash in Germany if (regionSettings.plan.findExtensions !== undefined && fields.subscriberNumber !== undefined) { var dash = enyo.indexOf("-", fields.subscriberNumber); if (dash > -1) { fields.subscriberNumber = fields.subscriberNumber.substring(0, dash); fields.extension = fields.subscriberNumber.substring(dash+1); } } ret = { number: "" }; return ret; }, none: function(number, currentChar, fields, regionSettings) { var ret; // this is a last resort function that is called when nothing is recognized. // When this happens, just put the whole stripped number into the subscriber number if ( regionSettings.plan && number.charAt(0) === regionSettings.plan.trunkCode ) { fields.trunkAccess = number.charAt(0); number = number.substring(1); //currentChar--; } if (number.length > 0) { this.processSubscriberNumber(number, fields, regionSettings); if ( currentChar > 0 && currentChar < number.length ) { // if we were part-way through parsing, and we hit an invalid digit, // indicate that the number could not be parsed properly fields.invalid = true; } } ret = { number: "" // indicate that there is nothing left to parse }; return ret; }, vsc: function(number, currentChar, fields, regionSettings) { var ret, length, end; if ( fields.vsc === undefined ) { length = regionSettings.plan.fieldLengths.vsc || 0; if ( length !== undefined && length > 0 ) { // fixed length end = length; } else { // variable length // the setting is the negative of the length to add, so subtract to make it positive end = currentChar + 1 - length; } // found a VSC code (ie. a "star code"), so save it and cause the function to // parse the rest of the number with the same table for this locale fields.vsc = number.substring(0, end); number = (number.length > end) ? "^" + number.substring(end) : ""; } else { // got it twice??? Okay, this is a bogus number then. Just put everything else into the subscriber number as the default this.processSubscriberNumber(number, fields, regionSettings); number = ""; } // treat the rest of the number as if it were a completely new number ret = { number: number }; return ret; }, cell: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('mobilePrefix', regionSettings.plan.fieldLengths.mobilePrefix, number, currentChar, fields, regionSettings); }, personal: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.personal, number, currentChar, fields, regionSettings); }, emergency: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('emergency', regionSettings.plan.fieldLengths.emergency, number, currentChar, fields, regionSettings, true); }, premium: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.premium, number, currentChar, fields, regionSettings); }, special: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.special, number, currentChar, fields, regionSettings); }, service2: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.service2, number, currentChar, fields, regionSettings); }, service3: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.service3, number, currentChar, fields, regionSettings); }, service4: function(number, currentChar, fields, regionSettings) { return this.processFieldWithSubscriberNumber('serviceCode', regionSettings.plan.fieldLengths.service4, number, currentChar, fields, regionSettings); }, cic2: function(number, currentChar, fields, regionSettings) { return this.processField('cic', regionSettings.plan.fieldLengths.cic2, number, currentChar, fields, regionSettings); }, cic3: function(number, currentChar, fields, regionSettings) { return this.processField('cic', regionSettings.plan.fieldLengths.cic3, number, currentChar, fields, regionSettings); }, start: function(number, currentChar, fields, regionSettings) { // don't do anything except transition to the next state return { number: number }; }, local: function(number, currentChar, fields, regionSettings) { // in open dialling plans, we can tell that this number is a local subscriber number because it // starts with a digit that indicates as such this.processSubscriberNumber(number, fields, regionSettings); return { number: "" }; } }; // context-sensitive handler enyo.g11n.CSStateHandler = function () { return this; }; enyo.g11n.CSStateHandler.prototype = new enyo.g11n.StateHandler(); enyo.g11n.CSStateHandler.prototype.special = function (number, currentChar, fields, regionSettings) { var ret; // found a special area code that is both a node and a leaf. In // this state, we have found the leaf, so chop off the end // character to make it a leaf. if (number.charAt(0) === "0") { fields.trunkAccess = number.charAt(0); fields.areaCode = number.substring(1, currentChar); } else { fields.areaCode = number.substring(0, currentChar); } this.processSubscriberNumber(number.substring(currentChar), fields, regionSettings); ret = { number: "" }; return ret; }; enyo.g11n.USStateHandler = function () { return this; }; enyo.g11n.USStateHandler.prototype = new enyo.g11n.StateHandler(); enyo.g11n.USStateHandler.prototype.vsc = function (number, currentChar, fields, regionSettings) { var ret, length, end; // found a VSC code (ie. a "star code") fields.vsc = number; // treat the rest of the number as if it were a completely new number ret = { number: "" }; return ret; }; enyo.g11n._handlerFactory = function (locale, plan) { if (typeof(plan.contextFree) === 'boolean' && plan.contextFree === false) { return new enyo.g11n.CSStateHandler(); } var region = (locale && locale.region) || "zz"; switch (region) { case 'us': return new enyo.g11n.USStateHandler(); break; default: return new enyo.g11n.StateHandler(); } };