New Interface : Delayed Call Around Selection Final Point... for showing translation bubble for example ?
-
Hello,
(Feature Request linked : Automatic and easy show for translation built-in bubble)
I tried to transpose a javascript feature to give an example of a new interface between the user and the browser.
I named it Delayed Call Around Selection Final Point (a great name indeed!!). Its purpose is to launch any functions ; but I developped it with the idea to display the Vivaldi translation bubble easily and quickly, almost transparently and not tiring.
I strongly believe this should be a built-in option (specially for this translation bubble) and I coded an example below :
(copy it and launch it into a script extension like ViolentMonkey with which I tested it)//Uses interface : examples //Opens tab for a search with selection text Interface_DelayedCallAroundSelectionFinalPoint(openTabForSearch, Delay=1550,SquareSide=30); //(Vivaldi 4.2) Translate Vivaldi System () : delay is quite low because the vivali translate system is itself low to be activated //Interface_DelayedCallAroundSelectionFinalPoint(callVivaldiTranslateSystem, Delay=150,SquareSide=30); //Plays beep //Interface_DelayedCallAroundSelectionFinalPoint(playBeep, Delay=1250,SquareSide=30); //====================================================================================================== // RUNS VIVALDI TRANSLATE SYSTEM // // Needs activation Vivaldi setting to show translate button that we catch to run Vivaldi Translation // runs until 4.2 (with shadowRoot opened) no more with 4.3 (with shadowRoot closed) //====================================================================================================== function callVivaldiTranslateSystem(){ var but; but=catchTranslateButton(); if (but!==undefined){but.click()}; function catchTranslateButton(){ var shr,ct,but; try{ shr=document.body.nextSibling.shadowRoot; //with shadowroot (open) if (shr==undefined){console.log("Translate tool : no have catched shadowRoot")}; ct=shr.querySelector(".vivaldi-translate-button-container"); but=ct.querySelector(".vivaldi-translate-button"); if (but!==undefined){ ct.style.zIndex="-1"; return but } }catch{}; }; }; //Get Style from object function getStyle(className,sheet) { var r; sheet = sheet || document.styleSheets[0]; var classes = sheet.rules || sheet.cssRules; for (var x = 0; x < classes.length; x++) { if (classes[x].selectorText == className) { r=classes[x]; } } return r; } //Catching shadowRoot after body element(!) and html vivaldi translate button to hide this last one var sr; var observerSR = new MutationObserver(observingShadowRoot); function observingShadowRoot(mutations) { var u,tbc; try{u=document.body.nextSibling.shadowRoot}catch{}; //with shadowroot (open) if (u!==undefined) { sr=u //console.log(sr); try{ tbc=getStyle(".vivaldi-translate-button-container",sr.styleSheets[0]); tbc.style.zIndex="-1"; }catch{}; //observerSR.disconnect; }; }; observerSR.observe(document, { attributes: false, childList: true, characterData: false, subtree: true }); //====================================================================================================== // ALTERNATE DO-FUNCTION EXAMPLES //====================================================================================================== //Plays a beep function playBeep() { var audio = new Audio( 'https://media.geeksforgeeks.org/wp-content/uploads/20190531135120/beep.mp3'); audio.play(); }; //Opens a new tab function openTabForSearch() { var url ="https://www.google.com/search?q={searchTerms}"; var s=document.getSelection(); if (s!==undefined) { url=url.replace("{searchTerms}",s.toString()); window.open(url, '_blank'); }; }; //====================================================================================================== // INTERFACE : DELAYED CALL AROUND SELECTION POINT FINAL POINT //====================================================================================================== //#After selection in all the document with mouse, it needs two conditions with mouse //to activate your own function : // -cursor should stay around a square area around the final-selection cursor position // when selection has just been ended (in px) // -wait a delay (in ms) //#Call example : // Interface_DelayedCallAroundSelectionFinalPoint (DoFunctionName, Delay = 1250, SquareSide = 20); // function Interface_DelayedCallAroundSelectionFinalPoint(DoFunction, Delay = 1250, SquareSide = 20) { //there is a selection document.addEventListener("selectstart", selectionStarting, true); function selectionStarting(e){ //mousearea detection square around selection point var AdX = SquareSide / 2, AdY = SquareSide / 2; var inside = true; var mousePosI = { x: -1, y: -1 }; var selection=false; var mouseSelection=false; //cancels all function cancelAll(){ inside=false; selection=false; mouseSelection=false; try{document.removeEventListener("mouseup", mouseUp, true)}catch{}; try{document.removeEventListener("mousemove", mouseMove, true)}catch{}; //document.removeEventListener("selectstart", DelayedCallMouseCallBack, true); try{document.removeEventListener("keypress", cancelAll, true)}catch{}; try{document.removeEventListener("mousedown",cancelAll, true)}catch{}; }; //if keypress we all cancel as well if there is a mousedown click document.addEventListener("mousedown", cancelAll, true); document.addEventListener("keypress", cancelAll); //selection starts selection=true; //made with mouse ? document.addEventListener("mouseup", mouseUp, true); function mouseUp(e){ if (selection==true){ if (e.button==0){ mouseSelection=true; mousePosI = { x: e.clientX, y: e.clientY }; //cursor is inside area ? document.addEventListener("mousemove", mouseMove, true); function mouseMove(e){ if (selection==true && mouseSelection==true){ if ((e.clientX <= mousePosI.x + AdX && e.clientX >= mousePosI.x - AdX) && (e.clientY <= mousePosI.y + AdY && e.clientY >= mousePosI.y - AdY)) { inside = true; //console.log("in"); } else { inside = false; //console.log("out"); }; }; }; //launch operations setTimeout(function () { if (inside == true) { DoFunction(); cancelAll(); }else{ cancelAll()}; }, Delay); }else{mouseSelection=false;cancelAll}; }; }; }; };
The code offers to try the interface with the display of the translation bubble : I launched the vivaldi function (for lack of knowing a particular api and how to apply it) by simulating a click on the displayed button to call the bubble (setting in vivaldi parameter) ; it works for version 4.2 (where the object uses a shadowroot opened) and not since 4.3 (where this object is closed); I also thought of simulating a keyboard shortcut, but the javascript blocks the attached browser features.
So I gave up illustrating the main function I was attaching to the interface, I quickly made some functions to show the interest (even if I think the interface is much better adapted for the translation bubble):- opening a search page in a new tab with the selection text
- playing a rather shrill beep!
-
Ppafflick moved this topic from Customizations & Extensions on