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 2016/05/31 07:58:49 UTC

[21/27] fauxton commit: updated refs/heads/master to 0ca35da

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/cors/tests/componentsSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/cors/tests/componentsSpec.react.jsx b/app/addons/cors/tests/componentsSpec.react.jsx
index 6446eef..0ab9b1b 100644
--- a/app/addons/cors/tests/componentsSpec.react.jsx
+++ b/app/addons/cors/tests/componentsSpec.react.jsx
@@ -9,233 +9,229 @@
 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 // License for the specific language governing permissions and limitations under
 // the License.
-define([
-  '../../../core/api',
-  '../components.react',
-  '../actions',
-  '../resources',
-  '../stores',
-  '../../../../test/mocha/testUtils',
-  "react",
-  'react-dom',
-  'react-addons-test-utils',
-  'sinon'
-], function (FauxtonAPI, Views, Actions, Resources, Stores, utils, React, ReactDOM, TestUtils, sinon) {
-
-  FauxtonAPI.router = new FauxtonAPI.Router([]);
-  var assert = utils.assert;
-  var corsStore = Stores.corsStore;
-
-  describe('CORS Components', function () {
-
-
-    describe('CorsController', function () {
-      var container, corsEl, saveStub;
-
-      beforeEach(function () {
-        container = document.createElement('div');
-        corsStore._origins = ['http://hello.com'];
-        corsStore._node = 'node2@127.0.0.1';
-        corsStore._isEnabled = true;
-        corsStore._configChanged = true;
-        corsEl = TestUtils.renderIntoDocument(<Views.CORSController />, container);
-        //stub this out so it doesn't keep trying to save cors and crash phantomjs
-        saveStub = sinon.stub(corsEl, 'save');
-      });
+import FauxtonAPI from "../../../core/api";
+import Views from "../components.react";
+import Actions from "../actions";
+import Resources from "../resources";
+import Stores from "../stores";
+import utils from "../../../../test/mocha/testUtils";
+import React from "react";
+import ReactDOM from "react-dom";
+import TestUtils from "react-addons-test-utils";
+import sinon from "sinon";
+
+FauxtonAPI.router = new FauxtonAPI.Router([]);
+var assert = utils.assert;
+var corsStore = Stores.corsStore;
+
+describe('CORS Components', function () {
+
+
+  describe('CorsController', function () {
+    var container, corsEl, saveStub;
+
+    beforeEach(function () {
+      container = document.createElement('div');
+      corsStore._origins = ['http://hello.com'];
+      corsStore._node = 'node2@127.0.0.1';
+      corsStore._isEnabled = true;
+      corsStore._configChanged = true;
+      corsEl = TestUtils.renderIntoDocument(<Views.CORSController />, container);
+      //stub this out so it doesn't keep trying to save cors and crash phantomjs
+      saveStub = sinon.stub(corsEl, 'save');
+    });
 
-      afterEach(function () {
-        utils.restore(Actions.toggleLoadingBarsToEnabled);
-        utils.restore(corsEl.save);
+    afterEach(function () {
+      utils.restore(Actions.toggleLoadingBarsToEnabled);
+      utils.restore(corsEl.save);
 
-        ReactDOM.unmountComponentAtNode(container);
-        window.confirm.restore && window.confirm.restore();
-      });
+      ReactDOM.unmountComponentAtNode(container);
+      window.confirm.restore && window.confirm.restore();
+    });
 
-      it('confirms user change from restricted origin to disabled cors', function () {
-        var spy = sinon.stub(window, 'confirm');
-        spy.returns(false);
-        corsEl.state.isAllOrigins = false;
-        corsEl.state.corsEnabled = true;
-        corsEl.enableCorsChange();
-        assert.ok(spy.calledOnce);
-      });
+    it('confirms user change from restricted origin to disabled cors', function () {
+      var spy = sinon.stub(window, 'confirm');
+      spy.returns(false);
+      corsEl.state.isAllOrigins = false;
+      corsEl.state.corsEnabled = true;
+      corsEl.enableCorsChange();
+      assert.ok(spy.calledOnce);
+    });
 
-      it('does not confirm for selected origins are emtpy for disabled cors change', function () {
-        var spy = sinon.stub(window, 'confirm');
-        sinon.stub(Actions, 'toggleLoadingBarsToEnabled');
-        spy.returns(false);
-        corsEl.state.corsEnabled = true;
-        corsEl.state.isAllOrigins = false;
-        corsEl.state.origins = [];
-        corsEl.enableCorsChange();
-        assert.notOk(spy.calledOnce);
-      });
+    it('does not confirm for selected origins are emtpy for disabled cors change', function () {
+      var spy = sinon.stub(window, 'confirm');
+      sinon.stub(Actions, 'toggleLoadingBarsToEnabled');
+      spy.returns(false);
+      corsEl.state.corsEnabled = true;
+      corsEl.state.isAllOrigins = false;
+      corsEl.state.origins = [];
+      corsEl.enableCorsChange();
+      assert.notOk(spy.calledOnce);
+    });
 
-      it('confirms user change when moving from selected origins to all origins', function () {
-        var spy = sinon.stub(window, 'confirm');
-        spy.returns(false);
-        corsEl.state.corsEnabled = true;
-        corsEl.state.isAllOrigins = false;
-        corsEl.originChange(true);
-        assert.ok(spy.calledOnce);
-      });
+    it('confirms user change when moving from selected origins to all origins', function () {
+      var spy = sinon.stub(window, 'confirm');
+      spy.returns(false);
+      corsEl.state.corsEnabled = true;
+      corsEl.state.isAllOrigins = false;
+      corsEl.originChange(true);
+      assert.ok(spy.calledOnce);
+    });
 
-      it('does not confirm all origins change if selected origins are emtpy', function () {
-        var spy = sinon.stub(window, 'confirm');
-        sinon.stub(Actions, 'toggleLoadingBarsToEnabled');
-        spy.returns(false);
-        corsEl.state.corsEnabled = true;
-        corsEl.state.isAllOrigins = false;
-        corsEl.state.origins = [];
-        corsEl.originChange(true);
+    it('does not confirm all origins change if selected origins are emtpy', function () {
+      var spy = sinon.stub(window, 'confirm');
+      sinon.stub(Actions, 'toggleLoadingBarsToEnabled');
+      spy.returns(false);
+      corsEl.state.corsEnabled = true;
+      corsEl.state.isAllOrigins = false;
+      corsEl.state.origins = [];
+      corsEl.originChange(true);
 
-        assert.notOk(spy.calledOnce);
-      });
+      assert.notOk(spy.calledOnce);
+    });
 
-      it('shows loading bars', function () {
-        Actions.toggleLoadingBarsToEnabled(true);
-        assert.equal($(ReactDOM.findDOMNode(corsEl)).find('.loading-lines').length, 1);
-      });
+    it('shows loading bars', function () {
+      Actions.toggleLoadingBarsToEnabled(true);
+      assert.equal($(ReactDOM.findDOMNode(corsEl)).find('.loading-lines').length, 1);
+    });
 
-      it('hides loading bars', function () {
-        Actions.toggleLoadingBarsToEnabled(false);
+    it('hides loading bars', function () {
+      Actions.toggleLoadingBarsToEnabled(false);
 
-        assert.equal($(ReactDOM.findDOMNode(corsEl)).find('.loading-lines').length, 0);
-      });
+      assert.equal($(ReactDOM.findDOMNode(corsEl)).find('.loading-lines').length, 0);
     });
+  });
 
-    describe('OriginInput', function () {
-      var container, inputEl, addOrigin;
-      var newOrigin = 'http://new-site.com';
+  describe('OriginInput', function () {
+    var container, inputEl, addOrigin;
+    var newOrigin = 'http://new-site.com';
 
-      beforeEach(function () {
-        addOrigin = sinon.spy();
-        container = document.createElement('div');
-        inputEl = TestUtils.renderIntoDocument(<Views.OriginInput isVisible={true} addOrigin={addOrigin}/>, container);
-      });
+    beforeEach(function () {
+      addOrigin = sinon.spy();
+      container = document.createElement('div');
+      inputEl = TestUtils.renderIntoDocument(<Views.OriginInput isVisible={true} addOrigin={addOrigin}/>, container);
+    });
 
-      afterEach(function () {
-        utils.restore(Resources.validateCORSDomain);
-        utils.restore(FauxtonAPI.addNotification);
-        ReactDOM.unmountComponentAtNode(container);
-      });
+    afterEach(function () {
+      utils.restore(Resources.validateCORSDomain);
+      utils.restore(FauxtonAPI.addNotification);
+      ReactDOM.unmountComponentAtNode(container);
+    });
 
-      it('calls validates each domain', function () {
-        var spy = sinon.spy(Resources, 'validateCORSDomain');
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: newOrigin}});
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
-        assert.ok(spy.calledWith(newOrigin));
-      });
+    it('calls validates each domain', function () {
+      var spy = sinon.spy(Resources, 'validateCORSDomain');
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: newOrigin}});
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
+      assert.ok(spy.calledWith(newOrigin));
+    });
 
-      it('calls addOrigin on add click with valid domain', function () {
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: newOrigin}});
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
-        assert.ok(addOrigin.calledWith(newOrigin));
-      });
+    it('calls addOrigin on add click with valid domain', function () {
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: newOrigin}});
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
+      assert.ok(addOrigin.calledWith(newOrigin));
+    });
 
-      it('shows notification if origin is not valid', function () {
-        var spy = sinon.spy(FauxtonAPI, 'addNotification');
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: 'badOrigin'}});
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
-        assert.ok(spy.calledOnce);
-      });
+    it('shows notification if origin is not valid', function () {
+      var spy = sinon.spy(FauxtonAPI, 'addNotification');
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: 'badOrigin'}});
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
+      assert.ok(spy.calledOnce);
     });
+  });
 
