3

I've seen from this post about Chromium DevTools that there exists the possibility to add DOM breakpoints. Given that I've a full range of elements to monitor I was trying to find a way to programmatically add such breakpoints. I also read this question about DOM breakpoints but it doesn't seem to give me any useful hint.

To achieve a similar result I've used to instrument the setAttribute() function of such DOM elements replacing it with a wrapper that uses the debugger; instruction to trigger the debugger. Anyway this approach fails when dealing with innerHTML or innerText assignments given that there is no way of achieving operator overloading in js.

Can someone suggest me a practical solution?

Gabrio
  • 388
  • 1
  • 4
  • 17
  • It would be great if someone has an answer to this! As DOM sometimes gets deleted by some script - and doing a debugger; on a MutationObserver doesn't really help - as that breakpoint does not have the call stack of who triggered it – João Antunes Nov 04 '22 at 12:27
  • This is definetly possible with usind DevtoolsOverDevtools, and may be found by debugging `oncontentmenu` of Elements pane. How exactly to do that I don't know yet – Dimava Nov 04 '22 at 12:46
  • Can you provide an example of what you trying to do or solve? – Evgeni Dikerman Nov 05 '22 at 11:20

3 Answers3

2

You may want to use MutationObserver, to observe for any change to a DOM at given root element. Also you can put debugger there and if devTools is open it should break.

const targetNode = document.getElementById('observed-element');
const config = { attributes: true, childList: true, subtree: true };

// Callback function to execute when mutations are observed
const callback = (mutationList, observer) => {
  for (const mutation of mutationList) {
    console.log(mutation.type);
    console.log(mutation.target);
    debugger; 
  }
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

// change class
setTimeout(()=>{
  targetNode.setAttribute('class', 'some-class')
}, 0);

// change innerText
setTimeout(()=>{
  targetNode.innerText = 'some text';  
}, 0);
<div id="observed-element">
</div>
Evgeni Dikerman
  • 486
  • 3
  • 18
0

You need to open Devtools-Over-Devtools and get references to instances of DOMModel and DOMDebuggerModel

// open Devtools (Ctrl+Shift+I)
// open DevtoolsOverDevtools (Ctrl+Shift+I in Devtools)
// open sdk.js from Ctrl+P pane
// set breakpoint in function setDOMBreakpoint(e, t)
// set HTML breakpoint in Devtools to pause on the created breakpoint 

// inside setDOMBreakpoint(e, t)
window.domModel = e.domModel()
window.domDebuggerModel = this

// resume execution, disable breakpoint
_k = [...domModel.idToDOMNode.keys()][0]
_a = await domModel.querySelectorAll(_k, 'div')
_b = _a.map(e => domModel.idToDOMNode.get(e)).filter(Boolean)
_b.map(e => domDebuggerModel.setDOMBreakpoint(e, 'node-removed'))
// 'subtree-modified' | 'attribute-modified' | 'node-removed'

// now all elements are breakpointed
Dimava
  • 7,654
  • 1
  • 9
  • 24
0
window.DEBUG = true; // toggles programmatic debugging

flag with a global check debug function, like so:

window.CHECK_DEBUG = function() {
  if (window.DEBUG) { debugger; } 
}

And then insert the following in any function you’re concerned about debugging:

   function foo() {
  CHECK_DEBUG();
// foo's usual procedure ...
}

To take this a step further (and to take a page out of Firebug's debug() and undebug() wrapper functions) you can decorate the native JavaScript Function object like so:

Function.prototype.debug = function(){   
   var fn = this;
   return function(){     
       if (window.DEBUG) { debugger; } 
       return fn.apply(this, arguments);     
   }; 
};

Then you can dynamically debug any function by calling:

foo = foo.debug();
Pawan
  • 92
  • 1
  • 10