aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMisko Hevery2010-04-05 20:53:33 -0700
committerMisko Hevery2010-04-05 20:53:33 -0700
commit2107eafcde390eebbf59e829194626c488de9e29 (patch)
tree5cd3d2e0921384edde5014f6af36280eacdde637
parent1c670b2a7c3f6153ea2e5047722f7151b9795b33 (diff)
downloadangular.js-2107eafcde390eebbf59e829194626c488de9e29.tar.bz2
added hover service
-rw-r--r--scenario/widgets.html3
-rw-r--r--src/Angular.js10
-rw-r--r--src/AngularPublic.js12
-rw-r--r--src/Browser.js48
-rw-r--r--src/angular-bootstrap.js2
-rw-r--r--src/jqLite.js2
-rw-r--r--src/services.js43
-rw-r--r--test/BrowserTest.js2
-rw-r--r--test/angular-mocks.js5
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;
},