Skip to content

Instantly share code, notes, and snippets.

@thesved
Last active February 20, 2023 21:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thesved/7974968fa64b5e0fab4f79c59af68444 to your computer and use it in GitHub Desktop.
Save thesved/7974968fa64b5e0fab4f79c59af68444 to your computer and use it in GitHub Desktop.
Open a page in Roam's sidebar POC
/*
* Open a page in Roam's sidebar POC, h/t @dvargas92495
* version: 0.4 Mutation Observer, returns Promise
* author: @ViktorTabori
* use: await openPageSidebar("Page Title")
*/
openPageSidebar = (function(){
var observer,
doLog = true, // console.log
running = false, // status;
wrapper = document.querySelector('.rm-find-or-create-wrapper'),
search = document.getElementById('find-or-create-input'),
css = document.createElement('style');
css.innerHTML = '.rm-find-or-create-wrapper, .rm-find-or-create-wrapper .bp3-overlay { visibility:hidden!important }';
return function(name){
return new Promise(function(resolve, reject) {
// don't open when we already in the search input or opening is in progress
if (search == document.activeElement || running) {
if (doLog) console.log('already running or search is active, page not loaded:', name);
reject(`already running or search is active, page not loaded: ${name}`);
return;
}
running = true;
// hide action
document.head.appendChild(css);
// focus and type in search box
'mousedown focus click'.split(' ').forEach(function(e){
search.dispatchEvent(new MouseEvent(e, {view: window, bubbles: true, cancelable: true, buttons: 1}));
});
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,"value").set.call(search, name);
search.dispatchEvent(new Event('input', {bubbles: true, cancelable: true }));
// listen for auto suggestion to arrive
observer = new MutationObserver(function(mutations, obs){
mutations.forEach(function(mutation) {
var result = Array.from(mutation.addedNodes).filter(el=>(el.querySelector('.rm-menu-item .rm-search-title')||{textContent:''}).textContent == name);
if (result.length == 0) return;
obs.disconnect(); // make sure it gets disconnected
// shift+enter to open in sidebar
setTimeout(()=>{
['keydown', 'keyup'].forEach(function(e){
search.dispatchEvent(new KeyboardEvent(e, {bubbles: true, cancelable: true, keyCode: 13, shiftKey: true}));
});
setTimeout(()=>{
cleanup();
if (doLog) console.log('** success, page opened:', name);
resolve(`** success, page opened: ${name}`);
}, 100);
}, 50);
});
});
observer.observe(wrapper, { subtree: true, childList: true });
// auto cleanup after 5 seconds
setTimeout(function(){ cleanup(); reject(`** max waiting time ellapsed, page not yet exists: ${name}`); }, 5000);
// clean up afterwards
function cleanup() {
observer.disconnect(); // disconnect observer
if (!running) return;
search.dispatchEvent(new MouseEvent('blur', {view: window, bubbles: true, cancelable: true, buttons: 1})); // unfocus from search
if (css.parentNode) css.parentNode.removeChild(css); // remove css
running = false;
}
});
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment