Today I discovered a neat feature available in both Firefox and Chrome: break on attribute change. This allows us to break when some code changes a DOM element attribute.
I was debugging an issue where some code involved with adding and removing styles for error indication on a table was incorrectly doing the following:
$("td").each(function() {
if (!$(this).hasClass("qc-error")) {
$(this.parentNode).attr("style", "");
} else {
$(this.parentNode).attr("style", "border: 1px solid #f00; background: #eee");
}
});
The templating code was responsible for the initial hiding of the row and would insert this style when rendered:
<tr id="second-fee-row" {{'style="display: none"' if bid.fee_type != constants.FEE_TYPE_PER else '' | n}>
Additionally, some code elsewhere on the page was also attempting to manage this row by setting the display in response to changes in a dropdown:
if ($("#fee-type").val() !== constants.FEE_TYPE_PER) {
$("#second-fee-row").css("display", "none");
} else {
$("#second-fee-row").css("display", "table-row");
}
After first verifying that Firefox thought it should display the element, I
looked at the page source. Checked out. display: none
was definitely
there.
Then I spent some time looking for modifications to #second-fee-row
. I
inspected all the sites that were modifying that row (by looking for that id).
Nope. Nothing setting the style to empty.
After a quick google to confirm that display: none
hadn't suddenly become
unsupported, I came across this Stack Overflow link:
https://stackoverflow.com/questions/13303650/break-when-style-has-changed-in-chrome-dev-tools.
This in turn led me to search for the same feature in Firefox (my day-to-day
browser) which resulted in: https://getfirebug.com/doc/breakpoints/demo.html.
I went ahead and set such a breakpoint on the afflicted element. Lo and behold, the offending code was found and repaired with:
$("td").each(function() {
if (!$(this).hasClass("qc-error")) {
$(this.parentNode).css({
border: null,
background: null
});
} else {
$(this.parentNode).css({
border: "1px solid #f00",
background: "#eee"
});
}
});
Not a perfect solution (should probably track the original value instead) but acceptable in this case.