mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-18 23:50:23 +00:00
Added basic Services, which support @memberOf and @methodOf
This commit is contained in:
parent
b467a50bc7
commit
cc749760fd
9 changed files with 840 additions and 67 deletions
105
docs/collect.js
105
docs/collect.js
|
|
@ -7,7 +7,8 @@ var fs = require('fs'),
|
||||||
Showdown = require('showdown').Showdown;
|
Showdown = require('showdown').Showdown;
|
||||||
|
|
||||||
var documentation = {
|
var documentation = {
|
||||||
pages:[]
|
pages:[],
|
||||||
|
byName: {}
|
||||||
};
|
};
|
||||||
var keywordPages = [];
|
var keywordPages = [];
|
||||||
|
|
||||||
|
|
@ -23,18 +24,7 @@ var work = callback.chain(function () {
|
||||||
//console.log('reading', file, '...');
|
//console.log('reading', file, '...');
|
||||||
findNgDoc(file, work.waitMany(function(doc) {
|
findNgDoc(file, work.waitMany(function(doc) {
|
||||||
parseNgDoc(doc);
|
parseNgDoc(doc);
|
||||||
if (doc.ngdoc) {
|
processNgDoc(documentation, doc);
|
||||||
keywordPages.push({
|
|
||||||
name:doc.name,
|
|
||||||
keywords:keywords(doc.raw.text)
|
|
||||||
}
|
|
||||||
);
|
|
||||||
documentation.pages.push(doc);
|
|
||||||
console.log('Found:', doc.ngdoc + ':' + doc.shortName);
|
|
||||||
mergeTemplate(
|
|
||||||
doc.ngdoc + '.template',
|
|
||||||
doc.name + '.html', doc, work.waitFor());
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
|
|
@ -42,6 +32,7 @@ var work = callback.chain(function () {
|
||||||
console.log('ERROR:', err.stack || err);
|
console.log('ERROR:', err.stack || err);
|
||||||
}).onDone(function(){
|
}).onDone(function(){
|
||||||
keywordPages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);});
|
keywordPages.sort(function(a,b){ return a.name == b.name ? 0:(a.name < b.name ? -1 : 1);});
|
||||||
|
writeDoc(documentation.pages);
|
||||||
mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(keywordPages)}, callback.chain());
|
mergeTemplate('docs-data.js', 'docs-data.js', {JSON:JSON.stringify(keywordPages)}, callback.chain());
|
||||||
mergeTemplate('docs-scenario.js', 'docs-scenario.js', documentation, callback.chain());
|
mergeTemplate('docs-scenario.js', 'docs-scenario.js', documentation, callback.chain());
|
||||||
copy('docs-scenario.html', callback.chain());
|
copy('docs-scenario.html', callback.chain());
|
||||||
|
|
@ -156,11 +147,17 @@ function markdownTag(doc, name, value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function markdown(text) {
|
function markdown(text) {
|
||||||
text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>');
|
var parts = text.split(/(<pre>[\s\S]*<\/pre>)/);
|
||||||
text = text.replace(/(angular\.[\w\._\-:]+)/gm, '<a href="#$1">$1</a>');
|
parts.forEach(function(text, i){
|
||||||
text = text.replace(/(`(ng:[\w\._\-]+)`)/gm, '<a href="#angular.directive.$2">$1</a>');
|
if (!text.match(/^<pre>/)) {
|
||||||
text = new Showdown.converter().makeHtml(text);
|
text = text.replace(/<angular\/>/gm, '<tt><angular/></tt>');
|
||||||
return text;
|
text = new Showdown.converter().makeHtml(text);
|
||||||
|
text = text.replace(/(angular\.[\$\w\._\-:]+)/gm, '<a href="#!$1">$1</a>');
|
||||||
|
text = text.replace(/(`(ng:[\w\._\-]+)`)/gm, '<a href="#!angular.directive.$2">$1</a>');
|
||||||
|
parts[i] = text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return parts.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function markdownNoP(text) {
|
function markdownNoP(text) {
|
||||||
|
|
@ -171,6 +168,43 @@ function markdownNoP(text) {
|
||||||
return lines.join('\n');
|
return lines.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requiresTag(doc, name, value) {
|
||||||
|
doc.requires = doc.requires || [];
|
||||||
|
doc.requires.push({name: value});
|
||||||
|
}
|
||||||
|
|
||||||
|
function propertyTag(doc, name, value) {
|
||||||
|
doc[name] = doc[name] || [];
|
||||||
|
var match = value.match(/^({(\S+)}\s*)?(\S+)(\s+(.*))?/);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
var tag = {
|
||||||
|
type: match[2],
|
||||||
|
name: match[3],
|
||||||
|
description: match[5] || false
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw "[" + doc.raw.file + ":" + doc.raw.line +
|
||||||
|
"]: @" + name + " must be in format '{type} name description' got: " + value;
|
||||||
|
}
|
||||||
|
return doc[name].push(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
function returnsTag(doc, name, value) {
|
||||||
|
var match = value.match(/^({(\S+)}\s*)?(.*)?/);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
var tag = {
|
||||||
|
type: match[2],
|
||||||
|
description: match[3] || false
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw "[" + doc.raw.file + ":" + doc.raw.line +
|
||||||
|
"]: @" + name + " must be in format '{type} description' got: " + value;
|
||||||
|
}
|
||||||
|
return doc[name] = tag;
|
||||||
|
}
|
||||||
|
|
||||||
var TAG = {
|
var TAG = {
|
||||||
ngdoc: valueTag,
|
ngdoc: valueTag,
|
||||||
example: escapedHtmlTag,
|
example: escapedHtmlTag,
|
||||||
|
|
@ -186,6 +220,7 @@ var TAG = {
|
||||||
paramDescription: markdownTag,
|
paramDescription: markdownTag,
|
||||||
exampleDescription: markdownTag,
|
exampleDescription: markdownTag,
|
||||||
element: valueTag,
|
element: valueTag,
|
||||||
|
methodOf: valueTag,
|
||||||
name: function(doc, name, value) {
|
name: function(doc, name, value) {
|
||||||
doc.name = value;
|
doc.name = value;
|
||||||
doc.shortName = value.split(/\./).pop();
|
doc.shortName = value.split(/\./).pop();
|
||||||
|
|
@ -212,7 +247,10 @@ var TAG = {
|
||||||
throw "[" + doc.raw.file + ":" + doc.raw.line +
|
throw "[" + doc.raw.file + ":" + doc.raw.line +
|
||||||
"]: @param must be in format '{type} name=value description' got: " + value;
|
"]: @param must be in format '{type} name=value description' got: " + value;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
property: propertyTag,
|
||||||
|
requires: requiresTag,
|
||||||
|
returns: returnsTag
|
||||||
};
|
};
|
||||||
|
|
||||||
function parseNgDoc(doc){
|
function parseNgDoc(doc){
|
||||||
|
|
@ -291,3 +329,32 @@ function findJsFiles(dir, callback){
|
||||||
callback.done();
|
callback.done();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function processNgDoc(documentation, doc) {
|
||||||
|
if (!doc.ngdoc) return;
|
||||||
|
console.log('Found:', doc.ngdoc + ':' + doc.name);
|
||||||
|
|
||||||
|
documentation.byName[doc.name] = doc;
|
||||||
|
|
||||||
|
if (doc.methodOf) {
|
||||||
|
if (parent = documentation.byName[doc.methodOf]) {
|
||||||
|
(parent.method = parent.method || []).push(doc);
|
||||||
|
} else {
|
||||||
|
throw 'Owner "' + doc.methodOf + '" is not defined.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
documentation.pages.push(doc);
|
||||||
|
keywordPages.push({
|
||||||
|
name:doc.name,
|
||||||
|
keywords:keywords(doc.raw.text)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeDoc(pages) {
|
||||||
|
pages.forEach(function(doc) {
|
||||||
|
mergeTemplate(
|
||||||
|
doc.ngdoc + '.template',
|
||||||
|
doc.name + '.html', doc, callback.chain());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,3 +125,8 @@ a {
|
||||||
margin-left: 2em;
|
margin-left: 2em;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#sidebar ul li.level-3 {
|
||||||
|
margin-left: 3em;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
|
||||||
37
docs/service.template
Normal file
37
docs/service.template
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<h1><tt>{{name}}</tt></h1>
|
||||||
|
<h2>Description</h2>
|
||||||
|
{{{description}}}
|
||||||
|
|
||||||
|
<h2>Dependencies</h2>
|
||||||
|
<ul>
|
||||||
|
{{#requires}}
|
||||||
|
<li><tt>{{name}}</tt></li>
|
||||||
|
{{/requires}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Methods</h2>
|
||||||
|
<ul>
|
||||||
|
{{#method}}
|
||||||
|
<li><tt>{{shortName}}</tt>: {{{description}}}</li>
|
||||||
|
{{/method}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Properties</h2>
|
||||||
|
<ul>
|
||||||
|
{{#property}}
|
||||||
|
<li><tt>{{name}}:{{#type}}{{type}}{{/type}}</tt>{{#description}}: {{{description}}}{{/description}}</li>
|
||||||
|
{{/property}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{#example}}
|
||||||
|
<h2>Example</h2>
|
||||||
|
{{{exampleDescription}}}
|
||||||
|
<doc:example>
|
||||||
|
<doc:source>
|
||||||
|
{{/example}}
|
||||||
|
{{{example}}}
|
||||||
|
{{#example}}
|
||||||
|
</doc:source>
|
||||||
|
{{#scenario}}<doc:scenario>{{{scenario}}}</doc:scenario>{{/scenario}}
|
||||||
|
</doc:example>
|
||||||
|
{{/example}}
|
||||||
|
|
@ -11,6 +11,63 @@ describe('collect', function(){
|
||||||
expect(collect.markdown('<angular/>')).
|
expect(collect.markdown('<angular/>')).
|
||||||
toEqual('<p><tt><angular/></tt></p>');
|
toEqual('<p><tt><angular/></tt></p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not replace anything in <pre>', function(){
|
||||||
|
expect(collect.markdown('angular.x\n<pre>\nangular.k\n</pre>\nangular.x')).
|
||||||
|
toEqual(
|
||||||
|
'<p><a href="#!angular.x">angular.x</a></p>' +
|
||||||
|
'<pre>\nangular.k\n</pre>' +
|
||||||
|
'<p><a href="#!angular.x">angular.x</a></p>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('processNgDoc', function() {
|
||||||
|
var processNgDoc = collect.processNgDoc,
|
||||||
|
documentation;
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
documentation = {
|
||||||
|
pages: [],
|
||||||
|
byName: {}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should store references to docs by name', function() {
|
||||||
|
var doc = {ngdoc: 'section', name: 'fake', raw: {text:''}};
|
||||||
|
processNgDoc(documentation, doc);
|
||||||
|
expect(documentation.byName.fake).toBe(doc);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should connect doc to owner (specified by @methodOf)', function() {
|
||||||
|
var parentDoc = {ngdoc: 'section', name: 'parent', raw: {text:''}};
|
||||||
|
var doc = {ngdoc: 'section', name: 'child', methodOf: 'parent', raw: {text:''}};
|
||||||
|
processNgDoc(documentation, parentDoc);
|
||||||
|
processNgDoc(documentation, doc);
|
||||||
|
expect(documentation.byName.parent.method).toBeDefined();
|
||||||
|
expect(documentation.byName.parent.method[0]).toBe(doc);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add doc to sections if @memberOf specified', function() {
|
||||||
|
var parentDoc = {ngdoc: 'parent', name: 'parent', raw: {text:''}};
|
||||||
|
var doc = {ngdoc: 'child', name: 'child', methodOf: 'parent', raw: {text:''}};
|
||||||
|
processNgDoc(documentation, parentDoc);
|
||||||
|
processNgDoc(documentation, doc);
|
||||||
|
expect(documentation.pages.child).not.toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw exception if owner does not exist', function() {
|
||||||
|
expect(function() {
|
||||||
|
processNgDoc(documentation, {ngdoc: 'section', methodOf: 'not.exist', raw: {text:''}});
|
||||||
|
}).toThrow('Owner "not.exist" is not defined.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should ignore non-ng docs', function() {
|
||||||
|
var doc = {name: 'anything'};
|
||||||
|
expect(function() {
|
||||||
|
processNgDoc(documentation, doc);
|
||||||
|
}).not.toThrow();
|
||||||
|
expect(documentation.pages).not.toContain(doc);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('TAG', function(){
|
describe('TAG', function(){
|
||||||
|
|
@ -41,6 +98,90 @@ describe('collect', function(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('@requires', function() {
|
||||||
|
it('should parse more @requires tag into array', function() {
|
||||||
|
TAG.requires(doc, 'requires', '$service');
|
||||||
|
TAG.requires(doc, 'requires', '$another');
|
||||||
|
|
||||||
|
expect(doc.requires).toEqual([
|
||||||
|
{name: '$service'},
|
||||||
|
{name: '$another'}
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('@property', function() {
|
||||||
|
it('should parse @property tags into array', function() {
|
||||||
|
TAG.property(doc, 'property', '{type} name1 desc');
|
||||||
|
TAG.property(doc, 'property', '{type} name2 desc');
|
||||||
|
expect(doc.property.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @property with only name', function() {
|
||||||
|
TAG.property(doc, 'property', 'fake');
|
||||||
|
expect(doc.property[0].name).toEqual('fake');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @property with optional type', function() {
|
||||||
|
TAG.property(doc, 'property', '{string} name');
|
||||||
|
expect(doc.property[0].name).toEqual('name');
|
||||||
|
expect(doc.property[0].type).toEqual('string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @property with optional description', function() {
|
||||||
|
TAG.property(doc, 'property', 'name desc rip tion');
|
||||||
|
expect(doc.property[0].name).toEqual('name');
|
||||||
|
expect(doc.property[0].description).toEqual('desc rip tion');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @property with type and description both', function() {
|
||||||
|
TAG.property(doc, 'property', '{bool} name desc rip tion');
|
||||||
|
expect(doc.property[0].name).toEqual('name');
|
||||||
|
expect(doc.property[0].type).toEqual('bool');
|
||||||
|
expect(doc.property[0].description).toEqual('desc rip tion');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If property description is undefined, this variable is not set in the template,
|
||||||
|
* so the whole @description tag is used instead
|
||||||
|
*/
|
||||||
|
it('should set undefined description to "false"', function() {
|
||||||
|
TAG.property(doc, 'property', 'name');
|
||||||
|
expect(doc.property[0].description).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('@methodOf', function() {
|
||||||
|
it('should parse @methodOf tag', function() {
|
||||||
|
expect(function() {
|
||||||
|
TAG.methodOf(doc, 'methodOf', 'parentName');
|
||||||
|
}).not.toThrow();
|
||||||
|
expect(doc.methodOf).toEqual('parentName');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('@returns', function() {
|
||||||
|
it('should parse @returns', function() {
|
||||||
|
expect(function() {TAG.returns(doc, 'returns', '');})
|
||||||
|
.not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @returns with type', function() {
|
||||||
|
TAG.returns(doc, 'returns', '{string}');
|
||||||
|
expect(doc.returns.type).toEqual('string');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @returns with description', function() {
|
||||||
|
TAG.returns(doc, 'returns', 'descrip tion');
|
||||||
|
expect(doc.returns.description).toEqual('descrip tion');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse @returns with type and description', function() {
|
||||||
|
TAG.returns(doc, 'returns', '{string} description');
|
||||||
|
expect(doc.returns).toEqual({type: 'string', description: 'description'});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('@describe', function(){
|
describe('@describe', function(){
|
||||||
it('should support pre blocks', function(){
|
it('should support pre blocks', function(){
|
||||||
TAG.description(doc, 'description', '<pre>abc</pre>');
|
TAG.description(doc, 'description', '<pre>abc</pre>');
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
require.paths.push("./lib");
|
require.paths.push("./lib");
|
||||||
var jasmine = require('jasmine-1.0.1');
|
var jasmine = require('jasmine-1.0.1');
|
||||||
var sys = require('sys');
|
var sys = require('util');
|
||||||
|
|
||||||
for(var key in jasmine) {
|
for(var key in jasmine) {
|
||||||
global[key] = jasmine[key];
|
global[key] = jasmine[key];
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,6 @@ var _undefined = undefined,
|
||||||
*/
|
*/
|
||||||
angularValidator = extensionMap(angular, 'validator'),
|
angularValidator = extensionMap(angular, 'validator'),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc overview
|
* @ngdoc overview
|
||||||
* @name angular.filter
|
* @name angular.filter
|
||||||
|
|
@ -473,6 +472,53 @@ var _undefined = undefined,
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
angularFormatter = extensionMap(angular, 'formatter'),
|
angularFormatter = extensionMap(angular, 'formatter'),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @name angular.service
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* # Overview
|
||||||
|
* Services are substituable objects, which are wired together using dependency injection.
|
||||||
|
* Each service could have dependencies (other services), which are passed in constructor.
|
||||||
|
* Because JS is dynamicaly typed language, dependency injection can not use static types
|
||||||
|
* to satisfy these dependencies, so each service must explicitely define its dependencies.
|
||||||
|
* This is done by $inject property.
|
||||||
|
*
|
||||||
|
* For now, life time of all services is the same as the life time of page.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* # Standard services
|
||||||
|
* The Angular framework provides a standard set of services for common operations.
|
||||||
|
* You can write your own services and rewrite these standard services as well.
|
||||||
|
* Like other core angular variables, standard services always start with $.
|
||||||
|
*
|
||||||
|
* * `angular.service.$window`
|
||||||
|
* * `angular.service.$document`
|
||||||
|
* * `angular.service.$location`
|
||||||
|
* * `angular.service.$log`
|
||||||
|
* * `angular.service.$exceptionHandler`
|
||||||
|
* * `angular.service.$hover`
|
||||||
|
* * `angular.service.$invalidWidgets`
|
||||||
|
* * `angular.service.$route`
|
||||||
|
* * `angular.service.$xhr`
|
||||||
|
* * `angular.service.$xhr.error`
|
||||||
|
* * `angular.service.$xhr.bulk`
|
||||||
|
* * `angular.service.$xhr.cache`
|
||||||
|
* * `angular.service.$resource`
|
||||||
|
* * `angular.service.$cookies`
|
||||||
|
* * `angular.service.$cookieStore`
|
||||||
|
*
|
||||||
|
* # Writing your own services
|
||||||
|
* <pre>
|
||||||
|
* angular.service('notify', function(location) {
|
||||||
|
* this.one = function() {
|
||||||
|
* }
|
||||||
|
* }, {$inject: ['$location']});
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* # Using services in controller
|
||||||
|
*/
|
||||||
angularService = extensionMap(angular, 'service'),
|
angularService = extensionMap(angular, 'service'),
|
||||||
angularCallbacks = extensionMap(angular, 'callbacks'),
|
angularCallbacks = extensionMap(angular, 'callbacks'),
|
||||||
nodeName,
|
nodeName,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,12 @@
|
||||||
var browserSingleton;
|
var browserSingleton;
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$browser
|
||||||
|
* @requires $log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Represents the browser.
|
||||||
|
*/
|
||||||
angularService('$browser', function($log){
|
angularService('$browser', function($log){
|
||||||
if (!browserSingleton) {
|
if (!browserSingleton) {
|
||||||
browserSingleton = new Browser(
|
browserSingleton = new Browser(
|
||||||
|
|
|
||||||
159
src/Browser.js
159
src/Browser.js
|
|
@ -19,7 +19,20 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
var outstandingRequestCount = 0;
|
var outstandingRequestCount = 0;
|
||||||
var outstandingRequestCallbacks = [];
|
var outstandingRequestCallbacks = [];
|
||||||
|
|
||||||
self.xhr = function(method, url, post, callback){
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#xhr
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {string} method Requested method (get|post|put|delete|head|json)
|
||||||
|
* @param {string} url Requested url
|
||||||
|
* @param {string=} post Post data to send
|
||||||
|
* @param {function(number, string)} callback Function that will be called on response
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Send ajax request
|
||||||
|
*/
|
||||||
|
self.xhr = function(method, url, post, callback) {
|
||||||
if (isFunction(post)) {
|
if (isFunction(post)) {
|
||||||
callback = post;
|
callback = post;
|
||||||
post = _null;
|
post = _null;
|
||||||
|
|
@ -63,7 +76,14 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.notifyWhenNoOutstandingRequests = function(callback){
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#notifyWhenNoOutstandingRequests
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {function} callback Function that will be called when no outstanding request
|
||||||
|
*/
|
||||||
|
self.notifyWhenNoOutstandingRequests = function(callback) {
|
||||||
if (outstandingRequestCount === 0) {
|
if (outstandingRequestCount === 0) {
|
||||||
callback();
|
callback();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -75,27 +95,48 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
// Poll Watcher API
|
// Poll Watcher API
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
var pollFns = [];
|
var pollFns = [];
|
||||||
function poll(){
|
|
||||||
foreach(pollFns, function(pollFn){ pollFn(); });
|
|
||||||
}
|
|
||||||
self.poll = poll;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a function to the list of functions that poller periodically executes
|
* @ngdoc method
|
||||||
* @return {Function} the added function
|
* @name angular.service.$browser#poll
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
*/
|
*/
|
||||||
self.addPollFn = function(/**Function*/fn){
|
self.poll = function() {
|
||||||
|
foreach(pollFns, function(pollFn){ pollFn(); });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#addPollFn
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {function} fn Poll function to add
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Adds a function to the list of functions that poller periodically executes
|
||||||
|
*
|
||||||
|
* @returns {function} the added function
|
||||||
|
*/
|
||||||
|
self.addPollFn = function(fn) {
|
||||||
pollFns.push(fn);
|
pollFns.push(fn);
|
||||||
return fn;
|
return fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the poller to run in the specified intervals, using the specified setTimeout fn and
|
* @ngdoc method
|
||||||
* kicks it off.
|
* @name angular.service.$browser#startPoller
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {number} interval How often should browser call poll functions (ms)
|
||||||
|
* @param {function} setTimeout
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Configures the poller to run in the specified intervals, using the specified
|
||||||
|
* setTimeout fn and kicks it off.
|
||||||
*/
|
*/
|
||||||
self.startPoller = function(/**number*/interval, /**Function*/setTimeout){
|
self.startPoller = function(interval, setTimeout) {
|
||||||
(function check(){
|
(function check(){
|
||||||
poll();
|
self.poll();
|
||||||
setTimeout(check, interval);
|
setTimeout(check, interval);
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
@ -103,15 +144,37 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// URL API
|
// URL API
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#setUrl
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {string} url New url
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Sets browser's url
|
||||||
|
*/
|
||||||
self.setUrl = function(url) {
|
self.setUrl = function(url) {
|
||||||
var existingURL = location.href;
|
var existingURL = location.href;
|
||||||
if (!existingURL.match(/#/)) existingURL += '#';
|
if (!existingURL.match(/#/)) existingURL += '#';
|
||||||
if (!url.match(/#/)) url += '#';
|
if (!url.match(/#/)) url += '#';
|
||||||
location.href = url;
|
location.href = url;
|
||||||
};
|
};
|
||||||
self.getUrl = function() {
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#getUrl
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Get current browser's url
|
||||||
|
*
|
||||||
|
* @returns {string} Browser's url
|
||||||
|
*/
|
||||||
|
self.getUrl = function() {
|
||||||
return location.href;
|
return location.href;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// Cookies API
|
// Cookies API
|
||||||
|
|
@ -121,19 +184,27 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
var lastCookieString = '';
|
var lastCookieString = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cookies method provides a 'private' low level access to browser cookies. It is not meant to
|
* @ngdoc method
|
||||||
* be used directly, use the $cookie service instead.
|
* @name angular.service.$browser#cookies
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {string=} name Cookie name
|
||||||
|
* @param {string=} value Cokkie value
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* The cookies method provides a 'private' low level access to browser cookies.
|
||||||
|
* It is not meant to be used directly, use the $cookie service instead.
|
||||||
*
|
*
|
||||||
* The return values vary depending on the arguments that the method was called with as follows:
|
* The return values vary depending on the arguments that the method was called with as follows:
|
||||||
* <ul><li>
|
* <ul>
|
||||||
* cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify it
|
* <li>cookies() -> hash of all cookies, this is NOT a copy of the internal state, so do not modify it</li>
|
||||||
* </li><li>
|
* <li>cookies(name, value) -> set name to value, if value is undefined delete the cookie</li>
|
||||||
* cookies(name, value) -> set name to value, if value is undefined delete the cookie
|
* <li>cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that way)</li>
|
||||||
* </li><li>
|
* </ul>
|
||||||
* cookies(name) -> the same as (name, undefined) == DELETES (no one calls it right now that way)
|
*
|
||||||
* </li></ul>
|
* @returns {Object} Hash of all cookies (if called without any parameter)
|
||||||
*/
|
*/
|
||||||
self.cookies = function (/**string*/name, /**string*/value){
|
self.cookies = function (name, value) {
|
||||||
var cookieLength, cookieArray, i, keyValue;
|
var cookieLength, cookieArray, i, keyValue;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
|
|
@ -175,7 +246,27 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
// Misc API
|
// Misc API
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
var hoverListener = noop;
|
var hoverListener = noop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#hover
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {function(Object, boolean)} listener
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Set hover listener - function that will be called when hover event occurs.
|
||||||
|
*/
|
||||||
self.hover = function(listener) { hoverListener = listener; };
|
self.hover = function(listener) { hoverListener = listener; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#bind
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Register hover function to real browser
|
||||||
|
*/
|
||||||
self.bind = function() {
|
self.bind = function() {
|
||||||
document.bind("mouseover", function(event){
|
document.bind("mouseover", function(event){
|
||||||
hoverListener(jqLite(msie ? event.srcElement : event.target), true);
|
hoverListener(jqLite(msie ? event.srcElement : event.target), true);
|
||||||
|
|
@ -189,9 +280,15 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#addCss
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {string} url Url to css file
|
||||||
|
* @description
|
||||||
* Adds a stylesheet tag to the head.
|
* Adds a stylesheet tag to the head.
|
||||||
*/
|
*/
|
||||||
self.addCss = function(/**string*/url) {
|
self.addCss = function(url) {
|
||||||
var link = jqLite(rawDocument.createElement('link'));
|
var link = jqLite(rawDocument.createElement('link'));
|
||||||
link.attr('rel', 'stylesheet');
|
link.attr('rel', 'stylesheet');
|
||||||
link.attr('type', 'text/css');
|
link.attr('type', 'text/css');
|
||||||
|
|
@ -201,9 +298,17 @@ function Browser(location, document, head, XHR, $log) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$browser#addJs
|
||||||
|
* @methodOf angular.service.$browser
|
||||||
|
*
|
||||||
|
* @param {string} url Url to js file
|
||||||
|
* @param {string=} dom_id Optional id for the script tag
|
||||||
|
*
|
||||||
|
* @description
|
||||||
* Adds a script tag to the head.
|
* Adds a script tag to the head.
|
||||||
*/
|
*/
|
||||||
self.addJs = function(/**string*/url, /**string*/dom_id) {
|
self.addJs = function(url, dom_id) {
|
||||||
var script = jqLite(rawDocument.createElement('script'));
|
var script = jqLite(rawDocument.createElement('script'));
|
||||||
script.attr('type', 'text/javascript');
|
script.attr('type', 'text/javascript');
|
||||||
script.attr('src', url);
|
script.attr('src', url);
|
||||||
|
|
|
||||||
402
src/services.js
402
src/services.js
|
|
@ -8,11 +8,64 @@ function angularServiceInject(name, fn, inject, eager) {
|
||||||
angularService(name, fn, {$inject:inject, $creation:eager});
|
angularService(name, fn, {$inject:inject, $creation:eager});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$window
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Is reference to the browser's <b>window</b> object. While <b>window</b>
|
||||||
|
* is globally available in JavaScript, it causes testability problems, because
|
||||||
|
* it is a global variable. In <b><angular/></b> we always refer to it through the
|
||||||
|
* $window service, so it may be overriden, removed or mocked for testing.
|
||||||
|
*
|
||||||
|
* All expressions are evaluated with respect to current scope so they don't
|
||||||
|
* suffer from window globality.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
<input ng:init="greeting='Hello World!'" type="text" name="greeting" />
|
||||||
|
<button ng:click="$window.alert(greeting)">ALERT</button>
|
||||||
|
*/
|
||||||
angularServiceInject("$window", bind(window, identity, window), [], EAGER_PUBLISHED);
|
angularServiceInject("$window", bind(window, identity, window), [], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$document
|
||||||
|
* @requires $window
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Reference to the browser window.document, but wrapped into angular.element().
|
||||||
|
*/
|
||||||
angularServiceInject("$document", function(window){
|
angularServiceInject("$document", function(window){
|
||||||
return jqLite(window.document);
|
return jqLite(window.document);
|
||||||
}, ['$window'], EAGER_PUBLISHED);
|
}, ['$window'], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$location
|
||||||
|
* @requires $browser
|
||||||
|
*
|
||||||
|
* @property {string} href
|
||||||
|
* @property {string} protocol
|
||||||
|
* @property {string} host
|
||||||
|
* @property {number} port
|
||||||
|
* @property {string} path
|
||||||
|
* @property {Object.<string|boolean>} search
|
||||||
|
* @property {string} hash
|
||||||
|
* @property {string} hashPath
|
||||||
|
* @property {Object.<string|boolean>} hashSearch
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Parses the browser location url and makes it available to your application.
|
||||||
|
* Any changes to the url are reflected into $location service and changes to
|
||||||
|
* $location are reflected to url.
|
||||||
|
* Notice that using browser's forward/back buttons changes the $location.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
<a href="#">clear hash</a> |
|
||||||
|
<a href="#myPath?name=misko">test hash</a><br/>
|
||||||
|
<input type='text' name="$location.hash"/>
|
||||||
|
<pre>$location = {{$location}}</pre>
|
||||||
|
*/
|
||||||
angularServiceInject("$location", function(browser) {
|
angularServiceInject("$location", function(browser) {
|
||||||
var scope = this,
|
var scope = this,
|
||||||
location = {toString:toString, update:update, updateHash: updateHash},
|
location = {toString:toString, update:update, updateHash: updateHash},
|
||||||
|
|
@ -39,6 +92,11 @@ angularServiceInject("$location", function(browser) {
|
||||||
// PUBLIC METHODS
|
// PUBLIC METHODS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$location#update
|
||||||
|
* @methodOf angular.service.$location
|
||||||
|
*
|
||||||
|
* @description
|
||||||
* Update location object
|
* Update location object
|
||||||
* Does not immediately update the browser
|
* Does not immediately update the browser
|
||||||
* Browser is updated at the end of $eval()
|
* Browser is updated at the end of $eval()
|
||||||
|
|
@ -69,7 +127,12 @@ angularServiceInject("$location", function(browser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update location hash
|
* @ngdoc method
|
||||||
|
* @name angular.service.$location#updateHash
|
||||||
|
* @methodOf angular.service.$location
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Update location hash part
|
||||||
* @see update()
|
* @see update()
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
|
|
@ -99,9 +162,12 @@ angularServiceInject("$location", function(browser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$location#toString
|
||||||
|
* @methodOf angular.service.$location
|
||||||
|
*
|
||||||
|
* @description
|
||||||
* Returns string representation - href
|
* Returns string representation - href
|
||||||
*
|
|
||||||
* @return {string} Location's href property
|
|
||||||
*/
|
*/
|
||||||
function toString() {
|
function toString() {
|
||||||
updateLocation();
|
updateLocation();
|
||||||
|
|
@ -224,23 +290,105 @@ angularServiceInject("$location", function(browser) {
|
||||||
}, ['$browser'], EAGER_PUBLISHED);
|
}, ['$browser'], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$log
|
||||||
|
* @requires $window
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Is simple service for logging. Default implementation writes the message
|
||||||
|
* into the browser's console (if present).
|
||||||
|
*
|
||||||
|
* This is useful for debugging.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
<p>Reload this page with open console, enter text and hit the log button...</p>
|
||||||
|
Message:
|
||||||
|
<input type="text" name="message" value="Hello World!"/>
|
||||||
|
<button ng:click="$log.log(message)">log</button>
|
||||||
|
<button ng:click="$log.warn(message)">warn</button>
|
||||||
|
<button ng:click="$log.info(message)">info</button>
|
||||||
|
<button ng:click="$log.error(message)">error</button>
|
||||||
|
*/
|
||||||
angularServiceInject("$log", function($window){
|
angularServiceInject("$log", function($window){
|
||||||
var console = $window.console || {log: noop, warn: noop, info: noop, error: noop},
|
var console = $window.console || {log: noop, warn: noop, info: noop, error: noop},
|
||||||
log = console.log || noop;
|
log = console.log || noop;
|
||||||
return {
|
return {
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$log#log
|
||||||
|
* @methodOf angular.service.$log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Write a log message
|
||||||
|
*/
|
||||||
log: bind(console, log),
|
log: bind(console, log),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$log#warn
|
||||||
|
* @methodOf angular.service.$log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Write a warning message
|
||||||
|
*/
|
||||||
warn: bind(console, console.warn || log),
|
warn: bind(console, console.warn || log),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$log#info
|
||||||
|
* @methodOf angular.service.$log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Write an information message
|
||||||
|
*/
|
||||||
info: bind(console, console.info || log),
|
info: bind(console, console.info || log),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$log#error
|
||||||
|
* @methodOf angular.service.$log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Write an error message
|
||||||
|
*/
|
||||||
error: bind(console, console.error || log)
|
error: bind(console, console.error || log)
|
||||||
};
|
};
|
||||||
}, ['$window'], EAGER_PUBLISHED);
|
}, ['$window'], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$exceptionHandler
|
||||||
|
* @requires $log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Any uncaught exception in <angular/> is delegated to this service.
|
||||||
|
* The default implementation simply delegates to $log.error which logs it into
|
||||||
|
* the browser console.
|
||||||
|
*
|
||||||
|
* When unit testing it is useful to have uncaught exceptions propagate
|
||||||
|
* to the test so the test will fail rather than silently log the exception
|
||||||
|
* to the browser console. For this purpose you can override this service with
|
||||||
|
* a simple rethrow.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
angularServiceInject('$exceptionHandler', function($log){
|
angularServiceInject('$exceptionHandler', function($log){
|
||||||
return function(e) {
|
return function(e) {
|
||||||
$log.error(e);
|
$log.error(e);
|
||||||
};
|
};
|
||||||
}, ['$log'], EAGER_PUBLISHED);
|
}, ['$log'], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$hover
|
||||||
|
* @requires $browser
|
||||||
|
* @requires $document
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
angularServiceInject("$hover", function(browser, document) {
|
angularServiceInject("$hover", function(browser, document) {
|
||||||
var tooltip, self = this, error, width = 300, arrowWidth = 10, body = jqLite(document[0].body);
|
var tooltip, self = this, error, width = 300, arrowWidth = 10, body = jqLite(document[0].body);
|
||||||
browser.hover(function(element, show){
|
browser.hover(function(element, show){
|
||||||
|
|
@ -287,9 +435,15 @@ angularServiceInject("$hover", function(browser, document) {
|
||||||
});
|
});
|
||||||
}, ['$browser', '$document'], EAGER);
|
}, ['$browser', '$document'], EAGER);
|
||||||
|
|
||||||
|
/**
|
||||||
/* Keeps references to all invalid widgets found during validation. Can be queried to find if there
|
* @ngdoc service
|
||||||
* are invalid widgets currently displayed
|
* @name angular.service.$invalidWidgets
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Keeps references to all invalid widgets found during validation.
|
||||||
|
* Can be queried to find whether there are any invalid widgets currently displayed.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
*/
|
*/
|
||||||
angularServiceInject("$invalidWidgets", function(){
|
angularServiceInject("$invalidWidgets", function(){
|
||||||
var invalidWidgets = [];
|
var invalidWidgets = [];
|
||||||
|
|
@ -373,7 +527,59 @@ function switchRouteMatcher(on, when, dstName) {
|
||||||
return match ? dst : _null;
|
return match ? dst : _null;
|
||||||
}
|
}
|
||||||
|
|
||||||
angularServiceInject('$route', function(location){
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$route
|
||||||
|
* @requires $location
|
||||||
|
*
|
||||||
|
* @property {Object} current Name of the current route
|
||||||
|
* @property {Array.<Object>} routes List of configured routes
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Watches $location.hashPath and tries to map the hash to an existing route
|
||||||
|
* definition. It is used for deep-linking URLs to controllers and views (HTML partials).
|
||||||
|
*
|
||||||
|
* $route is typically used in conjunction with ng:include widget.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
<p>
|
||||||
|
This example shows how changing the URL hash causes the <tt>$route</tt>
|
||||||
|
to match a route against the URL, and the <tt>[[ng:include]]</tt> pulls in the partial.
|
||||||
|
Try changing the URL in the input box to see changes.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
angular.service('myApp', function($route) {
|
||||||
|
$route.when('/Book/:bookId', {template:'rsrc/book.html', controller:BookCntl});
|
||||||
|
$route.when('/Book/:bookId/ch/:chapterId', {template:'rsrc/chapter.html', controller:ChapterCntl});
|
||||||
|
$route.onChange(function() {
|
||||||
|
$route.current.scope.params = $route.current.params;
|
||||||
|
});
|
||||||
|
}, {$inject: ['$route']});
|
||||||
|
|
||||||
|
function BookCntl() {
|
||||||
|
this.name = "BookCntl";
|
||||||
|
}
|
||||||
|
|
||||||
|
function ChapterCntl() {
|
||||||
|
this.name = "ChapterCntl";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
Chose:
|
||||||
|
<a href="#/Book/Moby">Moby</a> |
|
||||||
|
<a href="#/Book/Moby/ch/1">Moby: Ch1</a> |
|
||||||
|
<a href="#/Book/Gatsby">Gatsby</a> |
|
||||||
|
<a href="#/Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a><br/>
|
||||||
|
<input type="text" name="$location.hashPath" size="80" />
|
||||||
|
<pre>$location={{$location}}</pre>
|
||||||
|
<pre>$route.current.template={{$route.current.template}}</pre>
|
||||||
|
<pre>$route.current.params={{$route.current.params}}</pre>
|
||||||
|
<pre>$route.current.scope.name={{$route.current.scope.name}}</pre>
|
||||||
|
<hr/>
|
||||||
|
<ng:include src="$route.current.template" scope="$route.current.scope"/>
|
||||||
|
*/
|
||||||
|
angularServiceInject('$route', function(location) {
|
||||||
var routes = {},
|
var routes = {},
|
||||||
onChange = [],
|
onChange = [],
|
||||||
matcher = switchRouteMatcher,
|
matcher = switchRouteMatcher,
|
||||||
|
|
@ -381,8 +587,32 @@ angularServiceInject('$route', function(location){
|
||||||
dirty = 0,
|
dirty = 0,
|
||||||
$route = {
|
$route = {
|
||||||
routes: routes,
|
routes: routes,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$route#onChange
|
||||||
|
* @methodOf angular.service.$route
|
||||||
|
*
|
||||||
|
* @param {function} fn Function that will be called on route change
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Register a handler function that will be called when route changes
|
||||||
|
*/
|
||||||
onChange: bind(onChange, onChange.push),
|
onChange: bind(onChange, onChange.push),
|
||||||
when:function (path, params){
|
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$route#when
|
||||||
|
* @methodOf angular.service.$route
|
||||||
|
*
|
||||||
|
* @param {string} path Route path (matched against $location.hash)
|
||||||
|
* @param {Object} params
|
||||||
|
* @returns {Object} route object
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Add new route
|
||||||
|
*/
|
||||||
|
when:function (path, params) {
|
||||||
if (angular.isUndefined(path)) return routes;
|
if (angular.isUndefined(path)) return routes;
|
||||||
var route = routes[path];
|
var route = routes[path];
|
||||||
if (!route) route = routes[path] = {};
|
if (!route) route = routes[path] = {};
|
||||||
|
|
@ -415,6 +645,17 @@ angularServiceInject('$route', function(location){
|
||||||
return $route;
|
return $route;
|
||||||
}, ['$location'], EAGER_PUBLISHED);
|
}, ['$location'], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$xhr
|
||||||
|
* @requires $browser
|
||||||
|
* @requires $error
|
||||||
|
* @requires $log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
angularServiceInject('$xhr', function($browser, $error, $log){
|
angularServiceInject('$xhr', function($browser, $error, $log){
|
||||||
var self = this;
|
var self = this;
|
||||||
return function(method, url, post, callback){
|
return function(method, url, post, callback){
|
||||||
|
|
@ -446,12 +687,32 @@ angularServiceInject('$xhr', function($browser, $error, $log){
|
||||||
};
|
};
|
||||||
}, ['$browser', '$xhr.error', '$log']);
|
}, ['$browser', '$xhr.error', '$log']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$xhr.error
|
||||||
|
* @requires $log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
angularServiceInject('$xhr.error', function($log){
|
angularServiceInject('$xhr.error', function($log){
|
||||||
return function(request, response){
|
return function(request, response){
|
||||||
$log.error('ERROR: XHR: ' + request.url, request, response);
|
$log.error('ERROR: XHR: ' + request.url, request, response);
|
||||||
};
|
};
|
||||||
}, ['$log']);
|
}, ['$log']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$xhr.bulk
|
||||||
|
* @requires $xhr
|
||||||
|
* @requires $xhr.error
|
||||||
|
* @requires $log
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
angularServiceInject('$xhr.bulk', function($xhr, $error, $log){
|
angularServiceInject('$xhr.bulk', function($xhr, $error, $log){
|
||||||
var requests = [],
|
var requests = [],
|
||||||
scope = this;
|
scope = this;
|
||||||
|
|
@ -502,6 +763,15 @@ angularServiceInject('$xhr.bulk', function($xhr, $error, $log){
|
||||||
return bulkXHR;
|
return bulkXHR;
|
||||||
}, ['$xhr', '$xhr.error', '$log']);
|
}, ['$xhr', '$xhr.error', '$log']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$xhr.cache
|
||||||
|
* @requires $xhr
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
angularServiceInject('$xhr.cache', function($xhr){
|
angularServiceInject('$xhr.cache', function($xhr){
|
||||||
var inflight = {}, self = this;
|
var inflight = {}, self = this;
|
||||||
function cache(method, url, post, callback, verifyCache){
|
function cache(method, url, post, callback, verifyCache){
|
||||||
|
|
@ -546,18 +816,74 @@ angularServiceInject('$xhr.cache', function($xhr){
|
||||||
return cache;
|
return cache;
|
||||||
}, ['$xhr.bulk']);
|
}, ['$xhr.bulk']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc service
|
||||||
|
* @name angular.service.$resource
|
||||||
|
* @requires $xhr
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Is a factory which creates a resource object which lets you interact with
|
||||||
|
* <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">RESTful</a>
|
||||||
|
* server-side data sources.
|
||||||
|
* Resource object has action methods which provide high-level behaviors without
|
||||||
|
* the need to interact with the low level $xhr or XMLHttpRequest().
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
<script>
|
||||||
|
function BuzzController($resource) {
|
||||||
|
this.Activity = $resource(
|
||||||
|
'https://www.googleapis.com/buzz/v1/activities/:userId/:visibility/:activityId/:comments',
|
||||||
|
{alt:'json', callback:'JSON_CALLBACK'},
|
||||||
|
{get:{method:'JSON', params:{visibility:'@self'}}, replies: {method:'JSON', params:{visibility:'@self', comments:'@comments'}}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuzzController.prototype = {
|
||||||
|
fetch: function() {
|
||||||
|
this.activities = this.Activity.get({userId:this.userId});
|
||||||
|
},
|
||||||
|
expandReplies: function(activity) {
|
||||||
|
activity.replies = this.Activity.replies({userId:this.userId, activityId:activity.id});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BuzzController.$inject = ['$resource'];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div ng:controller="BuzzController">
|
||||||
|
<input name="userId" value="googlebuzz"/>
|
||||||
|
<button ng:click="fetch()">fetch</button>
|
||||||
|
<hr/>
|
||||||
|
<div ng:repeat="item in activities.data.items">
|
||||||
|
<h1 style="font-size: 15px;">
|
||||||
|
<img src="{{item.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||||
|
<a href="{{item.actor.profileUrl}}">{{item.actor.name}}</a>
|
||||||
|
<a href="#" ng:click="expandReplies(item)" style="float: right;">Expand replies: {{item.links.replies[0].count}}</a>
|
||||||
|
</h1>
|
||||||
|
{{item.object.content | html}}
|
||||||
|
<div ng:repeat="reply in item.replies.data.items" style="margin-left: 20px;">
|
||||||
|
<img src="{{reply.actor.thumbnailUrl}}" style="max-height:30px;max-width:30px;"/>
|
||||||
|
<a href="{{reply.actor.profileUrl}}">{{reply.actor.name}}</a>: {{reply.content | html}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
*/
|
||||||
angularServiceInject('$resource', function($xhr){
|
angularServiceInject('$resource', function($xhr){
|
||||||
var resource = new ResourceFactory($xhr);
|
var resource = new ResourceFactory($xhr);
|
||||||
return bind(resource, resource.route);
|
return bind(resource, resource.route);
|
||||||
}, ['$xhr.cache']);
|
}, ['$xhr.cache']);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $cookies service provides read/write access to the browser cookies. Currently only session
|
* @ngdoc service
|
||||||
* cookies are supported.
|
* @name angular.service.$cookies
|
||||||
*
|
* @requires $browser
|
||||||
* Only a simple Object is exposed and by adding or removing properties to/from this object, new
|
*
|
||||||
* cookies are created or deleted from the browser at the end of the current eval.
|
* @description
|
||||||
|
* Provides read/write access to browser's cookies.
|
||||||
|
*
|
||||||
|
* Only a simple Object is exposed and by adding or removing properties to/from
|
||||||
|
* this object, new cookies are created/deleted at the end of current $eval.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
*/
|
*/
|
||||||
angularServiceInject('$cookies', function($browser) {
|
angularServiceInject('$cookies', function($browser) {
|
||||||
var rootScope = this,
|
var rootScope = this,
|
||||||
|
|
@ -630,23 +956,61 @@ angularServiceInject('$cookies', function($browser) {
|
||||||
}
|
}
|
||||||
}, ['$browser'], EAGER_PUBLISHED);
|
}, ['$browser'], EAGER_PUBLISHED);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $cookieStore provides a key-value (string-object) storage that is backed by session cookies.
|
* @ngdoc service
|
||||||
* Objects put or retrieved from this storage are automatically serialized or deserialized.
|
* @name angular.service.$cookieStore
|
||||||
|
* @requires $cookies
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Provides a key-value (string-object) storage, that is backed by session cookies.
|
||||||
|
* Objects put or retrieved from this storage are automatically serialized or
|
||||||
|
* deserialized by angular's toJson/fromJson.
|
||||||
|
* @example
|
||||||
*/
|
*/
|
||||||
angularServiceInject('$cookieStore', function($store) {
|
angularServiceInject('$cookieStore', function($store) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$cookieStore#get
|
||||||
|
* @methodOf angular.service.$cookieStore
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Returns the value of given cookie key
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
* @returns Cookie value
|
||||||
|
*/
|
||||||
get: function(/**string*/key) {
|
get: function(/**string*/key) {
|
||||||
return fromJson($store[key]);
|
return fromJson($store[key]);
|
||||||
},
|
},
|
||||||
|
|
||||||
put: function(/**string*/key, /**Object*/value) {
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$cookieStore#put
|
||||||
|
* @methodOf angular.service.$cookieStore
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Sets a value for given cookie key
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
* @param {Object} value
|
||||||
|
*/
|
||||||
|
put: function(key, value) {
|
||||||
$store[key] = toJson(value);
|
$store[key] = toJson(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function(/**string*/key) {
|
/**
|
||||||
|
* @ngdoc method
|
||||||
|
* @name angular.service.$cookieStore#remove
|
||||||
|
* @methodOf angular.service.$cookieStore
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Remove given cookie
|
||||||
|
*
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
remove: function(key) {
|
||||||
delete $store[key];
|
delete $store[key];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue