How do i make my tampermonkey script work with soundcloud? - javascript

I have a tampermonkey script that i make a while ago.
And i want to improve it so it uses soundcloud's SPA and doesn't reload the page everytime you click on one of the shortcuts.
I have looked at some other questions in stackoverflow and tried many things can't figure out a way for it to work.
For example, if i use history.pushState it does change the URL ! But it doesn't update the page.
function insertButton(playlistname,playlistlink) {
let playlist = document.createElement('Button');
let header = document.querySelector('.header__middle');
playlist.innerHTML = playlistname;
playlist.onclick = function(){ history.pushState({}, '', playlistlink);};
playlist.className = 'playlist-button';
header.insertBefore(playlist, header.children[2]);
}

Related

How to store a newly created element to localStorage or Cookie with Javascript?

I am making an idle clicker game for fun, everything was going fine until I encountered a problem.
What I basically want to happen is when the image is clicked and the clickCounter element is over one, the new image element is created. No problem here, the main problem is saving the image. If the user refreshes the page, I want the created element to still be there. I have tried using outerHTML and following some other Stack Overflow forum questions but I could never get a proper solution to this certain problem. I have also tried localStorage and cookies but I believe I am using them wrong.
My code is below, my sololearn will be linked below, consisting of the full code to my project.
function oneHundThou() {
var countvar = document.getElementById("clickCounter")
if(document.getElementById("clickCounter").innerHTML > 1) {
alert("Achievement! 1 pat!")
var achievement1k = document.createElement("img");
// create a cookie so when the user refreshes the page, the achievement is shown again
document.cookie = "achievement1k=true";
achievement1k.src = "https://c.pxhere.com/images/f2/ec/a3fcfba7993c96fe881024fe21e7-1460589.jpg!d";
achievement1k.style.height = "1000px"
achievement1k.style.width = "1000px"
achievement1k.style.backgroundColor = "red"
document.body.appendChild(achievement1k);
oneHundThou = function(){}; // emptying my function after it is run once instead of using a standard switch statement
}
else {
return
}
}
oneHundThou();
I am aware that there is another post that is similar to this, however, my answer could not be answered on that post.
Full code is here: https://code.sololearn.com/Wwdw59oenFqB
Please help! Thank you. (:
Instead of storing the image, try storing the innerHTML, then create the image on document load:
function oneHundThou() {
countvar.innerHTML = localStorage.getItem('clickCount') ? localStorage.getItem('clickCount') : 0; //before if
//original code
localStorage.setItem('clickCount', countvar.innerHTML); //instead of doc.cookie
}
window.addEventListener('DOMContentLoaded', (event) => {
oneHundThou();
});
or, if you don't care that clickCounter may initialize to null, you can remove the ? : and just put
countvar.innerHTML = localStorage.getItem('clickCount');
Edit: shortened code with the countvar variable

Pure javascript from console: extract links from page, emulate click to another page and do the same

I'm curious if it is possible with pure (vanilla) javascript code, entered into the browser console, to extract all links this (first) page, then emulate a click to go to another page, extract links there and go to the third page.
Extract links means to write them into console.
The same question as 1 but link to go to another page makes just an ajax call to update the part of the page and does NOT actually go to another page.
P.S. All links belong to one domain.
Any ideas how can this be done based on pure javascript?
As example, if you go to Google and enter some word ("example"), you may then open the console and enter
var array = [];
var links = document.getElementsByTagName("cite");
for(var i=0; i<links.length; i++) {
array.push(links[i].innerHTML);
};
console.log(array);
to display the array of URLs (with some text, but that's OK).
It is possible to repeat it 3 times from page 1 to page 3 automatically with pure javascript?
P.S. I should actually extract tags in the code above, so tags I named "links". Sorry for confusion (that doesn't change the question).
Thank you again.
If you want to write all the links into the console, you can use a more specific command
FOR GOOGLES
// Firstly, you get all the titles
var allTitles = document.getElementById("ires").getElementsByTagName("h3");
for(var getTitle of allTitles ) { // For each title, we get the link.
console.log(getTitle.getElementsByTagName("a")[0].href)
}
Then, you only need to simulate a click on the nav.
var navLinks = document.getElementById("nav").getElementsByTagName("a");
navLinks [navLinks.length-1].click() // Click on the "Next" button.
FOR ALL SITES
If you want to get all the links, just do the same command, grab the div ID you want id you only want some part of the page, then use getElementsByTagName("a")
You can find out how to use XHR or other to make raw AJAX request
Simple example found on Google :
// jQuery
$.get('//example.com', function (data) {
// code
})
// Vanilla
var httpRequest = new XMLHttpRequest()
httpRequest.onreadystatechange = function (data) {
// code
}
httpRequest.open('GET', url)
httpRequest.send()

How to Handle redirects in Node.JS with HorsemanJs and PhantomJS

I´ve recently started using horseman.js to scrap a page with node. I can´t figure out how exactly it works and I can´t find good examples on the internet.
My main goal is to log on a platform and extract some data. I´ve managed to do this with PhantomJS, but know I want to learn how to do it with horseman.JS.
My code should open the login page, fill the login and password inputs and click on the "login" button. Pretty easy so far. However, after clicking on the "login" button the site makes 2 redirects before loading the actual page where I want to work.
My problem is that I don´t know how to make my code wait for that page.
With phantomJS I had a workaround with the page URL. The following code shows how I´ve managed to do it with phantomJS and it works just fine:
var page = require('webpage').create();
var urlHome = 'http://akna.com.br/site/montatela.php?t=acesse&header=n&footer=n';
var fillLoginInfo = function(){
$('#cmpLogin').val('mylogin');
$('#cmpSenha').val('mypassword');
$('.btn.btn-default').click();
};
page.onLoadFinished = function(){
var url = page.url;
console.log("Page Loaded: " + url);
if(url == urlHome){
page.evaluate(fillLoginInfo);
return;
}
// After the redirects the url has a "sid" parameter, I wait for that to apear when the page loads.
else if(url.indexOf("sid=") >0){
//Keep struggling with more codes!
return;
}
}
page.open(urlHome);
However, I can´t find a way to handle the redirects with horseman.JS.
Here is what I´ve been trying with horseman.JS without any success:
var Horseman = require("node-horseman");
var horseman = new Horseman();
var urlHome = 'http://akna.com.br/site/montatela.php?t=acesse&header=n&footer=n';
var fillLoginInfo = function(){
$('#cmpLogin').val('myemail');
$('#cmpSenha').val('mypassword');
$('.btn.btn-default').click();
}
var okStatus = function(){
return horseman.status();
}
horseman
.open(urlHome)
.type('input[name="cmpLogin"]','myemail')
.type('input[name="cmpSenha"]','mypassword')
.click('.btn-success')
.waitFor(okStatus, 200)
.screenshot('image.png')
.close();
How do I handle the redirects?
I'm currently solving the same problem, and my best solution so far is to use the waitForSelector method to target something on the final page.
E.g.
horseman
.open(urlHome)
.type('input[name="cmpLogin"]','myemail')
.type('input[name="cmpSenha"]','mypassword')
.click('.btn-success')
.waitForSelector("#loginComplete")
.screenshot('image.png')
.close();
Of course you have to know the page you're waiting for to do this.
If you know there are two redirects, you can use the approach of .waitForNextPage() twice. A naive approach if you didn't know how many redirects to expect would be to chain these until a timeout is reached (I don't recommend this as it will be slow!),
Perhaps a cleverer way, you can also use on events to capture redirects, like .on('navigationRequested') or .on('urlChanged').
Although it doesn't answer your question directly, this link may help: https://github.com/ariya/phantomjs/issues/11507

ReportViewer Web Form causes page to hang

I was asked to take a look at what should be a simple problem with one of our web pages for a small dashboard web app. This app just shows some basic state info for underlying backend apps which I work heavily on. The issues is as follows:
On a page where a user can input parameters and request to view a report with the given user input, a button invokes a JS function which opens a new page in the browser to show the rendered report. The code looks like this:
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}
});
The page that is then opened has the following code which is called from Page_Load:
rptViewer.ProcessingMode = ProcessingMode.Remote
rptViewer.AsyncRendering = True
rptViewer.ServerReport.Timeout = CInt(WebConfigurationManager.AppSettings("ReportTimeout")) * 60000
rptViewer.ServerReport.ReportServerUrl = New Uri(My.Settings.ReportURL)
rptViewer.ServerReport.ReportPath = "/" & My.Settings.ReportPath & "/" & Request("Report")
'Set the report to use the credentials from web.config
rptViewer.ServerReport.ReportServerCredentials = New SQLReportCredentials(My.Settings.ReportServerUser, My.Settings.ReportServerPassword, My.Settings.ReportServerDomain)
Dim myCredentials As New Microsoft.Reporting.WebForms.DataSourceCredentials
myCredentials.Name = My.Settings.ReportDataSource
myCredentials.UserId = My.Settings.DatabaseUser
myCredentials.Password = My.Settings.DatabasePassword
rptViewer.ServerReport.SetDataSourceCredentials(New Microsoft.Reporting.WebForms.DataSourceCredentials(0) {myCredentials})
rptViewer.ServerReport.SetParameters(parameters)
rptViewer.ServerReport.Refresh()
I have omitted some code which builds up the parameters for the report, but I doubt any of that is relevant.
The problem is that, when the user clicks the show report button, and this new page opens up, depending on the types of parameters they use the report could take quite some time to render, and in the mean time, the original page becomes completely unresponsive. The moment the report page actually renders, the main page begins functioning again. Where should I start (google keywords, ReportViewer properties, etc) if I want to fix this behavior such that the other page can load asynchronously without affecting the main page?
Edit -
I tried doing the follow, which was in a linked answer in a comment here:
$.ajax({
context: document.body,
async: true, //NOTE THIS
success: function () {
window.open(Address);
}
});
this replaced the window.open call. This seems to work, but when I check out the documentation, trying to understand what this is doing I found this:
The .context property was deprecated in jQuery 1.10 and is only maintained to the extent needed for supporting .live() in the jQuery Migrate plugin. It may be removed without notice in a future version.
I removed the context property entirely and it didnt seem to affect the code at all... Is it ok to use this ajax call in this way to open up the other window, or is there a better approach?
Using a timeout should open the window without blocking your main page
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
setTimeout(function() {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}, 0);
}
});
This is a long shot, but have you tried opening the window with a blank URL first, and subsequently changing the location?
$("#btnShowReport").click(function(){
If (CheckSession()) {
var pop = window.open ('', 'showReport');
pop = window.open ('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>', 'showReport');
}
})
use
`$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.location.href='<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>';
}
});`
it will work.

