delay closing window javascript - javascript

I am writing a Google Chrome extension. Thanks to everyone here for putting up with my silly-assed questions. The routine is primitive but runs fine. The only problem is that it runs so fast that it overloads the server and my ip address gets blocked. So it needs a throttle.
The question is whether it is better to construct something with a timer or with setInterval. After examining a particular page, the content script closes its window with self.close(). If I put this into a setInterval, I could delay the closing of the page and this would slow the whole process as much as the length of the interval. Seems like a good throttle.
Now the last line of the content script is simply:
self.close();
I presume that if I modify the code as follows I would get my delay:
var t=setTimeout("self.close()",2000);
Will this work? Is there a better way to do it?

I'd rather use :
setTimeout(function(){
self.close();
},2000);
But your way is valid too...

If the closing of the page is an appropriate point to wait, then this is perfectly fine. In this case, because it would appear to be a relevant place, then I think you are fine. Although I would use Christophes suggestion.
Using a setinterval to run them periodically will run into problems if your processing takes longer than the interval - as this seems to involve opening and closing pages, it could.
As a rule, setInterval is good for doing small processes regularly. In this case, you just want to put a wait into the processing, which suggests to me that setTimeout is better.

Related

Why is window.open() silently ignored iff called from within a loop and via setTimeout()?

--- EDIT.
I don't get it; yesterday it seemed to be ignored; now it seems to be working. Even within loop and called via setTimeout(). Currently I seem to be having difficulties replicating yesterday's behaviour... What is going on?
--- 2nd EDIT.
First idea how to "fix" the replication of the issue: weirdly, whether or not this works seems to be dependent on the current URL! E.g. works from SE-sites, but not from, say, http://www.asdf.com/. How so?
Whereas setTimeout() works here:
setTimeout(function(){ alert("Hello"); }, 3000);
and window.open() works here:
window.open("https://www.bbc.com","_self");
and even the combination of the two works here:
setTimeout(function(){ window.open("https://www.bbc.com","_self") }, 3000);
suddently and unexpectedly the combination of the two is - silently - ignored in a loop:
i=0;
while(i < 100)
{
setTimeout(function(){ window.open("https://www.bbc.com","_self") }, 3000);
i++
}
Why?
tldr;
This question seems to have come up close to a million times already but not yet (as far as I could tell / search) with a succinct Q&A format; e.g.
Settimeout() javascript function is ignored
Simulating JavaScript's setTimeout() method “from first principles”
Popup blockers in most popular browsers will only allow a new window to be opened if it is opened as a result of code running from a direct user action such as a click. Because a setTimeout() happens some time in the future, is not considered the direct result of a user action so attempts to open windows from setTimeout() are likely blocked by the popup blocker.
In essence, trying to fire window.open from within setTimeout() leaves the browser to "think" it's a popup which deserves (silent) blocking. -- If, in contrast, window.open is fired on it's own, the browser seems to treat it like a "user click", that is, not as spam to be blocked.

WebDriver.io: how to make browser pause/ wait?

For testing, I am loading a page and clicking a button, I am using webdriver.io for testing Since the page is quite heavy, it takes a bit of time to load, I would like the global variable browser to wait few seconds before clicking the button.
I know there is waitForVisible method, but not good enough, I still have no idea if the js has added click event to the button, I am looking for something similar to sleep method in selenium webdriver.
I think you are asking about the pause() method:
pauses queue execution for a specific amount of time
Since using pause() is not a good practice, you can use waitForExist() as an alternative

How can I debug "Back Navigation Caching" in IE?

I'm seeing an odd bug in IE that I'm not seeing in Chrome. Specifically, this involves some JS code not firing when a (Telerik) wizard is navigated back to it's first step.
When the user clicks their "Previous" button, some data isn't being properly loaded. Hitting F12 and bringing up the developer console has shown me the following Warning:
DOM7011: The code on this page disabled back and forward caching. For more information, see: http://go.microsoft.com/fwlink/?LinkID=291337
Ok, so I go to the link provided and I noticed the documentation states:
In order to be cached, webpages must meet these conditions:
...
- The F12 Developer tools window isn't open
This is a problem, because when I use the navigation buttons within my wizard WHILE the dev window is open, it behaves properly, just as it does in Chrome.
How can I debug my related Javascript so I can figure out what's going on? Also, I understand what caching is but I'm not exactly sure what this is about and I have no idea why Chrome behaves differently. Is there a way that I can force IE to behave like chrome and cut on (or off) whatever features that are causing this issue?
Yuck. Back to old school debugging for you.
Short of putting the whole browser into a Windows debugger, you can pretty much forget about setting breakpoints. All you can do is log.
If you are lucky and your problem isn't too deep, you can use a sprinkling of simple alert() statements to let you know the state of things at various stages in your code. One nice thing is that you can serialize objects now pretty nicely; for example, you can do JSON.stringify(this), which will probably give you a giant output, which you can copy and paste into your IDE and unpack. A major upside to doing this is that the alert will block, so you can take your time studying the output. A major downside to this is that race conditions are now much more likely.
Alternatively, you can add a <textarea> to the page and throw your JSON.stringify(this) results into that. Because this means extra DOM mutations, it also increases the odds of race conditions, but not by much. (If race conditions are a possibility, you can do this:
(function () {
var currentState = JSON.stringify(this);
setTimeout(function () {
document.querySelector('textarea').value = currentState;
}, 1000);
})()
Even though these are now asynchronous, if you use this multiple times in sequence, these will execute in that same sequence (unless you change the timeout period).
If you are doing actual page navigations (and not just changing the URL with pushState()), then actually reading those logs is going to be a problem. The solution is to put the page in a frame and write the content out to a sibling frame. As long as both frames are running on the same domain, you will have no problem pushing the data into the sibling frame. If you can't put them on the same domain, you are kind of screwed.

When running user inputed Javascript, is there a way to detect and stop "problem" scripts?

On a page, something like jsFiddle, that executes user inputed Javascript, is there a way to stop / disrupt "problem" scripts running in an iframe?
The major class of problem scripts would be infinite loops, I think. Browsers deal with multiple alerts quite well, but a script like, ​for (var i = 0; ++i; i < 100) { /* do stuff */ }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ will go forever.
How can I either detect and not run, or run and stop, say after 10 seconds of running, a script?
Removing the iframe is fine, but I only want to remove it if the script is still running after 10 seconds, but I don't want to remove it if the script has stopped running.
Here is how I imagine the page will work. If you have a better solution, let me know...
The input page contains a textarea and a blank iframe. The user enters their script into the textarea, and when ready they click on run. Then (backstage) a separate page is created that contains the user script in executable form on an HTML page. The src of the iframe is set to the page with the executable code. This all happens dynamically without a page refresh.
I haven't used this jsandbox script, but it appears to have what you want.
If one script freezes on a page, other scripts will not continue to run. Therefore, there is no way to detect if another script has stopped running, without using a custom plugin or something. Browsers do not use multithreading in that way.
You could set a timeout in the main window which stops / deletes the script after 10 seconds. Then you just have to clear the timeout when the script has finished (just add a line like this to the iframe script: window.frames[0].clearTimeout(window.frames[0].timeoutName) -- I don't know if it works, but it should)
I think this would largely depend on the script and how browsers handle scripts in iframes.
Let's say there's a while(true) in the iframe.
The browser may either lock up, or crash the tab (like what Chrome does), or it might lock up the iframe. If it locks up or crashes the tab, there's nothing you can do with JS itself to prevent it, other than attempting static analysis on the script to find possibly problematic statements (Static analysis to find problematic scripts like that would never be foolproof)
Assuming the browser only locks up the iframe or does something else while still allowing the scripts in the main page to do things, removing the iframe after a certain period of time is an option.
The browser might also display the "Script is slow" popup. In this case, it will most likely either completely shut down all scripts in the entire tab or just in the iframe. If just the iframe, the other scripts in the tab could still clean up after it after the predefined period of time.
Another alternative would be to pre-evaluate the script in a separate runtime where you can detect things like that yourself. You could run the script in, say, Rhino, and determine if it takes too long to process, or something similar.
I don't know if this would work exactly, you might be able to get something like this to work with a little bit of tinkering. I take it that you are taking in text JavaScript and then evaling it, right? You could parse or maybe even just use regex to replace all of the for, for..in, while, and function declaration's call with the function call then some logic that calls your code and figures out if it has been running for 10 secs. If it has it will either return; or break; or something. The code would likely freak out afterward and probably start throwing errors, but at least the script would stop.

How do you know when a download has started from JavaScript?

Basically, I would like to wait for the IE save dialog box to open up, and then run the next line of JavaScript.
Something like:
`window.open(URL,"_self",...);`
window.alert("save dialog started");
Can this be done? Thanks
Grae
I came up with this:
var iframe = document.getElementById("dFrameID");
if(iframe.readyState=='complete')
window.close();
else
wait and call this again.
Seems to work fine.
This is IE solution only. Good luck with FF.
Javascript and the browser do not interact on this level.
I haven't tested this, but you may be able to use setTimeout(...) to get there. I have used it (only in IE) to wait until a print preview dialog had been closed.
The trick would be to wait in a loop (say five times) with enough time between those five loops to guarantee that the save dialog would have appeared. Once the dialog appears, all javascript processing should freeze. Then, when the box is closed, the javascript would start up again, and your setTimeout handler would execute.
Again, I have no idea whether this will actually work, and it would probably be different based on the browser you're using. It is also complicated by the likelyhood that your download window and alert window would be separate.

Categories

Resources