implementation of new route event api and get all modules working with it
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/d8b88562 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/d8b88562 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/d8b88562 Branch: refs/heads/route-events Commit: d8b885629d943ddc6af99495a0c2cdaae3ccbc3a Parents: 10a69fb Author: Garren Smith <[email protected]> Authored: Thu May 2 15:26:26 2013 +0200 Committer: Garren Smith <[email protected]> Committed: Thu May 9 10:01:51 2013 +0200 ---------------------------------------------------------------------- src/fauxton/app/addons/config/routes.js | 10 +- src/fauxton/app/addons/logs/resources.js | 5 + src/fauxton/app/addons/logs/routes.js | 12 +- src/fauxton/app/addons/stats/routes.js | 10 +- src/fauxton/app/api.js | 72 ++-- src/fauxton/app/initialize.js | 6 +- src/fauxton/app/main.js | 3 +- src/fauxton/app/modules/databases/routes.js | 90 +--- src/fauxton/app/modules/databases/views.js | 5 +- src/fauxton/app/modules/documents/routes.js | 434 ++++++--------- src/fauxton/app/modules/documents/views.js | 12 + src/fauxton/app/modules/fauxton/base.js | 8 +- src/fauxton/app/router.js | 52 +-- .../templates/documents/doc_field_editor_tabs.html | 4 +- .../app/templates/documents/index_menu_item.html | 4 +- src/fauxton/app/templates/documents/sidebar.html | 2 +- src/fauxton/app/templates/fauxton/pagination.html | 10 +- 17 files changed, 304 insertions(+), 435 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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 4db4da7..495e3a9 100644 --- a/src/fauxton/app/addons/config/routes.js +++ b/src/fauxton/app/addons/config/routes.js @@ -24,6 +24,10 @@ function(app, FauxtonAPI, Config) { var ConfigRouteObject = FauxtonAPI.RouteObject.extend({ layout: "one_pane", + initialize: function () { + this.configs = new Config.Collection(); + }, + crumbs: [ {"name": "Config","link": "_config"} ], @@ -34,9 +38,9 @@ function(app, FauxtonAPI, Config) { routes: ["_config"], - views: function () { - this.configs = new Config.Collection(); + defaultRoute: "config", + config: function () { this.setView("#dashboard-content", new Config.View({collection: this.configs})); }, @@ -46,6 +50,6 @@ function(app, FauxtonAPI, Config) { }); - Config.RouteObjects = [new ConfigRouteObject()]; + Config.RouteObjects = [ConfigRouteObject]; return Config; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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/d8b88562/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 a6af39c..9bd8f65 100644 --- a/src/fauxton/app/addons/logs/routes.js +++ b/src/fauxton/app/addons/logs/routes.js @@ -30,25 +30,27 @@ function(app, FauxtonAPI, Log) { routes: ["_log"], + defaultRoute: "showLog", + apiUrl: function() { return this.logs.url(); }, - views: function () { + initialize: function () { this.logs = new Log.Collection(); - this.setView("#dashboard-content", new Log.Views.View({collection: this.logs})); this.setView("#sidebar-content", new Log.Views.FilterView({})); }, - route: function() { + showLog: function (event) { + this.setView("#dashboard-content", new Log.Views.View({collection: this.logs})); }, - establish: function() { + e1stablish: function() { return [this.logs.fetch()]; } }); - Log.RouteObjects = [new LogRouteObject()]; + Log.RouteObjects = [LogRouteObject]; return Log; http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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 a0fc3bf..7ad2a1f 100644 --- a/src/fauxton/app/addons/stats/routes.js +++ b/src/fauxton/app/addons/stats/routes.js @@ -22,14 +22,18 @@ function(app, FauxtonAPI, Stats) { layout: "with_sidebar", routes: ["stats", "_stats"], - views: function () { - this.stats = new Stats.Collection(); + defaultRoute: "showStats", + initialize: function () { + this.stats = new Stats.Collection(); this.setView("#sidebar-content", new Views.StatSelect({ collection: this.stats })); + }, + + showStats: function (event) { this.setView("#dashboard-content", new Views.Statistics({ collection: this.stats })); @@ -42,7 +46,7 @@ function(app, FauxtonAPI, Stats) { apiUrl: "_stats" }); - Stats.RouteObjects = [new StatsRouteObject()]; + Stats.RouteObjects = [StatsRouteObject]; return Stats; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/src/fauxton/app/api.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js index de0844c..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,7 @@ function(app, Fauxton) { } }); + // Not needed, could be removed. FauxtonAPI.routeCallChain = { callChain: {}, @@ -129,7 +142,7 @@ function(app, Fauxton) { _.extend(FauxtonAPI.RouteObject.prototype, Backbone.Events, { // Should these be default vals or empty funcs? - _views: {}, + views: {}, routes: {}, events: {}, data: {}, @@ -142,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 @@ -153,20 +162,17 @@ 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.preloadViews(); - this.renderWith.apply(this, arguments); - } + this.renderWith.apply(this, Array.prototype.slice.call(arguments)); }, renderWith: function(route, masterLayout, args) { var routeObject = this; - this.masterLayout = masterLayout; - 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'); @@ -178,7 +184,10 @@ function(app, Fauxton) { $.when.apply(this, this.establish()).done(function(resp) { _.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); @@ -192,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); + } + }); }); }); @@ -208,12 +215,6 @@ function(app, Fauxton) { this.renderedState = true; }, - preloadViews: function () { - _.each(this.get('views'), function (view, selector) { - this.setView(selector, view); - }, this); - }, - get: function(key) { return _.isFunction(this[key]) ? this[key]() : this[key]; }, @@ -237,27 +238,18 @@ function(app, Fauxton) { }, getView: function(selector) { - return this._views[selector]; + return this.views[selector]; }, setView: function(selector, view) { - this._views[selector] = view; + this.views[selector] = view; return view; }, - rerenderView: function(selector) { - var view = this._views[selector]; - this.masterLayout.setView(selector, view); - this.masterLayout.renderView(selector); - }, - getViews: function() { - return this._views; - }, - - clearViews: function () { - this._views = {}; + return this.views; } + }); app.fauxtonAPI = FauxtonAPI; http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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/d8b88562/src/fauxton/app/main.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/main.js b/src/fauxton/app/main.js index 99ea803..203b295 100644 --- a/src/fauxton/app/main.js +++ b/src/fauxton/app/main.js @@ -26,9 +26,10 @@ function(app, Router) { var routeEvent = $(this).attr("route-event"); if (routeEvent) { evt.preventDefault(); - app.router.triggerRouteEvent("route:"+routeEvent, href); // 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) { http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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 f332eac..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,35 +30,38 @@ 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() { return this.databases.url(); }, - views: function() { + initialize: function() { this.databases = new Databases.List(); this.deferred = FauxtonAPI.Deferred(); - this.databasesView = this.setView("#dashboard-content", new Views.List({ + this.sidebarView = this.setView("#sidebar-content", new Views.Sidebar({ collection: this.databases })); + }, - this.databasesView.setPage(this.dbPage); + allDatabases: function(event) { + event = event || {}; - this.sidebarView = this.setView("#sidebar-content", new Views.Sidebar({ + var params = app.getParams(event.attr), + dbPage = params.page; + + this.databasesView = this.setView("#dashboard-content", new Views.List({ collection: this.databases })); - }, - - route: function() { - var params = app.getParams(); - this.dbPage = params.page; - }, - rerender: function() { - this.databasesView.setPage(this.dbPage); - this.databasesView.render(); + this.databasesView.setPage(dbPage); }, establish: function() { @@ -73,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/d8b88562/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/d8b88562/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 78af28e..d57487f 100644 --- a/src/fauxton/app/modules/documents/routes.js +++ b/src/fauxton/app/modules/documents/routes.js @@ -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 })); }, @@ -182,13 +182,40 @@ function(app, FauxtonAPI, Documents, Databases) { var DocumentsRouteObject = FauxtonAPI.RouteObject.extend({ layout: "with_tabs_sidebar", - initialize: function () { - - }, - events: { "route:all_docs": "allDocs", - "route:all_design_docs": "allDesignDocs" + "route:all_design_docs": "allDesignDocs", + "route:view_fn": "viewFn", + "route:new_view": "newViewEditor" + }, + + 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}) + }; + + this.data.designDocs = new Documents.AllDocs(null, { + database: this.data.database, + params: {startkey: '"_design"', + endkey: '"_design1"', + include_docs: true} + }); + + this.sidebar = this.setView("#sidebar-content", new Documents.Views.Sidebar({ + collection: this.data.designDocs + })); + + this.setView("#tabs", new Documents.Views.Tabs({ + collection: this.data.designDocs, + database: this.data.database + })); }, crumbs: function () { @@ -198,140 +225,109 @@ function(app, FauxtonAPI, Documents, Databases) { ]; }, - allDocs: function() { - console.log("TRIGGERING all_docs ROUTE EVENT", arguments); - }, + allDocs: function(event) { + var docOptions; - allDesignDocs: function() { - console.log("TRIGGERING all_design_docs ROUTE EVENT", arguments); - }, + docOptions = app.getParams(event.attr); + docOptions.include_docs = true; - routes: ["database/:database/_all_docs(:extra)", "database/:database/_design/:ddoc/_view/:view"], + this.data.database.buildAllDocs(docOptions); + this.sidebar.setSelectedTab('all-docs'); - apiUrl: function() { - return this.data.database.allDocs.url(); - }, - - route: function(route, params) { - this.databaseName = params[0]; - - if (params.length > 2) { - this.view = params[2].replace(/\?.*$/,''); - this.ddoc = params[1]; - } else { - delete this.view; - delete this.ddoc; - } + this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({ + collection: this.data.database.allDocs + })); }, - // this works for now, but it might be work considering having a renderWith function - // that only renders a specific view and setups up that views establish beforehand. - rerender: function () { - var self = this, - options = app.getParams(); - - options.include_docs = true; - this.data.database.buildAllDocs(options); + allDesignDocs: function(event) { + var docOptions = app.getParams(event.attr); + docOptions.include_docs = true; - this.updateDashboardView(); + this.data.database.buildAllDocs(docOptions); + this.sidebar.setSelectedTab('design-docs'); - //this.documentsView.collection = this.data.database.allDocs; - - $.when.apply(null, this.documentsView.establish()).then(function () { - //self.documentsView.render(); - self.rerenderView('#dashboard-content'); - }); + this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({ + collection: this.data.database.allDocs + })); }, - updateDashboardView: function () { - var options = app.getParams(); + route: function (route, routeArgs) { + console.log('ROUTE ARG ', arguments); - if (this.view) { - var ddocInfo = { - id: "_design/" + this.ddoc, - currView: this.view, - designDocs: this.data.designDocs - }; + if (route === 'database/:database/_design/:ddoc/_view/:view') { - this.data.indexedDocs = new Documents.IndexCollection(null, { - database: this.data.database, - design: this.ddoc, - view: this.view, - params: options - }); - - this.documentsView = this.setView('#dashboard-content',new Documents.Views.AllDocsList({ - collection: this.data.indexedDocs, - nestedView: Documents.Views.Row, - viewList: true, - ddocInfo: ddocInfo, - params: options - })); + 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.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({ - collection: this.data.database.allDocs - })); + this.routeArgs = {}; + if (this.docCrumbs && this.docApiUrl) { + this.crumbs = this.docCrumbs; + this.docApiUrl = this.apiUrl; + } } - }, - views: function () { - this.data = { - database: new Databases.Model({id:this.databaseName}) - }; + viewFn: function (event) { + var view = this.routeArgs.view, + ddoc = this.routeArgs.designDoc, + params = app.getParams(event.attr); - this.data.designDocs = new Documents.AllDocs(null, { + console.log('PARAMS', params); + + this.data.indexedDocs = new Documents.IndexCollection(null, { database: this.data.database, - params: {startkey: '"_design"', - endkey: '"_design1"', - include_docs: true} + design: ddoc, + view: view, + params: params }); + var ddocInfo = { + id: "_design/" + ddoc, + currView: view, + designDocs: this.data.designDocs + }; - var options = app.getParams(); - options.include_docs = true; - this.data.database.buildAllDocs(options); + this.setView("#dashboard-content", new Documents.Views.AllDocsList({ + collection: this.data.indexedDocs, + nestedView: Documents.Views.Row, + viewList: true, + ddocInfo: ddocInfo, + params: params + })); - if (this.view) { - var ddocInfo = { - id: "_design/" + this.ddoc, - currView: this.view, - designDocs: this.data.designDocs - }; + this.crumbs = function () { + return [ + {"name": "Databases", "link": "/_all_dbs"}, + {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}, + {"name": ddoc + "/" + view, "link": this.data.indexedDocs.url()} + ]; + }; - this.data.indexedDocs = new Documents.IndexCollection(null, { - database: this.data.database, - design: this.ddoc, - view: this.view, - params: options - }); - - this.documentsView = this.setView('#dashboard-content',new Documents.Views.AllDocsList({ - collection: this.data.indexedDocs, - nestedView: Documents.Views.Row, - viewList: true, - ddocInfo: ddocInfo, - params: options - })); + // TODO: change to view URL + this.apiUrl = this.data.indexedDocs.url(); + }, - } else { + newViewEditor: function (event) { + // TODO: Get this working + this.setView("#dashboard-content", new Documents.Views.ViewEditor({ + model: this.data.database, + ddocs: this.data.designDocs + })); - this.documentsView = this.setView("#dashboard-content", new Documents.Views.AllDocsList({ - collection: this.data.database.allDocs - })); - } + }, - - this.setView("#sidebar-content", new Documents.Views.Sidebar({ - collection: this.data.designDocs - })); + routes: ["database/:database/_all_docs(:extra)", "database/:database/_design/:ddoc/_view/:view", "database/:database/new_view"], - this.setView("#tabs", new Documents.Views.Tabs({ - collection: this.data.designDocs, - database: this.data.database - })); + apiUrl: function() { + return this.data.database.allDocs.url(); } }); @@ -350,141 +346,63 @@ function(app, FauxtonAPI, Documents, Databases) { routes: ["database/:database/_changes(:params)"], - apiUrl: function() { - return this.database.changes.url(); + events: { + "route:_changes": "changes" }, - route: function(route, params) { - this.databaseName = params[0]; - }, + defaultRoute: "changes", - views: function () { + initialize: function (options) { + this.databaseName = options[0]; this.database = new Databases.Model({id: this.databaseName}); - var options = app.getParams(); - this.database.buildChanges(options); - + var docOptions = app.getParams(); - this.setView("#dashboard-content", new Documents.Views.Changes({ - model: this.database - })); + 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/:doc/code_editor": codeEditorCallback, - //"database/:database/:doc": codeEditorCallback, - "database/:database/_design%2F:doc": function(database, doc) { - var docID = "_design/"+doc; - return codeEditorCallback(database, docID); - }, - - "database/:database/_all_docs(:extra)": function(databaseName, page) { - var data = { -database: new Databases.Model({id:databaseName}) -}; -data.designDocs = new Documents.AllDocs(null, { -database: data.database, -params: {startkey: '"_design"', -endkey: '"_design1"', -include_docs: true} -}); + "database/:database/_design%2F:doc": function(database, doc) { + var docID = "_design/"+doc; + return codeEditorCallback(database, docID); + }, -var options = app.getParams(); -options.include_docs = true; -data.database.buildAllDocs(options); -return { -layout: "with_tabs_sidebar", - -data: data, -crumbs: [ -{"name": "Databases", "link": "/_all_dbs"}, -{"name": data.database.id, "link": Databases.databaseUrl(data.database)} -], - -views: { -"#dashboard-content": new Documents.Views.AllDocsList({ -collection: data.database.allDocs -}), - -"#sidebar-content": new Documents.Views.Sidebar({ -collection: data.designDocs -}), - -"#tabs": new Documents.Views.Tabs({ -collection: data.designDocs, -database: data.database -}) -}, - -apiUrl: data.database.allDocs.url() -}; -}, - -"database/:database/_changes(:params)": function(databaseName, params) { -var data = { -database: new Databases.Model({id:databaseName}) -}; - -var options = app.getParams(); -data.database.buildChanges(options); - -return { -layout: "with_tabs", - -data: data, - -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() - }; -}, - - "database/:database/new": newDocCodeEditorCallback, - "database/:database/new_view": newViewEditorCallback, + "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 = { +// 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, { +data.indexedDocs = new Documents.IndexCollection(null, { database: data.database, design: ddoc, view: view, @@ -500,17 +418,17 @@ include_docs: true} var ddocInfo = { id: "_design/" + ddoc, - currView: view, - designDocs: data.designDocs +currView: view, +designDocs: data.designDocs }; return { layout: "with_tabs_sidebar", - data: data, - // TODO: change dashboard-content - views: { - "#dashboard-content": new Documents.Views.AllDocsList({ +data: data, + // TODO: change dashboard-content +views: { +"#dashboard-content": new Documents.Views.AllDocsList({ collection: data.indexedDocs, nestedView: Documents.Views.Row, viewList: true, @@ -518,12 +436,12 @@ ddocInfo: ddocInfo, params: params }), - "#sidebar-content": new Documents.Views.Sidebar({ +"#sidebar-content": new Documents.Views.Sidebar({ collection: data.designDocs, ddocInfo: ddocInfo }), - "#tabs": new Documents.Views.Tabs({ +"#tabs": new Documents.Views.Tabs({ collection: data.designDocs, database: data.database }) @@ -540,7 +458,7 @@ crumbs: [ } };*/ - Documents.RouteObjects = [new DocEditorRouteObject(), new DocumentsRouteObject(), new ChangesRouteObject()]; + Documents.RouteObjects = [DocEditorRouteObject, DocumentsRouteObject, ChangesRouteObject]; return Documents; }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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/d8b88562/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/d8b88562/src/fauxton/app/router.js ---------------------------------------------------------------------- diff --git a/src/fauxton/app/router.js b/src/fauxton/app/router.js index 2bcd071..09b2338 100644 --- a/src/fauxton/app/router.js +++ b/src/fauxton/app/router.js @@ -97,51 +97,27 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents }; }; - FauxtonAPI.routeCallChain.registerBeforeRoute('no_deferred', function () { - console.log('This is a before route callback with no deferred.'); - }); - - FauxtonAPI.routeCallChain.registerBeforeRoute('deferred', function () { - var deferred = $.Deferred(); - - setTimeout(function () { - console.log('hi this is a delayed called before each route.'); - deferred.resolve(); - }, 10); - - return deferred; - }); - 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) { + _.each(RouteObject.prototype.get('routes'), function(route) { this.route(route, route.toString(), function() { - var args = arguments; + var args = Array.prototype.slice.call(arguments); - if (self.activeRouteObject && routeObject !== self.activeRouteObject) { - self.activeRouteObject.renderedState = false; - self.activeRouteObject.clearViews(); + 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; } - FauxtonAPI.routeCallChain.run().then(function () { - routeObject.initialize(); - routeObject.render(route, masterLayout, Array.prototype.slice.call(args)); - }); - - self.activeRouteObject = routeObject; - + self.activeRouteObject = new RouteObject(args); + self.activeRouteObject[self.activeRouteObject.defaultRoute].apply(self.activeRouteObject, args); + self.activeRouteObject.render(route, masterLayout, args); }); }, this); }, @@ -149,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); @@ -158,7 +133,6 @@ 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); } } @@ -201,8 +175,10 @@ function(req, app, Initialize, FauxtonAPI, Fauxton, Layout, Databases, Documents 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, [event].concat(args)); + this.activeRouteObject.trigger.apply(this.activeRouteObject, eventArgs ); + this.activeRouteObject.renderWith(eventArgs, this.masterLayout, args); } } }); http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/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. --> <ul class="nav nav-tabs"> - <li class="<%= isSelectedClass('field_editor') %>"><a href="#<%= doc.url('app') %>/field_editor">Doc fields</a></li> - <li class="<%= isSelectedClass('code_editor') %>"><a href="#<%= doc.url('app') %>/code_editor"><i class="icon-pencil"></i> Code editor</a></li> + <li id="field_editor" class="<%= isSelectedClass('field_editor') %>"><a route-event="field_editor" href="#<%= doc.url('app') %>/field_editor">Doc fields</a></li> + <li id="code_editor" class="<%= isSelectedClass('code_editor') %>"><a route-event="code_editor" href="#<%= doc.url('app') %>/code_editor"><i class="icon-pencil"></i> Code editor</a></li> <ul class="nav pull-right" style="margin:5px 10px 0px 10px;"> <li> <div class="btn-group"> http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/src/fauxton/app/templates/documents/index_menu_item.html ---------------------------------------------------------------------- diff --git a/src/fauxton/app/templates/documents/index_menu_item.html b/src/fauxton/app/templates/documents/index_menu_item.html index bb16b4f..2dac868 100644 --- a/src/fauxton/app/templates/documents/index_menu_item.html +++ b/src/fauxton/app/templates/documents/index_menu_item.html @@ -12,6 +12,6 @@ License for the specific language governing permissions and limitations under the License. --> -<a href="#database/<%= database %>/_design/<%= ddoc %>/_view/<%= index %>" class="toggle-view"> +<a route-event="view_fn" href="#database/<%= database %>/_design/<%= ddoc %>/_view/<%= index %>" class="toggle-view"> <i class="icon-list"></i> <%= ddoc %><span class="divider">/</span><%= index %> -</a> \ No newline at end of file +</a> http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/src/fauxton/app/templates/documents/sidebar.html ---------------------------------------------------------------------- diff --git a/src/fauxton/app/templates/documents/sidebar.html b/src/fauxton/app/templates/documents/sidebar.html index 9c61adc..a8841a2 100644 --- a/src/fauxton/app/templates/documents/sidebar.html +++ b/src/fauxton/app/templates/documents/sidebar.html @@ -24,6 +24,6 @@ the License. </ul> <ul class="nav nav-list views"> <li class="nav-header">Secondary Indexes</li> - <li><a href="#<%= database.url('app') %>/new_view" class="new"><i class="icon-plus"></i> New</a></li> + <li><a route-event="new_view" href="#<%= database.url('app') %>/new_view" class="new"><i class="icon-plus"></i> New</a></li> </ul> </div> http://git-wip-us.apache.org/repos/asf/couchdb/blob/d8b88562/src/fauxton/app/templates/fauxton/pagination.html ---------------------------------------------------------------------- diff --git a/src/fauxton/app/templates/fauxton/pagination.html b/src/fauxton/app/templates/fauxton/pagination.html index 161593b..2ec5ebe 100644 --- a/src/fauxton/app/templates/fauxton/pagination.html +++ b/src/fauxton/app/templates/fauxton/pagination.html @@ -1,17 +1,17 @@ <div class="pagination pagination-centered"> <ul> <% if (page > 1) { %> - <li><a href="<%= urlFun(page-1) %>">«</a></li> + <li><a route-event="<%= routeEvent %>" href="<%= urlFun(page-1) %>">«</a></li> <% } else { %> - <li class="disabled"><a href="<%= urlFun(page) %>">«</a></li> + <li class="disabled"><a a route-event="<%= routeEvent %>" href="<%= urlFun(page) %>">«</a></li> <% } %> <% _.each(_.range(1, totalPages+1), function(i) { %> - <li <% if (page == i) { %>class="active"<% } %>><a href="<%= urlFun(i) %>"><%= i %></a></li> + <li <% if (page == i) { %>class="active"<% } %>><a route-event="<%= routeEvent %>" href="<%= urlFun(i) %>"><%= i %></a></li> <% }) %> <% if (page < totalPages) { %> - <li><a href="<%= urlFun(page+1) %>">»</a></li> + <li><a route-event="<%= routeEvent %>" href="<%= urlFun(page+1) %>">»</a></li> <% } else { %> - <li class="disabled"><a href="<%= urlFun(page) %>">»</a></li> + <li class="disabled"><a route-event="<%= routeEvent %>" href="<%= urlFun(page) %>">»</a></li> <% } %> </ul> </div>
