Replace the home button with a javascript function?
-
I never use the Home button. Instead, I would like it to perform a bit of javascript. I would also like to change the button's icon if possible. Alternatively, I could add a new button, but I'd rather just replace Home.
Thanks much! -
@dracho Hmm, since you want to do another icon anyway, I'd create a new button. You would have to stop the home button performing it's standard functionality and that's overtly complicated if you really want a new button with new functionality. The home button can be hidden by right clicking on it, if you are on snapshot – or alternatively just write one line of css to get rid of it.
-
@luetage Thanks, but I'm still unsure as to how to create a new button from scratch...
-
@dracho One thing I quite like to use for my custom button is this mod: https://github.com/LonMcGregor/VivaldiMods/blob/master/mods/button_machine.js
You could get started by adding your own button definition into
MY_BUTTONS
(You can erase all the others if you don't need them, they're just a guide to show you how it works.)At the top of the file there's an explanation of the buttons, but I'd be happy to help explain how you build these buttons if you need more help.
-
@LonM I wonder if it's really that easy for a novice. I have created buttons with new functionality in various modifications and I honestly have to concede I couldn't make a button from this code. It's also so much, a button is only a few lines of code really . Has someone else ever used this?
The only hard thing about such a project is doing a decent svg path and this can't be automated in a serious way.
-
@luetage Fair enough. I would want to make it as easy as possible, but perhaps I'm over-engineering this.
-
@luetage Would this be easier to understand?
It makes it clearer where you define the
html
, where you define theonclick
and the css selector where you want to place the button.(function buttonFactory(){ const MY_BUTTONS = { doSomething: { html: `<button class="button-toolbar-small" title="Do something"> <svg viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> <path d="M9 8v2h-2v-2h-4v2h-2v-4h6v-2h-2v-4h6v4h-2v2h6v4h-2v-2h-4zm-9 2v3h4v-3h-4zm12 0v3h4v-3h-4zm-6 0v3h4v-3h-4z"></path> </svg> </button>`, onclick: () => { /* js goes here */ }, placeAfter: "#footer > .sync-status" } }; function mb(bd){const d=document.createElement("div");d.innerHTML=bd.html;const nb=d.firstChild;nb.addEventListener("click",bd.onclick);return nb;}function cb(bd){const eui=document.querySelector(bd.placeAfter);if(!eui){console.warn(`Can't add button as selector ${bd.placeAfter} is not ready`);return;}const b=mb(bd);eui.insertAdjacentElement("afterend",b);}function mab(){for(const bk in MY_BUTTONS){cb(MY_BUTTONS[bk]);}}function i(){if(!document.querySelector("#browser")){setTimeout(i,500);return;}mab();}i(); })();
Admittedly, it only gets very useful if you have more than 1 button to add.
-
@LonM Looks simpler. Good job on minifying that code Vivaldi style (:
-
@LonM Thanks much, that looks like it will do what I want.
I still am at a loss as to how to implement this new button though - where do I save this code to (what extension does it need) and how do I tell Vivaldi to call it?
-
@dracho Read this: https://forum.vivaldi.net/topic/10549/modding-vivaldi?page=1
The code goes into acustom.js
file and should work from there. -
@luetage I'm seeing no effect... I modified browser.html to include custom.js in the body. I copied only @LonM 's second posting of code (the simplified version) into a custom.js file located in the same directory as browser.html. I added my line of javascript, replacing the comment characters. Nothing has changed.
Also, It looks like it should create a button in the bottom status bar, after Sync. What would I need to replace "#footer > .sync-status" with to make it appear after the Refresh button in the navigation toolbar?
Here's my custom.js:
(function buttonFactory(){ const MY_BUTTONS = { doSomething: { html: `<button class="button-toolbar-small" title="Do something"> <svg viewBox="0 0 16 12" xmlns="http://www.w3.org/2000/svg"> <path d="M9 8v2h-2v-2h-4v2h-2v-4h6v-2h-2v-4h6v4h-2v2h6v4h-2v-2h-4zm-9 2v3h4v-3h-4zm12 0v3h4v-3h-4zm-6 0v3h4v-3h-4z"></path> </svg> </button>`, onclick: () => { javascript:(function(){var q=[];$('.up').each(function(){var that=this;var f=function(index){that.dispatchEvent(new MouseEvent('click',{bubbles:true,cancelable:true}));setTimeout(function(){if(q[index]){q[index](index+1);}else{if(upVoteTimer){window.clearTimeout(upVoteTimer);}}},1000);};q.push(f);});var upVoteTimer=window.setTimeout(function(){q[0](1);},50);}()); }, placeAfter: "#footer > .sync-status" } }; function mb(bd){const d=document.createElement("div");d.innerHTML=bd.html;const nb=d.firstChild;nb.addEventListener("click",bd.onclick);return nb;}function cb(bd){const eui=document.querySelector(bd.placeAfter);if(!eui){console.warn(`Can't add button as selector ${bd.placeAfter} is not ready`);return;}const b=mb(bd);eui.insertAdjacentElement("afterend",b);}function mab(){for(const bk in MY_BUTTONS){cb(MY_BUTTONS[bk]);}}function i(){if(!document.querySelector("#browser")){setTimeout(i,500);return;}mab();}i(); })();
Do I need to use the first bit of code that was posted? (https://github.com/LonMcGregor/VivaldiMods/blob/master/mods/button_machine.js) Or should the simplified version include everything I need?
(My javascript just upvotes everything on a reddit page, with a 1 second delay between each click. I use it as a bookmarklet currently; clicking it while on my frontpage results in a fresh page after 25 seconds of waiting, but that delay is necessary.)
Thanks much!
P.S. Yes, I completely exited and launched the program again.
P.P.S. I just tried the same thing with no effect; I saved buttonfactory.js into the folder, edited browser.html to include buttonfactory.js in the body, and I get nothing...
-
@dracho Second code should be enough. Inspect the UI and take a look at console. If not buttons is showing up, you should have some error in there (it will specify that it's coming from custom.js). Then you know why it doesn't work.
-
@luetage I can modify the CSS and javascript that make up this browser... in real-time... are you kidding me?! Just when I thought I couldn't be more amazed...
Anyway, this error appeared: Can't add button as selector #footer > .sync-status is not ready
I set up sync. No change.
I think I just need to specify where to place it?
-
edit: Hmm, strange, should work, as it's exactly LonM's code. I will take a look.
-
Try
.statusbar-left
Anyway, do you want that button really in the footer? Maybe it would be best if you decided for a location first, instead of copying the example. -
@luetage I mentioned a couple times that I'd like it after the Refresh button in the navigation bar... I just don't know how to translate that into the proper code...
When I try ".statusbar-left" I get "Uncaught SyntaxError: Unexpected token ."
When I try "statusbar-left" I get "Uncaught ReferenceError: left is not defined at buttonFactory (custom1.js:12) at custom1.js:16"
When I try "navigationbar" or "navbar" I get "Uncaught ReferenceError: navbar is not defined at buttonFactory..."
-
@dracho
.toolbar-addressbar > .toolbar > div:nth-of-type(5)
is what you need. This is assuming you are running a standard toolbar without hidden elements. Anyway, that's the problem with general code.The next problems you will run into are: Button has wrong height and not the icon you would like, your code doesn't work because you can't just put a bookmarklet in there :p etc. etc.
-
@luetage Can you give me the whole the line? I'm trying variations upon variations and nothing is working. The last thing I tried was:
placeAfter: toolbar-addressbar search toolbar > toolbar > div:nth-of-type(5)
I think I see the size variables. After inspecting the other toolbar buttons, I think the 12 should be a 16.
I don't see anywhere to specify an icon...
Yeah, I'm not sure why pasting the bookmarklet wouldn't work either...
I really appreciate the help.
P.S. I never specified, but I'm running 2.2.1386.4 (Official Build) (64-bit) on Windows 7.
-
@dracho That is the whole line, you are omitting the punctuation, which is crucial in coding. The dot indicates a class. When you look up code in the html there will be no dot, because it is declared like this:
class="something something-else third-some"
but in css and javascript the resulting selector would look like this:.something.something-else.thirdsome
.Therefore:
placeAfter: ".toolbar-addressbar > .toolbar > div:nth-of-type(5)"
-
@luetage Hooray! https://i.imgur.com/5JfY5LM.png Thank you!
I'll keep experimenting, but any additional help would be awesome.
Main priority is to get the functionality working. It doesn't, as you predicted. Hopefully it's a simple matter of altering the formatting of the bookmarklet?
Edit: I've gotten the size to be (approximately) correct. <button class="button-toolbar" (omitted "-small") and <svg viewBox="0 0 18 16 " ...
<path> must be for the icon... ick.
Edit2: I would be fine with using "[email protected]" from the \Resources folder, flipped upside down. (This button will upvote reddit posts, so an upward-arrow caret lookin' thing should suffice.) If that's too complicated / inefficient, I'll use whatever method to specify an icon that is recommended. Just brainstorming...
And of course it still doesn't do anything. :face_with_stuck-out_tongue_closed_eyes: