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

Commit 13f92de

Browse files
vojtajinaIgorMinar
authored andcommitted
feat(docs): use html5 history api for all routing in the docs app
- Configure our docs app to use new $location with html5 history api! - Update simple node web server to serve index.html for all links (rewritting). - Update .htaccess file to serve index.html for all links (rewritting). - At runtime determine the base href path and attach it to the DOM. We needed the absolute URL to get all browsers to work well. - Because of the above, we also need to dynamically determine all needed js/css resources and add them to the DOM. This was needed because FF6 would eagerly fetch resources with wrong URL since the base element is added to the dom at runtime. - All content html files were moved to the partials directory, because with the new html5 urls it was impossible to tell if request for http://domain/api/angular.filter.html was an html5 url for the html filter doc page, or an xhr/appcache request for the content html file for the html filter. f
1 parent 2bc39bb commit 13f92de

File tree

12 files changed

+150
-80
lines changed

12 files changed

+150
-80
lines changed

Rakefile

+25-4
Original file line numberDiff line numberDiff line change
@@ -209,18 +209,37 @@ task :package => [:clean, :compile, :docs] do
209209
text = f.read
210210
f.truncate 0
211211
f.rewind
212-
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
212+
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js").
213+
sub('/build/docs/', "/#{NG_VERSION.full}/docs-#{NG_VERSION.full}/")
213214
end
214215

215216

216217
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index-jq.html", File::RDWR) do |f|
217218
text = f.read
218219
f.truncate 0
219220
f.rewind
220-
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
221+
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js").
222+
sub('/build/docs/', "/#{NG_VERSION.full}/docs-#{NG_VERSION.full}/")
221223
end
222224

223225

226+
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index-debug.html", File::RDWR) do |f|
227+
text = f.read
228+
f.truncate 0
229+
f.rewind
230+
f.write text.sub('../angular.js', "../angular-#{NG_VERSION.full}.js").
231+
sub('/build/docs/', "/#{NG_VERSION.full}/docs-#{NG_VERSION.full}/")
232+
end
233+
234+
235+
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/index-jq-debug.html", File::RDWR) do |f|
236+
text = f.read
237+
f.truncate 0
238+
f.rewind
239+
f.write text.sub('../angular.js', "../angular-#{NG_VERSION.full}.js").
240+
sub('/build/docs/', "/#{NG_VERSION.full}/docs-#{NG_VERSION.full}/")
241+
end
242+
224243
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/docs-scenario.html", File::RDWR) do |f|
225244
text = f.read
226245
f.truncate 0
@@ -232,14 +251,16 @@ task :package => [:clean, :compile, :docs] do
232251
text = f.read
233252
f.truncate 0
234253
f.rewind
235-
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
254+
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js").
255+
sub('/build/docs/', "/#{NG_VERSION.full}/docs-#{NG_VERSION.full}/")
236256
end
237257

238258
File.open("#{pkg_dir}/docs-#{NG_VERSION.full}/appcache-offline.manifest", File::RDWR) do |f|
239259
text = f.read
240260
f.truncate 0
241261
f.rewind
242-
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js")
262+
f.write text.sub('angular.min.js', "angular-#{NG_VERSION.full}.min.js").
263+
sub('/build/docs/', "/#{NG_VERSION.full}/docs-#{NG_VERSION.full}/")
243264
end
244265

245266

docs/content/cookbook/deeplinking.ngdoc

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ controller.
2828

2929
In this example we have a simple app which consist of two screens:
3030

31-
* Welcome: url `#` Show the user contact information.
32-
* Settings: url `#/settings` Show an edit screen for user contact information.
31+
* Welcome: url `welcome` Show the user contact information.
32+
* Settings: url `settings` Show an edit screen for user contact information.
3333

3434

3535
The two partials are defined in the following URLs:
3636

37-
* {@link ./examples/settings.html}
38-
* {@link ./examples/welcome.html}
37+
* <a href="./examples/settings.html" ng:ext-link>./examples/settings.html</a>
38+
* <a href="./examples/welcome.html" ng:ext-link>./examples/welcome.html</a>
3939

4040
<doc:example>
4141
<doc:source>
@@ -79,7 +79,7 @@ The two partials are defined in the following URLs:
7979
</script>
8080
<div ng:controller="AppCntl">
8181
<h1>Your App Chrome</h1>
82-
[ <a href="#!/welcome">Welcome</a> | <a href="#!/settings">Settings</a> ]
82+
[ <a href="welcome">Welcome</a> | <a href="settings">Settings</a> ]
8383
<hr/>
8484
<span style="background-color: blue; color: white; padding: 3px;">
8585
Partial: {{$route.current.template}}

