couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject [3/7] Fauxton: move modules to addons
Date Mon, 06 Jan 2014 14:16:32 GMT
http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/layout.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/layout.js b/src/fauxton/app/addons/fauxton/layout.js
new file mode 100644
index 0000000..1422241
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/layout.js
@@ -0,0 +1,98 @@
+// 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.
+
+define(["backbone"],
+
+function(Backbone) {
+
+  // A wrapper of the main Backbone.layoutmanager
+  // Allows the main layout of the page to be changed by any plugin.
+  // Exposes the different views:
+  //    navBar -> the top navigation bar
+  //    dashboardContent -> Main display view
+  //    breadcrumbs -> Breadcrumbs navigation section
+  var Layout = function (navBar, apiBar) {
+    this.navBar = navBar;
+    this.apiBar = apiBar;
+
+    this.layout = new Backbone.Layout({
+      template: "templates/layouts/with_sidebar",
+
+      views: {
+        "#primary-navbar": this.navBar,
+        "#api-navbar": this.apiBar
+      },
+      afterRender: function(){
+
+      }
+    });
+
+    this.layoutViews = {};
+    //this.hooks = {};
+
+    this.el = this.layout.el;
+  };
+
+  // creatings the dashboard object same way backbone does
+  _.extend(Layout.prototype, {
+    render: function () {
+      return this.layout.render();
+    },
+
+    setTemplate: function(template) {
+      if (template.prefix){
+        this.layout.template = template.prefix + template.name;
+      } else{
+        this.layout.template = "templates/layouts/" + template;
+      }
+      // If we're changing layouts all bets are off, so kill off all the
+      // existing views in the layout.
+      _.each(this.layoutViews, function(view){view.remove();});
+      this.layoutViews = {};
+      this.render();
+    },
+
+    setTabs: function(view){
+      // TODO: Not sure I like this - seems fragile/repetitive
+      this.tabs = this.layout.setView("#tabs", view);
+      this.tabs.render();
+    },
+
+    setBreadcrumbs: function(view) {
+      this.breadcrumbs = this.layout.setView("#breadcrumbs", view);
+      this.breadcrumbs.render();
+    },
+
+    clearBreadcrumbs: function () {
+      if (!this.breadcrumbs) {return ;}
+
+      this.breadcrumbs.remove();
+    },
+
+    setView: function(selector, view) {
+      this.layoutViews[selector] = this.layout.setView(selector, view, false);
+    },
+
+    renderView: function(selector) {
+      var view = this.layoutViews[selector];
+      if (!view) {
+        return false;
+      } else {
+        return view.render();
+      }
+    }
+
+  });
+
+  return Layout;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/api_bar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/api_bar.html b/src/fauxton/app/addons/fauxton/templates/api_bar.html
new file mode 100644
index 0000000..1f03a2c
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/api_bar.html
@@ -0,0 +1,30 @@
+<!--
+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.
+-->
+
+<button class="button api-url-btn">
+  API URL 
+  <span class="fonticon-plus icon"></span>
+</button>
+<div class="api-navbar" style="display: none">
+    <div class="input-prepend input-append">
+      <span class="add-on">
+        API reference
+        <a href="<%=getDocUrl(documentation)%>" target="_blank">
+          <i class="icon-question-sign"></i>
+        </a>
+      </span>
+      <input type="text" class="input-xxlarge" value="<%= endpoint %>">
+      <a href="<%= endpoint %>" target="_blank" class="btn">Show me</a>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/breadcrumbs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/breadcrumbs.html b/src/fauxton/app/addons/fauxton/templates/breadcrumbs.html
new file mode 100644
index 0000000..026db89
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/breadcrumbs.html
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+
+<ul class="breadcrumb">
+  <% _.each(_.initial(crumbs), function(crumb) { %>
+    <li>
+      <a href="#<%= crumb.link %>"><%= crumb.name %></a>
+      <span class="divider fonticon fonticon-carrot"> </span>
+    </li>
+  <% }); %>
+  <% var last = _.last(crumbs) || {name: ''} %>
+  <li class="active"><%= last.name %></li>
+</ul>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/footer.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/footer.html b/src/fauxton/app/addons/fauxton/templates/footer.html
new file mode 100644
index 0000000..593c11f
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/footer.html
@@ -0,0 +1,15 @@
+<!--
+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.
+-->
+
+<p>Fauxton on <a href="http://couchdb.apache.org/">Apache CouchDB</a> <%=version%></p>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/index_pagination.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/index_pagination.html b/src/fauxton/app/addons/fauxton/templates/index_pagination.html
new file mode 100644
index 0000000..f445377
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/index_pagination.html
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+
+<div class="pagination pagination-centered">
+  <ul>
+    <li <% if (!canShowPreviousfn()) {%> class="disabled" <% } %>>
+       <a id="previous" href="#"> Previous </a>
+     </li>
+     <li <% if (!canShowNextfn()) {%> class="disabled" <% } %>>
+       <a id="next" href="#"> Next </a></li>
+  </ul>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/nav_bar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/nav_bar.html b/src/fauxton/app/addons/fauxton/templates/nav_bar.html
new file mode 100644
index 0000000..da030d6
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/nav_bar.html
@@ -0,0 +1,75 @@
+<!--
+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.
+-->
+
+<div class="brand">
+  <div class="burger">
+    <div><!-- * --></div>
+    <div><!-- * --></div>
+    <div><!-- * --></div>
+  </div>
+  <div class="icon">Apache Fauxton</div>
+</div>
+
+<nav id="main_navigation">
+  <ul id="nav-links" class="nav pull-right">
+    <% _.each(navLinks, function(link) { %>
+    <% if (link.view) {return;}  %>
+        <li data-nav-name= "<%= link.title %>" >
+          <a href="<%= link.href %>">
+            <span class="<%= link.icon %> fonticon"></span>
+            <%= link.title %>
+          </a>
+        </li>
+    <% }); %>
+  </ul>
+
+  <div id="footer-links">
+
+    <ul id="bottom-nav-links" class="nav">
+        <li data-nav-name= "Documentation">
+            <a href="<%=getDocUrl('docs')%>" target="_blank">
+              <span class="fonticon-bookmark fonticon"></span>
+                Documentation
+            </a>
+        </li>
+
+
+      <% _.each(bottomNavLinks, function(link) { %>
+      <% if (link.view) {return;}  %>
+        <li data-nav-name= "<%= link.title %>">
+            <a href="<%= link.href %>">
+              <span class="<%= link.icon %> fonticon"></span>
+              <%= link.title %>
+            </a>
+        </li>
+      <% }); %>
+    </ul>
+
+    <ul id="footer-nav-links" class="nav">
+      <% _.each(footerNavLinks, function(link) { %>
+      <% if (link.view) {return;}  %>
+        <li data-nav-name= "<%= link.title %>">
+            <a href="<%= link.href %>">
+              <span class="<%= link.icon %> fonticon"></span>
+              <%= link.title %>
+            </a>
+        </li>
+      <% }); %>
+    </ul>
+
+  </div>
+</nav>
+
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/notification.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/notification.html b/src/fauxton/app/addons/fauxton/templates/notification.html
new file mode 100644
index 0000000..ca8a903
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/notification.html
@@ -0,0 +1,18 @@
+<!--
+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.
+-->
+
+<div class="alert alert-<%= type %>">
+  <button type="button" class="close" data-dismiss="alert">×</button>
+  <%= msg %>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/fauxton/templates/pagination.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/templates/pagination.html b/src/fauxton/app/addons/fauxton/templates/pagination.html
new file mode 100644
index 0000000..19dfc8c
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/templates/pagination.html
@@ -0,0 +1,31 @@
+<!--
+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.
+-->
+
+<div class="pagination pagination-centered">
+  <ul>
+    <% if (page > 1) { %>
+    <li> <a href="<%= urlFun(page-1) %>">&laquo;</a></li>
+    <% } else { %>
+      <li class="disabled"> <a href="<%= urlFun(page) %>">&laquo;</a></li>
+    <% } %>
+    <% _.each(_.range(1, totalPages+1), function(i) { %>
+      <li <% if (page == i) { %>class="active"<% } %>> <a href="<%= urlFun(i) %>"><%= i %></a></li>
+    <% }) %>
+    <% if (page < totalPages) { %>
+      <li><a href="<%= urlFun(page+1) %>">&raquo;</a></li>
+    <% } else { %>
+      <li class="disabled"> <a href="<%= urlFun(page) %>">&raquo;</a></li>
+    <% } %>
+  </ul>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/permissions/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/permissions/routes.js b/src/fauxton/app/addons/permissions/routes.js
index 89c2bd7..0e9fa52 100644
--- a/src/fauxton/app/addons/permissions/routes.js
+++ b/src/fauxton/app/addons/permissions/routes.js
@@ -13,7 +13,7 @@
 define([
        "app",
        "api",
-       "modules/databases/base",
+       "addons/databases/base",
        "addons/permissions/views"
 ],
 function (app, FauxtonAPI, Databases, Permissions) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/pouchdb/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/pouchdb/base.js b/src/fauxton/app/addons/pouchdb/base.js
new file mode 100644
index 0000000..df6c726
--- /dev/null
+++ b/src/fauxton/app/addons/pouchdb/base.js
@@ -0,0 +1,47 @@
+/*
+ * NOTE:
+ * This temporarily uses the PouchDB map reduce implementation
+ * These files are modified locally until we make a more general version and
+ * push it back upstream.
+ */
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "addons/pouchdb/pouchdb.mapreduce.js"
+],
+
+function(app, FauxtonAPI, MapReduce) {
+  var Pouch = FauxtonAPI.addon();
+  Pouch.MapReduce = MapReduce;
+
+  Pouch.runViewQuery = function(fun, opts) {
+    /*docs = [
+      {_id: 'test_doc_1', foo: 'bar-1'},
+      {_id: 'test_doc_2', foo: 'bar-2'},
+      {_id: 'test_doc_3', foo: 'bar-3'},
+      {_id: 'test_doc_4', foo: 'bar-4'},
+      {_id: 'test_doc_5', foo: 'bar-5'},
+      {_id: 'test_doc_6', foo: 'bar-6'},
+      {_id: 'test_doc_7', foo: 'bar-7'},
+      {_id: 'test_doc_8', foo: 'bar-8'},
+      {_id: 'test_doc_9', foo: 'bar-9'},
+      {_id: 'test_doc_10', foo: 'bar-10'}
+    ];*/
+
+    var deferred = FauxtonAPI.Deferred();
+    var complete = function(resp, rows) {
+      deferred.resolve(rows);
+    };
+
+    var options = _.extend(opts, {complete: complete});
+
+    Pouch.MapReduce.query(fun, options);
+    return deferred;
+  };
+  //pdb.runViewQuery({map:function(doc) { emit(doc._id, doc.foo) }})
+  return Pouch;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/pouchdb/pouch.collate.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/pouchdb/pouch.collate.js b/src/fauxton/app/addons/pouchdb/pouch.collate.js
new file mode 100644
index 0000000..6c64410
--- /dev/null
+++ b/src/fauxton/app/addons/pouchdb/pouch.collate.js
@@ -0,0 +1,115 @@
+/*
+ * NOTE:
+ * This temporarily uses the PouchDB map reduce implementation
+ * These files are modified locally until we make a more general version and
+ * push it back upstream.
+ * Original file:
+ * https://github.com/daleharvey/pouchdb/blob/master/src/pouch.collate.js
+ */
+
+/*
+(function() {
+  // a few hacks to get things in the right place for node.js
+  if (typeof module !== 'undefined' && module.exports) {
+    module.exports = Pouch;
+  }
+*/
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "addons/pouchdb/pouch.collate.js"
+],
+
+function(app, FauxtonAPI, Collate) {
+  var Pouch = {};
+
+  Pouch.collate = function(a, b) {
+    var ai = collationIndex(a);
+    var bi = collationIndex(b);
+    if ((ai - bi) !== 0) {
+      return ai - bi;
+    }
+    if (a === null) {
+      return 0;
+    }
+    if (typeof a === 'number') {
+      return a - b;
+    }
+    if (typeof a === 'boolean') {
+      return a < b ? -1 : 1;
+    }
+    if (typeof a === 'string') {
+      return stringCollate(a, b);
+    }
+    if (Array.isArray(a)) {
+      return arrayCollate(a, b);
+    }
+    if (typeof a === 'object') {
+      return objectCollate(a, b);
+    }
+  };
+
+  var stringCollate = function(a, b) {
+    // See: https://github.com/daleharvey/pouchdb/issues/40
+    // This is incompatible with the CouchDB implementation, but its the
+    // best we can do for now
+    return (a === b) ? 0 : ((a > b) ? 1 : -1);
+  };
+
+  var objectCollate = function(a, b) {
+    var ak = Object.keys(a), bk = Object.keys(b);
+    var len = Math.min(ak.length, bk.length);
+    for (var i = 0; i < len; i++) {
+      // First sort the keys
+      var sort = Pouch.collate(ak[i], bk[i]);
+      if (sort !== 0) {
+        return sort;
+      }
+      // if the keys are equal sort the values
+      sort = Pouch.collate(a[ak[i]], b[bk[i]]);
+      if (sort !== 0) {
+        return sort;
+      }
+
+    }
+    return (ak.length === bk.length) ? 0 :
+      (ak.length > bk.length) ? 1 : -1;
+  };
+
+  var arrayCollate = function(a, b) {
+    var len = Math.min(a.length, b.length);
+    for (var i = 0; i < len; i++) {
+      var sort = Pouch.collate(a[i], b[i]);
+      if (sort !== 0) {
+        return sort;
+      }
+    }
+    return (a.length === b.length) ? 0 :
+      (a.length > b.length) ? 1 : -1;
+  };
+
+  // The collation is defined by erlangs ordered terms
+  // the atoms null, true, false come first, then numbers, strings,
+  // arrays, then objects
+  var collationIndex = function(x) {
+    var id = ['boolean', 'number', 'string', 'object'];
+    if (id.indexOf(typeof x) !== -1) {
+      if (x === null) {
+        return 1;
+      }
+      return id.indexOf(typeof x) + 2;
+    }
+    if (Array.isArray(x)) {
+      return 4.5;
+    }
+  };
+
+  return Pouch;
+
+//}).call(this);
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/pouchdb/pouchdb.mapreduce.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/pouchdb/pouchdb.mapreduce.js b/src/fauxton/app/addons/pouchdb/pouchdb.mapreduce.js
new file mode 100644
index 0000000..224a6f6
--- /dev/null
+++ b/src/fauxton/app/addons/pouchdb/pouchdb.mapreduce.js
@@ -0,0 +1,324 @@
+/*
+ * NOTE:
+ * This temporarily uses the PouchDB map reduce implementation
+ * These files are modified locally until we make a more general version and
+ * push it back upstream.
+ * Original file:
+ * https://github.com/daleharvey/pouchdb/blob/master/src/plugins/pouchdb.mapreduce.js
+ */
+
+/*global Pouch: true */
+
+//"use strict";
+
+// This is the first implementation of a basic plugin, we register the
+// plugin object with pouch and it is mixin'd to each database created
+// (regardless of adapter), adapters can override plugins by providing
+// their own implementation. functions on the plugin object that start
+// with _ are reserved function that are called by pouchdb for special
+// notifications.
+
+// If we wanted to store incremental views we can do it here by listening
+// to the changes feed (keeping track of our last update_seq between page loads)
+// and storing the result of the map function (possibly using the upcoming
+// extracted adapter functions)
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "addons/pouchdb/pouch.collate.js"
+],
+
+function(app, FauxtonAPI, Collate) {
+  var Pouch = {};
+  Pouch.collate = Collate.collate;
+
+  //var MapReduce = function(db) {
+  var MapReduce = function() {
+
+    var builtInReduce = {
+      "_sum": function(keys, values){
+        return sum(values);
+      },
+
+      "_count": function(keys, values, rereduce){
+        if (rereduce){
+          return sum(values);
+        } else {
+          return values.length;
+        }
+      },
+
+      "_stats": function(keys, values, rereduce){
+        return {
+          'sum': sum(values),
+          'min': Math.min.apply(null, values),
+          'max': Math.max.apply(null, values),
+          'count': values.length,
+          'sumsqr': (function(){
+            _sumsqr = 0;
+            for(var idx in values){
+              _sumsqr += values[idx] * values[idx];
+            }
+            return _sumsqr;
+          })()
+        };
+      }
+    };
+
+    function viewQuery(fun, options) {
+      console.log("IN VIEW QUERY");
+      if (!options.complete) {
+        return;
+      }
+
+      function sum(values) {
+        return values.reduce(function(a, b) { return a + b; }, 0);
+      }
+
+      var results = [];
+      var current = null;
+      var num_started= 0;
+      var completed= false;
+
+      var emit = function(key, val) {
+        //console.log("IN EMIT: ", key, val, current);
+        var viewRow = {
+          id: current.doc._id,
+          key: key,
+          value: val
+        }; 
+        //console.log("VIEW ROW: ", viewRow);
+
+        if (options.startkey && Pouch.collate(key, options.startkey) < 0) return;
+        if (options.endkey && Pouch.collate(key, options.endkey) > 0) return;
+        if (options.key && Pouch.collate(key, options.key) !== 0) return;
+        num_started++;
+        if (options.include_docs) {
+          // TODO:: FIX
+          throw({error: "Include Docs not supported"});
+          /*
+
+          //in this special case, join on _id (issue #106)
+          if (val && typeof val === 'object' && val._id){
+            db.get(val._id,
+                function(_, joined_doc){
+                  if (joined_doc) {
+                    viewRow.doc = joined_doc;
+                  }
+                  results.push(viewRow);
+                  checkComplete();
+                });
+            return;
+          } else {
+            viewRow.doc = current.doc;
+          }
+          */
+        }
+        console.log("EMITTING: ", viewRow);
+        results.push(viewRow);
+      };
+
+      // ugly way to make sure references to 'emit' in map/reduce bind to the
+      // above emit
+      eval('fun.map = ' + fun.map.toString() + ';');
+      if (fun.reduce && options.reduce) {
+        if (builtInReduce[fun.reduce]) {
+          console.log('built in reduce');
+          fun.reduce = builtInReduce[fun.reduce];
+        }
+        eval('fun.reduce = ' + fun.reduce.toString() + ';');
+      }
+
+      // exclude  _conflicts key by default
+      // or to use options.conflicts if it's set when called by db.query
+      var conflicts = ('conflicts' in options ? options.conflicts : false);
+
+      //only proceed once all documents are mapped and joined
+      var checkComplete= function(){
+        console.log('check');
+        if (completed && results.length == num_started){
+          results.sort(function(a, b) {
+            return Pouch.collate(a.key, b.key);
+          });
+          if (options.descending) {
+            results.reverse();
+          }
+          if (options.reduce === false) {
+            return options.complete(null, {rows: results});
+          }
+
+          console.log('reducing', options);
+          var groups = [];
+          results.forEach(function(e) {
+            var last = groups[groups.length-1] || null;
+            if (last && Pouch.collate(last.key[0][0], e.key) === 0) {
+              last.key.push([e.key, e.id]);
+              last.value.push(e.value);
+              return;
+            }
+            groups.push({key: [[e.key, e.id]], value: [e.value]});
+          });
+          groups.forEach(function(e) {
+            e.value = fun.reduce(e.key, e.value) || null;
+            e.key = e.key[0][0];
+          });
+          console.log('GROUPs', groups);
+          options.complete(null, {rows: groups});
+        }
+      };
+
+      if (options.docs) {
+        //console.log("RUNNING MR ON DOCS: ", options.docs);
+        _.each(options.docs, function(doc) {
+          current = {doc: doc};
+          fun.map.call(this, doc);
+        }, this);
+        completed = true;
+        return checkComplete();//options.complete(null, {rows: results});
+      } else {
+        //console.log("COULD NOT FIND DOCS");
+        return false;
+      }
+
+      /*
+      db.changes({
+        conflicts: conflicts,
+        include_docs: true,
+        onChange: function(doc) {
+          if (!('deleted' in doc)) {
+            current = {doc: doc.doc};
+            fun.map.call(this, doc.doc);
+          }
+        },
+        complete: function() {
+          completed= true;
+          checkComplete();
+        }
+      });
+      */
+    }
+
+    /*
+    function httpQuery(fun, opts, callback) {
+
+      // List of parameters to add to the PUT request
+      var params = [];
+      var body = undefined;
+      var method = 'GET';
+
+      // If opts.reduce exists and is defined, then add it to the list
+      // of parameters.
+      // If reduce=false then the results are that of only the map function
+      // not the final result of map and reduce.
+      if (typeof opts.reduce !== 'undefined') {
+        params.push('reduce=' + opts.reduce);
+      }
+      if (typeof opts.include_docs !== 'undefined') {
+        params.push('include_docs=' + opts.include_docs);
+      }
+      if (typeof opts.limit !== 'undefined') {
+        params.push('limit=' + opts.limit);
+      }
+      if (typeof opts.descending !== 'undefined') {
+        params.push('descending=' + opts.descending);
+      }
+      if (typeof opts.startkey !== 'undefined') {
+        params.push('startkey=' + encodeURIComponent(JSON.stringify(opts.startkey)));
+      }
+      if (typeof opts.endkey !== 'undefined') {
+        params.push('endkey=' + encodeURIComponent(JSON.stringify(opts.endkey)));
+      }
+      if (typeof opts.key !== 'undefined') {
+        params.push('key=' + encodeURIComponent(JSON.stringify(opts.key)));
+      }
+
+      // If keys are supplied, issue a POST request to circumvent GET query string limits
+      // see http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
+      if (typeof opts.keys !== 'undefined') {
+        method = 'POST';
+        body = JSON.stringify({keys:opts.keys});
+      }
+
+      // Format the list of parameters into a valid URI query string
+      params = params.join('&');
+      params = params === '' ? '' : '?' + params;
+
+      // We are referencing a query defined in the design doc
+      if (typeof fun === 'string') {
+        var parts = fun.split('/');
+        db.request({
+          method: method,
+          url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
+          body: body
+        }, callback);
+        return;
+      }
+
+      // We are using a temporary view, terrible for performance but good for testing
+      var queryObject = JSON.parse(JSON.stringify(fun, function(key, val) {
+        if (typeof val === 'function') {
+          return val + ''; // implicitly `toString` it
+        }
+        return val;
+      }));
+
+      db.request({
+        method:'POST',
+        url: '_temp_view' + params,
+        body: queryObject
+      }, callback);
+    }
+    */
+
+    function query(fun, opts, callback) {
+      if (typeof opts === 'function') {
+        callback = opts;
+        opts = {};
+      }
+
+      if (callback) {
+        opts.complete = callback;
+      }
+
+      /*
+      if (db.type() === 'http') {
+        return httpQuery(fun, opts, callback);
+      }
+      */
+
+      if (typeof fun === 'object') {
+        console.log("RUNNING VIEW QUERY", fun, opts, arguments);
+        return viewQuery(fun, opts);
+      }
+
+      throw({error: "Shouldn't have gotten here"});
+
+      /*
+      var parts = fun.split('/');
+      db.get('_design/' + parts[0], function(err, doc) {
+        if (err) {
+          if (callback) callback(err);
+          return;
+        }
+        viewQuery({
+          map: doc.views[parts[1]].map,
+          reduce: doc.views[parts[1]].reduce
+        }, opts);
+      });
+      */
+    }
+
+    return {'query': query};
+  };
+
+  // Deletion is a noop since we dont store the results of the view
+  MapReduce._delete = function() { };
+
+  //Pouch.plugin('mapreduce', MapReduce);
+
+  return MapReduce();
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/replication/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/replication/views.js b/src/fauxton/app/addons/replication/views.js
index f4b96fd..1b31a9d 100644
--- a/src/fauxton/app/addons/replication/views.js
+++ b/src/fauxton/app/addons/replication/views.js
@@ -13,7 +13,7 @@
 define([
        "app",
        "api",
-       "modules/fauxton/components",
+       "addons/fauxton/components",
        "addons/replication/resources"
 ],
 function(app, FauxtonAPI, Components, replication) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/stats/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/resources.js b/src/fauxton/app/addons/stats/resources.js
index a761e6b..b3c4ce1 100644
--- a/src/fauxton/app/addons/stats/resources.js
+++ b/src/fauxton/app/addons/stats/resources.js
@@ -15,7 +15,7 @@ define([
        "api",
        "backbone",
        "lodash",
-       "modules/fauxton/base"
+       "addons/fauxton/base"
 ],
 
 function (app, FauxtonAPI, backbone, _, Fauxton) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/addons/verifyinstall/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/resources.js b/src/fauxton/app/addons/verifyinstall/resources.js
index 5d83f9a..8a98883 100644
--- a/src/fauxton/app/addons/verifyinstall/resources.js
+++ b/src/fauxton/app/addons/verifyinstall/resources.js
@@ -13,8 +13,8 @@
 define([
   "app",
   "api",
-  "modules/databases/resources",
-  "modules/documents/resources"
+  "addons/databases/resources",
+  "addons/documents/resources"
 ],
 
 function (app, FauxtonAPI, Databases, Documents) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index 5ad032a..c9d08bf 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -14,7 +14,7 @@ define([
        "app",
 
        // Modules
-       "modules/fauxton/base",
+       "addons/fauxton/base",
        "spin"
 ],
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/app.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/app.js b/src/fauxton/app/app.js
index 0a51410..9ac5bc2 100644
--- a/src/fauxton/app/app.js
+++ b/src/fauxton/app/app.js
@@ -22,6 +22,8 @@ define([
 
   "helpers",
   "mixins",
+  // Modules
+  "resizeColumns",
 
    // Plugins.
   "plugins/backbone.layoutmanager",
@@ -29,7 +31,7 @@ define([
 
 ],
 
-function(app, $, _, Backbone, Bootstrap, Helpers, Mixins) {
+function(app, $, _, Backbone, Bootstrap, Helpers, Mixins, resizeColumns) {
 
    // Make sure we have a console.log
   if (typeof console == "undefined") {
@@ -81,6 +83,10 @@ function(app, $, _, Backbone, Bootstrap, Helpers, Mixins) {
     }
   });
 
+  //resizeAnimation
+  app.resizeColumns = new resizeColumns({});
+  app.resizeColumns.onResizeHandler();
+
   // Localize or create a new JavaScript Template object.
   var JST = window.JST = window.JST || {};
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/databases/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/base.js b/src/fauxton/app/modules/databases/base.js
deleted file mode 100644
index 6ff12c6..0000000
--- a/src/fauxton/app/modules/databases/base.js
+++ /dev/null
@@ -1,37 +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.
-
-define([
-  "app",
-
-  "api",
-
-  // Modules
-  "modules/databases/routes",
-  // Views
-  "modules/databases/views"
-
-],
-
-function(app, FauxtonAPI, Databases, Views) {
-  Databases.Views = Views;
-
-  // Utility functions
-  Databases.databaseUrl = function(database) {
-    var name = _.isObject(database) ? database.id : database,
-        dbname = app.mixins.safeURLName(name);
-
-    return ["/database/", dbname, "/_all_docs?limit=" + Databases.DocLimit].join('');
-  };
-
-  return Databases;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/resources.js b/src/fauxton/app/modules/databases/resources.js
deleted file mode 100644
index f3bde80..0000000
--- a/src/fauxton/app/modules/databases/resources.js
+++ /dev/null
@@ -1,193 +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.
-
-define([
-  "app",
-
-  "api",
-
-  // Modules
-  "modules/documents/resources"
-],
-
-function(app, FauxtonAPI, Documents) {
-  var Databases = FauxtonAPI.module();
-
-  Databases.DocLimit = 20;
-
-  Databases.Model = Backbone.Model.extend({
-    initialize: function(options) {
-      this.status = new Databases.Status({
-        database: this
-      });
-    },
-
-    documentation: function(){
-      return "all_dbs";
-    },
-    
-    buildAllDocs: function(params) {
-      this.allDocs = new Documents.AllDocs(null, {
-        database: this,
-        params: params
-      });
-
-      return this.allDocs;
-    },
-
-    isNew: function(){
-      // Databases are never new, to make Backbone do a PUT
-      return false;
-    },
-
-    url: function(context) {
-      if (context === "index") {
-        return "/database/" + this.safeID() + "/_all_docs";
-      } else if (context === "web-index") {
-        return "#/database/"+ this.safeID() + "/_all_docs?limit=" + Databases.DocLimit;
-      } else if (context === "apiurl") { 
-        return window.location.origin + "/database/" + this.safeID() + "/_all_docs";
-      } else if (context === "changes") {
-        return "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
-      } else if (context === "changes-apiurl") { 
-        return window.location.origin + "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
-      } else if (context === "app") {
-        return "/database/" + this.safeID();
-      } else {
-        return app.host + "/" + this.safeID();
-      }
-    },
-    safeName: function(){
-      return app.mixins.safeURLName(this.get("name"));
-    },
-    safeID: function() {
-      return app.mixins.safeURLName(this.id);
-    },
-    buildChanges: function (params) {
-      this.changes = new Databases.Changes({
-        database: this,
-        params: params
-      });
-
-      return this.changes;
-    }
-  });
-
-  Databases.Changes = Backbone.Collection.extend({
-
-    initialize: function(options) {
-      this.database = options.database;
-      this.params = options.params;
-    },
-    documentation: function(){
-      return "changes";
-    },
-    url: function (context) {
-      var query = "";
-      if (this.params) {
-        query = "?" + $.param(this.params);
-      }
-      if (context === "apiurl") { 
-        return window.location.origin + '/' + this.database.safeID() + '/_changes' + query;
-      } else {
-
-      return app.host + '/' + this.database.safeID() + '/_changes' + query;
-      }
-    },
-
-    parse: function (resp) {
-      this.last_seq = resp.last_seq;
-      return resp.results;
-    }
-  });
-
-  Databases.Status = Backbone.Model.extend({
-    url: function() {
-      return app.host + "/" + this.database.safeID();
-    },
-
-    initialize: function(options) {
-      this.database = options.database;
-    },
-
-    numDocs: function() {
-      return this.get("doc_count");
-    },
-
-    updateSeq: function(full) {
-      var updateSeq = this.get("update_seq");
-      if (full || (typeof(updateSeq) === 'number')) {
-        return updateSeq;
-      } else if (updateSeq) {
-        return updateSeq.split('-')[0];
-      } else {
-        return 0;
-      }
-    },
-
-    humanSize: function() {
-      // cribbed from http://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable
-      var i = -1;
-      var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
-      var fileSizeInBytes = this.dataSize();
-
-      if (!fileSizeInBytes) {
-        return 0;
-      }
-
-      do {
-          fileSizeInBytes = fileSizeInBytes / 1024;
-          i++;
-      } while (fileSizeInBytes > 1024);
-
-      return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
-    },
-    diskSize: function () {
-      return this.get("disk_size");
-    },
-
-    dataSize: function () {
-      if (this.get("other")){
-        return this.get("other").data_size;
-      }else{
-        return 0;
-      }  
-    }
-  });
-
-  // TODO: shared databases - read from the user doc
-  Databases.List = Backbone.Collection.extend({
-    model: Databases.Model,
-    documentation: function(){
-      return "all_dbs";
-    },
-    url: function(context) {
-      if (context === "apiurl") { 
-        return window.location.origin + "/_all_dbs";
-      } else {
-        return app.host + "/_all_dbs";
-      }
-    },
-
-    parse: function(resp) {
-      // TODO: pagination!
-      return _.map(resp, function(database) {
-        return {
-          id: app.mixins.safeURLName(database),
-          name: database
-        };
-      });
-    }
-  });
-
-  return Databases;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/databases/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/routes.js b/src/fauxton/app/modules/databases/routes.js
deleted file mode 100644
index ca3d640..0000000
--- a/src/fauxton/app/modules/databases/routes.js
+++ /dev/null
@@ -1,69 +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.
-
-define([
-  "app",
-
-  "api",
-
-  // Modules
-  "modules/databases/resources",
-  // TODO:: fix the include flow modules so we don't have to require views here
-  "modules/databases/views"
-],
-
-function(app, FauxtonAPI, Databases, Views) {
-
-  var AllDbsRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: "one_pane",
-
-    crumbs: [
-      {"name": "Databases", "link": "/_all_dbs"}
-    ],
-
-    routes: {
-      "": "allDatabases",
-      "index.html": "allDatabases",
-      "_all_dbs(:params)": "allDatabases"
-    },
-
-    apiUrl: function() {
-      return [this.databases.url("apiurl"), this.databases.documentation()];
-    },
-
-    selectedHeader: "Databases",
-
-    initialize: function() {
-      this.databases = new Databases.List();
-      this.deferred = FauxtonAPI.Deferred();
-    },
-
-    allDatabases: function() {
-      var params = app.getParams(),
-          dbPage = params.page;
-
-      this.databasesView = this.setView("#dashboard-content", new Views.List({
-        collection: this.databases
-      }));
-
-      this.databasesView.setPage(dbPage);
-    },
-
-    establish: function() {
-     return [this.databases.fetch()];
-    }
-  });
-
-  Databases.RouteObjects = [AllDbsRouteObject];
-
-  return Databases;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/databases/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/views.js b/src/fauxton/app/modules/databases/views.js
deleted file mode 100644
index dbeb475..0000000
--- a/src/fauxton/app/modules/databases/views.js
+++ /dev/null
@@ -1,255 +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.
-
-define([
-  "app",
-  
-  "modules/fauxton/components",
-  "api",
-  "modules/databases/resources"
-],
-
-function(app, Components, FauxtonAPI, Databases) {
-  var Views = {};
-
-  Views.Item = FauxtonAPI.View.extend({
-    template: "templates/databases/item",
-    tagName: "tr",
-    establish: function(){
-      return [this.model.fetch()];
-    },
-    serialize: function() {
-      return {
-        encoded: app.mixins.safeURLName(this.model.get("name")),
-        database: this.model,
-        docLimit: Databases.DocLimit
-      };
-    }
-  });
-
-  Views.List = FauxtonAPI.View.extend({
-    dbLimit: 20,
-    perPage: 20,
-    template: "templates/databases/list",
-    events: {
-      "click button.all": "selectAll",
-      "submit form#jump-to-db": "switchDatabase"
-    },
-
-    initialize: function(options) {
-      var params = app.getParams();
-      this.page = params.page ? parseInt(params.page, 10) : 1;
-    },
-
-    serialize: function() {
-      return {
-        databases: this.collection
-      };
-    },
-    establish: function(){
-      var currentDBs = this.paginated();
-      var deferred = FauxtonAPI.Deferred();
-
-      FauxtonAPI.when(currentDBs.map(function(database) {
-        return database.status.fetch();
-      })).always(function(resp) {
-        //make this always so that even if a user is not allowed access to a database
-        //they will still see a list of all databases
-        deferred.resolve();
-      });
-      return [deferred];
-    },
-    switchDatabase: function(event, selectedName) {
-      event && event.preventDefault();
-
-      var dbname = this.$el.find("[name='search-query']").val().trim();
-
-      if (selectedName) {
-        dbname = selectedName;
-      }
-
-      if (dbname && this.collection.where({"id":app.mixins.safeURLName(dbname)}).length > 0){
-          // TODO: switch to using a model, or Databases.databaseUrl()
-          // Neither of which are in scope right now
-          // var db = new Database.Model({id: dbname});
-          var url = ["/database/", app.mixins.safeURLName(dbname), "/_all_docs?limit=" + Databases.DocLimit].join('');
-          FauxtonAPI.navigate(url);
-      } else {
-        FauxtonAPI.addNotification({
-          msg: 'Database does not exist.',
-          type: 'error'
-        });
-      }
-    },
-
-    paginated: function() {
-      var start = (this.page - 1) * this.perPage;
-      var end = this.page * this.perPage;
-      return this.collection.slice(start, end);
-    },
-
-    beforeRender: function() {
-
-      this.insertView("#newButton", new Views.NewDatabaseButton({
-        collection: this.collection
-      }));
-
-      _.each(this.paginated(), function(database) {
-        this.insertView("table.databases tbody", new Views.Item({
-          model: database
-        }));
-      }, this);
-
-      this.insertView("#database-pagination", new Components.Pagination({
-        page: this.page,
-        perPage: this.perPage,
-        total: this.collection.length,
-        urlFun: function(page) {
-          return "#/_all_dbs?page=" + page;
-        }
-      }));
-    },
-
-    setPage: function(page) {
-      this.page = page || 1;
-    },
-
-    afterRender: function() {
-      var that = this;
-      this.dbSearchTypeahead = new Components.DbSearchTypeahead({
-        dbLimit: this.dbLimit,
-        el: "input.search-autocomplete",
-        onUpdate: function (item) {
-          that.switchDatabase(null, item);
-        }
-      });
-
-      this.dbSearchTypeahead.render();
-    },
-
-    selectAll: function(evt){
-      $("input:checkbox").attr('checked', !$(evt.target).hasClass('active'));
-    }
-  });
-
-
-  Views.NewDatabaseButton = FauxtonAPI.View.extend({
-    template: "templates/databases/newdatabase",
-    events: {
-      "click a#new": "newDatabase"
-    },
-    newDatabase: function() {
-      var notification;
-      var db;
-      // TODO: use a modal here instead of the prompt
-      var name = prompt('Name of database', 'newdatabase');
-      if (name === null) {
-        return;
-      } else if (name.length === 0) {
-        notification = FauxtonAPI.addNotification({
-          msg: "Please enter a valid database name",
-          type: "error",
-          clear: true
-        });
-        return;
-      }
-      db = new this.collection.model({
-        id: name,
-        name: name
-      });
-      notification = FauxtonAPI.addNotification({msg: "Creating database."});
-      db.save().done(function() {
-        notification = FauxtonAPI.addNotification({
-          msg: "Database created successfully",
-          type: "success",
-          clear: true
-        });
-        var route = "#/database/" +  app.mixins.safeURLName(name) + "/_all_docs?limit=" + Databases.DocLimit;
-        app.router.navigate(route, { trigger: true });
-      }
-      ).error(function(xhr) {
-        var responseText = JSON.parse(xhr.responseText).reason;
-        notification = FauxtonAPI.addNotification({
-          msg: "Create database failed: " + responseText,
-          type: "error",
-          clear: true
-        });
-      }
-      );
-    }
-  });
-
-  Views.Sidebar = FauxtonAPI.View.extend({
-    template: "templates/databases/sidebar",
-    events: {
-      "click a#new": "newDatabase",
-      "click a#owned": "showMine",
-      "click a#shared": "showShared"
-    },
-
-    newDatabase: function() {
-      var notification;
-      var db;
-      // TODO: use a modal here instead of the prompt
-      var name = prompt('Name of database', 'newdatabase');
-      if (name === null) {
-        return;
-      } else if (name.length === 0) {
-        notification = FauxtonAPI.addNotification({
-          msg: "Please enter a valid database name",
-          type: "error",
-          clear: true
-        });
-        return;
-      }
-      db = new this.collection.model({
-        id: encodeURIComponent(name),
-        name: name
-      });
-      notification = FauxtonAPI.addNotification({msg: "Creating database."});
-      db.save().done(function() {
-        notification = FauxtonAPI.addNotification({
-          msg: "Database created successfully",
-          type: "success",
-          clear: true
-        });
-        var route = "#/database/" +  name + "/_all_docs?limit=" + Databases.DocLimit;
-        app.router.navigate(route, { trigger: true });
-      }
-      ).error(function(xhr) {
-        var responseText = JSON.parse(xhr.responseText).reason;
-        notification = FauxtonAPI.addNotification({
-          msg: "Create database failed: " + responseText,
-          type: "error",
-          clear: true
-        });
-      }
-      );
-    },
-
-    showMine: function(){
-      $.contribute(
-        'Show unshared databases',
-        'app/addons/databases/views.js'
-      );
-    },
-
-    showShared: function(){
-      $.contribute(
-        'Show shared databases (e.g. continuous replications to/from the database)',
-        'app/addons/databases/views.js'
-      );
-    }
-  });
-
-  return Views;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/documents/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/base.js b/src/fauxton/app/modules/documents/base.js
deleted file mode 100644
index 96e4ada..0000000
--- a/src/fauxton/app/modules/documents/base.js
+++ /dev/null
@@ -1,24 +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.
-
-define([
-  "app",
-
-  "api",
-
-  // Modules
-  "modules/documents/routes"
-],
-
-function(app, FauxtonAPI, Documents) {
-  return Documents;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
deleted file mode 100644
index 83589ca..0000000
--- a/src/fauxton/app/modules/documents/resources.js
+++ /dev/null
@@ -1,638 +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.
-
-define([
-  "app",
-  "api"
-],
-
-function(app, FauxtonAPI) {
-  var Documents = app.module();
-
-  Documents.Doc = Backbone.Model.extend({
-    idAttribute: "_id",
-    documentation: function(){
-      return "docs";
-    },
-    url: function(context) {
-      if (context === "app") {
-        return this.getDatabase().url("app") + "/" + this.safeID();
-      } else if (context === "web-index") {
-        return this.getDatabase().url("app") + "/" + app.mixins.safeURLName(this.id);
-      } else if (context === "apiurl"){
-        return window.location.origin + "/" + this.getDatabase().safeID() + "/" + this.safeID();
-      } else {
-        return app.host + "/" + this.getDatabase().safeID() + "/" + this.safeID();
-      }
-    },
-
-    initialize: function(_attrs, options) {
-      if (this.collection && this.collection.database) {
-        this.database = this.collection.database;
-      } else if (options.database) {
-        this.database = options.database;
-      }
-    },
-
-    // HACK: the doc needs to know about the database, but it may be
-    // set directly or indirectly in all docs
-    getDatabase: function() {
-      return this.database ? this.database : this.collection.database;
-    },
-
-    validate: function(attrs, options) {
-      if (this.id && this.id !== attrs._id && this.get('_rev') ) {
-        return "Cannot change a documents id.";
-      }
-    },
-
-    docType: function() {
-      return this.id.match(/^_design/) ? "design doc" : "doc";
-    },
-
-    isEditable: function() {
-      return this.docType() != "reduction";
-    },
-
-    isDdoc: function() {
-      return this.docType() === "design doc";
-    },
-
-    hasViews: function() {
-      if (!this.isDdoc()) return false;
-      var doc = this.get('doc');
-      if (doc) {
-        return doc && doc.views && _.keys(doc.views).length > 0;
-      }
-
-      var views = this.get('views');
-      return views && _.keys(views).length > 0;
-    },
-
-    hasAttachments: function () {
-      return !!this.get('_attachments');
-    },
-
-    getDdocView: function(view) {
-      if (!this.isDdoc() || !this.hasViews()) return false;
-
-      var doc = this.get('doc');
-      if (doc) {
-        return doc.views[view];
-      }
-
-      return this.get('views')[view];
-    },
-
-    setDdocView: function (view, map, reduce) {
-      if (!this.isDdoc()) return false;
-      var views = this.get('views');
-          tempView = views[view] || {};
-
-      if (reduce) {
-        tempView.reduce=reduce;
-      } else {
-        delete tempView.reduce;
-      }
-      tempView.map= map;
-
-      views[view] = tempView;
-      this.set({views: views});
-
-      return true;
-    },
-
-    removeDdocView: function (viewName) {
-      if (!this.isDdoc()) return false;
-      var views = this.get('views');
-
-      delete views[viewName];
-      this.set({views: views});
-    },
-
-    dDocModel: function () {
-      if (!this.isDdoc()) return false;
-      var doc = this.get('doc');
-
-      if (doc) {
-        return new Documents.Doc(doc, {database: this.database});
-      } 
-
-      return this;
-    },
-
-    viewHasReduce: function(viewName) {
-      var view = this.getDdocView(viewName);
-
-      return view && view.reduce;
-    },
-
-    // Need this to work around backbone router thinking _design/foo
-    // is a separate route. Alternatively, maybe these should be
-    // treated separately. For instance, we could default into the
-    // json editor for docs, or into a ddoc specific page.
-    safeID: function() {
-      if (this.isDdoc()){
-        var ddoc = this.id.replace(/^_design\//,"");
-        return "_design/"+app.mixins.safeURLName(ddoc);
-      }else{
-        return app.mixins.safeURLName(this.id);
-      }
-    },
-
-    destroy: function() {
-      var url = this.url() + "?rev=" + this.get('_rev');
-      return $.ajax({
-        url: url,
-        dataType: 'json',
-        type: 'DELETE'
-      });
-    },
-
-    parse: function(resp) {
-      if (resp.rev) {
-        resp._rev = resp.rev;
-        delete resp.rev;
-      }
-      if (resp.id) {
-        if (typeof(this.id) === "undefined") {
-          resp._id = resp.id;
-        }
-        delete resp.id;
-      }
-      if (resp.ok) {
-        delete resp.ok;
-      }
-      return resp;
-    },
-
-    prettyJSON: function() {
-      var data = this.get("doc") ? this.get("doc") : this;
-
-      return JSON.stringify(data, null, "  ");
-    },
-
-    copy: function (copyId) {
-      return $.ajax({
-        type: 'COPY',
-        url: '/' + this.database.safeID() + '/' + this.safeID(),
-        headers: {Destination: copyId}
-      });
-    },
-
-    isNewDoc: function () {
-      return this.get('_rev') ? false : true;
-    }
-  });
-
-  Documents.DdocInfo = Backbone.Model.extend({
-    idAttribute: "_id",
-    documentation: function(){
-      return "docs";
-    },
-    initialize: function (_attrs, options) {
-      this.database = options.database;
-    },
-
-    url: function(context) {
-      if (context === "app") {
-        return this.database.url("app") + "/" + this.safeID() + '/_info';
-      } else if (context === "apiurl"){
-        return window.location.origin + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
-      } else {
-        return app.host + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
-      }
-    },
-
-    // Need this to work around backbone router thinking _design/foo
-    // is a separate route. Alternatively, maybe these should be
-    // treated separately. For instance, we could default into the
-    // json editor for docs, or into a ddoc specific page.
-    safeID: function() {
-      var ddoc = this.id.replace(/^_design\//,"");
-      return "_design/"+app.mixins.safeURLName(ddoc);
-    }
-
-  });
-
-  Documents.ViewRow = Backbone.Model.extend({
-    docType: function() {
-      if (!this.id) return "reduction";
-
-      return this.id.match(/^_design/) ? "design doc" : "doc";
-    },
-    documentation: function(){
-      return "docs";
-    },
-    url: function(context) {
-      if (!this.isEditable()) return false;
-
-      return this.collection.database.url(context) + "/" + this.safeID();
-    },
-
-    isEditable: function() {
-      return this.docType() != "reduction";
-    },
-    safeID: function() {
-      return app.mixins.safeURLName(this.id);
-    },
-
-    prettyJSON: function() {
-      //var data = this.get("doc") ? this.get("doc") : this;
-      return JSON.stringify(this, null, "  ");
-    }
-  });
-
-  Documents.NewDoc = Documents.Doc.extend({
-    fetch: function() {
-      var uuid = new FauxtonAPI.UUID();
-      var deferred = this.deferred = $.Deferred();
-      var that = this;
-
-      uuid.fetch().done(function() {
-        that.set("_id", uuid.next());
-        deferred.resolve();
-      });
-
-      return deferred.promise();
-    }
-
-  });
-
-  Documents.AllDocs = Backbone.Collection.extend({
-    model: Documents.Doc,
-    documentation: function(){
-      return "docs";
-    },
-    initialize: function(_models, options) {
-      this.database = options.database;
-      this.params = options.params;
-      this.skipFirstItem = false;
-
-      this.on("remove",this.decrementTotalRows , this);
-    },
-
-    url: function(context) {
-      var query = "";
-      if (this.params) {
-        query = "?" + $.param(this.params);
-      }
-
-      if (context === 'app') {
-        return 'database/' + this.database.safeID() + "/_all_docs" + query;
-      } else if (context === "apiurl"){
-        return window.location.origin + "/" + this.database.safeID() + "/_all_docs" + query;
-      } else {
-        return app.host + "/" + this.database.safeID() + "/_all_docs" + query;
-      }
-    },
-
-    simple: function () {
-      var docs = this.map(function (item) {
-        return {
-          _id: item.id,
-          _rev: item.get('_rev'),
-        };
-      });
-
-      return new Documents.AllDocs(docs, {
-        database: this.database,
-        params: this.params
-      });
-    },
-
-    urlNextPage: function (num, lastId) {
-      if (!lastId) {
-        var doc = this.last();
-
-        if (doc) {
-          lastId = doc.id;
-        } else {
-          lastId = '';
-        }
-      }
-
-      this.params.startkey_docid = '"' + lastId + '"';
-      this.params.startkey = '"' + lastId + '"';
-      // when paginating forward, fetch 21 and don't show
-      // the first item as it was the last item in the previous list
-      this.params.limit = num + 1;
-      return this.url('app');
-    },
-
-    urlPreviousPage: function (num, firstId) {
-      this.params.limit = num;
-      if (firstId) { 
-        this.params.startkey_docid = '"' + firstId + '"';
-        this.params.startkey = '"' + firstId + '"';
-      } else {
-        delete this.params.startkey;
-        delete this.params.startkey_docid;
-      }
-      return this.url('app');
-    },
-
-    totalRows: function() {
-      return this.viewMeta.total_rows || "unknown";
-    },
-
-    decrementTotalRows: function () {
-      if (this.viewMeta.total_rows) {
-        this.viewMeta.total_rows = this.viewMeta.total_rows -1;
-        this.trigger('totalRows:decrement');
-      }
-    },
-
-    updateSeq: function() {
-      return this.viewMeta.update_seq || false;
-    },
-
-    recordStart: function () {
-      if (this.viewMeta.offset === 0) {
-        return 1;
-      }
-
-      if (this.skipFirstItem) {
-        return this.viewMeta.offset + 2;
-      }
-
-      return this.viewMeta.offset + 1;
-    },
-
-    parse: function(resp) {
-      var rows = resp.rows;
-
-      this.viewMeta = {
-        total_rows: resp.total_rows,
-        offset: resp.offset,
-        update_seq: resp.update_seq
-      };
-
-      //Paginating, don't show first item as it was the last
-      //item in the previous page
-      if (this.skipFirstItem) {
-        rows = rows.splice(1);
-      }
-      return _.map(rows, function(row) {
-        return {
-          _id: row.id,
-          _rev: row.value.rev,
-          value: row.value,
-          key: row.key,
-          doc: row.doc || undefined
-        };
-      });
-    }
-  });
-
-  Documents.IndexCollection = Backbone.Collection.extend({
-    model: Documents.ViewRow,
-    documentation: function(){
-      return "docs";
-    },
-    initialize: function(_models, options) {
-      this.database = options.database;
-      this.params = _.extend({limit: 20, reduce: false}, options.params);
-      this.idxType = "_view";
-      this.view = options.view;
-      this.design = options.design.replace('_design/','');
-      this.skipFirstItem = false;
-    },
-
-    url: function(context) {
-      var query = "";
-      if (this.params) {
-        query = "?" + $.param(this.params);
-      }
-      
-      var startOfUrl = app.host;
-      if (context === 'app') {
-        startOfUrl = 'database';
-      } else if (context === "apiurl"){
-        startOfUrl = window.location.origin;
-      }
-      var design = app.mixins.safeURLName(this.design),
-          view = app.mixins.safeURLName(this.view);
-
-      var url = [startOfUrl, this.database.safeID(), "_design", design, this.idxType, view];
-      return url.join("/") + query;
-    },
-
-    urlNextPage: function (num, lastId) {
-      if (!lastId) {
-        lastId = this.last().id;
-      }
-
-      this.params.startkey_docid = '"' + lastId + '"';
-      this.params.startkey = '"' + lastId + '"';
-      this.params.limit = num;
-      return this.url('app');
-    },
-
-     urlPreviousPage: function (num, firstId) {
-      this.params.limit = num;
-      if (firstId) { 
-        this.params.startkey_docid = '"' + firstId + '"';
-        this.params.startkey = '"' + firstId + '"';
-      } else {
-        delete this.params.startkey;
-        delete this.params.startkey_docid;
-      }
-      return this.url('app');
-    },
-
-    recordStart: function () {
-      if (this.viewMeta.offset === 0) {
-        return 1;
-      }
-
-      if (this.skipFirstItem) {
-        return this.viewMeta.offset + 2;
-      }
-
-      return this.viewMeta.offset + 1;
-    },
-
-    totalRows: function() {
-      return this.viewMeta.total_rows || "unknown";
-    },
-
-    updateSeq: function() {
-      return this.viewMeta.update_seq || false;
-    },
-
-    simple: function () {
-      var docs = this.map(function (item) {
-        return {
-          _id: item.id,
-          key: item.get('key'),
-          value: item.get('value')
-        };
-      });
-
-      return new Documents.IndexCollection(docs, {
-        database: this.database,
-        params: this.params,
-        view: this.view,
-        design: this.design
-      });
-    },
-
-    parse: function(resp) {
-      var rows = resp.rows;
-      this.endTime = new Date().getTime();
-      this.requestDuration = (this.endTime - this.startTime);
-
-      if (this.skipFirstItem) {
-        rows = rows.splice(1);
-      }
-
-      this.viewMeta = {
-        total_rows: resp.total_rows,
-        offset: resp.offset,
-        update_seq: resp.update_seq
-      };
-      return _.map(rows, function(row) {
-        return {
-          value: row.value,
-          key: row.key,
-          doc: row.doc,
-          id: row.id
-        };
-      });
-    },
-
-    buildAllDocs: function(){
-      this.fetch();
-    },
-
-    // We implement our own fetch to store the starttime so we that
-    // we can get the request duration
-    fetch: function () {
-      this.startTime = new Date().getTime();
-      return Backbone.Collection.prototype.fetch.call(this);
-    },
-
-    allDocs: function(){
-      return this.models;
-    },
-
-    // This is taken from futon.browse.js $.timeString
-    requestDurationInString: function () {
-      var ms, sec, min, h, timeString, milliseconds = this.requestDuration;
-
-      sec = Math.floor(milliseconds / 1000.0);
-      min = Math.floor(sec / 60.0);
-      sec = (sec % 60.0).toString();
-      if (sec.length < 2) {
-         sec = "0" + sec;
-      }
-
-      h = (Math.floor(min / 60.0)).toString();
-      if (h.length < 2) {
-        h = "0" + h;
-      }
-
-      min = (min % 60.0).toString();
-      if (min.length < 2) {
-        min = "0" + min;
-      }
-
-      timeString = h + ":" + min + ":" + sec;
-
-      ms = (milliseconds % 1000.0).toString();
-      while (ms.length < 3) {
-        ms = "0" + ms;
-      }
-      timeString += "." + ms;
-
-      return timeString;
-    }
-  });
-
-  
-  Documents.PouchIndexCollection = Backbone.Collection.extend({
-    model: Documents.ViewRow,
-    documentation: function(){
-      return "docs";
-    },
-    initialize: function(_models, options) {
-      this.database = options.database;
-      this.rows = options.rows;
-      this.view = options.view;
-      this.design = options.design.replace('_design/','');
-      this.params = _.extend({limit: 20, reduce: false}, options.params);
-      this.idxType = "_view";
-    },
-
-    url: function () {
-      return '';
-    },
-
-    simple: function () {
-      var docs = this.map(function (item) {
-        return {
-          _id: item.id,
-          key: item.get('key'),
-          value: item.get('value')
-        };
-      });
-
-      return new Documents.PouchIndexCollection(docs, {
-        database: this.database,
-        params: this.params,
-        view: this.view,
-        design: this.design,
-        rows: this.rows
-      });
-
-    },
-
-    fetch: function() {
-      var deferred = FauxtonAPI.Deferred();
-      this.reset(this.rows, {silent: true});
-
-      this.viewMeta = {
-        total_rows: this.rows.length,
-        offset: 0,
-        update_seq: false
-      };
-
-      deferred.resolve();
-      return deferred;
-    },
-
-    recordStart: function () {
-      return 1;
-    },
-
-    totalRows: function() {
-      return this.viewMeta.total_rows || "unknown";
-    },
-
-    updateSeq: function() {
-      return this.viewMeta.update_seq || false;
-    },
-
-    buildAllDocs: function(){
-      this.fetch();
-    },
-
-    allDocs: function(){
-      return this.models;
-    }
-  });
-
-
-
-  return Documents;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js
deleted file mode 100644
index 538cd56..0000000
--- a/src/fauxton/app/modules/documents/routes.js
+++ /dev/null
@@ -1,408 +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.
-
-define([
-       "app",
-
-       "api",
-
-       // Modules
-       "modules/documents/views",
-       "modules/databases/base"
-],
-
-function(app, FauxtonAPI, Documents, Databases) {
-
-  var DocEditorRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: "one_pane",
-    disableLoader: true,
-    selectedHeader: "Databases",
-    initialize: function(route, masterLayout, options) {
-      var databaseName = options[0];
-      this.docID = options[1]||'new';
-
-      this.database = this.database || new Databases.Model({id: databaseName});
-      this.doc = new Documents.Doc({
-        _id: this.docID
-      }, {
-        database: this.database
-      });
-
-      this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({
-        disableLoader: true,
-        selected: "code_editor",
-        model: this.doc
-      }));
-
-    },
-
-    routes: {
-      // We are hiding the field_editor for this first release
-      // "database/:database/:doc/field_editor": "field_editor",
-      "database/:database/:doc/code_editor": "code_editor",
-      "database/:database/:doc": "code_editor"
-    },
-
-    events: {
-      "route:reRenderDoc": "reRenderDoc",
-      "route:duplicateDoc": "duplicateDoc"
-    },
-
-    crumbs: function() {
-      return [
-        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
-        {"name": this.docID, "link": "#"}
-      ];
-    },
-
-    code_editor: function (database, doc) {
-      this.tabsView.updateSelected('code_editor');
-
-      this.docView = this.setView("#dashboard-content", new Documents.Views.Doc({
-        model: this.doc,
-        database: this.database
-      }));
-    },
-
-    reRenderDoc: function () {
-      this.docView.forceRender();
-    },
-
-    field_editor: function(events) {
-      this.tabsView.updateSelected('field_editor');
-      this.docView = this.setView("#dashboard-content", new Documents.Views.DocFieldEditor({
-        model: this.doc
-      }));
-    },
-
-    duplicateDoc: function (newId) {
-      var doc = this.doc,
-      docView = this.docView,
-      database = this.database;
-
-      doc.copy(newId).then(function () {
-        doc.set({_id: newId}); 
-        docView.forceRender();
-        FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.mixins.safeURLName(newId), {trigger: true});
-        FauxtonAPI.addNotification({
-          msg: "Document has been duplicated."
-        });
-
-      }, function (error) {
-        var errorMsg = "Could not duplicate document, reason: " + error.responseText + ".";
-        FauxtonAPI.addNotification({
-          msg: errorMsg,
-          type: "error"
-        });
-      });
-    },
-
-    apiUrl: function() {
-      return [this.doc.url("apiurl"), this.doc.documentation()];
-    }
-  });
-
-  var NewDocEditorRouteObject = DocEditorRouteObject.extend({
-    initialize: function (route, masterLayout, options) {
-      var databaseName = options[0];
-
-      this.database = this.database || new Databases.Model({id: databaseName});
-      this.doc = new Documents.NewDoc(null,{
-        database: this.database
-      });
-
-      this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({
-        selected: "code_editor",
-        model: this.doc
-      }));
-
-    },
-    crumbs: function() {
-      return [
-        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
-        {"name": "New", "link": "#"}
-      ];
-    },
-    routes: {
-      "database/:database/new": "code_editor"
-    },
-    selectedHeader: "Databases",
-
-  });
-
-  var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: "with_tabs_sidebar",
-    selectedHeader: "Databases",
-    routes: {
-      "database/:database/_all_docs(:extra)": "allDocs", 
-      "database/:database/_design/:ddoc/_view/:view": {
-        route: "viewFn",
-        roles: ['_admin']
-      },
-      "database/:database/new_view": "newViewEditor"
-    },
-
-    events: {
-      "route:updateAllDocs": "updateAllDocsFromView",
-      "route:updatePreviewDocs": "updateAllDocsFromPreview",
-      "route:reloadDesignDocs": "reloadDesignDocs",
-      "route:paginate": "paginate"
-    },
-
-    initialize: function (route, masterLayout, options) {
-      var docOptions = app.getParams();
-      docOptions.include_docs = true;
-
-      this.databaseName = options[0];
-
-      this.data = {
-        database: new Databases.Model({id:this.databaseName})
-      };
-
-      this.data.designDocs = new Documents.AllDocs(null, {
-        database: this.data.database,
-        params: {startkey: '"_design"',
-          endkey: '"_design1"',
-          include_docs: true}
-      });
-
-      this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
-        collection: this.data.designDocs,
-        database: this.data.database
-      }));
-    },
-
-    establish: function () {
-      return this.data.designDocs.fetch();
-    },
-
-    allDocs: function(databaseName, options) {
-      var docOptions = app.getParams(options);
-
-      docOptions.include_docs = true;
-      this.data.database.buildAllDocs(docOptions);
-
-      if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
-        this.sidebar.setSelectedTab('design-docs');
-      } else {
-        this.sidebar.setSelectedTab('all-docs');
-      }
-
-      if (this.viewEditor) { this.viewEditor.remove(); }
-
-      this.toolsView = this.setView("#dashboard-upper-menu", new Documents.Views.JumpToDoc({
-        database: this.data.database,
-        collection: this.data.database.allDocs
-      }));
-
-      this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
-        database: this.data.database,
-        collection: this.data.database.allDocs,
-        params: docOptions
-      }));
-
-      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        collection: this.data.database.allDocs
-      }));
-
-      this.crumbs = [
-        {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}
-      ];
-
-      this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
-    },
-
-    viewFn: function (databaseName, ddoc, view) {
-      var params = app.getParams(),
-          decodeDdoc = decodeURIComponent(ddoc);
-
-      view = view.replace(/\?.*$/,'');
-
-      this.data.indexedDocs = new Documents.IndexCollection(null, {
-        database: this.data.database,
-        design: decodeDdoc,
-        view: view,
-        params: params
-      });
-
-
-
-      var ddocInfo = {
-        id: "_design/" + decodeDdoc,
-        currView: view,
-        designDocs: this.data.designDocs
-      };
-
-      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
-        model: this.data.database,
-        ddocs: this.data.designDocs,
-        viewName: view,
-        params: params,
-        newView: false,
-        database: this.data.database,
-        ddocInfo: ddocInfo
-      }));
-
-      if (this.toolsView) { this.toolsView.remove(); }
-
-      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: this.data.database,
-        collection: this.data.indexedDocs,
-        nestedView: Documents.Views.Row,
-        viewList: true,
-        ddocInfo: ddocInfo
-      }));
-
-      this.sidebar.setSelectedTab(app.mixins.removeSpecialCharacters(ddoc) + '_' + app.mixins.removeSpecialCharacters(view));
-
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-        ];
-      };
-
-      this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
-    },
-
-    newViewEditor: function () {
-      var params = app.getParams();
-
-      if (this.toolsView) {
-        this.toolsView.remove();
-      }
-
-      this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
-        ddocs: this.data.designDocs,
-        params: params,
-        database: this.data.database,
-        newView: true
-      }));
-
-      this.sidebar.setSelectedTab('new-view');
-      this.crumbs = function () {
-        return [
-          {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
-        ];
-      };
-    },
-
-    updateAllDocsFromView: function (event) {
-      var view = event.view,
-          docOptions = app.getParams(),
-          ddoc = event.ddoc;
-
-      if (event.allDocs) {
-        docOptions.include_docs = true;
-        this.data.database.buildAllDocs(docOptions);
-        return;
-      }
-
-      this.data.indexedDocs = new Documents.IndexCollection(null, {
-        database: this.data.database,
-        design: ddoc,
-        view: view,
-        params: app.getParams()
-      });
-
-      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: this.data.database,
-        collection: this.data.indexedDocs,
-        nestedView: Documents.Views.Row,
-        viewList: true
-      }));
-    },
-
-    updateAllDocsFromPreview: function (event) {
-      var view = event.view,
-      rows = event.rows,
-      ddoc = event.ddoc;
-
-      this.data.indexedDocs = new Documents.PouchIndexCollection(null, {
-        database: this.data.database,
-        design: ddoc,
-        view: view,
-        rows: rows
-      });
-
-      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: this.data.database,
-        collection: this.data.indexedDocs,
-        nestedView: Documents.Views.Row,
-        viewList: true
-      }));
-    },
-
-    paginate: function (direction) {
-      _.extend(this.documentsView.collection.params, app.getParams());
-      this.documentsView.forceRender();
-      if (direction === 'next') {
-        this.documentsView.collection.skipFirstItem = true;
-      } else {
-        this.documentsView.collection.skipFirstItem = false;
-      }
-    },
-
-    reloadDesignDocs: function (event) {
-      this.sidebar.forceRender();
-
-      if (event && event.selectedTab) {
-        this.sidebar.setSelectedTab(event.selectedTab);
-      }
-    }
-
-  });
-
-  var ChangesRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: "with_tabs",
-    selectedHeader: "Databases",
-    crumbs: function () {
-      return [
-        {"name": this.database.id, "link": Databases.databaseUrl(this.database)},
-        {"name": "_changes", "link": "/_changes"}
-      ];
-    },
-
-    routes: {
-      "database/:database/_changes(:params)": "changes"
-    },
-
-    initialize: function (route, masterLayout, options) {
-      this.databaseName = options[0];
-      this.database = new Databases.Model({id: this.databaseName});
-
-      var docOptions = app.getParams();
-
-      this.database.buildChanges(docOptions);
-
-      this.setView("#tabs", new Documents.Views.Tabs({
-        collection: this.designDocs,
-        database: this.database,
-        active_id: 'changes'
-      }));
-    },
-
-    changes: function (event) {
-      this.setView("#dashboard-content", new Documents.Views.Changes({
-        model: this.database
-      }));
-    },
-
-    apiUrl: function() {
-      return [this.database.url("apiurl"), this.database.documentation()];
-    }
-
-  });
-
-  Documents.RouteObjects = [DocEditorRouteObject, NewDocEditorRouteObject, DocumentsRouteObject, ChangesRouteObject];
-
-  return Documents;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/fae1de24/src/fauxton/app/modules/documents/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/tests/resourcesSpec.js b/src/fauxton/app/modules/documents/tests/resourcesSpec.js
deleted file mode 100644
index e78a3c3..0000000
--- a/src/fauxton/app/modules/documents/tests/resourcesSpec.js
+++ /dev/null
@@ -1,84 +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.
-define([
-       'modules/documents/resources',
-      'testUtils'
-], function (Models, testUtils) {
-  var assert = testUtils.assert;
-
-  describe('IndexCollection', function () {
-    var collection;
-    beforeEach(function () {
-      collection = new Models.IndexCollection([{
-        id:'myId1',
-        doc: 'num1'
-      },
-      {
-        id:'myId2',
-        doc: 'num2'
-      }], {
-        database: {id: 'databaseId'},
-        design: '_design/myDoc'
-      });
-
-    });
-
-    it('Should return urlNext', function () {
-      var url = collection.urlNextPage(20);
-
-      assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=20&reduce=false&startkey_docid=%22myId2%22&startkey=%22myId2%22');
-
-    });
-
-    it('Should return urlPrevious', function () {
-      var url = collection.urlPreviousPage(20, 'myId1');
-
-      assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=20&reduce=false&startkey_docid=%22myId1%22&startkey=%22myId1%22');
-
-    });
-
-  });
-
-  describe('AllDocs', function () {
-    var collection;
-    beforeEach(function () {
-      collection = new Models.AllDocs([{
-        _id:'myId1',
-        doc: 'num1'
-      },
-      {
-        _id:'myId2',
-        doc: 'num2'
-      }], {
-        database: {id: 'databaseId'},
-        params: {limit: 20}
-      });
-
-    });
-
-    it('Should return urlNext', function () {
-      var url = collection.urlNextPage(20);
-
-      assert.equal(url, 'database/databaseId/_all_docs?limit=21&startkey_docid=%22myId2%22&startkey=%22myId2%22');
-
-    });
-
-     it('Should return urlPrevious', function () {
-      var url = collection.urlPreviousPage(20, 'myId1');
-      assert.equal(url, 'database/databaseId/_all_docs?limit=20&startkey_docid=%22myId1%22&startkey=%22myId1%22');
-    });
-
-
-  });
-
-});
-


Mime
View raw message