You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by de...@apache.org on 2013/12/23 18:20:42 UTC

[1/3] git commit: updated refs/heads/master to b0bf0f3

Updated Branches:
  refs/heads/master a6d55bbfc -> b0bf0f369


decode ddoc from route.
Fix issue with adding ddoc to collection on save, but not on preview
regex fix
fixed the regex for sniffing for design docs
More encoding for Ddocs


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

Branch: refs/heads/master
Commit: d33b7dfc880523e7f3ad45bc47a3c8ae0abd5faf
Parents: 8c33315
Author: suelockwood <de...@apache.org>
Authored: Mon Dec 23 10:14:36 2013 -0500
Committer: suelockwood <de...@apache.org>
Committed: Mon Dec 23 12:20:29 2013 -0500

----------------------------------------------------------------------
 src/fauxton/app/modules/databases/resources.js       |  4 +++-
 src/fauxton/app/modules/documents/resources.js       | 11 +++++++++--
 src/fauxton/app/modules/documents/routes.js          | 15 +++++++++------
 src/fauxton/app/modules/documents/views.js           | 12 ++++++++----
 .../app/templates/documents/all_docs_item.html       |  2 +-
 5 files changed, 30 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/d33b7dfc/src/fauxton/app/modules/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/resources.js b/src/fauxton/app/modules/databases/resources.js
index 2e66176..a01c9ce 100644
--- a/src/fauxton/app/modules/databases/resources.js
+++ b/src/fauxton/app/modules/databases/resources.js
@@ -84,7 +84,9 @@ function(app, FauxtonAPI, Documents) {
       this.database = options.database;
       this.params = options.params;
     },
