Userscript that automatically runs on document-start - userscripts

// ==UserScript==
// #name Button
// #run-at document-start
// #include *
// #grant none
// #noframes
// #version 0.0.1
// ==/UserScript==
(function () {
var button = document.createElement("Button")
button.innerHTML = "Title"
button.style = "top:0px;right:0px;position:absolute"
button.style.background='#4CAF50'
document.body.appendChild(button)
var don = document.querySelector('button')
button.onclick = function() {
alert('Hey') }
})()
Script to auto add button on everysite
Trying to inject above script through adguard extension as local title.user.js
But it wasn't working
if i load this script locally it doesnt work
but if i upload it somewhere and load it via url it works
Also on some websites it is not working is it possible that site is blocking javascript injection. If so how to bypass that and run this script on such websites
Ok seems like the website i am trying to inject is arabic and has right to left text and maybe some overlay html and hence button is not visible but when i changed right to left in above code it worked
But still adguard not injecting above code from local user.js only from remote url
Script also not working on stackoverflow.com itself

Looking at the code, document.body is likely undefined, because your meta block #run-at is set to document-start. Try document-end instead.
Either that, or you should change document.body to document.documentElement.
// ==UserScript==
// #name New script - stackoverflow.com
// #namespace Violentmonkey Scripts
// #include *
// #grant none
// #version 1.0
// #run-at document-start
// ==/UserScript==
(() => {
const button = document.createElement('Button');
button.innerHTML = 'Title';
button.style = 'top:0px;right:0px;position:fixed;z-index:10000;';
button.style.background = '#4CAF50';
document.documentElement.appendChild(button);
button.onclick = () => {
alert('Hey');
};
})();

Related

Protractor : Error: Error while waiting for Protractor to sync with the page: "window.angular is undefined. If i create new object of PageObject

