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

Commit ace40d5

Browse files
committedSep 23, 2014
chore(docs): refactor the docs app search for better bootup time
This commit refactors how the search index is built. The docsSearch service is now defined by a provider, which returns a different implementation of the service depending upon whether the current browser supports WebWorkers or now. * **WebWorker supported**: The index is then built and stored in a new worker. The service posts and receives messages to and from this worker to make queries on the search index. * **WebWorker no supported**: The index is built locally but with a 500ms delay so that the initial page can render before the browser is blocked as the index is built. Also the way that the current app is identified has been modified so we can slim down the js data files (pages-data.js) to again improve startup time. Closes #9204 Closes #9203
1 parent fd89975 commit ace40d5

19 files changed

+260
-213
lines changed
 

‎docs/app/assets/css/docs.css

+3-3
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,10 @@ iframe.example {
316316
}
317317

318318
.search-results-group.col-group-api { width:30%; }
319-
.search-results-group.col-group-guide { width:30%; }
320-
.search-results-group.col-group-tutorial { width:25%; }
319+
.search-results-group.col-group-guide,
320+
.search-results-group.col-group-tutorial { width:20%; }
321321
.search-results-group.col-group-misc,
322-
.search-results-group.col-group-error { float:right; clear:both; width:15% }
322+
.search-results-group.col-group-error { width:15%; float: right; }
323323

324324

325325
.search-results-group.col-group-api .search-result {

‎docs/app/assets/js/search-worker.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"use strict";
2+
/* jshint browser: true */
3+
/* global importScripts, onmessage: true, postMessage, lunr */
4+
5+
// Load up the lunr library
6+
importScripts('../components/lunr.js-0.4.2/lunr.min.js');
7+
8+
// Create the lunr index - the docs should be an array of object, each object containing
9+
// the path and search terms for a page
10+
var index = lunr(function() {
11+
this.ref('path');
12+
this.field('titleWords', {boost: 50});
13+
this.field('members', { boost: 40});
14+
this.field('keywords', { boost : 20 });
15+
});
16+
17+
// Retrieve the searchData which contains the information about each page to be indexed
18+
var searchData = {};
19+
var searchDataRequest = new XMLHttpRequest();
20+
searchDataRequest.onload = function() {
21+
22+
// Store the pages data to be used in mapping query results back to pages
23+
searchData = JSON.parse(this.responseText);
24+
// Add search terms from each page to the search index
25+
searchData.forEach(function(page) {
26+
index.add(page);
27+
});
28+
postMessage({ e: 'index-ready' });
29+
};
30+
searchDataRequest.open('GET', 'search-data.json');
31+
searchDataRequest.send();
32+
33+
// The worker receives a message everytime the web app wants to query the index
34+
onmessage = function(oEvent) {
35+
var q = oEvent.data.q;
36+
var hits = index.search(q);
37+
var results = [];
38+
// Only return the array of paths to pages
39+
hits.forEach(function(hit) {
40+
results.push(hit.ref);
41+
});
42+
// The results of the query are sent back to the web app via a new message
43+
postMessage({ e: 'query-ready', q: q, d: results });
44+
};

‎docs/app/e2e/app.scenario.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,13 @@ describe('docs.angularjs.org', function () {
7777
});
7878

7979

80-
it("should display an error if the page does not exist", function() {
81-
browser.get('index-debug.html#!/api/does/not/exist');
82-
expect(element(by.css('h1')).getText()).toBe('Oops!');
83-
});
8480
});
8581

8682
});
83+
84+
describe('Error Handling', function() {
85+
it("should display an error if the page does not exist", function() {
86+
browser.get('index-debug.html#!/api/does/not/exist');
87+
expect(element(by.css('h1')).getText()).toBe('Oops!');
88+
});
89+
});

