HTML5accessibility icon indicating copy to clipboard operation
HTML5accessibility copied to clipboard

update bookmarklet to support iframes in shadow dom

Open nonmetalhail opened this issue 3 years ago • 0 comments

I found that the bookmarklet doesnt work when an iframe is located inside a shadow DOM because the code only looks for iframes that are part of the base document, not inside the shadow roots. This PR changes the code to also search for iframe elements in all shadowRoots and apply the style element to them.

Unminified bookmarklet:

javascript:(function(){
  var d=document,
      id='phltsbkmklt',
      el=d.getElementById(id),
      f=d.querySelectorAll('iframe'),
      i=0;
  
  if(el){
    function removeFromShadows(root){
      for(var el of root.querySelectorAll('*')){
        if(el.shadowRoot){
          el.shadowRoot.getElementById(id).remove();
          const frames = el.shadowRoot.querySelectorAll('iframe');
          removeFromIFrames(frames);
          removeFromShadows(el.shadowRoot);
        }
      }
    }
    function removeFromIFrames(frames) {
      for(i=0;i<frames.length;i++){
        try{
          frames[i].contentWindow.document.getElementById(id).remove();
          removeFromShadows(frames[i].contentWindow.document);
        }catch(e){
          console.log(e)
        }
      }
    }
    el.remove();
    removeFromIFrames(f);
    removeFromShadows(d);
  }else{
    s=d.createElement('style');
    s.id=id;
    s.appendChild(d.createTextNode('*{line-height:1.5 !important;letter-spacing:0.12em !important;word-spacing:0.16em !important;}p{margin-bottom:2em !important;}'));
    
    function applyToShadows(root){
      for(var el of root.querySelectorAll('*')){
        if(el.shadowRoot){
          el.shadowRoot.appendChild(s.cloneNode(true));
          const frames = el.shadowRoot.querySelectorAll('iframe');
          applyToIFrames(frames);
          applyToShadows(el.shadowRoot);
        }
      }
    }
    function applyToIFrames(frames) {
      for(i=0;i<frames.length;i++){
        try{
          frames[i].contentWindow.document.getElementsByTagName('head')[0].appendChild(s.cloneNode(true));
          applyToShadows(frames[i].contentWindow.document);
        }catch(e){
          console.log(e)
        }
      }
    }
    d.getElementsByTagName('head')[0].appendChild(s);
    applyToIFrames(f);
    applyToShadows(d);
  }
})();

nonmetalhail avatar Oct 11 '22 20:10 nonmetalhail