diff options
| author | Misko Hevery | 2010-04-05 20:53:33 -0700 | 
|---|---|---|
| committer | Misko Hevery | 2010-04-05 20:53:33 -0700 | 
| commit | 2107eafcde390eebbf59e829194626c488de9e29 (patch) | |
| tree | 5cd3d2e0921384edde5014f6af36280eacdde637 | |
| parent | 1c670b2a7c3f6153ea2e5047722f7151b9795b33 (diff) | |
| download | angular.js-2107eafcde390eebbf59e829194626c488de9e29.tar.bz2 | |
added hover service
| -rw-r--r-- | scenario/widgets.html | 3 | ||||
| -rw-r--r-- | src/Angular.js | 10 | ||||
| -rw-r--r-- | src/AngularPublic.js | 12 | ||||
| -rw-r--r-- | src/Browser.js | 48 | ||||
| -rw-r--r-- | src/angular-bootstrap.js | 2 | ||||
| -rw-r--r-- | src/jqLite.js | 2 | ||||
| -rw-r--r-- | src/services.js | 43 | ||||
| -rw-r--r-- | test/BrowserTest.js | 2 | ||||
| -rw-r--r-- | test/angular-mocks.js | 5 | 
9 files changed, 102 insertions, 25 deletions
diff --git a/scenario/widgets.html b/scenario/widgets.html index 73674be9..6cb8df05 100644 --- a/scenario/widgets.html +++ b/scenario/widgets.html @@ -2,12 +2,13 @@  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">    <head>      <link rel="stylesheet" type="text/css" href="style.css"></link> +    <!--<script type="text/javascript" src="../lib/jquery/jquery-1.4.2.js"></script>-->      <script type="text/javascript" src="../src/angular-bootstrap.js#autobind"></script>    </head>    <body ng-init="$window.$scope = this">      <table>        <tr> -        <th>Description</th> +        <th width="330">Description</th>          <th>Test</th>          <th>Result</th>        </tr> diff --git a/src/Angular.js b/src/Angular.js index 0952a352..2d67b2cb 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -313,8 +313,10 @@ function merge(src, dst) {  function compile(element, parentScope, overrides) {    var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget); -      $element = jqLite(element); -  return compiler.compile($element)($element, parentScope, overrides); +      $element = jqLite(element), +      parent = extend({}, parentScope); +  parent.$element = $element; +  return compiler.compile($element)($element, parent, overrides);  }  ///////////////////////////////////////////////// @@ -340,6 +342,8 @@ function toKeyValue(obj) {  function angularInit(config){    if (config.autobind) { -    compile(window.document, null, {'$config':config}).$init(); +    var scope = compile(window.document, null, {'$config':config}); +    scope.$browser.addCss('../css/angular.css'); +    scope.$init();    }  } diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 470eb258..176d6a91 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -1,17 +1,9 @@  var browserSingleton;  angularService('$browser', function browserFactory(){    if (!browserSingleton) { -    var XHR = XMLHttpRequest; -    if (isUndefined(XHR)) { -      XHR = function () { -        try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} -        try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} -        try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} -        throw new Error("This browser does not support XMLHttpRequest."); -      }; -    } -    browserSingleton = new Browser(window.location, XHR); +    browserSingleton = new Browser(window.location, window.document);      browserSingleton.startUrlWatcher(); +    browserSingleton.bind();    }    return browserSingleton;  }); diff --git a/src/Browser.js b/src/Browser.js index 6036884f..69f3eb9a 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -3,18 +3,52 @@  // Browser  ////////////////////////////// -function Browser(location, XHR) { -  this.location = location; +function Browser(location, document) {    this.delay = 25; -  this.XHR = XHR; +  this.expectedUrl = location.href; +  this.urlListeners = []; +  this.hoverListener = noop; + +  this.XHR = XMLHttpRequest || function () { +    try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e1) {} +    try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e2) {} +    try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e3) {} +    throw new Error("This browser does not support XMLHttpRequest."); +  };    this.setTimeout = function(fn, delay) {     window.setTimeout(fn, delay);    }; -  this.expectedUrl = location.href; -  this.listeners = []; + +  this.location = location; +  this.document = jqLite(document); +  this.body = jqLite(document.body);  }  Browser.prototype = { + +  bind: function() { +    var self = this; +    self.document.bind("mouseover", function(event){ +      self.hoverListener(jqLite(event.target), true); +      return true; +    }); +    self.document.bind("mouseleave mouseout click dblclick keypress keyup", function(event){ +      self.hoverListener(jqLite(event.target), false); +      return true; +    }); +  }, + +  hover: function(hoverListener) { +    this.hoverListener = hoverListener; +  }, + +  addCss: function(url) { +    var head = jqLite(this.document[0].getElementsByTagName('head')[0]), +        link = jqLite('<link rel="stylesheet" type="text/css"></link>'); +    link.attr('href', url); +    head.append(link); +  }, +    xhr: function(method, url, callback){      var xhr = new this.XHR();      xhr.open(method, url, true); @@ -27,14 +61,14 @@ Browser.prototype = {    },    watchUrl: function(fn){ -   this.listeners.push(fn); +    this.urlListeners.push(fn);    },    startUrlWatcher: function() {     var self = this;     (function pull () {       if (self.expectedUrl !== self.location.href) { -       foreach(self.listeners, function(listener){ +       foreach(self.urlListeners, function(listener){           try {             listener(self.location.href);           } catch (e) { diff --git a/src/angular-bootstrap.js b/src/angular-bootstrap.js index ce7849d8..d9633854 100644 --- a/src/angular-bootstrap.js +++ b/src/angular-bootstrap.js @@ -47,7 +47,7 @@    addScript("/Parser.js");    addScript("/Resource.js");    addScript("/Browser.js"); -  addScript("/~AngularPublic.js"); +  addScript("/AngularPublic.js");    // Extension points    addScript("/apis.js"); diff --git a/src/jqLite.js b/src/jqLite.js index f8ed4d7d..331db68d 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -78,7 +78,7 @@ JQLite.prototype = {          bind[type] = eventHandler = function(event) {            var bubbleEvent = false;            foreach(eventHandler.fns, function(fn){ -            bubbleEvent = bubbleEvent || fn.apply(self, arguments); +            bubbleEvent = bubbleEvent || fn.call(self, event);            });            if (!bubbleEvent) {              event.preventDefault(); diff --git a/src/services.js b/src/services.js index 2532d3d3..173cee98 100644 --- a/src/services.js +++ b/src/services.js @@ -44,3 +44,46 @@ angularService("$location", function(browser){    return location;  }, {inject: ['$browser']}); +angularService("$hover", function(browser) { +  var tooltip, self = this, error, width = 300, arrowWidth = 10; +  browser.hover(function(element, show){ +    if (show && (error = element.attr('ng-error'))) { +      if (!tooltip) { +        tooltip = { +            callout: jqLite('<div id="ng-callout"></div>'), +            arrow: jqLite('<div></div>'), +            title: jqLite('<div class="ng-title"></div>'), +            content: jqLite('<div class="ng-content"></div>') +        }; +        tooltip.callout.append(tooltip.arrow); +        tooltip.callout.append(tooltip.title); +        tooltip.callout.append(tooltip.content); +        self.$browser.body.append(tooltip.callout); +      } +      var docRect = self.$browser.body[0].getBoundingClientRect(), +          elementRect = element[0].getBoundingClientRect(), +          leftSpace = docRect.right - elementRect.right - arrowWidth; +      tooltip.title.text(element.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error..."); +      tooltip.content.text(error); +      if (leftSpace < width) { +        tooltip.arrow.addClass('ng-arrow-right'); +        tooltip.arrow.css({left: (width + 1)+'px'}); +        tooltip.callout.css({ +          left: (elementRect.left - arrowWidth - width - 4) + "px", +          top: (elementRect.top - 3) + "px", +          width: width + "px" +        }); +      } else { +        tooltip.arrow.addClass('ng-arrow-left'); +        tooltip.callout.css({ +          left: (elementRect.right + arrowWidth) + "px", +          top: (elementRect.top - 3) + "px", +          width: width + "px" +        }); +      } +    } else if (tooltip) { +      tooltip.callout.remove(); +      tooltip = null; +    } +  }); +}, {inject:['$browser']}); diff --git a/test/BrowserTest.js b/test/BrowserTest.js index 2e630172..5254840a 100644 --- a/test/BrowserTest.js +++ b/test/BrowserTest.js @@ -3,7 +3,7 @@ BrowserTest = TestCase('BrowserTest');  BrowserTest.prototype.testUrlWatcher = function () {    expectAsserts(2);    var location = {href:"http://server", hash:""}; -  var watcher = new Browser(location); +  var watcher = new Browser(location, {});    watcher.delay = 1;    watcher.watchUrl(function(url){      assertEquals('http://getangular.test', url); diff --git a/test/angular-mocks.js b/test/angular-mocks.js index 9c93f87f..e10ad4e2 100644 --- a/test/angular-mocks.js +++ b/test/angular-mocks.js @@ -8,7 +8,7 @@ function MockBrowser() {      var expect = expectations[method] || {};      var response = expect[url];      if (!response) { -      throw "Unexepected request for mothod '" + method + "' and url '" + url + "'."; +      throw "Unexepected request for method '" + method + "' and url '" + url + "'.";      }      requests.push(function(){        callback(200, response); @@ -32,6 +32,9 @@ function MockBrowser() {  }  MockBrowser.prototype = { +  hover: function(onHover) { +  }, +    getUrl: function(){      return this.url;    },  | 