I am trying to create a object of page object into spec and i am getting the error.
dashboard.pageObject.js
/*global exports,console*/
module.exports = function(){
this.dashboarurl = 'http://localhost:2525/ars-webapp/';
this.createNewReport_Clickhear = element(By.xpath("//a[contains(.,'Click Here')]"));
this.reportInputModel = element(by.model('reportDefCntrl.reportDef.reportname'));
this.reportDescriptionModel = element(by.model('reportDefCntrl.reportDef.reportdesc'));
this.templateListSelect = element(By.xpath("//select[#id='template-list-select']")).click();
this.selectAlarmDashboarTemplate= element(By.xpath("//option[contains(#value,'number:2')]"));
this.durationOfAlarmTemplate = element(By.xpath("//span[#class='ui-select-placeholder text-muted ng-binding']"));
this.duration_Daily = element(By.xpath("//span[contains(.,'Daily')]"));
this.addObject = element(By.xpath("//button[#data-ng-click='reportDefCntrl.addLogObjects()']"));
this.searchInput = element(By.xpath("//input[#type='search']"));
this.searchButton = element(By.xpath("//button[contains(.,'Search')]"));
this.selectAllButton = element(By.xpath("//button[contains(.,'SelectAll')]"));
this.addObjectButton = element(By.xpath("//button[#data-ng-click='addLogObjectsCntrl.submitObjects()']"));
this.saveButton = element(By.xpath("//button[contains(.,'Save')]"));
}
Specfile is
/global require,console/
var Dashboard = require('../pageObjects/dashboard.pageObject.js');
var dashboard = new Dashboard();
describe('angularjs homepage todo list', function() {
it('should add a todo', function() {
browser.get(dashboard.dashboarurl);
}
if i skip the line
var dashboard = new Dashboard();
and provide
browser.get('http://localhost:2525/ars-webapp/');
instead of
browser.get(dashboard.dashboarurl);
it's working .
but i can't use feature of page object.
if i use
var dashboard = new Dashboard();
so i am getting error
E/launcher - Error while waiting for Protractor to sync with the page:
"window.angular is undefined. This could be either because this is a
non-angular page or because your test involves client-side navigation,
which can interfere with Protractor's bootstrapping. See
http://git.io/v4gXM for details"
Oh Man .. found it !!.. Everything was fine in your code. You know what .. The problem was .. you had a click() in this line this.templateListSelect = element(By.xpath("")).click() in your file - dashboard.pageObject.js
Since you have a require() first .. The dashboard file is executed first and click() is trigerred even before browser.get() and thats the reason you were seeing that error

Displaying a var using AngularJS/HTML on the screen

I'm using MEAN Stack to construct my web application. (Mongo, Express, Angular, NodeJS) I have a server.js file, html file and a css file. My server.js generates a var number which I want to get rendered on the frontend, however I'm having some trouble doing that. Let me explain, on my html there a button I created, whenever the user clicks on that button, I want this specific var to be shown the screen, but it doesn't work.
Here is the code for the creation of the button:
Some Text
Below is the angularjs code for where I use the exact rendering to be occurred:
The Amount:
{{links.amountLinks}}
test this
My server.js code:(Please note I'm using jsdom module)
var jsdom = require("jsdom");
jsdom.env(
url,
["http://code.jquery.com/jquery.js"],
function (err, window) {
// console.log("there have been", window.$("a").length, "io.js releases!");
// alert("there have been", window.$("a").length, "io.js releases!");
console.log(window.$("a").length);
amountLinks = window.$("a").length;
json.amountLinks = amountLinks;
data = amountLinks;
});
Does anyone know how I can fix this?
The code can be fixed as follow:
jsdom.env(
url,
["http://code.jquery.com/jquery.js"],
function (err, window) {
// console.log("there have been", window.$("a").length, "io.js releases!");
// alert("there have been", window.$("a").length, "io.js releases!");
console.log(window.$("a").length);
amountLinks = window.$("a").length;
json.amountLinks = amountLinks;
data = amountLinks;
res.send(JSON.stringify(json, null, 4))
});
}

getting location and running a function on a new window (following window.open) and not the old

I'm a junior dev' and trying to open a new window following ng-click on a button, then run a function with setTimeout on the new window in order to parse a parameter from the new window url. This is my code, but it doesn't really work on the new window (nor console.log or alert):
window.open("https://runkeeper.com/apps/authorize?client_id=499eec7e74084561ac8cd8018fd090f2&redirect_uri=http://localhost:3000/&response_type=code")
setTimeout(function(){
var wl = window.location
alert(wl);
wl = wl.href.split("/code")
console.log("this is wl", wl);
wl = wl[1]
carrotService.connectRunkeeper(wl)
}, 5000)
Appreciate your time and help,
Ark
Since you can easily call functions on a popup window's opener why not have your new window call a function on the opener once it resolves to your redirect URI
On the page it redirects to (defined as redirect_uri in your location string), you could have some on-load JS code that gets the parameter you need and sends it to the window.opener
ie:
window.onload = function() {
var val=getQueryVariable(PARAM_YOU_NEED)
window.opener.myFunctionOnWindowLoad(val)
}
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
(Borrowed that non-jQuery param code from https://css-tricks.com/snippets/javascript/get-url-variables/)
Would that fix your wagon or did I misunderstand what you're trying to do?

Save PDF file loaded in iframe

I am trying to save a pdf file that is loaded in an iFrame. There is by default a button in the iFrame to save the file but I want an extra button (outside the iFrame) to save the file.
<iframe id="labelFrame" src="loadedFile.pdf"></iframe>
<button id="savePDF">Download File</button>
In javascript:
$('#savePDF').click(function(){
var save = document.getElementById('labelFrame');
//Save the file by opening the explorer for the user to select the place to save or save the file in a default location, how do I do this?
}
What is the best way to reach this?
I needed an answer to this question as well and found a solution.
When displaying a PDF in an IFrame the browser will render it in an <embed> element and from there we cant use it in javascript as far as i know.
We'll need to use XMLHttpRequest to get the PDF from a server as a Blob object only then we can both display it and save it using javascript.
var iframe = document.getElementById('labelFrame'),
saveBtn = document.getElementById('savePDF'),
pdfUrl = 'loadedFile.pdf';
var xhr = new XMLHttpRequest();
xhr.open("GET", pdfUrl);
xhr.responseType = 'blob'; // <- important (but since IE10)
xhr.onload = function() {
var blobUrl = URL.createObjectURL(xhr.response); // <- used for display + download
iframe.src = blobUrl
saveBtn.onclick = function() {
downloadBlob(blobUrl, 'myFilename.pdf');
}
};
xhr.send();
The xhr.onload function will set to src of the iframe and add the onclick handler to the save button
Here is the downloadBlob() function that i've used in the example
function downloadBlob(blobUrl, filename) {
var a = document.createElement('a');
a.href = blobUrl;
a.target = '_parent';
// Use a.download if available. This increases the likelihood that
// the file is downloaded instead of opened by another PDF plugin.
if ('download' in a) {
a.download = filename;
}
// <a> must be in the document for IE and recent Firefox versions,
// otherwise .click() is ignored.
(document.body || document.documentElement).appendChild(a);
a.click();
a.remove();
}

Angular - update services object during asynchronous function

Folks: Creating an app in angular and node webkit - where users queue up files for downloading, navigate to their dashboard view and this initiates the downloads.
I've created a service which holds an object of the files data:
..
var downloadObj = {};
// fileObj = {'name':'The file name'; 'download_progress' : dlProgress}
showcaseFactory.myDownloads = function(eventId, fileObj) {
if(eventId){
console.log('update the object');
downloadObj['event_'+eventId] = fileObj;
}
console.log(downloadObj);
};
showcaseFactory.getDownloads = function() {
return downloadObj;
};
..
When the dashboard view loads - ng-repeat loops over $scope.downloadFiles which references this object returning the data.
<div ng-repeat="file in downloadFiles">
<div><span>{{file.name}}</span> [{{file.download_progress}}%]</div>
</div>
I've created a custom module which utilises node_modules to perform the download of the files:
nwjsDownloadFactory.commenceDownload = function(event_id, url, dest, cb) {
var http = require('http');
var fs = require('fs');
var statusBar = require('status-bar');
var path = require('path');
// THIS UPDATES THE OBJECT AND DISPLAYS FINE --------- >>
var id = 7;
var testFileObj = {
'name' : 'This is the file name prior to the download...',
'download_progress' : 10
};
ShowCase.myDownloads(id, testFileObj);
// <<< THIS UPDATES THE OBJECT AND DISPLAYS FINE ---------
var file = fs.createWriteStream(dest);
var request = http.get(url, function(response) {
response.pipe(file);
file.on('finish', function() {
file.close(cb); // close() is async, call cb after close completes.
});
bar = statusBar.create({ total: response.headers['content-length'] })
.on('render', function (stats) {
// var percentage = this.format.percentage(stats.percentage);
// console.log(event_id + '....' + percentage);
var id = 7;
var testFileObj = {
'name' : 'This is the new file name during the download...',
'download_progress' : 35 // this will be replaced with percentage
};
ShowCase.myDownloads(id, testFileObj);
});
response.pipe(bar);
}).on('error', function(err) { // Handle errors
fs.unlink(dest); // Delete the file async. (But we don't check the result)
if (cb) cb(err.message);
});
}
QUESTION: Prior to the line var request = http.get(url, function(response) the object gets updated, and the changes are reflected in the UI. However, I need to constantly update the object with download complete % so I can create a progress bar.. However, as this asynchronous function executes, the object
appears to be updating - see the attached screen shot - but the UI is not reflecting this.
Can somebody please steer me in the right direction - I need the object to update during the function bar = statusBar.create({ and for the changes to reflect in the UI..
Call $scope.$apply() after making changes to your model to notify Angular that it has to update the UI.
showcaseFactory.myDownloads = function(eventId, fileObj) {
if(eventId){
console.log('update the object');
downloadObj['event_'+eventId] = fileObj;
$scope.$apply();
}
console.log(downloadObj);
};
If you use Angular's $http object, this is handled automatically for you, but if you update your model from other asynchronous callbacks, you have to take care of it yourself.
See this blog post and this documentation page for more in-depth explanations about what's going on.

Resources