Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

new launch page to make it easier to find/develop your apps

  • Loading branch information...
commit 7a9cbef5782bb280c0c8f487c83366389a33bf44 1 parent 7cf13ee
Marty Schoch mschoch authored

Showing 72 changed files with 12,084 additions and 4 deletions. Show diff stats Hide diff stats

  1. BIN  assets/welcome.couch
  2. +1 0  res/xml/phonegap.xml
  3. +19 4 src/com/couchbase/callback/AndroidCouchbaseCallback.java
  4. +7 0 welcome/.couchappignore
  5. +1 0  welcome/.couchapprc
  6. +11 0 welcome/.project
  7. +1 0  welcome/README.md
  8. +53 0 welcome/_attachments/index.html
  9. +80 0 welcome/_attachments/style/main.css
  10. +1 0  welcome/_id
  11. +4 0 welcome/couchapp.json
  12. +3 0  welcome/evently/couchapps/_init.js
  13. +6 0 welcome/evently/couchapps/refresh/after.js
  14. +26 0 welcome/evently/couchapps/refresh/async.js
  15. +11 0 welcome/evently/items/_changes/data.js
  16. +18 0 welcome/evently/items/_changes/mustache.html
  17. +5 0 welcome/evently/items/_changes/query.json
  18. +14 0 welcome/evently/profile/profileReady/mustache.html
  19. +12 0 welcome/evently/profile/profileReady/selectors/form/submit.js
  20. +1 0  welcome/language
  21. +239 0 welcome/vendor/couchapp/_attachments/jquery.couch.app.js
  22. +90 0 welcome/vendor/couchapp/_attachments/jquery.couch.app.util.js
  23. +1,097 0 welcome/vendor/couchapp/_attachments/jquery.couch.js
  24. +399 0 welcome/vendor/couchapp/_attachments/jquery.evently.js
  25. +6,240 0 welcome/vendor/couchapp/_attachments/jquery.js
  26. +346 0 welcome/vendor/couchapp/_attachments/jquery.mustache.js
  27. +174 0 welcome/vendor/couchapp/_attachments/jquery.pathbinder.js
  28. +482 0 welcome/vendor/couchapp/_attachments/json2.js
  29. +17 0 welcome/vendor/couchapp/_attachments/loader.js
  30. +202 0 welcome/vendor/couchapp/_attachments/sha1.js
  31. +22 0 welcome/vendor/couchapp/evently/README.md
  32. +16 0 welcome/vendor/couchapp/evently/account/_init.js
  33. +1 0  welcome/vendor/couchapp/evently/account/adminParty/mustache.html
  34. +10 0 welcome/vendor/couchapp/evently/account/doLogin.js
  35. +8 0 welcome/vendor/couchapp/evently/account/doLogout.js
  36. +10 0 welcome/vendor/couchapp/evently/account/doSignup.js
  37. +4 0 welcome/vendor/couchapp/evently/account/loggedIn/after.js
  38. +7 0 welcome/vendor/couchapp/evently/account/loggedIn/data.js
  39. +4 0 welcome/vendor/couchapp/evently/account/loggedIn/mustache.html
  40. +3 0  welcome/vendor/couchapp/evently/account/loggedIn/selectors.json
  41. +1 0  welcome/vendor/couchapp/evently/account/loggedOut/mustache.html
  42. +4 0 welcome/vendor/couchapp/evently/account/loggedOut/selectors.json
  43. +3 0  welcome/vendor/couchapp/evently/account/loginForm/after.js
  44. +6 0 welcome/vendor/couchapp/evently/account/loginForm/mustache.html
  45. +6 0 welcome/vendor/couchapp/evently/account/loginForm/selectors/form/submit.js
  46. +3 0  welcome/vendor/couchapp/evently/account/signupForm/after.js
  47. +6 0 welcome/vendor/couchapp/evently/account/signupForm/mustache.html
  48. +6 0 welcome/vendor/couchapp/evently/account/signupForm/selectors/form/submit.js
  49. +21 0 welcome/vendor/couchapp/evently/profile/loggedIn.js
  50. +3 0  welcome/vendor/couchapp/evently/profile/loggedOut/after.js
  51. +1 0  welcome/vendor/couchapp/evently/profile/loggedOut/mustache.html
  52. +3 0  welcome/vendor/couchapp/evently/profile/noProfile/data.js
  53. +11 0 welcome/vendor/couchapp/evently/profile/noProfile/mustache.html
  54. +36 0 welcome/vendor/couchapp/evently/profile/noProfile/selectors/form/submit.js
  55. +3 0  welcome/vendor/couchapp/evently/profile/profileReady/after.js
  56. +3 0  welcome/vendor/couchapp/evently/profile/profileReady/data.js
  57. +8 0 welcome/vendor/couchapp/evently/profile/profileReady/mustache.html
  58. +39 0 welcome/vendor/couchapp/lib/atom.js
  59. +25 0 welcome/vendor/couchapp/lib/cache.js
  60. +20 0 welcome/vendor/couchapp/lib/code.js
  61. +121 0 welcome/vendor/couchapp/lib/docform.js
  62. +18 0 welcome/vendor/couchapp/lib/linkup.js
  63. +13 0 welcome/vendor/couchapp/lib/list.js
  64. +1,300 0 welcome/vendor/couchapp/lib/markdown.js
  65. +261 0 welcome/vendor/couchapp/lib/md5.js
  66. +339 0 welcome/vendor/couchapp/lib/mustache.js
  67. +87 0 welcome/vendor/couchapp/lib/path.js
  68. +8 0 welcome/vendor/couchapp/lib/redirect.js
  69. +21 0 welcome/vendor/couchapp/lib/utils.js
  70. +53 0 welcome/vendor/couchapp/lib/validate.js
  71. +5 0 welcome/vendor/couchapp/metadata.json
  72. +5 0 welcome/views/recent-items/map.js
