mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1608261 - Shade untraversed and unscanned regions differently on timeline, r=jlast.
Differential Revision: https://phabricator.services.mozilla.com/D59421 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
b0f0989ac5
commit
ecd563dce4
@ -702,6 +702,13 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.webreplay-player .untraversed {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
background: #000000;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.webreplay-player .unscanned {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
|
@ -159,7 +159,7 @@ class WebReplayPlayer extends Component {
|
||||
this.overlayWidth = this.updateOverlayWidth();
|
||||
this.threadFront.on("paused", this.onPaused.bind(this));
|
||||
this.threadFront.on("resumed", this.onResumed.bind(this));
|
||||
this.threadFront.on("progress", this.onProgress.bind(this));
|
||||
this.threadFront.on("replayStatusUpdate", this.onStatusUpdate.bind(this));
|
||||
|
||||
this.toolbox.getPanelWhenReady("webconsole").then(panel => {
|
||||
const consoleFrame = panel.hud.ui;
|
||||
@ -270,13 +270,13 @@ class WebReplayPlayer extends Component {
|
||||
this.setState({ paused: false, closestMessage: null, pausedMessage: null });
|
||||
}
|
||||
|
||||
onProgress(packet) {
|
||||
onStatusUpdate({ status }) {
|
||||
const {
|
||||
recording,
|
||||
executionPoint,
|
||||
unscannedRegions,
|
||||
cachedPoints,
|
||||
} = packet;
|
||||
} = status;
|
||||
log(`progress: ${recording ? "rec" : "play"} ${executionPoint.progress}`);
|
||||
|
||||
if (this.state.seeking) {
|
||||
@ -689,7 +689,7 @@ class WebReplayPlayer extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
renderUnscannedRegion({ start, end }) {
|
||||
renderUnscannedRegion({ start, end, traversed }) {
|
||||
let startOffset = this.getVisibleOffset({ progress: start });
|
||||
let endOffset = this.getVisibleOffset({ progress: end });
|
||||
|
||||
@ -706,7 +706,7 @@ class WebReplayPlayer extends Component {
|
||||
}
|
||||
|
||||
return dom.span({
|
||||
className: classname("unscanned"),
|
||||
className: traversed ? classname("unscanned") : classname("untraversed"),
|
||||
style: {
|
||||
left: `${startOffset}px`,
|
||||
width: `${endOffset - startOffset}px`,
|
||||
|
@ -556,7 +556,7 @@ function spawnTrunkChild() {
|
||||
assert(gLastSavedCheckpoint == InvalidCheckpointId);
|
||||
}
|
||||
|
||||
function forkBranchChild(lastSavedCheckpoint, nextSavedCheckpoint) {
|
||||
async function forkBranchChild(lastSavedCheckpoint, nextSavedCheckpoint) {
|
||||
if (!RecordReplayControl.canRewind()) {
|
||||
return;
|
||||
}
|
||||
@ -574,7 +574,7 @@ function forkBranchChild(lastSavedCheckpoint, nextSavedCheckpoint) {
|
||||
gBranchChildren.push({ child, point });
|
||||
|
||||
const endpoint = checkpointExecutionPoint(nextSavedCheckpoint);
|
||||
gTrunkChild.sendManifest({
|
||||
await gTrunkChild.sendManifest({
|
||||
kind: "runToPoint",
|
||||
endpoint,
|
||||
|
||||
@ -582,6 +582,8 @@ function forkBranchChild(lastSavedCheckpoint, nextSavedCheckpoint) {
|
||||
// from throughout the recording will be cached in the root child.
|
||||
flushExternalCalls: true,
|
||||
});
|
||||
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
function respawnCrashedChild(child) {
|
||||
@ -861,9 +863,7 @@ async function scanRecording(checkpoint) {
|
||||
gScannedSavedCheckpoints.add(checkpoint);
|
||||
|
||||
// Update the unscanned regions in the UI.
|
||||
if (gDebugger) {
|
||||
gDebugger._callOnPositionChange();
|
||||
}
|
||||
updateStatus();
|
||||
|
||||
resolve(child);
|
||||
return child;
|
||||
@ -872,14 +872,24 @@ async function scanRecording(checkpoint) {
|
||||
function unscannedRegions() {
|
||||
const result = [];
|
||||
|
||||
const traversedCheckpoint =
|
||||
gTrunkChild && gTrunkChild.lastPausePoint
|
||||
? gTrunkChild.lastPausePoint.checkpoint
|
||||
: FirstCheckpointId;
|
||||
|
||||
function addRegion(startCheckpoint, endCheckpoint) {
|
||||
const start = checkpointExecutionPoint(startCheckpoint).progress;
|
||||
const end = checkpointExecutionPoint(endCheckpoint).progress;
|
||||
const traversed = endCheckpoint <= traversedCheckpoint;
|
||||
|
||||
if (result.length && result[result.length - 1].end == start) {
|
||||
if (
|
||||
result.length &&
|
||||
result[result.length - 1].end == start &&
|
||||
result[result.length - 1].traversed == traversed
|
||||
) {
|
||||
result[result.length - 1].end = end;
|
||||
} else {
|
||||
result.push({ start, end });
|
||||
result.push({ start, end, traversed });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1060,9 +1070,7 @@ function addPauseData(point, data, trackCached) {
|
||||
|
||||
if (trackCached) {
|
||||
gCachedPoints.set(pointToString(point), point);
|
||||
if (gDebugger) {
|
||||
gDebugger._callOnPositionChange();
|
||||
}
|
||||
updateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,6 +1142,7 @@ function setReplayingPauseTarget(point) {
|
||||
|
||||
const child = newLeafChild(point);
|
||||
setPauseState(PauseModes.PAUSED, point, child);
|
||||
updateStatus();
|
||||
|
||||
gDebugger._onPause();
|
||||
findFrameSteps(point);
|
||||
@ -1230,7 +1239,7 @@ async function finishResume() {
|
||||
assert(forward);
|
||||
RecordReplayControl.restoreMainGraphics();
|
||||
setPauseState(PauseModes.RUNNING, gMainChild.pausePoint(), gMainChild);
|
||||
gDebugger._callOnPositionChange();
|
||||
updateStatus();
|
||||
maybeResumeRecording();
|
||||
} else {
|
||||
// We searched backward to the beginning of the recording, so restore the
|
||||
@ -1720,6 +1729,7 @@ function maybeResumeRecording() {
|
||||
|
||||
gPausePoint = gMainChild.pausePoint();
|
||||
if (gDebugger) {
|
||||
updateStatus();
|
||||
gDebugger._onPause();
|
||||
} else {
|
||||
Services.tm.dispatchToMainThread(maybeResumeRecording);
|
||||
@ -1876,11 +1886,6 @@ const gControl = {
|
||||
return point;
|
||||
},
|
||||
|
||||
// Return whether the active child is currently recording.
|
||||
childIsRecording() {
|
||||
return gActiveChild && gActiveChild.recording;
|
||||
},
|
||||
|
||||
// Ensure the active child is paused.
|
||||
waitUntilPaused() {
|
||||
// The debugger should not use this method while we are actively resuming.
|
||||
@ -2007,9 +2012,6 @@ const gControl = {
|
||||
|
||||
setActiveEventBreakpoints,
|
||||
|
||||
unscannedRegions,
|
||||
cachedPoints,
|
||||
|
||||
debuggerRequests() {
|
||||
return gDebuggerRequests;
|
||||
},
|
||||
@ -2060,6 +2062,17 @@ const gControl = {
|
||||
},
|
||||
};
|
||||
|
||||
function updateStatus() {
|
||||
if (gDebugger && gDebugger.replayingOnStatusUpdate) {
|
||||
gDebugger.replayingOnStatusUpdate({
|
||||
recording: gActiveChild && gActiveChild.recording,
|
||||
executionPoint: gPausePoint,
|
||||
cachedPoints: cachedPoints(),
|
||||
unscannedRegions: unscannedRegions(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Utilities
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -229,8 +229,8 @@ function ReplayDebugger() {
|
||||
// a time warp target has been reached.
|
||||
this.replayingOnForcedPause = null;
|
||||
|
||||
// Handler called when the child pauses for any reason.
|
||||
this.replayingOnPositionChange = null;
|
||||
// Handler called when the status changes and the UI needs to be updated.
|
||||
this.replayingOnStatusUpdate = null;
|
||||
}
|
||||
|
||||
// Frame index used to refer to the newest frame in the child process.
|
||||
@ -265,18 +265,6 @@ ReplayDebugger.prototype = {
|
||||
return this._control.recordingEndpoint();
|
||||
},
|
||||
|
||||
replayIsRecording() {
|
||||
return this._control.childIsRecording();
|
||||
},
|
||||
|
||||
replayUnscannedRegions() {
|
||||
return this._control.unscannedRegions();
|
||||
},
|
||||
|
||||
replayCachedPoints() {
|
||||
return this._control.cachedPoints();
|
||||
},
|
||||
|
||||
replayDebuggerRequests() {
|
||||
return this._control.debuggerRequests();
|
||||
},
|
||||
@ -416,11 +404,6 @@ ReplayDebugger.prototype = {
|
||||
// within a control method (resume, timeWarp, waitUntilPaused) or be
|
||||
// delivered via the event loop.
|
||||
_onPause() {
|
||||
// The position change handler is always called on pause notifications.
|
||||
if (this.replayingOnPositionChange) {
|
||||
this.replayingOnPositionChange();
|
||||
}
|
||||
|
||||
// Call _performPause() soon via the event loop to check for breakpoint
|
||||
// handlers at this point.
|
||||
this._cancelPerformPause = false;
|
||||
@ -477,15 +460,6 @@ ReplayDebugger.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
// This hook is called whenever control state changes which affects something
|
||||
// the position change handler listens to (more than just position changes,
|
||||
// alas).
|
||||
_callOnPositionChange() {
|
||||
if (this.replayingOnPositionChange) {
|
||||
this.replayingOnPositionChange();
|
||||
}
|
||||
},
|
||||
|
||||
replayPushThreadPause() {
|
||||
// The thread has paused so that the user can interact with it. The child
|
||||
// will stay paused until this thread-wide pause has been popped.
|
||||
@ -539,7 +513,7 @@ ReplayDebugger.prototype = {
|
||||
},
|
||||
|
||||
replayPaintCurrentPoint() {
|
||||
if (this.replayIsRecording()) {
|
||||
if (this._control.childIsRecording()) {
|
||||
return RecordReplayControl.restoreMainGraphics();
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,7 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
||||
this.dbg.onNewDebuggee = this._onNewDebuggee;
|
||||
if (this.dbg.replaying) {
|
||||
this.dbg.replayingOnForcedPause = this.replayingOnForcedPause.bind(this);
|
||||
this.dbg.replayingOnPositionChange = this._makeReplayingOnPositionChange();
|
||||
this.dbg.replayingOnStatusUpdate = this._makeReplayingOnStatusUpdate();
|
||||
}
|
||||
|
||||
this._debuggerSourcesSeen = new WeakSet();
|
||||
@ -1944,23 +1944,14 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
||||
},
|
||||
|
||||
/*
|
||||
* A function that the engine calls when a recording/replaying process has
|
||||
* changed its position: a checkpoint was reached or a switch between a
|
||||
* recording and replaying child process occurred.
|
||||
* A function that the engine calls when replaying and the status has changed
|
||||
* in a way that affects the UI, such as switching between a recording and
|
||||
* replaying process or a change to the current execution point.
|
||||
*/
|
||||
_makeReplayingOnPositionChange() {
|
||||
return throttle(() => {
|
||||
_makeReplayingOnStatusUpdate() {
|
||||
return throttle(status => {
|
||||
if (this.attached) {
|
||||
const recording = this.dbg.replayIsRecording();
|
||||
const executionPoint = this.dbg.replayCurrentExecutionPoint();
|
||||
const unscannedRegions = this.dbg.replayUnscannedRegions();
|
||||
const cachedPoints = this.dbg.replayCachedPoints();
|
||||
this.emit("progress", {
|
||||
recording,
|
||||
executionPoint,
|
||||
unscannedRegions,
|
||||
cachedPoints,
|
||||
});
|
||||
this.emit("replayStatusUpdate", { status });
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
|
@ -66,11 +66,8 @@ const threadSpec = generateActorSpec({
|
||||
newSource: {
|
||||
source: Option(0, "json"),
|
||||
},
|
||||
progress: {
|
||||
recording: Option(0, "json"),
|
||||
executionPoint: Option(0, "json"),
|
||||
unscannedRegions: Option(0, "json"),
|
||||
cachedPoints: Option(0, "json"),
|
||||
replayStatusUpdate: {
|
||||
status: Option(0, "json"),
|
||||
},
|
||||
replayFramePositions: {
|
||||
positions: Option(0, "array:json"),
|
||||
|
Loading…
Reference in New Issue
Block a user