summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/www/browse/database.html20
-rw-r--r--share/www/script/browse.js39
-rw-r--r--share/www/script/couch.js4
-rw-r--r--share/www/script/jquery.couch.js30
-rw-r--r--share/www/script/jquery.resizer.js6
-rw-r--r--share/www/style/layout.css44
6 files changed, 98 insertions, 45 deletions
diff --git a/share/www/browse/database.html b/share/www/browse/database.html
index 76990608..51cc19f4 100644
--- a/share/www/browse/database.html
+++ b/share/www/browse/database.html
@@ -36,7 +36,7 @@ specific language governing permissions and limitations under the License.
$(document).ready(function() {
$("h1 strong").text(page.db.name);
- $("#viewcode label").click(function() {
+ $("#viewcode span").click(function() {
$("#viewcode").toggleClass("expanded");
});
$("#viewcode button.run").click(function() {
@@ -51,11 +51,14 @@ specific language governing permissions and limitations under the License.
$("#viewcode button.saveas").click(function() {
page.saveViewAs();
});
- $("#viewcode textarea").resizable({grippie: $("#viewcode .bottom")});
+ $("#viewcode textarea").resizable({
+ always: true,
+ grippie: $("#viewcode .bottom")
+ });
// Restore preferences/state from cookies
var query = $.cookies.get(page.db.name + ".query");
- if (query) $("#viewcode textarea").val(query);
+ if (query) $("#viewcode_map").val(query);
var desc = $.cookies.get(page.db.name + ".desc");
if (desc) $("#documents thead th.key").addClass("desc");
var rowsPerPage = $.cookies.get(page.db.name + ".perpage");
@@ -108,11 +111,18 @@ specific language governing permissions and limitations under the License.
<div id="viewcode" style="display: none">
<div class="top">
<a id="designdoc-link"></a>
- <label for="viewcode_textarea">View Function</label>
+ <span id="view-toggle">View Function</span>
</div>
- <textarea id="viewcode_textarea" rows="5" cols="79" spellcheck="false" wrap="off">function(doc) {
+ <div class="code map">
+ <label>Map Function:</label>
+ <textarea id="viewcode_map" class="map" rows="5" cols="79" spellcheck="false" wrap="off">function(doc) {
emit(null, doc);
}</textarea>
+ </div>
+ <div class="code reduce">
+ <label>Reduce Function (optional):</label>
+ <textarea id="viewcode_reduce" class="reduce" rows="5" cols="79" spellcheck="false" wrap="off"></textarea>
+ </div>
<div class="bottom">
<button class="save" type="button" disabled>Save</button>
<button class="saveas" type="button">Save As…</button>
diff --git a/share/www/script/browse.js b/share/www/script/browse.js
index 9d821d09..29e76d6a 100644
--- a/share/www/script/browse.js
+++ b/share/www/script/browse.js
@@ -145,7 +145,8 @@ function CouchDatabasePage() {
clearTimeout(dirtyTimeout);
dirtyTimeout = setTimeout(function() {
var buttons = $("#viewcode button.save, #viewcode button.revert");
- page.isDirty = $("#viewcode textarea").val() != page.storedViewCode;
+ page.isDirty = ($("#viewcode_map").val() != page.storedViewCode.map)
+ || ($("#viewcode_reduce").val() != page.storedViewCode.reduce);
if (page.isDirty) {
buttons.removeAttr("disabled");
} else {
@@ -153,7 +154,7 @@ function CouchDatabasePage() {
}
}, 100);
}
- $("#viewcode textarea").bind("input", updateDirtyState);
+ $("#viewcode_map").bind("input", updateDirtyState);
if ($.browser.msie) { // sorry, browser detection
$("#viewcode textarea").get(0).onpropertychange = updateDirtyState
} else if ($.browser.safari) {
@@ -214,13 +215,15 @@ function CouchDatabasePage() {
},
success: function(resp) {
page.storedViewCode = resp.views[localViewName];
- $("#viewcode textarea").val(page.storedViewCode);
+ $("#viewcode_map").val(page.storedViewCode.map);
+ $("#viewcode_reduce").val(page.storedViewCode.reduce || "");
$("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled");
if (callback) callback();
}
});
} else {
- $("#viewcode textarea").val(page.storedViewCode);
+ $("#viewcode_map").val(page.storedViewCode.map);
+ $("#viewcode_reduce").val(page.storedViewCode.reduce || "");
page.isDirty = false;
$("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled");
if (callback) callback();
@@ -274,7 +277,10 @@ function CouchDatabasePage() {
if (!data.name) errors.name = "Please enter a view name";
callback(errors);
} else {
- var viewCode = $("#viewcode textarea").val();
+ var viewCode = {
+ map: $("#viewcode_map").val(),
+ reduce: $("#viewcode_map").val() || undefined
+ };
var docId = ["_design", data.docid].join("/");
function save(doc) {
if (!doc) doc = {_id: docId, language: "javascript"};
@@ -311,7 +317,9 @@ function CouchDatabasePage() {
$(document.body).addClass("loading");
db.openDoc(["_design", designDocId].join("/"), {
success: function(doc) {
- doc.views[localViewName] = $("#viewcode textarea").val();
+ var viewDef = doc.views[localViewName];
+ viewDef.map = $("#viewcode_map").val();
+ viewDef.reduce = $("#viewcode_reduce").val() || undefined;
db.saveDoc(doc, {
success: function(resp) {
page.isDirty = false;
@@ -410,8 +418,9 @@ function CouchDatabasePage() {
$(document.body).removeClass("loading");
}
options.success = handleResults;
- options.error = function(error, reason) {
- alert(reason);
+ options.error = function(status, error, reason) {
+ alert("Error: " + error + "\n\n" + reason);
+ $(document.body).removeClass("loading");
}
if (!viewName) {
@@ -420,16 +429,22 @@ function CouchDatabasePage() {
} else {
if (viewName == "_temp_view") {
$("#viewcode").show().addClass("expanded");
- var query = $("#viewcode textarea").val();
- $.cookies.set(db.name + ".query", query);
- db.query(query, options);
+ var mapFun = $("#viewcode_map").val();
+ $.cookies.set(db.name + ".map", mapFun);
+ var reduceFun = $("#viewcode_reduce").val() || null;
+ if (reduceFun != null) {
+ $.cookies.set(db.name + ".reduce", reduceFun);
+ } else {
+ $.cookies.remove(db.name + ".reduce");
+ }
+ db.query(mapFun, reduceFun, null, options);
} else if (viewName == "_design_docs") {
options.startkey = options.descending ? "_design/ZZZZ" : "_design/";
options.endkey = options.descending ? "_design/" : "_design/ZZZZ";
db.allDocs(options);
} else {
$("#viewcode").show();
- var currentViewCode = $("#viewcode textarea").val();
+ var currentViewCode = $("#viewcode_map").val();
if (page.isDirty) {
db.query(currentViewCode, options);
} else {
diff --git a/share/www/script/couch.js b/share/www/script/couch.js
index 0b2f828c..d1cff6c1 100644
--- a/share/www/script/couch.js
+++ b/share/www/script/couch.js
@@ -113,7 +113,7 @@ function CouchDB(name) {
throw result;
return result;
}
-
+
this.view = function(viewname, options) {
var req = request("GET", this.uri + "_view/" + viewname + encodeOptions(options));
if (req.status == 404)
@@ -140,7 +140,7 @@ function CouchDB(name) {
throw result;
return result;
}
-
+
this.compact = function() {
var req = request("POST", this.uri + "_compact");
var result = JSON.parse(req.responseText);
diff --git a/share/www/script/jquery.couch.js b/share/www/script/jquery.couch.js
index 695b0f11..71a3c787 100644
--- a/share/www/script/jquery.couch.js
+++ b/share/www/script/jquery.couch.js
@@ -15,6 +15,7 @@
$.fn.extend($.couch, {
allDbs: function(options) {
+ options = options || {};
$.ajax({
type: "GET", url: "/_all_dbs",
complete: function(req) {
@@ -37,6 +38,7 @@
uri: "/" + encodeURIComponent(name) + "/",
compact: function(options) {
+ options = options || {};
$.ajax({
type: "POST", url: this.uri + "_compact", dataType: "json",
complete: function(req) {
@@ -52,6 +54,7 @@
});
},
create: function(options) {
+ options = options || {};
$.ajax({
type: "PUT", url: this.uri, dataType: "json",
complete: function(req) {
@@ -67,6 +70,7 @@
});
},
drop: function(options) {
+ options = options || {};
$.ajax({
type: "DELETE", url: this.uri, dataType: "json",
complete: function(req) {
@@ -82,6 +86,7 @@
});
},
info: function(options) {
+ options = options || {};
$.ajax({
type: "GET", url: this.uri, dataType: "json",
complete: function(req) {
@@ -98,6 +103,7 @@
});
},
allDocs: function(options) {
+ options = options || {};
$.ajax({
type: "GET", url: this.uri + "_all_docs" + encodeOptions(options),
dataType: "json",
@@ -115,6 +121,7 @@
});
},
openDoc: function(docId, options) {
+ options = options || {};
$.ajax({
type: "GET",
url: this.uri + encodeURIComponent(docId) + encodeOptions(options),
@@ -132,6 +139,7 @@
});
},
saveDoc: function(doc, options) {
+ options = options || {};
if (doc._id === undefined) {
var method = "POST";
var uri = this.uri;
@@ -158,6 +166,7 @@
});
},
removeDoc: function(doc, options) {
+ options = options || {};
$.ajax({
type: "DELETE",
url: this.uri + encodeURIComponent(doc._id) + encodeOptions({rev: doc._rev}),
@@ -174,14 +183,22 @@
}
});
},
- query: function(fun, options) {
- if (typeof(fun) != "string")
- fun = fun.toSource ? fun.toSource() : "(" + fun.toString() + ")";
+ query: function(mapFun, reduceFun, language, options) {
+ options = options || {};
+ language = language || "javascript"
+ if (typeof(mapFun) != "string") {
+ mapFun = mapFun.toSource ? mapFun.toSource() : "(" + mapFun.toString() + ")";
+ }
+ var body = {language: language, map: mapFun};
+ if (reduceFun != null) {
+ if (typeof(reduceFun) != "string")
+ reduceFun = reduceFun.toSource ? reduceFun.toSource() : "(" + reduceFun.toString() + ")";
+ body.reduce = reduceFun;
+ }
$.ajax({
type: "POST", url: this.uri + "_temp_view" + encodeOptions(options),
contentType: "application/json",
- data: toJSON({language:"javascript", map:fun}),
- dataType: "json",
+ data: toJSON(body), dataType: "json",
complete: function(req) {
var resp = $.httpData(req, "json");
if (req.status == 200 && options.success) {
@@ -195,6 +212,7 @@
});
},
view: function(name, options) {
+ options = options || {};
$.ajax({
type: "GET", url: this.uri + "_view/" + name + encodeOptions(options),
dataType: "json",
@@ -214,6 +232,7 @@
},
info: function(options) {
+ options = options || {};
$.ajax({
type: "GET", url: "/", dataType: "json",
complete: function(req) {
@@ -230,6 +249,7 @@
},
replicate: function(source, target, options) {
+ options = options || {};
$.ajax({
type: "POST", url: "/_replicate", dataType: "json",
data: JSON.stringify({source: source, target: target}),
diff --git a/share/www/script/jquery.resizer.js b/share/www/script/jquery.resizer.js
index 8ebd0c66..081c7177 100644
--- a/share/www/script/jquery.resizer.js
+++ b/share/www/script/jquery.resizer.js
@@ -13,13 +13,15 @@
(function($) {
$.fn.resizable = function(options) {
- if ($.browser.safari && parseInt($.browser.version) >= 522)
- return this; // safari3 and later provides textarea resizing natively
options = options || {};
+ options.always = options.always || false;
options.grippie = options.grippie || null;
options.minHeight = options.minHeight || 32;
options.maxHeight = options.maxHeight || null;
+ if (!options.always && $.browser.safari && parseInt($.browser.version) >= 522)
+ return this; // safari3 and later provides textarea resizing natively
+
return this.each(function() {
var grippie = options.grippie;
if (!grippie) grippie = $("<div></div>").appendTo(this.parentNode);
diff --git a/share/www/style/layout.css b/share/www/style/layout.css
index 0632d261..c899198d 100644
--- a/share/www/style/layout.css
+++ b/share/www/style/layout.css
@@ -251,35 +251,41 @@ ul.suggest-dropdown li.selected { cursor: pointer; background: Highlight;
#viewcode { background: #fff; border: 1px solid;
border-color: #999 #ddd #ddd #999; margin: 0 0 1em; padding: 0 .5em;
}
-#viewcode div { background-color: #e9e9e9; border: 1px solid;
- border-color: #ddd #ddd #e9e9e9 #ddd; color: #333; margin: 0 -.5em;
- padding: 0 .5em 2px;
+#viewcode .top, #viewcode .bottom { background-color: #e9e9e9;
+ border: 1px solid; border-color: #ddd #ddd #e9e9e9 #ddd; color: #333;
+ margin: 0 -.5em; padding: 0 .5em 2px;
}
#viewcode .top { color: #aaa; font-size: 95%; }
+#viewcode .top span { background: url(../image/twisty.gif) 0 3px no-repeat;
+ border: none; color: #666; cursor: pointer; display: block; font-size: 90%;
+ margin: 0; padding: 2px 0 0 15px;
+}
#viewcode .top a { float: right; font-size: 90%; line-height: 1.4em;
padding: 2px 2px 0 0;
}
#viewcode .top a:link, #viewcode .top a:visited { color: #999; }
-#viewcode label { background: url(../image/twisty.gif) 0 3px no-repeat;
- color: #666; cursor: pointer; display: block; padding: 2px 0 0 15px;
-}
-#viewcode div.bottom, #viewcode textarea { display: none; }
-#viewcode textarea { border: none; color: #333; max-width: 100%;
- min-height: 50px; padding: .5em 0; width: 100%;
-}
-#viewcode div.bottom { border-bottom: none; padding: 1px 3px; }
-#viewcode div.bottom button { font-size: 90%; margin: 0 1em 0 0;
+#viewcode .code, #viewcode .bottom { display: none; }
+#viewcode .code { float: left; padding: .2em 0; width: 49%; }
+#viewcode .code label { font-size: 90%; color: #999; }
+#viewcode .code textarea { border: none; border-top: 1px solid #ddd;
+ color: #333; min-height: 50px; max-width: 98%; padding-top: .5em;
+ resize: none;
+}
+#viewcode div.map { border-right: 1px dashed #ccc; margin-right: .5em; }
+#viewcode .bottom { border-bottom: none; clear: left; padding: 1px 3px; }
+#viewcode .bottom button { font-size: 90%; margin: 0 1em 0 0;
padding-left: 2em; padding-right: 2em;
}
-*html #viewcode div.bottom button { padding: 0 .5em; }
-*+html #viewcode div.bottom button { padding: 0 .5em; }
-#viewcode div.bottom button.revert, #viewcode div.bottom button.save,
-#viewcode div.bottom button.saveas {
+*html #viewcode .bottom button { padding: 0 .5em; }
+*+html #viewcode .bottom button { padding: 0 .5em; }
+#viewcode .bottom button.revert, #viewcode .bottom button.save,
+#viewcode .bottom button.saveas {
float: right; margin: 0 0 0 1em;
}
-#viewcode div.bottom button.save { font-weight: bold; }
-#viewcode.expanded label { background-position: 0 -96px; }
-#viewcode.expanded textarea, #viewcode.expanded div.bottom { display: block; }
+#viewcode .bottom button.save { font-weight: bold; }
+#viewcode .grippie { background-position: 49% 50%; }
+#viewcode.expanded .top span { background-position: 0 -96px; }
+#viewcode.expanded .code, #viewcode.expanded .bottom { display: block; }
/* Database table */