Merge "Patch optional commit field on CommitInfo response if missing"
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js
index 06dfdd4..1b129a7 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.js
@@ -29,6 +29,19 @@
     ],
 
     /**
+     * Get the plain text as it appears in the generated DOM.
+     *
+     * This differs from the `content` property in that it will not include
+     * formatting markers such as > characters to make quotes or * and - markers
+     * to make list items.
+     *
+     * @return {string}
+     */
+    getTextContent: function() {
+      return this._blocksToText(this._computeBlocks(this.content));
+    },
+
+    /**
      * Given a source string, update the DOM inside #container.
      */
     _contentOrConfigChanged: function(content) {
@@ -53,12 +66,15 @@
      * * 'pre' (Pre-formatted text.)
      * * 'list' (Unordered list.)
      *
-     * For blocks of type 'paragraph', 'quote' or 'pre', there is a `text`
-     * property that maps to a string of the block's content.
+     * For blocks of type 'paragraph' and 'pre' there is a `text` property that
+     * maps to a string of the block's content.
      *
      * For blocks of type 'list', there is an `items` property that maps to a
      * list of strings representing the list items.
      *
+     * For blocks of type 'quote', there is a `blocks` property that maps to a
+     * list of blocks contained in the quote.
+     *
      * NOTE: Strings appearing in all block objects are NOT escaped.
      *
      * @param {string} content
@@ -232,5 +248,19 @@
         }
       }.bind(this));
     },
+
+    _blocksToText: function(blocks) {
+      return blocks.map(function(block) {
+        if (block.type === 'paragraph' || block.type === 'pre') {
+          return block.text;
+        }
+        if (block.type === 'quote') {
+          return this._blocksToText(block.blocks);
+        }
+        if (block.type === 'list') {
+          return block.items.join('\n');
+        }
+      }.bind(this)).join('\n\n');
+    },
   });
 })();
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html
index 8561058..e7080c0 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html
@@ -346,5 +346,13 @@
       assertBlock(result[0].blocks[0].blocks, 0, 'paragraph', 'prior');
       assertBlock(result[0].blocks, 1, 'paragraph', 'next\n');
     });
+
+    test('getTextContent', function() {
+      var comment = 'Paragraph\n\n  pre\n\n* List\n* Of\n* Items\n\n> Quote';
+      element.content = comment;
+      var result = element.getTextContent();
+      var expected = 'Paragraph\n\n  pre\n\nList\nOf\nItems\n\nQuote';
+      assert.equal(result, expected);
+    });
   });
 </script>