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; }, |
