Merge "Add support for downloading binary files" into stable-2.16
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
index 06658da..3a5b3a1 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
@@ -26,6 +26,7 @@
 <link rel="import" href="../../core/gr-reporting/gr-reporting.html">
 <link rel="import" href="../../shared/gr-button/gr-button.html">
 <link rel="import" href="../../shared/gr-count-string-formatter/gr-count-string-formatter.html">
+<link rel="import" href="../../shared/gr-dropdown/gr-dropdown.html">
 <link rel="import" href="../../shared/gr-dropdown-list/gr-dropdown-list.html">
 <link rel="import" href="../../shared/gr-fixed-panel/gr-fixed-panel.html">
 <link rel="import" href="../../shared/gr-icons/gr-icons.html">
@@ -75,8 +76,7 @@
         align-items: center;
         display: flex;
       }
-      .navLink:not([href]),
-      .downloadLink:not([href]) {
+      .navLink:not([href]) {
         color: var(--deemphasized-text-color);
       }
       .navLinks {
@@ -266,12 +266,15 @@
           </gr-patch-range-select>
           <span class="download desktop">
             <span class="separator"></span>
-            <a
-              class="downloadLink"
-              download
-              href$="[[_computeDownloadLink(_change.project, _changeNum, _patchRange, _path)]]">
-              Download
-            </a>
+            <gr-dropdown
+                link
+                down-arrow
+                items="[[_computeDownloadDropdownLinks(_change.project, _changeNum, _patchRange, _path)]]"
+                horizontal-align="left">
+              <span class="downloadTitle">
+                Download
+              </span>
+            </gr-dropdown>
           </span>
         </div>
         <div class="rightControls">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index 89ad2d2..76a0bef 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -880,7 +880,36 @@
       history.replaceState(null, '', url);
     },
 
-    _computeDownloadLink(project, changeNum, patchRange, path) {
+    _computeDownloadDropdownLinks(project, changeNum, patchRange, path) {
+      if (!patchRange || !patchRange.patchNum) { return []; }
+
+      return [
+        {
+          url: this._computeDownloadPatchLink(
+              project, changeNum, patchRange, path),
+          name: 'Patch',
+        },
+        {
+          // We pass 1 here to indicate this is parent 1.
+          url: this._computeDownloadFileLink(
+              project, changeNum, patchRange, path, 1),
+          name: 'Left Content',
+        },
+        {
+          // We pass 0 here to indicate this is parent 0.
+          url: this._computeDownloadFileLink(
+              project, changeNum, patchRange, path, 0),
+          name: 'Right Content',
+        },
+      ];
+    },
+
+    _computeDownloadFileLink(project, changeNum, patchRange, path, parent) {
+      return this.changeBaseURL(project, changeNum, patchRange.patchNum) +
+          `/files/${encodeURIComponent(path)}/download?parent=${parent}`;
+    },
+
+    _computeDownloadPatchLink(project, changeNum, patchRange, path) {
       let url = this.changeBaseURL(project, changeNum, patchRange.patchNum);
       url += '/patch?zip&path=' + encodeURIComponent(path);
       return url;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
index 354bfef..92e2c52 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
@@ -556,22 +556,6 @@
           element._path, '1', 'PARENT'));
     });
 
-    test('download link', () => {
-      element._change = {project: 'test'},
-      element._changeNum = '42';
-      element._patchRange = {
-        basePatchNum: PARENT,
-        patchNum: '10',
-      };
-      element._fileList = ['chell.go', 'glados.txt', 'wheatley.md'];
-      element._path = 'glados.txt';
-      flushAsynchronousOperations();
-      const link = element.$$('.downloadLink');
-      assert.equal(link.getAttribute('href'),
-          '/changes/test~42/revisions/10/patch?zip&path=glados.txt');
-      assert.isTrue(link.hasAttribute('download'));
-    });
-
     test('_prefs.manual_review is respected', () => {
       const saveReviewedStub = sandbox.stub(element, '_saveReviewedState',
           () => Promise.resolve());
@@ -1124,5 +1108,47 @@
         1,
       ]);
     });
+
+    test('_computeDownloadDropdownLinks', () => {
+      const downloadLinks = [
+        {
+          url: '/changes/test~12/revisions/1/patch?zip&path=index.php',
+          name: 'Patch',
+        },
+        {
+          url: '/changes/test~12/revisions/1' +
+              '/files/index.php/download?parent=1',
+          name: 'Left Content',
+        },
+        {
+          url: '/changes/test~12/revisions/1' +
+              '/files/index.php/download?parent=0',
+          name: 'Right Content',
+        },
+      ];
+      assert.deepEqual(
+          element._computeDownloadDropdownLinks(
+              'test', 12, {patchNum: 1}, 'index.php'),
+          downloadLinks);
+    });
+
+    test('_computeDownloadFileLink', () => {
+      assert.equal(
+          element._computeDownloadFileLink(
+              'test', 12, {patchNum: 1}, 'index.php', 1),
+          '/changes/test~12/revisions/1/files/index.php/download?parent=1');
+
+      assert.equal(
+          element._computeDownloadFileLink(
+              'test', 12, {patchNum: 1}, 'index.php', 0),
+          '/changes/test~12/revisions/1/files/index.php/download?parent=0');
+    });
+
+    test('_computeDownloadPatchLink', () => {
+      assert.equal(
+          element._computeDownloadPatchLink(
+              'test', 12, {patchNum: 1}, 'index.php'),
+          '/changes/test~12/revisions/1/patch?zip&path=index.php');
+    });
   });
 </script>