docs/spec/ngdocSpec.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ describe('ngdoc', function(){
327327
expect(doc.requires).toEqual([
328328
{name:'$service', text:'<p>for \n<code>A</code></p>'},
329329
{name:'$another', text:'<p>for <code>B</code></p>'}]);
330-
expect(doc.html()).toContain('<a href="#!/api/angular.service.$service">$service</a>');
331-
expect(doc.html()).toContain('<a href="#!/api/angular.service.$another">$another</a>');
330+
expect(doc.html()).toContain('<a href="api/angular.service.$service">$service</a>');
331+
expect(doc.html()).toContain('<a href="api/angular.service.$another">$another</a>');
332332
expect(doc.html()).toContain('<p>for \n<code>A</code></p>');
333333
expect(doc.html()).toContain('<p>for <code>B</code></p>');
334334
});
@@ -429,13 +429,13 @@ describe('ngdoc', function(){
429429
doc.parse();
430430

431431
expect(doc.description).
432-
toContain('foo <a href="#!/api/angular.foo"><code>angular.foo</code></a>');
432+
toContain('foo <a href="api/angular.foo"><code>angular.foo</code></a>');
433433
expect(doc.description).
434-
toContain('da <a href="#!/api/angular.foo"><code>bar foo bar</code></a>');
434+
toContain('da <a href="api/angular.foo"><code>bar foo bar</code></a>');
435435
expect(doc.description).
436-
toContain('dad<a href="#!/api/angular.foo"><code>angular.foo</code></a>');
436+
toContain('dad<a href="api/angular.foo"><code>angular.foo</code></a>');
437437
expect(doc.description).
438-
toContain('<a href="#!/api/angular.directive.ng:foo"><code>ng:foo</code></a>');
438+
toContain('<a href="api/angular.directive.ng:foo"><code>ng:foo</code></a>');
439439
expect(doc.description).
440440
toContain('<a href="http://angularjs.org">http://angularjs.org</a>');
441441
expect(doc.description).
@@ -447,7 +447,7 @@ describe('ngdoc', function(){
447447
'{@link\napi/angular.foo\na\nb}');
448448
doc.parse();
449449
expect(doc.description).
450-
toContain('<a href="#!/api/angular.foo"><code>a b</code></a>');
450+
toContain('<a href="api/angular.foo"><code>a b</code></a>');
451451
});
452452

453453
});

docs/src/appCache.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function appCache(path) {
2929

3030
var resultPostfix = ["",
3131
"FALLBACK:",
32-
"/offline.html",
32+
"/ /build/docs/index.html",
3333
"",
3434
"# allow access to google analytics and twitter when we are online",
3535
"NETWORK:",
@@ -68,7 +68,7 @@ function appCacheTemplate() {
6868
"img/yellow_bkgnd.jpg",
6969
"",
7070
"FALLBACK:",
71-
"/ offline.html",
71+
"/ /build/docs/offline.html",
7272
"",
7373
"# allow access to google analytics and twitter when we are online",
7474
"NETWORK:",

docs/src/gen-docs.js

+6-15
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ writer.makeDir('build/docs/syntaxhighlighter').then(function() {
2222
ngdoc.merge(docs);
2323
var fileFutures = [];
2424
docs.forEach(function(doc){
25-
fileFutures.push(writer.output(doc.section + '/' + doc.id + '.html', doc.html()));
25+
fileFutures.push(writer.output('partials/' + doc.section + '/' + doc.id + '.html', doc.html()));
2626
});
2727

2828
writeTheRest(fileFutures);
@@ -43,28 +43,19 @@ function writeTheRest(writesFuture) {
4343
writesFuture.push(writer.copyDir('img'));
4444
writesFuture.push(writer.copyDir('examples'));
4545

46-
var manifest = 'manifest="appcache.manifest"',
47-
jq = '<script src="jquery.min.js"></script>',
48-
ngMin = '<script src="../angular.min.js" ng:autobind></script>',
49-
ng = '<script src="../angular.js" ng:autobind></script>';
46+
var manifest = 'manifest="/build/docs/appcache.manifest"';
5047

5148
writesFuture.push(writer.copy('docs/src/templates/index.html', 'build/docs/index.html',
52-
writer.replace, {'doc:manifest': manifest,
53-
'<!-- angular script place holder -->': ngMin}));
49+
writer.replace, {'doc:manifest': manifest}));
5450

5551
writesFuture.push(writer.copy('docs/src/templates/index.html', 'build/docs/index-jq.html',
56-
writer.replace, {'doc:manifest': manifest,
57-
'<!-- angular script place holder -->': ngMin,
58-
'<!-- jquery place holder -->': jq}));
52+
writer.replace, {'doc:manifest': manifest}));
5953

6054
writesFuture.push(writer.copy('docs/src/templates/index.html', 'build/docs/index-debug.html',
61-
writer.replace, {'doc:manifest': '',
62-
'<!-- angular script place holder -->': ng}));
55+
writer.replace, {'doc:manifest': ''}));
6356

