Index: chrome/content/ui/sendReport.js |
=================================================================== |
--- a/chrome/content/ui/sendReport.js |
+++ b/chrome/content/ui/sendReport.js |
@@ -316,105 +316,64 @@ var subscriptionsDataSource = |
callback(); |
} |
}; |
var screenshotDataSource = |
{ |
imageOffset: 10, |
- // Fields used for color reduction |
- _mapping: [0x00, 0x55, 0xAA, 0xFF], |
- _i: null, |
- _max: null, |
- _pixelData: null, |
- _callback: null, |
- |
// Fields used for user interaction |
_enabled: true, |
_canvas: null, |
_context: null, |
_selectionType: "mark", |
_currentData: null, |
_undoQueue: [], |
collectData: function(wnd, windowURI, callback) |
{ |
- this._callback = callback; |
- this._canvas = E("screenshotCanvas"); |
- this._canvas.width = this._canvas.offsetWidth; |
+ let outerWindowID = wnd.QueryInterface(Ci.nsIInterfaceRequestor) |
+ .getInterface(Ci.nsIDOMWindowUtils) |
+ .outerWindowID; |
+ let dataCollector = require("dataCollector"); |
+ let canvas = E("screenshotCanvas"); |
+ let screenshotWidth = canvas.offsetWidth - this.imageOffset * 2; |
+ dataCollector.collectData(outerWindowID, screenshotWidth, data => { |
+ if (!data || !data.screenshot) |
+ { |
+ callback(); |
+ return; |
+ } |
- // Do not resize canvas any more (no idea why Gecko requires both to be set) |
- this._canvas.parentNode.style.MozBoxAlign = "center"; |
- this._canvas.parentNode.align = "center"; |
+ let image = new Image(); |
+ image.src = data.screenshot; |
+ image.addEventListener("load", () => { |
+ canvas.width = image.width + this.imageOffset * 2; |
+ canvas.height = image.height + this.imageOffset * 2; |
- this._context = this._canvas.getContext("2d"); |
- let wndWidth = wnd.document.documentElement.scrollWidth; |
- let wndHeight = wnd.document.documentElement.scrollHeight; |
+ // Do not resize canvas any more (no idea why Gecko requires both to be set) |
+ canvas.parentNode.style.MozBoxAlign = "center"; |
+ canvas.parentNode.align = "center"; |
- // Copy scaled screenshot of the webpage. We scale the webpage by width |
- // but leave 10px on each side for easier selecting. |
+ let context = canvas.getContext("2d"); |
+ context.drawImage(image, this.imageOffset, this.imageOffset); |
- // Gecko doesn't like sizes more than 64k, restrict to 30k to be on the safe side. |
- // Also, make sure height is at most five times the width to keep image size down. |
- let copyWidth = Math.min(wndWidth, 30000); |
- let copyHeight = Math.min(wndHeight, 30000, copyWidth * 5); |
- let copyX = Math.max(Math.min(wnd.scrollX - copyWidth / 2, wndWidth - copyWidth), 0); |
- let copyY = Math.max(Math.min(wnd.scrollY - copyHeight / 2, wndHeight - copyHeight), 0); |
+ // Init canvas settings |
+ context.fillStyle = "rgb(0, 0, 0)"; |
+ context.strokeStyle = "rgba(255, 0, 0, 0.7)"; |
+ context.lineWidth = 3; |
+ context.lineJoin = "round"; |
- let scalingFactor = (this._canvas.width - this.imageOffset * 2) / copyWidth; |
- this._canvas.height = copyHeight * scalingFactor + this.imageOffset * 2; |
+ this._canvas = canvas; |
+ this._context = context; |
- this._context.save(); |
- this._context.translate(this.imageOffset, this.imageOffset); |
- this._context.scale(scalingFactor, scalingFactor); |
- try |
- { |
- this._context.drawWindow(wnd, copyX, copyY, copyWidth, copyHeight, "rgb(255,255,255)"); |
- } |
- catch (e) |
- { |
- Cu.reportError(e); |
- } |
- this._context.restore(); |
- |
- // Init canvas settings |
- this._context.fillStyle = "rgb(0, 0, 0)"; |
- this._context.strokeStyle = "rgba(255, 0, 0, 0.7)"; |
- this._context.lineWidth = 3; |
- this._context.lineJoin = "round"; |
- |
- // Reduce colors asynchronously |
- this._pixelData = this._context.getImageData(this.imageOffset, this.imageOffset, |
- this._canvas.width - this.imageOffset * 2, |
- this._canvas.height - this.imageOffset * 2); |
- this._max = this._pixelData.width * this._pixelData.height * 4; |
- this._i = 0; |
- Utils.runAsync(this.run.bind(this)); |
- }, |
- |
- run: function() |
- { |
- // Process only 5000 bytes at a time to prevent browser hangs |
- let endIndex = Math.min(this._i + 5000, this._max); |
- let i = this._i; |
- for (; i < endIndex; i++) |
- this._pixelData.data[i] = this._mapping[this._pixelData.data[i] >> 6]; |
- |
- if (i >= this._max) |
- { |
- // Save data back and we are done |
- this._context.putImageData(this._pixelData, this.imageOffset, this.imageOffset); |
- this._callback(); |
- } |
- else |
- { |
- this._i = i; |
- Utils.runAsync(this.run.bind(this)); |
- } |
+ callback(); |
+ }); |
+ }); |
}, |
get enabled() this._enabled, |
set enabled(enabled) |
{ |
if (this._enabled == enabled) |
return; |