I am pretty new in Tampermonkey Javascript and inherited below script to create a button and hoping to select a file upon click.
However, the import data button is not showing in https://test.com/*. I have tested alert("hi"); code in https://test.com/* and it is working fine. Can somebody help me with the solution? What is wrong with the code? Or is it me since I'm noob :) Thank you very much in advance.
// ==UserScript==
// #name Test Tampermonkey Script
// #version 0.1
// #description Test
// #author Me
// #match https://test.com/*
// #grant GM_xmlhttpRequest
// #grant GM_info
// ==/UserScript==
(function() {
'use strict';
function importData() {
let input = document.createElement('input');
input.type = 'file';
input.onchange = _ => {
// you can use this method to get file and perform respective operations
let files = Array.from(input.files);
console.log(files);
};
input.click();
}
})();
Related
I understand that we can create a context menu option/button with Tampermonkey using
// ==UserScript==
// #name Context Menu
// #namespace http://tampermonkey.net/
// #description Test
// #version 0.1
// #author author
// #include *
// #exclude file://*
// #grant GM_openInTab
// #grant GM_registerMenuCommand
// ==/UserScript==]
However, I wanted to create multiple context menu options using a single Tampermonkey script and create multiple functions to perform the task according to the menu option/button that user has clicked.
As mentioned in the comment, you can use GM_registerMenuCommand to open a pop-up and then put all the requirements in that pop-up.
AFA shortcut keys, here is an example of how to set it up. You can adjust it according to your needs.
document.addEventListener('keydown', keydown);
function keydown(e) {
if (e.altKey && e.key === 'j') { // ALT+j
e.preventDefault(); // prevent default action of key
// do something
}
}
Ok so I have the following user script(tampermonkey):
// ==UserScript==
// #name Allow only multiples
// #namespace http://tampermonkey.net/
// #version 0.1
// #description observe and remove multiples
// #author You
// #match https://www.bet365.com/*
// #grant none
// ==/UserScript==
(async function loop() {
try{
const betsipframe = window.getBetslipFrame.bind(window)
const element = betsipframe().bsFrame.getElement().contentDocument.getElementsByClassName("betSlip")[0];
(new MutationObserver(mutations => console.log(mutations))).observe(element, {attributes: true,
attributeFilter: ["data-restrictedmultiples"]})
}
catch(error){console.log(error), setTimeout(loop,89)}
})()
It's basically looping until no error occurs (which means the host page has fully loaded) and then it creates an attribute observer. However the attribute observer never gets executed nevertheless the "data-restrictedmultiples" on the betslip changes.
I don't know can the page scripts have some anti-tamper measures. (I've searched MutationObserver inside them but have not found anything matching.)
A lot of this script is basically cut and paste from other people's scripts that are working for them, but I'm having a strange issue with either .remove or .removeChild failing to run. The script crashes out the userscript engine at this point.
// ==UserScript==
// #name Strip Gocomics Sidebar
// #version 1
// #grant none
// #include https://www.gocomics.com/*
// ==/UserScript==
window.addEventListener('load', setkillsidebar);
function setkillsidebar() {
var interval = Math.random() * 5000 + 1000;
setTimeout(killsidebar, interval);
}
function killsidebar() {
console.log("Start Session");
// const adSidebar = document.querySelectorAll('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar');
var adSidebar = document.getElementsByClassName('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar');
console.log("Got Elements " + adSidebar.length );
if (adSidebar) {
console.log("Found SideBar");
var myParent = adSidebar.parentNode;
console.log("Made Parent");
// myParent.remove();
adSidebar.parentNode.removeChild(adSidebar);
console.log("Stripped SideBar");
var interval = Math.random() * 5000 + 1000;
console.log("Timer Time " + interval );
setTimeout(killsidebar, interval);
console.log("Set Timer");
}
}
So with the addition of the console.log items, I get the following in the Firefox's Web Console:
Start Session
Got Elements
Found SideBar
Made Parent
And that's a wrap, I have a death at either the .remove or the .removeChild so either I am not doing something correctly, or I am having an issue with a security setting that is preventing me from deleting elements from webpages that nobody has told me about.
And for more interesting information, although the title of this post is Greasemonkey, this fails with Tampermonkey as well.
P.S. This is being used in addition to some Stylish CSS that permits me to have a bigger comic view on a small monitor. Doesn't matter if Stylish is running or not.
There are many problems with that userscript, but they mostly boil down to: You need to note the error messages in the console and google the functions that are causing them.
For example:
That's not how getElementsByClassName works.
querySelectorAll does not return a node.
parentNode and removeChild both act on a single node.
Also: the second setTimeout does not appear to be needed. And the load event listener is also (probably) superfluous.
Here is the script with those deficiencies corrected:
// ==UserScript==
// #name Gocomics, Strip Sidebar
// #match https://www.gocomics.com/*
// #version 2
// #grant none
// ==/UserScript==
var interval = Math.random () * 5000 + 1000;
setTimeout (killsidebar, interval);
function killsidebar () {
//-- querySelector() and querySelectorAll () are not the same.
var adSidebar = document.querySelector ('.gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar');
if (adSidebar) {
adSidebar.parentNode.removeChild (adSidebar);
}
}
Although, this script will probably perform better:
// ==UserScript==
// #name Gocomics, Strip Sidebar
// #match https://www.gocomics.com/*
// #version 2
// #require https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #grant GM_addStyle
// #grant GM.getValue
// ==/UserScript==
//- The #grant directives are needed to restore the proper sandbox.
waitForKeyElements (
".gc-container-fluid .layout-2col-sidebar, .gc-page-header--hero .layout-2col-sidebar",
removeNode
);
function removeNode (jNode) {
jNode.remove ();
}
It uses waitForKeyElements -- which is faster and more robust that a straight setTimeout.
I'm trying to click the "Mehr Laden" Button on the URL http://www.sparhandy.de/handy-kaufen/ with Tampermonkey. The Button is located underneath the Smartphone pictures. Here is the script that I wrote so far:
// ==UserScript==
// #name SparhandyScript
// #namespace http://tampermonkey.net/
// #version 0.1
// #description try to take over the world!
// #author Nigel
// #match http://www.sparhandy.de/handy-kaufen/
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #grant GM_addStyle
// ==/UserScript==
waitForKeyElements ("[data\\-behavior=result\\-paging]", triggerMostButtons);
function triggerMostButtons (jNode) {
triggerMouseEvent (jNode[0], "mouseover");
triggerMouseEvent (jNode[0], "mousedown");
triggerMouseEvent (jNode[0], "mouseup");
triggerMouseEvent (jNode[0], "click");
//alert(jNode[0].className);
//alert(jNode[0].parentNode.className);
}
function triggerMouseEvent (node, eventType) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent (eventType, true, true);
node.dispatchEvent (clickEvent);
}
That button is loaded before the jQuery that runs it is ready to fire. So it is not enough to wait for the button in this case. You must also wait for the attached JS to initialize.
A quick and dirty test shows that, for me, the button is not ready until over a second after page load! (Actual time may vary and I did not attempt to find a suitable state marker (that's for you to do ;). )
So, adjusting the code to allow for the button to initialize, works for me:
// ==UserScript==
// #name SparhandyScript
// #match http://www.sparhandy.de/handy-kaufen/
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #grant GM_addStyle
// ==/UserScript==
waitForKeyElements ("[data\\-behavior=result\\-paging]", clickButtonAfterDelay);
function clickButtonAfterDelay (jNode) {
if (document.readyState != "complete") return true;
//triggerMouseEvent (jNode[0], "click");
//-- WARNING: Fixed time may not always work unless it is ridiculously long.
setTimeout (triggerMouseEvent, 2222, jNode[0], "click");
}
function triggerMouseEvent (node, eventType) {
var clickEvent = document.createEvent('MouseEvents');
clickEvent.initEvent (eventType, true, true);
node.dispatchEvent (clickEvent);
}
NOTE: This code will fetch the first additional page of results and then stop. It will not fetch all possible pages; you need a fancier state machine for that.
It's beyond the scope of this question. If you need help with that part, open a new question (after an honest attempt to solve it yourself).
I'm using NinjaKit in Safari (Same as Greasemonkey). The codes are like this
// ==UserScript==
// #name demo
// #namespace http://dailymed.nlm.nih.gov/
// #include http://dailymed.nlm.nih.gov/dailymed/*
// #require http://code.jquery.com/jquery-1.11.0.min.js
// #require http://johannburkard.de/resources/Johann/jquery.highlight-4.closure.js
// ==/UserScript==
$(document).ready(function () {
document.title = 'Hello!' + document.title;
alert("ZaiJian");
$("body p").highlight(["a"]);
});
When I visit this page, the alert can be displayed well, but the .highlight function which depends on jQuery.highlight and jQuery doesn't work. It says:
TypeError: 'undefined' is not a function (evaluating 'c.toUpperCase()')
And I find it quite hard to debug this.. Does anyone have ideas about it?
I believe that NinjaKit currently doesn't do #require. Here's an example I made, that works in Firefox/GreaseMonkey and not in Safari/Ninjakit:
// ==UserScript==
// #name DEBUG
// #include http://localhost/Library.html
// #require file:///Users/#######/Sites/hello_world.js
// #require http://localhost/~#######/hello_world.js // EITHER WAY
// ==/UserScript==
alert('activated');
hello_world();
# hello_world.js
function hello_world(){
alert('Hello World!');
}
Either as a "remote" address or a local file, it worked fine in GreaseMonkey and failed in Safari. It's hard to get the ins-and-outs of NinjaKit currently, in my experience.
You need to read relevant docs before using the jQuery plugin.
First,
Create an entry in your style sheet for the highlight class.
.highlight { background-color: yellow }
In Greasemonkey, the equivalent of that is GM_addStyle('.highlight { background-color: yellow }');.
Second,
To highlight all occurrances of “bla” (case insensitive) in all li elements, use the following code:
$('li').highlight('bla');
You should have left out the brackets, i.e. $("body p").highlight("a");.
Third, I don't think you need $(document).ready() as Greasemonkey scripts are, by default, executed upon DOMContentLoaded event.
Putting it all together:
// ==UserScript==
// #name demo
// #namespace http://dailymed.nlm.nih.gov/
// #include http://dailymed.nlm.nih.gov/dailymed/*
// #require http://code.jquery.com/jquery-1.11.0.min.js
// #require http://johannburkard.de/resources/Johann/jquery.highlight-4.closure.js
// #grant GM_addStyle
// ==/UserScript==
GM_addStyle('.highlight { background-color: yellow }');
document.title = 'Hello!' + document.title;
$("body p").highlight("a");