6457
writesFuture.push(writer.copy('docs/src/templates/index.html', 'build/docs/index-jq-debug.html',
65-
writer.replace, {'doc:manifest': '',
66-
'<!-- angular script place holder -->': ng,
67-
'<!-- jquery place holder -->': jq}));
58+
writer.replace, {'doc:manifest': ''}));
6859

6960
writesFuture.push(writer.copyTpl('offline.html'));
7061
writesFuture.push(writer.copyTpl('docs-scenario.html'));

docs/src/ngdoc.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ Doc.prototype = {
133133

134134
if (!isFullUrl) self.links.push(absUrl);
135135

136-
return '<a href="' + (isFullUrl ? '' + url : '#!/' + absUrl) + '">'
136+
return '<a href="' + absUrl + '">'
137137
+ (isAngular ? '<code>' : '')
138138
+ (title || url).replace(/\n/g, ' ')
139139
+ (isAngular ? '</code>' : '')
@@ -243,7 +243,7 @@ Doc.prototype = {
243243
}
244244
dom.h('Dependencies', self.requires, function(require){
245245
dom.tag('code', function(){
246-
dom.tag('a', {href:"#!/api/angular.service." + require.name}, require.name);
246+
dom.tag('a', {href: 'api/angular.service.' + require.name}, require.name);
247247
});
248248
dom.html(require.text);
249249
});
@@ -570,23 +570,23 @@ function scenarios(docs){
570570
var specs = [];
571571

572572
specs.push('describe("angular+jqlite", function() {');
573-
appendSpecs('index.html');
573+
appendSpecs('');
574574
specs.push('});');
575575

576576
specs.push('');
577577
specs.push('');
578578

579579
specs.push('describe("angular+jquery", function() {');
580-
appendSpecs('index-jq.html');
580+
appendSpecs('index-jq.html#!/');
581581
specs.push('});');
582582

583583
return specs.join('\n');
584584

585-
function appendSpecs(htmlFile) {
585+
function appendSpecs(urlPrefix) {
586586
docs.forEach(function(doc){
587587
specs.push(' describe("' + doc.section + '/' + doc.id + '", function(){');
588588
specs.push(' beforeEach(function(){');
589-
specs.push(' browser().navigateTo("' + htmlFile + '#!/' + doc.section + '/' + doc.id + '");');
589+
specs.push(' browser().navigateTo("' + urlPrefix + doc.section + '/' + doc.id + '");');
590590
specs.push(' });');
591591
specs.push(' ');
592592
doc.scenarios.forEach(function(scenario){

docs/src/templates/.htaccess

+5-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@
88

99
RewriteEngine on
1010
RewriteCond %{HTTP_COOKIE} ng-offline="NG_VERSION_FULL"
11-
RewriteRule appcache.manifest appcache-offline.manifest
11+
RewriteRule appcache.manifest appcache-offline.manifest
12+
13+
14+
## HTML5 URL Support ##
15+
RewriteRule ^(guide|api|cookbook|misc|tutorial)(/.*)?$ index.html

docs/src/templates/docs.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ function DocsController($location, $browser, $window, $cookies) {
44

55
var self = this,
66
OFFLINE_COOKIE_NAME = 'ng-offline',
7-
DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)/;
7+
DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)/,
8+
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
89

910
this.$location = $location;
1011

@@ -13,7 +14,7 @@ function DocsController($location, $browser, $window, $cookies) {
1314
self.subpage = false;
1415
self.offlineEnabled = ($cookies[OFFLINE_COOKIE_NAME] == angular.version.full);
1516

16-
if (!$location.path()) {
17+
if (!$location.path() || INDEX_PATH.test($location.path())) {
1718
$location.path('/api').replace();
1819
}
1920

@@ -40,11 +41,11 @@ function DocsController($location, $browser, $window, $cookies) {
4041
});
4142

4243
this.getUrl = function(page){
43-
return '#!/' + page.section + '/' + page.id;
44+
return page.section + '/' + page.id;
4445
};
4546

4647
this.getCurrentPartial = function(){
47-
return this.partialId ? ('./' + this.sectionId + '/' + this.partialId + '.html') : '';
48+
return this.partialId ? ('./partials/' + this.sectionId + '/' + this.partialId + '.html') : '';
4849
};
4950

5051
this.getClass = function(page) {
@@ -127,7 +128,7 @@ function TutorialInstructionsCtrl($cookieStore) {
127128

128129
angular.service('$locationConfig', function() {
129130
return {
130-
html5Mode: false,
131+
html5Mode: true,
131132
hashPrefix: '!'
132133
};
133134
});

0 commit comments

Comments
 (0)