Skip to content

[WIP] Support worker contexts capturing #298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions dist/spector.bundle.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion extensions/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var refreshCanvases = function() {
for (var frameId in tabInfo[tabId]) {
var infos = tabInfo[tabId][frameId];
canvasesToSend.captureOffScreen = infos.captureOffScreen;
canvasesToSend.captureWorker = infos.captureWorker;
for (var i = 0; i < infos.canvases.length; i++) {
var info = infos.canvases[i];
canvasesToSend.canvases.push({
Expand Down Expand Up @@ -107,7 +108,7 @@ listenForMessage(function(request, sender, sendResponse) {
tabInfo[tabId] = { };
}

tabInfo[tabId][frameId] = { canvases: request.canvases, captureOffScreen: request.captureOffScreen };
tabInfo[tabId][frameId] = { canvases: request.canvases, captureOffScreen: request.captureOffScreen, captureWorker: request.captureWorker };
}
else if (request.errorString) {
// Close the wait message and may display an error.
Expand Down
124 changes: 90 additions & 34 deletions extensions/contentScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function insertTextScript(text) {
var script = document.createElement("script");
script.type = "text/javascript";
script.text = text;
script.nonce = ""
insertHeaderNode(script);
return script;
};
Expand Down Expand Up @@ -78,6 +79,7 @@ var spectorCaptureOnLoadTransientKey = "SPECTOR_CAPTUREONLOAD_TRANSIENT";
var spectorCaptureOnLoadQuickCaptureKey = "SPECTOR_CAPTUREONLOAD_QUICKCAPTURE";
var spectorCaptureOnLoadFullCaptureKey = "SPECTOR_CAPTUREONLOAD_FULLCAPTURE";
var captureOffScreenKey = "SPECTOR_CAPTUREOFFSCREEN";
var captureWorkerKey = "SPECTOR_CAPTUREWORKER";
var spectorCommunicationElementId = "SPECTOR_COMMUNICATION";
var spectorCommunicationQuickCaptureElementId = "SPECTOR_COMMUNICATION_QUICKCAPTURE";
var spectorCommunicationFullCaptureElementId = "SPECTOR_COMMUNICATION_FULLCAPTURE";
Expand All @@ -87,6 +89,7 @@ var spectorCommunicationRebuildProgramElementId = "SPECTOR_COMMUNICATION_REBUILD
var spectorContextTypeKey = "__spector_context_type";

var captureOnLoad = false;
var captureWorker = false;
var captureOnLoadTransient = false;
var captureOnLoadQuickCapture = false;
var captureOnLoadFullCapture = false;
Expand All @@ -104,6 +107,7 @@ if (sessionStorage.getItem(spectorCaptureOnLoadKey) === "true") {
}

captureOffScreen = (sessionStorage.getItem(captureOffScreenKey) === "true");
captureWorker = (sessionStorage.getItem(captureWorkerKey) === "true");

var canvasGetContextDetection = `
var spector;
Expand All @@ -114,6 +118,8 @@ var canvasGetContextDetection = `
(function() {
var __SPECTOR_Origin_EXTENSION_GetContext = HTMLCanvasElement.prototype.getContext;
HTMLCanvasElement.prototype.__SPECTOR_Origin_EXTENSION_GetContext = __SPECTOR_Origin_EXTENSION_GetContext;
var __SPECTOR_Origin_EXTENSION_TransferControlToOffscreen = HTMLCanvasElement.prototype.transferControlToOffscreen;
HTMLCanvasElement.prototype.__SPECTOR_Origin_EXTENSION_TransferControlToOffscreen = __SPECTOR_Origin_EXTENSION_TransferControlToOffscreen;

if (typeof OffscreenCanvas !== 'undefined') {
var __SPECTOR_Origin_EXTENSION_OffscreenGetContext = OffscreenCanvas.prototype.getContext;
Expand Down Expand Up @@ -210,24 +216,38 @@ var canvasGetContextDetection = `

return context;
}

HTMLCanvasElement.prototype.transferControlToOffscreen = function() {
var offscreenCanvas = this.__SPECTOR_Origin_EXTENSION_TransferControlToOffscreen();
var myEvent = new CustomEvent("SpectorWebGLCanvasAvailableEvent");
document.dispatchEvent(myEvent);
return offscreenCanvas;
}
})()`;
insertTextScript(canvasGetContextDetection);

var frameId = null;

// In case the spector injection has been requested, inject the library in the page.
if (sessionStorage.getItem(spectorLoadedKey)) {

if (debug) {
insertScript("http://localhost:1337/tools/loader.js");
} else {
insertTextScript('(' + spectorBundleHook.toString() + ' )();');
}
else {
insertTextScript( '(' + spectorBundleHook.toString() + ' )();');
}

// Defer exec to next slot to ensure proper loading of the lib.
setTimeout(function () {
var captureLib = `spector = new SPECTOR.Spector();
function loadCaptureLib() {
// Defer exec to next slot to ensure proper loading of the lib.
setTimeout(function () {
var captureLib = `(function() {
if (window.__SPECTOR_spector_${captureWorker ? "worker" : "main"}) {
spector = window.__SPECTOR_spector_${captureWorker ? "worker" : "main"};
return;
}
if (${captureWorker} && !window.__SPECTOR_worker) {
console.error("Worker not found, please create worker and set to window.__SPECTOR_worker");
console.assert(false);
return;
}
spector = ${captureWorker} ? new SPECTOR.RemoteSpector({}, window.__SPECTOR_worker) : new SPECTOR.Spector();
spector.spyCanvases();
document.addEventListener("SpectorRequestPauseEvent", function() {
spector.pause();
Expand All @@ -242,14 +262,14 @@ if (sessionStorage.getItem(spectorLoadedKey)) {
var canvasIndex = document.getElementById('${spectorCommunicationElementId}').value;

var canvas = null;
if (${captureOffScreen}) {
if (${!captureWorker && captureOffScreen}) {
canvas = window.__SPECTOR_Canvases[canvasIndex];
} else {
canvas = document.body.querySelectorAll("canvas")[canvasIndex];
}
var quickCapture = (document.getElementById('${spectorCommunicationQuickCaptureElementId}').value === "true");
var fullCapture = (document.getElementById('${spectorCommunicationFullCaptureElementId}').value === "true");
var commandCount = 0 + document.getElementById('${spectorCommunicationCommandCountElementId}').value;
var commandCount = 0 + parseInt(document.getElementById('${spectorCommunicationCommandCountElementId}').value);

spector.captureCanvas(canvas, commandCount, quickCapture, fullCapture);
});
Expand Down Expand Up @@ -296,27 +316,40 @@ if (sessionStorage.getItem(spectorLoadedKey)) {
var myEvent = new CustomEvent("SpectorOnErrorEvent", { detail: { errorString: error } });
document.dispatchEvent(myEvent);
});
spector.onCapture.add((capture) => {
var myEvent = new CustomEvent("SpectorOnCaptureEvent", { detail: { capture: capture } });
document.dispatchEvent(myEvent);
});
setInterval(() => {
var myEvent = new CustomEvent("SpectorFPSEvent", { detail: { fps: (spector ? spector.getFps() : 0) } });
if (${captureWorker}) {
spector.addOnCapture((capture) => {
var myEvent = new CustomEvent("SpectorOnCaptureEvent", { detail: { capture: capture } });
document.dispatchEvent(myEvent);
});
} else {
spector.onCapture.add((capture) => {
var myEvent = new CustomEvent("SpectorOnCaptureEvent", { detail: { capture: capture } });
document.dispatchEvent(myEvent);
});
}
setInterval(async () => {
var myEvent = new CustomEvent("SpectorFPSEvent", { detail: { fps: (spector ? await spector.getFps() : 0) } });
document.dispatchEvent(myEvent);
}, 1500);
window.spector = spector;`;
window.spector = spector;
console.log("Spector init. Spied on ${captureWorker ? "worker" : "main" }");
window.__SPECTOR_spector_${captureWorker ? "worker" : "main"} = spector;
})()`;

if (debug) {
insertTextScript(`SPECTORTOOLS.Loader
if (debug) {
insertTextScript(`SPECTORTOOLS.Loader
.onReady(function() {
${captureLib}
})
.load();`);
}
else {
insertTextScript(captureLib);
}
}, 0);
} else {
insertTextScript(captureLib);
}
}, 0);
}
if (!captureWorker) {
loadCaptureLib();
}

document.addEventListener("DOMContentLoaded", function () {
var script = `var input = document.createElement('input');
Expand Down Expand Up @@ -455,7 +488,7 @@ if (sessionStorage.getItem(spectorLoadedKey)) {
}

// Inform the extension that canvases are present (2 means injection has been done, 1 means ready to inject)
sendMessage({ canvases: uiInformation, captureOffScreen: true }, function (response) {
sendMessage({ canvases: uiInformation, captureOffScreen: true, captureWorker: false }, function (response) {
frameId = response.frameId;
});
});
Expand All @@ -470,7 +503,10 @@ else {
}

var refreshCanvases = function() {
if (captureOffScreen) {
if (captureWorker) {
loadCaptureLib();
}
if (!captureWorker && captureOffScreen) {
// List is retrieved from all the ever created canvases.
var myEvent = new CustomEvent("SpectorRequestCanvasListEvent");
document.dispatchEvent(myEvent);
Expand All @@ -484,11 +520,23 @@ var refreshCanvases = function() {
for (var i = 0; i < canvasElements.length; i++) {
var canvas = canvasElements[i];
var context = null;
try {
context = canvas.getContext(canvas.getAttribute(spectorContextTypeKey));
}
catch (e) {
// Do Nothing.

if (captureWorker) {
if (!canvas.getAttribute(spectorContextTypeKey)) {
// Empty attr means we didn't call getContext, or it is transfered
canvasesInformation.push({
id: canvas.id,
width: canvas.width,
height: canvas.height,
ref: i
});
}
} else {
try {
context = canvas.getContext(canvas.getAttribute(spectorContextTypeKey));
} catch (e) {
// Do Nothing.
}
}

if (context) {
Expand All @@ -500,7 +548,7 @@ var refreshCanvases = function() {
});
}
}
sendMessage({ canvases: canvasesInformation, captureOffScreen: false }, function (response) {
sendMessage({ canvases: canvasesInformation, captureOffScreen: false, captureWorker: captureWorker }, function (response) {
frameId = response.frameId;
});
}
Expand Down Expand Up @@ -550,6 +598,14 @@ listenForMessage(function (message) {
return;
}

// Set worker canvas mode.
if (action === "changeCaptureWorker") {
sessionStorage.setItem(captureWorkerKey, message.captureWorker ? "true" : "false");
// Delay for all frames.
setTimeout(function () { window.location.reload(); }, 50);
return;
}

// We need to reload to inject the capture loading sequence.
if (action === "captureOnLoad") {
var transient = message.transient;
Expand Down Expand Up @@ -584,7 +640,7 @@ listenForMessage(function (message) {

// Following actions are only valid for the selected frame.
var canvasRef = message.canvasRef;
if (canvasRef.frameId !== frameId) {
if (!canvasRef || canvasRef.frameId !== frameId) {
return;
}

Expand Down
7 changes: 5 additions & 2 deletions extensions/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
.filler {
position:absolute;
top:120px;
bottom:140px;
bottom:170px;
left:0px;
right:0px;
}
Expand All @@ -62,7 +62,7 @@

.captureHint {
position:absolute;
bottom:146px;
bottom:175px;
left:0px;
right:0px;
text-align:center;
Expand Down Expand Up @@ -111,6 +111,9 @@
<p>
<label><input type="checkbox" id="offScreen" /> Show offscreen canvas(es)</label>
</p>
<p>
<label><input type="checkbox" id="captureWorker" /> Capture worker (window.__SPECTOR_worker)</label>
</p>
<p>
<label><input type="checkbox" id="quickCapture" /> Quick Capture (no thumbnails)</label>
</p>
Expand Down
15 changes: 15 additions & 0 deletions extensions/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function sendMessage(message) {

var ui = null;
var offScreenInput = null;
var captureWorkerInput = null;

// Display the capture UI.
window.addEventListener("DOMContentLoaded", function() {
Expand All @@ -34,6 +35,7 @@ window.addEventListener("DOMContentLoaded", function() {
var captureOnLoadTransientInput = document.getElementById("captureOnLoadTransient");
var quickCaptureInput = document.getElementById("quickCapture");
var fullCaptureInput = document.getElementById("fullCapture");
captureWorkerInput = document.getElementById("captureWorker");
offScreenInput = document.getElementById("offScreen");

captureNowElement.addEventListener("click", (e) => {
Expand Down Expand Up @@ -68,6 +70,10 @@ window.addEventListener("DOMContentLoaded", function() {
this.changeOffScreenStatus(offScreenInput.checked);
};

captureWorkerInput.onchange = () => {
this.changeCaptureWorker(captureWorkerInput.checked);
};

initUI();
refreshCanvases();
playAll();
Expand Down Expand Up @@ -110,6 +116,14 @@ var changeOffScreenStatus = function(offScreen) {
});
}

var changeCaptureWorker = function(captureWorker) {
sendMessage({
action: "changeCaptureWorker",
captureWorker : captureWorker,
});
}


var drag = function(e) {
e.stopPropagation();
e.preventDefault();
Expand Down Expand Up @@ -179,6 +193,7 @@ var refreshCanvases = function() {
var updateCanvasesListInformation = function (canvasesToSend) {
ui.updateCanvasesListInformation(canvasesToSend.canvases);
offScreenInput.checked = canvasesToSend.captureOffScreen;
captureWorkerInput.checked = canvasesToSend.captureWorker;
}

var refreshFps = function(fps, frameId, tabId) {
Expand Down
43 changes: 22 additions & 21 deletions extensions/spector.bundle.func.js

Large diffs are not rendered by default.

43 changes: 22 additions & 21 deletions extensions/spector.bundle.js

Large diffs are not rendered by default.

Loading