diff options
| author | Chirayu Krishnappa | 2013-07-15 12:26:46 -0700 | 
|---|---|---|
| committer | Chirayu Krishnappa | 2013-07-19 01:44:57 -0700 | 
| commit | b99d064b6ddbcc9f59ea45004279833e9ea82928 (patch) | |
| tree | 94406ce1926027de90a43b4abf4a7c7c8b0651c6 /src/ng/urlUtils.js | |
| parent | 715d97d5c87c9250f8ac8b5801b8c7f3b197e815 (diff) | |
| download | angular.js-b99d064b6ddbcc9f59ea45004279833e9ea82928.tar.bz2 | |
fix(core): parse URLs using the browser's DOM API
Diffstat (limited to 'src/ng/urlUtils.js')
| -rw-r--r-- | src/ng/urlUtils.js | 111 | 
1 files changed, 111 insertions, 0 deletions
| diff --git a/src/ng/urlUtils.js b/src/ng/urlUtils.js new file mode 100644 index 00000000..e19f9860 --- /dev/null +++ b/src/ng/urlUtils.js @@ -0,0 +1,111 @@ +'use strict'; + +function $$UrlUtilsProvider() { +  this.$get = ['$window', '$document', function($window, $document) { +    var urlParsingNode = $document[0].createElement("a"), +        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} requestUrl The url of the request. +       * @returns {boolean} Whether the request is for the same origin as the application document. +       */ +      isSameOrigin: function isSameOrigin(requestUrl) { +        var parsed = resolve(requestUrl, true); +        return (parsed.protocol === originUrl.protocol && +                parsed.host === originUrl.host); +      } +    }; +  }]; +} | 
