summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Lenz <cmlenz@apache.org>2009-01-12 21:06:35 +0000
committerChristopher Lenz <cmlenz@apache.org>2009-01-12 21:06:35 +0000
commita58246859370c52b5209fe94a043bdcc7f8b7001 (patch)
tree9cdc1bb00a2b007a2b1bd057a35777532b4b995d
parentd51618067f7d2fcb8fa751ddb89e4c9693d0b52c (diff)
Add syntax highlighting of JSON code in Futon.
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@733897 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--share/Makefile.am2
-rw-r--r--share/www/config.html1
-rw-r--r--share/www/couch_tests.html1
-rw-r--r--share/www/database.html2
-rw-r--r--share/www/document.html4
-rw-r--r--share/www/index.html2
-rw-r--r--share/www/replicator.html1
-rw-r--r--share/www/script/browse.js30
-rw-r--r--share/www/script/futon.format.js118
-rw-r--r--share/www/script/futon.js2
-rw-r--r--share/www/script/jquery.cookies.js2
-rw-r--r--share/www/script/jquery.couch.js2
-rw-r--r--share/www/script/pprint.js74
-rw-r--r--share/www/style/layout.css26
14 files changed, 157 insertions, 110 deletions
diff --git a/share/Makefile.am b/share/Makefile.am
index fa7545d2..b78fbb7a 100644
--- a/share/Makefile.am
+++ b/share/Makefile.am
@@ -59,6 +59,7 @@ nobase_dist_localdata_DATA = \
www/script/couch_tests.js \
www/script/couch_test_runner.js \
www/script/futon.js \
+ www/script/futon.format.js \
www/script/jquery.js \
www/script/jquery.cookies.js \
www/script/jquery.couch.js \
@@ -67,5 +68,4 @@ nobase_dist_localdata_DATA = \
www/script/jquery.resizer.js \
www/script/jquery.suggest.js \
www/script/json2.js \
- www/script/pprint.js \
www/style/layout.css
diff --git a/share/www/config.html b/share/www/config.html
index f9b95c1a..6830d26c 100644
--- a/share/www/config.html
+++ b/share/www/config.html
@@ -23,7 +23,6 @@ specific language governing permissions and limitations under the License.
<script src="script/jquery.cookies.js?0.9.0"></script>
<script src="script/jquery.couch.js?0.9.0"></script>
<script src="script/futon.js?0.9.0"></script>
- <script src="script/pprint.js?0.9.0"></script>
<script>
$(document).ready(function() {
$(document.body).addClass("loading");
diff --git a/share/www/couch_tests.html b/share/www/couch_tests.html
index bab4912d..d4fba447 100644
--- a/share/www/couch_tests.html
+++ b/share/www/couch_tests.html
@@ -24,7 +24,6 @@ specific language governing permissions and limitations under the License.
<script src="script/jquery.couch.js?0.9.0"></script>
<script src="script/couch.js?0.9.0"></script>
<script src="script/futon.js?0.9.0"></script>
- <script src="script/pprint.js?0.9.0"></script>
<script src="script/couch_test_runner.js"></script>
<script>
$(function() {
diff --git a/share/www/database.html b/share/www/database.html
index c627e21f..02886ef4 100644
--- a/share/www/database.html
+++ b/share/www/database.html
@@ -27,7 +27,7 @@ specific language governing permissions and limitations under the License.
<script src="script/jquery.suggest.js?0.9.0"></script>
<script src="script/futon.js?0.9.0"></script>
<script src="script/browse.js?0.9.0"></script>
- <script src="script/pprint.js?0.9.0"></script>
+ <script src="script/futon.format.js?0.9.0"></script>
<script>
var page = new CouchDatabasePage();
diff --git a/share/www/document.html b/share/www/document.html
index 8308d9d9..a6a4821c 100644
--- a/share/www/document.html
+++ b/share/www/document.html
@@ -27,7 +27,7 @@ specific language governing permissions and limitations under the License.
<script src="script/jquery.resizer.js?0.9.0"></script>
<script src="script/futon.js?0.9.0"></script>
<script src="script/browse.js?0.9.0"></script>
- <script src="script/pprint.js?0.9.0"></script>
+ <script src="script/futon.format.js?0.9.0"></script>
<script>
var page = new CouchDocumentPage();
@@ -59,7 +59,7 @@ specific language governing permissions and limitations under the License.
$("#fields thead th:first").text("Source").attr("colspan", 2).next().hide();
$("#fields tbody.content").hide();
$("#fields tbody.source").find("td").each(function() {
- $(this).html($("<code></code>").text(prettyPrintJSON(page.doc)));
+ $(this).html($("<pre></pre>").html($.futon.formatJSON(page.doc, {html: true})));
}).end().show();
});
diff --git a/share/www/index.html b/share/www/index.html
index 37df0960..22f2892c 100644
--- a/share/www/index.html
+++ b/share/www/index.html
@@ -25,7 +25,7 @@ specific language governing permissions and limitations under the License.
<script src="script/jquery.dialog.js?0.9.0"></script>
<script src="script/futon.js?0.9.0"></script>
<script src="script/browse.js?0.9.0"></script>
- <script src="script/pprint.js?0.9.0"></script>
+ <script src="script/futon.format.js?0.9.0"></script>
<script>
var page = new CouchIndexPage();
$(document).ready(function() {
diff --git a/share/www/replicator.html b/share/www/replicator.html
index 2637cc1b..e873f141 100644
--- a/share/www/replicator.html
+++ b/share/www/replicator.html
@@ -23,7 +23,6 @@ specific language governing permissions and limitations under the License.
<script src="script/jquery.cookies.js?0.9.0"></script>
<script src="script/jquery.couch.js?0.9.0"></script>
<script src="script/futon.js?0.9.0"></script>
- <script src="script/pprint.js?0.9.0"></script>
<script>
$(document).ready(function() {
$("fieldset input[type=radio]").click(function() {
diff --git a/share/www/script/browse.js b/share/www/script/browse.js
index 5ee3e3cd..c27f48ef 100644
--- a/share/www/script/browse.js
+++ b/share/www/script/browse.js
@@ -59,7 +59,7 @@ function CouchIndexPage() {
$.couch.db(dbName).info({
success: function(info) {
$("#databases tbody.content tr:eq(" + idx + ")")
- .find("td.size").text(prettyPrintSize(info.disk_size)).end()
+ .find("td.size").text($.futon.formatSize(info.disk_size)).end()
.find("td.count").text(info.doc_count).end()
.find("td.seq").text(info.update_seq);
if (idx == dbsOnPage.length - 1) {
@@ -457,22 +457,28 @@ function CouchDatabasePage() {
for (var i = 0; i < resp.rows.length; i++) {
var row = resp.rows[i];
var tr = $("<tr></tr>");
- var key = row.key;
+ var key = "null";
+ if (row.key !== null) {
+ key = $.futon.formatJSON(row.key, {indent: 0, linesep: ""});
+ }
if (row.id) {
$("<td class='key'><a href='document.html?" + encodeURIComponent(db.name) +
"/" + encodeDocId(row.id) + "'><strong></strong><br>" +
"<span class='docid'>ID:&nbsp;" + row.id + "</span></a></td>")
- .find("strong").text(key !== null ? prettyPrintJSON(key, 0, "") : "null").end()
+ .find("strong").text(key).end()
.appendTo(tr);
} else {
$("<td class='key'><strong></strong></td>")
- .find("strong").text(key !== null ? prettyPrintJSON(key, 0, "") : "null").end()
+ .find("strong").text(key).end()
.appendTo(tr);
}
- var value = row.value;
- $("<td class='value'></td>").text(
- value !== null ? prettyPrintJSON(value, 0, "") : "null"
- ).appendTo(tr).dblclick(function() {
+ var value = "null";
+ if (row.value !== null) {
+ value = $.futon.formatJSON(row.value, {
+ html: true, indent: 0, linesep: "", quoteKeys: false
+ });
+ }
+ $("<td class='value'><div></div></td>").find("div").html(value).end().appendTo(tr).dblclick(function() {
location.href = this.previousSibling.firstChild.href;
});
tr.appendTo("#documents tbody.content");
@@ -736,7 +742,7 @@ function CouchDocumentPage() {
_initValue(value);
}
}
- $("#fields tbody tr").removeClass("odd").filter(":odd").addClass("odd");
+ $("#fields tbody.content tr").removeClass("odd").filter(":odd").addClass("odd");
return row;
}
@@ -838,7 +844,7 @@ function CouchDocumentPage() {
cancelChange();
}).appendTo(tools);
tools.appendTo(td);
- input.val(prettyPrintJSON(value)).appendTo(td);
+ input.val($.futon.formatJSON(value)).appendTo(td);
input.each(function() { this.focus(); this.select(); });
if (needsTextarea) input.makeResizable({vertical: true});
}
@@ -849,7 +855,7 @@ function CouchDocumentPage() {
delete doc[fieldName];
row.remove();
page.isDirty = true;
- $("#fields tbody tr").removeClass("odd").filter(":odd").addClass("odd");
+ $("#fields tbody.content tr").removeClass("odd").filter(":odd").addClass("odd");
}).prependTo(row.find("th"));
}
}
@@ -894,7 +900,7 @@ function CouchDocumentPage() {
$("<a href='' title='Download file' target='_top'></a>").text(name)
.attr("href", attachmentHref)
.wrapInner("<tt></tt>").appendTo(li);
- $("<span>()</span>").text("" + prettyPrintSize(attachment.length) +
+ $("<span>()</span>").text("" + $.futon.formatSize(attachment.length) +
", " + attachment.content_type).addClass("info").appendTo(li);
if (name == "tests.js") {
li.find('span.info').append(', <a href="/_utils/couch_tests.html?'
diff --git a/share/www/script/futon.format.js b/share/www/script/futon.format.js
new file mode 100644
index 00000000..b8870a94
--- /dev/null
+++ b/share/www/script/futon.format.js
@@ -0,0 +1,118 @@
+// 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.
+
+(function($) {
+ $.futon = $.futon || {};
+ $.extend($.futon, {
+
+ // JSON pretty printing
+ formatJSON: function(val, options) {
+ options = options || {};
+ if (options.indent === undefined) {
+ options.indent = 4;
+ }
+ options.indent = options.indent !== undefined ? options.indent : 4;
+ options.linesep = options.linesep !== undefined ? options.linesep : "\n";
+ options.quoteKeys = options.quoteKeys !== undefined ? options.quoteKeys : true;
+ var itemsep = options.linesep.length ? "," + options.linesep : ", ";
+
+ function escape(string) {
+ return string.replace(/&/g, "&amp;")
+ .replace(/</g, "&lt;")
+ .replace(/>/g, "&gt;");
+ }
+
+ function format(val, depth) {
+ var tab = [];
+ for (var i = 0; i < options.indent * depth; i++) tab.push("");
+ tab = tab.join(" ");
+
+ var type = typeof val;
+ switch (type) {
+ case "boolean":
+ case "number":
+ case "string":
+ var retval = JSON.stringify(val);
+ if (options.html) {
+ retval = "<code class='" + type + "'>" + escape(retval) + "</code>";
+ }
+ return retval;
+
+ case "object": {
+ if (val === null) {
+ if (options.html) {
+ return "<code class='null'>null</code>";
+ }
+ return "null";
+ }
+ if (val.constructor == Date) {
+ return JSON.stringify(val);
+ }
+
+ var buf = [];
+
+ if (val.constructor == Array) {
+ buf.push("[");
+ for (var index = 0; index < val.length; index++) {
+ buf.push(index > 0 ? itemsep : options.linesep);
+ buf.push(tab, format(val[index], depth + 1));
+ }
+ if (index >= 0) buf.push(options.linesep, tab.substr(options.indent));
+ buf.push("]");
+
+ } else {
+ buf.push("{");
+ var index = 0;
+ for (var key in val) {
+ if (!val.hasOwnProperty(key)) continue;
+ buf.push(index > 0 ? itemsep : options.linesep);
+ var keyDisplay = options.quoteKeys ? JSON.stringify(key) : key;
+ if (options.html) {
+ if (options.quoteKeys) {
+ keyDisplay = keyDisplay.substr(1, keyDisplay.length - 2);
+ }
+ keyDisplay = "<code class='key'>" + escape(keyDisplay) + "</code>";
+ if (options.quoteKeys) {
+ keyDisplay = '"' + keyDisplay + '"';
+ }
+ }
+ buf.push(tab, keyDisplay,
+ ": ", format(val[key], depth + 1));
+ index++;
+ }
+ if (index >= 0) buf.push(options.linesep, tab.substr(options.indent));
+ buf.push("}");
+ }
+
+ return buf.join("");
+ }
+ }
+ }
+
+ return format(val, 1);
+ },
+
+ // File size pretty printing
+ formatSize: function(size) {
+ var jump = 512;
+ if (size < jump) return size + " bytes";
+ var units = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
+ var i = 0;
+ while (size >= jump && i < units.length) {
+ i += 1;
+ size /= 1024
+ }
+ return size.toFixed(1) + ' ' + units[i - 1];
+ }
+
+ });
+})(jQuery);
diff --git a/share/www/script/futon.js b/share/www/script/futon.js
index bf148189..493637ec 100644
--- a/share/www/script/futon.js
+++ b/share/www/script/futon.js
@@ -103,7 +103,7 @@
}
$.futon = $.futon || {};
- $.fn.extend($.futon, {
+ $.extend($.futon, {
navigation: new Navigation()
});
diff --git a/share/www/script/jquery.cookies.js b/share/www/script/jquery.cookies.js
index 77c5e0a9..1a0f012c 100644
--- a/share/www/script/jquery.cookies.js
+++ b/share/www/script/jquery.cookies.js
@@ -12,7 +12,7 @@
(function($) {
$.cookies = $.cookies || {}
- $.fn.extend($.cookies, {
+ $.extend($.cookies, {
/* Return the value of a cookie. */
get: function(name, defaultValue) {
diff --git a/share/www/script/jquery.couch.js b/share/www/script/jquery.couch.js
index a36387a0..915918d8 100644
--- a/share/www/script/jquery.couch.js
+++ b/share/www/script/jquery.couch.js
@@ -12,7 +12,7 @@
(function($) {
$.couch = $.couch || {};
- $.fn.extend($.couch, {
+ $.extend($.couch, {
allDbs: function(options) {
options = options || {};
diff --git a/share/www/script/pprint.js b/share/www/script/pprint.js
deleted file mode 100644
index 1499a128..00000000
--- a/share/www/script/pprint.js
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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.
-
-// JSON pretty printing
-
-function prettyPrintJSON(val, indent, linesep, depth) {
- indent = indent != null ? indent : 4;
- linesep = linesep != null ? linesep : "\n";
- depth = depth != null ? depth : 1;
- var propsep = linesep.length ? "," + linesep : ", ";
- var tab = [];
- for (var i = 0; i < indent * depth; i++) tab.push("");
- tab = tab.join(" ");
- switch (typeof val) {
- case "boolean":
- case "number":
- case "string":
- return JSON.stringify(val);
- case "object": {
- if (val === null) return "null";
- if (val.constructor == Date) return JSON.stringify(val);
- var buf = [];
- if (val.constructor == Array) {
- buf.push("[");
- for (var index = 0; index < val.length; index++) {
- buf.push(index > 0 ? propsep : linesep);
- buf.push(
- tab, prettyPrintJSON(val[index], indent, linesep, depth + 1)
- );
- }
- if (index >= 0) buf.push(linesep, tab.substr(indent));
- buf.push("]");
- } else {
- buf.push("{");
- var index = 0;
- for (var key in val) {
- if (!val.hasOwnProperty(key)) continue;
- buf.push(index > 0 ? propsep : linesep);
- buf.push(
- tab, JSON.stringify(key), ": ",
- prettyPrintJSON(val[key], indent, linesep, depth + 1)
- );
- index++;
- }
- if (index >= 0) buf.push(linesep, tab.substr(indent));
- buf.push("}");
- }
- return buf.join("");
- }
- }
-}
-
-// File size pretty printing
-
-function prettyPrintSize(size) {
- var jump = 512;
- if (size < jump) return size + " bytes";
- var units = ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
- var i = 0;
- while (size >= jump && i < units.length) {
- i += 1;
- size /= 1024
- }
- return size.toFixed(1) + ' ' + units[i - 1];
-}
diff --git a/share/www/style/layout.css b/share/www/style/layout.css
index a3c771e2..20aaaf82 100644
--- a/share/www/style/layout.css
+++ b/share/www/style/layout.css
@@ -43,7 +43,11 @@ body.loading h1 strong {
hr { border: 1px solid #999; border-width: 1px 0 0; }
dl dt { font-weight: bold; }
-code, tt { font-family: "DejaVu Sans Mono",Monaco,monospace; }
+code, tt, pre { font-family: "DejaVu Sans Mono",Monaco,monospace; }
+code.key { color: #333; font-weight: bold; }
+code.string { color: #393; }
+code.number, code.boolean { color: #339; }
+code.null { color: #666; }
button { font-size: 100%; -webkit-appearance: square-button; }
input, select, textarea { background: #fff; border: 1px solid;
@@ -321,7 +325,7 @@ ul.suggest-dropdown li.selected { cursor: pointer; background: Highlight;
/* Documents table */
#documents thead th { width: 50%; }
-#documents tbody.content td { color: #666;
+#documents tbody.content td { color: #999;
font: normal 11px "DejaVu Sans Mono",Monaco,monospace;
}
#documents tbody.content td.key { color: #333; }
@@ -355,19 +359,15 @@ ul.suggest-dropdown li.selected { cursor: pointer; background: Highlight;
background-image: url(../image/delete-mini.png);
}
#fields tbody.content th b { display: block; padding: 2px; }
-#fields tbody.content td { padding-left: 14px; padding-right: 48px; }
-#fields tbody.content td code { color: #999; display: block; font-size: 11px;
- padding: 2px;
-}
-#fields tbody.content td code.string { color: #393; }
-#fields tbody.content td code.number, #fields tbody.content td code.boolean {
- color: #339;
+#fields tbody.content td { color: #999; padding-left: 14px;
+ padding-right: 48px;
}
+#fields tbody.content td code { display: block; font-size: 11px; padding: 2px; }
#fields tbody.content td dl { margin: 0; padding: 0; }
#fields tbody.content td dt {
background: transparent url(../image/toggle-collapse.gif) 0 3px no-repeat;
- clear: left; cursor: pointer; line-height: 1em; margin-left: -12px;
- padding-left: 14px;
+ clear: left; color: #333; cursor: pointer; line-height: 1em;
+ margin-left: -12px; padding-left: 14px;
}
#fields tbody.content td dd { line-height: 1em; margin: 0;
padding: 0 0 0 1em;
@@ -431,8 +431,8 @@ ul.suggest-dropdown li.selected { cursor: pointer; background: Highlight;
#fields tbody.content td ul.attachments li button.delete {
background-image: url(../image/delete-mini.png);
}
-#fields tbody.source td code { display: block; overflow: auto;
- white-space: pre-wrap; width: 100%;
+#fields tbody.source td pre { color: #999; font-size: 11px; line-height: 1.6em;
+ margin: 0; overflow: auto; white-space: pre-wrap; width: 100%;
}
/* Test suite */