Merge "Show 404 when project lookup fails"
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index ec7efb6..991ce2e 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -163,7 +163,7 @@
         ],
     ),
     outs = ["polygerrit_embed_ui.zip"],
-    app = "embed/change-diff-views.html",
+    app = "embed/embed.html",
 )
 
 filegroup(
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
index 4013b37..2294621 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
@@ -89,11 +89,13 @@
         <div class="header">
           <span class="title">[[name]]</span>
           <div class="right">
-            <paper-toggle-button
-                id="exclusiveToggle"
-                checked="{{permission.value.exclusive}}"
-                on-change="_handleValueChange"
-                disabled$="[[!editing]]"></paper-toggle-button>Exclusive
+            <template is=dom-if if="[[!_permissionIsOwner(permission.id)]]">
+              <paper-toggle-button
+                  id="exclusiveToggle"
+                  checked="{{permission.value.exclusive}}"
+                  on-change="_handleValueChange"
+                  disabled$="[[!editing]]"></paper-toggle-button>Exclusive
+            </template>
             <gr-button
                 link
                 id="removeBtn"
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
index f9c04e60..cfb0ad5 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
@@ -89,6 +89,10 @@
       this._setupValues();
     },
 
+    _permissionIsOwner(permissionId) {
+      return permissionId === 'owner';
+    },
+
     _handleEditingChanged(editing, editingOld) {
       // Ignore when editing gets set initially.
       if (!editingOld) { return; }
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
index b67d705..ec93a5c 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
@@ -335,7 +335,7 @@
 
         assert.isFalse(element._originalExclusiveValue);
         assert.isNotOk(element.permission.value.modified);
-        MockInteractions.tap(element.$.exclusiveToggle);
+        MockInteractions.tap(element.$$('#exclusiveToggle'));
         flushAsynchronousOperations();
         assert.isTrue(element.permission.value.exclusive);
         assert.isTrue(element.permission.value.modified);
@@ -353,6 +353,15 @@
         assert.isTrue(element.permission.value.modified);
         assert.isTrue(modifiedHandler.called);
       });
+
+      test('Exclusive hidden for owner permission', () => {
+        assert.equal(getComputedStyle(element.$$('#exclusiveToggle')).display,
+            'flex');
+        element.set(['permission', 'id'], 'owner');
+        flushAsynchronousOperations();
+        assert.equal(getComputedStyle(element.$$('#exclusiveToggle')).display,
+            'none');
+      });
     });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
index 92dc887..8e00c06 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -501,7 +501,7 @@
                 this.notifyPath('actions.rebaseEdit');
               }
             } else {
-              if (!changeActions.rebasEdit) {
+              if (!changeActions.rebaseEdit) {
                 this.set('actions.rebaseEdit', REBASE_EDIT);
               }
               if (changeActions.publishEdit) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index 758a862..c2f2f6f 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -76,7 +76,10 @@
       }
       gr-change-status {
         display: initial;
-        margin: .1em .5em .1em 0;
+        margin: .1em .1em .1em .4em;
+      }
+      gr-change-status:first-child {
+        margin-left: 0;
       }
       .header-title {
         align-items: center;
@@ -144,7 +147,9 @@
         }
       }
       .changeStatuses,
