Scriptish and Multiple Iterations of the Script Launching - firefox

// ==UserScript==
// #id rtskincruff
// #name Right Gmail
// #version 1.0
// #namespace OK
// #author Exaskryz
// #description
// #include https://mail.google.com/*
// #run-at window-load
// ==/UserScript==
//I tried for the #run-at document-end and document-idle
var colored = setInterval(function () {coloring()}, 10000);
function coloring() {
console.log("ping");
var name = document.getElementsByClassName("gb_l gb_n");
console.log("got name");
console.log(name.length);
if (name[0].innerHTML = "+Exaskryz") {
name[0].style.color = "#FF0000";
name[0].style.fontSize = "xx-large";
name[0].innerHTML = "WRONG ACCOUNT TO SEND EMAIL FROM";
//var backg = document.getElementsByClassName("AO");
//backg[0].style.backgroundColor = "#FF0000";
} else if (name[0].innerHTML = "WRONG ACCOUNT TO SEND EMAIL FROM") {
clearInterval(colored);
alert("pun");
}
The script is being launched 5 times and I can't figure out why or how to stop the other instances. The other instances seem to never be able to find any element with a class name (gb_l gb_n) and report back to me a name.length of 0. It's also really weird because it will only ever get up to the part where it logs the name.length and never does any other console.log UNLESS it did get a value for the variable name.
Here's the full script with the full mess of trying to figure out how to stop this script from running every 10 seconds (originally had it set at 1 second):
// ==UserScript==
// #id rtskincruff
// #name Right Gmail
// #version 1.0
// #namespace OK
// #author Exaskryz
// #description
// #include https://mail.google.com/*
// #run-at document-idle
// ==/UserScript==
var colored = setInterval(function () {coloring()}, 10000);
function coloring() {
console.log("ping");
var name = document.getElementsByClassName("gb_l gb_n");
console.log("got name");
console.log(name.length);
if (name[0].innerHTML = "+Exaskryz") {
name[0].style.color = "#FF0000";
name[0].style.fontSize = "xx-large";
name[0].innerHTML = "WRONG ACCOUNT TO SEND EMAIL FROM";
//var backg = document.getElementsByClassName("AO");
//backg[0].style.backgroundColor = "#FF0000";
} else if (name[0].innerHTML = "WRONG ACCOUNT TO SEND EMAIL FROM") {
clearInterval(colored);
alert("pun");
}
console.log("passed first if");
if (name.length>0) {
if (name[0].innerHTML = "+Exaskryz") {
name[0].style.color = "#FF0000";
name[0].style.fontSize = "xx-large";
name[0].innerHTML = "WRONG ACCOUNT TO SEND EMAIL FROM";
//var backg = document.getElementsByClassName("AO");
//backg[0].style.backgroundColor = "#FF0000";
alert("bun");
clearInterval(colored);
alert("done");
}
}
console.log("passed second if");
var nong = document.getElementsByClassName("gb_K gb_ka gb_n gb_ga");
console.log("got nong");
alert(nong.length);
if (nong[0].innerHTML = "CorrectAccount#gmail.com") {
alert("hun");
clearInterval(colored);
alert("done");
}
}

This is a shot in the dark, but it may be possible that your script is also running on any iframes present at mail.google.com. To stop the script from running on iframes, there's two options.
In the meta data block of the script, you can set #noframes to true.
// #noframes true
Or, you can check at the beginning of the script whether or not the script's window is in fact the 'top most' window.
if (window != window.top) { return; }

Related

Getting 'Error: AppleEvent handler failed' every time I run this script in Script Editor

Been struggling to get this script to work. It's meant to batch export notes out of Apple Notes. Script is below.
// set things up
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var notesApp = Application('Notes');
notesApp.includeStandardAdditions = true;
// choose which notes
var notes = notesApp.notes;
var whichNotes = app.chooseFromList(notes.name(), { withPrompt: "Which Notes?", multipleSelectionsAllowed: true });
if (whichNotes) {
// choose save location
var saveWhere = app.chooseFolder().toString();
if (saveWhere) {
// loop through all notes
for(var i=0; i<notes.length; i++) {
// is this note one to be exported?
if (whichNotes.indexOf(notes[i].name()) > -1) {
// save file as html
var filename = saveWhere+"/"+notes[i].name()+".html";
var file = app.openForAccess(Path(filename), { writePermission: true });
app.setEof(file, { to: 0 });
app.write(notes[i].body(), {to: file});
app.closeAccess(file);
}
}
}
}
A bunch of other people have used it with no problems.
I have the same problem with the same script on 10.15.7. The issue is raised on notes.name().
I assume this is related to either too many notes (it used to work, but I created a lot of notes since), or some special char in the note title. But I did not managed to fix it with my notes.
I copied my version below.
(notice the replace to build a valid file name if your note title contain "/".)
// set things up
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var notesApp = Application('Notes');
notesApp.includeStandardAdditions = true;
// choose which notes
var notes = notesApp.notes;
this.console.log("before notes.name()")
var whichNotes = app.chooseFromList(notes.name(), { withPrompt: "Which Notes?", multipleSelectionsAllowed: true });
this.console.log("After notes.name()")
this.console.log("Let's do it") // view / show log / message tab
if (whichNotes) {
// choose save location
var saveWhere = app.chooseFolder().toString();
if (saveWhere) {
this.console.log("note count:"+notes.length)
// loop through all notes
for(var i=0; i<notes.length; i++) {
// is this note one to be exported?
if (whichNotes.indexOf(notes[i].name()) > -1) {
// save file as html
var notename = notes[i].name().replace(/\//gi,'-')
this.console.log("next:"+notename) // view / show log / message tab
var filename = saveWhere+"/"+ notename +".html";
var file = app.openForAccess(Path(filename), { writePermission: true });
app.setEof(file, { to: 0 });
app.write(notes[i].body(), {to: file});
app.closeAccess(file);
}
}
}
}

Display Wikipedia pages clutter free using Tampermonkey

At the end of wikipedia pages, there are reference links. I am trying to not display reference list, and list is toggled when clicked on heading of reference links, like 'Further Reading', 'Notes', 'References' etc. Every reference list has class name 'reflist'. Problem I am having is, when I try to find div with reflist class after heading,
if (div.className == 'reflist') statement does not work. What could be going wrong?
I wrote following code. Problem is when I click 'Further reading', 'reflist' of 'References' is toggled. Clicking 'References' also toggle the same 'relist'. By the way I am not Professional Programmer...
if (document.getElementsByClassName("reflist")) {
let x = document.getElementsByClassName("reflist");
for (let i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
}
function toggle(element) {
element.style.display = element.style.display == "none" ? "block" : "none";
}
// furtherReading is <span> element.
var furtherReading = document.getElementById("Further_reading");
// parentElement is <h2> element
furtherReading.parentElement.style.background = '#f8f9fa';
furtherReading.parentNode.style.borderBottom = 'none';
furtherReading.style.cursor = "pointer";
var references = document.getElementById("References");
references.parentElement.style.background = '#f8f9fa';
references.parentElement.style.borderBottom = 'none';
references.style.cursor = "pointer";
if (furtherReading) {
/* There may be other 'style' or 'div' elements before 'div' having className 'reflist' */
let a = furtherReading.parentElement.nextElementSibling;
while (a) {
if (a.className == 'reflist') {
break;
} else
a = a.nextElementSibling;
}
furtherReading.addEventListener("click", toggle.bind(null, a));
}
if (references) {
let b = references.parentElement.nextElementSibling;
while (b) {
if (b.className == 'reflist') {
break;
} else
b = b.nextElementSibling;
}
references.addEventListener("click", toggle.bind(null, b));
}
Try the following code, test with https://en.wikipedia.org/wiki/Perast
// ==UserScript==
// #name Toggle Wikipedia Reference
// #namespace http://tampermonkey.net/
// #version 0.1
// #description Toggle Wikipedia Reference
// #author Ynjxsjmh
// #match *://*.wikipedia.org/wiki/*
// #grant none
// ==/UserScript==
(function() {
'use strict';
var reflist = document.getElementsByClassName("reflist")[0];
var reference = document.getElementById("References");
console.log("Toggle Wikipedia Reference");
reflist.style.display = "none";
console.log(reference);
reference.addEventListener("click", toggleReference.bind(null, reflist));
function toggleReference(element) {
element.style.display = element.style.display == "none" ? "block" : "none";
}
})();
The problem is that you should get the div manually since nobody help you loop through the div.

postman - how to check picture size

I am trying to write some tests in Postman (I am running the Postman Jetpacks packaged app, if it does matter) and I am facing some inconsistencies.
The scope of my test is to verify the size (width and height) of a set of images against some predefined values.
The scenario is like this: I make a call to a method that returns some urls, then I set the URLs as environment variables and then I verifying the size of each picture. Below is the code I am using in Tests tab in Postman.
tests["Status code is 200"] = responseCode.code === 200;
var data = JSON.parse(responseBody);
//test that response contains the expected attributes
tests["splash_image_url present"] = data.hasOwnProperty("splash_image_url");
tests["home_image_url present"] = data.hasOwnProperty("home_image_url");
tests["login_image_url present"] = data.hasOwnProperty("login_image_url");
tests["register_image_url present"] = data.hasOwnProperty("register_image_url");
tests["splash_logo_url present"] = data.hasOwnProperty("splash_logo_url");
tests["bar_logo_url present"] = data.hasOwnProperty("bar_logo_url");
//set each image URL as environment variable
postman.setEnvironmentVariable("splash_image_url", data.splash_image_url);
postman.setEnvironmentVariable("home_image_url", data.home_image_url);
postman.setEnvironmentVariable("login_image_url", data.login_image_url);
postman.setEnvironmentVariable("register_image_url", data.register_image_url);
postman.setEnvironmentVariable("splash_logo_url", data.splash_logo_url);
postman.setEnvironmentVariable("bar_logo_url", data.bar_logo_url);
//extract images from each URL
var splash_image_url = document.createElement("img");
splash_image_url.src = environment.splash_image_url;
var home_image_url = document.createElement("img");
home_image_url.src = environment.home_image_url;
var login_image_url = document.createElement("img");
login_image_url.src = environment.login_image_url;
var register_image_url = document.createElement("img");
register_image_url.src = environment.register_image_url;
var splash_logo_url = document.createElement("img");
splash_logo_url.src = environment.splash_logo_url;
var bar_logo_url = document.createElement("img");
bar_logo_url.src = environment.bar_logo_url;
//test the size for each picture
tests["splash_image_url width"] = splash_image_url.width === 640;
tests["splash_image_url height"] = splash_image_url.height === 960;
tests["home_image_url width"] = home_image_url.width === 640;
tests["home_image_url height"] = home_image_url.height === 960;
tests["login_image_url width"] = login_image_url.width === 640;
tests["login_image_url height"] = login_image_url.height === 960;
tests["register_image_url width"] = register_image_url.width === 640;
tests["register_image_url height"] = register_image_url.height === 960;
tests["splash_logo_url width"] = splash_logo_url.width === 310;
tests["splash_logo_url height"] = splash_logo_url.height === 80;
tests["bar_logo_url width"] = bar_logo_url.width === 155;
tests["bar_logo_url height"] = bar_logo_url.height === 40;
The problem is that sometimes when running the request all or some of the picture size verification fail. If I continue to manually run the same request again and again it will eventually show all the tests passed. This inconsistency makes the test unreliable.
I am missing something or doing something wrong? Is there a batter way to verify the picture size?
Thanks
Very nice question, was a fun challenge. Thanks !
1. Your problem
The tests actually work after you manually run them a couple of times, because the images are cached at that point.
The main issue here, is that you are not waiting for images to actually load, before checking the properties associated with them.
2. Postman Test Results
I tried a proof of concept on this by waiting for the images to actually load and found out... that my tests were not actually being displayed either as passing or failing.
This was mainly due to the way tests are run. Postman uses eval in the context of the request (more or less).
in Evaluator.js # 111
if (command === "runcode") {
try {
var result = eval(code);
event.source.postMessage({'type': 'test_result', 'result': result, 'scriptType': scriptType}, event.origin);
}
catch(e) {
console.log(e);
event.source.postMessage({'type': 'test_error', 'errorMessage': e.message, 'scriptType': scriptType}, event.origin);
}
}
Unfortunately for us, any sort of the callback logic will not get retroactively pushed back into the results chain.
2.1 Postman Secondary Test Results
It seems that posting a new set of results to event.source will not trigger a new set of results, but get completely discarded.
I have managed to find a workaround for this. Simply end the script with:
function postmanJetpacksSupportsOnlyOneResultPerTest()
{
event.source.postMessage({'type': 'test_result', 'result': tests, 'scriptType': 'test'}, event.origin);
}
throw 'ignore this. Enforcing failure on this test case, real values will come by manually calling *postmanJetpacksSupportsOnlyOneResultPerTest* when you are done with the test case.';
Then just call postmanJetpacksSupportsOnlyOneResultPerTest when all of your callbacks are done.
3. Postman Developers
I really hope you can somehow include the concept of promises. Example:
In the test runner:
var defered = new jQuery.Deferred();
tests['before timeout'] = true;
setTimeout(function() {
tests['on timeout'] = true;
defered.resolve(tests);
}, 500);
tests['after timeout'] = true;
return defered.promise();
In Evaluator.js # 113:
var result = eval(code);
if (result.promise instanceof Function) {
result.then(function(result) {
event.source.postMessage({'type': 'test_result', 'result': result, 'scriptType': scriptType}, event.origin);
});
} else {
event.source.postMessage({'type': 'test_result', 'result': result, 'scriptType': scriptType}, event.origin);
}
4. An example
// handlers
var waiting = 0;
function errorHandler() {
waiting--;
tests[this.image.name + ' load'] = false;
}
function successHandler() {
waiting--;
tests[this.image.name + ' load'] = true;
tests[this.image.name + ' width'] = this.image.width == this.width;
tests[this.image.name + ' height'] = this.image.height == this.height;
}
// test case kind of
function createImageTest(name, url, width, height)
{
// create image tag
var image = document.createElement('img');
// set the name
image.name = name;
// set error handlers
image.onerror = errorHandler.bind({
image: image
});
image.onload = successHandler.bind({
image: image,
width: width,
height: height
});
// finally attach the src
image.src = url;
// waiting on either a fail or a load
waiting++;
}
// the actual test cases
createImageTest('stackexchange logo', 'http://cdn.sstatic.net/stackexchange/img/se-logo.png', 223, 52);
createImageTest('stackoverflow logo', 'http://cdn.sstatic.net/stackoverflow/img/sprites.png', 240, 500);
// wait for all callbacks finished
(function checkFinished(){
// still images to process
if (waiting) {
// check back in another 0.1 seconds
return setTimeout(checkFinished, 100);
}
// ready to send result
postmanJetpacksSupportsOnlyOneResultPerTest();
})();
// the hack from #2.1
function postmanJetpacksSupportsOnlyOneResultPerTest()
{
event.source.postMessage({'type': 'test_result', 'result': tests, 'scriptType': 'test'}, event.origin);
}
throw 'ignore this. Enforcing failure on this test case, real values will come from init...';

Pictures keep going to the top left.(Actionscript 3)

So my project was to make two gallery pages. I called them "gallery1" and "gallery2".The gallery pages each have 5 thumbnails that act like buttons so when you click on em, it opens an swf of the picture. Now the problem is, it always opens on the top left, i want them to be in the middle of the page. This is the code for gallery1. Gallery 2 is the samething but with different pics. b1-b5 are the thumbnails.Please help.
var swfRequest1:URLRequest = new URLRequest("image1.swf");
var swfRequest2:URLRequest = new URLRequest("image2.swf");
var swfRequest3:URLRequest = new URLRequest("image3.swf");
var swfRequest4:URLRequest = new URLRequest("image4.swf");
var swfRequest5:URLRequest = new URLRequest("image5.swf");
var swfLoader:Loader = new Loader();
function opengal(evt:MouseEvent):void
{
var pTarget:String = evt.currentTarget.name;
if(pTarget == "b1")
{
swfLoader.load(swfRequest1);
addChild(swfLoader);
}
else if(pTarget == "b2")
{
swfLoader.load(swfRequest2);
addChild(swfLoader);
}
else if(pTarget == "b3")
{
swfLoader.load(swfRequest3);
addChild(swfLoader);
}
else if (pTarget == "b4")
{
swfLoader.load(swfRequest4);
addChild(swfLoader);
}
else if(pTarget == "b5")
{
swfLoader.load(swfRequest5);
addChild(swfLoader);
}
};
b1.addEventListener(MouseEvent.CLICK, opengal);
b2.addEventListener(MouseEvent.CLICK, opengal);
b3.addEventListener(MouseEvent.CLICK, opengal);
b4.addEventListener(MouseEvent.CLICK, opengal);
b5.addEventListener(MouseEvent.CLICK, opengal);
To set your loaded content in the middle of your stage, you can do like this :
// store files path into an array
var files:Array = ['image01.swf', 'image02.swf', 'image03.swf', 'image04.swf', 'image05.swf'];
var loader:Loader = new Loader();
// use loader.contentLoaderInfo to listen to Event.INIT
loader.contentLoaderInfo.addEventListener(
Event.INIT, function(e:Event):void {
// center our loader
loader.x = (stage.stageWidth - loader.width)/2;
loader.y = (stage.stageHeight - loader.height)/2;
})
addChild(loader);
function opengal(evt:MouseEvent):void {
// here the pTarget should be between 0 and 4 as an array index
var pTarget:int = Number((evt.currentTarget.name).substr(-1, 1)) - 1;
loader.load(new URLRequest(files[pTarget]));
};
...
I hope this can help you.
You have to position your swfLoader in the middle of the screen.
You can do this with this code:
swfLoader.x = (swfLoader.width - stage.stageWidth)/2; // and the y axis in a similar way
The required width and height properties can be retrieved when the contentLoaderInfo dispatches an Event.INIT.

greasemonkey script that outputs all data corresponding to xpath

I would like to write a greasemonkey script that given an xpath returns all of the output of that xpath executed on the current page in a .txt file with one result per row.
How do I do this?
EDIT: Its ok if the output is not written to a file. I just want to have it displayed.
Here is an example that appends a list of all href links to the body of the html. You can pretty it up with style, and make it hidden, floating, etc.
// ==UserScript==
// #name test
// #namespace johnweldon.com
// #description test
// #include *
// ==/UserScript==
(function() {
try {
var xpath = "//a[#href]"; // get all links
var res = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var str = "<div><ul>";
for ( var i = 0; i < res.snapshotLength; i++) {
str = str + "\n<li>" + res.snapshotItem(i);
}
str += "</ul></div>";
var ev = document.createElement("div"); // parent element for our display
ev.innerHTML = str; //quick and dirty
document.body.appendChild(ev);
}
catch (e) {
alert(e.message);
}
}())

Resources