Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'v0.12'

Conflicts:
	docs/guide/architecture.md
  • Loading branch information...
commit fefddb1ab7dfec163ce9bf014dae64d624c073e3 2 parents 33f9b6f + 5ff7422
@mde mde authored
View
2  docs/guide/architecture.md
@@ -33,7 +33,7 @@ Geddy is built on the same MVC principles that many popular frameworks are based
#### config
`geddy.config`
-Geddy has built in configuration management. Global config options should go in your **'config/environments.js'** file. Likewise, your production and development config options should go in their respective files
+Geddy has built in configuration management. Global config options should go in your **'config/environments.js'** file. Likewise, your production and development config options should go in their respective files.
If you want to start up your app in a specific environment, use the `-e` option:
View
12 docs/reference/sessions.md
@@ -53,3 +53,15 @@ Returns true if the current session has expired
```
this.session.isExpired
```
+
+#### .reset
+```
+reset()
+```
+
+Completely resets the user's session -- wipes all data, sets a new session ID.
+
+##### example
+```
+this.session.reset
+```
View
9 lib/cluster/master.js
@@ -145,7 +145,7 @@ Master.prototype = new (function () {
// If this worker is past its freshness date, retire it
if (now > data.retireAt) {
self.stdoutLog.info('Rotating ' +
- worker.pid + ', killing process.');
+ id + ', killing process.');
data.retired = true;
self.sendMessage(id, {
method: 'retire'
@@ -272,7 +272,7 @@ Master.prototype = new (function () {
, currentCount = this.workers.count
, needed
, rotationWindow = this.config.rotationWindow
- , staggerInterval = rotationWindow / needed
+ , staggerInterval
, retirement = (new Date()).getTime() + rotationWindow
, msg;
@@ -280,6 +280,7 @@ Master.prototype = new (function () {
currentCount = 0;
}
needed = configCount - currentCount
+ staggerInterval = rotationWindow / needed;
if (needed) {
msg = 'Creating ' + needed + ' worker process';
@@ -300,8 +301,8 @@ Master.prototype = new (function () {
// Node 0.8 vs. 0.6
, proc = w.process || w
, id = proc.pid.toString()
- , data = new WorkerData(id, w);
- this.workers.addItem(id, data, retireAt);
+ , data = new WorkerData(id, w, retireAt);
+ this.workers.addItem(id, data);
this.addWorkerListeners(w);
this.sendMessage(id, {
method: 'config'
View
5 lib/init/session.js
@@ -2,9 +2,8 @@ var sessions = require('../sessions');
module.exports = new (function () {
this.init = function (app, callback) {
- sessionsConfig = app.config.sessions;
- if (sessionsConfig) {
- sessions.createStore(sessionsConfig.store, callback);
+ if (app.config.sessions) {
+ sessions.createStore(app.config, callback);
}
else {
callback();
View
23 lib/sessions/index.js
@@ -22,11 +22,16 @@ var session = new (function () {
var KEY_LENGTH = 32;
this.store = null;
+ this.config = null;
- this.createStore = function (type, callback) {
- var key
+ this.createStore = function (config, callback) {
+ var type = config.sessions.store
+ , key
, constructor;
+ this.config = config;
+
+ // Normalize
if (type === 'mongo') {
type = 'mongodb';
}
@@ -45,14 +50,14 @@ var session = new (function () {
session.Session = function (controller, callback) {
var self = this
, cookies = controller.cookies
- , keyName = geddy.config.sessions.key
+ , keyName = session.config.sessions.key
, sid = cookies.get(keyName);
this.id = null;
this.controller = controller;
this.data = null;
this.expires = this.controller.accessTime +
- (geddy.config.sessions.expiry * 1000);
+ (session.config.sessions.expiry * 1000);
this.flash = null;
this.setId(sid);
@@ -64,9 +69,9 @@ session.Session = function (controller, callback) {
session.Session.prototype = new function () {
this.setId = function (s) {
- var sid = s || geddy.string.uuid(128)
+ var sid = s || utils.string.uuid(128)
, cookies = this.controller.cookies
- , keyName = geddy.config.sessions.key
+ , keyName = session.config.sessions.key
, opts = {
expires: (new Date(this.expires)).toGMTString()
};
@@ -78,12 +83,12 @@ session.Session.prototype = new function () {
this.init = function (appCallback) {
var self = this;
var localCallback = function (result) {
- self.data = result;
+ self.data = result; // Access time is in the data
if (self.isExpired()) {
self.reset(appCallback);
}
else {
- self.flash = new Flash(self, geddy.config.flashes);
+ self.flash = new Flash(self, session.config.flashes);
appCallback();
}
};
@@ -106,7 +111,7 @@ session.Session.prototype = new function () {
this.reset = function (callback) {
this.setId();
this.data = {};
- this.flash = null;
+ this.flash = new Flash(this, session.config.flashes);
if (typeof callback == 'function') {
callback();
}
View
10 lib/template/helpers/index.js
@@ -27,7 +27,8 @@ _getAssetPath = function (assetType, src) {
var host
, basePath
, hasProto = /^http:\/\/|^https:\/\/|^data:/
- , isAbs;
+ , isAbs
+ , assetPath;
// Does not handle exotic protocols like SPDY, or file:// URLs
isAbs = hasProto.test(src) || utils.file.isAbsolute(src);
@@ -40,7 +41,12 @@ _getAssetPath = function (assetType, src) {
// Include poss. extra leading slash in path.join to ensure
// there's at least one
- return host + path.join('/', basePath, assetType, src);
+ assetPath = host + path.join('/', basePath, assetType, src);
+
+ // If we are running server on MS Windows it generates asset paths \ instead of /
+ // some browsers (for example FF 27.0.1) is sending this symbols as %5C in GET request
+ // which results in 404 from server, but / is usable on any OS.
+ return process.platform === 'win32' ? assetPath.replace(/\\/g, '/') : assetPath;
};
View
2  package.json
@@ -8,7 +8,7 @@
"MVC",
"realtime"
],
- "version": "0.12.4",
+ "version": "0.12.8",
"author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",
"dependencies": {
"jake": "0.7.x",
View
158 site/app/controllers/main.js
@@ -19,11 +19,83 @@
var fs = require('fs')
, path = require('path')
, md = require('marked')
- , hljs = require('highlight.js');
+ , hljs = require('highlight.js')
+ , TOC = function (parent, text) {
+ this.parent = parent;
+ this.text = text;
+ this.name = null;
+ this.children = [];
+ if (parent) {
+ parent.children.push(this);
+ };
+ }
+ , _processContent = function (d) {
+ var content
+ , lines = d.split('\n')
+ , sections = []
+ , data = []
+ , currentLength = 0
+ , currentObj = new TOC()
+ , topObj = currentObj;
+
+ lines.forEach(function (line) {
+ var s
+ , t
+ , n
+ , match
+ , pat = /^#{2,4}[^#]/ // Grab h2, h3
+ , diff;
+
+ // Found a header line
+ if ((match = pat.exec(line))) {
+ // Is this a different header level?
+ diff = currentLength - match[0].length;
+ // Title, trim pounds and spaces
+ t = geddy.string.trim(line.replace(pat, ''));
+ // Name for anchor-nav, spaces will break anchor name in Firefox
+ // Snakeize method-names, strip dots
+ n = geddy.string.snakeize(t.replace(/ /g, '_').replace(/\./, ''));
+ // If more pound signs, we're descending into children
+ if (diff < 0) {
+ s = new TOC(currentObj, t);
+ }
+ // Fewer pound signs, we're going up to next sibling of parent
+ else if (diff > 0) {
+ // Go up the number of levels of difference in length
+ var diff = currentLength - match[0].length
+ , parentObj;
+ while (diff > -1) {
+ parentObj = currentObj.parent;
+ currentObj = parentObj;
+ diff--;
+ }
+ s = new TOC(parentObj, t);
+ }
+ // Same number, next sibling
+ else {
+ s = new TOC(currentObj.parent, t);
+ }
+ currentObj = s;
+ // Namespace the name of the new TOC object with parent's
+ n = s.parent && s.parent.name ? s.parent.name + '_' + n : n;
+ s.name = n;
+ // Insert a named anchor tag just before the header
+ data.push('<a name="' + n + '"></a>');
+ currentLength = match[0].length;
+ }
+ data.push(line);
+ });
+ content = md(data.join('\n'));
+ return {
+ content: content
+ , toc: topObj
+ };
+ };
+
var BRANCH = 'v0.12'
- , URL_PREFIX = 'https://raw.github.com/mde/geddy/' +
- BRANCH + '/docs/'
+ , URL_PREFIX = 'https://raw.github.com/geddy/geddy/' +
+ BRANCH + '/'
// If set to true, uses the local copy on the filesystem
// Use for development work
, USE_LOCAL = false;
@@ -45,7 +117,7 @@ var Main = function () {
var opts
, filePath;
if (USE_LOCAL) {
- filePath = path.join('../docs', p);
+ filePath = path.join('../', p);
fs.readFile(filePath, function (err, data) {
if (err) { throw err; }
cb(data.toString());
@@ -67,8 +139,7 @@ var Main = function () {
// Get the list of topics either for Ref or Guide
// Parse the JSON data and return as JS obj
, getTopicsForDocType = function (docType, callback) {
- fetch(docType + '/topics.json', function (data) {
- console.log(data);
+ fetch('docs/' + docType + '/topics.json', function (data) {
callback(JSON.parse(data));
});
}
@@ -76,7 +147,7 @@ var Main = function () {
// Get the doc content for a particular topic
// Convert MD to HTML, return with name and list of subheads
, getDocForTopic = function (docType, topic, callback) {
- fetch(docType + '/' + topic.path + '.md', function (data) {
+ fetch('docs/' + docType + '/' + topic.path + '.md', function (data) {
var content = data
, name = topic.name
, subHeads = []
@@ -86,7 +157,6 @@ var Main = function () {
subHeads.push(geddy.string.trim(lines[l].replace('#### ', '')));
}
}
- content = md(content);
callback({
name: name
, content: content
@@ -120,15 +190,19 @@ var Main = function () {
// {name: 'Foo', path: 'foo'}
getTopicsForDocType(docType, function (topics) {
var count = topics.length
- , docs = [];
+ , docs = '';
// Pull down and format the content for each topic
topics.forEach(function (t) {
getDocForTopic(docType, t, function (content) {
- docs.push(content);
+ var aggregated;
+ //docs.push(content);
+ docs += '### ' + content.name + '\n';
+ docs += content.content + '\n';
count--;
// Render when they're all assembled
if (count == 0) {
- self.respond({docs: docs}, {
+ var processed = _processContent(docs);
+ self.respond(processed, {
format: 'html'
, template: 'app/views/main/' + docType
});
@@ -142,68 +216,24 @@ var Main = function () {
this.tutorial = function (req, resp, params) {
var self = this;
-
- // respond to the request
- var respond = function (sections, content) {
- self.respond({sections: sections, content: content}, {
+ fetch('tutorial.md', function (data) {
+ var processed = _processContent(data);
+ self.respond(processed, {
format: 'html'
, template: 'app/views/main/tutorial'
});
- }
-
- // find the sections
- var gotTutorial = function (err, tutorial) {
- if (err) {
- throw err;
- }
- var content = md(tutorial);
- var lines = tutorial.split('\n');
- var sections = [];
- for (var i in lines) {
- if (lines[i].indexOf('### ') == 0) {
- sections.push(geddy.string.trim(lines[i].replace("###", '')));
- }
- }
- respond(sections, content);
- }
-
- // get the tutorial markdown file
- geddy.request({
- url: 'https://raw.github.com/mde/geddy/' + BRANCH + '/tutorial.md'
- , headers: {'User-Agent': 'GeddyJS documentation site'}
- }, gotTutorial);
+ });
};
this.changelog = function (req, resp, params) {
var self = this;
-
- // respond to the request
- var respond = function (sections, content) {
- self.respond({sections: sections, content: content}, {
+ fetch('changelog.md', function (data) {
+ var processed = _processContent(data);
+ self.respond(processed, {
format: 'html'
, template: 'app/views/main/changelog'
});
- }
-
- // find the sections
- var gotTutorial = function (err, tutorial) {
- var content = md(tutorial);
- var lines = tutorial.split('\n');
- var sections = [];
- for (var i in lines) {
- if (lines[i].indexOf('### ') == 0) {
- sections.push(geddy.string.trim(lines[i].replace("###", '')));
- }
- }
- respond(sections, content);
- }
-
- // get the tutorial markdown file
- geddy.request({
- url: 'https://raw.github.com/mde/geddy/' + BRANCH + '/changelog.md'
- , headers: {'User-Agent': 'GeddyJS documentation site'}
-
- }, gotTutorial);
+ });
};
this.community = function (req, resp, params) {
@@ -217,7 +247,7 @@ var Main = function () {
// get stargazers
var opts = {
- url: 'https://api.github.com/repos/mde/geddy/stargazers?page='+(Math.floor(Math.random()*10)+1)
+ url: 'https://api.github.com/repos/geddy/geddy/stargazers?page='+(Math.floor(Math.random()*10)+1)
, dataType: 'json'
, headers: {'User-Agent': 'GeddyJS documentation site'}
};
View
19 site/app/helpers/main.js
@@ -0,0 +1,19 @@
+
+
+var tocNav = function (item) {
+ var res = '';
+ if (item.text) {
+ res += '<li><a href="#' + item.name + '">' + item.text + '</a>\n';
+ }
+ if (item.children.length) {
+ res += '<ul>\n'
+ item.children.forEach(function (child) {
+ res += tocNav(child);
+ });
+ res += '</ul>\n';
+ }
+ res += '</li>';
+ return res;
+ };
+
+module.exports.tocNav = tocNav;
View
3  site/app/views/errors/default.html.ejs
@@ -1,4 +1,7 @@
<h2>Error: <%= statusCode %> <%= statusText %></h2>
<% if (stack) { %>
<code><%= stack %></code>
+<% } else if (typeof message != 'undefined') { %>
+<code><%= message %></code>
<% } %>
+
View
8 site/app/views/main/changelog.html.jade
@@ -4,10 +4,6 @@
h2 Changelog
.row.content
.span4.toc
- - if (sections.length > 1)
- ul
- each section in sections
- li
- a(href="#"+section)=section
- .span8
+ != tocNav(toc)
+ .span8.docs
!=content
View
16 site/app/views/main/guide.html.jade
@@ -1,19 +1,9 @@
#documentation
.row.title
.span12
- h2 Geddy Guide
+ h2 Geddy guide
.row.content
.span6.toc
- ul
- each doc in docs
- li
- a(href="#"+doc.name)=geddy.string.capitalize(doc.name)
- if doc.subs
- ul
- each sub in doc.subs
- li
- a(href="#"+ encodeURIComponent(doc.name+sub))=sub
+ != tocNav(toc)
.span6.docs
- each doc in docs
- h3(id=doc.name)=geddy.string.capitalize(doc.name)
- !=doc.content
+ !=content
View
14 site/app/views/main/reference.html.jade
@@ -4,16 +4,6 @@
h2 API reference
.row.content
.span6.toc
- ul
- each doc in docs
- li
- a(href="#"+doc.name)=geddy.string.capitalize(doc.name)
- if doc.subs
- ul
- each sub in doc.subs
- li
- a(href="#"+ encodeURIComponent(doc.name+sub))=sub
+ != tocNav(toc)
.span6.docs
- each doc in docs
- h3(id=doc.name)=geddy.string.capitalize(doc.name)
- !=doc.content
+ !=content
View
7 site/app/views/main/tutorial.html.jade
@@ -3,9 +3,6 @@
h2 Quick start tutorial
.row.content
.span4.toc
- ul
- each section in sections
- li
- a(href="#"+section)=section
- .span8
+ != tocNav(toc)
+ .span8.docs
!=content
View
12 site/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "geddy-site",
+ "description": "Documentation site for the Geddy Web framework",
+ "version": "0.0.0",
+ "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",
+ "dependencies": {
+ "highlight.js": "~8.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+}
View
20 site/public/js/site.js
@@ -11,7 +11,6 @@ app.docs = new (function() {
this.init = function() {
this.$toc = $('.toc');
this.$content = $('content .span8');
- this.giveSubIDs();
this.registerScroll();
this.registerMenu();
};
@@ -61,25 +60,6 @@ app.docs = new (function() {
});
};
- // make internal anchor links work for sub menu items
- this.giveSubIDs = function() {
- $('.content .docs').find('h3, h4').each(function (i, el) {
- var $el = $(el);
- console.log($el);
- if (el.nodeName == "H3") {
- section = $el.attr('id');
- if (!section) {
- section = $el.text()
- $el.attr('id', section);
- }
- }
- else {
- console.log($el.text());
- $el.attr('id', encodeURIComponent(section + $el.text()));
- }
- });
- };
-
})();
// wait for document to load
View
69 test/sessions/session.js
@@ -10,46 +10,55 @@ var session = require('../../lib/sessions')
, sess
, tests = {};
-tests['before'] = function (next) {
- session.createStore('memory', function () {
- var tempGeddy = geddy;
-
- geddy = {
- config: {
- sessions: {
- key: 'test_'
- }
- , flashes: {
- }
- }
- };
+tests = {
+ 'before': function (next) {
+ var config = {
+ sessions: {
+ store: 'memory'
+ , key: 'test_'
+ }
+ , flashes: {}
+ };
+ session.createStore(config, next);
+ }
+, 'beforeEach': function (next) {
sess = new session.Session(mockController, function () {
- geddy = tempGeddy;
next();
});
- });
-};
+ }
-tests['session set and get'] = function () {
- sess.set('Zooby', 2020);
- assert.equal(sess.get('Zooby'), 2020);
-};
+, 'session set and get': function () {
+ sess.set('Zooby', 2020);
+ assert.equal(sess.get('Zooby'), 2020);
+ }
-tests['session toJSON'] = function () {
- sess.set('Zooby', 2030);
- assert.deepEqual(sess.toJSON(), {Zooby: 2030});
-};
+, 'session toJSON': function () {
+ sess.set('Zooby', 2030);
+ assert.deepEqual(sess.toJSON(), {Zooby: 2030});
+ }
-tests['session toJSON returns a shallow copy'] = function () {
- var result;
+, 'session toJSON returns a shallow copy': function () {
+ var result;
+ sess.set('Zooby', 2040);
+ result = sess.toJSON();
+ result.Zooby = 2000;
+ assert.deepEqual(sess.toJSON(), {Zooby: 2040});
+ }
- sess.set('Zooby', 2040);
+, 'session reset': function () {
+ var origId = sess.id;
+ sess.set('Zooby', 1001);
+ sess.reset();
+ assert.ok(origId != sess.id);
+ assert.equal(undefined, sess.get('Zooby'));
+ }
- result = sess.toJSON();
- result.Zooby = 2000;
+, 'session close after reset': function (next) {
+ sess.reset();
+ sess.close(next);
+ }
- assert.deepEqual(sess.toJSON(), {Zooby: 2040});
};
module.exports = tests;
View
2  tutorial.md
@@ -3,7 +3,7 @@
In this tutorial we'll learn how to use Geddy by creating a simple To-Do
Manager applciation.
-#### In this tutorial we'll cover:
+In this tutorial we'll cover:
- Creating a Geddy application
- Learning how to use the Geddy executable
Please sign in to comment.
Something went wrong with that request. Please try again.