-
+    documentation: function(){
+      return "changes";
+    },
     url: function () {
       var query = "";
       if (this.params) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d33b7dfc/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index a171cae..f833ded 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -26,6 +26,8 @@ function(app, FauxtonAPI) {
     url: function(context) {
       if (context === "app") {
         return this.getDatabase().url("app") + "/" + this.safeID();
+      } else if (context === "web-index") {
+        return this.getDatabase().url("app") + "/" + app.mixins.safeURLName(this.id);
       } else {
         return app.host + "/" + this.getDatabase().safeID() + "/" + this.safeID();
       }
@@ -139,7 +141,12 @@ function(app, FauxtonAPI) {
     // treated separately. For instance, we could default into the
     // json editor for docs, or into a ddoc specific page.
     safeID: function() {
-      return app.mixins.safeURLName(this.id);
+      if (this.isDdoc()){
+        var ddoc = this.id.replace(/^_design\//,"");
+        return "_design/"+app.mixins.safeURLName(ddoc);
+      }else{
+        return app.mixins.safeURLName(this.id);
+      }
     },
 
     destroy: function() {
@@ -209,7 +216,7 @@ function(app, FauxtonAPI) {
     // treated separately. For instance, we could default into the
     // json editor for docs, or into a ddoc specific page.
     safeID: function() {
-      var ddoc = this.id.replace(/_design\//,"");
+      var ddoc = this.id.replace(/^_design\//,"");
       return "_design/"+app.mixins.safeURLName(ddoc);
     }
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d33b7dfc/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 4727cdc..56cdc1b 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -162,7 +162,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       var docOptions = app.getParams();
       docOptions.include_docs = true;
 
-      this.databaseName = app.mixins.safeURLName(options[0]);
+      this.databaseName = options[0];
 
       this.data = {
         database: new Databases.Model({id:this.databaseName})
@@ -222,19 +222,22 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     viewFn: function (databaseName, ddoc, view) {
-      var params = app.getParams();
+      var params = app.getParams(),
+          decodeDdoc = decodeURIComponent(ddoc);
 
       view = view.replace(/\?.*$/,'');
 
       this.data.indexedDocs = new Documents.IndexCollection(null, {
         database: this.data.database,
-        design: ddoc,
+        design: decodeDdoc,
         view: view,
         params: params
       });
 
+
+
       var ddocInfo = {
-        id: "_design/" + ddoc,
+        id: "_design/" + decodeDdoc,
         currView: view,
         designDocs: this.data.designDocs
       };
@@ -373,7 +376,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     initialize: function (route, masterLayout, options) {
-      this.databaseName = app.mixins.safeURLName(options[0]);
+      this.databaseName = options[0];
       this.database = new Databases.Model({id: this.databaseName});
 
       var docOptions = app.getParams();
@@ -394,7 +397,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     apiUrl: function() {
-      return [this.database.changes.url(), this.database.changes.documentation()];
+      return [this.database.url(), this.database.documentation()];
     }
 
   });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d33b7dfc/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 94fe699..96314ad 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -238,10 +238,11 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     duplicate: function (event) {
       event.preventDefault();
-      var newId = this.$('#dup-id').val();
+      var newId = this.$('#dup-id').val(),
+          encodedID = app.mixins.safeURLName(newId);
 
       this.hideModal();
-      FauxtonAPI.triggerRouteEvent('duplicateDoc', newId);
+      FauxtonAPI.triggerRouteEvent('duplicateDoc', encodedID);
     },
 
     _showModal: function () {
@@ -1161,6 +1162,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     newDesignDoc: function () {
+
       return this.$('#ddoc').val() === 'new-doc';
     },
 
@@ -1175,7 +1177,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           language: "javascript"
         };
         var ddoc = new this.DocModel(doc, {database: this.database});
-        this.collection.add(ddoc);
+        //this.collection.add(ddoc);
         return ddoc;
       } else if ( !this.newDesignDoc() ) {
         var ddocName = this.$('#ddoc').val();
@@ -1303,6 +1305,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         ddoc.setDdocView(viewName, mapVal, reduceVal);
 
         ddoc.save().then(function () {
+          that.ddocs.add(ddoc);
+
           that.mapEditor.editSaved();
           that.reduceEditor && that.reduceEditor.editSaved();
 
@@ -1714,7 +1718,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.collection.each(function(design) {
         if (design.has('doc')){
-          var ddoc = design.id.replace(/_design\//,"");
+          var ddoc = design.id.replace(/^_design\//,"");
           if (design.get('doc').views){
             this.buildIndexList(design.get('doc').views, "views", ddoc);
           }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/d33b7dfc/src/fauxton/app/templates/documents/all_docs_item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/documents/all_docs_item.html b/src/fauxton/app/templates/documents/all_docs_item.html
index c0e61cf..bfedaaa 100644
--- a/src/fauxton/app/templates/documents/all_docs_item.html
+++ b/src/fauxton/app/templates/documents/all_docs_item.html
@@ -18,7 +18,7 @@ the License.
     <pre class="prettyprint"><%- doc.prettyJSON() %></pre>
     <% if (doc.isEditable()) { %>
       <div class="btn-group">
-        <a href="#<%= doc.url('app') %>" class="btn btn-small edits">Edit <%= doc.docType() %></a>
+        <a href="#<%= doc.url('web-index') %>" class="btn btn-small edits">Edit <%= doc.docType() %></a>
         <button href="#" class="btn btn-small btn-danger delete" title="Delete this document."><i class="icon icon-trash"></i></button>
       </div>
     <% } %>


[3/3] git commit: updated refs/heads/master to b0bf0f3

Posted by de...@apache.org.
Fix API urls
Fix data size


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

Branch: refs/heads/master
Commit: b0bf0f369f46b027c03b258344923cea36cb75c8
Parents: d33b7df
Author: suelockwood <de...@apache.org>
Authored: Mon Dec 23 11:01:34 2013 -0500
Committer: suelockwood <de...@apache.org>
Committed: Mon Dec 23 12:20:30 2013 -0500

----------------------------------------------------------------------
 src/fauxton/app/addons/activetasks/resources.js |  8 +++++--
 src/fauxton/app/addons/activetasks/routes.js    |  2 +-
 src/fauxton/app/modules/databases/resources.js  | 25 ++++++++++++++++----
 src/fauxton/app/modules/databases/routes.js     |  2 +-
 src/fauxton/app/modules/documents/resources.js  | 11 ++++++++-
 src/fauxton/app/modules/documents/routes.js     |  8 +++----
 6 files changed, 42 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0bf0f36/src/fauxton/app/addons/activetasks/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/resources.js b/src/fauxton/app/addons/activetasks/resources.js
index 4625871..ca732fb 100644
--- a/src/fauxton/app/addons/activetasks/resources.js
+++ b/src/fauxton/app/addons/activetasks/resources.js
@@ -38,8 +38,12 @@ function (app, backbone, Fauxton) {
       "view_compaction": "View Compaction"
     },
     documentation: "_active_tasks",
-    url: function () {
-      return app.host + '/_active_tasks';
+    url: function (context) {
+      if (context === "apiurl"){
+        return window.location.origin + '/_active_tasks';
+      } else {
+        return app.host + '/_active_tasks';
+      }
     },
     fetch: function (options) {
      var fetchoptions = options || {};

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0bf0f36/src/fauxton/app/addons/activetasks/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/routes.js b/src/fauxton/app/addons/activetasks/routes.js
index e0454b7..89bcfcc 100644
--- a/src/fauxton/app/addons/activetasks/routes.js
+++ b/src/fauxton/app/addons/activetasks/routes.js
@@ -30,7 +30,7 @@ function (app, FauxtonAPI, Activetasks, Views) {
     {"name": "Active tasks", "link": "activetasks"}
     ],
     apiUrl: function(){
-      return [this.newtasks.url(), this.newtasks.documentation];
+      return [this.newtasks.url("apiurl"), this.newtasks.documentation];
     }, 
 
     roles: ["_admin"],

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0bf0f36/src/fauxton/app/modules/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/resources.js b/src/fauxton/app/modules/databases/resources.js
index a01c9ce..a716ea1 100644
--- a/src/fauxton/app/modules/databases/resources.js
+++ b/src/fauxton/app/modules/databases/resources.js
@@ -54,8 +54,12 @@ function(app, FauxtonAPI, Documents) {
         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 "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
+      } else if (context === "changes-apiurl") { 
+        return window.location.origin + "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
       } else if (context === "app") {
         return "/database/" + this.safeID();
       } else {
@@ -87,13 +91,17 @@ function(app, FauxtonAPI, Documents) {
     documentation: function(){
       return "changes";
     },
-    url: function () {
+    url: function (context) {
       var query = "";
       if (this.params) {
         query = "?" + $.param(this.params);
       }
+      if (context === "apiurl") { 
+        return window.location.origin + '/' + this.database.safeID() + '/_changes' + query;
+      } else {
 
       return app.host + '/' + this.database.safeID() + '/_changes' + query;
+      }
     },
 
     parse: function (resp) {
@@ -130,7 +138,7 @@ function(app, FauxtonAPI, Documents) {
       // cribbed from http://stackoverflow.com/questions/10420352/converting-file-size-in-bytes-to-human-readable
       var i = -1;
       var byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
-      var fileSizeInBytes = this.diskSize();
+      var fileSizeInBytes = this.dataSize();
 
       if (!fileSizeInBytes) {
         return 0;
@@ -143,9 +151,12 @@ function(app, FauxtonAPI, Documents) {
 
       return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
     },
-
     diskSize: function () {
       return this.get("disk_size");
+    },
+
+    dataSize: function () {
+      return this.get("other").data_size;
     }
   });
 
@@ -155,8 +166,12 @@ function(app, FauxtonAPI, Documents) {
     documentation: function(){
       return "all_dbs";
     },
-    url: function() {
-      return app.host + "/_all_dbs";
+    url: function(context) {
+      if (context === "apiurl") { 
+        return window.location.origin + "/_all_dbs";
+      } else {
+        return app.host + "/_all_dbs";
+      }
     },
 
     parse: function(resp) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0bf0f36/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 e63c3a7..ca3d640 100644
--- a/src/fauxton/app/modules/databases/routes.js
+++ b/src/fauxton/app/modules/databases/routes.js
@@ -37,7 +37,7 @@ function(app, FauxtonAPI, Databases, Views) {
     },
 
     apiUrl: function() {
-      return [this.databases.url(), this.databases.documentation()];
+      return [this.databases.url("apiurl"), this.databases.documentation()];
     },
 
     selectedHeader: "Databases",

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0bf0f36/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index f833ded..8dd283b 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -28,6 +28,8 @@ function(app, FauxtonAPI) {
         return this.getDatabase().url("app") + "/" + this.safeID();
       } else if (context === "web-index") {
         return this.getDatabase().url("app") + "/" + app.mixins.safeURLName(this.id);
+      } else if (context === "apiurl"){
+        return window.location.origin + "/" + this.getDatabase().safeID() + "/" + this.safeID();
       } else {
         return app.host + "/" + this.getDatabase().safeID() + "/" + this.safeID();
       }
@@ -206,6 +208,8 @@ function(app, FauxtonAPI) {
     url: function(context) {
       if (context === "app") {
         return this.database.url("app") + "/" + this.safeID() + '/_info';
+      } else if (context === "apiurl"){
+        return window.location.origin + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
       } else {
         return app.host + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
       }
@@ -287,8 +291,11 @@ function(app, FauxtonAPI) {
 
       if (context === 'app') {
         return 'database/' + this.database.safeID() + "/_all_docs" + query;
+      } else if (context === "apiurl"){
+        return window.location.origin + "/" + this.database.safeID() + "/_all_docs" + query;
+      } else {
+        return app.host + "/" + this.database.safeID() + "/_all_docs" + query;
       }
-      return app.host + "/" + this.database.safeID() + "/_all_docs" + query;
     },
 
     simple: function () {
@@ -412,6 +419,8 @@ function(app, FauxtonAPI) {
       var startOfUrl = app.host;
       if (context === 'app') {
         startOfUrl = 'database';
+      } else if (context === "apiurl"){
+        startOfUrl = window.location.origin;
       }
       var design = app.mixins.safeURLName(this.design),
           view = app.mixins.safeURLName(this.view);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/b0bf0f36/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 56cdc1b..538cd56 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -107,7 +107,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     apiUrl: function() {
-      return [this.doc.url(), this.doc.documentation()];
+      return [this.doc.url("apiurl"), this.doc.documentation()];
     }
   });
 
@@ -218,7 +218,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)}
       ];
 
-      this.apiUrl = [this.data.database.allDocs.url(), this.data.database.allDocs.documentation() ];
+      this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
     },
 
     viewFn: function (databaseName, ddoc, view) {
@@ -270,7 +270,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         ];
       };
 
-      this.apiUrl = [this.data.indexedDocs.url(), "docs"];
+      this.apiUrl = [this.data.indexedDocs.url("apiurl"), "docs"];
     },
 
     newViewEditor: function () {
@@ -397,7 +397,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     apiUrl: function() {
-      return [this.database.url(), this.database.documentation()];
+      return [this.database.url("apiurl"), this.database.documentation()];
     }
 
   });


[2/3] git commit: updated refs/heads/master to b0bf0f3

Posted by de...@apache.org.
URL ENCODE ALL THE THINGS.
Mixin added to test for bad characters that get through couch validation & encode when found.
Do not encode already encoded entries.

mixin added for scrubbing special characters out of names used as CSS selectors

SafeIDs used wherever there is a URL in views redirects & models.

Better parsing of _design doc names (use regex)

Allow the use of couchdb special characters / _ , $ etc in names for DBs, Views, Search Indexes etc, without breaking everything.


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

Branch: refs/heads/master
Commit: 8c333157b335d40225323d34d54c3f5e31e1c40d
Parents: a6d55bb
Author: suelockwood <de...@apache.org>
Authored: Fri Dec 20 14:16:23 2013 -0500
Committer: suelockwood <de...@apache.org>
Committed: Mon Dec 23 12:20:29 2013 -0500

----------------------------------------------------------------------
 src/fauxton/app/mixins.js                       |  9 ++++++++
 src/fauxton/app/modules/databases/base.js       |  5 ++--
 src/fauxton/app/modules/databases/resources.js  | 23 +++++++++++--------
 src/fauxton/app/modules/databases/views.js      |  8 +++----
 src/fauxton/app/modules/documents/resources.js  | 24 ++++++++++++--------
 src/fauxton/app/modules/documents/routes.js     |  8 +++----
 src/fauxton/app/modules/documents/views.js      | 23 ++++++++++++-------
 src/fauxton/app/templates/databases/item.html   |  3 ++-
 .../templates/documents/index_menu_item.html    |  2 +-
 9 files changed, 67 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/src/fauxton/app/mixins.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/mixins.js b/src/fauxton/app/mixins.js
index b17e15c..15af3ee 100644
--- a/src/fauxton/app/mixins.js
+++ b/src/fauxton/app/mixins.js
@@ -51,6 +51,15 @@ function($, _ ) {
     };
   };
 
+  mixins.removeSpecialCharacters = function(name){
+    return name.replace(/[^\w\s]/gi,"");
+  };
+
+  mixins.safeURLName = function(name){
+    var checkforBad = name.match(/[\$\-/_,+-]/g);
+    return (checkforBad !== null)?encodeURIComponent(name):name;
+  };
+
   return mixins;
 });
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/src/fauxton/app/modules/databases/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/base.js b/src/fauxton/app/modules/databases/base.js
index 2e768e9..6ff12c6 100644
--- a/src/fauxton/app/modules/databases/base.js
+++ b/src/fauxton/app/modules/databases/base.js
@@ -27,9 +27,10 @@ function(app, FauxtonAPI, Databases, Views) {
 
   // Utility functions
   Databases.databaseUrl = function(database) {
-    var name = _.isObject(database) ? database.id : database;
+    var name = _.isObject(database) ? database.id : database,
+        dbname = app.mixins.safeURLName(name);
 
-    return ["/database/", name, "/_all_docs?limit=" + Databases.DocLimit].join('');
+    return ["/database/", dbname, "/_all_docs?limit=" + Databases.DocLimit].join('');
   };
 
   return Databases;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/src/fauxton/app/modules/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/databases/resources.js b/src/fauxton/app/modules/databases/resources.js
index a577847..2e66176 100644
--- a/src/fauxton/app/modules/databases/resources.js
+++ b/src/fauxton/app/modules/databases/resources.js
@@ -51,18 +51,23 @@ function(app, FauxtonAPI, Documents) {
 
     url: function(context) {
       if (context === "index") {
-        return "/database/" + this.id + "/_all_docs";
+        return "/database/" + this.safeID() + "/_all_docs";
       } else if (context === "web-index") {
-        return "#/database/"+ encodeURIComponent(this.get("name"))  + "/_all_docs?limit=" + Databases.DocLimit;
+        return "#/database/"+ this.safeID() + "/_all_docs?limit=" + Databases.DocLimit;
       } else if (context === "changes") {
-        return "/database/" + this.id + "/_changes?descending=true&limit=100&include_docs=true";
+        return "/database/" + this.safeID() + "/_changes?descending=true&limit=100&include_docs=true";
       } else if (context === "app") {
-        return "/database/" + this.id;
+        return "/database/" + this.safeID();
       } else {
-        return app.host + "/" + this.id;
+        return app.host + "/" + this.safeID();
       }
     },
-
+    safeName: function(){
+      return app.mixins.safeURLName(this.get("name"));
+    },
+    safeID: function() {
+      return app.mixins.safeURLName(this.id);
+    },
     buildChanges: function (params) {
       this.changes = new Databases.Changes({
         database: this,
@@ -86,7 +91,7 @@ function(app, FauxtonAPI, Documents) {
         query = "?" + $.param(this.params);
       }
 
-      return app.host + '/' + this.database.id + '/_changes' + query;
+      return app.host + '/' + this.database.safeID() + '/_changes' + query;
     },
 
     parse: function (resp) {
@@ -97,7 +102,7 @@ function(app, FauxtonAPI, Documents) {
 
   Databases.Status = Backbone.Model.extend({
     url: function() {
-      return app.host + "/" + this.database.id;
+      return app.host + "/" + this.database.safeID();
     },
 
     initialize: function(options) {
@@ -156,7 +161,7 @@ function(app, FauxtonAPI, Documents) {
       // TODO: pagination!
       return _.map(resp, function(database) {
         return {
-          id: encodeURIComponent(database),
+          id: app.mixins.safeURLName(database),
           name: database
         };
       });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/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 02b0297..0b4e0b0 100644
--- a/src/fauxton/app/modules/databases/views.js
+++ b/src/fauxton/app/modules/databases/views.js
@@ -29,7 +29,7 @@ function(app, Components, FauxtonAPI, Databases) {
     },
     serialize: function() {
       return {
-        encoded: encodeURIComponent(this.model.get("name")),
+        encoded: app.mixins.safeURLName(this.model.get("name")),
         database: this.model,
         docLimit: Databases.DocLimit
       };
@@ -82,7 +82,7 @@ function(app, Components, FauxtonAPI, Databases) {
         // TODO: switch to using a model, or Databases.databaseUrl()
         // Neither of which are in scope right now
         // var db = new Database.Model({id: dbname});
-        var url = ["/database/", encodeURIComponent(dbname), "/_all_docs?limit=" + Databases.DocLimit].join('');
+        var url = ["/database/", app.mixins.safeURLName(dbname), "/_all_docs?limit=" + Databases.DocLimit].join('');
         FauxtonAPI.navigate(url);
       }
     },
@@ -159,7 +159,7 @@ function(app, Components, FauxtonAPI, Databases) {
         return;
       }
       db = new this.collection.model({
-        id: encodeURIComponent(name),
+        id: name,
         name: name
       });
       notification = FauxtonAPI.addNotification({msg: "Creating database."});
@@ -169,7 +169,7 @@ function(app, Components, FauxtonAPI, Databases) {
           type: "success",
           clear: true
         });
-        var route = "#/database/" +  name + "/_all_docs?limit=" + Databases.DocLimit;
+        var route = "#/database/" +  app.mixins.safeURLName(name) + "/_all_docs?limit=" + Databases.DocLimit;
         app.router.navigate(route, { trigger: true });
       }
       ).error(function(xhr) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/src/fauxton/app/modules/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/resources.js b/src/fauxton/app/modules/documents/resources.js
index 8633605..a171cae 100644
--- a/src/fauxton/app/modules/documents/resources.js
+++ b/src/fauxton/app/modules/documents/resources.js
@@ -27,7 +27,7 @@ function(app, FauxtonAPI) {
       if (context === "app") {
         return this.getDatabase().url("app") + "/" + this.safeID();
       } else {
-        return app.host + "/" + this.getDatabase().id + "/" + this.id;
+        return app.host + "/" + this.getDatabase().safeID() + "/" + this.safeID();
       }
     },
 
@@ -139,7 +139,7 @@ function(app, FauxtonAPI) {
     // treated separately. For instance, we could default into the
     // json editor for docs, or into a ddoc specific page.
     safeID: function() {
-      return this.id.replace('/', '%2F');
+      return app.mixins.safeURLName(this.id);
     },
 
     destroy: function() {
@@ -177,7 +177,7 @@ function(app, FauxtonAPI) {
     copy: function (copyId) {
       return $.ajax({
         type: 'COPY',
-        url: '/' + this.database.id + '/' + this.id,
+        url: '/' + this.database.safeID() + '/' + this.safeID(),
         headers: {Destination: copyId}
       });
     },
@@ -200,7 +200,7 @@ function(app, FauxtonAPI) {
       if (context === "app") {
         return this.database.url("app") + "/" + this.safeID() + '/_info';
       } else {
-        return app.host + "/" + this.database.id + "/" + this.id + '/_info';
+        return app.host + "/" + this.database.safeID() + "/" + this.safeID() + '/_info';
       }
     },
 
@@ -209,7 +209,8 @@ function(app, FauxtonAPI) {
     // treated separately. For instance, we could default into the
     // json editor for docs, or into a ddoc specific page.
     safeID: function() {
-      return this.id.replace('/', '%2F');
+      var ddoc = this.id.replace(/_design\//,"");
+      return "_design/"+app.mixins.safeURLName(ddoc);
     }
 
   });
@@ -226,12 +227,15 @@ function(app, FauxtonAPI) {
     url: function(context) {
       if (!this.isEditable()) return false;
 
-      return this.collection.database.url(context) + "/" + this.id;
+      return this.collection.database.url(context) + "/" + this.safeID();
     },
 
     isEditable: function() {
       return this.docType() != "reduction";
     },
+    safeID: function() {
+      return app.mixins.safeURLName(this.id);
+    },
 
     prettyJSON: function() {
       //var data = this.get("doc") ? this.get("doc") : this;
@@ -275,9 +279,9 @@ function(app, FauxtonAPI) {
       }
 
       if (context === 'app') {
-        return 'database/' + this.database.id + "/_all_docs" + query;
+        return 'database/' + this.database.safeID() + "/_all_docs" + query;
       }
-      return app.host + "/" + this.database.id + "/_all_docs" + query;
+      return app.host + "/" + this.database.safeID() + "/_all_docs" + query;
     },
 
     simple: function () {
@@ -402,8 +406,10 @@ function(app, FauxtonAPI) {
       if (context === 'app') {
         startOfUrl = 'database';
       }
+      var design = app.mixins.safeURLName(this.design),
+          view = app.mixins.safeURLName(this.view);
 
-      var url = [startOfUrl, this.database.id, "_design", this.design, this.idxType, this.view];
+      var url = [startOfUrl, this.database.safeID(), "_design", design, this.idxType, view];
       return url.join("/") + query;
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/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 b8b74b6..4727cdc 100644
--- a/src/fauxton/app/modules/documents/routes.js
+++ b/src/fauxton/app/modules/documents/routes.js
@@ -92,7 +92,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       doc.copy(newId).then(function () {
         doc.set({_id: newId}); 
         docView.forceRender();
-        FauxtonAPI.navigate('/database/' + database.id + '/' + newId, {trigger: true});
+        FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.mixins.safeURLName(newId), {trigger: true});
         FauxtonAPI.addNotification({
           msg: "Document has been duplicated."
         });
@@ -162,7 +162,7 @@ function(app, FauxtonAPI, Documents, Databases) {
       var docOptions = app.getParams();
       docOptions.include_docs = true;
 
-      this.databaseName = encodeURIComponent(options[0]);
+      this.databaseName = app.mixins.safeURLName(options[0]);
 
       this.data = {
         database: new Databases.Model({id:this.databaseName})
@@ -259,7 +259,7 @@ function(app, FauxtonAPI, Documents, Databases) {
         ddocInfo: ddocInfo
       }));
 
-      this.sidebar.setSelectedTab(ddoc + '_' + view);
+      this.sidebar.setSelectedTab(app.mixins.removeSpecialCharacters(ddoc) + '_' + app.mixins.removeSpecialCharacters(view));
 
       this.crumbs = function () {
         return [
@@ -373,7 +373,7 @@ function(app, FauxtonAPI, Documents, Databases) {
     },
 
     initialize: function (route, masterLayout, options) {
-      this.databaseName = encodeURIComponent(options[0]);
+      this.databaseName = app.mixins.safeURLName(options[0]);
       this.database = new Databases.Model({id: this.databaseName});
 
       var docOptions = app.getParams();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/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 9f95686..94fe699 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -420,6 +420,11 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         index: this.index,
         ddoc: this.ddoc,
         database: this.database,
+        index_clean: app.mixins.removeSpecialCharacters(this.index),
+        ddoc_clean: app.mixins.removeSpecialCharacters(this.ddoc), 
+        index_encoded: app.mixins.safeURLName(this.index),
+        ddoc_encoded: app.mixins.safeURLName(this.ddoc),
+        database_encoded: app.mixins.safeURLName(this.database),
         selected: this.selected
       };
     },
@@ -798,7 +803,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     establish: function() {
       var promise = this.model.fetch(),
-          databaseId = this.database.id,
+          databaseId = this.database.safeID(),
           deferred = $.Deferred();
 
       promise.then(function () {
@@ -831,7 +836,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
         this.model.save().then(function () {
           editor.editSaved();
-          FauxtonAPI.navigate('/database/' + that.database.id + '/' + that.model.id);
+          FauxtonAPI.navigate('/database/' + that.database.safeID() + '/' + that.model.id);
         }).fail(function(xhr) {
           var responseText = JSON.parse(xhr.responseText).reason;
           notification = FauxtonAPI.addNotification({
@@ -1270,7 +1275,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       }
 
       promise.then(function () {
-        FauxtonAPI.navigate('/database/' + that.database.id + '/_all_docs?limit=' + Databases.DocLimit);
+        FauxtonAPI.navigate('/database/' + that.database.safeID() + '/_all_docs?limit=' + Databases.DocLimit);
         FauxtonAPI.triggerRouteEvent('reloadDesignDocs');
       });
     },
@@ -1308,16 +1313,18 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           });
 
           if (that.newView) {
-            var fragment = '/database/' + that.database.id +'/' + ddocName + '/_view/' + viewName; 
+            var fragment = '/database/' + that.database.safeID() +'/' + ddoc.safeID() + '/_view/' + app.mixins.safeURLName(viewName); 
 
             FauxtonAPI.navigate(fragment, {trigger: false});
             that.newView = false;
-            that.ddocID = ddoc.id;
+            that.ddocID = ddoc.safeID();
             that.viewName = viewName;
             that.ddocInfo = ddoc;
             that.showIndex = true;
             that.render();
-            FauxtonAPI.triggerRouteEvent('reloadDesignDocs',{selectedTab: ddocName.replace('_design/','') + '_' + viewName});
+            FauxtonAPI.triggerRouteEvent('reloadDesignDocs', {
+              selectedTab: app.mixins.removeSpecialCharacters(ddocName.replace(/_design\//,'')) + '_' + app.mixins.removeSpecialCharacters(viewName)
+            });
           }
 
           if (that.reduceFunStr !== reduceVal) {
@@ -1614,7 +1621,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       var docId = this.$('#jump-to-doc-id').val().trim();
 
       if (this.database.allDocs.where({"_id":docId}).length > 0){
-        FauxtonAPI.navigate('/database/' + this.database.id +'/' + docId, {trigger: true});
+        FauxtonAPI.navigate('/database/' + app.mixins.safeURLName(this.database.id) +'/' + app.mixins.safeURLName(docId), {trigger: true});
       } else {
         FauxtonAPI.addNotification({
           msg: 'Document ID does not exist.',
@@ -1707,7 +1714,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.collection.each(function(design) {
         if (design.has('doc')){
-          var ddoc = design.id.split('/')[1];
+          var ddoc = design.id.replace(/_design\//,"");
           if (design.get('doc').views){
             this.buildIndexList(design.get('doc').views, "views", ddoc);
           }

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/src/fauxton/app/templates/databases/item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/databases/item.html b/src/fauxton/app/templates/databases/item.html
index 701e58e..e2f8071 100644
--- a/src/fauxton/app/templates/databases/item.html
+++ b/src/fauxton/app/templates/databases/item.html
@@ -19,5 +19,6 @@ the License.
 <td><%= database.status.numDocs() %></td>
 <td><%= database.status.updateSeq() %></td>
 <td>
-  <a class="db-actions btn fonticon-replicate set-replication-start" href="#/replication/<%= database.get("name") %>"></a>
+  <a class="db-actions btn fonticon-replicate set-replication-start" title="Replicate <%= database.get("name") %>" href="#/replication/new/<%=encoded%>"></a>
+  <a class="db-actions btn icon-lock set-permissions" title="Set permissions for <%= database.get("name") %>" href="#/database/<%=encoded%>/permissions"></a>
 </td>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/8c333157/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 1b141b2..7ca9012 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 id="<%= ddoc %>_<%= index %>" href="#database/<%= database %>/_design/<%= ddoc %>/_view/<%= index %>" class="toggle-view">
+<a id="<%= ddoc_clean %>_<%= index_clean %>" href="#database/<%= database_encoded %>/_design/<%= ddoc_encoded %>/_view/<%= index_encoded %>" class="toggle-view">
   <%= ddoc %><span class="divider">/</span><%= index %>
 </a>