‎docs/app/src/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ angular.module('docsApp', [
66
'DocsController',
77
'versionsData',
88
'pagesData',
9+
'navData',
910
'directives',
1011
'errors',
1112
'examples',

‎docs/app/src/docs.js

+11-71
Original file line numberDiff line numberDiff line change
@@ -6,87 +6,39 @@ angular.module('DocsController', [])
66
function($scope, $rootScope, $location, $window, $cookies, openPlunkr,
77
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
88

9-
109
$scope.openPlunkr = openPlunkr;
1110

1211
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
1312

14-
$scope.fold = function(url) {
15-
if(url) {
16-
$scope.docs_fold = '/notes/' + url;
17-
if(/\/build/.test($window.location.href)) {
18-
$scope.docs_fold = '/build/docs' + $scope.docs_fold;
19-
}
20-
window.scrollTo(0,0);
21-
}
22-
else {
23-
$scope.docs_fold = null;
24-
}
25-
};
26-
var OFFLINE_COOKIE_NAME = 'ng-offline',
27-
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
28-
29-
30-
/**********************************
31-
Publish methods
32-
***********************************/
33-
3413
$scope.navClass = function(navItem) {
3514
return {
3615
active: navItem.href && this.currentPage && this.currentPage.path,
3716
'nav-index-section': navItem.type === 'section'
3817
};
3918
};
4019

41-
$scope.afterPartialLoaded = function() {
42-
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
43-
$window._gaq.push(['_trackPageview', pagePath]);
44-
};
45-
46-
/** stores a cookie that is used by apache to decide which manifest ot send */
47-
$scope.enableOffline = function() {
48-
//The cookie will be good for one year!
49-
var date = new Date();
50-
date.setTime(date.getTime()+(365*24*60*60*1000));
51-
var expires = "; expires="+date.toGMTString();
52-
var value = angular.version.full;
53-
document.cookie = OFFLINE_COOKIE_NAME + "="+value+expires+"; path=" + $location.path;
54-
55-
//force the page to reload so server can serve new manifest file
56-
window.location.reload(true);
57-
};
5820

5921

22+
$scope.$on('$includeContentLoaded', function() {
23+
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
24+
$window._gaq.push(['_trackPageview', pagePath]);
25+
});
6026

61-
/**********************************
62-
Watches
63-
***********************************/
27+
$scope.$on('$includeContentError', function() {
28+
$scope.partialPath = 'Error404.html';
29+
});
6430

6531

6632
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
6733

68-
var currentPage = $scope.currentPage = NG_PAGES[path];
69-
if ( !currentPage && path.charAt(0)==='/' ) {
70-
// Strip off leading slash
71-
path = path.substr(1);
72-
}
73-
74-
currentPage = $scope.currentPage = NG_PAGES[path];
75-
if ( !currentPage && path.charAt(path.length-1) === '/' && path.length > 1 ) {
76-
// Strip off trailing slash
77-
path = path.substr(0, path.length-1);
78-
}
34+
path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
7935

80-
currentPage = $scope.currentPage = NG_PAGES[path];
81-
if ( !currentPage && /\/index$/.test(path) ) {
82-
// Strip off index from the end
83-
path = path.substr(0, path.length - 6);
84-
}
36+
$scope.partialPath = 'partials/' + path + '.html';
8537

8638
currentPage = $scope.currentPage = NG_PAGES[path];
8739

8840
if ( currentPage ) {
89-
$scope.currentArea = currentPage && NG_NAVIGATION[currentPage.area];
41+
$scope.currentArea = NG_NAVIGATION[currentPage.area];
9042
var pathParts = currentPage.path.split('/');
9143
var breadcrumb = $scope.breadcrumb = [];
9244
var breadcrumbPath = '';
@@ -107,24 +59,12 @@ angular.module('DocsController', [])
10759

10860
$scope.versionNumber = angular.version.full;
10961
$scope.version = angular.version.full + " " + angular.version.codeName;
110-
$scope.subpage = false;
111-
$scope.offlineEnabled = ($cookies[OFFLINE_COOKIE_NAME] == angular.version.full);
112-
$scope.futurePartialTitle = null;
11362
$scope.loading = 0;
114-
$scope.$cookies = $cookies;
11563

116-
$cookies.platformPreference = $cookies.platformPreference || 'gitUnix';
11764

65+
var INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
11866
if (!$location.path() || INDEX_PATH.test($location.path())) {
11967
$location.path('/api').replace();
12068
}
12169

122-
// bind escape to hash reset callback
123-
angular.element(window).on('keydown', function(e) {
124-
if (e.keyCode === 27) {
125-
$scope.$apply(function() {
126-
$scope.subpage = false;
127-
});
128-
}
129-
});
13070
}]);

‎docs/app/src/navigationService.js

-24
This file was deleted.

0 commit comments

Comments
 (0)
This repository has been archived.