One of the things that I'm convinced a debugger has to have - and basically has to have early - is the ability to set a breakpoint.
In this episode, I'm not going to sweat actually making the program stop at the breakpoint; the question is just whether or not I can specify where to set a breakpoint.
I'm thinking that it should be possible to have some kind of gesture (my first thought is to click on the line number) that says "I want to break here". We then need to check that there is in fact some code there which we could break at.
So we have something like the following set of tasks:
- Handle a click event on the table;
- Add a style to the line number if it has been selected;
- Get a copy of the compiled JSON code;
- Check whether any of the items has the line number that has been selected.
Handling Events
We can add an event handler to the table easily enough, and use that to toggle the class breakpoint on the appropriate line number table element, although there are a few hoops to jump through to find that.tbody.addEventListener('click', ev => {
var target = ev.target;
var row = target.parentElement;
if (row.tagName == 'TR') {
var lineNo = row.querySelector(".line-no");
lineNo.classList.toggle("breakpoint");
}
});
CDP_BREAKPOINT_EVENT:cdp-till/plugin/html/js/sidepanel.js
.line-no.breakpoint {
background-color: red;
color: white;
}
CDP_BREAKPOINT_EVENT:cdp-till/plugin/html/css/sidepanel.css
If we click anywhere on a line row, the line number becomes a white number on a red background. Clicking again toggles it back.Obtain the Compiled Code
We have already done this in the service worker as an experiment, so let's just move that over here.fetch("http://localhost:1399/till-code").then(resp => {
resp.json().then(code => {
for (var entry of code) {
if (entry.LineNo) {
breakLines[entry.LineNo] = entry;
}
if (entry.Actions) {
for (var a of entry.Actions) {
if (a.LineNo) {
breakLines[a.LineNo] = a;
}
}
}
}
})
});
CDP_BREAK_LINES:cdp-till/plugin/html/js/sidepanel.js
Then inside the callback, we can analyze all of the entries and all of the actions and, for any that have line numbers, we can say "this is a valid line to break at". Note that we don't do this for the Rows nested within the layout, but (for now at least) we are allowing a breakpoint on the layout itself.I have (somewhat capriciously) chosen to represent this using a map of the line number to the entry or action. I think this will come in useful later, but for sure we need to know the line numbers where we can usefully break.
The documentation has dark mutterings about things "possibly going away", but I think if it does, this whole script is re-evaluated, and I don't think that anything bad can happen. If it does, we will return to that. I think the warning is more about if you expect state to persist when the side panel is closed and then re-opened (we may find that with our breakpoints, for example).
Validate the Chosen Line Number
Once we have these line numbers, we can use that to see if the selected line number is in the map. There are a number of ways of obtaining the selected line number but the "easiest" is just to pull it out of the leading td.tbody.addEventListener('click', ev => {
var target = ev.target;
var row = target.parentElement;
if (row.tagName == 'TR') {
var lineNo = row.querySelector(".line-no"); // this is a td
var lineText = lineNo.innerText;
if (breakLines[Number(lineText)]) {
lineNo.classList.toggle("breakpoint");
}
}
});
CDP_VALIDATE_BREAKS:cdp-till/plugin/html/js/sidepanel.js
Then, if there is an entry in breakLines for that number, we can go ahead and "set" the breakpoint, otherwise not.Conclusion
We have successfully loaded both the source and compiled code into our plugin, and we have added all the appropriate UI and UX to set a breakpoint.Of course, what we haven't done is attempted to do anything with that information.
No comments:
Post a Comment