diff --git a/client/js/controllers/auth_controller.js b/client/js/controllers/auth_controller.js index 4470ae0f..b8ca2896 100644 --- a/client/js/controllers/auth_controller.js +++ b/client/js/controllers/auth_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const api = require('../api.js'); const events = require('../events.js'); const topNavController = require('../controllers/top_nav_controller.js'); @@ -14,13 +14,20 @@ class AuthController { } registerRoutes() { - page(/\/password-reset\/([^:]+):([^:]+)$/, + router.enter( + /\/password-reset\/([^:]+):([^:]+)$/, (ctx, next) => { this._passwordResetFinishRoute(ctx.params[0], ctx.params[1]); }); - page('/password-reset', (ctx, next) => { this._passwordResetRoute(); }); - page('/login', (ctx, next) => { this._loginRoute(); }); - page('/logout', (ctx, next) => { this._logoutRoute(); }); + router.enter( + '/password-reset', + (ctx, next) => { this._passwordResetRoute(); }); + router.enter( + '/login', + (ctx, next) => { this._loginRoute(); }); + router.enter( + '/logout', + (ctx, next) => { this._logoutRoute(); }); } _loginRoute() { @@ -33,7 +40,7 @@ class AuthController { api.login(name, password, doRemember) .then(() => { resolve(); - page('/'); + router.show('/'); events.notify(events.Success, 'Logged in'); }, errorMessage => { reject(errorMessage); @@ -46,7 +53,7 @@ class AuthController { _logoutRoute() { api.forget(); api.logout(); - page('/'); + router.show('/'); events.notify(events.Success, 'Logged out'); } @@ -68,10 +75,10 @@ class AuthController { }, response => { return Promise.reject(response.description); }).then(() => { - page('/'); + router.show('/'); events.notify(events.Success, 'New password: ' + password); }, errorMessage => { - page('/'); + router.show('/'); events.notify(events.Error, errorMessage); }); } diff --git a/client/js/controllers/comments_controller.js b/client/js/controllers/comments_controller.js index fbc48965..61e23253 100644 --- a/client/js/controllers/comments_controller.js +++ b/client/js/controllers/comments_controller.js @@ -1,7 +1,7 @@ 'use strict'; const api = require('../api.js'); -const page = require('page'); +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'); @@ -10,7 +10,7 @@ const EmptyView = require('../views/empty_view.js'); class CommentsController { registerRoutes() { - page('/comments/:query?', + router.enter('/comments/:query?', (ctx, next) => { misc.parseSearchQueryRoute(ctx, next); }, (ctx, next) => { this._listCommentsRoute(ctx); }); this._commentsPageView = new CommentsPageView(); diff --git a/client/js/controllers/help_controller.js b/client/js/controllers/help_controller.js index 6c352c33..73c18965 100644 --- a/client/js/controllers/help_controller.js +++ b/client/js/controllers/help_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const topNavController = require('../controllers/top_nav_controller.js'); const HelpView = require('../views/help_view.js'); @@ -10,11 +10,13 @@ class HelpController { } registerRoutes() { - page('/help', () => { this._showHelpRoute(); }); - page( + router.enter( + '/help', + (ctx, next) => { this._showHelpRoute(); }); + router.enter( '/help/:section', (ctx, next) => { this._showHelpRoute(ctx.params.section); }); - page( + router.enter( '/help/:section/:subsection', (ctx, next) => { this._showHelpRoute(ctx.params.section, ctx.params.subsection); diff --git a/client/js/controllers/history_controller.js b/client/js/controllers/history_controller.js index fdd85622..0b7dc851 100644 --- a/client/js/controllers/history_controller.js +++ b/client/js/controllers/history_controller.js @@ -1,11 +1,13 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const topNavController = require('../controllers/top_nav_controller.js'); class HistoryController { registerRoutes() { - page('/history', (ctx, next) => { this._listHistoryRoute(); }); + router.enter( + '/history', + (ctx, next) => { this._listHistoryRoute(); }); } _listHistoryRoute() { diff --git a/client/js/controllers/home_controller.js b/client/js/controllers/home_controller.js index 81777ecb..76987b92 100644 --- a/client/js/controllers/home_controller.js +++ b/client/js/controllers/home_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const api = require('../api.js'); const events = require('../events.js'); const topNavController = require('../controllers/top_nav_controller.js'); @@ -14,8 +14,12 @@ class HomeController { } registerRoutes() { - page('/', (ctx, next) => { this._indexRoute(); }); - page('*', (ctx, next) => { this._notFoundRoute(ctx); }); + router.enter( + '/', + (ctx, next) => { this._indexRoute(); }); + router.enter( + '*', + (ctx, next) => { this._notFoundRoute(ctx); }); } _indexRoute() { diff --git a/client/js/controllers/posts_controller.js b/client/js/controllers/posts_controller.js index b22b7be2..296455d8 100644 --- a/client/js/controllers/posts_controller.js +++ b/client/js/controllers/posts_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const api = require('../api.js'); const settings = require('../settings.js'); const events = require('../events.js'); @@ -20,14 +20,17 @@ class PostsController { } registerRoutes() { - page('/upload', (ctx, next) => { this._uploadPostsRoute(); }); - page('/posts/:query?', + router.enter( + '/upload', + (ctx, next) => { this._uploadPostsRoute(); }); + router.enter( + '/posts/:query?', (ctx, next) => { misc.parseSearchQueryRoute(ctx, next); }, (ctx, next) => { this._listPostsRoute(ctx); }); - page( + router.enter( '/post/:id', (ctx, next) => { this._showPostRoute(ctx.params.id, false); }); - page( + router.enter( '/post/:id/edit', (ctx, next) => { this._showPostRoute(ctx.params.id, true); }); this._emptyView = new EmptyView(); diff --git a/client/js/controllers/settings_controller.js b/client/js/controllers/settings_controller.js index 96da12c9..d7bcd7e9 100644 --- a/client/js/controllers/settings_controller.js +++ b/client/js/controllers/settings_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const settings = require('../settings.js'); const topNavController = require('../controllers/top_nav_controller.js'); const SettingsView = require('../views/settings_view.js'); @@ -11,7 +11,7 @@ class SettingsController { } registerRoutes() { - page('/settings', (ctx, next) => { this._settingsRoute(); }); + router.enter('/settings', (ctx, next) => { this._settingsRoute(); }); } _settingsRoute() { diff --git a/client/js/controllers/tags_controller.js b/client/js/controllers/tags_controller.js index cd0acf8b..ed29c4a3 100644 --- a/client/js/controllers/tags_controller.js +++ b/client/js/controllers/tags_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const api = require('../api.js'); const tags = require('../tags.js'); const events = require('../events.js'); @@ -23,20 +23,22 @@ class TagsController { } registerRoutes() { - page('/tag-categories', () => { this._tagCategoriesRoute(); }); - page( + router.enter( + '/tag-categories', + (ctx, next) => { this._tagCategoriesRoute(ctx, next); }); + router.enter( '/tag/:name', (ctx, next) => { this._loadTagRoute(ctx, next); }, (ctx, next) => { this._showTagRoute(ctx, next); }); - page( + router.enter( '/tag/:name/merge', (ctx, next) => { this._loadTagRoute(ctx, next); }, (ctx, next) => { this._mergeTagRoute(ctx, next); }); - page( + router.enter( '/tag/:name/delete', (ctx, next) => { this._loadTagRoute(ctx, next); }, (ctx, next) => { this._deleteTagRoute(ctx, next); }); - page( + router.enter( '/tags/:query?', (ctx, next) => { misc.parseSearchQueryRoute(ctx, next); }, (ctx, next) => { this._listTagsRoute(ctx, next); }); @@ -136,7 +138,7 @@ class TagsController { _saveTag(tag, input) { return api.put('/tag/' + tag.names[0], input).then(response => { if (input.names && input.names[0] !== tag.names[0]) { - page('/tag/' + input.names[0]); + router.show('/tag/' + input.names[0]); } events.notify(events.Success, 'Tag saved.'); return Promise.resolve(); @@ -151,7 +153,7 @@ class TagsController { '/tag-merge/', {remove: tag.names[0], mergeTo: targetTagName} ).then(response => { - page('/tag/' + targetTagName + '/merge'); + router.show('/tag/' + targetTagName + '/merge'); events.notify(events.Success, 'Tag merged.'); return Promise.resolve(); }, response => { @@ -162,7 +164,7 @@ class TagsController { _deleteTag(tag) { return api.delete('/tag/' + tag.names[0]).then(response => { - page('/tags/'); + router.show('/tags/'); events.notify(events.Success, 'Tag deleted.'); return Promise.resolve(); }, response => { diff --git a/client/js/controllers/users_controller.js b/client/js/controllers/users_controller.js index 8691eb36..a2e276ae 100644 --- a/client/js/controllers/users_controller.js +++ b/client/js/controllers/users_controller.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const api = require('../api.js'); const config = require('../config.js'); const events = require('../events.js'); @@ -34,28 +34,31 @@ class UsersController { } registerRoutes() { - page('/register', () => { this._createUserRoute(); }); - page( + router.enter( + '/register', + (ctx, next) => { this._createUserRoute(ctx, next); }); + router.enter( '/users/:query?', (ctx, next) => { misc.parseSearchQueryRoute(ctx, next); }, (ctx, next) => { this._listUsersRoute(ctx, next); }); - page( + router.enter( '/user/:name', (ctx, next) => { this._loadUserRoute(ctx, next); }, (ctx, next) => { this._showUserRoute(ctx, next); }); - page( + router.enter( '/user/:name/edit', (ctx, next) => { this._loadUserRoute(ctx, next); }, (ctx, next) => { this._editUserRoute(ctx, next); }); - page( + router.enter( '/user/:name/delete', (ctx, next) => { this._loadUserRoute(ctx, next); }, (ctx, next) => { this._deleteUserRoute(ctx, next); }); - page.exit(/\/users\/.*/, (ctx, next) => { - pageController.stop(); - next(); - }); - page.exit(/\/user\/.*/, (ctx, next) => { + router.exit( + /\/users\/.*/, (ctx, next) => { + pageController.stop(); + next(); + }); + router.exit(/\/user\/.*/, (ctx, next) => { this._cachedUser = null; next(); }); @@ -81,7 +84,7 @@ class UsersController { }); } - _createUserRoute() { + _createUserRoute(ctx, next) { topNavController.activate('register'); this._registrationView.render({ register: (...args) => { @@ -135,7 +138,7 @@ class UsersController { return Promise.reject(response.description); }).then(() => { resolve(); - page('/'); + router.show('/'); events.notify(events.Success, 'Welcome aboard!'); }, errorMessage => { reject(); @@ -184,7 +187,7 @@ class UsersController { }).then(() => { resolve(); if (data.name && data.name !== user.name) { - page('/user/' + data.name + '/edit'); + router.show('/user/' + data.name + '/edit'); } events.notify(events.Success, 'Settings updated.'); }, errorMessage => { @@ -203,9 +206,9 @@ class UsersController { api.logout(); } if (api.hasPrivilege('users:list')) { - page('/users'); + router.show('/users'); } else { - page('/'); + router.show('/'); } events.notify(events.Success, 'Account deleted.'); return Promise.resolve(); diff --git a/client/js/main.js b/client/js/main.js index 7afb1e05..103d25b9 100644 --- a/client/js/main.js +++ b/client/js/main.js @@ -3,32 +3,37 @@ require('./util/polyfill.js'); const misc = require('./util/misc.js'); -const page = require('page'); -const origPushState = page.Context.prototype.pushState; -page.Context.prototype.pushState = function() { +const router = require('./router.js'); + +const origPushState = router.Context.prototype.pushState; +router.Context.prototype.pushState = function() { window.scrollTo(0, 0); origPushState.call(this); }; -page.cancel = function(ctx) { +router.cancel = function(ctx) { prevContext = ctx; ctx.pushState(); }; -page.exit((ctx, next) => { - views.unlistenToMessages(); - if (misc.confirmPageExit()) { - next(); - } else { - page.cancel(ctx); - } -}); +router.exit( + /.*/, + (ctx, next) => { + views.unlistenToMessages(); + if (misc.confirmPageExit()) { + next(); + } else { + router.cancel(ctx); + } + }); const mousetrap = require('mousetrap'); -page(/.*/, (ctx, next) => { - mousetrap.reset(); - next(); -}); +router.enter( + /.*/, + (ctx, next) => { + mousetrap.reset(); + next(); + }); let controllers = []; controllers.push(require('./controllers/auth_controller.js')); @@ -40,6 +45,7 @@ controllers.push(require('./controllers/history_controller.js')); controllers.push(require('./controllers/tags_controller.js')); controllers.push(require('./controllers/settings_controller.js')); +// home defines 404 routes, need to be registered as last controllers.push(require('./controllers/home_controller.js')); const tags = require('./tags.js'); @@ -52,13 +58,13 @@ for (let controller of controllers) { const api = require('./api.js'); Promise.all([tags.refreshExport(), api.loginFromCookies()]) .then(() => { - page(); + router.start(); }).catch(errorMessage => { if (window.location.href.indexOf('login') !== -1) { api.forget(); - page(); + router.start(); } else { - page('/'); + router.start('/'); events.notify( events.Error, 'An error happened while trying to log you in: ' + diff --git a/client/js/router.js b/client/js/router.js new file mode 100644 index 00000000..84733269 --- /dev/null +++ b/client/js/router.js @@ -0,0 +1,293 @@ +'use strict'; + +// modified page.js by visionmedia +// - removed unused crap +// - refactored to classes + +const pathToRegexp = require('path-to-regexp'); +const clickEvent = document.ontouchstart ? 'touchstart' : 'click'; +let location = window.history.location || window.location; + +const base = ''; +let prevContext = null; + +function _decodeURLEncodedURIComponent(val) { + if (typeof val !== 'string') { + return val; + } + return decodeURIComponent(val.replace(/\+/g, ' ')); +} + +function _isSameOrigin(href) { + let origin = location.protocol + '//' + location.hostname; + if (location.port) { + origin += ':' + location.port; + } + return href && href.indexOf(origin) === 0; +} + +class Context { + constructor(path, state) { + if (path[0] === '/' && path.indexOf(base) !== 0) { + path = base + path; + } + + this.canonicalPath = path; + this.path = path.replace(base, '') || '/'; + + this.title = document.title; + this.state = state || {}; + this.state.path = path; + this.params = {}; + } + + pushState() { + history.pushState(this.state, this.title, this.canonicalPath); + } + + save() { + history.replaceState(this.state, this.title, this.canonicalPath); + } +}; + +class Route { + constructor(path, options) { + options = options || {}; + this.path = (path === '*') ? '(.*)' : path; + this.method = 'GET'; + this.regexp = pathToRegexp(this.path, this.keys = [], options); + } + + middleware(fn) { + return (ctx, next) => { + if (this.match(ctx.path, ctx.params)) { + return fn(ctx, next); + } + next(); + }; + } + + match(path, params) { + const keys = this.keys; + const qsIndex = path.indexOf('?'); + const pathname = ~qsIndex ? path.slice(0, qsIndex) : path; + const m = this.regexp.exec(decodeURIComponent(pathname)); + + if (!m) { + return false; + } + + for (let i = 1, len = m.length; i < len; ++i) { + const key = keys[i - 1]; + const val = _decodeURLEncodedURIComponent(m[i]); + if (val !== undefined || !(hasOwnProperty.call(params, key.name))) { + params[key.name] = val; + } + } + + return true; + } +}; + +class Router { + constructor() { + this._callbacks = []; + this._exits = []; + this._current = ''; + } + + enter(path) { + const route = new Route(path); + for (let i = 1; i < arguments.length; ++i) { + this._callbacks.push(route.middleware(arguments[i])); + } + } + + exit(path, fn) { + const route = new Route(path); + for (let i = 1; i < arguments.length; ++i) { + this._exits.push(route.middleware(arguments[i])); + } + } + + start() { + if (this._running) { + return; + } + this._running = true; + this._onPopState = _onPopState(this); + this._onClick = _onClick(this); + window.addEventListener('popstate', this._onPopState, false); + document.addEventListener(clickEvent, this._onClick, false); + const url = location.pathname + location.search + location.hash; + this.replace(url, null, true); + } + + stop() { + if (!this._running) { + return; + } + this._current = ''; + this._running = false; + document.removeEventListener(clickEvent, this._onClick, false); + window.removeEventListener('popstate', this._onPopState, false); + } + + show(path, state, push) { + const ctx = new Context(path, state); + this._current = ctx.path; + this.dispatch(ctx); + if (ctx.handled !== false && push !== false) { + ctx.pushState(); + } + return ctx; + } + + replace(path, state, dispatch) { + var ctx = new Context(path, state); + this._current = ctx.path; + ctx.save(); + if (dispatch) { + this.dispatch(ctx); + } + return ctx; + } + + dispatch(ctx) { + const prev = prevContext; + let i = 0; + let j = 0; + + prevContext = ctx; + + const nextExit = () => { + const fn = this._exits[j++]; + if (!fn) { + return nextEnter(); + } + fn(prev, nextExit); + }; + + const nextEnter = () => { + const fn = this._callbacks[i++]; + if (ctx.path !== this._current) { + ctx.handled = false; + return; + } + if (!fn) { + return this._unhandled(ctx); + } + fn(ctx, nextEnter); + }; + + if (prev) { + nextExit(); + } else { + nextEnter(); + } + } + + _unhandled(ctx) { + if (ctx.handled) { + return; + } + let current = location.pathname + location.search; + if (current === ctx.canonicalPath) { + return; + } + router.stop(); + ctx.handled = false; + location.href = ctx.canonicalPath; + } +}; + +const _onPopState = router => { + let loaded = false; + if (document.readyState === 'complete') { + loaded = true; + } else { + window.addEventListener( + 'load', + () => { + setTimeout(() => { + loaded = true; + }, 0); + }); + } + return e => { + if (!loaded) { + return; + } + if (e.state) { + const path = e.state.path; + router.replace(path, e.state, true); + } else { + router.show( + location.pathname + location.hash, + undefined, + false); + } + }; +}; + +const _onClick = router => { + return e => { + if (1 !== _which(e)) { + return; + } + if (e.metaKey || e.ctrlKey || e.shiftKey) { + return; + } + if (e.defaultPrevented) { + return; + } + + let el = e.path ? e.path[0] : e.target; + while (el && el.nodeName !== 'A') { + el = el.parentNode; + } + if (!el || el.nodeName !== 'A') { + return; + } + + if (el.hasAttribute('download') || + el.getAttribute('rel') === 'external') { + return; + } + + const link = el.getAttribute('href'); + if (el.pathname === location.pathname && (el.hash || '#' === link)) { + return; + } + if (link && link.indexOf('mailto:') > -1) { + return; + } + if (el.target) { + return; + } + if (!_isSameOrigin(el.href)) { + return; + } + + let path = el.pathname + el.search + (el.hash || ''); + + const orig = path; + if (path.indexOf(base) === 0) { + path = path.substr(base.length); + } + if (base && orig === path) { + return; + } + e.preventDefault(); + router.show(orig); + }; +}; + +function _which(e) { + e = e || window.event; + return e.which === null ? e.button : e.which; +} + +Router.prototype.Context = Context; +Router.prototype.Route = Route; +module.exports = new Router(); diff --git a/client/js/views/endless_page_view.js b/client/js/views/endless_page_view.js index 579db944..14892ae5 100644 --- a/client/js/views/endless_page_view.js +++ b/client/js/views/endless_page_view.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const events = require('../events.js'); const views = require('../util/views.js'); @@ -55,10 +55,9 @@ class EndlessPageView { } let topPageNumber = parseInt(topPageNode.getAttribute('data-page')); if (topPageNumber !== this.currentPage) { - page.replace( + router.replace( _formatUrl(ctx.clientUrl, topPageNumber), - null, - false, + {}, false); this.currentPage = topPageNumber; } diff --git a/client/js/views/home_view.js b/client/js/views/home_view.js index c945d744..25f51c4b 100644 --- a/client/js/views/home_view.js +++ b/client/js/views/home_view.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const config = require('../config.js'); const misc = require('../util/misc.js'); const views = require('../util/views.js'); @@ -32,7 +32,7 @@ class HomeView { form.querySelector('input[name=all-posts') .addEventListener('click', e => { e.preventDefault(); - page('/posts/'); + router.show('/posts/'); }); const searchTextInput = form.querySelector( @@ -42,7 +42,7 @@ class HomeView { e.preventDefault(); const text = searchTextInput.value; searchTextInput.blur(); - page('/posts/' + misc.formatSearchQuery({text: text})); + router.show('/posts/' + misc.formatSearchQuery({text: text})); }); } diff --git a/client/js/views/manual_page_view.js b/client/js/views/manual_page_view.js index e67c9cf3..58761d59 100644 --- a/client/js/views/manual_page_view.js +++ b/client/js/views/manual_page_view.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const events = require('../events.js'); const keyboard = require('../util/keyboard.js'); const misc = require('../util/misc.js'); @@ -85,12 +85,12 @@ class ManualPageView { keyboard.bind(['a', 'left'], () => { if (currentPage > 1) { - page.show(_formatUrl(ctx.clientUrl, currentPage - 1)); + router.show(_formatUrl(ctx.clientUrl, currentPage - 1)); } }); keyboard.bind(['d', 'right'], () => { if (currentPage < totalPages) { - page.show(_formatUrl(ctx.clientUrl, currentPage + 1)); + router.show(_formatUrl(ctx.clientUrl, currentPage + 1)); } }); diff --git a/client/js/views/post_view.js b/client/js/views/post_view.js index 0968682f..1fe2f369 100644 --- a/client/js/views/post_view.js +++ b/client/js/views/post_view.js @@ -1,9 +1,9 @@ 'use strict'; const api = require('../api.js'); +const router = require('../router.js'); const views = require('../util/views.js'); const keyboard = require('../util/keyboard.js'); -const page = require('page'); const PostContentControl = require('../controls/post_content_control.js'); const PostNotesOverlayControl = require('../controls/post_notes_overlay_control.js'); @@ -60,19 +60,19 @@ class PostView { keyboard.bind('e', () => { if (ctx.editMode) { - page.show('/post/' + ctx.post.id); + router.show('/post/' + ctx.post.id); } else { - page.show('/post/' + ctx.post.id + '/edit'); + router.show('/post/' + ctx.post.id + '/edit'); } }); keyboard.bind(['a', 'left'], () => { if (ctx.nextPostId) { - page.show('/post/' + ctx.nextPostId); + router.show('/post/' + ctx.nextPostId); } }); keyboard.bind(['d', 'right'], () => { if (ctx.prevPostId) { - page.show('/post/' + ctx.prevPostId); + router.show('/post/' + ctx.prevPostId); } }); } diff --git a/client/js/views/posts_header_view.js b/client/js/views/posts_header_view.js index 261aa87a..79537e45 100644 --- a/client/js/views/posts_header_view.js +++ b/client/js/views/posts_header_view.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const settings = require('../settings.js'); const keyboard = require('../util/keyboard.js'); const misc = require('../util/misc.js'); @@ -56,14 +56,14 @@ class PostsHeaderView { browsingSettings.listPosts[safety] = !browsingSettings.listPosts[safety]; settings.saveSettings(browsingSettings, true); - page(url.replace(/{page}/, 1)); + router.show(url.replace(/{page}/, 1)); } _evtFormSubmit(e, searchTextInput) { e.preventDefault(); const text = searchTextInput.value; searchTextInput.blur(); - page('/posts/' + misc.formatSearchQuery({text: text})); + router.show('/posts/' + misc.formatSearchQuery({text: text})); } } diff --git a/client/js/views/tags_header_view.js b/client/js/views/tags_header_view.js index ac4dbf5e..e175bf5c 100644 --- a/client/js/views/tags_header_view.js +++ b/client/js/views/tags_header_view.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const keyboard = require('../util/keyboard.js'); const misc = require('../util/misc.js'); const views = require('../util/views.js'); @@ -31,7 +31,7 @@ class TagsHeaderView { e.preventDefault(); const text = searchTextInput.value; searchTextInput.blur(); - page('/tags/' + misc.formatSearchQuery({text: text})); + router.show('/tags/' + misc.formatSearchQuery({text: text})); }); views.showView(target, source); diff --git a/client/js/views/users_header_view.js b/client/js/views/users_header_view.js index 1f60e971..601dfd04 100644 --- a/client/js/views/users_header_view.js +++ b/client/js/views/users_header_view.js @@ -1,6 +1,6 @@ 'use strict'; -const page = require('page'); +const router = require('../router.js'); const keyboard = require('../util/keyboard.js'); const misc = require('../util/misc.js'); const views = require('../util/views.js'); @@ -25,7 +25,7 @@ class UsersHeaderView { const searchTextInput = form.querySelector('[name=search-text]'); const text = searchTextInput.value; searchTextInput.blur(); - page('/users/' + misc.formatSearchQuery({text: text})); + router.show('/users/' + misc.formatSearchQuery({text: text})); }); views.showView(target, source); diff --git a/client/package.json b/client/package.json index 250013b8..fa5d78b6 100644 --- a/client/package.json +++ b/client/package.json @@ -22,7 +22,7 @@ "merge": "^1.2.0", "mousetrap": "^1.5.3", "nprogress": "^0.2.0", - "page": "^1.7.1", + "path-to-regexp": "^1.5.1", "stylus": "^0.54.2", "superagent": "^1.8.3", "uglify-js": "git://github.com/mishoo/UglifyJS2.git#harmony",