mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-23 11:37:38 +08:00
feat(ngdocs): provide support for user to jump between different versions of the angularjs documentation
This commit is contained in:
committed by
Misko Hevery
parent
ef22968810
commit
46dfb92afd
@@ -61,7 +61,7 @@ function appCacheTemplate() {
|
||||
"syntaxhighlighter/syntaxhighlighter-combined.js",
|
||||
"../angular.min.js",
|
||||
"docs-combined.js",
|
||||
"docs-keywords.js",
|
||||
"docs-data.js",
|
||||
"docs-combined.css",
|
||||
"syntaxhighlighter/syntaxhighlighter-combined.css",
|
||||
"img/texture_1.png",
|
||||
|
||||
@@ -43,6 +43,8 @@ writer.makeDir('build/docs/', true).then(function() {
|
||||
|
||||
function writeTheRest(writesFuture) {
|
||||
var metadata = ngdoc.metadata(docs);
|
||||
var versions = ngdoc.ngVersions();
|
||||
var currentVersion = ngdoc.ngCurrentVersion();
|
||||
|
||||
writesFuture.push(writer.symlink('../../docs/content/notes', 'build/docs/notes', 'dir'));
|
||||
writesFuture.push(writer.symlinkTemplate('css', 'dir'));
|
||||
@@ -90,8 +92,12 @@ function writeTheRest(writesFuture) {
|
||||
writesFuture.push(writer.copyTemplate('docs-scenario.html')); // will be rewritten, don't symlink
|
||||
writesFuture.push(writer.output('docs-scenario.js', ngdoc.scenarios(docs)));
|
||||
|
||||
writesFuture.push(writer.output('docs-keywords.js',
|
||||
['NG_PAGES=', JSON.stringify(metadata).replace(/{/g, '\n{'), ';']));
|
||||
writesFuture.push(writer.output('docs-data.js',[
|
||||
"angular.module('docsData', [])",
|
||||
".value('NG_PAGES'," + JSON.stringify(metadata).replace(/{/g, '\n{') + ")",
|
||||
".value('NG_VERSION'," + JSON.stringify(currentVersion) + ")",
|
||||
".value('NG_VERSIONS'," + JSON.stringify(versions) + ");"
|
||||
]));
|
||||
writesFuture.push(writer.output('sitemap.xml', new SiteMap(docs).render()));
|
||||
|
||||
writesFuture.push(writer.output('robots.txt', 'Sitemap: http://docs.angularjs.org/sitemap.xml\n'));
|
||||
|
||||
@@ -11,6 +11,8 @@ var globalID = 0;
|
||||
var fs = require('fs');
|
||||
var fspath = require('path');
|
||||
var markdown = new Showdown.converter({ extensions : ['table'] });
|
||||
var shell = require('shelljs');
|
||||
var gruntUtil = require('../../lib/grunt/utils.js');
|
||||
|
||||
exports.trim = trim;
|
||||
exports.metadata = metadata;
|
||||
@@ -18,6 +20,23 @@ exports.scenarios = scenarios;
|
||||
exports.merge = merge;
|
||||
exports.Doc = Doc;
|
||||
|
||||
exports.ngVersions = function() {
|
||||
var line, versions = [], regex = /^v([1-9]\d*(?:\.\d+)+)$/; //only fetch >= 1.0.0 versions
|
||||
shell.exec('git tag', {silent: true}).output.split(/\s*\n\s*/)
|
||||
.forEach(function(line) {
|
||||
var matches = regex.exec(line);
|
||||
if(matches && matches.length > 0) {
|
||||
versions.push(matches[1]);
|
||||
}
|
||||
});
|
||||
versions.push(exports.ngCurrentVersion().number);
|
||||
return versions;
|
||||
};
|
||||
|
||||
exports.ngCurrentVersion = function() {
|
||||
return gruntUtil.getVersion();
|
||||
};
|
||||
|
||||
var BOOLEAN_ATTR = {};
|
||||
['multiple', 'selected', 'checked', 'disabled', 'readOnly', 'required'].forEach(function(value) {
|
||||
BOOLEAN_ATTR[value] = true;
|
||||
|
||||
@@ -461,4 +461,8 @@ pre ol li {
|
||||
box-shadow:-6px 0 5px #555;
|
||||
display:block;
|
||||
border-radius:10px;
|
||||
|
||||
.docs-version-jump {
|
||||
width:180px;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
addTag('script', {src: 'components/google-code-prettify.js' }, sync);
|
||||
addTag('script', {src: 'components/' + (debug ? 'lunr.js' : 'lunr.min.js') }, sync);
|
||||
addTag('script', {src: 'components/' + (debug ? 'showdown.js' : 'showdown.min.js') }, sync);
|
||||
addTag('script', {src: 'docs-data.js'}, sync);
|
||||
addTag('script', {src: 'js/docs.js'}, sync);
|
||||
addTag('script', {src: 'docs-keywords.js'}, sync);
|
||||
|
||||
function path(name) {
|
||||
if (production) {
|
||||
@@ -233,74 +233,83 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="span3">
|
||||
<form class="well form-search" ng-submit="submitForm()">
|
||||
<div class="dropdown search"
|
||||
ng-class="{open: focused && bestMatch.rank > 0 && bestMatch.page != currentPage}">
|
||||
<input type="text" ng-model="search" placeholder="search the docs"
|
||||
tabindex="1" accesskey="s" class="input-medium search-query" focused="focused">
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="{{bestMatch.page.url}}">{{bestMatch.page.shortName}}</a>
|
||||
<div class="well">
|
||||
<div ng-controller="DocsVersionsCtrl">
|
||||
<select ng-options="v.version as v.title group by v.group for v in versions"
|
||||
ng-model="version"
|
||||
ng-change="jumpToDocsVersion(version)"
|
||||
class="docs-version-jump">
|
||||
</select>
|
||||
</div>
|
||||
<form class="form-search" ng-submit="submitForm()">
|
||||
<div class="dropdown search"
|
||||
ng-class="{open: focused && bestMatch.rank > 0 && bestMatch.page != currentPage}">
|
||||
<input type="text" ng-model="search" placeholder="search the docs"
|
||||
tabindex="1" accesskey="s" class="input-medium search-query" focused="focused">
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="{{bestMatch.page.url}}">{{bestMatch.page.shortName}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
<div ng-show="search">Filtered results:</div>
|
||||
|
||||
<ul class="nav nav-list" ng-hide="page">
|
||||
<li ng-repeat="page in pages track by page.url" ng-class="navClass(page)" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
<div ng-show="search">Filtered results:</div>
|
||||
|
||||
<ul class="nav nav-list" ng-hide="page">
|
||||
<li ng-repeat="page in pages track by page.url" ng-class="navClass(page)" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="nav nav-list well" ng-repeat="module in modules track by module.url" class="api-list-item">
|
||||
<li class="nav-header module">
|
||||
<a class="guide" href="{{URL.module}}">module</a>
|
||||
<a class="code" href="{{module.url}}">{{module.name}}</a>
|
||||
</li>
|
||||
<ul class="nav nav-list well" ng-repeat="module in modules track by module.url" class="api-list-item">
|
||||
<li class="nav-header module">
|
||||
<a class="guide" href="{{URL.module}}">module</a>
|
||||
<a class="code" href="{{module.url}}">{{module.name}}</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-header section" ng-show="module.directives">
|
||||
<a href="{{URL.directive}}" class="guide">directive</a>
|
||||
</li>
|
||||
<li ng-repeat="page in module.directives track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
<li class="nav-header section" ng-show="module.directives">
|
||||
<a href="{{URL.directive}}" class="guide">directive</a>
|
||||
</li>
|
||||
<li ng-repeat="page in module.directives track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-header section" ng-show="module.filters">
|
||||
<a href="{{URL.filter}}" class="guide">filter</a>
|
||||
</li>
|
||||
<li ng-repeat="page in module.filters track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
<li class="nav-header section" ng-show="module.filters">
|
||||
<a href="{{URL.filter}}" class="guide">filter</a>
|
||||
</li>
|
||||
<li ng-repeat="page in module.filters track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-header section" ng-show="module.services">
|
||||
<a href="{{URL.service}}" class="guide">service</a>
|
||||
</li>
|
||||
<li ng-repeat="service in module.services track by service.instance.url" ng-animate="'expand'" ng-class="navClass(service.instance, service.provider)" class="api-list-item">
|
||||
<a ng-show="service.provider" class="pull-right" href="{{service.provider.url}}" tabindex="2"><i class="icon-cog"></i></a>
|
||||
<a href="{{service.instance.url}}" tabindex="2">{{service.name}}</a>
|
||||
</li>
|
||||
<li class="nav-header section" ng-show="module.services">
|
||||
<a href="{{URL.service}}" class="guide">service</a>
|
||||
</li>
|
||||
<li ng-repeat="service in module.services track by service.instance.url" ng-animate="'expand'" ng-class="navClass(service.instance, service.provider)" class="api-list-item">
|
||||
<a ng-show="service.provider" class="pull-right" href="{{service.provider.url}}" tabindex="2"><i class="icon-cog"></i></a>
|
||||
<a href="{{service.instance.url}}" tabindex="2">{{service.name}}</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-header section" ng-show="module.types">
|
||||
<a href="{{URL.type}}" class="guide">Types</a>
|
||||
</li>
|
||||
<li ng-repeat="page in module.types track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
<li class="nav-header section" ng-show="module.types">
|
||||
<a href="{{URL.type}}" class="guide">Types</a>
|
||||
</li>
|
||||
<li ng-repeat="page in module.types track by page.url" ng-class="navClass(page)" ng-animate="'expand'" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.shortName}}</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-header section" ng-show="module.globals">
|
||||
<a href="{{URL.api}}" class="global guide">global APIs</a>
|
||||
|
||||
</li>
|
||||
<li ng-repeat="page in module.globals track by page.url" ng-class="navClass(page)" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.id}}</a>
|
||||
</li>
|
||||
<li class="nav-header section" ng-show="module.globals">
|
||||
<a href="{{URL.api}}" class="global guide">global APIs</a>
|
||||
|
||||
</li>
|
||||
<li ng-repeat="page in module.globals track by page.url" ng-class="navClass(page)" class="api-list-item">
|
||||
<a href="{{page.url}}" tabindex="2">{{page.id}}</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span9">
|
||||
|
||||
|
||||
@@ -4,6 +4,64 @@ var docsApp = {
|
||||
serviceFactory: {}
|
||||
};
|
||||
|
||||
docsApp.controller.DocsVersionsCtrl = ['$scope', '$window', 'NG_VERSIONS', function($scope, $window, NG_VERSIONS) {
|
||||
$scope.versions = expandVersions(NG_VERSIONS);
|
||||
$scope.version = ($scope.version || angular.version.full).match(/^([\d\.]+\d+)/)[1]; //match only the number
|
||||
|
||||
$scope.jumpToDocsVersion = function(value) {
|
||||
var isLastStable,
|
||||
version,
|
||||
versions = $scope.versions;
|
||||
for(var i=versions.length-1;i>=0;i--) {
|
||||
var v = versions[i];
|
||||
if(v.version == value) {
|
||||
var next = versions[i - 1];
|
||||
isLastStable = v.stable && (!next || next && !next.stable);
|
||||
version = v;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if(version && version.version >= '1.0.0') {
|
||||
//the older versions have a different path to the docs within their repo directory
|
||||
var docsPath = version.version < '1.0.2' ? 'docs-' + version.version : 'docs';
|
||||
|
||||
//the last stable version should redirect to docs.angularjs.org instead of code.angularjs.org
|
||||
var url = 'http://' +
|
||||
(isLastStable ?
|
||||
'docs.angularjs.org' :
|
||||
'code.angularjs.org/' + version.version + '/' + docsPath);
|
||||
|
||||
$window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
function expandVersions(angularVersions) {
|
||||
var unstableVersionStart = 0;
|
||||
angularVersions.forEach(function(version) {
|
||||
var split = version.split('.');
|
||||
unstableVersionStart = split[1] % 2 == 1 ?
|
||||
Math.max(unstableVersionStart, parseInt(split[0] + '' + split[1])) :
|
||||
unstableVersionStart;
|
||||
});
|
||||
|
||||
var versions = [];
|
||||
for(var i=angularVersions.length-1;i>=0;i--) {
|
||||
var version = angularVersions[i];
|
||||
var split = version.split('.');
|
||||
var stable = parseInt(split[0] + '' + split[1]) < unstableVersionStart;
|
||||
versions.push({
|
||||
version : version,
|
||||
stable : stable,
|
||||
title : 'AngularJS - v' + version,
|
||||
group : (stable ? 'Stable' : 'Unstable')
|
||||
});
|
||||
};
|
||||
|
||||
return versions;
|
||||
};
|
||||
}];
|
||||
|
||||
docsApp.controller.DocsNavigationCtrl = ['$scope', 'fullTextSearch', '$location', function($scope, fullTextSearch, $location) {
|
||||
fullTextSearch.init();
|
||||
$scope.search = function(q) {
|
||||
@@ -47,7 +105,7 @@ docsApp.controller.DocsNavigationCtrl = ['$scope', 'fullTextSearch', '$location'
|
||||
};
|
||||
}];
|
||||
|
||||
docsApp.serviceFactory.fullTextSearch = ['$q', '$rootScope', function($q, $rootScope) {
|
||||
docsApp.serviceFactory.fullTextSearch = ['$q', '$rootScope', 'NG_PAGES', function($q, $rootScope, NG_PAGES) {
|
||||
return {
|
||||
dbName : 'docs',
|
||||
indexName : 'docsindex',
|
||||
@@ -374,7 +432,7 @@ docsApp.serviceFactory.openJsFiddle = function(templateMerge, formPostData, angu
|
||||
};
|
||||
|
||||
|
||||
docsApp.serviceFactory.sections = function sections() {
|
||||
docsApp.serviceFactory.sections = ['NG_PAGES', function sections(NG_PAGES) {
|
||||
var sections = {
|
||||
guide: [],
|
||||
api: [],
|
||||
@@ -407,7 +465,7 @@ docsApp.serviceFactory.sections = function sections() {
|
||||
});
|
||||
|
||||
return sections;
|
||||
};
|
||||
}];
|
||||
|
||||
|
||||
docsApp.controller.DocsController = function($scope, $location, $window, $cookies, sections) {
|
||||
@@ -706,7 +764,7 @@ docsApp.controller.DocsController = function($scope, $location, $window, $cookie
|
||||
};
|
||||
|
||||
|
||||
angular.module('docsApp', ['ngResource', 'ngRoute', 'ngCookies', 'ngSanitize', 'bootstrap', 'bootstrapPrettify']).
|
||||
angular.module('docsApp', ['ngResource', 'ngRoute', 'ngCookies', 'ngSanitize', 'bootstrap', 'bootstrapPrettify', 'docsData']).
|
||||
config(function($locationProvider) {
|
||||
$locationProvider.html5Mode(true).hashPrefix('!');
|
||||
}).
|
||||
|
||||
Reference in New Issue
Block a user