client/top-nav: trying out actual mvc
This commit is contained in:
parent
e93af8b577
commit
0f1e234a5d
22 changed files with 240 additions and 174 deletions
|
@ -1,6 +1,6 @@
|
|||
$main-color = #24AADD
|
||||
$window-color = white
|
||||
$top-nav-color = #F5F5F5
|
||||
$top-navigation-color = #F5F5F5
|
||||
$text-color = #111
|
||||
$inactive-link-color = #888
|
||||
$line-color = #DDD
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
line-height: 16pt
|
||||
vertical-align: middle
|
||||
margin-bottom: 0.5em
|
||||
background: $top-nav-color
|
||||
background: $top-navigation-color
|
||||
padding: 0.2em 0.5em
|
||||
|
||||
.date, .score-container, .edit, .delete
|
||||
|
|
|
@ -68,7 +68,7 @@ form .fa-question-circle-o
|
|||
>*:first-child, form h1
|
||||
margin-top: 0
|
||||
>.content-wrapper:not(.transparent)
|
||||
background: $top-nav-color
|
||||
background: $top-navigation-color
|
||||
padding: 2vw
|
||||
|
||||
hr
|
||||
|
@ -113,8 +113,8 @@ nav
|
|||
background: $focused-tab-background-color
|
||||
outline: 0
|
||||
|
||||
&#top-nav
|
||||
background: $top-nav-color
|
||||
&#top-navigation
|
||||
background: $top-navigation-color
|
||||
margin: 0
|
||||
ul
|
||||
display: block
|
||||
|
@ -207,7 +207,7 @@ a .access-key
|
|||
top: 50%
|
||||
right: 0
|
||||
height: 3px
|
||||
background: $top-nav-color
|
||||
background: $top-navigation-color
|
||||
z-index: 1
|
||||
span
|
||||
position: relative
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
text-align: left
|
||||
line-height: 1.3em
|
||||
tr:hover td
|
||||
background: $top-nav-color
|
||||
background: $top-navigation-color
|
||||
th, td
|
||||
padding: 0.1em 0.5em
|
||||
th
|
||||
background: $top-nav-color
|
||||
background: $top-navigation-color
|
||||
.names
|
||||
width: 28%
|
||||
.implications
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
margin: 0 0.5em 1em 0.5em
|
||||
padding: 0.75em
|
||||
vertical-align: top
|
||||
background: $top-nav-color
|
||||
background: $top-navigation-color
|
||||
text-align: left
|
||||
.wrapper
|
||||
display: flex
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<link rel='shortcut icon' type='image/png' href='/img/favicon.png'/>
|
||||
</head>
|
||||
<body>
|
||||
<div id='top-nav-holder'></div>
|
||||
<div id='top-navigation-holder'></div>
|
||||
<div id='content-holder'></div>
|
||||
<script type='text/javascript' src='/js/vendor.min.js'></script>
|
||||
<script type='text/javascript' src='/js/app.min.js'></script>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<nav id='top-nav' class='buttons'>
|
||||
<ul><!--
|
||||
--><% for (let [key, item] of ctx.items) { %><!--
|
||||
<nav id='top-navigation' class='buttons'><!--
|
||||
--><ul><!--
|
||||
--><% for (let item of ctx.items) { %><!--
|
||||
--><% if (item.available) { %><!--
|
||||
--><li data-name='<%= key %>'><!--
|
||||
--><li data-name='<%= item.key %>'><!--
|
||||
--><a href='<%= item.url %>' accesskey='<%= item.accessKey %>'><!--
|
||||
--><% if (item.imageUrl) { print(ctx.makeThumbnail(item.imageUrl)); } %><!--
|
||||
--><span class='text'><%= ctx.makeAccessKey(item.name, item.accessKey) %></span><!--
|
||||
--><span class='text'><%= ctx.makeAccessKey(item.title, item.accessKey) %></span><!--
|
||||
--></a><!--
|
||||
--></li><!--
|
||||
--><% } %><!--
|
||||
--><% } %><!--
|
||||
--></ul>
|
||||
</nav>
|
||||
--></ul><!--
|
||||
--></nav>
|
|
@ -3,7 +3,7 @@
|
|||
const router = require('../router.js');
|
||||
const api = require('../api.js');
|
||||
const events = require('../events.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const LoginView = require('../views/login_view.js');
|
||||
const PasswordResetView = require('../views/password_reset_view.js');
|
||||
|
||||
|
@ -32,7 +32,7 @@ class AuthController {
|
|||
|
||||
_loginRoute() {
|
||||
api.forget();
|
||||
topNavController.activate('login');
|
||||
TopNavigation.activate('login');
|
||||
this._loginView.render({
|
||||
login: (name, password, doRemember) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -58,7 +58,7 @@ class AuthController {
|
|||
}
|
||||
|
||||
_passwordResetRoute() {
|
||||
topNavController.activate('login');
|
||||
TopNavigation.activate('login');
|
||||
this._passwordResetView.render({
|
||||
proceed: (...args) => {
|
||||
return this._passwordReset(...args);
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
const api = require('../api.js');
|
||||
const router = require('../router.js');
|
||||
const misc = require('../util/misc.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const pageController = require('../controllers/page_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const CommentsPageView = require('../views/comments_page_view.js');
|
||||
const EmptyView = require('../views/empty_view.js');
|
||||
|
||||
|
@ -18,7 +18,7 @@ class CommentsController {
|
|||
}
|
||||
|
||||
_listCommentsRoute(ctx) {
|
||||
topNavController.activate('comments');
|
||||
TopNavigation.activate('comments');
|
||||
|
||||
pageController.run({
|
||||
searchQuery: ctx.searchQuery,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const router = require('../router.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const HelpView = require('../views/help_view.js');
|
||||
|
||||
class HelpController {
|
||||
|
@ -24,7 +24,7 @@ class HelpController {
|
|||
}
|
||||
|
||||
_showHelpRoute(section, subsection) {
|
||||
topNavController.activate('help');
|
||||
TopNavigation.activate('help');
|
||||
this._helpView.render({
|
||||
section: section,
|
||||
subsection: subsection,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const router = require('../router.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
|
||||
class HistoryController {
|
||||
registerRoutes() {
|
||||
|
@ -11,7 +11,7 @@ class HistoryController {
|
|||
}
|
||||
|
||||
_listHistoryRoute() {
|
||||
topNavController.activate('');
|
||||
TopNavigation.activate('');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
const router = require('../router.js');
|
||||
const api = require('../api.js');
|
||||
const events = require('../events.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const HomeView = require('../views/home_view.js');
|
||||
const NotFoundView = require('../views/not_found_view.js');
|
||||
|
||||
|
@ -23,7 +23,7 @@ class HomeController {
|
|||
}
|
||||
|
||||
_indexRoute() {
|
||||
topNavController.activate('home');
|
||||
TopNavigation.activate('home');
|
||||
|
||||
api.get('/info')
|
||||
.then(response => {
|
||||
|
@ -45,7 +45,7 @@ class HomeController {
|
|||
}
|
||||
|
||||
_notFoundRoute(ctx) {
|
||||
topNavController.activate('');
|
||||
TopNavigation.activate('');
|
||||
this._notFoundView.render({path: ctx.canonicalPath});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ const api = require('../api.js');
|
|||
const settings = require('../settings.js');
|
||||
const events = require('../events.js');
|
||||
const misc = require('../util/misc.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const pageController = require('../controllers/page_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const PostsHeaderView = require('../views/posts_header_view.js');
|
||||
const PostsPageView = require('../views/posts_page_view.js');
|
||||
const PostView = require('../views/post_view.js');
|
||||
|
@ -37,12 +37,12 @@ class PostsController {
|
|||
}
|
||||
|
||||
_uploadPostsRoute() {
|
||||
topNavController.activate('upload');
|
||||
TopNavigation.activate('upload');
|
||||
this._emptyView.render();
|
||||
}
|
||||
|
||||
_listPostsRoute(ctx) {
|
||||
topNavController.activate('posts');
|
||||
TopNavigation.activate('posts');
|
||||
|
||||
pageController.run({
|
||||
searchQuery: ctx.searchQuery,
|
||||
|
@ -67,7 +67,7 @@ class PostsController {
|
|||
}
|
||||
|
||||
_showPostRoute(id, editMode) {
|
||||
topNavController.activate('posts');
|
||||
TopNavigation.activate('posts');
|
||||
Promise.all([
|
||||
api.get('/post/' + id),
|
||||
api.get(`/post/${id}/around?fields=id&query=` +
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
const router = require('../router.js');
|
||||
const settings = require('../settings.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const SettingsView = require('../views/settings_view.js');
|
||||
|
||||
class SettingsController {
|
||||
|
@ -15,7 +15,7 @@ class SettingsController {
|
|||
}
|
||||
|
||||
_settingsRoute() {
|
||||
topNavController.activate('settings');
|
||||
TopNavigation.activate('settings');
|
||||
this._settingsView.render({
|
||||
getSettings: () => settings.getSettings(),
|
||||
saveSettings: newSettings => settings.saveSettings(newSettings),
|
||||
|
|
|
@ -5,8 +5,8 @@ const api = require('../api.js');
|
|||
const tags = require('../tags.js');
|
||||
const events = require('../events.js');
|
||||
const misc = require('../util/misc.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const pageController = require('../controllers/page_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const TagView = require('../views/tag_view.js');
|
||||
const TagsHeaderView = require('../views/tags_header_view.js');
|
||||
const TagsPageView = require('../views/tags_page_view.js');
|
||||
|
@ -114,7 +114,7 @@ class TagsController {
|
|||
}
|
||||
|
||||
_show(tag, section) {
|
||||
topNavController.activate('tags');
|
||||
TopNavigation.activate('tags');
|
||||
const categories = {};
|
||||
for (let category of tags.getAllCategories()) {
|
||||
categories[category.name] = category.name;
|
||||
|
@ -174,7 +174,7 @@ class TagsController {
|
|||
}
|
||||
|
||||
_tagCategoriesRoute(ctx, next) {
|
||||
topNavController.activate('tags');
|
||||
TopNavigation.activate('tags');
|
||||
api.get('/tag-categories/').then(response => {
|
||||
this._tagCategoriesView.render({
|
||||
tagCategories: response.results,
|
||||
|
@ -201,7 +201,7 @@ class TagsController {
|
|||
}
|
||||
|
||||
_listTagsRoute(ctx, next) {
|
||||
topNavController.activate('tags');
|
||||
TopNavigation.activate('tags');
|
||||
|
||||
pageController.run({
|
||||
searchQuery: ctx.searchQuery,
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const api = require('../api.js');
|
||||
const events = require('../events.js');
|
||||
const TopNavView = require('../views/top_nav_view.js');
|
||||
|
||||
function _createNavigationItemMap() {
|
||||
const ret = new Map();
|
||||
ret.set('home', new NavigationItem('H', 'Home', '/'));
|
||||
ret.set('posts', new NavigationItem('P', 'Posts', '/posts'));
|
||||
ret.set('upload', new NavigationItem('U', 'Upload', '/upload'));
|
||||
ret.set('comments', new NavigationItem('C', 'Comments', '/comments'));
|
||||
ret.set('tags', new NavigationItem('T', 'Tags', '/tags'));
|
||||
ret.set('users', new NavigationItem('S', 'Users', '/users'));
|
||||
ret.set('account', new NavigationItem('A', 'Account', '/user/{me}'));
|
||||
ret.set('register', new NavigationItem('R', 'Register', '/register'));
|
||||
ret.set('login', new NavigationItem('L', 'Log in', '/login'));
|
||||
ret.set('logout', new NavigationItem('O', 'Logout', '/logout'));
|
||||
ret.set('help', new NavigationItem('E', 'Help', '/help'));
|
||||
ret.set(
|
||||
'settings',
|
||||
new NavigationItem(null, '<i class=\'fa fa-cog\'></i>', '/settings'));
|
||||
return ret;
|
||||
}
|
||||
|
||||
class NavigationItem {
|
||||
constructor(accessKey, name, url) {
|
||||
this.accessKey = accessKey;
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
this.available = true;
|
||||
this.imageUrl = null;
|
||||
}
|
||||
}
|
||||
|
||||
class TopNavController {
|
||||
constructor() {
|
||||
this._topNavView = new TopNavView();
|
||||
this._activeItem = null;
|
||||
this._items = _createNavigationItemMap();
|
||||
|
||||
const rerender = () => {
|
||||
this._updateVisibility();
|
||||
this._topNavView.render({
|
||||
items: this._items,
|
||||
activeItem: this._activeItem});
|
||||
this._topNavView.activate(this._activeItem);
|
||||
};
|
||||
|
||||
events.listen(
|
||||
events.Authentication,
|
||||
() => { rerender(); return true; });
|
||||
rerender();
|
||||
}
|
||||
|
||||
_updateVisibility() {
|
||||
this._items.get('account').url = '/user/' + api.userName;
|
||||
this._items.get('account').imageUrl = api.user ?
|
||||
api.user.avatarUrl : null;
|
||||
|
||||
for (let [key, item] of this._items) {
|
||||
item.available = true;
|
||||
}
|
||||
if (!api.hasPrivilege('posts:list')) {
|
||||
this._items.get('posts').available = false;
|
||||
}
|
||||
if (!api.hasPrivilege('posts:create')) {
|
||||
this._items.get('upload').available = false;
|
||||
}
|
||||
if (!api.hasPrivilege('comments:list')) {
|
||||
this._items.get('comments').available = false;
|
||||
}
|
||||
if (!api.hasPrivilege('tags:list')) {
|
||||
this._items.get('tags').available = false;
|
||||
}
|
||||
if (!api.hasPrivilege('users:list')) {
|
||||
this._items.get('users').available = false;
|
||||
}
|
||||
if (api.isLoggedIn()) {
|
||||
this._items.get('register').available = false;
|
||||
this._items.get('login').available = false;
|
||||
} else {
|
||||
this._items.get('account').available = false;
|
||||
this._items.get('logout').available = false;
|
||||
}
|
||||
}
|
||||
|
||||
activate(itemName) {
|
||||
this._activeItem = itemName;
|
||||
this._topNavView.activate(this._activeItem);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new TopNavController();
|
70
client/js/controllers/top_navigation_controller.js
Normal file
70
client/js/controllers/top_navigation_controller.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
'use strict';
|
||||
|
||||
const api = require('../api.js');
|
||||
const events = require('../events.js');
|
||||
const TopNavigationView = require('../views/top_navigation_view.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
|
||||
class TopNavigationController {
|
||||
constructor() {
|
||||
this._topNavigationView = new TopNavigationView();
|
||||
|
||||
TopNavigation.addEventListener(
|
||||
'activate', e => this._evtActivate(e));
|
||||
|
||||
events.listen(
|
||||
events.Authentication,
|
||||
() => {
|
||||
this._render();
|
||||
return true;
|
||||
});
|
||||
|
||||
this._render();
|
||||
}
|
||||
|
||||
_evtActivate(e) {
|
||||
this._topNavigationView.activate(e.key);
|
||||
}
|
||||
|
||||
_updateNavigationFromPrivileges() {
|
||||
TopNavigation.get('account').url = '/user/' + api.userName;
|
||||
TopNavigation.get('account').imageUrl =
|
||||
api.user ? api.user.avatarUrl : null;
|
||||
|
||||
TopNavigation.showAll();
|
||||
if (!api.hasPrivilege('posts:list')) {
|
||||
TopNavigation.hide('posts');
|
||||
}
|
||||
if (!api.hasPrivilege('posts:create')) {
|
||||
TopNavigation.hide('upload');
|
||||
}
|
||||
if (!api.hasPrivilege('comments:list')) {
|
||||
TopNavigation.hide('comments');
|
||||
}
|
||||
if (!api.hasPrivilege('tags:list')) {
|
||||
TopNavigation.hide('tags');
|
||||
}
|
||||
if (!api.hasPrivilege('users:list')) {
|
||||
TopNavigation.hide('users');
|
||||
}
|
||||
if (api.isLoggedIn()) {
|
||||
TopNavigation.hide('register');
|
||||
TopNavigation.hide('login');
|
||||
} else {
|
||||
TopNavigation.hide('account');
|
||||
TopNavigation.hide('logout');
|
||||
}
|
||||
}
|
||||
|
||||
_render() {
|
||||
this._updateNavigationFromPrivileges();
|
||||
console.log(TopNavigation.getAll());
|
||||
this._topNavigationView.render({
|
||||
items: TopNavigation.getAll(),
|
||||
});
|
||||
this._topNavigationView.activate(
|
||||
TopNavigation.activeItem ? TopNavigation.activeItem.key : '');
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = new TopNavigationController();
|
|
@ -6,8 +6,8 @@ const config = require('../config.js');
|
|||
const events = require('../events.js');
|
||||
const misc = require('../util/misc.js');
|
||||
const views = require('../util/views.js');
|
||||
const topNavController = require('../controllers/top_nav_controller.js');
|
||||
const pageController = require('../controllers/page_controller.js');
|
||||
const TopNavigation = require('../models/top_navigation.js');
|
||||
const RegistrationView = require('../views/registration_view.js');
|
||||
const UserView = require('../views/user_view.js');
|
||||
const UsersHeaderView = require('../views/users_header_view.js');
|
||||
|
@ -65,7 +65,7 @@ class UsersController {
|
|||
}
|
||||
|
||||
_listUsersRoute(ctx, next) {
|
||||
topNavController.activate('users');
|
||||
TopNavigation.activate('users');
|
||||
|
||||
pageController.run({
|
||||
searchQuery: ctx.searchQuery,
|
||||
|
@ -87,7 +87,7 @@ class UsersController {
|
|||
}
|
||||
|
||||
_createUserRoute(ctx, next) {
|
||||
topNavController.activate('register');
|
||||
TopNavigation.activate('register');
|
||||
this._registrationView.render({
|
||||
register: (...args) => {
|
||||
return this._register(...args);
|
||||
|
@ -237,9 +237,9 @@ class UsersController {
|
|||
}
|
||||
|
||||
if (isLoggedIn) {
|
||||
topNavController.activate('account');
|
||||
TopNavigation.activate('account');
|
||||
} else {
|
||||
topNavController.activate('users');
|
||||
TopNavigation.activate('users');
|
||||
}
|
||||
this._userView.render({
|
||||
user: user,
|
||||
|
|
93
client/js/models/top_navigation.js
Normal file
93
client/js/models/top_navigation.js
Normal file
|
@ -0,0 +1,93 @@
|
|||
'use strict';
|
||||
|
||||
const events = require('../events.js');
|
||||
|
||||
class TopNavigationItem {
|
||||
constructor(accessKey, title, url, available, imageUrl) {
|
||||
this.accessKey = accessKey;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.available = available === undefined ? true : available;
|
||||
this.imageUrl = imageUrl === undefined ? null : imageUrl;
|
||||
this.key = null;
|
||||
}
|
||||
};
|
||||
|
||||
class TopNavigation extends events.EventTarget {
|
||||
constructor() {
|
||||
super();
|
||||
this.activeItem = null;
|
||||
this._keyToItem = new Map();
|
||||
this._items = [];
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return this._items;
|
||||
}
|
||||
|
||||
get(key) {
|
||||
if (!this._keyToItem.has(key)) {
|
||||
throw `An item with key ${key} does not exist.`;
|
||||
}
|
||||
return this._keyToItem.get(key);
|
||||
}
|
||||
|
||||
add(key, item) {
|
||||
item.key = key;
|
||||
if (this._keyToItem.has(key)) {
|
||||
throw `An item with key ${key} was already added.`;
|
||||
}
|
||||
this._keyToItem.set(key, item);
|
||||
this._items.push(item);
|
||||
}
|
||||
|
||||
activate(key) {
|
||||
const event = new Event('activate');
|
||||
event.key = key;
|
||||
if (key) {
|
||||
event.item = this.get(key);
|
||||
} else {
|
||||
event.item = null;
|
||||
}
|
||||
this.activeItem = null;
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
showAll() {
|
||||
for (let item of this._items) {
|
||||
item.available = true;
|
||||
}
|
||||
}
|
||||
|
||||
show(key) {
|
||||
this.get(key).available = true;
|
||||
}
|
||||
|
||||
hide(key) {
|
||||
this.get(key).available = false;
|
||||
}
|
||||
};
|
||||
|
||||
function _makeTopNavigation() {
|
||||
const ret = new TopNavigation();
|
||||
ret.add('home', new TopNavigationItem('H', 'Home', '/'));
|
||||
ret.add('posts', new TopNavigationItem('P', 'Posts', '/posts'));
|
||||
ret.add('upload', new TopNavigationItem('U', 'Upload', '/upload'));
|
||||
ret.add('comments', new TopNavigationItem('C', 'Comments', '/comments'));
|
||||
ret.add('tags', new TopNavigationItem('T', 'Tags', '/tags'));
|
||||
ret.add('users', new TopNavigationItem('S', 'Users', '/users'));
|
||||
ret.add('account', new TopNavigationItem('A', 'Account', '/user/{me}'));
|
||||
ret.add('register', new TopNavigationItem('R', 'Register', '/register'));
|
||||
ret.add('login', new TopNavigationItem('L', 'Log in', '/login'));
|
||||
ret.add('logout', new TopNavigationItem('O', 'Logout', '/logout'));
|
||||
ret.add('help', new TopNavigationItem('E', 'Help', '/help'));
|
||||
ret.add(
|
||||
'settings',
|
||||
new TopNavigationItem(
|
||||
null,
|
||||
'<i class=\'fa fa-cog\'></i>',
|
||||
'/settings'));
|
||||
return ret;
|
||||
}
|
||||
|
||||
module.exports = _makeTopNavigation();
|
|
@ -29,12 +29,13 @@ class PostView {
|
|||
views.listenToMessages(source);
|
||||
views.showView(target, source);
|
||||
|
||||
const topNavNode = document.body.querySelector('#top-nav');
|
||||
const postViewNode = document.body.querySelector('.content-wrapper');
|
||||
const topNavigationNode =
|
||||
document.body.querySelector('#top-navigation');
|
||||
|
||||
const margin = (
|
||||
postViewNode.getBoundingClientRect().top -
|
||||
topNavNode.getBoundingClientRect().height);
|
||||
topNavigationNode.getBoundingClientRect().height);
|
||||
|
||||
this._postContentControl = new PostContentControl(
|
||||
postContainerNode,
|
||||
|
@ -45,7 +46,7 @@ class PostView {
|
|||
postContainerNode.getBoundingClientRect().left -
|
||||
margin,
|
||||
window.innerHeight -
|
||||
topNavNode.getBoundingClientRect().height -
|
||||
topNavigationNode.getBoundingClientRect().height -
|
||||
margin * 2,
|
||||
];
|
||||
});
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const views = require('../util/views.js');
|
||||
|
||||
class TopNavView {
|
||||
constructor() {
|
||||
this._template = views.getTemplate('top-nav');
|
||||
this._navHolder = document.getElementById('top-nav-holder');
|
||||
this._lastCtx = null;
|
||||
}
|
||||
|
||||
render(ctx) {
|
||||
this._lastCtx = ctx;
|
||||
const target = this._navHolder;
|
||||
const source = this._template(ctx);
|
||||
views.showView(this._navHolder, source);
|
||||
}
|
||||
|
||||
activate(itemName) {
|
||||
const allItemsSelector = '#top-nav-holder [data-name]';
|
||||
const currentItemSelector =
|
||||
'#top-nav-holder [data-name="' + itemName + '"]';
|
||||
for (let item of document.querySelectorAll(allItemsSelector)) {
|
||||
item.className = '';
|
||||
}
|
||||
const currentItem = document.querySelectorAll(currentItemSelector);
|
||||
if (currentItem.length > 0) {
|
||||
currentItem[0].className = 'active';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TopNavView;
|
29
client/js/views/top_navigation_view.js
Normal file
29
client/js/views/top_navigation_view.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
const views = require('../util/views.js');
|
||||
|
||||
class TopNavigationView {
|
||||
constructor() {
|
||||
this._template = views.getTemplate('top-navigation');
|
||||
this._navHolder = document.getElementById('top-navigation-holder');
|
||||
this._lastCtx = null;
|
||||
}
|
||||
|
||||
render(ctx) {
|
||||
this._lastCtx = ctx;
|
||||
const target = this._navHolder;
|
||||
const source = this._template(ctx);
|
||||
views.showView(this._navHolder, source);
|
||||
}
|
||||
|
||||
activate(key) {
|
||||
const allItemNodes = document.querySelectorAll(
|
||||
'#top-navigation-holder [data-name]');
|
||||
for (let itemNode of allItemNodes) {
|
||||
itemNode.classList.toggle(
|
||||
'active', itemNode.getAttribute('data-name') === key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TopNavigationView;
|
Loading…
Reference in a new issue