Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ED3529EB0 for ; Tue, 14 May 2013 13:29:46 +0000 (UTC) Received: (qmail 90525 invoked by uid 500); 14 May 2013 13:29:41 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 90352 invoked by uid 500); 14 May 2013 13:29:37 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 89795 invoked by uid 99); 14 May 2013 13:29:32 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 14 May 2013 13:29:32 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id A0BC083B1; Tue, 14 May 2013 13:29:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: garren@apache.org To: commits@couchdb.apache.org Date: Tue, 14 May 2013 13:29:32 -0000 Message-Id: <03ec4155bf0e4be798cff27c097174de@git.apache.org> In-Reply-To: <6f68a4bcb28c47c79be873f0789fa061@git.apache.org> References: <6f68a4bcb28c47c79be873f0789fa061@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [2/7] git commit: updated refs/heads/route-events to 3ebf299 Get Route Event api working with modules and addons Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/fca31261 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/fca31261 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/fca31261 Branch: refs/heads/route-events Commit: fca312614f37dc9db1613f63ff562d53e1bdd72a Parents: 55b585c Author: Garren Smith Authored: Wed Apr 24 15:57:15 2013 +0200 Committer: Garren Smith Committed: Tue May 14 15:26:49 2013 +0200 ---------------------------------------------------------------------- src/fauxton/app/addons/config/routes.js | 57 ++- src/fauxton/app/addons/logs/resources.js | 5 + src/fauxton/app/addons/logs/routes.js | 57 ++- src/fauxton/app/addons/stats/base.js | 4 +- src/fauxton/app/addons/stats/resources.js | 2 +- src/fauxton/app/addons/stats/routes.js | 59 +-- src/fauxton/app/addons/stats/views.js | 4 +- src/fauxton/app/api.js | 72 ++- src/fauxton/app/initialize.js | 6 +- src/fauxton/app/main.js | 25 +- src/fauxton/app/modules/databases/routes.js | 86 +--- src/fauxton/app/modules/databases/views.js | 5 +- src/fauxton/app/modules/documents/routes.js | 438 +++++++++------ src/fauxton/app/modules/documents/views.js | 12 + src/fauxton/app/modules/fauxton/base.js | 8 +- src/fauxton/app/router.js | 39 +- .../templates/documents/doc_field_editor_tabs.html | 4 +- .../app/templates/documents/index_menu_item.html | 4 +- src/fauxton/app/templates/documents/sidebar.html | 6 +- src/fauxton/app/templates/fauxton/pagination.html | 10 +- src/fauxton/app/templates/layouts/with_tabs.html | 2 +- src/fauxton/assets/index.underscore | 1 + 22 files changed, 535 insertions(+), 371 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/config/routes.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/config/routes.js b/src/fauxton/app/addons/config/routes.js index 7ed6498..495e3a9 100644 --- a/src/fauxton/app/addons/config/routes.js +++ b/src/fauxton/app/addons/config/routes.js @@ -11,34 +11,45 @@ // the License. define([ - "app", + "app", - "api", + "api", - // Modules - "addons/config/resources" + // Modules + "addons/config/resources" ], function(app, FauxtonAPI, Config) { - var configRoute = function () { - var configs = new Config.Collection(); - - return { - layout: "one_pane", - crumbs: [ - {"name": "Config","link": "_config"} - ], - views: { - "#dashboard-content": new Config.View({collection: configs}) - }, - apiUrl: configs.url() - }; - }; - - Config.Routes = { - "_config": configRoute - }; - return Config; + var ConfigRouteObject = FauxtonAPI.RouteObject.extend({ + layout: "one_pane", + + initialize: function () { + this.configs = new Config.Collection(); + }, + + crumbs: [ + {"name": "Config","link": "_config"} + ], + + apiUrl: function () { + this.configs.url(); + }, + + routes: ["_config"], + defaultRoute: "config", + + config: function () { + this.setView("#dashboard-content", new Config.View({collection: this.configs})); + }, + + establish: function () { + return [this.configs.fetch()]; + } + }); + + + Config.RouteObjects = [ConfigRouteObject]; + return Config; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/logs/resources.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/logs/resources.js b/src/fauxton/app/addons/logs/resources.js index d1e6d20..91a9bcb 100644 --- a/src/fauxton/app/addons/logs/resources.js +++ b/src/fauxton/app/addons/logs/resources.js @@ -98,11 +98,16 @@ function (app, FauxtonAPI, Backbone) { this.filters = []; this.filteredCollection = new Log.Collection(this.collection.toJSON()); + this.collection.on("add", function () { this.createFilteredCollection(); }, this); }, + establish: function () { + return [this.collection.fetch()]; + }, + serialize: function () { return { logs: this.filteredCollection}; }, http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/logs/routes.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/logs/routes.js b/src/fauxton/app/addons/logs/routes.js index 4e04d08..9bd8f65 100644 --- a/src/fauxton/app/addons/logs/routes.js +++ b/src/fauxton/app/addons/logs/routes.js @@ -11,37 +11,48 @@ // the License. define([ - "app", + "app", - "api", + "api", - // Modules - "addons/logs/resources" + // Modules + "addons/logs/resources" ], function(app, FauxtonAPI, Log) { - Log.Routes = { - "_log": function() { - var logs = new Log.Collection(); - - return { - layout: "with_sidebar", - crumbs: [ - {"name": "Logs", "link": "_log"} - ], - views: { - "#dashboard-content": new Log.Views.View({collection: logs}), - "#sidebar-content": new Log.Views.FilterView({}) - }, - apiUrl: logs.url(), - establish: function() { - return [logs.fetch()]; - } - }; + var LogRouteObject = FauxtonAPI.RouteObject.extend({ + layout: "with_sidebar", + + crumbs: [ + {"name": "Logs", "link": "_log"} + ], + + routes: ["_log"], + + defaultRoute: "showLog", + + apiUrl: function() { + return this.logs.url(); + }, + + initialize: function () { + this.logs = new Log.Collection(); + this.setView("#sidebar-content", new Log.Views.FilterView({})); + }, + + showLog: function (event) { + this.setView("#dashboard-content", new Log.Views.View({collection: this.logs})); + }, + + e1stablish: function() { + return [this.logs.fetch()]; } - }; + }); + + Log.RouteObjects = [LogRouteObject]; return Log; }); + http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/stats/base.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/stats/base.js b/src/fauxton/app/addons/stats/base.js index 33316c4..4721399 100644 --- a/src/fauxton/app/addons/stats/base.js +++ b/src/fauxton/app/addons/stats/base.js @@ -16,13 +16,11 @@ define([ "addons/stats/routes" ], -function(app, FauxtonAPI, AddonRoutes) { - var Stats = new FauxtonAPI.addon(); +function(app, FauxtonAPI, Stats) { Stats.initialize = function() { FauxtonAPI.addHeaderLink({title: "Statistics", href: "#stats"}); }; - Stats.Routes = AddonRoutes; return Stats; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/stats/resources.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/stats/resources.js b/src/fauxton/app/addons/stats/resources.js index 238a032..94be6bb 100644 --- a/src/fauxton/app/addons/stats/resources.js +++ b/src/fauxton/app/addons/stats/resources.js @@ -19,7 +19,7 @@ define([ ], function (app, FauxtonAPI, backbone, _, Fauxton) { - var Stats = {}; + var Stats = new FauxtonAPI.addon(); Stats.Collection = Backbone.Collection.extend({ model: Backbone.Model, http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/stats/routes.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/stats/routes.js b/src/fauxton/app/addons/stats/routes.js index 84947fa..7ad2a1f 100644 --- a/src/fauxton/app/addons/stats/routes.js +++ b/src/fauxton/app/addons/stats/routes.js @@ -11,49 +11,42 @@ // the License. define([ - "app", - "api", - "addons/stats/resources", - "addons/stats/views" + "app", + "api", + "addons/stats/views" ], -function(app, FauxtonAPI, Stats, Views) { - var data = { - stats: new Stats.Collection() - }; +function(app, FauxtonAPI, Stats) { - var deferred = FauxtonAPI.Deferred(); + var StatsRouteObject = FauxtonAPI.RouteObject.extend({ + layout: "with_sidebar", - var routeCallback = function() { - return { - layout: "with_sidebar", + routes: ["stats", "_stats"], + defaultRoute: "showStats", - data: data, + initialize: function () { + this.stats = new Stats.Collection(); - crumbs: [], + this.setView("#sidebar-content", new Views.StatSelect({ + collection: this.stats + })); - views: { - "#sidebar-content": new Views.StatSelect({ - collection: data.stats - }), + }, - "#dashboard-content": new Views.Statistics({ - collection: data.stats - }) - }, + showStats: function (event) { + this.setView("#dashboard-content", new Views.Statistics({ + collection: this.stats + })); + }, - establish: function() { - return [data.stats.fetch()]; - }, + establish: function() { + return [this.stats.fetch()]; + }, - apiUrl: "_stats" - }; - }; + apiUrl: "_stats" + }); - Routes = { - "stats": routeCallback, - "_stats": routeCallback - }; + Stats.RouteObjects = [StatsRouteObject]; - return Routes; + return Stats; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/addons/stats/views.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/addons/stats/views.js b/src/fauxton/app/addons/stats/views.js index 21454f9..9fda708 100644 --- a/src/fauxton/app/addons/stats/views.js +++ b/src/fauxton/app/addons/stats/views.js @@ -168,5 +168,7 @@ function(app, FauxtonAPI,Stats) { } }); - return Views; + Stats.Views = Views; + + return Stats; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/api.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js index 2c68086..6591daf 100644 --- a/src/fauxton/app/api.js +++ b/src/fauxton/app/api.js @@ -43,6 +43,14 @@ function(app, Fauxton) { // This should return an array of promises, an empty array, or null establish: function() { return null; + }, + + hasRendered: function () { + return !!this.__manager__.hasRendered; + }, + + reRender: function () { + this.__manager__.hasRendered = false; } }); @@ -62,6 +70,10 @@ function(app, Fauxton) { app.router.route(route.route, route.name, route.callback); }; + FauxtonAPI.triggerRouteEvent = function (routeEvent, args) { + app.router.triggerRouteEvent("route:"+routeEvent, args); + }; + FauxtonAPI.module = function(extra) { return app.module(_.extend(FauxtonAPI.moduleExtensions, extra)); }; @@ -96,6 +108,25 @@ function(app, Fauxton) { } }); + // Not needed, could be removed. + FauxtonAPI.routeCallChain = { + callChain: {}, + + registerBeforeRoute: function (name, fn) { + this.callChain[name] = fn; + }, + + unregisterBeforeRoute: function (name) { + delete callChain[name]; + }, + + run: function () { + var callChainDeferreds = _.map(this.callChain, function (cb) { return cb(); }); + return $.when(null, callChainDeferreds ); + } + }; + + FauxtonAPI.RouteObject = function(options) { this._options = options; @@ -124,10 +155,6 @@ function(app, Fauxton) { route: function() {}, initialize: function() {} }, { - // By default, rerender is a full rerender - rerender: function() { - this.renderWith.apply(this, arguments); - }, // TODO:: combine this and the renderWith function // All the things should go through establish, as it will resolve @@ -135,30 +162,32 @@ function(app, Fauxton) { // function can rebuild the deferred as needed render: function(route, masterLayout, args) { this.route.call(this, route, args); - - if (this.renderedState === true) { - this.rerender.apply(this, arguments); - } else { - this.renderWith.apply(this, arguments); - } + this.renderWith.apply(this, Array.prototype.slice.call(arguments)); }, renderWith: function(route, masterLayout, args) { var routeObject = this; - //this.route.apply(this, args); - masterLayout.setTemplate(this.layout); + // Only want to redo the template if its a full render + if (!this.renderedState) { + masterLayout.setTemplate(this.layout); + } + masterLayout.clearBreadcrumbs(); + var crumbs = this.get('crumbs'); - if (this.crumbs.length) { + if (crumbs.length) { masterLayout.setBreadcrumbs(new Fauxton.Breadcrumbs({ - crumbs: this.crumbs + crumbs: crumbs })); } $.when.apply(this, this.establish()).done(function(resp) { - _.each(routeObject.views, function(view, selector) { + _.each(routeObject.getViews(), function(view, selector) { + if(view.hasRendered()) { console.log('view been rendered'); return; } + masterLayout.setView(selector, view); + console.log('set and render ', selector, view); $.when.apply(null, view.establish()).then(function(resp) { masterLayout.renderView(selector); @@ -172,13 +201,11 @@ function(app, Fauxton) { var hooks = masterLayout.hooks[selector]; - if(hooks){ - _.each(hooks, function(hook){ - if (_.any(hook.routes, function(route){return route == boundRoute;})){ - hook.callback(view); - } - }); - } + _.each(hooks, function(hook){ + if (_.any(hook.routes, function(route){return route == boundRoute;})){ + hook.callback(view); + } + }); }); }); @@ -222,6 +249,7 @@ function(app, Fauxton) { getViews: function() { return this.views; } + }); app.fauxtonAPI = FauxtonAPI; http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/initialize.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/initialize.js b/src/fauxton/app/initialize.js index 5699678..e5dbc73 100644 --- a/src/fauxton/app/initialize.js +++ b/src/fauxton/app/initialize.js @@ -37,8 +37,12 @@ function(app, _, Bootstrap) { // Thanks to: http://stackoverflow.com/a/2880929 getParams: function(queryString) { if (typeof queryString !== "undefined") { - if (queryString.substring(0,1) === "?") + // I think this could be combined into one if + if (queryString.substring(0,1) === "?") { queryString = queryString.substring(1); + } else if (queryString.indexOf('?') > -1) { + queryString = queryString.split('?')[1]; + } } var hash = window.location.hash.split('?')[1]; queryString = queryString || hash || window.location.search.substring(1); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/main.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/main.js b/src/fauxton/app/main.js index d3f8ac2..203b295 100644 --- a/src/fauxton/app/main.js +++ b/src/fauxton/app/main.js @@ -23,16 +23,25 @@ function(app, Router) { // Get the absolute root. var root = location.protocol + "//" + location.host + app.root; - // Ensure the root is part of the anchor href, meaning it's relative. - if (href.prop && href.prop.slice(0, root.length) === root) { - // Stop the default event to ensure the link will not cause a page - // refresh. + var routeEvent = $(this).attr("route-event"); + if (routeEvent) { evt.preventDefault(); - - // `Backbone.history.navigate` is sufficient for all Routers and will - // trigger the correct events. The Router's internal `navigate` method - // calls this anyways. The fragment is sliced from the root. + // TODO:: change to false when route events are functional Backbone.history.navigate(href.attr, true); + // Trigger route events after update of history so that we can get params from url + app.router.triggerRouteEvent("route:"+routeEvent, href); + } else { + // Ensure the root is part of the anchor href, meaning it's relative. + if (href.prop && href.prop.slice(0, root.length) === root) { + // Stop the default event to ensure the link will not cause a page + // refresh. + evt.preventDefault(); + + // `Backbone.history.navigate` is sufficient for all Routers and will + // trigger the correct events. The Router's internal `navigate` method + // calls this anyways. The fragment is sliced from the root. + Backbone.history.navigate(href.attr, true); + } } }); }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/modules/databases/routes.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/modules/databases/routes.js b/src/fauxton/app/modules/databases/routes.js index b7f1dbb..f1be372 100644 --- a/src/fauxton/app/modules/databases/routes.js +++ b/src/fauxton/app/modules/databases/routes.js @@ -22,6 +22,7 @@ define([ ], function(app, FauxtonAPI, Databases, Views) { + var AllDbsRouteObject = FauxtonAPI.RouteObject.extend({ layout: "with_sidebar", @@ -29,6 +30,12 @@ function(app, FauxtonAPI, Databases, Views) { {"name": "Databases", "link": "/_all_dbs"} ], + events: { + "route:all_databases": "allDatabases" + }, + + defaultRoute: "allDatabases", + routes: ["", "index.html", "_all_dbs(:params)"], apiUrl: function() { @@ -39,21 +46,22 @@ function(app, FauxtonAPI, Databases, Views) { this.databases = new Databases.List(); this.deferred = FauxtonAPI.Deferred(); - this.databasesView = this.setView("#dashboard-content", new Views.List({ - collection: this.databases - })); this.sidebarView = this.setView("#sidebar-content", new Views.Sidebar({ collection: this.databases })); }, - route: function() { - var params = app.getParams(); - this.databasesView.setPage(params.page); - }, + allDatabases: function(event) { + event = event || {}; + + var params = app.getParams(event.attr), + dbPage = params.page; + + this.databasesView = this.setView("#dashboard-content", new Views.List({ + collection: this.databases + })); - rerender: function() { - this.databasesView.render(); + this.databasesView.setPage(dbPage); }, establish: function() { @@ -69,66 +77,10 @@ function(app, FauxtonAPI, Databases, Views) { }); return [deferred]; - }, - - mrEvent: function() { - console.log("Triggering a most excellent event!!!!"); - }, - - events: { - "myrandom_event": "mrEvent" } }); - - var allDbsCallback = function() { - var data = { - databases: new Databases.List() - }; - var deferred = FauxtonAPI.Deferred(); - - return { - layout: "with_sidebar", - - data: data, - - crumbs: [ - {"name": "Databases", "link": "/_all_dbs"} - ], - - views: { - "#dashboard-content": new Databases.Views.List({ - collection: data.databases - }), - - "#sidebar-content": new Databases.Views.Sidebar({ - collection: data.databases - }) - }, - - apiUrl: data.databases.url(), - - establish: function() { - data.databases.fetch().done(function(resp) { - $.when.apply(null, data.databases.map(function(database) { - return database.status.fetch(); - })).done(function(resp) { - deferred.resolve(); - }); - }); - return [deferred]; - } - }; - }; - - /* - Databases.Routes = { - "": allDbsCallback, - "index.html": allDbsCallback, - "_all_dbs(:params)": allDbsCallback - }; - */ - - Databases.RouteObjects = [new AllDbsRouteObject()]; + + Databases.RouteObjects = [AllDbsRouteObject]; return Databases; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/modules/databases/views.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/modules/databases/views.js b/src/fauxton/app/modules/databases/views.js index 6b9cfea..23145fe 100644 --- a/src/fauxton/app/modules/databases/views.js +++ b/src/fauxton/app/modules/databases/views.js @@ -66,7 +66,7 @@ function(app, Fauxton, FauxtonAPI) { paginated: function() { var start = (this.page - 1) * this.perPage; - var end = this.page * this.perPage - 1; + var end = this.page * this.perPage; return this.collection.slice(start, end); }, @@ -83,7 +83,8 @@ function(app, Fauxton, FauxtonAPI) { total: this.collection.length, urlFun: function(page) { return "#/_all_dbs?page=" + page; - } + }, + routeEvent: "all_databases" })); }, http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/modules/documents/routes.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/modules/documents/routes.js b/src/fauxton/app/modules/documents/routes.js index ffed186..d57487f 100644 --- a/src/fauxton/app/modules/documents/routes.js +++ b/src/fauxton/app/modules/documents/routes.js @@ -11,13 +11,13 @@ // the License. define([ - "app", + "app", - "api", + "api", - // Modules - "modules/documents/resources", - "modules/databases/base" + // Modules + "modules/documents/resources", + "modules/databases/base" ], function(app, FauxtonAPI, Documents, Databases) { @@ -25,12 +25,24 @@ function(app, FauxtonAPI, Documents, Databases) { // var Documents = require("modules/documents/models_collections"); // var Databases = require("modules/databases/module"); - // TODO:: expand this for new docs and design docs var DocEditorRouteObject = FauxtonAPI.RouteObject.extend({ layout: "one_pane", - initialize: function() { - this.selected = false; + initialize: function(options) { + var databaseName = options[0], docID = options[1]; + + this.database = this.database || new Databases.Model({id: databaseName}); + this.doc = this.doc || new Documents.Doc({ + _id: docID + }, { + database: this.database + }); + + this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({ + selected: "code_editor", + model: this.doc + })); + }, routes: function() { @@ -43,6 +55,13 @@ function(app, FauxtonAPI, Documents, Databases) { "database/:database/:doc": "code_editor" }, + events: { + "route:field_editor": "field_editor", + "route:code_editor": "code_editor" + }, + + defaultRoute: "code_editor", + crumbs: function() { return [ {"name": "Databases", "link": "/_all_dbs"}, @@ -51,35 +70,16 @@ function(app, FauxtonAPI, Documents, Databases) { ]; }, - setEditorView: function() { - if (this.selected === "field_editor") { - this.docView = this.setView("#dashboard-content", new Documents.Views.DocFieldEditor({ - model: this.doc - })); - } else { - this.docView = this.setView("#dashboard-content", new Documents.Views.Doc({ - model: this.doc - })); - } + code_editor: function (event) { + this.tabsView.updateSelected('code_editor'); + this.docView = this.setView("#dashboard-content", new Documents.Views.Doc({ + model: this.doc + })); }, - route: function(route, args) { - var databaseName = args[0], docID = args[1]; - - this.database = this.database || new Databases.Model({id: databaseName}); - this.doc = this.doc || new Documents.Doc({ - _id: docID - }, { - database: this.database - }); - - if (this.selected !== this.selectedRoutes[route]) { - this.selected = this.selectedRoutes[route]; - this.setEditorView(); - } - - this.tabsView = this.setView("#tabs", new Documents.Views.FieldEditorTabs({ - selected: this.selected, + field_editor: function(events) { + this.tabsView.updateSelected('field_editor'); + this.docView = this.setView("#dashboard-content", new Documents.Views.DocFieldEditor({ model: this.doc })); }, @@ -96,8 +96,8 @@ function(app, FauxtonAPI, Documents, Databases) { data.designDocs = new Documents.AllDocs(null, { database: data.database, params: {startkey: '"_design"', - endkey: '"_design1"', - include_docs: true} + endkey: '"_design1"', + include_docs: true} }); return { @@ -178,165 +178,287 @@ function(app, FauxtonAPI, Documents, Databases) { }; }; - Documents.Routes = { - //"database/:database/:doc/code_editor": codeEditorCallback, - //"database/:database/:doc": codeEditorCallback, - "database/:database/_design%2F:doc": function(database, doc) { - var docID = "_design/"+doc; - return codeEditorCallback(database, docID); + + var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({ + layout: "with_tabs_sidebar", + + events: { + "route:all_docs": "allDocs", + "route:all_design_docs": "allDesignDocs", + "route:view_fn": "viewFn", + "route:new_view": "newViewEditor" }, - "database/:database/_all_docs(:extra)": function(databaseName, page) { - var data = { - database: new Databases.Model({id:databaseName}) + defaultRoute: "allDocs", + + initialize: function (options) { + var docOptions = app.getParams(); + docOptions.include_docs = true; + + this.databaseName = options[0]; + + this.data = { + database: new Databases.Model({id:this.databaseName}) }; - data.designDocs = new Documents.AllDocs(null, { - database: data.database, + + this.data.designDocs = new Documents.AllDocs(null, { + database: this.data.database, params: {startkey: '"_design"', endkey: '"_design1"', include_docs: true} }); - var options = app.getParams(); - options.include_docs = true; - data.database.buildAllDocs(options); - - return { - layout: "with_tabs_sidebar", + this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({ + collection: this.data.designDocs + })); - data: data, + this.setView("#tabs", new Documents.Views.Tabs({ + collection: this.data.designDocs, + database: this.data.database + })); + }, - crumbs: [ - {"name": "Databases", "link": "/_all_dbs"}, - {"name": data.database.id, "link": Databases.databaseUrl(data.database)} - ], + crumbs: function () { + return [ + {"name": "Databases", "link": "/_all_dbs"}, + {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)} + ]; + }, - views: { - "#dashboard-content": new Documents.Views.AllDocsList({ - collection: data.database.allDocs - }), + allDocs: function(event) { + var docOptions; - "#sidebar-content": new Documents.Views.Sidebar({ - collection: data.designDocs - }), + docOptions = app.getParams(event.attr); + docOptions.include_docs = true; - "#tabs": new Documents.Views.Tabs({ - collection: data.designDocs, - database: data.database - }) - }, + this.data.database.buildAllDocs(docOptions); + this.sidebar.setSelectedTab('all-docs'); - apiUrl: data.database.allDocs.url() - }; + this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({ + collection: this.data.database.allDocs + })); }, - "database/:database/_changes(:params)": function(databaseName, params) { - var data = { - database: new Databases.Model({id:databaseName}) - }; + allDesignDocs: function(event) { + var docOptions = app.getParams(event.attr); + docOptions.include_docs = true; - var options = app.getParams(); - data.database.buildChanges(options); + this.data.database.buildAllDocs(docOptions); + this.sidebar.setSelectedTab('design-docs'); - return { - layout: "with_tabs", + this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({ + collection: this.data.database.allDocs + })); + }, - data: data, + route: function (route, routeArgs) { + console.log('ROUTE ARG ', arguments); - crumbs: [ - {"name": "Databases", "link": "/_all_dbs"}, - {"name": data.database.id, "link": Databases.databaseUrl(data.database)}, - {"name": "_changes", "link": "/_changes"} - ], - - views: { - "#dashboard-content": new Documents.Views.Changes({ - model: data.database - }), - - "#tabs": new Documents.Views.Tabs({ - collection: data.designDocs, - database: data.database, - active_id: 'changes' - }) - }, - - apiUrl: data.database.changes.url() - }; + if (route === 'database/:database/_design/:ddoc/_view/:view') { + + if (!this.docCrumbs && !this.docApiUrl) { + // Save the old crumbs and API. Easier to do it here than in each event + this.docCrumbs = this.crumbs; + this.docApiUrl = this.apiUrl; + } + + this.routeArgs = { + designDoc: routeArgs[1], + view: routeArgs[2].replace(/\?.*$/,'') + }; + } else { + this.routeArgs = {}; + if (this.docCrumbs && this.docApiUrl) { + this.crumbs = this.docCrumbs; + this.docApiUrl = this.apiUrl; + } + } }, - "database/:database/new": newDocCodeEditorCallback, - "database/:database/new_view": newViewEditorCallback, - - // TODO: fix optional search params - // Can't get ":view(?*search)" to work - // However ":view?*search" does work - //"database/:database/_design/:ddoc/_view/:view(\?*options)": function(databaseName, ddoc, view, options) { - "database/:database/_design/:ddoc/_view/:view": function(databaseName, ddoc, view, options) { - // hack around backbone router limitations - view = view.replace(/\?.*$/,''); - var params = app.getParams(); - var data = { - database: new Databases.Model({id:databaseName}) - }; + viewFn: function (event) { + var view = this.routeArgs.view, + ddoc = this.routeArgs.designDoc, + params = app.getParams(event.attr); + + console.log('PARAMS', params); - data.indexedDocs = new Documents.IndexCollection(null, { - database: data.database, + this.data.indexedDocs = new Documents.IndexCollection(null, { + database: this.data.database, design: ddoc, view: view, params: params }); - data.designDocs = new Documents.AllDocs(null, { - database: data.database, - params: {startkey: '"_design"', - endkey: '"_design1"', - include_docs: true} - }); - var ddocInfo = { id: "_design/" + ddoc, currView: view, - designDocs: data.designDocs + designDocs: this.data.designDocs }; - return { - layout: "with_tabs_sidebar", - - data: data, - // TODO: change dashboard-content - views: { - "#dashboard-content": new Documents.Views.AllDocsList({ - collection: data.indexedDocs, - nestedView: Documents.Views.Row, - viewList: true, - ddocInfo: ddocInfo, - params: params - }), - - "#sidebar-content": new Documents.Views.Sidebar({ - collection: data.designDocs, - ddocInfo: ddocInfo - }), - - "#tabs": new Documents.Views.Tabs({ - collection: data.designDocs, - database: data.database - }) - }, - - crumbs: [ + this.setView("#dashboard-content", new Documents.Views.AllDocsList({ + collection: this.data.indexedDocs, + nestedView: Documents.Views.Row, + viewList: true, + ddocInfo: ddocInfo, + params: params + })); + + this.crumbs = function () { + return [ {"name": "Databases", "link": "/_all_dbs"}, - {"name": data.database.id, "link": Databases.databaseUrl(data.database)}, - {"name": ddoc + "/" + view, "link": data.indexedDocs.url()} - ], - // TODO: change to view URL - apiUrl: data.indexedDocs.url() + {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}, + {"name": ddoc + "/" + view, "link": this.data.indexedDocs.url()} + ]; }; + + // TODO: change to view URL + this.apiUrl = this.data.indexedDocs.url(); + }, + + newViewEditor: function (event) { + // TODO: Get this working + this.setView("#dashboard-content", new Documents.Views.ViewEditor({ + model: this.data.database, + ddocs: this.data.designDocs + })); + + }, + + routes: ["database/:database/_all_docs(:extra)", "database/:database/_design/:ddoc/_view/:view", "database/:database/new_view"], + + apiUrl: function() { + return this.data.database.allDocs.url(); } + }); + + + + var ChangesRouteObject = FauxtonAPI.RouteObject.extend({ + layout: "with_tabs", + + crumbs: function () { + return [ + {"name": "Databases", "link": "/_all_dbs"}, + {"name": this.database.id, "link": Databases.databaseUrl(this.database)}, + {"name": "_changes", "link": "/_changes"} + ]; + }, + + routes: ["database/:database/_changes(:params)"], + + events: { + "route:_changes": "changes" + }, + + defaultRoute: "changes", + + initialize: function (options) { + this.databaseName = options[0]; + this.database = new Databases.Model({id: this.databaseName}); + + var docOptions = app.getParams(); + + this.database.buildChanges(docOptions); + + this.setView("#tabs", new Documents.Views.Tabs({ + collection: this.designDocs, + database: this.database, + active_id: 'changes' + })); + }, + + changes: function (event) { + this.setView("#dashboard-content", new Documents.Views.Changes({ + model: this.database + })); + }, + + apiUrl: function() { + return this.database.changes.url(); + } + + }); + + /* Documents.Routes = { + "database/:database/_design%2F:doc": function(database, doc) { + var docID = "_design/"+doc; + return codeEditorCallback(database, docID); + }, + + + + "database/:database/new": newDocCodeEditorCallback, + "database/:database/new_view": newViewEditorCallback, + + // TODO: fix optional search params + // Can't get ":view(?*search)" to work + // However ":view?*search" does work + //"database/:database/_design/:ddoc/_view/:view(\?*options)": function(databaseName, ddoc, view, options) { + "database/:database/_design/:ddoc/_view/:view": function(databaseName, ddoc, view, options) { +// hack around backbone router limitations +view = view.replace(/\?.*$/,''); +var params = app.getParams(); +var data = { +database: new Databases.Model({id:databaseName}) +}; + +data.indexedDocs = new Documents.IndexCollection(null, { +database: data.database, +design: ddoc, +view: view, +params: params +}); + +data.designDocs = new Documents.AllDocs(null, { +database: data.database, +params: {startkey: '"_design"', +endkey: '"_design1"', +include_docs: true} +}); + +var ddocInfo = { +id: "_design/" + ddoc, +currView: view, +designDocs: data.designDocs +}; + +return { +layout: "with_tabs_sidebar", + +data: data, + // TODO: change dashboard-content +views: { +"#dashboard-content": new Documents.Views.AllDocsList({ +collection: data.indexedDocs, +nestedView: Documents.Views.Row, +viewList: true, +ddocInfo: ddocInfo, +params: params +}), + +"#sidebar-content": new Documents.Views.Sidebar({ +collection: data.designDocs, +ddocInfo: ddocInfo +}), + +"#tabs": new Documents.Views.Tabs({ +collection: data.designDocs, +database: data.database +}) +}, + +crumbs: [ +{"name": "Databases", "link": "/_all_dbs"}, +{"name": data.database.id, "link": Databases.databaseUrl(data.database)}, +{"name": ddoc + "/" + view, "link": data.indexedDocs.url()} +], + // TODO: change to view URL + apiUrl: data.indexedDocs.url() }; +} +};*/ - Documents.RouteObjects = [new DocEditorRouteObject()]; + Documents.RouteObjects = [DocEditorRouteObject, DocumentsRouteObject, ChangesRouteObject]; return Documents; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/modules/documents/views.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/modules/documents/views.js b/src/fauxton/app/modules/documents/views.js index 558f0c1..6ac9b44 100644 --- a/src/fauxton/app/modules/documents/views.js +++ b/src/fauxton/app/modules/documents/views.js @@ -163,6 +163,12 @@ function(app, FauxtonAPI, Codemirror, JSHint) { }); }, + updateSelected: function (selected) { + this.selected = selected; + this.$('.active').removeClass('active'); + this.$('#'+this.selected).addClass('active'); + }, + serialize: function() { var selected = this.selected; return { @@ -390,6 +396,7 @@ function(app, FauxtonAPI, Codemirror, JSHint) { var fragment = window.location.hash.replace(/\?.*$/, ''); fragment = fragment + '?' + $.param(params); FauxtonAPI.navigate(fragment); + FauxtonAPI.triggerRouteEvent('view_fn', params); }, updateFilters: function(event) { @@ -921,6 +928,11 @@ function(app, FauxtonAPI, Codemirror, JSHint) { } } }, this); + }, + + setSelectedTab: function (selectedTab) { + this.$('li').removeClass('active'); + this.$('#' + selectedTab).parent().addClass('active'); } }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/modules/fauxton/base.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/modules/fauxton/base.js b/src/fauxton/app/modules/fauxton/base.js index 8ddbb17..3bcae5d 100644 --- a/src/fauxton/app/modules/fauxton/base.js +++ b/src/fauxton/app/modules/fauxton/base.js @@ -11,8 +11,7 @@ // the License. define([ - "app", - + "app", // Libs "backbone" @@ -157,6 +156,8 @@ function(app, Backbone) { this.total = options.total; this.totalPages = Math.ceil(this.total / this.perPage); this.urlFun = options.urlFun; + this.routeEvent = options.routeEvent; + }, serialize: function() { @@ -165,7 +166,8 @@ function(app, Backbone) { perPage: this.perPage, total: this.total, totalPages: this.totalPages, - urlFun: this.urlFun + urlFun: this.urlFun, + routeEvent: this.routeEvent }; } }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/router.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/router.js b/src/fauxton/app/router.js index 45fd282..09b2338 100644 --- a/src/fauxton/app/router.js +++ b/src/fauxton/app/router.js @@ -100,19 +100,24 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents var Router = app.router = Backbone.Router.extend({ routes: {}, - // These moduleRoutes functions are aguably better outside but - // need access to the Router instance which is not created in this - // module - addModuleRoute: function(generator, route) { - this.route(route, route.toString(), generateRoute(generator, route)); - }, - - addModuleRouteObject: function(routeObject) { + addModuleRouteObject: function(RouteObject) { + var self = this; var masterLayout = this.masterLayout; - _.each(routeObject.get('routes'), function(route) { - //this.route(route, route.toString(), _.partial(routeObject.renderWith, route, this.masterLayout)); + + _.each(RouteObject.prototype.get('routes'), function(route) { this.route(route, route.toString(), function() { - routeObject.render(route, masterLayout, Array.prototype.slice.call(arguments)); + var args = Array.prototype.slice.call(arguments); + + if (self.activeRouteObject && self.activeRouteObject.get('routes').indexOf(route) > -1) { + //Don't need to do anything here as this route has been initialised + self.activeRouteObject.route.call(self.activeRouteObject, route, args); + console.log('Avoiding Route creation'); + return; + } + + self.activeRouteObject = new RouteObject(args); + self.activeRouteObject[self.activeRouteObject.defaultRoute].apply(self.activeRouteObject, args); + self.activeRouteObject.render(route, masterLayout, args); }); }, this); }, @@ -120,7 +125,6 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents setModuleRoutes: function() { _.each(modules, function(module) { if (module){ - _.each(module.Routes, this.addModuleRoute, this); _.each(module.RouteObjects, this.addModuleRouteObject, this); } }, this); @@ -129,7 +133,7 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents module.initialize(); // This is pure routes the addon provides if (module.Routes) { - _.each(module.Routes, this.addModuleRoute, this); + _.each(module.RouteObjects, this.addModuleRouteObject, this); } } }, this); @@ -167,6 +171,15 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents this.masterLayout.render(); app.footer.render(); + }, + + triggerRouteEvent: function(event, args) { + if (this.activeRouteObject) { + var eventArgs = [event].concat(args); + console.log("CALLING ROUTE EVENT ON", this.activeRouteObject, arguments); + this.activeRouteObject.trigger.apply(this.activeRouteObject, eventArgs ); + this.activeRouteObject.renderWith(eventArgs, this.masterLayout, args); + } } }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/fca31261/src/fauxton/app/templates/documents/doc_field_editor_tabs.html ---------------------------------------------------------------------- diff --git a/src/fauxton/app/templates/documents/doc_field_editor_tabs.html b/src/fauxton/app/templates/documents/doc_field_editor_tabs.html index bb16d73..b094e0e 100644 --- a/src/fauxton/app/templates/documents/doc_field_editor_tabs.html +++ b/src/fauxton/app/templates/documents/doc_field_editor_tabs.html @@ -13,8 +13,8 @@ the License. -->