Close the browser window in Vaadin - javascript

I have google'd quite a lot but was not able to find a solution for this problem. I have a Vaadin application that runs in a browser window. I have a logout button on it, clicking on it must invalidate the session and close the browser window. I was able to get this code to invalidate the session and close the application. However, I am looking to close the browser window also, which is where I am not having any success
WebApplicationContext webCtx = (WebApplicationContext) appRef.getMainWindow().getApplication().getContext();
HttpSession session = webCtx.getHttpSession();
session.invalidate();
appRef.getMainWindow().getApplication().close();
I am using vaadin 6.x and tried the following but they don't work on browsers I tried which is Chrome and IE.
appRef.getMainWindow().executeJavaScript("window.close();");
Any ideas would be greatly appreciated. Another question I have is do I need to get the name of the main Window and then call mainWindow.close(); or just window.close() ?

Read https://vaadin.com/book/vaadin6/-/page/application.close.html if you haven't done so far.
If appRef is already your Application, you do not have to call appRef.getMainWindow().getApplication() to get the Application. Just do appRef.close();
Do not invalidate the session manually. It messes with the vaadin lifecycle, so the next lines are not executed anymore, at least not in the vaadin context. Just do "application.close()" and let vaadin do the rest.
In vaadin 6 "window.close()" works, i use it with IE and chrome. So after you removed the session invalidation stuff, your code appRef.getMainWindow().executeJavascript("window.close()"); will work as expected.

Related

How to communicate between Edge-in-Edge-mode and Edge-in-IE-mode?

I have got a legacy system with a web page A which calls some other web page B.
When the web page B is closed, the web page A must be refreshed, it has to read some stuff from the database which has been changed by B.
Until now, this is done by calling some function on page A when B is closed, via JavaScript.
The function on page B is something like this:
function goBack() {
window.opener.RefreshStuff(); <--- Calls RefreshStuff on page A
window.close();
}
This works well.
From now on, page A shall run in Edge-in-IE-mode and page B shall run in Edge-in-Edge-mode.
Edge-in-IE-mode is running in another process than Edge-in-Edge-mode.
Therefore in the function goBack, the window.opener is not known anymore and the function goBack does not work anymore.
I need some way to communicate between Javascript in page B, which runs in Edge-in-Edge-mode and Javascript in page A which runs in Edge-in-IE-mode.
Can you help me?
As far as I know, Edge and Edge IE mode actually run different browsers, so you can't get a handle to the IE window from Edge.
You can try sharing cookies between Edge and IE, it may work for you, it needs to be configured through group policy, please refer to this document: Configure IE mode policy.
Finally, set the source-engine="Both" attribute in the sites.xml file to share the cookie between Edge and IE of the stie you need. Just refer to this doc: Cookie sharing between Microsoft Edge and Internet Explorer.

How to free "busy" c# webbrowser

I am using c# and webbrowser to scrape a web page.
Sometimes, I will run into a "Message from webpage" popup error.
I use:
hwnd = FindWindow("#32770", "Message from webpage");
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Button", "OK");
SendMessage(hwnd, 0xf5, IntPtr.Zero, IntPtr.Zero);
To press ok. However when I try to navigate again, I'll get an error that the webbrowser is still busy. How can I force it to become free again?
The only workaround I have found is to try to "restart" the browser. I am doing the following:
ie.Dispose();
ie = new System.Windows.Forms.WebBrowser();
This seems to work, but as soon as I navigate, I get a "A script on this page is causing Internet Explorer to run slowly" popup. I can still continue navigating but I notice that overtime I have a rather large memory leak. I'm not sure if it is from the way I have "restarting" the browser or from leaving the popup up.
If you have a way to "free" the browser or if you can confirm the correct way to restart a browser, that would be greatly appreciated.
It certainly seems that you are using Dispose() correctly to destroy (elegantly) the WebBrowser class. And creating it with new is fine also. (Just take care of which thread you use - as per link below)
According to here, you could try a Stop() and Refresh() sequence, although this may not prevent the memory leak.
It's hard to tell from your scant code if the leak is due to the Browser class, your code or the webpages themselves...(Most likely the web pages, considering the amount of buggy webpages)
But if speed is not important, disposing and renewing the WebBrowser class should not be an issue

HTML transient modal window

