libphonenumber-execjs 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|