You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by de...@apache.org on 2014/08/25 15:39:45 UTC

[05/48] fauxton commit: updated refs/heads/secondary-indexes to 8688d16

Upgrade backbone.layoutmanager

Work off Tim's initial commits and adjust to cater for the use of
establish functions in views and routeObjects.
We don't want to immediately render the view. We first want any pending
promises returned from a routeObjects establish and a view's establish
to complete before rendering the view.


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

Branch: refs/heads/secondary-indexes
Commit: 2283352a0938129d0acc04927bdb0e175bd61b4f
Parents: 07cce5a
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Aug 11 12:06:21 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Aug 18 11:30:50 2014 +0200

----------------------------------------------------------------------
 app/addons/activetasks/tests/viewsSpec.js       | 15 ++--
 app/addons/config/tests/resourcesSpec.js        |  4 +-
 app/addons/documents/tests/views-changesSpec.js |  7 +-
 app/addons/fauxton/tests/baseSpec.js            | 12 ++-
 app/addons/fauxton/tests/filterViewSpec.js      | 10 ++-
 app/addons/fauxton/tests/paginateSpec.js        |  4 +-
 app/addons/permissions/tests/viewsSpec.js       | 12 +--
 app/core/base.js                                |  4 +-
 app/core/layout.js                              | 81 ++++++++++++++++----
 app/core/routeObject.js                         | 11 ++-
 app/core/tests/layoutSpec.js                    | 79 +++++++++++++++++--
 app/core/tests/routeObjectSpec.js               |  6 ++
 test/mocha/testUtils.js                         |  8 +-
 13 files changed, 198 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/activetasks/tests/viewsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/activetasks/tests/viewsSpec.js b/app/addons/activetasks/tests/viewsSpec.js
