Fix cancel link URL when ddoc name has special chars (#1161)

* Fix cancel link URL when ddoc name has special chars
diff --git a/app/addons/documents/index-editor/__tests__/components.test.js b/app/addons/documents/index-editor/__tests__/components.test.js
index a3d4c20..33936d7 100644
--- a/app/addons/documents/index-editor/__tests__/components.test.js
+++ b/app/addons/documents/index-editor/__tests__/components.test.js
@@ -243,6 +243,17 @@
     sinon.assert.calledWith(spy, 'newViewName');
   });
 
+  it('generates the correct cancel link when db, ddoc and views have special chars', () => {
+    const editorEl = mount(<Views.IndexEditor
+      {...defaultProps}
+      database={{ id: 'db%$1' }}
+      designDocId={'_design/doc/1$2'}
+      viewName={'v?abc/123'}
+    />);
+    const expectedUrl = `/${encodeURIComponent('db%$1')}/_design/${encodeURIComponent('doc/1$2')}/_view/${encodeURIComponent('v?abc/123')}`;
+    expect(editorEl.find('a.index-cancel-link').prop('href')).toMatch(expectedUrl);
+  });
+
   it('shows warning when trying to save a partitioned view with custom reduce', () => {
     sinon.stub(FauxtonAPI, 'addNotification');
     const editorEl = mount(<Views.IndexEditor
diff --git a/app/addons/documents/index-editor/components/IndexEditor.js b/app/addons/documents/index-editor/components/IndexEditor.js
index 2d1a2cc..b2a14bf 100644
--- a/app/addons/documents/index-editor/components/IndexEditor.js
+++ b/app/addons/documents/index-editor/components/IndexEditor.js
@@ -98,11 +98,13 @@
   getCancelLink() {
     const encodedDatabase = encodeURIComponent(this.props.database.id);
     const encodedPartitionKey = this.props.partitionKey ? encodeURIComponent(this.props.partitionKey) : '';
-    const encodedDDoc = encodeURIComponent(this.props.designDocId);
-    const encodedView = encodeURIComponent(this.props.viewName);
     if (this.props.designDocId === 'new-doc' || this.props.isNewView) {
       return '#' + FauxtonAPI.urls('allDocs', 'app', encodedDatabase, encodedPartitionKey);
     }
+    const encodedDDoc = this.props.designDocId.startsWith('_design/') ?
+      '_design/' + encodeURIComponent(this.props.designDocId.substring(8)) :
+      encodeURIComponent(this.props.designDocId);
+    const encodedView = encodeURIComponent(this.props.viewName);
     return '#' + FauxtonAPI.urls('view', 'showView', encodedDatabase, encodedPartitionKey, encodedDDoc, encodedView);
   }