[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/externals/javelin/lib/ -> URI.js (source)

   1  /**
   2   * @provides javelin-uri
   3   * @requires javelin-install
   4   *           javelin-util
   5   *           javelin-stratcom
   6   *
   7   * @javelin-installs JX.$U
   8   *
   9   * @javelin
  10   */
  11  
  12  /**
  13   * Handy convenience function that returns a @{class:JX.URI} instance. This
  14   * allows you to write things like:
  15   *
  16   *   JX.$U('http://zombo.com/').getDomain();
  17   *
  18   * @param string            Unparsed URI.
  19   * @return  @{class:JX.URI} JX.URI instance.
  20   */
  21  JX.$U = function(uri) {
  22    return new JX.URI(uri);
  23  };
  24  
  25  /**
  26   * Convert a string URI into a maleable object.
  27   *
  28   *   var uri = new JX.URI('http://www.example.com/asdf.php?a=b&c=d#anchor123');
  29   *   uri.getProtocol();    // http
  30   *   uri.getDomain();      // www.example.com
  31   *   uri.getPath();        // /asdf.php
  32   *   uri.getQueryParams(); // {a: 'b', c: 'd'}
  33   *   uri.getFragment();    // anchor123
  34   *
  35   * ...and back into a string:
  36   *
  37   *   uri.setFragment('clowntown');
  38   *   uri.toString() // http://www.example.com/asdf.php?a=b&c=d#clowntown
  39   */
  40  JX.install('URI', {
  41    statics : {
  42      _uriPattern : /(?:([^:\/?#]+):)?(?:\/\/([^:\/?#]*)(?::(\d*))?)?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/,
  43  
  44      /**
  45       *  Convert a Javascript object into an HTTP query string.
  46       *
  47       *  @param  Object  Map of query keys to values.
  48       *  @return String  HTTP query string, like 'cow=quack&duck=moo'.
  49       */
  50      _defaultQuerySerializer : function(obj) {
  51        var kv_pairs = [];
  52        for (var key in obj) {
  53          if (obj[key] !== null) {
  54            var value = encodeURIComponent(obj[key]);
  55            kv_pairs.push(encodeURIComponent(key) + (value ? '=' + value : ''));
  56          }
  57        }
  58  
  59        return kv_pairs.join('&');
  60      },
  61  
  62      _decode : function(str) {
  63        return decodeURIComponent(str.replace(/\+/g, ' '));
  64      }
  65    },
  66  
  67    /**
  68     * Construct a URI
  69     *
  70     * Accepts either absolute or relative URIs. Relative URIs may have protocol
  71     * and domain properties set to undefined
  72     *
  73     * @param string    absolute or relative URI
  74     */
  75    construct : function(uri) {
  76      // need to set the default value here rather than in the properties map,
  77      // or else we get some crazy global state breakage
  78      this.setQueryParams({});
  79  
  80      if (uri) {
  81        // parse the url
  82        var result = JX.URI._uriPattern.exec(uri);
  83  
  84        // fallback to undefined because IE has weird behavior otherwise
  85        this.setProtocol(result[1] || undefined);
  86        this.setDomain(result[2] || undefined);
  87        this.setPort(result[3] || undefined);
  88        var path = result[4];
  89        var query = result[5];
  90        this.setFragment(result[6] || undefined);
  91  
  92        // parse the path
  93        this.setPath(path.charAt(0) == '/' ? path : '/' + path);
  94  
  95        // parse the query data
  96        if (query && query.length) {
  97          var dict = {};
  98          var parts = query.split('&');
  99          for (var ii = 0; ii < parts.length; ii++) {
 100            var part = parts[ii];
 101            if (!part.length) {
 102              continue;
 103            }
 104            var pieces = part.split('=');
 105            var name = pieces[0];
 106            if (!name.length) {
 107              continue;
 108            }
 109            var value = pieces.slice(1).join('=') || '';
 110            dict[JX.URI._decode(name)] = JX.URI._decode(value);
 111          }
 112          this.setQueryParams(dict);
 113        }
 114      }
 115    },
 116  
 117    properties : {
 118      protocol: undefined,
 119      port: undefined,
 120      path: undefined,
 121      queryParams: undefined,
 122      fragment: undefined,
 123      querySerializer: undefined
 124    },
 125  
 126    members : {
 127      _domain: undefined,
 128  
 129      /**
 130       * Append and override query data values
 131       * Remove a query key by setting it undefined
 132       *
 133       * @param map
 134       * @return @{JX.URI} self
 135       */
 136      addQueryParams : function(map) {
 137        JX.copy(this.getQueryParams(), map);
 138        return this;
 139      },
 140  
 141      /**
 142       * Set a specific query parameter
 143       * Remove a query key by setting it undefined
 144       *
 145       * @param string
 146       * @param wild
 147       * @return @{JX.URI} self
 148       */
 149      setQueryParam : function(key, value) {
 150        var map = {};
 151        map[key] = value;
 152        return this.addQueryParams(map);
 153      },
 154  
 155      /**
 156       * Set the domain
 157       *
 158       * This function checks the domain name to ensure that it is safe for
 159       * browser consumption.
 160       */
 161      setDomain : function(domain) {
 162        var re = new RegExp(
 163          // For the bottom 128 code points, we use a strict whitelist of
 164          // characters that are allowed by all browsers: -.0-9:A-Z[]_a-z
 165          '[\\x00-\\x2c\\x2f\\x3b-\\x40\\x5c\\x5e\\x60\\x7b-\\x7f' +
 166          // In IE, these chararacters cause problems when entity-encoded.
 167          '\\uFDD0-\\uFDEF\\uFFF0-\\uFFFF' +
 168          // In Safari, these characters terminate the hostname.
 169          '\\u2047\\u2048\\uFE56\\uFE5F\\uFF03\\uFF0F\\uFF1F]');
 170        if (re.test(domain)) {
 171          JX.$E('JX.URI.setDomain(...): invalid domain specified.');
 172        }
 173        this._domain = domain;
 174        return this;
 175      },
 176  
 177      getDomain : function() {
 178        return this._domain;
 179      },
 180  
 181      toString : function() {
 182        if (__DEV__) {
 183          if (this.getPath() && this.getPath().charAt(0) != '/') {
 184            JX.$E(
 185              'JX.URI.toString(): ' +
 186              'Path does not begin with a "/" which means this URI will likely' +
 187              'be malformed. Ensure any string passed to .setPath() leads "/"');
 188          }
 189        }
 190        var str = '';
 191        if (this.getProtocol()) {
 192          str += this.getProtocol() + '://';
 193        }
 194        str += this.getDomain() || '';
 195  
 196        if (this.getPort()) {
 197          str += ':' + this.getPort();
 198        }
 199  
 200        // If there is a domain or a protocol, we need to provide '/' for the
 201        // path. If we don't have either and also don't have a path, we can omit
 202        // it to produce a partial URI without path information which begins
 203        // with "?", "#", or is empty.
 204        str += this.getPath() || (str ? '/' : '');
 205  
 206        str += this._getQueryString();
 207        if (this.getFragment()) {
 208          str += '#' + this.getFragment();
 209        }
 210        return str;
 211      },
 212  
 213      _getQueryString : function() {
 214        var str = (
 215          this.getQuerySerializer() || JX.URI._defaultQuerySerializer
 216        )(this.getQueryParams());
 217        return str ? '?' + str : '';
 218      },
 219  
 220      /**
 221       * Redirect the browser to another page by changing the window location. If
 222       * the URI is empty, reloads the current page.
 223       *
 224       * You can install a Stratcom listener for the 'go' event if you need to log
 225       * or prevent redirects.
 226       *
 227       * @return void
 228       */
 229      go : function() {
 230        var uri = this.toString();
 231        if (JX.Stratcom.invoke('go', null, {uri: uri}).getPrevented()) {
 232          return;
 233        }
 234        if (!uri) {
 235          // window.location.reload clears cache in Firefox.
 236          uri = window.location.pathname + (window.location.query || '');
 237        }
 238        window.location = uri;
 239      }
 240  
 241    }
 242  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1