We have a legacy web application. At various places it opens a window with the help of Privilege Manager on Firefox to get the needed result.
Some of these windows open a Java applet or a PDF document.
The client machines are updating Firefox and Privilege Manager is gone.
What is the easiest way around it?
The problems are :
There must be only one instance of the pop-up at anyone time. This could be done by selecting appropriate window name on window.open() call.
If the window is opened again (by means of user action), it should not reload but just focus to bring it to the foreground (I have seen I can keep a reference to the window on JavaScript to do that)
It basically really must be transient/modal so that the client cannot leave the current page or reload or any other kind of interaction with the parent window (except opening/refocusing the child window) without closing the child window first. I have no idea how to do that.
Do anyone has an idea how to do that?
The client is only Firefox (it works in a special kiosk configuration) on Linux.
I read somewhere that I could somehow write an extension but I am basically clueless about extensions and its API.
Edit1:
Example of (simplified) legacy code. Not really sure if all the permissions were required, but this is it: This function opens a window that stays over the parent window and prevents any interaction from the user with the parent window.
function fWindowOpen(url, name) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
netscape.security.PrivilegeManager
.enablePrivilege("CapabilityPreferencesAccess");
netscape.security.PrivilegeManager
.enablePrivilege("UniversalPreferencesWrite");
netscape.security.PrivilegeManager
.enablePrivilege("UniversalPreferencesRead");
netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
window.open(
url,
name,
"screenX=70,dependent=yes,menubar=0,toolbar=0,width=900,height=700,modal=1,dialog=1"
);
}
function fnCapture(){
fWindowOpen("/path/to/document_or_japplet/page","_blank");
}
HTML:
<button value="Capture" property="btnCapture" onclick="javascript:fnCapture();"/>
Edit2: Solution
On a typical extension, on the xul code, define this javascript code:
var dialogExt = {
listener: function(evt) {
// Do work with parameters read through evt.target.getAttribute("attribute_name")
window.openDialog(evt.target.getAttribute("url"), evt.target.getAttribute("name"), evt.target.getAttribute("features"));
}
}
// from examples
document.addEventListener("dialogExtEvent", function(e){ dialogExt.listener(e); }, false, true);
Then, on the web page:
var element = document.createElement("dialogExtElement");
element.setAttribute("url", url);
element.setAttribute("name", name);
element.setAttribute("features", features);
document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent("dialogExtEvent", true, false);
element.dispatchEvent(evt);
Now, maybe I am missing some security checks to let the code work if it originates from the same host, and how to handle a reference to the document that requested the dialog as means of interaction between the dialog window and it's opener.
The Privilege Manager was deprecated in Firefox 12 and removed in Firefox 17 (briefly restored).
You might want to look into Window.showModalDialog(). However, it is deprecated and is expected to go away within the year, or in 2016 if you go with an extended service release (ESR) of Firefox 38. It may be a temporary solution while you develop an extension.
In order to accomplish the same tasks, you will need to write an extension and ask the user to install it (from Bypassing Security Restrictions and Signing Code, the old information about Privilege Manager):
Sites that require additional permissions should now ask Firefox users to install an extension, which can interact with non-privileged pages if needed.
It is possible to write such an extension using any of the three different extension types:
XUL overlay
Restartless/Bootstrap
Add-on SDK
For the first two types, you would use window.open(). The modal option is in "Features requiring privileges". You will probably also want to look at Window.openDialog().
For the Add-on SDK, you would normally use the open() function in the SDK's window/utils module. Here, again, you will probably want to look at openDialog().
It appears you may be opening content that is supplied from the web in these modal windows. It is unlikely that you will get an extension approved to be hosted on AMO which opens content in such windows which in not included in the add-on release. This does not mean you can not develop the extension and have it installed on your kiosk clients without hosting it on AMO. However, there are additional restrictions in development for Firefox this year which will make this significantly more difficult, see: "Introducing Extension Signing: A Safer Add-on Experience".
You should be able to get similiar window.open behavior, including support for the modal option from the sdk's window/utils module.
You will have to install the onclick listener with a content script, send a message to the addon-main through its port and then open that window from the addon main.

Debugging Javascript (and Facebook Login)

