Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 11a6431

Browse files
committed
started to add services
1 parent 35a9108 commit 11a6431

File tree

11 files changed

+290
-167
lines changed

11 files changed

+290
-167
lines changed

src/Angular.js

Lines changed: 104 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,61 @@
1+
2+
//////////////////////////////
3+
//UrlWatcher
4+
//////////////////////////////
5+
6+
function UrlWatcher(location) {
7+
this.location = location;
8+
this.delay = 25;
9+
this.setTimeout = function(fn, delay) {
10+
window.setTimeout(fn, delay);
11+
};
12+
this.expectedUrl = location.href;
13+
this.listeners = [];
14+
}
15+
16+
UrlWatcher.prototype = {
17+
watch: function(fn){
18+
this.listeners.push(fn);
19+
},
20+
21+
start: function() {
22+
var self = this;
23+
(function pull () {
24+
if (self.expectedUrl !== self.location.href) {
25+
foreach(self.listeners, function(listener){
26+
listener(self.location.href);
27+
});
28+
self.expectedUrl = self.location.href;
29+
}
30+
self.setTimeout(pull, self.delay);
31+
})();
32+
},
33+
34+
set: function(url) {
35+
var existingURL = this.location.href;
36+
if (!existingURL.match(/#/))
37+
existingURL += '#';
38+
if (existingURL != url)
39+
this.location.href = url;
40+
this.existingURL = url;
41+
},
42+
43+
get: function() {
44+
return this.location.href;
45+
}
46+
};
47+
48+
49+
150
if (typeof document.getAttribute == 'undefined')
251
document.getAttribute = function() {};
352

453
if (!window['console']) window['console']={'log':noop, 'error':noop};
554

655
var consoleNode,
56+
PRIORITY_FIRST = -99999;
57+
PRIORITY_WATCH = -1000;
58+
PRIORITY_LAST = 99999;
759
NOOP = 'noop',
860
NG_ERROR = 'ng-error',
961
NG_EXCEPTION = 'ng-exception',
@@ -13,19 +65,38 @@ var consoleNode,
1365
msie = !!/(msie) ([\w.]+)/.exec(lowercase(navigator.userAgent)),
1466
jqLite = jQuery || jqLiteWrap,
1567
slice = Array.prototype.slice,
16-
angular = window['angular'] || (window['angular'] = {}),
68+
angular = window['angular'] || (window['angular'] = {}),
1769
angularTextMarkup = extensionMap(angular, 'textMarkup'),
1870
angularAttrMarkup = extensionMap(angular, 'attrMarkup'),
1971
angularDirective = extensionMap(angular, 'directive'),
2072
angularWidget = extensionMap(angular, 'widget'),
2173
angularValidator = extensionMap(angular, 'validator'),
2274
angularFilter = extensionMap(angular, 'filter'),
2375
angularFormatter = extensionMap(angular, 'formatter'),
76+
angularService = extensionMap(angular, 'service'),
2477
angularCallbacks = extensionMap(angular, 'callbacks'),
25-
angularAlert = angular['alert'] || (angular['alert'] = function(){
26-
log(arguments); window.alert.apply(window, arguments);
27-
});
28-
angular['copy'] = copy;
78+
urlWatcher = new UrlWatcher(window.location);
79+
80+
function angularAlert(){
81+
log(arguments); window.alert.apply(window, arguments);
82+
};
83+
84+
extend(angular, {
85+
'compile': compile,
86+
'startUrlWatch': bind(urlWatcher, urlWatcher.start),
87+
'copy': copy,
88+
'extend': extend,
89+
'foreach': foreach,
90+
'noop':noop,
91+
'identity':identity,
92+
'isUndefined': isUndefined,
93+
'isDefined': isDefined,
94+
'isString': isString,
95+
'isFunction': isFunction,
96+
'isNumber': isNumber,
97+
'isArray': isArray,
98+
'alert': angularAlert
99+
});
29100

30101
function foreach(obj, iterator, context) {
31102
var key;
@@ -43,6 +114,17 @@ function foreach(obj, iterator, context) {
43114
return obj;
44115
}
45116

117+
function foreachSorted(obj, iterator, context) {
118+
var keys = [];
119+
for (var key in obj) keys.push(key);
120+
keys.sort();
121+
for ( var i = 0; i < keys.length; i++) {
122+
iterator.call(context, obj[keys[i]], keys[i]);
123+
}
124+
return keys;
125+
}
126+
127+
46128
function extend(dst) {
47129
foreach(arguments, function(obj){
48130
if (obj !== dst) {
@@ -285,19 +367,22 @@ function merge(src, dst) {
285367
}
286368
}
287369

288-
/////////////////////////////////////////////////
289-
290-
angular['compile'] = function(element, config) {
291-
config = extend({
292-
'onUpdateView': noop,
293-
'server': "",
294-
'location': {'get':noop, 'set':noop, 'listen':noop}
295-
}, config||{});
296-
370+
function compile(element, config) {
297371
var compiler = new Compiler(angularTextMarkup, angularAttrMarkup, angularDirective, angularWidget);
298372
$element = jqLite(element),
299-
rootScope = {
300-
'$window': window
301-
};
302-
return rootScope['$root'] = compiler.compile($element)($element, rootScope);
303-
};
373+
rootScope = createScope({
374+
$element: $element,
375+
$config: extend({
376+
'onUpdateView': noop,
377+
'server': "",
378+
'location': {
379+
'get':bind(urlWatcher, urlWatcher.get),
380+
'set':bind(urlWatcher, urlWatcher.set),
381+
'watch':bind(urlWatcher, urlWatcher.watch)
382+
}
383+
}, config || {})
384+
}, serviceAdapter(angularService));
385+
return compiler.compile($element)($element, rootScope);
386+
}
387+
/////////////////////////////////////////////////
388+

src/Compiler.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ Compiler.prototype = {
6565
element = jqLite(element);
6666
parentScope = parentScope || {};
6767
var scope = createScope(parentScope);
68-
parentScope.$root = parentScope.$root || scope;
6968
return extend(scope, {
7069
$element:element,
7170
$init: function() {

src/Parser.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ Lexer.OPERATORS = {
1111
'true':function(self){return true;},
1212
'false':function(self){return false;},
1313
'undefined':noop,
14-
'+':function(self, a,b){return (a||0)+(b||0);},
15-
'-':function(self, a,b){return (a||0)-(b||0);},
14+
'+':function(self, a,b){return (isDefined(a)?a:0)+(isDefined(b)?b:0);},
15+
'-':function(self, a,b){return (isDefined(a)?a:0)-(isDefined(b)?b:0);},
1616
'*':function(self, a,b){return a*b;},
1717
'/':function(self, a,b){return a/b;},
1818
'%':function(self, a,b){return a%b;},

src/Scope.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ function createScope(parent, Class) {
8989
function API(){}
9090
function Behavior(){}
9191

92-
var instance, behavior, api, watchList = [], evalList = [];
92+
var instance, behavior, api, evalLists = {};
93+
if (isFunction(parent)) {
94+
Class = parent;
95+
parent = {};
96+
}
9397

9498
Class = Class || noop;
9599
parent = Parent.prototype = parent || {};
@@ -107,15 +111,10 @@ function createScope(parent, Class) {
107111
if (isDefined(exp)) {
108112
return expressionCompile(exp).apply(instance, slice.call(arguments, 1, arguments.length));
109113
} else {
110-
foreach(watchList, function(watch) {
111-
var value = instance.$tryEval(watch.watch, watch.handler);
112-
if (watch.last !== value) {
113-
instance.$tryEval(watch.listener, watch.handler, value, watch.last);
114-
watch.last = value;
115-
}
116-
});
117-
foreach(evalList, function(eval) {
118-
instance.$tryEval(eval.fn, eval.handler);
114+
foreachSorted(evalLists, function(list) {
115+
foreach(list, function(eval) {
116+
instance.$tryEval(eval.fn, eval.handler);
117+
});
119118
});
120119
}
121120
},
@@ -134,24 +133,46 @@ function createScope(parent, Class) {
134133
},
135134

136135
$watch: function(watchExp, listener, exceptionHandler) {
137-
var watch = expressionCompile(watchExp);
138-
watchList.push({
139-
watch: watch,
140-
last: watch.call(instance),
141-
handler: exceptionHandler,
142-
listener:expressionCompile(listener)
136+
var watch = expressionCompile(watchExp),
137+
last = watch.call(instance);
138+
instance.$onEval(PRIORITY_WATCH, function(){
139+
var value = watch.call(instance);
140+
if (last !== value) {
141+
instance.$tryEval(listener, exceptionHandler, value, last);
142+
last = value;
143+
}
143144
});
144145
},
145146

146-
$onEval: function(expr, exceptionHandler){
147+
$onEval: function(priority, expr, exceptionHandler){
148+
if (!isNumber(priority)) {
149+
exceptionHandler = expr;
150+
expr = priority;
151+
priority = 0;
152+
}
153+
var evalList = evalLists[priority] || (evalLists[priority] = []);
147154
evalList.push({
148155
fn: expressionCompile(expr),
149156
handler: exceptionHandler
150157
});
151158
}
152159
});
153160

161+
if (isUndefined(instance.$root)) {
162+
behavior.$root = instance;
163+
behavior.$parent = instance;
164+
}
165+
154166
Class.apply(instance, slice.call(arguments, 2, arguments.length));
155167

156168
return instance;
157169
}
170+
171+
function serviceAdapter(services) {
172+
return function(){
173+
var self = this;
174+
foreach(services, function(service, name){
175+
self[name] = service.call(self);
176+
});
177+
};
178+
};

src/UrlWatcher.js

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/services.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
angularService("$window", bind(window, identity, window));
2+
3+
angularService("$anchor", function(){
4+
var scope = this;
5+
function anchor(url){
6+
if (isDefined(url)) {
7+
if (url.charAt(0) == '#') url = url.substr(1);
8+
var pathQuery = url.split('?');
9+
anchor.path = decodeURIComponent(pathQuery[0]);
10+
anchor.param = {};
11+
foreach((pathQuery[1] || "").split('&'), function(keyValue){
12+
if (keyValue) {
13+
var parts = keyValue.split('=');
14+
var key = decodeURIComponent(parts[0]);
15+
var value = parts[1];
16+
if (!value) value = true;
17+
anchor.param[key] = decodeURIComponent(value);
18+
}
19+
});
20+
}
21+
var params = [];
22+
foreach(anchor.param, function(value, key){
23+
params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
24+
});
25+
return (anchor.path ? anchor.path : '') + (params.length ? '?' + params.join('&') : '');
26+
};
27+
this.$config.location.watch(function(url){
28+
anchor(url);
29+
});
30+
this.$onEval(PRIORITY_LAST, function(){
31+
scope.$config.location.set(anchor());
32+
});
33+
return anchor;
34+
});

0 commit comments

Comments
 (0)