diff --git a/Gruntfile.js b/Gruntfile.js index 47d30f509c5f..032039096aea 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -346,7 +346,7 @@ module.exports = function(grunt) { grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']); grunt.registerTask('webserver', ['connect:devserver']); - grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']); + grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']); grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']); grunt.registerTask('default', ['package']); }; diff --git a/docs/app/src/app.js b/docs/app/src/app.js index 607cc0f0e1ec..df6272b0bf0b 100644 --- a/docs/app/src/app.js +++ b/docs/app/src/app.js @@ -6,7 +6,6 @@ angular.module('docsApp', [ 'ngSanitize', 'ngAnimate', 'DocsController', - 'versionsData', 'pagesData', 'navData', 'directives', diff --git a/docs/app/src/docs.js b/docs/app/src/docs.js index cb06ec646c45..e2bd613a0f90 100644 --- a/docs/app/src/docs.js +++ b/docs/app/src/docs.js @@ -1,12 +1,12 @@ 'use strict'; -angular.module('DocsController', []) +angular.module('DocsController', ['currentVersionData']) .controller('DocsController', [ '$scope', '$rootScope', '$location', '$window', '$cookies', - 'NG_PAGES', 'NG_NAVIGATION', 'NG_VERSION', + 'NG_PAGES', 'NG_NAVIGATION', 'CURRENT_NG_VERSION', function($scope, $rootScope, $location, $window, $cookies, - NG_PAGES, NG_NAVIGATION, NG_VERSION) { + NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) { $scope.navClass = function(navItem) { return { @@ -58,8 +58,8 @@ angular.module('DocsController', []) Initialize ***********************************/ - $scope.versionNumber = NG_VERSION.full; - $scope.version = NG_VERSION.full + ' ' + NG_VERSION.codeName; + $scope.versionNumber = CURRENT_NG_VERSION.full; + $scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName; $scope.loading = 0; diff --git a/docs/app/src/versions.js b/docs/app/src/versions.js index 04abeedc5615..9f0d3dc0c5c4 100644 --- a/docs/app/src/versions.js +++ b/docs/app/src/versions.js @@ -1,37 +1,42 @@ 'use strict'; +/* global console */ -angular.module('versions', []) +angular.module('versions', ['currentVersionData', 'allVersionsData']) -.controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) { - $scope.docs_version = NG_VERSIONS[0]; - $scope.docs_versions = NG_VERSIONS; +.directive('versionPicker', function() { + return { + restrict: 'E', + scope: true, + controllerAs: '$ctrl', + controller: ['$location', '$window', 'CURRENT_NG_VERSION', 'ALL_NG_VERSIONS', + /** @this VersionPickerController */ + function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) { - for (var i = 0, minor = NaN; i < NG_VERSIONS.length; i++) { - var version = NG_VERSIONS[i]; - if (version.isSnapshot) { - version.isLatest = true; - continue; - } - // NaN will give false here - if (minor <= version.minor) { - continue; - } - version.isLatest = true; - minor = version.minor; - } + var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version; - $scope.getGroupName = function(v) { - return v.isLatest ? 'Latest' : ('v' + v.major + '.' + v.minor + '.x'); + this.versions = ALL_NG_VERSIONS; + this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; }); + + this.jumpToDocsVersion = function(value) { + var currentPagePath = $location.path().replace(/\/$/, ''); + $window.location = value.docsUrl + currentPagePath; + }; + }], + template: + '
' + + ' ' + + '
' }; - $scope.jumpToDocsVersion = function(version) { - var currentPagePath = $location.path().replace(/\/$/, ''), - url = ''; - if (version.isOldDocsUrl) { - url = version.docsUrl; - } else { - url = version.docsUrl + currentPagePath; + function find(collection, matcherFn) { + for (var i = 0, ii = collection.length; i < ii; ++i) { + if (matcherFn(collection[i])) { + return collection[i]; + } } - $window.location = url; - }; -}]); + } +}); diff --git a/docs/app/test/docsSpec.js b/docs/app/test/docsSpec.js index 905a6d511181..d5424ef2ff79 100644 --- a/docs/app/test/docsSpec.js +++ b/docs/app/test/docsSpec.js @@ -6,8 +6,13 @@ describe('DocsController', function() { angular.module('fake', []) .value('$cookies', {}) .value('NG_PAGES', {}) - .value('NG_NAVIGATION', {}) - .value('NG_VERSION', {}); + .value('NG_NAVIGATION', {}); + + angular.module('currentVersionData', []) + .value('CURRENT_NG_VERSION', {}); + + angular.module('allVersionsData', []) + .value('ALL_NG_VERSIONS', {}); beforeEach(module('fake', 'DocsController')); beforeEach(inject(function($rootScope, $controller) { diff --git a/docs/config/processors/versions-data.js b/docs/config/processors/versions-data.js index 5e0fa94cb7e0..8b8d0fd52d36 100644 --- a/docs/config/processors/versions-data.js +++ b/docs/config/processors/versions-data.js @@ -1,6 +1,7 @@ 'use strict'; -var _ = require('lodash'); +var exec = require('shelljs').exec; +var semver = require('semver'); /** * @dgProcessor generateVersionDocProcessor @@ -12,23 +13,96 @@ module.exports = function generateVersionDocProcessor(gitData) { return { $runAfter: ['generatePagesDataProcessor'], $runBefore: ['rendering-docs'], + // the blacklist is to remove rogue builds that are in npm but not on code.angularjs.org + blacklist: ['1.3.4-build.3588'], $process: function(docs) { - var versionDoc = { - docType: 'versions-data', - id: 'versions-data', - template: 'versions-data.template.js', - outputPath: 'js/versions-data.js', - currentVersion: gitData.version - }; - - versionDoc.versions = _(gitData.versions) - .filter(function(version) { return version.major > 0; }) - .push(gitData.version) - .reverse() - .value(); - - docs.push(versionDoc); + var blacklist = this.blacklist; + var currentVersion = require('../../../build/version.json'); + var output = exec('npm info angular versions --json', { silent: true }).stdout; + var allVersions = processAllVersionsResponse(JSON.parse(output)); + + docs.push({ + docType: 'current-version-data', + id: 'current-version-data', + template: 'angular-service.template.js', + outputPath: 'js/current-version-data.js', + ngModuleName: 'currentVersionData', + serviceName: 'CURRENT_NG_VERSION', + serviceValue: currentVersion + }); + + docs.push({ + docType: 'allversions-data', + id: 'allversions-data', + template: 'angular-service.template.js', + outputPath: 'js/all-versions-data.js', + ngModuleName: 'allVersionsData', + serviceName: 'ALL_NG_VERSIONS', + serviceValue: allVersions + }); + + + function processAllVersionsResponse(versions) { + + var latestMap = {}; + + versions = versions + .filter(function(versionStr) { + return blacklist.indexOf(versionStr) === -1; + }) + .map(function(versionStr) { + return semver.parse(versionStr); + }) + .filter(function(version) { + return version && version.major > 0; + }) + .map(function(version) { + var key = version.major + '.' + version.minor; + var latest = latestMap[key]; + if (!latest || version.compare(latest) > 0) { + latestMap[key] = version; + } + return version; + }) + .map(function(version) { + return makeOption(version); + }) + .reverse(); + + var latest = sortObject(latestMap, reverse(semver.compare)) + .map(function(version) { return makeOption(version, 'Latest'); }); + + return [makeOption({version: 'snapshot'}, 'Latest', 'master')] + .concat(latest) + .concat(versions); + } + + function makeOption(version, group, label) { + return { + version: version, + label: label || 'v' + version.raw, + group: group || 'v' + version.major + '.' + version.minor, + docsUrl: createDocsUrl(version) + }; + } + + function createDocsUrl(version) { + var url = 'https://code.angularjs.org/' + version.version + '/docs'; + // Versions before 1.0.2 had a different docs folder name + if (version.major === 1 && version.minor === 0 && version.patch < 2) { + url += '-' + version.version; + } + return url; + } + + function reverse(fn) { + return function(left, right) { return -fn(left, right); }; + } + + function sortObject(obj, cmp) { + return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp); + } } }; }; diff --git a/docs/config/services/deployments/debug.js b/docs/config/services/deployments/debug.js index 991474c47ea0..f7381b129697 100644 --- a/docs/config/services/deployments/debug.js +++ b/docs/config/services/deployments/debug.js @@ -22,7 +22,8 @@ module.exports = function debugDeployment(getVersion) { 'components/lunr.js-' + getVersion('lunr.js') + '/lunr.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js', - 'js/versions-data.js', + 'js/current-version-data.js', + 'js/all-versions-data.js', 'js/pages-data.js', 'js/nav-data.js', 'js/docs.js' diff --git a/docs/config/services/deployments/default.js b/docs/config/services/deployments/default.js index 5a10e4dbddf0..c489946d8884 100644 --- a/docs/config/services/deployments/default.js +++ b/docs/config/services/deployments/default.js @@ -22,7 +22,8 @@ module.exports = function defaultDeployment(getVersion) { 'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js', - 'js/versions-data.js', + 'js/current-version-data.js', + 'js/all-versions-data.js', 'js/pages-data.js', 'js/nav-data.js', 'js/docs.min.js' diff --git a/docs/config/services/deployments/jquery.js b/docs/config/services/deployments/jquery.js index b480b9f50056..b224830af43a 100644 --- a/docs/config/services/deployments/jquery.js +++ b/docs/config/services/deployments/jquery.js @@ -26,7 +26,8 @@ module.exports = function jqueryDeployment(getVersion) { 'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js', - 'js/versions-data.js', + 'js/current-version-data.js', + 'js/all-versions-data.js', 'js/pages-data.js', 'js/nav-data.js', 'js/docs.min.js' diff --git a/docs/config/services/deployments/production.js b/docs/config/services/deployments/production.js index 112d20889520..2e090bf3d5a9 100644 --- a/docs/config/services/deployments/production.js +++ b/docs/config/services/deployments/production.js @@ -39,7 +39,8 @@ module.exports = function productionDeployment(getVersion) { 'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js', 'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js', - 'js/versions-data.js', + 'js/current-version-data.js', + 'https://code.angularjs.org/snapshot/docs/js/all-versions-data.js', 'js/pages-data.js', 'js/nav-data.js', 'js/docs.min.js' diff --git a/docs/config/templates/angular-service.template.js b/docs/config/templates/angular-service.template.js new file mode 100644 index 000000000000..c44925dcde96 --- /dev/null +++ b/docs/config/templates/angular-service.template.js @@ -0,0 +1,4 @@ +'use strict'; + +angular.module('{$ doc.ngModuleName $}', []) + .value('{$ doc.serviceName $}', {$ doc.serviceValue | json $}); diff --git a/docs/config/templates/indexPage.template.html b/docs/config/templates/indexPage.template.html index a97fc9e6ed55..884763dcc838 100644 --- a/docs/config/templates/indexPage.template.html +++ b/docs/config/templates/indexPage.template.html @@ -165,13 +165,7 @@

{{ key }}

-
- -
+