Promise resolve not called because popup closes too fast - firefox-addon

I have the following piece of code:
browser.windows.create({ url: urls }).then((newWindow) => {
newWindow.tabs.slice(0, pins.length).map((tab, index) => {
browser.tabs.update(tab.id, { pinned: true })
})
})
It works great when I prevent the popup from closing (via webdev tools) but in a regular use case, the resolve is not triggered.

I struggled with this same problem when I started working on my addon (In My Pocket for Firefox, you can have a look at the code on bitbucket if it can help, I implement exactly what I'm about to explain). I needed to trigger network calls to an API from the popup and do something when the request was succesful, and I got the exact same problem.
What you have to keep in mind is that code from a popup is executed as long as the popup is open. Closing the popup is like closing a webpage that contains Javascript: all its JS code is "unloaded", code execution stops, there's nothing more to handle the resolved promise.
A way to circumvent this is to implement the actual behaviour in a background script that will always be running all the time, and communicate between the background script and the popup via messages, through the runtime.sendMessage method and an event listener setup with runtime.onMessage.addListener.
Background scripts are the place to put code that needs to maintain long-term state, or perform long-term operations, independently of the lifetime of any particular web pages or browser windows.
You can get fancy with messages (sharing objects and not plain string) but you get the idea. And this way, your code that does not resolve immediately will still get processed all the way until it's finished, even if the popup is closed before the processing is over.

Related

How to warn user if he/she accidentally close/leave session at website?

We develop accounting system on a web with ASP.NET MVC and encountered this problem - if user is in the middle of the work and somehow manages to close browser all work is gone (and users are not geeks at all it did happen and will happen). Especially problematic at Chrome in Windows after they removed warning of closing tabs from philosophical reasons so now it will just shut down. We would like to be able to somehow catch this behavior. Also even when Firefox for example has warning that user is going to shut down his tabs - simple clicking the checkbox will remove it all again. So is it possible to keep track of this action to prevent user accidentally closing browser and lost all the work? Or is it even possible to do for example in Chrome? The solution would be simple warning window but it needs to show basically everytime if closing while our web application is alive. We don't want to keep session alive after closing browser for obvious security reasons. Also - it should work at Chrome, IE and Firefox. Thank you for your help.
you can try the below code:
window.onbeforeunload = function()
{
return "Are you sure you want to exit";
}
If your front end is using MVVM such as AngularJS or Knockout, or any of the other popular binding libraries, consider a different approach to preventing the user from quitting the page.
In a client-side interval, serialize your view model and store it in local storage.
When the save/exit condition for the current page is met, clear the local storage.
If the page is loaded again, and there is something in local storage, this means that on the previous session, the browser was closed before saving - so deserialize the local storage object back into the viewmodel (use a unique key per page) - you can combine this with some UI that tells the user that their previous state has been restored, click ok to continue or start over to start again (which would reset the viewmodel)
I should add that you'll have to watch out for multiple simultaneous tabs, so you may want to work around this by making the key unique somehow, e.g. creating two invoices simultaneously.
This essentially provides an auto-save but client-side only.
You can combine this technique with using window.onBeforeUnload as per Tejinder's answer, but as you cannot style the "unload confirmation" prompt, providing an auto-resume is a much better experience.

Can you intercept hyperlink clicks with FireMonkey (cross platform)

I have a TWebBrowser on a FireMonkey app (Android and iOS).
I'd like to be able to intercept (trap) hyperlink clicks in the TWebBrowser and do something different with them.
I've found references to working with the BeforeNavigate2 event. However, I see no way of adding a procedure for that event in the Object Inspector. And I'm not sure if that event exists for Android or iOS; or if it's just a Windows event.
Is there any way to get to intercept hyperlink clicks cross platform?
[Edit]
My ultimate goal here is to intercept a hyperlink click in the browser component and do something different with it (e.g., I'd like to spawn it off to the native browser instead).
OnShouldStartLoadWithRequest doesn't trigger on a click. Actually it doesn't seem to trigger anywhere for me. Others have had this issue (Incus J).
OnDidStartLoad does trigger; however, it appears to carry on with the page load in the background regardless of what's going on in the trigger. I can add a myWebBrowser.Stop in the trigger; however, it does not reliably work. I suspect that sometimes the page load completes before the Stop gets fired off.
Playing with OnDidFinishLoad and using the GoBack method proved awkward because the previous page would reload to the top of the page instead of what was being shown in the control (if the user scrolled).
Am I stuck trying to hack Android/iOS equivalents of TWindowsWebBrowserService as Incus J suggests in the thread I reference above?

pause or stop Firefox 'tamper data'?

I have been using 'tamper data' of Firefox to sniff the requests sent back and forth. I don't change the requests, just want a clear view of them. 'tamper data' is a great tool, except for 1 thing, to me,
there is no way to pause, ie, stop tracking requests. I have an application that is sending an ajax call every 1 second or so. All I want is to track the initial requests when the applciation starts. but the ajax calls keep polluting the 'tamper data' window and I cannot get hold of the initial requests as they get rolled to the top.
Can anyone please share some hints to achieve what I want? Really appreciate it
the net tab of firebug does not have that problem. It always fixes on the earliest entries

Long running MVC action execution is it going to stop if the user closes the page?

I have long running data processing on one page. It takes 3 minutes - that is an operation done by the admin and it is not executed very often.
What will happen if the user closes the page? I suppose if that user have more tabs or pages opened to the same site, the execution will continue otherwise will stop. Is that correct thinking?
When an ASP.NET page runs, the page goes through a life cycle in which it performs a series of processing steps. These include initialization, instantiating controls, restoring and maintaining state, running event handler code, and rendering.
All your code will be running no matter if the client is there or not to receive it . as #DLeh mentioned in his comment The server doesn't know and doesnt' care if the browser has closed the page.
check this out for more info MS Link

MVC 4: How to display visual feedback while an Action executes?

I have an Action (Controller Action)that can take a couple minutes to run under some circumstances. I would like to provide our users a visual indication that the Action is running, such as a message, a spinner, or a progress bar. The trouble is, I'm having a tough time figuring out how to "detect" on the front end that the Action has completed.
After researching this for a bit, I stumbled across an article titled "Using Asynchronous Methods in ASP.NET MVC 4." It explains the use of asynchronous actions and .NET Tasks. It looks like good stuff, and I'm going to spend some time studying it, but I am too new to the concept to really understand if it is going to give me what I want.
So, my question to the SO community is, if you have lots of experience with Asynch Actions and Tasks, are these going to help me provide visual feedback to my users while my Action executes? Or, am I starting down the wrong trail?
EDIT:
Thanks, everyone, for your responses. Sorry for my delayed return to this. After having posted this, I realized I got this situation a bit wrong. It turns out what I really need is a FileResult that generates a PDF and then returns it to the browser, and for a visual indicator to be shown to the user while the file is generated.
In my opinion, this is an entirely different question. So, I'll post it as a separate question.
Using an Asynchronous Controller would free up IIS request threads but it won't help you solve your problem. You probably don't need to do much research in this area if you're not already concerned about many long-running user requests coming in at once (enough to starve the IIS request pool).
If you have a traditional Post, Redirect, Get flow, you can easily show a spinner on post which will go away when the browser gets its response and redirects to the new page.
If you are using asynchronous JavaScript, you can show the spinner in your call and hide it in your completion handler.
I would suggest you don't try to start your own background tasks or threads from IIS because it can recycle your app domain at any time. With a user request it will normally drain stop but it won't know about any additional background tasks you start. You can register your object with IIS so it will first notify you before it intends to tear your app domain down but you can only hold off for up to 30 seconds before IIS will continue anyway. Since your work typically takes longer than this to complete, I'm suggesting this more complicated route is probably not going to work well for you and will make your code a bit more complex.
It really comes down to your requirements. Is it alright to make the user wait for the work to complete before they can continue using your application or do they need to be able to continue to interact while waiting for the work to complete?
If you can make them wait, go with the Post, Redirect, Get pattern and a modal spinner you pop up on submit.
If the user must be able to keep working, you're going to need a PartialResponse action and AJAX calls with handlers to show and hide a non-modal spinner to indicate work is in progress.
You could simply have a page, then kick off an AJAX request to your action. When you kick off the request, show a spinner.
You would then hide the spinner when the AJAX request succeeds or errors out.
With this approach, you would not need to have the Action method be asynchronous since you are not tying up the UI.
This is an example of an approach I take with longer running processes to avoid blocking the UI thread and giving visual feedback to the user.
I will demonstrate with a generating report example, this requires .net 4.5.
Create a method around the report generating processing that returns a task.
As an example please see below:
private Task RunReport()
{
return Task.Run(() =>
// The below should contain your generate report code
Thread.Sleep(5000)
);
}
Then make your Action return a task and put an await before calling the report.
This will unblock the UI thread allowing users to continue using the site while the report is being generated. The content is what will be returned to page when it has finished processing.
[HttpPost]
public async Task<ActionResult> RequestReportGen()
{
await RunReport();
// Add your link to the report in the content below
return Content("Report generated!";
}
Include the following javascript libraries:
<script src="#Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
Then use an ajax form to post to your method, please note the LoadingElementId (displays when waiting) and the UpdatedTargetId (displays the finished message).
#using (Ajax.BeginForm("RequestReportGen", "Home", new AjaxOptions { UpdateTargetId = "result", LoadingElementId="loading" }))
{
<div id="loading" style="display:none;">Generating Report...</div>
<div id="result"></div>
<input type="submit" />
}
Using the above method your user can still use the site as your UI thread is not blocked and messages are relayed back to the user when loading and on completion.

Resources