You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2014/02/03 11:12:25 UTC

[01/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Updated Branches:
  refs/heads/paginate-api-options cbd201516 -> 5d2a6f9c9 (forced update)


Fix for beautify to work with require.js


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/6d171cbe
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/6d171cbe
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/6d171cbe

Branch: refs/heads/paginate-api-options
Commit: 6d171cbecc3338f11d72c5aa3218d791d6e2363a
Parents: bcb6e04
Author: suelockwood <de...@apache.org>
Authored: Tue Jan 28 10:39:05 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Tue Jan 28 11:31:37 2014 -0500

----------------------------------------------------------------------
 .../addons/documents/templates/view_editor.html    |  4 ++--
 src/fauxton/app/addons/documents/views.js          |  4 ++--
 src/fauxton/assets/js/plugins/beautify.js          | 17 ++++-------------
 3 files changed, 8 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/6d171cbe/src/fauxton/app/addons/documents/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/view_editor.html b/src/fauxton/app/addons/documents/templates/view_editor.html
index bf31ba2..d02971e 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -41,7 +41,7 @@ the License.
             <div class="js-editor" id="map-function"><%= langTemplates.map %></div>
             <% } else { %>
             <div class="js-editor" id="map-function"><%- ddoc.get('views')[viewName].map %></div>
-            <button class="beautify beautify_map button hidden beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it.">beautify this code</button>
+            <button class="beautify beautify_map button hide beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it.">beautify this code</button>
             <% } %>
           </div>
 
@@ -64,7 +64,7 @@ the License.
             <div class="js-editor" id="reduce-function"><%= langTemplates.reduce %></div>
             <% } else { %>
             <div class="js-editor" id="reduce-function"><%- ddoc.get('views')[viewName].reduce %></div>
-            <button class="beautify beautify_reduce button hidden beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it.">beautify this code</button>
+            <button class="beautify beautify_reduce button hide beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it.">beautify this code</button>
             <% } %>
           </div>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6d171cbe/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index e2f5578..9516355 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -1630,7 +1630,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.reduceEditor.render();
 
       if (this.reduceEditor.getLines() === 1){
-        this.$('.beautify_reduce').removeClass("hidden");
+        this.$('.beautify_reduce').removeClass("hide");
         $('.beautify-tooltip').tooltip();
       }
     },
@@ -1709,7 +1709,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.reduceEditor && this.reduceEditor.editSaved();
 
       if (this.mapEditor.getLines() === 1){
-        this.$('.beautify_map').removeClass("hidden");
+        this.$('.beautify_map').removeClass("hide");
         $('.beautify-tooltip').tooltip();
       }
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6d171cbe/src/fauxton/assets/js/plugins/beautify.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/beautify.js b/src/fauxton/assets/js/plugins/beautify.js
index e934fe3..07b6617 100644
--- a/src/fauxton/assets/js/plugins/beautify.js
+++ b/src/fauxton/assets/js/plugins/beautify.js
@@ -1611,19 +1611,10 @@
     }
 
 
