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/03/03 17:58:13 UTC

[01/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Repository: couchdb
Updated Branches:
  refs/heads/paginate-api-options 5ab96a460 -> b63c79130 (forced update)


Fix documentation wording

The warning regarding the Response Object was unclear.


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

Branch: refs/heads/paginate-api-options
Commit: 08cf09fc0ae828e05c3ab01b11d561b4e717e0c4
Parents: dea6cef
Author: Andy Wenk <an...@apache.org>
Authored: Thu Feb 20 20:57:11 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Feb 20 20:57:11 2014 +0100

----------------------------------------------------------------------
 share/doc/src/json-structure.rst | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/08cf09fc/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index 4ab2f65..8eae7df 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -481,10 +481,10 @@ Response object
 +--------------------------------+---------------------------------------------+
 
 .. warning::
-   The ``body``, ``base64`` and ``json`` object keys are overlapping each other
-   where the last one wins. Since most realizations of key-value objects do
-   not preserve the key order or if they are mixed, confusing situations can
-   occure. Try to use only one of them.
+   The ``body``, ``base64`` and ``json`` object keys overlapp each other
+   where in the last one wins. Since most implementations of key-value objects do
+   not preserve the key order, confusing situations can emerge. The same applies,
+   when they are mixed. Try to use only one of them.
 
 .. note::
    Any custom property makes CouchDB raise an internal exception.


[08/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Remove editor reference to go to line 2 to stop browsers from crashing on people who have minified index functions.


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

Branch: refs/heads/paginate-api-options
Commit: e0b860d0f1e024c1fd691a643dc65a4aa5d302c1
Parents: 17a9763
Author: suelockwood <de...@apache.org>
Authored: Tue Feb 25 14:58:26 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Tue Feb 25 14:58:36 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/fauxton/components.js | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/e0b860d0/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 8b21916..39c213d 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -284,11 +284,11 @@ function(app, FauxtonAPI, ace, spin) {
     afterRender: function () {
       this.editor = ace.edit(this.editorId);
       this.setHeightToLineCount();
+      this.editor.getSession().setUseWorker(false);
       this.editor.setTheme("ace/theme/" + this.theme);
+
       this.editor.getSession().setMode("ace/mode/" + this.mode);
-      this.editor.getSession().setUseWrapMode(true);
       this.editor.setShowPrintMargin(false);
-      this.editor.gotoLine(2);
       this.addCommands();
 
       if (this.couchJSHINT) {
@@ -329,7 +329,8 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     getLines: function(){
-      return this.editor.getSession().getDocument().getLength();
+      return 5;
+     // return this.editor.getSession().getDocument().getLength();
     },
 
     addCommands: function () {


[10/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Revert "fix right hand side scrolling over navigation"

This reverts commit e389a8ba2a79da2669b536ca242b5dfdee4faba3.

This is the commit that broke modals.

Reverting it fixes COUCHDB-2086

Fixing the right hand content overlapping the left
hand navigation will require a bigger fix...
This sadly was not it...


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

Branch: refs/heads/paginate-api-options
Commit: 5989bb324a7998f931050b542f7e526309bdcc32
Parents: b4b6fe1
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Mon Feb 24 15:39:26 2014 -0500
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Wed Feb 26 08:49:43 2014 -0500

----------------------------------------------------------------------
 src/fauxton/assets/less/fauxton.less | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/5989bb32/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 4ec502a..82c65bd 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -490,9 +490,8 @@ table.databases {
   max-width: 1500px;
   .box-shadow(-6px 0 rgba(0, 0, 0, 0.1));
   border-left: 1px solid #999;
-  position: fixed;
+  position: absolute;
   left: @navWidth;
-  right: 0;
   margin-left: 0;
   padding-left: 0;
   padding-right: 0;


[05/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Move myself from THANKS to AUTHORS


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

Branch: refs/heads/paginate-api-options
Commit: 358901a50b83fd40fe8916b922e0737e96dbabeb
Parents: 8c86757
Author: Klaus Trainer <kl...@apache.org>
Authored: Sun Feb 23 19:11:51 2014 +0100
Committer: Klaus Trainer <kl...@apache.org>
Committed: Sun Feb 23 19:11:51 2014 +0100

----------------------------------------------------------------------
 AUTHORS   | 1 +
 THANKS.in | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/358901a5/AUTHORS
----------------------------------------------------------------------
diff --git a/AUTHORS b/AUTHORS
index 863e87b..dd0260a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -27,5 +27,6 @@ documentation or developing software. Some of these people are:
  * Garren Smith <ga...@apache.org>
  * Sue Lockwood <de...@apache.org>
  * Andy Wenk <an...@apache.org>
+ * Klaus Trainer <kl...@apache.org>
 
 For a list of other credits see the `THANKS` file.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/358901a5/THANKS.in
----------------------------------------------------------------------
diff --git a/THANKS.in b/THANKS.in
index 67678f6..bdfb3cd 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -64,7 +64,6 @@ suggesting improvements or submitting changes. Some of these people are:
  * David Rose <do...@gmail.com>
  * Lim Yue Chuan <sh...@gmail.com>
  * David Davis <xa...@xantus.org>
- * Klaus Trainer <kl...@web.de>
  * Juuso Väänänen <ju...@vaananen.org>
  * Jeff Zellner <je...@gmail.com>
  * Benjamin Young <by...@bigbluehat.com>


[09/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Accidentally committed debugging code. Return 5 ... (thanks kxepal!)


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

Branch: refs/heads/paginate-api-options
Commit: b4b6fe15366c9b5ffa535df12c3060554d2af960
Parents: e0b860d
Author: suelockwood <de...@apache.org>
Authored: Tue Feb 25 15:05:07 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Tue Feb 25 15:05:07 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/fauxton/components.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b4b6fe15/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 39c213d..71d78b1 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -329,8 +329,7 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     getLines: function(){
-      return 5;
-     // return this.editor.getSession().getDocument().getLength();
+     return this.editor.getSession().getDocument().getLength();
     },
 
     addCommands: function () {


[32/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Continued work


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

Branch: refs/heads/paginate-api-options
Commit: 0901b9bbd6ba43652d27210be1b809186777bd6c
Parents: 747e004
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Feb 21 06:06:03 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:43 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 2 +-
 src/fauxton/app/addons/documents/views.js     | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0901b9bb/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 c5a2e2c..69c9e1a 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -33,7 +33,7 @@ function(app, FauxtonAPI) {
         throw "Require docs to paginate";
       }
 
-      var params = _.reduce(['reduce', 'keys', 'endkey', 'descending', 'inclusive_end'], function (params, key) {
+      var params = _.reduce(['reduce', 'keys', 'key', 'endkey', 'descending', 'inclusive_end'], function (params, key) {
         if (_.has(currentParams, key)) {
           params[key] = currentParams[key]; 
         }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0901b9bb/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 5468948..f80d07e 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -457,7 +457,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         database: app.utils.safeURLName(this.collection.database.id),
         updateSeq: updateSeq,
         totalRows: totalRows,
-        numModels: this.collection.models.length + recordStart - 1,
         pageStart: pageStart,
         pageEnd: pageEnd
       };


[26/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Add new pagination algorithmn


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

Branch: refs/heads/paginate-api-options
Commit: f796b38ef2474bdfed5303a627136ee3ad8ea8d2
Parents: 4e10385
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Feb 19 15:23:52 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:42 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js   |  54 ++
 src/fauxton/app/addons/documents/routes.js      | 105 +--
 .../app/addons/documents/tests/resourcesSpec.js |  27 -
 src/fauxton/app/addons/documents/views.js       | 133 +--
 src/fauxton/app/addons/fauxton/base.js          |  14 +-
 src/fauxton/app/addons/fauxton/components.js    |  38 +-
 .../app/addons/fauxton/tests/paginateSpec.js    |  18 -
 src/fauxton/test/mocha/chai.js                  | 804 ++++++++++++++-----
 src/fauxton/test/test.config.underscore         |   4 +
 9 files changed, 765 insertions(+), 432 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/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 c2f9a70..6112bab 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -18,6 +18,51 @@ define([
 function(app, FauxtonAPI) {
   var Documents = FauxtonAPI.addon();
 
+  Documents.paginate = {
+    next: function (docs, currentParams, perPage, _isAllDocs) {
+      var params = {limit: perPage, skip: 1},
+          doc = _.last(docs),
+          docId = '',
+          lastId = '',
+          isView = !!!_isAllDocs,
+          key;
+
+      if (currentParams.keys) {
+        throw "Cannot paginate _all_docs with keys";
+      }
+
+      if (_.isUndefined(doc)) {
+        throw "Require docs to paginate";
+      }
+
+      params = _.reduce(['reduce', 'keys', 'endkey', 'descending', 'inclusive_end'], function (params, p) {
+        if (_.has(currentParams, p)) {
+          params[p] = currentParams[p]; 
+        }
+        return params;
+      }, params);
+
+      lastId = doc.id || doc._id;
+
+      if (isView) {
+        key = doc.key;
+        docId = lastId;
+      } else {
+        docId = key = lastId;
+      }
+
+      if (isView && !currentParams.keys) {
+        params.startkey_docid = docId; 
+        params.startkey = key;
+      } else if (currentParams.startkey) {
+        params.startkey = key;
+      } else {
+        params.startkey_docid = docId; 
+      }
+      return params;
+    }
+ };
+
   Documents.Doc = FauxtonAPI.Model.extend({
     idAttribute: "_id",
     documentation: function(){
@@ -274,6 +319,7 @@ function(app, FauxtonAPI) {
 
   Documents.AllDocs = FauxtonAPI.Collection.extend({
     model: Documents.Doc,
+    isAllDocs: true,
     documentation: function(){
       return "docs";
     },
@@ -330,6 +376,10 @@ function(app, FauxtonAPI) {
       this.params.limit = limit;
     },
 
+    updateParams: function (params) {
+      this.params = params;
+    },
+
     nextPage: function (num, lastId) {
       if (!lastId) {
         var doc = this.last();
@@ -478,6 +528,10 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
+    updateParams: function (params) {
+      this.params = params;
+    },
+
     updateLimit: function (limit) {
       if (this.params.startkey_docid && this.params.startkey) {
         //we are paginating so set limit + 1

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/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 0d143de..5ce66b1 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -160,8 +160,8 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     initialize: function (route, masterLayout, options) {
-      var docOptions = app.getParams();
-      docOptions.include_docs = true;
+      var docParams = app.getParams();
+      docParams.include_docs = true;
 
       this.databaseName = options[0];
 
@@ -186,23 +186,32 @@ function(app, FauxtonAPI, Documents, Databases) {
       return this.data.designDocs.fetch();
     },
 
+    createParams: function (options) {
+      var urlParams = app.getParams(options);
+      return {
+        urlParams: urlParams,
+        docParams: _.extend(_.clone(urlParams), {limit: 20})
+      };
+    },
+
+    /*
+    * docParams are the options collection uses to fetch from the server 
+    * urlParams are what are shown in the url and to the user
+    * They are not the same when paginating
+    */
     allDocs: function(databaseName, options) {
-      var docOptions = app.getParams(options),
-          docLimit;
+      var params = this.createParams(options),
+          urlParams = params.urlParams,
+          docParams = params.docParams;
 
       if (this.eventAllDocs) {
         this.eventAllDocs = false;
         return;
       }
 
-      if (docOptions.limit) {
-        docLimit = docOptions.limit;
-      }
-
-      docOptions.limit = 20; //default per page
-      this.data.database.buildAllDocs(docOptions);
+      this.data.database.buildAllDocs(docParams);
 
-      if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
+      if (docParams.startkey && docParams.startkey.indexOf('_design') > -1) {
         this.sidebar.setSelectedTab('design-docs');
       } else {
         this.sidebar.setSelectedTab('all-docs');
@@ -218,12 +227,14 @@ function(app, FauxtonAPI, Documents, Databases) {
       this.setView("#dashboard-upper-content", new Documents.Views.AllDocsLayout({
         database: this.data.database,
         collection: this.data.database.allDocs,
-        params: docOptions
+        params: urlParams,
+        docParams: docParams
       }));
 
       this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         collection: this.data.database.allDocs,
-        docLimit: parseInt(docLimit, 10)
+        docParams: docParams,
+        params: urlParams
       }));
 
       this.crumbs = [
@@ -313,43 +324,34 @@ function(app, FauxtonAPI, Documents, Databases) {
 
     updateAllDocsFromView: function (event) {
       var view = event.view,
-          docOptions = app.getParams(),
+          params = this.createParams(),
+          urlParams = params.urlParams,
+          docParams = params.docParams,
           ddoc = event.ddoc,
-          docLimit;
+          collection;
 
-      if (docOptions.limit) {
-        docLimit = docOptions.limit;
-      }
+      docParams.limit = this.documentsView.perPage();
 
-      docOptions.limit = this.documentsView.perPage();
-      this.documentsView && this.documentsView.remove();
+      this.documentsView.forceRender();
 
       if (event.allDocs) {
         this.eventAllDocs = true; // this is horrible. But I cannot get the trigger not to fire the route!
-        this.data.database.buildAllDocs(docOptions);
-        this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-          collection: this.data.database.allDocs,
-          docLimit: parseInt(docLimit, 10)
-        }));
-        return;
-      }
+        this.data.database.buildAllDocs(docParams);
+        collection = this.data.database.allDocs;
 
-      this.data.indexedDocs = new Documents.IndexCollection(null, {
-        database: this.data.database,
-        design: ddoc,
-        view: view,
-        params: app.getParams()
-      });
+      } else {
+        collection = this.data.indexedDocs = new Documents.IndexCollection(null, {
+          database: this.data.database,
+          design: ddoc,
+          view: view,
+          params: docParams
+        });
 
-      this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-        database: this.data.database,
-        collection: this.data.indexedDocs,
-        nestedView: Documents.Views.Row,
-        viewList: true,
-        docLimit: parseInt(docLimit, 10)
-      }));
+        this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
+      }
 
-      this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
+      this.documentsView.setCollection(collection);
+      this.documentsView.setParams(docParams, urlParams);
     },
 
     updateAllDocsFromPreview: function (event) {
@@ -373,24 +375,23 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     perPageChange: function (perPage) {
+      this.perPage = perPage;
       this.documentsView.collection.updateLimit(perPage);
       this.documentsView.forceRender();
     },
 
     paginate: function (options) {
+      var params = options.params,
+          urlParams = app.getParams(),
+          collection = this.documentsView.collection;
+
       this.documentsView.forceRender();
 
       if (options.direction === 'next') {
-        this.documentsView.collection.skipFirstItem = true;
-        this.documentsView.collection.nextPage(options.perPage);
-      } else {
-        if (options.params && options.params.startkey) {
-          this.documentsView.collection.skipFirstItem = true;
-        } else {
-          this.documentsView.collection.skipFirstItem = false;
-        }
-        this.documentsView.collection.previousPage(options.perPage, options.params);
+        params = Documents.paginate.next(collection.map(function (item) { return item.toJSON(); }), collection.params, options.perPage, !!collection.isAllDocs);
       }
+      
+      collection.updateParams(params);
     },
 
     reloadDesignDocs: function (event) {
@@ -421,9 +422,9 @@ function(app, FauxtonAPI, Documents, Databases) {
       this.databaseName = options[0];
       this.database = new Databases.Model({id: this.databaseName});
 
-      var docOptions = app.getParams();
+      var docParams = app.getParams();
 
-      this.database.buildChanges(docOptions);
+      this.database.buildChanges(docParams);
 
       this.setView("#tabs", new Documents.Views.Tabs({
         collection: this.designDocs,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/src/fauxton/app/addons/documents/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/tests/resourcesSpec.js b/src/fauxton/app/addons/documents/tests/resourcesSpec.js
index 380a4e4..62506e6 100644
--- a/src/fauxton/app/addons/documents/tests/resourcesSpec.js
+++ b/src/fauxton/app/addons/documents/tests/resourcesSpec.js
@@ -32,20 +32,6 @@ define([
 
     });
 
-    it('Should return urlNext', function () {
-      var url = collection.urlNextPage(20);
-
-      assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=21&reduce=false&startkey_docid=myId2&startkey=');
-
-    });
-
-    it('Should return urlPrevious', function () {
-      var url = collection.urlPreviousPage(20, {limit: 21, reduce: false,  startkey_docid: "myId1",startkey:"myId1"} );
-
-      assert.equal(url, 'database/databaseId/_design/myDoc/_view/?limit=20&reduce=false&startkey_docid=myId1&startkey=myId1');
-
-    });
-
   });
 
   describe('AllDocs', function () {
@@ -65,19 +51,6 @@ define([
 
     });
 
-    it('Should return urlNext', function () {
-      var url = collection.urlNextPage(20);
-
-      assert.equal(url, 'database/databaseId/_all_docs?limit=21&startkey_docid=%22myId2%22&startkey=%22myId2%22');
-
-    });
-
-     it('Should return urlPrevious', function () {
-      var url = collection.urlPreviousPage(20, {limit: 21, startkey_docid: "myId1",startkey:"myId1"} );
-      assert.equal(url, 'database/databaseId/_all_docs?limit=20&startkey_docid=myId1&startkey=myId1');
-    });
-
-
   });
 
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/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 c5ad1bb..dea0bc7 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -415,8 +415,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     initialize: function (options) {
       this.newView = options.newView || false;
       this.pagination = options.pagination;
+      _.bindAll(this);
       
-      this._perPage = 20;
+      this._perPage = options.perPageDefault || 20;
 
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
@@ -466,6 +467,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     perPage: function () {
       return this._perPage;
+    },
+
+    setCollection: function (collection) {
+      this.collection = collection;
     }
 
   });
@@ -484,20 +489,16 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     toggleQuery: function (event) {
       $('#dashboard-content').scrollTop(0);
-      console.log('hi');
       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,
-        eventer: this.eventer
       }));
     },
 
@@ -505,7 +506,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       if (this.params) {
         this.advancedOptions.updateFromParams(this.params);
       }
-
     },
 
     updateAllDocs: function (event, paramInfo) {
@@ -574,13 +574,16 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.rows = {};
       this.viewList = !! options.viewList;
       this.database = options.database;
+
       if (options.ddocInfo) {
         this.designDocs = options.ddocInfo.designDocs;
         this.ddocID = options.ddocInfo.id;
       }
       this.newView = options.newView || false;
-      this.docLimit = options.docLimit;
+      this.docParams = options.docParams;
+      this.params = options.params || {};
       this.expandDocs = true;
+      this.perPageDefault = options.perPageDefault || 20;
     },
 
     establish: function() {
@@ -666,13 +669,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.pagination = new Components.IndexPagination({
         collection: this.collection,
         scrollToSelector: '#dashboard-content',
-        docLimit: this.docLimit
+        docLimit: this.params.limit
       });
     },
 
     cleanup: function () {
-      this.pagination.remove();
-      this.allDocsNumber.remove();
+      this.pagination && this.pagination.remove();
+      this.allDocsNumber && this.allDocsNumber.remove();
       _.each(this.rows, function (row) {row.remove();});
     },
 
@@ -682,13 +685,16 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.addPagination();
       }
 
-      this.insertView('#documents-pagination', this.pagination);
+      if (!this.params.keys) { //cannot paginate with keys
+        this.insertView('#documents-pagination', this.pagination);
+      }
 
       if (!this.allDocsNumber) {
         this.allDocsNumber = new Views.AllDocsNumber({
           collection: this.collection,
           newView: this.newView,
-          pagination: this.pagination
+          pagination: this.pagination,
+          perPageDefault: this.perPageDefault
         });
       }
 
@@ -703,6 +709,21 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       }, this);
     },
 
+    setCollection: function (collection) {
+      this.collection = collection;
+      this.pagination.setCollection(collection);
+      this.allDocsNumber.setCollection(collection);
+    },
+
+    setParams: function (docParams, urlParams) {
+      this.docParams = docParams;
+      this.params = urlParams;
+
+      if (this.params.limit) {
+        this.pagination.docLimit = this.params.limit;
+      }
+    },
+
     afterRender: function(){
       prettyPrint();
     },
@@ -1007,73 +1028,6 @@ 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",
@@ -1084,7 +1038,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.viewName = options.viewName;
       this.updateViewFn = options.updateViewFn;
       this.previewFn = options.previewFn;
-      this.eventer = options.eventer;
 
       if (typeof(options.hasReduce) === 'undefined') {
         this.hasReduce = true;
@@ -1097,8 +1050,6 @@ 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: {
@@ -1108,24 +1059,6 @@ 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');

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/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 35babb5..a6e462a 100644
--- a/src/fauxton/app/addons/fauxton/base.js
+++ b/src/fauxton/app/addons/fauxton/base.js
@@ -45,7 +45,6 @@ function(app, FauxtonAPI, resizeColumns) {
     }
   });
 
-
   Fauxton.initialize = function () {
     app.footer = new Fauxton.Footer({el: "#footer-content"}),
     app.navBar = new Fauxton.NavBar();
@@ -93,7 +92,7 @@ function(app, FauxtonAPI, resizeColumns) {
     });
   };
 
-  Fauxton.Breadcrumbs = Backbone.View.extend({
+  Fauxton.Breadcrumbs = FauxtonAPI.View.extend({
     template: "templates/fauxton/breadcrumbs",
 
     serialize: function() {
@@ -114,10 +113,7 @@ function(app, FauxtonAPI, resizeColumns) {
     }
   });
 
-  // TODO: this View should extend from FauxtonApi.View.
-  // Chicken and egg problem, api.js extends fauxton/base.js.
-  // Need to sort the loading order.
-  Fauxton.Footer = Backbone.View.extend({
+  Fauxton.Footer = FauxtonAPI.View.extend({
     template: "templates/fauxton/footer",
 
     initialize: function() {
@@ -135,7 +131,7 @@ function(app, FauxtonAPI, resizeColumns) {
     }
   });
 
-  Fauxton.NavBar = Backbone.View.extend({
+  Fauxton.NavBar = FauxtonAPI.View.extend({
     className:"navbar",
     template: "templates/fauxton/nav_bar",
     // TODO: can we generate this list from the router?
@@ -260,7 +256,7 @@ function(app, FauxtonAPI, resizeColumns) {
     // TODO: ADD ACTIVE CLASS
   });
 
-  Fauxton.ApiBar = Backbone.View.extend({
+  Fauxton.ApiBar = FauxtonAPI.View.extend({
     template: "templates/fauxton/api_bar",
     endpoint: '_all_docs',
 
@@ -304,7 +300,7 @@ function(app, FauxtonAPI, resizeColumns) {
 
   });
 
-  Fauxton.Notification = Backbone.View.extend({
+  Fauxton.Notification = FauxtonAPI.View.extend({
     fadeTimer: 5000,
 
     initialize: function(options) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/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 f8032fe..a9f4ef4 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -71,14 +71,21 @@ function(app, FauxtonAPI, ace, spin) {
       this.nextUrlfn = options.nextUrlfn;
       this.scrollToSelector = options.scrollToSelector;
       _.bindAll(this);
+      this.docLimit = options.docLimit || 1000000;
+      this.perPage = 20;
+      this.setDefaults();
+    },
+
+    setDefaults: function () {
       this._pageNumber = [];
       this._pageStart = 1;
-      this.perPage = 20;
-      this.docLimit = options.docLimit || 1000000;
       this.paramsHistory = [];
+      this.enabled = true;
     },
 
     canShowPreviousfn: function () {
+      if (!this.enabled) { return this.enabled; }
+
       if (this._pageStart === 1) {
         return false;
       }
@@ -86,6 +93,8 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     canShowNextfn: function () {
+      if (!this.enabled) { return this.enabled; }
+
       if (this.collection.length < (this.perPage -1)) {
         return false;
       }
@@ -94,6 +103,10 @@ function(app, FauxtonAPI, ace, spin) {
         return false;
       }
 
+      if (this.collection.viewMeta && this.collection.viewMeta.total_rows <= this.pageStart() + this.perPage) {
+        return false;
+      }
+
       return true;
     },
 
@@ -103,11 +116,12 @@ function(app, FauxtonAPI, ace, spin) {
       if (!this.canShowPreviousfn()) { return; }
 
       this.decPageNumber();
+      var params = this.paramsHistory.pop();
 
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'previous',
        perPage: this.perPage,
-       params: this.paramsHistory.pop()
+       params: params
       });
     },
 
@@ -179,12 +193,22 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     pageEnd: function () {
-      if (this.collection.length < this.perPage) {
-        return this.page() + this.collection.length;
-      }
+      return this.page() + this.collection.length;
+    },
 
-      return this.page() + this.perPage;
+    disable: function () {
+      this.enabled = false;
+    },
+
+    enable: function () {
+      this.enabled = true;
+    },
+
+    setCollection: function (collection) {
+      this.collection = collection;
+      this.setDefaults();
     }
+
   });
 
   //TODO allow more of the typeahead options.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/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
index 535e26f..8fc409a 100644
--- a/src/fauxton/app/addons/fauxton/tests/paginateSpec.js
+++ b/src/fauxton/app/addons/fauxton/tests/paginateSpec.js
@@ -58,15 +58,6 @@ define([
         //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');
 
@@ -81,15 +72,6 @@ define([
 
     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');
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/src/fauxton/test/mocha/chai.js
----------------------------------------------------------------------
diff --git a/src/fauxton/test/mocha/chai.js b/src/fauxton/test/mocha/chai.js
index 2a67f98..9dd7b0a 100644
--- a/src/fauxton/test/mocha/chai.js
+++ b/src/fauxton/test/mocha/chai.js
@@ -27,10 +27,14 @@ function require(path, parent, orig) {
   // perform real require()
   // by invoking the module's
   // registered function
-  if (!module.exports) {
-    module.exports = {};
-    module.client = module.component = true;
-    module.call(this, module.exports, require.relative(resolved), module);
+  if (!module._resolving && !module.exports) {
+    var mod = {};
+    mod.exports = {};
+    mod.client = mod.component = true;
+    module._resolving = true;
+    module.call(this, mod.exports, require.relative(resolved), mod);
+    delete module._resolving;
+    module.exports = mod.exports;
   }
 
   return module.exports;
@@ -309,6 +313,411 @@ AssertionError.prototype.toJSON = function (stack) {
 };
 
 });
+require.register("chaijs-type-detect/lib/type.js", function(exports, require, module){
+/*!
+ * type-detect
+ * Copyright(c) 2013 jake luer <ja...@alogicalparadox.com>
+ * MIT Licensed
+ */
+
+/*!
+ * Primary Exports
+ */
+
+var exports = module.exports = getType;
+
+/*!
+ * Detectable javascript natives
+ */
+
+var natives = {
+    '[object Array]': 'array'
+  , '[object RegExp]': 'regexp'
+  , '[object Function]': 'function'
+  , '[object Arguments]': 'arguments'
+  , '[object Date]': 'date'
+};
+
+/**
+ * ### typeOf (obj)
+ *
+ * Use several different techniques to determine
+ * the type of object being tested.
+ *
+ *
+ * @param {Mixed} object
+ * @return {String} object type
+ * @api public
+ */
+
+function getType (obj) {
+  var str = Object.prototype.toString.call(obj);
+  if (natives[str]) return natives[str];
+  if (obj === null) return 'null';
+  if (obj === undefined) return 'undefined';
+  if (obj === Object(obj)) return 'object';
+  return typeof obj;
+}
+
+exports.Library = Library;
+
+/**
+ * ### Library
+ *
+ * Create a repository for custom type detection.
+ *
+ * ```js
+ * var lib = new type.Library;
+ * ```
+ *
+ */
+
+function Library () {
+  this.tests = {};
+}
+
+/**
+ * #### .of (obj)
+ *
+ * Expose replacement `typeof` detection to the library.
+ *
+ * ```js
+ * if ('string' === lib.of('hello world')) {
+ *   // ...
+ * }
+ * ```
+ *
+ * @param {Mixed} object to test
+ * @return {String} type
+ */
+
+Library.prototype.of = getType;
+
+/**
+ * #### .define (type, test)
+ *
+ * Add a test to for the `.test()` assertion.
+ *
+ * Can be defined as a regular expression:
+ *
+ * ```js
+ * lib.define('int', /^[0-9]+$/);
+ * ```
+ *
+ * ... or as a function:
+ *
+ * ```js
+ * lib.define('bln', function (obj) {
+ *   if ('boolean' === lib.of(obj)) return true;
+ *   var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
+ *   if ('string' === lib.of(obj)) obj = obj.toLowerCase();
+ *   return !! ~blns.indexOf(obj);
+ * });
+ * ```
+ *
+ * @param {String} type
+ * @param {RegExp|Function} test
+ * @api public
+ */
+
+Library.prototype.define = function (type, test) {
+  if (arguments.length === 1) return this.tests[type];
+  this.tests[type] = test;
+  return this;
+};
+
+/**
+ * #### .test (obj, test)
+ *
+ * Assert that an object is of type. Will first
+ * check natives, and if that does not pass it will
+ * use the user defined custom tests.
+ *
+ * ```js
+ * assert(lib.test('1', 'int'));
+ * assert(lib.test('yes', 'bln'));
+ * ```
+ *
+ * @param {Mixed} object
+ * @param {String} type
+ * @return {Boolean} result
+ * @api public
+ */
+
+Library.prototype.test = function (obj, type) {
+  if (type === getType(obj)) return true;
+  var test = this.tests[type];
+
+  if (test && 'regexp' === getType(test)) {
+    return test.test(obj);
+  } else if (test && 'function' === getType(test)) {
+    return test(obj);
+  } else {
+    throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
+  }
+};
+
+});
+require.register("chaijs-deep-eql/lib/eql.js", function(exports, require, module){
+/*!
+ * deep-eql
+ * Copyright(c) 2013 Jake Luer <ja...@alogicalparadox.com>
+ * MIT Licensed
+ */
+
+/*!
+ * Module dependencies
+ */
+
+var type = require('type-detect');
+
+/*!
+ * Buffer.isBuffer browser shim
+ */
+
+var Buffer;
+try { Buffer = require('buffer').Buffer; }
+catch(ex) {
+  Buffer = {};
+  Buffer.isBuffer = function() { return false; }
+}
+
+/*!
+ * Primary Export
+ */
+
+module.exports = deepEqual;
+
+/**
+ * Assert super-strict (egal) equality between
+ * two objects of any type.
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @param {Array} memoised (optional)
+ * @return {Boolean} equal match
+ */
+
+function deepEqual(a, b, m) {
+  if (sameValue(a, b)) {
+    return true;
+  } else if ('date' === type(a)) {
+    return dateEqual(a, b);
+  } else if ('regexp' === type(a)) {
+    return regexpEqual(a, b);
+  } else if (Buffer.isBuffer(a)) {
+    return bufferEqual(a, b);
+  } else if ('arguments' === type(a)) {
+    return argumentsEqual(a, b, m);
+  } else if (!typeEqual(a, b)) {
+    return false;
+  } else if (('object' !== type(a) && 'object' !== type(b))
+  && ('array' !== type(a) && 'array' !== type(b))) {
+    return sameValue(a, b);
+  } else {
+    return objectEqual(a, b, m);
+  }
+}
+
+/*!
+ * Strict (egal) equality test. Ensures that NaN always
+ * equals NaN and `-0` does not equal `+0`.
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @return {Boolean} equal match
+ */
+
+function sameValue(a, b) {
+  if (a === b) return a !== 0 || 1 / a === 1 / b;
+  return a !== a && b !== b;
+}
+
+/*!
+ * Compare the types of two given objects and
+ * return if they are equal. Note that an Array
+ * has a type of `array` (not `object`) and arguments
+ * have a type of `arguments` (not `array`/`object`).
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @return {Boolean} result
+ */
+
+function typeEqual(a, b) {
+  return type(a) === type(b);
+}
+
+/*!
+ * Compare two Date objects by asserting that
+ * the time values are equal using `saveValue`.
+ *
+ * @param {Date} a
+ * @param {Date} b
+ * @return {Boolean} result
+ */
+
+function dateEqual(a, b) {
+  if ('date' !== type(b)) return false;
+  return sameValue(a.getTime(), b.getTime());
+}
+
+/*!
+ * Compare two regular expressions by converting them
+ * to string and checking for `sameValue`.
+ *
+ * @param {RegExp} a
+ * @param {RegExp} b
+ * @return {Boolean} result
+ */
+
+function regexpEqual(a, b) {
+  if ('regexp' !== type(b)) return false;
+  return sameValue(a.toString(), b.toString());
+}
+
+/*!
+ * Assert deep equality of two `arguments` objects.
+ * Unfortunately, these must be sliced to arrays
+ * prior to test to ensure no bad behavior.
+ *
+ * @param {Arguments} a
+ * @param {Arguments} b
+ * @param {Array} memoize (optional)
+ * @return {Boolean} result
+ */
+
+function argumentsEqual(a, b, m) {
+  if ('arguments' !== type(b)) return false;
+  a = [].slice.call(a);
+  b = [].slice.call(b);
+  return deepEqual(a, b, m);
+}
+
+/*!
+ * Get enumerable properties of a given object.
+ *
+ * @param {Object} a
+ * @return {Array} property names
+ */
+
+function enumerable(a) {
+  var res = [];
+  for (var key in a) res.push(key);
+  return res;
+}
+
+/*!
+ * Simple equality for flat iterable objects
+ * such as Arrays or Node.js buffers.
+ *
+ * @param {Iterable} a
+ * @param {Iterable} b
+ * @return {Boolean} result
+ */
+
+function iterableEqual(a, b) {
+  if (a.length !==  b.length) return false;
+
+  var i = 0;
+  var match = true;
+
+  for (; i < a.length; i++) {
+    if (a[i] !== b[i]) {
+      match = false;
+      break;
+    }
+  }
+
+  return match;
+}
+
+/*!
+ * Extension to `iterableEqual` specifically
+ * for Node.js Buffers.
+ *
+ * @param {Buffer} a
+ * @param {Mixed} b
+ * @return {Boolean} result
+ */
+
+function bufferEqual(a, b) {
+  if (!Buffer.isBuffer(b)) return false;
+  return iterableEqual(a, b);
+}
+
+/*!
+ * Block for `objectEqual` ensuring non-existing
+ * values don't get in.
+ *
+ * @param {Mixed} object
+ * @return {Boolean} result
+ */
+
+function isValue(a) {
+  return a !== null && a !== undefined;
+}
+
+/*!
+ * Recursively check the equality of two objects.
+ * Once basic sameness has been established it will
+ * defer to `deepEqual` for each enumerable key
+ * in the object.
+ *
+ * @param {Mixed} a
+ * @param {Mixed} b
+ * @return {Boolean} result
+ */
+
+function objectEqual(a, b, m) {
+  if (!isValue(a) || !isValue(b)) {
+    return false;
+  }
+
+  if (a.prototype !== b.prototype) {
+    return false;
+  }
+
+  var i;
+  if (m) {
+    for (i = 0; i < m.length; i++) {
+      if ((m[i][0] === a && m[i][1] === b)
+      ||  (m[i][0] === b && m[i][1] === a)) {
+        return true;
+      }
+    }
+  } else {
+    m = [];
+  }
+
+  try {
+    var ka = enumerable(a);
+    var kb = enumerable(b);
+  } catch (ex) {
+    return false;
+  }
+
+  ka.sort();
+  kb.sort();
+
+  if (!iterableEqual(ka, kb)) {
+    return false;
+  }
+
+  m.push([ a, b ]);
+
+  var key;
+  for (i = ka.length - 1; i >= 0; i--) {
+    key = ka[i];
+    if (!deepEqual(a[key], b[key], m)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+});
 require.register("chai/index.js", function(exports, require, module){
 module.exports = require('./lib/chai');
 
@@ -316,7 +725,7 @@ module.exports = require('./lib/chai');
 require.register("chai/lib/chai.js", function(exports, require, module){
 /*!
  * chai
- * Copyright(c) 2011-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2011-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -327,7 +736,7 @@ var used = []
  * Chai version
  */
 
-exports.version = '1.7.2';
+exports.version = '1.8.1';
 
 /*!
  * Assertion Error
@@ -400,7 +809,7 @@ require.register("chai/lib/chai/assertion.js", function(exports, require, module
 /*!
  * chai
  * http://chaijs.com
- * Copyright(c) 2011-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2011-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -480,6 +889,10 @@ module.exports = function (_chai, util) {
     util.overwriteMethod(this.prototype, name, fn);
   };
 
+  Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
+    util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
+  };
+
   /*!
    * ### .assert(expression, message, negateMessage, expected, actual)
    *
@@ -533,7 +946,7 @@ require.register("chai/lib/chai/core/assertions.js", function(exports, require,
 /*!
  * chai
  * http://chaijs.com
- * Copyright(c) 2011-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2011-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -545,7 +958,7 @@ module.exports = function (chai, _) {
   /**
    * ### Language Chains
    *
-   * The following are provide as chainable getters to
+   * The following are provided as chainable getters to
    * improve the readability of your assertions. They
    * do not provide an testing capability unless they
    * have been overwritten by a plugin.
@@ -558,6 +971,7 @@ module.exports = function (chai, _) {
    * - is
    * - that
    * - and
+   * - has
    * - have
    * - with
    * - at
@@ -569,7 +983,7 @@ module.exports = function (chai, _) {
    */
 
   [ 'to', 'be', 'been'
-  , 'is', 'and', 'have'
+  , 'is', 'and', 'has', 'have'
   , 'with', 'that', 'at'
   , 'of', 'same' ].forEach(function (chain) {
     Assertion.addProperty(chain, function () {
@@ -677,9 +1091,21 @@ module.exports = function (chai, _) {
 
   function include (val, msg) {
     if (msg) flag(this, 'message', msg);
-    var obj = flag(this, 'object')
+    var obj = flag(this, 'object');
+
+    if (_.type(val) === 'object') {
+      if (!flag(this, 'negate')) {
+        for (var k in val) new Assertion(obj).property(k, val[k]);
+        return;
+      }
+      var subset = {}
+      for (var k in val) subset[k] = obj[k]
+      var expected = _.eql(subset, val);
+    } else {
+      var expected = obj && ~obj.indexOf(val)
+    }
     this.assert(
-        ~obj.indexOf(val)
+        expected
       , 'expected #{this} to include ' + _.inspect(val)
       , 'expected #{this} to not include ' + _.inspect(val));
   }
@@ -776,8 +1202,8 @@ module.exports = function (chai, _) {
    *
    * Asserts that the target is `undefined`.
    *
-   *      expect(undefined).to.be.undefined;
-   *      expect(null).to.not.be.undefined;
+   *     expect(undefined).to.be.undefined;
+   *     expect(null).to.not.be.undefined;
    *
    * @name undefined
    * @api public
@@ -1534,6 +1960,7 @@ module.exports = function (chai, _) {
    * @param {String|RegExp} expected error message
    * @param {String} message _optional_
    * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
+   * @returns error for chaining (null if no error)
    * @api public
    */
 
@@ -1558,7 +1985,10 @@ module.exports = function (chai, _) {
       constructor = null;
       errMsg = null;
     } else if (typeof constructor === 'function') {
-      name = (new constructor()).name;
+      name = constructor.prototype.name || constructor.name;
+      if (name === 'Error' && constructor !== Error) {
+        name = (new constructor()).name;
+      }
     } else {
       constructor = null;
     }
@@ -1572,12 +2002,14 @@ module.exports = function (chai, _) {
             err === desiredError
           , 'expected #{this} to throw #{exp} but #{act} was thrown'
           , 'expected #{this} to not throw #{exp}'
-          , desiredError
-          , err
+          , (desiredError instanceof Error ? desiredError.toString() : desiredError)
+          , (err instanceof Error ? err.toString() : err)
         );
 
+        flag(this, 'object', err);
         return this;
       }
+
       // next, check constructor
       if (constructor) {
         this.assert(
@@ -1585,11 +2017,15 @@ module.exports = function (chai, _) {
           , 'expected #{this} to throw #{exp} but #{act} was thrown'
           , 'expected #{this} to not throw #{exp} but #{act} was thrown'
           , name
-          , err
+          , (err instanceof Error ? err.toString() : err)
         );
 
-        if (!errMsg) return this;
+        if (!errMsg) {
+          flag(this, 'object', err);
+          return this;
+        }
       }
+
       // next, check message
       var message = 'object' === _.type(err) && "message" in err
         ? err.message
@@ -1604,6 +2040,7 @@ module.exports = function (chai, _) {
           , message
         );
 
+        flag(this, 'object', err);
         return this;
       } else if ((message != null) && errMsg && 'string' === typeof errMsg) {
         this.assert(
@@ -1614,6 +2051,7 @@ module.exports = function (chai, _) {
           , message
         );
 
+        flag(this, 'object', err);
         return this;
       } else {
         thrown = true;
@@ -1636,9 +2074,11 @@ module.exports = function (chai, _) {
         thrown === true
       , 'expected #{this} to throw ' + expectedThrown + actuallyGot
       , 'expected #{this} to not throw ' + expectedThrown + actuallyGot
-      , desiredError
-      , thrownError
+      , (desiredError instanceof Error ? desiredError.toString() : desiredError)
+      , (thrownError instanceof Error ? thrownError.toString() : thrownError)
     );
+
+    flag(this, 'object', thrownError);
   };
 
   Assertion.addMethod('throw', assertThrows);
@@ -1657,8 +2097,8 @@ module.exports = function (chai, _) {
    * To check if a constructor will respond to a static function,
    * set the `itself` flag.
    *
-   *    Klass.baz = function(){};
-   *    expect(Klass).itself.to.respondTo('baz');
+   *     Klass.baz = function(){};
+   *     expect(Klass).itself.to.respondTo('baz');
    *
    * @name respondTo
    * @param {String} method
@@ -1686,12 +2126,12 @@ module.exports = function (chai, _) {
    *
    * Sets the `itself` flag, later used by the `respondTo` assertion.
    *
-   *    function Foo() {}
-   *    Foo.bar = function() {}
-   *    Foo.prototype.baz = function() {}
+   *     function Foo() {}
+   *     Foo.bar = function() {}
+   *     Foo.prototype.baz = function() {}
    *
-   *    expect(Foo).itself.to.respondTo('bar');
-   *    expect(Foo).itself.not.to.respondTo('baz');
+   *     expect(Foo).itself.to.respondTo('bar');
+   *     expect(Foo).itself.not.to.respondTo('baz');
    *
    * @name itself
    * @api public
@@ -1805,7 +2245,7 @@ module.exports = function (chai, _) {
 require.register("chai/lib/chai/interface/assert.js", function(exports, require, module){
 /*!
  * chai
- * Copyright(c) 2011-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2011-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -1860,13 +2300,12 @@ module.exports = function (chai, util) {
    */
 
   assert.fail = function (actual, expected, message, operator) {
-    throw new chai.AssertionError({
+    message = message || 'assert.fail()';
+    throw new chai.AssertionError(message, {
         actual: actual
       , expected: expected
-      , message: message
       , operator: operator
-      , stackStartFunction: assert.fail
-    });
+    }, assert.fail);
   };
 
   /**
@@ -2462,19 +2901,7 @@ module.exports = function (chai, util) {
    */
 
   assert.include = function (exp, inc, msg) {
-    var obj = new Assertion(exp, msg);
-
-    if (Array.isArray(exp)) {
-      obj.to.include(inc);
-    } else if ('string' === typeof exp) {
-      obj.to.contain.string(inc);
-    } else {
-      throw new chai.AssertionError(
-          'expected an array or string'
-        , null
-        , assert.include
-      );
-    }
+    new Assertion(exp, msg).include(inc);
   };
 
   /**
@@ -2494,19 +2921,7 @@ module.exports = function (chai, util) {
    */
 
   assert.notInclude = function (exp, inc, msg) {
-    var obj = new Assertion(exp, msg);
-
-    if (Array.isArray(exp)) {
-      obj.to.not.include(inc);
-    } else if ('string' === typeof exp) {
-      obj.to.not.contain.string(inc);
-    } else {
-      throw new chai.AssertionError(
-          'expected an array or string'
-        , null
-        , assert.notInclude
-      );
-    }
+    new Assertion(exp, msg).not.include(inc);
   };
 
   /**
@@ -2750,7 +3165,8 @@ module.exports = function (chai, util) {
       errt = null;
     }
 
-    new Assertion(fn, msg).to.Throw(errt, errs);
+    var assertErr = new Assertion(fn, msg).to.Throw(errt, errs);
+    return flag(assertErr, 'object');
   };
 
   /**
@@ -2888,7 +3304,7 @@ module.exports = function (chai, util) {
 require.register("chai/lib/chai/interface/expect.js", function(exports, require, module){
 /*!
  * chai
- * Copyright(c) 2011-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2011-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -2903,7 +3319,7 @@ module.exports = function (chai, util) {
 require.register("chai/lib/chai/interface/should.js", function(exports, require, module){
 /*!
  * chai
- * Copyright(c) 2011-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2011-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -2982,7 +3398,7 @@ module.exports = function (chai, util) {
 require.register("chai/lib/chai/utils/addChainableMethod.js", function(exports, require, module){
 /*!
  * Chai - addChainingMethod utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3037,15 +3453,27 @@ var call  = Function.prototype.call,
  */
 
 module.exports = function (ctx, name, method, chainingBehavior) {
-  if (typeof chainingBehavior !== 'function')
+  if (typeof chainingBehavior !== 'function') {
     chainingBehavior = function () { };
+  }
+
+  var chainableBehavior = {
+      method: method
+    , chainingBehavior: chainingBehavior
+  };
+
+  // save the methods so we can overwrite them later, if we need to.
+  if (!ctx.__methods) {
+    ctx.__methods = {};
+  }
+  ctx.__methods[name] = chainableBehavior;
 
   Object.defineProperty(ctx, name,
     { get: function () {
-        chainingBehavior.call(this);
+        chainableBehavior.chainingBehavior.call(this);
 
         var assert = function () {
-          var result = method.apply(this, arguments);
+          var result = chainableBehavior.method.apply(this, arguments);
           return result === undefined ? this : result;
         };
 
@@ -3079,7 +3507,7 @@ module.exports = function (ctx, name, method, chainingBehavior) {
 require.register("chai/lib/chai/utils/addMethod.js", function(exports, require, module){
 /*!
  * Chai - addMethod utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3119,7 +3547,7 @@ module.exports = function (ctx, name, method) {
 require.register("chai/lib/chai/utils/addProperty.js", function(exports, require, module){
 /*!
  * Chai - addProperty utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3159,142 +3587,10 @@ module.exports = function (ctx, name, getter) {
 };
 
 });
-require.register("chai/lib/chai/utils/eql.js", function(exports, require, module){
-// This is (almost) directly from Node.js assert
-// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js
-
-module.exports = _deepEqual;
-
-var getEnumerableProperties = require('./getEnumerableProperties');
-
-// for the browser
-var Buffer;
-try {
-  Buffer = require('buffer').Buffer;
-} catch (ex) {
-  Buffer = {
-    isBuffer: function () { return false; }
-  };
-}
-
-function _deepEqual(actual, expected, memos) {
-
-  // 7.1. All identical values are equivalent, as determined by ===.
-  if (actual === expected) {
-    return true;
-
-  } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
-    if (actual.length != expected.length) return false;
-
-    for (var i = 0; i < actual.length; i++) {
-      if (actual[i] !== expected[i]) return false;
-    }
-
-    return true;
-
-  // 7.2. If the expected value is a Date object, the actual value is
-  // equivalent if it is also a Date object that refers to the same time.
-  } else if (expected instanceof Date) {
-    if (!(actual instanceof Date)) return false;
-    return actual.getTime() === expected.getTime();
-
-  // 7.3. Other pairs that do not both pass typeof value == 'object',
-  // equivalence is determined by ==.
-  } else if (typeof actual != 'object' && typeof expected != 'object') {
-    return actual === expected;
-
-  } else if (expected instanceof RegExp) {
-    if (!(actual instanceof RegExp)) return false;
-    return actual.toString() === expected.toString();
-
-  // 7.4. For all other Object pairs, including Array objects, equivalence is
-  // determined by having the same number of owned properties (as verified
-  // with Object.prototype.hasOwnProperty.call), the same set of keys
-  // (although not necessarily the same order), equivalent values for every
-  // corresponding key, and an identical 'prototype' property. Note: this
-  // accounts for both named and indexed properties on Arrays.
-  } else {
-    return objEquiv(actual, expected, memos);
-  }
-}
-
-function isUndefinedOrNull(value) {
-  return value === null || value === undefined;
-}
-
-function isArguments(object) {
-  return Object.prototype.toString.call(object) == '[object Arguments]';
-}
-
-function objEquiv(a, b, memos) {
-  if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
-    return false;
-
-  // an identical 'prototype' property.
-  if (a.prototype !== b.prototype) return false;
-
-  // check if we have already compared a and b
-  var i;
-  if (memos) {
-    for(i = 0; i < memos.length; i++) {
-      if ((memos[i][0] === a && memos[i][1] === b) ||
-          (memos[i][0] === b && memos[i][1] === a))
-        return true;
-    }
-  } else {
-    memos = [];
-  }
-
-  //~~~I've managed to break Object.keys through screwy arguments passing.
-  //   Converting to array solves the problem.
-  if (isArguments(a)) {
-    if (!isArguments(b)) {
-      return false;
-    }
-    a = pSlice.call(a);
-    b = pSlice.call(b);
-    return _deepEqual(a, b, memos);
-  }
-  try {
-    var ka = getEnumerableProperties(a),
-        kb = getEnumerableProperties(b),
-        key;
-  } catch (e) {//happens when one is a string literal and the other isn't
-    return false;
-  }
-
-  // having the same number of owned properties (keys incorporates
-  // hasOwnProperty)
-  if (ka.length != kb.length)
-    return false;
-
-  //the same set of keys (although not necessarily the same order),
-  ka.sort();
-  kb.sort();
-  //~~~cheap key test
-  for (i = ka.length - 1; i >= 0; i--) {
-    if (ka[i] != kb[i])
-      return false;
-  }
-
-  // remember objects we have compared to guard against circular references
-  memos.push([ a, b ]);
-
-  //equivalent values for every corresponding key, and
-  //~~~possibly expensive deep test
-  for (i = ka.length - 1; i >= 0; i--) {
-    key = ka[i];
-    if (!_deepEqual(a[key], b[key], memos)) return false;
-  }
-
-  return true;
-}
-
-});
 require.register("chai/lib/chai/utils/flag.js", function(exports, require, module){
 /*!
  * Chai - flag utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3329,7 +3625,7 @@ module.exports = function (obj, key, value) {
 require.register("chai/lib/chai/utils/getActual.js", function(exports, require, module){
 /*!
  * Chai - getActual utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3351,7 +3647,7 @@ module.exports = function (obj, args) {
 require.register("chai/lib/chai/utils/getEnumerableProperties.js", function(exports, require, module){
 /*!
  * Chai - getEnumerableProperties utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3379,7 +3675,7 @@ module.exports = function getEnumerableProperties(object) {
 require.register("chai/lib/chai/utils/getMessage.js", function(exports, require, module){
 /*!
  * Chai - message composition utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3431,7 +3727,7 @@ module.exports = function (obj, args) {
 require.register("chai/lib/chai/utils/getName.js", function(exports, require, module){
 /*!
  * Chai - getName utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3454,7 +3750,7 @@ module.exports = function (func) {
 require.register("chai/lib/chai/utils/getPathValue.js", function(exports, require, module){
 /*!
  * Chai - getPathValue utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * @see https://github.com/logicalparadox/filtr
  * MIT Licensed
  */
@@ -3559,7 +3855,7 @@ function _getPathValue (parsed, obj) {
 require.register("chai/lib/chai/utils/getProperties.js", function(exports, require, module){
 /*!
  * Chai - getProperties utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -3659,7 +3955,7 @@ exports.transferFlags = require('./transferFlags');
  * Deep equal utility
  */
 
-exports.eql = require('./eql');
+exports.eql = require('deep-eql');
 
 /*!
  * Deep path value
@@ -3703,6 +3999,12 @@ exports.overwriteMethod = require('./overwriteMethod');
 
 exports.addChainableMethod = require('./addChainableMethod');
 
+/*!
+ * Overwrite chainable method
+ */
+
+exports.overwriteChainableMethod = require('./overwriteChainableMethod');
+
 
 });
 require.register("chai/lib/chai/utils/inspect.js", function(exports, require, module){
@@ -4031,7 +4333,7 @@ function objectToString(o) {
 require.register("chai/lib/chai/utils/objDisplay.js", function(exports, require, module){
 /*!
  * Chai - flag utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -4082,7 +4384,7 @@ module.exports = function (obj) {
 require.register("chai/lib/chai/utils/overwriteMethod.js", function(exports, require, module){
 /*!
  * Chai - overwriteMethod utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -4136,7 +4438,7 @@ module.exports = function (ctx, name, method) {
 require.register("chai/lib/chai/utils/overwriteProperty.js", function(exports, require, module){
 /*!
  * Chai - overwriteProperty utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -4190,10 +4492,66 @@ module.exports = function (ctx, name, getter) {
 };
 
 });
+require.register("chai/lib/chai/utils/overwriteChainableMethod.js", function(exports, require, module){
+/*!
+ * Chai - overwriteChainableMethod utility
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
+ * MIT Licensed
+ */
+
+/**
+ * ### overwriteChainableMethod (ctx, name, fn)
+ *
+ * Overwites an already existing chainable method
+ * and provides access to the previous function or
+ * property.  Must return functions to be used for
+ * name.
+ *
+ *     utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',
+ *       function (_super) {
+ *       }
+ *     , function (_super) {
+ *       }
+ *     );
+ *
+ * Can also be accessed directly from `chai.Assertion`.
+ *
+ *     chai.Assertion.overwriteChainableMethod('foo', fn, fn);
+ *
+ * Then can be used as any other assertion.
+ *
+ *     expect(myFoo).to.have.length(3);
+ *     expect(myFoo).to.have.length.above(3);
+ *
+ * @param {Object} ctx object whose method / property is to be overwritten
+ * @param {String} name of method / property to overwrite
+ * @param {Function} method function that returns a function to be used for name
+ * @param {Function} chainingBehavior function that returns a function to be used for property
+ * @name overwriteChainableMethod
+ * @api public
+ */
+
+module.exports = function (ctx, name, method, chainingBehavior) {
+  var chainableBehavior = ctx.__methods[name];
+
+  var _chainingBehavior = chainableBehavior.chainingBehavior;
+  chainableBehavior.chainingBehavior = function () {
+    var result = chainingBehavior(_chainingBehavior).call(this);
+    return result === undefined ? this : result;
+  };
+
+  var _method = chainableBehavior.method;
+  chainableBehavior.method = function () {
+    var result = method(_method).apply(this, arguments);
+    return result === undefined ? this : result;
+  };
+};
+
+});
 require.register("chai/lib/chai/utils/test.js", function(exports, require, module){
 /*!
  * Chai - test utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -4222,7 +4580,7 @@ module.exports = function (obj, args) {
 require.register("chai/lib/chai/utils/transferFlags.js", function(exports, require, module){
 /*!
  * Chai - transferFlags utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -4269,7 +4627,7 @@ module.exports = function (assertion, object, includeAll) {
 require.register("chai/lib/chai/utils/type.js", function(exports, require, module){
 /*!
  * Chai - type utility
- * Copyright(c) 2012-2013 Jake Luer <ja...@alogicalparadox.com>
+ * Copyright(c) 2012-2014 Jake Luer <ja...@alogicalparadox.com>
  * MIT Licensed
  */
 
@@ -4314,17 +4672,25 @@ module.exports = function (obj) {
 };
 
 });
+
+
+
+
 require.alias("chaijs-assertion-error/index.js", "chai/deps/assertion-error/index.js");
 require.alias("chaijs-assertion-error/index.js", "chai/deps/assertion-error/index.js");
 require.alias("chaijs-assertion-error/index.js", "assertion-error/index.js");
 require.alias("chaijs-assertion-error/index.js", "chaijs-assertion-error/index.js");
-
-require.alias("chai/index.js", "chai/index.js");
-
-if (typeof exports == "object") {
+require.alias("chaijs-deep-eql/lib/eql.js", "chai/deps/deep-eql/lib/eql.js");
+require.alias("chaijs-deep-eql/lib/eql.js", "chai/deps/deep-eql/index.js");
+require.alias("chaijs-deep-eql/lib/eql.js", "deep-eql/index.js");
+require.alias("chaijs-type-detect/lib/type.js", "chaijs-deep-eql/deps/type-detect/lib/type.js");
+require.alias("chaijs-type-detect/lib/type.js", "chaijs-deep-eql/deps/type-detect/index.js");
+require.alias("chaijs-type-detect/lib/type.js", "chaijs-type-detect/index.js");
+require.alias("chaijs-deep-eql/lib/eql.js", "chaijs-deep-eql/index.js");
+require.alias("chai/index.js", "chai/index.js");if (typeof exports == "object") {
   module.exports = require("chai");
 } else if (typeof define == "function" && define.amd) {
-  define(function(){ return require("chai"); });
+  define([], function(){ return require("chai"); });
 } else {
   this["chai"] = require("chai");
 }})();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/f796b38e/src/fauxton/test/test.config.underscore
----------------------------------------------------------------------
diff --git a/src/fauxton/test/test.config.underscore b/src/fauxton/test/test.config.underscore
index 5cebe78..95494a4 100644
--- a/src/fauxton/test/test.config.underscore
+++ b/src/fauxton/test/test.config.underscore
@@ -7,7 +7,11 @@ require.config(
 require([
         "app",
         <% _.each(testFiles, function (test) {%>
+           <% if (test[0] === '.') { %>
            '../<%= test %>',
+           <% } else { %>
+           '<%= test %>',
+           <% }  %>
         <% }) %>
 ], function() {
   if (window.mochaPhantomJS) { mochaPhantomJS.run(); }


[23/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
remove api options


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

Branch: refs/heads/paginate-api-options
Commit: 69fa6c43e4cc23bf29b0aeeeb625bba20e4571ba
Parents: 2cf0f41
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Feb 11 08:49:47 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:41 2014 +0200

----------------------------------------------------------------------
 .../documents/templates/advanced_options.html   |  4 +--
 .../documents/templates/all_docs_layout.html    |  6 ++--
 .../addons/documents/templates/view_editor.html |  3 ++
 src/fauxton/app/addons/documents/views.js       | 30 +++++++++++---------
 4 files changed, 25 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/69fa6c43/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 8f592f4..fbf958e 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -71,9 +71,9 @@ the License.
             <option >20</option>
             <option>30</option>
             <option>50</option>
-            <option selected="selected">100</option>
+            <option >100</option>
             <option>500</option>
-            <option>None</option>
+            <option selected="selected">None</option>
           </select>
         </label>
         <div class="checkbox inline">  

http://git-wip-us.apache.org/repos/asf/couchdb/blob/69fa6c43/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 1bbe59d..2862e16 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_layout.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
@@ -11,9 +11,11 @@ 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/69fa6c43/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 36451e8..e08e36e 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -16,6 +16,9 @@ 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/69fa6c43/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 8fa426a..e9a0ee6 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -26,8 +26,6 @@ define([
        // Plugins
        "plugins/beautify",
        "plugins/prettify",
-
-
 ],
 
 function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColumns, beautify) {
@@ -498,18 +496,18 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         eventer: this.eventer
       }));
 
-      this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+      /*this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
         hasReduce: false,
         eventer:  this.eventer
-       }));
+       }));*/
 
-      this.$('#query').hide();
+      //this.$('#query').hide();
     },
 
     afterRender: function () {
       if (this.params) {
         this.advancedOptions.updateFromParams(this.params);
-        this.advancedOptionsMenu.updateFromParams(this.params);
+        //this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
     },
@@ -1143,9 +1141,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     queryParams: function () {
       var $form = this.$(".view-query-update");
       // Ignore params without a value
-      var params = _.filter($form.serializeArray(), function(param) {
-        return param.value;
-      });
+      var params = _.reduce($form.serializeArray(), function(params, param) {
+        if (!params.value) { return params; }
+        if (param.name === "limit" && param.value === 'None') { return params; }
+
+        params.push(param.value);
+        return params;
+      }, []);
 
       // Validate *key* params to ensure they're valid JSON
       var keyParams = ["key","keys","startkey","endkey"];
@@ -1467,8 +1469,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
             that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
           }
 
-          that.advancedOptionsMenu.setHasReduce(that.hasReduce());
-          that.advancedOptionsMenu.render();
+          //that.advancedOptionsMenu.setHasReduce(that.hasReduce());
+          //that.advancedOptionsMenu.render();
 
           FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
 
@@ -1711,10 +1713,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           eventer: this.eventer
         }));
 
-        this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+        /*this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
           hasReduce: this.hasReduce(),
           eventer:  this.eventer
-         }));
+         }));*/
       }
 
     },
@@ -1722,7 +1724,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     afterRender: function() {
       if (this.params && !this.newView) {
         this.advancedOptions.updateFromParams(this.params);
-        this.advancedOptionsMenu.updateFromParams(this.params);
+        //this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
       this.designDocSelector.updateDesignDoc();


[04/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Merge branch '1780-upgrade-password-hashes-on-authentication'


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

Branch: refs/heads/paginate-api-options
Commit: 8c867577cea2de7410eec33aa6358d1f20b5486d
Parents: 08cf09f 3488893
Author: Klaus Trainer <kl...@apache.org>
Authored: Sun Feb 23 18:59:35 2014 +0100
Committer: Klaus Trainer <kl...@apache.org>
Committed: Sun Feb 23 18:59:35 2014 +0100

----------------------------------------------------------------------
 share/www/script/couch_test_runner.js      |  4 +-
 share/www/script/test/auth_cache.js        | 12 +----
 share/www/script/test/cookie_auth.js       | 11 ++---
 share/www/script/test/users_db_security.js | 61 ++++++++++++++++++++++++-
 src/couchdb/couch_httpd_auth.erl           | 35 ++++++++++----
 5 files changed, 94 insertions(+), 29 deletions(-)
----------------------------------------------------------------------



[14/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Added comparitor to the configuration collection for alphabetical sorting


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

Branch: refs/heads/paginate-api-options
Commit: 929b3a08776674742353aab20d5f4adb331dd2a7
Parents: 0df722e
Author: suelockwood <de...@apache.org>
Authored: Thu Feb 27 16:15:51 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Fri Feb 28 12:42:49 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/config/resources.js | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/929b3a08/src/fauxton/app/addons/config/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/resources.js b/src/fauxton/app/addons/config/resources.js
index 14d2474..227e80d 100644
--- a/src/fauxton/app/addons/config/resources.js
+++ b/src/fauxton/app/addons/config/resources.js
@@ -51,6 +51,11 @@ function (app, FauxtonAPI) {
   Config.Collection = Backbone.Collection.extend({
     model: Config.Model,
     documentation: "config",
+    comparator: function (OptionModel) {
+      if (OptionModel.get("section")) {
+        return OptionModel.get("section");
+      }
+    },
     url: function () {
       return app.host + '/_config';
     },


[20/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

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/55b6ea67
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/55b6ea67
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/55b6ea67

Branch: refs/heads/paginate-api-options
Commit: 55b6ea67ac7e3b0180b216007c2018cd140e5703
Parents: fa33d4d
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Feb 3 12:10:08 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:41 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/55b6ea67/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 72cdb66..4028cb1 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/55b6ea67/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/55b6ea67/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/55b6ea67/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/55b6ea67/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 b1364df..36451e8 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -16,8 +16,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/55b6ea67/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 a33bd47..674b21b 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,
@@ -1697,27 +1698,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);
       }


[22/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Paginiation with no limit


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

Branch: refs/heads/paginate-api-options
Commit: 98b54724520bbebe46c09c8164690a42a3cda3d5
Parents: 69fa6c4
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Feb 11 17:24:02 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:41 2014 +0200

----------------------------------------------------------------------
 .../app/addons/databases/templates/item.html    |  2 +-
 src/fauxton/app/addons/databases/views.js       |  3 +-
 src/fauxton/app/addons/documents/routes.js      | 44 ++++++++++++---
 .../documents/templates/all_docs_number.html    | 22 ++++----
 .../app/addons/documents/templates/sidebar.html |  4 +-
 src/fauxton/app/addons/documents/views.js       | 58 +++++++++-----------
 src/fauxton/app/addons/fauxton/components.js    | 45 +++++++++------
 7 files changed, 104 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/98b54724/src/fauxton/app/addons/databases/templates/item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/templates/item.html b/src/fauxton/app/addons/databases/templates/item.html
index e2f8071..549f421 100644
--- a/src/fauxton/app/addons/databases/templates/item.html
+++ b/src/fauxton/app/addons/databases/templates/item.html
@@ -13,7 +13,7 @@ the License.
 -->
 
 <td>
-  <a href="#/database/<%=encoded%>/_all_docs?limit=<%=docLimit%>"><%= database.get("name") %></a>
+  <a href="#/database/<%=encoded%>/_all_docs"><%= database.get("name") %></a>
 </td>
 <td><%= database.status.humanSize() %></td>
 <td><%= database.status.numDocs() %></td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/98b54724/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 7f23d65..a56267f 100644
--- a/src/fauxton/app/addons/databases/views.js
+++ b/src/fauxton/app/addons/databases/views.js
@@ -31,8 +31,7 @@ function(app, Components, FauxtonAPI, Databases) {
       
       return {
         encoded: app.utils.safeURLName(this.model.get("name")),
-        database: this.model,
-        docLimit: Databases.DocLimit
+        database: this.model
       };
     }
   });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/98b54724/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 a0edc07..0d143de 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -187,8 +187,19 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     allDocs: function(databaseName, options) {
-      var docOptions = app.getParams(options);
+      var docOptions = app.getParams(options),
+          docLimit;
 
+      if (this.eventAllDocs) {
+        this.eventAllDocs = false;
+        return;
+      }
+
+      if (docOptions.limit) {
+        docLimit = docOptions.limit;
+      }
+
+      docOptions.limit = 20; //default per page
       this.data.database.buildAllDocs(docOptions);
 
       if (docOptions.startkey && docOptions.startkey.indexOf('_design') > -1) {
@@ -212,7 +223,7 @@ function(app, FauxtonAPI, Documents, Databases) {
 
       this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
         collection: this.data.database.allDocs,
-        docLimit: parseInt(docOptions.limit, 10)
+        docLimit: parseInt(docLimit, 10)
       }));
 
       this.crumbs = [
@@ -224,8 +235,14 @@ function(app, FauxtonAPI, Documents, Databases) {
 
     viewFn: function (databaseName, ddoc, view) {
       var params = app.getParams(),
-          decodeDdoc = decodeURIComponent(ddoc);
+          decodeDdoc = decodeURIComponent(ddoc),
+          docLimit;
+
+      if (params.limit) {
+        docLimit = params.limit;
+      } 
 
+      params.limit = 20; //default per page
       view = view.replace(/\?.*$/,'');
 
       this.data.indexedDocs = new Documents.IndexCollection(null, {
@@ -245,7 +262,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         model: this.data.database,
         ddocs: this.data.designDocs,
         viewName: view,
-        params: params,
+        params: _.extend(params, {limit: docLimit}),
         newView: false,
         database: this.data.database,
         ddocInfo: ddocInfo
@@ -258,7 +275,8 @@ function(app, FauxtonAPI, Documents, Databases) {
         collection: this.data.indexedDocs,
         nestedView: Documents.Views.Row,
         viewList: true,
-        ddocInfo: ddocInfo
+        ddocInfo: ddocInfo,
+        docLimit: parseInt(docLimit, 10)
       }));
 
       this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc) + '_' + app.utils.removeSpecialCharacters(view));
@@ -296,14 +314,22 @@ function(app, FauxtonAPI, Documents, Databases) {
     updateAllDocsFromView: function (event) {
       var view = event.view,
           docOptions = app.getParams(),
-          ddoc = event.ddoc;
+          ddoc = event.ddoc,
+          docLimit;
+
+      if (docOptions.limit) {
+        docLimit = docOptions.limit;
+      }
 
+      docOptions.limit = this.documentsView.perPage();
       this.documentsView && this.documentsView.remove();
 
       if (event.allDocs) {
+        this.eventAllDocs = true; // this is horrible. But I cannot get the trigger not to fire the route!
         this.data.database.buildAllDocs(docOptions);
         this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
-          collection: this.data.database.allDocs
+          collection: this.data.database.allDocs,
+          docLimit: parseInt(docLimit, 10)
         }));
         return;
       }
@@ -319,7 +345,8 @@ function(app, FauxtonAPI, Documents, Databases) {
         database: this.data.database,
         collection: this.data.indexedDocs,
         nestedView: Documents.Views.Row,
-        viewList: true
+        viewList: true,
+        docLimit: parseInt(docLimit, 10)
       }));
 
       this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
@@ -352,6 +379,7 @@ function(app, FauxtonAPI, Documents, Databases) {
 
     paginate: function (options) {
       this.documentsView.forceRender();
+
       if (options.direction === 'next') {
         this.documentsView.collection.skipFirstItem = true;
         this.documentsView.collection.nextPage(options.perPage);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/98b54724/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 fb9ea11..0461a4b 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_number.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_number.html
@@ -21,15 +21,15 @@ Showing <%=pageStart%> - <%= pageEnd %>
 <% } %>
 
 <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>
+  <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/98b54724/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 7358960..750cd30 100644
--- a/src/fauxton/app/addons/documents/templates/sidebar.html
+++ b/src/fauxton/app/addons/documents/templates/sidebar.html
@@ -55,8 +55,8 @@ the License.
 
   <nav>
     <ul class="nav nav-list">
-      <li class="active"><a id="all-docs" href="#<%= database.url('index') %>?limit=<%= docLimit %>" class="toggle-view"> All documents</a></li>
-      <li><a id="design-docs" href='#<%= database.url("index") %>?limit=<%= docLimit %>&startkey="_design"&endkey="_e"'  class="toggle-view"> All design docs</a></li>
+      <li class="active"><a id="all-docs" href="#<%= database.url('index') %>" class="toggle-view"> All documents</a></li>
+      <li><a id="design-docs" href='#<%= database.url("index") %>?startkey="_design"&endkey="_e"'  class="toggle-view"> All design docs</a></li>
     </ul>
     <ul class="nav nav-list views">
       <li class="nav-header">Secondary Indexes</li>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/98b54724/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 e9a0ee6..4f81016 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -416,8 +416,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.newView = options.newView || false;
       this.pagination = options.pagination;
       
-      this.perPage = 20;
-      
+      this._perPage = 20;
 
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
@@ -427,13 +426,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     updatePerPage: function (event) {
-      this.perPage = parseInt(this.$('#select-per-page :selected').val(), 10);
-      FauxtonAPI.triggerRouteEvent('perPageChange', this.perPage);
-      this.pagination.updatePerPage(this.perPage);
+      this._perPage = parseInt(this.$('#select-per-page :selected').val(), 10);
+      this.pagination.updatePerPage(this.perPage());
+      FauxtonAPI.triggerRouteEvent('perPageChange', this.pagination.documentsLeftToFetch());
     },
 
     afterRender: function () {
-      this.$('option[value="' + this.perPage + '"]').attr('selected', "selected");
+      this.$('option[value="' + this.perPage() + '"]').attr('selected', "selected");
     },
 
     serialize: function () {
@@ -463,6 +462,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         pageStart: pageStart,
         pageEnd: pageEnd
       };
+    },
+
+    perPage: function () {
+      return this._perPage;
     }
 
   });
@@ -495,19 +498,11 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         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);
       }
 
     },
@@ -540,9 +535,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       }
 
       var fragment = window.location.hash.replace(/\?.*$/, '');
-      fragment = fragment + '?' + $.param(params);
-      FauxtonAPI.navigate(fragment, {trigger: false});
 
+      if (!_.isEmpty(params)) {
+        fragment = fragment + '?' + $.param(params);
+      }
+
+      FauxtonAPI.navigate(fragment, {trigger: false});
       FauxtonAPI.triggerRouteEvent('updateAllDocs', {allDocs: true});
     },
 
@@ -706,6 +704,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     afterRender: function(){
       prettyPrint();
+    },
+
+    perPage: function () {
+      return this.allDocsNumber.perPage();
     }
   });
 
@@ -1142,10 +1144,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       var $form = this.$(".view-query-update");
       // Ignore params without a value
       var params = _.reduce($form.serializeArray(), function(params, param) {
-        if (!params.value) { return params; }
+        if (!param.value) { return params; }
         if (param.name === "limit" && param.value === 'None') { return params; }
 
-        params.push(param.value);
+        params.push(param);
         return params;
       }, []);
 
@@ -1209,6 +1211,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         switch (key) {
           case "limit":
           case "group_level":
+            if (!val) { return; }
             $form.find("select[name='"+key+"']").val(val);
           break;
           case "include_docs":
@@ -1469,9 +1472,6 @@ 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) {
@@ -1525,9 +1525,11 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       }
 
        var fragment = window.location.hash.replace(/\?.*$/, '');
-       fragment = fragment + '?' + $.param(params);
-       FauxtonAPI.navigate(fragment, {trigger: false});
+       if (!_.isEmpty(params)) {
+        fragment = fragment + '?' + $.param(params);
+       }
 
+       FauxtonAPI.navigate(fragment, {trigger: false});
        FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: this.ddocID, view: this.viewName});
     },
 
@@ -1712,11 +1714,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           hasReduce: this.hasReduce(),
           eventer: this.eventer
         }));
-
-        /*this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
-          hasReduce: this.hasReduce(),
-          eventer:  this.eventer
-         }));*/
       }
 
     },
@@ -1724,7 +1721,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     afterRender: function() {
       if (this.params && !this.newView) {
         this.advancedOptions.updateFromParams(this.params);
-        //this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
       this.designDocSelector.updateDesignDoc();
@@ -1736,7 +1732,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         this.$('#index-nav').parent().removeClass('active');
       }
 
-
     },
 
     showEditors: function () {
@@ -1827,11 +1822,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       return {
         changes_url: '#' + this.database.url('changes'),
         permissions_url: '#' + this.database.url('app') + '/permissions',
-        db_url: '#' + this.database.url('index') + '?limit=' + Databases.DocLimit,
+        db_url: '#' + this.database.url('index'),
         database: this.collection.database,
         database_url: '#' + this.database.url('app'),
         docLinks: docLinks,
-        docLimit: Databases.DocLimit,
         addLinks: addLinks,
         newLinks: newLinks,
         extensionList: extensionList > 0

http://git-wip-us.apache.org/repos/asf/couchdb/blob/98b54724/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 b31c623..f8032fe 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -71,15 +71,15 @@ function(app, FauxtonAPI, ace, spin) {
       this.nextUrlfn = options.nextUrlfn;
       this.scrollToSelector = options.scrollToSelector;
       _.bindAll(this);
-      this.pageNumber = 0;
+      this._pageNumber = [];
       this._pageStart = 1;
       this.perPage = 20;
-      this.docLimit = options.docLimit || 100;
+      this.docLimit = options.docLimit || 1000000;
       this.paramsHistory = [];
     },
 
     canShowPreviousfn: function () {
-      if (this.pageNumber <= 0) {
+      if (this._pageStart === 1) {
         return false;
       }
       return true;
@@ -102,8 +102,7 @@ function(app, FauxtonAPI, ace, spin) {
       event.stopPropagation();
       if (!this.canShowPreviousfn()) { return; }
 
-      this.pageNumber = this.pageNumber -1;
-      this.decPageStart();
+      this.decPageNumber();
 
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'previous',
@@ -112,25 +111,28 @@ function(app, FauxtonAPI, ace, spin) {
       });
     },
 
+    documentsLeftToFetch: function () {
+      var documentsLeftToFetch = this.docLimit - this.totalDocsViewed(),
+          limit = this.perPage;
+
+      if (documentsLeftToFetch < this.perPage ) {
+        limit = documentsLeftToFetch;
+      }
+
+      return limit;
+    },
+
     nextClicked: function (event) {
       event.preventDefault();
       event.stopPropagation();
       if (!this.canShowNextfn()) { return; }
 
       this.paramsHistory.push(_.clone(this.collection.params));
-      this.pageNumber = this.pageNumber + 1;
-      this.incPageStart();
-
-      var documentsLeftToFetch = this.docLimit - (this.pageNumber * this.perPage),
-          limit = this.perPage;
-
-      if (documentsLeftToFetch < this.perPage) {
-        limit = documentsLeftToFetch;
-      }
+      this.incPageNumber();
 
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'next',
-       perPage: limit
+       perPage: this.documentsLeftToFetch()
       });
 
     },
@@ -150,11 +152,19 @@ function(app, FauxtonAPI, ace, spin) {
       return this._pageStart - 1;
     },
 
-    incPageStart: function () {
+    incPageNumber: function () {
+      this._pageNumber.push({perPage: this.perPage});
       this._pageStart = this._pageStart + this.perPage;
     },
 
-    decPageStart: function () {
+    totalDocsViewed: function () {
+      return _.reduce(this._pageNumber, function (total, value) {
+        return total + value.perPage;
+      }, 0);
+    },
+
+    decPageNumber: function () {
+      this._pageNumber.pop();
       var val = this._pageStart - this.perPage;
       if (val < 1) {
         this._pageStart = 1;
@@ -175,7 +185,6 @@ function(app, FauxtonAPI, ace, spin) {
 
       return this.page() + this.perPage;
     }
-
   });
 
   //TODO allow more of the typeahead options.


[21/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
fix previous paginate


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

Branch: refs/heads/paginate-api-options
Commit: 2cf0f41324b5332e0b60690be669deec234c395e
Parents: 55b6ea6
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Feb 3 15:08:20 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:41 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 7 ++++++-
 src/fauxton/app/addons/documents/routes.js    | 8 ++++++--
 src/fauxton/app/addons/documents/views.js     | 1 -
 src/fauxton/app/addons/fauxton/components.js  | 8 ++++++--
 4 files changed, 18 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/2cf0f413/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 4028cb1..c2f9a70 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -281,7 +281,6 @@ function(app, FauxtonAPI) {
       this.database = options.database;
       this.params = _.clone(options.params);
       this.skipFirstItem = false;
-      this.totalRowsToPaginate = 100;
       this.on("remove",this.decrementTotalRows , this);
       this.perPageLimit = options.perPageLimit || 20;
 
@@ -426,6 +425,12 @@ function(app, FauxtonAPI) {
       this.view = options.view;
       this.design = options.design.replace('_design/','');
       this.skipFirstItem = false;
+      this.perPageLimit = options.perPageLimit || 20;
+
+      if (this.params.limit > this.perPageLimit) {
+        this.params.limit = this.perPageLimit; 
+      }
+
     },
 
     url: function(context) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2cf0f413/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 3ec640f..a0edc07 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -356,8 +356,12 @@ function(app, FauxtonAPI, Documents, Databases) {
         this.documentsView.collection.skipFirstItem = true;
         this.documentsView.collection.nextPage(options.perPage);
       } else {
-        this.documentsView.collection.skipFirstItem = false;
-        this.documentsView.collection.previousPage(options.perPage);
+        if (options.params && options.params.startkey) {
+          this.documentsView.collection.skipFirstItem = true;
+        } else {
+          this.documentsView.collection.skipFirstItem = false;
+        }
+        this.documentsView.collection.previousPage(options.perPage, options.params);
       }
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2cf0f413/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 674b21b..8fa426a 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -456,7 +456,6 @@ 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,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2cf0f413/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 c755428..b31c623 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -75,6 +75,7 @@ function(app, FauxtonAPI, ace, spin) {
       this._pageStart = 1;
       this.perPage = 20;
       this.docLimit = options.docLimit || 100;
+      this.paramsHistory = [];
     },
 
     canShowPreviousfn: function () {
@@ -106,7 +107,8 @@ function(app, FauxtonAPI, ace, spin) {
 
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'previous',
-       perPage: this.perPage
+       perPage: this.perPage,
+       params: this.paramsHistory.pop()
       });
     },
 
@@ -114,7 +116,8 @@ function(app, FauxtonAPI, ace, spin) {
       event.preventDefault();
       event.stopPropagation();
       if (!this.canShowNextfn()) { return; }
-      
+
+      this.paramsHistory.push(_.clone(this.collection.params));
       this.pageNumber = this.pageNumber + 1;
       this.incPageStart();
 
@@ -129,6 +132,7 @@ function(app, FauxtonAPI, ace, spin) {
        direction: 'next',
        perPage: limit
       });
+
     },
 
     serialize: function () {


[25/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
More pagination fixes


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

Branch: refs/heads/paginate-api-options
Commit: 77c06c28878015613c30f8c042aeaabdbb3423c8
Parents: 9848c76
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Feb 20 18:02:45 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:42 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 163 +++++++--------------
 src/fauxton/app/addons/documents/routes.js    |  26 +++-
 src/fauxton/app/addons/documents/views.js     |   3 -
 src/fauxton/app/addons/fauxton/components.js  |   4 -
 4 files changed, 70 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/77c06c28/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 d942cf6..c5a2e2c 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -19,10 +19,8 @@ function(app, FauxtonAPI) {
   var Documents = FauxtonAPI.addon();
 
   Documents.paginate = {
-    next: function (docs, currentParams, perPage, _isAllDocs) {
-      var params = {limit: perPage, skip: 1},
-          doc = _.last(docs),
-          docId = '',
+    calculate: function (doc, defaultParams, currentParams, _isAllDocs) {
+      var docId = '',
           lastId = '',
           isView = !!!_isAllDocs,
           key;
@@ -35,12 +33,12 @@ function(app, FauxtonAPI) {
         throw "Require docs to paginate";
       }
 
-      params = _.reduce(['reduce', 'keys', 'endkey', 'descending', 'inclusive_end'], function (params, key) {
+      var params = _.reduce(['reduce', 'keys', 'endkey', 'descending', 'inclusive_end'], function (params, key) {
         if (_.has(currentParams, key)) {
           params[key] = currentParams[key]; 
         }
         return params;
-      }, params);
+      }, defaultParams);
 
       lastId = doc.id || doc._id;
 
@@ -67,8 +65,22 @@ function(app, FauxtonAPI) {
       });
 
       return params;
+    },
+
+    next: function (docs, currentParams, perPage, _isAllDocs) {
+      var params = {limit: perPage, skip: 1},
+          doc = _.last(docs);
+          
+      return this.calculate(doc, params, currentParams, _isAllDocs);
+    },
+
+    previous: function (docs, currentParams, perPage, _isAllDocs) {
+      var params = {descending: true, limit: perPage, skip: 1},
+          doc = _.first(docs);
+
+      return this.calculate(doc, params, currentParams, _isAllDocs);
     }
- };
+  };
 
   Documents.Doc = FauxtonAPI.Model.extend({
     idAttribute: "_id",
@@ -333,7 +345,6 @@ function(app, FauxtonAPI) {
     initialize: function(_models, options) {
       this.database = options.database;
       this.params = _.clone(options.params);
-      this.skipFirstItem = false;
       this.on("remove",this.decrementTotalRows , this);
       this.perPageLimit = options.perPageLimit || 20;
 
@@ -342,9 +353,16 @@ function(app, FauxtonAPI) {
       }
     },
 
-    url: function(context) {
+    url: function(context, params) {
       var query = "";
-      if (this.params) {
+
+      if (params) {
+        if (!_.isEmpty(params)) {
+          query = "?" + $.param(params);
+        } else {
+          query = '';
+        }
+      } else if (this.params) {
         query = "?" + $.param(this.params);
       }
 
@@ -373,13 +391,6 @@ 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;
-        return;
-      }
-
       this.params.limit = limit;
     },
 
@@ -387,36 +398,6 @@ function(app, FauxtonAPI) {
       this.params = params;
     },
 
-    nextPage: function (num, lastId) {
-      if (!lastId) {
-        var doc = this.last();
-
-        if (doc) {
-          lastId = doc.id;
-        } else {
-          lastId = '';
-        }
-      }
-
-      this.params.startkey_docid = '"' + lastId + '"';
-      this.params.startkey = '"' + lastId + '"';
-      // when paginating forward, fetch 21 and don't show
-      // the first item as it was the last item in the previous list
-      this.params.limit = num + 1;
-      return this.url('app');
-    },
-
-    previousPage: function (num, params) {
-      if (params) { 
-        this.params = params;
-      } else {
-        this.params = {reduce: false};
-      }
-
-      this.params.limit = num;
-      return this.url('app'); 
-    },
-
     totalRows: function() {
       return this.viewMeta.total_rows || "unknown";
     },
@@ -432,18 +413,6 @@ function(app, FauxtonAPI) {
       return this.viewMeta.update_seq || false;
     },
 
-    recordStart: function () {
-      if (this.viewMeta.offset === 0) {
-        return 1;
-      }
-
-      if (this.skipFirstItem) {
-        return this.viewMeta.offset + 2;
-      }
-
-      return this.viewMeta.offset + 1;
-    },
-
     parse: function(resp) {
       var rows = resp.rows;
 
@@ -458,7 +427,7 @@ function(app, FauxtonAPI) {
       if (this.skipFirstItem) {
         rows = rows.splice(1);
       }
-      return _.map(rows, function(row) {
+      var mappedRows = _.map(rows, function(row) {
         return {
           _id: row.id,
           _rev: row.value.rev,
@@ -467,6 +436,12 @@ function(app, FauxtonAPI) {
           doc: row.doc || undefined
         };
       });
+
+      if (this.reverse) {
+        return _(mappedRows).reverse().value();
+      }
+
+      return mappedRows;
     }
   });
 
@@ -490,17 +465,15 @@ function(app, FauxtonAPI) {
 
     },
 
-    url: function(context) {
+    url: function(context, params) {
       var query = "";
-      if (this.params) {
-        /*this.params = _.reduce(['startkey', 'endkey', 'key', 'keys'], function (params, key) {
-          if (_.has(params, key)) {
-            params[key] = JSON.stringify(params[key]);
-          }
-
-          return params;
-        }, this.params);*/
-
+      if (params) {
+        if (!_.isEmpty(params)) {
+          query = "?" + $.param(params);
+        } else {
+          query = '';
+        }
+      } else if (this.params) {
         query = "?" + $.param(this.params);
       }
       
@@ -517,32 +490,6 @@ function(app, FauxtonAPI) {
       return url.join("/") + query;
     },
 
-    nextPage: function (num, lastId) {
-      if (!lastId) {
-        lastDoc = this.last();
-      }
-
-      var id = lastDoc.get("id");
-      if (id) {
-        this.params.startkey_docid = id;
-      }
-
-      this.params.startkey =  JSON.stringify(lastDoc.get('key'));
-      this.params.limit = num + 1;
-      return this.url('app');
-    },
-
-     previousPage: function (num, params) {
-      if (params) { 
-        this.params = params;
-      } else {
-        this.params = {reduce: false};
-      }
-
-      this.params.limit = num;
-      return this.url('app');
-    },
-
     updateParams: function (params) {
       this.params = params;
     },
@@ -557,18 +504,6 @@ function(app, FauxtonAPI) {
       this.params.limit = limit;
     },
 
-    recordStart: function () {
-      if (this.viewMeta.offset === 0) {
-        return 1;
-      }
-
-      if (this.skipFirstItem) {
-        return this.viewMeta.offset + 2;
-      }
-
-      return this.viewMeta.offset + 1;
-    },
-
     totalRows: function() {
       if (this.params.reduce) { return "unknown_reduce";}
 
@@ -610,7 +545,7 @@ function(app, FauxtonAPI) {
         offset: resp.offset,
         update_seq: resp.update_seq
       };
-      return _.map(rows, function(row) {
+      var mappedRows =  _.map(rows, function(row) {
         return {
           value: row.value,
           key: row.key,
@@ -618,6 +553,12 @@ function(app, FauxtonAPI) {
           id: row.id
         };
       });
+
+      if (this.reverse) {
+        return _(mappedRows).reverse().value();
+      }
+
+      return mappedRows;
     },
 
     buildAllDocs: function(){
@@ -720,10 +661,6 @@ function(app, FauxtonAPI) {
       return deferred;
     },
 
-    recordStart: function () {
-      return 1;
-    },
-
     totalRows: function() {
       return this.viewMeta.total_rows || "unknown";
     },

http://git-wip-us.apache.org/repos/asf/couchdb/blob/77c06c28/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 eeca7b7..ffe0b87 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -242,7 +242,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}
       ];
 
-      this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
+      this.apiUrl = [this.data.database.allDocs.url("apiurl", urlParams), this.data.database.allDocs.documentation() ];
     },
 
     viewFn: function (databaseName, ddoc, view) {
@@ -297,7 +297,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         ];
       };
 
-      this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
+      this.apiUrl = [this.data.indexedDocs.url("apiurl", urlParams), "docs"];
     },
 
     newViewEditor: function () {
@@ -345,11 +345,13 @@ function(app, FauxtonAPI, Documents, Databases) {
           params: docParams
         });
 
-        this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
       }
 
+
       this.documentsView.setCollection(collection);
       this.documentsView.setParams(docParams, urlParams);
+
+      this.apiUrl = [collection.url("apiurl", urlParams), "docs"];
     },
 
     updateAllDocsFromPreview: function (event) {
@@ -373,22 +375,34 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     perPageChange: function (perPage) {
+      console.log('pp', perPage);
       this.perPage = perPage;
       this.documentsView.collection.updateLimit(perPage);
       this.documentsView.forceRender();
     },
 
     paginate: function (options) {
-      var params = options.params,
+      var params = {},
           urlParams = app.getParams(),
           collection = this.documentsView.collection;
 
       this.documentsView.forceRender();
+      var rawCollection = collection.map(function (item) { return item.toJSON(); });
 
       if (options.direction === 'next') {
-          params = Documents.paginate.next(collection.map(function (item) { return item.toJSON(); }), collection.params, options.perPage, !!collection.isAllDocs);
+          collection.reverse = false;
+          params = Documents.paginate.next(rawCollection, 
+                                           collection.params,
+                                           options.perPage, 
+                                           !!collection.isAllDocs);
+      } else {
+          collection.reverse = true;
+          params = Documents.paginate.previous(rawCollection, 
+                                               collection.params, 
+                                               options.perPage, 
+                                               !!collection.isAllDocs);
       }
-      
+      params.limit = options.perPage;
       collection.updateParams(params);
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/77c06c28/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 dea0bc7..78a2c09 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -438,7 +438,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     serialize: function () {
        var totalRows = 0,
-          recordStart = 0,
           updateSeq = false,
           pageStart = 0,
           pageEnd = 20;
@@ -448,7 +447,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         updateSeq = this.collection.updateSeq();
       }
 
-      recordStart = this.collection.recordStart();
       if (this.pagination) {
         pageStart = this.pagination.pageStart();
         pageEnd =  this.pagination.pageEnd();
@@ -457,7 +455,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       return {
         database: app.utils.safeURLName(this.collection.database.id),
         updateSeq: updateSeq,
-        offset: recordStart,
         totalRows: totalRows,
         numModels: this.collection.models.length + recordStart - 1,
         pageStart: pageStart,

http://git-wip-us.apache.org/repos/asf/couchdb/blob/77c06c28/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 a9f4ef4..278831e 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -79,7 +79,6 @@ function(app, FauxtonAPI, ace, spin) {
     setDefaults: function () {
       this._pageNumber = [];
       this._pageStart = 1;
-      this.paramsHistory = [];
       this.enabled = true;
     },
 
@@ -116,12 +115,10 @@ function(app, FauxtonAPI, ace, spin) {
       if (!this.canShowPreviousfn()) { return; }
 
       this.decPageNumber();
-      var params = this.paramsHistory.pop();
 
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'previous',
        perPage: this.perPage,
-       params: params
       });
     },
 
@@ -141,7 +138,6 @@ function(app, FauxtonAPI, ace, spin) {
       event.stopPropagation();
       if (!this.canShowNextfn()) { return; }
 
-      this.paramsHistory.push(_.clone(this.collection.params));
       this.incPageNumber();
 
       FauxtonAPI.triggerRouteEvent('paginate', {


[29/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Invalid combination of query options causes the dashboard to hang


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

Branch: refs/heads/paginate-api-options
Commit: 747e0040b1c491db47b932c807aef1982f61f394
Parents: 77c06c2
Author: suelockwood <de...@apache.org>
Authored: Thu Feb 20 15:10:43 2014 -0500
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:42 2014 +0200

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


http://git-wip-us.apache.org/repos/asf/couchdb/blob/747e0040/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 78a2c09..5468948 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -439,6 +439,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     serialize: function () {
        var totalRows = 0,
           updateSeq = false,
+          recordStart = 0,
           pageStart = 0,
           pageEnd = 20;
 
@@ -586,10 +587,21 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     establish: function() {
       if (this.newView) { return null; }
 
-      return this.collection.fetch({reset: true}).fail(function() {
-        // TODO: handle error requests that slip through
-        // This should just throw a notification, not break the page
-        console.log("ERROR: ", arguments);
+      return this.collection.fetch({
+        reset: true,
+        success:  function() { },
+        error: function(model, xhr, options){
+          // TODO: handle error requests that slip through
+          // This should just throw a notification, not break the page
+          FauxtonAPI.addNotification({
+            msg: "Bad Request",
+            type: "error"
+          });
+
+          //now redirect back to alldocs
+          FauxtonAPI.navigate(model.database.url("index") + "?limit=100");
+          console.log("ERROR: ", arguments);
+        }
       });
     },
 


[34/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Code improvements to pagination


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

Branch: refs/heads/paginate-api-options
Commit: b63c79130e15c08810b1288495e0c0ba89358c3d
Parents: 7df61e7
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Mar 3 18:28:09 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 18:28:09 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js |  9 ++-
 src/fauxton/app/addons/documents/routes.js    | 68 +++++++++++++++-------
 src/fauxton/app/addons/documents/views.js     |  7 ++-
 src/fauxton/app/addons/fauxton/components.js  |  6 +-
 4 files changed, 57 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b63c7913/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 8bc52b0..73d9a0a 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -34,7 +34,6 @@ function(app, FauxtonAPI) {
         throw "Require docs to paginate";
       }
 
-
       // defaultParams should always override the user-specified parameters
       _.extend(currentParams, defaultParams);
 
@@ -51,12 +50,12 @@ function(app, FauxtonAPI) {
 
       // Set parameters to paginate
       if (isView) {
-        currentParams.startkey_docid = docId; 
+        currentParams.startkey_docid = docId;
         currentParams.startkey = key;
       } else if (currentParams.startkey) {
         currentParams.startkey = key;
       } else {
-        currentParams.startkey_docid = docId; 
+        currentParams.startkey_docid = docId;
       }
 
       return currentParams;
@@ -349,7 +348,7 @@ function(app, FauxtonAPI) {
       this.on("remove",this.decrementTotalRows , this);
       this.perPageLimit = options.perPageLimit || 20;
 
-      if (this.params.limit > this.perPageLimit) {
+      if (!this.params.limit) {
         this.params.limit = this.perPageLimit; 
       }
     },
@@ -454,7 +453,7 @@ function(app, FauxtonAPI) {
       this.skipFirstItem = false;
       this.perPageLimit = options.perPageLimit || 20;
 
-      if (this.params.limit > this.perPageLimit) {
+      if (!this.params.limit) {
         this.params.limit = this.perPageLimit; 
       }
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b63c7913/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 168807a..21e76e0 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -160,9 +160,6 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     initialize: function (route, masterLayout, options) {
-      var docParams = app.getParams();
-      docParams.include_docs = true;
-
       this.databaseName = options[0];
 
       this.data = {
@@ -171,9 +168,11 @@ function(app, FauxtonAPI, Documents, Databases) {
 
       this.data.designDocs = new Documents.AllDocs(null, {
         database: this.data.database,
-        params: {startkey: '"_design"',
+        params: {
+          startkey: '"_design"',
           endkey: '"_design1"',
-          include_docs: true}
+          include_docs: true
+        }
       });
 
       this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({
@@ -190,7 +189,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       var urlParams = app.getParams(options);
       return {
         urlParams: urlParams,
-        docParams: _.extend(_.clone(urlParams), {limit: 20})
+        docParams: _.extend(_.clone(urlParams), {limit: this.getDocPerPageLimit(urlParams, 20)})
       };
     },
 
@@ -209,7 +208,6 @@ function(app, FauxtonAPI, Documents, Databases) {
         return;
       }
 
-      docParams.limit = this.getDocPerPageLimit(urlParams, 20);
       this.data.database.buildAllDocs(docParams);
 
       if (docParams.startkey && docParams.startkey.indexOf('_design') > -1) {
@@ -243,6 +241,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       ];
 
       this.apiUrl = [this.data.database.allDocs.url("apiurl", urlParams), this.data.database.allDocs.documentation() ];
+      //reset the pagination history - the history is used for pagination.previous
       Documents.paginate.reset();
     },
 
@@ -252,7 +251,6 @@ function(app, FauxtonAPI, Documents, Databases) {
           docParams = params.docParams;
           decodeDdoc = decodeURIComponent(ddoc);
 
-      docParams.limit = this.getDocPerPageLimit(urlParams, 20);
       view = view.replace(/\?.*$/,'');
 
       this.data.indexedDocs = new Documents.IndexCollection(null, {
@@ -321,6 +319,8 @@ function(app, FauxtonAPI, Documents, Databases) {
           {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
         ];
       };
+
+      Documents.paginate.reset();
     },
 
     updateAllDocsFromView: function (event) {
@@ -349,7 +349,6 @@ function(app, FauxtonAPI, Documents, Databases) {
 
       }
 
-
       this.documentsView.setCollection(collection);
       this.documentsView.setParams(docParams, urlParams);
 
@@ -381,30 +380,33 @@ function(app, FauxtonAPI, Documents, Databases) {
       var params = app.getParams();
       this.perPage = perPage;
       this.documentsView.updatePerPage(perPage);
+      this.documentsView.forceRender();
       params.limit = perPage;
       this.documentsView.collection.params = params;
-      this.documentsView.forceRender();
+      this.setDocPerPageLimit(perPage);
     },
 
     paginate: function (options) {
       var params = {},
           urlParams = app.getParams(),
-          currentPage = options.currentPage,
           collection = this.documentsView.collection;
 
       this.documentsView.forceRender();
       var rawCollection = collection.map(function (item) { return item.toJSON(); });
-      collection.reverse = false;
 
-      _.each(collection.params, function (val, key) {
-        collection.params[key] = JSON.parse(val);
-      });
+      // this is really ugly. But we basically need to make sure that
+      // all parameters are in the correct state and have been parsed before we
+      // calculate how to paginate the collection
+      _.each(['startkey', 'endkey', 'key'], function (key) {
+        if (_.has(collection.params, key)) {
+          collection.params[key] = JSON.parse(collection.params[key]);
+        }
 
-      _.each(urlParams, function (val, key) {
-        urlParams[key] = JSON.parse(val);
+        if (_.has(urlParams, key)) {
+          urlParams[key] = JSON.parse(urlParams[key]);
+        }
       });
 
-
       if (options.direction === 'next') {
           params = Documents.paginate.next(rawCollection, 
                                            collection.params,
@@ -416,12 +418,19 @@ function(app, FauxtonAPI, Documents, Databases) {
                                                options.perPage, 
                                                !!collection.isAllDocs);
       }
+
+      // use the perPage sent from IndexPagination as it calculates how many
+      // docs to fetch for next page
       params.limit = options.perPage;
+
+      // again not pretty but need to make sure all the parameters can be correctly
+      // built into a query
       _.each(['startkey', 'endkey', 'key'], function (key) {
         if (_.has(params, key)) {
           params[key] = JSON.stringify(params[key]);
         }
-    });
+      });
+
       collection.updateParams(params);
     },
 
@@ -433,10 +442,27 @@ function(app, FauxtonAPI, Documents, Databases) {
       }
     },
 
+    setDocPerPageLimit: function (perPage) {
+      window.localStorage.setItem('fauxton:perpage', perPage);
+    },
+
 
     getDocPerPageLimit: function (urlParams, perPage) {
-      if (!urlParams.limit || urlParams.limit > perPage) {
-        return perPage;
+      var storedPerPage = perPage;
+
+      if (window.localStorage) {
+        storedPerPage = window.localStorage.getItem('fauxton:perpage');
+
+        if (!storedPerPage) {
+          this.setDocPerPageLimit(perPage);
+          storedPerPage = perPage;
+        } else {
+          storedPerPage = parseInt(storedPerPage, 10);
+        }
+      } 
+
+      if (!urlParams.limit || urlParams.limit > storedPerPage) {
+        return storedPerPage;
       } else {
         return urlParams.limit;
       }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b63c7913/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 1d07dae..f828d71 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -418,7 +418,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       _.bindAll(this);
       
       this._perPage = options.perPageDefault || 20;
-
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
 
@@ -579,7 +578,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.docParams = options.docParams;
       this.params = options.params || {};
       this.expandDocs = true;
-      this.perPageDefault = options.perPageDefault || 20;
+      this.perPageDefault = this.docParams.limit || 20;
     },
 
     establish: function() {
@@ -676,7 +675,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.pagination = new Components.IndexPagination({
         collection: this.collection,
         scrollToSelector: '#dashboard-content',
-        docLimit: this.params.limit
+        docLimit: this.params.limit,
+        perPage: this.perPageDefault
       });
     },
 
@@ -725,6 +725,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     setParams: function (docParams, urlParams) {
       this.docParams = docParams;
       this.params = urlParams;
+      this.perPageDefault = this.docParams.limit;
 
       if (this.params.limit) {
         this.pagination.docLimit = this.params.limit;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b63c7913/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 1174193..7dcf2d7 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -72,7 +72,7 @@ function(app, FauxtonAPI, ace, spin) {
       this.scrollToSelector = options.scrollToSelector;
       _.bindAll(this);
       this.docLimit = options.docLimit || 1000000;
-      this.perPage = 20;
+      this.perPage = options.perPage || 20;
       this.setDefaults();
     },
 
@@ -84,9 +84,7 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     canShowPreviousfn: function () {
-      if (!this.enabled) { return this.enabled; }
-
-      if (this._pageStart === 1) {
+      if (this._pageStart === 1 || !this.enabled) {
         return false;
       }
       return true;


[02/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Remove client-side password crypto from JS tests

This removes client-side password crypto from the JavaScript tests.

In some JavaScript tests, it has been assumed that SHA-1 is used for the
password hash in user docs.  Those tests should, however, not rely on
implementation details of the user authentication hash function, as it
isn't the goal of those tests to check these.  Furthermore, this causes
problems when a password scheme is changed, or a new one is introduced.


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

Branch: refs/heads/paginate-api-options
Commit: 45e17e5fbb3c5364e7f8d0e6bb4d79e2e291ecfa
Parents: 08cf09f
Author: Klaus Trainer <kl...@posteo.de>
Authored: Wed Feb 19 21:30:53 2014 +0100
Committer: Klaus Trainer <kl...@apache.org>
Committed: Sun Feb 23 18:59:21 2014 +0100

----------------------------------------------------------------------
 share/www/script/couch_test_runner.js |  4 +---
 share/www/script/test/auth_cache.js   | 12 ++----------
 share/www/script/test/cookie_auth.js  | 11 +++++------
 3 files changed, 8 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/45e17e5f/share/www/script/couch_test_runner.js
----------------------------------------------------------------------
diff --git a/share/www/script/couch_test_runner.js b/share/www/script/couch_test_runner.js
index c04e6b1..7f435bf 100644
--- a/share/www/script/couch_test_runner.js
+++ b/share/www/script/couch_test_runner.js
@@ -460,9 +460,7 @@ CouchDB.user_prefix = "org.couchdb.user:";
 CouchDB.prepareUserDoc = function(user_doc, new_password) {
   user_doc._id = user_doc._id || CouchDB.user_prefix + user_doc.name;
   if (new_password) {
-    // handle the password crypto
-    user_doc.salt = CouchDB.newUuids(1)[0];
-    user_doc.password_sha = hex_sha1(new_password + user_doc.salt);
+    user_doc.password = new_password;
   }
   user_doc.type = "user";
   if (!user_doc.roles) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/45e17e5f/share/www/script/test/auth_cache.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/auth_cache.js b/share/www/script/test/auth_cache.js
index 57e6a8d..2229c20 100644
--- a/share/www/script/test/auth_cache.js
+++ b/share/www/script/test/auth_cache.js
@@ -184,11 +184,7 @@ couchTests.auth_cache = function(debug) {
     hits_before = hits_after;
     misses_before = misses_after;
 
-    var new_salt = CouchDB.newUuids(1)[0];
-    var new_passwd = hex_sha1("foobar" + new_salt);
-    fdmanana.salt = new_salt;
-    fdmanana.password_sha = new_passwd;
-
+    fdmanana.password = "foobar";
     T(authDb.save(fdmanana).ok);
 
     // cache was refreshed
@@ -206,11 +202,7 @@ couchTests.auth_cache = function(debug) {
     misses_before = misses_after;
 
     // and yet another update
-    new_salt = CouchDB.newUuids(1)[0];
-    new_passwd = hex_sha1("javascript" + new_salt);
-    fdmanana.salt = new_salt;
-    fdmanana.password_sha = new_passwd;
-
+    fdmanana.password = "javascript";
     T(authDb.save(fdmanana).ok);
 
     // cache was refreshed

http://git-wip-us.apache.org/repos/asf/couchdb/blob/45e17e5f/share/www/script/test/cookie_auth.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/cookie_auth.js b/share/www/script/test/cookie_auth.js
index 40b633b..9b4bd64 100644
--- a/share/www/script/test/cookie_auth.js
+++ b/share/www/script/test/cookie_auth.js
@@ -115,7 +115,7 @@ couchTests.cookie_auth = function(debug) {
 
       // we can't create docs with malformed ids
       var badIdDoc = CouchDB.prepareUserDoc({
-        name: "foo"
+        name: "w00x"
       }, "bar");
 
       badIdDoc._id = "org.apache.couchdb:w00x";
@@ -153,8 +153,8 @@ couchTests.cookie_auth = function(debug) {
         usersDb.deleteDoc(jchrisUserDoc);
         T(false && "Can't delete other users docs. Should have thrown an error.");
       } catch (e) {
-        TEquals("forbidden", e.error);
-        TEquals(403, usersDb.last_req.status);
+        TEquals("not_found", e.error);
+        TEquals(404, usersDb.last_req.status);
       }
 
       // TODO should login() throw an exception here?
@@ -197,8 +197,8 @@ couchTests.cookie_auth = function(debug) {
         usersDb.save(jasonUserDoc);
         T(false && "Can't update someone else's user doc. Should have thrown an error.");
       } catch (e) {
-        T(e.error == "forbidden");
-        T(usersDb.last_req.status == 403);
+        T(e.error == "not_found");
+        T(usersDb.last_req.status == 404);
       }
 
       // test that you can't edit roles unless you are admin
@@ -272,7 +272,6 @@ couchTests.cookie_auth = function(debug) {
 
   var usersDb = new CouchDB("test_suite_users", {"X-Couch-Full-Commit":"false"});
   usersDb.deleteDb();
-  usersDb.createDb();
 
   run_on_modified_server(
     [


[28/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
More pagination improvements


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

Branch: refs/heads/paginate-api-options
Commit: 0beb91caeb1733d07f920a329ecbe3bb07f55187
Parents: f796b38
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Feb 19 16:47:30 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:42 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 13 ++++++++
 src/fauxton/app/addons/documents/routes.js    | 35 +++++++++++++---------
 2 files changed, 34 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0beb91ca/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 6112bab..6f6ed1c 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -26,6 +26,10 @@ function(app, FauxtonAPI) {
           lastId = '',
           isView = !!!_isAllDocs,
           key;
+      
+      _.each(doc, function (value, key) {
+        doc[key] = JSON.stringify(doc[key]);
+      });
 
       if (currentParams.keys) {
         throw "Cannot paginate _all_docs with keys";
@@ -45,6 +49,7 @@ function(app, FauxtonAPI) {
       lastId = doc.id || doc._id;
 
       if (isView) {
+        console.log(doc.key, doc, lastId);
         key = doc.key;
         docId = lastId;
       } else {
@@ -486,6 +491,14 @@ function(app, FauxtonAPI) {
     url: function(context) {
       var query = "";
       if (this.params) {
+        /*this.params = _.reduce(['startkey', 'endkey', 'key', 'keys'], function (params, key) {
+          if (_.has(params, key)) {
+            params[key] = JSON.stringify(params[key]);
+          }
+
+          return params;
+        }, this.params);*/
+
         query = "?" + $.param(this.params);
       }
       

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0beb91ca/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 5ce66b1..eeca7b7 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -209,6 +209,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         return;
       }
 
+      docParams.limit = this.getDocPerPageLimit(urlParams, 20);
       this.data.database.buildAllDocs(docParams);
 
       if (docParams.startkey && docParams.startkey.indexOf('_design') > -1) {
@@ -245,22 +246,19 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     viewFn: function (databaseName, ddoc, view) {
-      var params = app.getParams(),
-          decodeDdoc = decodeURIComponent(ddoc),
-          docLimit;
-
-      if (params.limit) {
-        docLimit = params.limit;
-      } 
+      var params = this.createParams(),
+          urlParams = params.urlParams,
+          docParams = params.docParams;
+          decodeDdoc = decodeURIComponent(ddoc);
 
-      params.limit = 20; //default per page
+      docParams.limit = this.getDocPerPageLimit(urlParams, 20);
       view = view.replace(/\?.*$/,'');
 
       this.data.indexedDocs = new Documents.IndexCollection(null, {
         database: this.data.database,
         design: decodeDdoc,
         view: view,
-        params: params
+        params: docParams
       });
 
       var ddocInfo = {
@@ -273,7 +271,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         model: this.data.database,
         ddocs: this.data.designDocs,
         viewName: view,
-        params: _.extend(params, {limit: docLimit}),
+        params: urlParams,
         newView: false,
         database: this.data.database,
         ddocInfo: ddocInfo
@@ -287,7 +285,8 @@ function(app, FauxtonAPI, Documents, Databases) {
         nestedView: Documents.Views.Row,
         viewList: true,
         ddocInfo: ddocInfo,
-        docLimit: parseInt(docLimit, 10)
+        docParams: docParams,
+        params: urlParams
       }));
 
       this.sidebar.setSelectedTab(app.utils.removeSpecialCharacters(ddoc) + '_' + app.utils.removeSpecialCharacters(view));
@@ -330,8 +329,7 @@ function(app, FauxtonAPI, Documents, Databases) {
           ddoc = event.ddoc,
           collection;
 
-      docParams.limit = this.documentsView.perPage();
-
+      docParams.limit = this.getDocPerPageLimit(urlParams, this.documentsView.perPage());
       this.documentsView.forceRender();
 
       if (event.allDocs) {
@@ -388,7 +386,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       this.documentsView.forceRender();
 
       if (options.direction === 'next') {
-        params = Documents.paginate.next(collection.map(function (item) { return item.toJSON(); }), collection.params, options.perPage, !!collection.isAllDocs);
+          params = Documents.paginate.next(collection.map(function (item) { return item.toJSON(); }), collection.params, options.perPage, !!collection.isAllDocs);
       }
       
       collection.updateParams(params);
@@ -400,6 +398,15 @@ function(app, FauxtonAPI, Documents, Databases) {
       if (event && event.selectedTab) {
         this.sidebar.setSelectedTab(event.selectedTab);
       }
+    },
+
+
+    getDocPerPageLimit: function (urlParams, perPage) {
+      if (!urlParams.limit || urlParams.limit > perPage) {
+        return perPage;
+      } else {
+        return urlParams.limit;
+      }
     }
 
   });


[31/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Improvements around parameter parsing


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

Branch: refs/heads/paginate-api-options
Commit: 8a27510e0ca8b3a9964df1232697a231c4d799af
Parents: 0901b9b
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Feb 21 15:50:24 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:43 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 34 +++++++++-------------
 src/fauxton/app/addons/documents/routes.js    | 23 +++++++++++++--
 src/fauxton/app/addons/documents/views.js     |  9 +++++-
 src/fauxton/app/addons/fauxton/components.js  | 18 ++++++++----
 4 files changed, 54 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/8a27510e/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 69c9e1a..fd1a558 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -26,22 +26,21 @@ function(app, FauxtonAPI) {
           key;
 
       if (currentParams.keys) {
-        throw "Cannot paginate _all_docs with keys";
+        throw "Cannot paginate when keys is specfied";
       }
 
       if (_.isUndefined(doc)) {
         throw "Require docs to paginate";
       }
 
-      var params = _.reduce(['reduce', 'keys', 'key', 'endkey', 'descending', 'inclusive_end'], function (params, key) {
-        if (_.has(currentParams, key)) {
-          params[key] = currentParams[key]; 
-        }
-        return params;
-      }, defaultParams);
+
+      // defaultParams should always override the user-specified parameters
+      _.extend(currentParams, defaultParams);
 
       lastId = doc.id || doc._id;
 
+      // If we are paginating on a view, we need to set a ``key`` and a ``docId``
+      // and expect that they are different values.
       if (isView) {
         key = doc.key;
         docId = lastId;
@@ -49,29 +48,24 @@ function(app, FauxtonAPI) {
         docId = key = lastId;
       }
 
-      if (isView && !currentParams.keys) {
-        params.startkey_docid = docId; 
-        params.startkey = key;
+      // Set parameters to paginate
+      if (isView) {
+        currentParams.startkey_docid = docId; 
+        currentParams.startkey = key;
       } else if (currentParams.startkey) {
-        params.startkey = key;
+        currentParams.startkey = key;
       } else {
-        params.startkey_docid = docId; 
+        currentParams.startkey_docid = docId; 
       }
 
-      _.each(['startkey', 'endkey', 'key'], function (key) {
-        if (_.has(params, key)) {
-          params[key] = JSON.stringify(params[key]);
-        }
-      });
-
-      return params;
+      return currentParams;
     },
 
     next: function (docs, currentParams, perPage, _isAllDocs) {
       var params = {limit: perPage, skip: 1},
           doc = _.last(docs);
           
-      return this.calculate(doc, params, currentParams, _isAllDocs);
+            return this.calculate(doc, params, currentParams, _isAllDocs);
     },
 
     previous: function (docs, currentParams, perPage, _isAllDocs) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8a27510e/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 ffe0b87..2d2b24b 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -375,34 +375,51 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     perPageChange: function (perPage) {
-      console.log('pp', perPage);
       this.perPage = perPage;
-      this.documentsView.collection.updateLimit(perPage);
+      this.documentsView.updatePerPage(perPage);
       this.documentsView.forceRender();
     },
 
     paginate: function (options) {
       var params = {},
           urlParams = app.getParams(),
+          currentPage = options.currentPage,
           collection = this.documentsView.collection;
 
       this.documentsView.forceRender();
       var rawCollection = collection.map(function (item) { return item.toJSON(); });
+      collection.reverse = false;
+
+      _.each(collection.params, function (val, key) {
+        collection.params[key] = JSON.parse(val);
+      });
+
+      _.each(urlParams, function (val, key) {
+        urlParams[key] = JSON.parse(val);
+      });
+
 
       if (options.direction === 'next') {
-          collection.reverse = false;
           params = Documents.paginate.next(rawCollection, 
                                            collection.params,
                                            options.perPage, 
                                            !!collection.isAllDocs);
       } else {
+        if (currentPage <= 1) {
+          params = _.clone(urlParams);
+          params.limit = collection.params.limit;
+        } else {
           collection.reverse = true;
           params = Documents.paginate.previous(rawCollection, 
                                                collection.params, 
                                                options.perPage, 
                                                !!collection.isAllDocs);
+        }
       }
       params.limit = options.perPage;
+      _.each(params, function (val, key) {
+        params[key] = JSON.stringify(val);
+      });
       collection.updateParams(params);
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8a27510e/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 f80d07e..f222b93 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -439,7 +439,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     serialize: function () {
        var totalRows = 0,
           updateSeq = false,
-          recordStart = 0,
           pageStart = 0,
           pageEnd = 20;
 
@@ -738,6 +737,14 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     perPage: function () {
       return this.allDocsNumber.perPage();
+    },
+
+    updatePerPage: function (newPerPage) {
+      if (this.collection.reverse) {
+        delete this.collection.params.descending
+        this.collection.reverse = false;
+      }
+      this.collection.updateLimit(newPerPage);
     }
   });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8a27510e/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 278831e..01ee4a9 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -80,6 +80,7 @@ function(app, FauxtonAPI, ace, spin) {
       this._pageNumber = [];
       this._pageStart = 1;
       this.enabled = true;
+      this.currentPage = 1;
     },
 
     canShowPreviousfn: function () {
@@ -119,6 +120,7 @@ function(app, FauxtonAPI, ace, spin) {
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'previous',
        perPage: this.perPage,
+       currentPage: this.currentPage
       });
     },
 
@@ -142,7 +144,8 @@ function(app, FauxtonAPI, ace, spin) {
 
       FauxtonAPI.triggerRouteEvent('paginate', {
        direction: 'next',
-       perPage: this.documentsLeftToFetch()
+       perPage: this.documentsLeftToFetch(),
+       currentPage: this.currentPage
       });
 
     },
@@ -154,8 +157,10 @@ function(app, FauxtonAPI, ace, spin) {
       };
     },
 
-    updatePerPage: function (perPage) {
-      this.perPage = perPage;
+    updatePerPage: function (newPerPage) {
+      var docsView = this.page() + newPerPage;
+      this.currentPage = Math.ceil(docsView / newPerPage);
+      this.perPage = newPerPage;
     },
 
     page: function () {
@@ -163,6 +168,7 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     incPageNumber: function () {
+      this.currentPage = this.currentPage + 1;
       this._pageNumber.push({perPage: this.perPage});
       this._pageStart = this._pageStart + this.perPage;
     },
@@ -174,11 +180,11 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     decPageNumber: function () {
+      this.currentPage = this.currentPage - 1;
       this._pageNumber.pop();
       var val = this._pageStart - this.perPage;
       if (val < 1) {
-        this._pageStart = 1;
-        return;
+        val = 1;
       }
 
       this._pageStart = val;
@@ -203,7 +209,7 @@ function(app, FauxtonAPI, ace, spin) {
     setCollection: function (collection) {
       this.collection = collection;
       this.setDefaults();
-    }
+    },
 
   });
 


[11/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Remove caching from design docs, so that edit revisions are updated


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

Branch: refs/heads/paginate-api-options
Commit: 055219f106b271dc17f0e469fb967489f4ef962e
Parents: 5989bb3
Author: suelockwood <de...@apache.org>
Authored: Wed Feb 26 17:00:07 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Wed Feb 26 17:00:07 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/routes.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/055219f1/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 be9ce2f..1510485 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -182,7 +182,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     establish: function () {
-      return this.data.designDocs.fetchOnce();
+      return this.data.designDocs.fetch();
     },
 
     allDocs: function(databaseName, options) {


[03/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Upgrade password hashes on authentication

We now upgrade user docs to the new PBKDF2 password scheme on successful
authentication if the password hash is still from the old days where we
only used plain SHA-1 for hashing salted passwords.

Closes COUCHDB-1780.


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

Branch: refs/heads/paginate-api-options
Commit: 348889380c3b98d7f1a6c8963fc2eb4ee08c1db7
Parents: 45e17e5
Author: Klaus Trainer <kl...@posteo.de>
Authored: Wed Feb 19 23:17:02 2014 +0100
Committer: Klaus Trainer <kl...@apache.org>
Committed: Sun Feb 23 18:59:22 2014 +0100

----------------------------------------------------------------------
 share/www/script/test/users_db_security.js | 61 ++++++++++++++++++++++++-
 src/couchdb/couch_httpd_auth.erl           | 35 ++++++++++----
 2 files changed, 86 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/34888938/share/www/script/test/users_db_security.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/users_db_security.js b/share/www/script/test/users_db_security.js
index 9bf9b8a..2a2bb9d 100644
--- a/share/www/script/test/users_db_security.js
+++ b/share/www/script/test/users_db_security.js
@@ -151,6 +151,63 @@ couchTests.users_db_security = function(debug) {
       TEquals(true, userDoc.derived_key != jchrisDoc.derived_key,
         "should have new derived_key");
 
+      // SHA-1 password hashes are upgraded to PBKDF2 on successful
+      // authentication
+      var rnewsonDoc = {
+        _id: "org.couchdb.user:rnewson",
+        type: "user",
+        name: "rnewson",
+        // password: "plaintext_password",
+        password_sha: "e29dc3aeed5abf43185c33e479f8998558c59474",
+        salt: "24f1e0a87c2e374212bda1073107e8ae",
+        roles: []
+      };
+
+      var password_sha = rnewsonDoc.password_sha,
+        salt = rnewsonDoc.salt,
+        derived_key,
+        iterations;
+
+      usersDb.save(rnewsonDoc);
+      rnewsonDoc = open_as(usersDb, rnewsonDoc._id, "jan");
+      T(!rnewsonDoc.password_scheme);
+      T(!rnewsonDoc.derived_key);
+      T(!rnewsonDoc.iterations);
+
+      // check that we don't upgrade when the password is wrong
+      TEquals("unauthorized", CouchDB.login("rnewson", "wrong_password").error);
+      rnewsonDoc = open_as(usersDb, rnewsonDoc._id, "jan");
+      TEquals(salt, rnewsonDoc.salt);
+      TEquals(password_sha, rnewsonDoc.password_sha);
+      T(!rnewsonDoc.password_scheme);
+      T(!rnewsonDoc.derived_key);
+      T(!rnewsonDoc.iterations);
+
+      TEquals(true, CouchDB.login("rnewson", "plaintext_password").ok);
+      rnewsonDoc = usersDb.open(rnewsonDoc._id);
+      TEquals("pbkdf2", rnewsonDoc.password_scheme);
+      T(rnewsonDoc.salt != salt);
+      T(!rnewsonDoc.password_sha);
+      T(rnewsonDoc.derived_key);
+      T(rnewsonDoc.iterations);
+
+      salt = rnewsonDoc.salt,
+      derived_key = rnewsonDoc.derived_key,
+      iterations = rnewsonDoc.iterations;
+
+      // check that authentication is still working
+      // and everything is staying the same now
+      CouchDB.logout();
+      TEquals(true, CouchDB.login("rnewson", "plaintext_password").ok);
+      rnewsonDoc = usersDb.open(rnewsonDoc._id);
+      TEquals("pbkdf2", rnewsonDoc.password_scheme);
+      TEquals(salt, rnewsonDoc.salt);
+      T(!rnewsonDoc.password_sha);
+      TEquals(derived_key, rnewsonDoc.derived_key);
+      TEquals(iterations, rnewsonDoc.iterations);
+
+      CouchDB.logout();
+
       // user should not be able to read another user's user document
       var fdmananaDoc = {
         _id: "org.couchdb.user:fdmanana",
@@ -209,11 +266,11 @@ couchTests.users_db_security = function(debug) {
 
       // admin should be able to read from any view
       var result = view_as(usersDb, "user_db_auth/test", "jan");
-      TEquals(3, result.total_rows, "should allow access and list two users to admin");
+      TEquals(4, result.total_rows, "should allow access and list four users to admin");
 
       // db admin should be able to read from any view
       var result = view_as(usersDb, "user_db_auth/test", "benoitc");
-      TEquals(3, result.total_rows, "should allow access and list two users to db admin");
+      TEquals(4, result.total_rows, "should allow access and list four users to db admin");
 
 
       // non-admins can't read design docs

http://git-wip-us.apache.org/repos/asf/couchdb/blob/34888938/src/couchdb/couch_httpd_auth.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_auth.erl b/src/couchdb/couch_httpd_auth.erl
index b8c4e26..08841fb 100644
--- a/src/couchdb/couch_httpd_auth.erl
+++ b/src/couchdb/couch_httpd_auth.erl
@@ -68,11 +68,14 @@ default_authentication_handler(Req) ->
             nil ->
                 throw({unauthorized, <<"Name or password is incorrect.">>});
             UserProps ->
-                case authenticate(?l2b(Pass), UserProps) of
+                UserName = ?l2b(User),
+                Password = ?l2b(Pass),
+                case authenticate(Password, UserProps) of
                     true ->
+                        UserProps2 = maybe_upgrade_password_hash(UserName, Password, UserProps),
                         Req#httpd{user_ctx=#user_ctx{
-                            name=?l2b(User),
-                            roles=couch_util:get_value(<<"roles">>, UserProps, [])
+                            name=UserName,
+                            roles=couch_util:get_value(<<"roles">>, UserProps2, [])
                         }};
                     _Else ->
                         throw({unauthorized, <<"Name or password is incorrect.">>})
@@ -263,15 +266,16 @@ handle_session_req(#httpd{method='POST', mochi_req=MochiReq}=Req) ->
     UserName = ?l2b(couch_util:get_value("name", Form, "")),
     Password = ?l2b(couch_util:get_value("password", Form, "")),
     ?LOG_DEBUG("Attempt Login: ~s",[UserName]),
-    User = case couch_auth_cache:get_user_creds(UserName) of
+    UserProps = case couch_auth_cache:get_user_creds(UserName) of
         nil -> [];
         Result -> Result
     end,
-    UserSalt = couch_util:get_value(<<"salt">>, User, <<>>),
-    case authenticate(Password, User) of
+    case authenticate(Password, UserProps) of
         true ->
+            UserProps2 = maybe_upgrade_password_hash(UserName, Password, UserProps),
             % setup the session cookie
             Secret = ?l2b(ensure_cookie_auth_secret()),
+            UserSalt = couch_util:get_value(<<"salt">>, UserProps2),
             CurrentTime = make_cookie_time(),
             Cookie = cookie_auth_cookie(Req, ?b2l(UserName), <<Secret/binary, UserSalt/binary>>, CurrentTime),
             % TODO document the "next" feature in Futon
@@ -284,8 +288,8 @@ handle_session_req(#httpd{method='POST', mochi_req=MochiReq}=Req) ->
             send_json(Req#httpd{req_body=ReqBody}, Code, Headers,
                 {[
                     {ok, true},
-                    {name, couch_util:get_value(<<"name">>, User, null)},
-                    {roles, couch_util:get_value(<<"roles">>, User, [])}
+                    {name, couch_util:get_value(<<"name">>, UserProps2, null)},
+                    {roles, couch_util:get_value(<<"roles">>, UserProps2, [])}
                 ]});
         _Else ->
             % clear the session
@@ -340,6 +344,21 @@ maybe_value(_Key, undefined, _Fun) -> [];
 maybe_value(Key, Else, Fun) ->
     [{Key, Fun(Else)}].
 
+maybe_upgrade_password_hash(UserName, Password, UserProps) ->
+    case couch_util:get_value(<<"password_scheme">>, UserProps, <<"simple">>) of
+    <<"simple">> ->
+        DbName = ?l2b(couch_config:get("couch_httpd_auth", "authentication_db", "_users")),
+        couch_util:with_db(DbName, fun(UserDb) ->
+            UserProps2 = proplists:delete(<<"password_sha">>, UserProps),
+            UserProps3 = [{<<"password">>, Password} | UserProps2],
+            NewUserDoc = couch_doc:from_json_obj({UserProps3}),
+            {ok, _NewRev} = couch_db:update_doc(UserDb, NewUserDoc, []),
+            couch_auth_cache:get_user_creds(UserName)
+        end);
+    _ ->
+        UserProps
+    end.
+
 authenticate(Pass, UserProps) ->
     UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<>>),
     {PasswordHash, ExpectedHash} =


[33/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Fix page count on perPage change


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

Branch: refs/heads/paginate-api-options
Commit: 7df61e79084a4a63ef0661d2e5eac556f6b8f5d4
Parents: cf7a92a
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Mar 3 11:31:26 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:31:26 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/fauxton/components.js | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/7df61e79/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 01ee4a9..1174193 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -158,8 +158,7 @@ function(app, FauxtonAPI, ace, spin) {
     },
 
     updatePerPage: function (newPerPage) {
-      var docsView = this.page() + newPerPage;
-      this.currentPage = Math.ceil(docsView / newPerPage);
+      this.setDefaults();
       this.perPage = newPerPage;
     },
 


[07/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Fix formatting


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

Branch: refs/heads/paginate-api-options
Commit: 17a97631fdbb3c45dd82081b51e9cf26c39fb884
Parents: 8de6b6e
Author: Alexander Shorin <kx...@apache.org>
Authored: Tue Feb 25 20:27:33 2014 +0400
Committer: Alexander Shorin <kx...@apache.org>
Committed: Tue Feb 25 20:27:33 2014 +0400

----------------------------------------------------------------------
 share/doc/src/json-structure.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/17a97631/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index 8eae7df..ab3ae45 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -227,7 +227,7 @@ List of Active Tasks
 +--------------------------------+---------------------------------------------+
 | Field                          | Description                                 |
 +================================+=============================================+
-| tasks [array]                  | Active Tasks                                 |
+| tasks [array]                  | Active Tasks                                |
 +--------------------------------+---------------------------------------------+
 |     pid                        | Process ID                                  |
 +--------------------------------+---------------------------------------------+


[15/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Turn workers back on for errors in the editors


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

Branch: refs/heads/paginate-api-options
Commit: 72d61343b8b6edbfea3c9412bcc9edb1c246bf34
Parents: 929b3a0
Author: suelockwood <de...@apache.org>
Authored: Fri Feb 28 15:38:17 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Fri Feb 28 15:38:17 2014 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/fauxton/components.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/72d61343/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 71d78b1..0422b5a 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -284,7 +284,7 @@ function(app, FauxtonAPI, ace, spin) {
     afterRender: function () {
       this.editor = ace.edit(this.editorId);
       this.setHeightToLineCount();
-      this.editor.getSession().setUseWorker(false);
+
       this.editor.setTheme("ace/theme/" + this.theme);
 
       this.editor.getSession().setMode("ace/mode/" + this.mode);


[27/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

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


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

Branch: refs/heads/paginate-api-options
Commit: 9848c76d30b17bdfec68edc28b18ee0fc1b786ab
Parents: 0beb91c
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Feb 20 11:15:16 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:42 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/9848c76d/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 6f6ed1c..d942cf6 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -26,10 +26,6 @@ function(app, FauxtonAPI) {
           lastId = '',
           isView = !!!_isAllDocs,
           key;
-      
-      _.each(doc, function (value, key) {
-        doc[key] = JSON.stringify(doc[key]);
-      });
 
       if (currentParams.keys) {
         throw "Cannot paginate _all_docs with keys";
@@ -39,9 +35,9 @@ function(app, FauxtonAPI) {
         throw "Require docs to paginate";
       }
 
-      params = _.reduce(['reduce', 'keys', 'endkey', 'descending', 'inclusive_end'], function (params, p) {
-        if (_.has(currentParams, p)) {
-          params[p] = currentParams[p]; 
+      params = _.reduce(['reduce', 'keys', 'endkey', 'descending', 'inclusive_end'], function (params, key) {
+        if (_.has(currentParams, key)) {
+          params[key] = currentParams[key]; 
         }
         return params;
       }, params);
@@ -49,7 +45,6 @@ function(app, FauxtonAPI) {
       lastId = doc.id || doc._id;
 
       if (isView) {
-        console.log(doc.key, doc, lastId);
         key = doc.key;
         docId = lastId;
       } else {
@@ -64,6 +59,13 @@ function(app, FauxtonAPI) {
       } else {
         params.startkey_docid = docId; 
       }
+
+      _.each(['startkey', 'endkey', 'key'], function (key) {
+        if (_.has(params, key)) {
+          params[key] = JSON.stringify(params[key]);
+        }
+      });
+
       return params;
     }
  };


[30/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
More pagination goodness


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

Branch: refs/heads/paginate-api-options
Commit: cf7a92a090d52f71bf00c6ca147125157688d7cd
Parents: 8a27510
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Feb 21 17:53:12 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:43 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/resources.js | 29 +++++++++-------------
 src/fauxton/app/addons/documents/routes.js    | 20 ++++++++-------
 src/fauxton/app/addons/documents/views.js     |  4 ---
 3 files changed, 23 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/cf7a92a0/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 fd1a558..8bc52b0 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -19,6 +19,7 @@ function(app, FauxtonAPI) {
   var Documents = FauxtonAPI.addon();
 
   Documents.paginate = {
+    history: [],
     calculate: function (doc, defaultParams, currentParams, _isAllDocs) {
       var docId = '',
           lastId = '',
@@ -65,14 +66,20 @@ function(app, FauxtonAPI) {
       var params = {limit: perPage, skip: 1},
           doc = _.last(docs);
           
-            return this.calculate(doc, params, currentParams, _isAllDocs);
+      this.history.push(_.clone(currentParams));
+      return this.calculate(doc, params, currentParams, _isAllDocs);
     },
 
     previous: function (docs, currentParams, perPage, _isAllDocs) {
-      var params = {descending: true, limit: perPage, skip: 1},
+      var params = this.history.pop(),
           doc = _.first(docs);
 
-      return this.calculate(doc, params, currentParams, _isAllDocs);
+      params.limit = perPage;
+      return params;
+    },
+
+    reset: function () {
+      this.history = [];
     }
   };
 
@@ -421,7 +428,7 @@ function(app, FauxtonAPI) {
       if (this.skipFirstItem) {
         rows = rows.splice(1);
       }
-      var mappedRows = _.map(rows, function(row) {
+      return _.map(rows, function(row) {
         return {
           _id: row.id,
           _rev: row.value.rev,
@@ -430,12 +437,6 @@ function(app, FauxtonAPI) {
           doc: row.doc || undefined
         };
       });
-
-      if (this.reverse) {
-        return _(mappedRows).reverse().value();
-      }
-
-      return mappedRows;
     }
   });
 
@@ -539,7 +540,7 @@ function(app, FauxtonAPI) {
         offset: resp.offset,
         update_seq: resp.update_seq
       };
-      var mappedRows =  _.map(rows, function(row) {
+      return _.map(rows, function(row) {
         return {
           value: row.value,
           key: row.key,
@@ -547,12 +548,6 @@ function(app, FauxtonAPI) {
           id: row.id
         };
       });
-
-      if (this.reverse) {
-        return _(mappedRows).reverse().value();
-      }
-
-      return mappedRows;
     },
 
     buildAllDocs: function(){

http://git-wip-us.apache.org/repos/asf/couchdb/blob/cf7a92a0/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 2d2b24b..168807a 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -243,6 +243,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       ];
 
       this.apiUrl = [this.data.database.allDocs.url("apiurl", urlParams), this.data.database.allDocs.documentation() ];
+      Documents.paginate.reset();
     },
 
     viewFn: function (databaseName, ddoc, view) {
@@ -298,6 +299,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       };
 
       this.apiUrl = [this.data.indexedDocs.url("apiurl", urlParams), "docs"];
+      Documents.paginate.reset();
     },
 
     newViewEditor: function () {
@@ -352,6 +354,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       this.documentsView.setParams(docParams, urlParams);
 
       this.apiUrl = [collection.url("apiurl", urlParams), "docs"];
+      Documents.paginate.reset();
     },
 
     updateAllDocsFromPreview: function (event) {
@@ -375,8 +378,11 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     perPageChange: function (perPage) {
+      var params = app.getParams();
       this.perPage = perPage;
       this.documentsView.updatePerPage(perPage);
+      params.limit = perPage;
+      this.documentsView.collection.params = params;
       this.documentsView.forceRender();
     },
 
@@ -405,21 +411,17 @@ function(app, FauxtonAPI, Documents, Databases) {
                                            options.perPage, 
                                            !!collection.isAllDocs);
       } else {
-        if (currentPage <= 1) {
-          params = _.clone(urlParams);
-          params.limit = collection.params.limit;
-        } else {
-          collection.reverse = true;
           params = Documents.paginate.previous(rawCollection, 
                                                collection.params, 
                                                options.perPage, 
                                                !!collection.isAllDocs);
-        }
       }
       params.limit = options.perPage;
-      _.each(params, function (val, key) {
-        params[key] = JSON.stringify(val);
-      });
+      _.each(['startkey', 'endkey', 'key'], function (key) {
+        if (_.has(params, key)) {
+          params[key] = JSON.stringify(params[key]);
+        }
+    });
       collection.updateParams(params);
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/cf7a92a0/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 f222b93..1d07dae 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -740,10 +740,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     updatePerPage: function (newPerPage) {
-      if (this.collection.reverse) {
-        delete this.collection.params.descending
-        this.collection.reverse = false;
-      }
       this.collection.updateLimit(newPerPage);
     }
   });


[18/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

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/0f69dc94
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0f69dc94
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0f69dc94

Branch: refs/heads/paginate-api-options
Commit: 0f69dc941479957a3eccb5c581af781da553d893
Parents: b22f2a4
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jan 28 16:30:38 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:40 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/0f69dc94/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 ea1aed2..80cd533 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 = FauxtonAPI.Model.extend({
     initialize: function(options) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0f69dc94/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 9dee85e..c30a9af 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/0f69dc94/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 adfee1f..a1f43a5 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/0f69dc94/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/0f69dc94/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/0f69dc94/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/0f69dc94/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/0f69dc94/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/0f69dc94/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 6a20849..b1364df 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -23,6 +23,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/0f69dc94/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 7282ed7..ce06189 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
@@ -463,29 +478,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);
       }
 
     },
@@ -576,15 +600,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
       };
     },
@@ -646,53 +664,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();
@@ -700,16 +685,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();
 
@@ -942,9 +926,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());
@@ -1023,6 +1004,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",
@@ -1033,7 +1081,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;
@@ -1046,6 +1094,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: {
@@ -1055,6 +1105,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');
@@ -1136,7 +1204,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":
@@ -1247,7 +1315,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: {
@@ -1368,6 +1437,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",
@@ -1395,6 +1465,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) {
@@ -1622,19 +1695,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/0f69dc94/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 0422b5a..3ead39d 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();
     }
 
   });


[19/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

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/9ccfdd96
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/9ccfdd96
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/9ccfdd96

Branch: refs/heads/paginate-api-options
Commit: 9ccfdd9685af2d746c1ea440fc5093eb7369110e
Parents: 0f69dc9
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jan 29 15:48:34 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:40 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/9ccfdd96/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 a1f43a5..15d4d30 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/9ccfdd96/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/9ccfdd96/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 ce06189..a33bd47 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -582,6 +582,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;
     },
 
@@ -667,7 +668,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/9ccfdd96/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 3ead39d..225a21b 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;
     },
 


[16/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Cancel event propagation on replication swap.

Previous implementation called e.preventDefault() but did not stop upwards
propagation - the click event would therefore trigger navigation to the main
database panel. jQuery calls preventDefault and stopPropagation
when false is returned from an event handler so just do that here.


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

Branch: refs/heads/paginate-api-options
Commit: b22f2a48c48f3cfa9b4c082cfee87b76e8d44c37
Parents: 72d6134
Author: Will Holley <wi...@gmail.com>
Authored: Fri Feb 28 15:07:13 2014 +0000
Committer: Will Holley <wi...@gmail.com>
Committed: Mon Mar 3 08:06:09 2014 +0000

----------------------------------------------------------------------
 src/fauxton/app/addons/replication/views.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b22f2a48/src/fauxton/app/addons/replication/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/replication/views.js b/src/fauxton/app/addons/replication/views.js
index 1b31a9d..a19e609 100644
--- a/src/fauxton/app/addons/replication/views.js
+++ b/src/fauxton/app/addons/replication/views.js
@@ -175,7 +175,6 @@ function(app, FauxtonAPI, Components, replication) {
       this.startReplication(formJSON);
     },	
     swapFields: function(e){
-      e.preventDefault();
       //WALL O' VARIABLES
       var $fromSelect = this.$('#from_name'),
           $toSelect = this.$('#to_name'),
@@ -191,6 +190,9 @@ function(app, FauxtonAPI, Components, replication) {
 
       $fromInput.val(toInputVal);
       $toInput.val(fromInputVal);
+
+      // prevent other click handlers from running
+      return false;
     }
   });
 


[12/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Added the "everyone is an admin" & "fix this" note  and move the text around on the page.
Got rid of the extra header


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

Branch: refs/heads/paginate-api-options
Commit: 48f586f850a4cc92e938d84bfc98ba33f125861e
Parents: 055219f
Author: suelockwood <de...@apache.org>
Authored: Thu Feb 27 15:33:48 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Thu Feb 27 15:33:48 2014 -0500

----------------------------------------------------------------------
 .../app/addons/auth/templates/create_admin.html | 21 ++++++++++----------
 .../addons/auth/templates/nav_link_title.html   |  3 ++-
 src/fauxton/assets/less/fauxton.less            |  4 +++-
 3 files changed, 15 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/48f586f8/src/fauxton/app/addons/auth/templates/create_admin.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/create_admin.html b/src/fauxton/app/addons/auth/templates/create_admin.html
index 4715be5..8f4ed2c 100644
--- a/src/fauxton/app/addons/auth/templates/create_admin.html
+++ b/src/fauxton/app/addons/auth/templates/create_admin.html
@@ -13,21 +13,20 @@ the License.
 -->
 
 <div class="span12">
-  <h2> Add Admin </h2>
+  <p class="help-block">
+  Before a server admin is configured, all clients have admin privileges.
+  This is fine when HTTP access is restricted 
+  to trusted users. <strong>If end-users will be accessing this CouchDB, you must
+    create an admin account to prevent accidental (or malicious) data loss.</strong>
+  </p>
+  <p class="help-block">Server admins can create and destroy databases, install 
+    and update _design documents, run the test suite, and edit all aspects of CouchDB 
+    configuration.
+  </p>
   <form id="create-admin-form">
     <input id="username" type="text" name="name" placeholder= "Username:" size="24">
     <br/>
     <input id="password" type="password" name="password" placeholder= "Password" size="24">
-    <p class="help-block">
-    Before a server admin is configured, all clients have admin privileges.
-    This is fine when HTTP access is restricted 
-    to trusted users. <strong>If end-users will be accessing this CouchDB, you must
-      create an admin account to prevent accidental (or malicious) data loss.</strong>
-    </p>
-    <p class="help-block">Server admins can create and destroy databases, install 
-    and update _design documents, run the test suite, and edit all aspects of CouchDB 
-    configuration.
-    </p>
     <p class="help-block">Non-admin users have read and write access to all databases, which
     are controlled by validation functions. CouchDB can be configured to block all
     access to anonymous users.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/48f586f8/src/fauxton/app/addons/auth/templates/nav_link_title.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/nav_link_title.html b/src/fauxton/app/addons/auth/templates/nav_link_title.html
index b23157e..699ea80 100644
--- a/src/fauxton/app/addons/auth/templates/nav_link_title.html
+++ b/src/fauxton/app/addons/auth/templates/nav_link_title.html
@@ -14,7 +14,8 @@ the License.
 <% if (admin_party) { %>
   <a id="user-create-admin" href="#createAdmin"> 
   	<span class="fonticon-user fonticon"></span>
-  	Admin Party! 
+  	Admin Party! [FIX THIS] 
+    <small>Everyone is an admin.</small>
   </a>
 <% } else if (user) { %>
   <a  href="#changePassword" >

http://git-wip-us.apache.org/repos/asf/couchdb/blob/48f586f8/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 82c65bd..229075b 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -340,7 +340,9 @@ table.databases {
     bottom: 0;
     width: 100%;
   }
-
+  #user-create-admin{
+    font-size: 12px
+  }
   .navbar {
     .brand {
       .box-sizing(content-box);


[13/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Added Highlight to the admin party to make it stand out more.


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

Branch: refs/heads/paginate-api-options
Commit: 0df722e66b66bbad172a237b6fd1521b4a346676
Parents: 48f586f
Author: suelockwood <de...@apache.org>
Authored: Fri Feb 28 09:55:05 2014 -0500
Committer: suelockwood <de...@apache.org>
Committed: Fri Feb 28 09:55:05 2014 -0500

----------------------------------------------------------------------
 src/Makefile.am                                      |  1 +
 src/fauxton/app/addons/auth/assets/less/auth.less    | 15 +++++++++++++++
 .../app/addons/auth/templates/nav_link_title.html    |  2 +-
 3 files changed, 17 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/0df722e6/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 32a1a6a..59aa6bf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,6 +52,7 @@ FAUXTON_FILES = \
     fauxton/app/addons/auth/base.js \
     fauxton/app/addons/auth/resources.js \
     fauxton/app/addons/auth/routes.js \
+    fauxton/app/addons/auth/assets/less/auth.less \
     fauxton/app/addons/auth/templates/change_password.html \
     fauxton/app/addons/auth/templates/create_admin.html \
     fauxton/app/addons/auth/templates/login.html \

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0df722e6/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
new file mode 100644
index 0000000..8a71817
--- /dev/null
+++ b/src/fauxton/app/addons/auth/assets/less/auth.less
@@ -0,0 +1,15 @@
+/*  Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ *  use this file except in compliance with the License. You may obtain a copy of
+ *  the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ *  License for the specific language governing permissions and limitations under
+ *  the License.
+ */
+#primary-navbar .navbar nav .nav li a#user-create-admin{
+  background-color: #af2d24;
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/0df722e6/src/fauxton/app/addons/auth/templates/nav_link_title.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/nav_link_title.html b/src/fauxton/app/addons/auth/templates/nav_link_title.html
index 699ea80..863955c 100644
--- a/src/fauxton/app/addons/auth/templates/nav_link_title.html
+++ b/src/fauxton/app/addons/auth/templates/nav_link_title.html
@@ -12,7 +12,7 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 <% if (admin_party) { %>
-  <a id="user-create-admin" href="#createAdmin"> 
+  <a id="user-create-admin" class="alert_nav" href="#createAdmin"> 
   	<span class="fonticon-user fonticon"></span>
   	Admin Party! [FIX THIS] 
     <small>Everyone is an admin.</small>


[17/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

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/fa33d4d3
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/fa33d4d3
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/fa33d4d3

Branch: refs/heads/paginate-api-options
Commit: fa33d4d3e7c13ac99c4e79f69cc191cdb8091f9c
Parents: 9ccfdd9
Author: Garren Smith <ga...@gmail.com>
Authored: Wed Jan 29 17:44:49 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:40 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/fa33d4d3/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 15d4d30..72cdb66 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/fa33d4d3/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 225a21b..c755428 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;
     }
 
   });


[24/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
Fix query options not toggling


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

Branch: refs/heads/paginate-api-options
Commit: 4e10385a13e335d00f5b342e32ac6964fbb6634f
Parents: 98b5472
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Feb 13 13:46:11 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Mar 3 11:18:41 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/documents/views.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/4e10385a/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 4f81016..c5ad1bb 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -479,11 +479,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     events: {
-      'click #query-nav': "toggleQuery"
+      'click #toggle-query': "toggleQuery"
     },
 
     toggleQuery: function (event) {
       $('#dashboard-content').scrollTop(0);
+      console.log('hi');
       this.$('#query').toggle('slow');
     },
 


[06/34] couchdb commit: updated refs/heads/paginate-api-options to b63c791

Posted by ga...@apache.org.
```validate_doc_update``` moved from views to root

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/8de6b6e1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/8de6b6e1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/8de6b6e1

Branch: refs/heads/paginate-api-options
Commit: 8de6b6e1c36212dd6615633cd1fddae430da9775
Parents: 358901a
Author: Anthony Ananich <an...@inpun.com>
Authored: Tue Feb 25 18:17:44 2014 +0200
Committer: Alexander Shorin <kx...@apache.org>
Committed: Tue Feb 25 20:22:20 2014 +0400

----------------------------------------------------------------------
 share/doc/src/query-server/javascript.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/8de6b6e1/share/doc/src/query-server/javascript.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/query-server/javascript.rst b/share/doc/src/query-server/javascript.rst
index 16590d6..386f9c5 100644
--- a/share/doc/src/query-server/javascript.rst
+++ b/share/doc/src/query-server/javascript.rst
@@ -273,12 +273,12 @@ The CommonJS module can be added to a design document, like so:
        "views": {
           "lib": {
              "security": "function user_context(userctx, secobj) { ... }"
-          },
-          "validate_doc_update": "function(newdoc, olddoc, userctx, secobj) {
-            user = require('lib/security').user(userctx, secobj);
-            return user.is_admin();
-          }"
+          }
        },
+       "validate_doc_update": "function(newdoc, olddoc, userctx, secobj) {
+          user = require('lib/security').user(userctx, secobj);
+          return user.is_admin();
+       }"
        "_id": "_design/test"
     }