Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 7f1290f1e572d5dc6c074aa826d38a87160f9216 @quirkey committed Sep 2, 2009
1 .gitignore
@@ -0,0 +1 @@
+.couchapprc
14 _attachments/index.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Generated CouchApp</title>
+ <link rel="stylesheet" href="style/main.css" type="text/css">
+ </head>
+ <body>
+ <h1>Generated CouchApp</h1>
+ <p>This is a placeholder page</p>
+ </body>
+ <script src="/_utils/script/json2.js"></script>
+ <script src="/_utils/script/jquery.js?1.3.1"></script>
+ <script src="/_utils/script/jquery.couch.js?0.9.0"></script>
+</html>
1 _attachments/style/main.css
@@ -0,0 +1 @@
+/* add styles here */
4 couchapp.json
@@ -0,0 +1,4 @@
+{
+ "name": "Name of your CouchApp",
+ "description": "CouchApp"
+}
3 vendor/couchapp/README.md
@@ -0,0 +1,3 @@
+## CouchApp - more than just a filesystem mapper
+
+This is where documentation will go for the client and server JavaScript parts of CouchApp.
200 vendor/couchapp/_attachments/jquery.couchapp.js
@@ -0,0 +1,200 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// Usage: The passed in function is called when the page is ready.
+// CouchApp passes in the app object, which takes care of linking to
+// the proper database, and provides access to the CouchApp helpers.
+// $.CouchApp(function(app) {
+// app.db.view(...)
+// ...
+// });
+
+(function($) {
+
+ function f(n) { // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ Date.prototype.toJSON = function() {
+ return this.getUTCFullYear() + '/' +
+ f(this.getUTCMonth() + 1) + '/' +
+ f(this.getUTCDate()) + ' ' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + ' +0000';
+ };
+
+ function Design(db, name) {
+ this.view = function(view, opts) {
+ db.view(name+'/'+view, opts);
+ };
+ };
+
+ var login;
+
+ function init(app) {
+ $(function() {
+ var dbname = document.location.href.split('/')[3];
+ var dname = unescape(document.location.href).split('/')[5];
+ var db = $.couch.db(dbname);
+ var design = new Design(db, dname);
+
+ // docForm applies CouchDB behavior to HTML forms.
+ function docForm(formSelector, opts) {
+ var localFormDoc = {};
+ opts = opts || {};
+ opts.fields = opts.fields || [];
+
+ // turn the form into deep json
+ // field names like 'author-email' get turned into json like
+ // {"author":{"email":"quentin@example.com"}}
+ function formToDeepJSON(form, fields, doc) {
+ var form = $(form);
+ opts.fields.forEach(function(field) {
+ var val = form.find("[name="+field+"]").val()
+ if (!val) return;
+ var parts = field.split('-');
+ var frontObj = doc, frontName = parts.shift();
+ while (parts.length > 0) {
+ frontObj[frontName] = frontObj[frontName] || {}
+ frontObj = frontObj[frontName];
+ frontName = parts.shift();
+ }
+ frontObj[frontName] = val;
+ });
+ };
+
+ // Apply the behavior
+ $(formSelector).submit(function(e) {
+ e.preventDefault();
+ // formToDeepJSON acts on localFormDoc by reference
+ formToDeepJSON(this, opts.fields, localFormDoc);
+ if (opts.beforeSave) opts.beforeSave(localFormDoc);
+ db.saveDoc(localFormDoc, {
+ success : function(resp) {
+ if (opts.success) opts.success(resp, localFormDoc);
+ }
+ })
+
+ return false;
+ });
+
+ // populate form from an existing doc
+ function docToForm(doc) {
+ var form = $(formSelector);
+ // fills in forms
+ opts.fields.forEach(function(field) {
+ var parts = field.split('-');
+ var run = true, frontObj = doc, frontName = parts.shift();
+ while (frontObj && parts.length > 0) {
+ frontObj = frontObj[frontName];
+ frontName = parts.shift();
+ }
+ if (frontObj && frontObj[frontName])
+ form.find("[name="+field+"]").val(frontObj[frontName]);
+ });
+ };
+
+ if (opts.id) {
+ db.openDoc(opts.id, {
+ success: function(doc) {
+ if (opts.onLoad) opts.onLoad(doc);
+ localFormDoc = doc;
+ docToForm(doc);
+ }});
+ } else if (opts.template) {
+ if (opts.onLoad) opts.onLoad(opts.template);
+ localFormDoc = opts.template;
+ docToForm(localFormDoc);
+ }
+ var instance = {
+ deleteDoc : function(opts) {
+ opts = opts || {};
+ if (confirm("Really delete this document?")) {
+ db.removeDoc(localFormDoc, opts);
+ }
+ },
+ localDoc : function() {
+ formToDeepJSON(formSelector, opts.fields, localFormDoc);
+ return localFormDoc;
+ }
+ }
+ return instance;
+ }
+
+ function prettyDate(time){
+ var date = new Date(time),
+ diff = (((new Date()).getTime() - date.getTime()) / 1000),
+ day_diff = Math.floor(diff / 86400);
+
+ // if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 ) return;
+
+ return day_diff < 1 && (
+ diff < 60 && "just now" ||
+ diff < 120 && "1 minute ago" ||
+ diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
+ diff < 7200 && "1 hour ago" ||
+ diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
+ day_diff == 1 && "yesterday" ||
+ day_diff < 21 && day_diff + " days ago" ||
+ day_diff < 45 && Math.ceil( day_diff / 7 ) + " weeks ago" ||
+ day_diff < 730 && Math.ceil( day_diff / 31 ) + " months ago" ||
+ Math.ceil( day_diff / 365 ) + " years ago";
+ };
+
+ app({
+ showPath : function(funcname, docid) {
+ // I wish this was shared with path.js...
+ return '/'+[dbname, '_design', dname, '_show', funcname, docid].join('/')
+ },
+ listPath : function(funcname, viewname) {
+ return '/'+[dbname, '_design', dname, '_list', funcname, viewname].join('/')
+ },
+ slugifyString : function(string) {
+ return string.replace(/\W/g,'-').
+ replace(/\-*$/,'').replace(/^\-*/,'').
+ replace(/\-{2,}/,'-');
+ },
+ attemptLogin : function(win, fail) {
+ // depends on nasty hack in blog validation function
+ db.saveDoc({"author":"_self"}, { error: function(s, e, r) {
+ var namep = r.split(':');
+ if (namep[0] == '_self') {
+ login = namep.pop();
+ $.cookies.set("login", login, '/'+dbname)
+ win && win(login);
+ } else {
+ $.cookies.set("login", "", '/'+dbname)
+ fail && fail(s, e, r);
+ }
+ }});
+ },
+ loggedInNow : function(loggedIn, loggedOut) {
+ login = login || $.cookies.get("login");
+ if (login) {
+ loggedIn && loggedIn(login);
+ } else {
+ loggedOut && loggedOut();
+ }
+ },
+ db : db,
+ design : design,
+ view : design.view,
+ docForm : docForm,
+ prettyDate : prettyDate
+ });
+ });
+ };
+
+ $.CouchApp = $.CouchApp || init;
+
+})(jQuery);
1 vendor/couchapp/couchapp.js
@@ -0,0 +1 @@
+// this stuff should be properly namespaced etc
23 vendor/couchapp/date.js
@@ -0,0 +1,23 @@
+function f(n) { // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+}
+
+Date.prototype.rfc3339 = function() {
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+};
+
+// This is a format that collates in order and tends to work with
+// JavaScript's new Date(string) date parsing capabilities, unlike rfc3339.
+Date.prototype.toJSON = function() {
+ return this.getUTCFullYear() + '/' +
+ f(this.getUTCMonth() + 1) + '/' +
+ f(this.getUTCDate()) + ' ' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + ' +0000';
+};
77 vendor/couchapp/path.js
@@ -0,0 +1,77 @@
+// from couch.js
+function encodeOptions(options, noJson) {
+ var buf = []
+ if (typeof(options) == "object" && options !== null) {
+ for (var name in options) {
+ if (!options.hasOwnProperty(name)) continue;
+ var value = options[name];
+ if (!noJson && (name == "key" || name == "startkey" || name == "endkey")) {
+ value = toJSON(value);
+ }
+ buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
+ }
+ }
+ if (!buf.length) {
+ return "";
+ }
+ return "?" + buf.join("&");
+}
+
+function concatArgs(array, args) {
+ for (var i=0; i < args.length; i++) {
+ array.push(args[i]);
+ };
+ return array;
+};
+
+function makePath(array) {
+ var options, path;
+
+ if (typeof array[array.length - 1] != "string") {
+ // it's a params hash
+ options = array.pop();
+ }
+ path = array.map(function(item) {return encodeURIComponent(item)}).join('/');
+ if (options) {
+ return path + encodeOptions(options);
+ } else {
+ return path;
+ }
+};
+
+function assetPath() {
+ var p = req.path, parts = ['', p[0], p[1] , p[2]];
+ return makePath(concatArgs(parts, arguments));
+};
+
+function showPath() {
+ var p = req.path, parts = ['', p[0], p[1] , p[2], '_show'];
+ return makePath(concatArgs(parts, arguments));
+};
+
+function listPath() {
+ var p = req.path, parts = ['', p[0], p[1] , p[2], '_list'];
+ return makePath(concatArgs(parts, arguments));
+};
+
+function olderPath(info) {
+ if (!info) return null;
+ var q = req.query;
+ q.startkey = info.prev_key;
+ q.skip=1;
+ return listPath('index','recent-posts',q);
+}
+
+function makeAbsolute(req, path) {
+ return 'http://' + req.headers.Host + path;
+}
+
+
+function currentPath() {
+ path = req.path.map(function(item) {return encodeURIComponent(item)}).join('/');
+ if (req.query) {
+ return path + encodeOptions(req.query, true);
+ } else {
+ return path;
+ }
+}
33 vendor/couchapp/template.js
@@ -0,0 +1,33 @@
+// Simple JavaScript Templating
+// John Resig - http://ejohn.org/ - MIT Licensed
+var cache = {};
+
+function template(str, data){
+ // Figure out if we're getting a template, or if we need to
+ // load the template - and be sure to cache the result.
+ var fn = cache[str] ||
+
+ // Generate a reusable function that will serve as a template
+ // generator (and which will be cached).
+ new Function("obj",
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
+
+ // Introduce the data as local variables using with(){}
+ "with(obj){p.push('" +
+
+ // Convert the template into pure JavaScript
+ str
+ .replace(/\n/g, "\\n")
+ .replace(/[\r\t]/g, " ")
+ .replace(/'(?=[^%]*%>)/g,"\t")
+ .split("'").join("\\'")
+ .split("\t").join("'")
+ .replace(/<%=(.+?)%>/g, "',$1,'")
+ .split("<%").join("');")
+ .split("%>").join("p.push('")
+ + "');}return p.join('');");
+ cache[str] = fn;
+
+ // Provide some basic currying to the user
+ return data ? fn( data ) : fn;
+};

0 comments on commit 7f1290f

Please sign in to comment.