BIN  assets/welcome.couch
Binary file not shown
1  res/xml/phonegap.xml
... ... @@ -1,5 +1,6 @@
1 1 <?xml version="1.0" encoding="utf-8"?>
2 2 <phonegap>
3 3 <access origin="http://127.0.0.1*"/>
  4 + <access origin="http://0.0.0.0*"/>
4 5 <log level="DEBUG"/>
5 6 </phonegap>
23 src/com/couchbase/callback/AndroidCouchbaseCallback.java
@@ -35,10 +35,16 @@
35 35 {
36 36 public static final String TAG = AndroidCouchbaseCallback.class.getName();
37 37 public static final String COUCHBASE_DATABASE_SUFFIX = ".couch";
  38 + public static final String WELCOME_DATABASE = "welcome";
  39 + public static final String DEFAULT_ATTACHMENT = "/index.html";
38 40 private CouchbaseMobile couchbaseMobile;
39 41 private ServiceConnection couchbaseService;
40 42 private String couchappDatabase;
41 43
  44 + protected boolean installWelcomeDatabase() {
  45 + return true;
  46 + }
  47 +
42 48 protected boolean showSplashScreen() {
43 49 return true;
44 50 }
@@ -56,13 +62,17 @@ protected String getDesignDocName() {
56 62 }
57 63
58 64 protected String getAttachmentPath() {
59   - return "/index.html";
  65 + return DEFAULT_ATTACHMENT;
60 66 }
61 67
62 68 protected String getCouchAppURL(String host, int port) {
63 69 return "http://" + host + ":" + port + "/" + getDatabaseName() + "/_design/" + getDesignDocName() + getAttachmentPath();
64 70 }
65 71
  72 + protected String getWelcomeAppURL(String host, int port) {
  73 + return "http://" + host + ":" + port + "/" + WELCOME_DATABASE + "/_design/" + WELCOME_DATABASE + DEFAULT_ATTACHMENT;
  74 + }
  75 +
66 76 protected void couchbaseStarted(String host, int port) {
67 77
68 78 }
@@ -86,6 +96,10 @@ public void onCreate(Bundle savedInstanceState)
86 96
87 97 couchbaseMobile = new CouchbaseMobile(getBaseContext(), couchCallbackHandler);
88 98 try {
  99 + if(installWelcomeDatabase()) {
  100 + couchbaseMobile.installDatabase(WELCOME_DATABASE + COUCHBASE_DATABASE_SUFFIX);
  101 + }
  102 +
89 103 // look for a .couch file in the assets folder
90 104 couchappDatabase = getDatabaseName();
91 105 if(couchappDatabase != null) {
@@ -101,7 +115,8 @@ public void onCreate(Bundle savedInstanceState)
101 115 }
102 116
103 117 /**
104   - * Look for the first .couch file that can be found in the assets folder
  118 + * Look for the first .couch file that is not named "welcome.couch"
  119 + * that can be found in the assets folder
105 120 *
106 121 * @return the name of the database (without the .couch extension)
107 122 * @throws IOException
@@ -117,7 +132,7 @@ public String findCouchApp() {
117 132 }
118 133 if(assets != null) {
119 134 for (String asset : assets) {
120   - if(asset.endsWith(COUCHBASE_DATABASE_SUFFIX)) {
  135 + if(!asset.startsWith(WELCOME_DATABASE) && asset.endsWith(COUCHBASE_DATABASE_SUFFIX)) {
121 136 result = asset.substring(0, asset.length() - COUCHBASE_DATABASE_SUFFIX.length());
122 137 break;
123 138 }
@@ -155,7 +170,7 @@ public void couchbaseStarted(String host, int port) {
155 170 AndroidCouchbaseCallback.this.loadUrl(getCouchAppURL(host, port));
156 171 }
157 172 else {
158   - AndroidCouchbaseCallback.this.loadUrl("file:///android_asset/www/couchapp.html");
  173 + AndroidCouchbaseCallback.this.loadUrl(getWelcomeAppURL(host, port));
159 174 }
160 175
161 176 AndroidCouchbaseCallback.this.couchbaseStarted(host, port);
7 welcome/.couchappignore
... ... @@ -0,0 +1,7 @@
  1 +[
  2 + // filenames matching these regexps will not be pushed to the database
  3 + // uncomment to activate; separate entries with ","
  4 + // ".*~$"
  5 + // ".*\\.swp$"
  6 + // ".*\\.bak$"
  7 +]
1  welcome/.couchapprc
... ... @@ -0,0 +1 @@
  1 +{}
11 welcome/.project
... ... @@ -0,0 +1,11 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<projectDescription>
  3 + <name>callbackwelcome</name>
  4 + <comment></comment>
  5 + <projects>
  6 + </projects>
  7 + <buildSpec>
  8 + </buildSpec>
  9 + <natures>
  10 + </natures>
  11 +</projectDescription>
1  welcome/README.md
Source Rendered
... ... @@ -0,0 +1 @@
  1 +## This couchapp is the source for the welcome page
53 welcome/_attachments/index.html
... ... @@ -0,0 +1,53 @@
  1 +<!DOCTYPE html>
  2 +<html>
  3 + <head>
  4 + <title>Couchbase Mobile with Callback</title>
  5 + <link rel="stylesheet" href="style/main.css" type="text/css">
  6 + </head>
  7 + <body>
  8 + <h1>Welcome to Couchbase Mobile with Callback!</h1>
  9 +
  10 + <p>These instructions are divided into two sections, the first describes the development mode. In this mode you can continually couchapp push your changes in for test. The second describes distribution mode where you package your application for distribution.</p>
  11 +
  12 + <h3>Development</h3>
  13 + <ol>
  14 + <li>Forward Couchbase Mobile from your device/emulator to your development machine. <pre>adb forward tcp:8984 tcp:<span id="couchbasePort">PORT</span></pre></li>
  15 + <li>From within your couchapp project directory run: <pre>couchapp push http://localhost:8984/couchapp<pre></li>
  16 + <li>Refresh the list of CouchApps below and navigate to your applicaiton</li>
  17 + </ol>
  18 +
  19 + <h5>Installed CouchApps (<a href="javascript:void(0)" onclick="refreshTable();">refresh</a>)</h5>
  20 + <table cellspacing=0>
  21 + <thead>
  22 + <tr>
  23 + <th>Database</th>
  24 + <th>Application</th>
  25 + </tr>
  26 + </thead>
  27 + <tbody id="couchappTableBody">
  28 + <tr id="noapps"><td colspan="2">No Couchapps Found</td></tr>
  29 + </tbody>
  30 + </table>
  31 +
  32 + <h3>Distribution</h3>
  33 + <ol>
  34 + <li>Compact your database. <pre>curl -X POST -H "Content-Type: application/json" http://localhost:8984/couchapp/_compact</pre></li>
  35 + <li>From within the Android project, copy the Couchbase Mobile database to the assets folder. <pre>adb pull /mnt/sdcard/Android/data/com.couchbase.callback/db/couchapp.couch assets</pre></li>
  36 + <li>Repackage your application for distribution. <pre>ant debug</pre></li>
  37 + </ol>
  38 +
  39 + </body>
  40 + <script src="vendor/couchapp/loader.js"></script>
  41 + <script type="text/javascript" charset="utf-8">
  42 +
  43 + $('#couchbasePort').replace(window.location.port);
  44 +
  45 + function refreshTable() {
  46 + $("#couchappTableBody").trigger('refresh');
  47 + }
  48 +
  49 + $.couch.app(function(app) {
  50 + $("#couchappTableBody").evently("couchapps", app);
  51 + });
  52 + </script>
  53 +</html>
80 welcome/_attachments/style/main.css
... ... @@ -0,0 +1,80 @@
  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 +
  77 +table, th, td
  78 +{
  79 +border: 1px solid black;
  80 +}
1  welcome/_id
... ... @@ -0,0 +1 @@
  1 +_design/welcome
4 welcome/couchapp.json
... ... @@ -0,0 +1,4 @@
  1 +{
  2 + "name": "Name of your CouchApp",
  3 + "description": "CouchApp"
  4 +}
3  welcome/evently/couchapps/_init.js
... ... @@ -0,0 +1,3 @@
  1 +function() {
  2 + $(this).trigger('refresh');
  3 +}
6 welcome/evently/couchapps/refresh/after.js
... ... @@ -0,0 +1,6 @@
  1 +function(e, r) {
  2 + if(e.db != 'welcome') {
  3 + $('#noapps').remove();
  4 + $(this).append('<tr><td>' + e.db + '</td><td><a href="' + e.appPath + '">' + e.appName + '</a></td></tr>');
  5 + }
  6 +};
26 welcome/evently/couchapps/refresh/async.js
... ... @@ -0,0 +1,26 @@
  1 +function(cb) {
  2 +
  3 + $(this).empty();
  4 + $(this).append('<tr id="noapps"><td colspan="2">No Couchapps Found</td></tr>');
  5 +
  6 + $.couch.allDbs({
  7 + success : function(dbs) {
  8 +
  9 + dbs.forEach( function(db) {
  10 +
  11 + $.couch.db(db).allApps({
  12 + eachApp: function(appName, appPath, ddoc) {
  13 + var app = new Object;
  14 + app.db = db;
  15 + app.appName = appName;
  16 + app.appPath = appPath;
  17 + app.ddoc = ddoc;
  18 + cb(app);
  19 + }
  20 + });
  21 +
  22 + });
  23 + }
  24 + });
  25 +
  26 +}
11 welcome/evently/items/_changes/data.js
... ... @@ -0,0 +1,11 @@
  1 +function(data) {
  2 + // $.log(data)
  3 + var p;
  4 + return {
  5 + items : data.rows.map(function(r) {
  6 + p = (r.value && r.value.profile) || {};
  7 + p.message = r.value && r.value.message;
  8 + return p;
  9 + })
  10 + }
  11 +};
18 welcome/evently/items/_changes/mustache.html
... ... @@ -0,0 +1,18 @@
  1 +<p>Customize this format here: <tt>ddoc.evently.items._changes.mustache</tt></p>
  2 +<h3>Recent Messages</h3>
  3 +<ul>
  4 + {{#items}}
  5 + <li>
  6 + <div class="avatar">
  7 + {{#gravatar_url}}<img src="{{gravatar_url}}" alt="{{name}}"/>{{/gravatar_url}}
  8 + <div class="name">
  9 + {{nickname}}
  10 + </div>
  11 + </div>
  12 + <p>{{message}}</p>
  13 + <div style="clear:left;"></div>
  14 + </li>
  15 + {{/items}}
  16 +</ul>
  17 +<p><em>Protip:</em> If you setup continuous replication between this database and a remote one, this list will reflect remote changes in near real-time.</p>
  18 +<p>This would be a good place to add pagination.</p>
5 welcome/evently/items/_changes/query.json
... ... @@ -0,0 +1,5 @@
  1 +{
  2 + "view" : "recent-items",
  3 + "descending" : "true",
  4 + "limit" : 50
  5 +}
14 welcome/evently/profile/profileReady/mustache.html
... ... @@ -0,0 +1,14 @@
  1 +<p>Most applications will customize this template (<tt>ddoc.evently.profile.profileReady.mustache</tt>) for user input.</p>
  2 +
  3 +<div class="avatar">
  4 + {{#gravatar_url}}<img src="{{gravatar_url}}"/>{{/gravatar_url}}
  5 + <div class="name">
  6 + {{name}}
  7 + </div>
  8 +</div>
  9 +
  10 +<form>
  11 + <label>New message from {{nickname}}: <input type="text" name="message" size=60 value=""></label>
  12 +</form>
  13 +
  14 +<div style="clear:left;"></div>
12 welcome/evently/profile/profileReady/selectors/form/submit.js
... ... @@ -0,0 +1,12 @@
  1 +function() {
  2 + var form = $(this);
  3 + var fdoc = form.serializeObject();
  4 + fdoc.created_at = new Date();
  5 + fdoc.profile = $$("#profile").profile;
  6 + $$(this).app.db.saveDoc(fdoc, {
  7 + success : function() {
  8 + form[0].reset();
  9 + }
  10 + });
  11 + return false;
  12 +};
1  welcome/language
... ... @@ -0,0 +1 @@
  1 +javascript
239 welcome/vendor/couchapp/_attachments/jquery.couch.app.js
... ... @@ -0,0 +1,239 @@
  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 +// Usage: The passed in function is called when the page is ready.
  14 +// CouchApp passes in the app object, which takes care of linking to
  15 +// the proper database, and provides access to the CouchApp helpers.
  16 +// $.couch.app(function(app) {
  17 +// app.db.view(...)
  18 +// ...
  19 +// });
  20 +
  21 +(function($) {
  22 +
  23 + function Design(db, name, code) {
  24 + this.doc_id = "_design/"+name;
  25 + if (code) {
  26 + this.code_path = this.doc_id + "/" + code;
  27 + } else {
  28 + this.code_path = this.doc_id;
  29 + }
  30 + this.view = function(view, opts) {
  31 + if (view.indexOf('/') === -1) {
  32 + db.view(name+'/'+view, opts);
  33 + } else {
  34 + db.view(view, opts);
  35 + }
  36 + };
  37 + this.list = function(list, view, opts) {
  38 + db.list(name+'/'+list, view, opts);
  39 + };
  40 + }
  41 +
  42 + function docForm() { alert("docForm has been moved to vendor/couchapp/lib/docForm.js, use app.require to load") };
  43 +
  44 + function resolveModule(path, names, parents, current) {
  45 + parents = parents || [];
  46 + if (names.length === 0) {
  47 + if (typeof current != "string") {
  48 + throw ["error","invalid_require_path",
  49 + 'Must require a JavaScript string, not: '+(typeof current)];
  50 + }
  51 + return [current, parents];
  52 + }
  53 + var n = names.shift();
  54 + if (n == '..') {
  55 + parents.pop();
  56 + var pp = parents.pop();
  57 + if (!pp) {
  58 + throw ["error", "invalid_require_path", path];
  59 + }
  60 + return resolveModule(path, names, parents, pp);
  61 + } else if (n == '.') {
  62 + var p = parents.pop();
  63 + if (!p) {
  64 + throw ["error", "invalid_require_path", path];
  65 + }
  66 + return resolveModule(path, names, parents, p);
  67 + } else {
  68 + parents = [];
  69 + }
  70 + if (!current[n]) {
  71 + throw ["error", "invalid_require_path", path];
  72 + }
  73 + parents.push(current);
  74 + return resolveModule(path, names, parents, current[n]);
  75 + }
  76 +
  77 + function makeRequire(ddoc) {
  78 + var moduleCache = [];
  79 + function getCachedModule(name, parents) {
  80 + var key, i, len = moduleCache.length;
  81 + for (i=0;i<len;++i) {
  82 + key = moduleCache[i].key;
  83 + if (key[0] === name && key[1] === parents) {
  84 + return moduleCache[i].module;
  85 + }
  86 + }
  87 + return null;
  88 + }
  89 + function setCachedModule(name, parents, module) {
  90 + moduleCache.push({ key: [name, parents], module: module });
  91 + }
  92 + var require = function (name, parents) {
  93 + var cachedModule = getCachedModule(name, parents);
  94 + if (cachedModule !== null) {
  95 + return cachedModule;
  96 + }
  97 + var exports = {};
  98 + var resolved = resolveModule(name, name.split('/'), parents, ddoc);
  99 + var source = resolved[0];
  100 + parents = resolved[1];
  101 + var s = "var func = function (exports, require) { " + source + " };";
  102 + try {
  103 + eval(s);
  104 + func.apply(ddoc, [exports, function(name) {return require(name, parents)}]);
  105 + } catch(e) {
  106 + throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()];
  107 + }
  108 + setCachedModule(name, parents, exports);
  109 + return exports;
  110 + }
  111 + return require;
  112 + };
  113 +
  114 + function mockReq() {
  115 + var p = document.location.pathname.split('/'),
  116 + qs = document.location.search.replace(/^\?/,'').split('&'),
  117 + q = {};
  118 + qs.forEach(function(param) {
  119 + var ps = param.split('='),
  120 + k = decodeURIComponent(ps[0]),
  121 + v = decodeURIComponent(ps[1]);
  122 + if (["startkey", "endkey", "key"].indexOf(k) != -1) {
  123 + q[k] = JSON.parse(v);
  124 + } else {
  125 + q[k] = v;
  126 + }
  127 + });
  128 + p.shift();
  129 + return {
  130 + path : p,
  131 + query : q
  132 + };
  133 + };
  134 +
  135 + $.couch.app = $.couch.app || function(appFun, opts) {
  136 + opts = opts || {};
  137 + var urlPrefix = (opts.urlPrefix || ""),
  138 + index = urlPrefix.split('/').length,
  139 + fragments = unescape(document.location.href).split('/'),
  140 + dbname = opts.db || fragments[index + 2],
  141 + dname = opts.design || fragments[index + 4];
  142 + $.couch.urlPrefix = urlPrefix;
  143 + var db = $.couch.db(dbname),
  144 + design = new Design(db, dname, opts.load_path);
  145 + var appExports = $.extend({
  146 + db : db,
  147 + design : design,
  148 + view : design.view,
  149 + list : design.list,
  150 + docForm : docForm, // deprecated
  151 + req : mockReq()
  152 + }, $.couch.app.app);
  153 + function handleDDoc(ddoc) {
  154 + if (ddoc) {
  155 + appExports.ddoc = ddoc;
  156 + appExports.require = makeRequire(ddoc);
  157 + }
  158 + appFun.apply(appExports, [appExports]);
  159 + }
  160 + if (opts.ddoc) {
  161 + // allow the ddoc to be embedded in the html
  162 + // to avoid a second http request
  163 + $.couch.app.ddocs[design.doc_id] = opts.ddoc;
  164 + }
  165 + if ($.couch.app.ddocs[design.doc_id]) {
  166 + $(function() {handleDDoc($.couch.app.ddocs[design.doc_id])});
  167 + } else {
  168 + // only open 1 connection for this ddoc
  169 + if ($.couch.app.ddoc_handlers[design.doc_id]) {
  170 + // we are already fetching, just wait
  171 + $.couch.app.ddoc_handlers[design.doc_id].push(handleDDoc);
  172 + } else {
  173 + $.couch.app.ddoc_handlers[design.doc_id] = [handleDDoc];
  174 + // use getDbProperty to bypass %2F encoding on _show/app
  175 + db.getDbProperty(design.code_path, {
  176 + success : function(doc) {
  177 + $.couch.app.ddocs[design.doc_id] = doc;
  178 + $.couch.app.ddoc_handlers[design.doc_id].forEach(function(h) {
  179 + $(function() {h(doc)});
  180 + });
  181 + $.couch.app.ddoc_handlers[design.doc_id] = null;
  182 + },
  183 + error : function() {
  184 + $.couch.app.ddoc_handlers[design.doc_id].forEach(function(h) {
  185 + $(function() {h()});
  186 + });
  187 + $.couch.app.ddoc_handlers[design.doc_id] = null;
  188 + }
  189 + });
  190 + }
  191 + }
  192 + };
  193 + $.couch.app.ddocs = {};
  194 + $.couch.app.ddoc_handlers = {};
  195 + // legacy support. $.CouchApp is deprecated, please use $.couch.app
  196 + $.CouchApp = $.couch.app;
  197 +})(jQuery);
  198 +
  199 +// JavaScript 1.6 compatibility functions that are missing from IE7/IE8
  200 +
  201 +if (!Array.prototype.forEach)
  202 +{
  203 + Array.prototype.forEach = function(fun /*, thisp*/)
  204 + {
  205 + var len = this.length >>> 0;
  206 + if (typeof fun != "function")
  207 + throw new TypeError();
  208 +
  209 + var thisp = arguments[1];
  210 + for (var i = 0; i < len; i++)
  211 + {
  212 + if (i in this)
  213 + fun.call(thisp, this[i], i, this);
  214 + }
  215 + };
  216 +}
  217 +
  218 +if (!Array.prototype.indexOf)
  219 +{
  220 + Array.prototype.indexOf = function(elt)
  221 + {
  222 + var len = this.length >>> 0;
  223 +
  224 + var from = Number(arguments[1]) || 0;
  225 + from = (from < 0)
  226 + ? Math.ceil(from)
  227 + : Math.floor(from);
  228 + if (from < 0)
  229 + from += len;
  230 +
  231 + for (; from < len; from++)
  232 + {
  233 + if (from in this &&
  234 + this[from] === elt)
  235 + return from;
  236 + }
  237 + return -1;
  238 + };
  239 +}
