From ebce9281499a18b5ac4ae3b5e9cdc7b5f06ecbb0 Mon Sep 17 00:00:00 2001
From: Jonas Jenwald <jonas.jenwald@gmail.com>
Date: Fri, 11 Sep 2015 13:11:49 +0200
Subject: [PATCH 1/3] Extract the conversion from `canvas` to `image` into a
 helper function in `PDFThumbnailView`

*Follow-up to PR 6299.*

This patch reduces unnecessary code duplication for the `canvas` to `image` conversion. It also does a bit of re-ordering (and adds new lines) in `_getPageDrawContext`, since that function currently is a bit hard to read.
---
 web/pdf_thumbnail_view.js | 47 ++++++++++++++++++++++++++-------------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 0d4752f2d..71488c114 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -186,24 +186,48 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
 
       var ctx = canvas.getContext('2d');
       var outputScale = getOutputScale(ctx);
+
       canvas.width = (this.canvasWidth * outputScale.sx) | 0;
       canvas.height = (this.canvasHeight * outputScale.sy) | 0;
       canvas.style.width = this.canvasWidth + 'px';
       canvas.style.height = this.canvasHeight + 'px';
+
       if (!noCtxScale && outputScale.scaled) {
         ctx.scale(outputScale.sx, outputScale.sy);
       }
-      this.image = document.createElement('img');
-      this.image.id = this.renderingId;
-      this.image.style.height = canvas.style.height;
-      this.image.style.width = canvas.style.width;
-      this.image.className = 'thumbnailImage';
-      this.image.setAttribute('aria-label', mozL10n.get('thumb_page_canvas',
+
+      var image = document.createElement('img');
+      image.id = this.renderingId;
+
+      image.className = 'thumbnailImage';
+      image.setAttribute('aria-label', mozL10n.get('thumb_page_canvas',
         { page: this.id }, 'Thumbnail of Page {{page}}'));
+
+      image.style.width = canvas.style.width;
+      image.style.height = canvas.style.height;
+
+      this.image = image;
       this.ring.appendChild(this.image);
+
       return ctx;
     },
 
+    /**
+     * @private
+     */
+    _convertCanvasToImage: function PDFThumbnailView_convertCanvasToImage() {
+       if (!this.canvas) {
+         return;
+       }
+       this.image.src = this.canvas.toDataURL();
+
+       // Zeroing the width and height causes Firefox to release graphics
+       // resources immediately, which can greatly reduce memory consumption.
+       this.canvas.width = 0;
+       this.canvas.height = 0;
+       delete this.canvas;
+    },
+
     draw: function PDFThumbnailView_draw() {
       if (this.renderingState !== RenderingStates.INITIAL) {
         console.error('Must be in new state before drawing');
@@ -232,12 +256,8 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
           rejectRenderPromise(error);
           return;
         }
-
-        self.image.src = self.canvas.toDataURL();
-        self.canvas.width = 0;
-        self.canvas.height = 0;
-        delete self.canvas;
         self.renderingState = RenderingStates.FINISHED;
+        self._convertCanvasToImage();
 
         if (!error) {
           resolveRenderPromise(undefined);
@@ -319,10 +339,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
       }
       ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight,
                     0, 0, canvas.width, canvas.height);
-      this.image.src = canvas.toDataURL();
-      this.canvas.width = 0;
-      this.canvas.height = 0;
-      delete this.canvas;
+      this._convertCanvasToImage();
     }
   };
 

From 555c7925a0da9606f70c8f97c23d041d686e53ae Mon Sep 17 00:00:00 2001
From: Jonas Jenwald <jonas.jenwald@gmail.com>
Date: Fri, 11 Sep 2015 13:18:35 +0200
Subject: [PATCH 2/3] Prevent `setImage` from failing to display small
 thumbnails, by adding a missing `canvas` to `image` conversion

*Follow-up to PR 6299.*
---
 web/pdf_thumbnail_view.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 71488c114..71f52aee6 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -315,6 +315,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
       if (img.width <= 2 * canvas.width) {
         ctx.drawImage(img, 0, 0, img.width, img.height,
                       0, 0, canvas.width, canvas.height);
+        this._convertCanvasToImage();
         return;
       }
       // drawImage does an awful job of rescaling the image, doing it gradually.

From d7a90d83de4fed4c5cbebe870c9ecf98f5769660 Mon Sep 17 00:00:00 2001
From: Jonas Jenwald <jonas.jenwald@gmail.com>
Date: Fri, 11 Sep 2015 13:42:10 +0200
Subject: [PATCH 3/3] Delete, and clear, the `image` in
 `PDFThumbnailView_reset`

*Follow-up to PR 6299.*
---
 web/pdf_thumbnail_view.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/web/pdf_thumbnail_view.js b/web/pdf_thumbnail_view.js
index 71f52aee6..b8c54fe4f 100644
--- a/web/pdf_thumbnail_view.js
+++ b/web/pdf_thumbnail_view.js
@@ -160,6 +160,10 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
         this.canvas.height = 0;
         delete this.canvas;
       }
+      if (this.image) {
+        this.image.removeAttribute('src');
+        delete this.image;
+      }
     },
 
     update: function PDFThumbnailView_update(rotation) {