Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 this.EXPORTED_SYMBOLS = ["TelURIParser"];
9 /**
10 * Singleton providing functionality for parsing tel: and sms: URIs
11 */
12 this.TelURIParser = {
13 parseURI: function(scheme, uri) {
14 // https://www.ietf.org/rfc/rfc2806.txt
15 let subscriber = decodeURIComponent(uri.slice((scheme + ':').length));
17 if (!subscriber.length) {
18 return null;
19 }
21 let number = '';
22 let pos = 0;
23 let len = subscriber.length;
25 // visual-separator
26 let visualSeparator = [ ' ', '-', '.', '(', ')' ];
27 let digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
28 let dtmfDigits = [ '*', '#', 'A', 'B', 'C', 'D' ];
29 let pauseCharacter = [ 'p', 'w' ];
31 // global-phone-number
32 if (subscriber[pos] == '+') {
33 number += '+';
34 for (++pos; pos < len; ++pos) {
35 if (visualSeparator.indexOf(subscriber[pos]) != -1) {
36 number += subscriber[pos];
37 } else if (digits.indexOf(subscriber[pos]) != -1) {
38 number += subscriber[pos];
39 } else {
40 break;
41 }
42 }
43 }
44 // local-phone-number
45 else {
46 for (; pos < len; ++pos) {
47 if (visualSeparator.indexOf(subscriber[pos]) != -1) {
48 number += subscriber[pos];
49 } else if (digits.indexOf(subscriber[pos]) != -1) {
50 number += subscriber[pos];
51 } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) {
52 number += subscriber[pos];
53 } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) {
54 number += subscriber[pos];
55 } else {
56 break;
57 }
58 }
60 // this means error
61 if (!number.length) {
62 return null;
63 }
65 // isdn-subaddress
66 if (subscriber.substring(pos, pos + 6) == ';isub=') {
67 let subaddress = '';
69 for (pos += 6; pos < len; ++pos) {
70 if (visualSeparator.indexOf(subscriber[pos]) != -1) {
71 subaddress += subscriber[pos];
72 } else if (digits.indexOf(subscriber[pos]) != -1) {
73 subaddress += subscriber[pos];
74 } else {
75 break;
76 }
77 }
79 // FIXME: ignore subaddress - Bug 795242
80 }
82 // post-dial
83 if (subscriber.substring(pos, pos + 7) == ';postd=') {
84 let subaddress = '';
86 for (pos += 7; pos < len; ++pos) {
87 if (visualSeparator.indexOf(subscriber[pos]) != -1) {
88 subaddress += subscriber[pos];
89 } else if (digits.indexOf(subscriber[pos]) != -1) {
90 subaddress += subscriber[pos];
91 } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) {
92 subaddress += subscriber[pos];
93 } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) {
94 subaddress += subscriber[pos];
95 } else {
96 break;
97 }
98 }
100 // FIXME: ignore subaddress - Bug 795242
101 }
103 // area-specific
104 if (subscriber.substring(pos, pos + 15) == ';phone-context=') {
105 pos += 15;
107 // global-network-prefix | local-network-prefix | private-prefi
108 number = subscriber.substring(pos, subscriber.length) + number;
109 }
110 }
112 // Ignore MWI and USSD codes. See 794034.
113 if (number.match(/[#\*]/) && !number.match(/^[#\*]\d+$/)) {
114 return null;
115 }
117 return number || null;
118 }
119 };