diff options
| author | Igor Minar | 2011-01-04 17:54:37 -0800 | 
|---|---|---|
| committer | Igor Minar | 2011-01-07 14:39:41 -0800 | 
| commit | 16086aa37c5c0c98f5c4a42d2a15136bb6d18605 (patch) | |
| tree | 8b8e4b6b585e9d267588cb324745a3246bc5bc41 /src | |
| parent | c0a26b18531482d493d544cf1a207586e8aacaf4 (diff) | |
| download | angular.js-16086aa37c5c0c98f5c4a42d2a15136bb6d18605.tar.bz2 | |
$location service should utilize onhashchange events instead of polling
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 2 | ||||
| -rw-r--r-- | src/AngularPublic.js | 9 | ||||
| -rw-r--r-- | src/Browser.js | 64 | ||||
| -rw-r--r-- | src/jqLite.js | 10 | ||||
| -rw-r--r-- | src/services.js | 16 | 
5 files changed, 74 insertions, 27 deletions
diff --git a/src/Angular.js b/src/Angular.js index 8b61970f..8ada7be6 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -271,7 +271,7 @@ function jqLiteWrap(element) {        var div = document.createElement('div');        div.innerHTML = element;        element = new JQLite(div.childNodes); -    } else if (!(element instanceof JQLite) && isElement(element)) { +    } else if (!(element instanceof JQLite)) {        element =  new JQLite(element);      }    } diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 38325404..ab37a772 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -10,13 +10,8 @@ var browserSingleton;   */  angularService('$browser', function($log){    if (!browserSingleton) { -    browserSingleton = new Browser( -        window.location, -        jqLite(window.document), -        jqLite(window.document.getElementsByTagName('head')[0]), -        XHR, -        $log, -        window.setTimeout); +    browserSingleton = new Browser(window, jqLite(window.document), jqLite(window.document.body), +                                   XHR, $log);      var addPollFn = browserSingleton.addPollFn;      browserSingleton.addPollFn = function(){        browserSingleton.addPollFn = addPollFn; diff --git a/src/Browser.js b/src/Browser.js index 4ab92f10..c93f115c 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -8,8 +8,29 @@ var XHR = window.XMLHttpRequest || function () {    throw new Error("This browser does not support XMLHttpRequest.");  }; -function Browser(location, document, head, XHR, $log, setTimeout) { -  var self = this; +/** + * @private + * @name Browser + * + * @description + * Constructor for the object exposed as $browser service. + * + * This object has two goals: + * + * - hide all the global state in the browser caused by the window object + * - abstract away all the browser specific features and inconsistencies + * + * @param {object} window The global window object. + * @param {object} document jQuery wrapped document. + * @param {object} body jQuery wrapped document.body. + * @param {function()} XHR XMLHttpRequest constructor. + * @param {object} $log console.log or an object with the same interface. + */ +function Browser(window, document, body, XHR, $log) { +  var self = this, +      location = window.location, +      setTimeout = window.setTimeout; +    self.isMock = false;    ////////////////////////////////////////////////////////////// @@ -70,7 +91,7 @@ function Browser(location, document, head, XHR, $log, setTimeout) {          window[callbackId] = _undefined;          callback(200, data);        }; -      head.append(script); +      body.append(script);      } else {        var xhr = new XHR();        xhr.open(method, url, true); @@ -195,6 +216,39 @@ function Browser(location, document, head, XHR, $log, setTimeout) {      return location.href;    }; + +  /** +   * @workInProgress +   * @ngdoc method +   * @name angular.service.$browser#onHashChange +   * @methodOf angular.service.$browser +   * +   * @description +   * Detects if browser support onhashchange events and register a listener otherwise registers +   * $browser poller. The `listener` will then get called when the hash changes. +   * +   * The listener gets called with either HashChangeEvent object or simple object that also contains +   * `oldURL` and `newURL` properties. +   * +   * NOTE: this is a api is intended for sole use by $location service. Please use +   * {@link angular.service.$location $location service} to monitor hash changes in angular apps. +   * +   * @param {function(event)} listener Listener function to be called when url hash changes. +   */ +  self.onHashChange = function(listener) { +    if ('onhashchange' in window) { +      jqLite(window).bind('hashchange', listener); +    } else { +      var lastBrowserUrl = self.getUrl(); + +      self.addPollFn(function() { +        if (lastBrowserUrl != self.getUrl()) { +          listener(); +        } +      }); +    } +  } +    //////////////////////////////////////////////////////////////    // Cookies API    ////////////////////////////////////////////////////////////// @@ -338,7 +392,7 @@ function Browser(location, document, head, XHR, $log, setTimeout) {      link.attr('rel', 'stylesheet');      link.attr('type', 'text/css');      link.attr('href', url); -    head.append(link); +    body.append(link);    }; @@ -359,6 +413,6 @@ function Browser(location, document, head, XHR, $log, setTimeout) {      script.attr('type', 'text/javascript');      script.attr('src', url);      if (dom_id) script.attr('id', dom_id); -    head.append(script); +    body.append(script);    };  } diff --git a/src/jqLite.js b/src/jqLite.js index 0d96d6e4..1bc966eb 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -47,14 +47,14 @@ function getStyle(element) {  }  function JQLite(element) { -  if (isElement(element)) { -    this[0] = element; -    this.length = 1; -  } else if (isDefined(element.length) && element.item) { +  if (!isElement(element) && isDefined(element.length) && element.item) {      for(var i=0; i < element.length; i++) {        this[i] = element[i];      }      this.length = element.length; +  } else { +    this[0] = element; +    this.length = 1;    }  } @@ -81,7 +81,7 @@ JQLite.prototype = {    dealoc: function(){      (function dealoc(element){        jqClearData(element); -      for ( var i = 0, children = element.childNodes; i < children.length; i++) { +      for ( var i = 0, children = element.childNodes || []; i < children.length; i++) {          dealoc(children[i]);        }      })(this[0]); diff --git a/src/services.js b/src/services.js index 0b983ffb..91bd226d 100644 --- a/src/services.js +++ b/src/services.js @@ -68,19 +68,17 @@ angularServiceInject("$document", function(window){     <input type='text' name="$location.hash"/>     <pre>$location = {{$location}}</pre>   */ -angularServiceInject("$location", function(browser) { +angularServiceInject("$location", function($browser) {    var scope = this,        location = {toString:toString, update:update, updateHash: updateHash}, -      lastBrowserUrl = browser.getUrl(), +      lastBrowserUrl = $browser.getUrl(),        lastLocationHref,        lastLocationHash; -  browser.addPollFn(function() { -    if (lastBrowserUrl != browser.getUrl()) { -      update(lastBrowserUrl = browser.getUrl()); -      updateLastLocation(); -      scope.$eval(); -    } +  $browser.onHashChange(function() { +    update(lastBrowserUrl = $browser.getUrl()); +    updateLastLocation(); +    scope.$eval();    });    this.$onEval(PRIORITY_FIRST, updateBrowser); @@ -219,7 +217,7 @@ angularServiceInject("$location", function(browser) {      updateLocation();      if (location.href != lastLocationHref) {    	 -      browser.setUrl(lastBrowserUrl = location.href); +      $browser.setUrl(lastBrowserUrl = location.href);        updateLastLocation();      }    }  | 
