libphonenumber-execjs 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +6 -1
- data/Rakefile +1 -4
- data/lib/libphonenumber-execjs/libphonenumber.rb +4 -0
- data/lib/libphonenumber-execjs/version.rb +1 -1
- data/support/libphonenumber.js +25 -984
- data/support/simple.coffee +19 -12
- data/test/libphonenumber_test.rb +40 -12
- metadata +5 -5
data/README.md
CHANGED
@@ -22,7 +22,7 @@ However, the entire js context of the library is available via the `context` acc
|
|
22
22
|
|
23
23
|
libphonenumber.context.call "i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber", "19255550100"
|
24
24
|
|
25
|
-
And
|
25
|
+
And two additional functions that I've put together to tie some of these things together in a useful way,
|
26
26
|
with the goal of trying to get a valid E164 formatted number back or not in one call.
|
27
27
|
|
28
28
|
You can pass:
|
@@ -36,6 +36,11 @@ Example (see tests for more examples):
|
|
36
36
|
libphonenumber.simple.get_e164_phone_number("5550100", "US", "925") # => "+19255550100"
|
37
37
|
libphonenumber.simple.get_e164_phone_number("+19255550100") # => "+19255550100"
|
38
38
|
|
39
|
+
Or to get back an array in the form of [ formatted, cc, ndc ]:
|
40
|
+
|
41
|
+
libphonenumber.simple.get_e164_phone_number_with_meta("+19255550100") # => [ "+19255550100", "1", "925" ]
|
42
|
+
libphonenumber.simple.get_e164_phone_number_with_meta("fake") # => []
|
43
|
+
|
39
44
|
## Development/Recompiling sources
|
40
45
|
|
41
46
|
There is a rake task `build_js` in the Rakefile. You will need the source for google closure, and libphonenumber checked out locally.
|
data/Rakefile
CHANGED
@@ -21,8 +21,6 @@ task :build_js do
|
|
21
21
|
--input="#{libphonenumber}javascript/i18n/phonenumbers/phonenumber.pb.js" \
|
22
22
|
--input="#{libphonenumber}javascript/i18n/phonenumbers/metadata.js" \
|
23
23
|
--input="#{libphonenumber}javascript/i18n/phonenumbers/phonenumberutil.js" \
|
24
|
-
--input="#{libphonenumber}javascript/i18n/phonenumbers/asyoutypeformatter.js" \
|
25
|
-
--namespace="i18n.phonenumbers.AsYouTypeFormatter" \
|
26
24
|
--namespace="i18n.phonenumbers.metadata" \
|
27
25
|
--namespace="i18n.phonenumbers.NumberFormat" \
|
28
26
|
--namespace="i18n.phonenumbers.PhoneNumberDesc" \
|
@@ -38,8 +36,7 @@ task :build_js do
|
|
38
36
|
"#{libphonenumber}javascript/i18n/phonenumbers/phonemetadata.pb.js" \
|
39
37
|
"#{libphonenumber}javascript/i18n/phonenumbers/phonenumber.pb.js" \
|
40
38
|
"#{libphonenumber}javascript/i18n/phonenumbers/metadata.js" \
|
41
|
-
"#{libphonenumber}javascript/i18n/phonenumbers/phonenumberutil.js"
|
42
|
-
"#{libphonenumber}javascript/i18n/phonenumbers/asyoutypeformatter.js"
|
39
|
+
"#{libphonenumber}javascript/i18n/phonenumbers/phonenumberutil.js"
|
43
40
|
}
|
44
41
|
out = `#{cmd.strip}`
|
45
42
|
simple = CoffeeScript.compile(File.read(File.join(File.dirname(__FILE__), "support", "simple.coffee")))
|
@@ -32,6 +32,10 @@ class Libphonenumber
|
|
32
32
|
def get_e164_phone_number(str, cc=nil, ndc=nil)
|
33
33
|
@context.call "getE164PhoneNumber", str, cc, ndc
|
34
34
|
end
|
35
|
+
|
36
|
+
def get_e164_phone_number_with_meta(str, cc=nil, ndc=nil)
|
37
|
+
@context.call "getE164PhoneNumberWithMeta", str, cc, ndc
|
38
|
+
end
|
35
39
|
|
36
40
|
end
|
37
41
|
|
data/support/libphonenumber.js
CHANGED
@@ -17674,981 +17674,9 @@ i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_ = function(regex, str) {
|
|
17674
17674
|
}
|
17675
17675
|
return false;
|
17676
17676
|
};
|
17677
|
-
/**
|
17678
|
-
* @license
|
17679
|
-
* Copyright (C) 2010 The Libphonenumber Authors
|
17680
|
-
*
|
17681
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
17682
|
-
* you may not use this file except in compliance with the License.
|
17683
|
-
* You may obtain a copy of the License at
|
17684
|
-
*
|
17685
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
17686
|
-
*
|
17687
|
-
* Unless required by applicable law or agreed to in writing, software
|
17688
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
17689
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17690
|
-
* See the License for the specific language governing permissions and
|
17691
|
-
* limitations under the License.
|
17692
|
-
*/
|
17693
|
-
|
17694
|
-
/**
|
17695
|
-
* @fileoverview A formatter which formats phone numbers as they are entered.
|
17696
|
-
* (based on the java implementation).
|
17697
|
-
*
|
17698
|
-
* <p>An AsYouTypeFormatter can be created by new AsYouTypeFormatter(). After
|
17699
|
-
* that, digits can be added by invoking {@link #inputDigit} on the formatter
|
17700
|
-
* instance, and the partially formatted phone number will be returned each time
|
17701
|
-
* a digit is added. {@link #clear} can be invoked before formatting a new
|
17702
|
-
* number.
|
17703
|
-
*
|
17704
|
-
* <p>See the unittests for more details on how the formatter is to be used.
|
17705
|
-
*
|
17706
|
-
* @author Nikolaos Trogkanis
|
17707
|
-
*/
|
17708
|
-
|
17709
|
-
goog.provide('i18n.phonenumbers.AsYouTypeFormatter');
|
17710
|
-
|
17711
|
-
goog.require('goog.string.StringBuffer');
|
17712
|
-
goog.require('i18n.phonenumbers.NumberFormat');
|
17713
|
-
goog.require('i18n.phonenumbers.PhoneMetadata');
|
17714
|
-
goog.require('i18n.phonenumbers.PhoneMetadataCollection');
|
17715
|
-
goog.require('i18n.phonenumbers.PhoneNumber');
|
17716
|
-
goog.require('i18n.phonenumbers.PhoneNumber.CountryCodeSource');
|
17717
|
-
goog.require('i18n.phonenumbers.PhoneNumberDesc');
|
17718
|
-
goog.require('i18n.phonenumbers.PhoneNumberUtil');
|
17719
|
-
goog.require('i18n.phonenumbers.metadata');
|
17720
|
-
|
17721
|
-
|
17722
|
-
|
17723
|
-
/**
|
17724
|
-
* Constructs an AsYouTypeFormatter for the specific region.
|
17725
|
-
*
|
17726
|
-
* @param {string} regionCode the ISO 3166-1 two-letter region code that denotes
|
17727
|
-
* the region where the phone number is being entered.
|
17728
|
-
* @constructor
|
17729
|
-
*/
|
17730
|
-
i18n.phonenumbers.AsYouTypeFormatter = function(regionCode) {
|
17731
|
-
/**
|
17732
|
-
* The digits that have not been entered yet will be represented by a \u2008,
|
17733
|
-
* the punctuation space.
|
17734
|
-
* @const
|
17735
|
-
* @type {string}
|
17736
|
-
* @private
|
17737
|
-
*/
|
17738
|
-
this.digitPlaceholder_ = '\u2008';
|
17739
|
-
/**
|
17740
|
-
* @type {RegExp}
|
17741
|
-
* @private
|
17742
|
-
*/
|
17743
|
-
this.digitPattern_ = new RegExp(this.digitPlaceholder_);
|
17744
|
-
/**
|
17745
|
-
* @type {string}
|
17746
|
-
* @private
|
17747
|
-
*/
|
17748
|
-
this.currentOutput_ = '';
|
17749
|
-
/**
|
17750
|
-
* @type {!goog.string.StringBuffer}
|
17751
|
-
* @private
|
17752
|
-
*/
|
17753
|
-
this.formattingTemplate_ = new goog.string.StringBuffer();
|
17754
|
-
/**
|
17755
|
-
* The pattern from numberFormat that is currently used to create
|
17756
|
-
* formattingTemplate.
|
17757
|
-
* @type {string}
|
17758
|
-
* @private
|
17759
|
-
*/
|
17760
|
-
this.currentFormattingPattern_ = '';
|
17761
|
-
/**
|
17762
|
-
* @type {!goog.string.StringBuffer}
|
17763
|
-
* @private
|
17764
|
-
*/
|
17765
|
-
this.accruedInput_ = new goog.string.StringBuffer();
|
17766
|
-
/**
|
17767
|
-
* @type {!goog.string.StringBuffer}
|
17768
|
-
* @private
|
17769
|
-
*/
|
17770
|
-
this.accruedInputWithoutFormatting_ = new goog.string.StringBuffer();
|
17771
|
-
/**
|
17772
|
-
* This indicates whether AsYouTypeFormatter is currently doing the
|
17773
|
-
* formatting.
|
17774
|
-
* @type {boolean}
|
17775
|
-
* @private
|
17776
|
-
*/
|
17777
|
-
this.ableToFormat_ = true;
|
17778
|
-
/**
|
17779
|
-
* Set to true when users enter their own formatting. AsYouTypeFormatter will
|
17780
|
-
* do no formatting at all when this is set to true.
|
17781
|
-
* @type {boolean}
|
17782
|
-
* @private
|
17783
|
-
*/
|
17784
|
-
this.inputHasFormatting_ = false;
|
17785
|
-
/**
|
17786
|
-
* @type {boolean}
|
17787
|
-
* @private
|
17788
|
-
*/
|
17789
|
-
this.isInternationalFormatting_ = false;
|
17790
|
-
/**
|
17791
|
-
* @type {boolean}
|
17792
|
-
* @private
|
17793
|
-
*/
|
17794
|
-
this.isExpectingCountryCallingCode_ = false;
|
17795
|
-
/**
|
17796
|
-
* @type {i18n.phonenumbers.PhoneNumberUtil}
|
17797
|
-
* @private
|
17798
|
-
*/
|
17799
|
-
this.phoneUtil_ = i18n.phonenumbers.PhoneNumberUtil.getInstance();
|
17800
|
-
/**
|
17801
|
-
* @type {number}
|
17802
|
-
* @private
|
17803
|
-
*/
|
17804
|
-
this.lastMatchPosition_ = 0;
|
17805
|
-
/**
|
17806
|
-
* The position of a digit upon which inputDigitAndRememberPosition is most
|
17807
|
-
* recently invoked, as found in the original sequence of characters the user
|
17808
|
-
* entered.
|
17809
|
-
* @type {number}
|
17810
|
-
* @private
|
17811
|
-
*/
|
17812
|
-
this.originalPosition_ = 0;
|
17813
|
-
/**
|
17814
|
-
* The position of a digit upon which inputDigitAndRememberPosition is most
|
17815
|
-
* recently invoked, as found in accruedInputWithoutFormatting.
|
17816
|
-
* entered.
|
17817
|
-
* @type {number}
|
17818
|
-
* @private
|
17819
|
-
*/
|
17820
|
-
this.positionToRemember_ = 0;
|
17821
|
-
/**
|
17822
|
-
* This contains anything that has been entered so far preceding the national
|
17823
|
-
* significant number, and it is formatted (e.g. with space inserted). For
|
17824
|
-
* example, this can contain IDD, country code, and/or NDD, etc.
|
17825
|
-
* @type {!goog.string.StringBuffer}
|
17826
|
-
* @private
|
17827
|
-
*/
|
17828
|
-
this.prefixBeforeNationalNumber_ = new goog.string.StringBuffer();
|
17829
|
-
/**
|
17830
|
-
* This contains the national prefix that has been extracted. It contains only
|
17831
|
-
* digits without formatting.
|
17832
|
-
* @type {string}
|
17833
|
-
* @private
|
17834
|
-
*/
|
17835
|
-
this.nationalPrefixExtracted_ = '';
|
17836
|
-
/**
|
17837
|
-
* @type {!goog.string.StringBuffer}
|
17838
|
-
* @private
|
17839
|
-
*/
|
17840
|
-
this.nationalNumber_ = new goog.string.StringBuffer();
|
17841
|
-
/**
|
17842
|
-
* @type {Array.<i18n.phonenumbers.NumberFormat>}
|
17843
|
-
* @private
|
17844
|
-
*/
|
17845
|
-
this.possibleFormats_ = [];
|
17846
|
-
/**
|
17847
|
-
* @type {string}
|
17848
|
-
* @private
|
17849
|
-
*/
|
17850
|
-
this.defaultCountry_ = regionCode;
|
17851
|
-
this.currentMetaData_ = this.getMetadataForRegion_(this.defaultCountry_);
|
17852
|
-
/**
|
17853
|
-
* @type {i18n.phonenumbers.PhoneMetadata}
|
17854
|
-
* @private
|
17855
|
-
*/
|
17856
|
-
this.defaultMetaData_ = this.currentMetaData_;
|
17857
|
-
};
|
17858
|
-
|
17859
|
-
|
17860
|
-
/**
|
17861
|
-
* @const
|
17862
|
-
* @type {i18n.phonenumbers.PhoneMetadata}
|
17863
|
-
* @private
|
17864
|
-
*/
|
17865
|
-
i18n.phonenumbers.AsYouTypeFormatter.EMPTY_METADATA_ =
|
17866
|
-
new i18n.phonenumbers.PhoneMetadata();
|
17867
|
-
i18n.phonenumbers.AsYouTypeFormatter.EMPTY_METADATA_
|
17868
|
-
.setInternationalPrefix('NA');
|
17869
|
-
|
17870
|
-
|
17871
|
-
/**
|
17872
|
-
* A pattern that is used to match character classes in regular expressions.
|
17873
|
-
* An example of a character class is [1-4].
|
17874
|
-
* @const
|
17875
|
-
* @type {RegExp}
|
17876
|
-
* @private
|
17877
|
-
*/
|
17878
|
-
i18n.phonenumbers.AsYouTypeFormatter.CHARACTER_CLASS_PATTERN_ =
|
17879
|
-
/\[([^\[\]])*\]/g;
|
17880
|
-
|
17881
|
-
|
17882
|
-
/**
|
17883
|
-
* Any digit in a regular expression that actually denotes a digit. For
|
17884
|
-
* example, in the regular expression 80[0-2]\d{6,10}, the first 2 digits
|
17885
|
-
* (8 and 0) are standalone digits, but the rest are not.
|
17886
|
-
* Two look-aheads are needed because the number following \\d could be a
|
17887
|
-
* two-digit number, since the phone number can be as long as 15 digits.
|
17888
|
-
* @const
|
17889
|
-
* @type {RegExp}
|
17890
|
-
* @private
|
17891
|
-
*/
|
17892
|
-
i18n.phonenumbers.AsYouTypeFormatter.STANDALONE_DIGIT_PATTERN_ =
|
17893
|
-
/\d(?=[^,}][^,}])/g;
|
17894
|
-
|
17895
|
-
|
17896
|
-
/**
|
17897
|
-
* A pattern that is used to determine if a numberFormat under availableFormats
|
17898
|
-
* is eligible to be used by the AYTF. It is eligible when the format element
|
17899
|
-
* under numberFormat contains groups of the dollar sign followed by a single
|
17900
|
-
* digit, separated by valid phone number punctuation. This prevents invalid
|
17901
|
-
* punctuation (such as the star sign in Israeli star numbers) getting into the
|
17902
|
-
* output of the AYTF.
|
17903
|
-
* @const
|
17904
|
-
* @type {RegExp}
|
17905
|
-
* @private
|
17906
|
-
*/
|
17907
|
-
i18n.phonenumbers.AsYouTypeFormatter.ELIGIBLE_FORMAT_PATTERN_ = new RegExp(
|
17908
|
-
'^[' + i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION + ']*' +
|
17909
|
-
'(\\$\\d[' + i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION + ']*)+$');
|
17910
|
-
|
17911
|
-
|
17912
|
-
/**
|
17913
|
-
* This is the minimum length of national number accrued that is required to
|
17914
|
-
* trigger the formatter. The first element of the leadingDigitsPattern of
|
17915
|
-
* each numberFormat contains a regular expression that matches up to this
|
17916
|
-
* number of digits.
|
17917
|
-
* @const
|
17918
|
-
* @type {number}
|
17919
|
-
* @private
|
17920
|
-
*/
|
17921
|
-
i18n.phonenumbers.AsYouTypeFormatter.MIN_LEADING_DIGITS_LENGTH_ = 3;
|
17922
|
-
|
17923
|
-
|
17924
|
-
/**
|
17925
|
-
* The metadata needed by this class is the same for all regions sharing the
|
17926
|
-
* same country calling code. Therefore, we return the metadata for "main"
|
17927
|
-
* region for this country calling code.
|
17928
|
-
* @param {string} regionCode
|
17929
|
-
* @return {i18n.phonenumbers.PhoneMetadata}
|
17930
|
-
* @private
|
17931
|
-
*/
|
17932
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.getMetadataForRegion_ =
|
17933
|
-
function(regionCode) {
|
17934
|
-
|
17935
|
-
/** @type {number} */
|
17936
|
-
var countryCallingCode = this.phoneUtil_.getCountryCodeForRegion(regionCode);
|
17937
|
-
/** @type {string} */
|
17938
|
-
var mainCountry =
|
17939
|
-
this.phoneUtil_.getRegionCodeForCountryCode(countryCallingCode);
|
17940
|
-
/** @type {i18n.phonenumbers.PhoneMetadata} */
|
17941
|
-
var metadata = this.phoneUtil_.getMetadataForRegion(mainCountry);
|
17942
|
-
if (metadata != null) {
|
17943
|
-
return metadata;
|
17944
|
-
}
|
17945
|
-
// Set to a default instance of the metadata. This allows us to function with
|
17946
|
-
// an incorrect region code, even if formatting only works for numbers
|
17947
|
-
// specified with '+'.
|
17948
|
-
return i18n.phonenumbers.AsYouTypeFormatter.EMPTY_METADATA_;
|
17949
|
-
};
|
17950
|
-
|
17951
|
-
|
17952
|
-
/**
|
17953
|
-
* @return {boolean} true if a new template is created as opposed to reusing the
|
17954
|
-
* existing template.
|
17955
|
-
* @private
|
17956
|
-
*/
|
17957
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.maybeCreateNewTemplate_ =
|
17958
|
-
function() {
|
17959
|
-
|
17960
|
-
// When there are multiple available formats, the formatter uses the first
|
17961
|
-
// format where a formatting template could be created.
|
17962
|
-
/** @type {number} */
|
17963
|
-
var possibleFormatsLength = this.possibleFormats_.length;
|
17964
|
-
for (var i = 0; i < possibleFormatsLength; ++i) {
|
17965
|
-
/** @type {i18n.phonenumbers.NumberFormat} */
|
17966
|
-
var numberFormat = this.possibleFormats_[i];
|
17967
|
-
/** @type {string} */
|
17968
|
-
var pattern = numberFormat.getPatternOrDefault();
|
17969
|
-
if (this.currentFormattingPattern_ == pattern) {
|
17970
|
-
return false;
|
17971
|
-
}
|
17972
|
-
if (this.createFormattingTemplate_(numberFormat)) {
|
17973
|
-
this.currentFormattingPattern_ = pattern;
|
17974
|
-
// With a new formatting template, the matched position using the old
|
17975
|
-
// template needs to be reset.
|
17976
|
-
this.lastMatchPosition_ = 0;
|
17977
|
-
return true;
|
17978
|
-
}
|
17979
|
-
}
|
17980
|
-
this.ableToFormat_ = false;
|
17981
|
-
return false;
|
17982
|
-
};
|
17983
|
-
|
17984
|
-
|
17985
|
-
/**
|
17986
|
-
* @param {string} leadingThreeDigits
|
17987
|
-
* @private
|
17988
|
-
*/
|
17989
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.getAvailableFormats_ =
|
17990
|
-
function(leadingThreeDigits) {
|
17991
|
-
|
17992
|
-
/** @type {Array.<i18n.phonenumbers.NumberFormat>} */
|
17993
|
-
var formatList =
|
17994
|
-
(this.isInternationalFormatting_ &&
|
17995
|
-
this.currentMetaData_.intlNumberFormatCount() > 0) ?
|
17996
|
-
this.currentMetaData_.intlNumberFormatArray() :
|
17997
|
-
this.currentMetaData_.numberFormatArray();
|
17998
|
-
/** @type {number} */
|
17999
|
-
var formatListLength = formatList.length;
|
18000
|
-
for (var i = 0; i < formatListLength; ++i) {
|
18001
|
-
/** @type {i18n.phonenumbers.NumberFormat} */
|
18002
|
-
var format = formatList[i];
|
18003
|
-
if (this.isFormatEligible_(format.getFormatOrDefault())) {
|
18004
|
-
this.possibleFormats_.push(format);
|
18005
|
-
}
|
18006
|
-
}
|
18007
|
-
this.narrowDownPossibleFormats_(leadingThreeDigits);
|
18008
|
-
};
|
18009
|
-
|
18010
|
-
|
18011
|
-
/**
|
18012
|
-
* @param {string} format
|
18013
|
-
* @return {boolean}
|
18014
|
-
* @private
|
18015
|
-
*/
|
18016
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.isFormatEligible_ =
|
18017
|
-
function(format) {
|
18018
|
-
return i18n.phonenumbers.AsYouTypeFormatter.ELIGIBLE_FORMAT_PATTERN_
|
18019
|
-
.test(format);
|
18020
|
-
};
|
18021
|
-
|
18022
|
-
|
18023
|
-
/**
|
18024
|
-
* @param {string} leadingDigits
|
18025
|
-
* @private
|
18026
|
-
*/
|
18027
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.narrowDownPossibleFormats_ =
|
18028
|
-
function(leadingDigits) {
|
18029
|
-
|
18030
|
-
/** @type {Array.<i18n.phonenumbers.NumberFormat>} */
|
18031
|
-
var possibleFormats = [];
|
18032
|
-
/** @type {number} */
|
18033
|
-
var indexOfLeadingDigitsPattern =
|
18034
|
-
leadingDigits.length -
|
18035
|
-
i18n.phonenumbers.AsYouTypeFormatter.MIN_LEADING_DIGITS_LENGTH_;
|
18036
|
-
/** @type {number} */
|
18037
|
-
var possibleFormatsLength = this.possibleFormats_.length;
|
18038
|
-
for (var i = 0; i < possibleFormatsLength; ++i) {
|
18039
|
-
/** @type {i18n.phonenumbers.NumberFormat} */
|
18040
|
-
var format = this.possibleFormats_[i];
|
18041
|
-
if (format.leadingDigitsPatternCount() > indexOfLeadingDigitsPattern) {
|
18042
|
-
/** @type {string} */
|
18043
|
-
var leadingDigitsPattern =
|
18044
|
-
format.getLeadingDigitsPatternOrDefault(indexOfLeadingDigitsPattern);
|
18045
|
-
if (leadingDigits.search(leadingDigitsPattern) == 0) {
|
18046
|
-
possibleFormats.push(this.possibleFormats_[i]);
|
18047
|
-
}
|
18048
|
-
} else {
|
18049
|
-
// else the particular format has no more specific leadingDigitsPattern,
|
18050
|
-
// and it should be retained.
|
18051
|
-
possibleFormats.push(this.possibleFormats_[i]);
|
18052
|
-
}
|
18053
|
-
}
|
18054
|
-
this.possibleFormats_ = possibleFormats;
|
18055
|
-
};
|
18056
|
-
|
18057
|
-
|
18058
|
-
/**
|
18059
|
-
* @param {i18n.phonenumbers.NumberFormat} format
|
18060
|
-
* @return {boolean}
|
18061
|
-
* @private
|
18062
|
-
*/
|
18063
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.createFormattingTemplate_ =
|
18064
|
-
function(format) {
|
18065
|
-
|
18066
|
-
/** @type {string} */
|
18067
|
-
var numberPattern = format.getPatternOrDefault();
|
18068
|
-
|
18069
|
-
// The formatter doesn't format numbers when numberPattern contains '|', e.g.
|
18070
|
-
// (20|3)\d{4}. In those cases we quickly return.
|
18071
|
-
if (numberPattern.indexOf('|') != -1) {
|
18072
|
-
return false;
|
18073
|
-
}
|
18074
|
-
|
18075
|
-
// Replace anything in the form of [..] with \d
|
18076
|
-
numberPattern = numberPattern.replace(
|
18077
|
-
i18n.phonenumbers.AsYouTypeFormatter.CHARACTER_CLASS_PATTERN_, '\\d');
|
18078
|
-
|
18079
|
-
// Replace any standalone digit (not the one in d{}) with \d
|
18080
|
-
numberPattern = numberPattern.replace(
|
18081
|
-
i18n.phonenumbers.AsYouTypeFormatter.STANDALONE_DIGIT_PATTERN_, '\\d');
|
18082
|
-
this.formattingTemplate_.clear();
|
18083
|
-
/** @type {string} */
|
18084
|
-
var tempTemplate = this.getFormattingTemplate_(numberPattern,
|
18085
|
-
format.getFormatOrDefault());
|
18086
|
-
if (tempTemplate.length > 0) {
|
18087
|
-
this.formattingTemplate_.append(tempTemplate);
|
18088
|
-
return true;
|
18089
|
-
}
|
18090
|
-
return false;
|
18091
|
-
};
|
18092
|
-
|
18093
|
-
|
18094
|
-
/**
|
18095
|
-
* Gets a formatting template which can be used to efficiently format a
|
18096
|
-
* partial number where digits are added one by one.
|
18097
|
-
*
|
18098
|
-
* @param {string} numberPattern
|
18099
|
-
* @param {string} numberFormat
|
18100
|
-
* @return {string}
|
18101
|
-
* @private
|
18102
|
-
*/
|
18103
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.getFormattingTemplate_ =
|
18104
|
-
function(numberPattern, numberFormat) {
|
18105
|
-
|
18106
|
-
// Creates a phone number consisting only of the digit 9 that matches the
|
18107
|
-
// numberPattern by applying the pattern to the longestPhoneNumber string.
|
18108
|
-
/** @type {string} */
|
18109
|
-
var longestPhoneNumber = '999999999999999';
|
18110
|
-
/** @type {Array.<string>} */
|
18111
|
-
var m = longestPhoneNumber.match(numberPattern);
|
18112
|
-
// this match will always succeed
|
18113
|
-
/** @type {string} */
|
18114
|
-
var aPhoneNumber = m[0];
|
18115
|
-
// No formatting template can be created if the number of digits entered so
|
18116
|
-
// far is longer than the maximum the current formatting rule can accommodate.
|
18117
|
-
if (aPhoneNumber.length < this.nationalNumber_.getLength()) {
|
18118
|
-
return '';
|
18119
|
-
}
|
18120
|
-
// Formats the number according to numberFormat
|
18121
|
-
/** @type {string} */
|
18122
|
-
var template = aPhoneNumber.replace(new RegExp(numberPattern, 'g'),
|
18123
|
-
numberFormat);
|
18124
|
-
// Replaces each digit with character digitPlaceholder
|
18125
|
-
template = template.replace(new RegExp('9', 'g'), this.digitPlaceholder_);
|
18126
|
-
return template;
|
18127
|
-
};
|
18128
|
-
|
18129
|
-
|
18130
|
-
/**
|
18131
|
-
* Clears the internal state of the formatter, so it can be reused.
|
18132
|
-
*/
|
18133
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.clear = function() {
|
18134
|
-
this.currentOutput_ = '';
|
18135
|
-
this.accruedInput_.clear();
|
18136
|
-
this.accruedInputWithoutFormatting_.clear();
|
18137
|
-
this.formattingTemplate_.clear();
|
18138
|
-
this.lastMatchPosition_ = 0;
|
18139
|
-
this.currentFormattingPattern_ = '';
|
18140
|
-
this.prefixBeforeNationalNumber_.clear();
|
18141
|
-
this.nationalPrefixExtracted_ = '';
|
18142
|
-
this.nationalNumber_.clear();
|
18143
|
-
this.ableToFormat_ = true;
|
18144
|
-
this.inputHasFormatting_ = false;
|
18145
|
-
this.positionToRemember_ = 0;
|
18146
|
-
this.originalPosition_ = 0;
|
18147
|
-
this.isInternationalFormatting_ = false;
|
18148
|
-
this.isExpectingCountryCallingCode_ = false;
|
18149
|
-
this.possibleFormats_ = [];
|
18150
|
-
if (this.currentMetaData_ != this.defaultMetaData_) {
|
18151
|
-
this.currentMetaData_ = this.getMetadataForRegion_(this.defaultCountry_);
|
18152
|
-
}
|
18153
|
-
};
|
18154
|
-
|
18155
|
-
|
18156
|
-
/**
|
18157
|
-
* Formats a phone number on-the-fly as each digit is entered.
|
18158
|
-
*
|
18159
|
-
* @param {string} nextChar the most recently entered digit of a phone number.
|
18160
|
-
* Formatting characters are allowed, but as soon as they are encountered
|
18161
|
-
* this method formats the number as entered and not 'as you type' anymore.
|
18162
|
-
* Full width digits and Arabic-indic digits are allowed, and will be shown
|
18163
|
-
* as they are.
|
18164
|
-
* @return {string} the partially formatted phone number.
|
18165
|
-
*/
|
18166
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigit = function(nextChar) {
|
18167
|
-
this.currentOutput_ =
|
18168
|
-
this.inputDigitWithOptionToRememberPosition_(nextChar, false);
|
18169
|
-
return this.currentOutput_;
|
18170
|
-
};
|
18171
|
-
|
18172
|
-
|
18173
|
-
/**
|
18174
|
-
* Same as {@link #inputDigit}, but remembers the position where
|
18175
|
-
* {@code nextChar} is inserted, so that it can be retrieved later by using
|
18176
|
-
* {@link #getRememberedPosition}. The remembered position will be automatically
|
18177
|
-
* adjusted if additional formatting characters are later inserted/removed in
|
18178
|
-
* front of {@code nextChar}.
|
18179
|
-
*
|
18180
|
-
* @param {string} nextChar
|
18181
|
-
* @return {string}
|
18182
|
-
*/
|
18183
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigitAndRememberPosition =
|
18184
|
-
function(nextChar) {
|
18185
|
-
|
18186
|
-
this.currentOutput_ =
|
18187
|
-
this.inputDigitWithOptionToRememberPosition_(nextChar, true);
|
18188
|
-
return this.currentOutput_;
|
18189
|
-
};
|
18190
|
-
|
18191
|
-
|
18192
|
-
/**
|
18193
|
-
* @param {string} nextChar
|
18194
|
-
* @param {boolean} rememberPosition
|
18195
|
-
* @return {string}
|
18196
|
-
* @private
|
18197
|
-
*/
|
18198
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.
|
18199
|
-
inputDigitWithOptionToRememberPosition_ = function(nextChar,
|
18200
|
-
rememberPosition) {
|
18201
|
-
|
18202
|
-
this.accruedInput_.append(nextChar);
|
18203
|
-
if (rememberPosition) {
|
18204
|
-
this.originalPosition_ = this.accruedInput_.getLength();
|
18205
|
-
}
|
18206
|
-
// We do formatting on-the-fly only when each character entered is either a
|
18207
|
-
// digit, or a plus sign (accepted at the start of the number only).
|
18208
|
-
if (!this.isDigitOrLeadingPlusSign_(nextChar)) {
|
18209
|
-
this.ableToFormat_ = false;
|
18210
|
-
this.inputHasFormatting_ = true;
|
18211
|
-
} else {
|
18212
|
-
nextChar = this.normalizeAndAccrueDigitsAndPlusSign_(nextChar,
|
18213
|
-
rememberPosition);
|
18214
|
-
}
|
18215
|
-
if (!this.ableToFormat_) {
|
18216
|
-
// When we are unable to format because of reasons other than that
|
18217
|
-
// formatting chars have been entered, it can be due to really long IDDs or
|
18218
|
-
// NDDs. If that is the case, we might be able to do formatting again after
|
18219
|
-
// extracting them.
|
18220
|
-
if (this.inputHasFormatting_) {
|
18221
|
-
return this.accruedInput_.toString();
|
18222
|
-
} else if (this.attemptToExtractIdd_()) {
|
18223
|
-
if (this.attemptToExtractCountryCallingCode_()) {
|
18224
|
-
return this.attemptToChoosePatternWithPrefixExtracted_();
|
18225
|
-
}
|
18226
|
-
} else if (this.ableToExtractLongerNdd_()) {
|
18227
|
-
// Add an additional space to separate long NDD and national significant
|
18228
|
-
// number for readability.
|
18229
|
-
this.prefixBeforeNationalNumber_.append(' ');
|
18230
|
-
return this.attemptToChoosePatternWithPrefixExtracted_();
|
18231
|
-
}
|
18232
|
-
return this.accruedInput_.toString();
|
18233
|
-
}
|
18234
|
-
|
18235
|
-
// We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH
|
18236
|
-
// digits (the plus sign is counted as a digit as well for this purpose) have
|
18237
|
-
// been entered.
|
18238
|
-
switch (this.accruedInputWithoutFormatting_.getLength()) {
|
18239
|
-
case 0:
|
18240
|
-
case 1:
|
18241
|
-
case 2:
|
18242
|
-
return this.accruedInput_.toString();
|
18243
|
-
case 3:
|
18244
|
-
if (this.attemptToExtractIdd_()) {
|
18245
|
-
this.isExpectingCountryCallingCode_ = true;
|
18246
|
-
} else {
|
18247
|
-
// No IDD or plus sign is found, might be entering in national format.
|
18248
|
-
this.nationalPrefixExtracted_ =
|
18249
|
-
this.removeNationalPrefixFromNationalNumber_();
|
18250
|
-
return this.attemptToChooseFormattingPattern_();
|
18251
|
-
}
|
18252
|
-
default:
|
18253
|
-
if (this.isExpectingCountryCallingCode_) {
|
18254
|
-
if (this.attemptToExtractCountryCallingCode_()) {
|
18255
|
-
this.isExpectingCountryCallingCode_ = false;
|
18256
|
-
}
|
18257
|
-
return this.prefixBeforeNationalNumber_.toString() +
|
18258
|
-
this.nationalNumber_.toString();
|
18259
|
-
}
|
18260
|
-
if (this.possibleFormats_.length > 0) {
|
18261
|
-
// The formatting pattern is already chosen.
|
18262
|
-
/** @type {string} */
|
18263
|
-
var tempNationalNumber = this.inputDigitHelper_(nextChar);
|
18264
|
-
// See if the accrued digits can be formatted properly already. If not,
|
18265
|
-
// use the results from inputDigitHelper, which does formatting based on
|
18266
|
-
// the formatting pattern chosen.
|
18267
|
-
/** @type {string} */
|
18268
|
-
var formattedNumber = this.attemptToFormatAccruedDigits_();
|
18269
|
-
if (formattedNumber.length > 0) {
|
18270
|
-
return formattedNumber;
|
18271
|
-
}
|
18272
|
-
this.narrowDownPossibleFormats_(this.nationalNumber_.toString());
|
18273
|
-
if (this.maybeCreateNewTemplate_()) {
|
18274
|
-
return this.inputAccruedNationalNumber_();
|
18275
|
-
}
|
18276
|
-
return this.ableToFormat_ ?
|
18277
|
-
this.prefixBeforeNationalNumber_.toString() + tempNationalNumber :
|
18278
|
-
tempNationalNumber;
|
18279
|
-
} else {
|
18280
|
-
return this.attemptToChooseFormattingPattern_();
|
18281
|
-
}
|
18282
|
-
}
|
18283
|
-
};
|
18284
|
-
|
18285
|
-
|
18286
|
-
/**
|
18287
|
-
* @return {string}
|
18288
|
-
* @private
|
18289
|
-
*/
|
18290
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.
|
18291
|
-
attemptToChoosePatternWithPrefixExtracted_ = function() {
|
18292
|
-
|
18293
|
-
this.ableToFormat_ = true;
|
18294
|
-
this.isExpectingCountryCallingCode_ = false;
|
18295
|
-
this.possibleFormats_ = [];
|
18296
|
-
return this.attemptToChooseFormattingPattern_();
|
18297
|
-
};
|
18298
|
-
|
18299
|
-
|
18300
|
-
/**
|
18301
|
-
* Some national prefixes are a substring of others. If extracting the shorter
|
18302
|
-
* NDD doesn't result in a number we can format, we try to see if we can extract
|
18303
|
-
* a longer version here.
|
18304
|
-
* @return {boolean}
|
18305
|
-
* @private
|
18306
|
-
*/
|
18307
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.ableToExtractLongerNdd_ =
|
18308
|
-
function() {
|
18309
|
-
if (this.nationalPrefixExtracted_.length > 0) {
|
18310
|
-
// Put the extracted NDD back to the national number before attempting to
|
18311
|
-
// extract a new NDD.
|
18312
|
-
/** @type {string} */
|
18313
|
-
var nationalNumberStr = this.nationalNumber_.toString();
|
18314
|
-
this.nationalNumber_.clear();
|
18315
|
-
this.nationalNumber_.append(this.nationalPrefixExtracted_);
|
18316
|
-
this.nationalNumber_.append(nationalNumberStr);
|
18317
|
-
// Remove the previously extracted NDD from prefixBeforeNationalNumber. We
|
18318
|
-
// cannot simply set it to empty string because people sometimes enter
|
18319
|
-
// national prefix after country code, e.g +44 (0)20-1234-5678.
|
18320
|
-
/** @type {string} */
|
18321
|
-
var prefixBeforeNationalNumberStr =
|
18322
|
-
this.prefixBeforeNationalNumber_.toString();
|
18323
|
-
/** @type {number} */
|
18324
|
-
var indexOfPreviousNdd = prefixBeforeNationalNumberStr.lastIndexOf(
|
18325
|
-
this.nationalPrefixExtracted_);
|
18326
|
-
this.prefixBeforeNationalNumber_.clear();
|
18327
|
-
this.prefixBeforeNationalNumber_.append(
|
18328
|
-
prefixBeforeNationalNumberStr.substring(0, indexOfPreviousNdd));
|
18329
|
-
}
|
18330
|
-
return this.nationalPrefixExtracted_ !=
|
18331
|
-
this.removeNationalPrefixFromNationalNumber_();
|
18332
|
-
};
|
18333
|
-
|
18334
|
-
|
18335
|
-
/**
|
18336
|
-
* @param {string} nextChar
|
18337
|
-
* @return {boolean}
|
18338
|
-
* @private
|
18339
|
-
*/
|
18340
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.isDigitOrLeadingPlusSign_ =
|
18341
|
-
function(nextChar) {
|
18342
|
-
return i18n.phonenumbers.PhoneNumberUtil.CAPTURING_DIGIT_PATTERN
|
18343
|
-
.test(nextChar) ||
|
18344
|
-
(this.accruedInput_.getLength() == 1 &&
|
18345
|
-
i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_PATTERN.test(nextChar));
|
18346
|
-
};
|
18347
|
-
|
18348
|
-
|
18349
|
-
/**
|
18350
|
-
* @return {string}
|
18351
|
-
* @private
|
18352
|
-
*/
|
18353
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToFormatAccruedDigits_ =
|
18354
|
-
function() {
|
18355
|
-
|
18356
|
-
/** @type {string} */
|
18357
|
-
var nationalNumber = this.nationalNumber_.toString();
|
18358
|
-
/** @type {number} */
|
18359
|
-
var possibleFormatsLength = this.possibleFormats_.length;
|
18360
|
-
for (var i = 0; i < possibleFormatsLength; ++i) {
|
18361
|
-
/** @type {i18n.phonenumbers.NumberFormat} */
|
18362
|
-
var numFormat = this.possibleFormats_[i];
|
18363
|
-
/** @type {string} */
|
18364
|
-
var pattern = numFormat.getPatternOrDefault();
|
18365
|
-
/** @type {RegExp} */
|
18366
|
-
var patternRegExp = new RegExp('^(?:' + pattern + ')$');
|
18367
|
-
if (patternRegExp.test(nationalNumber)) {
|
18368
|
-
/** @type {string} */
|
18369
|
-
var formattedNumber = nationalNumber.replace(new RegExp(pattern, 'g'),
|
18370
|
-
numFormat.getFormat());
|
18371
|
-
return this.prefixBeforeNationalNumber_.toString() + formattedNumber;
|
18372
|
-
}
|
18373
|
-
}
|
18374
|
-
return '';
|
18375
|
-
};
|
18376
|
-
|
18377
|
-
|
18378
|
-
/**
|
18379
|
-
* Returns the current position in the partially formatted phone number of the
|
18380
|
-
* character which was previously passed in as the parameter of
|
18381
|
-
* {@link #inputDigitAndRememberPosition}.
|
18382
|
-
*
|
18383
|
-
* @return {number}
|
18384
|
-
*/
|
18385
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.getRememberedPosition =
|
18386
|
-
function() {
|
18387
|
-
|
18388
|
-
if (!this.ableToFormat_) {
|
18389
|
-
return this.originalPosition_;
|
18390
|
-
}
|
18391
|
-
/** @type {number} */
|
18392
|
-
var accruedInputIndex = 0;
|
18393
|
-
/** @type {number} */
|
18394
|
-
var currentOutputIndex = 0;
|
18395
|
-
/** @type {string} */
|
18396
|
-
var accruedInputWithoutFormatting =
|
18397
|
-
this.accruedInputWithoutFormatting_.toString();
|
18398
|
-
/** @type {string} */
|
18399
|
-
var currentOutput = this.currentOutput_.toString();
|
18400
|
-
while (accruedInputIndex < this.positionToRemember_ &&
|
18401
|
-
currentOutputIndex < currentOutput.length) {
|
18402
|
-
if (accruedInputWithoutFormatting.charAt(accruedInputIndex) ==
|
18403
|
-
currentOutput.charAt(currentOutputIndex)) {
|
18404
|
-
accruedInputIndex++;
|
18405
|
-
}
|
18406
|
-
currentOutputIndex++;
|
18407
|
-
}
|
18408
|
-
return currentOutputIndex;
|
18409
|
-
};
|
18410
|
-
|
18411
|
-
|
18412
|
-
/**
|
18413
|
-
* Attempts to set the formatting template and returns a string which contains
|
18414
|
-
* the formatted version of the digits entered so far.
|
18415
|
-
*
|
18416
|
-
* @return {string}
|
18417
|
-
* @private
|
18418
|
-
*/
|
18419
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.
|
18420
|
-
attemptToChooseFormattingPattern_ = function() {
|
18421
|
-
|
18422
|
-
/** @type {string} */
|
18423
|
-
var nationalNumber = this.nationalNumber_.toString();
|
18424
|
-
// We start to attempt to format only when as least MIN_LEADING_DIGITS_LENGTH
|
18425
|
-
// digits of national number (excluding national prefix) have been entered.
|
18426
|
-
if (nationalNumber.length >=
|
18427
|
-
i18n.phonenumbers.AsYouTypeFormatter.MIN_LEADING_DIGITS_LENGTH_) {
|
18428
|
-
this.getAvailableFormats_(
|
18429
|
-
nationalNumber.substring(0,
|
18430
|
-
i18n.phonenumbers.AsYouTypeFormatter.MIN_LEADING_DIGITS_LENGTH_));
|
18431
|
-
this.maybeCreateNewTemplate_();
|
18432
|
-
return this.inputAccruedNationalNumber_();
|
18433
|
-
} else {
|
18434
|
-
return this.prefixBeforeNationalNumber_.toString() + nationalNumber;
|
18435
|
-
}
|
18436
|
-
};
|
18437
|
-
|
18438
|
-
|
18439
|
-
/**
|
18440
|
-
* Invokes inputDigitHelper on each digit of the national number accrued, and
|
18441
|
-
* returns a formatted string in the end.
|
18442
|
-
*
|
18443
|
-
* @return {string}
|
18444
|
-
* @private
|
18445
|
-
*/
|
18446
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.inputAccruedNationalNumber_ =
|
18447
|
-
function() {
|
18448
|
-
|
18449
|
-
/** @type {string} */
|
18450
|
-
var nationalNumber = this.nationalNumber_.toString();
|
18451
|
-
/** @type {number} */
|
18452
|
-
var lengthOfNationalNumber = nationalNumber.length;
|
18453
|
-
if (lengthOfNationalNumber > 0) {
|
18454
|
-
/** @type {string} */
|
18455
|
-
var tempNationalNumber = '';
|
18456
|
-
for (var i = 0; i < lengthOfNationalNumber; i++) {
|
18457
|
-
tempNationalNumber =
|
18458
|
-
this.inputDigitHelper_(nationalNumber.charAt(i));
|
18459
|
-
}
|
18460
|
-
return this.ableToFormat_ ?
|
18461
|
-
this.prefixBeforeNationalNumber_.toString() + tempNationalNumber :
|
18462
|
-
tempNationalNumber;
|
18463
|
-
} else {
|
18464
|
-
return this.prefixBeforeNationalNumber_.toString();
|
18465
|
-
}
|
18466
|
-
};
|
18467
|
-
|
18468
|
-
|
18469
|
-
/**
|
18470
|
-
* Returns the national prefix extracted, or an empty string if it is not
|
18471
|
-
* present.
|
18472
|
-
* @return {string}
|
18473
|
-
* @private
|
18474
|
-
*/
|
18475
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.
|
18476
|
-
removeNationalPrefixFromNationalNumber_ = function() {
|
18477
|
-
|
18478
|
-
/** @type {string} */
|
18479
|
-
var nationalNumber = this.nationalNumber_.toString();
|
18480
|
-
/** @type {number} */
|
18481
|
-
var startOfNationalNumber = 0;
|
18482
|
-
if (this.currentMetaData_.getCountryCode() == 1 &&
|
18483
|
-
nationalNumber.charAt(0) == '1') {
|
18484
|
-
startOfNationalNumber = 1;
|
18485
|
-
this.prefixBeforeNationalNumber_.append('1 ');
|
18486
|
-
this.isInternationalFormatting_ = true;
|
18487
|
-
} else if (this.currentMetaData_.hasNationalPrefixForParsing()) {
|
18488
|
-
/** @type {RegExp} */
|
18489
|
-
var nationalPrefixForParsing = new RegExp(
|
18490
|
-
'^(?:' + this.currentMetaData_.getNationalPrefixForParsing() + ')');
|
18491
|
-
/** @type {Array.<string>} */
|
18492
|
-
var m = nationalNumber.match(nationalPrefixForParsing);
|
18493
|
-
if (m != null && m[0] != null && m[0].length > 0) {
|
18494
|
-
// When the national prefix is detected, we use international formatting
|
18495
|
-
// rules instead of national ones, because national formatting rules could
|
18496
|
-
// contain local formatting rules for numbers entered without area code.
|
18497
|
-
this.isInternationalFormatting_ = true;
|
18498
|
-
startOfNationalNumber = m[0].length;
|
18499
|
-
this.prefixBeforeNationalNumber_.append(nationalNumber.substring(0,
|
18500
|
-
startOfNationalNumber));
|
18501
|
-
}
|
18502
|
-
}
|
18503
|
-
this.nationalNumber_.clear();
|
18504
|
-
this.nationalNumber_.append(nationalNumber.substring(startOfNationalNumber));
|
18505
|
-
return nationalNumber.substring(0, startOfNationalNumber);
|
18506
|
-
};
|
18507
|
-
|
18508
|
-
|
18509
|
-
/**
|
18510
|
-
* Extracts IDD and plus sign to prefixBeforeNationalNumber when they are
|
18511
|
-
* available, and places the remaining input into nationalNumber.
|
18512
|
-
*
|
18513
|
-
* @return {boolean} true when accruedInputWithoutFormatting begins with the
|
18514
|
-
* plus sign or valid IDD for defaultCountry.
|
18515
|
-
* @private
|
18516
|
-
*/
|
18517
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToExtractIdd_ =
|
18518
|
-
function() {
|
18519
|
-
|
18520
|
-
/** @type {string} */
|
18521
|
-
var accruedInputWithoutFormatting =
|
18522
|
-
this.accruedInputWithoutFormatting_.toString();
|
18523
|
-
/** @type {RegExp} */
|
18524
|
-
var internationalPrefix = new RegExp(
|
18525
|
-
'^(?:' + '\\' + i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + '|' +
|
18526
|
-
this.currentMetaData_.getInternationalPrefix() + ')');
|
18527
|
-
/** @type {Array.<string>} */
|
18528
|
-
var m = accruedInputWithoutFormatting.match(internationalPrefix);
|
18529
|
-
if (m != null && m[0] != null && m[0].length > 0) {
|
18530
|
-
this.isInternationalFormatting_ = true;
|
18531
|
-
/** @type {number} */
|
18532
|
-
var startOfCountryCallingCode = m[0].length;
|
18533
|
-
this.nationalNumber_.clear();
|
18534
|
-
this.nationalNumber_.append(
|
18535
|
-
accruedInputWithoutFormatting.substring(startOfCountryCallingCode));
|
18536
|
-
this.prefixBeforeNationalNumber_.clear();
|
18537
|
-
this.prefixBeforeNationalNumber_.append(
|
18538
|
-
accruedInputWithoutFormatting.substring(0, startOfCountryCallingCode));
|
18539
|
-
if (accruedInputWithoutFormatting.charAt(0) !=
|
18540
|
-
i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) {
|
18541
|
-
this.prefixBeforeNationalNumber_.append(' ');
|
18542
|
-
}
|
18543
|
-
return true;
|
18544
|
-
}
|
18545
|
-
return false;
|
18546
|
-
};
|
18547
|
-
|
18548
|
-
|
18549
|
-
/**
|
18550
|
-
* Extracts the country calling code from the beginning of nationalNumber to
|
18551
|
-
* prefixBeforeNationalNumber when they are available, and places the remaining
|
18552
|
-
* input into nationalNumber.
|
18553
|
-
*
|
18554
|
-
* @return {boolean} true when a valid country calling code can be found.
|
18555
|
-
* @private
|
18556
|
-
*/
|
18557
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.
|
18558
|
-
attemptToExtractCountryCallingCode_ = function() {
|
18559
|
-
|
18560
|
-
if (this.nationalNumber_.getLength() == 0) {
|
18561
|
-
return false;
|
18562
|
-
}
|
18563
|
-
/** @type {!goog.string.StringBuffer} */
|
18564
|
-
var numberWithoutCountryCallingCode = new goog.string.StringBuffer();
|
18565
|
-
/** @type {number} */
|
18566
|
-
var countryCode = this.phoneUtil_.extractCountryCode(
|
18567
|
-
this.nationalNumber_, numberWithoutCountryCallingCode);
|
18568
|
-
if (countryCode == 0) {
|
18569
|
-
return false;
|
18570
|
-
}
|
18571
|
-
this.nationalNumber_.clear();
|
18572
|
-
this.nationalNumber_.append(numberWithoutCountryCallingCode.toString());
|
18573
|
-
/** @type {string} */
|
18574
|
-
var newRegionCode = this.phoneUtil_.getRegionCodeForCountryCode(countryCode);
|
18575
|
-
if (newRegionCode != this.defaultCountry_) {
|
18576
|
-
this.currentMetaData_ = this.getMetadataForRegion_(newRegionCode);
|
18577
|
-
}
|
18578
|
-
/** @type {string} */
|
18579
|
-
var countryCodeString = '' + countryCode;
|
18580
|
-
this.prefixBeforeNationalNumber_.append(countryCodeString).append(' ');
|
18581
|
-
return true;
|
18582
|
-
};
|
18583
|
-
|
18584
|
-
|
18585
|
-
/**
|
18586
|
-
* Accrues digits and the plus sign to accruedInputWithoutFormatting for later
|
18587
|
-
* use. If nextChar contains a digit in non-ASCII format (e.g. the full-width
|
18588
|
-
* version of digits), it is first normalized to the ASCII version. The return
|
18589
|
-
* value is nextChar itself, or its normalized version, if nextChar is a digit
|
18590
|
-
* in non-ASCII format. This method assumes its input is either a digit or the
|
18591
|
-
* plus sign.
|
18592
|
-
*
|
18593
|
-
* @param {string} nextChar
|
18594
|
-
* @param {boolean} rememberPosition
|
18595
|
-
* @return {string}
|
18596
|
-
* @private
|
18597
|
-
*/
|
18598
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.
|
18599
|
-
normalizeAndAccrueDigitsAndPlusSign_ = function(nextChar,
|
18600
|
-
rememberPosition) {
|
18601
|
-
|
18602
|
-
/** @type {string} */
|
18603
|
-
var normalizedChar;
|
18604
|
-
if (nextChar == i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) {
|
18605
|
-
normalizedChar = nextChar;
|
18606
|
-
this.accruedInputWithoutFormatting_.append(nextChar);
|
18607
|
-
} else {
|
18608
|
-
normalizedChar = i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS[nextChar];
|
18609
|
-
this.accruedInputWithoutFormatting_.append(normalizedChar);
|
18610
|
-
this.nationalNumber_.append(normalizedChar);
|
18611
|
-
}
|
18612
|
-
if (rememberPosition) {
|
18613
|
-
this.positionToRemember_ = this.accruedInputWithoutFormatting_.getLength();
|
18614
|
-
}
|
18615
|
-
return normalizedChar;
|
18616
|
-
};
|
18617
|
-
|
18618
|
-
|
18619
|
-
/**
|
18620
|
-
* @param {string} nextChar
|
18621
|
-
* @return {string}
|
18622
|
-
* @private
|
18623
|
-
*/
|
18624
|
-
i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigitHelper_ =
|
18625
|
-
function(nextChar) {
|
18626
|
-
|
18627
|
-
/** @type {string} */
|
18628
|
-
var formattingTemplate = this.formattingTemplate_.toString();
|
18629
|
-
if (formattingTemplate.substring(this.lastMatchPosition_)
|
18630
|
-
.search(this.digitPattern_) >= 0) {
|
18631
|
-
/** @type {number} */
|
18632
|
-
var digitPatternStart = formattingTemplate.search(this.digitPattern_);
|
18633
|
-
/** @type {string} */
|
18634
|
-
var tempTemplate = formattingTemplate.replace(this.digitPattern_, nextChar);
|
18635
|
-
this.formattingTemplate_.clear();
|
18636
|
-
this.formattingTemplate_.append(tempTemplate);
|
18637
|
-
this.lastMatchPosition_ = digitPatternStart;
|
18638
|
-
return tempTemplate.substring(0, this.lastMatchPosition_ + 1);
|
18639
|
-
} else {
|
18640
|
-
if (this.possibleFormats_.length == 1) {
|
18641
|
-
// More digits are entered than we could handle, and there are no other
|
18642
|
-
// valid patterns to try.
|
18643
|
-
this.ableToFormat_ = false;
|
18644
|
-
} // else, we just reset the formatting pattern.
|
18645
|
-
this.currentFormattingPattern_ = '';
|
18646
|
-
return this.accruedInput_.toString();
|
18647
|
-
}
|
18648
|
-
};
|
18649
17677
|
|
18650
17678
|
(function() {
|
18651
|
-
var falsy;
|
17679
|
+
var falsy, getE164PhoneNumberWithMeta;
|
18652
17680
|
|
18653
17681
|
falsy = function(fn) {
|
18654
17682
|
try {
|
@@ -18658,15 +17686,15 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigitHelper_ =
|
|
18658
17686
|
}
|
18659
17687
|
};
|
18660
17688
|
|
18661
|
-
this.
|
18662
|
-
var attempt, e164, fixnumber,
|
17689
|
+
this.getE164PhoneNumberWithMeta = getE164PhoneNumberWithMeta = function(str, cc, ndc) {
|
17690
|
+
var attempt, complete, e164, fixnumber, inst, num, regionCode, res, util;
|
18663
17691
|
cc = "" + (cc != null ? cc : "");
|
18664
17692
|
ndc = "" + (ndc != null ? ndc : "");
|
18665
17693
|
util = i18n.phonenumbers.PhoneNumberUtil;
|
18666
17694
|
inst = util.getInstance();
|
18667
17695
|
e164 = i18n.phonenumbers.PhoneNumberFormat.E164;
|
18668
17696
|
num = util.extractPossibleNumber(str);
|
18669
|
-
if (cc && /^[\d]+$/.test(cc)) {
|
17697
|
+
if (cc && /^[\d]+$/.test("" + (cc != null ? cc : ""))) {
|
18670
17698
|
regionCode = inst.getRegionCodeForCountryCode(+cc);
|
18671
17699
|
} else if (inst.getMetadataForRegion(cc)) {
|
18672
17700
|
regionCode = cc;
|
@@ -18675,25 +17703,38 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigitHelper_ =
|
|
18675
17703
|
if (phone_obj) {
|
18676
17704
|
if (inst.isValidNumber(phone_obj)) return phone_obj;
|
18677
17705
|
if (ndc && inst.getLengthOfNationalDestinationCode(phone_obj) !== ndc.length) {
|
18678
|
-
phone_obj.setNationalNumber(+("" + ndc + (
|
17706
|
+
phone_obj.setNationalNumber(+("" + ndc + (inst.getNationalSignificantNumber(phone_obj))));
|
18679
17707
|
if (inst.isValidNumber(phone_obj)) return phone_obj;
|
18680
17708
|
}
|
18681
17709
|
}
|
18682
17710
|
};
|
18683
|
-
|
18684
|
-
|
17711
|
+
complete = function(phone_obj) {
|
17712
|
+
var formatted, _ref, _ref2;
|
17713
|
+
if (phone_obj) {
|
17714
|
+
formatted = inst.format(phone_obj, e164);
|
17715
|
+
cc = "" + ((_ref = phone_obj.getCountryCode()) != null ? _ref : "");
|
17716
|
+
ndc = ("" + ((_ref2 = inst.getNationalSignificantNumber(phone_obj)) != null ? _ref2 : "")).substring(0, inst.getLengthOfNationalDestinationCode(phone_obj));
|
17717
|
+
return [formatted, cc, ndc];
|
17718
|
+
} else {
|
17719
|
+
return [];
|
17720
|
+
}
|
18685
17721
|
};
|
18686
17722
|
attempt = function(fn) {
|
18687
|
-
return
|
17723
|
+
return complete(fixnumber(falsy(fn)));
|
18688
17724
|
};
|
18689
|
-
|
17725
|
+
res = attempt(function() {
|
18690
17726
|
return inst.parse(num);
|
18691
17727
|
});
|
18692
|
-
if (
|
18693
|
-
|
17728
|
+
if (res[0]) return res;
|
17729
|
+
res = attempt(function() {
|
18694
17730
|
return inst.parse(num, regionCode);
|
18695
17731
|
});
|
18696
|
-
if (
|
17732
|
+
if (res[0]) return res;
|
17733
|
+
return [];
|
17734
|
+
};
|
17735
|
+
|
17736
|
+
this.getE164PhoneNumber = function(str, cc, ndc) {
|
17737
|
+
return getE164PhoneNumberWithMeta(str, cc, ndc)[0];
|
18697
17738
|
};
|
18698
17739
|
|
18699
17740
|
}).call(this);
|
data/support/simple.coffee
CHANGED
@@ -5,14 +5,14 @@ falsy = (fn) ->
|
|
5
5
|
return false
|
6
6
|
return
|
7
7
|
|
8
|
-
this.
|
8
|
+
this.getE164PhoneNumberWithMeta = getE164PhoneNumberWithMeta = (str, cc, ndc) ->
|
9
9
|
cc = "#{cc ? ""}"
|
10
10
|
ndc = "#{ndc ? ""}"
|
11
11
|
util = i18n.phonenumbers.PhoneNumberUtil
|
12
12
|
inst = util.getInstance()
|
13
13
|
e164 = i18n.phonenumbers.PhoneNumberFormat.E164
|
14
14
|
num = util.extractPossibleNumber(str)
|
15
|
-
if cc && /^[\d]+$/.test(cc)
|
15
|
+
if cc && /^[\d]+$/.test("#{cc ? ""}")
|
16
16
|
regionCode = inst.getRegionCodeForCountryCode(+cc)
|
17
17
|
else if inst.getMetadataForRegion(cc)
|
18
18
|
regionCode = cc
|
@@ -21,17 +21,24 @@ this.getE164PhoneNumber = (str, cc, ndc) ->
|
|
21
21
|
if phone_obj
|
22
22
|
return phone_obj if inst.isValidNumber(phone_obj)
|
23
23
|
if ndc && inst.getLengthOfNationalDestinationCode(phone_obj) != ndc.length
|
24
|
-
phone_obj.setNationalNumber(+("#{ndc}#{
|
24
|
+
phone_obj.setNationalNumber(+("#{ndc}#{inst.getNationalSignificantNumber(phone_obj)}"))
|
25
25
|
return phone_obj if inst.isValidNumber(phone_obj)
|
26
26
|
return
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
complete = (phone_obj) ->
|
29
|
+
if phone_obj
|
30
|
+
formatted = inst.format(phone_obj, e164)
|
31
|
+
cc = "#{phone_obj.getCountryCode() ? ""}"
|
32
|
+
ndc = "#{inst.getNationalSignificantNumber(phone_obj) ? ""}".substring(0,inst.getLengthOfNationalDestinationCode(phone_obj))
|
33
|
+
return [ formatted, cc, ndc ]
|
34
|
+
else
|
35
|
+
return []
|
31
36
|
|
32
|
-
attempt = (fn) ->
|
33
|
-
|
34
|
-
return
|
35
|
-
|
36
|
-
return
|
37
|
-
|
37
|
+
attempt = (fn) -> complete(fixnumber(falsy(fn)))
|
38
|
+
res = attempt () -> inst.parse(num)
|
39
|
+
return res if res[0]
|
40
|
+
res = attempt () -> inst.parse(num, regionCode)
|
41
|
+
return res if res[0]
|
42
|
+
[]
|
43
|
+
|
44
|
+
this.getE164PhoneNumber = (str, cc, ndc) -> getE164PhoneNumberWithMeta(str, cc, ndc)[0]
|
data/test/libphonenumber_test.rb
CHANGED
@@ -13,7 +13,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
13
13
|
},
|
14
14
|
:expected => {
|
15
15
|
:normalized => "9255550100",
|
16
|
-
:e164 => "+19255550100"
|
16
|
+
:e164 => "+19255550100",
|
17
|
+
:cc => "1",
|
18
|
+
:ndc => "925"
|
17
19
|
}
|
18
20
|
},
|
19
21
|
{
|
@@ -23,7 +25,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
23
25
|
},
|
24
26
|
:expected => {
|
25
27
|
:normalized => "19255550100",
|
26
|
-
:e164 => "+19255550100"
|
28
|
+
:e164 => "+19255550100",
|
29
|
+
:cc => "1",
|
30
|
+
:ndc => "925"
|
27
31
|
}
|
28
32
|
},
|
29
33
|
{
|
@@ -34,7 +38,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
34
38
|
},
|
35
39
|
:expected => {
|
36
40
|
:normalized => "5550100",
|
37
|
-
:e164 => "+19255550100"
|
41
|
+
:e164 => "+19255550100",
|
42
|
+
:cc => "1",
|
43
|
+
:ndc => "925"
|
38
44
|
}
|
39
45
|
},
|
40
46
|
{
|
@@ -44,7 +50,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
44
50
|
},
|
45
51
|
:expected => {
|
46
52
|
:normalized => "5550100",
|
47
|
-
:e164 => nil
|
53
|
+
:e164 => nil,
|
54
|
+
:cc => nil,
|
55
|
+
:ndc => nil
|
48
56
|
}
|
49
57
|
},
|
50
58
|
{
|
@@ -54,7 +62,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
54
62
|
},
|
55
63
|
:expected => {
|
56
64
|
:normalized => "5550100",
|
57
|
-
:e164 => nil
|
65
|
+
:e164 => nil,
|
66
|
+
:cc => nil,
|
67
|
+
:ndc => nil
|
58
68
|
}
|
59
69
|
},
|
60
70
|
{
|
@@ -65,7 +75,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
65
75
|
},
|
66
76
|
:expected => {
|
67
77
|
:normalized => "9255550100",
|
68
|
-
:e164 => "+19255550100"
|
78
|
+
:e164 => "+19255550100",
|
79
|
+
:cc => "1",
|
80
|
+
:ndc => "925"
|
69
81
|
}
|
70
82
|
},
|
71
83
|
{
|
@@ -75,7 +87,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
75
87
|
},
|
76
88
|
:expected => {
|
77
89
|
:normalized => "19255550100",
|
78
|
-
:e164 => "+19255550100"
|
90
|
+
:e164 => "+19255550100",
|
91
|
+
:cc => "1",
|
92
|
+
:ndc => "925"
|
79
93
|
}
|
80
94
|
},
|
81
95
|
{
|
@@ -85,7 +99,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
85
99
|
},
|
86
100
|
:expected => {
|
87
101
|
:normalized => "19255550100",
|
88
|
-
:e164 => "+19255550100"
|
102
|
+
:e164 => "+19255550100",
|
103
|
+
:cc => "1",
|
104
|
+
:ndc => "925"
|
89
105
|
}
|
90
106
|
},
|
91
107
|
{
|
@@ -95,7 +111,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
95
111
|
},
|
96
112
|
:expected => {
|
97
113
|
:normalized => "9255550100",
|
98
|
-
:e164 => "+19255550100"
|
114
|
+
:e164 => "+19255550100",
|
115
|
+
:cc => "1",
|
116
|
+
:ndc => "925"
|
99
117
|
}
|
100
118
|
},
|
101
119
|
{
|
@@ -106,7 +124,9 @@ class LibphonenumberTest < MiniTest::Spec
|
|
106
124
|
},
|
107
125
|
:expected => {
|
108
126
|
:normalized => "5550100",
|
109
|
-
:e164 => "+19255550100"
|
127
|
+
:e164 => "+19255550100",
|
128
|
+
:cc => "1",
|
129
|
+
:ndc => "925"
|
110
130
|
}
|
111
131
|
}
|
112
132
|
]
|
@@ -135,9 +155,11 @@ class LibphonenumberTest < MiniTest::Spec
|
|
135
155
|
it "does not expose COMPILED" do
|
136
156
|
@lib.context.exec("return ('COMPILED' in this);").must_equal false
|
137
157
|
end
|
138
|
-
|
158
|
+
|
159
|
+
i = 0
|
160
|
+
|
139
161
|
SCENARIOS.each do |scenario|
|
140
|
-
d = "
|
162
|
+
d = "spec#{i+=1} #{scenario.inspect}"
|
141
163
|
describe d do
|
142
164
|
it "will normalize the number correctly" do
|
143
165
|
@lib.normalize(scenario[:given][:number]).must_equal(scenario[:expected][:normalized], d)
|
@@ -145,6 +167,12 @@ class LibphonenumberTest < MiniTest::Spec
|
|
145
167
|
it "will parse the e164 formatted version correctly" do
|
146
168
|
@lib.simple.get_e164_phone_number(scenario[:given][:number], scenario[:given][:cc], scenario[:given][:ndc]).must_equal(scenario[:expected][:e164], d)
|
147
169
|
end
|
170
|
+
it "will return the expected cc" do
|
171
|
+
@lib.simple.get_e164_phone_number_with_meta(scenario[:given][:number], scenario[:given][:cc], scenario[:given][:ndc])[1].must_equal(scenario[:expected][:cc], d)
|
172
|
+
end
|
173
|
+
it "will return the expected ndc" do
|
174
|
+
@lib.simple.get_e164_phone_number_with_meta(scenario[:given][:number], scenario[:given][:cc], scenario[:given][:ndc])[2].must_equal(scenario[:expected][:ndc], d)
|
175
|
+
end
|
148
176
|
end
|
149
177
|
end
|
150
178
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libphonenumber-execjs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-11-14 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: execjs
|
16
|
-
requirement: &
|
16
|
+
requirement: &70276826092700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70276826092700
|
25
25
|
description: ExecJS wrapper for Google's libphonenumber library
|
26
26
|
email:
|
27
27
|
- joenoon@gmail.com
|
@@ -55,7 +55,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
55
55
|
version: '0'
|
56
56
|
segments:
|
57
57
|
- 0
|
58
|
-
hash:
|
58
|
+
hash: -263098892156764030
|
59
59
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
60
|
none: false
|
61
61
|
requirements:
|
@@ -64,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
64
|
version: '0'
|
65
65
|
segments:
|
66
66
|
- 0
|
67
|
-
hash:
|
67
|
+
hash: -263098892156764030
|
68
68
|
requirements: []
|
69
69
|
rubyforge_project: libphonenumber-execjs
|
70
70
|
rubygems_version: 1.8.10
|