'use strict'; function $$UrlUtilsProvider() { this.$get = [function() { var urlParsingNode = document.createElement("a"), // NOTE: The usage of window and document instead of $window and $document here is // deliberate. This service depends on the specific behavior of anchor nodes created by the // browser (resolving and parsing URLs) that is unlikely to be provided by mock objects and // cause us to break tests. In addition, when the browser resolves a URL for XHR, it // doesn't know about mocked locations and resolves URLs to the real document - which is // exactly the behavior needed here. There is little value is mocking these our for this // service. originUrl = resolve(window.location.href, true); /** * @description * Normalizes and optionally parses a URL. * * NOTE: This is a private service. The API is subject to change unpredictably in any commit. * * Implementation Notes for non-IE browsers * ---------------------------------------- * Assigning a URL to the href property of an anchor DOM node, even one attached to the DOM, * results both in the normalizing and parsing of the URL. Normalizing means that a relative * URL will be resolved into an absolute URL in the context of the application document. * Parsing means that the anchor node's host, hostname, protocol, port, pathname and related * properties are all populated to reflect the normalized URL. This approach has wide * compatibility - Safari 1+, Mozilla 1+, Opera 7+,e etc. See * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html * * Implementation Notes for IE * --------------------------- * IE >= 8 and <= 10 normalizes the URL when assigned to the anchor node similar to the other * browsers. However, the parsed components will not be set if the URL assigned did not specify * them. (e.g. if you assign a.href = "foo", then a.protocol, a.host, etc. will be empty.) We * work around that by performing the parsing in a 2nd step by taking a previously normalized * URL (e.g. by assining to a.href) and assigning it a.href again. This correctly populates the * properties such as protocol, hostname, port, etc. * * IE7 does not normalize the URL when assigned to an anchor node. (Apparently, it does, if one * uses the inner HTML approach to assign the URL as part of an HTML snippet - * http://stackoverflow.com/a/472729) However, setting img[src] does normalize the URL. * Unfortunately, setting img[src] to something like "javascript:foo" on IE throws an exception. * Since the primary usage for normalizing URLs is to sanitize such URLs, we can't use that * method and IE < 8 is unsupported. * * References: * http://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement * http://www.aptana.com/reference/html/api/HTMLAnchorElement.html * http://url.spec.whatwg.org/#urlutils * https://github.com/angular/angular.js/pull/2902 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ * * @param {string} url The URL to be parsed. * @param {boolean=} parse When true, returns an object for the parsed URL. Otherwise, returns * a single string that is the normalized URL. * @returns {object|string} When parse is true, returns the normalized URL as a string. * Otherwise, returns an object with the following members. * * | member name | Description | * |===============|================| * | href | A normalized version of the provided URL if it was not an absolute URL | * | protocol | The protocol including the trailing colon | * | host | The host and port (if the port is non-default) of the normalizedUrl | * * These fields from the UrlUtils interface are currently not needed and hence not returned. * * | member name | Description | * |===============|================| * | hostname | The host without the port of the normalizedUrl | * | pathname | The path following the host in the normalizedUrl | * | hash | The URL hash if present | * | search | The query string | * */ function resolve(url, parse) { var href = url; if (msie) { // Normalize before parse. Refer Implementation Notes on why this is // done in two steps on IE. urlParsingNode.setAttribute("href", href); href = urlParsingNode.href; } urlParsingNode.setAttribute('href', href); if (!parse) { return urlParsingNode.href; } // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils return { href: urlParsingNode.href, protocol: urlParsingNode.protocol, host: urlParsingNode.host // Currently unused and hence commented out. // hostname: urlParsingNode.hostname, // port: urlParsingNode.port, // pathname: urlParsingNode.pathname, // hash: urlParsingNode.hash, // search: urlParsingNode.search }; } return { resolve: resolve, /** * Parse a request URL and determine whether this is a same-origin request as the application document. * * @param {string|object} requestUrl The url of the request as a string that will be resolved * or a parsed URL object. * @returns {boolean} Whether the request is for the same origin as the application document. */ isSameOrigin: function isSameOrigin(requestUrl) { var parsed = (typeof requestUrl === 'string') ? resolve(requestUrl, true) : requestUrl; return (parsed.protocol === originUrl.protocol && parsed.host === originUrl.host); } }; }]; }