index 19c5b65..8731200 100644
--- a/app/addons/activetasks/tests/viewsSpec.js
+++ b/app/addons/activetasks/tests/viewsSpec.js
@@ -27,9 +27,9 @@ define([
 
     describe("on change polling rate", function () {
       var viewSandbox;
-      beforeEach(function () {
+      beforeEach(function (done) {
         viewSandbox = new ViewSandbox();
-        viewSandbox.renderView(tabMenu);
+        viewSandbox.renderView(tabMenu, done);
       });
 
       afterEach(function () {
@@ -66,7 +66,7 @@ define([
 
     describe('on request by type', function () {
       var viewSandbox, mainView;
-      beforeEach(function () {
+      beforeEach(function (done) {
 
         mainView = new Views.View({
           collection: new Activetasks.AllTasks(),
@@ -74,8 +74,9 @@ define([
         });
 
         viewSandbox = new ViewSandbox();
-        viewSandbox.renderView(tabMenu);
-        viewSandbox.renderView(mainView);
+        viewSandbox.renderView(tabMenu).promise().then(function () {
+          viewSandbox.renderView(mainView, done);
+        });
       });
 
       afterEach(function () {
@@ -99,14 +100,14 @@ define([
 
   describe('DataSection', function () {
     var viewSandbox, mainView;
-    beforeEach(function () {
+    beforeEach(function (done) {
       mainView = new Views.View({
         collection: new Activetasks.AllTasks(),
         currentView: "all"
       });
 
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(mainView);
+      viewSandbox.renderView(mainView, done);
     });
 
     afterEach(function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/config/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/config/tests/resourcesSpec.js b/app/addons/config/tests/resourcesSpec.js
index 1cc9e62..8699e36 100644
--- a/app/addons/config/tests/resourcesSpec.js
+++ b/app/addons/config/tests/resourcesSpec.js
@@ -37,9 +37,9 @@ define([
 
     describe("editing Items", function () {
       var viewSandbox;
-      beforeEach(function () {
+      beforeEach(function (done) {
         viewSandbox = new ViewSandbox();
-        viewSandbox.renderView(tabMenu);
+        viewSandbox.renderView(tabMenu, done);
       });
 
       afterEach(function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/documents/tests/views-changesSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/views-changesSpec.js b/app/addons/documents/tests/views-changesSpec.js
index 94ca585..36669ad 100644
--- a/app/addons/documents/tests/views-changesSpec.js
+++ b/app/addons/documents/tests/views-changesSpec.js
@@ -28,7 +28,7 @@ define([
 
     handlerSpy = sinon.spy(Views.Changes.prototype, 'toggleJson');
 
-    beforeEach(function () {
+    beforeEach(function (done) {
       var database = new Databases.Model({id: 'bla'});
       database.buildChanges({descending: 'true', limit: '100', include_docs: 'true'} );
       filteredView = new Views.Changes({
@@ -36,10 +36,11 @@ define([
       });
 
       view = new Views.Changes({
-        model: model
+        model: model,
+        useRAF: false
       });
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(view);
+      viewSandbox.renderView(view, done);
     });
 
     afterEach(function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/fauxton/tests/baseSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/tests/baseSpec.js b/app/addons/fauxton/tests/baseSpec.js
index a7ff7a1..b9814bc 100644
--- a/app/addons/fauxton/tests/baseSpec.js
+++ b/app/addons/fauxton/tests/baseSpec.js
@@ -88,15 +88,19 @@ describe('Fauxton Notifications', function () {
       delete window.fauxton_xss_test_escaped;
     });
 
-    it('should be able to render unescaped', function () {
+    it('should be able to render unescaped', function (done) {
       var view = FauxtonAPI.addNotification({
         msg: '<script>window.fauxton_xss_test_unescaped = true;</script>',
         selector: 'body',
         escape: false
       });
-      view.$el.remove();
-      assert.ok(window.fauxton_xss_test_unescaped);
-      delete window.fauxton_xss_test_unescaped;
+
+      view.promise().then(function () {
+        view.$el.remove();
+        assert.ok(window.fauxton_xss_test_unescaped);
+        delete window.fauxton_xss_test_unescaped;
+        done();
+      });
     });
 
     it('should render escaped if the escape value is not explicitly false,' +

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/fauxton/tests/filterViewSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/tests/filterViewSpec.js b/app/addons/fauxton/tests/filterViewSpec.js
index 1eefa05..3a566dc 100644
--- a/app/addons/fauxton/tests/filterViewSpec.js
+++ b/app/addons/fauxton/tests/filterViewSpec.js
@@ -27,13 +27,15 @@ define([
       FauxtonAPI.router.triggerRouteEvent = function () {};
     }
 
-    beforeEach(function () {
+    beforeEach(function (done) {
       filterView = new Components.FilterView({
         eventNamespace: 'mynamespace'
       });
 
+      Components.FilterItemView.prototype.useRAF = false;
+
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(filterView);
+      viewSandbox.renderView(filterView, done);
     });
 
     afterEach(function () {
@@ -43,7 +45,6 @@ define([
     it('should add filter markup', function () {
       filterView.$('[name="filter"]').val('i was a lonely filter');
       filterView.$('.js-filter-form').submit();
-
       filterView.$('[name="filter"]').val('i am a filter');
       filterView.$('.js-filter-form').submit();
       assert.equal(2, filterView.$('.js-remove-filter').length);
@@ -73,7 +74,8 @@ define([
     it('should add tooltips when a text for it is defined', function () {
       filterView = new Components.FilterView({
         eventNamespace: 'mynamespace',
-        tooltipText: 'ente ente'
+        tooltipText: 'ente ente',
+        useRAF: false
       });
       viewSandbox.renderView(filterView);
       assert.equal(1, filterView.$('.js-filter-tooltip').length);

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/fauxton/tests/paginateSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/fauxton/tests/paginateSpec.js b/app/addons/fauxton/tests/paginateSpec.js
index d336ea8..f97b255 100644
--- a/app/addons/fauxton/tests/paginateSpec.js
+++ b/app/addons/fauxton/tests/paginateSpec.js
@@ -22,7 +22,7 @@ define([
 
   describe('IndexPaginate', function () {
     var viewSandbox, paginate, collection, navigateMock;
-    beforeEach(function () {
+    beforeEach(function (done) {
       collection = new Models.IndexCollection([{
         id:'myId1',
         doc: 'num1'
@@ -43,7 +43,7 @@ define([
         canShowNextfn: function () { return true;}
       });
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(paginate); 
+      viewSandbox.renderView(paginate, done); 
     });
 
     afterEach(function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/addons/permissions/tests/viewsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/permissions/tests/viewsSpec.js b/app/addons/permissions/tests/viewsSpec.js
index c22d405..147cee4 100644
--- a/app/addons/permissions/tests/viewsSpec.js
+++ b/app/addons/permissions/tests/viewsSpec.js
@@ -21,7 +21,7 @@ define([
   describe('Permission View', function () {
     var security, section, viewSandbox;
 
-    beforeEach(function () {
+    beforeEach(function (done) {
       security = new Models.Security({'admins': {
         'names': ['_user'],
         'roles': []
@@ -34,7 +34,7 @@ define([
       });
 
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(section); 
+      viewSandbox.renderView(section, done); 
     });
 
     afterEach(function () {
@@ -67,7 +67,7 @@ define([
         security,
         viewSandbox;
 
-    beforeEach(function () {
+    beforeEach(function (done) {
       security = new Models.Security({'admins': {
         'names': ['_user'],
         'roles': []
@@ -80,7 +80,7 @@ define([
       });
 
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(section); 
+      viewSandbox.renderView(section, done); 
     });
 
     afterEach(function () {
@@ -130,13 +130,13 @@ define([
     var item,
         viewSandbox;
 
-    beforeEach(function () {
+    beforeEach(function (done) {
       item = new Views.PermissionItem({
         item: '_user'
       });
 
       viewSandbox = new ViewSandbox();
-      viewSandbox.renderView(item); 
+      viewSandbox.renderView(item, done); 
     });
 
     afterEach(function () {

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/core/base.js
----------------------------------------------------------------------
diff --git a/app/core/base.js b/app/core/base.js
index 9fbb7a0..b9d0f7f 100644
--- a/app/core/base.js
+++ b/app/core/base.js
@@ -62,9 +62,7 @@ function(Backbone, LayoutManager) {
     manage: true,
     disableLoader: false,
 
-    // Either tests or source are expecting synchronous renders, so disable
-    // asynchronous rendering improvements.
-    useRAF: false,
+    useRAF: true,
 
     forceRender: function () {
       this.hasRendered = false;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/core/layout.js
----------------------------------------------------------------------
diff --git a/app/core/layout.js b/app/core/layout.js
index 0a45e62..8d589e7 100644
--- a/app/core/layout.js
+++ b/app/core/layout.js
@@ -10,31 +10,86 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define(function(require, exports, module) {
-  var Backbone = require("backbone");
-  var LayoutManager = require("plugins/backbone.layoutmanager");
+define([
+  "backbone", 
+  "plugins/backbone.layoutmanager"
+], function(Backbone) {
 
-  var Layout = Backbone.Layout.extend({
-    template: "templates/layouts/with_sidebar",
+  // A wrapper of the main Backbone.layoutmanager
+  // Allows the main layout of the page to be changed by any plugin.
+  var Layout = function () {
+    this.layout = new Backbone.Layout({
+      template: "templates/layouts/with_sidebar"
+    });
 
-    // Either tests or source are expecting synchronous renders, so disable
-    // asynchronous rendering improvements.
-    useRAF: false,
+    this.layoutViews = {};
+    //this views don't ever get removed. An example of this is the main navigation sidebar
+    this.permanentViews = {};
+    this.el = this.layout.el;
+  };
+
+  Layout.configure = function (options) {
+    Backbone.Layout.configure(options);
+  };
+
+  // creatings the dashboard object same way backbone does
+  _.extend(Layout.prototype, {
+    render: function () {
+      return this.layout.render();
+    },
 
     setTemplate: function(template) {
       if (template.prefix){
-        this.template = template.prefix + template.name;
+        this.layout.template = template.prefix + template.name;
       } else{
-        this.template = "templates/layouts/" + template;
+        this.layout.template = "templates/layouts/" + template;
       }
-
       // If we're changing layouts all bets are off, so kill off all the
       // existing views in the layout.
-      this.removeView();
+      _.each(this.layoutViews, function(view){view.removeView();});
+      this.layoutViews = {};
       this.render();
+    },
+
+    setView: function(selector, view, keep) {
+      this.layout.setView(selector, view, false);
+
+      if (!keep) {
+        this.layoutViews[selector] = view;
+      } else {
+        this.permanentViews[selector] = view;
+      }
+
+      return view;
+    },
+
+    renderView: function(selector) {
+      var view = this.layoutViews[selector];
+      if (!view) {
+        return false;
+      } else {
+        return view.render();
+      }
+    },
+
+    removeView: function (selector) {
+      var view = this.layout.getView(selector);
+
+      if (!view) {
+        return false;
+        }
+
+      this.layout.removeView(selector);
+      
+      if (this.layoutViews[selector]) {
+        delete this.layoutViews[selector];
+      }
+
+      return true;
     }
+
   });
 
-  module.exports = Layout;
+  return Layout;
 
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/core/routeObject.js
----------------------------------------------------------------------
diff --git a/app/core/routeObject.js b/app/core/routeObject.js
index f8a238f..898afcb 100644
--- a/app/core/routeObject.js
+++ b/app/core/routeObject.js
@@ -149,12 +149,17 @@ function(FauxtonAPI, Backbone) {
     },
 
     renderViewOnLayout: function(viewInfo, resp, xhr){
-      var masterLayout = viewInfo.masterLayout;
+      var masterLayout = viewInfo.masterLayout,
+          triggerBroadcast = _.bind(this.triggerBroadcast, this);
 
       masterLayout.setView(viewInfo.selector, viewInfo.view);
-      masterLayout.renderView(viewInfo.selector);
+      var promise = masterLayout.renderView(viewInfo.selector).promise();
 
-      this.triggerBroadcast('afterRender', viewInfo.view, viewInfo.selector);
+      promise.then(function () {
+        triggerBroadcast('afterRender', viewInfo.view, viewInfo.selector);
+      });
+
+      return promise;
     },
 
     establishError: function(resp){

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/core/tests/layoutSpec.js
----------------------------------------------------------------------
diff --git a/app/core/tests/layoutSpec.js b/app/core/tests/layoutSpec.js
index 2b87173..1ae5675 100644
--- a/app/core/tests/layoutSpec.js
+++ b/app/core/tests/layoutSpec.js
@@ -27,24 +27,24 @@ define([
       it("Should set template without prefix", function () {
         layout.setTemplate('myTemplate');
 
-        assert.equal(layout.template, 'templates/layouts/myTemplate');
+        assert.equal(layout.layout.template, 'templates/layouts/myTemplate');
 
       });
 
       it("Should set template with prefix", function () {
         layout.setTemplate({name: 'myTemplate', prefix: 'myPrefix/'});
 
-        assert.equal(layout.template, 'myPrefix/myTemplate');
+        assert.equal(layout.layout.template, 'myPrefix/myTemplate');
       });
 
       it("Should remove old views", function () {
-        var view = new FauxtonAPI.Layout();
+        var view = new FauxtonAPI.View();
 
-        layout.setView('selector', view);
+        layout.setView('#selector', view);
 
-        var mockRemove = sinon.spy(view, 'remove');
+        var removeSpy = sinon.spy(view, 'removeView');
         layout.setTemplate('myTemplate');
-        assert.ok(mockRemove.calledOnce);
+        assert.ok(removeSpy.calledOnce);
 
       });
 
@@ -58,5 +58,72 @@ define([
       });
 
     });
+
+    describe('#setView', function () {
+      var view;
+      beforeEach(function () {
+        view = new FauxtonAPI.View();
+      });
+
+      it("Should keep record of view", function () {
+        layout.setView('.selector', view);
+        assert.equal(view, layout.layoutViews['.selector']);
+      });
+
+      it("Should not keep record of view if keep is false", function () {
+        layout.setView('.selector', view, true);
+        assert.ok(_.isUndefined(layout.layoutViews['.selector']));
+        assert.equal(view, layout.permanentViews['.selector']);
+      });
+
+    });
+
+    describe('#removeView', function () {
+      var view;
+
+      beforeEach(function () {
+        view = new FauxtonAPI.View();
+        layout.setView('#selector', view);
+      });
+
+      it('Should remove view from layout', function () {
+        var removeSpy = sinon.spy(layout.layout, 'removeView');
+
+        layout.removeView('#selector');
+        assert.ok(removeSpy.calledOnce);
+      });
+
+      it('Should remove view from list of active views', function () {
+        layout.setView('#selector', view);
+        layout.removeView('#selector');
+
+        assert.ok(_.isUndefined(layout.layoutViews['#selector']));
+      });
+
+      it("should return false if view doesn't exist", function () {
+        assert.notOk(layout.removeView('#fake'));
+      });
+
+    });
+
+    describe('#renderView', function () {
+      var view;
+
+      beforeEach(function () {
+        view = new FauxtonAPI.View();
+        layout.setView('#selector', view);
+      });
+
+      it('should render view', function () {
+        var renderSpy = sinon.spy(view, 'render');
+        layout.renderView('#selector');
+        assert.ok(renderSpy.calledOnce);
+      });
+
+      it('should not render a non-existing view', function () {
+        assert.notOk(layout.renderView('#fake'));
+      });
+
+    });
   });
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/app/core/tests/routeObjectSpec.js
----------------------------------------------------------------------
diff --git a/app/core/tests/routeObjectSpec.js b/app/core/tests/routeObjectSpec.js
index 2fca94d..f3f4b48 100644
--- a/app/core/tests/routeObjectSpec.js
+++ b/app/core/tests/routeObjectSpec.js
@@ -71,7 +71,13 @@ define([
             viewSpy = sinon.stub(view, "establish");
         
         view.hasRendered = false;
+        view.promise = function () { 
+          var promise = $.Deferred();
+          promise.resolve();
+          return promise;
+        };
         getViewsSpy.returns({'#view': view});
+        mockLayout.renderView = function () { return view;};
 
         testRouteObject.renderWith('the-route', mockLayout, 'args');
         assert.ok(viewSpy.calledOnce, 'Should render view');

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/2283352a/test/mocha/testUtils.js
----------------------------------------------------------------------
diff --git a/test/mocha/testUtils.js b/test/mocha/testUtils.js
index 2c418f9..6b9e57f 100644
--- a/test/mocha/testUtils.js
+++ b/test/mocha/testUtils.js
@@ -29,15 +29,19 @@ function(FauxtonAPI,chai, sinonChai) {
       this.$ = this.$el.find;
     },
     views: [],
-    renderView: function (view) {
+    renderView: function (view, done) {
       this.views.push(view);
       this.$el.append(view.el);
       view.render();
+      if (done) { 
+        view.promise().done(function () { done(); });
+      }
+      return view;
     },
 
     remove: function () {
       _.each(this.views, function (view) {
-        view.remove();
+        view.removeView();
       }, this);
     }
   });