added hover service

This commit is contained in:
Misko Hevery 2010-04-05 20:53:33 -07:00
parent 1c670b2a7c
commit 2107eafcde
9 changed files with 102 additions and 25 deletions

View file

@ -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>

View file

@ -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();
}
}

View file

@ -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;
});

View file

@ -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) {

View file

@ -47,7 +47,7 @@
addScript("/Parser.js");
addScript("/Resource.js");
addScript("/Browser.js");
addScript("/~AngularPublic.js");
addScript("/AngularPublic.js");
// Extension points
addScript("/apis.js");

View file

@ -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();

View file

@ -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']});

View file

@ -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);

View file

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