Merge: nitweb: use ui-router
authorJean Privat <jean@pryen.org>
Mon, 12 Jun 2017 20:39:34 +0000 (16:39 -0400)
committerJean Privat <jean@pryen.org>
Mon, 12 Jun 2017 20:39:34 +0000 (16:39 -0400)
A lot of refactoring to replace ng-router by ui-router.

The finality is to provide direct links within documentations tabs:
 * link to dependencies: http://nitweb.moz-code.org/doc/core/graph
 * link to code: http://nitweb.moz-code.org/doc/core::kernel/code
 * link to linearization: http://nitweb.moz-code.org/doc/core::Array/lin

Also removed the special pages for mclassdefs and mpropdefs. They now link directly to their relative mclass/mproperty linearization:
* http://nitweb.moz-code.org/doc/core::Array/lin#pthreads::redef_collections$core::Array
* http://nitweb.moz-code.org/doc/core::SimpleCollection::add_all/lin#core$CircularArray$SimpleCollection::add_all

Demo: http://nitweb.moz-code.org/

Fixes #2177

Pull-Request: #2489

42 files changed:
share/nitweb/directives/entity/defcard.html
share/nitweb/directives/entity/link.html
share/nitweb/directives/metrics/chart_properties.html
share/nitweb/directives/metrics/metrics_list.html
share/nitweb/directives/ui/search-field.html [new file with mode: 0644]
share/nitweb/index.html
share/nitweb/javascripts/docdown.js
share/nitweb/javascripts/entities.js
share/nitweb/javascripts/grades.js
share/nitweb/javascripts/index.js
share/nitweb/javascripts/metrics.js
share/nitweb/javascripts/model.js [deleted file]
share/nitweb/javascripts/nitweb.js
share/nitweb/javascripts/ui.js
share/nitweb/javascripts/users.js
share/nitweb/stylesheets/cards.css [new file with mode: 0644]
share/nitweb/stylesheets/nitlight.css [new file with mode: 0644]
share/nitweb/stylesheets/nitweb.css
share/nitweb/stylesheets/nitweb_bootstrap.css
share/nitweb/stylesheets/search.css [new file with mode: 0644]
share/nitweb/views/catalog/by_tags.html [new file with mode: 0644]
share/nitweb/views/catalog/highlighted.html [new file with mode: 0644]
share/nitweb/views/catalog/index.html [new file with mode: 0644]
share/nitweb/views/catalog/most_required.html [new file with mode: 0644]
share/nitweb/views/class.html [deleted file]
share/nitweb/views/classdef.html [deleted file]
share/nitweb/views/doc/all.html [new file with mode: 0644]
share/nitweb/views/doc/code.html [new file with mode: 0644]
share/nitweb/views/doc/defs.html [new file with mode: 0644]
share/nitweb/views/doc/doc.html [new file with mode: 0644]
share/nitweb/views/doc/entity.html [new file with mode: 0644]
share/nitweb/views/doc/graph.html [new file with mode: 0644]
share/nitweb/views/doc/index.html [new file with mode: 0644]
share/nitweb/views/doc/lin.html [new file with mode: 0644]
share/nitweb/views/doc/metrics.html [new file with mode: 0644]
share/nitweb/views/group.html [deleted file]
share/nitweb/views/index.html [deleted file]
share/nitweb/views/module.html [deleted file]
share/nitweb/views/package.html [deleted file]
share/nitweb/views/propdef.html [deleted file]
share/nitweb/views/property.html [deleted file]
src/web/web_base.nit

index ddbef3b..2d14d83 100644 (file)
@@ -1,4 +1,4 @@
-<div class='card card-xl' ng-class='{active: isActive()}'>
+<div class='card card-xl' ng-class='{active: isActive()}' id='{{definition.full_name}}'>
        <div class='card-body'>
                <h5>
                        <span ng-if='definition.is_intro'>
index ae57696..740ea8b 100644 (file)
@@ -1,3 +1,3 @@
 <span>
-       <a ng-href='{{mentity.web_url | encodeURI}}'>{{mentity.name}}</a>
+       <a ng-href='{{mentity.web_url}}'>{{mentity.name}}</a>
 </span>
index 1a1916b..5873d28 100644 (file)
@@ -1,4 +1,4 @@
-<div class='card'>
+<div class='card' ng-if='listMetrics'>
        <div class='card-body'>
                <h4 class='card-heading'>{{listTitle}}</h4>
                <table class='table'>
diff --git a/share/nitweb/directives/ui/search-field.html b/share/nitweb/directives/ui/search-field.html
new file mode 100644 (file)
index 0000000..e0bd4fd
--- /dev/null
@@ -0,0 +1,8 @@
+<form style='margin-bottom: 0'>
+       <div class='form-group has-icon'>
+               <input placeholder='Search...' type='text' class='form-control search-input'
+                       ng-model-options='{ debounce: 300 }' ng-model='vm.query'
+                       ng-keydown='update($event)' ng-change='vm.search()'>
+               <span class='glyphicon glyphicon-search form-control-icon text-muted'></span>
+       </div>
+</form>
index 138955b..2812b99 100644 (file)
                        type='text/css' rel='stylesheet'>
 
 
-               <link href='/stylesheets/nitweb_bootstrap.css' rel='stylesheet'>
-               <link href='/stylesheets/nitweb.css' rel='stylesheet'>
+               <link rel='stylesheet' href='/stylesheets/nitweb_bootstrap.css'>
+               <link rel='stylesheet' href='/stylesheets/nitweb.css'>
+               <link rel='stylesheet' href='/stylesheets/nitlight.css'>
+               <link rel='stylesheet' href='/stylesheets/search.css'>
+               <link rel='stylesheet' href='/stylesheets/cards.css'>
 
                <script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.4/d3.min.js"></script>
                <script src="/vendors/d3pie.min.js"></script>
@@ -51,7 +54,7 @@
                                </div>
                        </div>
                </nav>
-               <div ng-view></div>
+               <ui-view></ui-view>
 
                <script src='https://code.jquery.com/jquery-1.12.4.min.js'
                        integrity='sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ='
                        crossorigin='anonymous'></script>
                <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js'>
                </script>
-               <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-route.js'>
-               </script>
+               <script src='http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js'></script>
                <script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js'>
                </script>
                <script src='//cdnjs.cloudflare.com/ajax/libs/angular-loading-bar/0.9.0/loading-bar.min.js'>
                </script>
 
                <script src='/javascripts/nitweb.js'></script>
-               <script src='/javascripts/model.js'></script>
                <script src='/javascripts/entities.js'></script>
                <script src='/javascripts/ui.js'></script>
                <script src='/javascripts/index.js'></script>
