### Eclipse Workspace Patch 1.0 #P org.eclipse.swt Index: Eclipse SWT Mozilla/common/org/eclipse/swt/browser/PromptService2.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/browser/PromptService2.java,v retrieving revision 1.9 diff -u -r1.9 PromptService2.java --- Eclipse SWT Mozilla/common/org/eclipse/swt/browser/PromptService2.java 19 Aug 2009 20:18:47 -0000 1.9 +++ Eclipse SWT Mozilla/common/org/eclipse/swt/browser/PromptService2.java 3 Sep 2009 02:09:00 -0000 @@ -162,22 +162,34 @@ String textLabel = new String (dest); /* - * If mozilla is showing its errors with dialogs (as opposed to pages) then the only - * opportunity to detect that a page has an invalid certificate, without receiving - * all notification callbacks on the channel, is to detect the displaying of an alert - * whose message contains an internal cert error code. If a such a message is - * detected then instead of showing it, re-navigate to the page with the invalid - * certificate so that the browser's nsIBadCertListener2 will be invoked. - */ - if (textLabel.indexOf ("ssl_error_bad_cert_domain") != -1 || - textLabel.indexOf ("sec_error_unknown_issuer") != -1 || - textLabel.indexOf ("sec_error_expired_certificate") != -1) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (browser != null) { - Mozilla mozilla = (Mozilla)browser.webBrowser; - mozilla.isRetrievingBadCert = true; - browser.setUrl (mozilla.lastNavigateURL); - return XPCOM.NS_OK; - } + * If mozilla is showing its errors with dialogs (as opposed to pages) + * then the only opportunity to detect that a page has an invalid + * certificate, without receiving all notification callbacks on the + * channel, is to detect the displaying of an alert whose message + * contains an internal cert error code. If a such a message is detected + * then instead of showing it, re-navigate to the page with the invalid + * certificate so that the browser's nsIBadCertListener2 will be + * invoked. + */ + if ((textLabel.indexOf("ssl_error_bad_cert_domain") != -1) + || textLabel.indexOf("sec_error_unknown_issuer") != -1 + || textLabel.indexOf("sec_error_expired_certificate") != -1) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (browser != null) { + Mozilla mozilla = (Mozilla) browser.webBrowser; + mozilla.isRetrievingBadCert = true; + browser.setUrl(mozilla.lastNavigateURL); + return XPCOM.NS_OK; + } + } + + for (int i = 0; i < browser.webBrowser.promptListeners.length; i++) { + PromptEvent event = new PromptEvent(browser); + event.title = titleLabel; + event.text = textLabel; + browser.webBrowser.promptListeners[i].prompt(event); + if (event.button == SWT.OK) { + return XPCOM.NS_OK; + } } Shell shell = browser == null ? new Shell () : browser.getShell (); @@ -206,10 +218,27 @@ XPCOM.memmove (dest, aCheckMsg, length * 2); String checkLabel = new String (dest); - Shell shell = browser == null ? new Shell () : browser.getShell (); - PromptDialog dialog = new PromptDialog (shell); int[] check = new int[1]; if (aCheckState != 0) XPCOM.memmove (check, aCheckState, 4); /* PRBool */ + + for (int i = 0; i < browser.webBrowser.promptListeners.length; i++) { + PromptEvent event = new PromptEvent(browser); + event.title = titleLabel; + event.text = textLabel; + event.checkLabel = checkLabel; + event.checked = check[0] == 1; + browser.webBrowser.promptListeners[i].prompt(event); + if (event.button == SWT.OK) { + if (aCheckState != 0) { + check[0] = event.checked ? 1 : 0; + XPCOM.memmove(aCheckState, check, 4); /* PRBool */ + } + return XPCOM.NS_OK; + } + } + + Shell shell = browser == null ? new Shell() : browser.getShell(); + PromptDialog dialog = new PromptDialog(shell); dialog.alertCheck (titleLabel, textLabel, checkLabel, check); if (aCheckState != 0) XPCOM.memmove (aCheckState, check, 4); /* PRBool */ return XPCOM.NS_OK; @@ -232,6 +261,20 @@ XPCOM.memmove (dest, aText, length * 2); String textLabel = new String (dest); + for (int i = 0; i < browser.webBrowser.promptListeners.length; i++) { + PromptEvent event = new PromptEvent(browser); + event.title = titleLabel; + event.text = textLabel; + browser.webBrowser.promptListeners[i].prompt(event); + if (event.button == SWT.OK) { + XPCOM.memmove(_retval, new int[] { 1 }, 4); + return XPCOM.NS_OK; + } else if (event.button == SWT.CANCEL) { + XPCOM.memmove(_retval, new int[] { 0 }, 4); + return XPCOM.NS_OK; + } + } + Shell shell = browser == null ? new Shell () : browser.getShell (); MessageBox messageBox = new MessageBox (shell, SWT.OK | SWT.CANCEL | SWT.ICON_QUESTION); messageBox.setText (titleLabel); @@ -277,11 +320,33 @@ } else if ((aButtonFlags & nsIPromptService.BUTTON_POS_2_DEFAULT) != 0) { defaultIndex = 2; } - - Shell shell = browser == null ? new Shell () : browser.getShell (); - PromptDialog dialog = new PromptDialog (shell); + int[] check = new int[1], result = new int[1]; if (aCheckState != 0) XPCOM.memmove (check, aCheckState, 4); + + for (int i = 0; i < browser.webBrowser.promptListeners.length; i++) { + PromptEvent event = new PromptEvent(browser); + event.title = titleLabel; + event.text = textLabel; + event.checkLabel = checkLabel; + event.checked = check[0] == 1; + event.buttonLabels = new String[] { button0Label, button1Label, + button2Label }; + browser.webBrowser.promptListeners[i].prompt(event); + if ((event.button == 0 && button0Label != null) + || (event.button == 1 && button1Label != null) + || (event.button == 2 && button2Label != null)) { + XPCOM.memmove(_retval, new int[] { event.button }, 4); + if (aCheckState != 0) { + check[0] = event.checked ? 1 : 0; + XPCOM.memmove(aCheckState, check, 4); /* PRBool */ + } + return XPCOM.NS_OK; + } + } + + Shell shell = browser == null ? new Shell () : browser.getShell (); + PromptDialog dialog = new PromptDialog (shell); dialog.confirmEx (titleLabel, textLabel, checkLabel, button0Label, button1Label, button2Label, defaultIndex, check, result); if (aCheckState != 0) XPCOM.memmove (aCheckState, check, 4); XPCOM.memmove (_retval, result, 4); @@ -324,51 +389,83 @@ } } - Shell shell = browser == null ? new Shell () : browser.getShell (); - PromptDialog dialog = new PromptDialog (shell); int[] check = new int[1], result = new int[1]; if (aCheckState != 0) XPCOM.memmove (check, aCheckState, 4); - dialog.prompt (titleLabel, textLabel, checkLabel, valueLabel, check, result); + + for (int i = 0; i < browser.webBrowser.promptListeners.length; i++) { + PromptEvent event = new PromptEvent(browser); + event.title = titleLabel; + event.text = textLabel; + event.checkLabel = checkLabel; + event.checked = check[0] == 1; + event.valueLabel = valueLabel[0]; + browser.webBrowser.promptListeners[i].prompt(event); + if (event.button == SWT.OK) { + movePromptString(aValue, valueAddr, event.valueLabel); + XPCOM.memmove(_retval, new int[] { 1 }, 4); + if (aCheckState != 0) { + check[0] = event.checked ? 1 : 0; + XPCOM.memmove(aCheckState, check, 4); /* PRBool */ + } + return XPCOM.NS_OK; + } else if (event.button == SWT.CANCEL) { + XPCOM.memmove(_retval, new int[] { 0 }, 4); + if (aCheckState != 0) { + check[0] = event.checked ? 1 : 0; + XPCOM.memmove(aCheckState, check, 4); /* PRBool */ + } + return XPCOM.NS_OK; + } + } + + Shell shell = browser == null ? new Shell() : browser.getShell(); + PromptDialog dialog = new PromptDialog(shell); + dialog.prompt(titleLabel, textLabel, checkLabel, valueLabel, check, result); XPCOM.memmove (_retval, result, 4); if (result[0] == 1) { - /* - * User selected OK. User name and password are returned as PRUnichar values. Any default - * value that we override must be freed using the nsIMemory service. - */ - if (valueLabel[0] != null) { - int /*long*/[] result2 = new int /*long*/[1]; - int rc = XPCOM.NS_GetServiceManager (result2); - if (rc != XPCOM.NS_OK) SWT.error (rc); - if (result2[0] == 0) SWT.error (XPCOM.NS_NOINTERFACE); - - nsIServiceManager serviceManager = new nsIServiceManager (result2[0]); - result2[0] = 0; - byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_MEMORY_CONTRACTID, true); - rc = serviceManager.GetServiceByContractID (aContractID, nsIMemory.NS_IMEMORY_IID, result2); - if (rc != XPCOM.NS_OK) SWT.error (rc); - if (result2[0] == 0) SWT.error (XPCOM.NS_NOINTERFACE); - serviceManager.Release (); - - nsIMemory memory = new nsIMemory (result2[0]); - result2[0] = 0; - - int cnt = valueLabel[0].length (); - char[] buffer = new char[cnt + 1]; - valueLabel[0].getChars (0, cnt, buffer, 0); - int size = buffer.length * 2; - int /*long*/ ptr = memory.Alloc (size); - XPCOM.memmove (ptr, buffer, size); - XPCOM.memmove (aValue, new int /*long*/[] {ptr}, C.PTR_SIZEOF); + movePromptString(aValue, valueAddr, valueLabel[0]); + } + if (aCheckState != 0) XPCOM.memmove(aCheckState, check, 4); + return XPCOM.NS_OK; +} - if (valueAddr[0] != 0) { - memory.Free (valueAddr[0]); - } - memory.Release (); +/* + * OK was selected. User name and password are returned as + * PRUnichar values. Any default value that we override must be + * freed using the nsIMemory service. + */ +private void movePromptString(int aValue, int[] valueAddr, String prompt) { + if (prompt != null) { + int /*long*/[] result2 = new int /*long*/[1]; + int rc = XPCOM.NS_GetServiceManager (result2); + if (rc != XPCOM.NS_OK) SWT.error(rc); + if (result2[0] == 0) SWT.error(XPCOM.NS_NOINTERFACE); + + nsIServiceManager serviceManager = new nsIServiceManager (result2[0]); + result2[0] = 0; + byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_MEMORY_CONTRACTID, true); + rc = serviceManager.GetServiceByContractID (aContractID,nsIMemory.NS_IMEMORY_IID, result2); + if (rc != XPCOM.NS_OK) SWT.error (rc); + if (result2[0] == 0) SWT.error (XPCOM.NS_NOINTERFACE); + serviceManager.Release (); + + nsIMemory memory = new nsIMemory (result2[0]); + result2[0] = 0; + + int cnt = prompt.length (); + char[] buffer = new char[cnt + 1]; + prompt.getChars (0, cnt, buffer, 0); + int size = buffer.length * 2; + int /*long*/ ptr = memory.Alloc (size); + XPCOM.memmove (ptr, buffer, size); + XPCOM.memmove (aValue, new int /* long */[] { ptr }, C.PTR_SIZEOF); + + if (valueAddr[0] != 0) { + memory.Free (valueAddr[0]); } + memory.Release (); } - if (aCheckState != 0) XPCOM.memmove (aCheckState, check, 4); - return XPCOM.NS_OK; } int PromptAuth(int /*long*/ aParent, int /*long*/ aChannel, int level, int /*long*/ authInfo, int /*long*/ checkboxLabel, int /*long*/ checkboxValue, int /*long*/ _retval) { Index: Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java,v retrieving revision 1.26 diff -u -r1.26 WebBrowser.java --- Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java 1 Jul 2009 14:50:17 -0000 1.26 +++ Eclipse SWT Browser/common/org/eclipse/swt/browser/WebBrowser.java 3 Sep 2009 02:08:59 -0000 @@ -23,6 +23,7 @@ LocationListener[] locationListeners = new LocationListener[0]; OpenWindowListener[] openWindowListeners = new OpenWindowListener[0]; ProgressListener[] progressListeners = new ProgressListener[0]; + PromptListener[] promptListeners = new PromptListener[0]; StatusTextListener[] statusTextListeners = new StatusTextListener[0]; TitleListener[] titleListeners = new TitleListener[0]; VisibilityWindowListener[] visibilityWindowListeners = new VisibilityWindowListener[0]; @@ -232,6 +233,13 @@ progressListeners[progressListeners.length - 1] = listener; } +public void addPromptListener (PromptListener listener) { + PromptListener[] newPromptListeners = new PromptListener[promptListeners.length + 1]; + System.arraycopy(promptListeners, 0, newPromptListeners, 0, promptListeners.length); + promptListeners = newPromptListeners; + promptListeners[promptListeners.length - 1] = listener; +} + public void addStatusTextListener (StatusTextListener listener) { StatusTextListener[] newStatusTextListeners = new StatusTextListener[statusTextListeners.length + 1]; System.arraycopy(statusTextListeners, 0, newStatusTextListeners, 0, statusTextListeners.length); @@ -519,6 +527,26 @@ progressListeners = newProgressListeners; } +public void removePromptListener (PromptListener listener) { + if (promptListeners.length == 0) return; + int index = -1; + for (int i = 0; i < promptListeners.length; i++) { + if (listener == promptListeners[i]){ + index = i; + break; + } + } + if (index == -1) return; + if (promptListeners.length == 1) { + promptListeners = new PromptListener[0]; + return; + } + PromptListener[] newPromptListeners = new PromptListener[promptListeners.length - 1]; + System.arraycopy (promptListeners, 0, newPromptListeners, 0, index); + System.arraycopy (promptListeners, index + 1, newPromptListeners, index, promptListeners.length - index - 1); + promptListeners = newPromptListeners; +} + public void removeStatusTextListener (StatusTextListener listener) { if (statusTextListeners.length == 0) return; int index = -1; Index: Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java,v retrieving revision 1.43 diff -u -r1.43 Browser.java --- Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java 1 Jul 2009 14:50:17 -0000 1.43 +++ Eclipse SWT Browser/common/org/eclipse/swt/browser/Browser.java 3 Sep 2009 02:08:59 -0000 @@ -358,6 +358,30 @@ } /** + * Adds the listener to the collection of listeners who will + * be notified when a dialog window has been requested by the + * browser or a page loaded in the browser. + * + * @param listener the listener which should be notified + * + * @exception IllegalArgumentException + * + * @exception SWTException + * + * @since 3.6 + */ +public void addPromptListener (PromptListener listener) { + checkWidget(); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + webBrowser.addPromptListener (listener); +} + +/** * Adds the listener to the collection of listeners who will be * notified when the status text is changed. *

@@ -828,6 +852,30 @@ } /** + * Removes the listener from the collection of listeners who will + * be notified when a dialog window has been requested by the + * browser or a page loaded in the browser. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException

+ * + * @exception SWTException + * + * @since 3.6 + */ +public void removePromptListener (PromptListener listener) { + checkWidget(); + if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); + webBrowser.removePromptListener (listener); +} + +/** * Removes the listener from the collection of listeners who will * be notified when the status text is changed. * Index: Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptListener.java =================================================================== RCS file: Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptListener.java diff -N Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptListener.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptListener.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2003, 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.browser; + +/** + * This listener interface may be implemented in order to receive a + * {@link PromptEvent} notification when the {@link Browser} encounters a page + * that displays a dialog window. + * + * @see Browser#addPromptListener(PromptListener) + * @see Browser#removePromptListener(PromptListener) + * + * @since 3.6 + */ +public interface PromptListener { + + /** + * This method is called when a dialog box is requested to be displayed by + * the underlying browser. This encapsulates prompts from all of the + * javascript alert/confirm/prompt methods as well as any non-javascript + * dialogs from the browser. + * + * @param event + * the PromptEvent that holds the information about + * the dialog requested + * + * @since 3.6 + */ + public void prompt(PromptEvent event); + +} Index: Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptEvent.java =================================================================== RCS file: Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptEvent.java diff -N Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptEvent.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Eclipse SWT Browser/common/org/eclipse/swt/browser/PromptEvent.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,85 @@ +package org.eclipse.swt.browser; + +import org.eclipse.swt.events.TypedEvent; +import org.eclipse.swt.widgets.Widget; + +/** + * A PromptEvent is sent by a {@link Browser} to + * {@link PromptListener}s when the Browser requests that a dialog + * box be drawn to the screen. This event allows a client to interact with any + * of the buttons in the dialog box and possibly check checkboxes and/or change + * the prompt text, or optionally do nothing and allow the user to access the + * dialog box. + * + * @see PromptListener + * + * @since 3.6 + */ +public class PromptEvent extends TypedEvent { + + private static final long serialVersionUID = -973372319865604852L; + + /** + * A flag indicating which button, if any, should be pressed instead of + * displaying the dialog. -1 indicates that no action should be taken (the + * dialog will be displayed in the display). If buttonLabels is is not null + * (and thus there are custom button labels), this value will be interpreted + * to be the button position in the array to press. Otherwise, it can have + * values of SWT.OK or SWT.CANCEL. Other values + * will be ignored. + */ + public int button = -1; + + /** + * The title of the dialog is available in every type of dialog, should be + * non-null, and is not returned to the browser. + */ + public String title = null; + + /** + * The text is the message in the dialog, should be non-null, and is not + * returned to the browser. + */ + public String text = null; + + /** + * The checkLabel is the label for an optional checkbox in the dialog. This + * will be null when the dialog does not contain a checkbox and is not + * returned to the browser. + */ + public String checkLabel = null; + + /** + * The checked value is whether or not an optional checkbox is checked or + * not. In the case where the checkLabel is non-null, this will hold the + * default value of the checkbox from the browser and it's post-event value + * will be returned to the browser. + */ + public boolean checked = false; + + /** + * The buttonLabels are the values of the buttons in the dialog. In the case + * of dialogs with buttons other than OK or CANCEL, this will have their + * values. Otherwise, it will be null. + */ + public String[] buttonLabels = null; + + /** + * The valueLabel is the value of a prompt text field, if one exists. If + * not, the value will be null. This value will be returned to the browser + * in the case of prompt dialogs when the OK button is pressed. + */ + public String valueLabel = null; + + /** + * Constructs a new instance of this class. + * + * @param widget the widget that fired the event + * + * @since 3.6 + */ + public PromptEvent(Widget widget) { + super(widget); + } + +}