You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					112 lines
				
				5.3 KiB
			
		
		
			
		
	
	
					112 lines
				
				5.3 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								import { VALID_DIGITS } from '../../constants.js'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// The RFC 3966 format for extensions.
							 | 
						||
| 
								 | 
							
								const RFC3966_EXTN_PREFIX = ';ext='
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Helper method for constructing regular expressions for parsing. Creates
							 | 
						||
| 
								 | 
							
								 * an expression that captures up to max_length digits.
							 | 
						||
| 
								 | 
							
								 * @return {string} RegEx pattern to capture extension digits.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								const getExtensionDigitsPattern = (maxLength) => `([${VALID_DIGITS}]{1,${maxLength}})`
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Helper initialiser method to create the regular-expression pattern to match
							 | 
						||
| 
								 | 
							
								 * extensions.
							 | 
						||
| 
								 | 
							
								 * Copy-pasted from Google's `libphonenumber`:
							 | 
						||
| 
								 | 
							
								 * https://github.com/google/libphonenumber/blob/55b2646ec9393f4d3d6661b9c82ef9e258e8b829/javascript/i18n/phonenumbers/phonenumberutil.js#L759-L766
							 | 
						||
| 
								 | 
							
								 * @return {string} RegEx pattern to capture extensions.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								export default function createExtensionPattern(purpose) {
							 | 
						||
| 
								 | 
							
									// We cap the maximum length of an extension based on the ambiguity of the way
							 | 
						||
| 
								 | 
							
									// the extension is prefixed. As per ITU, the officially allowed length for
							 | 
						||
| 
								 | 
							
									// extensions is actually 40, but we don't support this since we haven't seen real
							 | 
						||
| 
								 | 
							
									// examples and this introduces many false interpretations as the extension labels
							 | 
						||
| 
								 | 
							
									// are not standardized.
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var extLimitAfterExplicitLabel = '20';
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var extLimitAfterLikelyLabel = '15';
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var extLimitAfterAmbiguousChar = '9';
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var extLimitWhenNotSure = '6';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var possibleSeparatorsBetweenNumberAndExtLabel = "[ \u00A0\\t,]*";
							 | 
						||
| 
								 | 
							
									// Optional full stop (.) or colon, followed by zero or more spaces/tabs/commas.
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var possibleCharsAfterExtLabel = "[:\\.\uFF0E]?[ \u00A0\\t,-]*";
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var optionalExtnSuffix = "#?";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Here the extension is called out in more explicit way, i.e mentioning it obvious
							 | 
						||
| 
								 | 
							
									// patterns like "ext.".
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var explicitExtLabels =
							 | 
						||
| 
								 | 
							
									  "(?:e?xt(?:ensi(?:o\u0301?|\u00F3))?n?|\uFF45?\uFF58\uFF54\uFF4E?|\u0434\u043E\u0431|anexo)";
							 | 
						||
| 
								 | 
							
									// One-character symbols that can be used to indicate an extension, and less
							 | 
						||
| 
								 | 
							
									// commonly used or more ambiguous extension labels.
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var ambiguousExtLabels = "(?:[x\uFF58#\uFF03~\uFF5E]|int|\uFF49\uFF4E\uFF54)";
							 | 
						||
| 
								 | 
							
									// When extension is not separated clearly.
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var ambiguousSeparator = "[- ]+";
							 | 
						||
| 
								 | 
							
									// This is the same as possibleSeparatorsBetweenNumberAndExtLabel, but not matching
							 | 
						||
| 
								 | 
							
									// comma as extension label may have it.
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var possibleSeparatorsNumberExtLabelNoComma = "[ \u00A0\\t]*";
							 | 
						||
| 
								 | 
							
									// ",," is commonly used for auto dialling the extension when connected. First
							 | 
						||
| 
								 | 
							
									// comma is matched through possibleSeparatorsBetweenNumberAndExtLabel, so we do
							 | 
						||
| 
								 | 
							
									// not repeat it here. Semi-colon works in Iphone and Android also to pop up a
							 | 
						||
| 
								 | 
							
									// button with the extension number following.
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var autoDiallingAndExtLabelsFound = "(?:,{2}|;)";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var rfcExtn = RFC3966_EXTN_PREFIX
							 | 
						||
| 
								 | 
							
									     + getExtensionDigitsPattern(extLimitAfterExplicitLabel);
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var explicitExtn = possibleSeparatorsBetweenNumberAndExtLabel + explicitExtLabels
							 | 
						||
| 
								 | 
							
									     + possibleCharsAfterExtLabel
							 | 
						||
| 
								 | 
							
									     + getExtensionDigitsPattern(extLimitAfterExplicitLabel)
							 | 
						||
| 
								 | 
							
									     + optionalExtnSuffix;
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var ambiguousExtn = possibleSeparatorsBetweenNumberAndExtLabel + ambiguousExtLabels
							 | 
						||
| 
								 | 
							
									     + possibleCharsAfterExtLabel
							 | 
						||
| 
								 | 
							
									+ getExtensionDigitsPattern(extLimitAfterAmbiguousChar)
							 | 
						||
| 
								 | 
							
									+ optionalExtnSuffix;
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var americanStyleExtnWithSuffix = ambiguousSeparator
							 | 
						||
| 
								 | 
							
									+ getExtensionDigitsPattern(extLimitWhenNotSure) + "#";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var autoDiallingExtn = possibleSeparatorsNumberExtLabelNoComma
							 | 
						||
| 
								 | 
							
									     + autoDiallingAndExtLabelsFound + possibleCharsAfterExtLabel
							 | 
						||
| 
								 | 
							
									     + getExtensionDigitsPattern(extLimitAfterLikelyLabel)
							 | 
						||
| 
								 | 
							
									+ optionalExtnSuffix;
							 | 
						||
| 
								 | 
							
									/** @type {string} */
							 | 
						||
| 
								 | 
							
									var onlyCommasExtn = possibleSeparatorsNumberExtLabelNoComma
							 | 
						||
| 
								 | 
							
									    + "(?:,)+" + possibleCharsAfterExtLabel
							 | 
						||
| 
								 | 
							
									    + getExtensionDigitsPattern(extLimitAfterAmbiguousChar)
							 | 
						||
| 
								 | 
							
									    + optionalExtnSuffix;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// The first regular expression covers RFC 3966 format, where the extension is added
							 | 
						||
| 
								 | 
							
									// using ";ext=". The second more generic where extension is mentioned with explicit
							 | 
						||
| 
								 | 
							
									// labels like "ext:". In both the above cases we allow more numbers in extension than
							 | 
						||
| 
								 | 
							
									// any other extension labels. The third one captures when single character extension
							 | 
						||
| 
								 | 
							
									// labels or less commonly used labels are used. In such cases we capture fewer
							 | 
						||
| 
								 | 
							
									// extension digits in order to reduce the chance of falsely interpreting two
							 | 
						||
| 
								 | 
							
									// numbers beside each other as a number + extension. The fourth one covers the
							 | 
						||
| 
								 | 
							
									// special case of American numbers where the extension is written with a hash
							 | 
						||
| 
								 | 
							
									// at the end, such as "- 503#". The fifth one is exclusively for extension
							 | 
						||
| 
								 | 
							
									// autodialling formats which are used when dialling and in this case we accept longer
							 | 
						||
| 
								 | 
							
									// extensions. The last one is more liberal on the number of commas that acts as
							 | 
						||
| 
								 | 
							
									// extension labels, so we have a strict cap on the number of digits in such extensions.
							 | 
						||
| 
								 | 
							
									return rfcExtn + "|"
							 | 
						||
| 
								 | 
							
									       + explicitExtn + "|"
							 | 
						||
| 
								 | 
							
									       + ambiguousExtn + "|"
							 | 
						||
| 
								 | 
							
									       + americanStyleExtnWithSuffix + "|"
							 | 
						||
| 
								 | 
							
									       + autoDiallingExtn + "|"
							 | 
						||
| 
								 | 
							
									       + onlyCommasExtn;
							 | 
						||
| 
								 | 
							
								}
							 |