index 365b8c9..2b96d19 100644 (file)
 
 (function() {
        angular
-               .module('docdown', ['model', 'ngSanitize'])
+               .module('docdown', ['ngSanitize'])
 
-               .controller('DocdownCtrl', ['$routeParams', '$sce', '$scope', '$location', 'DocDown', function($routeParams, $sce, $scope, $location, DocDown) {
+               .config(function($stateProvider, $locationProvider) {
+                       $stateProvider
+                               .state('docdown', {
+                                       url: '/docdown',
+                                       templateUrl: 'views/docdown.html',
+                                       controller: 'DocdownCtrl',
+                                       controllerAs: 'docdownCtrl'
+                               })
+               })
+
+               .factory('DocDown', [ '$http', function($http) {
+                       return {
+                               postMarkdown: function(md, cb, cbErr) {
+                                       $http.post('/api/docdown', md)
+                                               .success(cb)
+                                               .error(cbErr);
+                               }
+                       }
+               }])
+
+               .controller('DocdownCtrl', ['$sce', '$scope', '$location', 'DocDown', function($sce, $scope, $location, DocDown) {
 
                        this.updateSnippet = function() {
                                this.updateLink();
index e48b40a..d5dd3ef 100644 (file)
 
 (function() {
        angular
-               .module('entities', ['ngSanitize', 'ui', 'model'])
+               .module('entities', ['ngSanitize', 'ui'])
 
-               .controller('EntityCtrl', ['Model', 'Metrics', 'Feedback', '$routeParams', '$scope', '$sce', function(Model, Metrics, Feedback, $routeParams, $scope, $sce) {
-                       $scope.entityId = $routeParams.id;
+               /* Router */
 
-                       this.loadEntityLinearization = function() {
-                               Model.loadEntityLinearization($routeParams.id,
-                                       function(data) {
-                                               $scope.linearization = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+               .config(function($stateProvider, $locationProvider) {
+                       $stateProvider
+                               .state('doc', {
+                                       url: '/doc/:id',
+                                       templateUrl: 'views/doc/index.html',
+                                       resolve: {
+                                               mentity: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntity($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity) {
+                                               this.mentity = mentity;
+                                       },
+                                       controllerAs: 'vm',
+                                       abstract: true
+                               })
+                               .state('doc.entity', {
+                                       url: '',
+                                       templateUrl: 'views/doc/entity.html',
+                                       controller: function(mentity) {
+                                               this.mentity = mentity;
+                                       },
+                                       controllerAs: 'vm',
+                                       abstract: true
+                               })
+                               .state('doc.entity.doc', {
+                                       url: '',
+                                       templateUrl: 'views/doc/doc.html',
+                                       controller: function(mentity) {
+                                               this.mentity = mentity;
+                                       },
+                                       controllerAs: 'vm',
+                               })
+                               .state('doc.entity.graph', {
+                                       url: '/graph',
+                                       templateUrl: 'views/doc/graph.html',
+                                       resolve: {
+                                               graph: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntityGraph($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(graph, $sce) {
+                                               this.graph = $sce.trustAsHtml(graph);
+                                       },
+                                       controllerAs: 'vm',
+                               })
+                               .state('doc.entity.metrics', {
+                                       url: '/metrics',
+                                       templateUrl: 'views/doc/metrics.html',
+                                       resolve: {
+                                               metrics: function(Metrics, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Metrics.loadStructuralMetrics($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity, metrics) {
+                                               this.mentity = mentity;
+                                               this.metrics = metrics;
+                                       },
+                                       controllerAs: 'vm',
+                               })
+                               .state('doc.entity.code', {
+                                       url: '/code',
+                                       templateUrl: 'views/doc/code.html',
+                                       resolve: {
+                                               code: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntityCode($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity, code) {
+                                               this.mentity = mentity;
+                                               this.code = code;
+                                       },
+                                       controllerAs: 'vm',
+                               })
+                               .state('doc.entity.defs', {
+                                       url: '/defs',
+                                       templateUrl: 'views/doc/defs.html',
+                                       resolve: {
+                                               defs: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntityDefs($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity, defs) {
+                                               this.mentity = mentity;
+                                               this.defs = defs;
+                                       },
+                                       controllerAs: 'vm',
+                               })
+                               .state('doc.entity.lin', {
+                                       url: '/lin',
+                                       templateUrl: 'views/doc/lin.html',
+                                       resolve: {
+                                               lin: function(Model, $q, $stateParams, $state) {
+                                                       var d = $q.defer();
+                                                       Model.loadEntityLinearization($stateParams.id, d.resolve,
+                                                               function() {
+                                                                       $state.go('404', null, { location: false })
+                                                               });
+                                                       return d.promise;
+                                               }
+                                       },
+                                       controller: function(mentity, lin, $scope, $location, $anchorScroll) {
+                                               var vm = this;
+                                               vm.focus = $location.hash() ?
+                                                       $location.hash() : mentity.intro.full_name;
+                                               vm.mentity = mentity;
+                                               vm.linearization = lin;
+                                               setTimeout(function() {
+                                                       $anchorScroll();
+                                               }, 400);
+                                               $scope.$watch(function () {
+                                                       return $location.hash();
+                                               }, function (value) {
+                                                       vm.focus = $location.hash() ?
+                                                               $location.hash() : mentity.intro.full_name;
+                                                       $anchorScroll();
+                                               });
+                                       },
+                                       controllerAs: 'vm'
+                               })
+                               .state('doc.entity.all', {
+                                       url: '/all',
+                                       templateUrl: 'views/doc/all.html',
+                                       controller: function(mentity) {
+                                               this.mentity = mentity;
+                                       },
+                                       controllerAs: 'vm',
+                               })
+               })
 
-                       this.loadEntityDefs = function() {
-                               Model.loadEntityDefs($routeParams.id,
-                                       function(data) {
-                                               $scope.defs = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+               /* Model */
 
-                       this.loadEntityCode = function() {
-                               Model.loadEntityCode($routeParams.id,
-                                       function(data) {
-                                               $scope.code = data;
-                                       }, function(err) {
-                                               $scope.code = err;
-                                       });
-                       };
+               .factory('Model', [ '$http', function($http) {
+                       return {
 
-                       this.loadEntityGraph = function(e) {
-                               Model.loadEntityGraph($routeParams.id,
-                                       function(data) {
-                                               $scope.graph = $sce.trustAsHtml(data);
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+                               loadEntity: function(id, cb, cbErr) {
+                                       $http.get('/api/entity/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
 
-                       this.loadStructuralMetrics = function() {
-                               Metrics.loadStructuralMetrics($routeParams.id,
-                                       function(data) {
-                                               $scope.metrics = data;
-                                       }, function(message, status) {
-                                               $scope.error = {message: message, status: status};
-                                       });
-                       };
+                               loadEntityLinearization: function(id, cb, cbErr) {
+                                       $http.get('/api/linearization/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
 
-                       Model.loadEntity($routeParams.id,
-                               function(data) {
-                                       $scope.mentity = data;
-                               }, function(message, status) {
-                                       $scope.error = {message: message, status: status};
-                               });
+                               loadEntityDefs: function(id, cb, cbErr) {
+                                       $http.get('/api/defs/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadEntityCode: function(id, cb, cbErr) {
+                                       $http.get('/api/code/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadEntityGraph: function(id, cb, cbErr) {
+                                       $http.get('/api/graph/inheritance/' + id + '?cdepth=3')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               search: function(q, n, cb, cbErr) {
+                                       $http.get('/api/search?q=' + q + '&n=' + n)
+                                               .success(cb)
+                                               .error(cbErr);
+                               }
+                       };
                }])
 
+               /* Directives */
+
                .directive('entityLink', function() {
                        return {
                                restrict: 'E',
                                        $scope.codeId = 'code_' + $scope.definition.full_name.replace(/[^a-zA-Z0-9]/g, '_');
 
                                        $scope.isActive = function() {
-                                               return $scope.focus.full_name == $scope.definition.full_name;
+                                               return $scope.focus == $scope.definition.full_name;
                                        }
 
                                        $scope.loadCardCode = function() {
                                                }
                                        };
 
-                                       if($scope.isActive()) $scope.loadCardCode();
+                                       $scope.$watch('focus', function() {
+                                               if($scope.isActive()) $scope.loadCardCode();
+                                       });
                                }
                        };
                }])
index 41d6647..72eadbc 100644 (file)
 
 (function() {
        angular
-               .module('grades', ['ngSanitize', 'model'])
+               .module('grades', ['ngSanitize'])
+
+               .config(function($stateProvider, $locationProvider) {
+                       $stateProvider
+                               .state('grades', {
+                                       url: '/grades',
+                                       templateUrl: 'views/grades.html',
+                                       controller: 'GradesCtrl',
+                                       controllerAs: 'gradesCtrl'
+                               })
+               })
+
+               .factory('Feedback', [ '$http', function($http) {
+                       return {
+                               loadEntityStars: function(id, cb, cbErr) {
+                                       $http.get('/api/feedback/stars/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               loadEntityStarsDimension: function(id, dimension, cb, cbErr) {
+                                       $http.get('/api/feedback/stars/' + id + '/dimension/' + dimension)
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               postEntityStarDimension: function(id, dimension, rating, cb, cbErr) {
+                                       $http.post('/api/feedback/stars/' + id + '/dimension/' + dimension,
+                                               {rating: rating})
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               loadMostRated: function(cb, cbErr) {
+                                       $http.get('/api/feedback/grades/most')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               loadBestRated: function(cb, cbErr) {
+                                       $http.get('/api/feedback/grades/best')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               loadWorstRated: function(cb, cbErr) {
+                                       $http.get('/api/feedback/grades/worst')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               loadUsersRatings: function(cb, cbErr) {
+                                       $http.get('/api/feedback/grades/users')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                       }
+               }])
 
                .controller('GradesCtrl', ['Feedback', '$scope', function(Feedback, $scope) {
 
index 534f462..104d627 100644 (file)
 
 (function() {
        angular
-               .module('index', ['model', 'ngSanitize'])
+               .module('index', [])
 
-               .run(['$anchorScroll', function($anchorScroll) {
-                       $anchorScroll.yOffset = 80;
+               .config(function($stateProvider, $locationProvider) {
+                       $stateProvider
+                               .state('catalog', {
+                                       url: '/',
+                                       templateUrl: 'views/catalog/index.html',
+                                       controller: 'CatalogCtrl',
+                                       controllerAs: 'vm',
+                                       abstract: true
+                               })
+                               .state('catalog.highlighted', {
+                                       url: '',
+                                       templateUrl: 'views/catalog/highlighted.html',
+                                       controller: 'CatalogHighlightedCtrl',
+                                       controllerAs: 'vm'
+                               })
+                               .state('catalog.required', {
+                                       url: 'required',
+                                       templateUrl: 'views/catalog/most_required.html',
+                                       controller: 'CatalogRequiredCtrl',
+                                       controllerAs: 'vm'
+                               })
+                               .state('catalog.tags', {
+                                       url: 'tags',
+                                       templateUrl: 'views/catalog/by_tags.html',
+                                       controller: 'CatalogTagsCtrl',
+                                       controllerAs: 'vm'
+                               })
+               })
+
+               .factory('Catalog', [ '$http', function($http) {
+                       return {
+                               loadHightlighted: function(cb, cbErr) {
+                                       $http.get('/api/catalog/highlighted')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadMostRequired: function(cb, cbErr) {
+                                       $http.get('/api/catalog/required')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadByTags: function(cb, cbErr) {
+                                       $http.get('/api/catalog/bytags')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadStats: function(cb, cbErr) {
+                                       $http.get('/api/catalog/stats')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+
+                               loadContributors: function(cb, cbErr) {
+                                       $http.get('/api/catalog/contributors')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                       }
                }])
 
-               .controller('IndexCtrl', ['Catalog', '$routeParams', '$sce', '$scope', '$location', '$anchorScroll', function(Catalog, $routeParams, $sce, $scope, $location, $anchorScroll) {
-                       this.loadHighlighted = function() {
-                               Catalog.loadHightlighted(
-                                       function(data) {
-                                               $scope.highlighted = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+               .controller('CatalogCtrl', function(Catalog) {
+                       var vm = this;
 
-                       this.loadMostRequired = function() {
-                               Catalog.loadMostRequired(
-                                       function(data) {
-                                               $scope.required = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+                       Catalog.loadContributors(
+                               function(data) {
+                                       vm.contributors = data;
+                               }, function(err) {
+                                       vm.error = err;
+                               });
 
-                       this.loadByTags = function() {
-                               Catalog.loadByTags(
-                                       function(data) {
-                                               $scope.bytags = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+                       Catalog.loadStats(
+                               function(data) {
+                                       vm.stats = data;
+                               }, function(err) {
+                                       vm.error = err;
+                               });
+               })
 
-                       this.loadStats = function() {
-                               Catalog.loadStats(
-                                       function(data) {
-                                               $scope.stats = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+               .controller('CatalogHighlightedCtrl', function(Catalog) {
+                       var vm = this;
 
-                       this.loadContributors = function() {
-                               Catalog.loadContributors(
-                                       function(data) {
-                                               $scope.contributors = data;
-                                       }, function(err) {
-                                               $scope.error = err;
-                                       });
-                       };
+                       Catalog.loadHightlighted(
+                               function(data) {
+                                       vm.highlighted = data;
+                               }, function(err) {
+                                       vm.error = err;
+                               });
+               })
 
+               .controller('CatalogRequiredCtrl', function(Catalog) {
+                       var vm = this;
 
-                       this.scrollTo = function(hash) {
-                               $anchorScroll(hash);
-                       }
+                       Catalog.loadMostRequired(
+                               function(data) {
+                                       vm.required = data;
+                               }, function(err) {
+                                       vm.error = err;
+                               });
+               })
+
+               .controller('CatalogTagsCtrl', function(Catalog, $anchorScroll, $location) {
+                       var vm = this;
+
+                       Catalog.loadByTags(
+                               function(data) {
+                                       vm.bytags = data;
+                               }, function(err) {
+                                       vm.error = err;
+                               });
 
-                       this.loadHighlighted();
-                       this.loadStats();
-                       this.loadContributors();
-               }])
 
-               .directive('contributorList', ['Model', function(Model) {
+                       vm.scrollTo = function(hash) {
+                               $location.hash(hash);
+                               $anchorScroll();
+                       }
+               })
+
+               .directive('contributorList', function(Model) {
                        return {
                                restrict: 'E',
                                scope: {
                                },
                                templateUrl: '/directives/contributor-list.html'
                        };
-               }])
+               })
 })();
index 9698e81..2fe8e15 100644 (file)
 
 (function() {
        angular
-               .module('metrics', ['model'])
+               .module('metrics', [])
+
+               .factory('Metrics', [ '$http', function($http) {
+                       return {
+                               loadStructuralMetrics: function(id, cb, cbErr) {
+                                       $http.get('/api/metrics/structural/' + id)
+                                               .success(cb)
+                                               .error(cbErr);
+                               }
+                       }
+               }])
 
                .directive('metricsList', function() {
                        return {
                                                                "content": [
                                                                        {
                                                                                "label": "Concrete classes",
-                                                                               "value": $scope.chartMetrics.mnbcc.avg,
+                                                                               "value": $scope.chartMetrics.mnbcc?
+                                                                                       $scope.chartMetrics.mnbcc.avg : 0,
                                                                                "color": "#228835"
                                                                        },
                                                                        {
                                                                                "label": "Abstract classes",
-                                                                               "value": $scope.chartMetrics.mnbac.avg,
+                                                                               "value": $scope.chartMetrics.mnbac?
+                                                                                       $scope.chartMetrics.mnbac.avg : 0,
                                                                                "color": "#103EB8"
                                                                        },
                                                                        {
                                                                                "label": "Interfaces",
-                                                                               "value": $scope.chartMetrics.mnbic.avg,
+                                                                               "value": $scope.chartMetrics.mnbic?
+                                                                                       $scope.chartMetrics.mnbic.avg : 0,
                                                                                "color": "#e65314"
                                                                        }
                                                                ]
diff --git a/share/nitweb/javascripts/model.js b/share/nitweb/javascripts/model.js
deleted file mode 100644 (file)
index fb2c008..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2016 Alexandre Terrasa <alexandre@moz-code.org>.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-(function() {
-       var apiUrl = '/api';
-
-       angular
-               .module('model', [])
-
-               .factory('Model', [ '$http', function($http) {
-                       return {
-
-                               loadEntity: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/entity/' + id)
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadEntityLinearization: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/linearization/' + id)
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadEntityDefs: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/defs/' + id)
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadEntityCode: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/code/' + id)
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadEntityGraph: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/graph/inheritance/' + id + '?cdepth=3')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               search: function(q, n, cb, cbErr) {
-                                       $http.get(apiUrl + '/search?q=' + q + '&n=' + n)
-                                               .success(cb)
-                                               .error(cbErr);
-                               }
-                       };
-               }])
-
-               .factory('Catalog', [ '$http', function($http) {
-                       return {
-                               loadHightlighted: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/catalog/highlighted')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadMostRequired: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/catalog/required')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadByTags: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/catalog/bytags')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadStats: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/catalog/stats')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-
-                               loadContributors: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/catalog/contributors')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                       }
-               }])
-
-               .factory('Feedback', [ '$http', function($http) {
-                       return {
-                               loadEntityStars: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/stars/' + id)
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               loadEntityStarsDimension: function(id, dimension, cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/stars/' + id + '/dimension/' + dimension)
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               postEntityStarDimension: function(id, dimension, rating, cb, cbErr) {
-                                       $http.post(apiUrl + '/feedback/stars/' + id + '/dimension/' + dimension,
-                                               {rating: rating})
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               loadMostRated: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/grades/most')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               loadBestRated: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/grades/best')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               loadWorstRated: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/grades/worst')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               loadUsersRatings: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/grades/users')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                       }
-               }])
-
-               .factory('DocDown', [ '$http', function($http) {
-                       return {
-                               postMarkdown: function(md, cb, cbErr) {
-                                       $http.post(apiUrl + '/docdown', md)
-                                               .success(cb)
-                                               .error(cbErr);
-                               }
-                       }
-               }])
-
-               .factory('Metrics', [ '$http', function($http) {
-                       return {
-                               loadStructuralMetrics: function(id, cb, cbErr) {
-                                       $http.get(apiUrl + '/metrics/structural/' + id)
-                                               .success(cb)
-                                               .error(cbErr);
-                               }
-                       }
-               }])
-
-               .factory('User', [ '$http', function($http) {
-                       return {
-                               loadUser: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/user')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                               loadUserStars: function(cb, cbErr) {
-                                       $http.get(apiUrl + '/feedback/user/stars')
-                                               .success(cb)
-                                               .error(cbErr);
-                               },
-                       }
-               }])
-})();
index 78f0f71..181da8e 100644 (file)
  */
 
 (function() {
-       angular.module('nitweb', ['ngRoute', 'ngSanitize', 'angular-loading-bar', 'entities', 'docdown', 'index', 'metrics', 'users', 'grades'])
+       angular.module('nitweb', ['ui.router', 'ngSanitize', 'angular-loading-bar', 'index', 'entities', 'docdown', 'metrics', 'users', 'grades'])
+
        .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {
                cfpLoadingBarProvider.includeSpinner = false;
        }])
-       .config(function($routeProvider, $locationProvider) {
-               $routeProvider
-                       .when('/', {
-                               templateUrl: 'views/index.html',
-                               controller: 'IndexCtrl',
-                               controllerAs: 'indexCtrl'
-                       })
-                       .when('/user', {
-                               templateUrl: 'views/user.html',
-                               controller: 'UserCtrl',
-                               controllerAs: 'userCtrl'
-                       })
-                       .when('/docdown', {
-                               templateUrl: 'views/docdown.html',
-                               controller: 'DocdownCtrl',
-                               controllerAs: 'docdownCtrl'
-                       })
-                       .when('/grades', {
-                               templateUrl: 'views/grades.html',
-                               controller: 'GradesCtrl',
-                               controllerAs: 'gradesCtrl'
-                       })
-                       .when('/login', {
-                               controller : function(){
-                                       window.location.replace('/login');
-                               },
-                           template : "<div></div>"
-                       })
-                       .when('/logout', {
-                               controller : function(){
-                                       window.location.replace('/logout');
-                               },
-                           template : "<div></div>"
-                       })
-                       .when('/doc/:id', {
-                               templateUrl: 'views/doc.html',
-                               controller: 'EntityCtrl',
-                               controllerAs: 'entityCtrl',
-                               reloadOnSearch: false
-                       })
-                       .otherwise({
+
+       .run(['$anchorScroll', function($anchorScroll) {
+               $anchorScroll.yOffset = 80;
+       }])
+
+       .config(function($stateProvider, $locationProvider) {
+               $stateProvider
+                       .state({
+                               name: '404',
+                               url: '*path',
                                templateUrl: 'views/error.html'
-                       });
+                       })
                $locationProvider.html5Mode(true);
        })
-
-       .filter('encodeURI', function() {
-               return encodeURIComponent;
-       });
 })();
index f6f5eca..7fc3f8a 100644 (file)
@@ -16,9 +16,9 @@
 
 (function() {
        angular
-               .module('ui', [ 'model' ])
+               .module('ui', [])
 
-               .controller('SearchCtrl', function(Model, $routeParams, $scope, $location, $document) {
+               .controller('SearchCtrl', function(Model, $scope, $location, $document) {
 
                        $scope.query = '';
 
index bd446b7..c148bbe 100644 (file)
 
 (function() {
        angular
-               .module('users', ['ngSanitize', 'model'])
+               .module('users', ['ngSanitize'])
 
-               .controller('UserCtrl', ['User', '$routeParams', '$scope', function(User, $routeParams, $scope) {
+               .config(function($stateProvider, $locationProvider) {
+                       $stateProvider
+                               .state('user', {
+                                       url: '/user',
+                                       templateUrl: 'views/user.html',
+                                       controller: 'UserCtrl',
+                                       controllerAs: 'userCtrl'
+                               })
+                               .state('login', {
+                                       url: '/login',
+                                       controller : function(){
+                                               window.location.replace('/login');
+                                       },
+                                       template : "<div></div>"
+                               })
+                               .state('logout', {
+                                       controller : function(){
+                                               window.location.replace('/logout');
+                                       },
+                                       template : "<div></div>"
+                               })
+               })
+
+               .factory('User', [ '$http', function($http) {
+                       return {
+                               loadUser: function(cb, cbErr) {
+                                       $http.get('/api/user')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                               loadUserStars: function(cb, cbErr) {
+                                       $http.get('/api/feedback/user/stars')
+                                               .success(cb)
+                                               .error(cbErr);
+                               },
+                       }
+               }])
+
+               .controller('UserCtrl', ['User', '$scope', function(User, $scope) {
                        this.loadUser = function() {
                                User.loadUser(
                                        function(data) {
diff --git a/share/nitweb/stylesheets/cards.css b/share/nitweb/stylesheets/cards.css
new file mode 100644 (file)
index 0000000..0d39859
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017 Alexandre Terrasa <alexandre@moz-code.org>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* cards */
+
+.card.active {
+       border: 1px solid #1E9431;
+}
+
+.card-heading {
+    margin-top: 0;
+    margin-bottom: 5px;
+}
+
+.card {
+       display: table;
+       width: 100%;
+       background: #fff;
+       border: 1px solid #ccc;
+       margin-top: 10px;
+       box-shadow: 0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);
+}
+
+.card-body, .card-left, .card-right {
+       display: table-cell;
+       padding: 15px;
+}
+
+.card-body {
+       padding: 15px 0;
+       width: 100%
+}
+
+.card-body:first-child {
+       padding-left: 15px;
+}
+
+.card-body:last-child {
+       padding-right: 15px;
+}
+
+.card-list {
+       margin-top: 10px;
+}
+
+.card-list > .card:first-child {
+       border-top: 1px solid #ccc;
+}
+
+.card-list > .card {
+       margin-top: 0;
+       border-top: none;
+}
+
+.card-title {
+    margin-top: 0;
+}
diff --git a/share/nitweb/stylesheets/nitlight.css b/share/nitweb/stylesheets/nitlight.css
new file mode 100644 (file)
index 0000000..63a1356
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 Alexandre Terrasa <alexandre@moz-code.org>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Code Highlighting
+ */
+
+.nitdoc h1, .nitdoc h2, .nitdoc h3, .nitdoc h4, .nitdoc h5, .nitdoc h6 {
+       color: #333;
+}
+
+.nitdoc .synopsys {
+       margin-top: 0;
+}
+
+.nitcode a { color: inherit; text-decoration: inherit; } /* hide links */
+.nitcode a:hover { text-decoration: underline; } /* underline links */
+.nitcode span[title]:hover { text-decoration: underline; } /* underline titles */
+/* lexical raw tokens. independent of usage or semantic: */
+.nitcode .nc_c { color: gray; font-style: italic; } /* comment */
+.nitcode .nc_d { color: #3D8127; font-style: italic; } /* documentation comments */
+.nitcode .nc_k { font-weight: bold; } /* keyword */
+.nitcode .nc_o {} /* operator */
+.nitcode .nc_i {} /* standard identifier */
+.nitcode .nc_t { color: #445588; font-weight: bold; } /* type/class identifier */
+.nitcode .nc_a { color: #445588; font-style: italic; } /* old style attribute identifier */
+.nitcode .nc_l { color: #009999; } /* char and number literal */
+.nitcode .nc_s { color: #8F1546; } /* string literal */
+/* syntactic token usage. added because of their position in the AST */
+.nitcode .nc_ast { color: blue; } /* assert label */
+.nitcode .nc_la { color: blue; } /* break/continue label */
+.nitcode .nc_m { color: #445588; } /* module name */
+/* syntactic groups */
+.nitcode .nc_def { font-weight: bold; color: blue; } /* name used in a definition */
+.nitcode .nc_def.nc_a { color: blue; } /* name used in a attribute definition */
+.nitcode .nc_def.nc_t { color: blue; } /* name used in a class or vt definition */
+.nitcode .nc_ss { color: #9E6BEB; } /* superstrings */
+.nitcode .nc_cdef {} /* A whole class definition */
+.nitcode .nc_pdef {} /* A whole property definition */
+/* semantic token usage */
+.nitcode .nc_v { font-style: italic; } /* local variable or parameter */
+.nitcode .nc_vt { font-style: italic; } /* virtual type or formal type */
+.nitcode .nc_error { border: 1px red solid;} /* not used */
index b78f244..864c296 100644 (file)
@@ -1,3 +1,38 @@
+/*
+ * Copyright 2017 Alexandre Terrasa <alexandre@moz-code.org>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* utils */
+
+.no-margin {
+       margin: 0;
+}
+
+.no-padding {
+       padding: 0;
+}
+
+.navbar-fixed-top {
+       background-color: #1E9431;
+       box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28);
+}
+
+#loading-bar .bar {
+       background: #FF8100;
+}
+
 /* Body */
 
 body {
@@ -14,70 +49,11 @@ a {
        cursor: pointer;
 }
 
-.nitdoc h1, .nitdoc h2, .nitdoc h3, .nitdoc h4, .nitdoc h5, .nitdoc h6 {
-       color: #333;
-}
-
 .page-header {
     margin-top: 0;
     border: none;
 }
 
-/* cards */
-
-.card.active {
-       border: 1px solid #1E9431;
-}
-
-.card-heading {
-    margin-top: 0;
-    margin-bottom: 5px;
-}
-
-.card {
-       display: table;
-       width: 100%;
-       background: #fff;
-       border: 1px solid #ccc;
-       margin-top: 10px;
-       box-shadow: 0 -1px 0 #e5e5e5,0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);
-}
-
-.card-body, .card-left, .card-right {
-       display: table-cell;
-       padding: 15px;
-}
-
-.card-body {
-       padding: 15px 0;
-       width: 100%
-}
-
-.card-body:first-child {
-       padding-left: 15px;
-}
-
-.card-body:last-child {
-       padding-right: 15px;
-}
-
-.card-list {
-       margin-top: 10px;
-}
-
-.card-list > .card:first-child {
-       border-top: 1px solid #ccc;
-}
-
-.card-list > .card {
-       margin-top: 0;
-       border-top: none;
-}
-
-.card-title {
-    margin-top: 0;
-}
-
 /* ui */
 
 .btn-bar { margin-top: -5px; float: right }
@@ -173,57 +149,10 @@ entity-list:hover .btn-filter {
        cursor: pointer;
 }
 
-/* loading bar */
-
-#loading-bar .bar {
-       background: #FF8100;
-}
-
 /* navs */
 
 .nav-tabs li { cursor: pointer; }
 
-.navbar-fixed-top {
-       background-color: #1E9431;
-       box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28);
-}
-
-.navbar-fixed-top .form-control:hover, .navbar-fixed-top .form-control:focus {
-       background: rgba(255, 255, 255, 0.2);
-}
-
-.navbar-fixed-top .form-control {
-       background: rgba(255, 255, 255, 0.1);
-    border: none;
-    color: #fff;
-    box-shadow: none;
-}
-
-.navbar-fixed-top .form-control-icon {
-       color: #fff;
-}
-
-.navbar-fixed-top *::-webkit-input-placeholder {
-    color: #fff;
-}
-.navbar-fixed-top *:-moz-placeholder {
-    /* FF 4-18 */
-    color: #fff;
-}
-.navbar-fixed-top *::-moz-placeholder {
-    /* FF 19+ */
-    color: #fff;
-}
-.navbar-fixed-top *:-ms-input-placeholder {
-    /* IE 10+ */
-    color: #fff;
-}
-
-.navbar-fixed-top .form-group {
-       margin-top: 8px;
-       margin-bottom: 0px;
-}
-
 /* Summary */
 
 .summary h1, .summary h2, .summary h3, .summary h4, .summary h5, .summary h6 {
@@ -260,49 +189,3 @@ entity-list:hover .btn-filter {
 .star.active {
        color: #FFC000
 }
-
-/*
- * Users
- */
-
-.avatar {
-       border-radius: 2px;
-}
-
-.avatar-icon {
-       width: 18px;
-       height: 18px;
-}
-
-/*
- * Code Highlighting
- */
-
-.nitcode a { color: inherit; text-decoration: inherit; } /* hide links */
-.nitcode a:hover { text-decoration: underline; } /* underline links */
-.nitcode span[title]:hover { text-decoration: underline; } /* underline titles */
-/* lexical raw tokens. independent of usage or semantic: */
-.nitcode .nc_c { color: gray; font-style: italic; } /* comment */
-.nitcode .nc_d { color: #3D8127; font-style: italic; } /* documentation comments */
-.nitcode .nc_k { font-weight: bold; } /* keyword */
-.nitcode .nc_o {} /* operator */
-.nitcode .nc_i {} /* standard identifier */
-.nitcode .nc_t { color: #445588; font-weight: bold; } /* type/class identifier */
-.nitcode .nc_a { color: #445588; font-style: italic; } /* old style attribute identifier */
-.nitcode .nc_l { color: #009999; } /* char and number literal */
-.nitcode .nc_s { color: #8F1546; } /* string literal */
-/* syntactic token usage. added because of their position in the AST */
-.nitcode .nc_ast { color: blue; } /* assert label */
-.nitcode .nc_la { color: blue; } /* break/continue label */
-.nitcode .nc_m { color: #445588; } /* module name */
-/* syntactic groups */
-.nitcode .nc_def { font-weight: bold; color: blue; } /* name used in a definition */
-.nitcode .nc_def.nc_a { color: blue; } /* name used in a attribute definition */
-.nitcode .nc_def.nc_t { color: blue; } /* name used in a class or vt definition */
-.nitcode .nc_ss { color: #9E6BEB; } /* superstrings */
-.nitcode .nc_cdef {} /* A whole class definition */
-.nitcode .nc_pdef {} /* A whole property definition */
-/* semantic token usage */
-.nitcode .nc_v { font-style: italic; } /* local variable or parameter */
-.nitcode .nc_vt { font-style: italic; } /* virtual type or formal type */
-.nitcode .nc_error { border: 1px red solid;} /* not used */
index e82732b..cff83cb 100644 (file)
@@ -330,7 +330,7 @@ hr {
   margin-top: 20px;\r
   margin-bottom: 20px;\r
   border: 0;\r
-  border-top: 1px solid #eeeeee;\r
+  border-top: 1px solid #ddd;\r
 }\r
 .sr-only {\r
   position: absolute;\r
diff --git a/share/nitweb/stylesheets/search.css b/share/nitweb/stylesheets/search.css
new file mode 100644 (file)
index 0000000..2f6e2db
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 Alexandre Terrasa <alexandre@moz-code.org>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* search */
+
+.has-icon {
+    position: relative;
+}
+
+.has-icon .form-control {
+       padding-left: 35px;
+}
+
+.form-control-icon {
+    position: absolute;
+    top: 0;
+    left: 0;
+    z-index: 2;
+    display: block;
+    width: 34px;
+    height: 34px;
+    line-height: 34px;
+    text-align: center;
+    pointer-events: none;
+}
+
+.navbar-fixed-top .form-control:hover, .navbar-fixed-top .form-control:focus {
+       background: rgba(255, 255, 255, 0.2);
+}
+
+.navbar-fixed-top .form-control {
+       background: rgba(255, 255, 255, 0.1);
+    border: none;
+    color: #fff;
+    box-shadow: none;
+}
+
+.navbar-fixed-top .form-control-icon {
+       color: #fff;
+}
+
+.navbar-fixed-top .form-group {
+       margin-top: 8px;
+       margin-bottom: 0px;
+}
+
+.navbar-fixed-top *::-webkit-input-placeholder { color: #fff; }
+.navbar-fixed-top *:-moz-placeholder { color: #fff; }
+.navbar-fixed-top *::-moz-placeholder { color: #fff; }
+.navbar-fixed-top *:-ms-input-placeholder { color: #fff; }
diff --git a/share/nitweb/views/catalog/by_tags.html b/share/nitweb/views/catalog/by_tags.html
new file mode 100644 (file)
index 0000000..31ca905
--- /dev/null
@@ -0,0 +1,14 @@
+<div>
+       <h3>Tags</h3>
+       <div class='container-fluid'>
+               <div class='col-xs-3' ng-repeat='(tag, packages) in vm.bytags'>
+                       <span class='badge'>{{packages.length}}</span>
+                       <a ng-click='vm.scrollTo(tag)'>{{tag}}</a>
+               </div>
+       </div>
+       <div ng-repeat='(tag, packages) in vm.bytags'>
+               <entity-list list-id='{{tag}}' list-title='{{tag}}'
+                       list-entities='packages'
+                       list-object-filter='{}' />
+       </div>
+</div>
diff --git a/share/nitweb/views/catalog/highlighted.html b/share/nitweb/views/catalog/highlighted.html
new file mode 100644 (file)
index 0000000..5607bd5
--- /dev/null
@@ -0,0 +1,5 @@
+<div>
+       <entity-list list-title='Highlighted packages'
+               list-entities='vm.highlighted'
+               list-object-filter='{}' />
+</div>
diff --git a/share/nitweb/views/catalog/index.html b/share/nitweb/views/catalog/index.html
new file mode 100644 (file)
index 0000000..877db4a
--- /dev/null
@@ -0,0 +1,47 @@
+<div class='container-fluid'>
+       <div class='page-header'>
+               <h2>Welcome to NitWeb!</h2>
+               <p class='text-muted'>The Nit knowledge base.</p>
+       </div>
+
+       <ul class='nav nav-tabs' role='tablist'>
+               <li role='presentation' ui-sref-active='active'>
+                       <a ui-sref='catalog.highlighted'>
+                               <span class='glyphicon glyphicon-book'/> Highlighed
+                       </a>
+               </li>
+               <li role='presentation' ui-sref-active='active'>
+                       <a ui-sref='catalog.required'>
+                               <span class='glyphicon glyphicon-book'/> Most required
+                       </a>
+               </li>
+               <li role='presentation' ui-sref-active='active'>
+                       <a ui-sref='catalog.tags'>
+                               <span class='glyphicon glyphicon-book'/> By tags
+                       </a>
+               </li>
+       </ul>
+       <table class='table'>
+               <tr>
+                       <td ng-repeat='(key, value) in vm.stats'>
+                               <h5><strong>{{value}}</strong>&nbsp;<span>{{key}}</span></h5>
+                       </td>
+               </tr>
+       </table>
+
+       <div class='container-fluid'>
+               <div class='col-xs-9'>
+                       <div class='tab-content'>
+                               <div role='tabpanel' class='tab-pane fade in active'>
+                                       <ui-view />
+                               </div>
+                       </div>
+               </div>
+               <div class='col-xs-3'>
+                       <contributor-list list-title='Maintainers'
+                                       list-contributors='vm.contributors.maintainers' />
+                       <contributor-list list-title='Contributors'
+                                       list-contributors='vm.contributors.contributors' />
+               </div>
+       </div>
+</div>
diff --git a/share/nitweb/views/catalog/most_required.html b/share/nitweb/views/catalog/most_required.html
new file mode 100644 (file)
index 0000000..93bf2e1
--- /dev/null
@@ -0,0 +1,5 @@
+<div>
+       <entity-list list-title='Most required'
+               list-entities='vm.required'
+               list-object-filter='{}' />
+</div>
diff --git a/share/nitweb/views/class.html b/share/nitweb/views/class.html
deleted file mode 100644 (file)
index 278e676..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<ul class='nav nav-tabs'>
-       <li role='presentation' class='active'>
-               <a data-toggle='tab' data-target='#doc'>
-                       <span class='glyphicon glyphicon-book'/> Doc
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#graph' ng-click="entityCtrl.loadEntityGraph()">
-                       <span class='glyphicon glyphicon-object-align-vertical'/> Inheritance
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#all_props'>
-                       <span class='glyphicon glyphicon-tags'/> All properties
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization' ng-click='entityCtrl.loadEntityLinearization()'>
-                       <span class='glyphicon glyphicon-arrow-down'/> Linearization
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' role='tab' data-target='#metrics' aria-controls='metrics' ng-click='entityCtrl.loadStructuralMetrics(); entityCtrl.loadPieChart()'>
-                       <span class='glyphicon glyphicon-stats'/> Metrics
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='doc'>
-               <div class='col-xs-3'>
-                       <ui-summary target='#summary-content' />
-               </div>
-               <div id='summary-content' class='col-xs-9'>
-                       <entity-card mentity='mentity' default-tab='doc' no-synopsis='true' />
-
-                       <entity-list list-title='Parents'
-                               list-entities='mentity.parents'
-                               list-object-filter='{}' />
-
-                       <entity-list list-title='Constructors'
-                               list-entities='mentity.all_mproperties'
-                               list-object-filter='{is_init: true}' />
-
-                       <entity-list list-title='Introduced properties'
-                               list-entities='mentity.intro_mproperties'
-                               list-object-filter='{is_init: "!true"}' />
-
-                       <entity-list list-title='Redefined properties'
-                               list-entities='mentity.redef_mproperties'
-                               list-object-filter='{is_init: "!true"}' />
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='all_props'>
-               <entity-list list-title='All properties' list-entities='mentity.all_mproperties'
-                       list-object-filter='{}' />
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='linearization'>
-               <entity-linearization
-                       list-title='Class definitions'
-                       list-entities='linearization'
-                       list-focus='mentity.intro' />
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='graph'>
-               <div class='card'>
-                       <div class='card-body text-center'>
-                               <entity-graph mentity='mentity' graph='graph' />
-                       </div>
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='metrics'>
-               <div class='card'>
-                       <div class='card-body container-fluid'>
-                               <h3 class='card-heading'>Class inheritance</h3>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Inheritance kind
-                                               <small>({{metrics.mclass['cnoa'].values[mentity.full_name].value}}
-                                               ancestors)</small>
-                                       </h4>
-                                       <chart-class-inheritance-kind chart-id='chartInheritanceKind'
-                                               chart-metrics='metrics.mclass' />
-                               </div>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Inheritance metrics
-                                       </h4>
-                                       <dl class='dl-horizontal'>
-                                               <dt>{{metrics.mclass.cnoa.values[mentity.full_name].value}}</dt>
-                                               <dd>ancestors</dd>
-                                               <dt>{{metrics.mclass.cnop.values[mentity.full_name].value}}</dt>
-                                               <dd>direct parents</dd>
-                                               <dt>{{metrics.mclass.cnoc.values[mentity.full_name].value}}</dt>
-                                               <dd>direct children</dd>
-                                               <dt>{{metrics.mclass.cnod.values[mentity.full_name].value}}</dt>
-                                               <dd>descendants</dd>
-                                       </dl>
-                                       <dl class='dl-horizontal'>
-                                               <dt>{{metrics.mclass.cdit.values[mentity.full_name].value}}</dt>
-                                               <dd>Depth in Inheritance Tree</dd>
-                                       </dl>
-                               </div>
-                       </div>
-               </div>
-               <div class='card'>
-                       <div class='card-body container-fluid'>
-                               <h3 class='card-heading'>Class properties</h3>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Properties kind
-                                               <small>({{metrics.mclass['cnbp'].values[mentity.full_name].value}}
-                                               accessible properties)</small>
-                                       </h4>
-                                       <chart-class-properties-kind chart-id='chartPropertiesKind'
-                                               chart-metrics='metrics.mclass' />
-                               </div>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Properties inheritance
-                                               <small>({{metrics.mclass['cnbp'].values[mentity.full_name].value}}
-                                               accessible properties)</small>
-                                       </h4>
-                                       <chart-class-properties-inh chart-id='chartPropertiesInh'
-                                               chart-metrics='metrics.mclass' />
-                               </div>
-                       </div>
-               </div>
-       </div>
-</div>
diff --git a/share/nitweb/views/classdef.html b/share/nitweb/views/classdef.html
deleted file mode 100644 (file)
index 1e1365b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<ul class='nav nav-tabs' ng-init='entityCtrl.loadEntityLinearization()'>
-       <li role='presentation' class='warning'>
-               <a ng-href='{{mentity.mclass.web_url}}'>
-                       <span class='glyphicon glyphicon-chevron-left'/> Go to class
-               </a>
-       </li>
-       <li role='presentation' class='active'>
-               <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization'>
-                       <span class='glyphicon glyphicon-arrow-down'/> Linearization
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='linearization'>
-               <entity-linearization
-                       list-title='Class definitions'
-                       list-entities='linearization'
-                       list-focus='mentity' />
-       </div>
-</div>
diff --git a/share/nitweb/views/doc/all.html b/share/nitweb/views/doc/all.html
new file mode 100644 (file)
index 0000000..927d312
--- /dev/null
@@ -0,0 +1,4 @@
+<div>
+       <entity-list list-title='All properties' list-entities='vm.mentity.all_mproperties'
+               list-object-filter='{}' />
+</div>
diff --git a/share/nitweb/views/doc/code.html b/share/nitweb/views/doc/code.html
new file mode 100644 (file)
index 0000000..48f4282
--- /dev/null
@@ -0,0 +1,6 @@
+<div class='card'>
+       <div class='card-body'>
+               <pre ng-bind-html='vm.code' />
+               <entity-location mentity='vm.mentity' />
+       </div>
+</div>
diff --git a/share/nitweb/views/doc/defs.html b/share/nitweb/views/doc/defs.html
new file mode 100644 (file)
index 0000000..66cd995
--- /dev/null
@@ -0,0 +1,4 @@
+<div>
+       <entity-list list-title='Class definitions'
+               list-entities='vm.defs' list-object-filter='{}' />
+</div>
diff --git a/share/nitweb/views/doc/doc.html b/share/nitweb/views/doc/doc.html
new file mode 100644 (file)
index 0000000..1cf3c8b
--- /dev/null
@@ -0,0 +1,46 @@
+<div>
+       <div class='col-xs-3'>
+               <ui-summary target='#summary-content' />
+       </div>
+       <div class='col-xs-9' id='summary-content'>
+               <entity-card mentity='vm.mentity' default-tab='doc' no-synopsis='true' />
+
+               <entity-list list-title='Groups' list-entities='vm.mentity.mgroups'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Parent group' list-entities='[vm.mentity.parent]'
+                       list-object-filter='{}' ng-if='vm.mentity.parent' />
+
+               <entity-list list-title='Subgroups' list-entities='vm.mentity.mgroups'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Modules' list-entities='vm.mentity.mmodules'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Imported modules' list-entities='vm.mentity.imports'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Introduced classes' list-entities='vm.mentity.intro_mclasses'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Class redefinitions' list-entities='vm.mentity.redef_mclassdefs'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Parents'
+                       list-entities='vm.mentity.parents'
+                       list-object-filter='{}' />
+
+               <entity-list list-title='Constructors'
+                       list-entities='vm.mentity.all_mproperties'
+                       list-object-filter='{is_init: true}' />
+
+               <entity-list list-title='Introduced properties'
+                       list-entities='vm.mentity.intro_mproperties'
+                       list-object-filter='{is_init: "!true"}' />
+
+               <entity-list list-title='Redefined properties'
+                       list-entities='vm.mentity.redef_mproperties'
+                       list-object-filter='{is_init: "!true"}' />
+
+       </div>
+</div>
diff --git a/share/nitweb/views/doc/entity.html b/share/nitweb/views/doc/entity.html
new file mode 100644 (file)
index 0000000..1a0dcf7
--- /dev/null
@@ -0,0 +1,81 @@
+<div>
+       <ul class='nav nav-tabs' role='tablist'>
+
+               <!-- doc -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MPackage" ||
+                               vm.mentity.class_name == "MGroup" ||
+                               vm.mentity.class_name == "MModule" ||
+                               vm.mentity.class_name == "MClass" ||
+                               vm.mentity.class_name == "MMethod" ||
+                               vm.mentity.class_name == "MAttribute" ||
+                               vm.mentity.class_name == "MVirtualTypeProp"'>
+                       <a ui-sref='.doc'>
+                               <span class='glyphicon glyphicon-book'/> Doc
+                       </a>
+               </li>
+
+               <!-- graph -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MPackage" ||
+                               vm.mentity.class_name == "MGroup" ||
+                               vm.mentity.class_name == "MModule" ||
+                               vm.mentity.class_name == "MClass"'>
+                       <a ui-sref='.graph'>
+                               <span class='glyphicon glyphicon-object-align-vertical'/>
+                               <span ng-if='vm.mentity.class_name == "MPackage"'>Dependencies</span>
+                               <span ng-if='vm.mentity.class_name == "MGroup"'>Imports</span>
+                               <span ng-if='vm.mentity.class_name == "MModule"'>Imports</span>
+                               <span ng-if='vm.mentity.class_name == "MClass"'>Inheritance</span>
+                       </a>
+               </li>
+
+               <!-- code -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MModule"'>
+                       <a ui-sref='.code'>
+                               <span class='glyphicon glyphicon-console'/> Code
+                       </a>
+               </li>
+
+               <!-- definitions -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MModule"'>
+                       <a ui-sref='.defs'>
+                               <span class='glyphicon glyphicon-asterisk'/> Class definitions
+                       </a>
+               </li>
+
+               <!-- all -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MClass"'>
+                       <a ui-sref='.all'>
+                               <span class='glyphicon glyphicon-tags'/> All properties
+                       </a>
+               </li>
+
+               <!-- linearization -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MClass" ||
+                               vm.mentity.class_name == "MMethod" ||
+                               vm.mentity.class_name == "MAttribute" ||
+                               vm.mentity.class_name == "MVirtualTypeProp"'>
+                       <a ui-sref='.lin'>
+                               <span class='glyphicon glyphicon-arrow-down'/> Linearization
+                       </a>
+               </li>
+
+               <!-- metrics -->
+               <li role='presentation' ui-sref-active='active' ng-if='
+                               vm.mentity.class_name == "MPackage" ||
+                               vm.mentity.class_name == "MGroup" ||
+                               vm.mentity.class_name == "MModule" ||
+                               vm.mentity.class_name == "MClass"'>
+                       <a ui-sref='.metrics'>
+                               <span class='glyphicon glyphicon-stats'/> Metrics
+                       </a>
+               </li>
+       </ul>
+       <br>
+       <ui-view />
+</div>
diff --git a/share/nitweb/views/doc/graph.html b/share/nitweb/views/doc/graph.html
new file mode 100644 (file)
index 0000000..a346d99
--- /dev/null
@@ -0,0 +1,5 @@
+<div class='card'>
+       <div class='card-body text-center'>
+               <entity-graph mentity='mentity' graph='vm.graph' />
+       </div>
+</div>
diff --git a/share/nitweb/views/doc/index.html b/share/nitweb/views/doc/index.html
new file mode 100644 (file)
index 0000000..aab7423
--- /dev/null
@@ -0,0 +1,18 @@
+<div class='container-fluid'>
+
+       <div ng-if='vm.error' class='alert alert-danger' role='alert'>
+               <span class='glyphicon glyphicon-exclamation-sign' aria-hidden='true'></span>
+               <span class='sr-only'>Error:</span>
+               <span ng-switch='vm.error.status'>
+                       <span ng-switch-when='404'>Entity <code>{{vm.entityId}}</code> not found!</span>
+                       <span ng-switch-default>An error occured<br/>{{vm.error.status}}: {{vm.error.message}}</span>
+               </span>
+       </div>
+
+       <div class='page-header'>
+               <h2><entity-signature mentity='vm.mentity' /></h2>
+               <entity-namespace namespace='vm.mentity.namespace' />
+       </div>
+
+       <ui-view />
+</div>
diff --git a/share/nitweb/views/doc/lin.html b/share/nitweb/views/doc/lin.html
new file mode 100644 (file)
index 0000000..96d9b82
--- /dev/null
@@ -0,0 +1,6 @@
+<div>
+       <entity-linearization
+               list-title='Class definitions'
+               list-entities='vm.linearization'
+               list-focus='vm.focus' />
+</div>
diff --git a/share/nitweb/views/doc/metrics.html b/share/nitweb/views/doc/metrics.html
new file mode 100644 (file)
index 0000000..fd52704
--- /dev/null
@@ -0,0 +1,157 @@
+<div id='metrics'>
+
+       <!-- packages, groups -->
+
+       <metrics-list
+               ng-if='vm.mentity.class_name == "MPackage" || vm.mentity.class_name == "MGroup"'
+               list-id='modules_importation'
+               list-title='Modules importation'
+               list-metrics='vm.metrics.mmodules'
+               list-metrics-names='["mdit", "mnoa", "mnop", "mnoc", "mnod"]'
+               list-metrics-default='"mdit"' />
+       <metrics-list
+               ng-if='vm.mentity.class_name == "MPackage" || vm.mentity.class_name == "MGroup"'
+               list-id='modules_definitions'
+               list-title='Modules content'
+               list-metrics='vm.metrics.mmodules'
+               list-metrics-names='["mnbi", "mnbr", "mnbic", "mnbac", "mnbcc"]'
+               list-metrics-default='"mnbi"' />
+       <metrics-list
+               ng-if='vm.mentity.class_name == "MPackage" || vm.mentity.class_name == "MGroup"'
+               list-id='classes_inheritance'
+               list-title='Classes inheritance'
+               list-metrics='vm.metrics.mclasses'
+               list-metrics-names='["cdit", "cnoa", "cnop", "cnoc", "cnod"]'
+               list-metrics-default='"cdit"' />
+       <metrics-list
+               ng-if='vm.mentity.class_name == "MPackage" || vm.mentity.class_name == "MGroup"'
+               list-id='classes_properties'
+               list-title='Classes properties'
+               list-metrics='vm.metrics.mclasses'
+               list-metrics-names='["cnbp", "cnba", "cnbip", "cnbrp", "cnbhp", "cnblp"]'
+               list-metrics-default='"cnbp"' />
+
+       <!-- module -->
+
+       <div class='card' ng-if='vm.mentity.class_name == "MModule"'>
+               <div class='card-body container-fluid'>
+                       <h3 class='card-heading'>Module importation</h3>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Importation metrics
+                               </h4>
+                               <dl class='dl-horizontal'>
+                                       <dt>{{vm.metrics.mmodule.mnoa.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>ancestors</dd>
+                                       <dt>{{vm.metrics.mmodule.mnop.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>direct parents</dd>
+                                       <dt>{{vm.metrics.mmodule.mnoc.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>direct children</dd>
+                                       <dt>{{vm.metrics.mmodule.mnod.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>descendants</dd>
+                               </dl>
+                               <dl class='dl-horizontal'>
+                                       <dt>{{vm.metrics.mmodule.mdit.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>Depth in Inheritance Tree</dd>
+                               </dl>
+                       </div>
+               </div>
+       </div>
+       <div class='card' ng-if='vm.mentity.class_name == "MModule"'>
+               <div class='card-body container-fluid'>
+                       <h3 class='card-heading'>Module definitions</h3>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Class definition kinds
+                                       <small>({{vm.metrics.mmodule['mnbi'].values[vm.mentity.full_name].value +
+                                               vm.metrics.mclass['mnbc'].values[vm.mentity.full_name].value}}
+                                       class definitions)</small>
+                               </h4>
+                               <chart-module-definitions-kind chart-id='chartDefinitionsKind'
+                                       chart-metrics='vm.metrics.mmodule' />
+                       </div>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Class definition inheritance
+                                       <small>({{vm.metrics.mmodule['mnbd'].values[vm.mentity.full_name].value}}
+                                       accessible definitions)</small>
+                               </h4>
+                               <chart-module-definitions-inh chart-id='chartDefinitionsInh'
+                                       chart-metrics='vm.metrics.mmodule' />
+                       </div>
+               </div>
+       </div>
+       <metrics-list
+               ng-if='vm.mentity.class_name == "MModule"'
+               list-id='classes_inheritance'
+               list-title='Classes inheritance'
+               list-metrics='vm.metrics.mclasses'
+               list-metrics-names='["cdit", "cnoa", "cnop", "cnoc", "cnod"]'
+               list-metrics-default='"cdit"' />
+       <metrics-list
+               ng-if='vm.mentity.class_name == "MModule"'
+               list-id='classes_properties'
+               list-title='Classes properties'
+               list-metrics='vm.metrics.mclasses'
+               list-metrics-names='["cnbp", "cnba", "cnbip", "cnbrp", "cnbhp", "cnblp"]'
+               list-metrics-default='"cnbp"' />
+
+       <!-- mclass -->
+
+       <div class='card' ng-if='vm.mentity.class_name == "MClass"'>
+               <div class='card-body container-fluid'>
+                       <h3 class='card-heading'>Class inheritance</h3>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Inheritance kind
+                                       <small>({{vm.metrics.mclass['cnoa'].values[vm.mentity.full_name].value}}
+                                       ancestors)</small>
+                               </h4>
+                               <chart-class-inheritance-kind chart-id='chartInheritanceKind'
+                                       chart-metrics='vm.metrics.mclass' />
+                       </div>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Inheritance metrics
+                               </h4>
+                               <dl class='dl-horizontal'>
+                                       <dt>{{vm.metrics.mclass.cnoa.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>ancestors</dd>
+                                       <dt>{{vm.metrics.mclass.cnop.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>direct parents</dd>
+                                       <dt>{{vm.metrics.mclass.cnoc.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>direct children</dd>
+                                       <dt>{{vm.metrics.mclass.cnod.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>descendants</dd>
+                               </dl>
+                               <dl class='dl-horizontal'>
+                                       <dt>{{vm.metrics.mclass.cdit.values[vm.mentity.full_name].value}}</dt>
+                                       <dd>Depth in Inheritance Tree</dd>
+                               </dl>
+                       </div>
+               </div>
+       </div>
+       <div class='card' ng-if='vm.mentity.class_name == "MClass"'>
+               <div class='card-body container-fluid'>
+                       <h3 class='card-heading'>Class properties</h3>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Properties kind
+                                       <small>({{vm.metrics.mclass['cnbp'].values[vm.mentity.full_name].value}}
+                                       accessible properties)</small>
+                               </h4>
+                               <chart-class-properties-kind chart-id='chartPropertiesKind'
+                                       chart-metrics='vm.metrics.mclass' />
+                       </div>
+                       <div class='col-sm-6'>
+                               <h4>
+                                       Properties inheritance
+                                       <small>({{vm.metrics.mclass['cnbp'].values[vm.mentity.full_name].value}}
+                                       accessible properties)</small>
+                               </h4>
+                               <chart-class-properties-inh chart-id='chartPropertiesInh'
+                                       chart-metrics='vm.metrics.mclass' />
+                       </div>
+               </div>
+       </div>
+</div>
diff --git a/share/nitweb/views/group.html b/share/nitweb/views/group.html
deleted file mode 100644 (file)
index 0f7347b..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<ul class='nav nav-tabs'>
-       <li class='active'>
-               <a data-toggle='tab' data-target='#doc'>
-                       <span class='glyphicon glyphicon-book'/> Doc
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#graph' ng-click="entityCtrl.loadEntityGraph()">
-                       <span class='glyphicon glyphicon-object-align-vertical'/> Imports
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' role='tab' data-target='#metrics' aria-controls='metrics' ng-click='entityCtrl.loadStructuralMetrics()'>
-                       <span class='glyphicon glyphicon-stats'/> Metrics
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='doc'>
-               <div class='col-xs-3'>
-                       <ui-summary target='#summary-content' />
-               </div>
-               <div class='col-xs-9' id='summary-content'>
-                       <entity-card mentity='mentity' default-tab='doc' no-synopsis='true' />
-
-                       <entity-list list-title='Parent group' list-entities='[mentity.parent]'
-                               list-object-filter='{}' ng-if='mentity.parent' />
-
-                       <entity-list list-title='Subgroups' list-entities='mentity.mgroups'
-                               list-object-filter='{}' />
-
-                       <entity-list list-title='Modules' list-entities='mentity.mmodules'
-                               list-object-filter='{}' />
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='graph'>
-               <div class='card'>
-                       <div class='card-body text-center'>
-                               <entity-graph mentity='mentity' graph='graph' />
-                       </div>
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='metrics'>
-               <metrics-list
-                       list-id='modules_importation'
-                       list-title='Modules importation'
-                       list-metrics='metrics.mmodules'
-                       list-metrics-names='["mdit", "mnoa", "mnop", "mnoc", "mnod"]'
-                       list-metrics-default='"mdit"' />
-               <metrics-list
-                       list-id='modules_definitions'
-                       list-title='Modules content'
-                       list-metrics='metrics.mmodules'
-                       list-metrics-names='["mnbi", "mnbr", "mnbic", "mnbac", "mnbcc"]'
-                       list-metrics-default='"mnbi"' />
-               <metrics-list
-                       list-id='classes_inheritance'
-                       list-title='Classes inheritance'
-                       list-metrics='metrics.mclasses'
-                       list-metrics-names='["cdit", "cnoa", "cnop", "cnoc", "cnod"]'
-                       list-metrics-default='"cdit"' />
-               <metrics-list
-                       list-id='classes_properties'
-                       list-title='Classes properties'
-                       list-metrics='metrics.mclasses'
-                       list-metrics-names='["cnbp", "cnba", "cnbip", "cnbrp", "cnbhp", "cnblp"]'
-                       list-metrics-default='"cnbp"' />
-       </div>
-</div>
diff --git a/share/nitweb/views/index.html b/share/nitweb/views/index.html
deleted file mode 100644 (file)
index b7bee8e..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-<div class='container-fluid'>
-       <div class='page-header'>
-               <h2>Welcome to NitWeb!</h2>
-               <p class='text-muted'>The Nit knowledge base.</p>
-       </div>
-
-       <ul class='nav nav-tabs' role='tablist'>
-               <li role='presentation' class='active'>
-                       <a data-toggle='tab' role='tab' data-target='#highlighted' aria-controls='highlighted'>
-                               <span class='glyphicon glyphicon-book'/> Highlighed
-                       </a>
-               </li>
-               <li role='presentation'>
-                       <a data-toggle='tab' role='tab' data-target='#required' aria-controls='required'
-                               ng-click='indexCtrl.loadMostRequired()'>
-                               <span class='glyphicon glyphicon-book'/> Most required
-                       </a>
-               </li>
-               <li role='presentation'>
-                       <a data-toggle='tab' role='tab' data-target='#bytags' aria-controls='bytags'
-                               ng-click='indexCtrl.loadByTags()'>
-                               <span class='glyphicon glyphicon-book'/> By tags
-                       </a>
-               </li>
-       </ul>
-       <table class='table'>
-               <tr>
-                       <td ng-repeat='(key, value) in stats'>
-                               <h5><strong>{{value}}</strong>&nbsp;<span>{{key}}</span></h5>
-                       </td>
-               </tr>
-       </table>
-
-       <div class='container-fluid'>
-               <div class='col-xs-9'>
-                       <div class='tab-content'>
-                               <div role='tabpanel' class='tab-pane fade in active' id='highlighted'>
-                                       <entity-list list-title='Highlighted packages'
-                                               list-entities='highlighted'
-                                               list-object-filter='{}' />
-                               </div>
-                               <div role='tabpanel' class='tab-pane fade' id='required'>
-                                       <entity-list list-title='Most required'
-                                               list-entities='required'
-                                               list-object-filter='{}' />
-                               </div>
-                               <div role='tabpanel' class='tab-pane fade' id='bytags'>
-                                       <h3>Tags</h3>
-                                       <div class='container-fluid'>
-                                               <div class='col-xs-3' ng-repeat='(tag, packages) in bytags'>
-                                                       <span class='badge'>{{packages.length}}</span>
-                                                       <a ng-click='indexCtrl.scrollTo(tag)'>{{tag}}</a>
-                                               </div>
-                                       </div>
-                                       <div ng-repeat='(tag, packages) in bytags'>
-                                               <entity-list list-id='{{tag}}' list-title='{{tag}}'
-                                                       list-entities='packages'
-                                                       list-object-filter='{}' />
-                                       </div>
-                               </div>
-                       </div>
-               </div>
-               <div class='col-xs-3'>
-                       <contributor-list list-title='Maintainers'
-                                       list-contributors='contributors.maintainers' />
-                       <contributor-list list-title='Contributors'
-                                       list-contributors='contributors.contributors' />
-               </div>
-       </div>
-</div>
diff --git a/share/nitweb/views/module.html b/share/nitweb/views/module.html
deleted file mode 100644 (file)
index 3891267..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-<ul class='nav nav-tabs'>
-       <li role='presentation' class='active'>
-               <a data-toggle='tab' data-target='#doc'>
-                       <span class='glyphicon glyphicon-book'/> Doc
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#graph' ng-click="entityCtrl.loadEntityGraph()">
-                       <span class='glyphicon glyphicon-object-align-vertical'/> Imports
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#code' ng-click="entityCtrl.loadEntityCode()">
-                       <span class='glyphicon glyphicon-console'/> Code
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#defs' ng-click="entityCtrl.loadEntityDefs()">
-                       <span class='glyphicon glyphicon-asterisk'/> Class definitions
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' role='tab' data-target='#metrics' aria-controls='metrics' ng-click='entityCtrl.loadStructuralMetrics()'>
-                       <span class='glyphicon glyphicon-stats'/> Metrics
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='doc'>
-               <div class='col-xs-3'>
-                       <ui-summary target='#summary-content' />
-               </div>
-               <div class='col-xs-9' id='summary-content'>
-                       <entity-card mentity='mentity' default-tab='doc' no-synopsis='true' />
-
-                       <entity-list list-title='Imported modules' list-entities='mentity.imports'
-                               list-object-filter='{}' />
-
-                       <entity-list list-title='Introduced classes' list-entities='mentity.intro_mclasses'
-                               list-object-filter='{}' />
-
-                       <entity-list list-title='Class redefinitions' list-entities='mentity.redef_mclassdefs'
-                               list-object-filter='{}' />
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='code'>
-               <div class='card'>
-                       <div class='card-body'>
-                               <pre ng-bind-html='code' />
-                               <entity-location mentity='mentity' />
-                       </div>
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='defs'>
-               <entity-list list-title='Class definitions' list-entities='defs'
-                       list-object-filter='{}' />
-       </div>
-       <div class='tab-pane fade' id='graph'>
-               <div class='card'>
-                       <div class='card-body text-center'>
-                               <entity-graph mentity='mentity' graph='graph' />
-                       </div>
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='metrics'>
-               <div class='card'>
-                       <div class='card-body container-fluid'>
-                               <h3 class='card-heading'>Module importation</h3>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Importation metrics
-                                       </h4>
-                                       <dl class='dl-horizontal'>
-                                               <dt>{{metrics.mmodule.mnoa.values[mentity.full_name].value}}</dt>
-                                               <dd>ancestors</dd>
-                                               <dt>{{metrics.mmodule.mnop.values[mentity.full_name].value}}</dt>
-                                               <dd>direct parents</dd>
-                                               <dt>{{metrics.mmodule.mnoc.values[mentity.full_name].value}}</dt>
-                                               <dd>direct children</dd>
-                                               <dt>{{metrics.mmodule.mnod.values[mentity.full_name].value}}</dt>
-                                               <dd>descendants</dd>
-                                       </dl>
-                                       <dl class='dl-horizontal'>
-                                               <dt>{{metrics.mmodule.mdit.values[mentity.full_name].value}}</dt>
-                                               <dd>Depth in Inheritance Tree</dd>
-                                       </dl>
-                               </div>
-                       </div>
-               </div>
-               <div class='card'>
-                       <div class='card-body container-fluid'>
-                               <h3 class='card-heading'>Module definitions</h3>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Class definition kinds
-                                               <small>({{metrics.mmodule['mnbi'].values[mentity.full_name].value +
-                                                       metrics.mclass['mnbc'].values[mentity.full_name].value}}
-                                               class definitions)</small>
-                                       </h4>
-                                       <chart-module-definitions-kind chart-id='chartDefinitionsKind'
-                                               chart-metrics='metrics.mmodule' />
-                               </div>
-                               <div class='col-sm-6'>
-                                       <h4>
-                                               Class definition inheritance
-                                               <small>({{metrics.mmodule['mnbd'].values[mentity.full_name].value}}
-                                               accessible definitions)</small>
-                                       </h4>
-                                       <chart-module-definitions-inh chart-id='chartDefinitionsInh'
-                                               chart-metrics='metrics.mmodule' />
-                               </div>
-                       </div>
-               </div>
-               <metrics-list
-                       list-id='classes_inheritance'
-                       list-title='Classes inheritance'
-                       list-metrics='metrics.mclasses'
-                       list-metrics-names='["cdit", "cnoa", "cnop", "cnoc", "cnod"]'
-                       list-metrics-default='"cdit"' />
-               <metrics-list
-                       list-id='classes_properties'
-                       list-title='Classes properties'
-                       list-metrics='metrics.mclasses'
-                       list-metrics-names='["cnbp", "cnba", "cnbip", "cnbrp", "cnbhp", "cnblp"]'
-                       list-metrics-default='"cnbp"' />
-       </div>
-</div>
diff --git a/share/nitweb/views/package.html b/share/nitweb/views/package.html
deleted file mode 100644 (file)
index 38b1bf6..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-<ul class='nav nav-tabs' role='tablist'>
-       <li role='presentation' class='active'>
-               <a data-toggle='tab' role='tab' data-target='#doc' aria-controls="doc">
-                       <span class='glyphicon glyphicon-book'/> Doc
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' data-target='#graph' ng-click="entityCtrl.loadEntityGraph()">
-                       <span class='glyphicon glyphicon-object-align-vertical'/> Dependencies
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' role='tab' data-target='#metrics' aria-controls='metrics' ng-click='entityCtrl.loadStructuralMetrics()'>
-                       <span class='glyphicon glyphicon-stats'/> Metrics
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='doc'>
-               <div class='col-xs-3'>
-                       <ui-summary target='#summary-content' />
-               </div>
-               <div class='col-xs-9' id='summary-content'>
-                       <entity-card mentity='mentity' default-tab='doc' no-synopsis='true' />
-
-                       <entity-list list-title='Groups' list-entities='mentity.mgroups'
-                               list-object-filter='{}' />
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='graph'>
-               <div class='card'>
-                       <div class='card-body text-center'>
-                               <entity-graph mentity='mentity' graph='graph' />
-                       </div>
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='metrics'>
-               <metrics-list
-                       list-id='modules_importation'
-                       list-title='Modules importation'
-                       list-metrics='metrics.mmodules'
-                       list-metrics-names='["mdit", "mnoa", "mnop", "mnoc", "mnod"]'
-                       list-metrics-default='"mdit"' />
-               <metrics-list
-                       list-id='modules_definitions'
-                       list-title='Modules content'
-                       list-metrics='metrics.mmodules'
-                       list-metrics-names='["mnbi", "mnbr", "mnbic", "mnbac", "mnbcc"]'
-                       list-metrics-default='"mnbi"' />
-               <metrics-list
-                       list-id='classes_inheritance'
-                       list-title='Classes inheritance'
-                       list-metrics='metrics.mclasses'
-                       list-metrics-names='["cdit", "cnoa", "cnop", "cnoc", "cnod"]'
-                       list-metrics-default='"cdit"' />
-               <metrics-list
-                       list-id='classes_properties'
-                       list-title='Classes properties'
-                       list-metrics='metrics.mclasses'
-                       list-metrics-names='["cnbp", "cnba", "cnbip", "cnbrp", "cnbhp", "cnblp"]'
-                       list-metrics-default='"cnbp"' />
-       </div>
-</div>
diff --git a/share/nitweb/views/propdef.html b/share/nitweb/views/propdef.html
deleted file mode 100644 (file)
index 975cfb5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<ul class='nav nav-tabs' ng-init='entityCtrl.loadEntityLinearization()'>
-       <li role='presentation' class='warning'>
-               <a href='{{mentity.mproperty.web_url}}'>
-                       <span class='glyphicon glyphicon-chevron-left'/> Go to property
-               </a>
-       </li>
-       <li role='presentation' class='active'>
-               <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization'>
-                       <span class='glyphicon glyphicon-arrow-down'/> Linearization
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='linearization'>
-               <entity-linearization
-                       list-title='Class definitions'
-                       list-entities='linearization'
-                       list-focus='mentity' />
-       </div>
-</div>
diff --git a/share/nitweb/views/property.html b/share/nitweb/views/property.html
deleted file mode 100644 (file)
index 345a3bf..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<ul class='nav nav-tabs'>
-       <li role='presentation' class='active'>
-               <a data-toggle='tab' data-target='#doc'>
-                       <span class='glyphicon glyphicon-book'/> Doc
-               </a>
-       </li>
-       <li role='presentation'>
-               <a data-toggle='tab' role='tab' data-target='#linearization' aria-controls='linearization' ng-click='entityCtrl.loadEntityLinearization()'>
-                       <span class='glyphicon glyphicon-arrow-down'/> Linearization
-               </a>
-       </li>
-</ul>
-
-<div class='tab-content'>
-       <div role='tabpanel' class='tab-pane fade in active' id='doc'>
-               <div class='col-xs-3'>
-                       <ui-summary target='#summary-content' />
-               </div>
-               <div class='col-xs-9' id='summary-content'>
-                       <entity-card mentity='mentity' default-tab='doc' no-synopsis='true' />
-               </div>
-       </div>
-       <div role='tabpanel' class='tab-pane fade' id='linearization'>
-               <entity-linearization
-                       list-title='Class definitions'
-                       list-entities='linearization'
-                       list-focus='mentity.intro' />
-       </div>
-</div>
index 265cadf..1daebdd 100644 (file)
@@ -278,6 +278,8 @@ redef class MClassDef
                end
                return new Namespace.from([mmodule.full_name, "$::", mclass.intro_mmodule.to_ns_ref: nullable NSEntity])
        end
+
+       redef fun web_url do return "{mclass.web_url}/lin#{full_name}"
 end
 
 redef class MProperty
@@ -317,6 +319,8 @@ redef class MPropDef
                end
                return res
        end
+
+       redef fun web_url do return "{mproperty.web_url}/lin#{full_name}"
 end
 
 redef class MClassType