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
5 // http://www.apache.org/licenses/LICENSE-2.0
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
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) {
23 function Design(db, name, code) {
24 this.doc_id = "_design/"+name;
26 this.code_path = this.doc_id + "/" + code;
28 this.code_path = this.doc_id;
30 this.view = function(view, opts) {
31 db.view(name+'/'+view, opts);
33 this.list = function(list, view, opts) {
34 db.list(name+'/'+list, view, opts);
38 function docForm() { alert("docForm has been moved to vendor/couchapp/lib/docForm.js, use app.require to load") };
40 function resolveModule(path, names, parents, current) {
41 parents = parents || [];
42 if (names.length === 0) {
43 if (typeof current != "string") {
44 throw ["error","invalid_require_path",
45 'Must require a JavaScript string, not: '+(typeof current)];
47 return [current, parents];
49 var n = names.shift();
52 var pp = parents.pop();
54 throw ["error", "invalid_require_path", path];
56 return resolveModule(path, names, parents, pp);
57 } else if (n == '.') {
58 var p = parents.pop();
60 throw ["error", "invalid_require_path", path];
62 return resolveModule(path, names, parents, p);
67 throw ["error", "invalid_require_path", path];
69 parents.push(current);
70 return resolveModule(path, names, parents, current[n]);
73 function makeRequire(ddoc) {
75 function getCachedModule(name, parents) {
76 var key, i, len = moduleCache.length;
78 key = moduleCache[i].key;
79 if (key[0] === name && key[1] === parents) {
80 return moduleCache[i].module;
85 function setCachedModule(name, parents, module) {
86 moduleCache.push({ key: [name, parents], module: module });
88 var require = function (name, parents) {
89 var cachedModule = getCachedModule(name, parents);
90 if (cachedModule !== null) {
94 var resolved = resolveModule(name, name.split('/'), parents, ddoc);
95 var source = resolved[0];
96 parents = resolved[1];
97 var s = "var func = function (exports, require) { " + source + " };";
100 func.apply(ddoc, [exports, function(name) {return require(name, parents)}]);
102 throw ["error","compilation_error","Module require('"+name+"') raised error "+e.toSource()];
104 setCachedModule(name, parents, exports);
111 var p = document.location.pathname.split('/'),
112 qs = document.location.search.replace(/^\?/,'').split('&'),
114 qs.forEach(function(param) {
115 var ps = param.split('='),
116 k = decodeURIComponent(ps[0]),
117 v = decodeURIComponent(ps[1]);
118 if (["startkey", "endkey", "key"].indexOf(k) != -1) {
119 q[k] = JSON.parse(v);
131 $.couch.app = $.couch.app || function(appFun, opts) {
133 var urlPrefix = (opts.urlPrefix || ""),
134 index = urlPrefix.split('/').length,
135 fragments = unescape(document.location.href).split('/'),
136 dbname = opts.db || fragments[index + 2],
137 dname = opts.design || fragments[index + 4];
138 $.couch.urlPrefix = urlPrefix;
139 var db = $.couch.db(dbname),
140 design = new Design(db, dname, opts.load_path);
141 var appExports = $.extend({
146 docForm : docForm, // deprecated
149 function handleDDoc(ddoc) {
151 appExports.ddoc = ddoc;
152 appExports.require = makeRequire(ddoc);
154 appFun.apply(appExports, [appExports]);
157 // allow the ddoc to be embedded in the html
158 // to avoid a second http request
159 $.couch.app.ddocs[design.doc_id] = opts.ddoc;
161 if ($.couch.app.ddocs[design.doc_id]) {
162 $(function() {handleDDoc($.couch.app.ddocs[design.doc_id])});
164 // only open 1 connection for this ddoc
165 if ($.couch.app.ddoc_handlers[design.doc_id]) {
166 // we are already fetching, just wait
167 $.couch.app.ddoc_handlers[design.doc_id].push(handleDDoc);
169 $.couch.app.ddoc_handlers[design.doc_id] = [handleDDoc];
170 // use getDbProperty to bypass %2F encoding on _show/app
171 db.getDbProperty(design.code_path, {
172 success : function(doc) {
173 $.couch.app.ddocs[design.doc_id] = doc;
174 $.couch.app.ddoc_handlers[design.doc_id].forEach(function(h) {
175 $(function() {h(doc)});
177 $.couch.app.ddoc_handlers[design.doc_id] = null;
180 $.couch.app.ddoc_handlers[design.doc_id].forEach(function(h) {
183 $.couch.app.ddoc_handlers[design.doc_id] = null;
189 $.couch.app.ddocs = {};
190 $.couch.app.ddoc_handlers = {};
191 // legacy support. $.CouchApp is deprecated, please use $.couch.app
192 $.CouchApp = $.couch.app;
195 // JavaScript 1.6 compatibility functions that are missing from IE7/IE8
197 if (!Array.prototype.forEach)
199 Array.prototype.forEach = function(fun /*, thisp*/)
201 var len = this.length >>> 0;
202 if (typeof fun != "function")
203 throw new TypeError();
205 var thisp = arguments[1];
206 for (var i = 0; i < len; i++)
209 fun.call(thisp, this[i], i, this);
214 if (!Array.prototype.indexOf)
216 Array.prototype.indexOf = function(elt)
218 var len = this.length >>> 0;
220 var from = Number(arguments[1]) || 0;
227 for (; from < len; from++)