Permalink
Browse files

Updated styling of the various views.

Bumped version to 0.3.0.
  • Loading branch information...
2 parents 6bae1a8 + 2986b8d commit 68c14e9b79771bc3fa9116a0515c0932d6239256 @fizker committed May 12, 2012
View
@@ -11,7 +11,10 @@ var storage
function storageOpened(err, st) {
- if(err) throw err;
+ if(err) {
+ console.log('%s\nCould not create a connection to the database.', err.toString());
+ return;
+ }
console.log('Storage is running..');
storage = st;
@@ -22,8 +25,8 @@ function storageOpened(err, st) {
};
function serverStarted(err, srv) {
if(err) {
+ console.log('%s\nCould not create the web-server.', err.toString());
storage.close(function() {
- throw err;
});
}
View
@@ -2,7 +2,7 @@
"author": "Benjamin Horsleben <benjamin@fizkerinc.dk>",
"name": "links",
"description": "A simple links-repository.",
- "version": "0.2.0",
+ "version": "0.3.0",
"repository": {
"type": "git",
"url": "git://github.com/fizker/links.git"
View
@@ -25,7 +25,7 @@ Only major point-releases are listed. Struck-through numbers are finished.
- <s>0.1</s>: Basic functionality in place.
- <s>0.2</s>: Permanent storage (Mongo).
-- 0.3: First shot at client-side UI.
+- <s>0.3</s>: First shot at client-side UI.
- 0.4: Bookmarklets.
- 0.5: Client-side UX (backbone, ajax, etc).
- 0.6: One-page app (html routing, fallback to current model).
View
@@ -16,13 +16,16 @@ function setupRoutes(options) {
http.post('/links', validateLink, postLink);
http.get('/links/new', newLink);
+
http.get('/links/:url', getLink);
http.put('/links/:url', validateLink, putLink);
+ http.post('/links/:url', validateLink, postUpdateLink);
http.del('/links/:url', deleteLink);
+
+ http.get('/links/:url/edit', editLink);
};
function validateLink(request, response, next) {
- var url = request.params && request.params.url
- , link = request.body
+ var link = request.body
, error
if(!link || link.url == null) {
@@ -32,18 +35,28 @@ function validateLink(request, response, next) {
return;
}
link.encodedUrl = encodeURIComponent(link.url);
- if(url !== undefined) {
- if(url !== link.url) {
- error = 'URL does not match';
- response.render('errors/400', { status: 400, error: error });
- next(new Error(error));
- return;
- }
- }
next();
};
function newLink(request, response) {
- response.render('link.edit.mustache');
+ response.render('link.edit.mustache', {});
+};
+function editLink(request, response) {
+ var url = request.params.url
+
+ db.get(url, linkLoaded)
+
+ function linkLoaded(err, link) {
+ if(err) {
+ response.render('errors/500', { status: 500, error: err });
+ return;
+ }
+ if(!link) {
+ response.render('errors/404', { status: 404 });
+ return;
+ }
+
+ response.render('link.edit.mustache', link);
+ };
};
function allLinks(request, response) {
db.get(function(err, data) {
@@ -83,6 +96,24 @@ function postLink(request, response) {
response.render('link.post.mustache', link);
});
};
+function postUpdateLink(request, response) {
+ var link = request.body
+ , url = request.params.url
+ , otherIsComplete
+
+ db.del(url, checkIsComplete);
+ db.add(link, checkIsComplete);
+
+ function checkIsComplete() {
+ if(otherIsComplete) {
+ allDone();
+ }
+ otherIsComplete = true;
+ };
+ function allDone() {
+ response.render('link.post.mustache', link);
+ };
+};
function putLink(request, response) {
var url = request.params.url
, link = request.body
@@ -8,9 +8,13 @@ var express = require('express')
, fs = require('fs')
, viewsDir = path.join(__dirname, '../../views')
- , layout = hogan
- .compile(fs
- .readFileSync(path.join(viewsDir, 'layout.mustache'), 'utf8'))
+ // We would want a dev-switch here, and use precompiled when not in dev mode.
+ , layout = { render: function(options) {
+ return hogan.compile(fs
+ .readFileSync(path.join(viewsDir, 'layout.mustache'), 'utf8'))
+ .render(options);
+ }
+ }
function config(options) {
var http = options.http
View
@@ -19,7 +19,14 @@ function start(options, callback) {
require('./../routes')(options);
- http.listen(port);
-
- callback(null, server);
+ http.listen(port, function(err) {
+ // TODO: If the port is in use, this is not actually called.
+ // We would want to look at that at some point.
+ if(err) {
+ return callback(err, {
+ port: options.port || port
+ });
+ }
+ callback(null, server);
+ });
};
@@ -30,7 +30,11 @@ function open(options, callback) {
storage.links = links(db);
db.open(function(err) {
- if(err) { return callback(err); }
+ if(err) { return callback(err, {
+ host: options.host || host,
+ port: options.port || port,
+ dbName: options.dbName || dbName
+ }); }
callback(null, storage);
});
View
@@ -0,0 +1,22 @@
+a:-webkit-any-link {
+ color: #40e;
+ text-decoration: none;
+}
+a:hover {
+ color: green;
+}
+
+body {
+ background: #999;
+ /* #036400 green */
+ /* #640303 red */
+ /* #120a64 blue */
+ background: -webkit-linear-gradient(top, #640303 0, #120a64 100%) fixed;
+
+ font-family: Cochin, helvetica, arial;
+ font-size: 14pt;
+ line-height: 13pt;
+
+ padding: 0;
+ margin: 0;
+}
View
@@ -0,0 +1,29 @@
+.lnk-menu {
+ text-align: center;
+ margin: 0 0 10px;
+ padding: 0 0 10px;
+ border-bottom: dashed 1px black;
+}
+.lnk-menu a {
+ display: inline-block;
+}
+.lnk-menu a:not(:last-child) {
+ content: '|';
+ padding: 0 6px;
+ margin: 0 6px;
+ border-right: 1px solid black;
+}
+.lnk-menu a:hover {
+}
+
+.lnk-root {
+ width: 800px;
+ margin: 5vh auto;
+ box-shadow: black 1px 2px 5px;
+ max-width: 90vw;
+ min-height: 90vh;
+ background: rgba(255,255,255,.90);
+ border-radius: 10px;
+ padding: 20px;
+ box-sizing: border-box;
+}
@@ -0,0 +1,30 @@
+.md-form {}
+
+.md-form-row {
+ display: -webkit-box;
+ max-width: 450px;
+ margin: 2px auto;
+}
+
+.md-form-lbl {
+ display: inline-block;
+ text-align: right;
+ vertical-align: top;
+}
+
+.md-form-inp-text,
+.md-form-text
+{
+ display: block;
+ -webkit-box-flex: 1;
+}
+
+.md-form-text {
+ height: 60px;
+}
+
+.md-form-btns {
+ max-width: 450px;
+ text-align: right;
+ margin: 10px auto 0;
+}
@@ -0,0 +1,8 @@
+.md-lnk-form-lbl {
+ width: 100px;
+}
+
+label[for=link-title] {
+}
+label[for=link-url] {
+}
View
@@ -0,0 +1,20 @@
+.md-lnk-int {}
+.md-lnk-ext {
+ font-size: .8em;
+}
+
+.md-lnk-lst {
+ padding: 0;
+}
+.md-lnk-lst-itm {
+ list-style: none;
+}
+
+.md-lnk-edit-btn {
+ font-size: 12pt;
+ display: sub;
+}
+
+.md-lnk-text {
+ white-space: pre;
+}
@@ -0,0 +1,7 @@
+@import url(base.css);
+@import url(layout.css);
+
+@import url(md-form.css);
+
+@import url(md-lnk.css);
+@import url(md-lnk-form.css);
View
@@ -62,6 +62,42 @@ describe('routes.links.js', function() {
storage: { links: storage }
});
});
+ describe('When getting "/links/:url/edit', function() {
+ describe('With a non-existing url', function() {
+ beforeEach(function() {
+ storage.get.yields(null, null);
+ request = {
+ params: {
+ url: 'abc'
+ }
+ };
+ caller(http.routes.get['/links/:url/edit'], request, response);
+ });
+ it('should return status 404', function() {
+ var data = response.render.lastCall.args[1];
+ expect(data.status).to.eql(404);
+ });
+ });
+ describe('With an existing url', function() {
+ beforeEach(function() {
+ storage.get.withArgs('abc').yields(null, { url: 'abc' });
+ request = {
+ params: {
+ url: 'abc'
+ }
+ };
+ caller(http.routes.get['/links/:url/edit'], request, response);
+ });
+ it('should return the link', function() {
+ var link = response.render.lastCall.args[1];
+ expect(link).to.eql({ url: 'abc' });
+ });
+ it('should present the link.edit view', function() {
+ var view = response.render.lastCall.args[0];
+ expect(view).to.match(/link\.edit/);
+ });
+ });
+ });
describe('When getting "/links/abc"', function() {
beforeEach(function() {
storage.get.withArgs('abc').yields(null, { url: 'abc' });
@@ -93,6 +129,35 @@ describe('routes.links.js', function() {
]);
});
});
+ describe('When posting to "/links/:url"', function() {
+ beforeEach(function() {
+ storage.del.withArgs('abc').yields({ url: 'abc' });
+ storage.add.yields({ url: 'abc' });
+ request = {
+ params: {
+ url: 'abc'
+ },
+ body: {
+ url: 'def'
+ }
+ };
+ caller(http.routes.post['/links/:url'], request, response);
+ });
+ it('should not fail for different urls', function() {
+ var status = response.render.lastCall.args[1].status;
+ expect(status).not.to.satisfy(function(num) {
+ return num < 200 || num > 299;
+ });
+ });
+ it('should remove the old link', function() {
+ expect(storage.del)
+ .to.have.been.calledWith('abc');
+ });
+ it('should add the new link', function() {
+ var url = storage.add.lastCall.args[0].url
+ expect(url).to.eql('def');
+ });
+ });
describe('When putting to "/links/:url"', function() {
describe('with invalid data', function() {
beforeEach(function() {
View
@@ -1,13 +1,12 @@
<!doctype html>
-<html>
- <head>
- <title>Links</title>
- </head>
- <body>
- <nav>
- <a href="/links">All links</a>
- <a href="/links/new">New link</a>
- </nav>
- {{{body}}}
- </body>
-</html>
+<title>Links</title>
+<meta name="viewport" content="initial-scale=1, maximum-scale=1">
+<link href=/css/styles.css rel=stylesheet>
+<div class="lnk-root">
+<nav class="lnk-menu">
+ <a href=/links>All links</a
+ ><a href=/links/new>New link</a
+ >
+</nav>
+{{{body}}}
+</div>
Oops, something went wrong.

0 comments on commit 68c14e9

Please sign in to comment.