Avoiding the extra prompt asking the user if they would like to close this window

In this article, I will discuss a technique to deal with a common problem in USD. The following is an IE dialog. This dialog will display when a web page attempts to call window.close() in javascript.  The intent of this message was to let the user know a page was trying to close the browser and to give the opportunity for the user to prevent the action.

2016-07-05_10-54-10

Because USD is hosting the IE browser, you may run into cases where you see this same message. In particular, the email form in CRM will do this when you click send. That is because internally when you click send on the email, it ultimate calls the browsers window.close() function.

The Real Problem

Problem #1 is simply that you have an extra click you must do before you can move on to something else. This extra click takes time and is really meaningless in this context.

Problem #2 is what happens when "No" is chosen. The email may actually display in the draft mode even though it has already been sent. If you then continue to make edits and save, it will produce an error indicating that the email is not in the correct state. Of course it isn't, because the email can't be edited after it has been sent but the user may have forgotten that they actually already sent the email because the display did not update.

Problem #3 is what happens when "Yes" is chosen. If you choose yes, the browser will close and USD makes an attempt to recognize this event and closes the hosted control. Ultimately this would be the desired behavior, however, in some circumstances, the browser closes within the WebBrowser .NET control and the control doesn't recognize it and does not notify USD. Now the next time you do something like calling Navigate action on the control, an invalid handle exception, that is unhandled in .NET will be thrown, which can crash USD. Later versions of USD have improved the stability on this scenario but you would still have problem #1.

Best case scenario is that you only deal with problem #1 in that it is a nuisance that the user must deal with.

An approach to deal with the problem

Utilizing the techniques described in Inserting USD Events into HTML Javascript logic and acting upon it, where I discuss techniques for manipulating javascript to interact with the USD environment, we can work around this issue and make a better user experience.

CRM happens to call a function internally called closeWindow(focus). This function is the one that ultimately calls window.close(). Now, it would be an unsupported thing to actually modify this function in CRM, but we can still use it as a workaround for our scenario by injecting the override script from USD itself. That way we are not changing the CRM code at all and no other clients are affected. It is possible that in the next version of CRM, this function could change or be removed. In that case, we may be defining a function that is no longer used or we may be modifying behavior we no longer want. We could then deactivate the action call or simply delete it. As a result, I would suggest marking this Action Call we plan to create with a note indicating that it should be reviewed after each CRM upgrade. This one would be fairly benign though because the likely worst case scenario is that it does some unnecessary work.

Solving the problem

Within our PageLoadComplete event for our Email control, we can add an action call designed to insert the modified script and override the CRM implementation.

2016-07-05_10-52-17

Now every time a frame loads within the web pages, it will inject the above script. Instead of calling window.close(), our new function will call window.open with the special USD close event syntax. USD will then take care of closing the hosted control. You may, alternatively, call the event syntax and create a custom event for yourself to handle to do some alternate behavior such as closing a panel layout that hosts the email control.  As a result, when the user clicks the send button on the email, the email tab will simply close, just as we intended and we will no longer receive the above prompt.