mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1238042 - Add about:checkerboard. r=ehsan,botond
This commit is contained in:
parent
ef957ce9f2
commit
ec251db847
@ -44,6 +44,11 @@ static RedirEntry kRedirMap[] = {
|
||||
"buildconfig", "chrome://global/content/buildconfig.html",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT
|
||||
},
|
||||
{
|
||||
"checkerboard", "chrome://global/content/aboutCheckerboard.xhtml",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||
nsIAboutModule::ALLOW_SCRIPT
|
||||
},
|
||||
{ "config", "chrome://global/content/config.xul", 0 },
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
{ "crashes", "chrome://global/content/crashes.xhtml", 0 },
|
||||
|
@ -24,12 +24,9 @@ protected:
|
||||
virtual ~nsAboutRedirector() {}
|
||||
};
|
||||
|
||||
#define NS_ABOUT_REDIRECTOR_MODULE_CID \
|
||||
{ /* f0acde16-1dd1-11b2-9e35-f5786fff5a66*/ \
|
||||
0xf0acde16, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0x9e, 0x35, 0xf5, 0x78, 0x6f, 0xff, 0x5a, 0x66} \
|
||||
}
|
||||
/* 56ebedd4-6ccf-48e8-bdae-adc77f044567 */
|
||||
#define NS_ABOUT_REDIRECTOR_MODULE_CID \
|
||||
{ 0x56ebedd4, 0x6ccf, 0x48e8, \
|
||||
{ 0xbd, 0xae, 0xad, 0xc7, 0x7f, 0x04, 0x45, 0x67 } }
|
||||
|
||||
#endif // nsAboutRedirector_h__
|
||||
|
@ -163,6 +163,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "about", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "addons", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "buildconfig", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "checkerboard", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "config", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "crashes", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
|
@ -0,0 +1,49 @@
|
||||
/* 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/. */
|
||||
|
||||
table.listing {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
padding: 5px;
|
||||
border: inset 2px black;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
hr {
|
||||
clear: both;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 900px;
|
||||
}
|
||||
|
||||
#player, #raw {
|
||||
width: 800px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#controls {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
border: solid 1px black;
|
||||
}
|
||||
|
||||
#active {
|
||||
width: 100%;
|
||||
border: solid 1px black;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#trace {
|
||||
width: 100%;
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
/* 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";
|
||||
|
||||
var trace;
|
||||
var service;
|
||||
var reports;
|
||||
|
||||
function onLoad() {
|
||||
trace = document.getElementById('trace');
|
||||
service = new CheckerboardReportService();
|
||||
updateEnabled();
|
||||
reports = service.getReports();
|
||||
for (var i = 0; i < reports.length; i++) {
|
||||
let text = "Severity " + reports[i].severity + " at " + new Date(reports[i].timestamp).toString();
|
||||
let link = document.createElement('a');
|
||||
link.href = 'javascript:showReport(' + i + ')';
|
||||
link.textContent = text;
|
||||
let bullet = document.createElement('li');
|
||||
bullet.appendChild(link);
|
||||
document.getElementById(reports[i].reason).appendChild(bullet);
|
||||
}
|
||||
}
|
||||
|
||||
function updateEnabled() {
|
||||
let enabled = document.getElementById('enabled');
|
||||
if (service.isRecordingEnabled()) {
|
||||
enabled.textContent = 'enabled';
|
||||
enabled.style.color = 'green';
|
||||
} else {
|
||||
enabled.textContent = 'disabled';
|
||||
enabled.style.color = 'red';
|
||||
}
|
||||
}
|
||||
|
||||
function toggleEnabled() {
|
||||
service.setRecordingEnabled(!service.isRecordingEnabled());
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
function showReport(index) {
|
||||
trace.value = reports[index].log;
|
||||
loadData();
|
||||
}
|
||||
|
||||
// -- Code to load and render the trace --
|
||||
|
||||
const CANVAS_USE_RATIO = 0.75;
|
||||
const FRAME_INTERVAL_MS = 50;
|
||||
const VECTOR_NORMALIZED_MAGNITUDE = 30.0;
|
||||
|
||||
var renderData = new Array();
|
||||
var currentFrame = 0;
|
||||
var playing = false;
|
||||
var timerId = 0;
|
||||
|
||||
var minX = undefined;
|
||||
var minY = undefined;
|
||||
var maxX = undefined;
|
||||
var maxY = undefined;
|
||||
|
||||
function log(x) {
|
||||
if (console) {
|
||||
console.log(x);
|
||||
}
|
||||
}
|
||||
|
||||
function getFlag(flag) {
|
||||
return document.getElementById(flag).checked;
|
||||
}
|
||||
|
||||
// parses the lines in the textarea, ignoring anything that doesn't have RENDERTRACE.
|
||||
// for each matching line, tokenizes on whitespace and ignores all tokens prior to
|
||||
// RENDERTRACE. Additional info can be included at the end of the line, and will be
|
||||
// displayed but not parsed. Allowed syntaxes:
|
||||
// <junk> RENDERTRACE <timestamp> rect <color> <x> <y> <width> <height> [extraInfo]
|
||||
function loadData() {
|
||||
stopPlay();
|
||||
renderData = new Array();
|
||||
currentFrame = 0;
|
||||
minX = undefined;
|
||||
minY = undefined;
|
||||
maxX = undefined;
|
||||
maxY = undefined;
|
||||
|
||||
var charPos = 0;
|
||||
var lastLineLength = 0;
|
||||
var lines = trace.value.split(/\r|\n/);
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
charPos += lastLineLength;
|
||||
lastLineLength = lines[i].length + 1;
|
||||
// skip lines without RENDERTRACE
|
||||
if (! /RENDERTRACE/.test(lines[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var tokens = lines[i].split(/\s+/);
|
||||
var j = 0;
|
||||
// skip tokens until RENDERTRACE
|
||||
while (j < tokens.length && tokens[j++] != "RENDERTRACE"); // empty loop body
|
||||
if (j >= tokens.length - 2) {
|
||||
log("Error parsing line: " + lines[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
var timestamp = tokens[j++];
|
||||
var destIndex = renderData.length;
|
||||
if (destIndex == 0) {
|
||||
// create the initial frame
|
||||
renderData.push({
|
||||
timestamp: timestamp,
|
||||
rects: {},
|
||||
});
|
||||
} else if (renderData[destIndex - 1].timestamp == timestamp) {
|
||||
// timestamp hasn't changed use, so update the previous object
|
||||
destIndex--;
|
||||
} else {
|
||||
// clone a new copy of the last frame and update timestamp
|
||||
renderData.push(JSON.parse(JSON.stringify(renderData[destIndex - 1])));
|
||||
renderData[destIndex].timestamp = timestamp;
|
||||
}
|
||||
|
||||
switch (tokens[j++]) {
|
||||
case "rect":
|
||||
if (j > tokens.length - 5) {
|
||||
log("Error parsing line: " + lines[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
var rect = {};
|
||||
var color = tokens[j++];
|
||||
renderData[destIndex].rects[color] = rect;
|
||||
rect.x = parseFloat(tokens[j++]);
|
||||
rect.y = parseFloat(tokens[j++]);
|
||||
rect.width = parseFloat(tokens[j++]);
|
||||
rect.height = parseFloat(tokens[j++]);
|
||||
rect.dataText = trace.value.substring(charPos, charPos + lines[i].length);
|
||||
|
||||
if (!getFlag('excludePageFromZoom') || color != 'brown') {
|
||||
if (typeof minX == "undefined") {
|
||||
minX = rect.x;
|
||||
minY = rect.y;
|
||||
maxX = rect.x + rect.width;
|
||||
maxY = rect.y + rect.height;
|
||||
} else {
|
||||
minX = Math.min(minX, rect.x);
|
||||
minY = Math.min(minY, rect.y);
|
||||
maxX = Math.max(maxX, rect.x + rect.width);
|
||||
maxY = Math.max(maxY, rect.y + rect.height);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log("Error parsing line " + lines[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! renderFrame()) {
|
||||
alert("No data found; nothing to render!");
|
||||
}
|
||||
}
|
||||
|
||||
// render the current frame (i.e. renderData[currentFrame])
|
||||
// returns false if currentFrame is out of bounds, true otherwise
|
||||
function renderFrame() {
|
||||
var frame = currentFrame;
|
||||
if (frame < 0 || frame >= renderData.length) {
|
||||
log("Invalid frame index");
|
||||
return false;
|
||||
}
|
||||
|
||||
var canvas = document.getElementById('canvas');
|
||||
if (! canvas.getContext) {
|
||||
log("No canvas context");
|
||||
}
|
||||
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
// midpoint of the bounding box
|
||||
var midX = (minX + maxX) / 2.0;
|
||||
var midY = (minY + maxY) / 2.0;
|
||||
|
||||
// midpoint of the canvas
|
||||
var cmx = canvas.width / 2.0;
|
||||
var cmy = canvas.height / 2.0;
|
||||
|
||||
// scale factor
|
||||
var scale = CANVAS_USE_RATIO * Math.min(canvas.width / (maxX - minX), canvas.height / (maxY - minY));
|
||||
|
||||
function projectX(value) {
|
||||
return cmx + ((value - midX) * scale);
|
||||
}
|
||||
|
||||
function projectY(value) {
|
||||
return cmy + ((value - midY) * scale);
|
||||
}
|
||||
|
||||
function drawRect(color, rect) {
|
||||
context.strokeStyle = color;
|
||||
context.strokeRect(
|
||||
projectX(rect.x),
|
||||
projectY(rect.y),
|
||||
rect.width * scale,
|
||||
rect.height * scale);
|
||||
}
|
||||
|
||||
// clear canvas
|
||||
context.fillStyle = 'white';
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
var activeData = '';
|
||||
// draw rects
|
||||
for (var i in renderData[frame].rects) {
|
||||
drawRect(i, renderData[frame].rects[i]);
|
||||
activeData += "\n" + renderData[frame].rects[i].dataText;
|
||||
}
|
||||
// draw timestamp and frame counter
|
||||
context.fillStyle = 'black';
|
||||
context.fillText((frame + 1) + "/" + renderData.length + ": " + renderData[frame].timestamp, 5, 15);
|
||||
|
||||
document.getElementById('active').textContent = activeData;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -- Player controls --
|
||||
|
||||
function reset(beginning) {
|
||||
currentFrame = (beginning ? 0 : renderData.length - 1);
|
||||
renderFrame();
|
||||
}
|
||||
|
||||
function step(backwards) {
|
||||
if (playing) {
|
||||
togglePlay();
|
||||
}
|
||||
currentFrame += (backwards ? -1 : 1);
|
||||
if (! renderFrame()) {
|
||||
currentFrame -= (backwards ? -1 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
function pause() {
|
||||
clearInterval(timerId);
|
||||
playing = false;
|
||||
}
|
||||
|
||||
function togglePlay() {
|
||||
if (playing) {
|
||||
pause();
|
||||
} else {
|
||||
timerId = setInterval(function() {
|
||||
currentFrame++;
|
||||
if (! renderFrame()) {
|
||||
currentFrame--;
|
||||
togglePlay();
|
||||
}
|
||||
}, FRAME_INTERVAL_MS);
|
||||
playing = true;
|
||||
}
|
||||
}
|
||||
|
||||
function stopPlay() {
|
||||
if (playing) {
|
||||
togglePlay();
|
||||
}
|
||||
currentFrame = 0;
|
||||
renderFrame();
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?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/. -->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width"/>
|
||||
<link rel="stylesheet" href="chrome://global/content/aboutCheckerboard.css" type="text/css"/>
|
||||
<script type="text/javascript;version=1.8" src="chrome://global/content/aboutCheckerboard.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="onLoad()">
|
||||
<p>Checkerboard recording is <span id="enabled" style="color: red">undetermined</span>.
|
||||
<button onclick="toggleEnabled()">Toggle it!</button>.</p>
|
||||
<table class="listing" cellspacing="0">
|
||||
<tr>
|
||||
<th>Most severe checkerboarding reports</th>
|
||||
<th>Most recent checkerboarding reports</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><ul id="severe"></ul></td>
|
||||
<td><ul id="recent"></ul></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div id="player">
|
||||
<div id="controls">
|
||||
<button onclick="reset(true)">«</button><!-- rewind button -->
|
||||
<button onclick="step(true)"><</button><!-- step back button -->
|
||||
<button onclick="togglePlay()">|| ▶</button><!-- pause button -->
|
||||
<button onclick="stopPlay()">☐</button><!-- stop button -->
|
||||
<button onclick="step(false)">></button><!-- step forward button -->
|
||||
<button onclick="reset(false)">»</button><!-- forward button -->
|
||||
</div>
|
||||
<canvas id="canvas" width="800" height="600">Canvas not supported!</canvas>
|
||||
<pre id="active">(Details for currently visible replay frame)</pre>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div id="raw">
|
||||
Raw log:<br/>
|
||||
<textarea id="trace" rows="10"></textarea>
|
||||
<div>
|
||||
<input type="checkbox" id="excludePageFromZoom" onclick="loadData()"/><label for="excludePageFromZoom">Exclude page coordinates from zoom calculations</label><br/>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
8
toolkit/components/aboutcheckerboard/jar.mn
Normal file
8
toolkit/components/aboutcheckerboard/jar.mn
Normal file
@ -0,0 +1,8 @@
|
||||
# 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/.
|
||||
|
||||
toolkit.jar:
|
||||
content/global/aboutCheckerboard.js (content/aboutCheckerboard.js)
|
||||
content/global/aboutCheckerboard.xhtml (content/aboutCheckerboard.xhtml)
|
||||
content/global/aboutCheckerboard.css (content/aboutCheckerboard.css)
|
10
toolkit/components/aboutcheckerboard/moz.build
Normal file
10
toolkit/components/aboutcheckerboard/moz.build
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Core', 'Panning and Zooming')
|
@ -10,6 +10,7 @@ if CONFIG['MOZ_ENABLE_XREMOTE']:
|
||||
|
||||
DIRS += [
|
||||
'aboutcache',
|
||||
'aboutcheckerboard',
|
||||
'aboutmemory',
|
||||
'addoncompat',
|
||||
'alerts',
|
||||
|
Loading…
Reference in New Issue
Block a user