You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2014/01/27 09:18:55 UTC
[10/16] couchdb commit: updated refs/heads/fauxton-file-reorder to
20f8d05
Initial run
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/719617e3
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/719617e3
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/719617e3
Branch: refs/heads/fauxton-file-reorder
Commit: 719617e336454807ce8fd3f5289f3a5aeb0f6a2a
Parents: 3150bb1
Author: Garren Smith <ga...@gmail.com>
Authored: Mon Jan 13 20:34:32 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Mon Jan 27 08:41:29 2014 +0200
----------------------------------------------------------------------
src/fauxton/app/core/couchdb.js | 78 +++++++++
src/fauxton/app/core/resources.js | 301 +++++++++++++++++++++++++++++++++
2 files changed, 379 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/719617e3/src/fauxton/app/core/couchdb.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/couchdb.js b/src/fauxton/app/core/couchdb.js
new file mode 100644
index 0000000..39cdc1a
--- /dev/null
+++ b/src/fauxton/app/core/couchdb.js
@@ -0,0 +1,78 @@
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+ "app",
+ "core/base"
+],
+function (app, FauxtonAPI) {
+ //this later needs to be dynamically loaded
+
+ FauxtonAPI.UUID = FauxtonAPI.Model.extend({
+ initialize: function(options) {
+ options = _.extend({count: 1}, options);
+ this.count = options.count;
+ },
+
+ url: function() {
+ return app.host + "/_uuids?count=" + this.count;
+ },
+
+ next: function() {
+ return this.get("uuids").pop();
+ }
+ });
+
+ FauxtonAPI.Session = FauxtonAPI.Model.extend({
+ url: app.host + '/_session',
+
+ user: function () {
+ var userCtx = this.get('userCtx');
+
+ if (!userCtx || !userCtx.name) { return null; }
+
+ return {
+ name: userCtx.name,
+ roles: userCtx.roles
+ };
+ },
+
+ fetchUser: function (opt) {
+ var that = this,
+ currentUser = this.user();
+
+ return this.fetchOnce(opt).then(function () {
+ var user = that.user();
+
+ // Notify anyone listening on these events that either a user has changed
+ // or current user is the same
+ if (currentUser !== user) {
+ that.trigger('session:userChanged');
+ } else {
+ that.trigger('session:userFetched');
+ }
+
+ // this will return the user as a value to all function that calls done on this
+ // eg. session.fetchUser().done(user) { .. do something with user ..}
+ return user;
+ });
+ }
+ });
+
+ FauxtonAPI.setSession = function (newSession) {
+ app.session = FauxtonAPI.session = newSession;
+ return FauxtonAPI.session.fetchUser();
+ };
+
+ //set default session
+ FauxtonAPI.setSession(new FauxtonAPI.Session());
+
+ return FauxtonAPI;
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/719617e3/src/fauxton/app/core/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/resources.js b/src/fauxton/app/core/resources.js
new file mode 100644
index 0000000..83111c7
--- /dev/null
+++ b/src/fauxton/app/core/resources.js
@@ -0,0 +1,301 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+define([
+ "app",
+ "core/couchdb",
+ "addons/fauxton/base",
+ "backbone"
+],
+function(app, FauxtonAPI, Fauxton) {
+
+ // This is not exposed externally as it should not need to be accessed or overridden
+ var Auth = function (options) {
+ this._options = options;
+ this.initialize.apply(this, arguments);
+ };
+
+ // Piggy-back on Backbone's self-propagating extend function,
+ Auth.extend = Backbone.Model.extend;
+
+ _.extend(Auth.prototype, Backbone.Events, {
+ authDeniedCb: function() {},
+
+ initialize: function() {
+ var that = this;
+ },
+
+ authHandlerCb : function (roles) {
+ var deferred = $.Deferred();
+ deferred.resolve();
+ return deferred;
+ },
+
+ registerAuth: function (authHandlerCb) {
+ this.authHandlerCb = authHandlerCb;
+ },
+
+ registerAuthDenied: function (authDeniedCb) {
+ this.authDeniedCb = authDeniedCb;
+ },
+
+ checkAccess: function (roles) {
+ var requiredRoles = roles || [],
+ that = this;
+
+ if (!FauxtonAPI.session) {
+ throw new Error("Fauxton.session is not configured.");
+ }
+
+ return FauxtonAPI.session.fetchUser().then(function (user) {
+ return FauxtonAPI.when(that.authHandlerCb(FauxtonAPI.session, requiredRoles));
+ });
+ }
+ });
+
+ FauxtonAPI.auth = new Auth();
+
+ FauxtonAPI.RouteObject = function(options) {
+ this._options = options;
+
+ this._configure(options || {});
+ this.initialize.apply(this, arguments);
+ this.addEvents();
+ };
+
+ var broadcaster = {};
+ _.extend(broadcaster, Backbone.Events);
+
+ FauxtonAPI.RouteObject.on = function (eventName, fn) {
+ broadcaster.on(eventName, fn);
+ };
+
+ /* How Route Object events work
+ To listen to a specific route objects events:
+
+ myRouteObject = FauxtonAPI.RouteObject.extend({
+ events: {
+ "beforeRender": "beforeRenderEvent"
+ },
+
+ beforeRenderEvent: function (view, selector) {
+ console.log('Hey, beforeRenderEvent triggered',arguments);
+ },
+ });
+
+ It is also possible to listen to events triggered from all Routeobjects.
+ This is great for more general things like adding loaders, hooks.
+
+ FauxtonAPI.RouteObject.on('beforeRender', function (routeObject, view, selector) {
+ console.log('hey, this will trigger when any routeobject renders a view');
+ });
+
+ Current Events to subscribe to:
+ * beforeFullRender -- before a full render is being done
+ * beforeEstablish -- before the routeobject calls establish
+ * AfterEstablish -- after the routeobject has run establish
+ * beforeRender -- before a view is rendered
+ * afterRender -- a view is finished being rendered
+ * renderComplete -- all rendering is complete
+
+ */
+
+ // Piggy-back on Backbone's self-propagating extend function
+ FauxtonAPI.RouteObject.extend = Backbone.Model.extend;
+
+ var routeObjectOptions = ["views", "routes", "events", "roles", "crumbs", "layout", "apiUrl", "establish"];
+
+ _.extend(FauxtonAPI.RouteObject.prototype, Backbone.Events, {
+ // Should these be default vals or empty funcs?
+ views: {},
+ routes: {},
+ events: {},
+ crumbs: [],
+ layout: "with_sidebar",
+ apiUrl: null,
+ disableLoader: false,
+ loaderClassname: 'loader',
+ renderedState: false,
+ establish: function() {},
+ route: function() {},
+ roles: [],
+ initialize: function() {}
+ }, {
+
+ renderWith: function(route, masterLayout, args) {
+ var routeObject = this,
+ triggerBroadcast = _.bind(this.triggerBroadcast, this);
+
+ // Only want to redo the template if its a full render
+ if (!this.renderedState) {
+ masterLayout.setTemplate(this.layout);
+ triggerBroadcast('beforeFullRender');
+ $('#primary-navbar li').removeClass('active');
+
+ if (this.selectedHeader) {
+ app.selectedHeader = this.selectedHeader;
+ $('#primary-navbar li[data-nav-name="' + this.selectedHeader + '"]').addClass('active');
+ }
+ }
+
+ masterLayout.clearBreadcrumbs();
+ var crumbs = this.get('crumbs');
+
+ if (crumbs.length) {
+ masterLayout.setBreadcrumbs(new Fauxton.Breadcrumbs({
+ crumbs: crumbs
+ }));
+ }
+
+ triggerBroadcast('beforeEstablish');
+ FauxtonAPI.when(this.establish()).then(function(resp) {
+ triggerBroadcast('afterEstablish');
+ _.each(routeObject.getViews(), function(view, selector) {
+ if(view.hasRendered) {
+ triggerBroadcast('viewHasRendered', view, selector);
+ return;
+ }
+
+ triggerBroadcast('beforeRender', view, selector);
+ FauxtonAPI.when(view.establish()).then(function(resp) {
+ masterLayout.setView(selector, view);
+
+ masterLayout.renderView(selector);
+ triggerBroadcast('afterRender', view, selector);
+ }, function(resp) {
+ view.establishError = {
+ error: true,
+ reason: resp
+ };
+
+ if (resp) {
+ var errorText = JSON.parse(resp.responseText).reason;
+ FauxtonAPI.addNotification({
+ msg: 'An Error occurred: ' + errorText,
+ type: 'error',
+ clear: true
+ });
+ }
+
+ masterLayout.renderView(selector);
+ });
+
+ });
+ }.bind(this), function (resp) {
+ if (!resp) { return; }
+ FauxtonAPI.addNotification({
+ msg: 'An Error occurred' + JSON.parse(resp.responseText).reason,
+ type: 'error',
+ clear: true
+ });
+ });
+
+ if (this.get('apiUrl')){
+ masterLayout.apiBar.update(this.get('apiUrl'));
+ } else {
+ masterLayout.apiBar.hide();
+ }
+
+ // Track that we've done a full initial render
+ this.renderedState = true;
+ triggerBroadcast('renderComplete');
+ },
+
+ triggerBroadcast: function (eventName) {
+ var args = Array.prototype.slice.call(arguments);
+ this.trigger.apply(this, args);
+
+ args.splice(0,1, eventName, this);
+ broadcaster.trigger.apply(broadcaster, args);
+ },
+
+ get: function(key) {
+ return _.isFunction(this[key]) ? this[key]() : this[key];
+ },
+
+ addEvents: function(events) {
+ events = events || this.get('events');
+ _.each(events, function(method, event) {
+ if (!_.isFunction(method) && !_.isFunction(this[method])) {
+ throw new Error("Invalid method: "+method);
+ }
+ method = _.isFunction(method) ? method : this[method];
+
+ this.on(event, method);
+ }, this);
+ },
+
+ _configure: function(options) {
+ _.each(_.intersection(_.keys(options), routeObjectOptions), function(key) {
+ this[key] = options[key];
+ }, this);
+ },
+
+ getView: function(selector) {
+ return this.views[selector];
+ },
+
+ setView: function(selector, view) {
+ this.views[selector] = view;
+ return view;
+ },
+
+ getViews: function() {
+ return this.views;
+ },
+
+ removeViews: function () {
+ _.each(this.views, function (view, selector) {
+ view.remove();
+ delete this.views[selector];
+ }, this);
+ },
+
+ getRouteUrls: function () {
+ return _.keys(this.get('routes'));
+ },
+
+ hasRoute: function (route) {
+ if (this.get('routes')[route]) {
+ return true;
+ }
+ return false;
+ },
+
+ routeCallback: function (route, args) {
+ var routes = this.get('routes'),
+ routeObj = routes[route],
+ routeCallback;
+
+ if (typeof routeObj === 'object') {
+ routeCallback = this[routeObj.route];
+ } else {
+ routeCallback = this[routeObj];
+ }
+
+ routeCallback.apply(this, args);
+ },
+
+ getRouteRoles: function (routeUrl) {
+ var route = this.get('routes')[routeUrl];
+
+ if ((typeof route === 'object') && route.roles) {
+ return route.roles;
+ }
+
+ return this.roles;
+ }
+
+ });
+
+ return FauxtonAPI;
+});