From c820655ccd64ce9b74f72ea0e73edaf1f15713f9 Mon Sep 17 00:00:00 2001 From: Georgios Kalpakas Date: Fri, 28 Nov 2014 17:59:08 +0200 Subject: [PATCH] docs(app): minor refactoring of 'docs/app/src/*' --- docs/app/src/app.js | 2 ++ docs/app/src/directives.js | 8 ++--- docs/app/src/docs.js | 6 ++-- docs/app/src/errors.js | 20 +++++------ docs/app/src/examples.js | 4 +-- docs/app/src/search.js | 74 ++++++++++++++++++++++---------------- docs/app/src/tutorials.js | 10 +++--- docs/app/src/versions.js | 34 +++++++++++++----- 8 files changed, 96 insertions(+), 62 deletions(-) diff --git a/docs/app/src/app.js b/docs/app/src/app.js index 53ef4881..7fa4c88e 100644 --- a/docs/app/src/app.js +++ b/docs/app/src/app.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('docsApp', [ 'ngMaterial', 'DocsController', diff --git a/docs/app/src/directives.js b/docs/app/src/directives.js index 4c3acf78..ed216153 100644 --- a/docs/app/src/directives.js +++ b/docs/app/src/directives.js @@ -10,13 +10,13 @@ angular.module('directives', []) return function link(scope, element) { element.on('click', function(event) { $location.hash(''); - scope.$apply($anchorScroll); + $anchorScroll(); }); }; }]) -.directive('code', function() { +.directive('code', ['$window', function($window) { return { restrict: 'E', terminal: true, @@ -25,10 +25,10 @@ angular.module('directives', []) var match = /lang-(\S+)/.exec(element[0].className); var lang = match && match[1]; var html = element.html(); - element.html(window.prettyPrintOne(html, lang, linenums)); + element.html($window.prettyPrintOne(html, lang, linenums)); } }; -}) +}]) .directive('scrollYOffsetElement', ['$anchorScroll', function($anchorScroll) { return function(scope, element) { diff --git a/docs/app/src/docs.js b/docs/app/src/docs.js index 1cdfed45..358829b6 100644 --- a/docs/app/src/docs.js +++ b/docs/app/src/docs.js @@ -25,13 +25,13 @@ angular.module('DocsController', []) $window._gaq.push(['_trackPageview', pagePath]); }); - $scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) { + $scope.$watch(function docsPathWatch() { return $location.path(); }, function docsPathWatchAction(path) { path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1'); - currentPage = $scope.currentPage = NG_PAGES[path]; + var currentPage = $scope.currentPage = NG_PAGES[path]; - if ( currentPage ) { + if (currentPage) { $scope.partialPath = 'partials/' + path + '.html'; $scope.currentArea = NG_NAVIGATION[currentPage.area]; var pathParts = currentPage.path.split('/'); diff --git a/docs/app/src/errors.js b/docs/app/src/errors.js index bd7f6bbe..a822f827 100644 --- a/docs/app/src/errors.js +++ b/docs/app/src/errors.js @@ -1,23 +1,23 @@ angular.module('errors', ['ngSanitize']) -.filter('errorLink', ['$sanitize', function ($sanitize) { +.filter('errorLink', ['$sanitize', function($sanitize) { var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}<>]/g, MAILTO_REGEXP = /^mailto:/, STACK_TRACE_REGEXP = /:\d+:\d+$/; - var truncate = function (text, nchars) { + var truncate = function(text, nchars) { if (text.length > nchars) { return text.substr(0, nchars - 3) + '...'; } return text; }; - return function (text, target) { + return function(text, target) { var targetHtml = target ? ' target="' + target + '"' : ''; if (!text) return text; - return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) { + return $sanitize(text.replace(LINKY_URL_REGEXP, function(url) { if (STACK_TRACE_REGEXP.test(url)) { return url; } @@ -47,16 +47,14 @@ angular.module('errors', ['ngSanitize']) }); }; - return { - link: function (scope, element, attrs) { - var search = $location.search(), + return function (scope, element, attrs) { + var search = $location.search(), formatArgs = [attrs.errorDisplay], i; - for (i = 0; angular.isDefined(search['p'+i]); i++) { - formatArgs.push(search['p'+i]); - } - element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank')); + for (i = 0; angular.isDefined(search['p'+i]); i++) { + formatArgs.push(search['p'+i]); } + element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank')); }; }]); diff --git a/docs/app/src/examples.js b/docs/app/src/examples.js index 2d882ea2..029307bd 100644 --- a/docs/app/src/examples.js +++ b/docs/app/src/examples.js @@ -2,7 +2,7 @@ angular.module('examples', []) .factory('formPostData', ['$document', function($document) { return function(url, fields) { - /** + /* * Form previously posted to target="_blank", but pop-up blockers were causing this to not work. * If a user chose to bypass pop-up blocker one time and click the link, they would arrive at * a new default plnkr, not a plnkr with the desired template. @@ -48,7 +48,7 @@ angular.module('examples', []) // The manifests provide the production index file but Plunkr wants // a straight index.html if (filename === "index-production.html") { - filename = "index.html" + filename = "index.html"; } return { diff --git a/docs/app/src/search.js b/docs/app/src/search.js index 8fc598e0..0d6fd5c1 100644 --- a/docs/app/src/search.js +++ b/docs/app/src/search.js @@ -15,25 +15,21 @@ angular.module('search', []) angular.forEach(hits, function(hit) { var area = hit.area; - var limit = (area == 'api') ? 40 : 14; + var limit = (area === 'api') ? 40 : 14; results[area] = results[area] || []; if(results[area].length < limit) { results[area].push(hit); } }); - var totalAreas = 0; - for(var i in results) { - ++totalAreas; - } + var totalAreas = Object.keys(results).length; if(totalAreas > 0) { $scope.colClassName = 'cols-' + totalAreas; } $scope.hasResults = totalAreas > 0; $scope.results = results; }); - } - else { + } else { clearResults(); } if(!$scope.$$phase) $scope.$apply(); @@ -65,16 +61,17 @@ angular.module('search', []) .controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch', - function($scope, $location, docsSearch) { - docsSearch($location.path().split(/[\/\.:]/).pop()).then(function(results) { - $scope.results = {}; - angular.forEach(results, function(result) { - var area = $scope.results[result.area] || []; - area.push(result); - $scope.results[result.area] = area; + function($scope, $location, docsSearch) { + docsSearch($location.path().split(/[\/\.:]/).pop()).then(function(results) { + $scope.results = {}; + angular.forEach(results, function(result) { + var area = $scope.results[result.area] || []; + area.push(result); + $scope.results[result.area] = area; + }); }); - }); -}]) + } +]) .provider('docsSearch', function() { @@ -82,9 +79,9 @@ angular.module('search', []) // This version of the service builds the index in the current thread, // which blocks rendering and other browser activities. // It should only be used where the browser does not support WebWorkers - function localSearchFactory($http, $timeout, NG_PAGES) { + function localSearchFactory($http, $log, $timeout, NG_PAGES) { - console.log('Using Local Search Index'); + $log.log('Using Local Search Index'); // Create the lunr index var index = lunr(function() { @@ -121,14 +118,14 @@ angular.module('search', []) }); }; } - localSearchFactory.$inject = ['$http', '$timeout', 'NG_PAGES']; + localSearchFactory.$inject = ['$http', '$log', '$timeout', 'NG_PAGES']; // This version of the service builds the index in a WebWorker, // which does not block rendering and other browser activities. // It should only be used where the browser does support WebWorkers - function webWorkerSearchFactory($q, $rootScope, NG_PAGES) { + function webWorkerSearchFactory($log, $q, $rootScope, NG_PAGES) { - console.log('Using WebWorker Search Index') + $log.log('Using WebWorker Search Index'); var searchIndex = $q.defer(); var results; @@ -163,14 +160,15 @@ angular.module('search', []) return searchIndex.promise.then(function() { results = $q.defer(); - worker.postMessage({ q: q }); + worker.postMessage({q: q}); return results.promise; }); }; } - webWorkerSearchFactory.$inject = ['$q', '$rootScope', 'NG_PAGES']; + webWorkerSearchFactory.$inject = ['$log', '$q', '$rootScope', 'NG_PAGES']; return { + // TODO(gkalpak): Would be nice to use `$window` (e.g. for easier testing) $get: window.Worker ? webWorkerSearchFactory : localSearchFactory }; }) @@ -188,31 +186,47 @@ angular.module('search', []) scope.$eval(attrs.focused + '=false'); }); }); + // TODO(gkalpak): Do we need this if we first register the listeners + // and the call `.focus()` ? scope.$eval(attrs.focused + '=true'); }; }) -.directive('docsSearchInput', ['$document',function($document) { +.directive('docsSearchInput', ['$document', function($document) { + var doc = $document[0]; + var body = angular.element(doc.body); + return function(scope, element, attrs) { var ESCAPE_KEY_KEYCODE = 27, FORWARD_SLASH_KEYCODE = 191; - angular.element($document[0].body).on('keydown', function(event) { + + element.on('keydown', onInputKeydown); + body.on('keydown', onBodyKeydown); + + // Since we are attaching a listener to , + // it is a good idea to detach it upon scope destruction + // (Not likely to happen with the current implemetation, but...things change.) + scope.$on('$destroy', function() { + body.off('keydown', onBodyKeydown); + }); + + function onBodyKeydown(event) { var input = element[0]; - if(event.keyCode == FORWARD_SLASH_KEYCODE && document.activeElement != input) { + if ((event.keyCode === FORWARD_SLASH_KEYCODE) && (doc.activeElement !== input)) { event.stopPropagation(); event.preventDefault(); input.focus(); } - }); + } - element.on('keydown', function(event) { - if(event.keyCode == ESCAPE_KEY_KEYCODE) { + function onInputKeydown(event) { + if (event.keyCode === ESCAPE_KEY_KEYCODE) { event.stopPropagation(); event.preventDefault(); scope.$apply(function() { scope.hideResults(); }); } - }); + } }; }]); diff --git a/docs/app/src/tutorials.js b/docs/app/src/tutorials.js index 639b8059..3249301b 100644 --- a/docs/app/src/tutorials.js +++ b/docs/app/src/tutorials.js @@ -10,8 +10,9 @@ angular.module('tutorials', []) return { scope: {}, template: + // TODO(gkalpak): Remove Bootstrap-specific staff '
  • Previous
  • \n' + - '
  • Live Demo
  • \n' + + '
  • Live Demo
  • \n' + '
  • Code Diff
  • \n' + '
  • Next
  • ', link: function(scope, element, attrs) { @@ -32,18 +33,19 @@ angular.module('tutorials', []) .directive('docTutorialReset', function() { return { scope: { - 'step': '@docTutorialReset' + step: '@docTutorialReset' }, template: + // TODO(gkalpak): Remove Bootstrap-specific staff '

    Workspace Reset Instructions ➤

    \n' + '
    \n' + '

    Reset the workspace to step {{step}}.

    ' + '

    git checkout -f step-{{step}}

    \n' + '

    Refresh your browser or check out this step online: '+ - 'Step {{step}} Live Demo.

    \n' + + 'Step {{step}} Live Demo.

    \n' + '
    \n' + '

    The most important changes are listed below. You can see the full diff on ' + 'GitHub\n' + '

    ' }; -}); \ No newline at end of file +}); diff --git a/docs/app/src/versions.js b/docs/app/src/versions.js index 6899bb6f..0ad055f9 100644 --- a/docs/app/src/versions.js +++ b/docs/app/src/versions.js @@ -2,8 +2,9 @@ angular.module('versions', []) .controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) { $scope.docs_version = NG_VERSIONS[0]; + $scope.docs_versions = NG_VERSIONS; - for(var i=0, minor = NaN; i < NG_VERSIONS.length; i++) { + for (var i = 0, ii = NG_VERSIONS.length, minor = NaN; i < ii; i++) { var version = NG_VERSIONS[i]; // NaN will give false here if (minor <= version.minor) { @@ -13,17 +14,34 @@ angular.module('versions', []) minor = version.minor; } - $scope.docs_versions = NG_VERSIONS; - $scope.getGroupName = function(v) { - return v.isLatest ? 'Latest' : (v.isStable ? 'Stable' : 'Unstable'); - }; + $scope.getGroupName = getGroupName; + $scope.groupBy = groupBy; + $scope.jumpToDocsVersion = jumpToDocsVersion; - $scope.jumpToDocsVersion = function(version) { + function getGroupName(v) { + return v.isLatest ? 'Latest' : ('v' + v.major + '.' + v.minor + '.x'); + } + + // TODO(gkalpak): Do we really need this as a "public" function ? + // Would a one-time groupping (in JS) be sufficient ? + function groupBy(items, prop) { + var groupped = {}; + var getter = angular.isFunction(prop) ? prop : function(item) { return item[prop]; }; + + items.forEach(function(item) { + var groupName = getter(item); + var groupList = groupped[groupName] = (groupped[groupName] || []); + groupList.push(item); + }); + + return groupped; + } + + function jumpToDocsVersion(version) { var currentPagePath = $location.path().replace(/\/$/, ''); // TODO: We need to do some munging of the path for different versions of the API... - $window.location = version.docsUrl + currentPagePath; - }; + } }]);