summaryrefslogtreecommitdiff
path: root/share
diff options
context:
space:
mode:
authorChristopher Lenz <cmlenz@apache.org>2009-01-14 21:59:48 +0000
committerChristopher Lenz <cmlenz@apache.org>2009-01-14 21:59:48 +0000
commit892590e3a20c617b30ec8f89b0a895b753651e57 (patch)
treeebf61f745040329f32b56dcf5fc4678e6fa46b10 /share
parentfe135f33f6c817b96ff0f59f93c1040a087491e8 (diff)
Add view language selection to Futon, based on patch by Brian Palmer. Closes COUCHDB-202.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@734528 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'share')
-rw-r--r--share/www/database.html7
-rw-r--r--share/www/script/futon.browse.js95
-rw-r--r--share/www/script/jquery.resizer.js2
-rw-r--r--share/www/style/layout.css6
4 files changed, 92 insertions, 18 deletions
diff --git a/share/www/database.html b/share/www/database.html
index 3b968487..0d508794 100644
--- a/share/www/database.html
+++ b/share/www/database.html
@@ -72,8 +72,6 @@ specific language governing permissions and limitations under the License.
});
// Restore preferences/state from cookies
- var query = $.cookies.get(page.db.name + ".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");
@@ -137,9 +135,7 @@ specific language governing permissions and limitations under the License.
<table summary="View functions" cellspacing="0"><tr>
<td class="code map">
<label for="viewcode_map">Map Function:</label>
- <textarea id="viewcode_map" class="map" rows="5" cols="20" spellcheck="false" wrap="off">function(doc) {
- emit(null, doc);
-}</textarea>
+ <textarea id="viewcode_map" class="map" rows="5" cols="20" spellcheck="false" wrap="off"></textarea>
</td>
<td class="splitter"></td>
<td class="code reduce">
@@ -152,6 +148,7 @@ specific language governing permissions and limitations under the License.
<button class="saveas" type="button">Save As…</button>
<button class="revert" type="button" disabled>Revert</button>
<button class="run" type="button">Run</button>
+ <label>Language: <select id="language"></select></label>
</div>
</div>
diff --git a/share/www/script/futon.browse.js b/share/www/script/futon.browse.js
index 832ac1b7..7528ee6e 100644
--- a/share/www/script/futon.browse.js
+++ b/share/www/script/futon.browse.js
@@ -117,11 +117,18 @@
this.dbName = dbName;
this.viewName = viewName;
+ this.viewLanguage = "javascript";
this.db = db;
this.isDirty = false;
this.isTempView = viewName == "_slow_view";
page = this;
+ var templates = {
+ javascript: "function(doc) {\n emit(null, doc);\n}",
+ python: "def fun(doc):\n yield None, doc",
+ ruby: "{|doc|\n emit(nil, doc);\n}",
+ }
+
this.addDocument = function() {
$.showDialog("dialog/_create_document.html", {
submit: function(data, callback) {
@@ -178,7 +185,8 @@
dirtyTimeout = setTimeout(function() {
var buttons = $("#viewcode button.save, #viewcode button.revert");
page.isDirty = ($("#viewcode_map").val() != page.storedViewCode.map)
- || ($("#viewcode_reduce").val() != (page.storedViewCode.reduce || ""));
+ || ($("#viewcode_reduce").val() != (page.storedViewCode.reduce || ""))
+ || page.viewLanguage != page.storedViewLanguage;
if (page.isDirty) {
buttons.removeAttr("disabled");
} else {
@@ -195,13 +203,48 @@
.bind("keyup", updateDirtyState)
.bind("textInput", updateDirtyState);
}
+ $("#language").change(updateDirtyState);
});
} else if (viewName == "_slow_view") {
+ page.viewLanguage = $.cookies.get(db.name + ".language", page.viewLanguage);
page.updateViewEditor(
- $.cookies.get(db.name + ".map"),
+ $.cookies.get(db.name + ".map", templates[page.viewLanguage]),
$.cookies.get(db.name + ".reduce", "")
);
}
+ page.populateLanguagesMenu();
+ }
+
+ // Populate the languages dropdown, and listen to selection changes
+ this.populateLanguagesMenu = function() {
+ $.couch.config({
+ success: function(resp) {
+ var select = $("#language");
+ for (var language in resp) {
+ var option = $(document.createElement("option"))
+ .attr("value", language).text(language)
+ .appendTo(select);
+ }
+ if (select[0].options.length == 1) {
+ select[0].disabled = true;
+ } else {
+ select.val(page.viewLanguage);
+ select.change(function() {
+ var language = $("#language").val();
+ if (language != page.viewLanguage) {
+ var mapFun = $("#viewcode_map").val();
+ if (mapFun == "" || mapFun == templates[page.viewLanguage]) {
+ // no edits made, so change to the new default
+ $("#viewcode_map").val(templates[language]);
+ }
+ page.viewLanguage = language;
+ $("#viewcode_map")[0].focus();
+ }
+ return false;
+ });
+ }
+ }
+ }, "query_servers");
}
this.populateViewsMenu = function() {
@@ -212,7 +255,6 @@
for (var i = 0; i < resp.rows.length; i++) {
db.openDoc(resp.rows[i].id, {
success: function(doc) {
- var optGroup = $("<optgroup></optgroup>").attr("label", doc._id.substr(8));
var optGroup = $(document.createElement("optgroup"))
.attr("label", doc._id.substr(8));
for (var name in doc.views) {
@@ -248,22 +290,27 @@
error: function(status, error, reason) {
if (status == 404) {
$.cookies.remove(dbName + ".view");
- location.reload();
+ location.href = "database.html?" + encodeURIComponent(db.name);
}
},
success: function(resp) {
var viewCode = resp.views[localViewName];
+ page.viewLanguage = resp.language || "javascript";
+ $("#language").val(page.viewLanguage);
page.updateViewEditor(viewCode.map, viewCode.reduce || "");
$("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled");
page.storedViewCode = viewCode;
+ page.storedViewLanguage = page.viewLanguage;
if (callback) callback();
}
});
} else {
- $("#viewcode_map").val(page.storedViewCode.map);
- $("#viewcode_reduce").val(page.storedViewCode.reduce || "");
- page.isDirty = false;
+ page.updateViewEditor(page.storedViewCode.map,
+ page.storedViewCode.reduce || "");
+ page.viewLanguage = page.storedViewLanguage;
+ $("#language").val(page.viewLanguage);
$("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled");
+ page.isDirty = false;
if (callback) callback();
}
}
@@ -332,7 +379,23 @@
};
var docId = ["_design", data.docid].join("/");
function save(doc) {
- if (!doc) doc = {_id: docId, language: "javascript"};
+ if (!doc) {
+ doc = {_id: docId, language: page.viewLanguage};
+ } else {
+ var numViews = 0;
+ for (var viewName in (doc.views || {})) {
+ if (viewName != data.name) numViews++;
+ }
+ if (numViews > 0 && page.viewLanguage != doc.language) {
+ callback({
+ docid: "Cannot save to " + data.docid +
+ " because its language is \"" + doc.language +
+ "\", not \"" + page.viewLanguage + "\"."
+ });
+ return;
+ }
+ doc.language = page.viewLanguage;
+ }
if (doc.views === undefined) doc.views = {};
doc.views[data.name] = viewCode;
db.saveDoc(doc, {
@@ -366,6 +429,17 @@
$(document.body).addClass("loading");
db.openDoc(["_design", designDocId].join("/"), {
success: function(doc) {
+ var numViews = 0;
+ for (var viewName in (doc.views || {})) {
+ if (viewName != localViewName) numViews++;
+ }
+ if (numViews > 0 && page.viewLanguage != doc.language) {
+ alert("Cannot save view because the design document language " +
+ "is \"" + doc.language + "\", not \"" +
+ page.viewLanguage + "\".");
+ return;
+ }
+ doc.language = page.viewLanguage;
var viewDef = doc.views[localViewName];
viewDef.map = $("#viewcode_map").val();
viewDef.reduce = $("#viewcode_reduce").val() || undefined;
@@ -524,7 +598,8 @@
} else {
$.cookies.remove(db.name + ".reduce");
}
- db.query(mapFun, reduceFun, null, options);
+ $.cookies.set(db.name + ".language", page.viewLanguage);
+ db.query(mapFun, reduceFun, page.viewLanguage, options);
} else if (viewName == "_design_docs") {
options.startkey = options.descending ? "_design0" : "_design";
options.endkey = options.descending ? "_design" : "_design0";
@@ -534,7 +609,7 @@
var currentMapCode = $("#viewcode_map").val();
var currentReduceCode = $("#viewcode_reduce").val() || null;
if (page.isDirty) {
- db.query(currentMapCode, currentReduceCode, null, options);
+ db.query(currentMapCode, currentReduceCode, page.viewLanguage, options);
} else {
db.view(viewName.substr(8), options);
}
diff --git a/share/www/script/jquery.resizer.js b/share/www/script/jquery.resizer.js
index 9e0a291b..45c6c39a 100644
--- a/share/www/script/jquery.resizer.js
+++ b/share/www/script/jquery.resizer.js
@@ -76,7 +76,7 @@
$(document).unbind("mousemove");
document.onselectstart = null; // for IE
});
- return false;
+ return true;
});
});
}
diff --git a/share/www/style/layout.css b/share/www/style/layout.css
index 0691a1ad..2df42734 100644
--- a/share/www/style/layout.css
+++ b/share/www/style/layout.css
@@ -54,6 +54,7 @@ code.number, code.boolean { color: #339; }
code.null { color: #666; }
button { font-size: 100%; -webkit-appearance: square-button; }
+button[disabled] { color: #999; }
input, select, textarea { background: #fff; border: 1px solid;
border-color: #999 #ddd #ddd #999; margin: 0; padding: 1px;
}
@@ -309,8 +310,8 @@ ul.suggest-dropdown li.selected { cursor: pointer; background: Highlight;
white-space: nowrap;
}
#viewcode .code textarea { border: none; border-top: 1px solid #ccc;
- color: #333; margin: 0; min-height: 50px; padding: .4em 0 0; resize: none;
- width: 100%; overflow: auto;
+ color: #333; font-size: 11px; margin: 0; min-height: 50px; padding: .4em 0 0;
+ resize: none; width: 100%; overflow: auto;
}
#viewcode .code textarea:focus { background: #e9f4ff; }
#viewcode .bottom { border-bottom: none; clear: left; padding: 1px 3px; }
@@ -324,6 +325,7 @@ ul.suggest-dropdown li.selected { cursor: pointer; background: Highlight;
float: right; margin: 0 0 0 1em;
}
#viewcode .bottom button.save { font-weight: bold; }
+#viewcode .bottom label { color: #666; font-size: 90%; }
#viewcode .grippie { background-position: 50% 50%; }
#viewcode.collapsed { background: #e9e9e9; }
#viewcode.collapsed .top { border-bottom: none; }