90 welcome/vendor/couchapp/_attachments/jquery.couch.app.util.js
... ... @@ -0,0 +1,90 @@
  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 +// http://stackoverflow.com/questions/1184624/serialize-form-to-json-with-jquery/1186309#1186309
  8 +$.fn.serializeObject = function() {
  9 + var o = {};
  10 + var a = this.serializeArray();
  11 + $.each(a, function() {
  12 + if (o[this.name]) {
  13 + if (!o[this.name].push) {
  14 + o[this.name] = [o[this.name]];
  15 + }
  16 + o[this.name].push(this.value || '');
  17 + } else {
  18 + o[this.name] = this.value || '';
  19 + }
  20 + });
  21 + return o;
  22 +};
  23 +
  24 +// todo remove this crap
  25 +function escapeHTML(st) {
  26 + return(
  27 + st && st.replace(/&/g,'&amp;').
  28 + replace(/>/g,'&gt;').
  29 + replace(/</g,'&lt;').
  30 + replace(/"/g,'&quot;')
  31 + );
  32 +};
  33 +
  34 +function safeHTML(st, len) {
  35 + return st ? escapeHTML(st.substring(0,len)) : '';
  36 +}
  37 +
  38 +// todo this should take a replacement template
  39 +$.linkify = function(body) {
  40 + return body.replace(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi,function(a) {
  41 + return '<a target="_blank" href="'+a+'">'+a+'</a>';
  42 + }).replace(/\@([\w\-]+)/g,function(user,name) {
  43 + return '<a href="#/mentions/'+encodeURIComponent(name.toLowerCase())+'">'+user+'</a>';
  44 + }).replace(/\#([\w\-\.]+)/g,function(word,tag) {
  45 + return '<a href="#/tags/'+encodeURIComponent(tag.toLowerCase())+'">'+word+'</a>';
  46 + });
  47 +};
  48 +
  49 +$.fn.prettyDate = function() {
  50 + $(this).each(function() {
  51 + var string, title = $(this).attr("title");
  52 + if (title) {
  53 + string = $.prettyDate(title);
  54 + } else {
  55 + string = $.prettyDate($(this).text());
  56 + }
  57 + $(this).text(string);
  58 + });
  59 +};
  60 +
  61 +$.prettyDate = function(time){
  62 +
  63 + var date = new Date(time.replace(/-/g,"/").replace("T", " ").replace("Z", " +0000").replace(/(\d*\:\d*:\d*)\.\d*/g,"$1")),
  64 + diff = (((new Date()).getTime() - date.getTime()) / 1000),
  65 + day_diff = Math.floor(diff / 86400);
  66 +
  67 + if (isNaN(day_diff)) return time;
  68 +
  69 + return day_diff < 1 && (
  70 + diff < 60 && "just now" ||
  71 + diff < 120 && "1 minute ago" ||
  72 + diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
  73 + diff < 7200 && "1 hour ago" ||
  74 + diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
  75 + day_diff == 1 && "yesterday" ||
  76 + day_diff < 21 && day_diff + " days ago" ||
  77 + day_diff < 45 && Math.ceil( day_diff / 7 ) + " weeks ago" ||
  78 + time;
  79 + // day_diff < 730 && Math.ceil( day_diff / 31 ) + " months ago" ||
  80 + // Math.ceil( day_diff / 365 ) + " years ago";
  81 +};
  82 +
  83 +$.argsToArray = function(args) {
  84 + if (!args.callee) return args;
  85 + var array = [];
  86 + for (var i=0; i < args.length; i++) {
  87 + array.push(args[i]);
  88 + };
  89 + return array;
  90 +}
1,097 welcome/vendor/couchapp/_attachments/jquery.couch.js
... ... @@ -0,0 +1,1097 @@
  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 of
  3 +// 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 +/**
  14 + * @namespace
  15 + * $.couch is used to communicate with a CouchDB server, the server methods can
  16 + * be called directly without creating an instance. Typically all methods are
  17 + * passed an <code>options</code> object which defines a success callback which
  18 + * is called with the data returned from the http request to CouchDB, you can
  19 + * find the other settings that can be used in the <code>options</code> object
  20 + * from <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  21 + * jQuery.ajax settings</a>
  22 + * <pre><code>$.couch.activeTasks({
  23 + * success: function (data) {
  24 + * console.log(data);
  25 + * }
  26 + * });</code></pre>
  27 + * Outputs (for example):
  28 + * <pre><code>[
  29 + * {
  30 + * "pid" : "<0.11599.0>",
  31 + * "status" : "Copied 0 of 18369 changes (0%)",
  32 + * "task" : "recipes",
  33 + * "type" : "Database Compaction"
  34 + * }
  35 + *]</code></pre>
  36 + */
  37 +(function($) {
  38 +
  39 + $.couch = $.couch || {};
  40 + /** @lends $.couch */
  41 +
  42 + /**
  43 + * @private
  44 + */
  45 + function encodeDocId(docID) {
  46 + var parts = docID.split("/");
  47 + if (parts[0] == "_design") {
  48 + parts.shift();
  49 + return "_design/" + encodeURIComponent(parts.join('/'));
  50 + }
  51 + return encodeURIComponent(docID);
  52 + }
  53 +
  54 + /**
  55 + * @private
  56 + */
  57 +
  58 + var uuidCache = [];
  59 +
  60 + $.extend($.couch, {
  61 + urlPrefix: '',
  62 +
  63 + /**
  64 + * You can obtain a list of active tasks by using the /_active_tasks URL.
  65 + * The result is a JSON array of the currently running tasks, with each task
  66 + * being described with a single object.
  67 + * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
  68 + * all/documentation/couchbase-api-misc.html#couchbase-api-misc_active-task
  69 + * s_get">docs for /_active_tasks</a>
  70 + * @param {ajaxSettings} options <a href="http://api.jquery.com/jQuery.ajax
  71 + * /#jQuery-ajax-settings">jQuery ajax settings</a>
  72 + */
  73 + activeTasks: function(options) {
  74 + ajax(
  75 + {url: this.urlPrefix + "/_active_tasks"},
  76 + options,
  77 + "Active task status could not be retrieved"
  78 + );
  79 + },
  80 +
  81 + /**
  82 + * Returns a list of all the databases in the CouchDB instance
  83 + * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
  84 + * all/documentation/couchbase-api-misc.html#couchbase-api-misc_active-task
  85 + * s_get">docs for /_all_dbs</a>
  86 + * @param {ajaxSettings} options <a href="http://api.jquery.com/jQuery.ajax
  87 + * /#jQuery-ajax-settings">jQuery ajax settings</a>
  88 + */
  89 + allDbs: function(options) {
  90 + ajax(
  91 + {url: this.urlPrefix + "/_all_dbs"},
  92 + options,
  93 + "An error occurred retrieving the list of all databases"
  94 + );
  95 + },
  96 +
  97 + /**
  98 + * View and edit the CouchDB configuration, called with just the options
  99 + * parameter the entire config is returned, you can be more specific by
  100 + * passing the section and option parameters, if you specify a value that
  101 + * value will be stored in the configuration.
  102 + * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
  103 + * all/documentation/couchbase-api-config.html#couchbase-api-config_config
  104 + * -section-key_put">docs for /_config</a>
  105 + * @param {ajaxSettings} options
  106 + * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  107 + * jQuery ajax settings</a>
  108 + * @param {String} [section] the section of the config
  109 + * @param {String} [option] the particular config option
  110 + * @param {String} [value] value to be set
  111 + */
  112 + config: function(options, section, option, value) {
  113 + var req = {url: this.urlPrefix + "/_config/"};
  114 + if (section) {
  115 + req.url += encodeURIComponent(section) + "/";
  116 + if (option) {
  117 + req.url += encodeURIComponent(option);
  118 + }
  119 + }
  120 + if (value === null) {
  121 + req.type = "DELETE";
  122 + } else if (value !== undefined) {
  123 + req.type = "PUT";
  124 + req.data = toJSON(value);
  125 + req.contentType = "application/json";
  126 + req.processData = false
  127 + }
  128 +
  129 + ajax(req, options,
  130 + "An error occurred retrieving/updating the server configuration"
  131 + );
  132 + },
  133 +
  134 + /**
  135 + * Returns the session information for the currently logged in user.
  136 + * @param {ajaxSettings} options
  137 + * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  138 + * jQuery ajax settings</a>
  139 + */
  140 + session: function(options) {
  141 + options = options || {};
  142 + $.ajax({
  143 + type: "GET", url: this.urlPrefix + "/_session",
  144 + beforeSend: function(xhr) {
  145 + xhr.setRequestHeader('Accept', 'application/json');
  146 + },
  147 + complete: function(req) {
  148 + var resp = $.parseJSON(req.responseText);
  149 + if (req.status == 200) {
  150 + if (options.success) options.success(resp);
  151 + } else if (options.error) {
  152 + options.error(req.status, resp.error, resp.reason);
  153 + } else {
  154 + alert("An error occurred getting session info: " + resp.reason);
  155 + }
  156 + }
  157 + });
  158 + },
  159 +
  160 + /**
  161 + * @private
  162 + */
  163 + userDb : function(callback) {
  164 + $.couch.session({
  165 + success : function(resp) {
  166 + var userDb = $.couch.db(resp.info.authentication_db);
  167 + callback(userDb);
  168 + }
  169 + });
  170 + },
  171 +
  172 + /**
  173 + * Create a new user on the CouchDB server, <code>user_doc</code> is an
  174 + * object with a <code>name</code> field and other information you want
  175 + * to store relating to that user, for example
  176 + * <code>{"name": "daleharvey"}</code>
  177 + * @param {Object} user_doc Users details
  178 + * @param {String} password Users password
  179 + * @param {ajaxSettings} options
  180 + * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  181 + * jQuery ajax settings</a>
  182 + */
  183 + signup: function(user_doc, password, options) {
  184 + options = options || {};
  185 + // prepare user doc based on name and password
  186 + user_doc = this.prepareUserDoc(user_doc, password);
  187 + $.couch.userDb(function(db) {
  188 + db.saveDoc(user_doc, options);
  189 + });
  190 + },
  191 +
  192 + /**
  193 + * Populates a user doc with a new password.
  194 + * @param {Object} user_doc User details
  195 + * @param {String} new_password New Password
  196 + */
  197 + prepareUserDoc: function(user_doc, new_password) {
  198 + if (typeof hex_sha1 == "undefined") {
  199 + alert("creating a user doc requires sha1.js to be loaded in the page");
  200 + return;
  201 + }
  202 + var user_prefix = "org.couchdb.user:";
  203 + user_doc._id = user_doc._id || user_prefix + user_doc.name;
  204 + if (new_password) {
  205 + // handle the password crypto
  206 + user_doc.salt = $.couch.newUUID();
  207 + user_doc.password_sha = hex_sha1(new_password + user_doc.salt);
  208 + }
  209 + user_doc.type = "user";
  210 + if (!user_doc.roles) {
  211 + user_doc.roles = [];
  212 + }
  213 + return user_doc;
  214 + },
  215 +
  216 + /**
  217 + * Authenticate against CouchDB, the <code>options</code> parameter is
  218 + *expected to have <code>name</code> and <code>password</code> fields.
  219 + * @param {ajaxSettings} options
  220 + * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  221 + * jQuery ajax settings</a>
  222 + */
  223 + login: function(options) {
  224 + options = options || {};
  225 + $.ajax({
  226 + type: "POST", url: this.urlPrefix + "/_session", dataType: "json",
  227 + data: {name: options.name, password: options.password},
  228 + beforeSend: function(xhr) {
  229 + xhr.setRequestHeader('Accept', 'application/json');
  230 + },
  231 + complete: function(req) {
  232 + var resp = $.parseJSON(req.responseText);
  233 + if (req.status == 200) {
  234 + if (options.success) options.success(resp);
  235 + } else if (options.error) {
  236 + options.error(req.status, resp.error, resp.reason);
  237 + } else {
  238 + alert("An error occurred logging in: " + resp.reason);
  239 + }
  240 + }
  241 + });
  242 + },
  243 +
  244 +
  245 + /**
  246 + * Delete your current CouchDB user session
  247 + * @param {ajaxSettings} options
  248 + * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  249 + * jQuery ajax settings</a>
  250 + */
  251 + logout: function(options) {
  252 + options = options || {};
  253 + $.ajax({
  254 + type: "DELETE", url: this.urlPrefix + "/_session", dataType: "json",
  255 + username : "_", password : "_",
  256 + beforeSend: function(xhr) {
  257 + xhr.setRequestHeader('Accept', 'application/json');
  258 + },
  259 + complete: function(req) {
  260 + var resp = $.parseJSON(req.responseText);
  261 + if (req.status == 200) {
  262 + if (options.success) options.success(resp);
  263 + } else if (options.error) {
  264 + options.error(req.status, resp.error, resp.reason);
  265 + } else {
  266 + alert("An error occurred logging out: " + resp.reason);
  267 + }
  268 + }
  269 + });
  270 + },
  271 +
  272 + /**
  273 + * @namespace
  274 + * $.couch.db is used to communicate with a specific CouchDB database
  275 + * <pre><code>var $db = $.couch.db("mydatabase");
  276 + *$db.allApps({
  277 + * success: function (data) {
  278 + * ... process data ...
  279 + * }
  280 + *});
  281 + * </code></pre>
  282 + */
  283 + db: function(name, db_opts) {
  284 + db_opts = db_opts || {};
  285 + var rawDocs = {};
  286 + function maybeApplyVersion(doc) {
  287 + if (doc._id && doc._rev && rawDocs[doc._id] &&
  288 + rawDocs[doc._id].rev == doc._rev) {
  289 + // todo: can we use commonjs require here?
  290 + if (typeof Base64 == "undefined") {
  291 + alert("please include /_utils/script/base64.js in the page for " +
  292 + "base64 support");
  293 + return false;
  294 + } else {
  295 + doc._attachments = doc._attachments || {};
  296 + doc._attachments["rev-"+doc._rev.split("-")[0]] = {
  297 + content_type :"application/json",
  298 + data : Base64.encode(rawDocs[doc._id].raw)
  299 + };
  300 + return true;
  301 + }
  302 + }
  303 + };
  304 + return /** @lends $.couch.db */{
  305 + name: name,
  306 + uri: this.urlPrefix + "/" + encodeURIComponent(name) + "/",
  307 +
  308 + /**
  309 + * Request compaction of the specified database.
  310 + * @see <a href="http://techzone.couchbase.com/sites/default/files/
  311 + * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
  312 + * db-compact_post">docs for /db/_compact</a>
  313 + * @param {ajaxSettings} options
  314 + * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
  315 + * jQuery ajax settings</a>
  316 + */
  317 + compact: function(options) {
  318 + $.extend(options, {successStatus: 202});
  319 + ajax({