├── language ├── _id ├── .gitignore ├── vendor └── couchapp │ ├── evently │ ├── docs │ │ ├── index │ │ │ ├── path.txt │ │ │ ├── mustache.html │ │ │ └── data.js │ │ └── topic │ │ │ ├── path.txt │ │ │ ├── mustache.html │ │ │ ├── data.js │ │ │ ├── edit │ │ │ └── _init │ │ │ │ ├── selectors │ │ │ │ ├── a.edit │ │ │ │ │ └── click.js │ │ │ │ └── a.run │ │ │ │ │ └── click.js │ │ │ │ └── fun.js │ │ │ └── after.js │ ├── account │ │ ├── loginForm │ │ │ ├── selectors │ │ │ │ ├── a[href=#signup].json │ │ │ │ └── form │ │ │ │ │ └── submit.js │ │ │ ├── after.js │ │ │ └── mustache.html │ │ ├── signupForm │ │ │ ├── selectors │ │ │ │ ├── a[href=#login].json │ │ │ │ └── form │ │ │ │ │ └── submit.js │ │ │ ├── after.js │ │ │ └── mustache.html │ │ ├── loggedIn │ │ │ ├── selectors.json │ │ │ ├── after.js │ │ │ ├── mustache.html │ │ │ └── data.js │ │ ├── loggedOut │ │ │ ├── mustache.html │ │ │ └── selectors.json │ │ ├── adminParty │ │ │ └── mustache.html │ │ ├── doLogout.js │ │ ├── doLogin.js │ │ ├── doSignup.js │ │ └── _init.js │ ├── profile │ │ ├── loggedOut │ │ │ ├── mustache.html │ │ │ └── after.js │ │ ├── profileReady │ │ │ ├── data.js │ │ │ ├── after.js │ │ │ └── mustache.html │ │ ├── noProfile │ │ │ ├── data.js │ │ │ ├── mustache.html │ │ │ └── selectors │ │ │ │ └── form │ │ │ │ └── submit.js │ │ └── loggedIn.js │ └── README.md │ ├── metadata.json │ ├── docs │ ├── profile.md │ ├── docs.md │ ├── couchapp.md │ ├── pathbinder.md │ ├── evently.md │ └── account.md │ ├── README.md │ ├── lib │ ├── redirect.js │ ├── list.js │ ├── cache.js │ ├── atom.js │ ├── path.js │ ├── docform.js │ ├── md5.js │ └── markdown.js │ └── _attachments │ ├── docs.js │ ├── loader.js │ ├── docs.css │ ├── docs.html │ ├── jquery.couch.app.util.js │ ├── jquery.pathbinder.js │ ├── jquery.mustache.js │ ├── jquery.couch.app.js │ └── jquery.evently.js ├── couchapp.json ├── views └── recent-items │ └── map.js ├── evently ├── items │ └── _changes │ │ ├── query.json │ │ ├── data.js │ │ └── mustache.html └── profile │ └── profileReady │ ├── selectors │ └── form │ │ └── submit.js │ └── mustache.html ├── _attachments ├── style │ ├── brandongrotesque_light │ │ ├── Brandon_light-webfont.eot │ │ ├── Brandon_light-webfont.ttf │ │ ├── Brandon_light-webfont.woff │ │ ├── Extras │ │ │ └── Brandon_light-webfont.svgz │ │ ├── stylesheet.css │ │ └── demo.html │ ├── main.css │ ├── ui.css │ ├── blueprint-screen.css │ └── application.css ├── index.html └── couchappspora.js └── README.textile /language: -------------------------------------------------------------------------------- 1 | javascript -------------------------------------------------------------------------------- /_id: -------------------------------------------------------------------------------- 1 | _design/couchappspora -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .couchapprc -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/index/path.txt: -------------------------------------------------------------------------------- 1 | / -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/path.txt: -------------------------------------------------------------------------------- 1 | /topic/:id -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/mustache.html: -------------------------------------------------------------------------------- 1 |
{{{html}}}
-------------------------------------------------------------------------------- /couchapp.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Name of your CouchApp", 3 | "description": "CouchApp" 4 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loginForm/selectors/a[href=#signup].json: -------------------------------------------------------------------------------- 1 | {"click" : ["signupForm"]} -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/signupForm/selectors/a[href=#login].json: -------------------------------------------------------------------------------- 1 | {"click" : ["loginForm"]} -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/loggedOut/mustache.html: -------------------------------------------------------------------------------- 1 |

Please log in to see your profile.

-------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/profileReady/data.js: -------------------------------------------------------------------------------- 1 | function(e, p) { 2 | return p 3 | } 4 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/loggedOut/after.js: -------------------------------------------------------------------------------- 1 | function() { 2 | $$(this).profile = null; 3 | }; -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/noProfile/data.js: -------------------------------------------------------------------------------- 1 | function(e, userCtx) { 2 | return userCtx; 3 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/profileReady/after.js: -------------------------------------------------------------------------------- 1 | function(e, p) { 2 | $$(this).profile = p; 3 | }; -------------------------------------------------------------------------------- /vendor/couchapp/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "couchapp", 3 | "description": "official couchapp vendor" 4 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loggedIn/selectors.json: -------------------------------------------------------------------------------- 1 | { 2 | "a[href=#logout]" : {"click" : ["doLogout"]} 3 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loggedOut/mustache.html: -------------------------------------------------------------------------------- 1 | Signup or Login -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loginForm/after.js: -------------------------------------------------------------------------------- 1 | function() { 2 | $("input[name=name]", this).focus(); 3 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/signupForm/after.js: -------------------------------------------------------------------------------- 1 | function() { 2 | $("input[name=name]", this).focus(); 3 | } -------------------------------------------------------------------------------- /views/recent-items/map.js: -------------------------------------------------------------------------------- 1 | function(doc) { 2 | if (doc.created_at) { 3 | emit(doc.created_at, doc); 4 | } 5 | }; -------------------------------------------------------------------------------- /evently/items/_changes/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "view" : "recent-items", 3 | "descending" : "true", 4 | "limit" : 50 5 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/index/mustache.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/couchapp/docs/profile.md: -------------------------------------------------------------------------------- 1 | # docs for the profile evently widget 2 | 3 | This widget makes it easy to give users a profile for your application. -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loggedOut/selectors.json: -------------------------------------------------------------------------------- 1 | { 2 | "a[href=#signup]" : {"click" : ["signupForm"]}, 3 | "a[href=#login]" : {"click" : ["loginForm"]} 4 | } -------------------------------------------------------------------------------- /vendor/couchapp/README.md: -------------------------------------------------------------------------------- 1 | ## CouchApp - more than just a filesystem mapper 2 | 3 | This is where documentation will go for the client and server JavaScript parts of CouchApp. -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/adminParty/mustache.html: -------------------------------------------------------------------------------- 1 |

Admin party, everyone is admin! Fix this in Futon before proceeding.

-------------------------------------------------------------------------------- /vendor/couchapp/lib/redirect.js: -------------------------------------------------------------------------------- 1 | exports.permanent = function(redirect) { 2 | return { 3 | code : 301, 4 | headers : { 5 | "Location" : redirect 6 | } 7 | }; 8 | }; -------------------------------------------------------------------------------- /_attachments/style/brandongrotesque_light/Brandon_light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchris/couchappspora/master/_attachments/style/brandongrotesque_light/Brandon_light-webfont.eot -------------------------------------------------------------------------------- /_attachments/style/brandongrotesque_light/Brandon_light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchris/couchappspora/master/_attachments/style/brandongrotesque_light/Brandon_light-webfont.ttf -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loggedIn/after.js: -------------------------------------------------------------------------------- 1 | // todo move to template 2 | function(e, r) { 3 | $(this).attr("data-name", r.userCtx.name); 4 | $$(this).userCtx = r.userCtx; 5 | } 6 | -------------------------------------------------------------------------------- /_attachments/style/brandongrotesque_light/Brandon_light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchris/couchappspora/master/_attachments/style/brandongrotesque_light/Brandon_light-webfont.woff -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/doLogout.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var elem = $(this); 3 | $.couch.logout({ 4 | success : function() { 5 | elem.trigger("_init"); 6 | } 7 | }); 8 | } -------------------------------------------------------------------------------- /_attachments/style/brandongrotesque_light/Extras/Brandon_light-webfont.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jchris/couchappspora/master/_attachments/style/brandongrotesque_light/Extras/Brandon_light-webfont.svgz -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loggedIn/mustache.html: -------------------------------------------------------------------------------- 1 | Welcome 2 | {{name}}! 3 | Logout? 4 | -------------------------------------------------------------------------------- /vendor/couchapp/_attachments/docs.js: -------------------------------------------------------------------------------- 1 | $.log = function() { 2 | // console.log(arguments) 3 | }; 4 | 5 | $.couch.app(function(app) { 6 | $("#docs").evently(app.ddoc.vendor.couchapp.evently.docs, app); 7 | $.pathbinder.begin("/"); 8 | }); -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loggedIn/data.js: -------------------------------------------------------------------------------- 1 | function(e, r) { 2 | return { 3 | name : r.userCtx.name, 4 | uri_name : encodeURIComponent(r.userCtx.name), 5 | auth_db : encodeURIComponent(r.info.authentication_db) 6 | }; 7 | } -------------------------------------------------------------------------------- /evently/items/_changes/data.js: -------------------------------------------------------------------------------- 1 | function(data) { 2 | $.log(data) 3 | var p; 4 | return { 5 | items : data.rows.map(function(r) { 6 | p = r.value.profile; 7 | p.message = r.value.message; 8 | return p; 9 | }) 10 | } 11 | }; -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/data.js: -------------------------------------------------------------------------------- 1 | function(e, p) { 2 | var doc = $$(this).app.ddoc.vendor.couchapp.docs[p.id]; 3 | var converter = new Showdown.converter(); 4 | var html = converter.makeHtml(doc); 5 | return { 6 | html : html 7 | }; 8 | }; -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/doLogin.js: -------------------------------------------------------------------------------- 1 | function(e, name, pass) { 2 | var elem = $(this); 3 | $.couch.login({ 4 | name : name, 5 | password : pass, 6 | success : function(r) { 7 | elem.trigger("_init") 8 | } 9 | }); 10 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/doSignup.js: -------------------------------------------------------------------------------- 1 | function(e, name, pass) { 2 | var elem = $(this); 3 | $.couch.signup({ 4 | name : name 5 | }, pass, { 6 | success : function() { 7 | elem.trigger("doLogin", [name, pass]); 8 | } 9 | }); 10 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loginForm/selectors/form/submit.js: -------------------------------------------------------------------------------- 1 | function(e) { 2 | var name = $('input[name=name]', this).val(), 3 | pass = $('input[name=password]', this).val(); 4 | $(this).trigger('doLogin', [name, pass]); 5 | return false; 6 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/signupForm/selectors/form/submit.js: -------------------------------------------------------------------------------- 1 | function(e) { 2 | var name = $('input[name=name]', this).val(), 3 | pass = $('input[name=password]', this).val(); 4 | $(this).trigger('doSignup', [name, pass]); 5 | return false; 6 | } -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/profileReady/mustache.html: -------------------------------------------------------------------------------- 1 |
2 | {{#gravatar_url}}{{/gravatar_url}} 3 |
4 | {{nickname}} 5 |
6 |
7 |

Hello {{nickname}}!

8 |
-------------------------------------------------------------------------------- /vendor/couchapp/evently/account/loginForm/mustache.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | or Signup 6 |
7 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/signupForm/mustache.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | or Login 6 |
7 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/index/data.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var docs = $$(this).app.ddoc.vendor.couchapp.docs; 3 | var dnames = []; 4 | $.forIn(docs, function(d) { 5 | dnames.push({ 6 | title: d, 7 | href : "#/topic/"+encodeURIComponent(d) 8 | }); 9 | }); 10 | return {docs:dnames}; 11 | }; -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/edit/_init/selectors/a.edit/click.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var pre = $(this).prev('pre'); 3 | var js = pre.text(); 4 | var lines = js.split('\n').length; 5 | var ta = $(''); 6 | ta.text(js); 7 | pre.replace(ta); 8 | return false; 9 | }; 10 | -------------------------------------------------------------------------------- /vendor/couchapp/lib/list.js: -------------------------------------------------------------------------------- 1 | // Helpers for writing server-side _list functions in CouchDB 2 | exports.withRows = function(fun) { 3 | var f = function() { 4 | var row = getRow(); 5 | return row && fun(row); 6 | }; 7 | f.iterator = true; 8 | return f; 9 | } 10 | 11 | exports.send = function(chunk) { 12 | send(chunk + "\n") 13 | } -------------------------------------------------------------------------------- /evently/profile/profileReady/selectors/form/submit.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var form = this; 3 | var doc = { 4 | created_at : new Date(), 5 | profile : $$("#profile").profile, 6 | message : $("[name=message]", form).val() 7 | }; 8 | $$(this).app.db.saveDoc(doc, { 9 | success : function() { 10 | $("[name=message]", form).val(""); 11 | } 12 | }); 13 | return false; 14 | }; 15 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/account/_init.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var elem = $(this); 3 | $.couch.session({ 4 | success : function(r) { 5 | var userCtx = r.userCtx; 6 | if (userCtx.name) { 7 | elem.trigger("loggedIn", [r]); 8 | } else if (userCtx.roles.indexOf("_admin") != -1) { 9 | elem.trigger("adminParty"); 10 | } else { 11 | elem.trigger("loggedOut"); 12 | }; 13 | } 14 | }); 15 | } -------------------------------------------------------------------------------- /evently/profile/profileReady/mustache.html: -------------------------------------------------------------------------------- 1 |

Most applications will customize this template (ddoc.evently.profile.profileReady.mustache) for user input.

2 | 3 |
4 | {{#gravatar_url}}{{/gravatar_url}} 5 |
6 | {{name}} 7 |
8 |
9 | 10 |
11 | 12 |
13 | 14 |
-------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/after.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var app = $$(this).app; 3 | var self = $(this); 4 | $("pre", self).each(function() { 5 | var pre = $(this); 6 | var js = pre.text(); 7 | var r = js.match(/\$\(\"\#([^\"]*)\"\)/); 8 | if (r) { 9 | var id = r[1]; 10 | var code_id = 'code-'+id; 11 | pre.wrap('
'); 12 | $('#'+code_id).evently(app.ddoc.vendor.couchapp.evently.docs.topic.edit, app, [id]); 13 | } 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /vendor/couchapp/_attachments/loader.js: -------------------------------------------------------------------------------- 1 | 2 | function couchapp_load(scripts) { 3 | document.write(scripts.map(function(s) { 4 | return ''; 5 | }).join('')); 6 | }; 7 | 8 | couchapp_load([ 9 | "/_utils/script/sha1.js", 10 | "/_utils/script/json2.js", 11 | "/_utils/script/jquery.js", 12 | "/_utils/script/jquery.couch.js", 13 | "vendor/couchapp/jquery.couch.app.js", 14 | "vendor/couchapp/jquery.couch.app.util.js", 15 | "vendor/couchapp/jquery.mustache.js", 16 | "vendor/couchapp/jquery.evently.js" 17 | ]); 18 | -------------------------------------------------------------------------------- /vendor/couchapp/docs/docs.md: -------------------------------------------------------------------------------- 1 | # Docs for the docs system. 2 | 3 | You are encouraged to use the couchapp docs system to write documentation for your plugins and applications. Extra bonus points because it's fun. 4 | 5 | Docs automatically make divs based on `$("#foo")` pattern matching. That is, we regex the code looking for the first id we see referenced. Remember ids need to be unique on a page. For doc examples you only get one id. 6 | 7 | Example Code: 8 | 9 | $("#hide_foo").hide("slow"); 10 | 11 | That's all it takes. You only get one div in each example for now. Have fun! -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/noProfile/mustache.html: -------------------------------------------------------------------------------- 1 |
2 |

Hello {{name}}, Please setup your user profile.

3 | 5 | 7 | 9 | 10 | 11 |
-------------------------------------------------------------------------------- /vendor/couchapp/lib/cache.js: -------------------------------------------------------------------------------- 1 | exports.get = function(db, docid, setFun, getFun) { 2 | db.openDoc(docid, { 3 | success : function(doc) { 4 | getFun(doc.cache); 5 | }, 6 | error : function() { 7 | setFun(function(cache) { 8 | db.saveDoc({ 9 | _id : docid, 10 | cache : cache 11 | }); 12 | getFun(cache); 13 | }); 14 | } 15 | }); 16 | }; 17 | 18 | exports.clear = function(db, docid) { 19 | db.openDoc(docid, { 20 | success : function(doc) { 21 | db.removeDoc(doc); 22 | }, 23 | error : function() {} 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/edit/_init/selectors/a.run/click.js: -------------------------------------------------------------------------------- 1 | function(e) { 2 | try { 3 | function err(y, id) { 4 | $('#'+id).html(['

Error running #', id, 5 | ' code block:

',
 6 |       (y.toSource ? y.toSource() : JSON.stringify(y)),
 7 |       '

'].join('')); 8 | } 9 | var id = e.data.args[1]; 10 | var example = $("#code-"+id); 11 | var js = $('textarea',example).val() || $('pre',example).text(); 12 | $('#'+id).unbind(); 13 | try { 14 | eval(js); 15 | } catch (y) { 16 | err(y, id); 17 | } 18 | } catch(x) { 19 | err(x, id); 20 | } 21 | return false; 22 | } -------------------------------------------------------------------------------- /evently/items/_changes/mustache.html: -------------------------------------------------------------------------------- 1 |

Customize this format here: ddoc.evently.items._changes.mustache

2 |

Recent Messages

3 | 17 |

Protip: If you setup continuous replication between this database and a remote one, this list will reflect remote changes in near real-time.

18 |

This would be a good place to add pagination.

19 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/docs/topic/edit/_init/fun.js: -------------------------------------------------------------------------------- 1 | function(e, id) { 2 | var editable = $(this); 3 | if ($$(editable)._init_ran) {return false;} 4 | // add edit link 5 | var edit = $('edit code'); 6 | editable.append(edit); 7 | 8 | // add run box 9 | var example = $('
run #'+id+'
#'+id+' output will be here
'); 10 | var s = $("#sidebar"); 11 | var o = s.offset(); 12 | example.offset({ 13 | left: o.left 14 | }); 15 | example.width(s.width()*0.75); 16 | editable.prepend(example); 17 | $$(editable)._init_ran = true; 18 | return false; 19 | } -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. CouchAppspora 2 | 3 | h3. ..is Diaspora implemented on CouchDB 4 | 5 | p. The Diaspora source code was initially "released":http://www.joindiaspora.com/2010/09/15/developer-release.html on September 15th, 2010. This project is an implementation of the Diaspora protocol as a CouchApp built entirely on CouchDB. 6 | 7 | h3. Why? 8 | 9 | p. CouchDB is a good fit for a federated social web node due to it's robust replication and MVCC implementations. Diaspora is an attractive implementation of a federated social web application. I want to marry the front end and features of Diaspora, but build them on the flexible replication of CouchDB. 10 | 11 | h3. License 12 | 13 | TODO: I think I have to comply with Diaspora's AGPLV3 License... -------------------------------------------------------------------------------- /vendor/couchapp/_attachments/docs.css: -------------------------------------------------------------------------------- 1 | body { 2 | font:1em Helvetica, sans-serif; 3 | margin:0; 4 | padding:4px; 5 | } 6 | 7 | h1 { 8 | margin:0.5em; 9 | } 10 | 11 | h2 { 12 | color:#222; 13 | } 14 | 15 | pre { 16 | padding:4px; 17 | margin:4px; 18 | background:#bbb; 19 | } 20 | 21 | #content { 22 | padding:4px; 23 | margin:2px; 24 | } 25 | 26 | #sidebar { 27 | float:right; 28 | width:34%; 29 | } 30 | 31 | #docs { 32 | -moz-box-shadow:0 0 2em #000; 33 | -webkit-box-shadow:0 0 2em #000; 34 | width:58%; 35 | padding:8px; 36 | margin:4px; 37 | } 38 | 39 | .example { 40 | background:#ffd; 41 | padding:4px; 42 | margin:4px; 43 | position:absolute; 44 | } 45 | 46 | textarea.code { 47 | width:100%; 48 | } 49 | 50 | .edit { 51 | float:right; 52 | font-size:0.8em; 53 | } 54 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/loggedIn.js: -------------------------------------------------------------------------------- 1 | function(e, r) { 2 | var userCtx = r.userCtx; 3 | var widget = $(this); 4 | // load the profile from the user doc 5 | $.couch.userDb(function(db) { 6 | var userDocId = "org.couchdb.user:"+userCtx.name; 7 | db.openDoc(userDocId, { 8 | success : function(userDoc) { 9 | var profile = userDoc["couch.app.profile"]; 10 | if (profile) { 11 | // we copy the name to the profile so it can be used later 12 | // without publishing the entire userdoc (roles, pass, etc) 13 | profile.name = userDoc.name; 14 | $$(widget).profile = profile; 15 | widget.trigger("profileReady", [profile]); 16 | } else { 17 | widget.trigger("noProfile", [userCtx]); 18 | } 19 | } 20 | }); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /_attachments/style/brandongrotesque_light/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Web Fonts from fontspring.com 3 | * 4 | * All OpenType features and all extended glyphs have been removed. 5 | * Fully installable fonts can be purchased at http://www.fontspring.com 6 | * 7 | * The fonts included in this stylesheet are subject to the End User License you purchased 8 | * from Fontspring. The fonts are protected under domestic and international trademark and 9 | * copyright law. You are prohibited from modifying, reverse engineering, duplicating, or 10 | * distributing this font software. 11 | * 12 | * (c) 2010 Fontspring 13 | * 14 | * 15 | * 16 | * 17 | * The fonts included are copyrighted by the vendor listed below. 18 | * 19 | * Vendor: HVD Fonts 20 | * License URL: http://www.fontspring.com/fflicense/hvd-fonts 21 | * 22 | * 23 | */ 24 | 25 | @font-face { 26 | font-family: 'BrandonGrotesqueLightRegular'; 27 | src: url('Brandon_light-webfont.eot'); 28 | src: local('☺'), url('Brandon_light-webfont.woff') format('woff'), url('Brandon_light-webfont.ttf') format('truetype'), url('Brandon_light-webfont.svg#webfont') format('svg'); 29 | font-weight: normal; 30 | font-style: normal; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/README.md: -------------------------------------------------------------------------------- 1 | ## Starting the Document this code challenge 2 | 3 | I need help on this code. I only have so many hours in the day. Please be liberal about patching and hacking (and sharing code!) so we can all benefit. 4 | 5 | Docs patches are deeply appreciated. For now you can just stick Markdown files in the Docs directory. 6 | 7 | # Evently 8 | 9 | These are some vendor Evently widgets that are running on the CouchApp system. 10 | 11 | ## Account 12 | This is how you signup, login and logout without worry about the code. 13 | Todo, we could have this work against remote APIs like that Facebook stuff or whatever. 14 | 15 | 16 | ## Profile 17 | Use this to load the local users profile for the logged in user. Useful if you're going to be posting new messages. Most applications end up customizing `profile.profileReady` to render the primary data-entry form. This gets you benefits like refreshing on login / logout, etc, automatically. 18 | 19 | 20 | ## Docs 21 | This needs to be moved to it's own app. 22 | I have this vision of a docs app designed for offline editing, that involves each Markdown paragraph being it's own document, with automatic use of Bespin for code samples. Any help on this would be thanked much. 23 | -------------------------------------------------------------------------------- /_attachments/style/main.css: -------------------------------------------------------------------------------- 1 | /* add styles here */ 2 | 3 | body { 4 | font:1em Helvetica, sans-serif; 5 | padding:4px; 6 | } 7 | 8 | h1 { 9 | margin-top:0; 10 | } 11 | 12 | #account { 13 | float:right; 14 | } 15 | 16 | #profile { 17 | border:4px solid #edd; 18 | background:#fee; 19 | padding:8px; 20 | margin-bottom:8px; 21 | } 22 | 23 | #items { 24 | border:4px solid #dde; 25 | background:#eef; 26 | padding:8px; 27 | width:60%; 28 | float:left; 29 | } 30 | 31 | #sidebar { 32 | border:4px solid #dfd; 33 | padding:8px; 34 | float:right; 35 | width:30%; 36 | } 37 | 38 | #items li { 39 | border:4px solid #f5f5ff; 40 | background:#fff; 41 | padding:8px; 42 | margin:4px 0; 43 | } 44 | 45 | form { 46 | padding:4px; 47 | margin:6px; 48 | background-color:#ddd; 49 | } 50 | 51 | div.avatar { 52 | padding:2px; 53 | padding-bottom:0; 54 | margin-right:4px; 55 | float:left; 56 | font-size:0.78em; 57 | width : 60px; 58 | height : 60px; 59 | text-align: center; 60 | } 61 | 62 | div.avatar .name { 63 | padding-top:2px; 64 | } 65 | 66 | div.avatar img { 67 | margin:0 auto; 68 | padding:0; 69 | width : 40px; 70 | height : 40px; 71 | } 72 | 73 | #items ul { 74 | list-style: none; 75 | } 76 | -------------------------------------------------------------------------------- /vendor/couchapp/docs/couchapp.md: -------------------------------------------------------------------------------- 1 | # Docs for $.couch.app 2 | 3 | The simplest use of CouchApp in the browser is to get access to information about the database you are running in. 4 | 5 | $.couch.app(function(app) { 6 | $("#dbinfo").evently({ 7 | _init : { 8 | mustache : '

The db name is {{name}}

', 9 | data : app.db 10 | } 11 | }); 12 | }); 13 | 14 | Yay couchapp. 15 | 16 | The `$.couch.app()` function also loads the current design document so that it is available for templates etc. That is how the words you are reading were loaded. This file is included in the CouchApp application library. Let's look at the design doc: 17 | 18 | $.couch.app(function(app) { 19 | $("#ddoc").evently({ 20 | _init : { 21 | mustache : '

Click to show the full doc source:

{{ddoc}}
', 22 | data : { 23 | ddoc : JSON.stringify(app.ddoc, null, 2).slice(0,100) + '...' 24 | } 25 | }, 26 | click : { 27 | mustache : '

The full doc source (rerun to hide):

{{ddoc}}
', 28 | data : { 29 | ddoc : JSON.stringify(app.ddoc, null, 2) 30 | } 31 | } 32 | }); 33 | }); 34 | 35 | -------------------------------------------------------------------------------- /vendor/couchapp/_attachments/docs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Evently and CouchApp Docs 5 | 6 | 7 | 8 | 12 |
13 | 16 |
17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /_attachments/style/brandongrotesque_light/demo.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | Font Face Demo 9 | 10 | 29 | 30 | 31 | 32 |
33 |

Webfont Demo

34 | 35 |

To use the kit, include the stylesheet.css file in your HTML and wherever you want to use the font insert:

36 | 37 | font-family: 'BrandonGrotesqueLightRegular',Arial,sans-serif; 38 | 39 |

40 | The quick brown fox jumps over the lazy dog. 41 |

42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /vendor/couchapp/lib/atom.js: -------------------------------------------------------------------------------- 1 | // atom feed generator 2 | // requries E4X support. 3 | 4 | function f(n) { // Format integers to have at least two digits. 5 | return n < 10 ? '0' + n : n; 6 | } 7 | 8 | function rfc3339(date) { 9 | return date.getUTCFullYear() + '-' + 10 | f(date.getUTCMonth() + 1) + '-' + 11 | f(date.getUTCDate()) + 'T' + 12 | f(date.getUTCHours()) + ':' + 13 | f(date.getUTCMinutes()) + ':' + 14 | f(date.getUTCSeconds()) + 'Z'; 15 | }; 16 | 17 | exports.header = function(data) { 18 | var f = ; 19 | f.title = data.title; 20 | f.id = data.feed_id; 21 | f.link.@href = data.feed_link; 22 | f.link.@rel = "self"; 23 | f.generator = "CouchApp on CouchDB"; 24 | f.updated = rfc3339(data.updated); 25 | return f.toXMLString().replace(/\<\/feed\>/,''); 26 | }; 27 | 28 | exports.entry = function(data) { 29 | var entry = ; 30 | entry.id = data.entry_id; 31 | entry.title = data.title; 32 | entry.content = data.content; 33 | entry.content.@type = (data.content_type || 'html'); 34 | entry.updated = rfc3339(data.updated); 35 | entry.author = {data.author}; 36 | entry.link.@href = data.alternate; 37 | entry.link.@rel = "alternate"; 38 | return entry; 39 | } 40 | -------------------------------------------------------------------------------- /vendor/couchapp/evently/profile/noProfile/selectors/form/submit.js: -------------------------------------------------------------------------------- 1 | function() { 2 | var md5 = $$(this).app.require("vendor/couchapp/lib/md5"); 3 | 4 | // TODO this can be cleaned up with docForm? 5 | // it still needs the workflow to edit an existing profile 6 | var name = $("input[name=userCtxName]",this).val(); 7 | var newProfile = { 8 | rand : Math.random().toString(), 9 | nickname : $("input[name=nickname]",this).val(), 10 | email : $("input[name=email]",this).val(), 11 | url : $("input[name=url]",this).val() 12 | }, widget = $(this); 13 | 14 | // setup gravatar_url 15 | if (md5) { 16 | newProfile.gravatar_url = 'http://www.gravatar.com/avatar/'+md5.hex(newProfile.email || newProfile.rand)+'.jpg?s=40&d=identicon'; 17 | } 18 | 19 | // store the user profile on the user account document 20 | $.couch.userDb(function(db) { 21 | var userDocId = "org.couchdb.user:"+name; 22 | db.openDoc(userDocId, { 23 | success : function(userDoc) { 24 | userDoc["couch.app.profile"] = newProfile; 25 | db.saveDoc(userDoc, { 26 | success : function() { 27 | newProfile.name = userDoc.name; 28 | $$(widget).profile = newProfile; 29 | widget.trigger("profileReady", [newProfile]); 30 | } 31 | }); 32 | } 33 | }); 34 | }); 35 | return false; 36 | } -------------------------------------------------------------------------------- /_attachments/style/ui.css: -------------------------------------------------------------------------------- 1 | .button, .button_set { 2 | font-family: "Lucida Grande", sans-serif; 3 | font-style: normal; 4 | display: inline; 5 | padding: 4px; 6 | font-size: 12px; 7 | line-height: 100%; 8 | text-shadow: 0 1px 0 white; 9 | min-height: 10px; 10 | background: -webkit-gradient(linear, 0% 29%, 0% 85%, from(#fcfcfc), to(#f6f6f6)); 11 | background: -moz-linear-gradient(top, #fcfcfc, #f6f6f6); 12 | border: 1px solid #eeeeee; 13 | border-bottom: 1px solid #999999; 14 | border-left: 1px solid #cccccc; 15 | border-right: 1px solid #cccccc; 16 | border-radius: 3px; 17 | -moz-border-radius: 3px; 18 | -webkit-border-radius: 3px; 19 | cursor: pointer; 20 | box-shadow: 0 1px 1px #eeeeee; 21 | -webkit-box-shadow: 0 1px 1px #eeeeee; 22 | -moz-box-shadow: 0 1px 1px #eeeeee; 23 | font-weight: normal; 24 | color: #666666; } 25 | .button:hover, .button_set:hover { 26 | color: #666666; 27 | background: -webkit-gradient(linear, 0% 29%, 0% 85%, from(#fafafa), to(#f0f0f0)); 28 | background: -moz-linear-gradient(top, #fafafa, #f0f0f0); } 29 | .button:active, .button_set:active { 30 | color: #666666; 31 | background: -webkit-gradient(linear, 0% 29%, 0% 85%, from(#f0f0f0), to(#fafafa)); 32 | background: -moz-linear-gradient(top, #f0f0f0, #fafafa); 33 | border-top: 1px solid #cccccc; } 34 | 35 | ul.button_set { 36 | padding-left: 0; 37 | padding-right: 0; } 38 | ul.button_set > li { 39 | padding: 5px; 40 | display: inline; 41 | height: 100%; 42 | border-left: 1px solid #cccccc; 43 | border-right: 1px solid white; 44 | margin-left: -3px; 45 | margin-right: -3px; } 46 | ul.button_set > li:first-child { 47 | margin-left: 0; 48 | border-left: none; } 49 | ul.button_set > li:last-child { 50 | margin-right: 0; 51 | border-right: none; } 52 | 53 | .button .selected, .button_set .selected { 54 | background: -webkit-gradient(linear, 0% 29%, 0% 85%, from(#f0f0f0), to(#fafafa)); 55 | background: -moz-linear-gradient(top, #f0f0f0, #fafafa); 56 | border-top: 1px solid #aaaaaa; } 57 | 58 | .right { 59 | position: absolute; 60 | right: 0; } 61 | 62 | .contextual_pane { 63 | z-index: 20; 64 | position: absolute; 65 | display: none; 66 | background-color: white; 67 | border: 4px solid black; 68 | border-radius: 3px; 69 | -moz-border-radius: 3px; 70 | -webkit-border-radius: 3px; 71 | box-shadow: 0 0 5px black; 72 | -webkit-box-shadow: 0 0 10px black; 73 | padding: 2em; } 74 | -------------------------------------------------------------------------------- /vendor/couchapp/_attachments/jquery.couch.app.util.js: -------------------------------------------------------------------------------- 1 | $.log = function(m) { 2 | if (window && window.console && window.console.log) { 3 | window.console.log(arguments.length == 1 ? m : arguments); 4 | } 5 | }; 6 | 7 | // todo remove this crap 8 | function escapeHTML(st) { 9 | return( 10 | st && st.replace(/&/g,'&'). 11 | replace(/>/g,'>'). 12 | replace(/'+a+''; 25 | }).replace(/\@([\w\-]+)/g,function(user,name) { 26 | return ''+user+''; 27 | }).replace(/\#([\w\-\.]+)/g,function(word,tag) { 28 | return ''+word+''; 29 | }); 30 | }; 31 | 32 | $.fn.prettyDate = function() { 33 | $(this).each(function() { 34 | $(this).text($.prettyDate($(this).text())); 35 | }); 36 | }; 37 | 38 | $.prettyDate = function(time){ 39 | 40 | var date = new Date(time.replace(/-/g,"/").replace("T", " ").replace("Z", " +0000").replace(/(\d*\:\d*:\d*)\.\d*/g,"$1")), 41 | diff = (((new Date()).getTime() - date.getTime()) / 1000), 42 | day_diff = Math.floor(diff / 86400); 43 | 44 | if (isNaN(day_diff)) return time; 45 | 46 | return day_diff < 1 && ( 47 | diff < 60 && "just now" || 48 | diff < 120 && "1 minute ago" || 49 | diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" || 50 | diff < 7200 && "1 hour ago" || 51 | diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") || 52 | day_diff == 1 && "yesterday" || 53 | day_diff < 21 && day_diff + " days ago" || 54 | day_diff < 45 && Math.ceil( day_diff / 7 ) + " weeks ago" || 55 | day_diff < 730 && Math.ceil( day_diff / 31 ) + " months ago" || 56 | Math.ceil( day_diff / 365 ) + " years ago"; 57 | }; 58 | 59 | $.argsToArray = function(args) { 60 | if (!args.callee) return args; 61 | var array = []; 62 | for (var i=0; i < args.length; i++) { 63 | array.push(args[i]); 64 | }; 65 | return array; 66 | } 67 | -------------------------------------------------------------------------------- /vendor/couchapp/lib/path.js: -------------------------------------------------------------------------------- 1 | // from couch.js 2 | function encodeOptions(options) { 3 | var buf = []; 4 | if (typeof(options) == "object" && options !== null) { 5 | for (var name in options) { 6 | if (!options.hasOwnProperty(name)) {continue;} 7 | var value = options[name]; 8 | if (name == "key" || name == "startkey" || name == "endkey") { 9 | value = JSON.stringify(value); 10 | } 11 | buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value)); 12 | } 13 | } 14 | if (!buf.length) { 15 | return ""; 16 | } 17 | return "?" + buf.join("&"); 18 | } 19 | 20 | function concatArgs(array, args) { 21 | for (var i=0; i < args.length; i++) { 22 | array.push(args[i]); 23 | }; 24 | return array; 25 | }; 26 | 27 | function makePath(array) { 28 | var options, path; 29 | 30 | if (typeof array[array.length - 1] != "string") { 31 | // it's a params hash 32 | options = array.pop(); 33 | } 34 | path = array.map(function(item) {return encodeURIComponent(item)}).join('/'); 35 | if (options) { 36 | return path + encodeOptions(options); 37 | } else { 38 | return path; 39 | } 40 | }; 41 | 42 | exports.init = function(req) { 43 | return { 44 | asset : function() { 45 | var p = req.path, parts = ['', p[0], p[1] , p[2]]; 46 | return makePath(concatArgs(parts, arguments)); 47 | }, 48 | show : function() { 49 | var p = req.path, parts = ['', p[0], p[1] , p[2], '_show']; 50 | return makePath(concatArgs(parts, arguments)); 51 | }, 52 | list : function() { 53 | var p = req.path, parts = ['', p[0], p[1] , p[2], '_list']; 54 | return makePath(concatArgs(parts, arguments)); 55 | }, 56 | update : function() { 57 | var p = req.path, parts = ['', p[0], p[1] , p[2], '_update']; 58 | return makePath(concatArgs(parts, arguments)); 59 | }, 60 | limit : function(limit) { 61 | var query = req.query; 62 | var l = query.limit; 63 | query.limit = limit; 64 | var view = req.path[req.path.length - 1]; 65 | var list = req.path[req.path.length - 2]; 66 | var link = this.list(list, view, query); 67 | query.limit = l; 68 | return link; 69 | }, 70 | older : function(key) { 71 | if (!typeof key == "undefined") return null; 72 | var query = req.query; 73 | query.startkey = key; 74 | query.skip=1; 75 | var view = req.path[req.path.length - 1]; 76 | var list = req.path[req.path.length - 2]; 77 | return this.list(list, view, query); 78 | }, 79 | absolute : function(path) { 80 | return 'http://' + req.headers.Host + path; 81 | } 82 | } 83 | }; 84 | -------------------------------------------------------------------------------- /_attachments/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 | 15 | COUCHAPPSPORA* 16 | 17 | 18 | PREVIEW 19 | 20 |
21 |
22 | 39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | 47 |
    48 |
  • 49 |
    50 | 51 | 52 |
    53 |
  • 54 |
  • 55 |
    56 | 57 | 58 |
    59 |
  • 60 |
  • 61 |
    62 | 65 | 66 | x 67 |
    68 |
  • 69 |
70 | 71 | + Add Header 72 | 73 |
74 |

Drag and drop files on the page to attach

75 |
76 |
77 |
78 | 79 | 80 | 81 | 82 | 83 | 84 |
85 |
86 |
87 | 88 |
89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /vendor/couchapp/lib/docform.js: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 | // use this file except in compliance with the License. You may obtain a copy 3 | // of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | // License for the specific language governing permissions and limitations under 11 | // the License. 12 | 13 | // turn the form into deep json 14 | // field names like 'author-email' get turned into json like 15 | // {"author":{"email":"quentin@example.com"}} 16 | // acts on doc by reference, so you can safely pass non-form fields through 17 | function formToDeepJSON(form, fields, doc) { 18 | form = $(form); 19 | fields.forEach(function(field) { 20 | var val = form.find("[name="+field+"]").val(); 21 | if (!val) {return;} 22 | var parts = field.split('-'); 23 | var frontObj = doc, frontName = parts.shift(); 24 | while (parts.length > 0) { 25 | frontObj[frontName] = frontObj[frontName] || {}; 26 | frontObj = frontObj[frontName]; 27 | frontName = parts.shift(); 28 | } 29 | frontObj[frontName] = val; 30 | }); 31 | } 32 | 33 | function onSubmit(form, db, doc, opts) { 34 | formToDeepJSON(form, opts.fields, doc); 35 | if (opts.beforeSave) {opts.beforeSave(doc);} 36 | db.saveDoc(localFormDoc, { 37 | success : function(resp) { 38 | if (opts.success) {opts.success(resp, doc);} 39 | } 40 | }); 41 | }; 42 | 43 | function applyFields(form, doc) { 44 | 45 | }; 46 | exports.applyFields = applyFields; 47 | 48 | // docForm applies CouchDB behavior to HTML forms. 49 | // todo make this a couch.app plugin 50 | function docForm(formSelector, opts) { 51 | var localFormDoc = {}; 52 | opts = opts || {}; 53 | opts.fields = opts.fields || []; 54 | 55 | // Apply the behavior 56 | $(formSelector).submit(function(e) { 57 | 58 | 59 | return false; 60 | }); 61 | 62 | // populate form from an existing doc 63 | function docToForm(doc) { 64 | var form = $(formSelector); 65 | // fills in forms 66 | opts.fields.forEach(function(field) { 67 | var parts = field.split('-'); 68 | var run = true, frontObj = doc, frontName = parts.shift(); 69 | while (frontObj && parts.length > 0) { 70 | frontObj = frontObj[frontName]; 71 | frontName = parts.shift(); 72 | } 73 | if (frontObj && frontObj[frontName]) { 74 | form.find("[name="+field+"]").val(frontObj[frontName]); 75 | } 76 | }); 77 | } 78 | 79 | if (opts.id) { 80 | db.openDoc(opts.id, { 81 | success: function(doc) { 82 | if (opts.onLoad) {opts.onLoad(doc);} 83 | localFormDoc = doc; 84 | docToForm(doc); 85 | }}); 86 | } else if (opts.template) { 87 | if (opts.onLoad) {opts.onLoad(opts.template);} 88 | localFormDoc = opts.template; 89 | docToForm(localFormDoc); 90 | } 91 | var instance = { 92 | deleteDoc : function(opts) { 93 | opts = opts || {}; 94 | if (confirm("Really delete this document?")) { 95 | db.removeDoc(localFormDoc, opts); 96 | } 97 | }, 98 | localDoc : function() { 99 | formToDeepJSON(formSelector, opts.fields, localFormDoc); 100 | return localFormDoc; 101 | } 102 | }; 103 | return instance; 104 | } 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /vendor/couchapp/docs/pathbinder.md: -------------------------------------------------------------------------------- 1 | # Docs about $.pathbinder 2 | 3 | Pathbinder is a tiny framework for triggering events based on paths in URL hash. For example, you might want to render one panel when the user clicks a link to `#/foo` and another when the URL hash changes to `#/bar`. If you've never used URL hashes for application state in an Ajax app before, prepare to be happy. 4 | 5 | There are two big advantages to having the state in the URL-hash. One is that users can bookmark screens they may have reached by navigating within your app. The other is that the back button will continue to work. 6 | 7 | The page you are on has a URL hash of `#/topic/pathbinder` right now. You can follow links to other "pages" within this application, and Pathbinder takes care of triggering the proper events. 8 | 9 | ## A simple example 10 | 11 | $("#basic_path").html('

click for foo

'); 12 | $("#basic_path").bind("foo", function() { 13 | $(this).html("

you went to foo

"); 14 | }); 15 | $("#basic_path").pathbinder("foo", "/foo"); 16 | 17 | This code sets up the `#basic_path` div with some initial content, including a link to `#/foo`. If you click the link to foo, you'll see the URL change. It is the changed URL which Pathbinder sees and uses to trigger any running code. You can experiment by manually entering the `#/foo` URL hash, instead of clicking the link, and you'll see that it also triggers the `foo` event. 18 | 19 | ## Using path parameters 20 | 21 | Pathbinder was inspired by the path handling in [Sammy.js](http://github.com/aq/sammy.js). Like Sammy, you can use it to pull parameters from the URL-hash. This page can be linked [using a path that has "pathbinder" as a parameter](#/topic/pathbinder). Let's explore how you can pull parameters out of a path. 22 | 23 | $("#param_path").html('

click for super foo

'); 24 | $("#param_path").bind("foo", function(e, params) { 25 | $(this).html("

you went to foo - "+params.id+"

"); 26 | }); 27 | $("#param_path").pathbinder("foo", "/foo/:id"); 28 | 29 | When you click the link to super foo, you'll see the param is passed through the event. You can also edit the URL to see that "super" is not hard coded and can be replaced with other values. 30 | 31 | ## Pathbinder with Evently 32 | 33 | It should be no suprise that Pathbinder and Evently play well together. The gist of it is that Evently looks for a key called `path` and if it finds it, uses Pathbinder to connect that event handler to the path. Let's try it out: 34 | 35 | $("#evently_path").evently({ 36 | _init : { 37 | path : '/index', 38 | mustache : '

the index. more cowbell!

' 39 | }, 40 | cowbell : { 41 | path : '/cowbell', 42 | mustache : '

Now that is a lot of cowbell. back to the index

' 43 | } 44 | }); 45 | 46 | Note that when you use an Evently path, Evently also takes care to visit the path when the corresponding event is triggered. So running the above example code (which automatically triggers the `_init` event) will set the hash to `#/index`. If you were to trigger the `cowbell` event through non-path means, you'd see that it changes the path to `#/cowbell` anyway. 47 | 48 | ### Too many widgets 49 | 50 | One thing worth noting: there is only one URL hash for any given page, so be aware that if you have multiple widgets competing for the real-estate, they could conflict with each other. Pathbinder won't do anything when presented with a path it doesn't care about (go ahead, try out some non-sense ones on this page). 51 | 52 | This means that if you have a few widgets all using the path, the page should still behave in a useful way. However, this breaks down if you intend people to be able to use the URL hash to link to page state. Since there can be only one URL hash, whichever action they took last will be reflected in the bookmarked URL. For this reason it makes sense to limit yourself to one path-based Evently widget per page. 53 | -------------------------------------------------------------------------------- /_attachments/couchappspora.js: -------------------------------------------------------------------------------- 1 | var CouchAppspora = (function() { 2 | 3 | var dbName = "couchappspora", 4 | attachments = []; 5 | 6 | function cloneHeader(e) { 7 | e.preventDefault(); 8 | $("#headertemplate").clone().appendTo($("#headers")).show(); 9 | }; 10 | 11 | function removeHeader(e) { 12 | if (e.target.getAttribute("data-action") === "delete") { 13 | e.preventDefault(); 14 | $(e.target).closest("li").remove(); 15 | } 16 | }; 17 | 18 | function removeAttachment(e) { 19 | 20 | if (e.target.getAttribute("data-action") === "delete") { 21 | e.preventDefault(); 22 | 23 | var i, attach = [], 24 | $parent = $(e.target).closest("li"), 25 | text = $parent.find("span").text(); 26 | 27 | for (i = 0; i < attachments.length; i += 1) { 28 | if (attachments[i].file.name !== text) { 29 | attach.push(attachments[i]); 30 | } 31 | } 32 | attachments = attach; 33 | renderAttachments(); 34 | } 35 | }; 36 | 37 | function hasStupidChromeBug() { 38 | return typeof(FileReader.prototype.addEventListener) !== "function"; 39 | }; 40 | 41 | function isImage(type) { 42 | return type === "image/png" || type === "image/jpeg"; 43 | }; 44 | 45 | function renderAttachments() { 46 | 47 | var i, tmp, html = "