-      .commitActions {
+      .changeText,
+      .commitActions,
+      .statusText {
         align-items: center;
         display: flex;
       }
@@ -225,6 +230,7 @@
       }
       gr-commit-info {
         display: inline-block;
+        margin-right: -5px;
       }
       @media screen and (min-width: 80em) {
         .commitMessage {
@@ -327,19 +333,22 @@
                   status="[[status]]"></gr-change-status>
             </template>
           </div>
+          <div class="statusText">
+            <template
+                is="dom-if"
+                if="[[_computeShowCommitInfo(_changeStatus, _change.current_revision)]]">
+              <span class="text"> as </span>
+              <gr-commit-info
+                  change="[[_change]]"
+                  commit-info="[[_computeMergedCommitInfo(_change.current_revision, _change.revisions)]]"
+                  server-config="[[_serverConfig]]"></gr-commit-info>
+            </template>
+          </div>
+          <span class="separator"></span>
           <div class="changeText">
             <a aria-label$="[[_computeChangePermalinkAriaLabel(_change._number)]]"
-                href$="[[_computeChangeUrl(_change)]]">[[_change._number]]</a><!--
-         --><template
-                is="dom-if"
-                if="[[_computeShowCommitInfo(_changeStatus, _change.current_revision)]]"><!--
-           --><span class="text"> ([[_changeStatus]] as </span><!--
-             --><gr-commit-info
-                    change="[[_change]]"
-                    commit-info="[[_computeMergedCommitInfo(_change.current_revision, _change.revisions)]]"
-                    server-config="[[_serverConfig]]"></gr-commit-info>)<!--
-         --></template><!--
-         --><span class="text">: </span><span class="headerSubject">[[_change.subject]]</span>
+                href$="[[_computeChangeUrl(_change)]]">[[_change._number]]</a>
+            <span class="headerSubject">: [[_change.subject]]</span>
           </div>
         </div><!-- end header-title -->
         <div class="commitActions" hidden$="[[!_loggedIn]]">
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index b4fb92a..1800175 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -151,17 +151,7 @@
       _patchRange: {
         type: Object,
       },
-      // These are kept as separate properties from the patchRange so that the
-      // observer can be aware of the previous value. In order to view sub
-      // property changes for _patchRange, a complex observer must be used, and
-      // that only displays the new value.
-      //
-      // If a previous value did not exist, the change is not reloaded with the
-      // new patches. This is just the initial setting from the change view vs.
-      // an update coming from the two way data binding.
-      _patchNum: String,
       _filesExpanded: String,
-      _basePatchNum: String,
       _currentRevision: Object,
       _currentRevisionActions: Object,
       _allPatchSets: {
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html
index 67b54d6..3eaeab25 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html
@@ -25,9 +25,6 @@
         align-items: center;
         display: flex;
       }
-      gr-copy-clipboard {
-        padding-left: .5em;
-      }
     </style>
     <div class="container">
       <template is="dom-if" if="[[_showWebLink]]">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html
index c92919d..4c6b95a 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html
@@ -135,6 +135,9 @@
         font-family: var(--font-family-bold);
         margin-right: 24px;
       }
+      gr-commit-info {
+        margin-right: -5px;
+      }
       @media screen and (max-width: 50em) {
         .patchInfo-header .desktop {
           display: none;
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index 7b17f22..006b9d9 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -319,10 +319,12 @@
       /**
        * @param {{ _number: number, project: string }} change The change object.
        * @param {string} path The file path.
+       * @param {number=} opt_patchNum
        * @return {string}
        */
-      getEditUrlForDiff(change, path) {
-        return this.getEditUrlForDiffById(change._number, change.project, path);
+      getEditUrlForDiff(change, path, opt_patchNum) {
+        return this.getEditUrlForDiffById(change._number, change.project, path,
+            opt_patchNum);
       },
 
       /**
@@ -331,13 +333,13 @@
        * @param {string} path The file path.
        * @return {string}
        */
-      getEditUrlForDiffById(changeNum, project, path) {
+      getEditUrlForDiffById(changeNum, project, path, opt_patchNum) {
         return this._getUrlFor({
           view: Gerrit.Nav.View.EDIT,
           changeNum,
           project,
           path,
-          patchNum: EDIT_PATCHNUM,
+          patchNum: opt_patchNum || EDIT_PATCHNUM,
         });
       },
 
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index d85b810..cc59be8 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -114,9 +114,8 @@
     // eslint-disable-next-line max-len
     CHANGE_OR_DIFF: /^\/c\/(.+)\/\+\/(\d+)(\/?((-?\d+|edit)(\.\.(\d+|edit))?(\/(.+))?))?\/?$/,
 
-    // Matches /c/<project>/+/<changeNum>/edit/<path>,edit
-    // eslint-disable-next-line max-len
-    DIFF_EDIT: /^\/c\/(.+)\/\+\/(\d+)\/edit\/(.+),edit$/,
+    // Matches /c/<project>/+/<changeNum>/[<patchNum|edit>]/<path>,edit
+    DIFF_EDIT: /^\/c\/(.+)\/\+\/(\d+)\/(\d+|edit)\/(.+),edit$/,
 
     // Matches non-project-relative
     // /c/<changeNum>/[<basePatchNum>..]<patchNum>/<path>.
@@ -1253,7 +1252,8 @@
       this._redirectOrNavigate({
         project: ctx.params[0],
         changeNum: ctx.params[1],
-        path: ctx.params[2],
+        patchNum: ctx.params[2],
+        path: ctx.params[3],
         view: Gerrit.Nav.View.EDIT,
       });
     },
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index 4af8130..f5a7dd9 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -1317,7 +1317,8 @@
             params: [
               'foo/bar', // 0 Project
               1234, // 1 Change number
-              'foo/bar/baz', // 2 File path
+              3, // 2 Patch num
+              'foo/bar/baz', // 3 File path
             ],
           };
           const appParams = {
@@ -1325,6 +1326,7 @@
             changeNum: 1234,
             view: Gerrit.Nav.View.EDIT,
             path: 'foo/bar/baz',
+            patchNum: 3,
           };
 
           element._handleDiffEditRoute(ctx);
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html
index f0d7f6f..96ba196b 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html
@@ -37,6 +37,12 @@
       #more {
         margin-right: 1em;
       }
+      gr-button,
+      gr-dropdown {
+        --gr-button: {
+          height: 1.8em;
+        }
+      }
       gr-dropdown {
         --gr-dropdown-item: {
           background-color: transparent;
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
index 6d7df94..62da3bb 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
@@ -37,11 +37,8 @@
         background-color: #fff;
         box-shadow: 0 1px 5px rgba(0, 0, 0, .3);
       }
-      button {
-        background: none;
-        border: none;
-        font: inherit;
-        padding: .3em 0;
+      gr-button {
+        @apply --gr-button;
       }
       gr-avatar {
         height: 2em;
diff --git a/polygerrit-ui/app/embed/change-diff-views.html b/polygerrit-ui/app/embed/embed.html
similarity index 81%
rename from polygerrit-ui/app/embed/change-diff-views.html
rename to polygerrit-ui/app/embed/embed.html
index 8426585..14b6b66 100644
--- a/polygerrit-ui/app/embed/change-diff-views.html
+++ b/polygerrit-ui/app/embed/embed.html
@@ -16,4 +16,6 @@
 <link rel="import" href="../bower_components/polymer/polymer.html">
 <link rel="import" href="../elements/change/gr-change-view/gr-change-view.html">
 <link rel="import" href="../elements/diff/gr-diff-view/gr-diff-view.html">
+<link rel="import" href="../elements/change-list/gr-dashboard-view/gr-dashboard-view.html">
+<link rel="import" href="../elements/change-list/gr-change-list-view/gr-change-list-view.html">
 <link rel="import" href="../styles/app-theme.html">
diff --git a/polygerrit-ui/app/embed/embed_test.html b/polygerrit-ui/app/embed/embed_test.html
index 26ea895..80f7e5d 100644
--- a/polygerrit-ui/app/embed/embed_test.html
+++ b/polygerrit-ui/app/embed/embed_test.html
@@ -16,11 +16,11 @@
 -->
 
 <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>change-diff-views-embed_test</title>
+<title>embed_test</title>
 
 <script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
 <script src="../../../bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../polygerrit_ui/elements/change-diff-views.html"/>
+<link rel="import" href="../polygerrit_ui/elements/embed.html"/>
 
 <script>void(0);</script>
 
@@ -36,6 +36,18 @@
   </template>
 </test-fixture>
 
+<test-fixture id="dashboard-view">
+  <template>
+    <gr-dashboard-view></gr-dashboard-view>
+  </template>
+</test-fixture>
+
+<test-fixture id="change-list-view">
+  <template>
+    <gr-change-list-view></gr-change-list-view>
+  </template>
+</test-fixture>
+
 <script>
   suite('embed test', () => {
     test('gr-change-view is embedded', () => {
@@ -47,5 +59,15 @@
       const element = fixture('diff-view');
       assert.equal(element.is, 'gr-diff-view');
     });
+
+    test('dashboard-view is embedded', () => {
+      const element = fixture('dashboard-view');
+      assert.equal(element.is, 'gr-dashboard-view');
+    });
+
+    test('change-list-view is embedded', () => {
+      const element = fixture('change-list-view');
+      assert.equal(element.is, 'gr-change-list-view');
+    });
   });
 </script>