couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From beno...@apache.org
Subject [33/57] [abbrv] [partial] inital move to rebar compilation
Date Tue, 07 Jan 2014 00:36:53 GMT
http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/stats/templates/pie_table.html
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/stats/templates/pie_table.html b/apps/fauxton/app/addons/stats/templates/pie_table.html
new file mode 100644
index 0000000..c8e89cd
--- /dev/null
+++ b/apps/fauxton/app/addons/stats/templates/pie_table.html
@@ -0,0 +1,54 @@
+<!--
+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="row-fluid">
+    <h2>  <%= datatype %> </h2>
+</div>
+
+<div class="row-fluid">
+  <div>
+    <table class="table table-condensed table-striped">
+      <thead>
+        <tr>
+          <th> Description </th>
+          <th> current </th>
+          <th>  sum </th>
+          <th>  mean </th>
+          <th>  stddev </th>
+          <th>  min </th>
+          <th>  max </th>
+        </tr>
+      </thead>
+      <% _.each (statistics, function (stat_line) {
+        if (stat_line.get("sum")){
+       %>
+      <tr>
+        <td><%= stat_line.get("description") %></td>
+        <td><%= stat_line.get("current") %></td>
+        <td><%= stat_line.get("sum") %></td>
+        <td><%= stat_line.get("mean") %></td>
+        <td><%= stat_line.get("stddev") %></td>
+        <td><%= stat_line.get("min") %></td>
+        <td><%= stat_line.get("max") %></td>
+      </tr>
+      <% }}) %>
+    </table>
+  </div>
+
+  <div class="span5" style="height:430px;min-width: 430px">
+    <center>
+      <svg id="<%= datatype %>_graph"></svg>
+    </center>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/stats/templates/stats.html
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/stats/templates/stats.html b/apps/fauxton/app/addons/stats/templates/stats.html
new file mode 100644
index 0000000..ae7ce14
--- /dev/null
+++ b/apps/fauxton/app/addons/stats/templates/stats.html
@@ -0,0 +1,16 @@
+<!--
+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="datatypes">
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/stats/templates/statselect.html
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/stats/templates/statselect.html b/apps/fauxton/app/addons/stats/templates/statselect.html
new file mode 100644
index 0000000..ef1133c
--- /dev/null
+++ b/apps/fauxton/app/addons/stats/templates/statselect.html
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+
+<% _.each(datatypes, function (datatype) { %>
+<li> 
+<a href="#stats" class="datatype-select" data-type-select="<%= datatype %>"> 
+  <%= datatype %>
+  <i class="icon-chevron-right" style="float:right"></i>
+</a>
+</li>
+<% }); %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/stats/views.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/stats/views.js b/apps/fauxton/app/addons/stats/views.js
new file mode 100644
index 0000000..9dd9cbc
--- /dev/null
+++ b/apps/fauxton/app/addons/stats/views.js
@@ -0,0 +1,171 @@
+// 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",
+  'addons/stats/resources',
+  "d3",
+  "nv.d3"
+
+],
+
+function(app, FauxtonAPI,Stats) {
+  Views = {};
+
+  datatypeEventer = {};
+  _.extend(datatypeEventer, Backbone.Events);
+
+  Views.Legend = FauxtonAPI.View.extend({
+    tagName: 'ul',
+    template: "addons/stats/templates/legend",
+
+    serialize: function () {
+      return {
+        legend_items: this.collection.toJSON()
+      };
+    }
+  });
+
+  Views.Pie = FauxtonAPI.View.extend({
+    className: "datatype-section",
+    template: 'addons/stats/templates/pie_table',
+
+    initialize: function(args){
+      this.datatype = args.datatype;
+    },
+
+    serialize: function() {
+      return {
+        statistics: this.collection.where({type: this.datatype}),
+        datatype: this.datatype
+      };
+    },
+
+    afterRender: function(){
+        var collection = this.collection,
+            chartelem = "#" + this.datatype + '_graph',
+            series = _.map(this.collection.where({type: this.datatype}),
+          function(d, counter){
+            // TODO: x should be a counter
+            var point = {
+              y: d.get("sum") || 0,
+              key: d.id
+            };
+            return point;
+          }
+        );
+
+        series = _.filter(series, function(d){return d.y > 0;});
+        series = _.sortBy(series, function(d){return -d.y;});
+
+        nv.addGraph(function() {
+            var width = 550,
+                height = 400;
+
+            var chart = nv.models.pieChart()
+                .x(function(d) { return d.key; })
+                .y(function(d) { return d.y; })
+                .showLabels(true)
+                .showLegend(false)
+                .values(function(d) { return d; })
+                .color(d3.scale.category10().range())
+                .width(width)
+                .height(height);
+
+              d3.select(chartelem)
+                  .datum([series])
+                .transition().duration(300)
+                  .attr('width', width)
+                  .attr('height', height)
+                  .call(chart);
+
+            return chart;
+        });
+
+      this.$el.addClass(this.datatype + '_section');
+    }
+  });
+
+  Views.StatSelect = FauxtonAPI.View.extend({
+    className: 'nav nav-tabs nav-stacked',
+    tagName: 'ul',
+
+    template: "addons/stats/templates/statselect",
+
+    initialize: function (options) {
+      this.rows = [];
+    },
+
+    events: {
+      'click .datatype-select': "datatype_selected"
+    },
+
+    serialize: function () {
+      return {
+        datatypes: _.uniq(this.collection.pluck("type"))
+      };
+    },
+
+    afterRender: function () {
+      this.$('.datatype-select').first().addClass('active');
+    },
+
+    datatype_selected: function (event) {
+      var $target = $(event.currentTarget);
+
+      event.preventDefault();
+      event.stopPropagation();
+      this.$('.datatype-select').removeClass('active');
+      $target.addClass('active');
+      datatypeEventer.trigger('datatype-select', $target.attr('data-type-select'));
+    }
+  });
+
+  Views.Statistics = FauxtonAPI.View.extend({
+    template: "addons/stats/templates/stats",
+
+    initialize: function (options) {
+      this.rows = [];
+      datatypeEventer.on('datatype-select', this.display_datatype, this);
+    },
+
+    serialize: function () {
+      return {
+        datatypes: _.uniq(this.collection.pluck("type"))
+      };
+    },
+
+    beforeRender: function () {
+      _.each(_.uniq(this.collection.pluck("type")), function(datatype) {
+        this.rows[datatype] = this.insertView(".datatypes", new Views.Pie({
+          collection: this.collection,
+          datatype: datatype
+        }));
+      }, this);
+    },
+
+    afterRender: function () {
+      this.$('.datatype-section').hide().first().toggle();
+    },
+
+    display_datatype: function (datatype) {
+      this.$('.datatype-section').hide();
+      this.$('.' + datatype + '_section').show();
+    }
+  });
+
+  Stats.Views = Views;
+
+  return Stats;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less b/apps/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less
new file mode 100644
index 0000000..e084cb3
--- /dev/null
+++ b/apps/fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less
@@ -0,0 +1,16 @@
+// 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.
+
+#start {
+  margin-bottom: 20px;
+}
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/verifyinstall/base.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/verifyinstall/base.js b/apps/fauxton/app/addons/verifyinstall/base.js
new file mode 100644
index 0000000..d17c353
--- /dev/null
+++ b/apps/fauxton/app/addons/verifyinstall/base.js
@@ -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.
+
+define([
+  "app",
+  "api",
+  "addons/verifyinstall/routes"
+],
+
+function(app, FauxtonAPI, VerifyInstall) {
+  VerifyInstall.initialize = function () {
+    FauxtonAPI.addHeaderLink({
+        title: "Verify", 
+        href: "#verifyinstall",
+        icon: "fonticon-circle-check",
+        bottomNav: true,
+      });
+  };
+
+
+  return VerifyInstall;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/verifyinstall/resources.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/verifyinstall/resources.js b/apps/fauxton/app/addons/verifyinstall/resources.js
new file mode 100644
index 0000000..5d83f9a
--- /dev/null
+++ b/apps/fauxton/app/addons/verifyinstall/resources.js
@@ -0,0 +1,181 @@
+// 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/databases/resources",
+  "modules/documents/resources"
+],
+
+function (app, FauxtonAPI, Databases, Documents) {
+  var Verifyinstall = FauxtonAPI.addon();
+
+  var db = new Databases.Model({
+    id: 'verifytestdb',
+    name: 'verifytestdb'
+  });
+
+  var dbReplicate = new Databases.Model({
+    id: 'verifytestdb_replicate',
+    name: 'verifytestdb_replicate'
+  });
+
+  var doc, viewDoc;
+
+  Verifyinstall.testProcess = {
+
+    saveDoc: function () {
+      doc = new Documents.Doc({_id: 'test_doc_1', a: 1}, {
+        database: db
+      });
+
+      return doc.save();
+    },
+
+    destroyDoc: function () {
+     return doc.destroy();
+    },
+
+    updateDoc: function () {
+      doc.set({b: "hello"});
+      return doc.save(); 
+    },
+
+    saveDB: function () {
+      return db.save();
+    },
+
+    setupDB: function (db) {
+      var deferred = FauxtonAPI.Deferred();
+      db.fetch()
+      .then(function () {
+        return db.destroy();
+      }, function (xhr) {
+        deferred.resolve();
+      })
+      .then(function () {
+        deferred.resolve();
+      }, function (xhr, error, reason) {
+        if (reason === "Unauthorized") {
+          deferred.reject(xhr, error, reason);
+        }
+      });
+
+      return deferred;
+    },
+
+    setup: function () {
+      return FauxtonAPI.when([
+        this.setupDB(db), 
+        this.setupDB(dbReplicate)
+      ]);
+    },
+
+    testView: function () {
+      var deferred = FauxtonAPI.Deferred();
+      var promise = $.get(viewDoc.url() + '/_view/testview');
+
+      promise.then(function (resp) { 
+        var row = JSON.parse(resp).rows[0];
+        if (row.value === 6) {
+          return deferred.resolve();
+        }
+        var reason = {
+            reason: 'Values expect 6, got ' + row.value
+          };
+
+        deferred.reject({responseText: JSON.stringify(reason)});
+      }, deferred.reject);
+
+      return deferred;
+    },
+
+    setupView: function () {
+      var doc1 = new Documents.Doc({_id: 'test_doc10', a: 1}, {
+        database: db
+      });
+
+      var doc2 = new Documents.Doc({_id: 'test_doc_20', a: 2}, {
+        database: db
+      });
+
+      var doc3 = new Documents.Doc({_id: 'test_doc_30', a: 3}, {
+        database: db
+      });
+
+      viewDoc = new Documents.Doc({
+        _id: '_design/view_check',
+        views: {
+          'testview': { 
+            map:'function (doc) { emit(doc._id, doc.a); }',
+            reduce: '_sum'
+          }
+        } 
+      },{
+        database: db,
+      });
+
+      return FauxtonAPI.when([doc1.save(),doc2.save(), doc3.save(), viewDoc.save()]);
+    },
+
+    setupReplicate: function () {
+      return $.ajax({
+        url: '/_replicate',
+        contentType: 'application/json',
+        type: 'POST',
+        dataType: 'json',
+        processData: false,
+        data: JSON.stringify({
+          create_target: true,
+          source: 'verifytestdb',
+          target: 'verifytestdb_replicate'
+        }),
+      });
+    },
+
+    testReplicate: function () {
+      var deferred = FauxtonAPI.Deferred();
+      /*var dbReplicate = new Databases.Model({
+          id: 'verifytestdb_replicate',
+          name: 'verifytestdb_replicate'
+        });*/
+
+      var promise = dbReplicate.fetch();
+
+      promise.then(function () {
+        var docCount = dbReplicate.get('doc_count');
+        if ( docCount === 4) {
+          deferred.resolve();
+          return;
+        }
+
+        var reason = {
+          reason: 'Replication Failed, expected 4 docs got ' + docCount
+        };
+
+        deferred.reject({responseText: JSON.stringify(reason)});
+      }, deferred.reject);
+
+      return deferred;
+    },
+
+    removeDBs: function () {
+      dbReplicate.destroy();
+      db.destroy();
+
+    }
+  };
+
+
+  return Verifyinstall;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/verifyinstall/routes.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/verifyinstall/routes.js b/apps/fauxton/app/addons/verifyinstall/routes.js
new file mode 100644
index 0000000..e5024ba
--- /dev/null
+++ b/apps/fauxton/app/addons/verifyinstall/routes.js
@@ -0,0 +1,37 @@
+// 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",
+  "addons/verifyinstall/views"
+],
+function(app, FauxtonAPI, VerifyInstall) {
+
+  var VerifyRouteObject = FauxtonAPI.RouteObject.extend({
+    layout: 'one_pane',
+
+    routes: {
+      'verifyinstall': "verifyInstall"
+    },
+    selectedHeader: "Verify",
+
+    verifyInstall: function () {
+      this.setView('#dashboard-content', new VerifyInstall.Main({}));
+    },
+
+    crumbs: [{name: 'Verify Couchdb Installation', link: '#'}]
+  });
+
+  VerifyInstall.RouteObjects = [VerifyRouteObject];
+  return VerifyInstall;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/verifyinstall/templates/main.html
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/verifyinstall/templates/main.html b/apps/fauxton/app/addons/verifyinstall/templates/main.html
new file mode 100644
index 0000000..fa41907
--- /dev/null
+++ b/apps/fauxton/app/addons/verifyinstall/templates/main.html
@@ -0,0 +1,50 @@
+<!--
+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 id="start" class="btn btn-large btn-success"> Verify Installation </button>
+<div id="error"> </div>
+
+<table id="test-score" class="table table-striped table-bordered" >
+  <thead>
+    <tr>
+      <th> Test </th>
+      <th> Status </th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td> Create Database </td>
+      <td id="create-database" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Create Document </td>
+      <td id="create-document" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Update Document </td>
+      <td id="update-document" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Delete Document </td>
+      <td id="delete-document" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Create View </td>
+      <td id="create-view" class="status">  </td>
+    </tr>
+    <tr>
+      <td> Replication </td>
+      <td id="replicate" class="status">  </td>
+    </tr>
+  </tbody>
+</table>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/addons/verifyinstall/views.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/addons/verifyinstall/views.js b/apps/fauxton/app/addons/verifyinstall/views.js
new file mode 100644
index 0000000..eb6dac4
--- /dev/null
+++ b/apps/fauxton/app/addons/verifyinstall/views.js
@@ -0,0 +1,127 @@
+// 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",
+  "addons/verifyinstall/resources",
+],
+function(app, FauxtonAPI, VerifyInstall) {
+
+  VerifyInstall.Main = FauxtonAPI.View.extend({
+    template: 'addons/verifyinstall/templates/main',
+
+    events: {
+      "click #start": "startTest"
+    },
+
+    initialize: function (options) {
+      _.bindAll(this);
+    },
+
+    setPass: function (id) {
+      this.$('#' + id).html('&#10003;');
+    },
+
+    setError: function (id, msg) {
+      this.$('#' + id).html('&#x2717;');
+      FauxtonAPI.addNotification({
+        msg: 'Error: ' + msg,
+        type: 'error',
+        selector: '#error'
+      });
+    },
+
+    complete: function () {
+      FauxtonAPI.addNotification({
+        msg: 'Success! You Couchdb install is working. Time to Relax',
+        type: 'success',
+        selector: '#error'
+      });
+    },
+
+    enableButton: function () {
+      this.$('#start').removeAttr('disabled').text('Verify Installation');
+    },
+
+    disableButton: function () {
+      this.$('#start').attr('disabled','disabled').text('Verifying');
+    },
+
+    formatError: function (id) {
+      var enableButton = this.enableButton,
+          setError = this.setError;
+
+      return function (xhr, error, reason) {
+        enableButton();
+
+        if (!xhr) { return; }
+
+        setError(id, JSON.parse(xhr.responseText).reason);
+      };
+    },
+
+    
+    startTest: function () {
+      this.disableButton();
+      this.$('.status').text('');
+
+      var testProcess = VerifyInstall.testProcess,
+          setPass = this.setPass,
+          complete = this.complete,
+          setError = this.setError,
+          formatError = this.formatError;
+
+      testProcess.setup()
+      .then(function () {
+        return testProcess.saveDB();
+      }, formatError('create-database'))
+      .then(function () {
+        setPass('create-database');
+        return testProcess.saveDoc();
+      }, formatError('create-document'))
+      .then(function () {
+        setPass('create-document');
+        return testProcess.updateDoc();
+      }, formatError('update-document'))
+      .then(function () {
+        setPass('update-document');
+        return testProcess.destroyDoc();
+      }, formatError('delete-document'))
+      .then(function () {
+        setPass('delete-document');
+        return testProcess.setupView();
+      }, formatError('create-view'))
+      .then(function () {
+        return testProcess.testView();
+      }, formatError('create-view'))
+      .then(function () {
+        setPass('create-view');
+        return testProcess.setupReplicate();
+      }, formatError('create-view'))
+      .then(function () {
+        return testProcess.testReplicate();
+      }, formatError('replicate'))
+      .then(function () {
+          setPass('replicate');
+          complete();
+          testProcess.removeDBs();
+      }, formatError('replicate'));
+
+      this.enableButton();
+    }
+  });
+
+
+  return VerifyInstall;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/api.js b/apps/fauxton/app/api.js
new file mode 100644
index 0000000..5ad032a
--- /dev/null
+++ b/apps/fauxton/app/api.js
@@ -0,0 +1,558 @@
+// 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
+       "modules/fauxton/base",
+       "spin"
+],
+
+function(app, Fauxton) {
+  var FauxtonAPI = app.module();
+
+  FauxtonAPI.moduleExtensions = {
+    Routes: {
+    }
+  };
+
+  FauxtonAPI.addonExtensions = {
+    initialize: function() {}
+  };
+
+  // List of JSHINT errors to ignore
+  // Gets around problem of anonymous functions not being a valid statement
+  FauxtonAPI.excludedViewErrors = [
+    "Missing name in function declaration.",
+    "['{a}'] is better written in dot notation."
+  ];
+
+  FauxtonAPI.isIgnorableError = function(msg) {
+    return _.contains(FauxtonAPI.excludedViewErrors, msg);
+  };
+
+  FauxtonAPI.View = Backbone.View.extend({
+    // This should return an array of promises, an empty array, or null
+    establish: function() {
+      return null;
+    },
+
+    loaderClassname: 'loader',
+
+    disableLoader: false,
+
+    forceRender: function () {
+      this.hasRendered = false;
+    }
+  });
+
+  FauxtonAPI.navigate = function(url, _opts) {
+    var options = _.extend({trigger: true}, _opts );
+    app.router.navigate(url,options);
+  };
+
+  FauxtonAPI.beforeUnload = function () {
+    app.router.beforeUnload.apply(app.router, arguments);
+  };
+
+  FauxtonAPI.removeBeforeUnload = function () {
+    app.router.removeBeforeUnload.apply(app.router, arguments);
+  };
+
+  FauxtonAPI.addHeaderLink = function(link) {
+    app.masterLayout.navBar.addLink(link);
+  };
+
+  FauxtonAPI.removeHeaderLink = function(link) {
+    app.masterLayout.navBar.removeLink(link);
+  };
+
+  FauxtonAPI.Deferred = function() {
+    return $.Deferred();
+  };
+
+  FauxtonAPI.when = function (deferreds) {
+    if (deferreds instanceof Array) {
+      return $.when.apply(null, deferreds);
+    }
+
+    return $.when(deferreds);
+  };
+
+  FauxtonAPI.addRoute = function(route) {
+    app.router.route(route.route, route.name, route.callback);
+  };
+
+  FauxtonAPI.triggerRouteEvent = function (routeEvent, args) {
+    app.router.triggerRouteEvent("route:"+routeEvent, args);
+  };
+
+  FauxtonAPI.module = function(extra) {
+    return app.module(_.extend(FauxtonAPI.moduleExtensions, extra));
+  };
+
+  FauxtonAPI.addon = function(extra) {
+    return FauxtonAPI.module(FauxtonAPI.addonExtensions, extra);
+  };
+
+  FauxtonAPI.addNotification = function(options) {
+    options = _.extend({
+      msg: "Notification Event Triggered!",
+      type: "info",
+      selector: "#global-notifications"
+    }, options);
+    var view = new Fauxton.Notification(options);
+
+    return view.renderNotification();
+  };
+
+  FauxtonAPI.UUID = Backbone.Model.extend({
+    initialize: function(options) {
+      options = _.extend({count: 1}, options);
+      this.count = options.count;
+    },
+
+    url: function() {
+      return app.host + "/_uuids?count=" + this.count;
+    },
+
+    next: function() {
+      return this.get("uuids").pop();
+    }
+  });
+
+  FauxtonAPI.Session = Backbone.Model.extend({
+    url: '/_session',
+
+    user: function () {
+      var userCtx = this.get('userCtx');
+
+      if (!userCtx || !userCtx.name) { return null; }
+
+      return {
+        name: userCtx.name,
+        roles: userCtx.roles
+      };
+    },
+
+    fetchOnce: function (opt) {
+      var options = _.extend({}, opt);
+
+      if (!this._deferred || this._deferred.state() === "rejected" || options.forceFetch ) {
+        this._deferred = this.fetch();
+      }
+
+      return this._deferred;
+    },
+
+    fetchUser: function (opt) {
+      var that = this,
+      currentUser = this.user();
+
+      return this.fetchOnce(opt).then(function () {
+        var user = that.user();
+
+        // Notify anyone listening on these events that either a user has changed
+        // or current user is the same
+        if (currentUser !== user) {
+          that.trigger('session:userChanged');
+        } else {
+          that.trigger('session:userFetched');
+        }
+
+        // this will return the user as a value to all function that calls done on this
+        // eg. session.fetchUser().done(user) { .. do something with user ..}
+        return user; 
+      });
+    }
+  });
+
+  FauxtonAPI.setSession = function (newSession) {
+    app.session = FauxtonAPI.session = newSession;
+    return FauxtonAPI.session.fetchUser();
+  };
+
+  FauxtonAPI.setSession(new FauxtonAPI.Session());
+
+  // This is not exposed externally as it should not need to be accessed or overridden
+  var Auth = function (options) {
+    this._options = options;
+    this.initialize.apply(this, arguments);
+  };
+
+  // Piggy-back on Backbone's self-propagating extend function,
+  Auth.extend = Backbone.Model.extend;
+
+  _.extend(Auth.prototype, Backbone.Events, {
+    authDeniedCb: function() {},
+
+    initialize: function() {
+      var that = this;
+    },
+
+    authHandlerCb : function (roles) {
+      var deferred = $.Deferred();
+      deferred.resolve();
+      return deferred;
+    },
+
+    registerAuth: function (authHandlerCb) {
+      this.authHandlerCb = authHandlerCb;
+    },
+
+    registerAuthDenied: function (authDeniedCb) {
+      this.authDeniedCb = authDeniedCb;
+    },
+
+    checkAccess: function (roles) {
+      var requiredRoles = roles || [],
+      that = this;
+
+      return FauxtonAPI.session.fetchUser().then(function (user) {
+        return FauxtonAPI.when(that.authHandlerCb(FauxtonAPI.session, requiredRoles));
+      });
+    }
+  });
+
+  FauxtonAPI.auth = new Auth();
+
+  FauxtonAPI.RouteObject = function(options) {
+    this._options = options;
+
+    this._configure(options || {});
+    this.initialize.apply(this, arguments);
+    this.addEvents();
+  };
+
+  var broadcaster = {};
+  _.extend(broadcaster, Backbone.Events);
+
+  FauxtonAPI.RouteObject.on = function (eventName, fn) {
+    broadcaster.on(eventName, fn); 
+  };
+  
+  /* How Route Object events work
+   To listen to a specific route objects events:
+
+   myRouteObject = FauxtonAPI.RouteObject.extend({
+    events: {
+      "beforeRender": "beforeRenderEvent"
+    },
+
+    beforeRenderEvent: function (view, selector) {
+      console.log('Hey, beforeRenderEvent triggered',arguments);
+    },
+   });
+
+    It is also possible to listen to events triggered from all Routeobjects. 
+    This is great for more general things like adding loaders, hooks.
+
+    FauxtonAPI.RouteObject.on('beforeRender', function (routeObject, view, selector) {
+      console.log('hey, this will trigger when any routeobject renders a view');
+    });
+
+   Current Events to subscribe to:
+    * beforeFullRender -- before a full render is being done
+    * beforeEstablish -- before the routeobject calls establish
+    * AfterEstablish -- after the routeobject has run establish
+    * beforeRender -- before a view is rendered
+    * afterRender -- a view is finished being rendered
+    * renderComplete -- all rendering is complete
+    
+  */
+
+  // Piggy-back on Backbone's self-propagating extend function
+  FauxtonAPI.RouteObject.extend = Backbone.Model.extend;
+
+  var routeObjectOptions = ["views", "routes", "events", "roles", "crumbs", "layout", "apiUrl", "establish"];
+
+  _.extend(FauxtonAPI.RouteObject.prototype, Backbone.Events, {
+    // Should these be default vals or empty funcs?
+    views: {},
+    routes: {},
+    events: {},
+    crumbs: [],
+    layout: "with_sidebar",
+    apiUrl: null,
+    disableLoader: false,
+    loaderClassname: 'loader',
+    renderedState: false,
+    establish: function() {},
+    route: function() {},
+    roles: [],
+    initialize: function() {}
+  }, {
+
+    renderWith: function(route, masterLayout, args) {
+      var routeObject = this,
+          triggerBroadcast = _.bind(this.triggerBroadcast, this);
+
+      // Only want to redo the template if its a full render
+      if (!this.renderedState) {
+        masterLayout.setTemplate(this.layout);
+        triggerBroadcast('beforeFullRender');
+        $('#primary-navbar li').removeClass('active');
+
+        if (this.selectedHeader) {
+          app.selectedHeader = this.selectedHeader;
+          $('#primary-navbar li[data-nav-name="' + this.selectedHeader + '"]').addClass('active');
+        }
+      }
+
+      masterLayout.clearBreadcrumbs();
+      var crumbs = this.get('crumbs');
+
+      if (crumbs.length) {
+        masterLayout.setBreadcrumbs(new Fauxton.Breadcrumbs({
+          crumbs: crumbs
+        }));
+      }
+
+      triggerBroadcast('beforeEstablish');
+      FauxtonAPI.when(this.establish()).then(function(resp) {
+        triggerBroadcast('afterEstablish');
+        _.each(routeObject.getViews(), function(view, selector) {
+          if(view.hasRendered) { 
+            triggerBroadcast('viewHasRendered', view, selector);
+            return;
+          }
+
+          triggerBroadcast('beforeRender', view, selector);
+          FauxtonAPI.when(view.establish()).then(function(resp) {
+            masterLayout.setView(selector, view);
+
+            masterLayout.renderView(selector);
+            triggerBroadcast('afterRender', view, selector);
+            }, function(resp) {
+              view.establishError = {
+                error: true,
+                reason: resp
+              };
+
+              if (resp) { 
+                var errorText = JSON.parse(resp.responseText).reason;
+                FauxtonAPI.addNotification({
+                  msg: 'An Error occurred: ' + errorText,
+                  type: 'error',
+                  clear: true
+                });
+              }
+
+              masterLayout.renderView(selector);
+          });
+
+        });
+      }.bind(this), function (resp) {
+          if (!resp) { return; }
+          FauxtonAPI.addNotification({
+                msg: 'An Error occurred' + JSON.parse(resp.responseText).reason,
+                type: 'error',
+                clear: true
+          });
+      });
+
+      if (this.get('apiUrl')){
+        masterLayout.apiBar.update(this.get('apiUrl'));
+      } else {
+        masterLayout.apiBar.hide();
+      }
+
+      // Track that we've done a full initial render
+      this.renderedState = true;
+      triggerBroadcast('renderComplete');
+    },
+
+    triggerBroadcast: function (eventName) {
+      var args = Array.prototype.slice.call(arguments);
+      this.trigger.apply(this, args);
+
+      args.splice(0,1, eventName, this);
+      broadcaster.trigger.apply(broadcaster, args);
+    },
+
+    get: function(key) {
+      return _.isFunction(this[key]) ? this[key]() : this[key];
+    },
+
+    addEvents: function(events) {
+      events = events || this.get('events');
+      _.each(events, function(method, event) {
+        if (!_.isFunction(method) && !_.isFunction(this[method])) {
+          throw new Error("Invalid method: "+method);
+        }
+        method = _.isFunction(method) ? method : this[method];
+
+        this.on(event, method);
+      }, this);
+    },
+
+    _configure: function(options) {
+      _.each(_.intersection(_.keys(options), routeObjectOptions), function(key) {
+        this[key] = options[key];
+      }, this);
+    },
+
+    getView: function(selector) {
+      return this.views[selector];
+    },
+
+    setView: function(selector, view) {
+      this.views[selector] = view;
+      return view;
+    },
+
+    getViews: function() {
+      return this.views;
+    },
+
+    removeViews: function () {
+      _.each(this.views, function (view, selector) {
+        view.remove();
+        delete this.views[selector];
+      }, this);
+    },
+
+    getRouteUrls: function () {
+      return _.keys(this.get('routes'));
+    },
+
+    hasRoute: function (route) {
+      if (this.get('routes')[route]) {
+        return true;
+      }
+      return false;
+    },
+
+    routeCallback: function (route, args) {
+      var routes = this.get('routes'),
+      routeObj = routes[route],
+      routeCallback;
+
+      if (typeof routeObj === 'object') {
+        routeCallback = this[routeObj.route];
+      } else {
+        routeCallback = this[routeObj];
+      }
+
+      routeCallback.apply(this, args);
+    },
+
+    getRouteRoles: function (routeUrl) {
+      var route = this.get('routes')[routeUrl];
+
+      if ((typeof route === 'object') && route.roles) {
+        return route.roles; 
+      }
+
+      return this.roles;
+    }
+
+  });
+
+  // We could look at moving the spinner code out to its own module
+  var routeObjectSpinner;
+  FauxtonAPI.RouteObject.on('beforeEstablish', function (routeObject) {
+    if (!routeObject.disableLoader){ 
+      var opts = {
+        lines: 16, // The number of lines to draw
+        length: 8, // The length of each line
+        width: 4, // The line thickness
+        radius: 12, // The radius of the inner circle
+        color: '#333', // #rbg or #rrggbb
+        speed: 1, // Rounds per second
+        trail: 10, // Afterglow percentage
+        shadow: false // Whether to render a shadow
+     };
+
+     if (!$('.spinner').length) {
+       $('<div class="spinner"></div>')
+        .appendTo('#app-container');
+     }
+
+     routeObjectSpinner = new Spinner(opts).spin();
+     $('.spinner').append(routeObjectSpinner.el);
+   }
+  });
+
+  var removeRouteObjectSpinner = function () {
+    if (routeObjectSpinner) {
+      routeObjectSpinner.stop();
+      $('.spinner').remove();
+    }
+  };
+
+  var removeViewSpinner = function () {
+    if (viewSpinner){
+      viewSpinner.stop();
+      $('.spinner').remove();
+    }
+  };
+
+  var viewSpinner;
+  FauxtonAPI.RouteObject.on('beforeRender', function (routeObject, view, selector) {
+    removeRouteObjectSpinner();
+
+    if (!view.disableLoader){ 
+      var opts = {
+        lines: 16, // The number of lines to draw
+        length: 8, // The length of each line
+        width: 4, // The line thickness
+        radius: 12, // The radius of the inner circle
+        color: '#333', // #rbg or #rrggbb
+        speed: 1, // Rounds per second
+        trail: 10, // Afterglow percentage
+        shadow: false // Whether to render a shadow
+      };
+
+      viewSpinner = new Spinner(opts).spin();
+      $('<div class="spinner"></div>')
+        .appendTo(selector)
+        .append(viewSpinner.el);
+    }
+  });
+
+  FauxtonAPI.RouteObject.on('afterRender', function (routeObject, view, selector) {
+    removeViewSpinner();
+  });
+
+  FauxtonAPI.RouteObject.on('viewHasRendered', function () {
+    removeViewSpinner();
+    removeRouteObjectSpinner();
+  });
+
+  var extensions = _.extend({}, Backbone.Events);
+  // Can look at a remove function later.
+  FauxtonAPI.registerExtension = function (name, view) {
+    if (!extensions[name]) {
+      extensions[name] = [];
+    }
+
+    extensions.trigger('add:' + name, view);
+    extensions[name].push(view);
+  };
+
+  FauxtonAPI.getExtensions = function (name) {
+    var views = extensions[name];
+
+    if (!views) {
+      views = [];
+    }
+
+    return views;
+  };
+
+  FauxtonAPI.extensions = extensions;
+
+  app.fauxtonAPI = FauxtonAPI;
+  return app.fauxtonAPI;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/app.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/app.js b/apps/fauxton/app/app.js
new file mode 100644
index 0000000..0a51410
--- /dev/null
+++ b/apps/fauxton/app/app.js
@@ -0,0 +1,122 @@
+// 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([
+  // Application.
+  "initialize",
+
+  // Libraries
+  "jquery",
+  "lodash",
+  "backbone",
+  "bootstrap",
+
+  "helpers",
+  "mixins",
+
+   // Plugins.
+  "plugins/backbone.layoutmanager",
+  "plugins/jquery.form"
+
+],
+
+function(app, $, _, Backbone, Bootstrap, Helpers, Mixins) {
+
+   // Make sure we have a console.log
+  if (typeof console == "undefined") {
+    console = {
+      log: function(){}
+    };
+  }
+
+  // Provide a global location to place configuration settings and module
+  // creation also mix in Backbone.Events
+  _.extend(app, Backbone.Events, {
+    mixins: Mixins,
+
+    renderView: function(baseView, selector, view, options, callback) {
+      baseView.setView(selector, new view(options)).render().then(callback);
+    },
+
+    // Create a custom object with a nested Views object.
+    module: function(additionalProps) {
+      return _.extend({ Views: {} }, additionalProps);
+    },
+
+    // Thanks to: http://stackoverflow.com/a/2880929
+    getParams: function(queryString) {
+      if (queryString) {
+        // I think this could be combined into one if
+        if (queryString.substring(0,1) === "?") {
+          queryString = queryString.substring(1);
+        } else if (queryString.indexOf('?') > -1) {
+          queryString = queryString.split('?')[1];
+        }
+      }
+      var hash = window.location.hash.split('?')[1];
+      queryString = queryString || hash || window.location.search.substring(1);
+      var match,
+      urlParams = {},
+      pl     = /\+/g,  // Regex for replacing addition symbol with a space
+      search = /([^&=]+)=?([^&]*)/g,
+      decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
+      query  = queryString;
+
+      if (queryString) {
+        while ((match = search.exec(query))) {
+          urlParams[decode(match[1])] = decode(match[2]);
+        }
+      }
+
+      return urlParams;
+    }
+  });
+
+  // Localize or create a new JavaScript Template object.
+  var JST = window.JST = window.JST || {};
+
+  // Configure LayoutManager with Backbone Boilerplate defaults.
+  Backbone.Layout.configure({
+    // Allow LayoutManager to augment Backbone.View.prototype.
+    manage: true,
+
+    prefix: "app/",
+
+    // Inject app/helper.js for shared functionality across all html templates
+    renderTemplate: function(template, context) {
+      return template(_.extend(Helpers, context));
+    },
+
+    fetchTemplate: function(path) {
+      // Initialize done for use in async-mode
+      var done;
+
+      // Concatenate the file extension.
+      path = path + ".html";
+
+      // If cached, use the compiled template.
+      if (JST[path]) {
+        return JST[path];
+      } else {
+        // Put fetch into `async-mode`.
+        done = this.async();
+        // Seek out the template asynchronously.
+        return $.ajax({ url: app.root + path }).then(function(contents) {
+          done(JST[path] = _.template(contents));
+        });
+      }
+    }
+  });
+
+
+  return app;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/config.js b/apps/fauxton/app/config.js
new file mode 100644
index 0000000..2977969
--- /dev/null
+++ b/apps/fauxton/app/config.js
@@ -0,0 +1,60 @@
+// 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.
+
+// Set the require.js configuration for your application.
+require.config({
+
+  // Initialize the application with the main application file.
+  deps: ["main"],
+
+  paths: {
+    // JavaScript folders.
+    libs: "../assets/js/libs",
+    plugins: "../assets/js/plugins",
+
+    // Libraries.
+    jquery: "../assets/js/libs/jquery",
+    lodash: "../assets/js/libs/lodash",
+    backbone: "../assets/js/libs/backbone",
+    "backbone.layoutmanger": "../assets/js/plugins/backbone.layoutmanager",
+    bootstrap: "../assets/js/libs/bootstrap",
+    spin: "../assets/js/libs/spin.min",
+    d3: "../assets/js/libs/d3",
+    "nv.d3": "../assets/js/libs/nv.d3",
+    "ace":"../assets/js/libs/ace"
+  },
+
+  baseUrl: '/',
+
+  map: {
+    "*": {
+      'underscore': 'lodash'
+    }
+  },
+
+  shim: {
+    // Backbone library depends on lodash and jQuery.
+    backbone: {
+      deps: ["lodash", "jquery"],
+      exports: "Backbone"
+    },
+
+    bootstrap: {
+      deps: ["jquery"],
+      exports: "Bootstrap"
+    },
+
+    "plugins/prettify": [],
+
+    "plugins/jquery.form": ["jquery"]
+  }
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/helpers.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/helpers.js b/apps/fauxton/app/helpers.js
new file mode 100644
index 0000000..73a37ca
--- /dev/null
+++ b/apps/fauxton/app/helpers.js
@@ -0,0 +1,78 @@
+// 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.
+
+
+// This file creates a set of helper functions that will be loaded for all html
+// templates. These functions should be self contained and not rely on any 
+// external dependencies as they are loaded prior to the application. We may
+// want to change this later, but for now this should be thought of as a
+// "purely functional" helper system.
+
+
+define([
+  "d3"
+],
+
+function() {
+
+  var Helpers = {};
+
+  Helpers.imageUrl = function(path) {
+    // TODO: add dynamic path for different deploy targets
+    return path;
+  };
+
+
+  // Get the URL for documentation, wiki, wherever we store it.
+  // update the URLs in documentation_urls.js 
+  Helpers.docs =  {
+    "docs": "http://docs.couchdb.org/en/latest/intro/api.html#documents",
+    "all_dbs": "http://docs.couchdb.org/en/latest/api/server/common.html?highlight=all_dbs#get--_all_dbs",
+    "replication_doc": "http://docs.couchdb.org/en/latest/replication/replicator.html#basics",
+    "design_doc": "http://docs.couchdb.org/en/latest/couchapp/ddocs.html#design-docs",
+    "view_functions": "http://docs.couchdb.org/en/latest/couchapp/ddocs.html#view-functions",
+    "map_functions": "http://docs.couchdb.org/en/latest/couchapp/ddocs.html#map-functions",
+    "reduce_functions": "http://docs.couchdb.org/en/latest/couchapp/ddocs.html#reduce-and-rereduce-functions",
+    "api_reference": "http://docs.couchdb.org/en/latest/http-api.html",
+    "database_permission": "http://docs.couchdb.org/en/latest/api/database/security.html#db-security",
+    "stats": "http://docs.couchdb.org/en/latest/api/server/common.html?highlight=stats#get--_stats",
+    "_active_tasks": "http://docs.couchdb.org/en/latest/api/server/common.html?highlight=stats#active-tasks",
+    "log": "http://docs.couchdb.org/en/latest/api/server/common.html?highlight=stats#log",
+    "config": "http://docs.couchdb.org/en/latest/config/index.html",
+    "views": "http://docs.couchdb.org/en/latest/intro/overview.html#views"
+  }; 
+  
+  Helpers.getDocUrl = function(docKey){
+    return Helpers.docs[docKey] || '#';
+  };
+
+  // File size pretty printing, taken from futon.format.js
+  Helpers.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];
+    };
+
+  Helpers.formatDate = function(timestamp){
+    format = d3.time.format("%b. %e at %H:%M%p"); 
+    return format(new Date(timestamp*1000));
+  };
+
+  return Helpers;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/initialize.js.underscore
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/initialize.js.underscore b/apps/fauxton/app/initialize.js.underscore
new file mode 100644
index 0000000..02689a1
--- /dev/null
+++ b/apps/fauxton/app/initialize.js.underscore
@@ -0,0 +1,33 @@
+// 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.
+
+/*
+ * ::WARNING::
+ * THIS IS A GENERATED FILE. DO NOT EDIT.
+ */
+
+
+define([],
+function() {
+  // Provide a global location to place configuration settings and module
+  // creation.
+  var app = {
+    // The root path to run the application.
+    root: "<%= root %>",
+    version: "<%= version %>",
+    // Host is used as prefix for urls
+    host: "<%= host %>" ,
+  };
+
+  return app; 
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/load_addons.js.underscore
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/load_addons.js.underscore b/apps/fauxton/app/load_addons.js.underscore
new file mode 100644
index 0000000..9686ad7
--- /dev/null
+++ b/apps/fauxton/app/load_addons.js.underscore
@@ -0,0 +1,27 @@
+// 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.
+
+
+/*
+ * ::WARNING::
+ * THIS IS A GENERATED FILE. DO NOT EDIT.
+ */
+define([
+  <%= '"' + deps.join('","') + '"' %>
+],
+function() {
+  var LoadAddons = {
+    addons: arguments
+  };
+
+  return LoadAddons;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/main.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/main.js b/apps/fauxton/app/main.js
new file mode 100644
index 0000000..6fe9991
--- /dev/null
+++ b/apps/fauxton/app/main.js
@@ -0,0 +1,48 @@
+// 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.
+
+require([
+        // Application.
+        "app",
+
+        // Main Router.
+        "router"
+],
+
+function(app, Router) {
+
+  // Define your master router on the application namespace and trigger all
+  // navigation from this instance.
+  app.router = new Router();
+  // Trigger the initial route and enable HTML5 History API support, set the
+  // root folder to '/' by default.  Change in app.js.
+  Backbone.history.start({ pushState: false, root: app.root });
+  // All navigation that is relative should be passed through the navigate
+  // method, to be processed by the router. If the link has a `data-bypass`
+  // attribute, bypass the delegation completely.
+  $(document).on("click", "a:not([data-bypass])", function(evt) {
+    // Get the absolute anchor href.
+    var href = { prop: $(this).prop("href"), attr: $(this).attr("href") };
+    // Get the absolute root.
+    var root = location.protocol + "//" + location.host + app.root;
+    // Ensure the root is part of the anchor href, meaning it's relative.
+    if (href.prop && href.prop.slice(0, root.length) === root) {
+      // Stop the default event to ensure the link will not cause a page
+      // refresh.
+      evt.preventDefault();
+
+      //User app navigate so that navigate goes through a central place
+      app.router.navigate(href.attr, true);
+    }
+
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/mixins.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/mixins.js b/apps/fauxton/app/mixins.js
new file mode 100644
index 0000000..15af3ee
--- /dev/null
+++ b/apps/fauxton/app/mixins.js
@@ -0,0 +1,65 @@
+// 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.
+
+
+// This file creates a set of helper functions that will be loaded for all html
+// templates. These functions should be self contained and not rely on any 
+// external dependencies as they are loaded prior to the application. We may
+// want to change this later, but for now this should be thought of as a
+// "purely functional" helper system.
+
+
+define([
+  "jquery",
+  "lodash"
+],
+
+function($, _ ) {
+
+  var mixins = {};
+
+  var onWindowResize = {};
+   
+  mixins.addWindowResize = function(fun, key){
+    onWindowResize[key]=fun;
+    // You shouldn't need to call it here. Just define it at startup and each time it will loop 
+    // through all the functions in the hash.
+    //app.initWindowResize();
+  };
+   
+  mixins.removeWindowResize = function(key){
+    delete onWindowResize[key];
+    mixins.initWindowResize();
+  };
+   
+  mixins.initWindowResize = function(){
+  //when calling this it should be overriding what was called previously
+    window.onresize = function(e) {
+       // could do this instead of the above for loop
+      _.each(onWindowResize, function (fn) {
+        fn();
+      });
+    };
+  };
+
+  mixins.removeSpecialCharacters = function(name){
+    return name.replace(/[^\w\s]/gi,"");
+  };
+
+  mixins.safeURLName = function(name){
+    var checkforBad = name.match(/[\$\-/_,+-]/g);
+    return (checkforBad !== null)?encodeURIComponent(name):name;
+  };
+
+  return mixins;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/add91738/apps/fauxton/app/modules/databases/base.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/modules/databases/base.js b/apps/fauxton/app/modules/databases/base.js
new file mode 100644
index 0000000..6ff12c6
--- /dev/null
+++ b/apps/fauxton/app/modules/databases/base.js
@@ -0,0 +1,37 @@
+// 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/add91738/apps/fauxton/app/modules/databases/resources.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/modules/databases/resources.js b/apps/fauxton/app/modules/databases/resources.js
new file mode 100644
index 0000000..f3bde80
--- /dev/null
+++ b/apps/fauxton/app/modules/databases/resources.js
@@ -0,0 +1,193 @@
+// 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/add91738/apps/fauxton/app/modules/databases/routes.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/modules/databases/routes.js b/apps/fauxton/app/modules/databases/routes.js
new file mode 100644
index 0000000..ca3d640
--- /dev/null
+++ b/apps/fauxton/app/modules/databases/routes.js
@@ -0,0 +1,69 @@
+// 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/add91738/apps/fauxton/app/modules/databases/views.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/modules/databases/views.js b/apps/fauxton/app/modules/databases/views.js
new file mode 100644
index 0000000..dbeb475
--- /dev/null
+++ b/apps/fauxton/app/modules/databases/views.js
@@ -0,0 +1,255 @@
+// 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/add91738/apps/fauxton/app/modules/documents/base.js
----------------------------------------------------------------------
diff --git a/apps/fauxton/app/modules/documents/base.js b/apps/fauxton/app/modules/documents/base.js
new file mode 100644
index 0000000..96e4ada
--- /dev/null
+++ b/apps/fauxton/app/modules/documents/base.js
@@ -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.
+
+define([
+  "app",
+
+  "api",
+
+  // Modules
+  "modules/documents/routes"
+],
+
+function(app, FauxtonAPI, Documents) {
+  return Documents;
+});


Mime
View raw message