I have the following simple Greasemonkey script:
// ==UserScript==
// #name MetaCPAN Everywhere
// #description Add to every link to CPAN a link to MetaCPAN on a Google results page.
// #namespace http://ajct.info
// #match http://*/*
// #version 0.1
// ==/UserScript==
(function() {
var page_links = document.links;
for (var i=0; i<page_links.length; i++){
if (page_links[i].href.match(/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i)) {
var match = page_links[i].href.match(/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i);
var span = document.createElement("span");
span.innerHTML = " MetaCPAN";
page_links[i].parentNode.insertBefore(span, page_links[i].nextSibling);
}
}
})();
If I run the JavaScript snippet through firebug it does the right thing but if I install it and visit the search results page it doesn't seem to execute the script.
It's presumably something trivial but can anyone point out what I missed?
The main thing is that Google ajaxes-in just about all of its results, so you need a way to wait for the first batch and to check for later batches.
There are numerous techniques. A simple one is to use a timer:
//--- This handles both page-load delays, and AJAX changes.
var chkInterval = setInterval (checkForResultsLinks, 500);
function checkForResultsLinks () {
var links = document.querySelectorAll ('#search a');
if (links) {
for (var J = links.length - 1; J >= 0; --J) {
var link = links[J];
if (link.weHaveProcessed)
continue;
if (link.href.match (/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i) ) {
var match = link.href.match (/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i);
var span = document.createElement("span");
span.innerHTML = " MetaCPAN";
link.parentNode.insertBefore (span, link.nextSibling);
link.weHaveProcessed = true;
}
}
}
}
Notes:
Google search results appear inside a div with the id, "search".
Best add the // #run-at document-end directive to this kind of script.
The current script's#match directive is overly broad, the script will fire on every web page!
You probably want to restrict it to:
// #match http://www.google.com/*
// #match http://google.com/*
There is no need or point to wrapping the code in an anonymous function, like: (function() { ... })(); .
I found that some scripts although really simple wouldn't run in chrome, however I did find a chrome extension that fully supports greasemonkey scripts, it's called Tampermonkey
Related
I am trying to run the following block of code on https://lichess.org/uZIjh0SXxnt5.
var x = document.getElementsByTagName("a");
for(var i = 0; i < x.length; i++) {
if(x[i].href.includes("WaisKamal") && x[i].classList.contains("user_link")) {
x[i].innerHTML = '<span class="title" data-title="GM" title="Grandmaster">GM</span> ' + x[i].innerHTML;
}
if(x[i].href.includes("WaisKamal") && x[i].classList.contains("text")) {
x[i].innerHTML = '<span class="title" data-title="GM" title="Grandmaster">GM</span> ' + x[i].innerHTML;
console.log(x[i]);
}
}
I am using tampermonkey to automate the process. When the page loads, the first if statement runs correctly, but not the second one. However, when I run the second one from the browser console, it works fine.
Here is what the script does in more detail (I want to add those orange "GM"s):
Without the script
With the script
What I want
I have checked this but it didn't solve my problem.
Any help? Thanks in advance.
Most of that page is loaded dynamically (AJAX-driven), which means that your script will normally finish running long before the nodes, that you are interested in, appear in/on the page.
You must use AJAX-aware techniques such as waitForKeyElements or MutationObserver.
Here's a complete Tampermonkey script that illustrates the process:
// ==UserScript==
// #name _Lichess.org, Glorify select users
// #match *://lichess.org/*
// #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 ("a[href*='WaisKamal']", spiffifyLink);
function spiffifyLink (jNode) {
var oldHtml = jNode.html ();
var newHtml = '<span class="title" data-title="GM" title="Grandmaster">GM</span> ' + oldHtml;
jNode.html (newHtml);
}
See this other answer for more information about choosing and using waitForKeyElements and/with jQuery selectors.
I'd like to get all the images in a facebook newsfeed as it is loaded. I'm running a tampermonkey script. I'm having a few problems:
the end result is including in the images with urls that I'm excluding (with facebook static urls).
it only includes some of the images in the newsfeed, and if i scroll down it does not re-evaluate its outputs. This is probably because of the load function, but how can I make it a dynamic load instead? Where could I add a function like .scroll for example?
I'm using jquery to run the functions only when the page is loaded. Should I do something else instead?
Below is some part of the code:
// ==UserScript==
// #name Accountability
// #namespace http://tampermonkey.net/
// #include https://www.facebook.com/*
// #include http*://*.facebook.com/*
// #exclude htt*://*static*.facebook.com*
// #version 0.1
// #description
// #author You
// #match http://tampermonkey.net/scripts.php
// #grant none
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// ==/UserScript==
/* jshint -W097 */
'use strict';
window.addEventListener('load', function() {
var all_images = document.evaluate('//img[#src]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var newsfeed = document.evaluate('//*[contains(#id, topnews_main_stream_408239535924329)]', document, null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var imgSrcs = [];
for (var i=0; i < all_images.snapshotLength; i++){
var this_image = all_images.snapshotItem(i);
var src = this_image.src;
if(src.indexOf('static') > -1){
continue;
}
if(src.indexOf('external') > -1){
continue;
}
imgSrcs.push(src);
console.log(this_image.src);
this_image.addEventListener("click", my_func, false);
}
for (var i=0; i < newsfeed.snapshotLength; i++){
var this_news = newsfeed.snapshotItem(i);
var src = this_news.src;
if(this_news.children.length>0){
}
if(Object.getOwnPropertyNames(this_news)[0]== '_startTime'){
var x = this_news.onreadystatechange();
}
this_news.addEventListener("click", my_func, false);
this_news.addEventListener("mouseover", my_func, false);
}
var my_func = function(){
console.log("the list", imgSrcs);
}
}, false);
You can bind load on all img tags like
$("img").on("load", function() {
console.log($(this)[0].src)
});
If you really want to use pure javascript to mimic on, you can reference Emulate jQuery "on" with selector in pure javascript
sorry for bad english and maybe newby question.
I want to write script that makes something automatic (in web game), everything I need to is go to subpage, then next one, and other. Then script needs to wait specific time and repeat.
I'm using global variable (boolean) and if its true I'm trying to do something like that:
unsafeWindow.location.href = linktodo + linkequipeq + accesKey;
unsafeWindow.location.href = linktodo + linkjednoraz + accesKey;
Script skips first going to page. Using setTimeout doesn't helped. I'm using:
// #run-at document-end
Still not working, I tried to use addEventListener wit parametr 'load' but nothing (I think I need to "clean" eventlistener by closing the window? - tried to use removeEventListener after first function/window redirect is done, fail).
Is it possible to do this without opening and closing new tabs/popups?
Will script like this work in inactive tab?
Can somebody post some example of doing it or tutorial I'll learn it alone?
P.s
for some explanations, those subpages will fill on some equipment, then get some cash and go quest.
linktodo is hostname, linkequipeq is pathname, and accesKey is some secuirty builded in webpage to not doing something after reload (I get acces to it via GM using unsafeWindow).
Huh mayby somebody understand me :D
// #include "site"
// #grant GM_addStyle
// #grant GM_getValue
// #grant GM_setValue
// #grant GM_deleteValue
// #grant GM_listValues
// #grant GM_xmlhttpRequest
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #require https://gist.github.com/raw/2625891/waitForKeyElements.js
// #run-at document-end
var wypki = 0;
var cash = 0;
var czas = 0;
var autowypki = false;
var linkwypki = '?a=q';
var linksklep = '?a=town=';
var linkequipeq = '?a=equip';
var linkjednoraz = '?a=buyone';
var linkrealm;
var accesKey = unsafeWindow.accessKey;
var numbercash = document.getElementsByClassName('cash')[0].getElementsByClassName('panel');
var mynumbercash = numbercash[0];
var cash1 = (mynumbercash.innerHTML);
cash = cash1.slice(28, cash1.indexOf('PLN'));
cash = parseInt(cash.replace(/\s+/g, ''));
var linktodo = link.slice(0, link.indexOf('?a='));
function doquest() {
'use strict';
unsafeWindow.location.href = linktodo + linkwypki;
setTimeout(function () {
unsafeWindow.getElementById('start')[0].click();
}, 2000);
}
function zlomek() {
'use strict';
if (cash < 20000) {
unsafeWindow.location.href = linktodo + linksklep + accesKey;
}
}
function jednoraz() {
'use strict';
if (autowypki === true && cash > 20000) {
unsafeWindow.location.href = linktodo + linkjednoraz + accesKey;
}
}
function equip() {
'use strict';
unsafeWindow.location.href = linktodo + linkequipeq + accesKey;
}
/* --- Main ----*/
function autoQuest() {
'use strict';
autowypki = true;
equip();
setTimeout(jednoraz(),5000);
}
/* --- Main ----*/
if (a === linkwypki) {
var przyciskwypki = document.getElementsByTagName("form")[0].getElementsByTagName('div')[13];
przyciskwypki.innerHTML = przyciskwypki.innerHTML + '<input class="button" type="button" style="height: 20px; width: 110px;" id="autowypki" value=" Robimy wypki" />';
}
document.getElementById("autowypki").addEventListener("click", autoQuest, false);
Greasemonkey scripts are exactly like normal scripts, they don't run unless the page is loaded
On any page that this script is injected loaded, this script will add a click event listener to the element with ID='autowypki'
when that event is fired, the script will set the page to linktodo + linkequipeq + accesKey in function equip
and that's all this script will ever do
there's nowhere that invokes functions doquest and zlomak, so they're just along for the ride in this script
function jednoraz is set to be called after a timeout of 5 seconds, but by then equip has loaded a new page, so, jednoraz wont actually be called as the page it was on is no longer loaded
however, if the same click event is fired in the page that equip loads, then perhaps jednoraz will be called - and then the page linktodo + linkjednoraz + accesKey will be loaded ... I say perhaps, because I'm not 100% sure what function equip will do if it's effectively setting the page to the current page - i.e. if that causes a page load, then jednoraz wont be called because the timeout will probably never fire as the page has reloaded
For this linkify plus script, I'm trying to make the href links 1-click copy to the clipboard, using GM_Setclipboard.
The script works fine if the webpage in question only finds and "linkifies" one string of text. If it linkifies two strings, the 1-click copy function works on both links but will only copy the last string to be "linkified".
I'm not even sure what I am trying to do is possible. Found some similar questions/workarounds that use flash+jQuery+zeroClipboard. But not sure if I can implement this into a Greasemonkey script.
// ==UserScript==
// #name 1Click_COPY
// #include http*://www.w3schools.com/*
// $Revision: #2 $
// ==/UserScript==
// Originally written by Anthony Lieuallen of http://www.arantius.com/
// Licensed for unlimited modification and redistribution as long as this notice is kept intact.
//
// If possible, please contact me regarding new features, bugfixes
// or changes that I could integrate into the existing code instead of
// creating a different script. Thank you
(function (){
function linkify () {
try {
var notInTags=['a', 'head', 'noscript', 'option', 'script', 'style', 'title', 'textarea'];
var res = document.evaluate("//text()[not(ancestor::"+notInTags.join(') and not(ancestor::')+")]",
document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i, el, l, m, p, span, txt, urlRE, linky;
//The string you want to find using reg ex. This finds http to create links.
urlRE=/\b(https?:\/\/[^\s+\"\<\>]+)/ig.
for (i=0; el=res.snapshotItem(i); i++) {
//grab the text of this element and be sure it has a URL in it
txt=el.textContent;
span=null;
p=0;
while (m=urlRE.exec(txt)) {
if (null==span) {
//create a span to hold the new text with links in it
span=document.createElement('span');
}
//get the link without trailing dots
l=m[0].replace(/\.*$/, '');
//put in text up to the link
span.appendChild(document.createTextNode(txt.substring(p, m.index)));
//create a link and put it in the span
a=document.createElement('a');
a.className='linkifyplus';
a.appendChild(document.createTextNode(l));
a.setAttribute('href', l);
//a.setAttribute('onclick', "return false");
//linky=a.getAttritube('href');
//a.setAttritube("onclick", function() { GM_setClipboard(l, 'text')
} );
//copy text to clipboard
a.onclick = function() { GM_setClipboard(l, 'text'); return false};
span.appendChild(a);
p=m.index+m[0].length;
}
// This removes the non linked text
if (span) {
//take the text after the last link
span.appendChild(document.createTextNode(txt.substring(p, txt.length)));
//replace the original text with the new span
el.parentNode.replaceChild(span, el);
}
}
}
catch(e) {dump('Linkify Plus Error ('+e.lineNumber+'): '+e+'\n');}
}
window.addEventListener("load", linkify, false);
} ) ();
Use Anthony Lieuallen latest v2.0.2 of the script. GM_setClipboard works like a charm now. See below:
// ==UserScript==
// #name Linkify Plus
// #version 2.0.2
// #namespace http://arantius.com/misc/greasemonkey/
// #description Turn plain text URLs into links. Supports http, https, ftp, email addresses.
// #grant GM_setClipboard
// ==/UserScript==
/*******************************************************************************
Loosely based on the Linkify script located at:
http://downloads.mozdev.org/greasemonkey/linkify.user.js
Originally written by Anthony Lieuallen of http://arantius.com/
Licensed for unlimited modification and redistribution as long as
this notice is kept intact.
If possible, please contact me regarding new features, bugfixes
or changes that I could integrate into the existing code instead of
creating a different script. Thank you.
Version history:
Version 2.0.3:
- Fix infinite recursion on X(HT)ML pages.
Version 2.0.2:
- Limit #include, for greater site/plugin compatibility.
Version 2.0.1:
- Fix aberrant 'mailto:' where it does not belong.
Version 2.0:
- Apply incrementally, so the browser does not hang on large pages.
- Continually apply to new content added to the page (i.e. AJAX).
Version 1.1.4:
- Basic "don't screw up xml pretty printing" exception case
Version 1.1.3:
- Include "+" in the username of email addresses.
Version 1.1.2:
- Include "." in the username of email addresses.
Version 1.1:
- Fixed a big that caused the first link in a piece of text to
be skipped (i.e. not linkified).
*******************************************************************************/
var notInTags=[
'a', 'head', 'noscript', 'option', 'script', 'style', 'title', 'textarea'
];
var textNodeXpath=
".//text()[not(ancestor::ns:"+notInTags.join(') and not(ancestor::ns:')+")]";
//Insert Your personal Regex below. (My example: ip + port in "xxx.xxx.xxx.xxx PORT" format)
var urlRE=/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s\d{1,5}\b/gi;
var queue=[];
/******************************************************************************/
linkifyContainer(document.body);
document.body.addEventListener('DOMNodeInserted', function(event) {
linkifyContainer(event.target);
}, false);
/******************************************************************************/
function linkifyContainer(container) {
var xpathResult=document.evaluate(
textNodeXpath,
container,
{ lookupNamespaceURI: function(prefix) { return container.namespaceURI; } },
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null
);
var i=0;
function continuation() {
var node, counter=0;
while (node=xpathResult.snapshotItem(i++)) {
linkifyTextNode(node);
if (++counter>50) {
return setTimeout(continuation, 0);
}
}
}
setTimeout(continuation, 0);
}
function linkifyTextNode(node) {
var i, l, m;
var txt=node.textContent;
var span=null;
var p=0;
while (m=urlRE.exec(txt)) {
if (null==span) {
//create a span to hold the new text with links in it
span=document.createElement('span');
}
//get the link without trailing dots
l=m[0].replace(/\.*$/, '');
//put in text up to the link
span.appendChild(document.createTextNode(txt.substring(p, m.index)));
//create a link and put it in the span
a=document.createElement('a');
a.appendChild(document.createTextNode(l));
//if (l.match(/^www/i)) {
// l='http://'+l;
//} else if (-1==l.indexOf('://')) {
// l='mailto:'+l;
//}
a.setAttribute('href', l);
a.onclick = function() { GM_setClipboard(l, 'text'); return false};
span.appendChild(a);
//track insertion point
p=m.index+m[0].length;
}
if (span) {
//take the text after the last link
span.appendChild(document.createTextNode(txt.substring(p, txt.length)));
//replace the original text with the new span
try {
node.parentNode.replaceChild(span, node);
} catch (e) {
console.error(e);
console.log(node);
}
}
}
http://www.htmlgoodies.com/beyond/javascript/article.php/3458851
See if this helps.
I am right now on phone so can't explore much. Will try once I get on a system.
For example, I am trying to change this:
<a href="javascript: void(null)" class="jv-redirectCandidate"
key="pcxe7gwP"
>Some Name</a>
Into this:
Some Name
I need the string "pcxe7gwP" that is currently part of
key="pcxe7gwp"
and then I want to attach it to part of a URL
https://www.foo.com/something.aspx?p=
and the use that as the href in place of the current
"javascript: void(null)"
I am using the Tampermonkey Chrome extension and trying to create a userscript to accomplish this. I am new to userscripts and would love any help. Thanks!
Test in Greasemonkey, don't need jquery.
// ==UserScript==
// #name Change link href with it's key
// #namespace test
// #grant none
// #version 1
// #include http://localhost:8000/*.html
// ==/UserScript==
var prefix = 'https://www.foo.com/something.aspx?p=';
var links = document.querySelectorAll('a.jv-redirectCandidate[key]');
for (var i = 0; i < links.length; i += 1) {
var link = links[i];
link.href = prefix + link.getAttribute('key');
}
If I understood right, this is what you are looking for:
<html>
<script type="text/javascript">
function changeHREF(element){
element.href = "https://www.foo.com/something.aspx?p=" + element.key;
}
</script>
<body>
Some Name
</body></html>
Another possible solution:
<html>
<script type="text/javascript">
function changeHREF(){
elements = document.getElementsByClassName("jv-redirectCandidate");
for(i = 0; i<elements.length; i++) {
elements[i].href = "https://www.foo.com/something.aspx?p=" + elements[i].getAttribute("key");
}
}
</script>
<body onload="javascript:changeHREF()">
Some Name
</body></html>
Well, there are other solutions to achieve the same results. But, I think that it is out of topic.
Cheers
Here is a complete script that will work in either Tampermonkey or Greasemonkey. It use's jQuery for ease and power:
// ==UserScript==
// #name _De-javascript links
// #include http://YOUR_SERVER.COM/YOUR_PATH/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #grant GM_addStyle
// ==/UserScript==
/*- The #grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
//-- Get links with the class "jv-redirectCandidate".
var linksToFix = $("a.jv-redirectCandidate");
//-- Loop through the links
linksToFix.each ( function () {
var jThis = $(this); //-- An individual link
var key = jThis.attr ("key");
jThis.attr ("href", "https://www.foo.com/something.aspx?p=" + key);
} );