Last active
August 29, 2015 14:07
-
-
Save gabrielmiller/c750d3c231c8673683d0 to your computer and use it in GitHub Desktop.
AngularJS URL Parser Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @ngdoc service | |
* @name utilityService | |
* @description Contains utility methods for formatting | |
* @requires $interpolate | |
*/ | |
angular.module('resApp').factory('utilityService', function($interpolate) { | |
/** | |
* @ngdoc method | |
* @name utilityService#parseUrl | |
* @description Parses a URL | |
* @param {String} URL to be prepared | |
* @param {String} Regex to use for matches | |
* {'strict','lite','loose','performant'} | |
* @return {Object} Parsed URL's components | |
* | |
* This code is adapted from parseUri 1.2.2 by Steven Levithan | |
* http://blog.stevenlevithan.com/archives/parseuri | |
* | |
* Performant regex taken from http://jsperf.com/url-parsing | |
* | |
* WARNING: Objects returned may differ based on the requested regex | |
* | |
*/ | |
function parseUrl(urlToParse, regex) { | |
urlParser = { | |
options: { | |
keys: { | |
defaults: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"], | |
lite: ["href", "origin", "protocol", "username", "password", "host", "hostname", "port", "pathname", "search", "host"], | |
performant: ["href", "withoutHash", "url", "origin", "protocol", "protocolseparator", "credentialedhost", "credentials", "username", "password", "host", "hostname", "port", "pathname", "segment1", "segment2", "search", "hash"], | |
}, | |
parser: { | |
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, | |
lite: /^(?:(?:(([^:\/#\?]+:)?(?:(?:\/\/)(?:(?:(?:([^:@\/#\?]+)(?:\:([^:@\/#\?]*))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((?:\/?(?:[^\/\?#]+\/+)*)(?:[^\?#]*)))?(\?[^#]+)?)(#.*)?/, | |
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/, | |
performant: /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/ | |
} | |
} | |
}; | |
if (!(regex in urlParser.options.keys)) { | |
regex = "loose"; | |
} | |
var regexKeys; | |
if (regex === "loose" || regex === "strict") { | |
regexKeys = "defaults"; | |
} else { | |
regexKeys = regex; | |
} | |
var options = urlParser.options, | |
mode = options.parser[regex].exec(urlToParse), | |
url = {}, | |
length = urlParser.options.keys[regexKeys].length - 1; | |
while (length--) { | |
url[options.keys[regex][length]] = mode[length] || ""; | |
} | |
return url; | |
} | |
/** | |
* @ngdoc method | |
* @name utilityService#prepareUrl | |
* @description Parses a URL and returns it prepared for use externally | |
* or internally. Returns "#" if URL is empty or otherwise | |
* invalid. | |
* @param {Boolean} Domain is external | |
* @param {String} URL to be prepared | |
* @return {String} Prepared URL | |
*/ | |
function prepareUrl(isExternal, url) { | |
console.log(url); | |
var failSafe = "#"; | |
if (url === "") { | |
return failSafe; | |
} | |
var defaultProtocol = "http:", | |
interpolation = $interpolate('{{protocol}}//{{host}}/{{path}}{{search}}{{hash}}'), | |
parsedUrl = parseUrl(url, "loose"), | |
validProtocols = { | |
"http:": true, | |
"https:": true, | |
"ftp:": true | |
}; | |
console.log(parsedUrl); | |
// Enforce that a protocol is set on external URLs | |
if (isExternal) { | |
if (!(parsedUrl.protocol in validProtocols)) { | |
parsedUrl.protocol = defaultProtocol; | |
} | |
if (parsedUrl.host === "") { | |
return failSafe; | |
} | |
} | |
return interpolation(parsedUrl); | |
} | |
return { | |
parseUrl: parseUrl, | |
prepareUrl: prepareUrl, | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment