зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1403938 - remove Canvas Debugger client; r=vporof
Assigning sole for now Differential Revision: https://phabricator.services.mozilla.com/D14730 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c89f4b00ab
Коммит
45147b86ec
|
@ -107,9 +107,6 @@ module.exports = {
|
|||
}
|
||||
}, {
|
||||
"files": [
|
||||
// Note: Bug 1403938 may be removing canvasdebugger, check before
|
||||
// doing more work on enabling these rules.
|
||||
"client/canvasdebugger/**",
|
||||
// Note: Bug 1342237 may be removing shadereditor, check before
|
||||
// doing more work on enabling these rules.
|
||||
"client/shadereditor/**",
|
||||
|
|
|
@ -1,453 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* import-globals-from canvasdebugger.js */
|
||||
/* globals window, document */
|
||||
"use strict";
|
||||
|
||||
const { METHOD_FUNCTION } = require("devtools/shared/fronts/function-call");
|
||||
/**
|
||||
* Functions handling details about a single recorded animation frame snapshot
|
||||
* (the calls list, rendering preview, thumbnails filmstrip etc.).
|
||||
*/
|
||||
var CallsListView = extend(WidgetMethods, {
|
||||
/**
|
||||
* Initialization function, called when the tool is started.
|
||||
*/
|
||||
initialize: function() {
|
||||
this.widget = new SideMenuWidget($("#calls-list"));
|
||||
this._searchbox = $("#calls-searchbox");
|
||||
this._filmstrip = $("#snapshot-filmstrip");
|
||||
|
||||
this._onSelect = this._onSelect.bind(this);
|
||||
this._onSearch = this._onSearch.bind(this);
|
||||
this._onScroll = this._onScroll.bind(this);
|
||||
this._onExpand = this._onExpand.bind(this);
|
||||
this._onStackFileClick = this._onStackFileClick.bind(this);
|
||||
this._onThumbnailClick = this._onThumbnailClick.bind(this);
|
||||
|
||||
this.widget.addEventListener("select", this._onSelect);
|
||||
this._searchbox.addEventListener("input", this._onSearch);
|
||||
this._filmstrip.addEventListener("wheel", this._onScroll);
|
||||
},
|
||||
|
||||
/**
|
||||
* Destruction function, called when the tool is closed.
|
||||
*/
|
||||
destroy: function() {
|
||||
this.widget.removeEventListener("select", this._onSelect);
|
||||
this._searchbox.removeEventListener("input", this._onSearch);
|
||||
this._filmstrip.removeEventListener("wheel", this._onScroll);
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates this container with a list of function calls.
|
||||
*
|
||||
* @param array functionCalls
|
||||
* A list of function call actors received from the backend.
|
||||
*/
|
||||
showCalls: function(functionCalls) {
|
||||
this.empty();
|
||||
|
||||
for (let i = 0, len = functionCalls.length; i < len; i++) {
|
||||
const call = functionCalls[i];
|
||||
|
||||
const view = document.createElement("vbox");
|
||||
view.className = "call-item-view devtools-monospace";
|
||||
view.setAttribute("flex", "1");
|
||||
|
||||
const contents = document.createElement("hbox");
|
||||
contents.className = "call-item-contents";
|
||||
contents.setAttribute("align", "center");
|
||||
contents.addEventListener("dblclick", this._onExpand);
|
||||
view.appendChild(contents);
|
||||
|
||||
const index = document.createElement("label");
|
||||
index.className = "plain call-item-index";
|
||||
index.setAttribute("flex", "1");
|
||||
index.setAttribute("value", i + 1);
|
||||
|
||||
const gutter = document.createElement("hbox");
|
||||
gutter.className = "call-item-gutter";
|
||||
gutter.appendChild(index);
|
||||
contents.appendChild(gutter);
|
||||
|
||||
if (call.callerPreview) {
|
||||
const context = document.createElement("label");
|
||||
context.className = "plain call-item-context";
|
||||
context.setAttribute("value", call.callerPreview);
|
||||
contents.appendChild(context);
|
||||
|
||||
const separator = document.createElement("label");
|
||||
separator.className = "plain call-item-separator";
|
||||
separator.setAttribute("value", ".");
|
||||
contents.appendChild(separator);
|
||||
}
|
||||
|
||||
const name = document.createElement("label");
|
||||
name.className = "plain call-item-name";
|
||||
name.setAttribute("value", call.name);
|
||||
contents.appendChild(name);
|
||||
|
||||
const argsPreview = document.createElement("label");
|
||||
argsPreview.className = "plain call-item-args";
|
||||
argsPreview.setAttribute("crop", "end");
|
||||
argsPreview.setAttribute("flex", "100");
|
||||
// Getters and setters are displayed differently from regular methods.
|
||||
if (call.type == METHOD_FUNCTION) {
|
||||
argsPreview.setAttribute("value", "(" + call.argsPreview + ")");
|
||||
} else {
|
||||
argsPreview.setAttribute("value", " = " + call.argsPreview);
|
||||
}
|
||||
contents.appendChild(argsPreview);
|
||||
|
||||
const location = document.createElement("label");
|
||||
location.className = "plain call-item-location";
|
||||
location.setAttribute("value", getFileName(call.file) + ":" + call.line);
|
||||
location.setAttribute("crop", "start");
|
||||
location.setAttribute("flex", "1");
|
||||
location.addEventListener("mousedown", this._onExpand);
|
||||
contents.appendChild(location);
|
||||
|
||||
// Append a function call item to this container.
|
||||
this.push([view], {
|
||||
staged: true,
|
||||
attachment: {
|
||||
actor: call,
|
||||
},
|
||||
});
|
||||
|
||||
// Highlight certain calls that are probably more interesting than
|
||||
// everything else, making it easier to quickly glance over them.
|
||||
if (CanvasFront.DRAW_CALLS.has(call.name)) {
|
||||
view.setAttribute("draw-call", "");
|
||||
}
|
||||
if (CanvasFront.INTERESTING_CALLS.has(call.name)) {
|
||||
view.setAttribute("interesting-call", "");
|
||||
}
|
||||
}
|
||||
|
||||
// Flushes all the prepared function call items into this container.
|
||||
this.commit();
|
||||
window.emit(EVENTS.CALL_LIST_POPULATED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays an image in the rendering preview of this container, generated
|
||||
* for the specified draw call in the recorded animation frame snapshot.
|
||||
*
|
||||
* @param array screenshot
|
||||
* A single "snapshot-image" instance received from the backend.
|
||||
*/
|
||||
showScreenshot: function(screenshot) {
|
||||
const { index, width, height, scaling, flipped, pixels } = screenshot;
|
||||
|
||||
const screenshotNode = $("#screenshot-image");
|
||||
screenshotNode.setAttribute("flipped", flipped);
|
||||
drawBackground("screenshot-rendering", width, height, pixels);
|
||||
|
||||
const dimensionsNode = $("#screenshot-dimensions");
|
||||
const actualWidth = (width / scaling) | 0;
|
||||
const actualHeight = (height / scaling) | 0;
|
||||
dimensionsNode.setAttribute("value",
|
||||
SHARED_L10N.getFormatStr("dimensions", actualWidth, actualHeight));
|
||||
|
||||
window.emit(EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates this container's footer with a list of thumbnails, one generated
|
||||
* for each draw call in the recorded animation frame snapshot.
|
||||
*
|
||||
* @param array thumbnails
|
||||
* An array of "snapshot-image" instances received from the backend.
|
||||
*/
|
||||
showThumbnails: function(thumbnails) {
|
||||
while (this._filmstrip.hasChildNodes()) {
|
||||
this._filmstrip.firstChild.remove();
|
||||
}
|
||||
for (const thumbnail of thumbnails) {
|
||||
this.appendThumbnail(thumbnail);
|
||||
}
|
||||
|
||||
window.emit(EVENTS.THUMBNAILS_DISPLAYED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays an image in the thumbnails list of this container, generated
|
||||
* for the specified draw call in the recorded animation frame snapshot.
|
||||
*
|
||||
* @param array thumbnail
|
||||
* A single "snapshot-image" instance received from the backend.
|
||||
*/
|
||||
appendThumbnail: function(thumbnail) {
|
||||
const { index, width, height, flipped, pixels } = thumbnail;
|
||||
|
||||
const thumbnailNode = document.createElementNS(HTML_NS, "canvas");
|
||||
thumbnailNode.setAttribute("flipped", flipped);
|
||||
thumbnailNode.width = Math.max(CanvasFront.THUMBNAIL_SIZE, width);
|
||||
thumbnailNode.height = Math.max(CanvasFront.THUMBNAIL_SIZE, height);
|
||||
drawImage(thumbnailNode, width, height, pixels, { centered: true });
|
||||
|
||||
thumbnailNode.className = "filmstrip-thumbnail";
|
||||
thumbnailNode.onmousedown = e => this._onThumbnailClick(e, index);
|
||||
thumbnailNode.setAttribute("index", index);
|
||||
this._filmstrip.appendChild(thumbnailNode);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the currently highlighted thumbnail in this container.
|
||||
* A screenshot will always correlate to a thumbnail in the filmstrip,
|
||||
* both being identified by the same 'index' of the context function call.
|
||||
*
|
||||
* @param number index
|
||||
* The context function call's index.
|
||||
*/
|
||||
set highlightedThumbnail(index) {
|
||||
const currHighlightedThumbnail = $(".filmstrip-thumbnail[index='" + index + "']");
|
||||
if (currHighlightedThumbnail == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const prevIndex = this._highlightedThumbnailIndex;
|
||||
const prevHighlightedThumbnail = $(".filmstrip-thumbnail[index='" + prevIndex + "']");
|
||||
if (prevHighlightedThumbnail) {
|
||||
prevHighlightedThumbnail.removeAttribute("highlighted");
|
||||
}
|
||||
|
||||
currHighlightedThumbnail.setAttribute("highlighted", "");
|
||||
currHighlightedThumbnail.scrollIntoView();
|
||||
this._highlightedThumbnailIndex = index;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the currently highlighted thumbnail in this container.
|
||||
* @return number
|
||||
*/
|
||||
get highlightedThumbnail() {
|
||||
return this._highlightedThumbnailIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* The select listener for this container.
|
||||
*/
|
||||
_onSelect: function({ detail: callItem }) {
|
||||
if (!callItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some of the stepping buttons don't make sense specifically while the
|
||||
// last function call is selected.
|
||||
if (this.selectedIndex == this.itemCount - 1) {
|
||||
$("#resume").setAttribute("disabled", "true");
|
||||
$("#step-over").setAttribute("disabled", "true");
|
||||
$("#step-out").setAttribute("disabled", "true");
|
||||
} else {
|
||||
$("#resume").removeAttribute("disabled");
|
||||
$("#step-over").removeAttribute("disabled");
|
||||
$("#step-out").removeAttribute("disabled");
|
||||
}
|
||||
|
||||
// Can't generate screenshots for function call actors loaded from disk.
|
||||
// XXX: Bug 984844.
|
||||
if (callItem.attachment.actor.isLoadedFromDisk) {
|
||||
return;
|
||||
}
|
||||
|
||||
// To keep continuous selection buttery smooth (for example, while pressing
|
||||
// the DOWN key or moving the slider), only display the screenshot after
|
||||
// any kind of user input stops.
|
||||
setConditionalTimeout("screenshot-display", SCREENSHOT_DISPLAY_DELAY, () => {
|
||||
return !this._isSliding;
|
||||
}, () => {
|
||||
const frameSnapshot = SnapshotsListView.selectedItem.attachment.actor;
|
||||
const functionCall = callItem.attachment.actor;
|
||||
frameSnapshot.generateScreenshotFor(functionCall).then(screenshot => {
|
||||
this.showScreenshot(screenshot);
|
||||
this.highlightedThumbnail = screenshot.index;
|
||||
}).catch(console.error);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The input listener for the calls searchbox.
|
||||
*/
|
||||
_onSearch: function(e) {
|
||||
const lowerCaseSearchToken = this._searchbox.value.toLowerCase();
|
||||
|
||||
this.filterContents(e => {
|
||||
const call = e.attachment.actor;
|
||||
const name = call.name.toLowerCase();
|
||||
const file = call.file.toLowerCase();
|
||||
const line = call.line.toString().toLowerCase();
|
||||
const args = call.argsPreview.toLowerCase();
|
||||
|
||||
return name.includes(lowerCaseSearchToken) ||
|
||||
file.includes(lowerCaseSearchToken) ||
|
||||
line.includes(lowerCaseSearchToken) ||
|
||||
args.includes(lowerCaseSearchToken);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The wheel listener for the filmstrip that contains all the thumbnails.
|
||||
*/
|
||||
_onScroll: function(e) {
|
||||
this._filmstrip.scrollLeft += e.deltaX;
|
||||
},
|
||||
|
||||
/**
|
||||
* The click/dblclick listener for an item or location url in this container.
|
||||
* When expanding an item, it's corresponding call stack will be displayed.
|
||||
*/
|
||||
_onExpand: function(e) {
|
||||
const callItem = this.getItemForElement(e.target);
|
||||
const view = $(".call-item-view", callItem.target);
|
||||
|
||||
// If the call stack nodes were already created, simply re-show them
|
||||
// or jump to the corresponding file and line in the Debugger if a
|
||||
// location link was clicked.
|
||||
if (view.hasAttribute("call-stack-populated")) {
|
||||
const isExpanded = view.getAttribute("call-stack-expanded") == "true";
|
||||
|
||||
// If clicking on the location, jump to the Debugger.
|
||||
if (e.target.classList.contains("call-item-location")) {
|
||||
const { file, line } = callItem.attachment.actor;
|
||||
this._viewSourceInDebugger(file, line);
|
||||
return;
|
||||
}
|
||||
// Otherwise hide the call stack.
|
||||
|
||||
view.setAttribute("call-stack-expanded", !isExpanded);
|
||||
$(".call-item-stack", view).hidden = isExpanded;
|
||||
return;
|
||||
}
|
||||
|
||||
const list = document.createElement("vbox");
|
||||
list.className = "call-item-stack";
|
||||
view.setAttribute("call-stack-populated", "");
|
||||
view.setAttribute("call-stack-expanded", "true");
|
||||
view.appendChild(list);
|
||||
|
||||
/**
|
||||
* Creates a function call nodes in this container for a stack.
|
||||
*/
|
||||
const display = stack => {
|
||||
for (let i = 1; i < stack.length; i++) {
|
||||
const call = stack[i];
|
||||
|
||||
const contents = document.createElement("hbox");
|
||||
contents.className = "call-item-stack-fn";
|
||||
contents.style.paddingInlineStart = (i * STACK_FUNC_INDENTATION) + "px";
|
||||
|
||||
const name = document.createElement("label");
|
||||
name.className = "plain call-item-stack-fn-name";
|
||||
name.setAttribute("value", "↳ " + call.name + "()");
|
||||
contents.appendChild(name);
|
||||
|
||||
const spacer = document.createElement("spacer");
|
||||
spacer.setAttribute("flex", "100");
|
||||
contents.appendChild(spacer);
|
||||
|
||||
const location = document.createElement("label");
|
||||
location.className = "plain call-item-stack-fn-location";
|
||||
location.setAttribute("value", getFileName(call.file) + ":" + call.line);
|
||||
location.setAttribute("crop", "start");
|
||||
location.setAttribute("flex", "1");
|
||||
location.addEventListener("mousedown", e => this._onStackFileClick(e, call));
|
||||
contents.appendChild(location);
|
||||
|
||||
list.appendChild(contents);
|
||||
}
|
||||
|
||||
window.emit(EVENTS.CALL_STACK_DISPLAYED);
|
||||
};
|
||||
|
||||
// If this animation snapshot is loaded from disk, there are no corresponding
|
||||
// backend actors available and the data is immediately available.
|
||||
const functionCall = callItem.attachment.actor;
|
||||
if (functionCall.isLoadedFromDisk) {
|
||||
display(functionCall.stack);
|
||||
} else {
|
||||
// ..otherwise we need to request the function call stack from the backend.
|
||||
callItem.attachment.actor.getDetails().then(fn => display(fn.stack));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for a location link in the call stack.
|
||||
*
|
||||
* @param string file
|
||||
* The url of the source owning the function.
|
||||
* @param number line
|
||||
* The line of the respective function.
|
||||
*/
|
||||
_onStackFileClick: function(e, { file, line }) {
|
||||
this._viewSourceInDebugger(file, line);
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for a thumbnail in the filmstrip.
|
||||
*
|
||||
* @param number index
|
||||
* The function index in the recorded animation frame snapshot.
|
||||
*/
|
||||
_onThumbnailClick: function(e, index) {
|
||||
this.selectedIndex = index;
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "resume" button in this container's toolbar.
|
||||
*/
|
||||
_onResume: function() {
|
||||
// Jump to the next draw call in the recorded animation frame snapshot.
|
||||
const drawCall = getNextDrawCall(this.items, this.selectedItem);
|
||||
if (drawCall) {
|
||||
this.selectedItem = drawCall;
|
||||
return;
|
||||
}
|
||||
|
||||
// If there are no more draw calls, just jump to the last context call.
|
||||
this._onStepOut();
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "step over" button in this container's toolbar.
|
||||
*/
|
||||
_onStepOver: function() {
|
||||
this.selectedIndex++;
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "step in" button in this container's toolbar.
|
||||
*/
|
||||
_onStepIn: function() {
|
||||
if (this.selectedIndex == -1) {
|
||||
this._onResume();
|
||||
return;
|
||||
}
|
||||
const callItem = this.selectedItem;
|
||||
const { file, line } = callItem.attachment.actor;
|
||||
this._viewSourceInDebugger(file, line);
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "step out" button in this container's toolbar.
|
||||
*/
|
||||
_onStepOut: function() {
|
||||
this.selectedIndex = this.itemCount - 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens the specified file and line in the debugger. Falls back to Firefox's View Source.
|
||||
*/
|
||||
_viewSourceInDebugger: function(file, line) {
|
||||
gToolbox.viewSourceInDebugger(file, line).then(success => {
|
||||
if (success) {
|
||||
window.emit(EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
|
||||
} else {
|
||||
window.emit(EVENTS.SOURCE_NOT_FOUND_IN_JS_DEBUGGER);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
|
@ -1,334 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
|
||||
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const { SideMenuWidget } = require("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
|
||||
const Services = require("Services");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const { CanvasFront } = require("devtools/shared/fronts/canvas");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
const { extend } = require("devtools/shared/extend");
|
||||
const flags = require("devtools/shared/flags");
|
||||
const { LocalizationHelper } = require("devtools/shared/l10n");
|
||||
const { PluralForm } = require("devtools/shared/plural-form");
|
||||
const { WidgetMethods, setNamedTimeout, clearNamedTimeout,
|
||||
setConditionalTimeout } = require("devtools/client/shared/widgets/view-helpers");
|
||||
|
||||
// Use privileged promise in panel documents to prevent having them to freeze
|
||||
// during toolbox destruction. See bug 1402779.
|
||||
const Promise = require("Promise");
|
||||
|
||||
const CANVAS_ACTOR_RECORDING_ATTEMPT = flags.testing ? 500 : 5000;
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "NetUtil",
|
||||
"resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "NetworkHelper", function() {
|
||||
return require("devtools/shared/webconsole/network-helper");
|
||||
});
|
||||
|
||||
// The panel's window global is an EventEmitter firing the following events:
|
||||
const EVENTS = {
|
||||
// When the UI is reset from tab navigation.
|
||||
UI_RESET: "CanvasDebugger:UIReset",
|
||||
|
||||
// When all the animation frame snapshots are removed by the user.
|
||||
SNAPSHOTS_LIST_CLEARED: "CanvasDebugger:SnapshotsListCleared",
|
||||
|
||||
// When an animation frame snapshot starts/finishes being recorded, and
|
||||
// whether it was completed succesfully or cancelled.
|
||||
SNAPSHOT_RECORDING_STARTED: "CanvasDebugger:SnapshotRecordingStarted",
|
||||
SNAPSHOT_RECORDING_FINISHED: "CanvasDebugger:SnapshotRecordingFinished",
|
||||
SNAPSHOT_RECORDING_COMPLETED: "CanvasDebugger:SnapshotRecordingCompleted",
|
||||
SNAPSHOT_RECORDING_CANCELLED: "CanvasDebugger:SnapshotRecordingCancelled",
|
||||
|
||||
// When an animation frame snapshot was selected and all its data displayed.
|
||||
SNAPSHOT_RECORDING_SELECTED: "CanvasDebugger:SnapshotRecordingSelected",
|
||||
|
||||
// After all the function calls associated with an animation frame snapshot
|
||||
// are displayed in the UI.
|
||||
CALL_LIST_POPULATED: "CanvasDebugger:CallListPopulated",
|
||||
|
||||
// After the stack associated with a call in an animation frame snapshot
|
||||
// is displayed in the UI.
|
||||
CALL_STACK_DISPLAYED: "CanvasDebugger:CallStackDisplayed",
|
||||
|
||||
// After a screenshot associated with a call in an animation frame snapshot
|
||||
// is displayed in the UI.
|
||||
CALL_SCREENSHOT_DISPLAYED: "CanvasDebugger:ScreenshotDisplayed",
|
||||
|
||||
// After all the thumbnails associated with an animation frame snapshot
|
||||
// are displayed in the UI.
|
||||
THUMBNAILS_DISPLAYED: "CanvasDebugger:ThumbnailsDisplayed",
|
||||
|
||||
// When a source is shown in the JavaScript Debugger at a specific location.
|
||||
SOURCE_SHOWN_IN_JS_DEBUGGER: "CanvasDebugger:SourceShownInJsDebugger",
|
||||
SOURCE_NOT_FOUND_IN_JS_DEBUGGER: "CanvasDebugger:SourceNotFoundInJsDebugger",
|
||||
};
|
||||
XPCOMUtils.defineConstant(this, "EVENTS", EVENTS);
|
||||
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const STRINGS_URI = "devtools/client/locales/canvasdebugger.properties";
|
||||
const SHARED_STRINGS_URI = "devtools/client/locales/shared.properties";
|
||||
|
||||
const SNAPSHOT_START_RECORDING_DELAY = 10; // ms
|
||||
const SNAPSHOT_DATA_EXPORT_MAX_BLOCK = 1000; // ms
|
||||
const SNAPSHOT_DATA_DISPLAY_DELAY = 10; // ms
|
||||
const SCREENSHOT_DISPLAY_DELAY = 100; // ms
|
||||
const STACK_FUNC_INDENTATION = 14; // px
|
||||
|
||||
// This identifier string is simply used to tentatively ascertain whether or not
|
||||
// a JSON loaded from disk is actually something generated by this tool or not.
|
||||
// It isn't, of course, a definitive verification, but a Good Enough™
|
||||
// approximation before continuing the import. Don't localize this.
|
||||
const CALLS_LIST_SERIALIZER_IDENTIFIER = "Recorded Animation Frame Snapshot";
|
||||
const CALLS_LIST_SERIALIZER_VERSION = 1;
|
||||
const CALLS_LIST_SLOW_SAVE_DELAY = 100; // ms
|
||||
|
||||
/**
|
||||
* The current target and the Canvas front, set by this tool's host.
|
||||
*/
|
||||
var gToolbox, gTarget, gFront;
|
||||
|
||||
/**
|
||||
* Initializes the canvas debugger controller and views.
|
||||
*/
|
||||
function startupCanvasDebugger() {
|
||||
return Promise.all([
|
||||
EventsHandler.initialize(),
|
||||
SnapshotsListView.initialize(),
|
||||
CallsListView.initialize(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the canvas debugger controller and views.
|
||||
*/
|
||||
function shutdownCanvasDebugger() {
|
||||
return Promise.all([
|
||||
EventsHandler.destroy(),
|
||||
SnapshotsListView.destroy(),
|
||||
CallsListView.destroy(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions handling target-related lifetime events.
|
||||
*/
|
||||
var EventsHandler = {
|
||||
/**
|
||||
* Listen for events emitted by the current tab target.
|
||||
*/
|
||||
initialize: function() {
|
||||
// Make sure the backend is prepared to handle <canvas> contexts.
|
||||
// Since actors are created lazily on the first request to them, we need to send an
|
||||
// early request to ensure the CallWatcherActor is running and watching for new window
|
||||
// globals.
|
||||
gFront.setup({ reload: false });
|
||||
|
||||
this._onTabWillNavigate = this._onTabWillNavigate.bind(this);
|
||||
gTarget.on("will-navigate", this._onTabWillNavigate);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove events emitted by the current tab target.
|
||||
*/
|
||||
destroy: function() {
|
||||
gTarget.off("will-navigate", this._onTabWillNavigate);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called for each location change in the debugged tab.
|
||||
*/
|
||||
_onTabWillNavigate: function() {
|
||||
// Reset UI.
|
||||
SnapshotsListView.empty();
|
||||
CallsListView.empty();
|
||||
|
||||
$("#record-snapshot").removeAttribute("checked");
|
||||
$("#record-snapshot").removeAttribute("disabled");
|
||||
$("#record-snapshot").hidden = false;
|
||||
|
||||
$("#reload-notice").hidden = true;
|
||||
$("#empty-notice").hidden = false;
|
||||
$("#waiting-notice").hidden = true;
|
||||
|
||||
$("#debugging-pane-contents").hidden = true;
|
||||
$("#screenshot-container").hidden = true;
|
||||
$("#snapshot-filmstrip").hidden = true;
|
||||
|
||||
window.emit(EVENTS.UI_RESET);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Localization convenience methods.
|
||||
*/
|
||||
var L10N = new LocalizationHelper(STRINGS_URI);
|
||||
var SHARED_L10N = new LocalizationHelper(SHARED_STRINGS_URI);
|
||||
|
||||
/**
|
||||
* Convenient way of emitting events from the panel window.
|
||||
*/
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
/**
|
||||
* DOM query helpers.
|
||||
*/
|
||||
var $ = (selector, target = document) => target.querySelector(selector);
|
||||
var $all = (selector, target = document) => target.querySelectorAll(selector);
|
||||
|
||||
/**
|
||||
* Gets the fileName part of a string which happens to be an URL.
|
||||
*/
|
||||
function getFileName(url) {
|
||||
try {
|
||||
const { fileName } = NetworkHelper.nsIURL(url);
|
||||
return fileName || "/";
|
||||
} catch (e) {
|
||||
// This doesn't look like a url, or nsIURL can't handle it.
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an image data object containing a buffer large enough to hold
|
||||
* width * height pixels.
|
||||
*
|
||||
* This method avoids allocating memory and tries to reuse a common buffer
|
||||
* as much as possible.
|
||||
*
|
||||
* @param number w
|
||||
* The desired image data storage width.
|
||||
* @param number h
|
||||
* The desired image data storage height.
|
||||
* @return ImageData
|
||||
* The requested image data buffer.
|
||||
*/
|
||||
function getImageDataStorage(ctx, w, h) {
|
||||
const storage = getImageDataStorage.cache;
|
||||
if (storage && storage.width == w && storage.height == h) {
|
||||
return storage;
|
||||
}
|
||||
return getImageDataStorage.cache = ctx.createImageData(w, h);
|
||||
}
|
||||
|
||||
// The cache used in the `getImageDataStorage` function.
|
||||
getImageDataStorage.cache = null;
|
||||
|
||||
/**
|
||||
* Draws image data into a canvas.
|
||||
*
|
||||
* This method makes absolutely no assumptions about the canvas element
|
||||
* dimensions, or pre-existing rendering. It's a dumb proxy that copies pixels.
|
||||
*
|
||||
* @param HTMLCanvasElement canvas
|
||||
* The canvas element to put the image data into.
|
||||
* @param number width
|
||||
* The image data width.
|
||||
* @param number height
|
||||
* The image data height.
|
||||
* @param array pixels
|
||||
* An array buffer view of the image data.
|
||||
* @param object options
|
||||
* Additional options supported by this operation:
|
||||
* - centered: specifies whether the image data should be centered
|
||||
* when copied in the canvas; this is useful when the
|
||||
* supplied pixels don't completely cover the canvas.
|
||||
*/
|
||||
function drawImage(canvas, width, height, pixels, options = {}) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// FrameSnapshot actors return "snapshot-image" type instances with just an
|
||||
// empty pixel array if the source image is completely transparent.
|
||||
if (pixels.length <= 1) {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
return;
|
||||
}
|
||||
|
||||
const imageData = getImageDataStorage(ctx, width, height);
|
||||
imageData.data.set(pixels);
|
||||
|
||||
if (options.centered) {
|
||||
const left = (canvas.width - width) / 2;
|
||||
const top = (canvas.height - height) / 2;
|
||||
ctx.putImageData(imageData, left, top);
|
||||
} else {
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws image data into a canvas, and sets that as the rendering source for
|
||||
* an element with the specified id as the -moz-element background image.
|
||||
*
|
||||
* @param string id
|
||||
* The id of the -moz-element background image.
|
||||
* @param number width
|
||||
* The image data width.
|
||||
* @param number height
|
||||
* The image data height.
|
||||
* @param array pixels
|
||||
* An array buffer view of the image data.
|
||||
*/
|
||||
function drawBackground(id, width, height, pixels) {
|
||||
const canvas = document.createElementNS(HTML_NS, "canvas");
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
drawImage(canvas, width, height, pixels);
|
||||
document.mozSetImageElement(id, canvas);
|
||||
|
||||
// Used in tests. Not emitting an event because this shouldn't be "interesting".
|
||||
if (window._onMozSetImageElement) {
|
||||
window._onMozSetImageElement(pixels);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates forward to find the next draw call in a snapshot.
|
||||
*/
|
||||
function getNextDrawCall(calls, call) {
|
||||
for (let i = calls.indexOf(call) + 1, len = calls.length; i < len; i++) {
|
||||
const nextCall = calls[i];
|
||||
const name = nextCall.attachment.actor.name;
|
||||
if (CanvasFront.DRAW_CALLS.has(name)) {
|
||||
return nextCall;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates backwards to find the most recent screenshot for a function call
|
||||
* in a snapshot loaded from disk.
|
||||
*/
|
||||
function getScreenshotFromCallLoadedFromDisk(calls, call) {
|
||||
for (let i = calls.indexOf(call); i >= 0; i--) {
|
||||
const prevCall = calls[i];
|
||||
const screenshot = prevCall.screenshot;
|
||||
if (screenshot) {
|
||||
return screenshot;
|
||||
}
|
||||
}
|
||||
return CanvasFront.INVALID_SNAPSHOT_IMAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates backwards to find the most recent thumbnail for a function call.
|
||||
*/
|
||||
function getThumbnailForCall(thumbnails, index) {
|
||||
for (let i = thumbnails.length - 1; i >= 0; i--) {
|
||||
const thumbnail = thumbnails[i];
|
||||
if (thumbnail.index <= index) {
|
||||
return thumbnail;
|
||||
}
|
||||
}
|
||||
return CanvasFront.INVALID_SNAPSHOT_IMAGE;
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/canvasdebugger.css" type="text/css"?>
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % canvasDebuggerDTD SYSTEM "chrome://devtools/locale/canvasdebugger.dtd">
|
||||
%canvasDebuggerDTD;
|
||||
]>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script src="chrome://devtools/content/shared/theme-switching.js"/>
|
||||
<script type="application/javascript" src="canvasdebugger.js"/>
|
||||
<script type="application/javascript" src="callslist.js"/>
|
||||
<script type="application/javascript" src="snapshotslist.js"/>
|
||||
|
||||
<hbox class="theme-body" flex="1">
|
||||
<vbox id="snapshots-pane">
|
||||
<toolbar id="snapshots-toolbar"
|
||||
class="devtools-toolbar">
|
||||
<hbox id="snapshots-controls">
|
||||
<toolbarbutton id="clear-snapshots"
|
||||
class="devtools-toolbarbutton devtools-clear-icon"
|
||||
oncommand="SnapshotsListView._onClearButtonClick()"
|
||||
tooltiptext="&canvasDebuggerUI.clearSnapshots;"/>
|
||||
<toolbarbutton id="record-snapshot"
|
||||
class="devtools-toolbarbutton"
|
||||
oncommand="SnapshotsListView._onRecordButtonClick()"
|
||||
tooltiptext="&canvasDebuggerUI.recordSnapshot.tooltip;"
|
||||
hidden="true"/>
|
||||
<toolbarbutton id="import-snapshot"
|
||||
class="devtools-toolbarbutton"
|
||||
oncommand="SnapshotsListView._onImportButtonClick()"
|
||||
tooltiptext="&canvasDebuggerUI.importSnapshot;"/>
|
||||
</hbox>
|
||||
</toolbar>
|
||||
<vbox id="snapshots-list" flex="1"/>
|
||||
</vbox>
|
||||
|
||||
<vbox id="debugging-pane" class="devtools-main-content" flex="1">
|
||||
<hbox id="reload-notice"
|
||||
class="notice-container"
|
||||
align="center"
|
||||
pack="center"
|
||||
flex="1">
|
||||
<button id="reload-notice-button"
|
||||
class="devtools-toolbarbutton"
|
||||
standalone="true"
|
||||
label="&canvasDebuggerUI.reloadNotice1;"
|
||||
oncommand="gFront.setup({ reload: true })"/>
|
||||
<label id="reload-notice-label"
|
||||
class="plain"
|
||||
value="&canvasDebuggerUI.reloadNotice2;"/>
|
||||
</hbox>
|
||||
|
||||
<hbox id="empty-notice"
|
||||
class="notice-container"
|
||||
align="center"
|
||||
pack="center"
|
||||
flex="1"
|
||||
hidden="true">
|
||||
<label value="&canvasDebuggerUI.emptyNotice1;"/>
|
||||
<button id="canvas-debugging-empty-notice-button"
|
||||
class="devtools-toolbarbutton"
|
||||
standalone="true"
|
||||
oncommand="SnapshotsListView._onRecordButtonClick()"/>
|
||||
<label value="&canvasDebuggerUI.emptyNotice2;"/>
|
||||
</hbox>
|
||||
|
||||
<hbox id="waiting-notice"
|
||||
class="notice-container devtools-throbber"
|
||||
align="center"
|
||||
pack="center"
|
||||
flex="1"
|
||||
hidden="true">
|
||||
<label id="requests-menu-waiting-notice-label"
|
||||
class="plain"
|
||||
value="&canvasDebuggerUI.waitingNotice;"/>
|
||||
</hbox>
|
||||
|
||||
<box id="debugging-pane-contents"
|
||||
class="devtools-responsive-container"
|
||||
flex="1"
|
||||
hidden="true">
|
||||
<vbox id="calls-list-container" flex="1">
|
||||
<toolbar id="debugging-toolbar"
|
||||
class="devtools-toolbar">
|
||||
<hbox id="debugging-controls"
|
||||
class="devtools-toolbarbutton-group">
|
||||
<toolbarbutton id="resume"
|
||||
class="devtools-toolbarbutton"
|
||||
oncommand="CallsListView._onResume()"/>
|
||||
<toolbarbutton id="step-over"
|
||||
class="devtools-toolbarbutton"
|
||||
oncommand="CallsListView._onStepOver()"/>
|
||||
<toolbarbutton id="step-in"
|
||||
class="devtools-toolbarbutton"
|
||||
oncommand="CallsListView._onStepIn()"/>
|
||||
<toolbarbutton id="step-out"
|
||||
class="devtools-toolbarbutton"
|
||||
oncommand="CallsListView._onStepOut()"/>
|
||||
</hbox>
|
||||
<toolbarbutton id="debugging-toolbar-sizer-button"
|
||||
class="devtools-toolbarbutton"
|
||||
label=""/>
|
||||
<textbox id="calls-searchbox"
|
||||
class="devtools-filterinput"
|
||||
placeholder="&canvasDebuggerUI.searchboxPlaceholder;"
|
||||
flex="1"/>
|
||||
</toolbar>
|
||||
<vbox id="calls-list" flex="1"/>
|
||||
</vbox>
|
||||
|
||||
<splitter class="devtools-side-splitter"/>
|
||||
|
||||
<vbox id="screenshot-container"
|
||||
hidden="true">
|
||||
<vbox id="screenshot-image" flex="1"/>
|
||||
<label id="screenshot-dimensions" class="plain"/>
|
||||
</vbox>
|
||||
</box>
|
||||
|
||||
<hbox id="snapshot-filmstrip"
|
||||
hidden="true"/>
|
||||
</vbox>
|
||||
|
||||
</hbox>
|
||||
</window>
|
|
@ -1,13 +0,0 @@
|
|||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'panel.js'
|
||||
)
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('DevTools', 'Canvas Debugger')
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const { Cc, Ci, Cu, Cr } = require("chrome");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const { CanvasFront } = require("devtools/shared/fronts/canvas");
|
||||
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
|
||||
function CanvasDebuggerPanel(iframeWindow, toolbox) {
|
||||
this.panelWin = iframeWindow;
|
||||
this._toolbox = toolbox;
|
||||
this._destroyer = null;
|
||||
|
||||
EventEmitter.decorate(this);
|
||||
}
|
||||
|
||||
exports.CanvasDebuggerPanel = CanvasDebuggerPanel;
|
||||
|
||||
CanvasDebuggerPanel.prototype = {
|
||||
/**
|
||||
* Open is effectively an asynchronous constructor.
|
||||
*
|
||||
* @return object
|
||||
* A promise that is resolved when the Canvas Debugger completes opening.
|
||||
*/
|
||||
open: async function() {
|
||||
this.panelWin.gToolbox = this._toolbox;
|
||||
this.panelWin.gTarget = this.target;
|
||||
this.panelWin.gFront = await this.target.getFront("canvas");
|
||||
|
||||
await this.panelWin.startupCanvasDebugger();
|
||||
|
||||
this.isReady = true;
|
||||
this.emit("ready");
|
||||
return this;
|
||||
},
|
||||
|
||||
// DevToolPanel API
|
||||
|
||||
get target() {
|
||||
return this._toolbox.target;
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
// Make sure this panel is not already destroyed.
|
||||
if (this._destroyer) {
|
||||
return this._destroyer;
|
||||
}
|
||||
|
||||
return this._destroyer = this.panelWin.shutdownCanvasDebugger().then(() => {
|
||||
// Destroy front to ensure packet handler is removed from client
|
||||
this.panelWin.gFront.destroy();
|
||||
this.emit("destroyed");
|
||||
});
|
||||
},
|
||||
};
|
|
@ -1,549 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* import-globals-from canvasdebugger.js */
|
||||
/* globals window, document */
|
||||
"use strict";
|
||||
|
||||
var promise = require("promise");
|
||||
var defer = require("devtools/shared/defer");
|
||||
|
||||
/**
|
||||
* Functions handling the recorded animation frame snapshots UI.
|
||||
*/
|
||||
var SnapshotsListView = extend(WidgetMethods, {
|
||||
/**
|
||||
* Initialization function, called when the tool is started.
|
||||
*/
|
||||
initialize: function() {
|
||||
this.widget = new SideMenuWidget($("#snapshots-list"), {
|
||||
showArrows: true,
|
||||
});
|
||||
|
||||
this._onSelect = this._onSelect.bind(this);
|
||||
this._onClearButtonClick = this._onClearButtonClick.bind(this);
|
||||
this._onRecordButtonClick = this._onRecordButtonClick.bind(this);
|
||||
this._onImportButtonClick = this._onImportButtonClick.bind(this);
|
||||
this._onSaveButtonClick = this._onSaveButtonClick.bind(this);
|
||||
this._onRecordSuccess = this._onRecordSuccess.bind(this);
|
||||
this._onRecordFailure = this._onRecordFailure.bind(this);
|
||||
this._stopRecordingAnimation = this._stopRecordingAnimation.bind(this);
|
||||
|
||||
window.on(EVENTS.SNAPSHOT_RECORDING_FINISHED, this._enableRecordButton);
|
||||
this.emptyText = L10N.getStr("noSnapshotsText");
|
||||
this.widget.addEventListener("select", this._onSelect);
|
||||
},
|
||||
|
||||
/**
|
||||
* Destruction function, called when the tool is closed.
|
||||
*/
|
||||
destroy: function() {
|
||||
clearNamedTimeout("canvas-actor-recording");
|
||||
window.off(EVENTS.SNAPSHOT_RECORDING_FINISHED, this._enableRecordButton);
|
||||
this.widget.removeEventListener("select", this._onSelect);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a snapshot entry to this container.
|
||||
*
|
||||
* @return object
|
||||
* The newly inserted item.
|
||||
*/
|
||||
addSnapshot: function() {
|
||||
const contents = document.createElement("hbox");
|
||||
contents.className = "snapshot-item";
|
||||
|
||||
const thumbnail = document.createElementNS(HTML_NS, "canvas");
|
||||
thumbnail.className = "snapshot-item-thumbnail";
|
||||
thumbnail.width = CanvasFront.THUMBNAIL_SIZE;
|
||||
thumbnail.height = CanvasFront.THUMBNAIL_SIZE;
|
||||
|
||||
const title = document.createElement("label");
|
||||
title.className = "plain snapshot-item-title";
|
||||
title.setAttribute("value",
|
||||
L10N.getFormatStr("snapshotsList.itemLabel", this.itemCount + 1));
|
||||
|
||||
const calls = document.createElement("label");
|
||||
calls.className = "plain snapshot-item-calls";
|
||||
calls.setAttribute("value",
|
||||
L10N.getStr("snapshotsList.loadingLabel"));
|
||||
|
||||
const save = document.createElement("label");
|
||||
save.className = "plain snapshot-item-save";
|
||||
save.addEventListener("click", this._onSaveButtonClick);
|
||||
|
||||
const spacer = document.createElement("spacer");
|
||||
spacer.setAttribute("flex", "1");
|
||||
|
||||
const footer = document.createElement("hbox");
|
||||
footer.className = "snapshot-item-footer";
|
||||
footer.appendChild(save);
|
||||
|
||||
const details = document.createElement("vbox");
|
||||
details.className = "snapshot-item-details";
|
||||
details.appendChild(title);
|
||||
details.appendChild(calls);
|
||||
details.appendChild(spacer);
|
||||
details.appendChild(footer);
|
||||
|
||||
contents.appendChild(thumbnail);
|
||||
contents.appendChild(details);
|
||||
|
||||
// Append a recorded snapshot item to this container.
|
||||
return this.push([contents], {
|
||||
attachment: {
|
||||
// The snapshot and function call actors, along with the thumbnails
|
||||
// will be available as soon as recording finishes.
|
||||
actor: null,
|
||||
calls: null,
|
||||
thumbnails: null,
|
||||
screenshot: null,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the last snapshot added, in the event no requestAnimationFrame loop was found.
|
||||
*/
|
||||
removeLastSnapshot: function() {
|
||||
this.removeAt(this.itemCount - 1);
|
||||
// If this is the only item, revert back to the empty notice
|
||||
if (this.itemCount === 0) {
|
||||
$("#empty-notice").hidden = false;
|
||||
$("#waiting-notice").hidden = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Customizes a shapshot in this container.
|
||||
*
|
||||
* @param Item snapshotItem
|
||||
* An item inserted via `SnapshotsListView.addSnapshot`.
|
||||
* @param object snapshotActor
|
||||
* The frame snapshot actor received from the backend.
|
||||
* @param object snapshotOverview
|
||||
* Additional data about the snapshot received from the backend.
|
||||
*/
|
||||
customizeSnapshot: function(snapshotItem, snapshotActor, snapshotOverview) {
|
||||
// Make sure the function call actors are stored on the item,
|
||||
// to be used when populating the CallsListView.
|
||||
snapshotItem.attachment.actor = snapshotActor;
|
||||
const functionCalls = snapshotItem.attachment.calls = snapshotOverview.calls;
|
||||
const thumbnails = snapshotItem.attachment.thumbnails = snapshotOverview.thumbnails;
|
||||
const screenshot = snapshotItem.attachment.screenshot = snapshotOverview.screenshot;
|
||||
|
||||
const lastThumbnail = thumbnails[thumbnails.length - 1];
|
||||
const { width, height, flipped, pixels } = lastThumbnail;
|
||||
|
||||
const thumbnailNode = $(".snapshot-item-thumbnail", snapshotItem.target);
|
||||
thumbnailNode.setAttribute("flipped", flipped);
|
||||
drawImage(thumbnailNode, width, height, pixels, { centered: true });
|
||||
|
||||
const callsNode = $(".snapshot-item-calls", snapshotItem.target);
|
||||
const drawCalls = functionCalls.filter(e => CanvasFront.DRAW_CALLS.has(e.name));
|
||||
|
||||
const drawCallsStr = PluralForm.get(drawCalls.length,
|
||||
L10N.getStr("snapshotsList.drawCallsLabel"));
|
||||
const funcCallsStr = PluralForm.get(functionCalls.length,
|
||||
L10N.getStr("snapshotsList.functionCallsLabel"));
|
||||
|
||||
callsNode.setAttribute("value",
|
||||
drawCallsStr.replace("#1", drawCalls.length) + ", " +
|
||||
funcCallsStr.replace("#1", functionCalls.length));
|
||||
|
||||
const saveNode = $(".snapshot-item-save", snapshotItem.target);
|
||||
saveNode.setAttribute("disabled", !!snapshotItem.isLoadedFromDisk);
|
||||
saveNode.setAttribute("value", snapshotItem.isLoadedFromDisk
|
||||
? L10N.getStr("snapshotsList.loadedLabel")
|
||||
: L10N.getStr("snapshotsList.saveLabel"));
|
||||
|
||||
// Make sure there's always a selected item available.
|
||||
if (!this.selectedItem) {
|
||||
this.selectedIndex = 0;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The select listener for this container.
|
||||
*/
|
||||
_onSelect: function({ detail: snapshotItem }) {
|
||||
// Check to ensure the attachment has an actor, like
|
||||
// an in-progress recording.
|
||||
if (!snapshotItem || !snapshotItem.attachment.actor) {
|
||||
return;
|
||||
}
|
||||
const { calls, thumbnails, screenshot } = snapshotItem.attachment;
|
||||
|
||||
$("#reload-notice").hidden = true;
|
||||
$("#empty-notice").hidden = true;
|
||||
$("#waiting-notice").hidden = false;
|
||||
|
||||
$("#debugging-pane-contents").hidden = true;
|
||||
$("#screenshot-container").hidden = true;
|
||||
$("#snapshot-filmstrip").hidden = true;
|
||||
|
||||
(async function() {
|
||||
// Wait for a few milliseconds between presenting the function calls,
|
||||
// screenshot and thumbnails, to allow each component being
|
||||
// sequentially drawn. This gives the illusion of snappiness.
|
||||
|
||||
await DevToolsUtils.waitForTime(SNAPSHOT_DATA_DISPLAY_DELAY);
|
||||
CallsListView.showCalls(calls);
|
||||
$("#debugging-pane-contents").hidden = false;
|
||||
$("#waiting-notice").hidden = true;
|
||||
|
||||
await DevToolsUtils.waitForTime(SNAPSHOT_DATA_DISPLAY_DELAY);
|
||||
CallsListView.showThumbnails(thumbnails);
|
||||
$("#snapshot-filmstrip").hidden = false;
|
||||
|
||||
await DevToolsUtils.waitForTime(SNAPSHOT_DATA_DISPLAY_DELAY);
|
||||
CallsListView.showScreenshot(screenshot);
|
||||
$("#screenshot-container").hidden = false;
|
||||
|
||||
window.emit(EVENTS.SNAPSHOT_RECORDING_SELECTED);
|
||||
})();
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "clear" button in this container.
|
||||
*/
|
||||
_onClearButtonClick: function() {
|
||||
(async function() {
|
||||
SnapshotsListView.empty();
|
||||
CallsListView.empty();
|
||||
|
||||
$("#reload-notice").hidden = true;
|
||||
$("#empty-notice").hidden = true;
|
||||
$("#waiting-notice").hidden = true;
|
||||
|
||||
if (await gFront.isInitialized()) {
|
||||
$("#empty-notice").hidden = false;
|
||||
} else {
|
||||
$("#reload-notice").hidden = false;
|
||||
}
|
||||
|
||||
$("#debugging-pane-contents").hidden = true;
|
||||
$("#screenshot-container").hidden = true;
|
||||
$("#snapshot-filmstrip").hidden = true;
|
||||
|
||||
window.emit(EVENTS.SNAPSHOTS_LIST_CLEARED);
|
||||
})();
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "record" button in this container.
|
||||
*/
|
||||
_onRecordButtonClick: function() {
|
||||
this._disableRecordButton();
|
||||
|
||||
if (this._recording) {
|
||||
this._stopRecordingAnimation();
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert a "dummy" snapshot item in the view, to hint that recording
|
||||
// has now started. However, wait for a few milliseconds before actually
|
||||
// starting the recording, since that might block rendering and prevent
|
||||
// the dummy snapshot item from being drawn.
|
||||
this.addSnapshot();
|
||||
|
||||
// If this is the first item, immediately show the "Loading…" notice.
|
||||
if (this.itemCount == 1) {
|
||||
$("#empty-notice").hidden = true;
|
||||
$("#waiting-notice").hidden = false;
|
||||
}
|
||||
|
||||
this._recordAnimation();
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes the record button able to be clicked again.
|
||||
*/
|
||||
_enableRecordButton: function() {
|
||||
$("#record-snapshot").removeAttribute("disabled");
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes the record button unable to be clicked.
|
||||
*/
|
||||
_disableRecordButton: function() {
|
||||
$("#record-snapshot").setAttribute("disabled", true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Begins recording an animation.
|
||||
*/
|
||||
async _recordAnimation() {
|
||||
if (this._recording) {
|
||||
return;
|
||||
}
|
||||
this._recording = true;
|
||||
$("#record-snapshot").setAttribute("checked", "true");
|
||||
|
||||
setNamedTimeout("canvas-actor-recording", CANVAS_ACTOR_RECORDING_ATTEMPT, this._stopRecordingAnimation);
|
||||
|
||||
await DevToolsUtils.waitForTime(SNAPSHOT_START_RECORDING_DELAY);
|
||||
window.emit(EVENTS.SNAPSHOT_RECORDING_STARTED);
|
||||
|
||||
gFront.recordAnimationFrame().then(snapshot => {
|
||||
if (snapshot) {
|
||||
this._onRecordSuccess(snapshot);
|
||||
} else {
|
||||
this._onRecordFailure();
|
||||
}
|
||||
});
|
||||
|
||||
// Wait another delay before reenabling the button to stop the recording
|
||||
// if a recording is not found.
|
||||
await DevToolsUtils.waitForTime(SNAPSHOT_START_RECORDING_DELAY);
|
||||
this._enableRecordButton();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops recording animation. Called when a click on the stopwatch occurs during a recording,
|
||||
* or if a recording times out.
|
||||
*/
|
||||
async _stopRecordingAnimation() {
|
||||
clearNamedTimeout("canvas-actor-recording");
|
||||
const actorCanStop = await gTarget.actorHasMethod("canvas", "stopRecordingAnimationFrame");
|
||||
|
||||
if (actorCanStop) {
|
||||
await gFront.stopRecordingAnimationFrame();
|
||||
} else {
|
||||
// If actor does not have the method to stop recording (Fx39+),
|
||||
// manually call the record failure method. This will call a connection failure
|
||||
// on disconnect as a result of `gFront.recordAnimationFrame()` never resolving,
|
||||
// but this is better than it hanging when there is no requestAnimationFrame anyway.
|
||||
this._onRecordFailure();
|
||||
}
|
||||
|
||||
this._recording = false;
|
||||
$("#record-snapshot").removeAttribute("checked");
|
||||
this._enableRecordButton();
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves from the front's recordAnimationFrame to setup the interface with the screenshots.
|
||||
*/
|
||||
async _onRecordSuccess(snapshotActor) {
|
||||
// Clear bail-out case if frame found in CANVAS_ACTOR_RECORDING_ATTEMPT milliseconds
|
||||
clearNamedTimeout("canvas-actor-recording");
|
||||
const snapshotItem = this.getItemAtIndex(this.itemCount - 1);
|
||||
const snapshotOverview = await snapshotActor.getOverview();
|
||||
this.customizeSnapshot(snapshotItem, snapshotActor, snapshotOverview);
|
||||
|
||||
this._recording = false;
|
||||
$("#record-snapshot").removeAttribute("checked");
|
||||
|
||||
window.emit(EVENTS.SNAPSHOT_RECORDING_COMPLETED);
|
||||
window.emit(EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called as a reject from the front's recordAnimationFrame.
|
||||
*/
|
||||
_onRecordFailure: function() {
|
||||
clearNamedTimeout("canvas-actor-recording");
|
||||
showNotification(gToolbox, "canvas-debugger-timeout", L10N.getStr("recordingTimeoutFailure"));
|
||||
window.emit(EVENTS.SNAPSHOT_RECORDING_CANCELLED);
|
||||
window.emit(EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
this.removeLastSnapshot();
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "import" button in this container.
|
||||
*/
|
||||
_onImportButtonClick: function() {
|
||||
const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, L10N.getStr("snapshotsList.saveDialogTitle"), Ci.nsIFilePicker.modeOpen);
|
||||
fp.appendFilter(L10N.getStr("snapshotsList.saveDialogJSONFilter"), "*.json");
|
||||
fp.appendFilter(L10N.getStr("snapshotsList.saveDialogAllFilter"), "*.*");
|
||||
|
||||
fp.open(rv => {
|
||||
if (rv != Ci.nsIFilePicker.returnOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = NetUtil.newChannel({
|
||||
uri: NetUtil.newURI(fp.file), loadUsingSystemPrincipal: true});
|
||||
channel.contentType = "text/plain";
|
||||
|
||||
NetUtil.asyncFetch(channel, (inputStream, status) => {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
console.error("Could not import recorded animation frame snapshot file.");
|
||||
return;
|
||||
}
|
||||
var data;
|
||||
try {
|
||||
const string = NetUtil.readInputStreamToString(inputStream, inputStream.available());
|
||||
data = JSON.parse(string);
|
||||
} catch (e) {
|
||||
console.error("Could not read animation frame snapshot file.");
|
||||
return;
|
||||
}
|
||||
if (data.fileType != CALLS_LIST_SERIALIZER_IDENTIFIER) {
|
||||
console.error("Unrecognized animation frame snapshot file.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add a `isLoadedFromDisk` flag on everything to avoid sending invalid
|
||||
// requests to the backend, since we're not dealing with actors anymore.
|
||||
const snapshotItem = this.addSnapshot();
|
||||
snapshotItem.isLoadedFromDisk = true;
|
||||
data.calls.forEach(e => e.isLoadedFromDisk = true);
|
||||
|
||||
this.customizeSnapshot(snapshotItem, data.calls, data);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The click listener for the "save" button of each item in this container.
|
||||
*/
|
||||
_onSaveButtonClick: function(e) {
|
||||
const snapshotItem = this.getItemForElement(e.target);
|
||||
|
||||
const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, L10N.getStr("snapshotsList.saveDialogTitle"), Ci.nsIFilePicker.modeSave);
|
||||
fp.appendFilter(L10N.getStr("snapshotsList.saveDialogJSONFilter"), "*.json");
|
||||
fp.appendFilter(L10N.getStr("snapshotsList.saveDialogAllFilter"), "*.*");
|
||||
fp.defaultString = "snapshot.json";
|
||||
|
||||
// Start serializing all the function call actors for the specified snapshot,
|
||||
// while the nsIFilePicker dialog is being opened. Snappy.
|
||||
const serialized = (async function() {
|
||||
const data = {
|
||||
fileType: CALLS_LIST_SERIALIZER_IDENTIFIER,
|
||||
version: CALLS_LIST_SERIALIZER_VERSION,
|
||||
calls: [],
|
||||
thumbnails: [],
|
||||
screenshot: null,
|
||||
};
|
||||
const functionCalls = snapshotItem.attachment.calls;
|
||||
const thumbnails = snapshotItem.attachment.thumbnails;
|
||||
const screenshot = snapshotItem.attachment.screenshot;
|
||||
|
||||
// Prepare all the function calls for serialization.
|
||||
await yieldingEach(functionCalls, (call, i) => {
|
||||
const { type, name, file, line, timestamp, argsPreview, callerPreview } = call;
|
||||
return call.getDetails().then(({ stack }) => {
|
||||
data.calls[i] = {
|
||||
type: type,
|
||||
name: name,
|
||||
file: file,
|
||||
line: line,
|
||||
stack: stack,
|
||||
timestamp: timestamp,
|
||||
argsPreview: argsPreview,
|
||||
callerPreview: callerPreview,
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Prepare all the thumbnails for serialization.
|
||||
await yieldingEach(thumbnails, (thumbnail, i) => {
|
||||
const { index, width, height, flipped, pixels } = thumbnail;
|
||||
data.thumbnails.push({ index, width, height, flipped, pixels });
|
||||
});
|
||||
|
||||
// Prepare the screenshot for serialization.
|
||||
const { index, width, height, flipped, pixels } = screenshot;
|
||||
data.screenshot = { index, width, height, flipped, pixels };
|
||||
|
||||
const string = JSON.stringify(data);
|
||||
const converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
|
||||
converter.charset = "UTF-8";
|
||||
return converter.convertToInputStream(string);
|
||||
})();
|
||||
|
||||
// Open the nsIFilePicker and wait for the function call actors to finish
|
||||
// being serialized, in order to save the generated JSON data to disk.
|
||||
fp.open({ done: result => {
|
||||
if (result == Ci.nsIFilePicker.returnCancel) {
|
||||
return;
|
||||
}
|
||||
const footer = $(".snapshot-item-footer", snapshotItem.target);
|
||||
const save = $(".snapshot-item-save", snapshotItem.target);
|
||||
|
||||
// Show a throbber and a "Saving…" label if serializing isn't immediate.
|
||||
setNamedTimeout("call-list-save", CALLS_LIST_SLOW_SAVE_DELAY, () => {
|
||||
footer.classList.add("devtools-throbber");
|
||||
save.setAttribute("disabled", "true");
|
||||
save.setAttribute("value", L10N.getStr("snapshotsList.savingLabel"));
|
||||
});
|
||||
|
||||
serialized.then(inputStream => {
|
||||
const outputStream = FileUtils.openSafeFileOutputStream(fp.file);
|
||||
|
||||
NetUtil.asyncCopy(inputStream, outputStream, status => {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
console.error("Could not save recorded animation frame snapshot file.");
|
||||
}
|
||||
clearNamedTimeout("call-list-save");
|
||||
footer.classList.remove("devtools-throbber");
|
||||
save.removeAttribute("disabled");
|
||||
save.setAttribute("value", L10N.getStr("snapshotsList.saveLabel"));
|
||||
});
|
||||
});
|
||||
}});
|
||||
},
|
||||
});
|
||||
|
||||
function showNotification(toolbox, name, message) {
|
||||
const notificationBox = toolbox.getNotificationBox();
|
||||
const notification = notificationBox.getNotificationWithValue(name);
|
||||
if (!notification) {
|
||||
notificationBox.appendNotification(message, name, "", notificationBox.PRIORITY_WARNING_HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like Array.prototype.forEach, but doesn't cause jankiness when iterating over
|
||||
* very large arrays by yielding to the browser and continuing execution on the
|
||||
* next tick.
|
||||
*
|
||||
* @param Array array
|
||||
* The array being iterated over.
|
||||
* @param Function fn
|
||||
* The function called on each item in the array. If a promise is
|
||||
* returned by this function, iterating over the array will be paused
|
||||
* until the respective promise is resolved.
|
||||
* @returns Promise
|
||||
* A promise that is resolved once the whole array has been iterated
|
||||
* over, and all promises returned by the fn callback are resolved.
|
||||
*/
|
||||
function yieldingEach(array, fn) {
|
||||
const deferred = defer();
|
||||
|
||||
let i = 0;
|
||||
const len = array.length;
|
||||
const outstanding = [deferred.promise];
|
||||
|
||||
(function loop() {
|
||||
const start = Date.now();
|
||||
|
||||
while (i < len) {
|
||||
// Don't block the main thread for longer than 16 ms at a time. To
|
||||
// maintain 60fps, you have to render every frame in at least 16ms; we
|
||||
// aren't including time spent in non-JS here, but this is Good
|
||||
// Enough(tm).
|
||||
if (Date.now() - start > 16) {
|
||||
DevToolsUtils.executeSoon(loop);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
outstanding.push(fn(array[i], i++));
|
||||
} catch (e) {
|
||||
deferred.reject(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
deferred.resolve();
|
||||
}());
|
||||
|
||||
return promise.all(outstanding);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../.eslintrc.mochitests.js"
|
||||
};
|
|
@ -1,69 +0,0 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
call-watcher-actor.js
|
||||
call-watcher-front.js
|
||||
call-watcher-spec.js
|
||||
doc_raf-begin.html
|
||||
doc_settimeout.html
|
||||
doc_no-canvas.html
|
||||
doc_raf-no-canvas.html
|
||||
doc_simple-canvas.html
|
||||
doc_simple-canvas-bitmasks.html
|
||||
doc_simple-canvas-deep-stack.html
|
||||
doc_simple-canvas-transparent.html
|
||||
doc_webgl-bindings.html
|
||||
doc_webgl-enum.html
|
||||
doc_webgl-drawArrays.html
|
||||
doc_webgl-drawElements.html
|
||||
head.js
|
||||
!/devtools/client/shared/test/frame-script-utils.js
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
!/devtools/client/debugger/new/test/mochitest/helpers/context.js
|
||||
!/devtools/client/shared/test/telemetry-test-helpers.js
|
||||
|
||||
[browser_canvas-actor-test-01.js]
|
||||
[browser_canvas-actor-test-02.js]
|
||||
[browser_canvas-actor-test-03.js]
|
||||
[browser_canvas-actor-test-04.js]
|
||||
[browser_canvas-actor-test-05.js]
|
||||
[browser_canvas-actor-test-06.js]
|
||||
[browser_canvas-actor-test-07.js]
|
||||
[browser_canvas-actor-test-08.js]
|
||||
[browser_canvas-actor-test-09.js]
|
||||
subsuite = gpu
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_canvas-actor-test-10.js]
|
||||
subsuite = gpu
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_canvas-actor-test-11.js]
|
||||
subsuite = gpu
|
||||
skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
|
||||
[browser_canvas-actor-test-12.js]
|
||||
[browser_canvas-frontend-call-highlight.js]
|
||||
[browser_canvas-frontend-call-list.js]
|
||||
[browser_canvas-frontend-call-search.js]
|
||||
[browser_canvas-frontend-call-stack-01.js]
|
||||
[browser_canvas-frontend-call-stack-02.js]
|
||||
[browser_canvas-frontend-call-stack-03.js]
|
||||
[browser_canvas-frontend-clear.js]
|
||||
[browser_canvas-frontend-img-screenshots.js]
|
||||
[browser_canvas-frontend-img-thumbnails-01.js]
|
||||
[browser_canvas-frontend-img-thumbnails-02.js]
|
||||
[browser_canvas-frontend-open.js]
|
||||
[browser_canvas-frontend-record-01.js]
|
||||
[browser_canvas-frontend-record-02.js]
|
||||
[browser_canvas-frontend-record-03.js]
|
||||
[browser_canvas-frontend-record-04.js]
|
||||
[browser_canvas-frontend-reload-01.js]
|
||||
[browser_canvas-frontend-reload-02.js]
|
||||
[browser_canvas-frontend-snapshot-select-01.js]
|
||||
[browser_canvas-frontend-snapshot-select-02.js]
|
||||
[browser_canvas-frontend-stepping.js]
|
||||
[browser_canvas-frontend-stop-01.js]
|
||||
[browser_canvas-frontend-stop-02.js]
|
||||
[browser_canvas-frontend-stop-03.js]
|
||||
[browser_profiling-canvas.js]
|
||||
[browser_profiling-webgl.js]
|
||||
subsuite = gpu
|
|
@ -1,17 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the canvas debugger leaks on initialization and sudden destruction.
|
||||
* You can also use this initialization format as a template for other tests.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCallWatcherBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
ok(target, "Should have a target available.");
|
||||
ok(front, "Should have a protocol front available.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if functions calls are recorded and stored for a canvas context,
|
||||
* and that their stack is successfully retrieved.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCallWatcherBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({
|
||||
tracedGlobals: ["CanvasRenderingContext2D", "WebGLRenderingContext"],
|
||||
startRecording: true,
|
||||
performReload: true,
|
||||
storeCalls: true,
|
||||
});
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
// Allow the content to execute some functions.
|
||||
await waitForTick();
|
||||
|
||||
const functionCalls = await front.pauseRecording();
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after reloading.");
|
||||
ok(functionCalls.length > 0,
|
||||
"There's at least one function call actor available.");
|
||||
|
||||
is(functionCalls[0].type, METHOD_FUNCTION,
|
||||
"The called function is correctly identified as a method.");
|
||||
is(functionCalls[0].name, "clearRect",
|
||||
"The called function's name is correct.");
|
||||
is(functionCalls[0].file, SIMPLE_CANVAS_URL,
|
||||
"The called function's file is correct.");
|
||||
is(functionCalls[0].line, 25,
|
||||
"The called function's line is correct.");
|
||||
|
||||
is(functionCalls[0].callerPreview, "Object",
|
||||
"The called function's caller preview is correct.");
|
||||
is(functionCalls[0].argsPreview, "0, 0, 128, 128",
|
||||
"The called function's args preview is correct.");
|
||||
|
||||
const details = await functionCalls[1].getDetails();
|
||||
ok(details,
|
||||
"The first called function has some details available.");
|
||||
|
||||
is(details.stack.length, 3,
|
||||
"The called function's stack depth is correct.");
|
||||
|
||||
is(details.stack[0].name, "fillStyle",
|
||||
"The called function's stack is correct (1.1).");
|
||||
is(details.stack[0].file, SIMPLE_CANVAS_URL,
|
||||
"The called function's stack is correct (1.2).");
|
||||
is(details.stack[0].line, 20,
|
||||
"The called function's stack is correct (1.3).");
|
||||
|
||||
is(details.stack[1].name, "drawRect",
|
||||
"The called function's stack is correct (2.1).");
|
||||
is(details.stack[1].file, SIMPLE_CANVAS_URL,
|
||||
"The called function's stack is correct (2.2).");
|
||||
is(details.stack[1].line, 26,
|
||||
"The called function's stack is correct (2.3).");
|
||||
|
||||
is(details.stack[2].name, "drawScene",
|
||||
"The called function's stack is correct (3.1).");
|
||||
is(details.stack[2].file, SIMPLE_CANVAS_URL,
|
||||
"The called function's stack is correct (3.2).");
|
||||
is(details.stack[2].line, 33,
|
||||
"The called function's stack is correct (3.3).");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if functions inside a single animation frame are recorded and stored
|
||||
* for a canvas context.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
ok(snapshotActor,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
const functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
is(functionCalls.length, 8,
|
||||
"The number of function call actors is correct.");
|
||||
|
||||
is(functionCalls[0].type, METHOD_FUNCTION,
|
||||
"The first called function is correctly identified as a method.");
|
||||
is(functionCalls[0].name, "clearRect",
|
||||
"The first called function's name is correct.");
|
||||
is(functionCalls[0].file, SIMPLE_CANVAS_URL,
|
||||
"The first called function's file is correct.");
|
||||
is(functionCalls[0].line, 25,
|
||||
"The first called function's line is correct.");
|
||||
is(functionCalls[0].argsPreview, "0, 0, 128, 128",
|
||||
"The first called function's args preview is correct.");
|
||||
is(functionCalls[0].callerPreview, "Object",
|
||||
"The first called function's caller preview is correct.");
|
||||
|
||||
is(functionCalls[6].type, METHOD_FUNCTION,
|
||||
"The penultimate called function is correctly identified as a method.");
|
||||
is(functionCalls[6].name, "fillRect",
|
||||
"The penultimate called function's name is correct.");
|
||||
is(functionCalls[6].file, SIMPLE_CANVAS_URL,
|
||||
"The penultimate called function's file is correct.");
|
||||
is(functionCalls[6].line, 21,
|
||||
"The penultimate called function's line is correct.");
|
||||
is(functionCalls[6].argsPreview, "10, 10, 55, 50",
|
||||
"The penultimate called function's args preview is correct.");
|
||||
is(functionCalls[6].callerPreview, "Object",
|
||||
"The penultimate called function's caller preview is correct.");
|
||||
|
||||
is(functionCalls[7].type, METHOD_FUNCTION,
|
||||
"The last called function is correctly identified as a method.");
|
||||
is(functionCalls[7].name, "requestAnimationFrame",
|
||||
"The last called function's name is correct.");
|
||||
is(functionCalls[7].file, SIMPLE_CANVAS_URL,
|
||||
"The last called function's file is correct.");
|
||||
is(functionCalls[7].line, 30,
|
||||
"The last called function's line is correct.");
|
||||
ok(functionCalls[7].argsPreview.includes("Function"),
|
||||
"The last called function's args preview is correct.");
|
||||
is(functionCalls[7].callerPreview, "Object",
|
||||
"The last called function's caller preview is correct.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if draw calls inside a single animation frame generate and retrieve
|
||||
* the correct thumbnails.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
ok(animationOverview,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
const thumbnails = animationOverview.thumbnails;
|
||||
ok(thumbnails,
|
||||
"An array of thumbnails was sent after recording.");
|
||||
is(thumbnails.length, 4,
|
||||
"The number of thumbnails is correct.");
|
||||
|
||||
is(thumbnails[0].index, 0,
|
||||
"The first thumbnail's index is correct.");
|
||||
is(thumbnails[0].width, 50,
|
||||
"The first thumbnail's width is correct.");
|
||||
is(thumbnails[0].height, 50,
|
||||
"The first thumbnail's height is correct.");
|
||||
is(thumbnails[0].flipped, false,
|
||||
"The first thumbnail's flipped flag is correct.");
|
||||
is([].find.call(Uint32(thumbnails[0].pixels), e => e > 0), undefined,
|
||||
"The first thumbnail's pixels seem to be completely transparent.");
|
||||
|
||||
is(thumbnails[1].index, 2,
|
||||
"The second thumbnail's index is correct.");
|
||||
is(thumbnails[1].width, 50,
|
||||
"The second thumbnail's width is correct.");
|
||||
is(thumbnails[1].height, 50,
|
||||
"The second thumbnail's height is correct.");
|
||||
is(thumbnails[1].flipped, false,
|
||||
"The second thumbnail's flipped flag is correct.");
|
||||
is([].find.call(Uint32(thumbnails[1].pixels), e => e > 0), 4290822336,
|
||||
"The second thumbnail's pixels seem to not be completely transparent.");
|
||||
|
||||
is(thumbnails[2].index, 4,
|
||||
"The third thumbnail's index is correct.");
|
||||
is(thumbnails[2].width, 50,
|
||||
"The third thumbnail's width is correct.");
|
||||
is(thumbnails[2].height, 50,
|
||||
"The third thumbnail's height is correct.");
|
||||
is(thumbnails[2].flipped, false,
|
||||
"The third thumbnail's flipped flag is correct.");
|
||||
is([].find.call(Uint32(thumbnails[2].pixels), e => e > 0), 4290822336,
|
||||
"The third thumbnail's pixels seem to not be completely transparent.");
|
||||
|
||||
is(thumbnails[3].index, 6,
|
||||
"The fourth thumbnail's index is correct.");
|
||||
is(thumbnails[3].width, 50,
|
||||
"The fourth thumbnail's width is correct.");
|
||||
is(thumbnails[3].height, 50,
|
||||
"The fourth thumbnail's height is correct.");
|
||||
is(thumbnails[3].flipped, false,
|
||||
"The fourth thumbnail's flipped flag is correct.");
|
||||
is([].find.call(Uint32(thumbnails[3].pixels), e => e > 0), 4290822336,
|
||||
"The fourth thumbnail's pixels seem to not be completely transparent.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function Uint32(src) {
|
||||
const charView = new Uint8Array(src);
|
||||
return new Uint32Array(charView.buffer);
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if draw calls inside a single animation frame generate and retrieve
|
||||
* the correct "end result" screenshot.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
ok(snapshotActor,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
const screenshot = animationOverview.screenshot;
|
||||
ok(screenshot,
|
||||
"A screenshot was sent after recording.");
|
||||
|
||||
is(screenshot.index, 6,
|
||||
"The screenshot's index is correct.");
|
||||
is(screenshot.width, 128,
|
||||
"The screenshot's width is correct.");
|
||||
is(screenshot.height, 128,
|
||||
"The screenshot's height is correct.");
|
||||
is(screenshot.flipped, false,
|
||||
"The screenshot's flipped flag is correct.");
|
||||
is([].find.call(Uint32(screenshot.pixels), e => e > 0), 4290822336,
|
||||
"The screenshot's pixels seem to not be completely transparent.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function Uint32(src) {
|
||||
const charView = new Uint8Array(src);
|
||||
return new Uint32Array(charView.buffer);
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if screenshots for arbitrary draw calls are generated properly.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_CANVAS_TRANSPARENT_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
|
||||
const functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
is(functionCalls.length, 8,
|
||||
"The number of function call actors is correct.");
|
||||
|
||||
is(functionCalls[0].name, "clearRect",
|
||||
"The first called function's name is correct.");
|
||||
is(functionCalls[2].name, "fillRect",
|
||||
"The second called function's name is correct.");
|
||||
is(functionCalls[4].name, "fillRect",
|
||||
"The third called function's name is correct.");
|
||||
is(functionCalls[6].name, "fillRect",
|
||||
"The fourth called function's name is correct.");
|
||||
|
||||
const firstDrawCallScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[0]);
|
||||
const secondDrawCallScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[2]);
|
||||
const thirdDrawCallScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[4]);
|
||||
const fourthDrawCallScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[6]);
|
||||
|
||||
ok(firstDrawCallScreenshot,
|
||||
"The first draw call has a screenshot attached.");
|
||||
is(firstDrawCallScreenshot.index, 0,
|
||||
"The first draw call has the correct screenshot index.");
|
||||
is(firstDrawCallScreenshot.width, 128,
|
||||
"The first draw call has the correct screenshot width.");
|
||||
is(firstDrawCallScreenshot.height, 128,
|
||||
"The first draw call has the correct screenshot height.");
|
||||
is([].find.call(Uint32(firstDrawCallScreenshot.pixels), e => e > 0), undefined,
|
||||
"The first draw call's screenshot's pixels seems to be completely transparent.");
|
||||
|
||||
ok(secondDrawCallScreenshot,
|
||||
"The second draw call has a screenshot attached.");
|
||||
is(secondDrawCallScreenshot.index, 2,
|
||||
"The second draw call has the correct screenshot index.");
|
||||
is(secondDrawCallScreenshot.width, 128,
|
||||
"The second draw call has the correct screenshot width.");
|
||||
is(secondDrawCallScreenshot.height, 128,
|
||||
"The second draw call has the correct screenshot height.");
|
||||
is([].find.call(Uint32(firstDrawCallScreenshot.pixels), e => e > 0), undefined,
|
||||
"The second draw call's screenshot's pixels seems to be completely transparent.");
|
||||
|
||||
ok(thirdDrawCallScreenshot,
|
||||
"The third draw call has a screenshot attached.");
|
||||
is(thirdDrawCallScreenshot.index, 4,
|
||||
"The third draw call has the correct screenshot index.");
|
||||
is(thirdDrawCallScreenshot.width, 128,
|
||||
"The third draw call has the correct screenshot width.");
|
||||
is(thirdDrawCallScreenshot.height, 128,
|
||||
"The third draw call has the correct screenshot height.");
|
||||
is([].find.call(Uint32(thirdDrawCallScreenshot.pixels), e => e > 0), 2160001024,
|
||||
"The third draw call's screenshot's pixels seems to not be completely transparent.");
|
||||
|
||||
ok(fourthDrawCallScreenshot,
|
||||
"The fourth draw call has a screenshot attached.");
|
||||
is(fourthDrawCallScreenshot.index, 6,
|
||||
"The fourth draw call has the correct screenshot index.");
|
||||
is(fourthDrawCallScreenshot.width, 128,
|
||||
"The fourth draw call has the correct screenshot width.");
|
||||
is(fourthDrawCallScreenshot.height, 128,
|
||||
"The fourth draw call has the correct screenshot height.");
|
||||
is([].find.call(Uint32(fourthDrawCallScreenshot.pixels), e => e > 0), 2147483839,
|
||||
"The fourth draw call's screenshot's pixels seems to not be completely transparent.");
|
||||
|
||||
isnot(firstDrawCallScreenshot.pixels, secondDrawCallScreenshot.pixels,
|
||||
"The screenshots taken on consecutive draw calls are different (1).");
|
||||
isnot(secondDrawCallScreenshot.pixels, thirdDrawCallScreenshot.pixels,
|
||||
"The screenshots taken on consecutive draw calls are different (2).");
|
||||
isnot(thirdDrawCallScreenshot.pixels, fourthDrawCallScreenshot.pixels,
|
||||
"The screenshots taken on consecutive draw calls are different (3).");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function Uint32(src) {
|
||||
const charView = new Uint8Array(src);
|
||||
return new Uint32Array(charView.buffer);
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if screenshots for non-draw calls can still be retrieved properly,
|
||||
* by deferring the the most recent previous draw-call.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
|
||||
const functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
is(functionCalls.length, 8,
|
||||
"The number of function call actors is correct.");
|
||||
|
||||
const firstNonDrawCall = await functionCalls[1].getDetails();
|
||||
const secondNonDrawCall = await functionCalls[3].getDetails();
|
||||
const lastNonDrawCall = await functionCalls[7].getDetails();
|
||||
|
||||
is(firstNonDrawCall.name, "fillStyle",
|
||||
"The first non-draw function's name is correct.");
|
||||
is(secondNonDrawCall.name, "fillStyle",
|
||||
"The second non-draw function's name is correct.");
|
||||
is(lastNonDrawCall.name, "requestAnimationFrame",
|
||||
"The last non-draw function's name is correct.");
|
||||
|
||||
const firstScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[1]);
|
||||
const secondScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[3]);
|
||||
const lastScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[7]);
|
||||
|
||||
ok(firstScreenshot,
|
||||
"A screenshot was successfully retrieved for the first non-draw function.");
|
||||
ok(secondScreenshot,
|
||||
"A screenshot was successfully retrieved for the second non-draw function.");
|
||||
ok(lastScreenshot,
|
||||
"A screenshot was successfully retrieved for the last non-draw function.");
|
||||
|
||||
const firstActualScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[0]);
|
||||
ok(sameArray(firstScreenshot.pixels, firstActualScreenshot.pixels),
|
||||
"The screenshot for the first non-draw function is correct.");
|
||||
is(firstScreenshot.width, 128,
|
||||
"The screenshot for the first non-draw function has the correct width.");
|
||||
is(firstScreenshot.height, 128,
|
||||
"The screenshot for the first non-draw function has the correct height.");
|
||||
|
||||
const secondActualScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[2]);
|
||||
ok(sameArray(secondScreenshot.pixels, secondActualScreenshot.pixels),
|
||||
"The screenshot for the second non-draw function is correct.");
|
||||
is(secondScreenshot.width, 128,
|
||||
"The screenshot for the second non-draw function has the correct width.");
|
||||
is(secondScreenshot.height, 128,
|
||||
"The screenshot for the second non-draw function has the correct height.");
|
||||
|
||||
const lastActualScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[6]);
|
||||
ok(sameArray(lastScreenshot.pixels, lastActualScreenshot.pixels),
|
||||
"The screenshot for the last non-draw function is correct.");
|
||||
is(lastScreenshot.width, 128,
|
||||
"The screenshot for the last non-draw function has the correct width.");
|
||||
is(lastScreenshot.height, 128,
|
||||
"The screenshot for the last non-draw function has the correct height.");
|
||||
|
||||
ok(!sameArray(firstScreenshot.pixels, secondScreenshot.pixels),
|
||||
"The screenshots taken on consecutive draw calls are different (1).");
|
||||
ok(!sameArray(secondScreenshot.pixels, lastScreenshot.pixels),
|
||||
"The screenshots taken on consecutive draw calls are different (2).");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function sameArray(a, b) {
|
||||
if (a.length != b.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that integers used in arguments are not cast to their constant, enum value
|
||||
* forms if the method's signature does not expect an enum. Bug 999687.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_BITMASKS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
const functionCalls = animationOverview.calls;
|
||||
|
||||
is(functionCalls[0].name, "clearRect",
|
||||
"The first called function's name is correct.");
|
||||
is(functionCalls[0].argsPreview, "0, 0, 4, 4",
|
||||
"The first called function's args preview is not cast to enums.");
|
||||
|
||||
is(functionCalls[2].name, "fillRect",
|
||||
"The fillRect called function's name is correct.");
|
||||
is(functionCalls[2].argsPreview, "0, 0, 1, 1",
|
||||
"The fillRect called function's args preview is not casted to enums.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that integers used in arguments are not cast to their constant, enum value
|
||||
* forms if the method's signature does not expect an enum. Bug 999687.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(WEBGL_ENUM_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
const functionCalls = animationOverview.calls;
|
||||
|
||||
is(functionCalls[0].name, "clear",
|
||||
"The function's name is correct.");
|
||||
is(functionCalls[0].argsPreview, "DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT",
|
||||
"The bits passed into `gl.clear` have been cast to their enum values.");
|
||||
|
||||
is(functionCalls[1].name, "bindTexture",
|
||||
"The function's name is correct.");
|
||||
is(functionCalls[1].argsPreview, "TEXTURE_2D, null",
|
||||
"The bits passed into `gl.bindTexture` have been cast to their enum values.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the correct framebuffer, renderbuffer and textures are re-bound
|
||||
* after generating screenshots using the actor.
|
||||
*/
|
||||
|
||||
var { CanvasFront } = require("devtools/shared/fronts/canvas");
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(WEBGL_BINDINGS_URL);
|
||||
loadFrameScriptUtils();
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
const functionCalls = animationOverview.calls;
|
||||
|
||||
const firstScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[0]);
|
||||
is(firstScreenshot.index, -1,
|
||||
"The first screenshot didn't encounter any draw call.");
|
||||
is(firstScreenshot.scaling, 0.25,
|
||||
"The first screenshot has the correct scaling.");
|
||||
is(firstScreenshot.width, CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT,
|
||||
"The first screenshot has the correct width.");
|
||||
is(firstScreenshot.height, CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT,
|
||||
"The first screenshot has the correct height.");
|
||||
is(firstScreenshot.flipped, true,
|
||||
"The first screenshot has the correct 'flipped' flag.");
|
||||
is(firstScreenshot.pixels.length, 0,
|
||||
"The first screenshot should be empty.");
|
||||
|
||||
is((await evalInDebuggee("gl.getParameter(gl.FRAMEBUFFER_BINDING) === customFramebuffer")),
|
||||
true,
|
||||
"The debuggee's gl context framebuffer wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.RENDERBUFFER_BINDING) === customRenderbuffer")),
|
||||
true,
|
||||
"The debuggee's gl context renderbuffer wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.TEXTURE_BINDING_2D) === customTexture")),
|
||||
true,
|
||||
"The debuggee's gl context texture binding wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[0]")),
|
||||
128,
|
||||
"The debuggee's gl context viewport's left coord. wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[1]")),
|
||||
256,
|
||||
"The debuggee's gl context viewport's left coord. wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[2]")),
|
||||
384,
|
||||
"The debuggee's gl context viewport's left coord. wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[3]")),
|
||||
512,
|
||||
"The debuggee's gl context viewport's left coord. wasn't changed.");
|
||||
|
||||
const secondScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[1]);
|
||||
is(secondScreenshot.index, 1,
|
||||
"The second screenshot has the correct index.");
|
||||
is(secondScreenshot.width, CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT,
|
||||
"The second screenshot has the correct width.");
|
||||
is(secondScreenshot.height, CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT,
|
||||
"The second screenshot has the correct height.");
|
||||
is(secondScreenshot.scaling, 0.25,
|
||||
"The second screenshot has the correct scaling.");
|
||||
is(secondScreenshot.flipped, true,
|
||||
"The second screenshot has the correct 'flipped' flag.");
|
||||
is(secondScreenshot.pixels.length, Math.pow(CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT, 2) * 4,
|
||||
"The second screenshot should not be empty.");
|
||||
is(secondScreenshot.pixels[0], 0,
|
||||
"The second screenshot has the correct red component.");
|
||||
is(secondScreenshot.pixels[1], 0,
|
||||
"The second screenshot has the correct green component.");
|
||||
is(secondScreenshot.pixels[2], 255,
|
||||
"The second screenshot has the correct blue component.");
|
||||
is(secondScreenshot.pixels[3], 255,
|
||||
"The second screenshot has the correct alpha component.");
|
||||
|
||||
is((await evalInDebuggee("gl.getParameter(gl.FRAMEBUFFER_BINDING) === customFramebuffer")),
|
||||
true,
|
||||
"The debuggee's gl context framebuffer still wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.RENDERBUFFER_BINDING) === customRenderbuffer")),
|
||||
true,
|
||||
"The debuggee's gl context renderbuffer still wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.TEXTURE_BINDING_2D) === customTexture")),
|
||||
true,
|
||||
"The debuggee's gl context texture binding still wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[0]")),
|
||||
128,
|
||||
"The debuggee's gl context viewport's left coord. still wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[1]")),
|
||||
256,
|
||||
"The debuggee's gl context viewport's left coord. still wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[2]")),
|
||||
384,
|
||||
"The debuggee's gl context viewport's left coord. still wasn't changed.");
|
||||
is((await evalInDebuggee("gl.getParameter(gl.VIEWPORT)[3]")),
|
||||
512,
|
||||
"The debuggee's gl context viewport's left coord. still wasn't changed.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that loops using setTimeout are recorded and stored
|
||||
* for a canvas context, and that the generated screenshots are correct.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(SET_TIMEOUT_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
ok(snapshotActor,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
const functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
is(functionCalls.length, 8,
|
||||
"The number of function call actors is correct.");
|
||||
|
||||
is(functionCalls[0].type, METHOD_FUNCTION,
|
||||
"The first called function is correctly identified as a method.");
|
||||
is(functionCalls[0].name, "clearRect",
|
||||
"The first called function's name is correct.");
|
||||
is(functionCalls[0].file, SET_TIMEOUT_URL,
|
||||
"The first called function's file is correct.");
|
||||
is(functionCalls[0].line, 25,
|
||||
"The first called function's line is correct.");
|
||||
is(functionCalls[0].argsPreview, "0, 0, 128, 128",
|
||||
"The first called function's args preview is correct.");
|
||||
is(functionCalls[0].callerPreview, "Object",
|
||||
"The first called function's caller preview is correct.");
|
||||
|
||||
is(functionCalls[6].type, METHOD_FUNCTION,
|
||||
"The penultimate called function is correctly identified as a method.");
|
||||
is(functionCalls[6].name, "fillRect",
|
||||
"The penultimate called function's name is correct.");
|
||||
is(functionCalls[6].file, SET_TIMEOUT_URL,
|
||||
"The penultimate called function's file is correct.");
|
||||
is(functionCalls[6].line, 21,
|
||||
"The penultimate called function's line is correct.");
|
||||
is(functionCalls[6].argsPreview, "10, 10, 55, 50",
|
||||
"The penultimate called function's args preview is correct.");
|
||||
is(functionCalls[6].callerPreview, "Object",
|
||||
"The penultimate called function's caller preview is correct.");
|
||||
|
||||
is(functionCalls[7].type, METHOD_FUNCTION,
|
||||
"The last called function is correctly identified as a method.");
|
||||
is(functionCalls[7].name, "setTimeout",
|
||||
"The last called function's name is correct.");
|
||||
is(functionCalls[7].file, SET_TIMEOUT_URL,
|
||||
"The last called function's file is correct.");
|
||||
is(functionCalls[7].line, 30,
|
||||
"The last called function's line is correct.");
|
||||
ok(functionCalls[7].argsPreview.includes("Function"),
|
||||
"The last called function's args preview is correct.");
|
||||
is(functionCalls[7].callerPreview, "Object",
|
||||
"The last called function's caller preview is correct.");
|
||||
|
||||
const firstNonDrawCall = await functionCalls[1].getDetails();
|
||||
const secondNonDrawCall = await functionCalls[3].getDetails();
|
||||
const lastNonDrawCall = await functionCalls[7].getDetails();
|
||||
|
||||
is(firstNonDrawCall.name, "fillStyle",
|
||||
"The first non-draw function's name is correct.");
|
||||
is(secondNonDrawCall.name, "fillStyle",
|
||||
"The second non-draw function's name is correct.");
|
||||
is(lastNonDrawCall.name, "setTimeout",
|
||||
"The last non-draw function's name is correct.");
|
||||
|
||||
const firstScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[1]);
|
||||
const secondScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[3]);
|
||||
const lastScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[7]);
|
||||
|
||||
ok(firstScreenshot,
|
||||
"A screenshot was successfully retrieved for the first non-draw function.");
|
||||
ok(secondScreenshot,
|
||||
"A screenshot was successfully retrieved for the second non-draw function.");
|
||||
ok(lastScreenshot,
|
||||
"A screenshot was successfully retrieved for the last non-draw function.");
|
||||
|
||||
const firstActualScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[0]);
|
||||
ok(sameArray(firstScreenshot.pixels, firstActualScreenshot.pixels),
|
||||
"The screenshot for the first non-draw function is correct.");
|
||||
is(firstScreenshot.width, 128,
|
||||
"The screenshot for the first non-draw function has the correct width.");
|
||||
is(firstScreenshot.height, 128,
|
||||
"The screenshot for the first non-draw function has the correct height.");
|
||||
|
||||
const secondActualScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[2]);
|
||||
ok(sameArray(secondScreenshot.pixels, secondActualScreenshot.pixels),
|
||||
"The screenshot for the second non-draw function is correct.");
|
||||
is(secondScreenshot.width, 128,
|
||||
"The screenshot for the second non-draw function has the correct width.");
|
||||
is(secondScreenshot.height, 128,
|
||||
"The screenshot for the second non-draw function has the correct height.");
|
||||
|
||||
const lastActualScreenshot = await snapshotActor.generateScreenshotFor(functionCalls[6]);
|
||||
ok(sameArray(lastScreenshot.pixels, lastActualScreenshot.pixels),
|
||||
"The screenshot for the last non-draw function is correct.");
|
||||
is(lastScreenshot.width, 128,
|
||||
"The screenshot for the last non-draw function has the correct width.");
|
||||
is(lastScreenshot.height, 128,
|
||||
"The screenshot for the last non-draw function has the correct height.");
|
||||
|
||||
ok(!sameArray(firstScreenshot.pixels, secondScreenshot.pixels),
|
||||
"The screenshots taken on consecutive draw calls are different (1).");
|
||||
ok(!sameArray(secondScreenshot.pixels, lastScreenshot.pixels),
|
||||
"The screenshots taken on consecutive draw calls are different (2).");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function sameArray(a, b) {
|
||||
if (a.length != b.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the recording can be disabled via stopRecordingAnimationFrame
|
||||
* in the event no rAF loop is found.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, front } = await initCanvasDebuggerBackend(NO_CANVAS_URL);
|
||||
loadFrameScriptUtils();
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const startRecording = front.recordAnimationFrame();
|
||||
await front.stopRecordingAnimationFrame();
|
||||
|
||||
ok(!(await startRecording),
|
||||
"recordAnimationFrame() does not return a SnapshotActor when cancelled.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if certain function calls are properly highlighted in the UI.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated]);
|
||||
|
||||
is(CallsListView.itemCount, 8,
|
||||
"All the function calls should now be displayed in the UI.");
|
||||
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(0).target).hasAttribute("draw-call"), true,
|
||||
"The first item's node should have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(1).target).hasAttribute("draw-call"), false,
|
||||
"The second item's node should not have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(2).target).hasAttribute("draw-call"), true,
|
||||
"The third item's node should have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(3).target).hasAttribute("draw-call"), false,
|
||||
"The fourth item's node should not have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(4).target).hasAttribute("draw-call"), true,
|
||||
"The fifth item's node should have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(5).target).hasAttribute("draw-call"), false,
|
||||
"The sixth item's node should not have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(6).target).hasAttribute("draw-call"), true,
|
||||
"The seventh item's node should have a draw-call attribute.");
|
||||
is($(".call-item-view", CallsListView.getItemAtIndex(7).target).hasAttribute("draw-call"), false,
|
||||
"The eigth item's node should not have a draw-call attribute.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if all the function calls associated with an animation frame snapshot
|
||||
* are properly displayed in the UI.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated]);
|
||||
|
||||
is(CallsListView.itemCount, 8,
|
||||
"All the function calls should now be displayed in the UI.");
|
||||
|
||||
testItem(CallsListView.getItemAtIndex(0),
|
||||
"1", "Object", "clearRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:25");
|
||||
|
||||
testItem(CallsListView.getItemAtIndex(1),
|
||||
"2", "Object", "fillStyle", " = rgb(192, 192, 192)", "doc_simple-canvas.html:20");
|
||||
testItem(CallsListView.getItemAtIndex(2),
|
||||
"3", "Object", "fillRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:21");
|
||||
|
||||
testItem(CallsListView.getItemAtIndex(3),
|
||||
"4", "Object", "fillStyle", " = rgba(0, 0, 192, 0.5)", "doc_simple-canvas.html:20");
|
||||
testItem(CallsListView.getItemAtIndex(4),
|
||||
"5", "Object", "fillRect", "(30, 30, 55, 50)", "doc_simple-canvas.html:21");
|
||||
|
||||
testItem(CallsListView.getItemAtIndex(5),
|
||||
"6", "Object", "fillStyle", " = rgba(192, 0, 0, 0.5)", "doc_simple-canvas.html:20");
|
||||
testItem(CallsListView.getItemAtIndex(6),
|
||||
"7", "Object", "fillRect", "(10, 10, 55, 50)", "doc_simple-canvas.html:21");
|
||||
|
||||
testItem(CallsListView.getItemAtIndex(7),
|
||||
"8", "", "requestAnimationFrame", "(Function)", "doc_simple-canvas.html:30");
|
||||
|
||||
function testItem(item, index, context, name, args, location) {
|
||||
const i = CallsListView.indexOfItem(item);
|
||||
is(i, index - 1,
|
||||
"The item at index " + index + " is correctly displayed in the UI.");
|
||||
|
||||
is($(".call-item-index", item.target).getAttribute("value"), index,
|
||||
"The item's gutter label has the correct text.");
|
||||
|
||||
if (context) {
|
||||
is($(".call-item-context", item.target).getAttribute("value"), context,
|
||||
"The item's context label has the correct text.");
|
||||
} else {
|
||||
is($(".call-item-context", item.target) + "", "[object XULTextElement]",
|
||||
"The item's context label should not be available.");
|
||||
}
|
||||
|
||||
is($(".call-item-name", item.target).getAttribute("value"), name,
|
||||
"The item's name label has the correct text.");
|
||||
is($(".call-item-args", item.target).getAttribute("value"), args,
|
||||
"The item's args label has the correct text.");
|
||||
is($(".call-item-location", item.target).getAttribute("value"), location,
|
||||
"The item's location label has the correct text.");
|
||||
}
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if filtering the items in the call list works properly.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
const searchbox = $("#calls-searchbox");
|
||||
|
||||
await reload(target);
|
||||
|
||||
const firstRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([firstRecordingFinished, callListPopulated]);
|
||||
|
||||
is(searchbox.value, "",
|
||||
"The searchbox should be initially empty.");
|
||||
is(CallsListView.visibleItems.length, 8,
|
||||
"All the items should be initially visible in the calls list.");
|
||||
|
||||
searchbox.focus();
|
||||
EventUtils.sendString("clear", window);
|
||||
|
||||
is(searchbox.value, "clear",
|
||||
"The searchbox should now contain the 'clear' string.");
|
||||
is(CallsListView.visibleItems.length, 1,
|
||||
"Only one item should now be visible in the calls list.");
|
||||
|
||||
is(CallsListView.visibleItems[0].attachment.actor.type, METHOD_FUNCTION,
|
||||
"The visible item's type has the expected value.");
|
||||
is(CallsListView.visibleItems[0].attachment.actor.name, "clearRect",
|
||||
"The visible item's name has the expected value.");
|
||||
is(CallsListView.visibleItems[0].attachment.actor.file, SIMPLE_CANVAS_URL,
|
||||
"The visible item's file has the expected value.");
|
||||
is(CallsListView.visibleItems[0].attachment.actor.line, 25,
|
||||
"The visible item's line has the expected value.");
|
||||
is(CallsListView.visibleItems[0].attachment.actor.argsPreview, "0, 0, 128, 128",
|
||||
"The visible item's args have the expected value.");
|
||||
is(CallsListView.visibleItems[0].attachment.actor.callerPreview, "Object",
|
||||
"The visible item's caller has the expected value.");
|
||||
|
||||
const secondRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await secondRecordingFinished;
|
||||
|
||||
SnapshotsListView.selectedIndex = 1;
|
||||
await callListPopulated;
|
||||
|
||||
is(searchbox.value, "clear",
|
||||
"The searchbox should still contain the 'clear' string.");
|
||||
is(CallsListView.visibleItems.length, 1,
|
||||
"Only one item should still be visible in the calls list.");
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
searchbox.focus();
|
||||
EventUtils.sendKey("BACK_SPACE", window);
|
||||
}
|
||||
|
||||
is(searchbox.value, "",
|
||||
"The searchbox should now be emptied.");
|
||||
is(CallsListView.visibleItems.length, 8,
|
||||
"All the items should be initially visible again in the calls list.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the a function call's stack is properly displayed in the UI.
|
||||
*/
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_DEEP_STACK_URL);
|
||||
const { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated]);
|
||||
|
||||
const callItem = CallsListView.getItemAtIndex(2);
|
||||
const locationLink = $(".call-item-location", callItem.target);
|
||||
|
||||
is($(".call-item-stack", callItem.target), null,
|
||||
"There should be no stack container available yet for the draw call.");
|
||||
|
||||
const callStackDisplayed = once(window, EVENTS.CALL_STACK_DISPLAYED);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, locationLink, window);
|
||||
await callStackDisplayed;
|
||||
|
||||
isnot($(".call-item-stack", callItem.target), null,
|
||||
"There should be a stack container available now for the draw call.");
|
||||
// We may have more than 4 functions, depending on whether async
|
||||
// stacks are available.
|
||||
ok($all(".call-item-stack-fn", callItem.target).length >= 4,
|
||||
"There should be at least 4 functions on the stack for the draw call.");
|
||||
|
||||
ok($all(".call-item-stack-fn-name", callItem.target)[0].getAttribute("value")
|
||||
.includes("C()"),
|
||||
"The first function on the stack has the correct name.");
|
||||
ok($all(".call-item-stack-fn-name", callItem.target)[1].getAttribute("value")
|
||||
.includes("B()"),
|
||||
"The second function on the stack has the correct name.");
|
||||
ok($all(".call-item-stack-fn-name", callItem.target)[2].getAttribute("value")
|
||||
.includes("A()"),
|
||||
"The third function on the stack has the correct name.");
|
||||
ok($all(".call-item-stack-fn-name", callItem.target)[3].getAttribute("value")
|
||||
.includes("drawRect()"),
|
||||
"The fourth function on the stack has the correct name.");
|
||||
|
||||
is($all(".call-item-stack-fn-location", callItem.target)[0].getAttribute("value"),
|
||||
"doc_simple-canvas-deep-stack.html:26",
|
||||
"The first function on the stack has the correct location.");
|
||||
is($all(".call-item-stack-fn-location", callItem.target)[1].getAttribute("value"),
|
||||
"doc_simple-canvas-deep-stack.html:28",
|
||||
"The second function on the stack has the correct location.");
|
||||
is($all(".call-item-stack-fn-location", callItem.target)[2].getAttribute("value"),
|
||||
"doc_simple-canvas-deep-stack.html:30",
|
||||
"The third function on the stack has the correct location.");
|
||||
is($all(".call-item-stack-fn-location", callItem.target)[3].getAttribute("value"),
|
||||
"doc_simple-canvas-deep-stack.html:35",
|
||||
"The fourth function on the stack has the correct location.");
|
||||
|
||||
const jumpedToSource = once(window, EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $(".call-item-stack-fn-location", callItem.target));
|
||||
await jumpedToSource;
|
||||
|
||||
const toolbox = await gDevTools.getToolbox(target);
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
await validateDebuggerLocation(dbg, SIMPLE_CANVAS_DEEP_STACK_URL, 26);
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the a function call's stack is properly displayed in the UI
|
||||
* and jumping to source in the debugger for the topmost call item works.
|
||||
*/
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_DEEP_STACK_URL);
|
||||
const { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated]);
|
||||
|
||||
const callItem = CallsListView.getItemAtIndex(2);
|
||||
const locationLink = $(".call-item-location", callItem.target);
|
||||
|
||||
is($(".call-item-stack", callItem.target), null,
|
||||
"There should be no stack container available yet for the draw call.");
|
||||
|
||||
const callStackDisplayed = once(window, EVENTS.CALL_STACK_DISPLAYED);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, locationLink, window);
|
||||
await callStackDisplayed;
|
||||
|
||||
isnot($(".call-item-stack", callItem.target), null,
|
||||
"There should be a stack container available now for the draw call.");
|
||||
// We may have more than 4 functions, depending on whether async
|
||||
// stacks are available.
|
||||
ok($all(".call-item-stack-fn", callItem.target).length >= 4,
|
||||
"There should be at least 4 functions on the stack for the draw call.");
|
||||
|
||||
const jumpedToSource = once(window, EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $(".call-item-location", callItem.target));
|
||||
await jumpedToSource;
|
||||
|
||||
const toolbox = await gDevTools.getToolbox(target);
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
await validateDebuggerLocation(dbg, SIMPLE_CANVAS_DEEP_STACK_URL, 24);
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the a function call's stack can be shown/hidden by double-clicking
|
||||
* on a function call item.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_DEEP_STACK_URL);
|
||||
const { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated]);
|
||||
|
||||
const callItem = CallsListView.getItemAtIndex(2);
|
||||
const view = $(".call-item-view", callItem.target);
|
||||
const contents = $(".call-item-contents", callItem.target);
|
||||
|
||||
is(view.hasAttribute("call-stack-populated"), false,
|
||||
"The call item's view should not have the stack populated yet.");
|
||||
is(view.hasAttribute("call-stack-expanded"), false,
|
||||
"The call item's view should not have the stack populated yet.");
|
||||
is($(".call-item-stack", callItem.target), null,
|
||||
"There should be no stack container available yet for the draw call.");
|
||||
|
||||
const callStackDisplayed = once(window, EVENTS.CALL_STACK_DISPLAYED);
|
||||
EventUtils.sendMouseEvent({ type: "dblclick" }, contents, window);
|
||||
await callStackDisplayed;
|
||||
|
||||
is(view.hasAttribute("call-stack-populated"), true,
|
||||
"The call item's view should have the stack populated now.");
|
||||
is(view.getAttribute("call-stack-expanded"), "true",
|
||||
"The call item's view should have the stack expanded now.");
|
||||
isnot($(".call-item-stack", callItem.target), null,
|
||||
"There should be a stack container available now for the draw call.");
|
||||
is($(".call-item-stack", callItem.target).hidden, false,
|
||||
"The stack container should now be visible.");
|
||||
// We may have more than 4 functions, depending on whether async
|
||||
// stacks are available.
|
||||
ok($all(".call-item-stack-fn", callItem.target).length >= 4,
|
||||
"There should be at least 4 functions on the stack for the draw call.");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "dblclick" }, contents, window);
|
||||
|
||||
is(view.hasAttribute("call-stack-populated"), true,
|
||||
"The call item's view should still have the stack populated.");
|
||||
is(view.getAttribute("call-stack-expanded"), "false",
|
||||
"The call item's view should not have the stack expanded anymore.");
|
||||
isnot($(".call-item-stack", callItem.target), null,
|
||||
"There should still be a stack container available for the draw call.");
|
||||
is($(".call-item-stack", callItem.target).hidden, true,
|
||||
"The stack container should now be hidden.");
|
||||
// We may have more than 4 functions, depending on whether async
|
||||
// stacks are available.
|
||||
ok($all(".call-item-stack-fn", callItem.target).length >= 4,
|
||||
"There should still be at least 4 functions on the stack for the draw call.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if clearing the snapshots list works as expected.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, EVENTS, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const firstRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await firstRecordingFinished;
|
||||
ok(true, "Finished recording a snapshot of the animation loop.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 1,
|
||||
"There should be one item available in the snapshots list.");
|
||||
|
||||
const secondRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await secondRecordingFinished;
|
||||
ok(true, "Finished recording another snapshot of the animation loop.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 2,
|
||||
"There should be two items available in the snapshots list.");
|
||||
|
||||
const clearingFinished = once(window, EVENTS.SNAPSHOTS_LIST_CLEARED);
|
||||
SnapshotsListView._onClearButtonClick();
|
||||
|
||||
await clearingFinished;
|
||||
ok(true, "Finished recording all snapshots.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 0,
|
||||
"There should be no items available in the snapshots list.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if screenshots are properly displayed in the UI.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
const screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated, screenshotDisplayed]);
|
||||
|
||||
is($("#screenshot-container").hidden, false,
|
||||
"The screenshot container should now be visible.");
|
||||
|
||||
is($("#screenshot-dimensions").getAttribute("value"), "128" + "\u00D7" + "128",
|
||||
"The screenshot dimensions label has the expected value.");
|
||||
|
||||
is($("#screenshot-image").getAttribute("flipped"), "false",
|
||||
"The screenshot element should not be flipped vertically.");
|
||||
|
||||
ok(window.getComputedStyle($("#screenshot-image")).backgroundImage.includes("#screenshot-rendering"),
|
||||
"The screenshot element should have an offscreen canvas element as a background.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if thumbnails are properly displayed in the UI.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, $all, EVENTS, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
const thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated, thumbnailsDisplayed]);
|
||||
|
||||
is($all(".filmstrip-thumbnail").length, 4,
|
||||
"There should be 4 thumbnails displayed in the UI.");
|
||||
|
||||
const firstThumbnail = $(".filmstrip-thumbnail[index='0']");
|
||||
ok(firstThumbnail,
|
||||
"The first thumbnail element should be for the function call at index 0.");
|
||||
is(firstThumbnail.width, 50,
|
||||
"The first thumbnail's width is correct.");
|
||||
is(firstThumbnail.height, 50,
|
||||
"The first thumbnail's height is correct.");
|
||||
is(firstThumbnail.getAttribute("flipped"), "false",
|
||||
"The first thumbnail should not be flipped vertically.");
|
||||
|
||||
const secondThumbnail = $(".filmstrip-thumbnail[index='2']");
|
||||
ok(secondThumbnail,
|
||||
"The second thumbnail element should be for the function call at index 2.");
|
||||
is(secondThumbnail.width, 50,
|
||||
"The second thumbnail's width is correct.");
|
||||
is(secondThumbnail.height, 50,
|
||||
"The second thumbnail's height is correct.");
|
||||
is(secondThumbnail.getAttribute("flipped"), "false",
|
||||
"The second thumbnail should not be flipped vertically.");
|
||||
|
||||
const thirdThumbnail = $(".filmstrip-thumbnail[index='4']");
|
||||
ok(thirdThumbnail,
|
||||
"The third thumbnail element should be for the function call at index 4.");
|
||||
is(thirdThumbnail.width, 50,
|
||||
"The third thumbnail's width is correct.");
|
||||
is(thirdThumbnail.height, 50,
|
||||
"The third thumbnail's height is correct.");
|
||||
is(thirdThumbnail.getAttribute("flipped"), "false",
|
||||
"The third thumbnail should not be flipped vertically.");
|
||||
|
||||
const fourthThumbnail = $(".filmstrip-thumbnail[index='6']");
|
||||
ok(fourthThumbnail,
|
||||
"The fourth thumbnail element should be for the function call at index 6.");
|
||||
is(fourthThumbnail.width, 50,
|
||||
"The fourth thumbnail's width is correct.");
|
||||
is(fourthThumbnail.height, 50,
|
||||
"The fourth thumbnail's height is correct.");
|
||||
is(fourthThumbnail.getAttribute("flipped"), "false",
|
||||
"The fourth thumbnail should not be flipped vertically.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if thumbnails are correctly linked with other UI elements like
|
||||
* function call items and their respective screenshots.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
const thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
|
||||
const screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([
|
||||
recordingFinished,
|
||||
callListPopulated,
|
||||
thumbnailsDisplayed,
|
||||
screenshotDisplayed,
|
||||
]);
|
||||
|
||||
is($all(".filmstrip-thumbnail[highlighted]").length, 0,
|
||||
"There should be no highlighted thumbnail available yet.");
|
||||
is(CallsListView.selectedIndex, -1,
|
||||
"There should be no selected item in the calls list view.");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $all(".filmstrip-thumbnail")[0], window);
|
||||
await once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
info("The first draw call was selected, by clicking the first thumbnail.");
|
||||
|
||||
isnot($(".filmstrip-thumbnail[highlighted][index='0']"), null,
|
||||
"There should be a highlighted thumbnail available now, for the first draw call.");
|
||||
is($all(".filmstrip-thumbnail[highlighted]").length, 1,
|
||||
"There should be only one highlighted thumbnail available now.");
|
||||
is(CallsListView.selectedIndex, 0,
|
||||
"The first draw call should be selected in the calls list view.");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $all(".call-item-view")[1], window);
|
||||
await once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
info("The second context call was selected, by clicking the second call item.");
|
||||
|
||||
isnot($(".filmstrip-thumbnail[highlighted][index='0']"), null,
|
||||
"There should be a highlighted thumbnail available, for the first draw call.");
|
||||
is($all(".filmstrip-thumbnail[highlighted]").length, 1,
|
||||
"There should be only one highlighted thumbnail available.");
|
||||
is(CallsListView.selectedIndex, 1,
|
||||
"The second draw call should be selected in the calls list view.");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, $all(".call-item-view")[2], window);
|
||||
await once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
info("The second draw call was selected, by clicking the third call item.");
|
||||
|
||||
isnot($(".filmstrip-thumbnail[highlighted][index='2']"), null,
|
||||
"There should be a highlighted thumbnail available, for the second draw call.");
|
||||
is($all(".filmstrip-thumbnail[highlighted]").length, 1,
|
||||
"There should be only one highlighted thumbnail available.");
|
||||
is(CallsListView.selectedIndex, 2,
|
||||
"The second draw call should be selected in the calls list view.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the frontend UI is properly configured when opening the tool.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { $ } = panel.panelWin;
|
||||
|
||||
is($("#snapshots-pane").hasAttribute("hidden"), false,
|
||||
"The snapshots pane should initially be visible.");
|
||||
is($("#debugging-pane").hasAttribute("hidden"), false,
|
||||
"The debugging pane should initially be visible.");
|
||||
|
||||
is($("#record-snapshot").getAttribute("hidden"), "true",
|
||||
"The 'record snapshot' button should initially be hidden.");
|
||||
is($("#import-snapshot").hasAttribute("hidden"), false,
|
||||
"The 'import snapshot' button should initially be visible.");
|
||||
is($("#clear-snapshots").hasAttribute("hidden"), false,
|
||||
"The 'clear snapshots' button should initially be visible.");
|
||||
|
||||
is($("#reload-notice").hasAttribute("hidden"), false,
|
||||
"The reload notice should initially be visible.");
|
||||
is($("#empty-notice").getAttribute("hidden"), "true",
|
||||
"The empty notice should initially be hidden.");
|
||||
is($("#waiting-notice").getAttribute("hidden"), "true",
|
||||
"The waiting notice should initially be hidden.");
|
||||
|
||||
is($("#screenshot-container").getAttribute("hidden"), "true",
|
||||
"The screenshot container should initially be hidden.");
|
||||
is($("#snapshot-filmstrip").getAttribute("hidden"), "true",
|
||||
"The snapshot filmstrip should initially be hidden.");
|
||||
|
||||
is($("#debugging-pane-contents").getAttribute("hidden"), "true",
|
||||
"The rest of the UI should initially be hidden.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests whether the frontend behaves correctly while reording a snapshot.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
is($("#record-snapshot").hasAttribute("checked"), false,
|
||||
"The 'record snapshot' button should initially be unchecked.");
|
||||
is($("#record-snapshot").hasAttribute("disabled"), false,
|
||||
"The 'record snapshot' button should initially be enabled.");
|
||||
is($("#record-snapshot").hasAttribute("hidden"), false,
|
||||
"The 'record snapshot' button should now be visible.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 0,
|
||||
"There should be no items available in the snapshots list view.");
|
||||
is(SnapshotsListView.selectedIndex, -1,
|
||||
"There should be no selected item in the snapshots list view.");
|
||||
|
||||
const recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await recordingStarted;
|
||||
ok(true, "Started recording a snapshot of the animation loop.");
|
||||
|
||||
is($("#record-snapshot").getAttribute("checked"), "true",
|
||||
"The 'record snapshot' button should now be checked.");
|
||||
is($("#record-snapshot").hasAttribute("hidden"), false,
|
||||
"The 'record snapshot' button should still be visible.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 1,
|
||||
"There should be one item available in the snapshots list view now.");
|
||||
is(SnapshotsListView.selectedIndex, -1,
|
||||
"There should be no selected item in the snapshots list view yet.");
|
||||
|
||||
await recordingFinished;
|
||||
ok(true, "Finished recording a snapshot of the animation loop.");
|
||||
|
||||
is($("#record-snapshot").hasAttribute("checked"), false,
|
||||
"The 'record snapshot' button should now be unchecked.");
|
||||
is($("#record-snapshot").hasAttribute("disabled"), false,
|
||||
"The 'record snapshot' button should now be re-enabled.");
|
||||
is($("#record-snapshot").hasAttribute("hidden"), false,
|
||||
"The 'record snapshot' button should still be visible.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 1,
|
||||
"There should still be only one item available in the snapshots list view.");
|
||||
is(SnapshotsListView.selectedIndex, 0,
|
||||
"There should be one selected item in the snapshots list view now.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests whether the frontend displays a placeholder snapshot while recording.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, EVENTS, L10N, $, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const recordingSelected = once(window, EVENTS.SNAPSHOT_RECORDING_SELECTED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await recordingStarted;
|
||||
ok(true, "Started recording a snapshot of the animation loop.");
|
||||
|
||||
const item = SnapshotsListView.getItemAtIndex(0);
|
||||
|
||||
is($(".snapshot-item-title", item.target).getAttribute("value"),
|
||||
L10N.getFormatStr("snapshotsList.itemLabel", 1),
|
||||
"The placeholder item's title label is correct.");
|
||||
|
||||
is($(".snapshot-item-calls", item.target).getAttribute("value"),
|
||||
L10N.getStr("snapshotsList.loadingLabel"),
|
||||
"The placeholder item's calls label is correct.");
|
||||
|
||||
is($(".snapshot-item-save", item.target).getAttribute("value"), "",
|
||||
"The placeholder item's save label should not have a value yet.");
|
||||
|
||||
is($("#reload-notice").getAttribute("hidden"), "true",
|
||||
"The reload notice should now be hidden.");
|
||||
is($("#empty-notice").getAttribute("hidden"), "true",
|
||||
"The empty notice should now be hidden.");
|
||||
is($("#waiting-notice").hasAttribute("hidden"), false,
|
||||
"The waiting notice should now be visible.");
|
||||
|
||||
is($("#screenshot-container").getAttribute("hidden"), "true",
|
||||
"The screenshot container should still be hidden.");
|
||||
is($("#snapshot-filmstrip").getAttribute("hidden"), "true",
|
||||
"The snapshot filmstrip should still be hidden.");
|
||||
|
||||
is($("#debugging-pane-contents").getAttribute("hidden"), "true",
|
||||
"The rest of the UI should still be hidden.");
|
||||
|
||||
await recordingFinished;
|
||||
ok(true, "Finished recording a snapshot of the animation loop.");
|
||||
|
||||
await recordingSelected;
|
||||
ok(true, "Finished selecting a snapshot of the animation loop.");
|
||||
|
||||
is($("#reload-notice").getAttribute("hidden"), "true",
|
||||
"The reload notice should now be hidden.");
|
||||
is($("#empty-notice").getAttribute("hidden"), "true",
|
||||
"The empty notice should now be hidden.");
|
||||
is($("#waiting-notice").getAttribute("hidden"), "true",
|
||||
"The waiting notice should now be hidden.");
|
||||
|
||||
is($("#screenshot-container").hasAttribute("hidden"), false,
|
||||
"The screenshot container should now be visible.");
|
||||
is($("#snapshot-filmstrip").hasAttribute("hidden"), false,
|
||||
"The snapshot filmstrip should now be visible.");
|
||||
|
||||
is($("#debugging-pane-contents").hasAttribute("hidden"), false,
|
||||
"The rest of the UI should now be visible.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests whether the frontend displays the correct info for a snapshot
|
||||
* after finishing recording.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await recordingFinished;
|
||||
ok(true, "Finished recording a snapshot of the animation loop.");
|
||||
|
||||
const item = SnapshotsListView.getItemAtIndex(0);
|
||||
|
||||
is(SnapshotsListView.selectedItem, item,
|
||||
"The first item should now be selected in the snapshots list view (1).");
|
||||
is(SnapshotsListView.selectedIndex, 0,
|
||||
"The first item should now be selected in the snapshots list view (2).");
|
||||
|
||||
is($(".snapshot-item-calls", item.target).getAttribute("value"), "4 draws, 8 calls",
|
||||
"The placeholder item's calls label is correct.");
|
||||
is($(".snapshot-item-save", item.target).getAttribute("value"), "Save",
|
||||
"The placeholder item's save label is correct.");
|
||||
is($(".snapshot-item-save", item.target).getAttribute("disabled"), "false",
|
||||
"The placeholder item's save label should be clickable.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 1122766
|
||||
* Tests that the canvas actor correctly returns from recordAnimationFrame
|
||||
* in the scenario where a loop starts with rAF and has rAF in the beginning
|
||||
* of its loop, when the recording starts before the rAFs start.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(RAF_BEGIN_URL);
|
||||
const { window, EVENTS, gFront, SnapshotsListView } = panel.panelWin;
|
||||
loadFrameScriptUtils();
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
// Wait until after the recording started to trigger the content.
|
||||
// Use the gFront method rather than the SNAPSHOT_RECORDING_STARTED event
|
||||
// which triggers before the underlying actor call
|
||||
await waitUntil(async function() {
|
||||
return !(await gFront.isRecording());
|
||||
});
|
||||
|
||||
// Start animation in content
|
||||
evalInDebuggee("start();");
|
||||
|
||||
await recordingFinished;
|
||||
ok(true, "Finished recording a snapshot of the animation loop.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the frontend UI is properly reconfigured after reloading.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS } = panel.panelWin;
|
||||
|
||||
const reset = once(window, EVENTS.UI_RESET);
|
||||
const navigated = reload(target);
|
||||
|
||||
await reset;
|
||||
ok(true, "The UI was reset after the refresh button was clicked.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "The target finished reloading.");
|
||||
|
||||
is($("#snapshots-pane").hasAttribute("hidden"), false,
|
||||
"The snapshots pane should still be visible.");
|
||||
is($("#debugging-pane").hasAttribute("hidden"), false,
|
||||
"The debugging pane should still be visible.");
|
||||
|
||||
is($("#record-snapshot").hasAttribute("checked"), false,
|
||||
"The 'record snapshot' button should not be checked.");
|
||||
is($("#record-snapshot").hasAttribute("disabled"), false,
|
||||
"The 'record snapshot' button should not be disabled.");
|
||||
|
||||
is($("#record-snapshot").hasAttribute("hidden"), false,
|
||||
"The 'record snapshot' button should now be visible.");
|
||||
is($("#import-snapshot").hasAttribute("hidden"), false,
|
||||
"The 'import snapshot' button should still be visible.");
|
||||
is($("#clear-snapshots").hasAttribute("hidden"), false,
|
||||
"The 'clear snapshots' button should still be visible.");
|
||||
|
||||
is($("#reload-notice").getAttribute("hidden"), "true",
|
||||
"The reload notice should now be hidden.");
|
||||
is($("#empty-notice").hasAttribute("hidden"), false,
|
||||
"The empty notice should now be visible.");
|
||||
is($("#waiting-notice").getAttribute("hidden"), "true",
|
||||
"The waiting notice should now be hidden.");
|
||||
|
||||
is($("#snapshot-filmstrip").getAttribute("hidden"), "true",
|
||||
"The snapshot filmstrip should still be hidden.");
|
||||
is($("#screenshot-container").getAttribute("hidden"), "true",
|
||||
"The screenshot container should still be hidden.");
|
||||
|
||||
is($("#debugging-pane-contents").getAttribute("hidden"), "true",
|
||||
"The rest of the UI should still be hidden.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the frontend UI is properly reconfigured after reloading.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
is(SnapshotsListView.itemCount, 0,
|
||||
"There should be no snapshots initially displayed in the UI.");
|
||||
is(CallsListView.itemCount, 0,
|
||||
"There should be no function calls initially displayed in the UI.");
|
||||
|
||||
is($("#screenshot-container").hidden, true,
|
||||
"The screenshot should not be initially displayed in the UI.");
|
||||
is($("#snapshot-filmstrip").hidden, true,
|
||||
"There should be no thumbnails initially displayed in the UI (1).");
|
||||
is($all(".filmstrip-thumbnail").length, 0,
|
||||
"There should be no thumbnails initially displayed in the UI (2).");
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
const thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
|
||||
const screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([
|
||||
recordingFinished,
|
||||
callListPopulated,
|
||||
thumbnailsDisplayed,
|
||||
screenshotDisplayed,
|
||||
]);
|
||||
|
||||
is(SnapshotsListView.itemCount, 1,
|
||||
"There should be one snapshot displayed in the UI.");
|
||||
is(CallsListView.itemCount, 8,
|
||||
"All the function calls should now be displayed in the UI.");
|
||||
|
||||
is($("#screenshot-container").hidden, false,
|
||||
"The screenshot should now be displayed in the UI.");
|
||||
is($("#snapshot-filmstrip").hidden, false,
|
||||
"All the thumbnails should now be displayed in the UI (1).");
|
||||
is($all(".filmstrip-thumbnail").length, 4,
|
||||
"All the thumbnails should now be displayed in the UI (2).");
|
||||
|
||||
const reset = once(window, EVENTS.UI_RESET);
|
||||
const navigated = reload(target);
|
||||
|
||||
await reset;
|
||||
ok(true, "The UI was reset after the refresh button was clicked.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 0,
|
||||
"There should be no snapshots displayed in the UI after navigating.");
|
||||
is(CallsListView.itemCount, 0,
|
||||
"There should be no function calls displayed in the UI after navigating.");
|
||||
is($("#snapshot-filmstrip").hidden, true,
|
||||
"There should be no thumbnails displayed in the UI after navigating.");
|
||||
is($("#screenshot-container").hidden, true,
|
||||
"The screenshot should not be displayed in the UI after navigating.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "The target finished reloading.");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if selecting snapshots in the frontend displays the appropriate data
|
||||
* respective to their recorded animation frame.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
await recordAndWaitForFirstSnapshot();
|
||||
info("First snapshot recorded.");
|
||||
|
||||
is(SnapshotsListView.selectedIndex, 0,
|
||||
"A snapshot should be automatically selected after first recording.");
|
||||
is(CallsListView.selectedIndex, -1,
|
||||
"There should be no call item automatically selected in the snapshot.");
|
||||
|
||||
await recordAndWaitForAnotherSnapshot();
|
||||
info("Second snapshot recorded.");
|
||||
|
||||
is(SnapshotsListView.selectedIndex, 0,
|
||||
"A snapshot should not be automatically selected after another recording.");
|
||||
is(CallsListView.selectedIndex, -1,
|
||||
"There should still be no call item automatically selected in the snapshot.");
|
||||
|
||||
const secondSnapshotTarget = SnapshotsListView.getItemAtIndex(1).target;
|
||||
let snapshotSelected = waitForSnapshotSelection();
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, secondSnapshotTarget, window);
|
||||
|
||||
await snapshotSelected;
|
||||
info("Second snapshot selected.");
|
||||
|
||||
is(SnapshotsListView.selectedIndex, 1,
|
||||
"The second snapshot should now be selected.");
|
||||
is(CallsListView.selectedIndex, -1,
|
||||
"There should still be no call item automatically selected in the snapshot.");
|
||||
|
||||
const firstDrawCallContents = $(".call-item-contents", CallsListView.getItemAtIndex(2).target);
|
||||
const screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, firstDrawCallContents, window);
|
||||
|
||||
await screenshotDisplayed;
|
||||
info("First draw call in the second snapshot selected.");
|
||||
|
||||
is(SnapshotsListView.selectedIndex, 1,
|
||||
"The second snapshot should still be selected.");
|
||||
is(CallsListView.selectedIndex, 2,
|
||||
"The first draw call should now be selected in the snapshot.");
|
||||
|
||||
const firstSnapshotTarget = SnapshotsListView.getItemAtIndex(0).target;
|
||||
snapshotSelected = waitForSnapshotSelection();
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, firstSnapshotTarget, window);
|
||||
|
||||
await snapshotSelected;
|
||||
info("First snapshot re-selected.");
|
||||
|
||||
is(SnapshotsListView.selectedIndex, 0,
|
||||
"The first snapshot should now be re-selected.");
|
||||
is(CallsListView.selectedIndex, -1,
|
||||
"There should still be no call item automatically selected in the snapshot.");
|
||||
|
||||
function recordAndWaitForFirstSnapshot() {
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const snapshotSelected = waitForSnapshotSelection();
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
return Promise.all([recordingFinished, snapshotSelected]);
|
||||
}
|
||||
|
||||
function recordAndWaitForAnotherSnapshot() {
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
return recordingFinished;
|
||||
}
|
||||
|
||||
function waitForSnapshotSelection() {
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
const thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
|
||||
const screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
|
||||
return Promise.all([
|
||||
callListPopulated,
|
||||
thumbnailsDisplayed,
|
||||
screenshotDisplayed,
|
||||
]);
|
||||
}
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if selecting snapshots in the frontend displays the appropriate data
|
||||
* respective to their recorded animation frame.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
const snapshotTarget = SnapshotsListView.getItemAtIndex(0).target;
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, snapshotTarget, window);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, snapshotTarget, window);
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, snapshotTarget, window);
|
||||
|
||||
ok(true, "clicking in-progress snapshot does not fail");
|
||||
|
||||
const finished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await finished;
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the stepping buttons in the call list toolbar work as advertised.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(SIMPLE_CANVAS_URL);
|
||||
const { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
await Promise.all([recordingFinished, callListPopulated]);
|
||||
|
||||
checkSteppingButtons(1, 1, 1, 1);
|
||||
is(CallsListView.selectedIndex, -1,
|
||||
"There should be no selected item in the calls list view initially.");
|
||||
|
||||
CallsListView._onResume();
|
||||
checkSteppingButtons(1, 1, 1, 1);
|
||||
is(CallsListView.selectedIndex, 0,
|
||||
"The first draw call should now be selected.");
|
||||
|
||||
CallsListView._onResume();
|
||||
checkSteppingButtons(1, 1, 1, 1);
|
||||
is(CallsListView.selectedIndex, 2,
|
||||
"The second draw call should now be selected.");
|
||||
|
||||
CallsListView._onStepOver();
|
||||
checkSteppingButtons(1, 1, 1, 1);
|
||||
is(CallsListView.selectedIndex, 3,
|
||||
"The next context call should now be selected.");
|
||||
|
||||
CallsListView._onStepOut();
|
||||
checkSteppingButtons(0, 0, 1, 0);
|
||||
is(CallsListView.selectedIndex, 7,
|
||||
"The last context call should now be selected.");
|
||||
|
||||
function checkSteppingButtons(resume, stepOver, stepIn, stepOut) {
|
||||
if (!resume) {
|
||||
is($("#resume").getAttribute("disabled"), "true",
|
||||
"The resume button doesn't have the expected disabled state.");
|
||||
} else {
|
||||
is($("#resume").hasAttribute("disabled"), false,
|
||||
"The resume button doesn't have the expected enabled state.");
|
||||
}
|
||||
if (!stepOver) {
|
||||
is($("#step-over").getAttribute("disabled"), "true",
|
||||
"The stepOver button doesn't have the expected disabled state.");
|
||||
} else {
|
||||
is($("#step-over").hasAttribute("disabled"), false,
|
||||
"The stepOver button doesn't have the expected enabled state.");
|
||||
}
|
||||
if (!stepIn) {
|
||||
is($("#step-in").getAttribute("disabled"), "true",
|
||||
"The stepIn button doesn't have the expected disabled state.");
|
||||
} else {
|
||||
is($("#step-in").hasAttribute("disabled"), false,
|
||||
"The stepIn button doesn't have the expected enabled state.");
|
||||
}
|
||||
if (!stepOut) {
|
||||
is($("#step-out").getAttribute("disabled"), "true",
|
||||
"The stepOut button doesn't have the expected disabled state.");
|
||||
} else {
|
||||
is($("#step-out").hasAttribute("disabled"), false,
|
||||
"The stepOut button doesn't have the expected enabled state.");
|
||||
}
|
||||
}
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that you can stop a recording that does not have a rAF cycle.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(NO_CANVAS_URL);
|
||||
const { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await recordingStarted;
|
||||
|
||||
is($("#empty-notice").hidden, true, "Empty notice not shown");
|
||||
is($("#waiting-notice").hidden, false, "Waiting notice shown");
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const recordingCancelled = once(window, EVENTS.SNAPSHOT_RECORDING_CANCELLED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await Promise.all([recordingFinished, recordingCancelled]);
|
||||
|
||||
ok(true, "Recording stopped and was considered failed.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 0, "No snapshots in the list.");
|
||||
is($("#empty-notice").hidden, false, "Empty notice shown");
|
||||
is($("#waiting-notice").hidden, true, "Waiting notice not shown");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that a recording that does not have a rAF cycle fails after timeout.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(NO_CANVAS_URL);
|
||||
const { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await recordingStarted;
|
||||
|
||||
is($("#empty-notice").hidden, true, "Empty notice not shown");
|
||||
is($("#waiting-notice").hidden, false, "Waiting notice shown");
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const recordingCancelled = once(window, EVENTS.SNAPSHOT_RECORDING_CANCELLED);
|
||||
|
||||
await Promise.all([recordingFinished, recordingCancelled]);
|
||||
|
||||
ok(true, "Recording stopped and was considered failed.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 0, "No snapshots in the list.");
|
||||
is($("#empty-notice").hidden, false, "Empty notice shown");
|
||||
is($("#waiting-notice").hidden, true, "Waiting notice not shown");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that a recording that has a rAF cycle, but no draw calls, fails
|
||||
* after timeout.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const { target, panel } = await initCanvasDebuggerFrontend(RAF_NO_CANVAS_URL);
|
||||
const { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
|
||||
|
||||
await reload(target);
|
||||
|
||||
const recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
|
||||
SnapshotsListView._onRecordButtonClick();
|
||||
|
||||
await recordingStarted;
|
||||
|
||||
is($("#empty-notice").hidden, true, "Empty notice not shown");
|
||||
is($("#waiting-notice").hidden, false, "Waiting notice shown");
|
||||
|
||||
const recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
|
||||
const recordingCancelled = once(window, EVENTS.SNAPSHOT_RECORDING_CANCELLED);
|
||||
|
||||
await Promise.all([recordingFinished, recordingCancelled]);
|
||||
|
||||
ok(true, "Recording stopped and was considered failed.");
|
||||
|
||||
is(SnapshotsListView.itemCount, 0, "No snapshots in the list.");
|
||||
is($("#empty-notice").hidden, false, "Empty notice shown");
|
||||
is($("#waiting-notice").hidden, true, "Waiting notice not shown");
|
||||
|
||||
await teardown(panel);
|
||||
finish();
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if functions inside a single animation frame are recorded and stored
|
||||
* for a canvas context profiling.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const currentTime = window.performance.now();
|
||||
const { target, front } = await initCanvasDebuggerBackend(SIMPLE_CANVAS_URL);
|
||||
|
||||
const navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
const snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
const animationOverview = await snapshotActor.getOverview();
|
||||
ok(animationOverview,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
const functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
is(functionCalls.length, 8,
|
||||
"The number of function call actors is correct.");
|
||||
|
||||
info("Check the timestamps of function calls");
|
||||
|
||||
for (let i = 0; i < functionCalls.length - 1; i += 2) {
|
||||
ok(functionCalls[i].timestamp > 0, "The timestamp of the called function is larger than 0.");
|
||||
ok(functionCalls[i].timestamp < currentTime, "The timestamp has been minus the frame start time.");
|
||||
ok(functionCalls[i + 1].timestamp >= functionCalls[i].timestamp, "The timestamp of the called function is correct.");
|
||||
}
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if functions inside a single animation frame are recorded and stored
|
||||
* for a canvas context profiling.
|
||||
*/
|
||||
|
||||
async function ifTestingSupported() {
|
||||
const currentTime = window.performance.now();
|
||||
info("Start to estimate WebGL drawArrays function.");
|
||||
var { target, front } = await initCanvasDebuggerBackend(WEBGL_DRAW_ARRAYS);
|
||||
|
||||
let navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
let snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
let animationOverview = await snapshotActor.getOverview();
|
||||
ok(animationOverview,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
let functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
|
||||
testFunctionCallTimestamp(functionCalls, currentTime);
|
||||
|
||||
info("Check triangle and vertex counts in drawArrays()");
|
||||
is(animationOverview.primitive.tris, 5, "The count of triangles is correct.");
|
||||
is(animationOverview.primitive.vertices, 26, "The count of vertices is correct.");
|
||||
is(animationOverview.primitive.points, 4, "The count of points is correct.");
|
||||
is(animationOverview.primitive.lines, 8, "The count of lines is correct.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
|
||||
info("Start to estimate WebGL drawElements function.");
|
||||
const result = await initCanvasDebuggerBackend(WEBGL_DRAW_ELEMENTS);
|
||||
target = result.target;
|
||||
front = result.front;
|
||||
|
||||
navigated = once(target, "navigate");
|
||||
|
||||
await front.setup({ reload: true });
|
||||
ok(true, "The front was setup up successfully.");
|
||||
|
||||
await navigated;
|
||||
ok(true, "Target automatically navigated when the front was set up.");
|
||||
|
||||
snapshotActor = await front.recordAnimationFrame();
|
||||
ok(snapshotActor,
|
||||
"A snapshot actor was sent after recording.");
|
||||
|
||||
animationOverview = await snapshotActor.getOverview();
|
||||
ok(animationOverview,
|
||||
"An animation overview could be retrieved after recording.");
|
||||
|
||||
functionCalls = animationOverview.calls;
|
||||
ok(functionCalls,
|
||||
"An array of function call actors was sent after recording.");
|
||||
|
||||
testFunctionCallTimestamp(functionCalls, currentTime);
|
||||
|
||||
info("Check triangle and vertex counts in drawElements()");
|
||||
is(animationOverview.primitive.tris, 5, "The count of triangles is correct.");
|
||||
is(animationOverview.primitive.vertices, 26, "The count of vertices is correct.");
|
||||
is(animationOverview.primitive.points, 4, "The count of points is correct.");
|
||||
is(animationOverview.primitive.lines, 8, "The count of lines is correct.");
|
||||
|
||||
await removeTab(target.tab);
|
||||
finish();
|
||||
}
|
||||
|
||||
function testFunctionCallTimestamp(functionCalls, currentTime) {
|
||||
info("Check the timestamps of function calls");
|
||||
|
||||
for (let i = 0; i < functionCalls.length - 1; i += 2) {
|
||||
ok(functionCalls[i].timestamp > 0, "The timestamp of the called function is larger than 0.");
|
||||
ok(functionCalls[i].timestamp < currentTime, "The timestamp has been minus the frame start time.");
|
||||
ok(functionCalls[i + 1].timestamp >= functionCalls[i].timestamp, "The timestamp of the called function is correct.");
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const {
|
||||
callWatcherSpec,
|
||||
} = require("chrome://mochitests/content/browser/devtools/client/canvasdebugger/test/call-watcher-spec");
|
||||
const {CallWatcher} = require("devtools/server/actors/utils/call-watcher");
|
||||
|
||||
/**
|
||||
* This actor observes function calls on certain objects or globals.
|
||||
* It wraps the CallWatcher Helper so that it can be observed by tests
|
||||
*/
|
||||
exports.CallWatcherActor = protocol.ActorClassWithSpec(callWatcherSpec, {
|
||||
initialize: function(conn, targetActor) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
CallWatcher.call(this, conn, targetActor);
|
||||
},
|
||||
destroy: function(conn) {
|
||||
protocol.Actor.prototype.destroy.call(this, conn);
|
||||
this.finalize();
|
||||
},
|
||||
...CallWatcher.prototype,
|
||||
});
|
|
@ -1,23 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
callWatcherSpec,
|
||||
} = require("chrome://mochitests/content/browser/devtools/client/canvasdebugger/test/call-watcher-spec");
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
|
||||
/**
|
||||
* The corresponding Front object for the CallWatcherActor.
|
||||
*/
|
||||
class CallWatcherFront extends protocol.FrontClassWithSpec(callWatcherSpec) {
|
||||
constructor(client) {
|
||||
super(client);
|
||||
|
||||
// Attribute name from which to retrieve the actorID out of the target actor's form
|
||||
this.formAttributeName = "callWatcherActor";
|
||||
}
|
||||
}
|
||||
exports.CallWatcherFront = CallWatcherFront;
|
||||
protocol.registerFront(CallWatcherFront);
|
|
@ -1,49 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const { Arg, RetVal, Option, generateActorSpec } = protocol;
|
||||
|
||||
const callWatcherSpec = generateActorSpec({
|
||||
typeName: "call-watcher",
|
||||
|
||||
events: {
|
||||
/**
|
||||
* Events emitted when the `onCall` function isn't provided.
|
||||
*/
|
||||
"call": {
|
||||
type: "call",
|
||||
function: Arg(0, "function-call"),
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
setup: {
|
||||
request: {
|
||||
tracedGlobals: Option(0, "nullable:array:string"),
|
||||
tracedFunctions: Option(0, "nullable:array:string"),
|
||||
startRecording: Option(0, "boolean"),
|
||||
performReload: Option(0, "boolean"),
|
||||
holdWeak: Option(0, "boolean"),
|
||||
storeCalls: Option(0, "boolean"),
|
||||
},
|
||||
oneway: true,
|
||||
},
|
||||
finalize: {
|
||||
oneway: true,
|
||||
},
|
||||
isRecording: {
|
||||
response: RetVal("boolean"),
|
||||
},
|
||||
initTimestampEpoch: {},
|
||||
resumeRecording: {},
|
||||
pauseRecording: {
|
||||
response: { calls: RetVal("array:function-call") },
|
||||
},
|
||||
eraseRecording: {},
|
||||
},
|
||||
});
|
||||
|
||||
exports.callWatcherSpec = callWatcherSpec;
|
|
@ -1,14 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,38 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var ctx = document.querySelector("canvas").getContext("2d");
|
||||
|
||||
function drawRect(fill, size) {
|
||||
ctx.fillStyle = fill;
|
||||
ctx.fillRect(size[0], size[1], size[2], size[3]);
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
window.requestAnimationFrame(drawScene);
|
||||
ctx.clearRect(0, 0, 128, 128);
|
||||
drawRect("rgb(192, 192, 192)", [0, 0, 128, 128]);
|
||||
drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
|
||||
drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
|
||||
}
|
||||
|
||||
function start() {
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
function render() {
|
||||
window.requestAnimationFrame(render);
|
||||
}
|
||||
window.requestAnimationFrame(render);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,37 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var ctx = document.querySelector("canvas").getContext("2d");
|
||||
|
||||
function drawRect(fill, size) {
|
||||
ctx.fillStyle = fill;
|
||||
ctx.fillRect(size[0], size[1], size[2], size[3]);
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
ctx.clearRect(0, 0, 128, 128);
|
||||
drawRect("rgb(192, 192, 192)", [0, 0, 128, 128]);
|
||||
drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
|
||||
drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
|
||||
|
||||
window.setTimeout(drawScene, 50);
|
||||
}
|
||||
|
||||
drawScene();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,34 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var ctx = document.querySelector("canvas").getContext("2d");
|
||||
|
||||
function drawRect(fill, size) {
|
||||
ctx.fillStyle = fill;
|
||||
ctx.fillRect(size[0], size[1], size[2], size[3]);
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
ctx.clearRect(0, 0, 4, 4);
|
||||
drawRect("rgb(192, 192, 192)", [0, 0, 1, 1]);
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
|
||||
drawScene();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,46 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var ctx = document.querySelector("canvas").getContext("2d");
|
||||
|
||||
function drawRect(fill, size) {
|
||||
function A() {
|
||||
function B() {
|
||||
function C() {
|
||||
ctx.fillStyle = fill;
|
||||
ctx.fillRect(size[0], size[1], size[2], size[3]);
|
||||
}
|
||||
C();
|
||||
}
|
||||
B();
|
||||
}
|
||||
A();
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
ctx.clearRect(0, 0, 128, 128);
|
||||
drawRect("rgb(192, 192, 192)", [0, 0, 128, 128]);
|
||||
drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
|
||||
drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
|
||||
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
|
||||
drawScene();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,37 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var ctx = document.querySelector("canvas").getContext("2d");
|
||||
|
||||
function drawRect(fill, size) {
|
||||
ctx.fillStyle = fill;
|
||||
ctx.fillRect(size[0], size[1], size[2], size[3]);
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
ctx.clearRect(0, 0, 128, 128);
|
||||
drawRect("rgba(255, 255, 255, 0)", [0, 0, 128, 128]);
|
||||
drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
|
||||
drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
|
||||
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
|
||||
drawScene();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,37 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Canvas inspector test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
var ctx = document.querySelector("canvas").getContext("2d");
|
||||
|
||||
function drawRect(fill, size) {
|
||||
ctx.fillStyle = fill;
|
||||
ctx.fillRect(size[0], size[1], size[2], size[3]);
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
ctx.clearRect(0, 0, 128, 128);
|
||||
drawRect("rgb(192, 192, 192)", [0, 0, 128, 128]);
|
||||
drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
|
||||
drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
|
||||
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
|
||||
drawScene();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,61 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>WebGL editor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="canvas" width="1024" height="1024"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
let canvas, gl;
|
||||
let customFramebuffer;
|
||||
let customRenderbuffer;
|
||||
let customTexture;
|
||||
|
||||
window.onload = function() {
|
||||
canvas = document.querySelector("canvas");
|
||||
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
|
||||
gl.clearColor(1.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
customFramebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, customFramebuffer);
|
||||
|
||||
customRenderbuffer = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, customRenderbuffer);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1024, 1024);
|
||||
|
||||
customTexture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, customTexture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1024, 1024, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, customTexture, 0);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, customRenderbuffer);
|
||||
|
||||
gl.viewport(128, 256, 384, 512);
|
||||
gl.clearColor(0.0, 1.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
drawScene();
|
||||
};
|
||||
|
||||
function drawScene() {
|
||||
gl.clearColor(0.0, 0.0, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,187 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>WebGL editor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="canvas" width="128" height="128"></canvas>
|
||||
<script id="shader-fs" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform vec4 mtrColor;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0) * mtrColor;
|
||||
}
|
||||
</script>
|
||||
<script id="shader-vs" type="x-shader/x-vertex">
|
||||
attribute vec3 aVertexPosition;
|
||||
|
||||
void main(void) {
|
||||
gl_PointSize = 5.0;
|
||||
gl_Position = vec4(aVertexPosition, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
let canvas, gl, shaderProgram;
|
||||
let triangleVertexPositionBuffer, squareVertexPositionBuffer;
|
||||
|
||||
window.onload = function() {
|
||||
canvas = document.querySelector("canvas");
|
||||
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
|
||||
gl.viewportWidth = canvas.width;
|
||||
gl.viewportHeight = canvas.height;
|
||||
|
||||
initShaders();
|
||||
initBuffers();
|
||||
|
||||
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
drawScene();
|
||||
};
|
||||
|
||||
function getShader(gl, id) {
|
||||
var shaderScript = document.getElementById(id);
|
||||
if (!shaderScript) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var str = "";
|
||||
var k = shaderScript.firstChild;
|
||||
while (k) {
|
||||
if (k.nodeType == 3) {
|
||||
str += k.textContent;
|
||||
}
|
||||
k = k.nextSibling;
|
||||
}
|
||||
|
||||
var shader;
|
||||
if (shaderScript.type == "x-shader/x-fragment") {
|
||||
shader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
} else if (shaderScript.type == "x-shader/x-vertex") {
|
||||
shader = gl.createShader(gl.VERTEX_SHADER);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
gl.shaderSource(shader, str);
|
||||
gl.compileShader(shader);
|
||||
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||
alert(gl.getShaderInfoLog(shader));
|
||||
return null;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
function initShaders() {
|
||||
var fragmentShader = getShader(gl, "shader-fs");
|
||||
var vertexShader = getShader(gl, "shader-vs");
|
||||
|
||||
shaderProgram = gl.createProgram();
|
||||
gl.attachShader(shaderProgram, vertexShader);
|
||||
gl.attachShader(shaderProgram, fragmentShader);
|
||||
gl.linkProgram(shaderProgram);
|
||||
|
||||
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
||||
alert("Could not initialise shaders");
|
||||
}
|
||||
|
||||
gl.useProgram(shaderProgram);
|
||||
|
||||
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
|
||||
shaderProgram.pMaterialColor = gl.getUniformLocation(shaderProgram, "mtrColor");
|
||||
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
|
||||
}
|
||||
|
||||
function initBuffers() {
|
||||
// Create triangle vertex/index buffer
|
||||
triangleVertexPositionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
|
||||
var vertices = [
|
||||
0.0, 0.5, 0.0,
|
||||
-0.5, -0.5, 0.0,
|
||||
0.5, -0.5, 0.0,
|
||||
];
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
||||
triangleVertexPositionBuffer.itemSize = 3;
|
||||
triangleVertexPositionBuffer.numItems = 3;
|
||||
|
||||
// Create square vertex/index buffer
|
||||
squareVertexPositionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
vertices = [
|
||||
0.8, 0.8, 0.0,
|
||||
-0.8, 0.8, 0.0,
|
||||
0.8, -0.8, 0.0,
|
||||
-0.8, -0.8, 0.0,
|
||||
];
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
||||
squareVertexPositionBuffer.itemSize = 3;
|
||||
squareVertexPositionBuffer.numItems = 4;
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
// DrawArrays
|
||||
// --------------
|
||||
// draw square - triangle strip
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 1, 1, 1, 1);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
|
||||
|
||||
// draw square - triangle fan
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0, 1, 0, 1);
|
||||
gl.drawArrays(gl.TRIANGLE_FAN, 0, squareVertexPositionBuffer.numItems);
|
||||
|
||||
// draw triangle
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 1, 0, 0, 1);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
|
||||
|
||||
// draw points
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 1, 0, 1, 1);
|
||||
gl.drawArrays(gl.POINTS, 0, squareVertexPositionBuffer.numItems);
|
||||
|
||||
// draw lines
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0, 0, 1, 1);
|
||||
gl.lineWidth(8.0);
|
||||
gl.drawArrays(gl.LINES, 0, squareVertexPositionBuffer.numItems);
|
||||
|
||||
// draw line strip
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0.9, 0.6, 0, 1);
|
||||
gl.lineWidth(3.0);
|
||||
gl.drawArrays(gl.LINE_STRIP, 0, squareVertexPositionBuffer.numItems);
|
||||
|
||||
// draw line loop
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0, 1, 1, 1);
|
||||
gl.lineWidth(3.0);
|
||||
gl.drawArrays(gl.LINE_LOOP, 0, triangleVertexPositionBuffer.numItems);
|
||||
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,224 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>WebGL editor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="canvas" width="128" height="128"></canvas>
|
||||
<script id="shader-fs" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform vec4 mtrColor;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0) * mtrColor;
|
||||
}
|
||||
</script>
|
||||
<script id="shader-vs" type="x-shader/x-vertex">
|
||||
attribute vec3 aVertexPosition;
|
||||
|
||||
void main(void) {
|
||||
gl_PointSize = 5.0;
|
||||
gl_Position = vec4(aVertexPosition, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
let canvas, gl, shaderProgram;
|
||||
let triangleVertexPositionBuffer, squareVertexPositionBuffer;
|
||||
let triangleIndexBuffer;
|
||||
let squareIndexBuffer, squareStripIndexBuffer, squareFanIndexBuffer;
|
||||
|
||||
window.onload = function() {
|
||||
canvas = document.querySelector("canvas");
|
||||
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
|
||||
gl.viewportWidth = canvas.width;
|
||||
gl.viewportHeight = canvas.height;
|
||||
|
||||
initShaders();
|
||||
initBuffers();
|
||||
|
||||
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
drawScene();
|
||||
};
|
||||
|
||||
function getShader(gl, id) {
|
||||
var shaderScript = document.getElementById(id);
|
||||
if (!shaderScript) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var str = "";
|
||||
var k = shaderScript.firstChild;
|
||||
while (k) {
|
||||
if (k.nodeType == 3) {
|
||||
str += k.textContent;
|
||||
}
|
||||
k = k.nextSibling;
|
||||
}
|
||||
|
||||
var shader;
|
||||
if (shaderScript.type == "x-shader/x-fragment") {
|
||||
shader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
} else if (shaderScript.type == "x-shader/x-vertex") {
|
||||
shader = gl.createShader(gl.VERTEX_SHADER);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
gl.shaderSource(shader, str);
|
||||
gl.compileShader(shader);
|
||||
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||
alert(gl.getShaderInfoLog(shader));
|
||||
return null;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
function initShaders() {
|
||||
var fragmentShader = getShader(gl, "shader-fs");
|
||||
var vertexShader = getShader(gl, "shader-vs");
|
||||
|
||||
shaderProgram = gl.createProgram();
|
||||
gl.attachShader(shaderProgram, vertexShader);
|
||||
gl.attachShader(shaderProgram, fragmentShader);
|
||||
gl.linkProgram(shaderProgram);
|
||||
|
||||
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
|
||||
alert("Could not initialise shaders");
|
||||
}
|
||||
|
||||
gl.useProgram(shaderProgram);
|
||||
|
||||
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
|
||||
shaderProgram.pMaterialColor = gl.getUniformLocation(shaderProgram, "mtrColor");
|
||||
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
|
||||
}
|
||||
|
||||
function initBuffers() {
|
||||
// Create triangle vertex/index buffer
|
||||
triangleVertexPositionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
|
||||
var vertices = [
|
||||
0.0, 0.5, 0.0,
|
||||
-0.5, -0.5, 0.0,
|
||||
0.5, -0.5, 0.0,
|
||||
];
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
||||
triangleVertexPositionBuffer.itemSize = 3;
|
||||
triangleVertexPositionBuffer.numItems = 3;
|
||||
|
||||
triangleIndexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleIndexBuffer);
|
||||
var indices = [
|
||||
0, 1, 2,
|
||||
];
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
|
||||
triangleIndexBuffer.itemSize = 1;
|
||||
triangleIndexBuffer.numItems = 3;
|
||||
|
||||
// Create square vertex/index buffer
|
||||
squareVertexPositionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
vertices = [
|
||||
0.8, 0.8, 0.0,
|
||||
-0.8, 0.8, 0.0,
|
||||
0.8, -0.8, 0.0,
|
||||
-0.8, -0.8, 0.0,
|
||||
];
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
|
||||
squareVertexPositionBuffer.itemSize = 3;
|
||||
squareVertexPositionBuffer.numItems = 4;
|
||||
|
||||
squareIndexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer);
|
||||
indices = [
|
||||
0, 1, 2,
|
||||
1, 3, 2,
|
||||
];
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
|
||||
squareIndexBuffer.itemSize = 1;
|
||||
squareIndexBuffer.numItems = 6;
|
||||
|
||||
squareStripIndexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareStripIndexBuffer);
|
||||
indices = [
|
||||
0, 1, 2, 3,
|
||||
];
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
|
||||
squareStripIndexBuffer.itemSize = 1;
|
||||
squareStripIndexBuffer.numItems = 4;
|
||||
}
|
||||
|
||||
function drawScene() {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
// DrawElements
|
||||
// --------------
|
||||
// draw triangle
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 1, 1, 1, 1);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer);
|
||||
gl.drawElements(gl.TRIANGLES, squareIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw square - triangle strip
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0, 1, 0, 1);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareStripIndexBuffer);
|
||||
gl.drawElements(gl.TRIANGLE_FAN, squareStripIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw square - triangle fan
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 1, 0, 0, 1);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleIndexBuffer);
|
||||
gl.drawElements(gl.TRIANGLE_FAN, triangleIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw points
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 1, 0, 1, 1);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareStripIndexBuffer);
|
||||
gl.drawElements(gl.POINTS, squareStripIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw lines
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0, 0, 1, 1);
|
||||
gl.lineWidth(8.0);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareStripIndexBuffer);
|
||||
gl.drawElements(gl.LINES, squareStripIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw line strip
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0.9, 0.6, 0, 1);
|
||||
gl.lineWidth(3.0);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareStripIndexBuffer);
|
||||
gl.drawElements(gl.LINE_STRIP, squareStripIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
// draw line loop
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
|
||||
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
|
||||
gl.uniform4f(shaderProgram.pMaterialColor, 0, 1, 1, 1);
|
||||
gl.lineWidth(3.0);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleIndexBuffer);
|
||||
gl.drawElements(gl.LINE_LOOP, triangleIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
|
||||
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,34 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>WebGL editor test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="canvas" width="128" height="128"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
let canvas, gl;
|
||||
|
||||
window.onload = function() {
|
||||
canvas = document.querySelector("canvas");
|
||||
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
drawScene();
|
||||
};
|
||||
|
||||
function drawScene() {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
window.requestAnimationFrame(drawScene);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,198 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
||||
/* import-globals-from ../../shared/test/shared-head.js */
|
||||
/* import-globals-from ../../debugger/new/test/mochitest/helpers/context.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Load the shared-head file first.
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
|
||||
this);
|
||||
|
||||
// Import helpers for the new debugger
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/debugger/new/test/mochitest/helpers/context.js",
|
||||
this);
|
||||
|
||||
var { generateUUID } = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
|
||||
|
||||
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
||||
var { DebuggerServer } = require("devtools/server/main");
|
||||
var { METHOD_FUNCTION } = require("devtools/shared/fronts/function-call");
|
||||
var { Toolbox } = require("devtools/client/framework/toolbox");
|
||||
var { isWebGLSupported } = require("devtools/client/shared/webgl-utils");
|
||||
|
||||
const EXAMPLE_URL = "http://example.com/browser/devtools/client/canvasdebugger/test/";
|
||||
const SET_TIMEOUT_URL = EXAMPLE_URL + "doc_settimeout.html";
|
||||
const NO_CANVAS_URL = EXAMPLE_URL + "doc_no-canvas.html";
|
||||
const RAF_NO_CANVAS_URL = EXAMPLE_URL + "doc_raf-no-canvas.html";
|
||||
const SIMPLE_CANVAS_URL = EXAMPLE_URL + "doc_simple-canvas.html";
|
||||
const SIMPLE_BITMASKS_URL = EXAMPLE_URL + "doc_simple-canvas-bitmasks.html";
|
||||
const SIMPLE_CANVAS_TRANSPARENT_URL = EXAMPLE_URL + "doc_simple-canvas-transparent.html";
|
||||
const SIMPLE_CANVAS_DEEP_STACK_URL = EXAMPLE_URL + "doc_simple-canvas-deep-stack.html";
|
||||
const WEBGL_ENUM_URL = EXAMPLE_URL + "doc_webgl-enum.html";
|
||||
const WEBGL_BINDINGS_URL = EXAMPLE_URL + "doc_webgl-bindings.html";
|
||||
const WEBGL_DRAW_ARRAYS = EXAMPLE_URL + "doc_webgl-drawArrays.html";
|
||||
const WEBGL_DRAW_ELEMENTS = EXAMPLE_URL + "doc_webgl-drawElements.html";
|
||||
const RAF_BEGIN_URL = EXAMPLE_URL + "doc_raf-begin.html";
|
||||
|
||||
// Disable logging for all the tests. Both the debugger server and frontend will
|
||||
// be affected by this pref.
|
||||
var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
var gToolEnabled = Services.prefs.getBoolPref("devtools.canvasdebugger.enabled");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
|
||||
Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", gToolEnabled);
|
||||
|
||||
// Some of yhese tests use a lot of memory due to GL contexts, so force a GC
|
||||
// to help fragmentation.
|
||||
info("Forcing GC after canvas debugger test.");
|
||||
Cu.forceGC();
|
||||
});
|
||||
|
||||
function handleError(aError) {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
finish();
|
||||
}
|
||||
|
||||
var gRequiresWebGL = false;
|
||||
|
||||
function ifTestingSupported() {
|
||||
ok(false, "You need to define a 'ifTestingSupported' function.");
|
||||
finish();
|
||||
}
|
||||
|
||||
function ifTestingUnsupported() {
|
||||
todo(false, "Skipping test because some required functionality isn't supported.");
|
||||
finish();
|
||||
}
|
||||
|
||||
async function test() {
|
||||
const generator = isTestingSupported() ? ifTestingSupported : ifTestingUnsupported;
|
||||
try {
|
||||
await generator();
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
function createCanvas() {
|
||||
return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
}
|
||||
|
||||
function isTestingSupported() {
|
||||
if (!gRequiresWebGL) {
|
||||
info("This test does not require WebGL support.");
|
||||
return true;
|
||||
}
|
||||
|
||||
const supported = isWebGLSupported(document);
|
||||
|
||||
info("This test requires WebGL support.");
|
||||
info("Apparently, WebGL is" + (supported ? "" : " not") + " supported.");
|
||||
return supported;
|
||||
}
|
||||
|
||||
function navigateInHistory(aTarget, aDirection, aWaitForTargetEvent = "navigate") {
|
||||
executeSoon(() => content.history[aDirection]());
|
||||
return once(aTarget, aWaitForTargetEvent);
|
||||
}
|
||||
|
||||
function navigate(aTarget, aUrl, aWaitForTargetEvent = "navigate") {
|
||||
executeSoon(() => aTarget.navigateTo({ url: aUrl }));
|
||||
return once(aTarget, aWaitForTargetEvent);
|
||||
}
|
||||
|
||||
function reload(aTarget, aWaitForTargetEvent = "navigate") {
|
||||
executeSoon(() => aTarget.reload());
|
||||
return once(aTarget, aWaitForTargetEvent);
|
||||
}
|
||||
|
||||
function initServer() {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.registerAllActors();
|
||||
}
|
||||
|
||||
function initCallWatcherBackend(aUrl) {
|
||||
info("Initializing a call watcher front.");
|
||||
initServer();
|
||||
|
||||
return (async function() {
|
||||
const tab = await addTab(aUrl);
|
||||
|
||||
await registerActorInContentProcess("chrome://mochitests/content/browser/devtools/client/canvasdebugger/test/call-watcher-actor.js", {
|
||||
prefix: "callWatcher",
|
||||
constructor: "CallWatcherActor",
|
||||
type: { target: true },
|
||||
});
|
||||
|
||||
const target = await TargetFactory.forTab(tab);
|
||||
await target.attach();
|
||||
|
||||
// Load the Front module in order to register it and have getFront to find it.
|
||||
require("chrome://mochitests/content/browser/devtools/client/canvasdebugger/test/call-watcher-front.js");
|
||||
|
||||
const front = await target.getFront("call-watcher");
|
||||
return { target, front };
|
||||
})();
|
||||
}
|
||||
|
||||
function initCanvasDebuggerBackend(aUrl) {
|
||||
info("Initializing a canvas debugger front.");
|
||||
initServer();
|
||||
|
||||
return (async function() {
|
||||
const tab = await addTab(aUrl);
|
||||
const target = await TargetFactory.forTab(tab);
|
||||
await target.attach();
|
||||
|
||||
const front = await target.getFront("canvas");
|
||||
return { target, front };
|
||||
})();
|
||||
}
|
||||
|
||||
function initCanvasDebuggerFrontend(aUrl) {
|
||||
info("Initializing a canvas debugger pane.");
|
||||
|
||||
return (async function() {
|
||||
const tab = await addTab(aUrl);
|
||||
const target = await TargetFactory.forTab(tab);
|
||||
|
||||
await target.attach();
|
||||
|
||||
Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", true);
|
||||
const toolbox = await gDevTools.showToolbox(target, "canvasdebugger");
|
||||
const panel = toolbox.getCurrentPanel();
|
||||
return { target, panel };
|
||||
})();
|
||||
}
|
||||
|
||||
function teardown({target}) {
|
||||
info("Destroying the specified canvas debugger.");
|
||||
|
||||
const {tab} = target;
|
||||
return gDevTools.closeToolbox(target).then(() => {
|
||||
removeTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
function getSourceActor(aSources, aURL) {
|
||||
const item = aSources.getItemForAttachment(a => a.source.url === aURL);
|
||||
return item ? item.value : null;
|
||||
}
|
||||
|
||||
async function validateDebuggerLocation(dbg, url, line) {
|
||||
const location = dbg.selectors.getSelectedLocation(dbg.getState());
|
||||
const sourceUrl = dbg.selectors.getSelectedSource(dbg.getState()).url;
|
||||
|
||||
is(sourceUrl, url,
|
||||
"The expected source was shown in the debugger.");
|
||||
is(location.line, line,
|
||||
"The expected source line is highlighted in the debugger.");
|
||||
}
|
|
@ -14,7 +14,6 @@ loader.lazyGetter(this, "InspectorPanel", () => require("devtools/client/inspect
|
|||
loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/client/webconsole/panel").WebConsolePanel);
|
||||
loader.lazyGetter(this, "NewDebuggerPanel", () => require("devtools/client/debugger/new/panel").DebuggerPanel);
|
||||
loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/client/styleeditor/panel").StyleEditorPanel);
|
||||
loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/client/canvasdebugger/panel").CanvasDebuggerPanel);
|
||||
loader.lazyGetter(this, "WebAudioEditorPanel", () => require("devtools/client/webaudioeditor/panel").WebAudioEditorPanel);
|
||||
loader.lazyGetter(this, "MemoryPanel", () => require("devtools/client/memory/panel").MemoryPanel);
|
||||
loader.lazyGetter(this, "PerformancePanel", () => require("devtools/client/performance/panel").PerformancePanel);
|
||||
|
@ -204,29 +203,6 @@ Tools.shaderEditor = {
|
|||
},
|
||||
};
|
||||
|
||||
Tools.canvasDebugger = {
|
||||
id: "canvasdebugger",
|
||||
deprecated: true,
|
||||
deprecationURL: DEPRECATION_URL,
|
||||
ordinal: 6,
|
||||
visibilityswitch: "devtools.canvasdebugger.enabled",
|
||||
icon: "chrome://devtools/skin/images/tool-canvas.svg",
|
||||
url: "chrome://devtools/content/canvasdebugger/index.xul",
|
||||
label: l10n("ToolboxCanvasDebugger.label"),
|
||||
panelLabel: l10n("ToolboxCanvasDebugger.panelLabel"),
|
||||
tooltip: l10n("ToolboxCanvasDebugger.tooltip"),
|
||||
|
||||
// Hide the Canvas Debugger in the Add-on Debugger and Browser Toolbox
|
||||
// (bug 1047520).
|
||||
isTargetSupported: function(target) {
|
||||
return target.hasActor("canvas") && !target.chrome;
|
||||
},
|
||||
|
||||
build: function(iframeWindow, toolbox) {
|
||||
return new CanvasDebuggerPanel(iframeWindow, toolbox);
|
||||
},
|
||||
};
|
||||
|
||||
Tools.performance = {
|
||||
id: "performance",
|
||||
ordinal: 7,
|
||||
|
@ -467,7 +443,6 @@ var defaultTools = [
|
|||
Tools.jsdebugger,
|
||||
Tools.styleEditor,
|
||||
Tools.shaderEditor,
|
||||
Tools.canvasDebugger,
|
||||
Tools.webAudioEditor,
|
||||
Tools.performance,
|
||||
Tools.netMonitor,
|
||||
|
|
|
@ -24,10 +24,6 @@ devtools.jar:
|
|||
content/shared/sourceeditor/codemirror/cmiframe.html (shared/sourceeditor/codemirror/cmiframe.html)
|
||||
content/debugger/new/index.html (debugger/new/index.html)
|
||||
content/shadereditor/index.xul (shadereditor/index.xul)
|
||||
content/canvasdebugger/index.xul (canvasdebugger/index.xul)
|
||||
content/canvasdebugger/canvasdebugger.js (canvasdebugger/canvasdebugger.js)
|
||||
content/canvasdebugger/snapshotslist.js (canvasdebugger/snapshotslist.js)
|
||||
content/canvasdebugger/callslist.js (canvasdebugger/callslist.js)
|
||||
content/webaudioeditor/index.xul (webaudioeditor/index.xul)
|
||||
content/webaudioeditor/includes.js (webaudioeditor/includes.js)
|
||||
content/webaudioeditor/models.js (webaudioeditor/models.js)
|
||||
|
@ -134,7 +130,6 @@ devtools.jar:
|
|||
skin/images/webconsole/return.svg (themes/images/webconsole/return.svg)
|
||||
skin/images/breadcrumbs-scrollbutton.svg (themes/images/breadcrumbs-scrollbutton.svg)
|
||||
skin/animation.css (themes/animation.css)
|
||||
skin/canvasdebugger.css (themes/canvasdebugger.css)
|
||||
skin/perf.css (themes/perf.css)
|
||||
skin/performance.css (themes/performance.css)
|
||||
skin/memory.css (themes/memory.css)
|
||||
|
@ -163,9 +158,6 @@ devtools.jar:
|
|||
skin/images/pause.svg (themes/images/pause.svg)
|
||||
skin/images/play.svg (themes/images/play.svg)
|
||||
skin/images/rewind.svg (themes/images/rewind.svg)
|
||||
skin/images/canvasdebugger-step-in.svg (themes/images/canvasdebugger-step-in.svg)
|
||||
skin/images/canvasdebugger-step-out.svg (themes/images/canvasdebugger-step-out.svg)
|
||||
skin/images/canvasdebugger-step-over.svg (themes/images/canvasdebugger-step-over.svg)
|
||||
skin/images/dock-bottom.svg (themes/images/dock-bottom.svg)
|
||||
skin/images/dock-side-left.svg (themes/images/dock-side-left.svg)
|
||||
skin/images/dock-side-right.svg (themes/images/dock-side-right.svg)
|
||||
|
@ -186,7 +178,6 @@ devtools.jar:
|
|||
skin/images/sad-face.svg (themes/images/sad-face.svg)
|
||||
skin/images/shape-swatch.svg (themes/images/shape-swatch.svg)
|
||||
skin/images/tool-webconsole.svg (themes/images/tool-webconsole.svg)
|
||||
skin/images/tool-canvas.svg (themes/images/tool-canvas.svg)
|
||||
skin/images/tool-debugger.svg (themes/images/tool-debugger.svg)
|
||||
skin/images/tool-inspector.svg (themes/images/tool-inspector.svg)
|
||||
skin/images/tool-shadereditor.svg (themes/images/tool-shadereditor.svg)
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE : FILE This file contains the Debugger strings -->
|
||||
<!-- LOCALIZATION NOTE : FILE Do not translate commandkey -->
|
||||
|
||||
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
|
||||
- keep it in English, or another language commonly spoken among web developers.
|
||||
- You want to make that choice consistent across the developer tools.
|
||||
- A good criteria is the language in which you'd find the best
|
||||
- documentation on web development on the web. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.reloadNotice1): This is the label shown
|
||||
- on the button that triggers a page refresh. -->
|
||||
<!ENTITY canvasDebuggerUI.reloadNotice1 "Reload">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.reloadNotice2): This is the label shown
|
||||
- along with the button that triggers a page refresh. -->
|
||||
<!ENTITY canvasDebuggerUI.reloadNotice2 "the page to be able to debug <canvas> contexts.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.emptyNotice1/2): This is the label shown
|
||||
- in the call list view when empty. -->
|
||||
<!ENTITY canvasDebuggerUI.emptyNotice1 "Click on the">
|
||||
<!ENTITY canvasDebuggerUI.emptyNotice2 "button to record an animation frame’s call stack.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.waitingNotice): This is the label shown
|
||||
- in the call list view while recording a snapshot. -->
|
||||
<!ENTITY canvasDebuggerUI.waitingNotice "Recording an animation cycle…">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.recordSnapshot): This string is displayed
|
||||
- on a button that starts a new snapshot. -->
|
||||
<!ENTITY canvasDebuggerUI.recordSnapshot.tooltip "Record the next frame in the animation loop.">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.importSnapshot): This string is displayed
|
||||
- on a button that opens a dialog to import a saved snapshot data file. -->
|
||||
<!ENTITY canvasDebuggerUI.importSnapshot "Import…">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.clearSnapshots): This string is displayed
|
||||
- on a button that remvoes all the snapshots. -->
|
||||
<!ENTITY canvasDebuggerUI.clearSnapshots "Clear">
|
||||
|
||||
<!-- LOCALIZATION NOTE (canvasDebuggerUI.searchboxPlaceholder): This string is displayed
|
||||
- as a placeholder of the search box that filters the calls list. -->
|
||||
<!ENTITY canvasDebuggerUI.searchboxPlaceholder "Filter calls">
|
|
@ -1,70 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# LOCALIZATION NOTE These strings are used inside the Canvas Debugger
|
||||
# which is available from the Web Developer sub-menu -> 'Canvas'.
|
||||
# The correct localization of this file might be to keep it in
|
||||
# English, or another language commonly spoken among web developers.
|
||||
# You want to make that choice consistent across the developer tools.
|
||||
# A good criteria is the language in which you'd find the best
|
||||
# documentation on web development on the web.
|
||||
|
||||
# LOCALIZATION NOTE (noSnapshotsText): The text to display in the snapshots menu
|
||||
# when there are no recorded snapshots yet.
|
||||
noSnapshotsText=There are no snapshots yet.
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.itemLabel):
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# identifying a set of function calls of a recorded animation frame.
|
||||
snapshotsList.itemLabel=Snapshot #%S
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.loadingLabel):
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# for an item that has not finished loading.
|
||||
snapshotsList.loadingLabel=Loading…
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.saveLabel):
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# for saving an item to disk.
|
||||
snapshotsList.saveLabel=Save
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.savingLabel):
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# while saving an item to disk.
|
||||
snapshotsList.savingLabel=Saving…
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.loadedLabel):
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# for an item which was loaded from disk
|
||||
snapshotsList.loadedLabel=Loaded from disk
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.saveDialogTitle):
|
||||
# This string is displayed as a title for saving a snapshot to disk.
|
||||
snapshotsList.saveDialogTitle=Save animation frame snapshot…
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.saveDialogJSONFilter):
|
||||
# This string is displayed as a filter for saving a snapshot to disk.
|
||||
snapshotsList.saveDialogJSONFilter=JSON Files
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.saveDialogAllFilter):
|
||||
# This string is displayed as a filter for saving a snapshot to disk.
|
||||
snapshotsList.saveDialogAllFilter=All Files
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.drawCallsLabel):
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# as a generic description about how many draw calls were made.
|
||||
snapshotsList.drawCallsLabel=#1 draw;#1 draws
|
||||
|
||||
# LOCALIZATION NOTE (snapshotsList.functionCallsLabel):
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
# This string is displayed in the snapshots list of the Canvas Debugger,
|
||||
# as a generic description about how many function calls were made in total.
|
||||
snapshotsList.functionCallsLabel=#1 call;#1 calls
|
||||
|
||||
# LOCALIZATION NOTE (recordingTimeoutFailure):
|
||||
# This notification alert is displayed when attempting to record a requestAnimationFrame
|
||||
# cycle in the Canvas Debugger and no cycles detected. This alerts the user that no
|
||||
# loops were found.
|
||||
recordingTimeoutFailure=Canvas Debugger could not find a requestAnimationFrame or setTimeout cycle.
|
|
@ -112,20 +112,6 @@ ToolboxShaderEditor.panelLabel=Shader Editor Panel
|
|||
# displayed inside the developer tools window.
|
||||
ToolboxShaderEditor.tooltip=Live GLSL shader language editor for WebGL
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxCanvasDebugger.label):
|
||||
# This string is displayed in the title of the tab when the Shader Editor is
|
||||
# displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
ToolboxCanvasDebugger.label=Canvas
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxCanvasDebugger.panelLabel):
|
||||
# This is used as the label for the toolbox panel.
|
||||
ToolboxCanvasDebugger.panelLabel=Canvas Panel
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxCanvasDebugger.tooltip):
|
||||
# This string is displayed in the tooltip of the tab when the Shader Editor is
|
||||
# displayed inside the developer tools window.
|
||||
ToolboxCanvasDebugger.tooltip=Tools to inspect and debug <canvas> contexts
|
||||
|
||||
# LOCALIZATION NOTE (ToolboxWebAudioEditor1.label):
|
||||
# This string is displayed in the title of the tab when the Web Audio Editor
|
||||
# is displayed inside the developer tools window and in the Developer Tools Menu.
|
||||
|
|
|
@ -11,7 +11,6 @@ DIRS += [
|
|||
'aboutdebugging-new',
|
||||
'accessibility',
|
||||
'application',
|
||||
'canvasdebugger',
|
||||
'debugger',
|
||||
'dom',
|
||||
'framework',
|
||||
|
|
|
@ -232,9 +232,6 @@ pref("devtools.screenshot.audio.enabled", true);
|
|||
// Enable the Shader Editor.
|
||||
pref("devtools.shadereditor.enabled", false);
|
||||
|
||||
// Enable the Canvas Debugger.
|
||||
pref("devtools.canvasdebugger.enabled", false);
|
||||
|
||||
// Enable the Web Audio Editor
|
||||
pref("devtools.webaudioeditor.enabled", false);
|
||||
|
||||
|
|
|
@ -692,7 +692,6 @@ function getChartsFromToolId(id) {
|
|||
switch (id) {
|
||||
case "ABOUTDEBUGGING":
|
||||
case "BROWSERCONSOLE":
|
||||
case "CANVASDEBUGGER":
|
||||
case "DOM":
|
||||
case "INSPECTOR":
|
||||
case "JSBROWSERDEBUGGER":
|
||||
|
|
|
@ -215,7 +215,6 @@ skip-if = !e10s || os == "win" # RDM only works for remote tabs, Win: bug 140419
|
|||
[browser_telemetry_misc.js]
|
||||
[browser_telemetry_sidebar.js]
|
||||
[browser_telemetry_toolbox.js]
|
||||
[browser_telemetry_toolboxtabs_canvasdebugger.js]
|
||||
[browser_telemetry_toolboxtabs_inspector.js]
|
||||
[browser_telemetry_toolboxtabs_jsdebugger.js]
|
||||
[browser_telemetry_toolboxtabs_jsprofiler.js]
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<p>browser_telemetry_toolboxtabs_canvasdebugger.js</p>";
|
||||
|
||||
// Because we need to gather stats for the period of time that a tool has been
|
||||
// opened we make use of setTimeout() to create tool active times.
|
||||
const TOOL_DELAY = 200;
|
||||
|
||||
add_task(async function() {
|
||||
info("Activate the canvasdebugger");
|
||||
const originalPref = Services.prefs.getBoolPref("devtools.canvasdebugger.enabled");
|
||||
Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", true);
|
||||
|
||||
await addTab(TEST_URI);
|
||||
startTelemetry();
|
||||
|
||||
await openAndCloseToolbox(2, TOOL_DELAY, "canvasdebugger");
|
||||
checkResults();
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
info("De-activate the canvasdebugger");
|
||||
Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", originalPref);
|
||||
});
|
||||
|
||||
function checkResults() {
|
||||
// For help generating these tests use generateTelemetryTests("DEVTOOLS_CANVASDEBUGGER")
|
||||
// here.
|
||||
checkTelemetry("DEVTOOLS_CANVASDEBUGGER_OPENED_COUNT", "", {0: 2, 1: 0}, "array");
|
||||
checkTelemetry("DEVTOOLS_CANVASDEBUGGER_TIME_ACTIVE_SECONDS", "", null, "hasentries");
|
||||
}
|
|
@ -1,345 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
:root {
|
||||
--gutter-width: 3em;
|
||||
--gutter-padding-start: 22px;
|
||||
--checkerboard-pattern: linear-gradient(45deg, rgba(128,128,128,0.2) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.2) 75%, rgba(128,128,128,0.2)),
|
||||
linear-gradient(45deg, rgba(128,128,128,0.2) 25%, transparent 25%, transparent 75%, rgba(128,128,128,0.2) 75%, rgba(128,128,128,0.2));
|
||||
}
|
||||
|
||||
:root.theme-dark {
|
||||
--draw-call-background: rgba(112,191,83,0.15);
|
||||
--interesting-call-background: rgba(223,128,255,0.15);
|
||||
}
|
||||
|
||||
:root.theme-light {
|
||||
--draw-call-background: rgba(44,187,15,0.1);
|
||||
--interesting-call-background: rgba(184,46,229,0.1);
|
||||
}
|
||||
|
||||
/* Reload and waiting notices */
|
||||
|
||||
.notice-container {
|
||||
margin-top: -50vh;
|
||||
color: var(--theme-body-color-alt);
|
||||
}
|
||||
|
||||
#empty-notice > button {
|
||||
min-width: 30px;
|
||||
min-height: 28px;
|
||||
margin: 0;
|
||||
list-style-image: url(images/profiler-stopwatch.svg);
|
||||
}
|
||||
|
||||
#empty-notice > button .button-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#waiting-notice {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
/* Snapshots pane */
|
||||
|
||||
#snapshots-pane {
|
||||
border-inline-end: 1px solid var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
#record-snapshot {
|
||||
list-style-image: url("chrome://devtools/skin/images/profiler-stopwatch.svg");
|
||||
}
|
||||
|
||||
#import-snapshot {
|
||||
list-style-image: url("images/import.svg");
|
||||
}
|
||||
|
||||
/* Snapshots items */
|
||||
|
||||
.snapshot-item-thumbnail {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
background-image: var(--checkerboard-pattern);
|
||||
background-size: 12px 12px, 12px 12px;
|
||||
background-position: 0px 0px, 6px 6px;
|
||||
background-repeat: repeat, repeat;
|
||||
}
|
||||
|
||||
.snapshot-item-thumbnail[flipped=true] {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.snapshot-item-thumbnail {
|
||||
background-color: var(--theme-body-background);
|
||||
}
|
||||
|
||||
.snapshot-item-details {
|
||||
padding-inline-start: 6px;
|
||||
}
|
||||
|
||||
.snapshot-item-calls {
|
||||
padding-top: 4px;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.snapshot-item-save {
|
||||
padding-bottom: 2px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.snapshot-item-calls,
|
||||
.snapshot-item-save {
|
||||
color: var(--theme-body-color-alt);
|
||||
}
|
||||
|
||||
.snapshot-item-save {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.snapshot-item-save[disabled=true] {
|
||||
text-decoration: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.snapshot-item-footer.devtools-throbber::before {
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
#snapshots-list .selected label {
|
||||
/* Text inside a selected item should not be custom colored. */
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* Debugging pane controls */
|
||||
#resume {
|
||||
list-style-image: url(images/play.svg);
|
||||
}
|
||||
|
||||
#step-over {
|
||||
list-style-image: url(images/canvasdebugger-step-over.svg);
|
||||
}
|
||||
|
||||
#step-in {
|
||||
list-style-image: url(images/canvasdebugger-step-in.svg);
|
||||
}
|
||||
|
||||
#step-out {
|
||||
list-style-image: url(images/canvasdebugger-step-out.svg);
|
||||
}
|
||||
|
||||
#debugging-toolbar-sizer-button {
|
||||
/* This button's only purpose in life is to make the
|
||||
container .devtools-toolbar have the right height. */
|
||||
visibility: hidden;
|
||||
min-width: 1px;
|
||||
}
|
||||
|
||||
/* Calls list pane */
|
||||
|
||||
#calls-list .side-menu-widget-container {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Calls list items */
|
||||
|
||||
#calls-list .side-menu-widget-item {
|
||||
padding: 0;
|
||||
border-color: var(--theme-splitter-color);
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.call-item-view:hover {
|
||||
background-color: rgba(128,128,128,0.05);
|
||||
}
|
||||
|
||||
.call-item-view[draw-call] {
|
||||
background-color: var(--draw-call-background);
|
||||
}
|
||||
|
||||
.call-item-view[interesting-call] {
|
||||
background-color: var(--interesting-call-background);
|
||||
}
|
||||
|
||||
.call-item-gutter {
|
||||
width: calc(var(--gutter-width) + var(--gutter-padding-start));
|
||||
padding-inline-start: var(--gutter-padding-start);
|
||||
padding-inline-end: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
border-inline-end: 1px solid var(--theme-splitter-color);
|
||||
margin-inline-end: 6px;
|
||||
background-color: var(--theme-sidebar-background);
|
||||
color: var(--theme-content-color3);
|
||||
}
|
||||
|
||||
.selected .call-item-gutter {
|
||||
background-color: #2cbb0f;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.call-item-index {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.call-item-context {
|
||||
color: var(--theme-highlight-orange);
|
||||
}
|
||||
|
||||
.call-item-name {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
.call-item-location {
|
||||
padding-inline-start: 2px;
|
||||
padding-inline-end: 6px;
|
||||
text-align: end;
|
||||
cursor: pointer;
|
||||
color: var(--theme-highlight-bluegrey);
|
||||
border-color: var(--theme-splitter-color);
|
||||
}
|
||||
|
||||
.call-item-location:hover {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
.call-item-view:hover .call-item-location,
|
||||
.call-item-view[expanded] .call-item-location {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.call-item-stack {
|
||||
padding-inline-start: calc(var(--gutter-width) + var(--gutter-padding-start));
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.theme-dark .call-item-stack {
|
||||
background: rgba(0,0,0,0.9);
|
||||
}
|
||||
|
||||
.theme-light .call-item-stack {
|
||||
background: rgba(255,255,255,0.9);
|
||||
}
|
||||
|
||||
.call-item-stack-fn {
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.call-item-stack-fn-location {
|
||||
padding-inline-start: 2px;
|
||||
padding-inline-end: 6px;
|
||||
text-align: end;
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.call-item-stack-fn-name {
|
||||
color: var(--theme-content-color3);
|
||||
}
|
||||
|
||||
.call-item-stack-fn-location {
|
||||
color: var(--theme-highlight-bluegrey);
|
||||
}
|
||||
|
||||
.call-item-stack-fn-location:hover {
|
||||
color: var(--theme-highlight-blue);
|
||||
}
|
||||
|
||||
#calls-list .selected .call-item-contents > label:not(.call-item-gutter) {
|
||||
/* Text inside a selected item should not be custom colored. */
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
/* Rendering preview */
|
||||
|
||||
#screenshot-container {
|
||||
background-color: var(--theme-body-background);
|
||||
background-image: var(--checkerboard-pattern);
|
||||
background-size: 30px 30px, 30px 30px;
|
||||
background-position: 0px 0px, 15px 15px;
|
||||
background-repeat: repeat, repeat;
|
||||
}
|
||||
|
||||
@media (min-width: 701px) {
|
||||
#screenshot-container {
|
||||
width: 30vw;
|
||||
max-width: 50vw;
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
#screenshot-container {
|
||||
height: 40vh;
|
||||
max-height: 70vh;
|
||||
min-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
#screenshot-image {
|
||||
background-image: -moz-element(#screenshot-rendering);
|
||||
background-size: contain;
|
||||
background-position: center, center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#screenshot-image[flipped=true] {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
#screenshot-dimensions {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.theme-dark #screenshot-dimensions {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.theme-light #screenshot-dimensions {
|
||||
background-color: rgba(255,255,255,0.8);
|
||||
}
|
||||
|
||||
/* Snapshot filmstrip */
|
||||
|
||||
#snapshot-filmstrip {
|
||||
border-top: 1px solid var(--theme-splitter-color);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.theme-dark #snapshot-filmstrip {
|
||||
color: var(--theme-selection-color);
|
||||
}
|
||||
|
||||
.theme-light #snapshot-filmstrip {
|
||||
color: var(--theme-body-color-alt);
|
||||
}
|
||||
|
||||
.filmstrip-thumbnail {
|
||||
image-rendering: -moz-crisp-edges;
|
||||
background-color: var(--theme-body-background);
|
||||
background-image: var(--checkerboard-pattern);
|
||||
background-size: 12px 12px, 12px 12px;
|
||||
background-position: 0px -1px, 6px 5px;
|
||||
background-repeat: repeat, repeat;
|
||||
background-origin: content-box;
|
||||
cursor: pointer;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
border-inline-end: 1px solid var(--theme-splitter-color);
|
||||
transition: opacity 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
.filmstrip-thumbnail[flipped=true] {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
#snapshot-filmstrip > .filmstrip-thumbnail:hover,
|
||||
#snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
|
||||
border: 1px solid var(--theme-highlight-blue);
|
||||
margin: 0 0 0 -1px;
|
||||
padding: 0;
|
||||
opacity: 0.66;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill #0b0b0b">
|
||||
<path d="M1.5 14.042h4.095a.5.5 0 0 0 0-1H1.5a.5.5 0 1 0 0 1zM7.5 3v6.983L4.364 6.657a.5.5 0 0 0-.728.686l4 4.243a.51.51 0 0 0 .021.02.5.5 0 0 0 .71-.024l3.997-4.239a.5.5 0 1 0-.728-.686L8.5 9.983V2.5a.5.5 0 0 0-.536-.5H1.536C1.24 2 1 2.224 1 2.5s.24.5.536.5H7.5zM10.5 14.042h4.095a.5.5 0 0 0 0-1H10.5a.5.5 0 1 0 0 1z"/>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 654 B |
|
@ -1,6 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill #0b0b0b">
|
||||
<path d="M5 13.5H1a.5.5 0 1 0 0 1h4a.5.5 0 1 0 0-1zM12 13.5H8a.5.5 0 1 0 0 1h4a.5.5 0 1 0 0-1zM6.11 5.012A.427.427 0 0 1 6.21 5h7.083L9.646 1.354a.5.5 0 1 1 .708-.708l4.5 4.5a.498.498 0 0 1 0 .708l-4.5 4.5a.5.5 0 0 1-.708-.708L13.293 6H6.5v5.5a.5.5 0 1 1-1 0v-6a.5.5 0 0 1 .61-.488z"/>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 619 B |
|
@ -1,7 +0,0 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill #0b0b0b">
|
||||
<path d="M13.297 6.912C12.595 4.39 10.167 2.5 7.398 2.5A5.898 5.898 0 0 0 1.5 8.398a.5.5 0 0 0 1 0A4.898 4.898 0 0 1 7.398 3.5c2.75 0 5.102 2.236 5.102 4.898v.004L8.669 7.029a.5.5 0 0 0-.338.942l4.462 1.598a.5.5 0 0 0 .651-.34.506.506 0 0 0 .02-.043l2-5a.5.5 0 1 0-.928-.372l-1.24 3.098z"/>
|
||||
<circle cx="7" cy="12" r="1"/>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 657 B |
|
@ -149,15 +149,6 @@
|
|||
background: var(--theme-selection-background);
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the default fill color to toolbar icons
|
||||
*/
|
||||
#canvas-debugging-empty-notice-button .button-icon,
|
||||
.event-tooltip-debugger-icon {
|
||||
-moz-context-properties: fill;
|
||||
fill: var(--theme-icon-color);
|
||||
}
|
||||
|
||||
.devtools-invisible-splitter {
|
||||
border-color: transparent;
|
||||
background-color: transparent;
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
"devtools/client/aboutdebugging/test/browser_addons_remove.js": 4510,
|
||||
"devtools/client/aboutdebugging/test/browser_service_workers_not_compatible.js": 5357,
|
||||
"devtools/client/aboutdebugging/test/browser_service_workers_status.js": 5267,
|
||||
"devtools/client/canvasdebugger/test/browser_canvas-frontend-call-stack-01.js": 4584,
|
||||
"devtools/client/canvasdebugger/test/browser_canvas-frontend-call-stack-02.js": 4191,
|
||||
"devtools/client/debugger/new/test/mochitest/browser_dbg-breaking-from-console.js": 7303,
|
||||
"devtools/client/debugger/new/test/mochitest/browser_dbg-breaking.js": 7881,
|
||||
"devtools/client/debugger/new/test/mochitest/browser_dbg-breakpoints-cond.js": 5276,
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
"devtools/client/aboutdebugging/test/browser_service_workers_not_compatible.js": 5813,
|
||||
"devtools/client/aboutdebugging/test/browser_service_workers_push.js": 29415,
|
||||
"devtools/client/aboutdebugging/test/browser_service_workers_push_service.js": 29953,
|
||||
"devtools/client/canvasdebugger/test/browser_canvas-frontend-call-stack-01.js": 5152,
|
||||
"devtools/client/canvasdebugger/test/browser_canvas-frontend-call-stack-02.js": 4743,
|
||||
"devtools/client/commandline/test/browser_cmd_addon.js": 5312,
|
||||
"devtools/client/commandline/test/browser_cmd_commands.js": 4915,
|
||||
"devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js": 5247,
|
||||
|
|
Загрузка…
Ссылка в новой задаче