-    describe('Origins', function () {
-      var container, originEl, changeOrigin;
+  describe('Origins', function () {
+    var container, originEl, changeOrigin;
 
-      beforeEach(function () {
-        changeOrigin = sinon.spy();
-        container = document.createElement('div');
-        originEl = TestUtils.renderIntoDocument(<Views.Origins corsEnabled={true} isAllOrigins={false} originChange={changeOrigin}/>, container);
-      });
+    beforeEach(function () {
+      changeOrigin = sinon.spy();
+      container = document.createElement('div');
+      originEl = TestUtils.renderIntoDocument(<Views.Origins corsEnabled={true} isAllOrigins={false} originChange={changeOrigin}/>, container);
+    });
 
-      afterEach(function () {
-        ReactDOM.unmountComponentAtNode(container);
-      });
+    afterEach(function () {
+      ReactDOM.unmountComponentAtNode(container);
+    });
 
-      it('calls change Origin on all origins selected', function () {
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(originEl)).find('input[value="all"]')[0]);
-        assert.ok(changeOrigin.calledWith(true));
-      });
+    it('calls change Origin on all origins selected', function () {
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originEl)).find('input[value="all"]')[0]);
+      assert.ok(changeOrigin.calledWith(true));
+    });
 
-      it('calls changeOrigin() when you switch from "Allow All Origins" to "Select List of Origins"', function () {
-        //changeOrigin(true) = sets origins to ['*']
-        //changeOrigin(false) = sets origins to [] (an empty array which user can populate with URLs)
+    it('calls changeOrigin() when you switch from "Allow All Origins" to "Select List of Origins"', function () {
+      //changeOrigin(true) = sets origins to ['*']
+      //changeOrigin(false) = sets origins to [] (an empty array which user can populate with URLs)
 
-        //this test begins with 'select origins' checked,
-        //1. render radio buttons with 'all origins'
-        originEl = TestUtils.renderIntoDocument(<Views.Origins corsEnabled={true} isAllOrigins={true} originChange={changeOrigin}/>, container);
-        //2. switch back to 'select origins'
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(originEl)).find('input[value="selected"]')[0]);
-        assert.ok(changeOrigin.calledWith(false));
-      });
+      //this test begins with 'select origins' checked,
+      //1. render radio buttons with 'all origins'
+      originEl = TestUtils.renderIntoDocument(<Views.Origins corsEnabled={true} isAllOrigins={true} originChange={changeOrigin}/>, container);
+      //2. switch back to 'select origins'
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originEl)).find('input[value="selected"]')[0]);
+      assert.ok(changeOrigin.calledWith(false));
     });
+  });
 
-    describe('OriginRow', function () {
-      var container, originTableEl, origin, deleteOrigin, updateOrigin;
+  describe('OriginRow', function () {
+    var container, originTableEl, origin, deleteOrigin, updateOrigin;
 
-      beforeEach(function () {
-        deleteOrigin = sinon.spy();
-        updateOrigin = sinon.spy();
-        container = document.createElement('div');
-        origin = 'https://hello.com';
-        //because OriginRow is inside a table have to render the whole table to test
-        originTableEl = TestUtils.renderIntoDocument(<Views.OriginTable updateOrigin={updateOrigin} deleteOrigin={deleteOrigin} isVisible={true} origins={[origin]}/>, container);
-      });
+    beforeEach(function () {
+      deleteOrigin = sinon.spy();
+      updateOrigin = sinon.spy();
+      container = document.createElement('div');
+      origin = 'https://hello.com';
+      //because OriginRow is inside a table have to render the whole table to test
+      originTableEl = TestUtils.renderIntoDocument(<Views.OriginTable updateOrigin={updateOrigin} deleteOrigin={deleteOrigin} isVisible={true} origins={[origin]}/>, container);
+    });
 
-      afterEach(function () {
-        window.confirm.restore && window.confirm.restore();
-        Actions.deleteOrigin.restore && Actions.deleteOrigin.restore();
-        ReactDOM.unmountComponentAtNode(container);
-        Actions.hideDeleteDomainModal();
-      });
+    afterEach(function () {
+      window.confirm.restore && window.confirm.restore();
+      Actions.deleteOrigin.restore && Actions.deleteOrigin.restore();
+      ReactDOM.unmountComponentAtNode(container);
+      Actions.hideDeleteDomainModal();
+    });
 
-      it('should show confirm modal on delete', function () {
-        assert.equal($('body').find('.confirmation-modal').length, 0);
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-trash')[0]);
-        assert.notEqual($('body').find('.confirmation-modal').length, 1); // a little sneaky.
-      });
+    it('should show confirm modal on delete', function () {
+      assert.equal($('body').find('.confirmation-modal').length, 0);
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-trash')[0]);
+      assert.notEqual($('body').find('.confirmation-modal').length, 1); // a little sneaky.
+    });
 
-      it('does not throw on origins being undefined', function () {
-        TestUtils.renderIntoDocument(
-          <Views.OriginTable
-            updateOrigin={updateOrigin}
-            isVisible={true}
-            origins={false} />,
-          container
-        );
-      });
+    it('does not throw on origins being undefined', function () {
+      TestUtils.renderIntoDocument(
+        <Views.OriginTable
+          updateOrigin={updateOrigin}
+          isVisible={true}
+          origins={false} />,
+        container
+      );
+    });
 
-      it('should change origin to input on edit click', function () {
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
-        assert.ok($(ReactDOM.findDOMNode(originTableEl)).find('input').length === 1);
-      });
+    it('should change origin to input on edit click', function () {
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
+      assert.ok($(ReactDOM.findDOMNode(originTableEl)).find('input').length === 1);
+    });
 
-      it('should update origin on update clicked', function () {
-        var updatedOrigin = 'https://updated-origin.com';
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(originTableEl)).find('input')[0], {
-          target: {
-            value: updatedOrigin
-          }
-        });
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.btn')[0]);
-        assert.ok(updateOrigin.calledWith(updatedOrigin));
+    it('should update origin on update clicked', function () {
+      var updatedOrigin = 'https://updated-origin.com';
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originTableEl)).find('input')[0], {
+        target: {
+          value: updatedOrigin
+        }
       });
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.btn')[0]);
+      assert.ok(updateOrigin.calledWith(updatedOrigin));
+    });
 
-      it('should not update origin on update clicked with bad origin', function () {
-        var updatedOrigin = 'updated-origin';
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
-        TestUtils.Simulate.change($(ReactDOM.findDOMNode(originTableEl)).find('input')[0], {
-          target: {
-            value: updatedOrigin
-          }
-        });
-        TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.btn')[0]);
-        assert.notOk(updateOrigin.calledOnce);
+    it('should not update origin on update clicked with bad origin', function () {
+      var updatedOrigin = 'updated-origin';
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
+      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originTableEl)).find('input')[0], {
+        target: {
+          value: updatedOrigin
+        }
       });
-
+      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.btn')[0]);
+      assert.notOk(updateOrigin.calledOnce);
     });
 
   });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/cors/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/cors/tests/resourcesSpec.js b/app/addons/cors/tests/resourcesSpec.js
index e271386..9c02a7e 100644
--- a/app/addons/cors/tests/resourcesSpec.js
+++ b/app/addons/cors/tests/resourcesSpec.js
@@ -9,70 +9,67 @@
 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 // License for the specific language governing permissions and limitations under
 // the License.
