diff --git a/.gitignore b/.gitignore index 2ee1a2cde2a7..6b010da1206c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ angular.js.tmproj angular.xcodeproj .idea .agignore +libpeerconnection.log diff --git a/.travis.yml b/.travis.yml index 92da3ed94641..cce2331846b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,8 @@ before_script: - export SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev` - ./lib/sauce/sauce_connect_setup.sh - npm install -g grunt-cli - - grunt package - - grunt webserver > /dev/null & + - grunt ci-checks package - ./lib/sauce/sauce_connect_block.sh script: - - grunt test --reporters dots --browsers SL_Chrome + - grunt parallel:travis --reporters dots --browsers SL_Chrome diff --git a/Gruntfile.js b/Gruntfile.js index 1d5f35426d2b..de0d6c72c8cd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -8,7 +8,10 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-contrib-compress'); grunt.loadNpmTasks('grunt-contrib-jasmine-node'); + grunt.loadNpmTasks('grunt-ddescribe-iit'); + grunt.loadNpmTasks('grunt-merge-conflict'); grunt.loadNpmTasks('grunt-shell'); + grunt.loadNpmTasks('grunt-parallel'); grunt.loadTasks('lib/grunt'); var NG_VERSION = util.getVersion(); @@ -23,6 +26,21 @@ module.exports = function(grunt) { grunt.initConfig({ NG_VERSION: NG_VERSION, + parallel: { + travis: { + options: { + stream: true + }, + tasks: [ + util.parallelTask('test:docs'), + util.parallelTask('test:modules'), + util.parallelTask('test:jquery'), + util.parallelTask('test:jqlite'), + util.parallelTask('test:e2e') + ] + } + }, + connect: { devserver: { options: { @@ -42,7 +60,24 @@ module.exports = function(grunt) { } } }, - testserver: {} + testserver: { + options: { + middleware: function(connect, options){ + return [ + function(req, resp, next) { + // cache get requests to speed up tests on travis + if (req.method === 'GET') { + resp.setHeader('Cache-control', 'public, max-age=3600'); + } + + next(); + }, + connect.favicon('images/favicon.ico'), + connect.static(options.base) + ]; + } + } + } }, @@ -161,6 +196,22 @@ module.exports = function(grunt) { run: { spec: 'docs/spec' } }, + "ddescribe-iit": { + files: [ + 'test/**/*.js', + '!test/ngScenario/DescribeSpec.js' + ] + }, + + "merge-conflict": { + files: [ + 'src/**/*', + 'test/**/*', + 'docs/**/*', + 'css/**/*' + ] + }, + copy: { i18n: { files: [ @@ -191,6 +242,7 @@ module.exports = function(grunt) { grunt.registerTask('minify', ['shell:bower','clean', 'build', 'minall']); grunt.registerTask('test:e2e', ['connect:testserver', 'test:end2end']); grunt.registerTask('webserver', ['connect:devserver']); - grunt.registerTask('package', ['shell:bower','clean', 'buildall', 'minall', 'docs', 'copy', 'write', 'compress']); + grunt.registerTask('package', ['shell:bower','clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']); + grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict']); grunt.registerTask('default', ['package']); }; diff --git a/angularFiles.js b/angularFiles.js index a9d636b115f2..b93283a7cc21 100755 --- a/angularFiles.js +++ b/angularFiles.js @@ -30,6 +30,7 @@ angularFiles = { 'src/ng/httpBackend.js', 'src/ng/locale.js', 'src/ng/timeout.js', + 'src/ng/urlUtils.js', 'src/ng/filter.js', 'src/ng/filter/filter.js', diff --git a/bower.json b/bower.json index 8bdcc8389d8d..ebbd67978d95 100644 --- a/bower.json +++ b/bower.json @@ -6,6 +6,7 @@ "google-code-prettify": "1.0.0", "components-font-awesome": "3.1.0", "bootstrap": "https://raw.github.com/twitter/bootstrap/v2.0.2/docs/assets/bootstrap.zip", - "closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip" + "closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip", + "ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.1.1/assets/ng-closure-runner.zip" } } diff --git a/css/angular.css b/css/angular.css index 44513c652e6f..0cd9d7dc51fb 100644 --- a/css/angular.css +++ b/css/angular.css @@ -2,7 +2,7 @@ [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { - display: none; + display: none !important; } ng\:form { diff --git a/docs/component-spec/annotationsSpec.js b/docs/component-spec/annotationsSpec.js index b4c8cd9decbd..29cb9c53ef99 100644 --- a/docs/component-spec/annotationsSpec.js +++ b/docs/component-spec/annotationsSpec.js @@ -91,13 +91,21 @@ describe('Docs Annotations', function() { } }); }); - inject(function($rootScope, $compile, $templateCache) { + inject(function($rootScope, $compile, $templateCache, $rootElement, $animator) { + $animator.enabled(true); url = '/page.html'; $scope = $rootScope.$new(); parent = angular.element('
'); element = angular.element(''); - body.append(parent); + + //we're injecting the element to the $rootElement since the changes in + //$animator only detect and perform animations if the root element has + //animations enabled. If the element is not apart of the DOM + //then animations are skipped. parent.append(element); + $rootElement.append(parent); + body.append($rootElement); + $compile(parent)($scope); $scope.$apply(); }); diff --git a/docs/content/guide/dev_guide.e2e-testing.ngdoc b/docs/content/guide/dev_guide.e2e-testing.ngdoc index 8d297cff1b64..243517adf692 100644 --- a/docs/content/guide/dev_guide.e2e-testing.ngdoc +++ b/docs/content/guide/dev_guide.e2e-testing.ngdoc @@ -136,7 +136,7 @@ the given jQuery `selector`. The `label` is used for test output. ## select(name).option(value) Picks the option with the given `value` on the select with the given `name`. -## select(name).option(value1, value2...) +## select(name).options(value1, value2...) Picks the options with the given `values` on the multi select with the given `name`. ## element(selector, label).count() diff --git a/docs/content/guide/dev_guide.services.$location.ngdoc b/docs/content/guide/dev_guide.services.$location.ngdoc index 99a75f87a547..fdfa2b0b5fa7 100644 --- a/docs/content/guide/dev_guide.services.$location.ngdoc +++ b/docs/content/guide/dev_guide.services.$location.ngdoc @@ -212,7 +212,7 @@ In this mode, `$location` uses Hashbang URLs in all browsers. it('should show example', inject( function($locationProvider) { $locationProvider.html5Mode(false); - $locationProvider.hashPrefix = '!'; + $locationProvider.hashPrefix('!'); }, function($location) { // open http://host.com/base/index.html#!/a @@ -261,7 +261,7 @@ having to worry about whether the browser displaying your app supports the histo it('should show example', inject( function($locationProvider) { $locationProvider.html5Mode(true); - $locationProvider.hashPrefix = '!'; + $locationProvider.hashPrefix('!'); }, function($location) { // in browser with HTML5 history support: diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc index 2ddbec91603b..fbfed468cf38 100644 --- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc +++ b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc @@ -57,6 +57,7 @@ myController.$inject = ['$scope','notify'];Let's try this simple notify service, injected into the controller...
+(you have to click 3 times to see an alert)
- var MyController = function($scope, dep1, dep2) {
+ someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
...
$scope.aMethod = function() {
...
}
- }
- MyController.$inject = ['$scope', 'dep1', 'dep2'];
+ ...
+ }]);
+This avoids the creation of global functions for controllers and also protects against minification.
+
### Factory methods
diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc
index 7e0860e09fe6..57cdebfe058e 100644
--- a/docs/content/guide/directive.ngdoc
+++ b/docs/content/guide/directive.ngdoc
@@ -269,7 +269,8 @@ Here's an example directive declared with a Directive Definition Object:
transclude: false,
restrict: 'A',
scope: false,
- controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
+ controller: ["$scope", "$element", "$attrs", "$transclude", "otherInjectables",
+ function($scope, $element, $attrs, $transclude, otherInjectables) { ... }],
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) { ... },
diff --git a/docs/content/guide/overview.ngdoc b/docs/content/guide/overview.ngdoc
index a8e806cd5f27..8e555bf26541 100644
--- a/docs/content/guide/overview.ngdoc
+++ b/docs/content/guide/overview.ngdoc
@@ -134,7 +134,7 @@ These input widgets look normal enough, but consider these points:
Model-View-Controller design pattern.
* Note that the HTML widget {@link api/ng.directive:input input}
has special powers. The input invalidates itself by turning red when you enter invalid data or
- leave the the input fields blank. These new widget behaviors make it easier to implement field
+ leave the input fields blank. These new widget behaviors make it easier to implement field
validation common in CRUD applications.
And finally, the mysterious `{{ double curly braces }}`:
diff --git a/docs/content/misc/contribute.ngdoc b/docs/content/misc/contribute.ngdoc
index 8b6a7627e30f..7cae67c36030 100644
--- a/docs/content/misc/contribute.ngdoc
+++ b/docs/content/misc/contribute.ngdoc
@@ -256,31 +256,27 @@ To create and submit a change:
[print, sign and one of scan+email, fax or mail the form](http://code.google.com/legal/corporate-cla-v1.0.html).
-2. Create a new branch off the master for your changes:
+2. Create and checkout a new branch off the master branch for your changes:
- git branch my-fix-branch
+ git checkout -b my-fix-branch master
-3. Check out the branch:
+3. Create your patch, make sure to have plenty of tests (that pass).
- git checkout my-fix-branch
-
-4. Create your patch, make sure to have plenty of tests (that pass).
-
-5. Commit your changes and create a descriptive commit message (the commit message is used to generate release notes,
+4. Commit your changes and create a descriptive commit message (the commit message is used to generate release notes,
please check out our
[commit message conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#)
and our commit message presubmit hook `validate-commit-msg.js`):
git commit -a
-6. Push your branch to Github:
+5. Push your branch to Github:
git push origin my-fix-branch
-7. In Github, send a pull request to `angular:master`.
+6. In Github, send a pull request to `angular:master`.
-8. When the patch is reviewed and merged, delete your branch and pull yours — and other — changes
+7. When the patch is reviewed and merged, delete your branch and pull yours — and other — changes
from the main (upstream) repository:
1. To delete the branch in Github, run:
diff --git a/docs/content/tutorial/index.ngdoc b/docs/content/tutorial/index.ngdoc
index 253906217ef5..3c0eebf821ea 100644
--- a/docs/content/tutorial/index.ngdoc
+++ b/docs/content/tutorial/index.ngdoc
@@ -1,117 +1,115 @@
@ngdoc overview
-@name Tutorial
+@name Tutorial: Index
@description
-
-
- Work through the tutorial to see how Angular makes browsers smarter — without the use of extensions
- or plug-ins. As you work through the tutorial, you will:
-
- * See examples of how to use client-side data binding and dependency injection to build dynamic
- views of data that change immediately in response to user actions.
- * See how Angular creates listeners on your data without the need for DOM manipulation.
- * Learn a better, easier way to test your web apps.
- * Learn how to use Angular services to make common web tasks, such as getting data into your app,
- easier.
-
- And all of this works in any browser without modification to the browser!
-
- When you finish the tutorial you will be able to:
-
- * Create a dynamic application that works in any browser.
- * Define the differences between Angular and common JavaScript frameworks.
- * Understand how data binding works in AngularJS.
- * Use the angular-seed project to quickly boot-strap your own projects.
- * Create and run tests.
- * Identify resources for learning more about AngularJS.
-
- The tutorial guides you through the entire process of building a simple application, including
- writing and running unit and end-to-end tests. Experiments at the end of each step provide
- suggestions for you to learn more about AngularJS and the application you are building.
-
- You can go through the whole tutorial in a couple of hours or you may want to spend a pleasant day
- really digging into it. If you're looking for a shorter introduction to AngularJS, check out the
- {@link misc/started Getting Started} document.
-
-
-
-
-
-
-
- # Working with the code
-
- You can follow this tutorial and hack on the code in either the Mac/Linux or the Windows
- environment. The tutorial relies on the use of Git versioning system for source code management.
- You don't need to know anything about Git to follow the tutorial. Select one of the tabs below
- and follow the instructions for setting up your computer.
-
- You will need Node.js and Karma to run unit tests, so please verify that you have
+A great way to get introduced to AngularJS is to work through this tutorial, which walks you through
+the construction of an AngularJS web app. The app you will build is a catalog that displays a list
+of Android devices, lets you filter the list to see only devices that interest you, and then view
+details for any device.
+
+
+
+Work through the tutorial to see how Angular makes browsers smarter — without the use of extensions
+or plug-ins. As you work through the tutorial, you will:
+
+* See examples of how to use client-side data binding and dependency injection to build dynamic
+views of data that change immediately in response to user actions.
+* See how Angular creates listeners on your data without the need for DOM manipulation.
+* Learn a better, easier way to test your web apps.
+* Learn how to use Angular services to make common web tasks, such as getting data into your app,
+easier.
+
+And all of this works in any browser without modification to the browser!
+
+When you finish the tutorial you will be able to:
+
+* Create a dynamic application that works in any browser.
+* Define the differences between Angular and common JavaScript frameworks.
+* Understand how data binding works in AngularJS.
+* Use the angular-seed project to quickly boot-strap your own projects.
+* Create and run tests.
+* Identify resources for learning more about AngularJS.
+
+The tutorial guides you through the entire process of building a simple application, including
+writing and running unit and end-to-end tests. Experiments at the end of each step provide
+suggestions for you to learn more about AngularJS and the application you are building.
+
+You can go through the whole tutorial in a couple of hours or you may want to spend a pleasant day
+really digging into it. If you're looking for a shorter introduction to AngularJS, check out the
+{@link misc/started Getting Started} document.
+
+
+
+
+
+
+
+# Working with the code
+
+You can follow this tutorial and hack on the code in either the Mac/Linux or the Windows
+environment. The tutorial relies on the use of Git versioning system for source code management.
+You don't need to know anything about Git to follow the tutorial. Select one of the tabs below
+and follow the instructions for setting up your computer.
+
+
You will need Node.js and Karma to run unit tests, so please verify that you have
+ Node.js v0.8 or better installed
+ and that the node executable is on your PATH by running the following
+ command in a terminal window:
node --version+
Additionally install Karma if you + don't have it already:
+npm install -g karma+
You'll also need Git, which you can get from + the Git site.
Clone the angular-phonecat repository located at Github by running the following command:
+git clone git://github.com/angular/angular-phonecat.git+
This command creates the angular-phonecat directory in your current
+directory.
Change your current directory to angular-phonecat:
cd angular-phonecat+
The tutorial instructions assume you are running all commands from the angular-phonecat
+directory.
You will need an http server running on your system. Mac and Linux machines typically
+have Apache pre-installed, but If you don't already have one installed, you can use node
+to run scripts/web-server.js, a simple bundled http server.
You will need Node.js and Karma to run unit tests, so please verify that you have
Node.js v0.8 or better installed
and that the node executable is on your PATH by running the following
command in a terminal window:
node --version
Additionally install Karma if you - don't have it already:
+ don't have it already:npm install -g karma-
You'll also need Git, which you can get from - the Git site.
Clone the angular-phonecat repository located at Github by running the following command:
-git clone git://github.com/angular/angular-phonecat.git-
This command creates the angular-phonecat directory in your current
- directory.
Change your current directory to angular-phonecat:
cd angular-phonecat-
The tutorial instructions assume you are running all commands from the angular-phonecat
- directory.
You will need an http server running on your system. Mac and Linux machines typically
- have Apache pre-installed, but If you don't already have one installed, you can use node
- to run scripts/web-server.js, a simple bundled http server.
You will need Node.js and Karma to run unit tests, so please verify that you have
- Node.js v0.8 or better installed
- and that the node executable is on your PATH by running the following
- command in a terminal window:
node --version-
Additionally install Karma if you - don't have it already:
-npm install -g karma-
You'll also need Git, which you can get from - the Git site.
Clone the angular-phonecat repository located at Github by running the following command:
-git clone git://github.com/angular/angular-phonecat.git-
This command creates the angular-phonecat directory in your current directory.
Change your current directory to angular-phonecat:
cd angular-phonecat-
The tutorial instructions assume you are running all commands from the angular-phonecat
- directory.
You should run all git commands from Git bash.
Other commands like test.bat or e2e-test.bat should be
- executed from the Windows command line.
You need an http server running on your system, but if you don't already have one
- already installed, you can use node to run scripts\web-server.js, a simple
- bundled http server.
You'll also need Git, which you can get from + the Git site.
Clone the angular-phonecat repository located at Github by running the following command:
+git clone git://github.com/angular/angular-phonecat.git+
This command creates the angular-phonecat directory in your current directory.
Change your current directory to angular-phonecat:
cd angular-phonecat+
The tutorial instructions assume you are running all commands from the angular-phonecat
+directory.
You should run all git commands from Git bash.
Other commands like test.bat or e2e-test.bat should be
+executed from the Windows command line.
You need an http server running on your system, but if you don't already have one
+already installed, you can use node to run scripts\web-server.js, a simple
+bundled http server.
short
', type:'*', optional:false, 'default':undefined}, - {name:'b', description:'med
', type:'Type', optional:false, 'default':undefined}, - {name:'c', description:'long\nline
', type:'Class', optional:true, 'default':'2'}, - {name:'d', description:'fn with optional arguments
', + {name:'a', description:'short
med
long\nline
fn with optional arguments
text bold.
' + description: 'text bold.
, but escape the html escape the content', function() {
expect(new Doc().markdown('bah x\n\nangular.k\n
\n asdf x')).
toEqual(
- 'bah x\n' +
+ '
bah x\n' +
'
\n' +
'<b>angular</b>.k\n' +
'\n' +
- ' asdf x');
+ ' asdf x');
+ });
+
+ it('should wrap everything inside a container tag', function() {
+ var doc = new Doc('@name superman').parse();
+ var content = doc.markdown('hello');
+
+ expect(content).toMatch('hello
');
+ });
+
+ it('should use the content before a colon as the name prefix for the className of the tag container', function() {
+ var doc = new Doc('@name super: man').parse();
+ var content = doc.markdown('hello');
+
+ expect(content).toMatch('hello
');
});
it('should replace text between two tags', function() {
@@ -162,11 +176,11 @@ describe('ngdoc', function() {
'\ngit bla bla\n\n' +
'')).toEqual(
- 'before
\n' +
+ 'before
\n' +
'\n' +
'git bla bla\n' +
'\n' +
- '');
+ '');
});
it('should unindent text before processing based on the second line', function() {
@@ -290,7 +304,7 @@ describe('ngdoc', function() {
name : 'number',
optional: false,
'default' : undefined,
- description : 'Number \nto format.
' }]);
+ description : 'Number \nto format.
' }]);
});
it('should parse with default and optional', function() {
@@ -301,7 +315,7 @@ describe('ngdoc', function() {
name : 'fractionSize',
optional: true,
'default' : '2',
- description : 'desc
' }]);
+ description : 'desc
' }]);
});
});
@@ -311,8 +325,8 @@ describe('ngdoc', function() {
doc.ngdoc = 'service';
doc.parse();
expect(doc.requires).toEqual([
- {name:'$service', text:'for \nA
'},
- {name:'$another', text:'for B
'}]);
+ {name:'$service', text:'for \nA
'},
+ {name:'$another', text:'for B
'}]);
expect(doc.html()).toContain('$service');
expect(doc.html()).toContain('$another');
expect(doc.html()).toContain('for \nA
');
@@ -364,7 +378,7 @@ describe('ngdoc', function() {
var doc = new Doc("@name a\n@property {string} name desc rip tion");
doc.parse();
expect(doc.properties[0].name).toEqual('name');
- expect(doc.properties[0].description).toEqual('desc rip tion
');
+ expect(doc.properties[0].description).toEqual('desc rip tion
');
});
it('should parse @property with type and description both', function() {
@@ -372,7 +386,7 @@ describe('ngdoc', function() {
doc.parse();
expect(doc.properties[0].name).toEqual('name');
expect(doc.properties[0].type).toEqual('bool');
- expect(doc.properties[0].description).toEqual('desc rip tion
');
+ expect(doc.properties[0].description).toEqual('desc rip tion
');
});
});
@@ -395,26 +409,26 @@ describe('ngdoc', function() {
it('should parse @returns with type and description', function() {
var doc = new Doc("@name a\n@returns {string} descrip tion");
doc.parse();
- expect(doc.returns).toEqual({type: 'string', description: 'descrip tion
'});
+ expect(doc.returns).toEqual({type: 'string', description: 'descrip tion
'});
});
it('should parse @returns with complex type and description', function() {
var doc = new Doc("@name a\n@returns {function(string, number=)} description");
doc.parse();
- expect(doc.returns).toEqual({type: 'function(string, number=)', description: 'description
'});
+ expect(doc.returns).toEqual({type: 'function(string, number=)', description: 'description
'});
});
it('should transform description of @returns with markdown', function() {
var doc = new Doc("@name a\n@returns {string} descrip *tion*");
doc.parse();
- expect(doc.returns).toEqual({type: 'string', description: 'descrip tion
'});
+ expect(doc.returns).toEqual({type: 'string', description: 'descrip tion
'});
});
it('should support multiline content', function() {
var doc = new Doc("@name a\n@returns {string} description\n new line\n another line");
doc.parse();
expect(doc.returns).
- toEqual({type: 'string', description: 'description\nnew line\nanother line
'});
+ toEqual({type: 'string', description: 'description\nnew line\nanother line
'});
});
});
@@ -423,18 +437,18 @@ describe('ngdoc', function() {
var doc = new Doc("@name a\n@description abc
");
doc.parse();
expect(doc.description).
- toBe('<b>abc</b>
');
+ toBe('<b>abc</b>
');
});
it('should support multiple pre blocks', function() {
var doc = new Doc("@name a\n@description foo \nabc
\n#bah\nfoo \ncba
");
doc.parse();
expect(doc.description).
- toBe('foo \n' +
+ toBe('
foo \n' +
'
abc
\n\n' +
'bah
\n\n' +
'foo \n' +
- '
cba
');
+ 'cba
');
});
@@ -477,7 +491,7 @@ describe('ngdoc', function() {
it('should not remove {{}}', function() {
var doc = new Doc('@name a\n@example text {{ abc }}');
doc.parse();
- expect(doc.example).toEqual('text {{ abc }}
');
+ expect(doc.example).toEqual('text {{ abc }}
');
});
});
@@ -496,10 +510,12 @@ describe('ngdoc', function() {
doc.parse();
expect(doc.html()).toContain('Method\'s this
\n' +
'' +
+ '' +
'I am self.
' +
+ '' +
'\n');
expect(doc.html()).toContain('Method\'s this
\n' +
- 'I am self.
');
+ 'I am self.
');
});
});
diff --git a/docs/spec/sourceLinkSpec.js b/docs/spec/sourceLinkSpec.js
new file mode 100644
index 000000000000..3dc73cc85c37
--- /dev/null
+++ b/docs/spec/sourceLinkSpec.js
@@ -0,0 +1,29 @@
+var ngdoc = require('../src/ngdoc.js');
+var gruntUtil = require('../../lib/grunt/utils.js');
+
+describe('Docs Links', function() {
+
+ describe('links', function() {
+ var doc;
+
+ beforeEach(function() {
+ doc = new ngdoc.Doc("@ngdoc function\n@name ng.filter:a\n@function");
+ doc.section = 'api';
+ doc.file = 'test.js';
+ doc.line = 42;
+ doc.parse();
+ });
+
+ it('should have an "improve this doc" button', function() {
+ expect(doc.html()).
+ toContain(' Improve this doc');
+ });
+
+ it('should have an "view source" button', function() {
+ expect(doc.html()).
+ toContain(' View source');
+ });
+
+ });
+
+});
diff --git a/docs/src/ngdoc.js b/docs/src/ngdoc.js
index af78c1e32382..f5f22ee84ef8 100644
--- a/docs/src/ngdoc.js
+++ b/docs/src/ngdoc.js
@@ -240,7 +240,25 @@ Doc.prototype = {
});
});
text = parts.join('');
- text = markdown.makeHtml(text);
+
+ function prepareClassName(text) {
+ return text.toLowerCase().replace(/[_\W]+/g, '-');
+ };
+
+ var pageClassName, suffix = '-page';
+ if(this.name) {
+ var split = this.name.match(/^\s*(.+?)\s*:\s*(.+)/);
+ if(split && split.length > 1) {
+ var before = prepareClassName(split[1]);
+ var after = prepareClassName(split[2]);
+ pageClassName = before + suffix + ' ' + before + '-' + after + suffix;
+ }
+ }
+ pageClassName = pageClassName || prepareClassName(this.name || 'docs') + suffix;
+
+ text = '' +
+ markdown.makeHtml(text) +
+ '';
text = text.replace(/(?:)?(REPLACEME\d+)(?:<\/p>)?/g, function(_, id) {
return placeholderMap[id];
});
@@ -378,7 +396,16 @@ Doc.prototype = {
dom.h(title(this.name), function() {
notice('deprecated', 'Deprecated API', self.deprecated);
- dom.tag('a', {href: 'http://github.com/angular/angular.js/edit/master/' + self.file, class: 'improve-docs btn btn-primary'}, 'Improve this doc');
+ dom.tag('a', {href: 'http://github.com/angular/angular.js/edit/master/' + self.file, class: 'improve-docs btn btn-primary'}, function(dom) {
+ dom.tag('i', {class:'icon-edit'}, ' ');
+ dom.text(' Improve this doc');
+ });
+ if (self.section === 'api') {
+ dom.tag('a', {href: 'http://github.com/angular/angular.js/tree/v' + gruntUtil.getVersion().number + '/' + self.file + '#L' + self.line, class: 'view-source btn btn-action'}, function(dom) {
+ dom.tag('i', {class:'icon-zoom-in'}, ' ');
+ dom.text(' View source');
+ });
+ }
if (self.ngdoc != 'overview') {
dom.h('Description', self.description, dom.html);
}
@@ -401,7 +428,7 @@ Doc.prototype = {
//////////////////////////
function notice(name, legend, msg){
- if (self[name] == undefined) return;
+ if (self[name] === undefined) return;
dom.tag('fieldset', {'class':name}, function(dom){
dom.tag('legend', legend);
dom.text(msg);
diff --git a/docs/src/templates/css/doc_widgets.css b/docs/src/templates/css/doc_widgets.css
index b0348b2218fb..587d5a7e3c99 100644
--- a/docs/src/templates/css/doc_widgets.css
+++ b/docs/src/templates/css/doc_widgets.css
@@ -15,7 +15,7 @@ ul.doc-example > li {
ul.doc-example > li.doc-example-heading {
border: none;
- border-radius: none;
+ border-radius: 0;
margin-bottom: -10px;
}
diff --git a/docs/src/templates/css/docs.css b/docs/src/templates/css/docs.css
index 5d769b29bec3..f4a86ba5e783 100644
--- a/docs/src/templates/css/docs.css
+++ b/docs/src/templates/css/docs.css
@@ -95,8 +95,14 @@
/* Content */
/* =============================== */
-.improve-docs {
+.improve-docs, .view-source {
float: right;
+ margin: 0 5px;
+ position: relative;
+}
+
+.improve-docs {
+ z-index:100;
}
.hint {
@@ -292,13 +298,16 @@ ul.events > li > h3 {
z-index:1031;
}
+.tutorial-index-page,
+.tutorial-the-end-page {
+ padding-top:50px;
+}
+
.tutorial-page {
position:relative;
}
-.tutorial-page-no-nav {
- padding-top:50px;
-}
-.tutorial-page-no-nav .improve-docs {
+
+.tutorial-page .improve-docs {
position:absolute;
top:0;
right:0;
@@ -371,7 +380,7 @@ ul.events > li > h3 {
content:"";
position:absolute;
left:50%;
- top:0px;
+ top:0;
margin-left:-10px;
border-width:10px;
border-style:solid;
diff --git a/docs/src/templates/index.html b/docs/src/templates/index.html
index 15093d4cd1ac..84423ee80bef 100644
--- a/docs/src/templates/index.html
+++ b/docs/src/templates/index.html
@@ -121,7 +121,7 @@