javascript:(()=>{const popupMsgs={normal:`
Navigate nodes to select them
`,info:`Entire page is selected.
To navigate relative to a pre-selected node:
- Refresh the page
- Make a small selection
- Activate this bookmarklet
`,};let popupEl,popupHeader,popupMsg,closeButton,popupButtons;const windowPosition={left:0,top:0,};let sel=window.getSelection();let currentNode,infoMsg;currentNode=sel.focusNode;if(!currentNode){currentNode=document.body;sel.selectAllChildren(currentNode);infoMsg=true;}function nodeSelectParent(thisNode){let targetNode=thisNode.nodeName.toLowerCase()==="body" ? thisNode:thisNode.parentNode;targetNode.nodeName.toLowerCase()==="body" ? sel.setBaseAndExtent(targetNode.firstChild,0,popupEl,0):sel.selectAllChildren(targetNode);return targetNode;}function nodeSelectFirstChild(thisNode){let targetNode;if(thisNode.firstElementChild&&thisNode.firstElementChild.nodeName.toLowerCase()!=="node-selector-popup"){targetNode=thisNode.firstElementChild;}else{return thisNode;}sel.setBaseAndExtent(targetNode,0,targetNode,targetNode.childNodes.length,);return targetNode;}function nodeSelectNextSibling(thisNode){if(thisNode.nodeName.toLowerCase()==="body"){return thisNode;}let loopNode=thisNode.parentNode.firstElementChild;let targetNode=thisNode.nextElementSibling&&thisNode.nextElementSibling.nodeName.toLowerCase()!=="node-selector-popup" ? thisNode.nextElementSibling:loopNode;if(targetNode===null){return thisNode;}sel.setBaseAndExtent(targetNode,0,targetNode,targetNode.childNodes.length,);return targetNode;}function nodeSelectPrevSibling(thisNode){if(thisNode.nodeName.toLowerCase()==="body"||thisNode.parentNode.childElementCount===0){return thisNode;}let loopNode=thisNode.parentNode.lastElementChild.nodeName.toLowerCase()==="node-selector-popup" ? thisNode.parentNode.lastElementChild.previousElementSibling:thisNode.parentNode.lastElementChild;let targetNode=thisNode.previousElementSibling ? thisNode.previousElementSibling:loopNode;if(targetNode===null){return thisNode;}sel.setBaseAndExtent(targetNode,0,targetNode,targetNode.childNodes.length,);return targetNode;}function buildPopup(){class NodeSelectorPopUp extends HTMLElement{constructor(){super();const shadow=this.attachShadow({mode:"open"});popupEl=document.createElement("div");popupEl.setAttribute("id","pop-up");popupHeader=document.createElement("div");popupHeader.setAttribute("id","header");const popupHeaderTitle=document.createElement("span");popupHeaderTitle.setAttribute("id","title");popupHeaderTitle.textContent="";closeButton=document.createElement("button");closeButton.setAttribute("id","close-button");closeButton.textContent="×";closeButton.addEventListener("click",()=>popupEl.remove(),false);const popupMsg=document.createElement("div");popupMsg.setAttribute("id","popup-message");popupMsg.innerHTML=infoMsg ? popupMsgs.info:popupMsgs.normal;infoMsg=false;popupButtons=document.createElement("div");popupButtons.setAttribute("id","buttons");const docBodyButton=document.createElement("button");docBodyButton.setAttribute("id","doc-body");docBodyButton.innerHTML="Document Body";docBodyButton.onclick=()=>{currentNode=document.body;currentNode=nodeSelectParent(currentNode)?? currentNode;popupMsg.innerHTML=popupMsgs.normal;};const parentButton=document.createElement("button");parentButton.setAttribute("id","parent");parentButton.innerHTML="Parent";parentButton.onclick=()=>{currentNode=nodeSelectParent(currentNode)?? currentNode;popupMsg.innerHTML=popupMsgs.normal;};const childButton=document.createElement("button");childButton.setAttribute("id","child");childButton.innerHTML="First
Child";childButton.onclick=()=>{currentNode=nodeSelectFirstChild(currentNode)?? currentNode;popupMsg.innerHTML=popupMsgs.normal;};const nextButton=document.createElement("button");nextButton.setAttribute("id","next");nextButton.innerHTML="Next
Sibling";nextButton.onclick=()=>{currentNode=nodeSelectNextSibling(currentNode)?? currentNode;popupMsg.innerHTML=popupMsgs.normal;};const prevButton=document.createElement("button");prevButton.setAttribute("id","prev");prevButton.innerHTML="Previous
Sibling";prevButton.onclick=()=>{currentNode=nodeSelectPrevSibling(currentNode)?? currentNode;popupMsg.innerHTML=popupMsgs.normal;};const style=document.createElement("style");style.textContent=`*{font-family:sans-serif;}#pop-up{position:fixed;left:0;top:0;z-index:${Number.MAX_SAFE_INTEGER};background:#333;opacity:.85;border-radius:.4em;border:1px solid #fff;padding-bottom:.75em;display:grid;gap:.25em;color:#fff;}#pop-up div:nth-child(n+2){padding-left:.75em;padding-right:.75em;}#header{display:flex;justify-content:space-between;align-items:center;}#header #title{}#close-button{aspect-ratio:1;border:none;padding:.25em .25em 0 0;line-height:1;text-align:center;color:#fff;font-size:1.2em;}#popup-message{font-size:.85em;max-width:15em;line-height:1.3;}#popup-message p{margin:.5em 0;}#popup-message ul{padding-left:1.1em;margin:.5em 0;}#buttons{display:grid;gap:.25em;grid-template-columns:1fr 1.25fr 1fr;grid-template-areas:"top top top" "left upper right" "left lower right";}button{background:none;border:1px solid #fff;border-radius:.4em;padding:.25em;color:#fff;cursor:pointer;}button#doc-body{grid-area:top;}button#parent{grid-area:left;}button#parent span{}button#child{grid-area:right;}button#child span{}button#prev{grid-area:upper;}button#next{grid-area:lower;}`;popupHeader.appendChild(popupHeaderTitle);popupHeader.appendChild(closeButton);popupButtons.appendChild(docBodyButton);popupButtons.appendChild(parentButton);popupButtons.appendChild(childButton);popupButtons.appendChild(nextButton);popupButtons.appendChild(prevButton);popupEl.appendChild(popupHeader);popupEl.appendChild(popupMsg);popupEl.appendChild(popupButtons);shadow.appendChild(style);shadow.appendChild(popupEl);}}customElements.define("node-selector-popup",NodeSelectorPopUp);}buildPopup();let test=document.createElement("node-selector-popup");document.body.appendChild(test);draggable(popupHeader);function offset(el){const rect=el.getBoundingClientRect(),scrollLeft=window.pageXOffset||document.documentElement.scrollLeft,scrollTop=window.pageYOffset||document.documentElement.scrollTop;return{top:rect.top+scrollTop,left:rect.left+scrollLeft};}function addListenerMulti(element,s,fn){s.split(" ").forEach((e)=>element.addEventListener(e,fn,false));}function draggable(el){const initialOffset=offset(el.parentElement);let isMouseDown=false;const currPos={x:0,y:0};const elPos={x:initialOffset.left,y:initialOffset.top};addListenerMulti(el.parentElement,"mousedown touchstart",onMouseDown);function onMouseDown(event){isMouseDown=true;currPos.x=event.clientX ?? event.touches[0].clientX;currPos.y=event.clientY ?? event.touches[0].clientY;el.parentElement.style.cursor="move";}addListenerMulti(el.parentElement,"mouseup touchend",onMouseUp);function onMouseUp(event){isMouseDown=false;elPos.x=parseInt(el.parentElement.style.left)||0;elPos.y=parseInt(el.parentElement.style.top)||0;el.parentElement.style.cursor="auto";}addListenerMulti(el.parentElement,"mousemove touchmove",onMouseMove);function onMouseMove(event){if(!isMouseDown)return;const newPos={x:event.clientX ?? event.touches[0].clientX,y:event.clientY ?? event.touches[0].clientY,};const delta={x:newPos.x-currPos.x,y:newPos.y-currPos.y,};const pos={x:elPos.x+delta.x,y:elPos.y+delta.y};if(pos.x<0){pos.x=0;}else if(pos.x+el.parentElement.offsetWidth>document.documentElement.clientWidth){pos.x=document.documentElement.clientWidth-el.parentElement.offsetWidth;}if(pos.y<0){pos.y=0;}else if(pos.y+el.parentElement.offsetHeight>document.documentElement.clientHeight){pos.y=document.documentElement.clientHeight-el.parentElement.offsetHeight;}el.parentElement.style.left=pos.x+"px";el.parentElement.style.top=pos.y+"px";}}})();