-define([
-  '../../../app',
-  '../../../../test/mocha/testUtils',
-  '../resources',
-], function (app, testUtils, CORS) {
-  var assert = testUtils.assert;
+import app from "../../../app";
+import testUtils from "../../../../test/mocha/testUtils";
+import CORS from "../resources";
+var assert = testUtils.assert;
 
-  describe('Cors Config Model', function () {
-    var cors;
+describe('Cors Config Model', function () {
+  var cors;
 
-    beforeEach(function () {
-      cors = new CORS.Config(null, {node: 'node2@127.0.0.1'});
-    });
-
-    it('Splits up origins into array', function () {
-      var origins = ['http://hello.com', 'http://another.co.a'];
-      cors.set(cors.parse({origins: origins.join(',')}));
-      assert.deepEqual(cors.get('origins'), origins);
-    });
+  beforeEach(function () {
+    cors = new CORS.Config(null, {node: 'node2@127.0.0.1'});
+  });
 
-    it('returns empty array for undefined', function () {
-      var origins = { origins : undefined };
-      cors.set(cors.parse(origins));
-      assert.deepEqual(cors.get('origins'), []);
-    });
+  it('Splits up origins into array', function () {
+    var origins = ['http://hello.com', 'http://another.co.a'];
+    cors.set(cors.parse({origins: origins.join(',')}));
+    assert.deepEqual(cors.get('origins'), origins);
+  });
 
-    it('does not return an empty string (empty origin), when "specific origins" is set, but there are no domains on that list', function () {
-        var emptyOrigins = {origins: ''};
-        cors.set(cors.parse(emptyOrigins));
-        assert.deepEqual(cors.get('origins'), []);
-      });
+  it('returns empty array for undefined', function () {
+    var origins = { origins : undefined };
+    cors.set(cors.parse(origins));
+    assert.deepEqual(cors.get('origins'), []);
+  });
 
-    it('allows valid domains', function () {
-      var urls = [
-        'http://something.com',
-        'https://a.ca',
-        'https://something.com:8000',
-        'https://www.some-valid-domain.com:80',
-        'http://localhost',
-        'https://localhost',
-        'http://192.168.1.113',
-        'http://192.168.1.113:1337'
-      ];
-      _.each(urls, function (url) {
-        assert.isTrue(CORS.validateCORSDomain(url));
-      });
+  it('does not return an empty string (empty origin), when "specific origins" is set, but there are no domains on that list', function () {
+      var emptyOrigins = {origins: ''};
+      cors.set(cors.parse(emptyOrigins));
+      assert.deepEqual(cors.get('origins'), []);
     });
 
-    it('fails on non http/https domains', function () {
-      var urls = [
-        'whoahnellythisaintright',
-        'ftp://site.com'
-      ];
-      _.each(urls, function (url) {
-        assert.isFalse(CORS.validateCORSDomain(url));
-      });
+  it('allows valid domains', function () {
+    var urls = [
+      'http://something.com',
+      'https://a.ca',
+      'https://something.com:8000',
+      'https://www.some-valid-domain.com:80',
+      'http://localhost',
+      'https://localhost',
+      'http://192.168.1.113',
+      'http://192.168.1.113:1337'
+    ];
+    _.each(urls, function (url) {
+      assert.isTrue(CORS.validateCORSDomain(url));
     });
+  });
 
-    it('normalizes common cases, like accidentally added subfolders', function () {
-      assert.equal('https://foo.com', CORS.normalizeUrls('https://foo.com/blerg'));
-      assert.equal('https://192.168.1.113', CORS.normalizeUrls('https://192.168.1.113/blerg'));
-      assert.equal('https://foo.com:1337', CORS.normalizeUrls('https://foo.com:1337/blerg'));
-      assert.equal('https://foo.com', CORS.normalizeUrls('https://foo.com'));
+  it('fails on non http/https domains', function () {
+    var urls = [
+      'whoahnellythisaintright',
+      'ftp://site.com'
+    ];
+    _.each(urls, function (url) {
+      assert.isFalse(CORS.validateCORSDomain(url));
     });
+  });
 
+  it('normalizes common cases, like accidentally added subfolders', function () {
+    assert.equal('https://foo.com', CORS.normalizeUrls('https://foo.com/blerg'));
+    assert.equal('https://192.168.1.113', CORS.normalizeUrls('https://192.168.1.113/blerg'));
+    assert.equal('https://foo.com:1337', CORS.normalizeUrls('https://foo.com:1337/blerg'));
+    assert.equal('https://foo.com', CORS.normalizeUrls('https://foo.com'));
   });
+
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/cors/tests/storesSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/cors/tests/storesSpec.js b/app/addons/cors/tests/storesSpec.js
index a603e0d..556e8f0 100644
--- a/app/addons/cors/tests/storesSpec.js
+++ b/app/addons/cors/tests/storesSpec.js
@@ -9,93 +9,89 @@
 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 // License for the specific language governing permissions and limitations under
 // the License.
-define([
-  '../../../app',
-  '../../../../test/mocha/testUtils',
-  '../../../core/api',
-  '../stores',
-], function (app, testUtils, FauxtonAPI, Stores) {
-  var assert = testUtils.assert;
-  var store = Stores.corsStore;
-
-  describe('CORS store', function () {
-
-    describe('isAllOrigins', function () {
-
-      it('returns true for all origins', function () {
-        store._origins = ['*'];
-
-        assert.ok(store.isAllOrigins());
-      });
-
-      it('returns false for specific origins', function () {
-        store._origins = ['https://hello.com', 'http://another.com'];
-        assert.notOk(store.isAllOrigins());
-      });
-
-      it('returns false for empty array', function () {
-        store._origins = [];
-        assert.notOk(store.isAllOrigins());
-      });
+import app from "../../../app";
+import testUtils from "../../../../test/mocha/testUtils";
+import FauxtonAPI from "../../../core/api";
+import Stores from "../stores";
+var assert = testUtils.assert;
+var store = Stores.corsStore;
+
+describe('CORS store', function () {
+
+  describe('isAllOrigins', function () {
+
+    it('returns true for all origins', function () {
+      store._origins = ['*'];
+
+      assert.ok(store.isAllOrigins());
     });
 
-    describe('addOrigin', function () {
+    it('returns false for specific origins', function () {
+      store._origins = ['https://hello.com', 'http://another.com'];
+      assert.notOk(store.isAllOrigins());
+    });
 
-      it('adds Origin to list', function () {
-        var origin = 'http://hello.com';
-        store._origins = [];
-        store.addOrigin(origin);
+    it('returns false for empty array', function () {
+      store._origins = [];
+      assert.notOk(store.isAllOrigins());
+    });
+  });
 
-        assert.ok(_.include(store.getOrigins(), origin));
-      });
+  describe('addOrigin', function () {
 
+    it('adds Origin to list', function () {
+      var origin = 'http://hello.com';
+      store._origins = [];
+      store.addOrigin(origin);
+
+      assert.ok(_.include(store.getOrigins(), origin));
     });
 
-    describe('originChange', function () {
+  });
 
-      it('sets origins to * for true', function () {
-        store.originChange(true);
+  describe('originChange', function () {
 
-        assert.deepEqual(store.getOrigins(), ['*']);
-      });
+    it('sets origins to * for true', function () {
+      store.originChange(true);
 
-      it('sets origins to [] for true', function () {
-        store.originChange(false);
+      assert.deepEqual(store.getOrigins(), ['*']);
+    });
 
-        assert.deepEqual(store.getOrigins(), []);
-      });
+    it('sets origins to [] for true', function () {
+      store.originChange(false);
 
+      assert.deepEqual(store.getOrigins(), []);
     });
 
-    describe('deleteOrigin', function () {
+  });
 
-      it('removes origin', function () {
-        store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
-        store.deleteOrigin('http://hello.com');
+  describe('deleteOrigin', function () {
 
-        assert.deepEqual(store.getOrigins(), ['http://first.com', 'http://second.com']);
+    it('removes origin', function () {
+      store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
+      store.deleteOrigin('http://hello.com');
 
-      });
+      assert.deepEqual(store.getOrigins(), ['http://first.com', 'http://second.com']);
 
     });
 
-    describe('update origin', function () {
+  });
 
-      it('removes old origin', function () {
-        store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
-        store.updateOrigin('http://hello123.com', 'http://hello.com');
+  describe('update origin', function () {
 
-        assert.notOk(_.include(store.getOrigins(), 'http://hello.com'));
+    it('removes old origin', function () {
+      store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
+      store.updateOrigin('http://hello123.com', 'http://hello.com');
 
-      });
+      assert.notOk(_.include(store.getOrigins(), 'http://hello.com'));
 
-      it('adds new origin', function () {
-        store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
-        store.updateOrigin('http://hello123.com', 'http://hello.com');
+    });
 
-        assert.ok(_.include(store.getOrigins(), 'http://hello123.com'));
+    it('adds new origin', function () {
+      store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
+      store.updateOrigin('http://hello123.com', 'http://hello.com');
 
-      });
+      assert.ok(_.include(store.getOrigins(), 'http://hello123.com'));
 
     });
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/actions.js b/app/addons/databases/actions.js
index 86d3279..06af7d4 100644
--- a/app/addons/databases/actions.js
+++ b/app/addons/databases/actions.js
@@ -9,131 +9,128 @@
 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 // License for the specific language governing permissions and limitations under
 // the License.
-define([
-  '../../app',
-  '../../core/api',
-  './stores',
-  './actiontypes',
-  './resources'
-],
-function (app, FauxtonAPI, Stores, ActionTypes, Resources) {
-  return {
+import app from "../../app";
+import FauxtonAPI from "../../core/api";
+import Stores from "./stores";
+import ActionTypes from "./actiontypes";
+import Resources from "./resources";
 
-    init: function (databases) {
-      var params = app.getParams();
-      var page = params.page ? parseInt(params.page, 10) : 1;
-      var perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
+export default {
 
-      this.setStartLoading();
-      FauxtonAPI.when(databases.fetch({ cache: false })).then(function () {
+  init: function (databases) {
+    var params = app.getParams();
+    var page = params.page ? parseInt(params.page, 10) : 1;
+    var perPage = FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
 
-        // if there are no databases, publish the init message anyway
-        if (!databases.paginated(page, perPage).length) {
+    this.setStartLoading();
+    FauxtonAPI.when(databases.fetch({ cache: false })).then(function () {
+
+      // if there are no databases, publish the init message anyway
+      if (!databases.paginated(page, perPage).length) {
+        FauxtonAPI.dispatch({
+          type: ActionTypes.DATABASES_INIT,
+          options: {
+            collection: [],
+            backboneCollection: databases,
+            page: page
+          }
+        });
+      }
+
+      var numComplete = 0;
+      _.each(databases.paginated(page, perPage), function (db) {
+        db.status.fetchOnce().always(function () {
+          numComplete++;
+          if (numComplete < databases.paginated(page, perPage).length) {
+            return;
+          }
           FauxtonAPI.dispatch({
             type: ActionTypes.DATABASES_INIT,
             options: {
-              collection: [],
+              collection: databases.paginated(page, perPage),
               backboneCollection: databases,
               page: page
             }
           });
-        }
-
-        var numComplete = 0;
-        _.each(databases.paginated(page, perPage), function (db) {
-          db.status.fetchOnce().always(function () {
-            numComplete++;
-            if (numComplete < databases.paginated(page, perPage).length) {
-              return;
-            }
-            FauxtonAPI.dispatch({
-              type: ActionTypes.DATABASES_INIT,
-              options: {
-                collection: databases.paginated(page, perPage),
-                backboneCollection: databases,
-                page: page
-              }
-            });
-          });
         });
-      }.bind(this));
-    },
-
-    setPage: function (page) {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.DATABASES_SETPAGE,
-        options: {
-          page: page
-        }
       });
-    },
+    }.bind(this));
+  },
 
-    setStartLoading: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.DATABASES_STARTLOADING
-      });
-    },
+  setPage: function (page) {
+    FauxtonAPI.dispatch({
+      type: ActionTypes.DATABASES_SETPAGE,
+      options: {
+        page: page
+      }
+    });
+  },
 
-    setLoadComplete: function () {
-      FauxtonAPI.dispatch({
-        type: ActionTypes.DATABASES_LOADCOMPLETE
+  setStartLoading: function () {
+    FauxtonAPI.dispatch({
+      type: ActionTypes.DATABASES_STARTLOADING
+    });
+  },
+
+  setLoadComplete: function () {
+    FauxtonAPI.dispatch({
+      type: ActionTypes.DATABASES_LOADCOMPLETE
+    });
+  },
+
+  createNewDatabase: function (databaseName) {
+    if (_.isNull(databaseName) || databaseName.trim().length === 0) {
+      FauxtonAPI.addNotification({
+        msg: 'Please enter a valid database name',
+        type: 'error',
+        clear: true
       });
-    },
+      return;
+    }
+    databaseName = databaseName.trim();
+    // name accepted, make sure prompt can be removed
+    FauxtonAPI.dispatch({
+      type: ActionTypes.DATABASES_SET_PROMPT_VISIBLE,
+      options: {
+        visible: false
+      }
+    });
 
-    createNewDatabase: function (databaseName) {
-      if (_.isNull(databaseName) || databaseName.trim().length === 0) {
+    var db = Stores.databasesStore.obtainNewDatabaseModel(databaseName);
+    FauxtonAPI.addNotification({ msg: 'Creating database.' });
+    db.save().done(function () {
         FauxtonAPI.addNotification({
-          msg: 'Please enter a valid database name',
-          type: 'error',
+          msg: 'Database created successfully',
+          type: 'success',
           clear: true
         });
-        return;
+        var route = FauxtonAPI.urls('allDocs', 'app', app.utils.safeURLName(databaseName), '?limit=' + Resources.DocLimit);
+        app.router.navigate(route, { trigger: true });
       }
-      databaseName = databaseName.trim();
-      // name accepted, make sure prompt can be removed
-      FauxtonAPI.dispatch({
-        type: ActionTypes.DATABASES_SET_PROMPT_VISIBLE,
-        options: {
-          visible: false
-        }
-      });
-
-      var db = Stores.databasesStore.obtainNewDatabaseModel(databaseName);
-      FauxtonAPI.addNotification({ msg: 'Creating database.' });
-      db.save().done(function () {
-          FauxtonAPI.addNotification({
-            msg: 'Database created successfully',
-            type: 'success',
-            clear: true
-          });
-          var route = FauxtonAPI.urls('allDocs', 'app', app.utils.safeURLName(databaseName), '?limit=' + Resources.DocLimit);
-          app.router.navigate(route, { trigger: true });
-        }
-      ).error(function (xhr) {
-          var responseText = JSON.parse(xhr.responseText).reason;
-          FauxtonAPI.addNotification({
-            msg: 'Create database failed: ' + responseText,
-            type: 'error',
-            clear: true
-          });
-        }
-      );
-    },
-
-    jumpToDatabase: function (databaseName) {
-      if (_.isNull(databaseName) || databaseName.trim().length === 0) {
-        return;
-      }
-      databaseName = databaseName.trim();
-      if (Stores.databasesStore.doesDatabaseExist(databaseName)) {
-        var url = FauxtonAPI.urls('allDocs', 'app', app.utils.safeURLName(databaseName), "");
-        FauxtonAPI.navigate(url);
-      } else {
+    ).error(function (xhr) {
+        var responseText = JSON.parse(xhr.responseText).reason;
         FauxtonAPI.addNotification({
-          msg: 'Database does not exist.',
-          type: 'error'
+          msg: 'Create database failed: ' + responseText,
+          type: 'error',
+          clear: true
         });
       }
+    );
+  },
+
+  jumpToDatabase: function (databaseName) {
+    if (_.isNull(databaseName) || databaseName.trim().length === 0) {
+      return;
+    }
+    databaseName = databaseName.trim();
+    if (Stores.databasesStore.doesDatabaseExist(databaseName)) {
+      var url = FauxtonAPI.urls('allDocs', 'app', app.utils.safeURLName(databaseName), "");
+      FauxtonAPI.navigate(url);
+    } else {
+      FauxtonAPI.addNotification({
+        msg: 'Database does not exist.',
+        type: 'error'
+      });
     }
-  };
-});
+  }
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/actiontypes.js b/app/addons/databases/actiontypes.js
index 7be561e..9305684 100644
--- a/app/addons/databases/actiontypes.js
+++ b/app/addons/databases/actiontypes.js
@@ -9,12 +9,10 @@
 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 // License for the specific language governing permissions and limitations under
 // the License.
-define([], function () {
-  return {
-    DATABASES_INIT: 'DATABASES_INIT',
-    DATABASES_SETPAGE: 'DATABASES_SETPAGE',
-    DATABASES_SET_PROMPT_VISIBLE: 'DATABASES_SET_PROMPT_VISIBLE',
-    DATABASES_STARTLOADING: 'DATABASES_STARTLOADING',
-    DATABASES_LOADCOMPLETE: 'DATABASES_LOADCOMPLETE'
-  };
-});
+export default {
+  DATABASES_INIT: 'DATABASES_INIT',
+  DATABASES_SETPAGE: 'DATABASES_SETPAGE',
+  DATABASES_SET_PROMPT_VISIBLE: 'DATABASES_SET_PROMPT_VISIBLE',
+  DATABASES_STARTLOADING: 'DATABASES_STARTLOADING',
+  DATABASES_LOADCOMPLETE: 'DATABASES_LOADCOMPLETE'
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/base.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/base.js b/app/addons/databases/base.js
index d0a56b9..b31fcc7 100644
--- a/app/addons/databases/base.js
+++ b/app/addons/databases/base.js
@@ -10,74 +10,69 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  "../../app",
-  "../../core/api",
-  "./routes",
-  "./assets/less/databases.less"
-],
+import app from "../../app";
+import FauxtonAPI from "../../core/api";
+import Databases from "./routes";
+import "./assets/less/databases.less";
 
-function (app, FauxtonAPI, Databases) {
-
-  Databases.initialize = function () {
-    FauxtonAPI.addHeaderLink({
-      href:"#/_all_dbs",
-      title:"Databases",
-      icon: "fonticon-database",
-      className: 'databases'
-    });
-  };
-
-  // Utility functions
-  Databases.databaseUrl = function (database) {
-    var name = _.isObject(database) ? database.id : database,
-        dbname = app.utils.safeURLName(name);
+Databases.initialize = function () {
+  FauxtonAPI.addHeaderLink({
+    href:"#/_all_dbs",
+    title:"Databases",
+    icon: "fonticon-database",
+    className: 'databases'
+  });
+};
 
-    return ['/database/', dbname, '/_all_docs?limit=' + Databases.DocLimit].join('');
-  };
+// Utility functions
+Databases.databaseUrl = function (database) {
+  var name = _.isObject(database) ? database.id : database,
+      dbname = app.utils.safeURLName(name);
 
-  FauxtonAPI.registerUrls('changes', {
-    server: function (id, query) {
-      return app.host + '/' + id + '/_changes' + query;
+  return ['/database/', dbname, '/_all_docs?limit=' + Databases.DocLimit].join('');
+};
 
-    },
-    app: function (id, query) {
-      return '/database/' + id + '/_changes' + query;
-    },
+FauxtonAPI.registerUrls('changes', {
+  server: function (id, query) {
+    return app.host + '/' + id + '/_changes' + query;
 
-    apiurl: function (id, query) {
-      return window.location.origin + '/' + id + '/_changes' + query;
-    }
-  });
+  },
+  app: function (id, query) {
+    return '/database/' + id + '/_changes' + query;
+  },
 
-  FauxtonAPI.registerUrls('allDBs', {
-    app: function () {
-      return '_all_dbs';
-    }
-  });
+  apiurl: function (id, query) {
+    return window.location.origin + '/' + id + '/_changes' + query;
+  }
+});
 
-  FauxtonAPI.registerUrls('databaseBaseURL', {
-    server: function (database) {
-      return window.location.origin + '/' + database;
-    },
-    app: function (database) {
-      return '/database/' + database;
-    }
-  });
+FauxtonAPI.registerUrls('allDBs', {
+  app: function () {
+    return '_all_dbs';
+  }
+});
 
-  FauxtonAPI.registerUrls('permissions', {
-    server: function (db) {
-      return app.host + '/' + db + '/_security';
-    },
+FauxtonAPI.registerUrls('databaseBaseURL', {
+  server: function (database) {
+    return window.location.origin + '/' + database;
+  },
+  app: function (database) {
+    return '/database/' + database;
+  }
+});
 
-    app: function (db) {
-      return '/database/' + db + '/permissions';
-    },
+FauxtonAPI.registerUrls('permissions', {
+  server: function (db) {
+    return app.host + '/' + db + '/_security';
+  },
 
-    apiurl: function (db) {
-      return window.location.origin + '/' + db + '/_security';
-    }
-  });
+  app: function (db) {
+    return '/database/' + db + '/permissions';
+  },
 
-  return Databases;
+  apiurl: function (db) {
+    return window.location.origin + '/' + db + '/_security';
+  }
 });
+
+export default Databases;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/databases/components.react.jsx b/app/addons/databases/components.react.jsx
index 395130c..e4a11c5 100644
--- a/app/addons/databases/components.react.jsx
+++ b/app/addons/databases/components.react.jsx
@@ -10,401 +10,395 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../app',
-  '../../core/api',
-  'react',
-  'react-dom',
-  '../components/react-components.react',
-  '../components/stores',
-  '../components/actions',
-  '..//fauxton/components.react',
-
-  './stores',
-  './resources',
-  './actions',
-  '../../helpers'
-], function (app, FauxtonAPI, React, ReactDOM,
-  Components, ComponentsStore, ComponentsActions, FauxtonComponentsReact,
-  Stores, Resources, Actions, Helpers) {
-
-  var ToggleHeaderButton = Components.ToggleHeaderButton;
-  var databasesStore = Stores.databasesStore;
-  var deleteDbModalStore = ComponentsStore.deleteDbModalStore;
-  var DeleteDatabaseModal = Components.DeleteDatabaseModal;
-
-
-  var DatabasesController = React.createClass({
-
-    getStoreState: function () {
-      return {
-        collection: databasesStore.getCollection(),
-        loading: databasesStore.isLoading(),
-        showDeleteDatabaseModal: deleteDbModalStore.getShowDeleteDatabaseModal()
-      };
-    },
-
-    getInitialState: function () {
-      return this.getStoreState();
-    },
-
-    componentDidMount: function () {
-      databasesStore.on('change', this.onChange, this);
-      deleteDbModalStore.on('change', this.onChange, this);
-    },
-
-    componentWillUnmount: function () {
-      databasesStore.off('change', this.onChange, this);
-      deleteDbModalStore.off('change', this.onChange, this);
-    },
-
-    onChange: function () {
-      if (this.isMounted()) {
-        this.setState(this.getStoreState());
-      }
-    },
+import app from "../../app";
+import FauxtonAPI from "../../core/api";
+import React from "react";
+import ReactDOM from "react-dom";
+import Components from "../components/react-components.react";
+import ComponentsStore from "../components/stores";
+import ComponentsActions from "../components/actions";
+import FauxtonComponentsReact from "..//fauxton/components.react";
+import Stores from "./stores";
+import Resources from "./resources";
+import Actions from "./actions";
+import Helpers from "../../helpers";
+
+var ToggleHeaderButton = Components.ToggleHeaderButton;
+var databasesStore = Stores.databasesStore;
+var deleteDbModalStore = ComponentsStore.deleteDbModalStore;
+var DeleteDatabaseModal = Components.DeleteDatabaseModal;
+
+
+var DatabasesController = React.createClass({
+
+  getStoreState: function () {
+    return {
+      collection: databasesStore.getCollection(),
+      loading: databasesStore.isLoading(),
+      showDeleteDatabaseModal: deleteDbModalStore.getShowDeleteDatabaseModal()
+    };
+  },
+
+  getInitialState: function () {
+    return this.getStoreState();
+  },
+
+  componentDidMount: function () {
+    databasesStore.on('change', this.onChange, this);
+    deleteDbModalStore.on('change', this.onChange, this);
+  },
+
+  componentWillUnmount: function () {
+    databasesStore.off('change', this.onChange, this);
+    deleteDbModalStore.off('change', this.onChange, this);
+  },
+
+  onChange: function () {
+    if (this.isMounted()) {
+      this.setState(this.getStoreState());
+    }
+  },
+
+  render: function () {
+    var collection = this.state.collection;
+    var loading = this.state.loading;
+    return (
+      <DatabaseTable
+        showDeleteDatabaseModal={this.state.showDeleteDatabaseModal}
+        body={collection}
+        loading={loading} />
+    );
+  }
+});
 
-    render: function () {
-      var collection = this.state.collection;
-      var loading = this.state.loading;
+var DatabaseTable = React.createClass({
+
+  createRows: function () {
+    return _.map(this.props.body, function (item, iteration) {
       return (
-        <DatabaseTable
-          showDeleteDatabaseModal={this.state.showDeleteDatabaseModal}
-          body={collection}
-          loading={loading} />
+        <DatabaseRow
+          row={item}
+          key={iteration} />
       );
-    }
-  });
-
-  var DatabaseTable = React.createClass({
-
-    createRows: function () {
-      return _.map(this.props.body, function (item, iteration) {
-        return (
-          <DatabaseRow
-            row={item}
-            key={iteration} />
-        );
-      });
-    },
-
-    getExtensionColumns: function () {
-      var cols = FauxtonAPI.getExtensions('DatabaseTable:head');
-      return _.map(cols, function (Item, index) {
-        return <Item key={index} />;
-      });
-    },
-
-    showDeleteDatabaseModal: function (name) {
-      ComponentsActions.showDeleteDatabaseModal({
-        showDeleteModal: !this.props.showDeleteDatabaseModal.showDeleteModal
-      });
-    },
-
-    render: function () {
-      if (this.props.loading) {
-        return (
-          <div className="view">
-            <Components.LoadLines />
-          </div>
-        );
-      }
-
-      var rows = this.createRows();
+    });
+  },
+
+  getExtensionColumns: function () {
+    var cols = FauxtonAPI.getExtensions('DatabaseTable:head');
+    return _.map(cols, function (Item, index) {
+      return <Item key={index} />;
+    });
+  },
+
+  showDeleteDatabaseModal: function (name) {
+    ComponentsActions.showDeleteDatabaseModal({
+      showDeleteModal: !this.props.showDeleteDatabaseModal.showDeleteModal
+    });
+  },
+
+  render: function () {
+    if (this.props.loading) {
       return (
         <div className="view">
-          <DeleteDatabaseModal
-            showHide={this.showDeleteDatabaseModal}
-            modalProps={this.props.showDeleteDatabaseModal} />
-          <table className="databases table table-striped">
-            <thead>
-              <tr>
-                <th>Name</th>
-                <th>Size</th>
-                <th># of Docs</th>
-                <th>Update Seq</th>
-                {this.getExtensionColumns()}
-                <th>Actions</th>
-              </tr>
-            </thead>
-            <tbody>
-            {rows}
-            </tbody>
-          </table>
+          <Components.LoadLines />
         </div>
       );
     }
-  });
 
-  var DatabaseRow = React.createClass({
+    var rows = this.createRows();
+    return (
+      <div className="view">
+        <DeleteDatabaseModal
+          showHide={this.showDeleteDatabaseModal}
+          modalProps={this.props.showDeleteDatabaseModal} />
+        <table className="databases table table-striped">
+          <thead>
+            <tr>
+              <th>Name</th>
+              <th>Size</th>
+              <th># of Docs</th>
+              <th>Update Seq</th>
+              {this.getExtensionColumns()}
+              <th>Actions</th>
+            </tr>
+          </thead>
+          <tbody>
+          {rows}
+          </tbody>
+        </table>
+      </div>
+    );
+  }
+});
 
-    propTypes: {
-      row: React.PropTypes.object
-    },
+var DatabaseRow = React.createClass({
 
-    renderGraveyard: function (row) {
-      if (row.status.isGraveYard()) {
-        return (
-          <GraveyardInfo row={row} />
-        );
-      } else {
-        return null;
-      }
-    },
-
-    getExtensionColumns: function (row) {
-      var cols = FauxtonAPI.getExtensions('DatabaseTable:databaseRow');
-      return _.map(cols, function (Item, index) {
-        return <Item row={row} key={index} />;
-      });
-    },
-
-    showDeleteDatabaseModal: function (name) {
-      ComponentsActions.showDeleteDatabaseModal({showDeleteModal: true, dbId: name});
-    },
-
-    render: function () {
-      var row = this.props.row;
-      //Adding this row check in as it seems our unit tests need them to pass
-      if (!row || !row.get) {return (<span></span>);};
-
-      var name = row.get("name");
-
-      // if the row status failed to load, inform the user
-      if (!row.status.loadSuccess) {
-        return (
-          <tr>
-            <td>{name}</td>
-            <td colSpan="4" className="database-load-fail">This database failed to load.</td>
-          </tr>
-        );
-      }
-      var encoded = app.utils.safeURLName(name);
-      var size = Helpers.formatSize(row.status.dataSize());
+  propTypes: {
+    row: React.PropTypes.object
+  },
 
+  renderGraveyard: function (row) {
+    if (row.status.isGraveYard()) {
       return (
-        <tr>
-          <td>
-            <a href={"#/database/" + encoded + "/_all_docs"}>{name}</a>
-          </td>
-          <td>{size}</td>
-          <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
-          <td>{row.status.updateSeq()}</td>
-          {this.getExtensionColumns(row)}
-          <td className="database-actions">
-            <a className="db-actions btn fonticon-replicate set-replication-start"
-              title={"Replicate " + name}
-              href={"#/replication/" + encoded} />
-            <a
-              className="db-actions btn icon-lock set-permissions"
-              title={"Set permissions for " + name} href={"#/database/" + encoded + "/permissions"} />
-            <a
-              className="db-actions btn icon-trash"
-              onClick={this.showDeleteDatabaseModal.bind(this, name)}
-              title={'Delete ' + name} data-bypass="true" />
-          </td>
-        </tr>
+        <GraveyardInfo row={row} />
       );
+    } else {
+      return null;
     }
-  });
+  },
 
-  var GraveyardInfo = React.createClass({
+  getExtensionColumns: function (row) {
+    var cols = FauxtonAPI.getExtensions('DatabaseTable:databaseRow');
+    return _.map(cols, function (Item, index) {
+      return <Item row={row} key={index} />;
+    });
+  },
 
-    componentDidMount: function () {
-      $(ReactDOM.findDOMNode(this.refs.myself)).tooltip();
-    },
+  showDeleteDatabaseModal: function (name) {
+    ComponentsActions.showDeleteDatabaseModal({showDeleteModal: true, dbId: name});
+  },
 
-    render: function () {
-      var row = this.props.row;
-      var graveyardTitle = "This database has just " + row.status.numDocs() +
-        " docs and " + row.status.numDeletedDocs() + " deleted docs";
-      return (
-        <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={graveyardTitle}></i>
-      );
-    }
-  });
+  render: function () {
+    var row = this.props.row;
+    //Adding this row check in as it seems our unit tests need them to pass
+    if (!row || !row.get) {return (<span></span>);};
 
-  var RightDatabasesHeader = React.createClass({
+    var name = row.get("name");
 
-    render: function () {
+    // if the row status failed to load, inform the user
+    if (!row.status.loadSuccess) {
       return (
-        <div className="header-right right-db-header flex-layout flex-row">
-          <JumpToDatabaseWidget />
-          <AddDatabaseWidget />
-        </div>
+        <tr>
+          <td>{name}</td>
+          <td colSpan="4" className="database-load-fail">This database failed to load.</td>
+        </tr>
       );
     }
-  });
-
-  var AddDatabaseWidget = React.createClass({
-
-    onTrayToggle: function (e) {
-      e.preventDefault();
+    var encoded = app.utils.safeURLName(name);
+    var size = Helpers.formatSize(row.status.dataSize());
+
+    return (
+      <tr>
+        <td>
+          <a href={"#/database/" + encoded + "/_all_docs"}>{name}</a>
+        </td>
+        <td>{size}</td>
+        <td>{row.status.numDocs()} {this.renderGraveyard(row)}</td>
+        <td>{row.status.updateSeq()}</td>
+        {this.getExtensionColumns(row)}
+        <td className="database-actions">
+          <a className="db-actions btn fonticon-replicate set-replication-start"
+            title={"Replicate " + name}
+            href={"#/replication/" + encoded} />
+          <a
+            className="db-actions btn icon-lock set-permissions"
+            title={"Set permissions for " + name} href={"#/database/" + encoded + "/permissions"} />
+          <a
+            className="db-actions btn icon-trash"
+            onClick={this.showDeleteDatabaseModal.bind(this, name)}
+            title={'Delete ' + name} data-bypass="true" />
+        </td>
+      </tr>
+    );
+  }
+});
 
-      this.setState({isPromptVisible: !this.state.isPromptVisible});
+var GraveyardInfo = React.createClass({
 
-      this.refs.newDbTray.toggle(function (shown) {
-        if (shown) {
-          ReactDOM.findDOMNode(this.refs.newDbName).focus();
-        }
-      }.bind(this));
-    },
+  componentDidMount: function () {
+    $(ReactDOM.findDOMNode(this.refs.myself)).tooltip();
+  },
 
-    onKeyUpInInput: function (e) {
-      if (e.which === 13) {
-        this.onAddDatabase();
-      }
-    },
+  render: function () {
+    var row = this.props.row;
+    var graveyardTitle = "This database has just " + row.status.numDocs() +
+      " docs and " + row.status.numDeletedDocs() + " deleted docs";
+    return (
+      <i className="js-db-graveyard icon icon-exclamation-sign" ref="myself" title={graveyardTitle}></i>
+    );
+  }
+});
 
-    getInitialState: function () {
-      return {
-        isPromptVisible: false
-      };
-    },
+var RightDatabasesHeader = React.createClass({
 
-    onAddDatabase: function () {
-      var databaseName = ReactDOM.findDOMNode(this.refs.newDbName).value;
-      Actions.createNewDatabase(databaseName);
-    },
+  render: function () {
+    return (
+      <div className="header-right right-db-header flex-layout flex-row">
+        <JumpToDatabaseWidget />
+        <AddDatabaseWidget />
+      </div>
+    );
+  }
+});
 
-    render: function () {
-      var headerButtonContainerClasses = 'header-control-box add-new-database-btn';
+var AddDatabaseWidget = React.createClass({
 
-      return (
-        <div>
-          <ToggleHeaderButton
-            selected={this.state.isPromptVisible}
-            toggleCallback={this.onTrayToggle}
-            containerClasses={headerButtonContainerClasses}
-            title="Create Database"
-            fonticon="fonticon-new-database"
-            text="Create Database" />
-          <FauxtonComponentsReact.Tray ref="newDbTray" className="new-database-tray">
-            <span className="add-on">Create Database</span>
-            <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
-            <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
-          </FauxtonComponentsReact.Tray>
-        </div>
-      );
-    }
-  });
-
-  var JumpToDatabaseWidget = React.createClass({
-
-    getStoreState: function () {
-      return {
-        databaseNames: databasesStore.getDatabaseNames()
-      };
-    },
-
-    getInitialState: function () {
-      return this.getStoreState();
-    },
-
-    componentDidMount: function () {
-      databasesStore.on('change', this.onChange, this);
-    },
-
-    componentDidUpdate: function () {
-      $(ReactDOM.findDOMNode(this.refs.searchDbName)).typeahead({
-        source: this.state.databaseNames,
-        updater: function (item) {
-          this.jumpToDb(item);
-        }.bind(this)
-      });
-    },
-
-    componentWillUnmount: function () {
-      databasesStore.off('change', this.onChange, this);
-    },
-
-    onChange: function () {
-      this.setState(this.getStoreState());
-    },
+  onTrayToggle: function (e) {
+    e.preventDefault();
 
-    jumpToDb: function (databaseName) {
-      databaseName = databaseName || ReactDOM.findDOMNode(this.refs.searchDbName).value;
-      Actions.jumpToDatabase(databaseName);
-    },
+    this.setState({isPromptVisible: !this.state.isPromptVisible});
 
-    jumpToDbHandler: function (e) {
-      e.preventDefault();
-      this.jumpToDb();
-    },
+    this.refs.newDbTray.toggle(function (shown) {
+      if (shown) {
+        ReactDOM.findDOMNode(this.refs.newDbName).focus();
+      }
+    }.bind(this));
+  },
 
-    render: function () {
-      return (
-        <div className="searchbox-wrapper">
-          <div id="header-search" className="js-search searchbox-container">
-            <form onSubmit={this.jumpToDbHandler} id="jump-to-db" className="navbar-form pull-right database-search">
-              <div className="input-append">
-                <input type="text" className="search-autocomplete" ref="searchDbName" name="search-query" placeholder="Database name" autoComplete="off" />
-                <span><button className="btn btn-primary" type="submit"><i className="icon icon-search"></i></button></span>
-              </div>
-            </form>
-          </div>
-        </div>
-      );
+  onKeyUpInInput: function (e) {
+    if (e.which === 13) {
+      this.onAddDatabase();
     }
-  });
-
-  var DatabasePagination = React.createClass({
-
-    getDefaultProps: function () {
-      return {
-        linkPath: '_all_dbs'
-      };
-    },
-
-    getStoreState: function () {
-      return {
-        databaseNames: databasesStore.getDatabaseNames(),
-        page: databasesStore.getPage()
-      };
-    },
-
-    getInitialState: function () {
-      return this.getStoreState();
-    },
-
-    componentDidMount: function () {
-      databasesStore.on('change', this.onChange, this);
-    },
-
-    componentWillUnmount: function () {
-      databasesStore.off('change', this.onChange, this);
-    },
-
-    onChange: function () {
-      this.setState(this.getStoreState());
-    },
+  },
+
+  getInitialState: function () {
+    return {
+      isPromptVisible: false
+    };
+  },
+
+  onAddDatabase: function () {
+    var databaseName = ReactDOM.findDOMNode(this.refs.newDbName).value;
+    Actions.createNewDatabase(databaseName);
+  },
+
+  render: function () {
+    var headerButtonContainerClasses = 'header-control-box add-new-database-btn';
+
+    return (
+      <div>
+        <ToggleHeaderButton
+          selected={this.state.isPromptVisible}
+          toggleCallback={this.onTrayToggle}
+          containerClasses={headerButtonContainerClasses}
+          title="Create Database"
+          fonticon="fonticon-new-database"
+          text="Create Database" />
+        <FauxtonComponentsReact.Tray ref="newDbTray" className="new-database-tray">
+          <span className="add-on">Create Database</span>
+          <input id="js-new-database-name" type="text" onKeyUp={this.onKeyUpInInput} ref="newDbName" className="input-xxlarge" placeholder="Name of database" />
+          <a className="btn" id="js-create-database" onClick={this.onAddDatabase}>Create</a>
+        </FauxtonComponentsReact.Tray>
+      </div>
+    );
+  }
+});
 
-    render: function () {
-      var page = this.state.page;
-      var total = this.props.total || this.state.databaseNames.length;
-      var urlPrefix = '#/' + this.props.linkPath + '?page=';
-      var start = 1 + (page - 1) * FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
-      var end = Math.min(total, page * FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE);
+var JumpToDatabaseWidget = React.createClass({
+
+  getStoreState: function () {
+    return {
+      databaseNames: databasesStore.getDatabaseNames()
+    };
+  },
+
+  getInitialState: function () {
+    return this.getStoreState();
+  },
+
+  componentDidMount: function () {
+    databasesStore.on('change', this.onChange, this);
+  },
+
+  componentDidUpdate: function () {
+    $(ReactDOM.findDOMNode(this.refs.searchDbName)).typeahead({
+      source: this.state.databaseNames,
+      updater: function (item) {
+        this.jumpToDb(item);
+      }.bind(this)
+    });
+  },
+
+  componentWillUnmount: function () {
+    databasesStore.off('change', this.onChange, this);
+  },
+
+  onChange: function () {
+    this.setState(this.getStoreState());
+  },
+
+  jumpToDb: function (databaseName) {
+    databaseName = databaseName || ReactDOM.findDOMNode(this.refs.searchDbName).value;
+    Actions.jumpToDatabase(databaseName);
+  },
+
+  jumpToDbHandler: function (e) {
+    e.preventDefault();
+    this.jumpToDb();
+  },
+
+  render: function () {
+    return (
+      <div className="searchbox-wrapper">
+        <div id="header-search" className="js-search searchbox-container">
+          <form onSubmit={this.jumpToDbHandler} id="jump-to-db" className="navbar-form pull-right database-search">
+            <div className="input-append">
+              <input type="text" className="search-autocomplete" ref="searchDbName" name="search-query" placeholder="Database name" autoComplete="off" />
+              <span><button className="btn btn-primary" type="submit"><i className="icon icon-search"></i></button></span>
+            </div>
+          </form>
+        </div>
+      </div>
+    );
+  }
+});
 
-      return (
-        <footer className="all-db-footer pagination-footer">
-          <div id="database-pagination">
-            <FauxtonComponentsReact.Pagination page={page} total={total} urlPrefix={urlPrefix} />
-          </div>
-          <div className="current-databases">Showing {start}&ndash;{end} of {total} databases.</div>
-        </footer>
-      );
-    }
-  });
-
-  return {
-    DatabasesController: DatabasesController,
-    DatabaseTable: DatabaseTable,
-    DatabaseRow: DatabaseRow,
-    RightDatabasesHeader: RightDatabasesHeader,
-    GraveyardInfo: GraveyardInfo,
-    AddDatabaseWidget: AddDatabaseWidget,
-    JumpToDatabaseWidget: JumpToDatabaseWidget,
-    DatabasePagination: DatabasePagination
-  };
+var DatabasePagination = React.createClass({
+
+  getDefaultProps: function () {
+    return {
+      linkPath: '_all_dbs'
+    };
+  },
+
+  getStoreState: function () {
+    return {
+      databaseNames: databasesStore.getDatabaseNames(),
+      page: databasesStore.getPage()
+    };
+  },
+
+  getInitialState: function () {
+    return this.getStoreState();
+  },
+
+  componentDidMount: function () {
+    databasesStore.on('change', this.onChange, this);
+  },
+
+  componentWillUnmount: function () {
+    databasesStore.off('change', this.onChange, this);
+  },
+
+  onChange: function () {
+    this.setState(this.getStoreState());
+  },
+
+  render: function () {
+    var page = this.state.page;
+    var total = this.props.total || this.state.databaseNames.length;
+    var urlPrefix = '#/' + this.props.linkPath + '?page=';
+    var start = 1 + (page - 1) * FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE;
+    var end = Math.min(total, page * FauxtonAPI.constants.MISC.DEFAULT_PAGE_SIZE);
+
+    return (
+      <footer className="all-db-footer pagination-footer">
+        <div id="database-pagination">
+          <FauxtonComponentsReact.Pagination page={page} total={total} urlPrefix={urlPrefix} />
+        </div>
+        <div className="current-databases">Showing {start}&ndash;{end} of {total} databases.</div>
+      </footer>
+    );
+  }
 });
+
+export default {
+  DatabasesController: DatabasesController,
+  DatabaseTable: DatabaseTable,
+  DatabaseRow: DatabaseRow,
+  RightDatabasesHeader: RightDatabasesHeader,
+  GraveyardInfo: GraveyardInfo,
+  AddDatabaseWidget: AddDatabaseWidget,
+  JumpToDatabaseWidget: JumpToDatabaseWidget,
+  DatabasePagination: DatabasePagination
+};

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/resources.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/resources.js b/app/addons/databases/resources.js
index 5d0471e..73c76d7 100644
--- a/app/addons/databases/resources.js
+++ b/app/addons/databases/resources.js
@@ -10,208 +10,202 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  "../../app",
-  "../../core/api",
-  // Modules
-  "../documents/resources"
-],
-
-function (app, FauxtonAPI, Documents) {
-  var Databases = FauxtonAPI.addon();
-
-  Databases.DocLimit = 100;
-
-  Databases.Model = FauxtonAPI.Model.extend({
-    initialize: function (options) {
-      this.status = new Databases.Status({
-        database: this
-      });
-    },
-
-    documentation: function () {
-      return FauxtonAPI.constants.DOC_URLS.ALL_DBS;
-    },
-
-    buildAllDocs: function (params) {
-      this.allDocs = new Documents.AllDocs(null, {
-        database: this,
-        params: params
-      });
-
-      return this.allDocs;
-    },
-
-    isNew: function () {
-      // Databases are never new, to make Backbone do a PUT
-      return false;
-    },
-
-    isSystemDatabase: function () {
-      return app.utils.isSystemDatabase(this.id);
-    },
-
-    url: function (context) {
-      if (context === "index") {
-        return "/database/" + this.safeID() + "/_all_docs";
-      } else if (context === "web-index") {
-        return "#/database/" + this.safeID() + "/_all_docs?limit=" + Databases.DocLimit;
-      } else if (context === "apiurl") {
-        return window.location.origin + "/database/" + this.safeID() + "/_all_docs";
-      } else if (context === "changes") {
-        return FauxtonAPI.urls('changes', 'app', this.safeID(), '?descending=true&limit=100&include_docs=true');
-      } else if (context === "changes-apiurl") {
-        return FauxtonAPI.urls('changes', 'apiurl', this.safeID(), '?descending=true&limit=100&include_docs=true');
-      } else if (context === "app") {
-        return "/database/" + this.safeID();
-      } else {
-        return app.host + "/" + this.safeID();
-      }
-    },
-    safeName: function () {
-      return app.utils.safeURLName(this.get("name"));
-    },
-    safeID: function () {
-      return app.utils.safeURLName(this.id);
-    },
-    buildChanges: function (params) {
-      if (!params.limit) {
-        params.limit = 100;
-      }
-
-      this.changes = new Databases.Changes({
-        database: this,
-        params: params
-      });
-
-      return this.changes;
+import app from "../../app";
+import FauxtonAPI from "../../core/api";
+import Documents from "../documents/resources";
+var Databases = FauxtonAPI.addon();
+
+Databases.DocLimit = 100;
+
+Databases.Model = FauxtonAPI.Model.extend({
+  initialize: function (options) {
+    this.status = new Databases.Status({
+      database: this
+    });
+  },
+
+  documentation: function () {
+    return FauxtonAPI.constants.DOC_URLS.ALL_DBS;
+  },
+
+  buildAllDocs: function (params) {
+    this.allDocs = new Documents.AllDocs(null, {
+      database: this,
+      params: params
+    });
+
+    return this.allDocs;
+  },
+
+  isNew: function () {
+    // Databases are never new, to make Backbone do a PUT
+    return false;
+  },
+
+  isSystemDatabase: function () {
+    return app.utils.isSystemDatabase(this.id);
+  },
+
+  url: function (context) {
+    if (context === "index") {
+      return "/database/" + this.safeID() + "/_all_docs";
+    } else if (context === "web-index") {
+      return "#/database/" + this.safeID() + "/_all_docs?limit=" + Databases.DocLimit;
+    } else if (context === "apiurl") {
+      return window.location.origin + "/database/" + this.safeID() + "/_all_docs";
+    } else if (context === "changes") {
+      return FauxtonAPI.urls('changes', 'app', this.safeID(), '?descending=true&limit=100&include_docs=true');
+    } else if (context === "changes-apiurl") {
+      return FauxtonAPI.urls('changes', 'apiurl', this.safeID(), '?descending=true&limit=100&include_docs=true');
+    } else if (context === "app") {
+      return "/database/" + this.safeID();
+    } else {
+      return app.host + "/" + this.safeID();
     }
-  });
-
-  Databases.Changes = FauxtonAPI.Collection.extend({
-
-    initialize: function (options) {
-      this.database = options.database;
-      this.params = options.params;
-    },
-    documentation: function () {
-      return FauxtonAPI.constants.DOC_URLS.CHANGES;
-    },
-    url: function (context) {
-      var query = "";
-      if (this.params) {
-        query = "?" + $.param(this.params);
-      }
-
-      if (!context) { context = 'server';}
-
-      return FauxtonAPI.urls('changes', context, this.database.safeID(), query);
-    },
-
-    parse: function (resp) {
-      this.last_seq = resp.last_seq;
-      return resp.results;
+  },
+  safeName: function () {
+    return app.utils.safeURLName(this.get("name"));
+  },
+  safeID: function () {
+    return app.utils.safeURLName(this.id);
+  },
+  buildChanges: function (params) {
+    if (!params.limit) {
+      params.limit = 100;
     }
-  });
-
-  Databases.Status = FauxtonAPI.Model.extend({
-    url: function () {
-      return app.host + "/" + this.database.safeID();
-    },
-
-    initialize: function (options) {
-      this.database = options.database;
-      this.loadSuccess = false;
-    },
-
-    numDocs: function () {
-      return this.get("doc_count");
-    },
-
-    numDeletedDocs: function () {
-      return this.get("doc_del_count");
-    },
-
-    isGraveYard: function () {
-      return this.numDeletedDocs() > this.numDocs();
-    },
-
-    updateSeq: function (full) {
-      var updateSeq = this.get("update_seq");
-      if (full || (typeof(updateSeq) === 'number')) {
-        return updateSeq;
-      } else if (updateSeq) {
-        return updateSeq[0];
-      } else {
-        return 0;
-      }
-    },
-
-    dataSize: function () {
-      if (this.get("other")) {
-        return this.get("other").data_size;
-      } else if (this.get('data_size')) {
-        return this.get('data_size');
-      } else if (this.get('disk_size')) {
-        return this.get('disk_size');
-      } else {
-        return 0;
-      }
-    },
-
-    parse: function (resp) {
-      this.loadSuccess = true;
-      return resp;
-    },
-
-    // a sure-fire way to know when the DB size info is actually available; dataSize() may return 0 before or after
-    // the data has been loaded
-    hasDataSize: function () {
-      return this.get('other') || this.get('data_size') || this.get('disk_size');
+
+    this.changes = new Databases.Changes({
+      database: this,
+      params: params
+    });
+
+    return this.changes;
+  }
+});
+
+Databases.Changes = FauxtonAPI.Collection.extend({
+
+  initialize: function (options) {
+    this.database = options.database;
+    this.params = options.params;
+  },
+  documentation: function () {
+    return FauxtonAPI.constants.DOC_URLS.CHANGES;
+  },
+  url: function (context) {
+    var query = "";
+    if (this.params) {
+      query = "?" + $.param(this.params);
     }
-  });
-
-  // TODO: shared databases - read from the user doc
-  Databases.List = FauxtonAPI.Collection.extend({
-    model: Databases.Model,
-    documentation: function () {
-      return FauxtonAPI.constants.DOC_URLS.ALL_DBS;
-    },
-
-    getDatabaseNames: function () {
-      return _.map(this.toArray(), function (model) {
-        return model.get('name');
-      });
-    },
-
-    cache: {
-      expires: 60
-    },
-
-    url: function (context) {
-      if (context === "apiurl") {
-        return window.location.origin + "/_all_dbs";
-      } else {
-        return app.host + "/_all_dbs";
-      }
-    },
-
-    parse: function (resp) {
-      // TODO: pagination!
-      return _.map(resp, function (database) {
-        return {
-          id: app.utils.safeURLName(database),
-          name: database
-        };
-      });
-    },
-
-    paginated: function (page, perPage) {
-      var start = (page - 1) * perPage;
-      var end = page * perPage;
-      return this.slice(start, end);
+
+    if (!context) { context = 'server';}
+
+    return FauxtonAPI.urls('changes', context, this.database.safeID(), query);
+  },
+
+  parse: function (resp) {
+    this.last_seq = resp.last_seq;
+    return resp.results;
+  }
+});
+
+Databases.Status = FauxtonAPI.Model.extend({
+  url: function () {
+    return app.host + "/" + this.database.safeID();
+  },
+
+  initialize: function (options) {
+    this.database = options.database;
+    this.loadSuccess = false;
+  },
+
+  numDocs: function () {
+    return this.get("doc_count");
+  },
+
+  numDeletedDocs: function () {
+    return this.get("doc_del_count");
+  },
+
+  isGraveYard: function () {
+    return this.numDeletedDocs() > this.numDocs();
+  },
+
+  updateSeq: function (full) {
+    var updateSeq = this.get("update_seq");
+    if (full || (typeof(updateSeq) === 'number')) {
+      return updateSeq;
+    } else if (updateSeq) {
+      return updateSeq[0];
+    } else {
+      return 0;
+    }
+  },
+
+  dataSize: function () {
+    if (this.get("other")) {
+      return this.get("other").data_size;
+    } else if (this.get('data_size')) {
+      return this.get('data_size');
+    } else if (this.get('disk_size')) {
+      return this.get('disk_size');
+    } else {
+      return 0;
     }
-  });
+  },
+
+  parse: function (resp) {
+    this.loadSuccess = true;
+    return resp;
+  },
+
+  // a sure-fire way to know when the DB size info is actually available; dataSize() may return 0 before or after
+  // the data has been loaded
+  hasDataSize: function () {
+    return this.get('other') || this.get('data_size') || this.get('disk_size');
+  }
+});
 
-  return Databases;
+// TODO: shared databases - read from the user doc
+Databases.List = FauxtonAPI.Collection.extend({
+  model: Databases.Model,
+  documentation: function () {
+    return FauxtonAPI.constants.DOC_URLS.ALL_DBS;
+  },
+
+  getDatabaseNames: function () {
+    return _.map(this.toArray(), function (model) {
+      return model.get('name');
+    });
+  },
+
+  cache: {
+    expires: 60
+  },
+
+  url: function (context) {
+    if (context === "apiurl") {
+      return window.location.origin + "/_all_dbs";
+    } else {
+      return app.host + "/_all_dbs";
+    }
+  },
+
+  parse: function (resp) {
+    // TODO: pagination!
+    return _.map(resp, function (database) {
+      return {
+        id: app.utils.safeURLName(database),
+        name: database
+      };
+    });
+  },
+
+  paginated: function (page, perPage) {
+    var start = (page - 1) * perPage;
+    var end = page * perPage;
+    return this.slice(start, end);
+  }
 });
+
+export default Databases;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/routes.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/routes.js b/app/addons/databases/routes.js
index fd38b34..c872692 100644
--- a/app/addons/databases/routes.js
+++ b/app/addons/databases/routes.js
@@ -10,50 +10,45 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  "../../app",
-  "../../core/api",
-  "./resources",
-  "./actions",
-  './components.react'
-],
-
-function (app, FauxtonAPI, Databases, Actions, Components) {
-
-  var AllDbsRouteObject = FauxtonAPI.RouteObject.extend({
-    layout: 'one_pane',
-
-    crumbs: [
-      {"name": "Databases", "link": "/_all_dbs"}
-    ],
-
-    routes: {
-      "": "allDatabases",
-      "index.html": "allDatabases",
-      "_all_dbs(:params)": "allDatabases"
-    },
-
-    roles: ['fx_loggedIn'],
-
-    selectedHeader: "Databases",
-    disableLoader: true,
-
-    initialize: function () {
-      this.databases = new Databases.List();
-    },
-
-    allDatabases: function () {
-      Actions.init(this.databases);
-      this.setComponent("#right-header", Components.RightDatabasesHeader);
-      this.setComponent("#dashboard-content", Components.DatabasesController);
-      this.setComponent("#footer", Components.DatabasePagination);
-    },
-
-    apiUrl: function () {
-      return [this.databases.url("apiurl"), this.databases.documentation()];
-    }
-  });
-  Databases.RouteObjects = [AllDbsRouteObject];
-
-  return Databases;
+import app from "../../app";
+import FauxtonAPI from "../../core/api";
+import Databases from "./resources";
+import Actions from "./actions";
+import Components from "./components.react";
+
+var AllDbsRouteObject = FauxtonAPI.RouteObject.extend({
+  layout: 'one_pane',
+
+  crumbs: [
+    {"name": "Databases", "link": "/_all_dbs"}
+  ],
+
+  routes: {
+    "": "allDatabases",
+    "index.html": "allDatabases",
+    "_all_dbs(:params)": "allDatabases"
+  },
+
+  roles: ['fx_loggedIn'],
+
+  selectedHeader: "Databases",
+  disableLoader: true,
+
+  initialize: function () {
+    this.databases = new Databases.List();
+  },
+
+  allDatabases: function () {
+    Actions.init(this.databases);
+    this.setComponent("#right-header", Components.RightDatabasesHeader);
+    this.setComponent("#dashboard-content", Components.DatabasesController);
+    this.setComponent("#footer", Components.DatabasePagination);
+  },
+
+  apiUrl: function () {
+    return [this.databases.url("apiurl"), this.databases.documentation()];
+  }
 });
+Databases.RouteObjects = [AllDbsRouteObject];
+
+export default Databases;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/0ca35da7/app/addons/databases/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/databases/stores.js b/app/addons/databases/stores.js
index 9331baf..9f5540b 100644
--- a/app/addons/databases/stores.js
+++ b/app/addons/databases/stores.js
@@ -10,119 +10,116 @@
 // License for the specific language governing permissions and limitations under
 // the License.
 
-define([
-  '../../app',
-  '../../core/api',
-  './actiontypes',
-  './resources'
-], function (app, FauxtonAPI, ActionTypes, Resources) {
-
-  var DatabasesStore = FauxtonAPI.Store.extend({
-
-    initialize: function () {
-      this.reset();
-    },
-
-    reset: function () {
-      this._collection = new Backbone.Collection();
-      this._loading = false;
-      this._promptVisible = false;
-    },
-
-    init: function (collection, backboneCollection) {
-      this._collection = collection;
-      this._backboneCollection = backboneCollection;
-    },
-
-    setPage: function (page) {
-      this._page = page;
-    },
-
-    getPage: function () {
-      if (this._page) {
-        return this._page;
-      } else {
-        return 1;
-      }
-    },
-
-    isLoading: function () {
-      return this._loading;
-    },
-
-    setLoading: function (loading) {
-      this._loading = loading;
-    },
-
-    isPromptVisible: function () {
-      return this._promptVisible;
-    },
-
-    setPromptVisible: function (promptVisible) {
-      this._promptVisible = promptVisible;
-    },
-
-    obtainNewDatabaseModel: function (databaseName, nameAccCallback) {
-      return new this._backboneCollection.model({
-        id: databaseName,
-        name: databaseName
+import app from "../../app";
+import FauxtonAPI from "../../core/api";
+import ActionTypes from "./actiontypes";
+import Resources from "./resources";
+
+var DatabasesStore = FauxtonAPI.Store.extend({
+
+  initialize: function () {
+    this.reset();
+  },
+
+  reset: function () {
+    this._collection = new Backbone.Collection();
+    this._loading = false;
+    this._promptVisible = false;
+  },
+
+  init: function (collection, backboneCollection) {
+    this._collection = collection;
+    this._backboneCollection = backboneCollection;
+  },
+
+  setPage: function (page) {
+    this._page = page;
+  },
+
+  getPage: function () {
+    if (this._page) {
+      return this._page;
+    } else {
+      return 1;
+    }
+  },
+
+  isLoading: function () {
+    return this._loading;
+  },
+
+  setLoading: function (loading) {
+    this._loading = loading;
+  },
+
+  isPromptVisible: function () {
+    return this._promptVisible;
+  },
+
+  setPromptVisible: function (promptVisible) {
+    this._promptVisible = promptVisible;
+  },
+
+  obtainNewDatabaseModel: function (databaseName, nameAccCallback) {
+    return new this._backboneCollection.model({
+      id: databaseName,
+      name: databaseName
+    });
+  },
+
+  getCollection: function () {
+    return this._collection;
+  },
+
+  getDatabaseNames: function () {
+    if (this._backboneCollection) {
+      return _.map(this._backboneCollection.toJSON(), function (item, key) {
+        return item.name;
       });
-    },
-
-    getCollection: function () {
-      return this._collection;
-    },
-
-    getDatabaseNames: function () {
-      if (this._backboneCollection) {
-        return _.map(this._backboneCollection.toJSON(), function (item, key) {
-          return item.name;
-        });
-      } else {
-        return [];
-      }
-    },
-
-    doesDatabaseExist: function (databaseName) {
-      return this.getDatabaseNames().indexOf(databaseName) >= 0;
-    },
-
-    dispatch: function (action) {
-      switch (action.type) {
-        case ActionTypes.DATABASES_INIT:
-          this.init(action.options.collection, action.options.backboneCollection);
-          this.setPage(action.options.page);
-          this.setLoading(false);
-        break;
-
-        case ActionTypes.DATABASES_SETPAGE:
-          this.setPage(action.options.page);
-        break;
-
-        case ActionTypes.DATABASES_SET_PROMPT_VISIBLE:
-          this.setPromptVisible(action.options.visible);
-        break;
-
-        case ActionTypes.DATABASES_STARTLOADING:
-          this.setLoading(true);
-        break;
-
-        case ActionTypes.DATABASES_LOADCOMPLETE:
-          this.setLoading(false);
-        break;
-
-        default:
-        return;
-      }
-
-      this.triggerChange();
+    } else {
+      return [];
+    }
+  },
+
+  doesDatabaseExist: function (databaseName) {
+    return this.getDatabaseNames().indexOf(databaseName) >= 0;
+  },
+
+  dispatch: function (action) {
+    switch (action.type) {
+      case ActionTypes.DATABASES_INIT:
+        this.init(action.options.collection, action.options.backboneCollection);
+        this.setPage(action.options.page);
+        this.setLoading(false);
+      break;
+
+      case ActionTypes.DATABASES_SETPAGE:
+        this.setPage(action.options.page);
+      break;
+
+      case ActionTypes.DATABASES_SET_PROMPT_VISIBLE:
+        this.setPromptVisible(action.options.visible);
+      break;
+
+      case ActionTypes.DATABASES_STARTLOADING:
+        this.setLoading(true);
+      break;
+
+      case ActionTypes.DATABASES_LOADCOMPLETE:
+        this.setLoading(false);
+      break;
+
+      default:
+      return;
     }
-  });
-
-  var databasesStore = new DatabasesStore();
-  databasesStore.dispatchToken = FauxtonAPI.dispatcher.register(databasesStore.dispatch.bind(databasesStore));
-  return {
-    databasesStore: databasesStore
-  };
 
+    this.triggerChange();
+  }
 });
+
+var databasesStore = new DatabasesStore();
+databasesStore.dispatchToken = FauxtonAPI.dispatcher.register(databasesStore.dispatch.bind(databasesStore));
+
+export default {
+  databasesStore: databasesStore
+};