Chrome JavaScript location object

I am trying to start 3 applications from a browser by use of custom protocol names associated with these applications. This might look familiar to other threads started on stackoverflow, I believe that they do not help in resolving this issue so please dont close this thread just yet, it needs a different approach than those suggested in other threads.
example:
ts3server://a.b.c?property1=value1&property2=value2
...
...
to start these applications I would do
location.href = ts3server://a.b.c?property1=value1&property2=value2
location.href = ...
location.href = ...
which would work in FF but not in Chrome
I figured that it might by optimizing the number of writes when there will be effectively only the last change present.
So i did this:
function a ()
{
var apps = ['ts3server://...', 'anotherapp://...', '...'];
b(apps);
}
function b (apps)
{
if (apps.length == 0) return;
location.href = apps[0]; alert(apps[0]);
setTimeout(function (rest) {return function () {b(rest);};} (apps.slice(1)), 1);
}
But it didn't solve my problem (actually only the first location.href assignment is taken into account and even though the other calls happen long enough after the first one (thanks to changing the timeout delay to lets say 10000) the applications do not get started (the alerts are displayed).
If I try accessing each of the URIs separately the apps get started (first I call location.href = uri1 by clicking on one button, then I call location.href = uri2 by clicking again on another button).
Replacing:
location.href = ...
with:
var form = document.createElement('form');
form.action = ...
document.body.appendChild(form);
form.submit();
does not help either, nor does:
var frame = document.createElement('iframe');
frame.src = ...
document.body.appendChild(frame);
Is it possible to do what I am trying to do? How would it be done?
EDIT:
a reworded summary
i want to start MULTIPLE applications after one click on a link or a button like element. I want to achieve that with starting applications associated to custom protocols ... i would hold a list of links (in each link there is one protocol used) and i would try to do "location.src = link" for all items of the list. Which when used with 'for' does optimize to assigning only once (the last value) so i make the function something like recursive function with delay (which eliminates the optimization and really forces 3 distinct calls of location.src = list[head] when the list gets sliced before each call so that all the links are taken into account and they are assigned to the location.src. This all works just fine in Mozilla Firefox, but in google, after the first assignment the rest of the assignments lose effect (they are probably performed but dont trigger the associated application launch))
Are you having trouble looping through the elements? if so try the for..in statement here
Or are you having trouble navigating? if so try window.location.assign(new_location);
[edit]
You can also use window.location = "...";
[edit]
Ok so I did some work, and here is what I got. in the example I open a random ace of spades link. which is a custom protocol. click here and then click on the "click me". The comments show where the JSFiddle debugger found errors.

Categories

Resources