michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: this.EXPORTED_SYMBOLS = ["TelURIParser"]; michael@0: michael@0: /** michael@0: * Singleton providing functionality for parsing tel: and sms: URIs michael@0: */ michael@0: this.TelURIParser = { michael@0: parseURI: function(scheme, uri) { michael@0: // https://www.ietf.org/rfc/rfc2806.txt michael@0: let subscriber = decodeURIComponent(uri.slice((scheme + ':').length)); michael@0: michael@0: if (!subscriber.length) { michael@0: return null; michael@0: } michael@0: michael@0: let number = ''; michael@0: let pos = 0; michael@0: let len = subscriber.length; michael@0: michael@0: // visual-separator michael@0: let visualSeparator = [ ' ', '-', '.', '(', ')' ]; michael@0: let digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; michael@0: let dtmfDigits = [ '*', '#', 'A', 'B', 'C', 'D' ]; michael@0: let pauseCharacter = [ 'p', 'w' ]; michael@0: michael@0: // global-phone-number michael@0: if (subscriber[pos] == '+') { michael@0: number += '+'; michael@0: for (++pos; pos < len; ++pos) { michael@0: if (visualSeparator.indexOf(subscriber[pos]) != -1) { michael@0: number += subscriber[pos]; michael@0: } else if (digits.indexOf(subscriber[pos]) != -1) { michael@0: number += subscriber[pos]; michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: // local-phone-number michael@0: else { michael@0: for (; pos < len; ++pos) { michael@0: if (visualSeparator.indexOf(subscriber[pos]) != -1) { michael@0: number += subscriber[pos]; michael@0: } else if (digits.indexOf(subscriber[pos]) != -1) { michael@0: number += subscriber[pos]; michael@0: } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) { michael@0: number += subscriber[pos]; michael@0: } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) { michael@0: number += subscriber[pos]; michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: // this means error michael@0: if (!number.length) { michael@0: return null; michael@0: } michael@0: michael@0: // isdn-subaddress michael@0: if (subscriber.substring(pos, pos + 6) == ';isub=') { michael@0: let subaddress = ''; michael@0: michael@0: for (pos += 6; pos < len; ++pos) { michael@0: if (visualSeparator.indexOf(subscriber[pos]) != -1) { michael@0: subaddress += subscriber[pos]; michael@0: } else if (digits.indexOf(subscriber[pos]) != -1) { michael@0: subaddress += subscriber[pos]; michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: // FIXME: ignore subaddress - Bug 795242 michael@0: } michael@0: michael@0: // post-dial michael@0: if (subscriber.substring(pos, pos + 7) == ';postd=') { michael@0: let subaddress = ''; michael@0: michael@0: for (pos += 7; pos < len; ++pos) { michael@0: if (visualSeparator.indexOf(subscriber[pos]) != -1) { michael@0: subaddress += subscriber[pos]; michael@0: } else if (digits.indexOf(subscriber[pos]) != -1) { michael@0: subaddress += subscriber[pos]; michael@0: } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) { michael@0: subaddress += subscriber[pos]; michael@0: } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) { michael@0: subaddress += subscriber[pos]; michael@0: } else { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: // FIXME: ignore subaddress - Bug 795242 michael@0: } michael@0: michael@0: // area-specific michael@0: if (subscriber.substring(pos, pos + 15) == ';phone-context=') { michael@0: pos += 15; michael@0: michael@0: // global-network-prefix | local-network-prefix | private-prefi michael@0: number = subscriber.substring(pos, subscriber.length) + number; michael@0: } michael@0: } michael@0: michael@0: // Ignore MWI and USSD codes. See 794034. michael@0: if (number.match(/[#\*]/) && !number.match(/^[#\*]\d+$/)) { michael@0: return null; michael@0: } michael@0: michael@0: return number || null; michael@0: } michael@0: }; michael@0: