Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 334088 - The code which should invoke onbeforeunload handlers is called when the browser window itself is disposed but not if Browser.close() is called
Summary: The code which should invoke onbeforeunload handlers is called when the brows...
Status: RESOLVED WORKSFORME
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.6.1   Edit
Hardware: All All
: P3 critical with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Grant Gayed CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-12 08:26 EST by Dominik ölzl CLA
Modified: 2019-09-02 15:08 EDT (History)
2 users (show)

See Also:


Attachments
onbeforeunload.html test file (188 bytes, text/html)
2011-01-13 14:06 EST, Grant Gayed CLA
no flags Details
Eclipse Project to reproduce Bug (Adjustment of Xulrunner Path required) (1.64 MB, application/zip)
2011-01-14 04:28 EST, Dominik ölzl CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dominik ölzl CLA 2011-01-12 08:26:00 EST
Build Identifier: 3.6.1, 3.7

When closing a browser window (SWT.MOZILLA or SWT.SAFARI) e.g. by invoking "window.close()" via Browser.evaluate onbeforeunload handlers on the page cannot find any globally defined javascript variables and simple calls like "alert(...)" cause java script exceptions. On linux and mac it seems to cause the whole jvm to crash.
If hosting internet explorer all seems to work, probably the onbeforeunload handlers are not called when calling Browser.close() (i have not tested this).


org.eclipse.swt.browser.Browser.java:
//
//
//
public boolean close () {
	checkWidget();
	if (webBrowser.close ()) {
		isClosing = true;
		dispose ();
		isClosing = false;
		return true;
	}
	return false;
}
//
//
//


org.eclipse.swt.browser.Mozilla.java:
//
//
//
void onDispose (Display display) {
	/* invoke onbeforeunload handlers */
	if (!browser.isClosing && !browser.isDisposed()) {
		LocationListener[] oldLocationListeners = locationListeners;
		locationListeners = new LocationListener[0];
		ignoreAllMessages = true;
		execute ("window.location.replace('about:blank');"); //$NON-NLS-1$
		ignoreAllMessages = false;
		locationListeners = oldLocationListeners;	
	}
...
//
//
//

org.eclipse.swt.browser.IE.java:
//
//
//
	Listener listener = new Listener() {
		public void handleEvent(Event e) {
			switch (e.type) {
				case SWT.Dispose: {
					/* make this handler run after other dispose listeners */
					if (ignoreDispose) {
						ignoreDispose = false;
						break;
					}
					ignoreDispose = true;
					browser.notifyListeners (e.type, e);
					e.type = SWT.NONE;

					/* invoke onbeforeunload handlers */
					if (!browser.isClosing) {
						LocationListener[] oldLocationListeners = locationListeners;
						locationListeners = new LocationListener[0];
						site.ignoreAllMessages = true;
						execute ("window.location.href='about:blank'"); //$NON-NLS-1$
						site.ignoreAllMessages = false;
						locationListeners = oldLocationListeners;
					}
...
//
//
//


org.eclipse.swt.browser.Safari.java:
//
//
//
	Listener listener = new Listener() {
		public void handleEvent(Event e) {
			switch (e.type) {
				case SWT.FocusIn:
					Safari.this.webView.window().makeFirstResponder(Safari.this.webView);
					break;
				case SWT.Dispose: {
					/* make this handler run after other dispose listeners */
					if (ignoreDispose) {
						ignoreDispose = false;
						break;
					}
					ignoreDispose = true;
					browser.notifyListeners (e.type, e);
					e.type = SWT.NONE;

					/* Browser could have been disposed by one of the Dispose listeners */
					if (!browser.isDisposed()) {
						/* invoke onbeforeunload handlers */
						if (!browser.isClosing) {
							close (false);
						}

						e.display.setData(ADD_WIDGET_KEY, new Object[] {delegate, null});
					}
...
//
//
//



Did you intend to call the code in the dispose listeners only when Browser.close() was called but not when the browser sends a dispose event?
The solution which works for me seems to be changing "!browser.isClosing" into "browser.isClosing".

Reproducible: Always

Steps to Reproduce:
1. Create an SWT application hosting capable hosting multiple browser windows, browser type: SWT.MOZILLA or SWT.SAFARI
3. execute "window.close()" on a browser window created by window.open;
   the opened window should have an onbeforeunload hanlder which uses global java script variables and calls "alert(...)".
4. --> global variables are not accessible inside the handler and alert cannot be called.
Comment 1 Grant Gayed CLA 2011-01-13 14:06:12 EST
Created attachment 186769 [details]
onbeforeunload.html test file

This works for me with the snippet below.  Does the snippet work for you?  To try it, extract the file attached in this comment anywhere on your machine and put its location into the snippet's FILENAME field.  If you're on OSX then BROWSER_STYLE = SWT.NONE will use WebKit (Safari).  To use Mozilla change BROWSER_STYLE to SWT.MOZILLA.

Assuming the snippet works for you, are you able to change it and/or the attached file to replicate the problem you're seeing?

public class ModifiedSnippet173 {

static final int BROWSER_STYLE = SWT.NONE;
static final String FILENAME = "file:///C:/workspace/Grant/browser/onbeforeunload.html";

public static void main(String[] args) {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setText("Main Window");
    shell.setLayout(new FillLayout());
    Browser browser = new Browser(shell, BROWSER_STYLE);
    initialize(display, browser);
    shell.open();
    browser.setText("<html><script type=\"text/javascript\">setTimeout(\"window.open(' " + FILENAME + "', '', '');\", 2000);</script><body>This will open a new window after 2 seconds.</body></html>");
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) display.sleep();
    }
    display.dispose();
}

static void initialize(final Display display, Browser browser) {
    browser.addOpenWindowListener(new OpenWindowListener() {
        public void open(WindowEvent event) {
            Shell shell = new Shell(display);
            shell.setText("This Browser will be window.close()d after 3 seconds");
            shell.setLayout(new FillLayout());
            final Browser browser = new Browser(shell, BROWSER_STYLE);
            initialize(display, browser);
            event.browser = browser;
            display.timerExec(2500, new Runnable() {
                public void run() {
                    browser.execute("window.asdf='asdf'");
                }
            });
            display.timerExec(3000, new Runnable() {			
                public void run() {
                    System.out.println("awake");
                    browser.execute("window.close()");
                }
            });
        }
    });
    browser.addVisibilityWindowListener(new VisibilityWindowListener() {
        public void hide(WindowEvent event) {
            ((Browser)event.widget).getShell().setVisible(false);
        }
        public void show(WindowEvent event) {
            ((Browser)event.widget).getShell().open();
        }
    });
    browser.addCloseWindowListener(new CloseWindowListener() {
        public void close(WindowEvent event) {
            ((Browser)event.widget).getShell().close();
        }
    });
}
}
Comment 2 Dominik ölzl CLA 2011-01-14 04:28:40 EST
Created attachment 186807 [details]
Eclipse Project to reproduce Bug (Adjustment of Xulrunner Path required)

Hello, sorry my bug report was incomplete. The described exceptions occur not in the onbeforeunload handler but in the onunload handler.

* Adjust the xulrunner path to get it work.
* Change line 2418 in "Mozilla.java" as described to avoid the exceptions/hangs.
* Remove "Mozilla.java" to ensure that the original SWT code is running.
Comment 3 Dominik ölzl CLA 2011-02-28 07:21:35 EST
Hello!

Could anybody reproduce the problem with my attached project?

Greetings,
Domnik
Comment 4 Grant Gayed CLA 2011-03-11 17:00:17 EST
Sorry, I lost track of this one, and will be away next week.  I'll look at it when I return.
Comment 5 Eclipse Genie CLA 2018-11-14 09:50:47 EST
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.
Comment 6 Lars Vogel CLA 2019-09-02 15:01:53 EDT
This bug was marked as stalebug a while ago. Marking as worksforme.

If this report is still relevant for the current release, please reopen and remove the stalebug whiteboard tag.
Comment 7 Lars Vogel CLA 2019-09-02 15:08:28 EDT
This bug has been marked as stalebug a while ago without any further interaction.

If this report is still relevant for the current release, please reopen and remove the stalebug whiteboard flag.