I am not good with JS :) I am messing around with adding the Facebook Login to my site here at http://www.comehike.com and on top right you can see that the FB login button renders, but if you click it, it doesn't work.
I tried putting the button into the body of the page and it actually worked. So my sense is that its some JS issue that caused the problem. How do I debug it in Firebug or another tool? I am just not fluent maneuvering in these technologies.
Any help would be appreciated. All I really want to do is make the FB login button click-able in the header :)
Thanks,
Alex
Use a console (Firebug, for instance) and the problem is pretty clear.
Uncaught ReferenceError: FB is not defined www.comehike.com:94
FB.login() called before calling FB.init(). all.js:3
My guess is that you're trying to call FB.init() before the Facebook script actually loads.
Line 94 contains this code:
window.onload=FB.init();cycleBan();
If you're trying to execute FB.init() (and also cycleBan()?) on the window's onload event, that's not going to work. What the above code does is set the value returned by FB.init() to the window.onload handler, and then calls cycleBan(). Try this instead:
window.onload = function () {
FB.init();
cycleBan();
};
Edit after reading a bit of the Facebook API docs, it looks like you're not passing an appId to FB.init(), which I think is necessary:
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId:'YOUR_APP_ID', cookie:true,
status:true, xfbml:true
});
</script>
<fb:login-button>Login with Facebook</fb:login-button>
So you should change your code to use the same structure.
Edit 2 okay, so I've never used the Facebook API before - just took another look at your page and it looks like you're already using the right basic template, and I guess you're passing the appId as a URL parameter. Oh well, shows how much I know.
On Firefox you can use the Firebug add-on (I'm guessing you know about it as you used the name in your question). Just go to the page, click the Firebug icon in the status bar at the bottom, and use the Scripts tab to go to your script code, set breakpoints, and single-step through.
You can also do this with the dev tools built into Chrome, Safari, Opera, and even IE from IE8 onward. (In earlier versions of IE you can use the free edition of VS.Net for debugging.)
One nice thing about all of these is that you can right-click an element (like your button) and choose "Inspect element" to go straight to information about it. On Chrome at least (and probably others) that includes event handlers assigned to it, which makes it easy to find things.
Make sure the script connecting to the js is secure
http://connect.facebook.net/en_US/all.js
should be
https://connect.facebook.net/en_US/all.js
If you pass the non existing FB app key to init() then only you get the error of 'FB.login() called before calling FB.init()'
Make sure, you haven't been doing the same.

Creating a tweet button without opening a new window

I'm looking to add a "tweet this" button to a site. Simple enough, right? The catch is that the site is meant to run on an embedded platform that doesn't particularly handle popup windows, so I'm trying to do everything inside the page.
I'm able to successfully create my tweet button, attach an onClick handler to it, and construct a proper twitter.com/share URL for the relevant content. All works fine when I open that URL in a new window with window.open. However, if I try to open the URL in an iframe, nothing loads inside the frame. Even loading http://twitter.com into the iframe fails in the same way. However, loading Google or any other website seems to work just fine.
Any thoughts on what I'm missing here? Thanks! --zach
Edit:
Yep, they are detecting the iframe on load and blanking the page:
if (window.top !== window.self) {
document.write = "";
window.top.location = window.self.location;
setTimeout(function(){ document.body.innerHTML='';},1);
window.self.onload=function(evt){document.body.innerHTML='';};
}
Any reasonable way to get around this, or am I stuck writing my own auth pipeline through oauth? I don't need anything from their API, just letting users tweet to their own accounts.
Twitter (like Stack Overflow) is probably using some Javascript to ensure they're not being presented in an iFrame:
if(top!=self){
//hates you
}
I ran into something similar recently, and ended up re-doing part of my app without the iFrame element.
Go and get a developper account on twitter and things are made easy for you :)
Can you simply redirect the the twitter share URL? I'm guessing they want to be careful about opening the window in iframe's to prevent malicious sites from tweeting in a user's account without giving the user a chance to first confirm their intent to send this tweet.
You said window.open worked fine for popping up the url in a new window but have you tried popping it into the parent frame?
twtWindow=window.open([url],'_parent',[specs])
#yuval Unfortunately for you, the twitter url goes to a page that has the X-FRAME-OPTIONS:SAMEORIGIN header set in the response. It's not a Javascript check. The browser will simply refuse to render the page after seeing the header. This is done to prevent a clickjacking attack, usually done to steal a user's password.
So your only other option is really to redirect your current page with window.location.href=url.

Categories