From 177a7d79f339a50423c7fc8a52f4248eab529876 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sat, 18 Oct 2014 12:37:01 +0200 Subject: [PATCH] Added 404 page --- TODO | 1 - public_html/.htaccess | 4 ++ public_html/css/http-error.css | 6 +++ public_html/img/404.png | Bin 0 -> 36800 bytes public_html/index.html | 2 + .../js/Presenters/HttpErrorPresenter.js | 48 ++++++++++++++++++ public_html/js/Router.js | 23 ++++++--- public_html/templates/404.tpl | 5 ++ 8 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 public_html/css/http-error.css create mode 100644 public_html/img/404.png create mode 100644 public_html/js/Presenters/HttpErrorPresenter.js create mode 100644 public_html/templates/404.tpl diff --git a/TODO b/TODO index 58124ade..b60c6852 100644 --- a/TODO +++ b/TODO @@ -20,7 +20,6 @@ first major release. - misc: add README - apache2 has good README: http://svn.apache.org/repos/asf/httpd/httpd/trunk/README - misc: add spinner to forms such as registration, login, settings... -- misc: add 404 pages - misc: improve throbber appearance - misc: try not to fade in images that are already in browser cache diff --git a/public_html/.htaccess b/public_html/.htaccess index 3e0484cc..8ed23b2d 100644 --- a/public_html/.htaccess +++ b/public_html/.htaccess @@ -1,8 +1,12 @@ DirectoryIndex app.min.html DirectoryIndex index.html +ErrorDocument 404 /404.html + RewriteEngine On +RewriteRule ^/?404.html$ /#/404 [NE,R,L] + #RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^/?data/posts/([^/]+)/? /api/posts/$1/content [L] diff --git a/public_html/css/http-error.css b/public_html/css/http-error.css new file mode 100644 index 00000000..39da9d92 --- /dev/null +++ b/public_html/css/http-error.css @@ -0,0 +1,6 @@ +.http-error { + text-align: center; +} +.http-error img { + margin: 0 auto; +} diff --git a/public_html/img/404.png b/public_html/img/404.png new file mode 100644 index 0000000000000000000000000000000000000000..668956d07bddf802697c5d7320b6afb64deec5e4 GIT binary patch literal 36800 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 literal 0 HcmV?d00001 diff --git a/public_html/index.html b/public_html/index.html index e6e384d7..eba9e20f 100644 --- a/public_html/index.html +++ b/public_html/index.html @@ -46,6 +46,7 @@ + @@ -105,6 +106,7 @@ + diff --git a/public_html/js/Presenters/HttpErrorPresenter.js b/public_html/js/Presenters/HttpErrorPresenter.js new file mode 100644 index 00000000..7e1a9b38 --- /dev/null +++ b/public_html/js/Presenters/HttpErrorPresenter.js @@ -0,0 +1,48 @@ +var App = App || {}; +App.Presenters = App.Presenters || {}; + +App.Presenters.HttpErrorPresenter = function( + jQuery, + promise, + util, + topNavigationPresenter) { + + var $el = jQuery('#content'); + var templates = {}; + + function init(params, loaded) { + topNavigationPresenter.changeTitle('Error ' + params.error); + + if (params.error === 404) { + promise.wait(util.promiseTemplate('404')) + .then(function(template) { + templates.errorPage = template; + reinit(params, loaded); + }).fail(function() { + console.log(arguments); + loaded(); + }); + } else { + console.log('Not supported.'); + loaded(); + } + } + + function reinit(params, loaded) { + render(); + loaded(); + } + + function render() { + $el.html(templates.errorPage()); + } + + return { + init: init, + reinit: reinit, + render: render, + }; + +}; + +App.DI.register('httpErrorPresenter', ['jQuery', 'promise', 'util', 'topNavigationPresenter'], App.Presenters.HttpErrorPresenter); diff --git a/public_html/js/Router.js b/public_html/js/Router.js index 005a963f..bfc02b25 100644 --- a/public_html/js/Router.js +++ b/public_html/js/Router.js @@ -11,6 +11,7 @@ App.Router = function(_, jQuery, promise, util, appState, presenterManager) { function injectRoutes() { inject('', 'homePresenter'); inject('#/', 'homePresenter'); + inject('#/404', 'httpErrorPresenter', {error: 404}); inject('#/home', 'homePresenter'); inject('#/login', 'loginPresenter'); inject('#/logout', 'logoutPresenter'); @@ -28,20 +29,29 @@ App.Router = function(_, jQuery, promise, util, appState, presenterManager) { inject('#/help(/:tab)', 'helpPresenter'); } - function navigate(url) { - window.location.href = url; + function navigate(url, useBrowserDispatcher) { + if (('pushState' in history) && !useBrowserDispatcher) { + history.pushState('', '', url); + dispatch(); + } else { + window.location.href = url; + } } function navigateToMainPage() { navigate(root); } - function navigateInplace(url) { + function navigateInplace(url, useBrowserDispatcher) { if ('replaceState' in history) { history.replaceState('', '', url); - dispatch(); + if (!useBrowserDispatcher) { + dispatch(); + } else { + location.reload(); + } } else { - navigate(url); + navigate(url, useBrowserDispatcher); } } @@ -90,8 +100,7 @@ App.Router = function(_, jQuery, promise, util, appState, presenterManager) { return true; } } - //todo: 404 - console.log(new Error('Unhandled route: ' + url)); + navigateInplace('#/404', true); return false; } diff --git a/public_html/templates/404.tpl b/public_html/templates/404.tpl new file mode 100644 index 00000000..42fa41a2 --- /dev/null +++ b/public_html/templates/404.tpl @@ -0,0 +1,5 @@ +