| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|  | 3  * Copyright (C) 2006-2015 Eyeo GmbH | 
|  | 4  * | 
|  | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
|  | 6  * it under the terms of the GNU General Public License version 3 as | 
|  | 7  * published by the Free Software Foundation. | 
|  | 8  * | 
|  | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
|  | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | 12  * GNU General Public License for more details. | 
|  | 13  * | 
|  | 14  * You should have received a copy of the GNU General Public License | 
|  | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
|  | 16  */ | 
|  | 17 | 
|  | 18 /** | 
|  | 19  * @fileOverview Collects some data for a content window, to be attached to | 
|  | 20  * issue reports. | 
|  | 21  */ | 
|  | 22 | 
|  | 23 "use strict"; | 
|  | 24 | 
|  | 25 let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); | 
|  | 26 let {Task} = Cu.import("resource://gre/modules/Task.jsm", {}); | 
|  | 27 | 
|  | 28 let {Utils} = require("utils"); | 
|  | 29 | 
|  | 30 addMessageListener("AdblockPlus:CollectData", onCollectData); | 
|  | 31 onShutdown.add(() => { | 
|  | 32   removeMessageListener("AdblockPlus:CollectData", onCollectData); | 
|  | 33 }); | 
|  | 34 | 
|  | 35 function onCollectData(message) | 
|  | 36 { | 
|  | 37   let {outerWindowID, screenshotWidth, responseID} = message.data; | 
|  | 38 | 
|  | 39   function success(data) | 
|  | 40   { | 
|  | 41     sendAsyncMessage("AdblockPlus:CollectDataResponse", { | 
|  | 42       responseID, | 
|  | 43       data | 
|  | 44     }); | 
|  | 45   } | 
|  | 46 | 
|  | 47   function error(e) | 
|  | 48   { | 
|  | 49     Cu.reportError(e); | 
|  | 50     sendAsyncMessage("AdblockPlus:CollectDataResponse", { | 
|  | 51       responseID, | 
|  | 52       data: null | 
|  | 53     }); | 
|  | 54   } | 
|  | 55 | 
|  | 56   let window = Services.wm.getOuterWindowWithId(outerWindowID); | 
|  | 57   if (window) | 
|  | 58   { | 
|  | 59     Task.spawn(function*() | 
|  | 60     { | 
|  | 61       let data = {}; | 
|  | 62       data.screenshot = yield createScreenshot(window, screenshotWidth); | 
|  | 63       return data; | 
|  | 64     }).then(success, error); | 
|  | 65   } | 
|  | 66 } | 
|  | 67 | 
|  | 68 function* createScreenshot(window, screenshotWidth) | 
|  | 69 { | 
|  | 70   let canvas = window.document.createElement("canvas"); | 
|  | 71   canvas.width = screenshotWidth; | 
|  | 72 | 
|  | 73   let context = canvas.getContext("2d"); | 
|  | 74   let wndWidth = window.document.documentElement.scrollWidth; | 
|  | 75   let wndHeight = window.document.documentElement.scrollHeight; | 
|  | 76 | 
|  | 77   // Copy scaled screenshot of the webpage, according to the specified width. | 
|  | 78 | 
|  | 79   // Gecko doesn't like sizes more than 64k, restrict to 30k to be on the safe s
     ide. | 
|  | 80   // Also, make sure height is at most five times the width to keep image size d
     own. | 
|  | 81   let copyWidth = Math.min(wndWidth, 30000); | 
|  | 82   let copyHeight = Math.min(wndHeight, 30000, copyWidth * 5); | 
|  | 83   let copyX = Math.max(Math.min(window.scrollX - copyWidth / 2, wndWidth - copyW
     idth), 0); | 
|  | 84   let copyY = Math.max(Math.min(window.scrollY - copyHeight / 2, wndHeight - cop
     yHeight), 0); | 
|  | 85 | 
|  | 86   let scalingFactor = screenshotWidth / copyWidth; | 
|  | 87   canvas.height = copyHeight * scalingFactor; | 
|  | 88 | 
|  | 89   context.save(); | 
|  | 90   context.scale(scalingFactor, scalingFactor); | 
|  | 91   context.drawWindow(window, copyX, copyY, copyWidth, copyHeight, "rgb(255,255,2
     55)"); | 
|  | 92   context.restore(); | 
|  | 93 | 
|  | 94   // Reduce colors | 
|  | 95   let pixelData = context.getImageData(0, 0, canvas.width, canvas.height); | 
|  | 96   let max = pixelData.width * pixelData.height * 4; | 
|  | 97   let mapping = [0x00,  0x55,  0xAA,  0xFF]; | 
|  | 98   for (let i = 0; i < max; i++) | 
|  | 99   { | 
|  | 100     pixelData.data[i] = mapping[pixelData.data[i] >> 6]; | 
|  | 101 | 
|  | 102     if (i % 5000 == 0) | 
|  | 103     { | 
|  | 104       // Take a break every 5000 bytes to prevent browser hangs | 
|  | 105       yield new Promise((resolve, reject) => Utils.runAsync(resolve)); | 
|  | 106     } | 
|  | 107   } | 
|  | 108 | 
|  | 109   // Convert the data into an image URL | 
|  | 110   context.putImageData(pixelData, 0, 0); | 
|  | 111   return canvas.toDataURL("image/png"); | 
|  | 112 } | 
| OLD | NEW | 
|---|