Mercurial > projects > dwt-mac
diff dwt/browser/Safari.d @ 45:d8635bb48c7c
Merge with SWT 3.5
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 01 Dec 2008 17:07:00 +0100 |
parents | 7d135fe0caf2 |
children | cfa563df4fdd |
line wrap: on
line diff
--- a/dwt/browser/Safari.d Tue Oct 21 15:20:04 2008 +0200 +++ b/dwt/browser/Safari.d Mon Dec 01 17:07:00 2008 +0100 @@ -1,5 +1,5 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. +/******************************************************************************* + * Copyright (c) 2000, 2008 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 @@ -7,37 +7,31 @@ * * Contributors: * IBM Corporation - initial API and implementation - * - * Port to the D programming language: - * Jacob Carlborg <jacob.carlborg@gmail.com> *******************************************************************************/ module dwt.browser.Safari; +import dwt.dwthelper.utils; + import dwt.DWT; -import dwt.browser.LocationEvent; -import dwt.browser.ProgressEvent; -import dwt.browser.ProgressListener; -import dwt.browser.StatusTextEvent; -import dwt.browser.TitleEvent; -import dwt.browser.TitleListener; -import dwt.browser.WebBrowser; -import dwt.dwthelper.utils; import dwt.graphics.Point; import dwt.graphics.Rectangle; +import dwt.internal.C; import dwt.internal.Callback; +import dwt.internal.Compatibility; import dwt.internal.cocoa.DOMDocument; -import dwt.internal.cocoa.DOMEvent; import dwt.internal.cocoa.DOMKeyboardEvent; import dwt.internal.cocoa.DOMMouseEvent; import dwt.internal.cocoa.DOMWheelEvent; import dwt.internal.cocoa.NSArray; import dwt.internal.cocoa.NSDictionary; +import dwt.internal.cocoa.NSError; import dwt.internal.cocoa.NSHTTPCookie; import dwt.internal.cocoa.NSHTTPCookieStorage; import dwt.internal.cocoa.NSNotificationCenter; import dwt.internal.cocoa.NSNumber; import dwt.internal.cocoa.NSPrintInfo; import dwt.internal.cocoa.NSPrintOperation; +import dwt.internal.cocoa.NSRect; import dwt.internal.cocoa.NSString; import dwt.internal.cocoa.NSURL; import dwt.internal.cocoa.NSURLDownload; @@ -53,7 +47,6 @@ import dwt.internal.cocoa.WebPreferences; import dwt.internal.cocoa.WebView; import dwt.internal.cocoa.id; - import dwt.widgets.Composite; import dwt.widgets.Display; import dwt.widgets.Event; @@ -62,65 +55,57 @@ import dwt.widgets.Menu; import dwt.widgets.MessageBox; import dwt.widgets.Shell; - -import Math = tango.math.Math; - -import dwt.dwthelper.Runnable; +import dwt.widgets.Widget; -class Safari : WebBrowser -{ +class Safari extends WebBrowser { WebView webView; - DWTWebViewDelegate delegatee; - int jniRef; + SWTWebViewDelegate delegate; bool changingLocation; String lastHoveredLinkURL; String html; - int identifier; + int /*long*/ identifier; int resourceCount; - String url = ""; + String url = ""; //$NON-NLS-1$ Point location; Point size; bool statusBar = true, toolBar = true, ignoreDispose; int lastMouseMoveX, lastMouseMoveY; //TEMPORARY CODE - // bool doit; +// bool doit; static bool Initialized; - static Callback Callback2, Callback3, Callback4, Callback5, Callback6, Callback7; - - static const int MIN_SIZE = 16; - static const int MAX_PROGRESS = 100; - static const String WebElementLinkURLKey = "WebElementLinkURL"; //$NON-NLS-1$ - static const String AGENT_STRING = "Safari/unknown"; //$NON-NLS-1$ - static const String URI_FROMMEMORY = "file:///"; //$NON-NLS-1$ - static const String PROTOCOL_FILE = "file:"; //$NON-NLS-1$ - static const String PROTOCOL_HTTP = "http:"; //$NON-NLS-1$ - static const String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$ - static const String SAFARI_EVENTS_FIX_KEY = "dwt.internal.safariEventsFix"; //$NON-NLS-1$ + // the following Callbacks are never freed + static Callback Callback3, Callback4, Callback5, Callback6, Callback7; - /* event Strings */ - static const String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$ - static const String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$ - static const String DOMEVENT_MOUSEDOWN = "mousedown"; //$NON-NLS-1$ - static const String DOMEVENT_MOUSEUP = "mouseup"; //$NON-NLS-1$ - static const String DOMEVENT_MOUSEMOVE = "mousemove"; //$NON-NLS-1$ - static const String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$ + static final int MIN_SIZE = 16; + static final int MAX_PROGRESS = 100; + static final String WebElementLinkURLKey = "WebElementLinkURL"; //$NON-NLS-1$ + static final String AGENT_STRING = "Safari/unknown"; //$NON-NLS-1$ + static final String URI_FROMMEMORY = "file:///"; //$NON-NLS-1$ + static final String PROTOCOL_FILE = "file://"; //$NON-NLS-1$ + static final String PROTOCOL_HTTP = "http://"; //$NON-NLS-1$ + static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$ + static final String ADD_WIDGET_KEY = "dwt.internal.addWidget"; //$NON-NLS-1$ + static final String SAFARI_EVENTS_FIX_KEY = "dwt.internal.safariEventsFix"; //$NON-NLS-1$ + static final String DWT_OBJECT = "DWT_OBJECT"; //$NON-NLS-1$ - static this () - { - NativeClearSessions = new class Runnable - { - public void run () - { + /* event strings */ + static final String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$ + static final String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$ + static final String DOMEVENT_MOUSEDOWN = "mousedown"; //$NON-NLS-1$ + static final String DOMEVENT_MOUSEUP = "mouseup"; //$NON-NLS-1$ + static final String DOMEVENT_MOUSEMOVE = "mousemove"; //$NON-NLS-1$ + static final String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$ + + static { + NativeClearSessions = new Runnable() { + public void run() { NSHTTPCookieStorage storage = NSHTTPCookieStorage.sharedHTTPCookieStorage(); NSArray cookies = storage.cookies(); - int count = cookies.count(); - - for (int i = 0; i < count; i++) - { + int /*long*/ count = cookies.count(); + for (int i = 0; i < count; i++) { NSHTTPCookie cookie = new NSHTTPCookie(cookies.objectAtIndex(i)); - if (cookie.isSessionOnly()) - { + if (cookie.isSessionOnly()) { storage.deleteCookie(cookie); } } @@ -128,1439 +113,1134 @@ }; } - public void create (Composite parent, int style) - { - - String className = "DWTWebViewDelegate"; - if (OS.objc_lookUpClass(className) == 0) - { - ClassInfo safaryClass = this.classinfo; - Callback2 = new Callback(safaryClass, "browserProc", 2); - int proc2 = Callback2.getAddress(); - if (proc2 is 0) - DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); - Callback3 = new Callback(safaryClass, "browserProc", 3); - int proc3 = Callback3.getAddress(); - if (proc3 is 0) - DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); - Callback4 = new Callback(safaryClass, "browserProc", 4); - int proc4 = Callback4.getAddress(); - if (proc4 is 0) - DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); - Callback5 = new Callback(safaryClass, "browserProc", 5); - int proc5 = Callback5.getAddress(); - if (proc5 is 0) - DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); - Callback6 = new Callback(safaryClass, "browserProc", 6); - int proc6 = Callback6.getAddress(); - if (proc6 is 0) - DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); - Callback7 = new Callback(safaryClass, "browserProc", 7); - int proc7 = Callback7.getAddress(); - if (proc7 is 0) - DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); - - int cls = OS.objc_allocateClassPair(OS.class_WebView, className, 0); - OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte) (Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i"); - OS.class_addMethod(cls, OS.sel_tag, proc2, "@:"); - OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i"); - OS.class_addMethod(cls, OS.sel_webView_1didChangeLocationWithinPageForFrame_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1didFailProvisionalLoadWithError_1forFrame_1, proc5, "@:@@@"); - OS.class_addMethod(cls, OS.sel_webView_1didFinishLoadForFrame_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1didReceiveTitle_1forFrame_1, proc5, "@:@@@"); - OS.class_addMethod(cls, OS.sel_webView_1didStartProvisionalLoadForFrame_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1didCommitLoadForFrame_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1resource_1didFinishLoadingFromDataSource_1, proc5, "@:@@@"); - OS.class_addMethod(cls, OS.sel_webView_1resource_1didFailLoadingWithError_1fromDataSource_1, proc6, "@:@@@@"); - OS.class_addMethod(cls, OS.sel_webView_1identifierForInitialRequest_1fromDataSource_1, proc5, "@:@@@"); - OS.class_addMethod(cls, OS.sel_webView_1resource_1willSendRequest_1redirectResponse_1fromDataSource_1, proc7, "@:@@@@@"); - OS.class_addMethod(cls, OS.sel_handleNotification_1, proc3, "@:@"); - OS.class_addMethod(cls, OS.sel_webView_1createWebViewWithRequest_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webViewShow_1, proc3, "@:@"); - OS.class_addMethod(cls, OS.sel_webView_1setFrame_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webViewClose_1, proc3, "@:@"); - OS.class_addMethod(cls, OS.sel_webView_1contextMenuItemsForElement_1defaultMenuItems_1, proc5, "@:@@@"); - OS.class_addMethod(cls, OS.sel_webView_1setStatusBarVisible_1, proc4, "@:@B"); - OS.class_addMethod(cls, OS.sel_webView_1setResizable_1, proc4, "@:@B"); - OS.class_addMethod(cls, OS.sel_webView_1setToolbarsVisible_1, proc4, "@:@B"); - OS.class_addMethod(cls, OS.sel_webView_1setStatusText_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webViewFocus_1, proc3, "@:@"); - OS.class_addMethod(cls, OS.sel_webViewUnfocus_1, proc3, "@:@"); - OS.class_addMethod(cls, OS.sel_webView_1runJavaScriptAlertPanelWithMessage_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1runJavaScriptConfirmPanelWithMessage_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1runOpenPanelForFileButtonWithResultListener_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1mouseDidMoveOverElement_1modifierFlags_1, proc5, "@:@@I"); - OS.class_addMethod(cls, OS.sel_webView_1printFrameView_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_webView_1decidePolicyForMIMEType_1request_1frame_1decisionListener_1, proc7, "@:@@@@@"); - OS.class_addMethod(cls, OS.sel_webView_1decidePolicyForNavigationAction_1request_1frame_1decisionListener_1, proc7, "@:@@@@@"); - OS.class_addMethod(cls, OS.sel_webView_1decidePolicyForNewWindowAction_1request_1newFrameName_1decisionListener_1, proc7, "@:@@@@@"); - OS.class_addMethod(cls, OS.sel_webView_1unableToImplementPolicyWithError_1frame_1, proc5, "@:@@@"); - OS.class_addMethod(cls, OS.sel_download_1decideDestinationWithSuggestedFilename_1, proc4, "@:@@"); - OS.class_addMethod(cls, OS.sel_handleEvent_1, proc3, "@:@"); - OS.objc_registerClassPair(cls); - } - - /* - * Override the default event mechanism to not send key events so - * that the browser can send them by listening to the DOM instead. - */ - browser.setData(SAFARI_EVENTS_FIX_KEY); - - WebView webView = cast(WebView) (new WebView()).alloc(); - if (webView is null) - DWT.error(DWT.ERROR_NO_HANDLES); - webView.initWithFrame(browser.view.frame(), null, null); - webView.setAutoresizingMask(OS.NSViewWidthSizable | OS.NSViewHeightSizable); - jniRef = OS.NewGlobalRef(this); - if (jniRef is 0) - DWT.error(DWT.ERROR_NO_HANDLES); - const DWTWebViewDelegate delegatee = cast(DWTWebViewDelegate) (new DWTWebViewDelegate()).alloc().init(); - delegatee.setTag(jniRef); - this.delegatee = delegatee; - this.webView = webView; - browser.view.addSubview_(webView); - - const NSNotificationCenter notificationCenter = NSNotificationCenter.defaultCenter(); +public void create (Composite parent, int style) { + String className = "SWTWebViewDelegate"; //$NON-NLS-1$ + if (OS.objc_lookUpClass(className) is 0) { + Class safariClass = this.getClass(); + Callback3 = new Callback(safariClass, "browserProc", 3); //$NON-NLS-1$ + int /*long*/ proc3 = Callback3.getAddress(); + if (proc3 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); + Callback4 = new Callback(safariClass, "browserProc", 4); //$NON-NLS-1$ + int /*long*/ proc4 = Callback4.getAddress(); + if (proc4 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); + Callback5 = new Callback(safariClass, "browserProc", 5); //$NON-NLS-1$ + int /*long*/ proc5 = Callback5.getAddress(); + if (proc5 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); + Callback6 = new Callback(safariClass, "browserProc", 6); //$NON-NLS-1$ + int /*long*/ proc6 = Callback6.getAddress(); + if (proc6 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); + Callback7 = new Callback(safariClass, "browserProc", 7); //$NON-NLS-1$ + int /*long*/ proc7 = Callback7.getAddress(); + if (proc7 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); + int /*long*/ setFrameProc = OS.webView_setFrame_CALLBACK(proc4); + if (setFrameProc is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS); - Listener listener = new class (notificationCenter) Listener - { - NSNotificationCenter notificationCenter; - - this (NSNotificationCenter notificationCenter) - { - this.notificationCenter = notificationCenter; - } - - public void handleEvent (Event e) - { - switch (e.type) - { - case DWT.Dispose: - { - /* make this handler run after other dispose listeners */ - if (ignoreDispose) - { - ignoreDispose = false; - break; - } - ignoreDispose = true; - browser.notifyListeners(e.type, e); - e.type = DWT.NONE; - - webView.setFrameLoadDelegate(null); - webView.setResourceLoadDelegate(null); - webView.setUIDelegate(null); - webView.setPolicyDelegate(null); - webView.setDownloadDelegate(null); - notificationCenter.removeObserver(delegatee); - - webView.release(); - webView = null; - delegatee.release(); - delegatee = null; - OS.DeleteGlobalRef(jniRef); - jniRef = 0; - html = null; - lastHoveredLinkURL = null; - break; - } - } - } - }; - browser.addListener(DWT.Dispose, listener); - - webView.setFrameLoadDelegate(delegatee); - webView.setResourceLoadDelegate(delegatee); - webView.setUIDelegate(delegatee); - notificationCenter.addObserver(delegatee, OS.sel_handleNotification_1, null, webView); - webView.setPolicyDelegate(delegatee); - webView.setDownloadDelegate(delegatee); - webView.setApplicationNameForUserAgent(NSString.StringWith(AGENT_STRING)); - - if (!Initialized) - { - Initialized = true; - /* disable applets */ - WebPreferences.standardPreferences().setJavaEnabled(false); - } - } - - public bool back () - { - html = null; - return webView.goBack(); - } - - static int browserProc (int delegatee, int sel) - { - if (sel is OS.sel_tag) - { - int[] tag = new int[1]; - OS.object_getInstanceVariable(delegatee, "tag", tag); - return tag[0]; - } - return 0; - } - - static int browserProc (int id, int sel, int arg0) - { - if (sel is OS.sel_setTag_1) - { - OS.object_setInstanceVariable(id, "tag", arg0); - return 0; - } - int jniRef = OS.objc_msgSend(id, OS.sel_tag); - if (jniRef is 0 || jniRef is -1) - return 0; - Safari widget = cast(Safari) OS.JNIGetObject(jniRef); - if (widget is null) - return 0; - if (sel is OS.sel_handleNotification_1) - { - widget.handleNotification(arg0); - } - else if (sel is OS.sel_webViewShow_1) - { - widget.webViewShow(arg0); - } - else if (sel is OS.sel_webViewClose_1) - { - widget.webViewClose(arg0); - } - else if (sel is OS.sel_webViewFocus_1) - { - widget.webViewFocus(arg0); - } - else if (sel is OS.sel_webViewUnfocus_1) - { - widget.webViewUnfocus(arg0); - } - else if (sel is OS.sel_handleEvent_1) - { - widget.handleEvent(arg0); - } - return 0; - } + String types = "*"; //$NON-NLS-1$ + int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF is 4 ? 2 : 3; - static int browserProc (int id, int sel, int arg0, int arg1) - { - if (sel is OS.sel_setTag_1) - { - OS.object_setInstanceVariable(id, "tag", arg0); - return 0; - } - int jniRef = OS.objc_msgSend(id, OS.sel_tag); - if (jniRef is 0 || jniRef is -1) - return 0; - Safari widget = cast(Safari) OS.JNIGetObject(jniRef); - if (widget is null) - return 0; - if (sel is OS.sel_webView_1didChangeLocationWithinPageForFrame_1) - { - widget.webView_didChangeLocationWithinPageForFrame(arg0, arg1); - } - else if (sel is OS.sel_webView_1didFinishLoadForFrame_1) - { - widget.webView_didFinishLoadForFrame(arg0, arg1); - } - else if (sel is OS.sel_webView_1didStartProvisionalLoadForFrame_1) - { - widget.webView_didStartProvisionalLoadForFrame(arg0, arg1); - } - else if (sel is OS.sel_webView_1didCommitLoadForFrame_1) - { - widget.webView_didCommitLoadForFrame(arg0, arg1); - } - else if (sel is OS.sel_webView_1setFrame_1) - { - widget.webView_setFrame(arg0, arg1); - } - else if (sel is OS.sel_webView_1createWebViewWithRequest_1) - { - return widget.webView_createWebViewWithRequest(arg0, arg1); - } - else if (sel is OS.sel_webView_1setStatusBarVisible_1) - { - widget.webView_setStatusBarVisible(arg0, arg1); - } - else if (sel is OS.sel_webView_1setResizable_1) - { - widget.webView_setResizable(arg0, arg1); - } - else if (sel is OS.sel_webView_1setStatusText_1) - { - widget.webView_setStatusText(arg0, arg1); - } - else if (sel is OS.sel_webView_1setToolbarsVisible_1) - { - widget.webView_setToolbarsVisible(arg0, arg1); - } - else if (sel is OS.sel_webView_1runJavaScriptAlertPanelWithMessage_1) - { - widget.webView_runJavaScriptAlertPanelWithMessage(arg0, arg1); - } - else if (sel is OS.sel_webView_1runJavaScriptConfirmPanelWithMessage_1) - { - return widget.webView_runJavaScriptConfirmPanelWithMessage(arg0, arg1); - } - else if (sel is OS.sel_webView_1runOpenPanelForFileButtonWithResultListener_1) - { - widget.webView_runOpenPanelForFileButtonWithResultListener(arg0, arg1); - } - else if (sel is OS.sel_download_1decideDestinationWithSuggestedFilename_1) - { - widget.download_decideDestinationWithSuggestedFilename(arg0, arg1); - } - else if (sel is OS.sel_webView_1printFrameView_1) - { - widget.webView_printFrameView(arg0, arg1); - } - return 0; - } - - static int browserProc (int id, int sel, int arg0, int arg1, int arg2) - { - int jniRef = OS.objc_msgSend(id, OS.sel_tag); - if (jniRef is 0 || jniRef is -1) - return 0; - Safari widget = cast(Safari) OS.JNIGetObject(jniRef); - if (widget is null) - return 0; - if (sel is OS.sel_webView_1didFailProvisionalLoadWithError_1forFrame_1) - { - widget.webView_didFailProvisionalLoadWithError_forFrame(arg0, arg1, arg2); - } - else if (sel is OS.sel_webView_1didReceiveTitle_1forFrame_1) - { - widget.webView_didReceiveTitle_forFrame(arg0, arg1, arg2); - } - else if (sel is OS.sel_webView_1resource_1didFinishLoadingFromDataSource_1) - { - widget.webView_resource_didFinishLoadingFromDataSource(arg0, arg1, arg2); - } - else if (sel is OS.sel_webView_1identifierForInitialRequest_1fromDataSource_1) - { - return widget.webView_identifierForInitialRequest_fromDataSource(arg0, arg1, arg2); - } - else if (sel is OS.sel_webView_1contextMenuItemsForElement_1defaultMenuItems_1) - { - return widget.webView_contextMenuItemsForElement_defaultMenuItems(arg0, arg1, arg2); - } - else if (sel is OS.sel_webView_1mouseDidMoveOverElement_1modifierFlags_1) - { - widget.webView_mouseDidMoveOverElement_modifierFlags(arg0, arg1, arg2); - } - else if (sel is OS.sel_webView_1unableToImplementPolicyWithError_1frame_1) - { - widget.webView_unableToImplementPolicyWithError_frame(arg0, arg1, arg2); - } - return 0; - } - - static int browserProc (int id, int sel, int arg0, int arg1, int arg2, int arg3) - { - int jniRef = OS.objc_msgSend(id, OS.sel_tag); - if (jniRef is 0 || jniRef is -1) - return 0; - Safari widget = cast(Safari) OS.JNIGetObject(jniRef); - if (widget is null) - return 0; - if (sel is OS.sel_webView_1resource_1didFailLoadingWithError_1fromDataSource_1) - { - widget.webView_resource_didFailLoadingWithError_fromDataSource(arg0, arg1, arg2, arg3); - } - return 0; - } - - static int browserProc (int id, int sel, int arg0, int arg1, int arg2, int arg3, int arg4) - { - int jniRef = OS.objc_msgSend(id, OS.sel_tag); - if (jniRef is 0 || jniRef is -1) - return 0; - Safari widget = cast(Safari) OS.JNIGetObject(jniRef); - if (widget is null) - return 0; - if (sel is OS.sel_webView_1resource_1willSendRequest_1redirectResponse_1fromDataSource_1) - { - return widget.webView_resource_willSendRequest_redirectResponse_fromDataSource(arg0, arg1, arg2, arg3, arg4); - } - else if (sel is OS.sel_webView_1decidePolicyForMIMEType_1request_1frame_1decisionListener_1) - { - widget.webView_decidePolicyForMIMEType_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4); - } - else if (sel is OS.sel_webView_1decidePolicyForNavigationAction_1request_1frame_1decisionListener_1) - { - widget.webView_decidePolicyForNavigationAction_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4); - } - else if (sel is OS.sel_webView_1decidePolicyForNewWindowAction_1request_1newFrameName_1decisionListener_1) - { - widget.webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener(arg0, arg1, arg2, arg3, arg4); - } - return 0; - } - - public bool execute (String script) - { - return webView.StringByEvaluatingJavaScriptFromString(NSString.StringWith(script)) !is null; - } - - public bool forward () - { - html = null; - return webView.goForward(); - } - - public String getText () - { - WebFrame mainFrame = webView.mainFrame(); - WebDataSource dataSource = mainFrame.dataSource(); - if (dataSource is null) - return ""; //$NON-NLS-1$ - WebDocumentRepresentation representation = dataSource.representation(); - if (representation is null) - return ""; //$NON-NLS-1$ - NSString source = representation.documentSource(); - if (source is null) - return ""; //$NON-NLS-1$ - char[] buffer = new char[source.length()]; - source.getCharacters_(buffer); - return new String(buffer); - } - - public String getUrl () - { - return url; - } - - public bool isBackEnabled () - { - return webView.canGoBack(); - } - - public bool isForwardEnabled () - { - return webView.canGoForward(); - } - - public void refresh () - { - webView.reload(null); - } - - public bool setText (String html) - { - /* - * Bug in Safari. The web view segment faults in some circumstances - * when the text changes during the location changing callback. The - * fix is to defer the work until the callback is done. - */ - if (changingLocation) - { - this.html = html; - } - else - { - _setText(html); - } - return true; - } - - void _setText (String html) - { - NSString String = NSString.StringWith(html); - NSString URLString = NSString.StringWith(URI_FROMMEMORY); - NSURL URL = NSURL.static_URLWithString_(URLString); - WebFrame mainFrame = webView.mainFrame(); - mainFrame.loadHTMLString(String, URL); - } - - public bool setUrl (String url) - { - html = null; - - NSURL inURL; - if (url.startsWith(PROTOCOL_FILE)) - { - url = url.substring(PROTOCOL_FILE.length()); - } - bool isHttpURL = url.indexOf('/') !is 0; - if (isHttpURL) - { - if (url.indexOf(':') is -1) - { - url = PROTOCOL_HTTP + "//" + url; //$NON-NLS-1$ - } - inURL = NSURL.static_URLWithString_(NSString.StringWith(url.toString())); - } - else - { - inURL = NSURL.static_fileURLWithPath_(NSString.StringWith(url.toString())); - } - if (inURL is null) - return false; - - NSURLRequest request = NSURLRequest.static_requestWithURL_(inURL); - WebFrame mainFrame = webView.mainFrame(); - mainFrame.loadRequest(request); - return true; - } - - public void stop () - { - html = null; - webView.stopLoading(null); - } - - /* WebFrameLoadDelegate */ - - void webView_didChangeLocationWithinPageForFrame (int sender, int frameID) - { - WebFrame frame = new WebFrame(frameID); - WebDataSource dataSource = frame.dataSource(); - NSURLRequest request = dataSource.request(); - NSURL url = request.URL(); - NSString s = url.absoluteString(); - int length = s.length(); - if (length is 0) - return; - char[] buffer = new char[length]; - s.getCharacters_(buffer); - String url2 = new String(buffer); - /* - * If the URI indicates that the page is being rendered from memory - * (via setText()) then set it to about:blank to be consistent with IE. - */ - if (url2.opEquals(URI_FROMMEMORY)) - url2 = ABOUT_BLANK; - - const Display display = browser.getDisplay(); - bool top = frameID is webView.mainFrame().id; - if (top) - { - StatusTextEvent statusText = new StatusTextEvent(browser); - statusText.display = display; - statusText.widget = browser; - statusText.text = url2; - for (int i = 0; i < statusTextListeners.length; i++) - { - statusTextListeners[i].changed(statusText); - } - } - - LocationEvent location = new LocationEvent(browser); - location.display = display; - location.widget = browser; - location.location = url2; - location.top = top; - for (int i = 0; i < locationListeners.length; i++) - { - locationListeners[i].changed(location); - } - } - - void webView_didFailProvisionalLoadWithError_forFrame (int sender, int error, int frame) - { - if (frame is webView.mainFrame().id) - { - /* - * Feature on Safari. The identifier is used here as a marker for the events - * related to the top frame and the URL changes related to that top frame as - * they should appear on the location bar of a browser. It is expected to reset - * the identifier to 0 when the event didFinishLoadingFromDataSource related to - * the identifierForInitialRequest event is received. However, Safari fires - * the didFinishLoadingFromDataSource event before the entire content of the - * top frame is loaded. It is possible to receive multiple willSendRequest - * events in this interval, causing the Browser widget to send unwanted - * Location.changing events. For this reason, the identifier is reset to 0 - * when the top frame has either finished loading (didFinishLoadForFrame - * event) or failed (didFailProvisionalLoadWithError). - */ - identifier = 0; - } + int /*long*/ cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0); + OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types); + OS.class_addMethod(cls, OS.sel_webView_didChangeLocationWithinPageForFrame_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_didFailProvisionalLoadWithError_forFrame_, proc5, "@:@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_didFinishLoadForFrame_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_didReceiveTitle_forFrame_, proc5, "@:@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_didStartProvisionalLoadForFrame_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_didCommitLoadForFrame_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_resource_didFinishLoadingFromDataSource_, proc5, "@:@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_resource_didFailLoadingWithError_fromDataSource_, proc6, "@:@@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_identifierForInitialRequest_fromDataSource_, proc5, "@:@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_resource_willSendRequest_redirectResponse_fromDataSource_, proc7, "@:@@@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_handleNotification_, proc3, "@:@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_createWebViewWithRequest_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webViewShow_, proc3, "@:@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webViewClose_, proc3, "@:@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_contextMenuItemsForElement_defaultMenuItems_, proc5, "@:@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_setStatusBarVisible_, proc4, "@:@B"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_setResizable_, proc4, "@:@B"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_setToolbarsVisible_, proc4, "@:@B"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_setStatusText_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webViewFocus_, proc3, "@:@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webViewUnfocus_, proc3, "@:@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_runJavaScriptAlertPanelWithMessage_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_runJavaScriptConfirmPanelWithMessage_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_runOpenPanelForFileButtonWithResultListener_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_mouseDidMoveOverElement_modifierFlags_, proc5, "@:@@I"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_printFrameView_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_decidePolicyForMIMEType_request_frame_decisionListener_, proc7, "@:@@@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_decidePolicyForNavigationAction_request_frame_decisionListener_, proc7, "@:@@@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener_, proc7, "@:@@@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_unableToImplementPolicyWithError_frame_, proc5, "@:@@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_download_decideDestinationWithSuggestedFilename_, proc4, "@:@@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_handleEvent_, proc3, "@:@"); //$NON-NLS-1$ + OS.class_addMethod(cls, OS.sel_webView_setFrame_, setFrameProc, "@:@{NSRect}"); //$NON-NLS-1$ + OS.objc_registerClassPair(cls); } - void webView_didFinishLoadForFrame (int sender, int frameID) - { - hookDOMMouseListeners(frameID); - if (frameID is webView.mainFrame().id) - { - hookDOMKeyListeners(frameID); + /* + * Override the default event mechanism to not send key events so + * that the browser can send them by listening to the DOM instead. + */ + browser.setData(SAFARI_EVENTS_FIX_KEY); + + WebView webView = (WebView)new WebView().alloc(); + if (webView is null) DWT.error(DWT.ERROR_NO_HANDLES); + webView.initWithFrame(browser.view.frame(), null, null); + webView.setAutoresizingMask(OS.NSViewWidthSizable | OS.NSViewHeightSizable); + final SWTWebViewDelegate delegate = (SWTWebViewDelegate)new SWTWebViewDelegate().alloc().init(); + Display display = browser.getDisplay(); + display.setData(ADD_WIDGET_KEY, new Object[] {delegate, browser}); + this.delegate = delegate; + this.webView = webView; + browser.view.addSubview(webView); + + final NSNotificationCenter notificationCenter = NSNotificationCenter.defaultCenter(); - const Display display = browser.getDisplay(); - /* - * To be consistent with other platforms a title event should be fired when a - * page has completed loading. A page with a <title> tag will do this - * automatically when the didReceiveTitle callback is received. However a page - * without a <title> tag will not do this by default, so fire the event - * here with the page's url as the title. - */ - WebFrame frame = new WebFrame(frameID); - WebDataSource dataSource = frame.dataSource(); - if (dataSource !is null) - { - NSString title = dataSource.pageTitle(); - if (title is null) - { /* page has no title */ - const TitleEvent newEvent = new TitleEvent(browser); - newEvent.display = display; - newEvent.widget = browser; - newEvent.title = url; - for (int i = 0; i < titleListeners.length; i++) - { - const TitleListener listener = titleListeners[i]; - /* - * Note on WebKit. Running the event loop from a Browser - * delegatee callback breaks the WebKit (stop loading or - * crash). The workaround is to invoke Display.asyncExec() - * so that the Browser does not crash if this is attempted. - */ - display.asyncExec(new class (display, listener) Runnable - { - Display display; - TitleListener listener; - - this (Display display, TitleListener listener) - { - this.display = display; - this.listener = listener; - } - - public void run () - { - if (!display.isDisposed() && !browser.isDisposed()) - { - listener.changed(newEvent); - } - } - }); + Listener listener = new Listener() { + public void handleEvent(Event e) { + switch (e.type) { + case DWT.FocusIn: + Safari.this.webView.window().makeFirstResponder(Safari.this.webView); + break; + case DWT.Dispose: { + /* make this handler run after other dispose listeners */ + if (ignoreDispose) { + ignoreDispose = false; + break; } + ignoreDispose = true; + browser.notifyListeners (e.type, e); + e.type = DWT.NONE; + + e.display.setData(ADD_WIDGET_KEY, new Object[] {delegate, null}); + + Safari.this.webView.setFrameLoadDelegate(null); + Safari.this.webView.setResourceLoadDelegate(null); + Safari.this.webView.setUIDelegate(null); + Safari.this.webView.setPolicyDelegate(null); + Safari.this.webView.setDownloadDelegate(null); + notificationCenter.removeObserver(delegate); + + Safari.this.webView.release(); + Safari.this.webView = null; + Safari.this.delegate.release(); + Safari.this.delegate = null; + html = null; + lastHoveredLinkURL = null; + break; } } - const ProgressEvent progress = new ProgressEvent(browser); - progress.display = display; - progress.widget = browser; - progress.current = MAX_PROGRESS; - progress.total = MAX_PROGRESS; - for (int i = 0; i < progressListeners.length; i++) - { - const ProgressListener listener = progressListeners[i]; - /* - * Note on WebKit. Running the event loop from a Browser - * delegatee callback breaks the WebKit (stop loading or - * crash). The ProgressBar widget currently touches the - * event loop every time the method setSelection is called. - * The workaround is to invoke Display.asyncExec() so that - * the Browser does not crash when the user updates the - * selection of the ProgressBar. - */ - display.asyncExec(new class (display, listener) Runnable - { - Display display; - ProgressListener listener; - - this (Display display, ProgressListener listener) - { - this.display = display; - this.listener = listener; - } - - public void run () - { - if (!display.isDisposed() && !browser.isDisposed()) - { - listener.completed(progress); - } - } - }); - } - /* - * Feature on Safari. The identifier is used here as a marker for the events - * related to the top frame and the URL changes related to that top frame as - * they should appear on the location bar of a browser. It is expected to reset - * the identifier to 0 when the event didFinishLoadingFromDataSource related to - * the identifierForInitialRequest event is received. However, Safari fires - * the didFinishLoadingFromDataSource event before the entire content of the - * top frame is loaded. It is possible to receive multiple willSendRequest - * events in this interval, causing the Browser widget to send unwanted - * Location.changing events. For this reason, the identifier is reset to 0 - * when the top frame has either finished loading (didFinishLoadForFrame - * event) or failed (didFailProvisionalLoadWithError). - */ - identifier = 0; } - } - - void hookDOMKeyListeners (int frameID) - { - WebFrame frame = new WebFrame(frameID); - DOMDocument document = frame.DOMDocument(); - - NSString type = NSString.StringWith(DOMEVENT_KEYDOWN); - document.addEventListener_listener_useCapture(type, delegatee, false); + }; + browser.addListener(DWT.Dispose, listener); + /* Needed to be able to tab into the browser */ + browser.addListener(DWT.KeyDown, listener); + browser.addListener(DWT.FocusIn, listener); - type = NSString.StringWith(DOMEVENT_KEYUP); - document.addEventListener_listener_useCapture(type, delegatee, false); - } + webView.setFrameLoadDelegate(delegate); + webView.setResourceLoadDelegate(delegate); + webView.setUIDelegate(delegate); + notificationCenter.addObserver(delegate, OS.sel_handleNotification_, null, webView); + webView.setPolicyDelegate(delegate); + webView.setDownloadDelegate(delegate); + webView.setApplicationNameForUserAgent(NSString.stringWith(AGENT_STRING)); - void hookDOMMouseListeners (int frameID) - { - WebFrame frame = new WebFrame(frameID); - DOMDocument document = frame.DOMDocument(); + if (!Initialized) { + Initialized = true; + /* disable applets */ + WebPreferences.standardPreferences().setJavaEnabled(false); + } +} - NSString type = NSString.StringWith(DOMEVENT_MOUSEDOWN); - document.addEventListener_listener_useCapture(type, delegatee, false); - - type = NSString.StringWith(DOMEVENT_MOUSEUP); - document.addEventListener_listener_useCapture(type, delegatee, false); +public bool back() { + html = null; + return webView.goBack(); +} - type = NSString.StringWith(DOMEVENT_MOUSEMOVE); - document.addEventListener_listener_useCapture(type, delegatee, false); - - type = NSString.StringWith(DOMEVENT_MOUSEWHEEL); - document.addEventListener_listener_useCapture(type, delegatee, false); +static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) { + Widget widget = Display.getCurrent().findWidget(id); + if (widget is null) return 0; + Safari safari = (Safari)((Browser)widget).webBrowser; + if (sel is OS.sel_handleNotification_) { + safari.handleNotification(arg0); + } else if (sel is OS.sel_webViewShow_) { + safari.webViewShow(arg0); + } else if (sel is OS.sel_webViewClose_) { + safari.webViewClose(arg0); + } else if (sel is OS.sel_webViewFocus_) { + safari.webViewFocus(arg0); + } else if (sel is OS.sel_webViewUnfocus_) { + safari.webViewUnfocus(arg0); + } else if (sel is OS.sel_handleEvent_) { + safari.handleEvent(arg0); } + return 0; +} - void webView_didReceiveTitle_forFrame (int sender, int titleID, int frameID) - { - if (frameID is webView.mainFrame().id) - { - NSString title = new NSString(titleID); - char[] buffer = new char[title.length()]; - title.getCharacters_(buffer); - String newTitle = new String(buffer); - TitleEvent newEvent = new TitleEvent(browser); - newEvent.display = browser.getDisplay(); - newEvent.widget = browser; - newEvent.title = newTitle; - for (int i = 0; i < titleListeners.length; i++) - { - titleListeners[i].changed(newEvent); - } - } +static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1) { + Widget widget = Display.getCurrent().findWidget(id); + if (widget is null) return 0; + Safari safari = (Safari)((Browser)widget).webBrowser; + if (sel is OS.sel_webView_didChangeLocationWithinPageForFrame_) { + safari.webView_didChangeLocationWithinPageForFrame(arg0, arg1); + } else if (sel is OS.sel_webView_didFinishLoadForFrame_) { + safari.webView_didFinishLoadForFrame(arg0, arg1); + } else if (sel is OS.sel_webView_didStartProvisionalLoadForFrame_) { + safari.webView_didStartProvisionalLoadForFrame(arg0, arg1); + } else if (sel is OS.sel_webView_didCommitLoadForFrame_) { + safari.webView_didCommitLoadForFrame(arg0, arg1); + } else if (sel is OS.sel_webView_setFrame_) { + safari.webView_setFrame(arg0, arg1); + } else if (sel is OS.sel_webView_createWebViewWithRequest_) { + return safari.webView_createWebViewWithRequest(arg0, arg1); + } else if (sel is OS.sel_webView_setStatusBarVisible_) { + safari.webView_setStatusBarVisible(arg0, arg1 !is 0); + } else if (sel is OS.sel_webView_setResizable_) { + safari.webView_setResizable(arg0, arg1 !is 0); + } else if (sel is OS.sel_webView_setStatusText_) { + safari.webView_setStatusText(arg0, arg1); + } else if (sel is OS.sel_webView_setToolbarsVisible_) { + safari.webView_setToolbarsVisible(arg0, arg1 !is 0); + } else if (sel is OS.sel_webView_runJavaScriptAlertPanelWithMessage_) { + safari.webView_runJavaScriptAlertPanelWithMessage(arg0, arg1); + } else if (sel is OS.sel_webView_runJavaScriptConfirmPanelWithMessage_) { + return safari.webView_runJavaScriptConfirmPanelWithMessage(arg0, arg1); + } else if (sel is OS.sel_webView_runOpenPanelForFileButtonWithResultListener_) { + safari.webView_runOpenPanelForFileButtonWithResultListener(arg0, arg1); + } else if (sel is OS.sel_download_decideDestinationWithSuggestedFilename_) { + safari.download_decideDestinationWithSuggestedFilename(arg0, arg1); + } else if (sel is OS.sel_webView_printFrameView_) { + safari.webView_printFrameView(arg0, arg1); } + return 0; +} - void webView_didStartProvisionalLoadForFrame (int sender, int frameID) - { - /* - * This code is intentionally commented. WebFrameLoadDelegate:didStartProvisionalLoadForFrame is - * called before WebResourceLoadDelegate:willSendRequest and - * WebFrameLoadDelegate:didCommitLoadForFrame. The resource count is reset when didCommitLoadForFrame - * is received for the top frame. - */ - // if (frameID is webView.mainFrame().id) { - // /* reset resource status variables */ - // resourceCount= 0; - // } +static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2) { + Widget widget = Display.getCurrent().findWidget(id); + if (widget is null) return 0; + Safari safari = (Safari)((Browser)widget).webBrowser; + if (sel is OS.sel_webView_didFailProvisionalLoadWithError_forFrame_) { + safari.webView_didFailProvisionalLoadWithError_forFrame(arg0, arg1, arg2); + } else if (sel is OS.sel_webView_didReceiveTitle_forFrame_) { + safari.webView_didReceiveTitle_forFrame(arg0, arg1, arg2); + } else if (sel is OS.sel_webView_resource_didFinishLoadingFromDataSource_) { + safari.webView_resource_didFinishLoadingFromDataSource(arg0, arg1, arg2); + } else if (sel is OS.sel_webView_identifierForInitialRequest_fromDataSource_) { + return safari.webView_identifierForInitialRequest_fromDataSource(arg0, arg1, arg2); + } else if (sel is OS.sel_webView_contextMenuItemsForElement_defaultMenuItems_) { + return safari.webView_contextMenuItemsForElement_defaultMenuItems(arg0, arg1, arg2); + } else if (sel is OS.sel_webView_mouseDidMoveOverElement_modifierFlags_) { + safari.webView_mouseDidMoveOverElement_modifierFlags(arg0, arg1, arg2); + } else if (sel is OS.sel_webView_unableToImplementPolicyWithError_frame_) { + safari.webView_unableToImplementPolicyWithError_frame(arg0, arg1, arg2); } + return 0; +} - void webView_didCommitLoadForFrame (int sender, int frameID) - { - WebFrame frame = new WebFrame(frameID); - WebDataSource dataSource = frame.dataSource(); - NSURLRequest request = dataSource.request(); - NSURL url = request.URL(); - NSString s = url.absoluteString(); - int length = s.length(); - if (length is 0) - return; - char[] buffer = new char[length]; - s.getCharacters_(buffer); - String url2 = new String(buffer); - /* - * If the URI indicates that the page is being rendered from memory - * (via setText()) then set it to about:blank to be consistent with IE. - */ - if (url2.opEquals(URI_FROMMEMORY)) - url2 = ABOUT_BLANK; +static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ arg3) { + Widget widget = Display.getCurrent().findWidget(id); + if (widget is null) return 0; + Safari safari = (Safari)((Browser)widget).webBrowser; + if (sel is OS.sel_webView_resource_didFailLoadingWithError_fromDataSource_) { + safari.webView_resource_didFailLoadingWithError_fromDataSource(arg0, arg1, arg2, arg3); + } + return 0; +} - const Display display = browser.getDisplay(); - bool top = frameID is webView.mainFrame().id; - if (top) - { - /* reset resource status variables */ - resourceCount = 0; - this.url = url2; +static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ arg3, int /*long*/ arg4) { + Widget widget = Display.getCurrent().findWidget(id); + if (widget is null) return 0; + Safari safari = (Safari)((Browser)widget).webBrowser; + if (sel is OS.sel_webView_resource_willSendRequest_redirectResponse_fromDataSource_) { + return safari.webView_resource_willSendRequest_redirectResponse_fromDataSource(arg0, arg1, arg2, arg3, arg4); + } else if (sel is OS.sel_webView_decidePolicyForMIMEType_request_frame_decisionListener_) { + safari.webView_decidePolicyForMIMEType_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4); + } else if (sel is OS.sel_webView_decidePolicyForNavigationAction_request_frame_decisionListener_) { + safari.webView_decidePolicyForNavigationAction_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4); + } else if (sel is OS.sel_webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener_) { + safari.webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener(arg0, arg1, arg2, arg3, arg4); + } + return 0; +} + +public bool execute(String script) { + return webView.stringByEvaluatingJavaScriptFromString(NSString.stringWith(script)) !is null; +} + +public bool forward() { + html = null; + return webView.goForward(); +} - const ProgressEvent progress = new ProgressEvent(browser); - progress.display = display; - progress.widget = browser; - progress.current = 1; - progress.total = MAX_PROGRESS; - for (int i = 0; i < progressListeners.length; i++) - { - const ProgressListener listener = progressListeners[i]; - /* - * Note on WebKit. Running the event loop from a Browser - * delegatee callback breaks the WebKit (stop loading or - * crash). The widget ProgressBar currently touches the - * event loop every time the method setSelection is called. - * The workaround is to invoke Display.asyncexec so that - * the Browser does not crash when the user updates the - * selection of the ProgressBar. - */ - display.asyncExec(new class (display, listener) Runnable - { - Display display; - ProgressListener listener; - - this (Display display, ProgressListener listener) - { - this.display = display; - this.listener = listener; - } - - public void run () - { - if (!display.isDisposed() && !browser.isDisposed()) - listener.changed(progress); - } - }); - } +public String getBrowserType () { + return "safari"; //$NON-NLS-1$ +} + +public String getText() { + WebFrame mainFrame = webView.mainFrame(); + WebDataSource dataSource = mainFrame.dataSource(); + if (dataSource is null) return ""; //$NON-NLS-1$ + WebDocumentRepresentation representation = dataSource.representation(); + if (representation is null) return ""; //$NON-NLS-1$ + NSString source = representation.documentSource(); + if (source is null) return ""; //$NON-NLS-1$ + return source.getString(); +} + +public String getUrl() { + return url; +} + +public bool isBackEnabled() { + return webView.canGoBack(); +} + +public bool isForwardEnabled() { + return webView.canGoForward(); +} - StatusTextEvent statusText = new StatusTextEvent(browser); - statusText.display = display; - statusText.widget = browser; - statusText.text = url2; - for (int i = 0; i < statusTextListeners.length; i++) - { - statusTextListeners[i].changed(statusText); - } - } - LocationEvent location = new LocationEvent(browser); - location.display = display; - location.widget = browser; - location.location = url2; - location.top = top; - for (int i = 0; i < locationListeners.length; i++) - { - locationListeners[i].changed(location); - } - } +public void refresh() { + webView.reload(null); +} - /* WebResourceLoadDelegate */ - - void webView_resource_didFinishLoadingFromDataSource (int sender, int identifier, int dataSource) - { +public bool setText(String html) { /* - * Feature on Safari. The identifier is used here as a marker for the events - * related to the top frame and the URL changes related to that top frame as - * they should appear on the location bar of a browser. It is expected to reset - * the identifier to 0 when the event didFinishLoadingFromDataSource related to - * the identifierForInitialRequest event is received. However, Safari fires - * the didFinishLoadingFromDataSource event before the entire content of the - * top frame is loaded. It is possible to receive multiple willSendRequest - * events in this interval, causing the Browser widget to send unwanted - * Location.changing events. For this reason, the identifier is reset to 0 - * when the top frame has either finished loading (didFinishLoadForFrame - * event) or failed (didFailProvisionalLoadWithError). - */ - // this code is intentionally commented - //if (this.identifier is identifier) this.identifier = 0; + * Bug in Safari. The web view segment faults in some circumstances + * when the text changes during the location changing callback. The + * fix is to defer the work until the callback is done. + */ + if (changingLocation) { + this.html = html; + } else { + _setText(html); + } + return true; +} + +void _setText(String html) { + NSString string = NSString.stringWith(html); + NSString URLString = NSString.stringWith(URI_FROMMEMORY); + NSURL URL = NSURL.URLWithString(URLString); + WebFrame mainFrame = webView.mainFrame(); + mainFrame.loadHTMLString(string, URL); +} + +public bool setUrl(String url) { + html = null; + + if (url.indexOf('/') is 0) { + url = PROTOCOL_FILE + url; + } else if (url.indexOf(':') is -1) { + url = PROTOCOL_HTTP + url; } - void webView_resource_didFailLoadingWithError_fromDataSource (int sender, int identifier, int error, int dataSource) - { - /* - * Feature on Safari. The identifier is used here as a marker for the events - * related to the top frame and the URL changes related to that top frame as - * they should appear on the location bar of a browser. It is expected to reset - * the identifier to 0 when the event didFinishLoadingFromDataSource related to - * the identifierForInitialRequest event is received. However, Safari fires - * the didFinishLoadingFromDataSource event before the entire content of the - * top frame is loaded. It is possible to receive multiple willSendRequest - * events in this interval, causing the Browser widget to send unwanted - * Location.changing events. For this reason, the identifier is reset to 0 - * when the top frame has either finished loading (didFinishLoadForFrame - * event) or failed (didFailProvisionalLoadWithError). - */ - // this code is intentionally commented - //if (this.identifier is identifier) this.identifier = 0; - } + NSString str = NSString.stringWith(url); + NSString unescapedStr = NSString.stringWith("%#"); //$NON-NLS-1$ + int /*long*/ ptr = OS.CFURLCreateStringByAddingPercentEscapes(0, str.id, unescapedStr.id, 0, OS.kCFStringEncodingUTF8); + NSString escapedString = new NSString(ptr); + NSURL inURL = NSURL.URLWithString(escapedString); + OS.CFRelease(ptr); + NSURLRequest request = NSURLRequest.requestWithURL(inURL); + WebFrame mainFrame = webView.mainFrame(); + mainFrame.loadRequest(request); + return true; +} - int webView_identifierForInitialRequest_fromDataSource (int sender, int request, int dataSourceID) - { - const Display display = browser.getDisplay(); - const ProgressEvent progress = new ProgressEvent(browser); - progress.display = display; - progress.widget = browser; - progress.current = resourceCount; - progress.total = Math.max(resourceCount, MAX_PROGRESS); - for (int i = 0; i < progressListeners.length; i++) - { - const ProgressListener listener = progressListeners[i]; - /* - * Note on WebKit. Running the event loop from a Browser - * delegatee callback breaks the WebKit (stop loading or - * crash). The widget ProgressBar currently touches the - * event loop every time the method setSelection is called. - * The workaround is to invoke Display.asyncexec so that - * the Browser does not crash when the user updates the - * selection of the ProgressBar. - */ - display.asyncExec(new class (display, listener) Runnable - { - Display display; - ProgressListener listener; - - this (Display display, ProgressListener listener) - { - this.display = display; - this.listener = listener; - } - - public void run () - { - if (!display.isDisposed() && !browser.isDisposed()) - listener.changed(progress); - } - }); - } +public void stop() { + html = null; + webView.stopLoading(null); +} - NSNumber identifier = NSNumber.numberWithInt(resourceCount++); - if (this.identifier is 0) - { - WebDataSource dataSource = new WebDataSource(dataSourceID); - WebFrame frame = dataSource.webFrame(); - if (frame.id is webView.mainFrame().id) - this.identifier = identifier.id; - } - return identifier.id; - - } - - int webView_resource_willSendRequest_redirectResponse_fromDataSource (int sender, int identifier, int request, int redirectResponse, - int dataSource) - { - return request; - } - - /* handleNotification */ - - void handleNotification (int notification) - { - } - - /* UIDelegate */ - int webView_createWebViewWithRequest (int sender, int request) - { - WindowEvent newEvent = new WindowEvent(browser); - newEvent.display = browser.getDisplay(); - newEvent.widget = browser; - newEvent.required = true; - if (openWindowListeners !is null) - { - for (int i = 0; i < openWindowListeners.length; i++) - { - openWindowListeners[i].open(newEvent); - } - } - Browser browser = null; - if (newEvent.browser !is null && cast(Safari) newEvent.browser.webBrowser) - { - browser = newEvent.browser; - } - if (browser !is null && !browser.isDisposed()) - { - if (request !is 0) - { - WebFrame mainFrame = webView.mainFrame(); - mainFrame.loadRequest(new NSURLRequest(request)); - } - } - return webView.id; - } +/* WebFrameLoadDelegate */ - void webViewShow (int sender) - { - /* - * Feature on WebKit. The Safari WebKit expects the application - * to create a new Window using the Objective C Cocoa API in response - * to UIDelegate.createWebViewWithRequest. The application is then - * expected to use Objective C Cocoa API to make this window visible - * when receiving the UIDelegate.webViewShow message. For some reason, - * a window created with the Carbon API hosting the new browser instance - * does not redraw until it has been resized. The fix is to increase the - * size of the Shell and restore it to its initial size. - */ - Shell parent = browser.getShell(); - Point pt = parent.getSize(); - parent.setSize(pt.x + 1, pt.y); - parent.setSize(pt.x, pt.y); - WindowEvent newEvent = new WindowEvent(browser); - newEvent.display = browser.getDisplay(); - newEvent.widget = browser; - if (location !is null) - newEvent.location = location; - if (size !is null) - newEvent.size = size; - /* - * Feature in Safari. Safari's tool bar contains - * the address bar. The address bar is displayed - * if the tool bar is displayed. There is no separate - * notification for the address bar. - * Feature in Safari. The menu bar is always - * displayed. There is no notification to hide - * the menu bar. - */ - newEvent.addressBar = toolBar; - newEvent.menuBar = true; - newEvent.statusBar = statusBar; - newEvent.toolBar = toolBar; - for (int i = 0; i < visibilityWindowListeners.length; i++) - { - visibilityWindowListeners[i].show(newEvent); - } - location = null; - size = null; - } - - void webView_setFrame (int sender, int frame) - { - float[] dest = new float[4]; - OS.memmove(dest, frame, 16); - /* convert to DWT system coordinates */ - Rectangle bounds = browser.getDisplay().getBounds(); - location = new Point(cast(int) dest[0], bounds.height - cast(int) dest[1] - cast(int) dest[3]); - size = new Point(cast(int) dest[2], cast(int) dest[3]); - } - - void webViewFocus (int sender) - { - } - - void webViewUnfocus (int sender) - { - } - - void webView_runJavaScriptAlertPanelWithMessage (int sender, int messageID) - { - NSString message = new NSString(messageID); - char[] buffer = new char[message.length()]; - message.getCharacters_(buffer); - String text = new String(buffer); - - MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.ICON_WARNING); - messageBox.setText("Javascript"); //$NON-NLS-1$ - messageBox.setMessage(text); - messageBox.open(); - } - - int webView_runJavaScriptConfirmPanelWithMessage (int sender, int messageID) - { - NSString message = new NSString(messageID); - char[] buffer = new char[message.length()]; - message.getCharacters_(buffer); - String text = new String(buffer); +void webView_didChangeLocationWithinPageForFrame(int /*long*/ sender, int /*long*/ frameID) { + WebFrame frame = new WebFrame(frameID); + WebDataSource dataSource = frame.dataSource(); + NSURLRequest request = dataSource.request(); + NSURL url = request.URL(); + NSString s = url.absoluteString(); + int length = (int)/*64*/s.length(); + if (length is 0) return; + String url2 = s.getString(); + /* + * If the URI indicates that the page is being rendered from memory + * (via setText()) then set it to about:blank to be consistent with IE. + */ + if (url2.equals (URI_FROMMEMORY)) url2 = ABOUT_BLANK; - MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.CANCEL | DWT.ICON_QUESTION); - messageBox.setText("Javascript"); //$NON-NLS-1$ - messageBox.setMessage(text); - return messageBox.open() is DWT.OK ? 1 : 0; - } - - void webView_runOpenPanelForFileButtonWithResultListener (int sender, int resultListenerID) - { - FileDialog dialog = new FileDialog(browser.getShell(), DWT.NONE); - String result = dialog.open(); - WebOpenPanelResultListener resultListener = new WebOpenPanelResultListener(resultListenerID); - if (result is null) - { - resultListener.cancel(); - return; - } - resultListener.chooseFilename(NSString.StringWith(result)); - } - - void webViewClose (int sender) - { - Shell parent = browser.getShell(); - WindowEvent newEvent = new WindowEvent(browser); - newEvent.display = browser.getDisplay(); - newEvent.widget = browser; - for (int i = 0; i < closeWindowListeners.length; i++) - { - closeWindowListeners[i].close(newEvent); - } - browser.dispose(); - if (parent.isDisposed()) - return; - /* - * Feature on WebKit. The Safari WebKit expects the application - * to create a new Window using the Objective C Cocoa API in response - * to UIDelegate.createWebViewWithRequest. The application is then - * expected to use Objective C Cocoa API to make this window visible - * when receiving the UIDelegate.webViewShow message. For some reason, - * a window created with the Carbon API hosting the new browser instance - * does not redraw until it has been resized. The fix is to increase the - * size of the Shell and restore it to its initial size. - */ - Point pt = parent.getSize(); - parent.setSize(pt.x + 1, pt.y); - parent.setSize(pt.x, pt.y); - } - - int webView_contextMenuItemsForElement_defaultMenuItems (int sender, int element, int defaultMenuItems) - { - Point pt = browser.getDisplay().getCursorLocation(); - Event event = new Event(); - event.x = pt.x; - event.y = pt.y; - browser.notifyListeners(DWT.MenuDetect, event); - Menu menu = browser.getMenu(); - if (!event.doit) - return 0; - if (menu !is null && !menu.isDisposed()) - { - if (event.x !is pt.x || event.y !is pt.y) - { - menu.setLocation(event.x, event.y); - } - menu.setVisible(true); - return 0; - } - return defaultMenuItems; - } - - void webView_setStatusBarVisible (int sender, int visible) - { - /* Note. Webkit only emits the notification when the status bar should be hidden. */ - statusBar = visible !is 0; - } - - void webView_setStatusText (int sender, int textID) - { - NSString text = new NSString(textID); - int length = text.length(); - if (length is 0) - return; - char[] buffer = new char[length]; - text.getCharacters_(buffer); - + final Display display = browser.getDisplay(); + bool top = frameID is webView.mainFrame().id; + if (top) { StatusTextEvent statusText = new StatusTextEvent(browser); - statusText.display = browser.getDisplay(); + statusText.display = display; statusText.widget = browser; - statusText.text = new String(buffer); - for (int i = 0; i < statusTextListeners.length; i++) - { + statusText.text = url2; + for (int i = 0; i < statusTextListeners.length; i++) { statusTextListeners[i].changed(statusText); } } - void webView_setResizable (int sender, int visible) - { + LocationEvent location = new LocationEvent(browser); + location.display = display; + location.widget = browser; + location.location = url2; + location.top = top; + for (int i = 0; i < locationListeners.length; i++) { + locationListeners[i].changed(location); } +} - void webView_setToolbarsVisible (int sender, int visible) - { - /* Note. Webkit only emits the notification when the tool bar should be hidden. */ - toolBar = visible !is 0; +void webView_didFailProvisionalLoadWithError_forFrame(int /*long*/ sender, int /*long*/ error, int /*long*/ frame) { + if (frame is webView.mainFrame().id) { + /* + * Feature on Safari. The identifier is used here as a marker for the events + * related to the top frame and the URL changes related to that top frame as + * they should appear on the location bar of a browser. It is expected to reset + * the identifier to 0 when the event didFinishLoadingFromDataSource related to + * the identifierForInitialRequest event is received. However, Safari fires + * the didFinishLoadingFromDataSource event before the entire content of the + * top frame is loaded. It is possible to receive multiple willSendRequest + * events in this interval, causing the Browser widget to send unwanted + * Location.changing events. For this reason, the identifier is reset to 0 + * when the top frame has either finished loading (didFinishLoadForFrame + * event) or failed (didFailProvisionalLoadWithError). + */ + identifier = 0; } - void webView_mouseDidMoveOverElement_modifierFlags (int sender, int elementInformationID, int modifierFlags) - { - if (elementInformationID is 0) - return; + NSError nserror = new NSError(error); + int /*long*/ errorCode = nserror.code(); + if (errorCode <= OS.NSURLErrorBadURL) { + NSString description = nserror.localizedDescription(); + if (description !is null) { + String descriptionString = description.getString(); + String urlString = null; + NSDictionary info = nserror.userInfo(); + if (info !is null) { + NSString key = new NSString(OS.NSErrorFailingURLStringKey()); + id id = info.valueForKey(key); + if (id !is null) { + NSString url = new NSString(id); + urlString = url.getString(); + } + } + String message = urlString !is null ? urlString + "\n\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$ + message += Compatibility.getMessage ("DWT_Page_Load_Failed", new Object[] {descriptionString}); //$NON-NLS-1$ + MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.ICON_ERROR); + messageBox.setMessage(message); + messageBox.open(); + } + } +} + +void webView_didFinishLoadForFrame(int /*long*/ sender, int /*long*/ frameID) { + hookDOMMouseListeners(frameID); + if (frameID is webView.mainFrame().id) { + hookDOMKeyListeners(frameID); - NSString key = NSString.StringWith(WebElementLinkURLKey); - NSDictionary elementInformation = new NSDictionary(elementInformationID); - id value = elementInformation.valueForKey(key); - if (value is null) - { - /* not currently over a link */ - if (lastHoveredLinkURL is null) - return; - lastHoveredLinkURL = null; - StatusTextEvent statusText = new StatusTextEvent(browser); - statusText.display = browser.getDisplay(); - statusText.widget = browser; - statusText.text = ""; //$NON-NLS-1$ - for (int i = 0; i < statusTextListeners.length; i++) - { - statusTextListeners[i].changed(statusText); + final Display display = browser.getDisplay(); + /* + * To be consistent with other platforms a title event should be fired when a + * page has completed loading. A page with a <title> tag will do this + * automatically when the didReceiveTitle callback is received. However a page + * without a <title> tag will not do this by default, so fire the event + * here with the page's url as the title. + */ + WebFrame frame = new WebFrame(frameID); + WebDataSource dataSource = frame.dataSource(); + if (dataSource !is null) { + NSString title = dataSource.pageTitle(); + if (title is null) { /* page has no title */ + final TitleEvent newEvent = new TitleEvent(browser); + newEvent.display = display; + newEvent.widget = browser; + newEvent.title = url; + for (int i = 0; i < titleListeners.length; i++) { + final TitleListener listener = titleListeners[i]; + /* + * Note on WebKit. Running the event loop from a Browser + * delegate callback breaks the WebKit (stop loading or + * crash). The workaround is to invoke Display.asyncExec() + * so that the Browser does not crash if this is attempted. + */ + display.asyncExec( + new Runnable() { + public void run() { + if (!display.isDisposed() && !browser.isDisposed()) { + listener.changed(newEvent); + } + } + } + ); + } } - return; + } + final ProgressEvent progress = new ProgressEvent(browser); + progress.display = display; + progress.widget = browser; + progress.current = MAX_PROGRESS; + progress.total = MAX_PROGRESS; + for (int i = 0; i < progressListeners.length; i++) { + final ProgressListener listener = progressListeners[i]; + /* + * Note on WebKit. Running the event loop from a Browser + * delegate callback breaks the WebKit (stop loading or + * crash). The ProgressBar widget currently touches the + * event loop every time the method setSelection is called. + * The workaround is to invoke Display.asyncExec() so that + * the Browser does not crash when the user updates the + * selection of the ProgressBar. + */ + display.asyncExec( + new Runnable() { + public void run() { + if (!display.isDisposed() && !browser.isDisposed()) { + listener.completed(progress); + } + } + } + ); + } + /* + * Feature on Safari. The identifier is used here as a marker for the events + * related to the top frame and the URL changes related to that top frame as + * they should appear on the location bar of a browser. It is expected to reset + * the identifier to 0 when the event didFinishLoadingFromDataSource related to + * the identifierForInitialRequest event is received. However, Safari fires + * the didFinishLoadingFromDataSource event before the entire content of the + * top frame is loaded. It is possible to receive multiple willSendRequest + * events in this interval, causing the Browser widget to send unwanted + * Location.changing events. For this reason, the identifier is reset to 0 + * when the top frame has either finished loading (didFinishLoadForFrame + * event) or failed (didFailProvisionalLoadWithError). + */ + identifier = 0; + } +} + +void hookDOMKeyListeners(int /*long*/ frameID) { + WebFrame frame = new WebFrame(frameID); + DOMDocument document = frame.DOMDocument(); + + NSString type = NSString.stringWith(DOMEVENT_KEYDOWN); + document.addEventListener(type, delegate, false); + + type = NSString.stringWith(DOMEVENT_KEYUP); + document.addEventListener(type, delegate, false); +} + +void hookDOMMouseListeners(int /*long*/ frameID) { + WebFrame frame = new WebFrame(frameID); + DOMDocument document = frame.DOMDocument(); + + NSString type = NSString.stringWith(DOMEVENT_MOUSEDOWN); + document.addEventListener(type, delegate, false); + + type = NSString.stringWith(DOMEVENT_MOUSEUP); + document.addEventListener(type, delegate, false); + + type = NSString.stringWith(DOMEVENT_MOUSEMOVE); + document.addEventListener(type, delegate, false); + + type = NSString.stringWith(DOMEVENT_MOUSEWHEEL); + document.addEventListener(type, delegate, false); +} + +void webView_didReceiveTitle_forFrame(int /*long*/ sender, int /*long*/ titleID, int /*long*/ frameID) { + if (frameID is webView.mainFrame().id) { + NSString title = new NSString(titleID); + String newTitle = title.getString(); + TitleEvent newEvent = new TitleEvent(browser); + newEvent.display = browser.getDisplay(); + newEvent.widget = browser; + newEvent.title = newTitle; + for (int i = 0; i < titleListeners.length; i++) { + titleListeners[i].changed(newEvent); + } + } +} + +void webView_didStartProvisionalLoadForFrame(int /*long*/ sender, int /*long*/ frameID) { + /* + * This code is intentionally commented. WebFrameLoadDelegate:didStartProvisionalLoadForFrame is + * called before WebResourceLoadDelegate:willSendRequest and + * WebFrameLoadDelegate:didCommitLoadForFrame. The resource count is reset when didCommitLoadForFrame + * is received for the top frame. + */ +// if (frameID is webView.mainFrame().id) { +// /* reset resource status variables */ +// resourceCount= 0; +// } +} + +void webView_didCommitLoadForFrame(int /*long*/ sender, int /*long*/ frameID) { + WebFrame frame = new WebFrame(frameID); + WebDataSource dataSource = frame.dataSource(); + NSURLRequest request = dataSource.request(); + NSURL url = request.URL(); + NSString s = url.absoluteString(); + int length = (int)/*64*/s.length(); + if (length is 0) return; + String url2 = s.getString(); + /* + * If the URI indicates that the page is being rendered from memory + * (via setText()) then set it to about:blank to be consistent with IE. + */ + if (url2.equals (URI_FROMMEMORY)) url2 = ABOUT_BLANK; + + final Display display = browser.getDisplay(); + bool top = frameID is webView.mainFrame().id; + if (top) { + /* reset resource status variables */ + resourceCount = 0; + this.url = url2; + + final ProgressEvent progress = new ProgressEvent(browser); + progress.display = display; + progress.widget = browser; + progress.current = 1; + progress.total = MAX_PROGRESS; + for (int i = 0; i < progressListeners.length; i++) { + final ProgressListener listener = progressListeners[i]; + /* + * Note on WebKit. Running the event loop from a Browser + * delegate callback breaks the WebKit (stop loading or + * crash). The widget ProgressBar currently touches the + * event loop every time the method setSelection is called. + * The workaround is to invoke Display.asyncexec so that + * the Browser does not crash when the user updates the + * selection of the ProgressBar. + */ + display.asyncExec( + new Runnable() { + public void run() { + if (!display.isDisposed() && !browser.isDisposed()) + listener.changed(progress); + } + } + ); } - NSString url = (new NSURL(value.id)).absoluteString(); - int length = url.length(); - String urlString; - if (length is 0) - { - urlString = ""; //$NON-NLS-1$ - } - else - { - char[] buffer = new char[length]; - url.getCharacters_(buffer); - urlString = new String(buffer); - } - if (urlString.opEquals(lastHoveredLinkURL)) - return; - - lastHoveredLinkURL = urlString; StatusTextEvent statusText = new StatusTextEvent(browser); - statusText.display = browser.getDisplay(); + statusText.display = display; statusText.widget = browser; - statusText.text = urlString; - for (int i = 0; i < statusTextListeners.length; i++) - { + statusText.text = url2; + for (int i = 0; i < statusTextListeners.length; i++) { statusTextListeners[i].changed(statusText); } } + LocationEvent location = new LocationEvent(browser); + location.display = display; + location.widget = browser; + location.location = url2; + location.top = top; + for (int i = 0; i < locationListeners.length; i++) { + locationListeners[i].changed(location); + } +} - void webView_printFrameView (int sender, int frameViewID) - { - WebFrameView view = new WebFrameView(frameViewID); - bool viewPrint = view.documentViewShouldHandlePrint(); - if (viewPrint) - { - view.printDocumentView(); - return; - } - NSPrintInfo info = NSPrintInfo.sharedPrintInfo(); - NSPrintOperation operation = view.printOperationWithPrintInfo(info); - if (operation !is null) - operation.runOperation(); - } +/* WebResourceLoadDelegate */ - /* PolicyDelegate */ - - void webView_decidePolicyForMIMEType_request_frame_decisionListener (int sender, int type, int request, int frame, int listenerID) - { - bool canShow = WebView.canShowMIMEType(new NSString(type)); - WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID); - if (canShow) - { - listener.use(); - } - else - { - listener.download(); - } - } +void webView_resource_didFinishLoadingFromDataSource(int /*long*/ sender, int /*long*/ identifier, int /*long*/ dataSource) { + /* + * Feature on Safari. The identifier is used here as a marker for the events + * related to the top frame and the URL changes related to that top frame as + * they should appear on the location bar of a browser. It is expected to reset + * the identifier to 0 when the event didFinishLoadingFromDataSource related to + * the identifierForInitialRequest event is received. However, Safari fires + * the didFinishLoadingFromDataSource event before the entire content of the + * top frame is loaded. It is possible to receive multiple willSendRequest + * events in this interval, causing the Browser widget to send unwanted + * Location.changing events. For this reason, the identifier is reset to 0 + * when the top frame has either finished loading (didFinishLoadForFrame + * event) or failed (didFailProvisionalLoadWithError). + */ + // this code is intentionally commented + //if (this.identifier is identifier) this.identifier = 0; +} - void webView_decidePolicyForNavigationAction_request_frame_decisionListener (int sender, int actionInformation, int request, int frame, - int listenerID) - { - NSURL url = (new NSURLRequest(request)).URL(); - WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID); - if (url is null) - { - /* indicates that a URL with an invalid format was specified */ - listener.ignore(); - return; - } - NSString s = url.absoluteString(); - char[] buffer = new char[s.length()]; - s.getCharacters_(buffer); - String url2 = new String(buffer); - /* - * If the URI indicates that the page is being rendered from memory - * (via setText()) then set it to about:blank to be consistent with IE. - */ - if (url2.opEquals(URI_FROMMEMORY)) - url2 = ABOUT_BLANK; +void webView_resource_didFailLoadingWithError_fromDataSource(int /*long*/ sender, int /*long*/ identifier, int /*long*/ error, int /*long*/ dataSource) { + /* + * Feature on Safari. The identifier is used here as a marker for the events + * related to the top frame and the URL changes related to that top frame as + * they should appear on the location bar of a browser. It is expected to reset + * the identifier to 0 when the event didFinishLoadingFromDataSource related to + * the identifierForInitialRequest event is received. However, Safari fires + * the didFinishLoadingFromDataSource event before the entire content of the + * top frame is loaded. It is possible to receive multiple willSendRequest + * events in this interval, causing the Browser widget to send unwanted + * Location.changing events. For this reason, the identifier is reset to 0 + * when the top frame has either finished loading (didFinishLoadForFrame + * event) or failed (didFailProvisionalLoadWithError). + */ + // this code is intentionally commented + //if (this.identifier is identifier) this.identifier = 0; +} - LocationEvent newEvent = new LocationEvent(browser); - newEvent.display = browser.getDisplay(); - newEvent.widget = browser; - newEvent.location = url2; - newEvent.doit = true; - if (locationListeners !is null) - { - changingLocation = true; - for (int i = 0; i < locationListeners.length; i++) - { - locationListeners[i].changing(newEvent); +int /*long*/ webView_identifierForInitialRequest_fromDataSource(int /*long*/ sender, int /*long*/ request, int /*long*/ dataSourceID) { + final Display display = browser.getDisplay(); + final ProgressEvent progress = new ProgressEvent(browser); + progress.display = display; + progress.widget = browser; + progress.current = resourceCount; + progress.total = Math.max(resourceCount, MAX_PROGRESS); + for (int i = 0; i < progressListeners.length; i++) { + final ProgressListener listener = progressListeners[i]; + /* + * Note on WebKit. Running the event loop from a Browser + * delegate callback breaks the WebKit (stop loading or + * crash). The widget ProgressBar currently touches the + * event loop every time the method setSelection is called. + * The workaround is to invoke Display.asyncexec so that + * the Browser does not crash when the user updates the + * selection of the ProgressBar. + */ + display.asyncExec( + new Runnable() { + public void run() { + if (!display.isDisposed() && !browser.isDisposed()) + listener.changed(progress); + } } - changingLocation = false; - } - if (newEvent.doit) - { - listener.use(); - } - else - { - listener.ignore(); - } - if (html !is null && !browser.isDisposed()) - { - String html = this.html; - this.html = null; - _setText(html); - } - } - - void webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener (int sender, int actionInformation, int request, int frameName, - int listenerID) - { - WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID); - listener.use(); + ); } - void webView_unableToImplementPolicyWithError_frame (int sender, int error, int frame) - { + NSNumber identifier = NSNumber.numberWithInt(resourceCount++); + if (this.identifier is 0) { + WebDataSource dataSource = new WebDataSource(dataSourceID); + WebFrame frame = dataSource.webFrame(); + if (frame.id is webView.mainFrame().id) this.identifier = identifier.id; + } + return identifier.id; + +} + +int /*long*/ webView_resource_willSendRequest_redirectResponse_fromDataSource(int /*long*/ sender, int /*long*/ identifier, int /*long*/ request, int /*long*/ redirectResponse, int /*long*/ dataSource) { + return request; +} + +/* handleNotification */ + +void handleNotification(int /*long*/ notification) { +} + +/* UIDelegate */ + +int /*long*/ webView_createWebViewWithRequest(int /*long*/ sender, int /*long*/ request) { + WindowEvent newEvent = new WindowEvent(browser); + newEvent.display = browser.getDisplay(); + newEvent.widget = browser; + newEvent.required = true; + if (openWindowListeners !is null) { + for (int i = 0; i < openWindowListeners.length; i++) { + openWindowListeners[i].open(newEvent); + } + } + WebView result = null; + Browser browser = null; + if (newEvent.browser !is null && newEvent.browser.webBrowser instanceof Safari) { + browser = newEvent.browser; + } + if (browser !is null && !browser.isDisposed()) { + result = ((Safari)browser.webBrowser).webView; + if (request !is 0) { + WebFrame mainFrame = webView.mainFrame(); + mainFrame.loadRequest(new NSURLRequest(request)); + } } + return result !is null ? result.id : 0; +} - /* WebDownload */ +void webViewShow(int /*long*/ sender) { + /* + * Feature on WebKit. The Safari WebKit expects the application + * to create a new Window using the Objective C Cocoa API in response + * to UIDelegate.createWebViewWithRequest. The application is then + * expected to use Objective C Cocoa API to make this window visible + * when receiving the UIDelegate.webViewShow message. For some reason, + * a window created with the Carbon API hosting the new browser instance + * does not redraw until it has been resized. The fix is to increase the + * size of the Shell and restore it to its initial size. + */ + Shell parent = browser.getShell(); + Point pt = parent.getSize(); + parent.setSize(pt.x+1, pt.y); + parent.setSize(pt.x, pt.y); + WindowEvent newEvent = new WindowEvent(browser); + newEvent.display = browser.getDisplay(); + newEvent.widget = browser; + if (location !is null) newEvent.location = location; + if (size !is null) newEvent.size = size; + /* + * Feature in Safari. Safari's tool bar contains + * the address bar. The address bar is displayed + * if the tool bar is displayed. There is no separate + * notification for the address bar. + * Feature in Safari. The menu bar is always + * displayed. There is no notification to hide + * the menu bar. + */ + newEvent.addressBar = toolBar; + newEvent.menuBar = true; + newEvent.statusBar = statusBar; + newEvent.toolBar = toolBar; + for (int i = 0; i < visibilityWindowListeners.length; i++) { + visibilityWindowListeners[i].show(newEvent); + } + location = null; + size = null; +} + +void webView_setFrame(int /*long*/ sender, int /*long*/ frame) { + NSRect rect = new NSRect(); + OS.memmove(rect, frame, NSRect.sizeof); + /* convert to DWT system coordinates */ + Rectangle bounds = browser.getDisplay().getBounds(); + location = new Point((int)rect.x, bounds.height - (int)rect.y - (int)rect.height); + size = new Point((int)rect.width, (int)rect.height); +} + +void webViewFocus(int /*long*/ sender) { +} + +void webViewUnfocus(int /*long*/ sender) { +} + +void webView_runJavaScriptAlertPanelWithMessage(int /*long*/ sender, int /*long*/ messageID) { + NSString message = new NSString(messageID); + String text = message.getString(); - void download_decideDestinationWithSuggestedFilename (int downloadId, int filename) - { - NSString String = new NSString(filename); - char[] buffer = new char[String.length()]; - String.getCharacters_(buffer); - String name = new String(buffer); - FileDialog dialog = new FileDialog(browser.getShell(), DWT.SAVE); - dialog.setText(DWT.getMessage("DWT_FileDownload")); //$NON-NLS-1$ - dialog.setFileName(name); - String path = dialog.open(); - NSURLDownload download = new NSURLDownload(downloadId); - if (path is null) - { - /* cancel pressed */ - download.cancel(); - return; + MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.ICON_WARNING); + messageBox.setText("Javascript"); //$NON-NLS-1$ + messageBox.setMessage(text); + messageBox.open(); +} + +int webView_runJavaScriptConfirmPanelWithMessage(int /*long*/ sender, int /*long*/ messageID) { + NSString message = new NSString(messageID); + String text = message.getString(); + + MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.CANCEL | DWT.ICON_QUESTION); + messageBox.setText("Javascript"); //$NON-NLS-1$ + messageBox.setMessage(text); + return messageBox.open() is DWT.OK ? 1 : 0; +} + +void webView_runOpenPanelForFileButtonWithResultListener(int /*long*/ sender, int /*long*/ resultListenerID) { + FileDialog dialog = new FileDialog(browser.getShell(), DWT.NONE); + String result = dialog.open(); + WebOpenPanelResultListener resultListener = new WebOpenPanelResultListener(resultListenerID); + if (result is null) { + resultListener.cancel(); + return; + } + resultListener.chooseFilename(NSString.stringWith(result)); +} + +void webViewClose(int /*long*/ sender) { + Shell parent = browser.getShell(); + WindowEvent newEvent = new WindowEvent(browser); + newEvent.display = browser.getDisplay(); + newEvent.widget = browser; + for (int i = 0; i < closeWindowListeners.length; i++) { + closeWindowListeners[i].close(newEvent); + } + browser.dispose(); + if (parent.isDisposed()) return; + /* + * Feature on WebKit. The Safari WebKit expects the application + * to create a new Window using the Objective C Cocoa API in response + * to UIDelegate.createWebViewWithRequest. The application is then + * expected to use Objective C Cocoa API to make this window visible + * when receiving the UIDelegate.webViewShow message. For some reason, + * a window created with the Carbon API hosting the new browser instance + * does not redraw until it has been resized. The fix is to increase the + * size of the Shell and restore it to its initial size. + */ + Point pt = parent.getSize(); + parent.setSize(pt.x+1, pt.y); + parent.setSize(pt.x, pt.y); +} + +int /*long*/ webView_contextMenuItemsForElement_defaultMenuItems(int /*long*/ sender, int /*long*/ element, int /*long*/ defaultMenuItems) { + Point pt = browser.getDisplay().getCursorLocation(); + Event event = new Event(); + event.x = pt.x; + event.y = pt.y; + browser.notifyListeners(DWT.MenuDetect, event); + Menu menu = browser.getMenu(); + if (!event.doit) return 0; + if (menu !is null && !menu.isDisposed()) { + if (event.x !is pt.x || event.y !is pt.y) { + menu.setLocation(event.x, event.y); } - download.setDestination(NSString.StringWith(path), true); + menu.setVisible(true); + return 0; + } + return defaultMenuItems; +} + +void webView_setStatusBarVisible(int /*long*/ sender, bool visible) { + /* Note. Webkit only emits the notification when the status bar should be hidden. */ + statusBar = visible; +} + +void webView_setStatusText(int /*long*/ sender, int /*long*/ textID) { + NSString text = new NSString(textID); + int length = (int)/*64*/text.length(); + if (length is 0) return; + + StatusTextEvent statusText = new StatusTextEvent(browser); + statusText.display = browser.getDisplay(); + statusText.widget = browser; + statusText.text = text.getString(); + for (int i = 0; i < statusTextListeners.length; i++) { + statusTextListeners[i].changed(statusText); + } +} + +void webView_setResizable(int /*long*/ sender, bool visible) { +} + +void webView_setToolbarsVisible(int /*long*/ sender, bool visible) { + /* Note. Webkit only emits the notification when the tool bar should be hidden. */ + toolBar = visible; +} + +void webView_mouseDidMoveOverElement_modifierFlags (int /*long*/ sender, int /*long*/ elementInformationID, int /*long*/ modifierFlags) { + if (elementInformationID is 0) return; + + NSString key = NSString.stringWith(WebElementLinkURLKey); + NSDictionary elementInformation = new NSDictionary(elementInformationID); + id value = elementInformation.valueForKey(key); + if (value is null) { + /* not currently over a link */ + if (lastHoveredLinkURL is null) return; + lastHoveredLinkURL = null; + StatusTextEvent statusText = new StatusTextEvent(browser); + statusText.display = browser.getDisplay(); + statusText.widget = browser; + statusText.text = ""; //$NON-NLS-1$ + for (int i = 0; i < statusTextListeners.length; i++) { + statusTextListeners[i].changed(statusText); + } + return; } - /* DOMEventListener */ + NSString url = new NSURL(value.id).absoluteString(); + int length = (int)/*64*/url.length(); + String urlString; + if (length is 0) { + urlString = ""; //$NON-NLS-1$ + } else { + urlString = url.getString(); + } + if (urlString.equals(lastHoveredLinkURL)) return; - void handleEvent (int evtId) - { - DOMEvent evt = new DOMEvent(evtId); - NSString String = evt.type(); - char[] buffer = new char[String.length()]; - String.getCharacters_(buffer); - String type = new String(buffer); + lastHoveredLinkURL = urlString; + StatusTextEvent statusText = new StatusTextEvent(browser); + statusText.display = browser.getDisplay(); + statusText.widget = browser; + statusText.text = urlString; + for (int i = 0; i < statusTextListeners.length; i++) { + statusTextListeners[i].changed(statusText); + } +} - if (DOMEVENT_KEYDOWN.opEquals(type) || DOMEVENT_KEYUP.opEquals(type)) - { - DOMKeyboardEvent event = new DOMKeyboardEvent(evtId); +void webView_printFrameView (int /*long*/ sender, int /*long*/ frameViewID) { + WebFrameView view = new WebFrameView(frameViewID); + bool viewPrint = view.documentViewShouldHandlePrint(); + if (viewPrint) { + view.printDocumentView(); + return; + } + NSPrintInfo info = NSPrintInfo.sharedPrintInfo(); + NSPrintOperation operation = view.printOperationWithPrintInfo(info); + if (operation !is null) operation.runOperation(); +} + +/* PolicyDelegate */ - bool ctrl = event.ctrlKey(); - bool shift = event.shiftKey(); - bool alt = event.altKey(); - bool meta = event.metaKey(); - int keyCode = event.keyCode(); - int charCode = event.charCode(); +void webView_decidePolicyForMIMEType_request_frame_decisionListener(int /*long*/ sender, int /*long*/ type, int /*long*/ request, int /*long*/ frame, int /*long*/ listenerID) { + bool canShow = WebView.canShowMIMEType(new NSString(type)); + WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID); + if (canShow) { + listener.use(); + } else { + listener.download(); + } +} + +void webView_decidePolicyForNavigationAction_request_frame_decisionListener(int /*long*/ sender, int /*long*/ actionInformation, int /*long*/ request, int /*long*/ frame, int /*long*/ listenerID) { + NSURL url = new NSURLRequest(request).URL(); + WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID); + if (url is null) { + /* indicates that a URL with an invalid format was specified */ + listener.ignore(); + return; + } + NSString s = url.absoluteString(); + String url2 = s.getString(); + /* + * If the URI indicates that the page is being rendered from memory + * (via setText()) then set it to about:blank to be consistent with IE. + */ + if (url2.equals (URI_FROMMEMORY)) url2 = ABOUT_BLANK; - Event keyEvent = new Event(); - keyEvent.widget = browser; - if (DOMEVENT_KEYDOWN.opEquals(type)) - { - keyEvent.type = DWT.KeyDown; - } - else - { - keyEvent.type = DWT.KeyUp; - } - keyEvent.keyCode = translateKey(keyCode); - keyEvent.character = cast(char) charCode; - keyEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); - browser.notifyListeners(keyEvent.type, keyEvent); - if (!keyEvent.doit) - { - event.preventDefault(); - } - return; + LocationEvent newEvent = new LocationEvent(browser); + newEvent.display = browser.getDisplay(); + newEvent.widget = browser; + newEvent.location = url2; + newEvent.doit = true; + if (locationListeners !is null) { + changingLocation = true; + for (int i = 0; i < locationListeners.length; i++) { + locationListeners[i].changing(newEvent); } + changingLocation = false; + } + if (newEvent.doit) { + listener.use(); + } else { + listener.ignore(); + } + if (html !is null && !browser.isDisposed()) { + String html = this.html; + this.html = null; + _setText(html); + } +} + +void webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener(int /*long*/ sender, int /*long*/ actionInformation, int /*long*/ request, int /*long*/ frameName, int /*long*/ listenerID) { + WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID); + listener.use(); +} - if (DOMEVENT_MOUSEWHEEL.opEquals(type)) - { - DOMWheelEvent event = new DOMWheelEvent(evtId); - int clientX = event.clientX(); - int clientY = event.clientY(); - int delta = event.wheelDelta(); - bool ctrl = event.ctrlKey(); - bool shift = event.shiftKey(); - bool alt = event.altKey(); - bool meta = event.metaKey(); - Event mouseEvent = new Event(); - mouseEvent.type = DWT.MouseWheel; - mouseEvent.widget = browser; - mouseEvent.x = clientX; - mouseEvent.y = clientY; - mouseEvent.count = delta / 120; - mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); - browser.notifyListeners(mouseEvent.type, mouseEvent); - return; - } +void webView_unableToImplementPolicyWithError_frame(int /*long*/ sender, int /*long*/ error, int /*long*/ frame) { +} + +/* WebDownload */ - /* mouse event */ - - DOMMouseEvent event = new DOMMouseEvent(evtId); +void download_decideDestinationWithSuggestedFilename(int /*long*/ downloadId, int /*long*/ filename) { + NSString string = new NSString(filename); + String name = string.getString(); + FileDialog dialog = new FileDialog(browser.getShell(), DWT.SAVE); + dialog.setText(DWT.getMessage ("DWT_FileDownload")); //$NON-NLS-1$ + dialog.setFileName(name); + String path = dialog.open(); + NSURLDownload download = new NSURLDownload(downloadId); + if (path is null) { + /* cancel pressed */ + download.cancel(); + return; + } + download.setDestination(NSString.stringWith(path), true); +} - int clientX = event.clientX(); - int clientY = event.clientY(); - int detail = event.detail(); - int button = event.button(); +/* DOMEventListener */ + +void handleEvent(int /*long*/ evtId) { + NSString string = new NSString(OS.objc_msgSend(evtId, OS.sel_type)); + String type = string.getString(); + + if (DOMEVENT_KEYDOWN.equals(type) || DOMEVENT_KEYUP.equals(type)) { + DOMKeyboardEvent event = new DOMKeyboardEvent(evtId); + bool ctrl = event.ctrlKey(); bool shift = event.shiftKey(); bool alt = event.altKey(); bool meta = event.metaKey(); + int keyCode = event.keyCode(); + int charCode = event.charCode(); - Event mouseEvent = new Event(); - mouseEvent.widget = browser; - mouseEvent.x = clientX; - mouseEvent.y = clientY; - mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); - if (DOMEVENT_MOUSEDOWN.opEquals(type)) - { - mouseEvent.type = DWT.MouseDown; - mouseEvent.button = button + 1; - mouseEvent.count = detail; + Event keyEvent = new Event(); + keyEvent.widget = browser; + if (DOMEVENT_KEYDOWN.equals(type)) { + keyEvent.type = DWT.KeyDown; + } else { + keyEvent.type = DWT.KeyUp; + } + keyEvent.keyCode = translateKey(keyCode); + keyEvent.character = (char)charCode; + keyEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); + browser.notifyListeners(keyEvent.type, keyEvent); + if (!keyEvent.doit) { + event.preventDefault(); } - else if (DOMEVENT_MOUSEUP.opEquals(type)) - { - mouseEvent.type = DWT.MouseUp; - mouseEvent.button = button + 1; - mouseEvent.count = detail; - switch (mouseEvent.button) - { - case 1: - mouseEvent.stateMask |= DWT.BUTTON1; - break; - case 2: - mouseEvent.stateMask |= DWT.BUTTON2; - break; - case 3: - mouseEvent.stateMask |= DWT.BUTTON3; - break; - case 4: - mouseEvent.stateMask |= DWT.BUTTON4; - break; - case 5: - mouseEvent.stateMask |= DWT.BUTTON5; - break; - } + return; + } + + if (DOMEVENT_MOUSEWHEEL.equals(type)) { + DOMWheelEvent event = new DOMWheelEvent(evtId); + int clientX = event.clientX(); + int clientY = event.clientY(); + int delta = event.wheelDelta(); + bool ctrl = event.ctrlKey(); + bool shift = event.shiftKey(); + bool alt = event.altKey(); + bool meta = event.metaKey(); + Event mouseEvent = new Event(); + mouseEvent.type = DWT.MouseWheel; + mouseEvent.widget = browser; + mouseEvent.x = clientX; mouseEvent.y = clientY; + mouseEvent.count = delta / 120; + mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); + browser.notifyListeners (mouseEvent.type, mouseEvent); + return; + } + + /* mouse event */ + + DOMMouseEvent event = new DOMMouseEvent(evtId); + + int clientX = event.clientX(); + int clientY = event.clientY(); + int detail = event.detail(); + int button = event.button(); + bool ctrl = event.ctrlKey(); + bool shift = event.shiftKey(); + bool alt = event.altKey(); + bool meta = event.metaKey(); + + Event mouseEvent = new Event (); + mouseEvent.widget = browser; + mouseEvent.x = clientX; mouseEvent.y = clientY; + mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); + if (DOMEVENT_MOUSEDOWN.equals (type)) { + mouseEvent.type = DWT.MouseDown; + mouseEvent.button = button + 1; + mouseEvent.count = detail; + } else if (DOMEVENT_MOUSEUP.equals (type)) { + mouseEvent.type = DWT.MouseUp; + mouseEvent.button = button + 1; + mouseEvent.count = detail; + switch (mouseEvent.button) { + case 1: mouseEvent.stateMask |= DWT.BUTTON1; break; + case 2: mouseEvent.stateMask |= DWT.BUTTON2; break; + case 3: mouseEvent.stateMask |= DWT.BUTTON3; break; + case 4: mouseEvent.stateMask |= DWT.BUTTON4; break; + case 5: mouseEvent.stateMask |= DWT.BUTTON5; break; } - else if (DOMEVENT_MOUSEMOVE.opEquals(type)) - { - /* - * Bug in Safari. Spurious and redundant mousemove events are received in - * various contexts, including following every MouseUp. The workaround is - * to not fire MouseMove events whose x and y values match the last MouseMove - */ - if (mouseEvent.x is lastMouseMoveX && mouseEvent.y is lastMouseMoveY) - return; - mouseEvent.type = DWT.MouseMove; - lastMouseMoveX = mouseEvent.x; - lastMouseMoveY = mouseEvent.y; - } + } else if (DOMEVENT_MOUSEMOVE.equals (type)) { + /* + * Bug in Safari. Spurious and redundant mousemove events are received in + * various contexts, including following every MouseUp. The workaround is + * to not fire MouseMove events whose x and y values match the last MouseMove + */ + if (mouseEvent.x is lastMouseMoveX && mouseEvent.y is lastMouseMoveY) return; + mouseEvent.type = DWT.MouseMove; + lastMouseMoveX = mouseEvent.x; lastMouseMoveY = mouseEvent.y; + } - browser.notifyListeners(mouseEvent.type, mouseEvent); - if (detail is 2 && DOMEVENT_MOUSEDOWN.opEquals(type)) - { - mouseEvent = new Event(); - mouseEvent.widget = browser; - mouseEvent.x = clientX; - mouseEvent.y = clientY; - mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); - mouseEvent.type = DWT.MouseDoubleClick; - mouseEvent.button = button + 1; - mouseEvent.count = detail; - browser.notifyListeners(mouseEvent.type, mouseEvent); - } + browser.notifyListeners (mouseEvent.type, mouseEvent); + if (detail is 2 && DOMEVENT_MOUSEDOWN.equals (type)) { + mouseEvent = new Event (); + mouseEvent.widget = browser; + mouseEvent.x = clientX; mouseEvent.y = clientY; + mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); + mouseEvent.type = DWT.MouseDoubleClick; + mouseEvent.button = button + 1; + mouseEvent.count = detail; + browser.notifyListeners (mouseEvent.type, mouseEvent); } } +}