-    if (typeof define === "function") {
-        // Add support for require.js
-        if (typeof define.amd === "undefined") {
-            define(function(require, exports, module) {
-                exports.js_beautify = js_beautify;
-            });
-        } else {
-            // if is AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
-            define([], function() {
-                return js_beautify;
-            });
-        }
-
+    if (typeof define === "function" && define.amd) {
+        define([], function() {
+            return js_beautify;
+        });
     } else if (typeof exports !== "undefined") {
         // Add support for CommonJS. Just put this file somewhere on your require.paths
         // and you will be able to `var js_beautify = require("beautify").js_beautify`.


[19/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
add per page view limit and new advanced options


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/344f3727
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/344f3727
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/344f3727

Branch: refs/heads/paginate-api-options
Commit: 344f3727ace2875cb444f7912f3bfe635995232b
Parents: b68eb17
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jan 28 16:30:38 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Feb 3 10:26:18 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/databases/resources.js   |   2 +-
 .../addons/documents/assets/less/documents.less |   8 +
 src/fauxton/app/addons/documents/resources.js   |  30 ++-
 src/fauxton/app/addons/documents/routes.js      |  16 +-
 .../documents/templates/advanced_options.html   |   6 +-
 .../templates/advanced_options_menu.html        |  46 +++++
 .../documents/templates/all_docs_layout.html    |   2 +
 .../documents/templates/all_docs_number.html    |  22 +-
 .../addons/documents/templates/view_editor.html |   1 +
 src/fauxton/app/addons/documents/views.js       | 207 +++++++++++++------
 src/fauxton/app/addons/fauxton/components.js    |  77 ++++---
 11 files changed, 312 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/resources.js b/src/fauxton/app/addons/databases/resources.js
index 1b55f88..1b65f97 100644
--- a/src/fauxton/app/addons/databases/resources.js
+++ b/src/fauxton/app/addons/databases/resources.js
@@ -22,7 +22,7 @@ define([
 function(app, FauxtonAPI, Documents) {
   var Databases = FauxtonAPI.addon();
 
-  Databases.DocLimit = 20;
+  Databases.DocLimit = 100;
 
   Databases.Model = Backbone.Model.extend({
     initialize: function(options) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 6f462ef..c1f0ed8 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -23,6 +23,14 @@ button.beautify {
 	margin-top: 20px;
 }
 
+#per-page {
+  float: right;
+
+  #select-per-page {
+    margin-top: 10px;
+  }
+  
+}
 
 /** used in all_docs_list.html **/
 .view {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index 831d5e3..cf1b4aa 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -281,7 +281,7 @@ function(app, FauxtonAPI) {
       this.database = options.database;
       this.params = options.params;
       this.skipFirstItem = false;
-
+      this.totalRowsToPaginate = 100;
       this.on("remove",this.decrementTotalRows , this);
     },
 
@@ -314,7 +314,17 @@ function(app, FauxtonAPI) {
       });
     },
 
-    urlNextPage: function (num, lastId) {
+    updateLimit: function (limit) {
+      if (this.params.startkey_docid && this.params.startkey) {
+        //we are paginating so set limit + 1
+        this.params.limit = limit + 1;
+        return;
+      }
+
+      this.params.limit = limit;
+    },
+
+    nextPage: function (num, lastId) {
       if (!lastId) {
         var doc = this.last();
 
@@ -333,7 +343,7 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
-    urlPreviousPage: function (num, params) {
+    previousPage: function (num, params) {
       if (params) { 
         this.params = params;
       } else {
@@ -430,7 +440,7 @@ function(app, FauxtonAPI) {
       return url.join("/") + query;
     },
 
-    urlNextPage: function (num, lastId) {
+    nextPage: function (num, lastId) {
       if (!lastId) {
         lastDoc = this.last();
       }
@@ -445,7 +455,7 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
-     urlPreviousPage: function (num, params) {
+     previousPage: function (num, params) {
       if (params) { 
         this.params = params;
       } else {
@@ -456,6 +466,16 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
+    updateLimit: function (limit) {
+      if (this.params.startkey_docid && this.params.startkey) {
+        //we are paginating so set limit + 1
+        this.params.limit = limit + 1;
+        return;
+      }
+
+      this.params.limit = limit;
+    },
+
     recordStart: function () {
       if (this.viewMeta.offset === 0) {
         return 1;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
index 1510485..0c95bcf 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -155,7 +155,8 @@ function(app, FauxtonAPI, Documents, Databases) {
       "route:updateAllDocs": "updateAllDocsFromView",
       "route:updatePreviewDocs": "updateAllDocsFromPreview",
       "route:reloadDesignDocs": "reloadDesignDocs",
-      "route:paginate": "paginate"
+      "route:paginate": "paginate",
+      "route:perPageChange": "perPageChange"
     },
 
     initialize: function (route, masterLayout, options) {
@@ -304,7 +305,6 @@ function(app, FauxtonAPI, Documents, Databases) {
         this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
           collection: this.data.database.allDocs
         }));
-        //this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
         return;
       }
 
@@ -345,13 +345,19 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
-    paginate: function (direction) {
-      _.extend(this.documentsView.collection.params, app.getParams());
+    perPageChange: function (perPage) {
+      this.documentsView.collection.updateLimit(perPage);
       this.documentsView.forceRender();
-      if (direction === 'next') {
+    },
+
+    paginate: function (options) {
+      this.documentsView.forceRender();
+      if (options.direction === 'next') {
         this.documentsView.collection.skipFirstItem = true;
+        this.documentsView.collection.nextPage(options.perPage);
       } else {
         this.documentsView.collection.skipFirstItem = false;
+        this.documentsView.collection.previousPage(options.perPage);
       }
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index bea256a..8f592f4 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -68,10 +68,12 @@ the License.
           <select name="limit" class="input-small">
             <option>5</option>
             <option>10</option>
-            <option selected="selected">20</option>
+            <option >20</option>
             <option>30</option>
             <option>50</option>
-            <option>100</option>
+            <option selected="selected">100</option>
+            <option>500</option>
+            <option>None</option>
           </select>
         </label>
         <div class="checkbox inline">  

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/templates/advanced_options_menu.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options_menu.html b/src/fauxton/app/addons/documents/templates/advanced_options_menu.html
new file mode 100644
index 0000000..abc08bd
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/advanced_options_menu.html
@@ -0,0 +1,46 @@
+<!--
+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 custom-inputs">
+  <div class="controls controls-row">
+    <div class="checkbox inline">  
+      <input id="include-docs-views" type="checkbox" name="include-docs" value="true">  
+      <label for="include-docs-views">
+        Include Docs</label>  
+    </div> 
+    <% if (hasReduce) { %>
+    <div class="checkbox inline">  
+      <input id="reduce" name="reduce" type="checkbox" value="true">
+      <label for="reduce">Reduce</label>  
+      <label id="group-level-label" style="display:none" class="drop-down inline">
+        Group Level:
+        <select id="group-level"  name="group_level" class="input-small">
+          <option value="0">None</option>
+          <option value="1">1</option>
+          <option value="2">2</option>
+          <option value="3">3</option>
+          <option value="4">4</option>
+          <option value="5">5</option>
+          <option value="6">6</option>
+          <option value="7">7</option>
+          <option value="8">8</option>
+          <option value="9">9</option>
+          <option value="999" selected="selected">exact</option>
+        </select>
+      </label>
+    </div> 
+    <% } %>
+    <a data-bypass="true" id="query-nav" class="" href="#query" data-toggle="tab">More query options</a></li>
+  </div> 
+</div> 
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/templates/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_layout.html b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
index 2862e16..b6428c9 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_layout.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
@@ -11,11 +11,13 @@ 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="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
   <li><a id="toggle-query" href="#query" data-bypass="true" data-toggle="tab">
     <i class="fonticon fonticon-plus"></i> Query Options</a></li>
 </ul>
 <div class="tab-content">
+  <div id="query-options-wrapper"></div>
   <div class="tab-pane" id="query">
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/templates/all_docs_number.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_number.html b/src/fauxton/app/addons/documents/templates/all_docs_number.html
index df8fe07..4c9130b 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_number.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_number.html
@@ -12,12 +12,24 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 <% if (totalRows === "unknown"){ %>
-  Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
-<% } else if (showNumbers) { %>
-  Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
+Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
 <% } else { %>
-  Showing <%=pageStart%> - <%= pageEnd %>
+Showing <%=pageStart%> - <%= pageEnd %>
 <%}%>
 <% if (updateSeq) { %>
-  -- Update Sequence: <%= updateSeq %>
+-- Update Sequence: <%= updateSeq %>
 <% } %>
+
+<div id="per-page">
+<label id="per-page" class="drop-down inline">
+  Per page:
+  <select id="select-per-page" name="per-page" class="input-small">
+    <option value="5">5</option>
+    <option value="10">10</option>
+    <option value="20">20</option>
+    <option value="30">30</option>
+    <option value="50">50</option>
+    <option value="100">100</option>
+  </select>
+</label>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/view_editor.html b/src/fauxton/app/addons/documents/templates/view_editor.html
index be60090..3a2c564 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -24,6 +24,7 @@ the License.
   </ul>
   <div class="all-docs-list errors-container"></div>
   <div class="tab-content">
+	 <div id="query-options-wrapper"></div>
     <div class="tab-pane active" id="index">
       <div id="define-view" class="ddoc-alert well">
         <div class="errors-container"></div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 298cfb4..8b8b7b3 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -416,12 +416,28 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     initialize: function (options) {
       this.newView = options.newView || false;
-      this.showNumbers = options.showNumbers;
       this.pagination = options.pagination;
+      
+      this.perPage = 20;
+      
 
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
 
+    events: {
+      'change #select-per-page': 'updatePerPage'
+    },
+
+    updatePerPage: function (event) {
+      this.perPage = parseInt(this.$('#select-per-page :selected').val(), 10);
+      FauxtonAPI.triggerRouteEvent('perPageChange', this.perPage);
+      this.pagination.updatePerPage(this.perPage);
+    },
+
+    afterRender: function () {
+      this.$('option[value="' + this.perPage + '"]').attr('selected', "selected");
+    },
+
     serialize: function () {
        var totalRows = 0,
           recordStart = 0,
@@ -445,7 +461,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         updateSeq: updateSeq,
         offset: recordStart,
         totalRows: totalRows,
-        showNumbers: this.showNumbers,
         numModels: this.collection.models.length + recordStart - 1,
         pageStart: pageStart,
         pageEnd: pageEnd
@@ -464,29 +479,38 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     events: {
-      'click #toggle-query': "toggleQuery"
+      'click #query-nav': "toggleQuery"
     },
 
     toggleQuery: function (event) {
       $('#dashboard-content').scrollTop(0);
-      this.$('#query').toggle('fast');
+      this.$('#query').toggle('slow');
     },
 
     beforeRender: function () {
+      this.eventer = _.extend({}, Backbone.Events);
+
       this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
         updateViewFn: this.updateAllDocs,
         previewFn: this.previewView,
         hasReduce: false,
         showPreview: false,
-        database: this.database
+        database: this.database,
+        eventer: this.eventer
       }));
 
+      this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+        hasReduce: false,
+        eventer:  this.eventer
+       }));
+
       this.$('#query').hide();
     },
 
     afterRender: function () {
       if (this.params) {
         this.advancedOptions.updateFromParams(this.params);
+        this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
     },
@@ -577,15 +601,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     serialize: function() {
-      var requestDuration = false;
-
-      if (this.collection.requestDurationInString) {
-        requestDuration = this.collection.requestDurationInString();
-      }
-
       return {
         viewList: this.viewList,
-        requestDuration: requestDuration,
+        requestDuration: false,
         expandDocs: this.expandDocs
       };
     },
@@ -647,53 +665,20 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     addPagination: function () {
       var collection = this.collection;
-      var perPage = function () {
-        if (collection.params.limit && collection.skipFirstItem) {
-          return parseInt(collection.params.limit, 10) - 1;
-        } else if (collection.params.limit) {
-          return parseInt(collection.params.limit, 10);
-        }
-
-        return 20;
-      };
 
       this.pagination = new Components.IndexPagination({
         collection: this.collection,
-        scrollToSelector: '#dashboard-content',
-        previousUrlfn: function () {
-          return collection.urlPreviousPage(perPage(), this.previousParams.pop());
-        },
-        canShowPreviousfn: function () {
-          if (this.previousParams.length === 0) {
-            return false;
-          }
-
-          return true;
-        },
-        canShowNextfn: function () {
-          if (collection.length < (perPage() -1)) {
-            return false;
-          }
-
-          return true;
-        },
-
-        nextUrlfn: function () {
-          return collection.urlNextPage(perPage());
-        }
+        scrollToSelector: '#dashboard-content'
       });
     },
 
     cleanup: function () {
+      this.pagination.remove();
       this.allDocsNumber.remove();
       _.each(this.rows, function (row) {row.remove();});
-
-      if (!this.pagination) { return; }
-      this.pagination.remove();
     },
 
     beforeRender: function() {
-      var showNumbers = true;
 
       if (!this.pagination) {
         this.addPagination();
@@ -701,16 +686,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.insertView('#documents-pagination', this.pagination);
 
-      if (this.designDocs || this.collection.idxType === '_view' || this.collection.params.startkey === '"_design"') {
-        showNumbers = false;
+      if (!this.allDocsNumber) {
+        this.allDocsNumber = new Views.AllDocsNumber({
+          collection: this.collection,
+          newView: this.newView,
+          pagination: this.pagination
+        });
       }
 
-      this.allDocsNumber = this.setView('#item-numbers', new Views.AllDocsNumber({
-        collection: this.collection,
-        newView: this.newView,
-        showNumbers: showNumbers,
-        pagination: this.pagination
-      }));
+      this.setView('#item-numbers', this.allDocsNumber);
 
       var docs = this.expandDocs ? this.collection : this.collection.simple();
 
@@ -943,9 +927,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           model = this.model;
 
       editor.editor.on("change", function (event) {
-        //if (event.data.action !== 'removeText') { return; }
-        //if (!event.data.text.match(/_id/) && !event.data.text.match(/_rev/)) { return; }
-
         var changedDoc;
         try {
           changedDoc = JSON.parse(editor.getValue());
@@ -1024,6 +1005,73 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     }
   });
 
+  Views.AdvancedOptionsMenu = FauxtonAPI.View.extend({
+    template: 'addons/documents/templates/advanced_options_menu',
+    tagName: "div",
+    className: "controls-group advanced-options-menu",
+    events: {
+      "click input": "updateRows",
+      'change #group-level': 'updateRows',
+      'click #query-nav': 'toggleMenu'
+    },
+
+    initialize: function (options) {
+      this.hasReduce = options.hasReduce;
+      this.eventer = options.eventer;
+    },
+
+    toggleMenu: function (event) {
+      this.$('.checkbox').toggle();
+    },
+
+    updateRows: function (event) {
+      var $groupLevel = this.$('#group-level-label'),
+          params = {
+            include_docs: false,
+            reduce: false,
+            group_level: 0
+          };
+
+      if (this.$('#include-docs-views').prop('checked')) {
+        params.include_docs = true;
+      }
+
+      if (this.hasReduce && this.$('#reduce').prop('checked')) {
+        params.reduce = true;
+        params.group_level = this.$('#group-level option:selected').val();
+        $groupLevel.show();
+      } else {
+        $groupLevel.hide();
+      }
+      this.eventer.trigger('options:param_update', params);
+    },
+
+    updateFromParams: function (params) {
+      if (params.reduce) {
+        var $reduce = this.$('#reduce');
+        $reduce.prop("checked", true);
+        this.$('#group-level-label').show();
+        this.$('option[value="' + params.group_level + '"]').prop('selected', true);
+
+      } else if (params.include_docs) {
+        var $include_docs = this.$('#include-docs-views');
+        $include_docs.prop("checked", true);
+      }
+    },
+
+    serialize: function () {
+      return {
+        hasReduce: this.hasReduce
+      };
+    },
+
+    setHasReduce: function (hasReduce) {
+      this.hasReduce = hasReduce;
+    }
+
+  });
+
+
   Views.AdvancedOptions = FauxtonAPI.View.extend({
     template: "addons/documents/templates/advanced_options",
     className: "advanced-options well",
@@ -1034,7 +1082,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.viewName = options.viewName;
       this.updateViewFn = options.updateViewFn;
       this.previewFn = options.previewFn;
-      //this.hadReduce = options.hasReduce || true;
+      this.eventer = options.eventer;
 
       if (typeof(options.hasReduce) === 'undefined') {
         this.hasReduce = true;
@@ -1047,6 +1095,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       } else {
         this.showPreview = options.showPreview;
       }
+
+      this.eventer && this.listenTo(this.eventer, 'options:param_update', this.optionsParamsUpdate);
     },
 
     events: {
@@ -1056,6 +1106,24 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       "click button.preview": "previewView"
     },
 
+    optionsParamsUpdate: function (params) {
+       var $form = this.$el.find("form.view-query-update");
+
+       if (!params.group_level) {
+        this.$("select[name='group_level']").attr('disabled', 'disabled');
+       }
+
+       if (params.reduce && params.group_level) {
+        $form.find("select[name='group_level']").val(params.group_level).removeAttr('disabled');
+        delete params.group_level;
+       } 
+
+      _.each(params, function(val, key) {
+        $form.find("input[name='"+key+"']").prop('checked', val);
+      });
+      this.$('form.view-query-update').submit();
+    },
+
     beforeRender: function () {
       if (this.viewName && this.ddocName) {
         var buttonViews = FauxtonAPI.getExtensions('advancedOptions:ViewButton');
@@ -1137,7 +1205,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         var $ele;
         switch (key) {
           case "limit":
-            case "group_level":
+          case "group_level":
             $form.find("select[name='"+key+"']").val(val);
           break;
           case "include_docs":
@@ -1248,7 +1316,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       "click button.preview": "previewView",
       "click #db-views-tabs-nav": 'toggleIndexNav',
       "click .beautify_map":  "beautifyCode",
-      "click .beautify_reduce":  "beautifyCode"
+      "click .beautify_reduce":  "beautifyCode",
+      "click #query-options-wrapper": 'toggleIndexNav'
     },
 
     langTemplates: {
@@ -1369,6 +1438,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           that.mapEditor.editSaved();
           that.reduceEditor && that.reduceEditor.editSaved();
 
+
           FauxtonAPI.addNotification({
             msg: "View has been saved.",
             type: "success",
@@ -1396,6 +1466,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
             that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
           }
 
+          that.advancedOptionsMenu.setHasReduce(that.hasReduce());
+          that.advancedOptionsMenu.render();
+
           FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
 
         }, function(xhr) {
@@ -1623,19 +1696,29 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         database: this.database
       }));
 
+      this.eventer = _.extend({}, Backbone.Events);
+
       this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
         updateViewFn: this.updateView,
         previewFn: this.previewView,
         database: this.database,
         viewName: this.viewName,
         ddocName: this.model.id,
-        hasReduce: this.hasReduce()
+        hasReduce: this.hasReduce(),
+        eventer: this.eventer
       }));
+
+      this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+        hasReduce: this.hasReduce(),
+        eventer:  this.eventer
+       }));
+
     },
 
     afterRender: function() {
       if (this.params) {
         this.advancedOptions.updateFromParams(this.params);
+        this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
       this.designDocSelector.updateDesignDoc();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/344f3727/src/fauxton/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/components.js b/src/fauxton/app/addons/fauxton/components.js
index 1f5e4ad..4f69412 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -69,34 +69,53 @@ function(app, FauxtonAPI, ace, spin) {
     initialize: function (options) {
       this.previousUrlfn = options.previousUrlfn;
       this.nextUrlfn = options.nextUrlfn;
-      this.canShowPreviousfn = options.canShowPreviousfn;
-      this.canShowNextfn = options.canShowNextfn;
       this.scrollToSelector = options.scrollToSelector;
       _.bindAll(this);
-      this.previousParams = [];
+      this.pageNumber = 0;
+      this._pageStart = 1;
+      this.perPage = 20;
+    },
+
+    canShowPreviousfn: function () {
+      if (this.pageNumber <= 0) {
+        return false;
+      }
+      return true;
+    },
+
+    canShowNextfn: function () {
+      if (this.collection.length < (this.perPage -1)) {
+        return false;
+      }
+      return true;
     },
 
     previousClicked: function (event) {
       event.preventDefault();
       event.stopPropagation();
       if (!this.canShowPreviousfn()) { return; }
-      FauxtonAPI.navigate(this.previousUrlfn(), {trigger: false});
-      FauxtonAPI.triggerRouteEvent('paginate', 'previous');
+
+      this.pageNumber = this.pageNumber -1;
+      this.decPageStart();
+
+      FauxtonAPI.triggerRouteEvent('paginate', {
+       direction: 'previous',
+       perPage: this.perPage
+      });
     },
 
     nextClicked: function (event) {
       event.preventDefault();
       event.stopPropagation();
       if (!this.canShowNextfn()) { return; }
+      
+      this.pageNumber = this.pageNumber + 1;
+      this.incPageStart();
 
-      var params = _.clone(this.collection.params);
-
-      if (params) {
-        this.previousParams.push(params);
-      }
-
-      FauxtonAPI.navigate(this.nextUrlfn(), {trigger: false});
-      FauxtonAPI.triggerRouteEvent('paginate', 'next');
+      FauxtonAPI.triggerRouteEvent('paginate', {
+       direction: 'next',
+       perPage: this.perPage
+      });
     },
 
     serialize: function () {
@@ -106,29 +125,37 @@ function(app, FauxtonAPI, ace, spin) {
       };
     },
 
-    pageLimit: function () {
-      var limit = 20;
+    updatePerPage: function (perPage) {
+      this.perPage = perPage;
+    },
 
-      if (this.collection.params.limit && this.collection.skipFirstItem) {
-        limit = parseInt(this.collection.params.limit, 10) - 1;
-      } else if (this.collection.params.limit) {
-        limit = parseInt(this.collection.params.limit, 10);
+    page: function () {
+      return this._pageStart - 1;
+    },
+
+    incPageStart: function () {
+      this._pageStart = this._pageStart + this.perPage;
+    },
+
+    decPageStart: function () {
+      var val = this._pageStart - this.perPage;
+      if (val < 1) {
+        this._pageStart = 1;
+        return;
       }
 
-      return limit;
+      this._pageStart = val;
     },
 
     pageStart: function () {
-      return (this.previousParams.length * this.pageLimit()) + 1;
-
+      return this._pageStart;
     },
 
     pageEnd: function () {
-      if (this.collection.length < this.pageLimit()) {
-        return (this.previousParams.length * this.pageLimit()) + this.collection.length;
+      if (this.collection.length < this.perPage) {
+        return this.page() + this.collection.length;
       }
 
-      return (this.previousParams.length * this.pageLimit()) + this.pageLimit();
     }
 
   });


[15/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Add Cachebusting to building new releases of fauxton


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/be3bd20b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/be3bd20b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/be3bd20b

Branch: refs/heads/paginate-api-options
Commit: be3bd20b2fd665d42bb49c66be52eb693f7f5109
Parents: 4f2e502
Author: suelockwood <de...@apache.org>
Authored: Thu Jan 30 13:32:45 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Thu Jan 30 13:32:45 2014 -0500

----------------------------------------------------------------------
 src/fauxton/assets/index.underscore | 4 ++--
 src/fauxton/settings.json.default   | 6 ++++--
 2 files changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/be3bd20b/src/fauxton/assets/index.underscore
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/index.underscore b/src/fauxton/assets/index.underscore
index cbf5bd6..396cce3 100644
--- a/src/fauxton/assets/index.underscore
+++ b/src/fauxton/assets/index.underscore
@@ -24,7 +24,7 @@
   <title>Project Fauxton</title>
 
   <!-- Application styles. -->
-  <link rel="stylesheet" href="<%= css %>">
+  <link rel="stylesheet" href="<%= css %><%=cachebuster%>">
   <% if (base) { %>
   <base href="<%= base %>"></base>
   <% } %>
@@ -42,6 +42,6 @@
   </div>
 
   <!-- Application source. -->
-  <script data-main="/config" src="<%= requirejs %>"></script>
+  <script data-main="/config" src="<%= requirejs %><%=cachebuster%>"></script>
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/be3bd20b/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index e817b79..1bc88f6 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -23,7 +23,8 @@
         "variables": {
           "requirejs": "/assets/js/libs/require.js",
           "css": "./css/index.css",
-          "base": null
+          "base": null,
+          "cachebuster": ""
         },
         "app": {
           "root": "/",
@@ -37,7 +38,8 @@
         "variables": {
           "requirejs": "./js/require.js",
           "css": "./css/index.css",
-          "base": null
+          "base": null,
+          "cachebuster": "?v1.0"
         },
         "app": {
           "root": "/_utils/fauxton/",


[10/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Fauxton: update dataSize


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/428099c7
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/428099c7
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/428099c7

Branch: refs/heads/paginate-api-options
Commit: 428099c77df46c42a2e2fc52a1ee8ec02d24981b
Parents: 7ca5f56
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jan 29 18:28:44 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Jan 29 18:29:03 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/databases/resources.js | 11 ++++++-----
 src/fauxton/app/addons/databases/views.js     |  1 +
 2 files changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/428099c7/src/fauxton/app/addons/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/resources.js b/src/fauxton/app/addons/databases/resources.js
index 3510154..1b55f88 100644
--- a/src/fauxton/app/addons/databases/resources.js
+++ b/src/fauxton/app/addons/databases/resources.js
@@ -151,16 +151,17 @@ function(app, FauxtonAPI, Documents) {
 
       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{
+      } else if (this.get('data_size')) {
+        return this.get('data_size');
+      } else if (this.get('disk_size')) {
+        return this.get('disk_size');
+      } else {
         return 0;
-      }  
+      } 
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/428099c7/src/fauxton/app/addons/databases/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/views.js b/src/fauxton/app/addons/databases/views.js
index df663eb..56001db 100644
--- a/src/fauxton/app/addons/databases/views.js
+++ b/src/fauxton/app/addons/databases/views.js
@@ -28,6 +28,7 @@ function(app, Components, FauxtonAPI, Databases) {
       return [this.model.fetch()];
     },
     serialize: function() {
+      console.log('db', this.model);
       return {
         encoded: app.utils.safeURLName(this.model.get("name")),
         database: this.model,


[07/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Make a ModalView to dry the code a bit


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/77fbb4db
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/77fbb4db
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/77fbb4db

Branch: refs/heads/paginate-api-options
Commit: 77fbb4dbed79e277063bea9fe52f132e5495f4ad
Parents: 24eb32c
Author: Simon Metson <si...@cloudant.com>
Authored: Mon Jan 27 11:38:35 2014 +0000
Committer: suelockwood <de...@apache.org>
Committed: Wed Jan 29 10:34:29 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/views.js    | 94 +----------------------
 src/fauxton/app/addons/fauxton/components.js | 43 ++++++++++-
 2 files changed, 46 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/77fbb4db/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 455bfda..8ddf46f 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -113,15 +113,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     }
   });
 
-  Views.DeleteDBModal = FauxtonAPI.View.extend({
+  Views.DeleteDBModal = Components.ModalView.extend({
     template: "addons/documents/templates/delete_database_modal",
 
-    disableLoader: true,
-
-    initialize: function (options) {
-      _.bindAll(this);
-    },
-
     events: {
       "click a#delete-db-btn": "deleteDatabase",
       "submit #delete-db-check": "deleteDatabase"
@@ -155,43 +149,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           clear: true
         });
       });
-    },
-
-    showModal: function () {
-      this.clear_error_msg();
-      this.$('.modal').modal();
-      // hack to get modal visible
-      $('.modal-backdrop').css('z-index',1025);
-    },
-
-    hideModal: function () {
-      this.$('.modal').modal('hide');
-    },
-
-    set_error_msg: function (msg) {
-      var text;
-      if (typeof(msg) == 'string') {
-        text = msg;
-      } else {
-        text = JSON.parse(msg.responseText).reason;
-      }
-      this.$('#modal-error').text(text).removeClass('hide');
-    },
-
-    clear_error_msg: function () {
-      this.$('#modal-error').text(' ').addClass('hide');
     }
   });
 
-  Views.UploadModal = FauxtonAPI.View.extend({
+  Views.UploadModal = Components.ModalView.extend({
     template: "addons/documents/templates/upload_modal",
 
-    disableLoader: true,
-
-    initialize: function (options) {
-      _.bindAll(this);
-    },
-
     events: {
       "click a#upload-btn": "uploadFile"
     },
@@ -247,39 +210,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.$('.progress').removeClass('hide');
     },
 
-    showModal: function () {
+    _showModal: function () {
       this.$('.bar').css({width: '0%'});
       this.$('.progress').addClass('hide');
-      this.clear_error_msg();
-      this.$('.modal').modal();
-      // hack to get modal visible
-      $('.modal-backdrop').css('z-index',1025);
-    },
-
-    hideModal: function () {
-      this.$('.modal').modal('hide');
-    },
-
-    set_error_msg: function (msg) {
-      var text;
-      if (typeof(msg) == 'string') {
-        text = msg;
-      } else {
-        text = JSON.parse(msg.responseText).reason;
-      }
-      this.$('#modal-error').text(text).removeClass('hide');
-    },
-
-    clear_error_msg: function () {
-      this.$('#modal-error').text(' ').addClass('hide');
-    },
-
-    serialize: function () {
-      return this.model.toJSON();
     }
   });
 
-  Views.DuplicateDocModal = FauxtonAPI.View.extend({
+  Views.DuplicateDocModal = Components.ModalView.extend({
     template: "addons/documents/templates/duplicate_doc_modal",
 
     initialize: function () {
@@ -325,30 +262,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     setDefaultIdValue: function (id) {
       this.$('#dup-id').val(id);
-    },
-
-    hideModal: function () {
-      this.$('.modal').modal('hide');
-    },
-
-    set_error_msg: function (msg) {
-      var text;
-      if (typeof(msg) == 'string') {
-        text = msg;
-      } else {
-        text = JSON.parse(msg.responseText).reason;
-      }
-      this.$('#modal-error').text(text).removeClass('hide');
-    },
-
-    clear_error_msg: function () {
-      this.$('#modal-error').text(' ').addClass('hide');
-    },
-
-    serialize: function () {
-      return this.model.toJSON();
     }
-
   });
 
   Views.FieldEditorTabs = FauxtonAPI.View.extend({

http://git-wip-us.apache.org/repos/asf/couchdb/blob/77fbb4db/src/fauxton/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/components.js b/src/fauxton/app/addons/fauxton/components.js
index c26fc96..1f5e4ad 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -119,7 +119,7 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     pageStart: function () {
-      return (this.previousParams.length * this.pageLimit()) + 1; 
+      return (this.previousParams.length * this.pageLimit()) + 1;
 
     },
 
@@ -160,6 +160,47 @@ function(app, FauxtonAPI, ace, spin) {
 
   });
 
+  Components.ModalView = FauxtonAPI.View.extend({
+
+    disableLoader: true,
+
+    initialize: function (options) {
+      _.bindAll(this);
+    },
+
+    showModal: function () {
+      if (this._showModal){ this._showModal();}
+      this.clear_error_msg();
+      this.$('.modal').modal();
+      // hack to get modal visible
+      $('.modal-backdrop').css('z-index',1025);
+    },
+
+    hideModal: function () {
+      this.$('.modal').modal('hide');
+    },
+
+    set_error_msg: function (msg) {
+      var text;
+      if (typeof(msg) == 'string') {
+        text = msg;
+      } else {
+        text = JSON.parse(msg.responseText).reason;
+      }
+      this.$('#modal-error').text(text).removeClass('hide');
+    },
+
+    clear_error_msg: function () {
+      this.$('#modal-error').text(' ').addClass('hide');
+    },
+
+    serialize: function () {
+      if (this.model){
+        return this.model.toJSON();
+      }
+      return {};
+    }
+  });
 
   Components.DbSearchTypeahead = Components.Typeahead.extend({
     initialize: function (options) {


[06/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Modal instead of prompt for delete

Display a modal asking for database name instead of a simple prompt.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/24eb32c8
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/24eb32c8
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/24eb32c8

Branch: refs/heads/paginate-api-options
Commit: 24eb32c809697605cc16136395c88fcfa5b3c840
Parents: e57286d
Author: Simon Metson <si...@cloudant.com>
Authored: Sun Jan 26 19:06:18 2014 +0000
Committer: suelockwood <de...@apache.org>
Committed: Wed Jan 29 10:34:29 2014 -0500

----------------------------------------------------------------------
 .../templates/delete_database_modal.html        |  37 ++++++
 .../app/addons/documents/templates/sidebar.html |   1 +
 src/fauxton/app/addons/documents/views.js       | 114 +++++++++++++------
 3 files changed, 119 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/24eb32c8/src/fauxton/app/addons/documents/templates/delete_database_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/delete_database_modal.html b/src/fauxton/app/addons/documents/templates/delete_database_modal.html
new file mode 100644
index 0000000..024f7c9
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/delete_database_modal.html
@@ -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.
+-->
+
+<div class="modal hide fade">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+    <h3>Delete Database</h3>
+  </div>
+  <div class="modal-body">
+    <form id="delete-db-check" class="form" method="post">
+      <p>
+      You've asked to <b>permanently delete</b> <code><%= database.id %></code>.
+      Please enter the database name below to confirm the deletion of the
+      database and all documents and attachments within.
+      </p>
+      <input class="input-block-level" type="text" name="db_name" id="db_name"></input>
+      <br/>
+      <div id="modal-error" class="alert alert-error hide" style="font-size: 16px;"></div>
+    </form>
+  </div>
+  <div class="modal-footer">
+    <a href="#" data-dismiss="modal" data-bypass="true" class="btn button cancel-button outlineGray fonticon-circle-x">Cancel</a>
+    <a href="#" id="delete-db-btn" data-bypass="true" class="btn btn-primary button red save fonticon-circle-check">Delete</a>
+  </div>
+</div>
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/24eb32c8/src/fauxton/app/addons/documents/templates/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/sidebar.html b/src/fauxton/app/addons/documents/templates/sidebar.html
index 8a73ae9..c8ce511 100644
--- a/src/fauxton/app/addons/documents/templates/sidebar.html
+++ b/src/fauxton/app/addons/documents/templates/sidebar.html
@@ -64,4 +64,5 @@ the License.
     </ul>
     <div id="extension-navs"></div>
   </nav>
+  <div id="delete-db-modal"> </div>
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/24eb32c8/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index fd7d034..455bfda 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -113,6 +113,76 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     }
   });
 
+  Views.DeleteDBModal = FauxtonAPI.View.extend({
+    template: "addons/documents/templates/delete_database_modal",
+
+    disableLoader: true,
+
+    initialize: function (options) {
+      _.bindAll(this);
+    },
+
+    events: {
+      "click a#delete-db-btn": "deleteDatabase",
+      "submit #delete-db-check": "deleteDatabase"
+    },
+
+    deleteDatabase: function (event) {
+      event.preventDefault();
+      var enterredName = this.$('#db_name')[0].value;
+      if (this.database.id != enterredName) {
+        this.set_error_msg(enterredName + " does not match database id - are you sure you want to delete " + this.database.id + "?");
+        return;
+      }
+      this.hideModal();
+      var databaseName = this.database.id;
+      FauxtonAPI.addNotification({
+        msg: "Deleting your database...",
+        type: "error",
+        clear: true
+      });
+
+      this.database.destroy().then(function () {
+        FauxtonAPI.navigate('#/_all_dbs');
+        FauxtonAPI.addNotification({
+          msg: 'The database <code>' + databaseName + '</code> has been deleted.',
+          clear: true
+        });
+      }).fail(function (rsp, error, msg) {
+        FauxtonAPI.addNotification({
+          msg: 'Could not delete the database, reason ' + msg + '.',
+          type: 'error',
+          clear: true
+        });
+      });
+    },
+
+    showModal: function () {
+      this.clear_error_msg();
+      this.$('.modal').modal();
+      // hack to get modal visible
+      $('.modal-backdrop').css('z-index',1025);
+    },
+
+    hideModal: function () {
+      this.$('.modal').modal('hide');
+    },
+
+    set_error_msg: function (msg) {
+      var text;
+      if (typeof(msg) == 'string') {
+        text = msg;
+      } else {
+        text = JSON.parse(msg.responseText).reason;
+      }
+      this.$('#modal-error').text(text).removeClass('hide');
+    },
+
+    clear_error_msg: function () {
+      this.$('#modal-error').text(' ').addClass('hide');
+    }
+  });
+
   Views.UploadModal = FauxtonAPI.View.extend({
     template: "addons/documents/templates/upload_modal",
 
@@ -411,7 +481,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         ddoc: this.ddoc,
         database: this.database,
         index_clean: app.utils.removeSpecialCharacters(this.index),
-        ddoc_clean: app.utils.removeSpecialCharacters(this.ddoc), 
+        ddoc_clean: app.utils.removeSpecialCharacters(this.ddoc),
         index_encoded: app.utils.safeURLName(this.index),
         ddoc_encoded: app.utils.safeURLName(this.ddoc),
         database_encoded: app.utils.safeURLName(this.database),
@@ -1393,7 +1463,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           });
 
           if (that.newView || viewNameChange) {
-            var fragment = '/database/' + that.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.utils.safeURLName(viewName); 
+            var fragment = '/database/' + that.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.utils.safeURLName(viewName);
 
             FauxtonAPI.navigate(fragment, {trigger: false});
             that.newView = false;
@@ -1507,7 +1577,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
        }
 
       promise.then(function () {
-        params.docs = that.database.allDocs.map(function (model) { return model.get('doc');}); 
+        params.docs = that.database.allDocs.map(function (model) { return model.get('doc');});
         var queryPromise = pouchdb.runViewQuery({map: mapVal, reduce: reduceVal}, params);
         queryPromise.then(function (results) {
           FauxtonAPI.triggerRouteEvent('updatePreviewDocs', {rows: results.rows, ddoc: that.getCurrentDesignDoc().id, view: that.viewName});
@@ -1534,7 +1604,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     reduceVal: function() {
       var reduceOption = this.$('#reduce-function-selector :selected').val(),
       reduceVal = "";
-      
+
       if (reduceOption === 'CUSTOM') {
         if (!this.reduceEditor) { this.createReduceEditor(); }
         reduceVal = this.reduceEditor.getValue();
@@ -1732,7 +1802,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
   Views.Sidebar = FauxtonAPI.View.extend({
     template: "addons/documents/templates/sidebar",
     events: {
-      "click button#delete-database": "deleteDatabase"
+      "click button#delete-database": "showDeleteDatabaseModal"
     },
 
     initialize: function(options) {
@@ -1742,33 +1812,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.currView = options.ddocInfo.currView;
       }
     },
-
-    deleteDatabase: function (event) {
-      event.preventDefault();
-
-      var result = confirm('Are you sure you want to delete this database?');
-
-      if (!result) { return; }
-      var databaseName = this.database.id;
-      FauxtonAPI.addNotification({
-        msg: "Deleting your database...",
-        type: "error",
-        clear: true
-      });
-
-      this.database.destroy().then(function () {
-        FauxtonAPI.navigate('#/_all_dbs');
-        FauxtonAPI.addNotification({
-          msg: 'The database <code>' + databaseName + '</code> has been deleted.',
-          clear: true
-        });
-      }).fail(function (rsp, error, msg) {
-        FauxtonAPI.addNotification({
-          msg: 'Could not delete the database, reason ' + msg + '.',
-          type: 'error',
-          clear: true
-        });
-      });
+    showDeleteDatabaseModal: function(event){
+      this.deleteDBModal.showModal();
     },
 
     serialize: function() {
@@ -1803,6 +1848,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     beforeRender: function(manage) {
+      this.deleteDBModal = this.setView(
+        '#delete-db-modal',
+        new Views.DeleteDBModal({database: this.database})
+      );
 
       var sidebarListViews = FauxtonAPI.getExtensions('sidebar:list');
       _.each(sidebarListViews, function (view) {
@@ -1811,7 +1860,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         extension.render();
       }, this);
 
-
       this.collection.each(function(design) {
         if (design.has('doc')){
           var ddoc = design.id.replace(/^_design\//,"");


[22/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Set view limit on pagination


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/5d2a6f9c
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/5d2a6f9c
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/5d2a6f9c

Branch: refs/heads/paginate-api-options
Commit: 5d2a6f9c9a212965d2f9972c07eae6ce7d3d509f
Parents: 5c7b312
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Feb 3 12:10:08 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Feb 3 12:10:08 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js   |  4 ++-
 src/fauxton/app/addons/documents/routes.js      |  5 ++-
 .../documents/templates/all_docs_layout.html    |  4 ---
 .../documents/templates/all_docs_number.html    |  2 +-
 .../addons/documents/templates/view_editor.html |  2 --
 src/fauxton/app/addons/documents/views.js       | 36 +++++++++++---------
 6 files changed, 26 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5d2a6f9c/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index f3e5043..ad4daca 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -285,7 +285,9 @@ function(app, FauxtonAPI) {
       this.on("remove",this.decrementTotalRows , this);
       this.perPageLimit = options.perPageLimit || 20;
 
-      this.params.limit = this.perPageLimit; 
+      if (this.params.limit > this.perPageLimit) {
+        this.params.limit = this.perPageLimit; 
+      }
     },
 
     url: function(context) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5d2a6f9c/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
index 9ef8837..3ec640f 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -275,9 +275,8 @@ function(app, FauxtonAPI, Documents, Databases) {
     newViewEditor: function () {
       var params = app.getParams();
 
-      if (this.toolsView) {
-        this.toolsView.remove();
-      }
+      this.toolsView && this.toolsView.remove();
+      this.documentsView && this.documentsView.remove();
 
       this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
         ddocs: this.data.designDocs,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5d2a6f9c/src/fauxton/app/addons/documents/templates/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_layout.html b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
index b6428c9..1bbe59d 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_layout.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
@@ -12,10 +12,6 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
-  <li><a id="toggle-query" href="#query" data-bypass="true" data-toggle="tab">
-    <i class="fonticon fonticon-plus"></i> Query Options</a></li>
-</ul>
 <div class="tab-content">
   <div id="query-options-wrapper"></div>
   <div class="tab-pane" id="query">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5d2a6f9c/src/fauxton/app/addons/documents/templates/all_docs_number.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_number.html b/src/fauxton/app/addons/documents/templates/all_docs_number.html
index 4c9130b..fb9ea11 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_number.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_number.html
@@ -11,7 +11,7 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 License for the specific language governing permissions and limitations under
 the License.
 -->
-<% if (totalRows === "unknown"){ %>
+<% if (totalRows === "unknown" || totalRows === 0){ %>
 Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
 <% } else { %>
 Showing <%=pageStart%> - <%= pageEnd %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5d2a6f9c/src/fauxton/app/addons/documents/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/view_editor.html b/src/fauxton/app/addons/documents/templates/view_editor.html
index 3a2c564..86802ec 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -17,8 +17,6 @@ the License.
       <i class="fonticon-wrench fonticon"></i>
       <% if (newView) { %>Create Index <% } else { %>Edit Index <% } %></a></li>
     <% if (!newView) { %>
-    <li><a data-bypass="true" id="query-nav" href="#query" data-toggle="tab">
-      <i class="fonticon-plus fonticon"></i> Query Options</a></li>
     <li><a data-bypass="true" id="meta-nav" href="#metadata" data-toggle="tab">Design Doc Metadata</a></li>
     <% } %>
   </ul>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5d2a6f9c/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 1af8183..33bdeb4 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -446,7 +446,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           pageEnd = 20;
 
       if (!this.newView) {
-        totalRows = this.collection.totalRows();
+        totalRows = this.collection.length;
         updateSeq = this.collection.updateSeq();
       }
 
@@ -456,6 +456,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         pageEnd =  this.pagination.pageEnd();
       }
 
+      console.log('t', totalRows, this.collection);
       return {
         database: app.utils.safeURLName(this.collection.database.id),
         updateSeq: updateSeq,
@@ -1698,27 +1699,30 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         database: this.database
       }));
 
-      this.eventer = _.extend({}, Backbone.Events);
 
-      this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
-        updateViewFn: this.updateView,
-        previewFn: this.previewView,
-        database: this.database,
-        viewName: this.viewName,
-        ddocName: this.model.id,
-        hasReduce: this.hasReduce(),
-        eventer: this.eventer
-      }));
+      if (!this.newView) {
+        this.eventer = _.extend({}, Backbone.Events);
+
+        this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
+          updateViewFn: this.updateView,
+          previewFn: this.previewView,
+          database: this.database,
+          viewName: this.viewName,
+          ddocName: this.model.id,
+          hasReduce: this.hasReduce(),
+          eventer: this.eventer
+        }));
 
-      this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
-        hasReduce: this.hasReduce(),
-        eventer:  this.eventer
-       }));
+        this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+          hasReduce: this.hasReduce(),
+          eventer:  this.eventer
+         }));
+      }
 
     },
 
     afterRender: function() {
-      if (this.params) {
+      if (this.params && !this.newView) {
         this.advancedOptions.updateFromParams(this.params);
         this.advancedOptionsMenu.updateFromParams(this.params);
       }


[11/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Compaction addon was missing from makefile


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/cd0193f1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/cd0193f1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/cd0193f1

Branch: refs/heads/paginate-api-options
Commit: cd0193f120e87a72ad8ee1c55dc2ea05c650018e
Parents: 428099c
Author: suelockwood <de...@apache.org>
Authored: Wed Jan 29 11:35:08 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Wed Jan 29 11:44:46 2014 -0500

----------------------------------------------------------------------
 src/Makefile.am | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/cd0193f1/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 5380bd9..17c3623 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,13 @@ FAUXTON_FILES = \
     fauxton/app/addons/auth/templates/nav_dropdown.html \
     fauxton/app/addons/auth/templates/nav_link_title.html \
     fauxton/app/addons/auth/templates/noAccess.html \
+    fauxton/app/addons/compaction/assets/less/compaction.less \
+    fauxton/app/addons/compaction/templates/compact_view.html \
+    fauxton/app/addons/compaction/templates/layout.html \
+    fauxton/app/addons/compaction/base.js \
+    fauxton/app/addons/compaction/resources.js \
+    fauxton/app/addons/compaction/routes.js \
+    fauxton/app/addons/compaction/views.js \
     fauxton/app/addons/config/base.js \
     fauxton/app/addons/config/resources.js \
     fauxton/app/addons/config/routes.js \
@@ -173,6 +180,7 @@ FAUXTON_FILES = \
     fauxton/app/addons/documents/templates/tabs.html \
     fauxton/app/addons/documents/templates/upload_modal.html \
     fauxton/app/addons/documents/templates/view_editor.html \
+    fauxton/app/addons/documents/tests/resourcesSpec.js \
     fauxton/app/addons/fauxton/templates/api_bar.html \
     fauxton/app/addons/fauxton/templates/breadcrumbs.html \
     fauxton/app/addons/fauxton/templates/footer.html \


[17/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
2029 Consolidate CSS/LESS class name usage to minimize custom-ness


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/6ea2b081
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/6ea2b081
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/6ea2b081

Branch: refs/heads/paginate-api-options
Commit: 6ea2b081bccb77acd04b59dc392be74c26714f82
Parents: be3bd20
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Thu Jan 30 13:32:45 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Fri Jan 31 15:33:47 2014 -0500

----------------------------------------------------------------------
 .gitignore                                      |   2 +
 src/Makefile.am                                 |   6 +-
 .../activetasks/assets/less/activetasks.less    |   6 +-
 .../app/addons/auth/assets/less/auth.less       |  15 -
 src/fauxton/app/addons/auth/resources.js        |   2 +-
 src/fauxton/app/addons/compaction/views.js      |   2 +-
 .../app/addons/config/assets/less/config.less   |  23 +-
 .../app/addons/config/templates/dashboard.html  |   6 +-
 .../app/addons/config/templates/item.html       |   6 +-
 .../addons/databases/assets/less/databases.less | 220 +-------
 .../app/addons/databases/templates/list.html    |   8 +-
 .../addons/databases/templates/newdatabase.html |   3 +-
 .../addons/documents/assets/less/documents.less |  70 ++-
 .../documents/templates/advanced_options.html   |   4 +-
 .../documents/templates/all_docs_layout.html    |   3 +-
 .../documents/templates/all_docs_list.html      |  10 +-
 .../app/addons/documents/templates/doc.html     |  16 +-
 .../documents/templates/doc_field_editor.html   |   4 +-
 .../templates/duplicate_doc_modal.html          |   4 +-
 .../app/addons/documents/templates/jumpdoc.html |   9 +-
 .../app/addons/documents/templates/sidebar.html |  10 +-
 .../documents/templates/upload_modal.html       |   4 +-
 .../addons/documents/templates/view_editor.html |  13 +-
 src/fauxton/app/addons/documents/views.js       |   2 +-
 .../app/addons/fauxton/templates/api_bar.html   |   4 +-
 .../app/addons/fauxton/templates/nav_bar.html   |   8 +-
 .../permissions/assets/less/permissions.less    |  39 +-
 .../app/addons/permissions/templates/item.html  |   2 +-
 .../addons/permissions/templates/section.html   |   8 +-
 .../replication/assets/less/replication.less    | 342 +++++++------
 .../app/addons/stats/assets/less/stats.less     |   6 +-
 src/fauxton/app/addons/styletests/base.js       |  33 ++
 src/fauxton/app/addons/styletests/resources.js  |  22 +
 src/fauxton/app/addons/styletests/routes.js     |  40 ++
 .../app/addons/styletests/templates/theme.html  | 496 +++++++++++++++++++
 src/fauxton/app/addons/styletests/views.js      |  29 ++
 src/fauxton/app/addons/verifyinstall/routes.js  |   2 +-
 src/fauxton/app/addons/verifyinstall/views.js   |   2 +-
 src/fauxton/app/templates/fauxton/api_bar.html  |   4 +-
 .../app/templates/fauxton/breadcrumbs.html      |   2 +-
 src/fauxton/app/templates/fauxton/nav_bar.html  |   8 +-
 src/fauxton/assets/less/fauxton.less            | 150 ++----
 src/fauxton/assets/less/variables.less          |   2 +
 src/fauxton/readme.md                           |  10 +-
 src/fauxton/settings.json.dev                   |  59 +++
 45 files changed, 1067 insertions(+), 649 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 784444d..5e4d220 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,8 +107,10 @@ src/fauxton/app/addons/*
 !src/fauxton/app/addons/pouchdb
 !src/fauxton/app/addons/databases
 !src/fauxton/app/addons/documents
+!src/fauxton/app/addons/styletests
 src/fauxton/settings.json*
 !src/fauxton/settings.json.default
+!src/fauxton/settings.json.dev
 src/ibrowse/ibrowse.app
 src/ibrowse/ibrowse.app
 src/mochiweb/mochiweb.app

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 17c3623..e7efd4c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,7 +49,6 @@ FAUXTON_FILES = \
     fauxton/app/addons/activetasks/templates/tabs.html \
     fauxton/app/addons/activetasks/tests/viewsSpec.js \
     fauxton/app/addons/activetasks/views.js \
-    fauxton/app/addons/auth/assets/less/auth.less \
     fauxton/app/addons/auth/base.js \
     fauxton/app/addons/auth/resources.js \
     fauxton/app/addons/auth/routes.js \
@@ -112,6 +111,11 @@ FAUXTON_FILES = \
     fauxton/app/addons/stats/templates/stats.html \
     fauxton/app/addons/stats/templates/statselect.html \
     fauxton/app/addons/stats/views.js \
+    fauxton/app/addons/styletests/base.js \
+    fauxton/app/addons/styletests/resources.js \
+    fauxton/app/addons/styletests/routes.js \
+    fauxton/app/addons/styletests/views.js \
+    fauxton/app/addons/styletests/templates/theme.html \
     fauxton/app/addons/verifyinstall/views.js \
     fauxton/app/addons/verifyinstall/resources.js \
     fauxton/app/addons/verifyinstall/base.js \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/assets/less/activetasks.less b/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
index 743917d..b06f550 100644
--- a/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
+++ b/src/fauxton/app/addons/activetasks/assets/less/activetasks.less
@@ -10,9 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-.task-tabs li {
+.task-tabs li,
+.active-tasks th {
   cursor: pointer;
 }
-table.active-tasks{
-	font-size: 16px;
-}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/auth/assets/less/auth.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/assets/less/auth.less b/src/fauxton/app/addons/auth/assets/less/auth.less
deleted file mode 100644
index 598da10..0000000
--- a/src/fauxton/app/addons/auth/assets/less/auth.less
+++ /dev/null
@@ -1,15 +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.
-
-.menuDropdown {
-  display: none;
-}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
index 321d302..0c9b1f5 100644
--- a/src/fauxton/app/addons/auth/resources.js
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -58,7 +58,7 @@ function (app, FauxtonAPI, CouchdbSession) {
           passwordsNotMatch:  'Passwords do not match.',
           incorrectCredentials: 'Incorrect username or password.',
           loggedIn: 'You have been logged in.',
-          adminCreated: 'Couchdb admin created',
+          adminCreated: 'CouchDB admin created',
           changePassword: 'Your password has been updated.'
         }, options.messages);
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/compaction/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/compaction/views.js b/src/fauxton/app/addons/compaction/views.js
index f5469cf..a68daef 100644
--- a/src/fauxton/app/addons/compaction/views.js
+++ b/src/fauxton/app/addons/compaction/views.js
@@ -85,7 +85,7 @@ function (app, FauxtonAPI, Compaction) {
 
   Compaction.CompactView = FauxtonAPI.View.extend({
     template: 'addons/compaction/templates/compact_view',
-    className: 'btn btn-info btn-large pull-right',
+    className: 'btn btn-info pull-right',
     tagName: 'button',
 
     initialize: function () {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/config/assets/less/config.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/assets/less/config.less b/src/fauxton/app/addons/config/assets/less/config.less
index 737beb4..88bbc66 100644
--- a/src/fauxton/app/addons/config/assets/less/config.less
+++ b/src/fauxton/app/addons/config/assets/less/config.less
@@ -13,11 +13,6 @@
 .config-item {
   height: 41px;
 
-  .edit-button {
-    float: right;
-    display:none;
-  }
-
   td:hover .edit-button {
     display: block;
   }
@@ -31,24 +26,10 @@
   }
 }
 
-.button-margin {
-  margin-bottom: 15px;
-}
-
 #add-section-modal {
   width: 400px;
 }
 
-table.config {
-  #config-trash {
-    width: 5%;
-  }
-  
-  #delete-value {
-    text-align: center;
-  } 
-}
-
-button#add-section {
-  float: right;
+#config-trash {
+  width: 5%;
 }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/config/templates/dashboard.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/templates/dashboard.html b/src/fauxton/app/addons/config/templates/dashboard.html
index ffbeb37..b7dbc55 100644
--- a/src/fauxton/app/addons/config/templates/dashboard.html
+++ b/src/fauxton/app/addons/config/templates/dashboard.html
@@ -13,12 +13,10 @@ the License.
 -->
 
 <div class="row">
-  <div class="span2 offset10">
-    <button id="add-section" href="#" class="button button-margin">
-      <i class="icon-plus icon-white"> </i>
+    <button id="add-section" href="#" class="btn btn-primary pull-right">
+      <i class="icon icon-plus icon-white"> </i>
       Add Section
     </button>
-  </div>
 </div>
 <table class="config table table-striped table-bordered">
   <thead>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/config/templates/item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/templates/item.html b/src/fauxton/app/addons/config/templates/item.html
index 1c808b9..502c9b3 100644
--- a/src/fauxton/app/addons/config/templates/item.html
+++ b/src/fauxton/app/addons/config/templates/item.html
@@ -20,12 +20,12 @@ the License.
 <td> <%= option.name %> </td>
 <td>
   <div id="show-value">
-    <%= option.value %> <button class="edit-button btn-mini btn"> Edit </button>
+    <%= option.value %> <button class="btn btn-mini pull-right hide edit-button"> Edit </button>
   </div>
   <div id="edit-value-form" style="display:none">
     <input class="value-input" type="text" value="<%= option.value %>" />
     <button id="save-value" class="btn btn-success btn-small"> Save </button>
-    <button id="cancel-value" class="btn btn-danger btn-small"> Cancel </button>
+    <button id="cancel-value" class="btn btn-small"> Cancel </button>
   </div>
 </td>
-<td id="delete-value"> <i class="icon-trash"> </i> </td>
+<td id="delete-value" class="text-center"> <i class="icon-trash"> </i> </td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/databases/assets/less/databases.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/assets/less/databases.less b/src/fauxton/app/addons/databases/assets/less/databases.less
index 3d86d81..7b7cf6a 100644
--- a/src/fauxton/app/addons/databases/assets/less/databases.less
+++ b/src/fauxton/app/addons/databases/assets/less/databases.less
@@ -15,194 +15,15 @@
    ---------------------------------------------------------------------- */
 @import "../../../../../assets/less/bootstrap/variables.less";  
 @import "../../../../../assets/less/bootstrap/mixins.less";   
-#db-tools {
-    position: absolute;
-    top: -7px;
-    right: 0;
-    width: 390px;
-
-    .btn-group {
-        position: absolute;
-        left: 0;
-        top: 6px;
-    }
-
-    form {
-        position: absolute;
-        right: 0;
-        top: 0;
-    }
-}
 
 .tools .nav {
     margin-bottom: 10px;
 }
 
-#sidenav {
-    padding-top: 10px;
-
-    h3 {
-        margin: 10px 0;
-    }
-
-    li a span.divider {
-        background: none;
-        color: #ccc;
-        padding: 0 2px;
-    }
-
-    li.nav-header a {
-        display: inline
-    }
-
-    div.btn-group {
-        display: inline-block;
-    }
-
-    li.nav-header, #sidenav li a {
-        padding-left: 4px;
-    }
-
-    li.active a {
-        background-color: #ddd;
-        color: #333;
-        text-shadow: none;
-    }
-}
-
-.edit {
-    display: none;
-
-    form {
-        margin-bottom: 0;
-    }
-
-    h3 {
-        border-bottom: 1px solid #ccc;
-        font-size: 100%;
-        line-height: 1;
-        margin-bottom: 18px;
-    }
-
-    textarea {
-        height: 100px;
-        width: 95%;
-    }
-
-    .btn-toolbar {
-        margin-bottom: 0;
-    }
-
-    .preview {
-        width: 100px;
-    }
-
-    .save {
-    }
-}
-
-#new-view-index {
-    .confirm {
-        display: none;
-    }
-
-    .confirm .progress {
-        display: none;
-        margin: 20px;
-    }
-
-    textarea {
-        height: 100px;
-        width: 95%;
-    }
-}
-
-.view {
-    display: none;
-
-    .result-tools {
-        float: left;
-        width: 100%;
-        margin-bottom: 10px;
-    }
-
-    table td div  {
-        position: relative;
-    }
-
-    table td div div {
-        display: none;
-        line-height: 1;
-        position: absolute;
-        right: 4px;
-        top: 4px;
-    }
-
-    table td div:hover div a.edits {
-        padding-left: 16px;
-        padding-right: 16px;
-    }
-
-    table td div:hover div {
-        display: block;
-    }
-
-}
-.view.show {
-    display: block;
-}
-.view.show.hidden-by-params {
-    display: none;
-}
-#database .view table tr td {
-    padding: 0;
-}
-
-.loading {display: none;}
-
-.view-request-duration {
-  padding-right: 10px;
-  float: right;
-}
-
-table.active-tasks{
-    th {
-        cursor: pointer;
-    }
-}
-
-.well{
-    .row-fluid{
-        margin: 0;
-    }
-    .row-fluid .row-fluid:last-child .well-item {
-        border: none;
-    }
-    .well-item{
-        color: #666;
-        font-size: 12px;
-        border-bottom: 1px solid #e5e5e5;
-        padding: 8px 4px;
-        strong {
-            font-size: 16px;
-        }  
-    } 
-}
-
-
-#doc {
-    .dropdown-menu{
-        width: auto;
-    }
-}
-// #tabs {
-//     height: 40px;
-// }
-
-.databases{
+.databases {
     a.db-actions,
-    a.db-actions:visited{
-        color: @red; 
+    a.db-actions:visited {
+        color: @red;
         border: 1px solid #e3e3e3;
         padding: 5px 7px;
         .border-radius(6px);
@@ -210,38 +31,3 @@ table.active-tasks{
         font-size: 19px;
     }
 }
-.btn-group{
-    ul.dropdown-menu li a:before{
-        margin-right: 10px;
-    }
-}
-
-.design-doc-group{
-    .span3 { margin: 0;}
-    #new-ddoc-section {
-        margin-top: 10px;
-        label{ width: 100px}
-        .controls{
-            margin-left: 100px;
-        }
-    }
-}
-table#changes-table {
-
-  #changes {
-    width: 50%;
-  }
-
-  #seq, #deleted {
-    width: 5%;
-  }
-
-}
-
-.doc-editor-buttons {
-    margin-bottom: 15px;
-    a.button.btn-large.gray {
-        padding: 9px 10px;
-        vertical-align: middle;
-    }
-}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/databases/templates/list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/list.html b/src/fauxton/app/addons/databases/templates/list.html
index 31c0977..1503c32 100644
--- a/src/fauxton/app/addons/databases/templates/list.html
+++ b/src/fauxton/app/addons/databases/templates/list.html
@@ -14,9 +14,11 @@ the License.
 
 <div class="result-tools" style="">
   <div id="newButton" class="pull-left"></div>
-  <form id="jump-to-db" class="navbar-form pull-right input-append database-search">
-    <input type="text" class="search-autocomplete" name="search-query" placeholder="Database name"></input>
-    <button class="fonticon-search btn button red " type="submit"></button>
+  <form id="jump-to-db" class="navbar-form pull-right database-search">
+    <div class="input-append">
+      <input type="text" class="search-autocomplete" name="search-query" placeholder="Database name" />
+      <button class="btn btn-primary" type="submit"><i class="icon icon-search"></i></button>
+    </div>
   </form>
 
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/databases/templates/newdatabase.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/newdatabase.html b/src/fauxton/app/addons/databases/templates/newdatabase.html
index b357e0b..1376ad5 100644
--- a/src/fauxton/app/addons/databases/templates/newdatabase.html
+++ b/src/fauxton/app/addons/databases/templates/newdatabase.html
@@ -12,6 +12,5 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<a class="button new" id="new"><i class="icon fonticon-new-database"></i>Add New Database</a>
-
+<a class="btn btn-primary new" id="new"><i class="icon fonticon-new-database"></i> Add New Database</a>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 68fc58d..6f462ef 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -10,7 +10,7 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 /*ALL DOCS TABLE*/
-tr.all-docs-item{
+tr.all-docs-item {
   border: none;
   background: transparent;
     .btn-group {
@@ -22,3 +22,71 @@ tr.all-docs-item{
 button.beautify {
 	margin-top: 20px;
 }
+
+
+/** used in all_docs_list.html **/
+.view {
+    table td div {
+        position: relative;
+    }
+
+    table td div div {
+        display: none;
+        line-height: 1;
+        position: absolute;
+        right: 4px;
+        top: 4px;
+    }
+
+    table td div:hover div a.edits {
+        padding-left: 16px;
+        padding-right: 16px;
+    }
+
+    table td div:hover div {
+        display: block;
+    }
+}
+
+/** used in ddocs_info.html **/
+.well {
+    .row-fluid {
+        margin: 0;
+    }
+    .row-fluid .row-fluid:last-child .well-item {
+        border: none;
+    }
+    .well-item {
+        color: #666;
+        font-size: 12px;
+        border-bottom: 1px solid #e5e5e5;
+        padding: 8px 4px;
+        strong {
+            font-size: 16px;
+        }
+    }
+}
+
+/** used in view_editor.html **/
+.design-doc-group{
+    .span3 { margin: 0;}
+    #new-ddoc-section {
+        margin-top: 10px;
+        label{ width: 100px}
+        .controls{
+            margin-left: 100px;
+        }
+    }
+}
+
+/** used in changes.html **/
+#changes-table {
+
+  #changes {
+    width: 50%;
+  }
+
+  #seq, #deleted {
+    width: 5%;
+  }
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index e256325..bea256a 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -86,9 +86,9 @@ the License.
   <div class="controls-group">
     <div class="row-fluid">
       <div id="button-options" class="controls controls-row">
-        <button type="submit" class="button green">Query</button>
+        <button type="submit" class="btn btn-success">Query</button>
         <% if (showPreview) { %>
-        <button class="button btn-info preview">Browser Preview</button>
+        <button class="btn btn-info preview">Browser Preview</button>
         <% } %>
       </div>
     </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_layout.html b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
index 6b4a31b..2862e16 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_layout.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
@@ -12,7 +12,8 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 <ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
-  <li><a id="toggle-query" class="fonticon-plus fonticon" href="#query" data-bypass="true" data-toggle="tab">Query Options</a></li>
+  <li><a id="toggle-query" href="#query" data-bypass="true" data-toggle="tab">
+    <i class="fonticon fonticon-plus"></i> Query Options</a></li>
 </ul>
 <div class="tab-content">
   <div class="tab-pane" id="query">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/all_docs_list.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_list.html b/src/fauxton/app/addons/documents/templates/all_docs_list.html
index 335b040..cdec81e 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_list.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_list.html
@@ -12,16 +12,16 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<div class="view show">
+<div class="view">
   <% if (!viewList) { %>
     <div class="row">
       <div class="btn-toolbar span6">
-        <button type="button" class="btn all" data-toggle="button">✓ All</button>
+        <button type="button" class="btn btn-small all" data-toggle="button">✓ All</button>
         <button class="btn btn-small disabled bulk-delete"><i class="icon-trash"></i></button>
         <% if (expandDocs) { %>
-        <button id="collapse" class="btn"><i class="icon-minus"></i> Collapse</button>
+        <button id="collapse" class="btn btn-small"><i class="icon-minus"></i> Collapse</button>
         <% } else { %>
-        <button id="collapse" class="btn"><i class="icon-plus"></i> Expand</button>
+        <button id="collapse" class="btn btn-small"><i class="icon-plus"></i> Expand</button>
         <% } %>
       </div>
     </div>
@@ -31,7 +31,7 @@ the License.
   <div id="item-numbers"> </div>
 
   <% if (requestDuration) { %>
-    <span class="view-request-duration">
+    <span class="view-request-duration pull-right">
     View request duration: <strong> <%= requestDuration %> </strong> 
     </span>
   <% } %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/doc.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/doc.html b/src/fauxton/app/addons/documents/templates/doc.html
index 10bbf8b..5ef70fe 100644
--- a/src/fauxton/app/addons/documents/templates/doc.html
+++ b/src/fauxton/app/addons/documents/templates/doc.html
@@ -15,19 +15,19 @@ the License.
 <div id="doc">
   <div class="errors-container"></div>
    
-<div class="row doc-editor-buttons"> 
+<div class="nav">
   <div class="span3">
-    <button class="save-doc button green btn-medium save fonticon-circle-check" type="button">Save</button>
-    <button class="button cancel-button gray btn-medium">Back to _all_docs</button>
+    <button class="save-doc btn btn-success save" type="button"><i class="icon fonticon-circle-check"></i> Save</button>
+    <button class="btn cancel-button">Back to _all_docs</button>
   </div>
 
   <div class="span7">
     <% if (attachments) { %>
     <div class="btn-group">
-      <a class="button gray btn-medium dropdown-toggle btn" data-bypass="true" data-toggle="dropdown" href="#">
+      <button class="dropdown-toggle btn" data-bypass="true" data-toggle="dropdown">
         View Attachments
         <span class="caret"></span>
-      </a>
+      </button>
       <ul class="dropdown-menu">
         <%_.each(attachments, function (att) { %>
         <li>
@@ -39,11 +39,11 @@ the License.
       </ul>
     </div>
     <% } %> 
-    <button class="button gray btn-medium  upload"><i class="icon-circle-arrow-up"></i> Upload Attachment</button>
-    <button class="button gray btn-medium duplicate"><i class="icon-repeat"></i> Duplicate document</button>
+    <button class="btn upload"><i class="icon icon-circle-arrow-up"></i> Upload Attachment</button>
+    <button class="btn duplicate"><i class="icon icon-repeat"></i> Duplicate document</button>
   </div>
 
-  <button class="button red btn-medium delete"><i class="icon-trash"></i></button>
+  <button class="btn btn-danger delete"><i class="icon icon-trash"></i></button>
   </ul>
 
 <div id="upload-modal"> </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/doc_field_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/doc_field_editor.html b/src/fauxton/app/addons/documents/templates/doc_field_editor.html
index 77d9278..3ad9484 100644
--- a/src/fauxton/app/addons/documents/templates/doc_field_editor.html
+++ b/src/fauxton/app/addons/documents/templates/doc_field_editor.html
@@ -21,8 +21,8 @@ the License.
       <button class="btn btn-small new" style="margin-left: 64px"><i class="icon-plus"></i> New field</button>
     </div>
     <div class="btn-toolbar pull-right">
-      <button class="btn btn-small cancel button cancel-button outlineGray fonticon-circle-x">Cancel</button>
-      <button class="btn btn-small save button green fonticon-circle-check">Save</button>
+      <button class="btn btn-small cancel cancel-button"><i class="icon fonticon-circle-x"></i> Cancel</button>
+      <button class="btn btn-small btn-success save"><i class="icon fonticon-circle-check"></i> Save</button>
     </div>
   </div>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html b/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
index dbb25bc..7616300 100644
--- a/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
+++ b/src/fauxton/app/addons/documents/templates/duplicate_doc_modal.html
@@ -28,8 +28,8 @@ the License.
 
   </div>
   <div class="modal-footer">
-    <a href="#" data-dismiss="modal" class="btn button cancel-button outlineGray fonticon-circle-x">Cancel</a>
-    <a href="#" id="duplicate-btn" class="btn btn-primary button green save fonticon-circle-check">Duplicate</a>
+    <button data-dismiss="modal" class="btn cancel-button"><i class="icon fonticon-circle-x"></i> Cancel</button>
+    <button id="duplicate-btn" class="btn btn-success save"><i class="fonticon-circle-check"></i> Duplicate</button>
   </div>
 </div>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/jumpdoc.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/jumpdoc.html b/src/fauxton/app/addons/documents/templates/jumpdoc.html
index 43fdb9c..1ad3de9 100644
--- a/src/fauxton/app/addons/documents/templates/jumpdoc.html
+++ b/src/fauxton/app/addons/documents/templates/jumpdoc.html
@@ -12,8 +12,9 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<form id="jump-to-doc" class="form-inline input-append" >
-  <input type="text" id="jump-to-doc-id" class="input-large" placeholder="Document ID"></input>
-
-  <button class="fonticon-search btn button red " type="submit"></button>
+<form id="jump-to-doc" class="pull-right">
+  <div class="input-append">
+    <input type="text" id="jump-to-doc-id" class="input-large" placeholder="Document ID"></input>
+    <button class="btn btn-primary" type="submit"><i class="icon icon-search"></i></button>
+  </div>
 </form>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/sidebar.html b/src/fauxton/app/addons/documents/templates/sidebar.html
index c8ce511..7358960 100644
--- a/src/fauxton/app/addons/documents/templates/sidebar.html
+++ b/src/fauxton/app/addons/documents/templates/sidebar.html
@@ -22,11 +22,11 @@ the License.
         </button>
         <ul class="dropdown-menu">
           <!-- dropdown menu links -->
-          <li><a class="icon-file" href="<%= db_url %>">Docs</a></li>
-          <li><a class="icon-lock" href="<%= permissions_url %>">Permissions</a></li>
-          <li><a class="icon-forward" href="<%= changes_url %>">Changes</a></li>
+          <li><a href="<%= db_url %>"><i class="icon icon-file"></i> Docs</a></li>
+          <li><a href="<%= permissions_url %>"><i class="icon icon-lock"></i> Permissions</a></li>
+          <li><a href="<%= changes_url %>"><i class="icon icon-forward"></i> Changes</a></li>
           <% _.each(docLinks, function (link) { %>
-          <li><a class="<%= link.icon %>" href="<%= database_url + '/' + link.url %>"><%= link.title %></a></li>
+          <li><a href="<%= database_url + '/' + link.url %>"><i class="icon <%= link.icon %>"></i> <%= link.title %></a></li>
           <% }); %>
         </ul>
       </div>
@@ -49,7 +49,7 @@ the License.
           </li>
         </ul>
       </div>
-        <button id="delete-database" class="btn"><i class="icon-trash"></i> Database</button>
+        <button id="delete-database" class="btn pull-right"><i class="icon-trash"></i> Database</button>
     </div>
   </header>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/upload_modal.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/upload_modal.html b/src/fauxton/app/addons/documents/templates/upload_modal.html
index 9a5c5cd..b71cd1e 100644
--- a/src/fauxton/app/addons/documents/templates/upload_modal.html
+++ b/src/fauxton/app/addons/documents/templates/upload_modal.html
@@ -35,8 +35,8 @@ the License.
     </div>
   </div>
   <div class="modal-footer">
-    <a href="#" data-dismiss="modal" data-bypass="true" class="btn button cancel-button outlineGray fonticon-circle-x">Cancel</a>
-    <a href="#" id="upload-btn" data-bypass="true" class="btn btn-primary button green save fonticon-circle-check">Upload</a>
+    <button href="#" data-dismiss="modal" data-bypass="true" class="btn"><i class="icon fonticon-circle-x"></i> Cancel</button>
+    <button href="#" id="upload-btn" data-bypass="true" class="btn btn-success save"><i class="icon fonticon-circle-check"></i> Upload</button>
   </div>
 </div>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/view_editor.html b/src/fauxton/app/addons/documents/templates/view_editor.html
index d02971e..be60090 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -13,9 +13,12 @@ the License.
 -->
 <div class="row">
   <ul class="nav nav-tabs" id="db-views-tabs-nav">
-    <li class="active"> <a data-bypass="true" id="index-nav" class="fonticon-wrench fonticon" data-toggle="tab" href="#index"><% if (newView) { %>Create Index <% } else { %>Edit Index <% } %></a></li>
+    <li class="active"> <a data-bypass="true" id="index-nav" data-toggle="tab" href="#index">
+      <i class="fonticon-wrench fonticon"></i>
+      <% if (newView) { %>Create Index <% } else { %>Edit Index <% } %></a></li>
     <% if (!newView) { %>
-    <li><a data-bypass="true" id="query-nav" class="fonticon-plus fonticon" href="#query" data-toggle="tab">Query Options</a></li>
+    <li><a data-bypass="true" id="query-nav" href="#query" data-toggle="tab">
+      <i class="fonticon-plus fonticon"></i> Query Options</a></li>
     <li><a data-bypass="true" id="meta-nav" href="#metadata" data-toggle="tab">Design Doc Metadata</a></li>
     <% } %>
   </ul>
@@ -69,10 +72,10 @@ the License.
           </div>
 
           <div class="control-group">
-            <button class="button green save fonticon-circle-check">Save &amp; Build Index</button>
-            <button class="button btn-info preview">Preview</button>
+            <button class="btn btn-success save"><i class="icon fonticon-circle-check"></i> Save &amp; Build Index</button>
+            <button class="btn btn-info preview">Preview</button>
             <% if (!newView) { %>
-            <button class="button delete outlineGray fonticon-circle-x">Delete</button>
+            <button class="btn btn-danger delete"><i class="icon fonticon-circle-x"></i> Delete</button>
             <% } %>
           </div>
           <div class="clearfix"></div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 8ddf46f..298cfb4 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -156,7 +156,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     template: "addons/documents/templates/upload_modal",
 
     events: {
-      "click a#upload-btn": "uploadFile"
+      "click #upload-btn": "uploadFile"
     },
 
     uploadFile: function (event) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/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
index 1f03a2c..4fb5971 100644
--- a/src/fauxton/app/addons/fauxton/templates/api_bar.html
+++ b/src/fauxton/app/addons/fauxton/templates/api_bar.html
@@ -12,9 +12,9 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<button class="button api-url-btn">
+<button class="btn btn-primary pull-right api-url-btn">
   API URL 
-  <span class="fonticon-plus icon"></span>
+  <i class="fonticon-plus icon"></i>
 </button>
 <div class="api-navbar" style="display: none">
     <div class="input-prepend input-append">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/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
index da030d6..9ba24f4 100644
--- a/src/fauxton/app/addons/fauxton/templates/nav_bar.html
+++ b/src/fauxton/app/addons/fauxton/templates/nav_bar.html
@@ -27,7 +27,7 @@ the License.
     <% if (link.view) {return;}  %>
         <li data-nav-name= "<%= link.title %>" >
           <a href="<%= link.href %>">
-            <span class="<%= link.icon %> fonticon"></span>
+            <i class="<%= link.icon %> fonticon"></i>
             <%= link.title %>
           </a>
         </li>
@@ -39,7 +39,7 @@ the License.
     <ul id="bottom-nav-links" class="nav">
         <li data-nav-name= "Documentation">
             <a href="<%=getDocUrl('docs')%>" target="_blank">
-              <span class="fonticon-bookmark fonticon"></span>
+              <i class="fonticon-bookmark fonticon"></i>
                 Documentation
             </a>
         </li>
@@ -49,7 +49,7 @@ the License.
       <% if (link.view) {return;}  %>
         <li data-nav-name= "<%= link.title %>">
             <a href="<%= link.href %>">
-              <span class="<%= link.icon %> fonticon"></span>
+              <i class="<%= link.icon %> fonticon"></i>
               <%= link.title %>
             </a>
         </li>
@@ -61,7 +61,7 @@ the License.
       <% if (link.view) {return;}  %>
         <li data-nav-name= "<%= link.title %>">
             <a href="<%= link.href %>">
-              <span class="<%= link.icon %> fonticon"></span>
+              <i class="<%= link.icon %> fonticon"></i>
               <%= link.title %>
             </a>
         </li>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/permissions/assets/less/permissions.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/permissions/assets/less/permissions.less b/src/fauxton/app/addons/permissions/assets/less/permissions.less
index 7ce4d10..83f270c 100644
--- a/src/fauxton/app/addons/permissions/assets/less/permissions.less
+++ b/src/fauxton/app/addons/permissions/assets/less/permissions.less
@@ -10,35 +10,18 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-.border-hdr {
-  border-bottom: 1px solid #E3E3E3;
-  margin-bottom: 10px;
-  .help{
-
-  }
-  h3{
-    text-transform: capitalize;
-    margin-bottom: 0;
-  }
-}
-
-
-.permission-items.unstyled{
-	margin-left: 0px;
-	li {
-		padding: 5px;
-		border-bottom: 1px solid #E3E3E3;
-		border-right: 1px solid #E3E3E3;
-		border-left: 3px solid #E3E3E3;
-		&:first-child{
-			border-top: 1px solid #E3E3E3;
-		}
-		&:nth-child(odd){
-      border-left: 3px solid red;
+.permission-items.unstyled {
+  margin-left: 0px;
+  li {
+    padding: 5px;
+    border-bottom: 1px solid #E3E3E3;
+    border-right: 1px solid #E3E3E3;
+    border-left: 3px solid #E3E3E3;
+    &:first-child {
+      border-top: 1px solid #E3E3E3;
     }
-    button {
-    	float: right;
-    	margin-bottom: 6px;
+    &:nth-child(odd){
+      border-left: 3px solid red;
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/permissions/templates/item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/permissions/templates/item.html b/src/fauxton/app/addons/permissions/templates/item.html
index 616ffd6..490cff4 100644
--- a/src/fauxton/app/addons/permissions/templates/item.html
+++ b/src/fauxton/app/addons/permissions/templates/item.html
@@ -13,5 +13,5 @@ the License.
 -->
 
 <span> <%= item %> </span>
-<button type="button" class="close">&times;</button>
+<button type="button" class="pull-right close">&times;</button>
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/permissions/templates/section.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/permissions/templates/section.html b/src/fauxton/app/addons/permissions/templates/section.html
index 3360308..8f4d552 100644
--- a/src/fauxton/app/addons/permissions/templates/section.html
+++ b/src/fauxton/app/addons/permissions/templates/section.html
@@ -11,9 +11,9 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 License for the specific language governing permissions and limitations under
 the License.
 -->
-<header class="border-hdr">
+<header class="page-header">
 <h3> <%= (section) %> </h3>
-<p id="help"> <%= help %> <a href="<%=getDocUrl('database_permission')%>" target="_blank"><i class="icon-question-sign"> </i> </a></p>
+<p class="help"> <%= help %> <a href="<%=getDocUrl('database_permission')%>" target="_blank"><i class="icon-question-sign"> </i> </a></p>
 </header>
 
 <div class="row">
@@ -24,7 +24,7 @@ the License.
     </header>
     <form class="permission-item-form form-inline">
       <input data-section="<%= section %>" data-type="names" type="text" class="item input-small" placeholder="Add Name">
-      <button type="submit" class="button btn green fonticon-circle-plus">Add Name</button>
+      <button type="submit" class="btn btn-success"><i class="icon fonticon-circle-plus"></i> Add Name</button>
     </form>
     <ul class="clearfix unstyled permission-items span10" id="<%= (section) %>-items-names">
     </ul>
@@ -38,7 +38,7 @@ the License.
 
     <form class="permission-item-form form-inline">
       <input data-section="<%= section %>" data-type="roles" type="text" class="item input-small" placeholder="Add Role">
-      <button type="submit" class="button btn green fonticon-circle-plus">Add Role</button>
+      <button type="submit" class="btn btn-success"><i class="icon fonticon-circle-plus"></i> Add Role</button>
     </form>
     <ul class="unstyled permission-items span10" id="<%= (section) %>-items-roles">
     </ul>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/replication/assets/less/replication.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/replication/assets/less/replication.less b/src/fauxton/app/addons/replication/assets/less/replication.less
index a301966..0f8a8f5 100644
--- a/src/fauxton/app/addons/replication/assets/less/replication.less
+++ b/src/fauxton/app/addons/replication/assets/less/replication.less
@@ -10,187 +10,179 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
+@import "../../../../../assets/less/variables.less";
 
-@brown: #3A2C2B;
-@red: #E33F3B;
-@darkRed: #AF2D24;
-@linkRed: #DA4F49;
-@greyBrown: #A59D9D;
-@fontGrey: #808080;
-@secondarySidebar: #E4DFDC;
+#replication {
+  position: relative;
+  max-width: none;
+  width: auto;
 
+  .form_set {
+    width: 350px;
+    display: inline-block;
+    border: 1px solid @greyBrownLighter;
+    padding: 15px 10px 0;
+    margin-bottom: 20px;
+    &.middle {
+      width: 100px;
+      border: none;
+      position: relative;
+      height: 100px;
+      margin: 0;
+    }
+    input, select {
+      margin: 0 0 16px 5px;
+      height: 40px;
+      width: 318px;
+    }
+    .btn-group {
+      margin: 0 0 16px 5px;
+      .btn {
+        padding: 10px 57px;
+      }
+    }
+    &.local {
+      .local_option {
+        display: block;
+      }
+      .remote_option {
+        display: none;
+      }
+      .local-btn {
+        background-color: @red;
+        color: #fff;
+      }
+      .remote-btn {
+        background-color: #f5f5f5;
+        color: @fontGrey;
+      }
+    }
+    .local_option {
+      display: none;
+    }
+    .remote-btn {
+      background-color: @red;
+      color: #fff;
+    }
+  }
 
-form#replication {
-	position: relative;
-	max-width: none;
-	width: auto;
 
-	.form_set{
-		width: 350px;
-		display: inline-block;
-		border: 1px solid @greyBrown;
-		padding: 15px 10px 0;
-		margin-bottom: 20px;
-		&.middle{
-			width: 100px;
-			border: none;
-			position: relative;
-			height: 100px;
-			margin: 0;
-		}
-		input, select {
-			margin: 0 0 16px 5px;
-			height: 40px;
-			width: 318px;
-		}
-		.btn-group{
-			margin: 0 0 16px 5px;
-			.btn {
-				padding: 10px 57px;
-			}
-		}
-		&.local{
-			.local_option{
-				display: block;
-			}
-			.remote_option{
-				display: none;
-			}
-			.local-btn{
-				background-color: @red;
-				color: #fff;
-			}
-			.remote-btn{
-				background-color: #f5f5f5;
-				color: @fontGrey;
-			}
-		}
-		.local_option{
-			display: none;
-		}
-		.remote-btn{
-			background-color: @red;
-			color: #fff;
-		}
-	}
+  .options {
+    position: relative;
+    &:after {
+      content: '';
+      display: block;
+      position: absolute;
+      right: -16px;
+      top: 9px;
+      width: 0;
+      height: 0;
+      border-left: 5px solid transparent;
+      border-right: 5px solid transparent;
+      border-bottom: 5px solid black;
+      border-top: none;
+    }
+    &.off {
+      &:after {
+      content: '';
+      display: block;
+      position: absolute;
+      right: -16px;
+      top: 9px;
+      width: 0;
+      height: 0;
+      border-left: 5px solid transparent;
+      border-right: 5px solid transparent;
+      border-bottom: none;
+      border-top: 5px solid black;
+      }
+    }
+  }
+  .control-group {
+    label {
+      float: left;
+      min-height: 30px;
+      vertical-align: top;
+      padding-right: 5px;
+      min-width: 130px;
+      padding-left: 0px;
+    }
+    input[type=radio],
+    input[type=checkbox] {
+      margin: 0 0 2px 0;
+    }
+  }
 
+  .circle {
+    z-index: 0;
+    position: absolute;
+    top: 20px;
+    left: 15px;
 
-	.options {
-		position: relative;
-		&:after{
-			content: '';
-			display: block;
-			position: absolute;
-			right: -16px;
-			top: 9px;
-			width: 0; 
-			height: 0; 
-			border-left: 5px solid transparent;
-			border-right: 5px solid transparent;
-			border-bottom: 5px solid black;
-			border-top: none;
-		}
-		&.off {
-			&:after{
-			content: '';
-			display: block;
-			position: absolute;
-			right: -16px;
-			top: 9px;
-			width: 0; 
-			height: 0; 
-			border-left: 5px solid transparent;
-			border-right: 5px solid transparent;
-			border-bottom: none;
-			border-top: 5px solid black;
-			}
-		}
-	}
-	.control-group{
-		label{
-			float: left;
-			min-height: 30px;
-			vertical-align: top;
-			padding-right: 5px;
-			min-width: 130px;
-			padding-left: 0px;
-		}
-		input[type=radio],
-		input[type=checkbox]{
-			margin: 0 0 2px 0;
-		}
-	}
-
-	.circle{
-		z-index: 0;
-		position: absolute;
-		top: 20px;
-		left: 15px;
-
-		&:after {
-			width: 70px;
-			height: 70px;
-			content: '';
-			display: block;
-			position: relative;
-			margin: 0 auto;
-			border: 1px solid @greyBrown;
-			-webkit-border-radius: 40px;
-			-moz-border-radius: 40px;
-			border-radius:40px;
-		}
-	}
-	.swap {
-		text-decoration: none;
-		z-index: 30;
-		cursor: pointer;
-		position: absolute;
-		font-size: 40px;
-		width: 27px;
-		height: 12px;
-		top: 31px;
-		left: 30px;
-		&:hover {
-			color: @greyBrown;
-		}
-	}
-
+    &:after {
+      width: 70px;
+      height: 70px;
+      content: '';
+      display: block;
+      position: relative;
+      margin: 0 auto;
+      border: 1px solid @greyBrownLighter;
+      -webkit-border-radius: 40px;
+      -moz-border-radius: 40px;
+      border-radius:40px;
+    }
+  }
+  .swap {
+    text-decoration: none;
+    z-index: 30;
+    cursor: pointer;
+    position: absolute;
+    font-size: 40px;
+    width: 27px;
+    height: 12px;
+    top: 31px;
+    left: 30px;
+    &:hover {
+      color: @greyBrownLighter;
+    }
+  }
 }
-#replicationStatus{
-	&.showHeader{
-		li.header{
-			display: block;
-			border: none;
-		}
-		ul {
-			border:1px solid @greyBrown;
-		}
-	}
-	li.header{
-		display: none;
-	}
-	ul{
-		margin: 0;
-		li{
-			.progress,
-			p{
-				margin: 0px;
-				vertical-align: bottom;
-				&.break {
-					-ms-word-break: break-all;
-					word-break: break-all;
 
-					/* Non standard for webkit */
-					word-break: break-word;
-					-webkit-hyphens: auto;
-					-moz-hyphens: auto;
-					hyphens: auto;
-				}
-			}
-			padding: 10px 10px;
-			margin: 0;
-			list-style: none;
-			border-top: 1px solid @greyBrown;
-		}
-	}
+#replicationStatus {
+  &.showHeader {
+    li.header {
+      display: block;
+      border: none;
+    }
+    ul {
+      border:1px solid @greyBrownLighter;
+    }
+  }
+  li.header {
+    display: none;
+  }
+  ul {
+    margin: 0;
+    li {
+      .progress,
+      p {
+        margin: 0px;
+        vertical-align: bottom;
+        &.break {
+          -ms-word-break: break-all;
+          word-break: break-all;
+
+          /* Non standard for webkit */
+          word-break: break-word;
+          -webkit-hyphens: auto;
+          -moz-hyphens: auto;
+          hyphens: auto;
+        }
+      }
+      padding: 10px 10px;
+      margin: 0;
+      list-style: none;
+      border-top: 1px solid @greyBrownLighter;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/stats/assets/less/stats.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/assets/less/stats.less b/src/fauxton/app/addons/stats/assets/less/stats.less
index cfa7679..7ec88b9 100644
--- a/src/fauxton/app/addons/stats/assets/less/stats.less
+++ b/src/fauxton/app/addons/stats/assets/less/stats.less
@@ -11,9 +11,5 @@
 // the License.
 
 .datatypes {
-  border: #d3d3d3 1px solid;
-  -webkit-border-radius: 5px;
-  -moz-border-radius: 5px;
-  border-radius: 5px;
-  padding: 15px;
+  padding: 0 15px;
 }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/styletests/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/styletests/base.js b/src/fauxton/app/addons/styletests/base.js
new file mode 100644
index 0000000..fae6d11
--- /dev/null
+++ b/src/fauxton/app/addons/styletests/base.js
@@ -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.
+
+define([
+  "app",
+  "api",
+  "addons/styletests/routes"
+],
+
+function(app, FauxtonAPI, tests) {
+
+	tests.initialize = function() {
+
+		FauxtonAPI.addHeaderLink({
+			title: "Tests", 
+			href: '#/tests',
+			bottomNav: true,
+			icon: "fonticon-wrench"
+		});
+		
+	};
+
+	return tests;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/styletests/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/styletests/resources.js b/src/fauxton/app/addons/styletests/resources.js
new file mode 100644
index 0000000..0309d8e
--- /dev/null
+++ b/src/fauxton/app/addons/styletests/resources.js
@@ -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.
+
+define([
+  "app",
+  "api"
+],
+
+function (app, FauxtonAPI) {
+  var resources = {};
+
+  return resources;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/styletests/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/styletests/routes.js b/src/fauxton/app/addons/styletests/routes.js
new file mode 100644
index 0000000..cafd9f2
--- /dev/null
+++ b/src/fauxton/app/addons/styletests/routes.js
@@ -0,0 +1,40 @@
+// 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/styletests/views"
+],
+
+function(app, FauxtonAPI, Views) {
+
+	var TestRouteObject = FauxtonAPI.RouteObject.extend({
+		layout: "one_pane",
+		routes: {
+			"tests": "initialize"
+		},
+		selectedHeader: 'theme tests',
+		crumbs:[],
+    apiUrl: function(){
+      return false;
+    },
+    initialize: function(){
+			this.setView("#dashboard-content", new Views.tests({}));
+    }
+	});
+
+	Views.RouteObjects = [TestRouteObject];
+
+	return Views;
+ 
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/styletests/templates/theme.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/styletests/templates/theme.html b/src/fauxton/app/addons/styletests/templates/theme.html
new file mode 100644
index 0000000..f05bad1
--- /dev/null
+++ b/src/fauxton/app/addons/styletests/templates/theme.html
@@ -0,0 +1,496 @@
+// 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="container theme-showcase">
+
+  <!-- Main jumbotron for a primary marketing message or call to action -->
+  <div class="jumbotron">
+    <h1>Fauxton Style Guide <small>mostly made of Bootstrap 2.x</small></h1>
+    <p>(Mostly) Standard Bootstrap styles customized for Fauxton.</p>
+  </div>
+
+  <div class="page-header">
+    <h1>Typography</h1>
+  </div>
+  <h1>h1. Heading 1</h1>
+  <h2>h2. Heading 2</h2>
+  <h3>h3. Heading 3</h3>
+  <h4>h4. Heading 4</h4>
+  <h5>h5. Heading 5</h5>
+  <h6>h6. Heading 6</h6>
+
+  <div class="page-header">
+    <h1>Buttons</h1>
+  </div>
+
+  <h4>Bootstrap Standard Button class names</h4>
+  <p>.btn.btn-large.btn-*<br />
+    <button type="button" class="btn btn-large btn-default">Default</button>
+    <button type="button" class="btn btn-large btn-primary">Primary</button>
+    <button type="button" class="btn btn-large btn-success">Success</button>
+    <button type="button" class="btn btn-large btn-info">Info</button>
+    <button type="button" class="btn btn-large btn-warning">Warning</button>
+    <button type="button" class="btn btn-large btn-danger">Danger</button>
+    <button type="button" class="btn btn-large btn-link">Link</button>
+  </p>
+  <p>.btn.btn-*<br />
+    <button type="button" class="btn btn-default">Default</button>
+    <button type="button" class="btn btn-primary">Primary</button>
+    <button type="button" class="btn btn-success">Success</button>
+    <button type="button" class="btn btn-info">Info</button>
+    <button type="button" class="btn btn-warning">Warning</button>
+    <button type="button" class="btn btn-danger">Danger</button>
+    <button type="button" class="btn btn-link">Link</button>
+  </p>
+  <p>.btn.btn-small.btn-*<br />
+    <button type="button" class="btn btn-small btn-default">Default</button>
+    <button type="button" class="btn btn-small btn-primary">Primary</button>
+    <button type="button" class="btn btn-small btn-success">Success</button>
+    <button type="button" class="btn btn-small btn-info">Info</button>
+    <button type="button" class="btn btn-small btn-warning">Warning</button>
+    <button type="button" class="btn btn-small btn-danger">Danger</button>
+    <button type="button" class="btn btn-small btn-link">Link</button>
+  </p>
+  <p>.btn.btn-mini.btn-*<br />
+    <button type="button" class="btn btn-mini btn-default">Default</button>
+    <button type="button" class="btn btn-mini btn-primary">Primary</button>
+    <button type="button" class="btn btn-mini btn-success">Success</button>
+    <button type="button" class="btn btn-mini btn-info">Info</button>
+    <button type="button" class="btn btn-mini btn-warning">Warning</button>
+    <button type="button" class="btn btn-mini btn-danger">Danger</button>
+    <button type="button" class="btn btn-mini btn-link">Link</button>
+  </p>
+
+  <h4>with Icons</h4>
+  <p>.btn.btn-large.btn-*<br />
+    <button type="button" class="btn btn-large btn-default"><i class="icon fonticon-new-database"></i> Default</button>
+    <button type="button" class="btn btn-large btn-primary"><i class="icon fonticon-new-database"></i> Primary</button>
+    <button type="button" class="btn btn-large btn-success"><i class="icon fonticon-new-database"></i> Success</button>
+    <button type="button" class="btn btn-large btn-info"><i class="icon fonticon-new-database"></i> Info</button>
+    <button type="button" class="btn btn-large btn-warning"><i class="icon fonticon-new-database"></i> Warning</button>
+    <button type="button" class="btn btn-large btn-danger"><i class="icon fonticon-new-database"></i> Danger</button>
+    <button type="button" class="btn btn-large btn-link"><i class="icon fonticon-new-database"></i> Link</button>
+  </p>
+
+  <p>.btn.btn-*<br />
+    <button type="button" class="btn btn-default"><i class="icon fonticon-new-database"></i> Default</button>
+    <button type="button" class="btn btn-primary"><i class="icon fonticon-new-database"></i> Primary</button>
+    <button type="button" class="btn btn-success"><i class="icon fonticon-new-database"></i> Success</button>
+    <button type="button" class="btn btn-info"><i class="icon fonticon-new-database"></i> Info</button>
+    <button type="button" class="btn btn-warning"><i class="icon fonticon-new-database"></i> Warning</button>
+    <button type="button" class="btn btn-danger"><i class="icon fonticon-new-database"></i> Danger</button>
+    <button type="button" class="btn btn-link"><i class="icon fonticon-new-database"></i> Link</button>
+  </p>
+  <p>.btn.btn-small.btn-*<br />
+    <button type="button" class="btn btn-small btn-default"><i class="icon fonticon-new-database"></i> Default</button>
+    <button type="button" class="btn btn-small btn-primary"><i class="icon fonticon-new-database"></i> Primary</button>
+    <button type="button" class="btn btn-small btn-success"><i class="icon fonticon-new-database"></i> Success</button>
+    <button type="button" class="btn btn-small btn-info"><i class="icon fonticon-new-database"></i> Info</button>
+    <button type="button" class="btn btn-small btn-warning"><i class="icon fonticon-new-database"></i> Warning</button>
+    <button type="button" class="btn btn-small btn-danger"><i class="icon fonticon-new-database"></i> Danger</button>
+    <button type="button" class="btn btn-small btn-link"><i class="icon fonticon-new-database"></i> Link</button>
+  </p>
+  <p>.btn.btn-mini.btn-*<br />
+    <button type="button" class="btn btn-mini btn-default"><i class="icon fonticon-new-database"></i> Default</button>
+    <button type="button" class="btn btn-mini btn-primary"><i class="icon fonticon-new-database"></i> Primary</button>
+    <button type="button" class="btn btn-mini btn-success"><i class="icon fonticon-new-database"></i> Success</button>
+    <button type="button" class="btn btn-mini btn-info"><i class="icon fonticon-new-database"></i> Info</button>
+    <button type="button" class="btn btn-mini btn-warning"><i class="icon fonticon-new-database"></i> Warning</button>
+    <button type="button" class="btn btn-mini btn-danger"><i class="icon fonticon-new-database"></i> Danger</button>
+    <button type="button" class="btn btn-mini btn-link"><i class="icon fonticon-new-database"></i> Link</button>
+  </p>
+
+  <h4>just Icons</h4>
+  <p>.btn.btn-large.btn-*<br />
+    <button type="button" class="btn btn-large btn-default"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-large btn-primary"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-large btn-success"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-large btn-info"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-large btn-warning"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-large btn-danger"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-large btn-link"><i class="icon fonticon-new-database"></i></button>
+  </p>
+
+  <p>.btn.btn-*<br />
+    <button type="button" class="btn btn-default"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-primary"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-success"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-info"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-warning"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-danger"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-link"><i class="icon fonticon-new-database"></i></button>
+  </p>
+  <p>.btn.btn-small.btn-*<br />
+    <button type="button" class="btn btn-small btn-default"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-small btn-primary"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-small btn-success"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-small btn-info"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-small btn-warning"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-small btn-danger"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-small btn-link"><i class="icon fonticon-new-database"></i></button>
+  </p>
+  <p>.btn.btn-mini.btn-*<br />
+    <button type="button" class="btn btn-mini btn-default"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-mini btn-primary"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-mini btn-success"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-mini btn-info"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-mini btn-warning"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-mini btn-danger"><i class="icon fonticon-new-database"></i></button>
+    <button type="button" class="btn btn-mini btn-link"><i class="icon fonticon-new-database"></i></button>
+  </p>
+  <p>.btn-group<br />
+    <div class="btn-group">
+      <a href="#" class="btn btn-small edits">Edit design doc</a>
+      <button href="#" class="btn btn-small btn-danger delete" title="Delete this document."><i class="icon icon-trash"></i></button>
+    </div>
+  </p>
+
+  <h4>disabled</h4>
+  <p>.btn.btn-*<br />
+    <button type="button" disabled="disabled" class="btn btn-default"><i class="icon fonticon-new-database"></i> Default</button>
+    <button type="button" disabled="disabled" class="btn btn-primary"><i class="icon fonticon-new-database"></i> Primary</button>
+    <button type="button" disabled="disabled" class="btn btn-success"><i class="icon fonticon-new-database"></i> Success</button>
+    <button type="button" disabled="disabled" class="btn btn-info"><i class="icon fonticon-new-database"></i> Info</button>
+    <button type="button" disabled="disabled" class="btn btn-warning"><i class="icon fonticon-new-database"></i> Warning</button>
+    <button type="button" disabled="disabled" class="btn btn-danger"><i class="icon fonticon-new-database"></i> Danger</button>
+    <button type="button" disabled="disabled" class="btn btn-link"><i class="icon fonticon-new-database"></i> Link</button>
+  </p>
+  <p>.btn.btn-*<br />
+    <button type="button" disabled="disabled" class="btn btn-default">Default</button>
+    <button type="button" disabled="disabled" class="btn btn-primary">Primary</button>
+    <button type="button" disabled="disabled" class="btn btn-success">Success</button>
+    <button type="button" disabled="disabled" class="btn btn-info">Info</button>
+    <button type="button" disabled="disabled" class="btn btn-warning">Warning</button>
+    <button type="button" disabled="disabled" class="btn btn-danger">Danger</button>
+    <button type="button" disabled="disabled" class="btn btn-link">Link</button>
+  </p>
+
+  <div class="page-header">
+    <h1>Forms</h1>
+  </div>
+
+  <form class="navbar-form database-search">
+    <div class="input-append">
+      <input class="search-autocomplete" name="search-query" placeholder="Database name" type="text">
+      <button class="btn btn-primary" type="submit"><i class="icon icon-search"></i></button>
+    </div>
+  </form>
+
+  <form class="navbar-form database-search">
+    <div class="input-append">
+      <input class="search-autocomplete" name="search-query" placeholder="Database name" type="text">
+      <button class="btn btn-primary" type="submit"><i class="icon icon-search"></i> Search</button>
+    </div>
+  </form>
+
+  <form class="navbar-form">
+    <div class="input-append">
+      <input name="search-query" placeholder="Database name" type="text">
+      <button class="btn btn-primary" type="submit">Search</button>
+    </div>
+  </form>
+
+  <form>
+    <fieldset>
+      <legend>Legend</legend>
+      <label>Label name</label>
+      <input type="text" placeholder="Type something…">
+      <span class="help-block">Example block-level help text here.</span>
+      <label class="checkbox">
+        <input type="checkbox"> Check me out
+      </label>
+      <button type="submit" class="btn">Submit</button>
+    </fieldset>
+  </form>
+
+  <p>Search</p>
+  <form class="form-search">
+    <input type="text" class="input-medium search-query">
+    <button type="submit" class="btn">Search</button>
+  </form>
+
+  <p>Sign in</p>
+  <form class="form-inline">
+    <input type="text" class="input-small" placeholder="Email">
+    <input type="password" class="input-small" placeholder="Password">
+    <label class="checkbox">
+      <input type="checkbox"> Remember me
+    </label>
+    <button type="submit" class="btn">Sign in</button>
+  </form>
+
+  <p>Whole form</p>
+  <form class="form-horizontal">
+  <div class="control-group">
+    <label class="control-label" for="inputEmail">Email</label>
+    <div class="controls">
+      <input type="text" id="inputEmail" placeholder="Email">
+    </div>
+  </div>
+  <div class="control-group">
+    <label class="control-label" for="inputPassword">Password</label>
+    <div class="controls">
+      <input type="password" id="inputPassword" placeholder="Password">
+    </div>
+  </div>
+  <div class="control-group">
+    <div class="controls">
+      <label class="checkbox">
+        <input type="checkbox"> Remember me
+      </label>
+      <button type="submit" class="btn">Sign in</button>
+    </div>
+  </div>
+  </form>
+
+  <p>Selects</p>
+  <select>
+    <option>1</option>
+    <option>2</option>
+    <option>3</option>
+    <option>4</option>
+    <option>5</option>
+  </select>
+   
+  <select multiple="multiple">
+    <option>1</option>
+    <option>2</option>
+    <option>3</option>
+    <option>4</option>
+    <option>5</option>
+  </select>
+
+  <p>Inputs with pre</p>
+  <div class="input-prepend">
+    <span class="add-on">@</span>
+    <input class="span2" id="prependedInput" type="text" placeholder="Username">
+  </div>
+  <p>Inputs with post</p>
+  <div class="input-append">
+    <input class="span2" id="appendedInput" type="text">
+    <span class="add-on">.00</span>
+  </div>
+  <p>Inputs with pre and post</p>
+  <div class="input-prepend input-append">
+    <span class="add-on">$</span>
+    <input class="span2" id="appendedPrependedInput" type="text">
+    <span class="add-on">.00</span>
+  </div>
+  <p>Inputs with button</p>
+<div class="input-append">
+  <input class="span2" id="appendedInputButton" type="text">
+  <button class="btn" type="button">Go!</button>
+</div>
+  <p>Inputs with two buttons</p>
+<div class="input-append">
+  <input class="span2" id="appendedInputButtons" type="text">
+  <button class="btn" type="button">Search</button>
+  <button class="btn" type="button">Options</button>
+</div>
+<p>Inputs with dropdown button</p>
+<div class="input-append">
+  <input class="span2" id="appendedDropdownButton" type="text">
+  <div class="btn-group">
+    <button class="btn dropdown-toggle" data-toggle="dropdown">
+      Action
+      <span class="caret"></span>
+    </button>
+    <ul class="dropdown-menu">
+      ...
+    </ul>
+  </div>
+</div>
+<p>Inputs sizes</p>
+<input class="input-mini" type="text" placeholder=".input-mini">
+<input class="input-small" type="text" placeholder=".input-small">
+<input class="input-medium" type="text" placeholder=".input-medium">
+<input class="input-large" type="text" placeholder=".input-large">
+<input class="input-xlarge" type="text" placeholder=".input-xlarge">
+<input class="input-xxlarge" type="text" placeholder=".input-xxlarge">
+
+
+  <div class="page-header">
+    <h1>Thumbnails</h1>
+  </div>
+<img src="https://dl.dropboxusercontent.com/u/44146427/ripley.jpeg" class="img-rounded">
+<img src="https://dl.dropboxusercontent.com/u/44146427/ripley.jpeg" class="img-circle">
+<img src="https://dl.dropboxusercontent.com/u/44146427/ripley.jpeg" class="img-polaroid">
+
+
+  <div class="page-header">
+    <h1>Dropdown menus</h1>
+  </div>
+  <div class="dropdown theme-dropdown clearfix">
+    <a id="dropdownMenu1" href="#" role="button" class="sr-only dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+    <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
+      <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Action</a></li>
+      <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Another action</a></li>
+      <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Something else here</a></li>
+      <li role="presentation" class="divider"></li>
+      <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Separated link</a></li>
+    </ul>
+  </div>
+
+
+
+
+  <div class="page-header">
+    <h1>Navbars</h1>
+  </div>
+
+  <div class="navbar navbar-default">
+    <div class="container">
+      <div class="navbar-header">
+        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button>
+        <a class="navbar-brand" href="#">Project name</a>
+      </div>
+      <div class="navbar-collapse collapse">
+        <ul class="nav navbar-nav">
+          <li class="active"><a href="#">Home</a></li>
+          <li><a href="#about">About</a></li>
+          <li><a href="#contact">Contact</a></li>
+        </ul>
+        <ul class="nav navbar-nav navbar-right">
+          <li><a href="../navbar/">Default</a></li>
+          <li><a href="../navbar-static-top/">Static top</a></li>
+          <li class="active"><a href="./">Fixed top</a></li>
+        </ul>
+      </div><!--/.nav-collapse -->
+    </div>
+  </div>
+
+  <div class="navbar navbar-inverse">
+    <div class="container">
+      <div class="navbar-header">
+        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button>
+        <a class="navbar-brand" href="#">Project name</a>
+      </div>
+      <div class="navbar-collapse collapse">
+        <ul class="nav navbar-nav">
+          <li class="active"><a href="#">Home</a></li>
+          <li><a href="#about">About</a></li>
+          <li><a href="#contact">Contact</a></li>
+        </ul>
+        <ul class="nav navbar-nav navbar-right">
+          <li><a href="../navbar/">Default</a></li>
+          <li><a href="../navbar-static-top/">Static top</a></li>
+          <li class="active"><a href="./">Fixed top</a></li>
+        </ul>
+      </div><!--/.nav-collapse -->
+    </div>
+  </div>
+
+
+
+  <div class="page-header">
+    <h1>Alerts</h1>
+  </div>
+  <div class="alert alert-success">
+    <strong>Well done!</strong> You successfully read this important alert message.
+  </div>
+  <div class="alert alert-info">
+    <strong>Heads up!</strong> This alert needs your attention, but it's not super important.
+  </div>
+  <div class="alert alert-warning">
+    <strong>Warning!</strong> Best check yo self, you're not looking too good.
+  </div>
+  <div class="alert alert-danger">
+    <strong>Oh snap!</strong> Change a few things up and try submitting again.
+  </div>
+
+
+
+  <div class="page-header">
+    <h1>Progresss</h1>
+  </div>
+  <div class="progress">
+    <div class="bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"><span class="sr-only">60% Complete</span></div>
+  </div>
+  <div class="progress">
+    <div class="bar bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"><span class="sr-only">40% Complete (success)</span></div>
+  </div>
+  <div class="progress">
+    <div class="bar bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%"><span class="sr-only">20% Complete</span></div>
+  </div>
+  <div class="progress">
+    <div class="bar bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"><span class="sr-only">60% Complete (warning)</span></div>
+  </div>
+  <div class="progress">
+    <div class="bar bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%"><span class="sr-only">80% Complete (danger)</span></div>
+  </div>
+  <div class="progress">
+    <div class="bar bar-success" style="width: 35%"><span class="sr-only">35% Complete (success)</span></div>
+    <div class="bar bar-warning" style="width: 20%"><span class="sr-only">20% Complete (warning)</span></div>
+    <div class="bar bar-danger" style="width: 10%"><span class='sr-only'>10% Complete (danger)</span></div>
+  </div>
+
+
+
+  <div class="page-header">
+    <h1>List groups</h1>
+  </div>
+  <div class="row">
+    <div class="col-sm-4">
+      <ul class="nav nav-tabs nav-stacked">
+        <li class="list-group-item">Cras justo odio</li>
+        <li class="list-group-item">Dapibus ac facilisis in</li>
+        <li class="list-group-item">Morbi leo risus</li>
+        <li class="list-group-item">Porta ac consectetur ac</li>
+        <li class="list-group-item">Vestibulum at eros</li>
+      </ul>
+    </div><!-- /.col-sm-4 -->
+    <div class="col-sm-4">
+      <div class="nav nav-tabs nav-stacked">
+        <a href="#" class="list-group-item active">
+          Cras justo odio
+        </a>
+        <a href="#" class="list-group-item">Dapibus ac facilisis in</a>
+        <a href="#" class="list-group-item">Morbi leo risus</a>
+        <a href="#" class="list-group-item">Porta ac consectetur ac</a>
+        <a href="#" class="list-group-item">Vestibulum at eros</a>
+      </div>
+    </div><!-- /.col-sm-4 -->
+    <div class="col-sm-4">
+      <div class="nav nav-tabs nav-stacked">
+        <a href="#" class="list-group-item active">
+          <h4 class="list-group-item-heading">List group item heading</h4>
+          <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
+        </a>
+        <a href="#" class="list-group-item">
+          <h4 class="list-group-item-heading">List group item heading</h4>
+          <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
+        </a>
+        <a href="#" class="list-group-item">
+          <h4 class="list-group-item-heading">List group item heading</h4>
+          <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
+        </a>
+      </div>
+    </div><!-- /.col-sm-4 -->
+  </div>
+
+  <div class="page-header">
+    <h1>Wells</h1>
+  </div>
+  <div class="well">
+    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed diam eget risus varius blandit sit amet non magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Aenean lacinia bibendum nulla sed consectetur.</p>
+  </div>
+
+
+</div> <!-- /container -->

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/styletests/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/styletests/views.js b/src/fauxton/app/addons/styletests/views.js
new file mode 100644
index 0000000..f3e8bbb
--- /dev/null
+++ b/src/fauxton/app/addons/styletests/views.js
@@ -0,0 +1,29 @@
+// 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 Views= {};
+
+  Views.tests = FauxtonAPI.View.extend({
+    template: "addons/styletests/templates/theme"
+  });
+
+  return Views;
+});
+
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/verifyinstall/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/routes.js b/src/fauxton/app/addons/verifyinstall/routes.js
index e5024ba..df00736 100644
--- a/src/fauxton/app/addons/verifyinstall/routes.js
+++ b/src/fauxton/app/addons/verifyinstall/routes.js
@@ -29,7 +29,7 @@ function(app, FauxtonAPI, VerifyInstall) {
       this.setView('#dashboard-content', new VerifyInstall.Main({}));
     },
 
-    crumbs: [{name: 'Verify Couchdb Installation', link: '#'}]
+    crumbs: [{name: 'Verify CouchDB Installation', link: '#'}]
   });
 
   VerifyInstall.RouteObjects = [VerifyRouteObject];

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/addons/verifyinstall/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/verifyinstall/views.js b/src/fauxton/app/addons/verifyinstall/views.js
index eb6dac4..1e7e6f5 100644
--- a/src/fauxton/app/addons/verifyinstall/views.js
+++ b/src/fauxton/app/addons/verifyinstall/views.js
@@ -43,7 +43,7 @@ function(app, FauxtonAPI, VerifyInstall) {
 
     complete: function () {
       FauxtonAPI.addNotification({
-        msg: 'Success! You Couchdb install is working. Time to Relax',
+        msg: 'Success! You CouchDB install is working. Time to Relax',
         type: 'success',
         selector: '#error'
       });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/templates/fauxton/api_bar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/fauxton/api_bar.html b/src/fauxton/app/templates/fauxton/api_bar.html
index 1f03a2c..4fb5971 100644
--- a/src/fauxton/app/templates/fauxton/api_bar.html
+++ b/src/fauxton/app/templates/fauxton/api_bar.html
@@ -12,9 +12,9 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 
-<button class="button api-url-btn">
+<button class="btn btn-primary pull-right api-url-btn">
   API URL 
-  <span class="fonticon-plus icon"></span>
+  <i class="fonticon-plus icon"></i>
 </button>
 <div class="api-navbar" style="display: none">
     <div class="input-prepend input-append">

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/templates/fauxton/breadcrumbs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/fauxton/breadcrumbs.html b/src/fauxton/app/templates/fauxton/breadcrumbs.html
index 026db89..34c4136 100644
--- a/src/fauxton/app/templates/fauxton/breadcrumbs.html
+++ b/src/fauxton/app/templates/fauxton/breadcrumbs.html
@@ -16,7 +16,7 @@ the License.
   <% _.each(_.initial(crumbs), function(crumb) { %>
     <li>
       <a href="#<%= crumb.link %>"><%= crumb.name %></a>
-      <span class="divider fonticon fonticon-carrot"> </span>
+      <i class="divider fonticon fonticon-carrot"> </i>
     </li>
   <% }); %>
   <% var last = _.last(crumbs) || {name: ''} %>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/app/templates/fauxton/nav_bar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/fauxton/nav_bar.html b/src/fauxton/app/templates/fauxton/nav_bar.html
index da030d6..9ba24f4 100644
--- a/src/fauxton/app/templates/fauxton/nav_bar.html
+++ b/src/fauxton/app/templates/fauxton/nav_bar.html
@@ -27,7 +27,7 @@ the License.
     <% if (link.view) {return;}  %>
         <li data-nav-name= "<%= link.title %>" >
           <a href="<%= link.href %>">
-            <span class="<%= link.icon %> fonticon"></span>
+            <i class="<%= link.icon %> fonticon"></i>
             <%= link.title %>
           </a>
         </li>
@@ -39,7 +39,7 @@ the License.
     <ul id="bottom-nav-links" class="nav">
         <li data-nav-name= "Documentation">
             <a href="<%=getDocUrl('docs')%>" target="_blank">
-              <span class="fonticon-bookmark fonticon"></span>
+              <i class="fonticon-bookmark fonticon"></i>
                 Documentation
             </a>
         </li>
@@ -49,7 +49,7 @@ the License.
       <% if (link.view) {return;}  %>
         <li data-nav-name= "<%= link.title %>">
             <a href="<%= link.href %>">
-              <span class="<%= link.icon %> fonticon"></span>
+              <i class="<%= link.icon %> fonticon"></i>
               <%= link.title %>
             </a>
         </li>
@@ -61,7 +61,7 @@ the License.
       <% if (link.view) {return;}  %>
         <li data-nav-name= "<%= link.title %>">
             <a href="<%= link.href %>">
-              <span class="<%= link.icon %> fonticon"></span>
+              <i class="<%= link.icon %> fonticon"></i>
               <%= link.title %>
             </a>
         </li>


[05/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Whitespace


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/af4a1b9d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/af4a1b9d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/af4a1b9d

Branch: refs/heads/paginate-api-options
Commit: af4a1b9dd3d68e5a722a5f1ccf3565491cfbfd2d
Parents: 96be583
Author: Simon Metson <si...@cloudant.com>
Authored: Sun Jan 26 19:05:22 2014 +0000
Committer: suelockwood <de...@apache.org>
Committed: Wed Jan 29 10:34:28 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/views.js | 52 +++++++++++++-------------
 1 file changed, 26 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/af4a1b9d/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index aeb5983..93fd0d4 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -136,7 +136,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     template: "addons/documents/templates/upload_modal",
 
     disableLoader: true,
-    
+
     initialize: function (options) {
       _.bindAll(this);
     },
@@ -201,7 +201,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.$('.progress').addClass('hide');
       this.clear_error_msg();
       this.$('.modal').modal();
-      // hack to get modal visible 
+      // hack to get modal visible
       $('.modal-backdrop').css('z-index',1025);
     },
 
@@ -257,7 +257,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.$('.progress').addClass('hide');
       this.clear_error_msg();
       this.$('.modal').modal();
-      // hack to get modal visible 
+      // hack to get modal visible
       $('.modal-backdrop').css('z-index',1025);
     },
 
@@ -400,8 +400,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     destroy: function (event) {
-      event.preventDefault(); 
-      
+      event.preventDefault();
+
       window.alert('Cannot delete a document generated from a view.');
     },
 
@@ -453,7 +453,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.newView = options.newView || false;
       this.showNumbers = options.showNumbers;
       this.pagination = options.pagination;
-      
+
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
 
@@ -667,7 +667,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           });
 
           model.collection.remove(model.id);
-          if (!!model.id.match('_design')) { 
+          if (!!model.id.match('_design')) {
             FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
           }
           that.$('.bulk-delete').addClass('disabled');
@@ -712,13 +712,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
           return true;
         },
-        
+
         nextUrlfn: function () {
           return collection.urlNextPage(perPage());
         }
       });
     },
-    
+
     cleanup: function () {
       this.allDocsNumber.remove();
       _.each(this.rows, function (row) {row.remove();});
@@ -869,12 +869,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         }
         deferred.reject();
      });
-      
+
       return deferred;
     },
 
     saveDoc: function(event) {
-      var json, notification, 
+      var json, notification,
       that = this,
       editor = this.editor,
       validDoc = this.getDocFromEditor();
@@ -1357,7 +1357,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       ddoc.removeDdocView(viewName);
 
       if (ddoc.hasViews()) {
-        promise = ddoc.save(); 
+        promise = ddoc.save();
       } else {
         promise = ddoc.destroy();
       }
@@ -1377,7 +1377,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       $('#dashboard-content').scrollTop(0); //scroll up
 
       if (this.hasValidCode() && this.$('#new-ddoc:visible').val() !=="") {
-        var mapVal = this.mapEditor.getValue(), 
+        var mapVal = this.mapEditor.getValue(),
         reduceVal = this.reduceVal(),
         viewName = this.$('#index-name').val(),
         ddoc = this.getCurrentDesignDoc(),
@@ -1428,7 +1428,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
           if (that.reduceFunStr !== reduceVal) {
             that.reduceFunStr = reduceVal;
-            that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce()); 
+            that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
           }
 
           FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
@@ -1454,15 +1454,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     updateView: function(event, paramInfo) {
        event.preventDefault();
- 
+
        if (this.newView) { return alert('Please save this new view before querying it.'); }
- 
+
        var errorParams = paramInfo.errorParams,
            params = paramInfo.params;
- 
+
        if (_.any(errorParams)) {
          _.map(errorParams, function(param) {
- 
+
            // TODO: Where to add this error?
            // bootstrap wants the error on a control-group div, but we're not using that
            //$('form.view-query-update input[name='+param+'], form.view-query-update select[name='+param+']').addClass('error');
@@ -1479,14 +1479,14 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
            selector: ".advanced-options .errors-container",
            clear: true
          });
- 
+
          return false;
       }
- 
+
        var fragment = window.location.hash.replace(/\?.*$/, '');
        fragment = fragment + '?' + $.param(params);
        FauxtonAPI.navigate(fragment, {trigger: false});
- 
+
        FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
     },
 
@@ -1537,7 +1537,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     getCurrentDesignDoc: function () {
       return this.designDocSelector.getCurrentDesignDoc();
     },
-    
+
     isCustomReduceEnabled: function() {
       return $("#reduce-function-selector").val() == "CUSTOM";
     },
@@ -1570,7 +1570,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         var editor = this[editorName];
         if (editorName === "reduceEditor" && ! this.isCustomReduceEnabled()) {
           return true;
-        } 
+        }
         return editor.hadValidCode();
       }, this);
     },
@@ -1657,7 +1657,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         ddocName: this.model.id,
         database: this.database
       }));
-      
+
       this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
         updateViewFn: this.updateView,
         previewFn: this.previewView,
@@ -1703,7 +1703,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.mapEditor.setValue(this.langTemplates[this.defaultLang].map);
         //Use a built in view by default
         //this.reduceEditor.setValue(this.langTemplates[this.defaultLang].reduce);
-      } 
+      }
 
       this.mapEditor.editSaved();
       this.reduceEditor && this.reduceEditor.editSaved();
@@ -1800,7 +1800,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         permissions_url: '#' + this.database.url('app') + '/permissions',
         db_url: '#' + this.database.url('index') + '?limit=' + Databases.DocLimit,
         database: this.collection.database,
-        database_url: '#' + this.database.url('app'), 
+        database_url: '#' + this.database.url('app'),
         docLinks: docLinks,
         docLimit: Databases.DocLimit,
         addLinks: addLinks,


[20/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Working on doc limit


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/d6f6d229
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/d6f6d229
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/d6f6d229

Branch: refs/heads/paginate-api-options
Commit: d6f6d229d337817f0be6b7ea3b8e49b0ca66e20c
Parents: 344f372
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jan 29 15:48:34 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Feb 3 10:27:38 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 5 ++++-
 src/fauxton/app/addons/documents/routes.js    | 3 ++-
 src/fauxton/app/addons/documents/views.js     | 4 +++-
 src/fauxton/app/addons/fauxton/components.js  | 7 +++++++
 4 files changed, 16 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/d6f6d229/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index cf1b4aa..1824da0 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -279,10 +279,11 @@ function(app, FauxtonAPI) {
     },
     initialize: function(_models, options) {
       this.database = options.database;
-      this.params = options.params;
+      this.params = _.clone(options.params);
       this.skipFirstItem = false;
       this.totalRowsToPaginate = 100;
       this.on("remove",this.decrementTotalRows , this);
+      this.perPageLimit = options.perPageLimit || 20;
     },
 
     url: function(context) {
@@ -315,6 +316,8 @@ function(app, FauxtonAPI) {
     },
 
     updateLimit: function (limit) {
+      this.perPageLimit = limit;
+
       if (this.params.startkey_docid && this.params.startkey) {
         //we are paginating so set limit + 1
         this.params.limit = limit + 1;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d6f6d229/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
index 0c95bcf..9ef8837 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -211,7 +211,8 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
 
       this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        collection: this.data.database.allDocs
+        collection: this.data.database.allDocs,
+        docLimit: parseInt(docOptions.limit, 10)
       }));
 
       this.crumbs = [

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d6f6d229/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 8b8b7b3..1af8183 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -583,6 +583,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.ddocID = options.ddocInfo.id;
       }
       this.newView = options.newView || false;
+      this.docLimit = options.docLimit;
       this.expandDocs = true;
     },
 
@@ -668,7 +669,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.pagination = new Components.IndexPagination({
         collection: this.collection,
-        scrollToSelector: '#dashboard-content'
+        scrollToSelector: '#dashboard-content',
+        docLimit: this.docLimit
       });
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d6f6d229/src/fauxton/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/components.js b/src/fauxton/app/addons/fauxton/components.js
index 4f69412..d5ba7a6 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -74,6 +74,7 @@ function(app, FauxtonAPI, ace, spin) {
       this.pageNumber = 0;
       this._pageStart = 1;
       this.perPage = 20;
+      this.docLimit = options.docLimit || 100;
     },
 
     canShowPreviousfn: function () {
@@ -87,6 +88,12 @@ function(app, FauxtonAPI, ace, spin) {
       if (this.collection.length < (this.perPage -1)) {
         return false;
       }
+
+      console.log(this.pageStart() + this.perPage, this.docLimit);
+      if ((this.pageStart() + this.perPage) >= this.docLimit) {
+        return false;
+      }
+
       return true;
     },
 


[12/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Allow cacertfile without verifying peers

COUCHDB-2028


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/2d080449
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/2d080449
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/2d080449

Branch: refs/heads/paginate-api-options
Commit: 2d080449ae8f1b66bcb90e90dcc8e41022f4584c
Parents: cd0193f
Author: Robert Newson <rn...@apache.org>
Authored: Sun Jan 12 11:57:41 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Jan 30 11:38:53 2014 +0000

----------------------------------------------------------------------
 src/couchdb/couch_httpd.erl | 81 ++++++++++++++++------------------------
 1 file changed, 33 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/2d080449/src/couchdb/couch_httpd.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index 9245f4b..acc20d7 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -39,57 +39,42 @@ start_link(http) ->
     start_link(?MODULE, [{port, Port}]);
 start_link(https) ->
     Port = couch_config:get("ssl", "port", "6984"),
-    CertFile = couch_config:get("ssl", "cert_file", nil),
-    KeyFile = couch_config:get("ssl", "key_file", nil),
-    Options = case CertFile /= nil andalso KeyFile /= nil of
+    ServerOpts0 =
+        [{cacertfile, couch_config:get("ssl", "cacert_file", nil)},
+         {keyfile, couch_config:get("ssl", "key_file", nil)},
+         {certfile, couch_config:get("ssl", "cert_file", nil)},
+         {password, couch_config:get("ssl", "password", nil)}],
+
+    case (couch_util:get_value(keyfile, ServerOpts0) == nil orelse
+        couch_util:get_value(certfile, ServerOpts0) == nil) of
         true ->
-            SslOpts = [{certfile, CertFile}, {keyfile, KeyFile}],
-
-            %% set password if one is needed for the cert
-            SslOpts1 = case couch_config:get("ssl", "password", nil) of
-                nil -> SslOpts;
-                Password ->
-                    SslOpts ++ [{password, Password}]
-            end,
-            % do we verify certificates ?
-            FinalSslOpts = case couch_config:get("ssl",
-                    "verify_ssl_certificates", "false") of
-                "false" -> SslOpts1;
-                "true" ->
-                    case couch_config:get("ssl",
-                            "cacert_file", nil) of
-                        nil ->
-                            io:format("Verify SSL certificate "
-                                ++"enabled but file containing "
-                                ++"PEM encoded CA certificates is "
-                                ++"missing", []),
-                            throw({error, missing_cacerts});
-                        CaCertFile ->
-                            Depth = list_to_integer(couch_config:get("ssl",
-                                    "ssl_certificate_max_depth",
-                                    "1")),
-                            FinalOpts = [
-                                {cacertfile, CaCertFile},
-                                {depth, Depth},
-                                {verify, verify_peer}],
-                            % allows custom verify fun.
-                            case couch_config:get("ssl",
-                                    "verify_fun", nil) of
-                                nil -> FinalOpts;
-                                SpecStr ->
-                                    FinalOpts
-                                    ++ [{verify_fun, make_arity_3_fun(SpecStr)}]
-                            end
-                    end
-            end,
-
-            [{port, Port},
-                {ssl, true},
-                {ssl_opts, FinalSslOpts}];
-        false ->
             io:format("SSL enabled but PEM certificates are missing.", []),
-            throw({error, missing_certs})
+            throw({error, missing_certs});
+        false ->
+            ok
     end,
+
+    ServerOpts = [Opt || {_, V}=Opt <- ServerOpts0, V /= nil],
+
+    ClientOpts = case couch_config:get("ssl", "verify_ssl_certificates", "false") of
+        "false" ->
+            [];
+        "true" ->
+            [{depth, list_to_integer(couch_config:get("ssl",
+                "ssl_certificate_max_depth", "1"))},
+             {verify, verify_peer}] ++
+            case couch_config:get("ssl", "verify_fun", nil) of
+                nil -> [];
+                SpecStr ->
+                    [{verify_fun, make_arity_3_fun(SpecStr)}]
+            end
+    end,
+    SslOpts = ServerOpts ++ ClientOpts,
+
+    Options =
+        [{port, Port},
+         {ssl, true},
+         {ssl_opts, SslOpts}],
     start_link(https, Options).
 start_link(Name, Options) ->
     % read config and register for configuration changes


[18/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Remove fauxton/layout.js from Makefile


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b68eb174
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b68eb174
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b68eb174

Branch: refs/heads/paginate-api-options
Commit: b68eb1746785e2bfbc43e188c4125092d9941bfc
Parents: 6ea2b08
Author: Garren Smith <ga...@gmail.com>
Authored: Sat Feb 1 12:02:58 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Sat Feb 1 12:02:58 2014 +0200

----------------------------------------------------------------------
 src/Makefile.am | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b68eb174/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index e7efd4c..32a1a6a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -149,7 +149,6 @@ FAUXTON_FILES = \
     fauxton/app/addons/documents/views.js \
     fauxton/app/addons/fauxton/base.js \
     fauxton/app/addons/fauxton/components.js \
-    fauxton/app/addons/fauxton/layout.js \
     fauxton/app/addons/fauxton/resizeColumns.js \
     fauxton/app/addons/fauxton/tests/baseSpec.js \
     fauxton/app/addons/fauxton/tests/navbarSpec.js \


[13/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Throw cleaner error on MD5 mismatch during compaction

COUCHDB-2040


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/e7fdc16a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e7fdc16a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e7fdc16a

Branch: refs/heads/paginate-api-options
Commit: e7fdc16a485ec9a9d3b6bb3555957e367ec55f11
Parents: 2d08044
Author: Robert Newson <rn...@apache.org>
Authored: Wed Jan 29 21:47:58 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Jan 30 11:39:07 2014 +0000

----------------------------------------------------------------------
 src/couchdb/couch_db_updater.erl | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e7fdc16a/src/couchdb/couch_db_updater.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_db_updater.erl b/src/couchdb/couch_db_updater.erl
index af7578e..947669c 100644
--- a/src/couchdb/couch_db_updater.erl
+++ b/src/couchdb/couch_db_updater.erl
@@ -824,14 +824,16 @@ copy_doc_attachments(#db{updater_fd = SrcFd} = SrcDb, SrcSp, DestFd) ->
     end,
     % copy the bin values
     NewBinInfos = lists:map(
-        fun({Name, Type, BinSp, AttLen, RevPos, Md5}) ->
+        fun({Name, Type, BinSp, AttLen, RevPos, ExpectedMd5}) ->
             % 010 UPGRADE CODE
-            {NewBinSp, AttLen, AttLen, Md5, _IdentityMd5} =
+            {NewBinSp, AttLen, AttLen, ActualMd5, _IdentityMd5} =
                 couch_stream:copy_to_new_stream(SrcFd, BinSp, DestFd),
-            {Name, Type, NewBinSp, AttLen, AttLen, RevPos, Md5, identity};
-        ({Name, Type, BinSp, AttLen, DiskLen, RevPos, Md5, Enc1}) ->
-            {NewBinSp, AttLen, _, Md5, _IdentityMd5} =
+            check_md5(ExpectedMd5, ActualMd5),
+            {Name, Type, NewBinSp, AttLen, AttLen, RevPos, ExpectedMd5, identity};
+        ({Name, Type, BinSp, AttLen, DiskLen, RevPos, ExpectedMd5, Enc1}) ->
+            {NewBinSp, AttLen, _, ActualMd5, _IdentityMd5} =
                 couch_stream:copy_to_new_stream(SrcFd, BinSp, DestFd),
+            check_md5(ExpectedMd5, ActualMd5),
             Enc = case Enc1 of
             true ->
                 % 0110 UPGRADE CODE
@@ -842,10 +844,13 @@ copy_doc_attachments(#db{updater_fd = SrcFd} = SrcDb, SrcSp, DestFd) ->
             _ ->
                 Enc1
             end,
-            {Name, Type, NewBinSp, AttLen, DiskLen, RevPos, Md5, Enc}
+            {Name, Type, NewBinSp, AttLen, DiskLen, RevPos, ExpectedMd5, Enc}
         end, BinInfos),
     {BodyData, NewBinInfos}.
 
+check_md5(Md5, Md5) -> ok;
+check_md5(_, _) -> throw(md5_mismatch).
+
 copy_docs(Db, #db{updater_fd = DestFd} = NewDb, InfoBySeq0, Retry) ->
     % COUCHDB-968, make sure we prune duplicates during compaction
     InfoBySeq = lists:usort(fun(#doc_info{id=A}, #doc_info{id=B}) -> A =< B end,


[14/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Include layout manager in base.js for release builds
Remove Console log


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/4f2e5028
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/4f2e5028
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/4f2e5028

Branch: refs/heads/paginate-api-options
Commit: 4f2e502867640e50ac0cffbec4d847654ad81fcc
Parents: e7fdc16
Author: suelockwood <de...@apache.org>
Authored: Thu Jan 30 13:08:52 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Thu Jan 30 13:12:08 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/databases/views.js | 2 +-
 src/fauxton/app/core/base.js              | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/4f2e5028/src/fauxton/app/addons/databases/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/views.js b/src/fauxton/app/addons/databases/views.js
index 56001db..afe2d1c 100644
--- a/src/fauxton/app/addons/databases/views.js
+++ b/src/fauxton/app/addons/databases/views.js
@@ -28,7 +28,7 @@ function(app, Components, FauxtonAPI, Databases) {
       return [this.model.fetch()];
     },
     serialize: function() {
-      console.log('db', this.model);
+      
       return {
         encoded: app.utils.safeURLName(this.model.get("name")),
         database: this.model,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/4f2e5028/src/fauxton/app/core/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/base.js b/src/fauxton/app/core/base.js
index 55a8d87..53316bc 100644
--- a/src/fauxton/app/core/base.js
+++ b/src/fauxton/app/core/base.js
@@ -11,7 +11,8 @@
 // the License.
 
 define([
-  "backbone"
+  "backbone",
+  "plugins/backbone.layoutmanager"
 ],
 
 function(Backbone) {
@@ -57,9 +58,8 @@ function(Backbone) {
     establish: function() {
       return null;
     },
-
     loaderClassname: 'loader',
-
+    manage: true,
     disableLoader: false,
 
     forceRender: function () {


[16/22] 2029 Consolidate CSS/LESS class name usage to minimize custom-ness

Posted by ga...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index e1cfa06..ec3ff55 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -65,7 +65,7 @@ body {
   /* OVERRIDE BOOTSTRAP BTN STYLES */
   .btn{
     .box-shadow(none);
-    .border-radius(0);
+    .border-radius(@baseBorderRadius);
     background-image: none;
     text-shadow: none;
     background-repeat: no-repeat;
@@ -125,11 +125,19 @@ a:hover{
   }
 }
 
-/* bootstrap override */
+/* bootstrap overrides */
 .container-fluid {
   padding-right: 0px;
   padding-left: 0px;
 }
+.page-header {
+  border-bottom: 1px solid #E3E3E3;
+  margin-bottom: 10px;
+  h3 {
+    text-transform: capitalize;
+    margin-bottom: 0;
+  }
+}
 
 /* Fixed side navigation */
 #primary-navbar {
@@ -209,11 +217,11 @@ a:hover{
             }
             background-color: @red;
           }
-          &:hover a.fonticon:before{
+          &:hover .fonticon:before{
             color: @white;
           }
-          &.active a.fonticon:before,
-          &:hover a.fonticon:before,
+          &.active .fonticon:before,
+          &:hover .fonticon:before,
           {
             text-shadow: @boxShadow;
             color: @NavIconActive;
@@ -226,7 +234,7 @@ a:hover{
             &.closeMenu{
               color: transparent;
             }
-            & span.fonticon {
+            .fonticon {
               position: relative;
               &:before {
                 position: absolute;
@@ -459,6 +467,11 @@ footer#mainFooter{
         padding: 10px 5px 10px 15px;
         color: #333333;
         border-bottom: 1px solid #989898;
+        .divider {
+          background: none;
+          color: #ccc;
+          padding: 0 2px;
+        }
       }
       .nav-header{
         background-color: #B2B2B2;
@@ -499,14 +512,6 @@ footer#mainFooter{
   margin-bottom: 10px;
 }
 
-.navbar-form.pull-right.database-search {
-  margin: -10px 50px 12px 0;
-  padding: 11px;
-    input[type=text]{
-      margin-top: 0px;
-    }
-}
-
 #db-views-tabs-nav{
   position: fixed;
   z-index: 12;
@@ -600,84 +605,27 @@ tbody {padding-top: 10px;}
 }
 
 .btn {
-  padding-top: 12px;
-  padding-bottom: 12px;
-  margin-top: 0px;
-}
-
-.button{
-  .button-style;
-  .transition(all @transitionSpeed @transitionEaseType);
-  border: none;
-  background-color: @redButton;
-  color: #fff;
   padding: 10px;
+  margin-top: 0px;
   .icon {
-    margin-right: 10px;
-    font-size: 20px;
-  }
-  &:hover {
-    color: #fff;
-    text-decoration: none;
-  }
-}
-
-
-.button-style{
-  background-color: @redButton;
-  color: #fff;
-  padding: 10px 15px;
-  cursor: pointer;
-  &:before{
-    padding-right: 5px;
+    margin-right: 0.2em;
   }
-  &.outlineGray{
-    border: 1px solid @grayLight;
-    background-color: transparent;
-    color: @grayDark;
-    &:hover{
-      border: 1px solid @orange;
+  &.btn-small {
+    padding: 5px 10px;
+    .icon {
+      margin-right: 0;
+      font-size: inherit;
     }
   }
-  &.gray{
-    background-color: #ddd;
-    color: @grayDark;
-  }
-  &.green{
-    background-color: @green;
-  }
-
-  &.round-btn {
-    .border-radius(@radius);
-  }
-  .icon {
-    margin-right: 10px;
-    font-size: 20px;
-  }
-  &:hover {
-    color: #fff;
-    text-decoration: none;
-    background-color: @orange;
-  }
-  a&,
-  a&:visited,
-  a&:active{
-    color: #fff;
-  }
-  &:disabled {
-    opacity: 0.5;
+  &.btn-mini {
+    padding: 3px 8px;
+    .icon {
+      margin-right: 0;
+      font-size: inherit;
+    }
   }
 }
 
-
-
-
-a.button, 
-a.button:visited, 
-a.button:active {
-  .button-style;
-}
-
 .select{
   > a{
     display: block;
@@ -883,15 +831,12 @@ form.view-query-update, form.view-query-save {
     font-size: 18px;
     padding: 14px 5px 30px;
   }
+  .btn .icon{
+    font-size: 21.5px;
+    margin-right: 0;
+  }
 }
 
-.input-append .btn:last-child, 
-.input-append .btn-group:last-child > .dropdown-toggle {
-  padding: 10px 5px 14px;
-}
-.input-append .btn{
-  padding: 10px 5px 14px;
-}
 .row-fluid .input-append [class*="span"],
 .input-prepend input[class*="span"]{
   width: auto;
@@ -936,6 +881,10 @@ div.spinner {
   border: solid 1px #ddd;
 }
 
+.btn-primary {
+  background: @redButton;
+}
+
 .btn-primary a:visited {
   color: #fff;
 }
@@ -944,11 +893,11 @@ div.spinner {
   position: relative;
 }
 
-.button.api-url-btn {
+.api-url-btn {
   position: absolute;
   right: 15px;
   top: -50px;
-  span.icon {
+  .icon {
     font-size: 11px;
   }
 }
@@ -975,17 +924,6 @@ div.spinner {
   }
 }
 
-#jump-to-doc,
-#jump-to-db
- {
-  width: auto;
-  float:right;
-  button{
-    padding-left: 20px;
-    padding-right: 10px;
-  }
-}
-
 #map-function, #reduce-function{
     width: 100%;
     font-size: 16px;
@@ -996,7 +934,3 @@ div.spinner {
     height: 688px;
     font-size: 16px;
 }
-
-#delete-database {
-  float: right;
-}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/assets/less/variables.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/variables.less b/src/fauxton/assets/less/variables.less
index bf97b5d..34f8b90 100644
--- a/src/fauxton/assets/less/variables.less
+++ b/src/fauxton/assets/less/variables.less
@@ -18,6 +18,7 @@
 @darkRed: #AF2D24;
 @linkRed: #DA4F49;
 @greyBrown: #554D4C;
+@greyBrownLighter: #A59D9D;
 @fontGrey: #808080;
 @secondarySidebar: #E4DFDC;
 
@@ -77,6 +78,7 @@
 @textShadowOff: 1px 2px rgba(0,0,0,0);
 
 @radius: 4px;
+@baseBorderRadius: 0;
 @transitionSpeed: .25s;
 @transitionEaseType: linear;
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/readme.md
----------------------------------------------------------------------
diff --git a/src/fauxton/readme.md b/src/fauxton/readme.md
index a0c7702..bb81095 100644
--- a/src/fauxton/readme.md
+++ b/src/fauxton/readme.md
@@ -21,7 +21,7 @@ A recent of [node.js](http://nodejs.org/) and npm is required.
 
 ### CouchDB Setup ###
 
-    1. Clone the Couchdb repo: https://github.com/apache/couchdb.git or http://git-wip-us.apache.org/repos/asf/couchdb.git
+    1. Clone the CouchDB repo: https://github.com/apache/couchdb.git or http://git-wip-us.apache.org/repos/asf/couchdb.git
     cd couchdb
 
 ### Fauxton Setup ###
@@ -32,7 +32,11 @@ A recent of [node.js](http://nodejs.org/) and npm is required.
     npm install
 
 ### Dev Server
-    Using the dev server is the easiest way to use fauxton, specially when developing for it.
+Using the dev server is the easiest way to use fauxton, specially when
+developing for it. Copy or symlink the `settings.json.default` (or the
+`settings.json.dev` file if you'd like to see the `styletests` addon).
+
+And then...
 
     grunt dev
 
@@ -63,7 +67,7 @@ A recent of [node.js](http://nodejs.org/) and npm is required.
 
 ### To Deploy Fauxton
 
-    ./bin/grunt couchapp_deploy - to deploy to your local [Couchdb instance] (http://localhost:5984/fauxton/_design/fauxton/index.html)
+    ./bin/grunt couchapp_deploy - to deploy to your local [CouchDB instance] (http://localhost:5984/fauxton/_design/fauxton/index.html)
 
 ## Understang Fauxton Code layout
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/6ea2b081/src/fauxton/settings.json.dev
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.dev b/src/fauxton/settings.json.dev
new file mode 100644
index 0000000..e2df66b
--- /dev/null
+++ b/src/fauxton/settings.json.dev
@@ -0,0 +1,59 @@
+{
+  "deps": [
+  { "name": "databases" },
+  { "name": "documents" },
+  { "name": "pouchdb" },
+  { "name": "activetasks" },
+  { "name": "config" },
+  { "name": "logs" },
+  { "name": "stats" },
+  { "name": "replication" },
+  { "name": "plugins" },
+  { "name": "contribute" },
+  { "name": "permissions" },
+  { "name": "compaction" },
+  { "name": "auth" },
+  { "name": "verifyinstall" },
+  { "name": "styletests" }
+  ],
+    "template": {
+      "development": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "/assets/js/libs/require.js",
+          "css": "./css/index.css",
+          "base": null
+        },
+        "app": {
+          "root": "/",
+          "host": "../..",
+          "version": "1.0.dev"
+        }
+      },
+      "release": {
+        "src": "assets/index.underscore",
+        "dest": "dist/debug/index.html",
+        "variables": {
+          "requirejs": "./js/require.js",
+          "css": "./css/index.css",
+          "base": null
+        },
+        "app": {
+          "root": "/_utils/fauxton/",
+          "host": "../..",
+          "version": "1.0"
+        }
+      }
+    },
+
+    "couch_config": {
+      "fauxton": {
+        "db": "http://localhost:5984/fauxton",
+        "app": "./couchapp.js",
+        "options": {
+          "okay_if_missing": true
+        }
+      }
+    }
+}


[03/22] Fauxton: Split up api.js

Posted by ga...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/tests/routeObjectSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/tests/routeObjectSpec.js b/src/fauxton/app/core/tests/routeObjectSpec.js
new file mode 100644
index 0000000..2fca94d
--- /dev/null
+++ b/src/fauxton/app/core/tests/routeObjectSpec.js
@@ -0,0 +1,96 @@
+// 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([
+       'api',
+      'testUtils'
+], function (FauxtonAPI, testUtils) {
+  var assert = testUtils.assert,
+      RouteObject = FauxtonAPI.RouteObject;
+
+  describe('RouteObjects', function () {
+
+    describe('renderWith', function () {
+      var TestRouteObject, testRouteObject, mockLayout;
+
+      beforeEach(function () {
+        TestRouteObject = RouteObject.extend({
+          crumbs: ['mycrumbs']
+        });
+
+        testRouteObject = new TestRouteObject();
+        var apiBar = {};
+        apiBar.hide = sinon.spy();
+
+        // Need to find a better way of doing this
+        mockLayout = {
+          setTemplate: sinon.spy(),
+          clearBreadcrumbs: sinon.spy(),
+          setView: sinon.spy(),
+          renderView: sinon.spy(),
+          hooks: [],
+          setBreadcrumbs: sinon.spy(),
+          apiBar: apiBar
+        };
+
+      });
+
+      it('Should set template for first render ', function () {
+        testRouteObject.renderWith('the-route', mockLayout, 'args');
+
+        assert.ok(mockLayout.setTemplate.calledOnce, 'setTempalte was called');
+      });
+
+      it('Should not set template after first render', function () {
+        testRouteObject.renderWith('the-route', mockLayout, 'args');
+
+        testRouteObject.renderWith('the-route', mockLayout, 'args');
+
+        assert.ok(mockLayout.setTemplate.calledOnce, 'SetTemplate not meant to be called');
+      });
+
+      
+      it("Should call establish of routeObject", function () {
+        var establishSpy = sinon.spy(testRouteObject,"establish");
+
+        testRouteObject.renderWith('the-route', mockLayout, 'args');
+        assert.ok(establishSpy.calledOnce, 'Calls establish');
+      });
+
+      it("Should render views", function () {
+        var view = new FauxtonAPI.View(),
+            getViewsSpy = sinon.stub(testRouteObject,"getViews"),
+            viewSpy = sinon.stub(view, "establish");
+        
+        view.hasRendered = false;
+        getViewsSpy.returns({'#view': view});
+
+        testRouteObject.renderWith('the-route', mockLayout, 'args');
+        assert.ok(viewSpy.calledOnce, 'Should render view');
+      });
+
+      it("Should not re-render a view", function () {
+        var view = new FauxtonAPI.View(),
+            getViewsSpy = sinon.stub(testRouteObject,"getViews"),
+            viewSpy = sinon.stub(view, "establish");
+        
+        view.hasRendered = true;
+        getViewsSpy.returns({'#view': view});
+
+        testRouteObject.renderWith('the-route', mockLayout, 'args');
+        assert.notOk(viewSpy.calledOnce, 'Should render view');
+      });
+    });
+
+  });
+
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/utils.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/utils.js b/src/fauxton/app/core/utils.js
new file mode 100644
index 0000000..44945e8
--- /dev/null
+++ b/src/fauxton/app/core/utils.js
@@ -0,0 +1,94 @@
+// 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 onWindowResize = {};
+
+  var utils = {
+    // 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;
+    },
+
+    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();
+    },
+
+    removeWindowResize: function(key){
+      delete onWindowResize[key];
+      utils.initWindowResize();
+    },
+
+    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();
+        });
+      };
+    },
+
+    removeSpecialCharacters: function(name){
+      return name.replace(/[^\w\s]/gi,"");
+    },
+
+    safeURLName: function(name){
+      var testName = name || "";
+      var checkforBad = testName.match(/[\$\-/_,+-]/g);
+      return (checkforBad !== null)?encodeURIComponent(name):name;
+    }
+  };
+
+  return utils;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/main.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/main.js b/src/fauxton/app/main.js
index 6fe9991..9df15c5 100644
--- a/src/fauxton/app/main.js
+++ b/src/fauxton/app/main.js
@@ -13,19 +13,18 @@
 require([
         // Application.
         "app",
-
-        // Main Router.
-        "router"
+        "api",
+        "load_addons"
 ],
 
-function(app, Router) {
+function(app, FauxtonAPI, LoadAddons) {
 
-  // Define your master router on the application namespace and trigger all
-  // navigation from this instance.
-  app.router = new Router();
+  app.addons = LoadAddons.addons;
+  FauxtonAPI.router = app.router = new FauxtonAPI.Router(app.addons);
   // 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.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/resizeColumns.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/resizeColumns.js b/src/fauxton/app/resizeColumns.js
deleted file mode 100644
index bb50767..0000000
--- a/src/fauxton/app/resizeColumns.js
+++ /dev/null
@@ -1,87 +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.
-
-
-// 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([
-  "utils"
-],
-
-function(utils) {
-
-  var Resize = function(options){
-    this.options = options;
-    this.options.selectorElements = options.selectorElements || ".window-resizeable";
-  };
-
-  Resize.prototype = {
-    getPrimaryNavWidth: function(){
-      var primaryNavWidth  = $('body').hasClass('closeMenu')? 64:224;
-      return primaryNavWidth;
-    },
-    getPanelWidth: function(){
-      var sidebarWidth = $('#sidebar-content').length > 0 ? $('#sidebar-content').width(): 0;
-      return (this.getPrimaryNavWidth() + sidebarWidth); 
-    },
-    initialize: function(){
-     // $(window).off('resize');
-      var that = this;
-      //add throttler :) 
-      this.lazyLayout = _.debounce(that.onResizeHandler, 300).bind(this);
-      utils.addWindowResize(this.lazyLayout,"animation");
-      utils.initWindowResize();
-      this.onResizeHandler();
-    },
-    updateOptions:function(options){
-      this.options = {};
-      this.options = options;
-      this.options.selectorElements = options.selectorElements || ".window-resizeable";
-    },
-    turnOff:function(){
-      utils.removeWindowResize("animation");
-    },
-    cleanupCallback: function(){
-      this.callback = null;
-    },
-    onResizeHandler: function (){
-      //if there is an override, do that instead
-      if (this.options.onResizeHandler){
-        this.options.onResizeHandler();
-      } else {
-        var combinedWidth = window.innerWidth - this.getPanelWidth(),
-        smallWidthConstraint = ($('#sidebar-content').length > 0)? 470:800,
-        panelWidth; 
-
-        if( combinedWidth > smallWidthConstraint  && combinedWidth < 1400){
-          panelWidth = window.innerWidth - this.getPanelWidth();
-        } else if (combinedWidth < smallWidthConstraint){
-          panelWidth = smallWidthConstraint;
-        } else if(combinedWidth > 1400){
-          panelWidth = 1400;
-        }
-
-        $(this.options.selectorElements).innerWidth(panelWidth);
-      }
-      //if there is a callback, run that
-      if(this.options.callback) {
-        this.options.callback();
-      }
-    } 
-  };
-
-  return Resize;
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/router.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/router.js b/src/fauxton/app/router.js
deleted file mode 100644
index 89c60cf..0000000
--- a/src/fauxton/app/router.js
+++ /dev/null
@@ -1,142 +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([
-       // Load require for use in nested requiring
-       // as per the note in: http://requirejs.org/docs/api.html#multiversion
-       "require",
-
-       // Application.
-       "app",
-
-       // Initialize application
-       "initialize",
-
-       // Load Fauxton API
-       "api",
-
-       // Modules
-       "addons/fauxton/base",
-       // Layout
-       "addons/fauxton/layout",
-
-       "load_addons"
-],
-
-function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, LoadAddons) {
-
-  var beforeUnloads = {};
-
-  var Router = app.router = Backbone.Router.extend({
-    routes: {},
-
-    beforeUnload: function (name, fn) {
-      beforeUnloads[name] = fn;
-    },
-
-    removeBeforeUnload: function (name) {
-      delete beforeUnloads[name];
-    },
-
-    navigate: function (fragment, trigger) {
-      var continueNav  = true,
-          msg = _.find(_.map(beforeUnloads, function (fn) { return fn(); }), function (beforeReturn) {
-            if (beforeReturn) { return true; }
-          });
-
-      if (msg) {
-        continueNav = window.confirm(msg);
-      }
-
-      if (continueNav) {
-        Backbone.Router.prototype.navigate(fragment, trigger);
-      }
-    },
-
-    addModuleRouteObject: function(RouteObject) {
-      var that = this;
-      var masterLayout = this.masterLayout,
-      routeUrls = RouteObject.prototype.getRouteUrls();
-
-      _.each(routeUrls, function(route) {
-        this.route(route, route.toString(), function() {
-          var args = Array.prototype.slice.call(arguments),
-          roles = RouteObject.prototype.getRouteRoles(route),
-          authPromise = app.auth.checkAccess(roles);
-
-          authPromise.then(function () {
-            if (!that.activeRouteObject || !that.activeRouteObject.hasRoute(route)) {
-              if (that.activeRouteObject) {
-                that.activeRouteObject.cleanup();
-              }
-              that.activeRouteObject = new RouteObject(route, masterLayout, args);
-            }
-
-            var routeObject = that.activeRouteObject;
-            routeObject.routeCallback(route, args);
-            routeObject.renderWith(route, masterLayout, args);
-          }, function () {
-            FauxtonAPI.auth.authDeniedCb();
-          });
-
-        }); 
-      }, this);
-    },
-
-    setModuleRoutes: function() {
-      _.each(LoadAddons.addons, function(module) {
-        if (module){
-          module.initialize();
-          // This is pure routes the addon provides
-          if (module.RouteObjects) {
-            _.each(module.RouteObjects, this.addModuleRouteObject, this);
-          }
-        }
-      }, this);
-    },
-
-    initialize: function() {
-      //TODO: It would be nice to handle this with a router
-      this.navBar = app.navBar = new Fauxton.NavBar();
-      this.apiBar = app.apiBar = new Fauxton.ApiBar();
-      this.auth = app.auth = FauxtonAPI.auth;
-      app.session = FauxtonAPI.session;
-
-      app.masterLayout = this.masterLayout = new Layout(this.navBar, this.apiBar);
-      app.footer = new Fauxton.Footer({el: "#footer-content"});
-
-      // NOTE: This must be below creation of the layout
-      // FauxtonAPI header links and others depend on existence of the layout
-      //this.setAddonHooks();
-      this.setModuleRoutes();
-
-      $("#app-container").html(this.masterLayout.el);
-      this.masterLayout.render();
-
-      // TODO: move this to a proper Fauxton.View
-      $.when.apply(null, app.footer.establish()).done(function() {
-        app.footer.render();
-      });
-    },
-
-    triggerRouteEvent: function(event, args) {
-      if (this.activeRouteObject) {
-        var eventArgs = [event].concat(args);
-        this.activeRouteObject.trigger.apply(this.activeRouteObject, eventArgs );
-        this.activeRouteObject.renderWith(eventArgs, this.masterLayout, args);
-      }
-    }
-  });
-
-  return Router;
-
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/utils.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/utils.js b/src/fauxton/app/utils.js
deleted file mode 100644
index ded7dac..0000000
--- a/src/fauxton/app/utils.js
+++ /dev/null
@@ -1,66 +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.
-
-
-// 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 utils = {};
-
-  var onWindowResize = {};
-   
-  utils.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();
-  };
-   
-  utils.removeWindowResize = function(key){
-    delete onWindowResize[key];
-    utils.initWindowResize();
-  };
-   
-  utils.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();
-      });
-    };
-  };
-
-  utils.removeSpecialCharacters = function(name){
-    return name.replace(/[^\w\s]/gi,"");
-  };
-
-  utils.safeURLName = function(name){
-    var testName = name || "";
-    var checkforBad = testName.match(/[\$\-/_,+-]/g);
-    return (checkforBad !== null)?encodeURIComponent(name):name;
-  };
-
-  return utils;
-});
-

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index cb09eb2..e817b79 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -1,5 +1,6 @@
 {
   "deps": [
+  { "name": "fauxton" },
   { "name": "databases" },
   { "name": "documents" },
   { "name": "pouchdb" },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/tasks/couchserver.js
----------------------------------------------------------------------
diff --git a/src/fauxton/tasks/couchserver.js b/src/fauxton/tasks/couchserver.js
index 5ccbfe1..21c2fcb 100644
--- a/src/fauxton/tasks/couchserver.js
+++ b/src/fauxton/tasks/couchserver.js
@@ -61,7 +61,7 @@ module.exports = function (grunt) {
         // server js from app directory
         filePath = path.join(app_dir, url.replace('/_utils/fauxton/',''));
       } else if (!!url.match(/testrunner/)) {
-        var testSetup = grunt.util.spawn({cmd: 'grunt', grunt: true, args: ['mochaSetup']}, function (error, result, code) {/* log.writeln(String(result));*/ });
+        var testSetup = grunt.util.spawn({cmd: 'grunt', grunt: true, args: ['test_inline']}, function (error, result, code) {/* log.writeln(String(result));*/ });
         testSetup.stdout.pipe(process.stdout);
         testSetup.stderr.pipe(process.stderr);
         filePath = path.join('./test/runner.html');

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/test/core/layoutSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/core/layoutSpec.js b/src/fauxton/test/core/layoutSpec.js
deleted file mode 100644
index 4167100..0000000
--- a/src/fauxton/test/core/layoutSpec.js
+++ /dev/null
@@ -1,94 +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([
-       'addons/fauxton/layout',
-      'testUtils'
-], function (Layout, testUtils) {
-  var assert = testUtils.assert;
-
-  describe("Faxuton Layout", function () {
-    var layout;
-
-    beforeEach(function () {
-      var navBar = new Backbone.View();
-      var apiBar = new Backbone.View();
-      layout = new Layout(navBar, apiBar);
-    });
-
-    describe('#setTemplate', function () {
-
-      it("Should set template without prefix", function () {
-        layout.setTemplate('myTemplate');
-
-        assert.equal(layout.layout.template, 'templates/layouts/myTemplate');
-
-      });
-
-      it("Should set template with prefix", function () {
-        layout.setTemplate({name: 'myTemplate', prefix: 'myPrefix/'});
-
-        assert.equal(layout.layout.template, 'myPrefix/myTemplate');
-      });
-
-      it("Should remove old views", function () {
-        var view = {
-          remove: function () {}
-        };
-
-        layout.layoutViews = {
-          'selector': view
-        };
-
-        var mockRemove = sinon.spy(view, 'remove');
-        layout.setTemplate('myTemplate');
-        assert.ok(mockRemove.calledOnce);
-
-      });
-
-      it("Should render", function () {
-        var mockRender = sinon.spy(layout, 'render');
-
-        layout.setTemplate('myTemplate');
-
-        assert.ok(mockRender.calledOnce);
-
-      });
-
-    });
-
-    describe('#renderView', function () {
-
-      it('Should render existing view', function () {
-        var view = new Backbone.View();
-        var mockRender = sinon.spy(view, 'render');
-        layout.layoutViews = {
-          '#selector': view
-        };
-
-        var out = layout.renderView('#selector');
-
-        assert.ok(mockRender.calledOnce);
-      });
-
-      it('Should return false for non-existing view', function () {
-        var view = new Backbone.View();
-        layout.layoutViews = {
-          'selector': view
-        };
-
-        var out = layout.renderView('wrongSelector');
-        assert.notOk(out, 'No view found');
-      });
-    });
-
-  });
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/test/core/navbarSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/core/navbarSpec.js b/src/fauxton/test/core/navbarSpec.js
deleted file mode 100644
index 3eca6f6..0000000
--- a/src/fauxton/test/core/navbarSpec.js
+++ /dev/null
@@ -1,107 +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([
-       'addons/fauxton/base',
-      'testUtils'
-], function (Fauxton, testUtils) {
-  var assert = testUtils.assert,
-      NavBar = Fauxton.NavBar;
-
-  describe('NavBar', function () {
-
-    describe('adding links', function () {
-      var navBar;
-
-      beforeEach(function () {
-        navBar = new NavBar();
-        navBar.navLinks = [];
-        navBar.bottomNavLinks = [];
-        navBar.footerNavLinks = [];
-      });
-
-      it('Should add link to navlinks', function () {
-        navBar.addLink({href: '#/test', title: 'Test Title'});
-
-        assert.equal(navBar.navLinks.length, 1);
-        assert.equal(navBar.footerNavLinks.length, 0);
-        assert.equal(navBar.bottomNavLinks.length, 0);
-      });
-
-      it('Should add link to bottom links', function () {
-        navBar.addLink({href: '#/test', bottomNav: true, title: 'Test Title'});
-
-        assert.equal(navBar.bottomNavLinks.length, 1);
-        assert.equal(navBar.navLinks.length, 0);
-        assert.equal(navBar.footerNavLinks.length, 0);
-      });
-
-      it('Should add link to footer links', function () {
-        navBar.addLink({href: '#/test', footerNav: true, title: 'Test Title'});
-
-        assert.equal(navBar.footerNavLinks.length, 1);
-        assert.equal(navBar.bottomNavLinks.length, 0);
-        assert.equal(navBar.navLinks.length, 0);
-      });
-    });
-
-    describe('removing links', function () {
-      var navBar;
-
-      beforeEach(function () {
-        navBar = new NavBar();
-        navBar.navLinks = [];
-        navBar.bottomNavLinks = [];
-        navBar.footerNavLinks = [];
-        navBar.addLink({
-          href: '#/test', 
-          footerNav: true, 
-          title: 'Test Title Footer'
-        });
-
-        navBar.addLink({
-          href: '#/test', 
-          bottomNav: true, 
-          title: 'Test Title Bottom'
-        });
-
-        navBar.addLink({
-          href: '#/test', 
-          title: 'Test Title'
-        });
-      });
-
-      it("should remove links from list", function () {
-        navBar.removeLink({
-          title: 'Test Title Footer',
-          footerNav: true
-        });
-
-        assert.equal(navBar.footerNavLinks.length, 0);
-        assert.equal(navBar.bottomNavLinks.length, 1);
-        assert.equal(navBar.navLinks.length, 1);
-      });
-
-      it("Should call render after removing links", function () {
-        var renderSpy = sinon.stub(navBar,'render');
-
-        navBar.removeLink({
-          title: 'Test Title Footer',
-          footerNav: true
-        });
-
-        assert.ok(renderSpy.calledOnce);
-      });
-
-    });
-  });
-
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/test/core/paginateSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/core/paginateSpec.js b/src/fauxton/test/core/paginateSpec.js
deleted file mode 100644
index d05b322..0000000
--- a/src/fauxton/test/core/paginateSpec.js
+++ /dev/null
@@ -1,109 +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([
-       'api',
-       'addons/fauxton/components',
-       'addons/documents/resources',
-       'testUtils',
-       'app'
-], function (FauxtonAPI, Views, Models, testUtils, app) {
-  var assert = testUtils.assert,
-  ViewSandbox = testUtils.ViewSandbox;
-
-
-  describe('IndexPaginate', function () {
-    var viewSandbox, paginate, collection, navigateMock;
-    beforeEach(function () {
-      app.router = {
-        navigate: function () {}
-      };
-
-      collection = new Models.IndexCollection([{
-        id:'myId1',
-        doc: 'num1'
-      },
-      {
-        id:'myId2',
-        doc: 'num2'
-      }], {
-        database: {id: 'databaseId'},
-        design: '_design/myDoc'
-      });
-
-      paginate = new Views.IndexPagination({
-        collection: collection,
-        previousUrlfn: function () {},
-        nextUrlfn: function () {},
-        canShowPreviousfn: function () { return true; },
-        canShowNextfn: function () { return true;}
-      });
-      viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(paginate); 
-    });
-
-    afterEach(function () {
-      viewSandbox.remove();
-    });
-
-    describe('#next', function () {
-      beforeEach(function () {
-        //do this so it doesn't throw an error on other unwired up components
-        FauxtonAPI.triggerRouteEvent = function () {};
-        //FauxtonAPI.triggerRouteEvent.restore && FauxtonAPI.triggerRouteEvent.restore();
-        //FauxtonAPI.navigate.restore && FauxtonAPI.navigate.restore(); 
-      });
-
-      it('Should navigate', function () {
-        var navigateMock = sinon.spy(FauxtonAPI, 'navigate');
-
-        paginate.$('a#next').click();
-
-        assert.ok(navigateMock.calledOnce);
-        FauxtonAPI.navigate.restore();
-      });
-
-      it('Should trigger routeEvent', function () {
-        var navigateMock = sinon.spy(FauxtonAPI, 'triggerRouteEvent');
-
-        paginate.$('a#next').click();
-
-        assert.ok(navigateMock.calledOnce);
-        FauxtonAPI.triggerRouteEvent.restore();
-      });
-
-    });
-
-
-    describe('#previous', function () {
-
-      it('Should navigate', function () {
-        var navigateMock = sinon.spy(FauxtonAPI, 'navigate');
-
-        paginate.$('a#previous').click();
-
-        assert.ok(navigateMock.calledOnce);
-        FauxtonAPI.navigate.restore();
-      });
-
-      it('Should trigger routeEvent', function () {
-        var navigateMock = sinon.spy(FauxtonAPI, 'triggerRouteEvent');
-
-        paginate.$('a#previous').click();
-
-        assert.ok(navigateMock.calledOnce);
-        FauxtonAPI.triggerRouteEvent.restore();
-      });
-
-    });
-
-  });
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/test/core/routeObjectSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/core/routeObjectSpec.js b/src/fauxton/test/core/routeObjectSpec.js
deleted file mode 100644
index 987d5b7..0000000
--- a/src/fauxton/test/core/routeObjectSpec.js
+++ /dev/null
@@ -1,105 +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([
-       'api',
-      'testUtils'
-], function (FauxtonAPI, testUtils) {
-  var assert = testUtils.assert,
-      RouteObject = FauxtonAPI.RouteObject;
-
-  describe('RouteObjects', function () {
-
-    describe('renderWith', function () {
-      var TestRouteObject, testRouteObject, mockLayout;
-
-      beforeEach(function () {
-        TestRouteObject = RouteObject.extend({
-          crumbs: ['mycrumbs']
-        });
-
-        testRouteObject = new TestRouteObject();
-        var apiBar = {};
-        apiBar.hide = sinon.spy();
-
-        // Need to find a better way of doing this
-        mockLayout = {
-          setTemplate: sinon.spy(),
-          clearBreadcrumbs: sinon.spy(),
-          setView: sinon.spy(),
-          renderView: sinon.spy(),
-          hooks: [],
-          setBreadcrumbs: sinon.spy(),
-          apiBar: apiBar
-        };
-
-      });
-
-      it('Should set template for first render ', function () {
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-
-        assert.ok(mockLayout.setTemplate.calledOnce, 'setTempalte was called');
-      });
-
-      it('Should not set template after first render', function () {
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-
-        assert.ok(mockLayout.setTemplate.calledOnce, 'SetTemplate not meant to be called');
-      });
-
-      it('Should clear breadcrumbs', function () {
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-        assert.ok(mockLayout.clearBreadcrumbs.calledOnce, 'Clear Breadcrumbs called');
-      });
-
-      it('Should set breadcrumbs when breadcrumbs exist', function () {
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-        assert.ok(mockLayout.setBreadcrumbs.calledOnce, 'Set Breadcrumbs was called');
-      });
-
-      it("Should call establish of routeObject", function () {
-        var establishSpy = sinon.spy(testRouteObject,"establish");
-
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-        assert.ok(establishSpy.calledOnce, 'Calls establish');
-      });
-
-      it("Should render views", function () {
-        var view = new FauxtonAPI.View(),
-            getViewsSpy = sinon.stub(testRouteObject,"getViews"),
-            viewSpy = sinon.stub(view, "establish");
-        
-        view.hasRendered = false;
-        getViewsSpy.returns({'#view': view});
-
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-        assert.ok(viewSpy.calledOnce, 'Should render view');
-      });
-
-      it("Should not re-render a view", function () {
-        var view = new FauxtonAPI.View(),
-            getViewsSpy = sinon.stub(testRouteObject,"getViews"),
-            viewSpy = sinon.stub(view, "establish");
-        
-        view.hasRendered = true;
-        getViewsSpy.returns({'#view': view});
-
-        testRouteObject.renderWith('the-route', mockLayout, 'args');
-        assert.notOk(viewSpy.calledOnce, 'Should render view');
-      });
-    });
-
-  });
-
-
-});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/test/mocha/testUtils.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/mocha/testUtils.js b/src/fauxton/test/mocha/testUtils.js
index f9643e8..2c418f9 100644
--- a/src/fauxton/test/mocha/testUtils.js
+++ b/src/fauxton/test/mocha/testUtils.js
@@ -11,11 +11,12 @@
 // the License.
 
 define([
+       "api",
        "chai",
        "sinon-chai",
        "underscore"
 ],
-function(chai, sinonChai) {
+function(FauxtonAPI,chai, sinonChai) {
   chai.use(sinonChai);
 
   var ViewSandbox = function () {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/test/test.config.underscore
----------------------------------------------------------------------
diff --git a/src/fauxton/test/test.config.underscore b/src/fauxton/test/test.config.underscore
index dda16f2..5cebe78 100644
--- a/src/fauxton/test/test.config.underscore
+++ b/src/fauxton/test/test.config.underscore
@@ -5,6 +5,7 @@ require.config(
 );
 
 require([
+        "app",
         <% _.each(testFiles, function (test) {%>
            '../<%= test %>',
         <% }) %>


[21/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
More working


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/5c7b3127
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/5c7b3127
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/5c7b3127

Branch: refs/heads/paginate-api-options
Commit: 5c7b3127980225d1935541687b384a3d6caf8558
Parents: d6f6d22
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jan 29 17:44:49 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Feb 3 10:27:38 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js |  2 ++
 src/fauxton/app/addons/fauxton/components.js  | 11 +++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5c7b3127/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index 1824da0..f3e5043 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -284,6 +284,8 @@ function(app, FauxtonAPI) {
       this.totalRowsToPaginate = 100;
       this.on("remove",this.decrementTotalRows , this);
       this.perPageLimit = options.perPageLimit || 20;
+
+      this.params.limit = this.perPageLimit; 
     },
 
     url: function(context) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/5c7b3127/src/fauxton/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/components.js b/src/fauxton/app/addons/fauxton/components.js
index d5ba7a6..7e884ae 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -89,7 +89,6 @@ function(app, FauxtonAPI, ace, spin) {
         return false;
       }
 
-      console.log(this.pageStart() + this.perPage, this.docLimit);
       if ((this.pageStart() + this.perPage) >= this.docLimit) {
         return false;
       }
@@ -119,9 +118,16 @@ function(app, FauxtonAPI, ace, spin) {
       this.pageNumber = this.pageNumber + 1;
       this.incPageStart();
 
+      var documentsLeftToFetch = this.docLimit - (this.pageNumber * this.perPage),
+          limit = this.perPage;
+
+      if (documentsLeftToFetch < this.perPage) {
+        limit = documentsLeftToFetch;
+      }
+
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'next',
-       perPage: this.perPage
+       perPage: limit
       });
     },
 
@@ -163,6 +169,7 @@ function(app, FauxtonAPI, ace, spin) {
         return this.page() + this.collection.length;
       }
 
+      return this.page() + this.perPage;
     }
 
   });


[08/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
dry out delete events


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/e57286d7
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e57286d7
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e57286d7

Branch: refs/heads/paginate-api-options
Commit: e57286d7295f58b64f158c411789c51c2b592304
Parents: af4a1b9
Author: Simon Metson <si...@cloudant.com>
Authored: Sun Jan 26 19:04:57 2014 +0000
Committer: suelockwood <de...@apache.org>
Committed: Wed Jan 29 10:34:29 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/views.js | 21 +--------------------
 1 file changed, 1 insertion(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e57286d7/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 93fd0d4..fd7d034 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -40,10 +40,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.active_id = options.active_id;
     },
 
-    events: {
-      "click #delete-database": "delete_database"
-    },
-
     serialize: function () {
       return {
         // TODO make this not hard coded here
@@ -64,21 +60,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.$('.active').removeClass('active');
         this.$('#'+this.active_id).addClass('active');
       }
-    },
-
-    delete_database: function (event) {
-      event.preventDefault();
-
-      var result = confirm("Are you sure you want to delete this database?");
-
-      if (!result) { return; }
-      FauxtonAPI.addNotification({
-        msg: "Deleting your database...",
-        type: "error"
-      });
-      return this.database.destroy().done(function () {
-        app.router.navigate('#/_all_dbs', {trigger: true});
-      });
     }
   });
 
@@ -1778,7 +1759,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.database.destroy().then(function () {
         FauxtonAPI.navigate('#/_all_dbs');
         FauxtonAPI.addNotification({
-          msg: 'The database ' + databaseName + ' has been deleted.',
+          msg: 'The database <code>' + databaseName + '</code> has been deleted.',
           clear: true
         });
       }).fail(function (rsp, error, msg) {


[02/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Adopt to the recent erlang-oauth (1.3+)

Signed-off-by: Peter Lemenkov <le...@gmail.com>
Signed-off-by: Alexander Shorin <kx...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/5c9f9a9f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/5c9f9a9f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/5c9f9a9f

Branch: refs/heads/paginate-api-options
Commit: 5c9f9a9f056ca71c516ddd7eb9ab32f8eb01dc12
Parents: 6d171cb
Author: Peter Lemenkov <le...@gmail.com>
Authored: Fri Jan 10 16:30:25 2014 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Wed Jan 29 04:18:16 2014 +0400

----------------------------------------------------------------------
 src/couchdb/couch_httpd_oauth.erl | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5c9f9a9f/src/couchdb/couch_httpd_oauth.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_oauth.erl b/src/couchdb/couch_httpd_oauth.erl
index 2094c08..60a937c 100644
--- a/src/couchdb/couch_httpd_oauth.erl
+++ b/src/couchdb/couch_httpd_oauth.erl
@@ -43,6 +43,7 @@ oauth_auth_callback(#httpd{mochi_req = MochiReq} = Req, CbParams) ->
     Method = atom_to_list(MochiReq:get(method)),
     #callback_params{
         consumer = Consumer,
+        token = Token,
         token_secret = TokenSecret,
         url = Url,
         signature = Sig,
@@ -61,7 +62,7 @@ oauth_auth_callback(#httpd{mochi_req = MochiReq} = Req, CbParams) ->
             "Consumer is `~p`, token secret is `~p`~n"
             "Expected signature was `~p`~n",
             [User, Sig, Method, Url, Params, Consumer, TokenSecret,
-                oauth:signature(Method, Url, Params, Consumer, TokenSecret)]),
+                oauth:sign(Method, Url, Params, Consumer, Token, TokenSecret)]),
         Req
     end.
 


[04/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Fauxton: Split up api.js

Split up api to core/*. To seperate out the Framework from the UI.
Move tests to fit with this refactor.
Change addons/Fauxton with work with api extraction.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/96be583d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/96be583d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/96be583d

Branch: refs/heads/paginate-api-options
Commit: 96be583d8566536b0356296d4f9b01164e31f4fc
Parents: 5c9f9a9
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jan 8 15:26:12 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Jan 29 16:53:46 2014 +0200

----------------------------------------------------------------------
 src/Makefile.am                                 |  22 +-
 src/fauxton/Gruntfile.js                        |   4 +-
 .../app/addons/activetasks/tests/viewsSpec.js   |   3 -
 src/fauxton/app/addons/auth/base.js             |   1 +
 src/fauxton/app/addons/auth/resources.js        |   7 +-
 src/fauxton/app/addons/documents/views.js       |   8 +-
 src/fauxton/app/addons/fauxton/base.js          | 109 +++-
 src/fauxton/app/addons/fauxton/components.js    | 100 +++-
 src/fauxton/app/addons/fauxton/layout.js        |  98 ---
 src/fauxton/app/addons/fauxton/resizeColumns.js |  87 +++
 .../app/addons/fauxton/tests/baseSpec.js        |  79 +++
 .../app/addons/fauxton/tests/navbarSpec.js      | 107 ++++
 .../app/addons/fauxton/tests/paginateSpec.js    | 105 ++++
 src/fauxton/app/api.js                          | 593 -------------------
 src/fauxton/app/app.js                          |  85 ++-
 src/fauxton/app/config.js                       |   5 +-
 src/fauxton/app/core/api.js                     |  53 ++
 src/fauxton/app/core/auth.js                    |  67 +++
 src/fauxton/app/core/base.js                    | 137 +++++
 src/fauxton/app/core/couchdbSession.js          |  54 ++
 src/fauxton/app/core/layout.js                  |  91 +++
 src/fauxton/app/core/routeObject.js             | 296 +++++++++
 src/fauxton/app/core/router.js                  | 113 ++++
 src/fauxton/app/core/tests/layoutSpec.js        |  92 +++
 src/fauxton/app/core/tests/routeObjectSpec.js   |  96 +++
 src/fauxton/app/core/utils.js                   |  94 +++
 src/fauxton/app/main.js                         |  13 +-
 src/fauxton/app/resizeColumns.js                |  87 ---
 src/fauxton/app/router.js                       | 142 -----
 src/fauxton/app/utils.js                        |  66 ---
 src/fauxton/settings.json.default               |   1 +
 src/fauxton/tasks/couchserver.js                |   2 +-
 src/fauxton/test/core/layoutSpec.js             |  94 ---
 src/fauxton/test/core/navbarSpec.js             | 107 ----
 src/fauxton/test/core/paginateSpec.js           | 109 ----
 src/fauxton/test/core/routeObjectSpec.js        | 105 ----
 src/fauxton/test/mocha/testUtils.js             |   3 +-
 src/fauxton/test/test.config.underscore         |   1 +
 38 files changed, 1731 insertions(+), 1505 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index ba160b9..0f5c491 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -111,14 +111,22 @@ FAUXTON_FILES = \
     fauxton/app/addons/verifyinstall/routes.js \
     fauxton/app/addons/verifyinstall/templates/main.html \
     fauxton/app/addons/verifyinstall/assets/less/verifyinstall.less \
-    fauxton/app/api.js \
+    fauxton/app/core/api.js \
+    fauxton/app/core/auth.js \
+    fauxton/app/core/base.js \
+    fauxton/app/core/couchdbSession.js \
+    fauxton/app/core/layout.js \
+    fauxton/app/core/routeObject.js \
+    fauxton/app/core/router.js \
+    fauxton/app/core/utils.js \
+    fauxton/app/core/tests/layoutSpec.js \
+    fauxton/app/core/tests/routeObjectSpec.js \
     fauxton/app/app.js \
     fauxton/app/config.js \
     fauxton/app/helpers.js \
     fauxton/app/initialize.js.underscore \
     fauxton/app/load_addons.js.underscore \
     fauxton/app/main.js \
-    fauxton/app/utils.js \
     fauxton/app/addons/databases/base.js \
     fauxton/app/addons/databases/resources.js \
     fauxton/app/addons/databases/routes.js \
@@ -131,11 +139,13 @@ FAUXTON_FILES = \
     fauxton/app/addons/fauxton/base.js \
     fauxton/app/addons/fauxton/components.js \
     fauxton/app/addons/fauxton/layout.js \
+    fauxton/app/addons/fauxton/resizeColumns.js \
+    fauxton/app/addons/fauxton/tests/baseSpec.js \
+    fauxton/app/addons/fauxton/tests/navbarSpec.js \
+    fauxton/app/addons/fauxton/tests/paginateSpec.js \
     fauxton/app/addons/pouchdb/base.js \
     fauxton/app/addons/pouchdb/pouch.collate.js \
     fauxton/app/addons/pouchdb/pouchdb.mapreduce.js \
-    fauxton/app/resizeColumns.js \
-    fauxton/app/router.js \
     fauxton/app/addons/databases/templates/item.html \
     fauxton/app/addons/databases/templates/list.html \
     fauxton/app/addons/databases/templates/newdatabase.html \
@@ -309,10 +319,6 @@ FAUXTON_FILES = \
     fauxton/tasks/couchserver.js \
     fauxton/tasks/fauxton.js \
     fauxton/tasks/helper.js \
-    fauxton/test/core/layoutSpec.js \
-    fauxton/test/core/navbarSpec.js \
-    fauxton/test/core/paginateSpec.js \
-    fauxton/test/core/routeObjectSpec.js \
     fauxton/test/mocha/chai.js \
     fauxton/test/mocha/mocha.css \
     fauxton/test/mocha/mocha.js \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index 32065b6..2c5a249 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -357,7 +357,7 @@ module.exports = function(grunt) {
 
     mochaSetup: {
       default: {
-        files: { src: helper.watchFiles(['[Ss]pec.js'], ['./test/core/**/*[Ss]pec.js', './app/**/*[Ss]pec.js'])},
+        files: { src: helper.watchFiles(['[Ss]pec.js'], ['./app/**/*[Ss]pec.js'])},
         template: 'test/test.config.underscore',
         config: './app/config.js'
       }
@@ -424,7 +424,7 @@ module.exports = function(grunt) {
   grunt.registerTask('lint', ['clean', 'jshint']);
   grunt.registerTask('test', ['lint', 'dependencies', 'test_inline']);
   // lighter weight test task for use inside dev/watch
-  grunt.registerTask('test_inline', ['mochaSetup','jst', 'concat:test_config_js', 'mocha_phantomjs']);
+  grunt.registerTask('test_inline', ['mochaSetup','jst', 'concat:test_config_js','mocha_phantomjs']);
   // Fetch dependencies (from git or local dir), lint them and make load_addons
   grunt.registerTask('dependencies', ['get_deps', 'gen_load_addons:default']);
   // build templates, js and css

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/activetasks/tests/viewsSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/tests/viewsSpec.js b/src/fauxton/app/addons/activetasks/tests/viewsSpec.js
index 395b60a..13c9049 100644
--- a/src/fauxton/app/addons/activetasks/tests/viewsSpec.js
+++ b/src/fauxton/app/addons/activetasks/tests/viewsSpec.js
@@ -132,8 +132,5 @@ define([
       });
 
     });
-
-
-
   });
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/auth/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/base.js b/src/fauxton/app/addons/auth/base.js
index 9f9a332..7f69a7f 100644
--- a/src/fauxton/app/addons/auth/base.js
+++ b/src/fauxton/app/addons/auth/base.js
@@ -20,6 +20,7 @@ function(app, FauxtonAPI, Auth) {
 
   Auth.session = new Auth.Session();
   FauxtonAPI.setSession(Auth.session);
+  app.session = Auth.session;
 
   Auth.initialize = function() {
     Auth.navLink = new Auth.NavLink({model: Auth.session});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
index 970d55b..321d302 100644
--- a/src/fauxton/app/addons/auth/resources.js
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -12,10 +12,11 @@
 
 define([
        "app",
-       "api"
+       "api",
+       "core/CouchdbSession"
 ],
 
-function (app, FauxtonAPI) {
+function (app, FauxtonAPI, CouchdbSession) {
 
   var Auth = new FauxtonAPI.addon();
 
@@ -46,7 +47,7 @@ function (app, FauxtonAPI) {
     }
   });
 
-  Auth.Session = FauxtonAPI.Session.extend({
+  Auth.Session = CouchdbSession.Session.extend({
     url: app.host + '/_session',
 
     initialize: function (options) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 9516355..aeb5983 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -21,7 +21,7 @@ define([
        "addons/pouchdb/base",
 
        // Libs
-       "resizeColumns",
+       "addons/Fauxton/resizeColumns",
 
        // Plugins
        "plugins/beautify",
@@ -720,11 +720,11 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
     
     cleanup: function () {
-      //if (!this.pagination) { return; }
-      this.pagination.remove();
-      //this.pagination = null;
       this.allDocsNumber.remove();
       _.each(this.rows, function (row) {row.remove();});
+
+      if (!this.pagination) { return; }
+      this.pagination.remove();
     },
 
     beforeRender: function() {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/fauxton/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/base.js b/src/fauxton/app/addons/fauxton/base.js
index 1811e84..35babb5 100644
--- a/src/fauxton/app/addons/fauxton/base.js
+++ b/src/fauxton/app/addons/fauxton/base.js
@@ -12,18 +12,86 @@
 
 define([
   "app",
-  // Libs
-  "backbone",
-  "resizeColumns",
+  "api",
+  "addons/fauxton/resizeColumns"
 ],
 
-function(app, Backbone, resizeColumns) {
+function(app, FauxtonAPI, resizeColumns) {
 
-  //resizeAnimation
-  app.resizeColumns = new resizeColumns({});
-  app.resizeColumns.onResizeHandler();
+  var Fauxton = FauxtonAPI.addon();
+  FauxtonAPI.addNotification = function (options) {
+    options = _.extend({
+      msg: "Notification Event Triggered!",
+      type: "info",
+      selector: "#global-notifications"
+    }, options);
 
-  var Fauxton = {};
+    var view = new Fauxton.Notification(options);
+    return view.renderNotification();
+  };
+
+  FauxtonAPI.UUID = FauxtonAPI.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();
+    }
+  });
+
+
+  Fauxton.initialize = function () {
+    app.footer = new Fauxton.Footer({el: "#footer-content"}),
+    app.navBar = new Fauxton.NavBar();
+    app.apiBar = new Fauxton.ApiBar();
+
+    FauxtonAPI.when.apply(null, app.footer.establish()).done(function() {
+      FauxtonAPI.masterLayout.setView("#primary-navbar", app.navBar, true);
+      FauxtonAPI.masterLayout.setView("#api-navbar", app.apiBar, true);
+      app.navBar.render();
+      app.apiBar.render();
+
+      app.footer.render();
+    });
+
+    FauxtonAPI.masterLayout.navBar = app.navBar;
+    FauxtonAPI.masterLayout.apiBar = app.apiBar;
+
+    FauxtonAPI.RouteObject.on('beforeFullRender', function (routeObject) {
+      $('#primary-navbar li').removeClass('active');
+
+      if (routeObject.selectedHeader) {
+        app.selectedHeader = routeObject.selectedHeader;
+        $('#primary-navbar li[data-nav-name="' + routeObject.selectedHeader + '"]').addClass('active');
+      }
+    });
+
+    FauxtonAPI.RouteObject.on('beforeEstablish', function (routeObject) {
+      FauxtonAPI.masterLayout.removeView('#breadcrumbs');
+      var crumbs = routeObject.get('crumbs');
+
+      if (crumbs.length) {
+        FauxtonAPI.masterLayout.setView('#breadcrumbs', new Fauxton.Breadcrumbs({
+          crumbs: crumbs
+        }), true).render();
+      }
+    });
+
+    FauxtonAPI.RouteObject.on('renderComplete', function (routeObject) {
+      var masterLayout = FauxtonAPI.masterLayout;
+      if (routeObject.get('apiUrl')){
+        masterLayout.apiBar.update(routeObject.get('apiUrl'));
+      } else {
+        masterLayout.apiBar.hide();
+      }
+    });
+  };
 
   Fauxton.Breadcrumbs = Backbone.View.extend({
     template: "templates/fauxton/breadcrumbs",
@@ -41,7 +109,9 @@ function(app, Backbone, resizeColumns) {
   });
 
   Fauxton.VersionInfo = Backbone.Model.extend({
-    url: app.host
+    url: function () {
+      return app.host;
+    }
   });
 
   // TODO: this View should extend from FauxtonApi.View.
@@ -76,6 +146,16 @@ function(app, Backbone, resizeColumns) {
     bottomNavLinks: [],
     footerNavLinks: [],
 
+    initialize: function () {
+      _.bindAll(this);
+      //resizeAnimation
+      this.resizeColumns = new resizeColumns({});
+      this.resizeColumns.onResizeHandler();
+      
+      FauxtonAPI.extensions.on('add:navbar:addHeaderLink', this.addLink);
+      FauxtonAPI.extensions.on('removeItem:navbar:addHeaderLink', this.removeLink);
+    },
+
     serialize: function() {
       return {
         navLinks: this.navLinks,
@@ -124,7 +204,6 @@ function(app, Backbone, resizeColumns) {
     },
 
     afterRender: function(){
-
       $('#primary-navbar li[data-nav-name="' + app.selectedHeader + '"]').addClass('active');
 
       var menuOpen = true;
@@ -141,21 +220,22 @@ function(app, Backbone, resizeColumns) {
       function toggleMenu(){
         $selectorList.toggleClass('closeMenu');
         menuOpen = $selectorList.hasClass('closeMenu');
-        app.resizeColumns.onResizeHandler();
+        this.resizeColumns.onResizeHandler();
       }
-
+      
+      var that = this;
       $('#primary-navbar').on("click", ".nav a", function(){
         if (!($selectorList.hasClass('closeMenu'))){
           setTimeout(
             function(){
             $selectorList.addClass('closeMenu');
-            app.resizeColumns.onResizeHandler();
+            that.resizeColumns.onResizeHandler();
           },3000);
 
         }
       });
 
-      app.resizeColumns.initialize();
+      this.resizeColumns.initialize();
     },
 
     beforeRender: function () {
@@ -265,6 +345,5 @@ function(app, Backbone, resizeColumns) {
     }
   });
 
-
   return Fauxton;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/components.js b/src/fauxton/app/addons/fauxton/components.js
index edde428..c26fc96 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -25,10 +25,11 @@ define([
   // Libs
   "api",
   "ace_configuration",
+  "spin"
 ],
 
-function(app, FauxtonAPI, ace) {
-  var Components = app.module();
+function(app, FauxtonAPI, ace, spin) {
+  var Components = FauxtonAPI.addon();
 
   Components.Pagination = FauxtonAPI.View.extend({
     template: "templates/fauxton/pagination",
@@ -124,7 +125,7 @@ function(app, FauxtonAPI, ace) {
 
     pageEnd: function () {
       if (this.collection.length < this.pageLimit()) {
-        return this.collection.length;
+        return (this.previousParams.length * this.pageLimit()) + this.collection.length;
       }
 
       return (this.previousParams.length * this.pageLimit()) + this.pageLimit();
@@ -235,6 +236,8 @@ function(app, FauxtonAPI, ace) {
       this.theme = options.theme || 'crimson_editor';
       this.couchJSHINT = options.couchJSHINT;
       this.edited = false;
+
+      _.bindAll(this);
     },
 
     afterRender: function () {
@@ -295,13 +298,14 @@ function(app, FauxtonAPI, ace) {
     },
 
     removeIncorrectAnnotations: function () {
-      var editor = this.editor;
+      var editor = this.editor,
+          isIgnorableError = this.isIgnorableError;
 
-      this.editor.getSession().on("changeAnnotation", function(){
+      this.editor.getSession().on("changeAnnotation", function () {
         var annotations = editor.getSession().getAnnotations();
 
         var newAnnotations = _.reduce(annotations, function (annotations, error) {
-          if (!FauxtonAPI.isIgnorableError(error.raw)) {
+          if (!isIgnorableError(error.raw)) {
             annotations.push(error);
           }
           return annotations;
@@ -338,12 +342,94 @@ function(app, FauxtonAPI, ace) {
      var errors = this.getAnnotations();
      // By default CouchDB view functions don't pass lint
      return _.every(errors, function(error) {
-      return FauxtonAPI.isIgnorableError(error.raw);
+      return this.isIgnorableError(error.raw);
       },this);
+    },
+
+    // List of JSHINT errors to ignore
+    // Gets around problem of anonymous functions not being a valid statement
+    excludedViewErrors: [
+      "Missing name in function declaration.",
+      "['{a}'] is better written in dot notation."
+    ],
+
+    isIgnorableError: function(msg) {
+      return _.contains(this.excludedViewErrors, msg);
     }
 
   });
 
+  //need to make this into a backbone view...
+  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();
+  });
+
   return Components;
 });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/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
deleted file mode 100644
index 1422241..0000000
--- a/src/fauxton/app/addons/fauxton/layout.js
+++ /dev/null
@@ -1,98 +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(["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/96be583d/src/fauxton/app/addons/fauxton/resizeColumns.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/resizeColumns.js b/src/fauxton/app/addons/fauxton/resizeColumns.js
new file mode 100644
index 0000000..abfcd2f
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/resizeColumns.js
@@ -0,0 +1,87 @@
+// 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([
+  "api"
+],
+
+function(FauxtonAPI) {
+
+  var Resize = function(options){
+    this.options = options;
+    this.options.selectorElements = options.selectorElements || ".window-resizeable";
+  };
+
+  Resize.prototype = {
+    getPrimaryNavWidth: function(){
+      var primaryNavWidth  = $('body').hasClass('closeMenu')? 64:224;
+      return primaryNavWidth;
+    },
+    getPanelWidth: function(){
+      var sidebarWidth = $('#sidebar-content').length > 0 ? $('#sidebar-content').width(): 0;
+      return (this.getPrimaryNavWidth() + sidebarWidth); 
+    },
+    initialize: function(){
+     // $(window).off('resize');
+      var that = this;
+      //add throttler :) 
+      this.lazyLayout = _.debounce(that.onResizeHandler, 300).bind(this);
+      FauxtonAPI.utils.addWindowResize(this.lazyLayout,"animation");
+      FauxtonAPI.utils.initWindowResize();
+      this.onResizeHandler();
+    },
+    updateOptions:function(options){
+      this.options = {};
+      this.options = options;
+      this.options.selectorElements = options.selectorElements || ".window-resizeable";
+    },
+    turnOff:function(){
+      FauxtonAPI.utils.removeWindowResize("animation");
+    },
+    cleanupCallback: function(){
+      this.callback = null;
+    },
+    onResizeHandler: function (){
+      //if there is an override, do that instead
+      if (this.options.onResizeHandler){
+        this.options.onResizeHandler();
+      } else {
+        var combinedWidth = window.innerWidth - this.getPanelWidth(),
+        smallWidthConstraint = ($('#sidebar-content').length > 0)? 470:800,
+        panelWidth; 
+
+        if( combinedWidth > smallWidthConstraint  && combinedWidth < 1400){
+          panelWidth = window.innerWidth - this.getPanelWidth();
+        } else if (combinedWidth < smallWidthConstraint){
+          panelWidth = smallWidthConstraint;
+        } else if(combinedWidth > 1400){
+          panelWidth = 1400;
+        }
+
+        $(this.options.selectorElements).innerWidth(panelWidth);
+      }
+      //if there is a callback, run that
+      if(this.options.callback) {
+        this.options.callback();
+      }
+    } 
+  };
+
+  return Resize;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/fauxton/tests/baseSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/tests/baseSpec.js b/src/fauxton/app/addons/fauxton/tests/baseSpec.js
new file mode 100644
index 0000000..7df4dfc
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/tests/baseSpec.js
@@ -0,0 +1,79 @@
+// 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([
+  'testUtils',
+  'api',
+  'addons/fauxton/base',
+  "backbone"
+], function (testUtils, FauxtonAPI, Base) {
+  var assert = testUtils.assert;
+
+
+  describe('Fauxton RouteObject:beforeEstablish', function () {
+    var TestRouteObject, testRouteObject, mockLayout, _layout;
+
+    before(function () {
+      Base.initialize();
+      _layout = FauxtonAPI.masterLayout;
+    });
+
+    beforeEach(function () {
+      TestRouteObject = FauxtonAPI.RouteObject.extend({
+        crumbs: ['mycrumbs']
+      });
+
+      testRouteObject = new TestRouteObject();
+      var apiBar = {};
+      apiBar.hide = sinon.spy();
+      var setViewSpy = sinon.stub();
+      setViewSpy.returns({
+        render: function () {}
+      });
+
+      // Need to find a better way of doing this
+      mockLayout = {
+        setTemplate: sinon.spy(),
+        clearBreadcrumbs: sinon.spy(),
+        setView: setViewSpy,
+        renderView: sinon.spy(),
+        removeView: sinon.spy(),
+        hooks: [],
+        setBreadcrumbs: sinon.spy(),
+        apiBar: apiBar,
+        layout: { 
+          setView: function () {}
+        }
+      };
+
+
+    });
+
+    after(function () {
+      FauxtonAPI.masterLayout = _layout;
+    });
+
+    it('Should clear breadcrumbs', function () {
+      FauxtonAPI.masterLayout = mockLayout;
+      testRouteObject.renderWith('the-route', mockLayout, 'args');
+      assert.ok(mockLayout.removeView.calledWith('#breadcrumbs'), 'Clear Breadcrumbs called');
+    });
+
+    it('Should set breadcrumbs when breadcrumbs exist', function () {
+      FauxtonAPI.masterLayout = mockLayout;
+      testRouteObject.renderWith('the-route', mockLayout, 'args');
+      assert.ok(mockLayout.setView.calledOnce, 'Set Breadcrumbs was called');
+    });
+
+  });
+
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/fauxton/tests/navbarSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/tests/navbarSpec.js b/src/fauxton/app/addons/fauxton/tests/navbarSpec.js
new file mode 100644
index 0000000..3eca6f6
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/tests/navbarSpec.js
@@ -0,0 +1,107 @@
+// 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([
+       'addons/fauxton/base',
+      'testUtils'
+], function (Fauxton, testUtils) {
+  var assert = testUtils.assert,
+      NavBar = Fauxton.NavBar;
+
+  describe('NavBar', function () {
+
+    describe('adding links', function () {
+      var navBar;
+
+      beforeEach(function () {
+        navBar = new NavBar();
+        navBar.navLinks = [];
+        navBar.bottomNavLinks = [];
+        navBar.footerNavLinks = [];
+      });
+
+      it('Should add link to navlinks', function () {
+        navBar.addLink({href: '#/test', title: 'Test Title'});
+
+        assert.equal(navBar.navLinks.length, 1);
+        assert.equal(navBar.footerNavLinks.length, 0);
+        assert.equal(navBar.bottomNavLinks.length, 0);
+      });
+
+      it('Should add link to bottom links', function () {
+        navBar.addLink({href: '#/test', bottomNav: true, title: 'Test Title'});
+
+        assert.equal(navBar.bottomNavLinks.length, 1);
+        assert.equal(navBar.navLinks.length, 0);
+        assert.equal(navBar.footerNavLinks.length, 0);
+      });
+
+      it('Should add link to footer links', function () {
+        navBar.addLink({href: '#/test', footerNav: true, title: 'Test Title'});
+
+        assert.equal(navBar.footerNavLinks.length, 1);
+        assert.equal(navBar.bottomNavLinks.length, 0);
+        assert.equal(navBar.navLinks.length, 0);
+      });
+    });
+
+    describe('removing links', function () {
+      var navBar;
+
+      beforeEach(function () {
+        navBar = new NavBar();
+        navBar.navLinks = [];
+        navBar.bottomNavLinks = [];
+        navBar.footerNavLinks = [];
+        navBar.addLink({
+          href: '#/test', 
+          footerNav: true, 
+          title: 'Test Title Footer'
+        });
+
+        navBar.addLink({
+          href: '#/test', 
+          bottomNav: true, 
+          title: 'Test Title Bottom'
+        });
+
+        navBar.addLink({
+          href: '#/test', 
+          title: 'Test Title'
+        });
+      });
+
+      it("should remove links from list", function () {
+        navBar.removeLink({
+          title: 'Test Title Footer',
+          footerNav: true
+        });
+
+        assert.equal(navBar.footerNavLinks.length, 0);
+        assert.equal(navBar.bottomNavLinks.length, 1);
+        assert.equal(navBar.navLinks.length, 1);
+      });
+
+      it("Should call render after removing links", function () {
+        var renderSpy = sinon.stub(navBar,'render');
+
+        navBar.removeLink({
+          title: 'Test Title Footer',
+          footerNav: true
+        });
+
+        assert.ok(renderSpy.calledOnce);
+      });
+
+    });
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/addons/fauxton/tests/paginateSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/tests/paginateSpec.js b/src/fauxton/app/addons/fauxton/tests/paginateSpec.js
new file mode 100644
index 0000000..535e26f
--- /dev/null
+++ b/src/fauxton/app/addons/fauxton/tests/paginateSpec.js
@@ -0,0 +1,105 @@
+// 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',
+       'addons/fauxton/components',
+       'addons/documents/resources',
+       'testUtils',
+       'api'
+], function (app, Views, Models, testUtils, FauxtonAPI) {
+  var assert = testUtils.assert,
+  ViewSandbox = testUtils.ViewSandbox;
+
+
+  describe('IndexPaginate', function () {
+    var viewSandbox, paginate, collection, navigateMock;
+    beforeEach(function () {
+      collection = new Models.IndexCollection([{
+        id:'myId1',
+        doc: 'num1'
+      },
+      {
+        id:'myId2',
+        doc: 'num2'
+      }], {
+        database: {id: 'databaseId'},
+        design: '_design/myDoc'
+      });
+
+      paginate = new Views.IndexPagination({
+        collection: collection,
+        previousUrlfn: function () {},
+        nextUrlfn: function () {},
+        canShowPreviousfn: function () { return true; },
+        canShowNextfn: function () { return true;}
+      });
+      viewSandbox = new ViewSandbox();
+      viewSandbox.renderView(paginate); 
+    });
+
+    afterEach(function () {
+      viewSandbox.remove();
+    });
+
+    describe('#next', function () {
+      beforeEach(function () {
+        //do this so it doesn't throw an error on other unwired up components
+        FauxtonAPI.triggerRouteEvent = function () {};
+        //FauxtonAPI.triggerRouteEvent.restore && FauxtonAPI.triggerRouteEvent.restore();
+        //FauxtonAPI.navigate.restore && FauxtonAPI.navigate.restore(); 
+      });
+
+      it('Should navigate', function () {
+        var navigateMock = sinon.spy(FauxtonAPI, 'navigate');
+
+        paginate.$('a#next').click();
+
+        assert.ok(navigateMock.calledOnce);
+        FauxtonAPI.navigate.restore();
+      });
+
+      it('Should trigger routeEvent', function () {
+        var navigateMock = sinon.spy(FauxtonAPI, 'triggerRouteEvent');
+
+        paginate.$('a#next').click();
+
+        assert.ok(navigateMock.calledOnce);
+        FauxtonAPI.triggerRouteEvent.restore();
+      });
+
+    });
+
+
+    describe('#previous', function () {
+
+      it('Should navigate', function () {
+        var navigateMock = sinon.spy(FauxtonAPI, 'navigate');
+
+        paginate.$('a#previous').click();
+
+        assert.ok(navigateMock.calledOnce);
+        FauxtonAPI.navigate.restore();
+      });
+
+      it('Should trigger routeEvent', function () {
+        var navigateMock = sinon.spy(FauxtonAPI, 'triggerRouteEvent');
+
+        paginate.$('a#previous').click();
+
+        assert.ok(navigateMock.calledOnce);
+        FauxtonAPI.triggerRouteEvent.restore();
+      });
+
+    });
+
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
deleted file mode 100644
index 9ac895e..0000000
--- a/src/fauxton/app/api.js
+++ /dev/null
@@ -1,593 +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
-       "addons/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: app.host + '/_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: [],
-    _promises: [],
-    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');
-      var establishPromise = this.establish();
-      this.addPromise(establishPromise);
-      FauxtonAPI.when(establishPromise).then(function(resp) {
-        triggerBroadcast('afterEstablish');
-        _.each(routeObject.getViews(), function(view, selector) {
-          if(view.hasRendered) { 
-            triggerBroadcast('viewHasRendered', view, selector);
-            return;
-          }
-
-          triggerBroadcast('beforeRender', view, selector);
-          var viewPromise = view.establish();
-          routeObject.addPromise(viewPromise);
-          FauxtonAPI.when(viewPromise).then(function(resp) {
-            masterLayout.setView(selector, view);
-
-            masterLayout.renderView(selector);
-            triggerBroadcast('afterRender', view, selector);
-            }, function(resp) {
-              view.establishError = {
-                error: true,
-                reason: resp
-              };
-
-              if (resp && resp.responseText) { 
-                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 || !resp.responseText) { 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);
-    },
-
-    addPromise: function (promise) {
-      if (_.isEmpty(promise)) { return; }
-
-      if (_.isArray(promise)) {
-        return _.each(promise, function (p) {
-          this._promises.push(p);
-        }, this);
-      }
-
-     this._promises.push(promise);
-    },
-
-    cleanup: function () {
-      this.removeViews();
-      this.rejectPromises();
-    },
-
-    rejectPromises: function () {
-      _.each(this._promises, function (promise) {
-        if (promise.state() === "resolved") { return; }
-        if (promise.abort) {
-          return promise.abort("Route change");
-        } 
-
-        promise.reject();
-      }, this);
-
-      this._promises = [];
-    },
-
-    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/96be583d/src/fauxton/app/app.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/app.js b/src/fauxton/app/app.js
index 5325f77..521ad6c 100644
--- a/src/fauxton/app/app.js
+++ b/src/fauxton/app/app.js
@@ -21,77 +21,38 @@ define([
   "bootstrap",
 
   "helpers",
-  "utils",
+  "core/utils",
   // Modules
-  "resizeColumns",
-
-   // Plugins.
+  "core/api",
+  "core/couchdbsession",
+  // Plugins.
   "plugins/backbone.layoutmanager",
   "plugins/jquery.form"
 
 ],
 
-function(app, $, _, Backbone, Bootstrap, Helpers, Utils, resizeColumns) {
-
-   // Make sure we have a console.log
+function(app, $, _, Backbone, Bootstrap, Helpers, Utils, FauxtonAPI, Couchdb) {
+  // Make sure we have a console.log
   if (typeof console == "undefined") {
     console = {
-      log: function(){}
+      log: function(){},
+      trace: function(){},
+      debug: function(){}
     };
   }
 
   // Provide a global location to place configuration settings and module
   // creation also mix in Backbone.Events
-  _.extend(app, Backbone.Events, {
+  _.extend(app, {
     utils: Utils,
-
-    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;
-    }
+    getParams: FauxtonAPI.utils.getParams
   });
 
-  //resizeAnimation
-  app.resizeColumns = new resizeColumns({});
-  app.resizeColumns.onResizeHandler();
-
   // Localize or create a new JavaScript Template object.
   var JST = window.JST = window.JST || {};
 
   // Configure LayoutManager with Backbone Boilerplate defaults.
-  Backbone.Layout.configure({
+  FauxtonAPI.Layout.configure({
     // Allow LayoutManager to augment Backbone.View.prototype.
     manage: true,
 
@@ -123,6 +84,28 @@ function(app, $, _, Backbone, Bootstrap, Helpers, Utils, resizeColumns) {
     }
   });
 
+  FauxtonAPI.setSession(new Couchdb.Session());
+
+  // Define your master router on the application namespace and trigger all
+  // navigation from this instance.
+  FauxtonAPI.config({
+    el: "#app-container",
+    masterLayout: new FauxtonAPI.Layout(),
+    
+    addHeaderLink: function(link) {
+      FauxtonAPI.registerExtension('navbar:addHeaderLink', link);
+    },
+
+    removeHeaderLink: function(link) {
+      FauxtonAPI.removeExtensionItem('navbar:addHeaderLink', link, function (item) {
+        if (item.title === link.title) {
+          return true;
+        }
+
+        return false;
+      });
+    }
+  });
 
   return app;
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 057523b..98be9c6 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -25,7 +25,7 @@ require.config({
     jquery: "../assets/js/libs/jquery",
     lodash: "../assets/js/libs/lodash",
     backbone: "../assets/js/libs/backbone",
-    "backbone.layoutmanger": "../assets/js/plugins/backbone.layoutmanager",
+    "backbone.layoutmanager": "../assets/js/plugins/backbone.layoutmanager",
     bootstrap: "../assets/js/libs/bootstrap",
     spin: "../assets/js/libs/spin.min",
     d3: "../assets/js/libs/d3",
@@ -37,7 +37,8 @@ require.config({
 
   map: {
     "*": {
-      'underscore': 'lodash'
+      'underscore': 'lodash',
+      'api':'core/api'
     }
   },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/api.js b/src/fauxton/app/core/api.js
new file mode 100644
index 0000000..1b21dca
--- /dev/null
+++ b/src/fauxton/app/core/api.js
@@ -0,0 +1,53 @@
+// 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([
+       "core/base",
+       "core/layout",
+       "core/router",
+       "core/routeObject",
+       "core/utils"
+],
+
+function(FauxtonAPI, Layout, Router, RouteObject, utils) {
+  FauxtonAPI = _.extend(FauxtonAPI, {
+    Layout: Layout,
+    Router: Router,
+    RouteObject: RouteObject,
+    utils: utils
+  });
+
+  FauxtonAPI.navigate = function(url, _opts) {
+    var options = _.extend({trigger: true}, _opts );
+    FauxtonAPI.router.navigate(url,options);
+  };
+
+  FauxtonAPI.beforeUnload = function () {
+    FauxtonAPI.router.beforeUnload.apply(FauxtonAPI.router, arguments);
+  };
+
+  FauxtonAPI.removeBeforeUnload = function () {
+    FauxtonAPI.router.removeBeforeUnload.apply(FauxtonAPI.router, arguments);
+  };
+
+  FauxtonAPI.addRoute = function(route) {
+    FauxtonAPI.router.route(route.route, route.name, route.callback);
+  };
+
+  FauxtonAPI.triggerRouteEvent = function (routeEvent, args) {
+    FauxtonAPI.router.triggerRouteEvent("route:"+routeEvent, args);
+  };
+
+  
+  return FauxtonAPI;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/auth.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/auth.js b/src/fauxton/app/core/auth.js
new file mode 100644
index 0000000..15cf566
--- /dev/null
+++ b/src/fauxton/app/core/auth.js
@@ -0,0 +1,67 @@
+// 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([
+  "core/base",
+  "backbone"
+],
+function(FauxtonAPI, Backbone) {
+
+  // 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;
+
+      if (!FauxtonAPI.session) {
+        throw new Error("Fauxton.session is not configured.");
+      }
+
+      return FauxtonAPI.session.fetchUser().then(function (user) {
+        return FauxtonAPI.when(that.authHandlerCb(FauxtonAPI.session, requiredRoles));
+      });
+    }
+  });
+
+//  FauxtonAPI.auth = new Auth();
+
+  return Auth;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/base.js b/src/fauxton/app/core/base.js
new file mode 100644
index 0000000..55a8d87
--- /dev/null
+++ b/src/fauxton/app/core/base.js
@@ -0,0 +1,137 @@
+// 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) {
+  var FauxtonAPI = {
+    //add default objects
+    router: {
+      navigate: function () {}
+    },
+
+    masterLayout: {},
+
+    addNotification: function () {},
+
+    config: function (options) {
+      return _.extend(this, options);
+    }
+  };
+
+  FauxtonAPI.Deferred = function() {
+    return $.Deferred();
+  };
+
+  FauxtonAPI.when = function (deferreds) {
+    if (deferreds instanceof Array) {
+      return $.when.apply(null, deferreds);
+    }
+
+    return $.when(deferreds);
+  };
+
+  FauxtonAPI.addonExtensions = {
+    initialize: function() {},
+    RouteObjects: {},
+    Views: {}
+  };
+
+  FauxtonAPI.addon = function(extra) {
+    return _.extend(_.clone(FauxtonAPI.addonExtensions), extra);
+  };
+
+  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.Model = Backbone.Model.extend({
+    fetchOnce: function (opt) {
+      var options = _.extend({}, opt);
+
+      if (!this._deferred || this._deferred.state() === "rejected" || options.forceFetch ) {
+        this._deferred = this.fetch();
+      }
+
+      return this._deferred;
+    }
+  });
+
+  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.unRegisterExtension = function (name) {
+    var views = extensions[name];
+    
+    if (!views) { return; }
+    extensions.trigger('remove:' + name, views);
+    delete extensions[name];
+  };
+
+  FauxtonAPI.getExtensions = function (name) {
+    var views = extensions[name];
+
+    if (!views) {
+      views = [];
+    }
+
+    return views;
+  };
+
+  FauxtonAPI.removeExtensionItem = function (name, view, cb) {
+    var views = extensions[name];
+    if (!views) { return; }
+
+    var _cb = arguments[arguments.length -1];
+    if (_.isObject(view) && !cb) {
+      _cb = function (item) { return _.isEqual(item, view);};
+    } 
+
+    views = _.filter(views, function (item) {
+      return !_cb(item);
+    });
+
+    extensions[name] = views;
+    extensions.trigger('removeItem:' + name, view);
+  };
+
+  FauxtonAPI.extensions = extensions;
+
+  FauxtonAPI.setSession = function (newSession) {
+    FauxtonAPI.session = newSession;
+    return FauxtonAPI.session.fetchUser();
+  };
+
+  return FauxtonAPI;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/couchdbSession.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/couchdbSession.js b/src/fauxton/app/core/couchdbSession.js
new file mode 100644
index 0000000..93bfd8a
--- /dev/null
+++ b/src/fauxton/app/core/couchdbSession.js
@@ -0,0 +1,54 @@
+// 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([
+  "core/base"
+],
+function (FauxtonAPI) {
+  var CouchdbSession = {
+    Session: FauxtonAPI.Model.extend({
+      url: '/_session',
+
+      user: function () {
+        var userCtx = this.get('userCtx');
+
+        if (!userCtx || !userCtx.name) { return null; }
+
+        return {
+          name: userCtx.name,
+          roles: userCtx.roles
+        };
+      },
+
+      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; 
+        });
+      }
+    })
+  };
+
+  return CouchdbSession;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/layout.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/layout.js b/src/fauxton/app/core/layout.js
new file mode 100644
index 0000000..ff339c7
--- /dev/null
+++ b/src/fauxton/app/core/layout.js
@@ -0,0 +1,91 @@
+// 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", 
+  "plugins/backbone.layoutmanager"
+], function(Backbone) {
+
+  // A wrapper of the main Backbone.layoutmanager
+  // Allows the main layout of the page to be changed by any plugin.
+  var Layout = function () {
+    this.layout = new Backbone.Layout({
+      template: "templates/layouts/with_sidebar",
+    });
+
+    this.layoutViews = {};
+    this.el = this.layout.el;
+  };
+
+  Layout.configure = function (options) {
+    Backbone.Layout.configure(options);
+  };
+
+  // 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();
+    },
+
+    setView: function(selector, view, keep) {
+      this.layout.setView(selector, view, false);
+
+      if (!keep) {
+        this.layoutViews[selector] = view;
+      }
+
+      return view;
+    },
+
+    renderView: function(selector) {
+      var view = this.layoutViews[selector];
+      if (!view) {
+        return false;
+      } else {
+        return view.render();
+      }
+    },
+
+    removeView: function (selector) {
+      var view = this.layout.getView(selector);
+
+      if (!view) {
+        return false;
+      }
+
+      view.remove();
+      
+      if (this.layoutViews[selector]) {
+        delete this.layoutViews[selector];
+      }
+
+      return true;
+    }
+
+  });
+
+  return Layout;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/routeObject.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/routeObject.js b/src/fauxton/app/core/routeObject.js
new file mode 100644
index 0000000..f3b8672
--- /dev/null
+++ b/src/fauxton/app/core/routeObject.js
@@ -0,0 +1,296 @@
+// 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([
+  "core/base",
+  "backbone"
+],
+function(FauxtonAPI, Backbone) {
+
+  var RouteObject = function(options) {
+    this._options = options;
+
+    this._configure(options || {});
+    this.initialize.apply(this, arguments);
+    this.addEvents();
+  };
+
+  var broadcaster = {};
+  _.extend(broadcaster, Backbone.Events);
+
+  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
+  RouteObject.extend = Backbone.Model.extend;
+
+  var routeObjectOptions = ["views", "routes", "events", "roles", "crumbs", "layout", "apiUrl", "establish"];
+
+  _.extend(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: [],
+    _promises: [],
+    initialize: function() {}
+  }, {
+
+    renderWith: function(route, masterLayout, args) {
+      //set the options for this render
+      var options = {
+        masterLayout: masterLayout,
+        route: route,
+        args: args
+      };
+
+      this.setTemplateOnFullRender(masterLayout);
+
+      this.triggerBroadcast('beforeEstablish');
+
+      var renderAllViews = _.bind(this.renderAllViews, this, options),
+          establishError = _.bind(this.establishError, this),
+          renderComplete = _.bind(this.renderComplete, this),
+          promise = this.establish();
+
+      this.callEstablish(promise)
+        .then(renderAllViews, establishError)
+        .then(renderComplete);
+    },
+
+    setTemplateOnFullRender: function(masterLayout){
+      // Only want to redo the template if its a full render
+      if (!this.renderedState) {
+        masterLayout.setTemplate(this.layout);
+        this.triggerBroadcast('beforeFullRender');
+      }
+    },
+
+    callEstablish: function(establishPromise) {
+      this.addPromise(establishPromise);
+      return FauxtonAPI.when(establishPromise);
+    },
+
+    renderAllViews: function(options, resp){
+      var routeObject = this,
+          renderView = _.bind(this.renderView, this, routeObject, options);
+
+      this.triggerBroadcast('afterEstablish');
+
+      var promises = _.map(routeObject.getViews(), renderView, this);
+      return FauxtonAPI.when(promises);
+    },
+    
+    renderView: function(routeObject, options, view, selector) {
+      var viewInfo = {
+        view: view, 
+        selector: selector,
+        masterLayout: options.masterLayout
+      };
+
+      var renderViewOnLayout = _.bind(this.renderViewOnLayout, this, viewInfo);
+
+      if(view.hasRendered) { 
+        this.triggerBroadcast('viewHasRendered', view, selector);
+        return;
+      }
+
+      this.triggerBroadcast('beforeRender', view, selector);
+      
+      return this.callEstablish(view.establish()).then(renderViewOnLayout, this.establishError);
+    },
+
+    renderViewOnLayout: function(viewInfo, resp, xhr){
+      var masterLayout = viewInfo.masterLayout;
+
+      masterLayout.setView(viewInfo.selector, viewInfo.view);
+      masterLayout.renderView(viewInfo.selector);
+
+      this.triggerBroadcast('afterRender', viewInfo.view, viewInfo.selector);
+    },
+
+    establishError: function(resp){
+      if (!resp || !resp.responseText) { return; }
+      FauxtonAPI.addNotification({
+            msg: 'An Error occurred' + JSON.parse(resp.responseText).reason,
+            type: 'error',
+            clear: true
+      });
+    },
+
+    renderComplete: function () {
+      // Track that we've done a full initial render
+      this.setRenderedState(true);
+      this.triggerBroadcast('renderComplete');
+    },
+
+    setRenderedState: function(bool){
+      this.renderedState = bool;
+    },
+    
+    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);
+    },
+
+    addPromise: function (promise) {
+      if (_.isEmpty(promise)) { return; }
+
+      if (!_.isArray(promise)) {
+        return this._promises.push(promise);
+      }
+
+      _.each(promise, function (p) {
+          this._promises.push(p);
+      }, this);
+    },
+
+    cleanup: function () {
+      this.removeViews();
+      this.rejectPromises();
+    },
+
+    rejectPromises: function () {
+      _.each(this._promises, function (promise) {
+        if (promise.state() === "resolved") { return; }
+        if (promise.abort) {
+          return promise.abort("Route change");
+        } 
+
+        promise.reject();
+      }, this);
+
+      this._promises = [];
+    },
+
+    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;
+    }
+
+  });
+  return RouteObject;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/router.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/router.js b/src/fauxton/app/core/router.js
new file mode 100644
index 0000000..cc1ca4f
--- /dev/null
+++ b/src/fauxton/app/core/router.js
@@ -0,0 +1,113 @@
+// 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([
+       "core/base",
+       "core/auth",
+       "backbone"
+],
+
+function(FauxtonAPI, Auth, Backbone) {
+
+  var beforeUnloads = {};
+
+  var Router = Backbone.Router.extend({
+    routes: {},
+
+    beforeUnload: function (name, fn) {
+      beforeUnloads[name] = fn;
+    },
+
+    removeBeforeUnload: function (name) {
+      delete beforeUnloads[name];
+    },
+
+    navigate: function (fragment, trigger) {
+      var continueNav  = true,
+          msg = _.find(_.map(beforeUnloads, function (fn) { return fn(); }), function (beforeReturn) {
+            if (beforeReturn) { return true; }
+          });
+
+      if (msg) {
+        continueNav = window.confirm(msg);
+      }
+
+      if (continueNav) {
+        Backbone.Router.prototype.navigate(fragment, trigger);
+      }
+    },
+
+    addModuleRouteObject: function(RouteObject) {
+      var that = this;
+      var masterLayout = FauxtonAPI.masterLayout,
+      routeUrls = RouteObject.prototype.getRouteUrls();
+
+      _.each(routeUrls, function(route) {
+        this.route(route, route.toString(), function() {
+          var args = Array.prototype.slice.call(arguments),
+          roles = RouteObject.prototype.getRouteRoles(route),
+          authPromise = FauxtonAPI.auth.checkAccess(roles);
+
+          authPromise.then(function () {
+            if (!that.activeRouteObject || !that.activeRouteObject.hasRoute(route)) {
+              if (that.activeRouteObject) {
+                that.activeRouteObject.cleanup();
+              }
+              that.activeRouteObject = new RouteObject(route, masterLayout, args);
+            }
+
+            var routeObject = that.activeRouteObject;
+            routeObject.routeCallback(route, args);
+            routeObject.renderWith(route, masterLayout, args);
+          }, function () {
+            FauxtonAPI.auth.authDeniedCb();
+          });
+
+        }); 
+      }, this);
+    },
+
+    setModuleRoutes: function(addons) {
+      _.each(addons, function(module) {
+        if (module){
+          module.initialize();
+          // This is pure routes the addon provides
+          if (module.RouteObjects) {
+            _.each(module.RouteObjects, this.addModuleRouteObject, this);
+          }
+        }
+      }, this);
+    },
+
+    initialize: function(addons) {
+      this.addons = addons;
+      this.auth = FauxtonAPI.auth = new Auth();
+      // NOTE: This must be below creation of the layout
+      // FauxtonAPI header links and others depend on existence of the layout
+      this.setModuleRoutes(addons);
+
+      $(FauxtonAPI.el).html(FauxtonAPI.masterLayout.el);
+      FauxtonAPI.masterLayout.render();
+    },
+
+    triggerRouteEvent: function(event, args) {
+      if (this.activeRouteObject) {
+        var eventArgs = [event].concat(args);
+        this.activeRouteObject.trigger.apply(this.activeRouteObject, eventArgs );
+        this.activeRouteObject.renderWith(eventArgs, FauxtonAPI.masterLayout, args);
+      }
+    }
+  });
+
+  return Router;
+});
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/96be583d/src/fauxton/app/core/tests/layoutSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/tests/layoutSpec.js b/src/fauxton/app/core/tests/layoutSpec.js
new file mode 100644
index 0000000..b58966b
--- /dev/null
+++ b/src/fauxton/app/core/tests/layoutSpec.js
@@ -0,0 +1,92 @@
+// 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([
+  'api',
+  'testUtils'
+], function (FauxtonAPI, testUtils) {
+  var assert = testUtils.assert;
+
+  describe("Faxuton Layout", function () {
+    var layout;
+
+    beforeEach(function () {
+      layout = new FauxtonAPI.Layout();
+    });
+
+    describe('#setTemplate', function () {
+
+      it("Should set template without prefix", function () {
+        layout.setTemplate('myTemplate');
+
+        assert.equal(layout.layout.template, 'templates/layouts/myTemplate');
+
+      });
+
+      it("Should set template with prefix", function () {
+        layout.setTemplate({name: 'myTemplate', prefix: 'myPrefix/'});
+
+        assert.equal(layout.layout.template, 'myPrefix/myTemplate');
+      });
+
+      it("Should remove old views", function () {
+        var view = {
+          remove: function () {}
+        };
+
+        layout.layoutViews = {
+          'selector': view
+        };
+
+        var mockRemove = sinon.spy(view, 'remove');
+        layout.setTemplate('myTemplate');
+        assert.ok(mockRemove.calledOnce);
+
+      });
+
+      it("Should render", function () {
+        var mockRender = sinon.spy(layout, 'render');
+
+        layout.setTemplate('myTemplate');
+
+        assert.ok(mockRender.calledOnce);
+
+      });
+
+    });
+
+    describe('#renderView', function () {
+
+      it('Should render existing view', function () {
+        var view = new Backbone.View();
+        var mockRender = sinon.spy(view, 'render');
+        layout.layoutViews = {
+          '#selector': view
+        };
+
+        var out = layout.renderView('#selector');
+
+        assert.ok(mockRender.calledOnce);
+      });
+
+      it('Should return false for non-existing view', function () {
+        var view = new Backbone.View();
+        layout.layoutViews = {
+          'selector': view
+        };
+
+        var out = layout.renderView('wrongSelector');
+        assert.notOk(out, 'No view found');
+      });
+    });
+
+  });
+});


[09/22] couchdb commit: updated refs/heads/paginate-api-options to 5d2a6f9

Posted by ga...@apache.org.
Add Delete_database_modal to the makefile list


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/7ca5f567
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7ca5f567
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7ca5f567

Branch: refs/heads/paginate-api-options
Commit: 7ca5f56721e4228e0e0fe4f0f47efc0b7ef83ed0
Parents: 77fbb4d
Author: suelockwood <de...@apache.org>
Authored: Wed Jan 29 10:43:12 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Wed Jan 29 10:43:12 2014 -0500

----------------------------------------------------------------------
 src/Makefile.am | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/7ca5f567/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 0f5c491..5380bd9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -157,6 +157,7 @@ FAUXTON_FILES = \
     fauxton/app/addons/documents/templates/all_docs_number.html \
     fauxton/app/addons/documents/templates/changes.html \
     fauxton/app/addons/documents/templates/ddoc_info.html \
+    fauxton/app/addons/documents/templates/delete_database_modal.html \
     fauxton/app/addons/documents/templates/design_doc_selector.html \
     fauxton/app/addons/documents/templates/doc.html \
     fauxton/app/addons/documents/templates/doc_field_editor.html \