comparison 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
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
8 * Contributors: 8 * Contributors:
9 * IBM Corporation - initial API and implementation 9 * IBM Corporation - initial API and implementation
10 *
11 * Port to the D programming language:
12 * Jacob Carlborg <jacob.carlborg@gmail.com>
13 *******************************************************************************/ 10 *******************************************************************************/
14 module dwt.browser.Safari; 11 module dwt.browser.Safari;
15 12
13 import dwt.dwthelper.utils;
14
16 import dwt.DWT; 15 import dwt.DWT;
17 import dwt.browser.LocationEvent;
18 import dwt.browser.ProgressEvent;
19 import dwt.browser.ProgressListener;
20 import dwt.browser.StatusTextEvent;
21 import dwt.browser.TitleEvent;
22 import dwt.browser.TitleListener;
23 import dwt.browser.WebBrowser;
24 import dwt.dwthelper.utils;
25 import dwt.graphics.Point; 16 import dwt.graphics.Point;
26 import dwt.graphics.Rectangle; 17 import dwt.graphics.Rectangle;
18 import dwt.internal.C;
27 import dwt.internal.Callback; 19 import dwt.internal.Callback;
20 import dwt.internal.Compatibility;
28 import dwt.internal.cocoa.DOMDocument; 21 import dwt.internal.cocoa.DOMDocument;
29 import dwt.internal.cocoa.DOMEvent;
30 import dwt.internal.cocoa.DOMKeyboardEvent; 22 import dwt.internal.cocoa.DOMKeyboardEvent;
31 import dwt.internal.cocoa.DOMMouseEvent; 23 import dwt.internal.cocoa.DOMMouseEvent;
32 import dwt.internal.cocoa.DOMWheelEvent; 24 import dwt.internal.cocoa.DOMWheelEvent;
33 import dwt.internal.cocoa.NSArray; 25 import dwt.internal.cocoa.NSArray;
34 import dwt.internal.cocoa.NSDictionary; 26 import dwt.internal.cocoa.NSDictionary;
27 import dwt.internal.cocoa.NSError;
35 import dwt.internal.cocoa.NSHTTPCookie; 28 import dwt.internal.cocoa.NSHTTPCookie;
36 import dwt.internal.cocoa.NSHTTPCookieStorage; 29 import dwt.internal.cocoa.NSHTTPCookieStorage;
37 import dwt.internal.cocoa.NSNotificationCenter; 30 import dwt.internal.cocoa.NSNotificationCenter;
38 import dwt.internal.cocoa.NSNumber; 31 import dwt.internal.cocoa.NSNumber;
39 import dwt.internal.cocoa.NSPrintInfo; 32 import dwt.internal.cocoa.NSPrintInfo;
40 import dwt.internal.cocoa.NSPrintOperation; 33 import dwt.internal.cocoa.NSPrintOperation;
34 import dwt.internal.cocoa.NSRect;
41 import dwt.internal.cocoa.NSString; 35 import dwt.internal.cocoa.NSString;
42 import dwt.internal.cocoa.NSURL; 36 import dwt.internal.cocoa.NSURL;
43 import dwt.internal.cocoa.NSURLDownload; 37 import dwt.internal.cocoa.NSURLDownload;
44 import dwt.internal.cocoa.NSURLRequest; 38 import dwt.internal.cocoa.NSURLRequest;
45 import dwt.internal.cocoa.OS; 39 import dwt.internal.cocoa.OS;
51 import dwt.internal.cocoa.WebOpenPanelResultListener; 45 import dwt.internal.cocoa.WebOpenPanelResultListener;
52 import dwt.internal.cocoa.WebPolicyDecisionListener; 46 import dwt.internal.cocoa.WebPolicyDecisionListener;
53 import dwt.internal.cocoa.WebPreferences; 47 import dwt.internal.cocoa.WebPreferences;
54 import dwt.internal.cocoa.WebView; 48 import dwt.internal.cocoa.WebView;
55 import dwt.internal.cocoa.id; 49 import dwt.internal.cocoa.id;
56
57 import dwt.widgets.Composite; 50 import dwt.widgets.Composite;
58 import dwt.widgets.Display; 51 import dwt.widgets.Display;
59 import dwt.widgets.Event; 52 import dwt.widgets.Event;
60 import dwt.widgets.FileDialog; 53 import dwt.widgets.FileDialog;
61 import dwt.widgets.Listener; 54 import dwt.widgets.Listener;
62 import dwt.widgets.Menu; 55 import dwt.widgets.Menu;
63 import dwt.widgets.MessageBox; 56 import dwt.widgets.MessageBox;
64 import dwt.widgets.Shell; 57 import dwt.widgets.Shell;
65 58 import dwt.widgets.Widget;
66 import Math = tango.math.Math; 59
67 60 class Safari extends WebBrowser {
68 import dwt.dwthelper.Runnable;
69
70 class Safari : WebBrowser
71 {
72 WebView webView; 61 WebView webView;
73 DWTWebViewDelegate delegatee; 62 SWTWebViewDelegate delegate;
74 int jniRef;
75 bool changingLocation; 63 bool changingLocation;
76 String lastHoveredLinkURL; 64 String lastHoveredLinkURL;
77 String html; 65 String html;
78 int identifier; 66 int /*long*/ identifier;
79 int resourceCount; 67 int resourceCount;
80 String url = ""; 68 String url = ""; //$NON-NLS-1$
81 Point location; 69 Point location;
82 Point size; 70 Point size;
83 bool statusBar = true, toolBar = true, ignoreDispose; 71 bool statusBar = true, toolBar = true, ignoreDispose;
84 int lastMouseMoveX, lastMouseMoveY; 72 int lastMouseMoveX, lastMouseMoveY;
85 //TEMPORARY CODE 73 //TEMPORARY CODE
86 // bool doit; 74 // bool doit;
87 75
88 static bool Initialized; 76 static bool Initialized;
89 static Callback Callback2, Callback3, Callback4, Callback5, Callback6, Callback7; 77 // the following Callbacks are never freed
90 78 static Callback Callback3, Callback4, Callback5, Callback6, Callback7;
91 static const int MIN_SIZE = 16; 79
92 static const int MAX_PROGRESS = 100; 80 static final int MIN_SIZE = 16;
93 static const String WebElementLinkURLKey = "WebElementLinkURL"; //$NON-NLS-1$ 81 static final int MAX_PROGRESS = 100;
94 static const String AGENT_STRING = "Safari/unknown"; //$NON-NLS-1$ 82 static final String WebElementLinkURLKey = "WebElementLinkURL"; //$NON-NLS-1$
95 static const String URI_FROMMEMORY = "file:///"; //$NON-NLS-1$ 83 static final String AGENT_STRING = "Safari/unknown"; //$NON-NLS-1$
96 static const String PROTOCOL_FILE = "file:"; //$NON-NLS-1$ 84 static final String URI_FROMMEMORY = "file:///"; //$NON-NLS-1$
97 static const String PROTOCOL_HTTP = "http:"; //$NON-NLS-1$ 85 static final String PROTOCOL_FILE = "file://"; //$NON-NLS-1$
98 static const String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$ 86 static final String PROTOCOL_HTTP = "http://"; //$NON-NLS-1$
99 static const String SAFARI_EVENTS_FIX_KEY = "dwt.internal.safariEventsFix"; //$NON-NLS-1$ 87 static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
100 88 static final String ADD_WIDGET_KEY = "dwt.internal.addWidget"; //$NON-NLS-1$
101 /* event Strings */ 89 static final String SAFARI_EVENTS_FIX_KEY = "dwt.internal.safariEventsFix"; //$NON-NLS-1$
102 static const String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$ 90 static final String DWT_OBJECT = "DWT_OBJECT"; //$NON-NLS-1$
103 static const String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$ 91
104 static const String DOMEVENT_MOUSEDOWN = "mousedown"; //$NON-NLS-1$ 92 /* event strings */
105 static const String DOMEVENT_MOUSEUP = "mouseup"; //$NON-NLS-1$ 93 static final String DOMEVENT_KEYUP = "keyup"; //$NON-NLS-1$
106 static const String DOMEVENT_MOUSEMOVE = "mousemove"; //$NON-NLS-1$ 94 static final String DOMEVENT_KEYDOWN = "keydown"; //$NON-NLS-1$
107 static const String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$ 95 static final String DOMEVENT_MOUSEDOWN = "mousedown"; //$NON-NLS-1$
108 96 static final String DOMEVENT_MOUSEUP = "mouseup"; //$NON-NLS-1$
109 static this () 97 static final String DOMEVENT_MOUSEMOVE = "mousemove"; //$NON-NLS-1$
110 { 98 static final String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$
111 NativeClearSessions = new class Runnable 99
112 { 100 static {
113 public void run () 101 NativeClearSessions = new Runnable() {
114 { 102 public void run() {
115 NSHTTPCookieStorage storage = NSHTTPCookieStorage.sharedHTTPCookieStorage(); 103 NSHTTPCookieStorage storage = NSHTTPCookieStorage.sharedHTTPCookieStorage();
116 NSArray cookies = storage.cookies(); 104 NSArray cookies = storage.cookies();
117 int count = cookies.count(); 105 int /*long*/ count = cookies.count();
118 106 for (int i = 0; i < count; i++) {
119 for (int i = 0; i < count; i++)
120 {
121 NSHTTPCookie cookie = new NSHTTPCookie(cookies.objectAtIndex(i)); 107 NSHTTPCookie cookie = new NSHTTPCookie(cookies.objectAtIndex(i));
122 if (cookie.isSessionOnly()) 108 if (cookie.isSessionOnly()) {
123 {
124 storage.deleteCookie(cookie); 109 storage.deleteCookie(cookie);
125 } 110 }
126 } 111 }
127 } 112 }
128 }; 113 };
129 } 114 }
130 115
131 public void create (Composite parent, int style) 116 public void create (Composite parent, int style) {
132 { 117 String className = "SWTWebViewDelegate"; //$NON-NLS-1$
133 118 if (OS.objc_lookUpClass(className) is 0) {
134 String className = "DWTWebViewDelegate"; 119 Class safariClass = this.getClass();
135 if (OS.objc_lookUpClass(className) == 0) 120 Callback3 = new Callback(safariClass, "browserProc", 3); //$NON-NLS-1$
136 { 121 int /*long*/ proc3 = Callback3.getAddress();
137 ClassInfo safaryClass = this.classinfo; 122 if (proc3 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
138 Callback2 = new Callback(safaryClass, "browserProc", 2); 123 Callback4 = new Callback(safariClass, "browserProc", 4); //$NON-NLS-1$
139 int proc2 = Callback2.getAddress(); 124 int /*long*/ proc4 = Callback4.getAddress();
140 if (proc2 is 0) 125 if (proc4 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
141 DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); 126 Callback5 = new Callback(safariClass, "browserProc", 5); //$NON-NLS-1$
142 Callback3 = new Callback(safaryClass, "browserProc", 3); 127 int /*long*/ proc5 = Callback5.getAddress();
143 int proc3 = Callback3.getAddress(); 128 if (proc5 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
144 if (proc3 is 0) 129 Callback6 = new Callback(safariClass, "browserProc", 6); //$NON-NLS-1$
145 DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); 130 int /*long*/ proc6 = Callback6.getAddress();
146 Callback4 = new Callback(safaryClass, "browserProc", 4); 131 if (proc6 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
147 int proc4 = Callback4.getAddress(); 132 Callback7 = new Callback(safariClass, "browserProc", 7); //$NON-NLS-1$
148 if (proc4 is 0) 133 int /*long*/ proc7 = Callback7.getAddress();
149 DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); 134 if (proc7 is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
150 Callback5 = new Callback(safaryClass, "browserProc", 5); 135 int /*long*/ setFrameProc = OS.webView_setFrame_CALLBACK(proc4);
151 int proc5 = Callback5.getAddress(); 136 if (setFrameProc is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
152 if (proc5 is 0) 137
153 DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); 138 String types = "*"; //$NON-NLS-1$
154 Callback6 = new Callback(safaryClass, "browserProc", 6); 139 int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF is 4 ? 2 : 3;
155 int proc6 = Callback6.getAddress(); 140
156 if (proc6 is 0) 141 int /*long*/ cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
157 DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); 142 OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
158 Callback7 = new Callback(safaryClass, "browserProc", 7); 143 OS.class_addMethod(cls, OS.sel_webView_didChangeLocationWithinPageForFrame_, proc4, "@:@@"); //$NON-NLS-1$
159 int proc7 = Callback7.getAddress(); 144 OS.class_addMethod(cls, OS.sel_webView_didFailProvisionalLoadWithError_forFrame_, proc5, "@:@@@"); //$NON-NLS-1$
160 if (proc7 is 0) 145 OS.class_addMethod(cls, OS.sel_webView_didFinishLoadForFrame_, proc4, "@:@@"); //$NON-NLS-1$
161 DWT.error(DWT.ERROR_NO_MORE_CALLBACKS); 146 OS.class_addMethod(cls, OS.sel_webView_didReceiveTitle_forFrame_, proc5, "@:@@@"); //$NON-NLS-1$
162 147 OS.class_addMethod(cls, OS.sel_webView_didStartProvisionalLoadForFrame_, proc4, "@:@@"); //$NON-NLS-1$
163 int cls = OS.objc_allocateClassPair(OS.class_WebView, className, 0); 148 OS.class_addMethod(cls, OS.sel_webView_didCommitLoadForFrame_, proc4, "@:@@"); //$NON-NLS-1$
164 OS.class_addIvar(cls, "tag", OS.PTR_SIZEOF, cast(byte) (Math.log(OS.PTR_SIZEOF) / Math.log(2)), "i"); 149 OS.class_addMethod(cls, OS.sel_webView_resource_didFinishLoadingFromDataSource_, proc5, "@:@@@"); //$NON-NLS-1$
165 OS.class_addMethod(cls, OS.sel_tag, proc2, "@:"); 150 OS.class_addMethod(cls, OS.sel_webView_resource_didFailLoadingWithError_fromDataSource_, proc6, "@:@@@@"); //$NON-NLS-1$
166 OS.class_addMethod(cls, OS.sel_setTag_1, proc3, "@:i"); 151 OS.class_addMethod(cls, OS.sel_webView_identifierForInitialRequest_fromDataSource_, proc5, "@:@@@"); //$NON-NLS-1$
167 OS.class_addMethod(cls, OS.sel_webView_1didChangeLocationWithinPageForFrame_1, proc4, "@:@@"); 152 OS.class_addMethod(cls, OS.sel_webView_resource_willSendRequest_redirectResponse_fromDataSource_, proc7, "@:@@@@@"); //$NON-NLS-1$
168 OS.class_addMethod(cls, OS.sel_webView_1didFailProvisionalLoadWithError_1forFrame_1, proc5, "@:@@@"); 153 OS.class_addMethod(cls, OS.sel_handleNotification_, proc3, "@:@"); //$NON-NLS-1$
169 OS.class_addMethod(cls, OS.sel_webView_1didFinishLoadForFrame_1, proc4, "@:@@"); 154 OS.class_addMethod(cls, OS.sel_webView_createWebViewWithRequest_, proc4, "@:@@"); //$NON-NLS-1$
170 OS.class_addMethod(cls, OS.sel_webView_1didReceiveTitle_1forFrame_1, proc5, "@:@@@"); 155 OS.class_addMethod(cls, OS.sel_webViewShow_, proc3, "@:@"); //$NON-NLS-1$
171 OS.class_addMethod(cls, OS.sel_webView_1didStartProvisionalLoadForFrame_1, proc4, "@:@@"); 156 OS.class_addMethod(cls, OS.sel_webViewClose_, proc3, "@:@"); //$NON-NLS-1$
172 OS.class_addMethod(cls, OS.sel_webView_1didCommitLoadForFrame_1, proc4, "@:@@"); 157 OS.class_addMethod(cls, OS.sel_webView_contextMenuItemsForElement_defaultMenuItems_, proc5, "@:@@@"); //$NON-NLS-1$
173 OS.class_addMethod(cls, OS.sel_webView_1resource_1didFinishLoadingFromDataSource_1, proc5, "@:@@@"); 158 OS.class_addMethod(cls, OS.sel_webView_setStatusBarVisible_, proc4, "@:@B"); //$NON-NLS-1$
174 OS.class_addMethod(cls, OS.sel_webView_1resource_1didFailLoadingWithError_1fromDataSource_1, proc6, "@:@@@@"); 159 OS.class_addMethod(cls, OS.sel_webView_setResizable_, proc4, "@:@B"); //$NON-NLS-1$
175 OS.class_addMethod(cls, OS.sel_webView_1identifierForInitialRequest_1fromDataSource_1, proc5, "@:@@@"); 160 OS.class_addMethod(cls, OS.sel_webView_setToolbarsVisible_, proc4, "@:@B"); //$NON-NLS-1$
176 OS.class_addMethod(cls, OS.sel_webView_1resource_1willSendRequest_1redirectResponse_1fromDataSource_1, proc7, "@:@@@@@"); 161 OS.class_addMethod(cls, OS.sel_webView_setStatusText_, proc4, "@:@@"); //$NON-NLS-1$
177 OS.class_addMethod(cls, OS.sel_handleNotification_1, proc3, "@:@"); 162 OS.class_addMethod(cls, OS.sel_webViewFocus_, proc3, "@:@"); //$NON-NLS-1$
178 OS.class_addMethod(cls, OS.sel_webView_1createWebViewWithRequest_1, proc4, "@:@@"); 163 OS.class_addMethod(cls, OS.sel_webViewUnfocus_, proc3, "@:@"); //$NON-NLS-1$
179 OS.class_addMethod(cls, OS.sel_webViewShow_1, proc3, "@:@"); 164 OS.class_addMethod(cls, OS.sel_webView_runJavaScriptAlertPanelWithMessage_, proc4, "@:@@"); //$NON-NLS-1$
180 OS.class_addMethod(cls, OS.sel_webView_1setFrame_1, proc4, "@:@@"); 165 OS.class_addMethod(cls, OS.sel_webView_runJavaScriptConfirmPanelWithMessage_, proc4, "@:@@"); //$NON-NLS-1$
181 OS.class_addMethod(cls, OS.sel_webViewClose_1, proc3, "@:@"); 166 OS.class_addMethod(cls, OS.sel_webView_runOpenPanelForFileButtonWithResultListener_, proc4, "@:@@"); //$NON-NLS-1$
182 OS.class_addMethod(cls, OS.sel_webView_1contextMenuItemsForElement_1defaultMenuItems_1, proc5, "@:@@@"); 167 OS.class_addMethod(cls, OS.sel_webView_mouseDidMoveOverElement_modifierFlags_, proc5, "@:@@I"); //$NON-NLS-1$
183 OS.class_addMethod(cls, OS.sel_webView_1setStatusBarVisible_1, proc4, "@:@B"); 168 OS.class_addMethod(cls, OS.sel_webView_printFrameView_, proc4, "@:@@"); //$NON-NLS-1$
184 OS.class_addMethod(cls, OS.sel_webView_1setResizable_1, proc4, "@:@B"); 169 OS.class_addMethod(cls, OS.sel_webView_decidePolicyForMIMEType_request_frame_decisionListener_, proc7, "@:@@@@@"); //$NON-NLS-1$
185 OS.class_addMethod(cls, OS.sel_webView_1setToolbarsVisible_1, proc4, "@:@B"); 170 OS.class_addMethod(cls, OS.sel_webView_decidePolicyForNavigationAction_request_frame_decisionListener_, proc7, "@:@@@@@"); //$NON-NLS-1$
186 OS.class_addMethod(cls, OS.sel_webView_1setStatusText_1, proc4, "@:@@"); 171 OS.class_addMethod(cls, OS.sel_webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener_, proc7, "@:@@@@@"); //$NON-NLS-1$
187 OS.class_addMethod(cls, OS.sel_webViewFocus_1, proc3, "@:@"); 172 OS.class_addMethod(cls, OS.sel_webView_unableToImplementPolicyWithError_frame_, proc5, "@:@@@"); //$NON-NLS-1$
188 OS.class_addMethod(cls, OS.sel_webViewUnfocus_1, proc3, "@:@"); 173 OS.class_addMethod(cls, OS.sel_download_decideDestinationWithSuggestedFilename_, proc4, "@:@@"); //$NON-NLS-1$
189 OS.class_addMethod(cls, OS.sel_webView_1runJavaScriptAlertPanelWithMessage_1, proc4, "@:@@"); 174 OS.class_addMethod(cls, OS.sel_handleEvent_, proc3, "@:@"); //$NON-NLS-1$
190 OS.class_addMethod(cls, OS.sel_webView_1runJavaScriptConfirmPanelWithMessage_1, proc4, "@:@@"); 175 OS.class_addMethod(cls, OS.sel_webView_setFrame_, setFrameProc, "@:@{NSRect}"); //$NON-NLS-1$
191 OS.class_addMethod(cls, OS.sel_webView_1runOpenPanelForFileButtonWithResultListener_1, proc4, "@:@@"); 176 OS.objc_registerClassPair(cls);
192 OS.class_addMethod(cls, OS.sel_webView_1mouseDidMoveOverElement_1modifierFlags_1, proc5, "@:@@I"); 177 }
193 OS.class_addMethod(cls, OS.sel_webView_1printFrameView_1, proc4, "@:@@"); 178
194 OS.class_addMethod(cls, OS.sel_webView_1decidePolicyForMIMEType_1request_1frame_1decisionListener_1, proc7, "@:@@@@@"); 179 /*
195 OS.class_addMethod(cls, OS.sel_webView_1decidePolicyForNavigationAction_1request_1frame_1decisionListener_1, proc7, "@:@@@@@"); 180 * Override the default event mechanism to not send key events so
196 OS.class_addMethod(cls, OS.sel_webView_1decidePolicyForNewWindowAction_1request_1newFrameName_1decisionListener_1, proc7, "@:@@@@@"); 181 * that the browser can send them by listening to the DOM instead.
197 OS.class_addMethod(cls, OS.sel_webView_1unableToImplementPolicyWithError_1frame_1, proc5, "@:@@@"); 182 */
198 OS.class_addMethod(cls, OS.sel_download_1decideDestinationWithSuggestedFilename_1, proc4, "@:@@"); 183 browser.setData(SAFARI_EVENTS_FIX_KEY);
199 OS.class_addMethod(cls, OS.sel_handleEvent_1, proc3, "@:@"); 184
200 OS.objc_registerClassPair(cls); 185 WebView webView = (WebView)new WebView().alloc();
201 } 186 if (webView is null) DWT.error(DWT.ERROR_NO_HANDLES);
202 187 webView.initWithFrame(browser.view.frame(), null, null);
203 /* 188 webView.setAutoresizingMask(OS.NSViewWidthSizable | OS.NSViewHeightSizable);
204 * Override the default event mechanism to not send key events so 189 final SWTWebViewDelegate delegate = (SWTWebViewDelegate)new SWTWebViewDelegate().alloc().init();
205 * that the browser can send them by listening to the DOM instead. 190 Display display = browser.getDisplay();
206 */ 191 display.setData(ADD_WIDGET_KEY, new Object[] {delegate, browser});
207 browser.setData(SAFARI_EVENTS_FIX_KEY); 192 this.delegate = delegate;
208 193 this.webView = webView;
209 WebView webView = cast(WebView) (new WebView()).alloc(); 194 browser.view.addSubview(webView);
210 if (webView is null) 195
211 DWT.error(DWT.ERROR_NO_HANDLES); 196 final NSNotificationCenter notificationCenter = NSNotificationCenter.defaultCenter();
212 webView.initWithFrame(browser.view.frame(), null, null); 197
213 webView.setAutoresizingMask(OS.NSViewWidthSizable | OS.NSViewHeightSizable); 198 Listener listener = new Listener() {
214 jniRef = OS.NewGlobalRef(this); 199 public void handleEvent(Event e) {
215 if (jniRef is 0) 200 switch (e.type) {
216 DWT.error(DWT.ERROR_NO_HANDLES); 201 case DWT.FocusIn:
217 const DWTWebViewDelegate delegatee = cast(DWTWebViewDelegate) (new DWTWebViewDelegate()).alloc().init(); 202 Safari.this.webView.window().makeFirstResponder(Safari.this.webView);
218 delegatee.setTag(jniRef); 203 break;
219 this.delegatee = delegatee; 204 case DWT.Dispose: {
220 this.webView = webView; 205 /* make this handler run after other dispose listeners */
221 browser.view.addSubview_(webView); 206 if (ignoreDispose) {
222 207 ignoreDispose = false;
223 const NSNotificationCenter notificationCenter = NSNotificationCenter.defaultCenter();
224
225 Listener listener = new class (notificationCenter) Listener
226 {
227 NSNotificationCenter notificationCenter;
228
229 this (NSNotificationCenter notificationCenter)
230 {
231 this.notificationCenter = notificationCenter;
232 }
233
234 public void handleEvent (Event e)
235 {
236 switch (e.type)
237 {
238 case DWT.Dispose:
239 {
240 /* make this handler run after other dispose listeners */
241 if (ignoreDispose)
242 {
243 ignoreDispose = false;
244 break;
245 }
246 ignoreDispose = true;
247 browser.notifyListeners(e.type, e);
248 e.type = DWT.NONE;
249
250 webView.setFrameLoadDelegate(null);
251 webView.setResourceLoadDelegate(null);
252 webView.setUIDelegate(null);
253 webView.setPolicyDelegate(null);
254 webView.setDownloadDelegate(null);
255 notificationCenter.removeObserver(delegatee);
256
257 webView.release();
258 webView = null;
259 delegatee.release();
260 delegatee = null;
261 OS.DeleteGlobalRef(jniRef);
262 jniRef = 0;
263 html = null;
264 lastHoveredLinkURL = null;
265 break; 208 break;
266 } 209 }
210 ignoreDispose = true;
211 browser.notifyListeners (e.type, e);
212 e.type = DWT.NONE;
213
214 e.display.setData(ADD_WIDGET_KEY, new Object[] {delegate, null});
215
216 Safari.this.webView.setFrameLoadDelegate(null);
217 Safari.this.webView.setResourceLoadDelegate(null);
218 Safari.this.webView.setUIDelegate(null);
219 Safari.this.webView.setPolicyDelegate(null);
220 Safari.this.webView.setDownloadDelegate(null);
221 notificationCenter.removeObserver(delegate);
222
223 Safari.this.webView.release();
224 Safari.this.webView = null;
225 Safari.this.delegate.release();
226 Safari.this.delegate = null;
227 html = null;
228 lastHoveredLinkURL = null;
229 break;
267 } 230 }
268 } 231 }
269 }; 232 }
270 browser.addListener(DWT.Dispose, listener); 233 };
271 234 browser.addListener(DWT.Dispose, listener);
272 webView.setFrameLoadDelegate(delegatee); 235 /* Needed to be able to tab into the browser */
273 webView.setResourceLoadDelegate(delegatee); 236 browser.addListener(DWT.KeyDown, listener);
274 webView.setUIDelegate(delegatee); 237 browser.addListener(DWT.FocusIn, listener);
275 notificationCenter.addObserver(delegatee, OS.sel_handleNotification_1, null, webView); 238
276 webView.setPolicyDelegate(delegatee); 239 webView.setFrameLoadDelegate(delegate);
277 webView.setDownloadDelegate(delegatee); 240 webView.setResourceLoadDelegate(delegate);
278 webView.setApplicationNameForUserAgent(NSString.StringWith(AGENT_STRING)); 241 webView.setUIDelegate(delegate);
279 242 notificationCenter.addObserver(delegate, OS.sel_handleNotification_, null, webView);
280 if (!Initialized) 243 webView.setPolicyDelegate(delegate);
281 { 244 webView.setDownloadDelegate(delegate);
282 Initialized = true; 245 webView.setApplicationNameForUserAgent(NSString.stringWith(AGENT_STRING));
283 /* disable applets */ 246
284 WebPreferences.standardPreferences().setJavaEnabled(false); 247 if (!Initialized) {
285 } 248 Initialized = true;
286 } 249 /* disable applets */
287 250 WebPreferences.standardPreferences().setJavaEnabled(false);
288 public bool back () 251 }
289 { 252 }
290 html = null; 253
291 return webView.goBack(); 254 public bool back() {
292 } 255 html = null;
293 256 return webView.goBack();
294 static int browserProc (int delegatee, int sel) 257 }
295 { 258
296 if (sel is OS.sel_tag) 259 static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
297 { 260 Widget widget = Display.getCurrent().findWidget(id);
298 int[] tag = new int[1]; 261 if (widget is null) return 0;
299 OS.object_getInstanceVariable(delegatee, "tag", tag); 262 Safari safari = (Safari)((Browser)widget).webBrowser;
300 return tag[0]; 263 if (sel is OS.sel_handleNotification_) {
301 } 264 safari.handleNotification(arg0);
302 return 0; 265 } else if (sel is OS.sel_webViewShow_) {
303 } 266 safari.webViewShow(arg0);
304 267 } else if (sel is OS.sel_webViewClose_) {
305 static int browserProc (int id, int sel, int arg0) 268 safari.webViewClose(arg0);
306 { 269 } else if (sel is OS.sel_webViewFocus_) {
307 if (sel is OS.sel_setTag_1) 270 safari.webViewFocus(arg0);
308 { 271 } else if (sel is OS.sel_webViewUnfocus_) {
309 OS.object_setInstanceVariable(id, "tag", arg0); 272 safari.webViewUnfocus(arg0);
310 return 0; 273 } else if (sel is OS.sel_handleEvent_) {
311 } 274 safari.handleEvent(arg0);
312 int jniRef = OS.objc_msgSend(id, OS.sel_tag); 275 }
313 if (jniRef is 0 || jniRef is -1) 276 return 0;
314 return 0; 277 }
315 Safari widget = cast(Safari) OS.JNIGetObject(jniRef); 278
316 if (widget is null) 279 static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1) {
317 return 0; 280 Widget widget = Display.getCurrent().findWidget(id);
318 if (sel is OS.sel_handleNotification_1) 281 if (widget is null) return 0;
319 { 282 Safari safari = (Safari)((Browser)widget).webBrowser;
320 widget.handleNotification(arg0); 283 if (sel is OS.sel_webView_didChangeLocationWithinPageForFrame_) {
321 } 284 safari.webView_didChangeLocationWithinPageForFrame(arg0, arg1);
322 else if (sel is OS.sel_webViewShow_1) 285 } else if (sel is OS.sel_webView_didFinishLoadForFrame_) {
323 { 286 safari.webView_didFinishLoadForFrame(arg0, arg1);
324 widget.webViewShow(arg0); 287 } else if (sel is OS.sel_webView_didStartProvisionalLoadForFrame_) {
325 } 288 safari.webView_didStartProvisionalLoadForFrame(arg0, arg1);
326 else if (sel is OS.sel_webViewClose_1) 289 } else if (sel is OS.sel_webView_didCommitLoadForFrame_) {
327 { 290 safari.webView_didCommitLoadForFrame(arg0, arg1);
328 widget.webViewClose(arg0); 291 } else if (sel is OS.sel_webView_setFrame_) {
329 } 292 safari.webView_setFrame(arg0, arg1);
330 else if (sel is OS.sel_webViewFocus_1) 293 } else if (sel is OS.sel_webView_createWebViewWithRequest_) {
331 { 294 return safari.webView_createWebViewWithRequest(arg0, arg1);
332 widget.webViewFocus(arg0); 295 } else if (sel is OS.sel_webView_setStatusBarVisible_) {
333 } 296 safari.webView_setStatusBarVisible(arg0, arg1 !is 0);
334 else if (sel is OS.sel_webViewUnfocus_1) 297 } else if (sel is OS.sel_webView_setResizable_) {
335 { 298 safari.webView_setResizable(arg0, arg1 !is 0);
336 widget.webViewUnfocus(arg0); 299 } else if (sel is OS.sel_webView_setStatusText_) {
337 } 300 safari.webView_setStatusText(arg0, arg1);
338 else if (sel is OS.sel_handleEvent_1) 301 } else if (sel is OS.sel_webView_setToolbarsVisible_) {
339 { 302 safari.webView_setToolbarsVisible(arg0, arg1 !is 0);
340 widget.handleEvent(arg0); 303 } else if (sel is OS.sel_webView_runJavaScriptAlertPanelWithMessage_) {
341 } 304 safari.webView_runJavaScriptAlertPanelWithMessage(arg0, arg1);
342 return 0; 305 } else if (sel is OS.sel_webView_runJavaScriptConfirmPanelWithMessage_) {
343 } 306 return safari.webView_runJavaScriptConfirmPanelWithMessage(arg0, arg1);
344 307 } else if (sel is OS.sel_webView_runOpenPanelForFileButtonWithResultListener_) {
345 static int browserProc (int id, int sel, int arg0, int arg1) 308 safari.webView_runOpenPanelForFileButtonWithResultListener(arg0, arg1);
346 { 309 } else if (sel is OS.sel_download_decideDestinationWithSuggestedFilename_) {
347 if (sel is OS.sel_setTag_1) 310 safari.download_decideDestinationWithSuggestedFilename(arg0, arg1);
348 { 311 } else if (sel is OS.sel_webView_printFrameView_) {
349 OS.object_setInstanceVariable(id, "tag", arg0); 312 safari.webView_printFrameView(arg0, arg1);
350 return 0; 313 }
351 } 314 return 0;
352 int jniRef = OS.objc_msgSend(id, OS.sel_tag); 315 }
353 if (jniRef is 0 || jniRef is -1) 316
354 return 0; 317 static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2) {
355 Safari widget = cast(Safari) OS.JNIGetObject(jniRef); 318 Widget widget = Display.getCurrent().findWidget(id);
356 if (widget is null) 319 if (widget is null) return 0;
357 return 0; 320 Safari safari = (Safari)((Browser)widget).webBrowser;
358 if (sel is OS.sel_webView_1didChangeLocationWithinPageForFrame_1) 321 if (sel is OS.sel_webView_didFailProvisionalLoadWithError_forFrame_) {
359 { 322 safari.webView_didFailProvisionalLoadWithError_forFrame(arg0, arg1, arg2);
360 widget.webView_didChangeLocationWithinPageForFrame(arg0, arg1); 323 } else if (sel is OS.sel_webView_didReceiveTitle_forFrame_) {
361 } 324 safari.webView_didReceiveTitle_forFrame(arg0, arg1, arg2);
362 else if (sel is OS.sel_webView_1didFinishLoadForFrame_1) 325 } else if (sel is OS.sel_webView_resource_didFinishLoadingFromDataSource_) {
363 { 326 safari.webView_resource_didFinishLoadingFromDataSource(arg0, arg1, arg2);
364 widget.webView_didFinishLoadForFrame(arg0, arg1); 327 } else if (sel is OS.sel_webView_identifierForInitialRequest_fromDataSource_) {
365 } 328 return safari.webView_identifierForInitialRequest_fromDataSource(arg0, arg1, arg2);
366 else if (sel is OS.sel_webView_1didStartProvisionalLoadForFrame_1) 329 } else if (sel is OS.sel_webView_contextMenuItemsForElement_defaultMenuItems_) {
367 { 330 return safari.webView_contextMenuItemsForElement_defaultMenuItems(arg0, arg1, arg2);
368 widget.webView_didStartProvisionalLoadForFrame(arg0, arg1); 331 } else if (sel is OS.sel_webView_mouseDidMoveOverElement_modifierFlags_) {
369 } 332 safari.webView_mouseDidMoveOverElement_modifierFlags(arg0, arg1, arg2);
370 else if (sel is OS.sel_webView_1didCommitLoadForFrame_1) 333 } else if (sel is OS.sel_webView_unableToImplementPolicyWithError_frame_) {
371 { 334 safari.webView_unableToImplementPolicyWithError_frame(arg0, arg1, arg2);
372 widget.webView_didCommitLoadForFrame(arg0, arg1); 335 }
373 } 336 return 0;
374 else if (sel is OS.sel_webView_1setFrame_1) 337 }
375 { 338
376 widget.webView_setFrame(arg0, arg1); 339 static int /*long*/ browserProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ arg3) {
377 } 340 Widget widget = Display.getCurrent().findWidget(id);
378 else if (sel is OS.sel_webView_1createWebViewWithRequest_1) 341 if (widget is null) return 0;
379 { 342 Safari safari = (Safari)((Browser)widget).webBrowser;
380 return widget.webView_createWebViewWithRequest(arg0, arg1); 343 if (sel is OS.sel_webView_resource_didFailLoadingWithError_fromDataSource_) {
381 } 344 safari.webView_resource_didFailLoadingWithError_fromDataSource(arg0, arg1, arg2, arg3);
382 else if (sel is OS.sel_webView_1setStatusBarVisible_1) 345 }
383 { 346 return 0;
384 widget.webView_setStatusBarVisible(arg0, arg1); 347 }
385 } 348
386 else if (sel is OS.sel_webView_1setResizable_1) 349 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) {
387 { 350 Widget widget = Display.getCurrent().findWidget(id);
388 widget.webView_setResizable(arg0, arg1); 351 if (widget is null) return 0;
389 } 352 Safari safari = (Safari)((Browser)widget).webBrowser;
390 else if (sel is OS.sel_webView_1setStatusText_1) 353 if (sel is OS.sel_webView_resource_willSendRequest_redirectResponse_fromDataSource_) {
391 { 354 return safari.webView_resource_willSendRequest_redirectResponse_fromDataSource(arg0, arg1, arg2, arg3, arg4);
392 widget.webView_setStatusText(arg0, arg1); 355 } else if (sel is OS.sel_webView_decidePolicyForMIMEType_request_frame_decisionListener_) {
393 } 356 safari.webView_decidePolicyForMIMEType_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4);
394 else if (sel is OS.sel_webView_1setToolbarsVisible_1) 357 } else if (sel is OS.sel_webView_decidePolicyForNavigationAction_request_frame_decisionListener_) {
395 { 358 safari.webView_decidePolicyForNavigationAction_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4);
396 widget.webView_setToolbarsVisible(arg0, arg1); 359 } else if (sel is OS.sel_webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener_) {
397 } 360 safari.webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener(arg0, arg1, arg2, arg3, arg4);
398 else if (sel is OS.sel_webView_1runJavaScriptAlertPanelWithMessage_1) 361 }
399 { 362 return 0;
400 widget.webView_runJavaScriptAlertPanelWithMessage(arg0, arg1); 363 }
401 } 364
402 else if (sel is OS.sel_webView_1runJavaScriptConfirmPanelWithMessage_1) 365 public bool execute(String script) {
403 { 366 return webView.stringByEvaluatingJavaScriptFromString(NSString.stringWith(script)) !is null;
404 return widget.webView_runJavaScriptConfirmPanelWithMessage(arg0, arg1); 367 }
405 } 368
406 else if (sel is OS.sel_webView_1runOpenPanelForFileButtonWithResultListener_1) 369 public bool forward() {
407 { 370 html = null;
408 widget.webView_runOpenPanelForFileButtonWithResultListener(arg0, arg1); 371 return webView.goForward();
409 } 372 }
410 else if (sel is OS.sel_download_1decideDestinationWithSuggestedFilename_1) 373
411 { 374 public String getBrowserType () {
412 widget.download_decideDestinationWithSuggestedFilename(arg0, arg1); 375 return "safari"; //$NON-NLS-1$
413 } 376 }
414 else if (sel is OS.sel_webView_1printFrameView_1) 377
415 { 378 public String getText() {
416 widget.webView_printFrameView(arg0, arg1); 379 WebFrame mainFrame = webView.mainFrame();
417 } 380 WebDataSource dataSource = mainFrame.dataSource();
418 return 0; 381 if (dataSource is null) return ""; //$NON-NLS-1$
419 } 382 WebDocumentRepresentation representation = dataSource.representation();
420 383 if (representation is null) return ""; //$NON-NLS-1$
421 static int browserProc (int id, int sel, int arg0, int arg1, int arg2) 384 NSString source = representation.documentSource();
422 { 385 if (source is null) return ""; //$NON-NLS-1$
423 int jniRef = OS.objc_msgSend(id, OS.sel_tag); 386 return source.getString();
424 if (jniRef is 0 || jniRef is -1) 387 }
425 return 0; 388
426 Safari widget = cast(Safari) OS.JNIGetObject(jniRef); 389 public String getUrl() {
427 if (widget is null) 390 return url;
428 return 0; 391 }
429 if (sel is OS.sel_webView_1didFailProvisionalLoadWithError_1forFrame_1) 392
430 { 393 public bool isBackEnabled() {
431 widget.webView_didFailProvisionalLoadWithError_forFrame(arg0, arg1, arg2); 394 return webView.canGoBack();
432 } 395 }
433 else if (sel is OS.sel_webView_1didReceiveTitle_1forFrame_1) 396
434 { 397 public bool isForwardEnabled() {
435 widget.webView_didReceiveTitle_forFrame(arg0, arg1, arg2); 398 return webView.canGoForward();
436 } 399 }
437 else if (sel is OS.sel_webView_1resource_1didFinishLoadingFromDataSource_1) 400
438 { 401 public void refresh() {
439 widget.webView_resource_didFinishLoadingFromDataSource(arg0, arg1, arg2); 402 webView.reload(null);
440 } 403 }
441 else if (sel is OS.sel_webView_1identifierForInitialRequest_1fromDataSource_1) 404
442 { 405 public bool setText(String html) {
443 return widget.webView_identifierForInitialRequest_fromDataSource(arg0, arg1, arg2); 406 /*
444 } 407 * Bug in Safari. The web view segment faults in some circumstances
445 else if (sel is OS.sel_webView_1contextMenuItemsForElement_1defaultMenuItems_1) 408 * when the text changes during the location changing callback. The
446 { 409 * fix is to defer the work until the callback is done.
447 return widget.webView_contextMenuItemsForElement_defaultMenuItems(arg0, arg1, arg2); 410 */
448 } 411 if (changingLocation) {
449 else if (sel is OS.sel_webView_1mouseDidMoveOverElement_1modifierFlags_1) 412 this.html = html;
450 { 413 } else {
451 widget.webView_mouseDidMoveOverElement_modifierFlags(arg0, arg1, arg2); 414 _setText(html);
452 } 415 }
453 else if (sel is OS.sel_webView_1unableToImplementPolicyWithError_1frame_1) 416 return true;
454 { 417 }
455 widget.webView_unableToImplementPolicyWithError_frame(arg0, arg1, arg2); 418
456 } 419 void _setText(String html) {
457 return 0; 420 NSString string = NSString.stringWith(html);
458 } 421 NSString URLString = NSString.stringWith(URI_FROMMEMORY);
459 422 NSURL URL = NSURL.URLWithString(URLString);
460 static int browserProc (int id, int sel, int arg0, int arg1, int arg2, int arg3) 423 WebFrame mainFrame = webView.mainFrame();
461 { 424 mainFrame.loadHTMLString(string, URL);
462 int jniRef = OS.objc_msgSend(id, OS.sel_tag); 425 }
463 if (jniRef is 0 || jniRef is -1) 426
464 return 0; 427 public bool setUrl(String url) {
465 Safari widget = cast(Safari) OS.JNIGetObject(jniRef); 428 html = null;
466 if (widget is null) 429
467 return 0; 430 if (url.indexOf('/') is 0) {
468 if (sel is OS.sel_webView_1resource_1didFailLoadingWithError_1fromDataSource_1) 431 url = PROTOCOL_FILE + url;
469 { 432 } else if (url.indexOf(':') is -1) {
470 widget.webView_resource_didFailLoadingWithError_fromDataSource(arg0, arg1, arg2, arg3); 433 url = PROTOCOL_HTTP + url;
471 } 434 }
472 return 0; 435
473 } 436 NSString str = NSString.stringWith(url);
474 437 NSString unescapedStr = NSString.stringWith("%#"); //$NON-NLS-1$
475 static int browserProc (int id, int sel, int arg0, int arg1, int arg2, int arg3, int arg4) 438 int /*long*/ ptr = OS.CFURLCreateStringByAddingPercentEscapes(0, str.id, unescapedStr.id, 0, OS.kCFStringEncodingUTF8);
476 { 439 NSString escapedString = new NSString(ptr);
477 int jniRef = OS.objc_msgSend(id, OS.sel_tag); 440 NSURL inURL = NSURL.URLWithString(escapedString);
478 if (jniRef is 0 || jniRef is -1) 441 OS.CFRelease(ptr);
479 return 0; 442 NSURLRequest request = NSURLRequest.requestWithURL(inURL);
480 Safari widget = cast(Safari) OS.JNIGetObject(jniRef); 443 WebFrame mainFrame = webView.mainFrame();
481 if (widget is null) 444 mainFrame.loadRequest(request);
482 return 0; 445 return true;
483 if (sel is OS.sel_webView_1resource_1willSendRequest_1redirectResponse_1fromDataSource_1) 446 }
484 { 447
485 return widget.webView_resource_willSendRequest_redirectResponse_fromDataSource(arg0, arg1, arg2, arg3, arg4); 448 public void stop() {
486 } 449 html = null;
487 else if (sel is OS.sel_webView_1decidePolicyForMIMEType_1request_1frame_1decisionListener_1) 450 webView.stopLoading(null);
488 { 451 }
489 widget.webView_decidePolicyForMIMEType_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4); 452
490 } 453 /* WebFrameLoadDelegate */
491 else if (sel is OS.sel_webView_1decidePolicyForNavigationAction_1request_1frame_1decisionListener_1) 454
492 { 455 void webView_didChangeLocationWithinPageForFrame(int /*long*/ sender, int /*long*/ frameID) {
493 widget.webView_decidePolicyForNavigationAction_request_frame_decisionListener(arg0, arg1, arg2, arg3, arg4); 456 WebFrame frame = new WebFrame(frameID);
494 } 457 WebDataSource dataSource = frame.dataSource();
495 else if (sel is OS.sel_webView_1decidePolicyForNewWindowAction_1request_1newFrameName_1decisionListener_1) 458 NSURLRequest request = dataSource.request();
496 { 459 NSURL url = request.URL();
497 widget.webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener(arg0, arg1, arg2, arg3, arg4); 460 NSString s = url.absoluteString();
498 } 461 int length = (int)/*64*/s.length();
499 return 0; 462 if (length is 0) return;
500 } 463 String url2 = s.getString();
501 464 /*
502 public bool execute (String script) 465 * If the URI indicates that the page is being rendered from memory
503 { 466 * (via setText()) then set it to about:blank to be consistent with IE.
504 return webView.StringByEvaluatingJavaScriptFromString(NSString.StringWith(script)) !is null; 467 */
505 } 468 if (url2.equals (URI_FROMMEMORY)) url2 = ABOUT_BLANK;
506 469
507 public bool forward () 470 final Display display = browser.getDisplay();
508 { 471 bool top = frameID is webView.mainFrame().id;
509 html = null; 472 if (top) {
510 return webView.goForward(); 473 StatusTextEvent statusText = new StatusTextEvent(browser);
511 } 474 statusText.display = display;
512 475 statusText.widget = browser;
513 public String getText () 476 statusText.text = url2;
514 { 477 for (int i = 0; i < statusTextListeners.length; i++) {
515 WebFrame mainFrame = webView.mainFrame(); 478 statusTextListeners[i].changed(statusText);
516 WebDataSource dataSource = mainFrame.dataSource(); 479 }
517 if (dataSource is null) 480 }
518 return ""; //$NON-NLS-1$ 481
519 WebDocumentRepresentation representation = dataSource.representation(); 482 LocationEvent location = new LocationEvent(browser);
520 if (representation is null) 483 location.display = display;
521 return ""; //$NON-NLS-1$ 484 location.widget = browser;
522 NSString source = representation.documentSource(); 485 location.location = url2;
523 if (source is null) 486 location.top = top;
524 return ""; //$NON-NLS-1$ 487 for (int i = 0; i < locationListeners.length; i++) {
525 char[] buffer = new char[source.length()]; 488 locationListeners[i].changed(location);
526 source.getCharacters_(buffer); 489 }
527 return new String(buffer); 490 }
528 } 491
529 492 void webView_didFailProvisionalLoadWithError_forFrame(int /*long*/ sender, int /*long*/ error, int /*long*/ frame) {
530 public String getUrl () 493 if (frame is webView.mainFrame().id) {
531 {
532 return url;
533 }
534
535 public bool isBackEnabled ()
536 {
537 return webView.canGoBack();
538 }
539
540 public bool isForwardEnabled ()
541 {
542 return webView.canGoForward();
543 }
544
545 public void refresh ()
546 {
547 webView.reload(null);
548 }
549
550 public bool setText (String html)
551 {
552 /* 494 /*
553 * Bug in Safari. The web view segment faults in some circumstances 495 * Feature on Safari. The identifier is used here as a marker for the events
554 * when the text changes during the location changing callback. The 496 * related to the top frame and the URL changes related to that top frame as
555 * fix is to defer the work until the callback is done. 497 * they should appear on the location bar of a browser. It is expected to reset
556 */ 498 * the identifier to 0 when the event didFinishLoadingFromDataSource related to
557 if (changingLocation) 499 * the identifierForInitialRequest event is received. However, Safari fires
558 { 500 * the didFinishLoadingFromDataSource event before the entire content of the
559 this.html = html; 501 * top frame is loaded. It is possible to receive multiple willSendRequest
560 } 502 * events in this interval, causing the Browser widget to send unwanted
561 else 503 * Location.changing events. For this reason, the identifier is reset to 0
562 { 504 * when the top frame has either finished loading (didFinishLoadForFrame
563 _setText(html); 505 * event) or failed (didFailProvisionalLoadWithError).
564 } 506 */
565 return true; 507 identifier = 0;
566 } 508 }
567 509
568 void _setText (String html) 510 NSError nserror = new NSError(error);
569 { 511 int /*long*/ errorCode = nserror.code();
570 NSString String = NSString.StringWith(html); 512 if (errorCode <= OS.NSURLErrorBadURL) {
571 NSString URLString = NSString.StringWith(URI_FROMMEMORY); 513 NSString description = nserror.localizedDescription();
572 NSURL URL = NSURL.static_URLWithString_(URLString); 514 if (description !is null) {
573 WebFrame mainFrame = webView.mainFrame(); 515 String descriptionString = description.getString();
574 mainFrame.loadHTMLString(String, URL); 516 String urlString = null;
575 } 517 NSDictionary info = nserror.userInfo();
576 518 if (info !is null) {
577 public bool setUrl (String url) 519 NSString key = new NSString(OS.NSErrorFailingURLStringKey());
578 { 520 id id = info.valueForKey(key);
579 html = null; 521 if (id !is null) {
580 522 NSString url = new NSString(id);
581 NSURL inURL; 523 urlString = url.getString();
582 if (url.startsWith(PROTOCOL_FILE)) 524 }
583 {
584 url = url.substring(PROTOCOL_FILE.length());
585 }
586 bool isHttpURL = url.indexOf('/') !is 0;
587 if (isHttpURL)
588 {
589 if (url.indexOf(':') is -1)
590 {
591 url = PROTOCOL_HTTP + "//" + url; //$NON-NLS-1$
592 } 525 }
593 inURL = NSURL.static_URLWithString_(NSString.StringWith(url.toString())); 526 String message = urlString !is null ? urlString + "\n\n" : ""; //$NON-NLS-1$ //$NON-NLS-2$
594 } 527 message += Compatibility.getMessage ("DWT_Page_Load_Failed", new Object[] {descriptionString}); //$NON-NLS-1$
595 else 528 MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.ICON_ERROR);
596 { 529 messageBox.setMessage(message);
597 inURL = NSURL.static_fileURLWithPath_(NSString.StringWith(url.toString())); 530 messageBox.open();
598 } 531 }
599 if (inURL is null) 532 }
600 return false; 533 }
601 534
602 NSURLRequest request = NSURLRequest.static_requestWithURL_(inURL); 535 void webView_didFinishLoadForFrame(int /*long*/ sender, int /*long*/ frameID) {
603 WebFrame mainFrame = webView.mainFrame(); 536 hookDOMMouseListeners(frameID);
604 mainFrame.loadRequest(request); 537 if (frameID is webView.mainFrame().id) {
605 return true; 538 hookDOMKeyListeners(frameID);
606 } 539
607 540 final Display display = browser.getDisplay();
608 public void stop () 541 /*
609 { 542 * To be consistent with other platforms a title event should be fired when a
610 html = null; 543 * page has completed loading. A page with a <title> tag will do this
611 webView.stopLoading(null); 544 * automatically when the didReceiveTitle callback is received. However a page
612 } 545 * without a <title> tag will not do this by default, so fire the event
613 546 * here with the page's url as the title.
614 /* WebFrameLoadDelegate */ 547 */
615
616 void webView_didChangeLocationWithinPageForFrame (int sender, int frameID)
617 {
618 WebFrame frame = new WebFrame(frameID); 548 WebFrame frame = new WebFrame(frameID);
619 WebDataSource dataSource = frame.dataSource(); 549 WebDataSource dataSource = frame.dataSource();
620 NSURLRequest request = dataSource.request(); 550 if (dataSource !is null) {
621 NSURL url = request.URL(); 551 NSString title = dataSource.pageTitle();
622 NSString s = url.absoluteString(); 552 if (title is null) { /* page has no title */
623 int length = s.length(); 553 final TitleEvent newEvent = new TitleEvent(browser);
624 if (length is 0) 554 newEvent.display = display;
625 return; 555 newEvent.widget = browser;
626 char[] buffer = new char[length]; 556 newEvent.title = url;
627 s.getCharacters_(buffer); 557 for (int i = 0; i < titleListeners.length; i++) {
628 String url2 = new String(buffer); 558 final TitleListener listener = titleListeners[i];
629 /* 559 /*
630 * If the URI indicates that the page is being rendered from memory 560 * Note on WebKit. Running the event loop from a Browser
631 * (via setText()) then set it to about:blank to be consistent with IE. 561 * delegate callback breaks the WebKit (stop loading or
632 */ 562 * crash). The workaround is to invoke Display.asyncExec()
633 if (url2.opEquals(URI_FROMMEMORY)) 563 * so that the Browser does not crash if this is attempted.
634 url2 = ABOUT_BLANK; 564 */
635 565 display.asyncExec(
636 const Display display = browser.getDisplay(); 566 new Runnable() {
637 bool top = frameID is webView.mainFrame().id; 567 public void run() {
638 if (top) 568 if (!display.isDisposed() && !browser.isDisposed()) {
639 {
640 StatusTextEvent statusText = new StatusTextEvent(browser);
641 statusText.display = display;
642 statusText.widget = browser;
643 statusText.text = url2;
644 for (int i = 0; i < statusTextListeners.length; i++)
645 {
646 statusTextListeners[i].changed(statusText);
647 }
648 }
649
650 LocationEvent location = new LocationEvent(browser);
651 location.display = display;
652 location.widget = browser;
653 location.location = url2;
654 location.top = top;
655 for (int i = 0; i < locationListeners.length; i++)
656 {
657 locationListeners[i].changed(location);
658 }
659 }
660
661 void webView_didFailProvisionalLoadWithError_forFrame (int sender, int error, int frame)
662 {
663 if (frame is webView.mainFrame().id)
664 {
665 /*
666 * Feature on Safari. The identifier is used here as a marker for the events
667 * related to the top frame and the URL changes related to that top frame as
668 * they should appear on the location bar of a browser. It is expected to reset
669 * the identifier to 0 when the event didFinishLoadingFromDataSource related to
670 * the identifierForInitialRequest event is received. However, Safari fires
671 * the didFinishLoadingFromDataSource event before the entire content of the
672 * top frame is loaded. It is possible to receive multiple willSendRequest
673 * events in this interval, causing the Browser widget to send unwanted
674 * Location.changing events. For this reason, the identifier is reset to 0
675 * when the top frame has either finished loading (didFinishLoadForFrame
676 * event) or failed (didFailProvisionalLoadWithError).
677 */
678 identifier = 0;
679 }
680 }
681
682 void webView_didFinishLoadForFrame (int sender, int frameID)
683 {
684 hookDOMMouseListeners(frameID);
685 if (frameID is webView.mainFrame().id)
686 {
687 hookDOMKeyListeners(frameID);
688
689 const Display display = browser.getDisplay();
690 /*
691 * To be consistent with other platforms a title event should be fired when a
692 * page has completed loading. A page with a <title> tag will do this
693 * automatically when the didReceiveTitle callback is received. However a page
694 * without a <title> tag will not do this by default, so fire the event
695 * here with the page's url as the title.
696 */
697 WebFrame frame = new WebFrame(frameID);
698 WebDataSource dataSource = frame.dataSource();
699 if (dataSource !is null)
700 {
701 NSString title = dataSource.pageTitle();
702 if (title is null)
703 { /* page has no title */
704 const TitleEvent newEvent = new TitleEvent(browser);
705 newEvent.display = display;
706 newEvent.widget = browser;
707 newEvent.title = url;
708 for (int i = 0; i < titleListeners.length; i++)
709 {
710 const TitleListener listener = titleListeners[i];
711 /*
712 * Note on WebKit. Running the event loop from a Browser
713 * delegatee callback breaks the WebKit (stop loading or
714 * crash). The workaround is to invoke Display.asyncExec()
715 * so that the Browser does not crash if this is attempted.
716 */
717 display.asyncExec(new class (display, listener) Runnable
718 {
719 Display display;
720 TitleListener listener;
721
722 this (Display display, TitleListener listener)
723 {
724 this.display = display;
725 this.listener = listener;
726 }
727
728 public void run ()
729 {
730 if (!display.isDisposed() && !browser.isDisposed())
731 {
732 listener.changed(newEvent); 569 listener.changed(newEvent);
733 } 570 }
734 } 571 }
735 }); 572 }
736 } 573 );
737 } 574 }
738 } 575 }
739 const ProgressEvent progress = new ProgressEvent(browser); 576 }
740 progress.display = display; 577 final ProgressEvent progress = new ProgressEvent(browser);
741 progress.widget = browser; 578 progress.display = display;
742 progress.current = MAX_PROGRESS; 579 progress.widget = browser;
743 progress.total = MAX_PROGRESS; 580 progress.current = MAX_PROGRESS;
744 for (int i = 0; i < progressListeners.length; i++) 581 progress.total = MAX_PROGRESS;
745 { 582 for (int i = 0; i < progressListeners.length; i++) {
746 const ProgressListener listener = progressListeners[i]; 583 final ProgressListener listener = progressListeners[i];
747 /* 584 /*
748 * Note on WebKit. Running the event loop from a Browser 585 * Note on WebKit. Running the event loop from a Browser
749 * delegatee callback breaks the WebKit (stop loading or 586 * delegate callback breaks the WebKit (stop loading or
750 * crash). The ProgressBar widget currently touches the 587 * crash). The ProgressBar widget currently touches the
751 * event loop every time the method setSelection is called. 588 * event loop every time the method setSelection is called.
752 * The workaround is to invoke Display.asyncExec() so that 589 * The workaround is to invoke Display.asyncExec() so that
753 * the Browser does not crash when the user updates the 590 * the Browser does not crash when the user updates the
754 * selection of the ProgressBar. 591 * selection of the ProgressBar.
755 */ 592 */
756 display.asyncExec(new class (display, listener) Runnable 593 display.asyncExec(
757 { 594 new Runnable() {
758 Display display; 595 public void run() {
759 ProgressListener listener; 596 if (!display.isDisposed() && !browser.isDisposed()) {
760
761 this (Display display, ProgressListener listener)
762 {
763 this.display = display;
764 this.listener = listener;
765 }
766
767 public void run ()
768 {
769 if (!display.isDisposed() && !browser.isDisposed())
770 {
771 listener.completed(progress); 597 listener.completed(progress);
772 } 598 }
773 } 599 }
774 }); 600 }
775 } 601 );
602 }
603 /*
604 * Feature on Safari. The identifier is used here as a marker for the events
605 * related to the top frame and the URL changes related to that top frame as
606 * they should appear on the location bar of a browser. It is expected to reset
607 * the identifier to 0 when the event didFinishLoadingFromDataSource related to
608 * the identifierForInitialRequest event is received. However, Safari fires
609 * the didFinishLoadingFromDataSource event before the entire content of the
610 * top frame is loaded. It is possible to receive multiple willSendRequest
611 * events in this interval, causing the Browser widget to send unwanted
612 * Location.changing events. For this reason, the identifier is reset to 0
613 * when the top frame has either finished loading (didFinishLoadForFrame
614 * event) or failed (didFailProvisionalLoadWithError).
615 */
616 identifier = 0;
617 }
618 }
619
620 void hookDOMKeyListeners(int /*long*/ frameID) {
621 WebFrame frame = new WebFrame(frameID);
622 DOMDocument document = frame.DOMDocument();
623
624 NSString type = NSString.stringWith(DOMEVENT_KEYDOWN);
625 document.addEventListener(type, delegate, false);
626
627 type = NSString.stringWith(DOMEVENT_KEYUP);
628 document.addEventListener(type, delegate, false);
629 }
630
631 void hookDOMMouseListeners(int /*long*/ frameID) {
632 WebFrame frame = new WebFrame(frameID);
633 DOMDocument document = frame.DOMDocument();
634
635 NSString type = NSString.stringWith(DOMEVENT_MOUSEDOWN);
636 document.addEventListener(type, delegate, false);
637
638 type = NSString.stringWith(DOMEVENT_MOUSEUP);
639 document.addEventListener(type, delegate, false);
640
641 type = NSString.stringWith(DOMEVENT_MOUSEMOVE);
642 document.addEventListener(type, delegate, false);
643
644 type = NSString.stringWith(DOMEVENT_MOUSEWHEEL);
645 document.addEventListener(type, delegate, false);
646 }
647
648 void webView_didReceiveTitle_forFrame(int /*long*/ sender, int /*long*/ titleID, int /*long*/ frameID) {
649 if (frameID is webView.mainFrame().id) {
650 NSString title = new NSString(titleID);
651 String newTitle = title.getString();
652 TitleEvent newEvent = new TitleEvent(browser);
653 newEvent.display = browser.getDisplay();
654 newEvent.widget = browser;
655 newEvent.title = newTitle;
656 for (int i = 0; i < titleListeners.length; i++) {
657 titleListeners[i].changed(newEvent);
658 }
659 }
660 }
661
662 void webView_didStartProvisionalLoadForFrame(int /*long*/ sender, int /*long*/ frameID) {
663 /*
664 * This code is intentionally commented. WebFrameLoadDelegate:didStartProvisionalLoadForFrame is
665 * called before WebResourceLoadDelegate:willSendRequest and
666 * WebFrameLoadDelegate:didCommitLoadForFrame. The resource count is reset when didCommitLoadForFrame
667 * is received for the top frame.
668 */
669 // if (frameID is webView.mainFrame().id) {
670 // /* reset resource status variables */
671 // resourceCount= 0;
672 // }
673 }
674
675 void webView_didCommitLoadForFrame(int /*long*/ sender, int /*long*/ frameID) {
676 WebFrame frame = new WebFrame(frameID);
677 WebDataSource dataSource = frame.dataSource();
678 NSURLRequest request = dataSource.request();
679 NSURL url = request.URL();
680 NSString s = url.absoluteString();
681 int length = (int)/*64*/s.length();
682 if (length is 0) return;
683 String url2 = s.getString();
684 /*
685 * If the URI indicates that the page is being rendered from memory
686 * (via setText()) then set it to about:blank to be consistent with IE.
687 */
688 if (url2.equals (URI_FROMMEMORY)) url2 = ABOUT_BLANK;
689
690 final Display display = browser.getDisplay();
691 bool top = frameID is webView.mainFrame().id;
692 if (top) {
693 /* reset resource status variables */
694 resourceCount = 0;
695 this.url = url2;
696
697 final ProgressEvent progress = new ProgressEvent(browser);
698 progress.display = display;
699 progress.widget = browser;
700 progress.current = 1;
701 progress.total = MAX_PROGRESS;
702 for (int i = 0; i < progressListeners.length; i++) {
703 final ProgressListener listener = progressListeners[i];
776 /* 704 /*
777 * Feature on Safari. The identifier is used here as a marker for the events 705 * Note on WebKit. Running the event loop from a Browser
778 * related to the top frame and the URL changes related to that top frame as 706 * delegate callback breaks the WebKit (stop loading or
779 * they should appear on the location bar of a browser. It is expected to reset 707 * crash). The widget ProgressBar currently touches the
780 * the identifier to 0 when the event didFinishLoadingFromDataSource related to 708 * event loop every time the method setSelection is called.
781 * the identifierForInitialRequest event is received. However, Safari fires 709 * The workaround is to invoke Display.asyncexec so that
782 * the didFinishLoadingFromDataSource event before the entire content of the 710 * the Browser does not crash when the user updates the
783 * top frame is loaded. It is possible to receive multiple willSendRequest 711 * selection of the ProgressBar.
784 * events in this interval, causing the Browser widget to send unwanted 712 */
785 * Location.changing events. For this reason, the identifier is reset to 0 713 display.asyncExec(
786 * when the top frame has either finished loading (didFinishLoadForFrame 714 new Runnable() {
787 * event) or failed (didFailProvisionalLoadWithError). 715 public void run() {
788 */
789 identifier = 0;
790 }
791 }
792
793 void hookDOMKeyListeners (int frameID)
794 {
795 WebFrame frame = new WebFrame(frameID);
796 DOMDocument document = frame.DOMDocument();
797
798 NSString type = NSString.StringWith(DOMEVENT_KEYDOWN);
799 document.addEventListener_listener_useCapture(type, delegatee, false);
800
801 type = NSString.StringWith(DOMEVENT_KEYUP);
802 document.addEventListener_listener_useCapture(type, delegatee, false);
803 }
804
805 void hookDOMMouseListeners (int frameID)
806 {
807 WebFrame frame = new WebFrame(frameID);
808 DOMDocument document = frame.DOMDocument();
809
810 NSString type = NSString.StringWith(DOMEVENT_MOUSEDOWN);
811 document.addEventListener_listener_useCapture(type, delegatee, false);
812
813 type = NSString.StringWith(DOMEVENT_MOUSEUP);
814 document.addEventListener_listener_useCapture(type, delegatee, false);
815
816 type = NSString.StringWith(DOMEVENT_MOUSEMOVE);
817 document.addEventListener_listener_useCapture(type, delegatee, false);
818
819 type = NSString.StringWith(DOMEVENT_MOUSEWHEEL);
820 document.addEventListener_listener_useCapture(type, delegatee, false);
821 }
822
823 void webView_didReceiveTitle_forFrame (int sender, int titleID, int frameID)
824 {
825 if (frameID is webView.mainFrame().id)
826 {
827 NSString title = new NSString(titleID);
828 char[] buffer = new char[title.length()];
829 title.getCharacters_(buffer);
830 String newTitle = new String(buffer);
831 TitleEvent newEvent = new TitleEvent(browser);
832 newEvent.display = browser.getDisplay();
833 newEvent.widget = browser;
834 newEvent.title = newTitle;
835 for (int i = 0; i < titleListeners.length; i++)
836 {
837 titleListeners[i].changed(newEvent);
838 }
839 }
840 }
841
842 void webView_didStartProvisionalLoadForFrame (int sender, int frameID)
843 {
844 /*
845 * This code is intentionally commented. WebFrameLoadDelegate:didStartProvisionalLoadForFrame is
846 * called before WebResourceLoadDelegate:willSendRequest and
847 * WebFrameLoadDelegate:didCommitLoadForFrame. The resource count is reset when didCommitLoadForFrame
848 * is received for the top frame.
849 */
850 // if (frameID is webView.mainFrame().id) {
851 // /* reset resource status variables */
852 // resourceCount= 0;
853 // }
854 }
855
856 void webView_didCommitLoadForFrame (int sender, int frameID)
857 {
858 WebFrame frame = new WebFrame(frameID);
859 WebDataSource dataSource = frame.dataSource();
860 NSURLRequest request = dataSource.request();
861 NSURL url = request.URL();
862 NSString s = url.absoluteString();
863 int length = s.length();
864 if (length is 0)
865 return;
866 char[] buffer = new char[length];
867 s.getCharacters_(buffer);
868 String url2 = new String(buffer);
869 /*
870 * If the URI indicates that the page is being rendered from memory
871 * (via setText()) then set it to about:blank to be consistent with IE.
872 */
873 if (url2.opEquals(URI_FROMMEMORY))
874 url2 = ABOUT_BLANK;
875
876 const Display display = browser.getDisplay();
877 bool top = frameID is webView.mainFrame().id;
878 if (top)
879 {
880 /* reset resource status variables */
881 resourceCount = 0;
882 this.url = url2;
883
884 const ProgressEvent progress = new ProgressEvent(browser);
885 progress.display = display;
886 progress.widget = browser;
887 progress.current = 1;
888 progress.total = MAX_PROGRESS;
889 for (int i = 0; i < progressListeners.length; i++)
890 {
891 const ProgressListener listener = progressListeners[i];
892 /*
893 * Note on WebKit. Running the event loop from a Browser
894 * delegatee callback breaks the WebKit (stop loading or
895 * crash). The widget ProgressBar currently touches the
896 * event loop every time the method setSelection is called.
897 * The workaround is to invoke Display.asyncexec so that
898 * the Browser does not crash when the user updates the
899 * selection of the ProgressBar.
900 */
901 display.asyncExec(new class (display, listener) Runnable
902 {
903 Display display;
904 ProgressListener listener;
905
906 this (Display display, ProgressListener listener)
907 {
908 this.display = display;
909 this.listener = listener;
910 }
911
912 public void run ()
913 {
914 if (!display.isDisposed() && !browser.isDisposed()) 716 if (!display.isDisposed() && !browser.isDisposed())
915 listener.changed(progress); 717 listener.changed(progress);
916 } 718 }
917 }); 719 }
918 } 720 );
919 721 }
920 StatusTextEvent statusText = new StatusTextEvent(browser); 722
921 statusText.display = display; 723 StatusTextEvent statusText = new StatusTextEvent(browser);
922 statusText.widget = browser; 724 statusText.display = display;
923 statusText.text = url2; 725 statusText.widget = browser;
924 for (int i = 0; i < statusTextListeners.length; i++) 726 statusText.text = url2;
925 { 727 for (int i = 0; i < statusTextListeners.length; i++) {
926 statusTextListeners[i].changed(statusText); 728 statusTextListeners[i].changed(statusText);
927 } 729 }
928 } 730 }
929 LocationEvent location = new LocationEvent(browser); 731 LocationEvent location = new LocationEvent(browser);
930 location.display = display; 732 location.display = display;
931 location.widget = browser; 733 location.widget = browser;
932 location.location = url2; 734 location.location = url2;
933 location.top = top; 735 location.top = top;
934 for (int i = 0; i < locationListeners.length; i++) 736 for (int i = 0; i < locationListeners.length; i++) {
935 { 737 locationListeners[i].changed(location);
936 locationListeners[i].changed(location); 738 }
937 } 739 }
938 } 740
939 741 /* WebResourceLoadDelegate */
940 /* WebResourceLoadDelegate */ 742
941 743 void webView_resource_didFinishLoadingFromDataSource(int /*long*/ sender, int /*long*/ identifier, int /*long*/ dataSource) {
942 void webView_resource_didFinishLoadingFromDataSource (int sender, int identifier, int dataSource)
943 {
944 /* 744 /*
945 * Feature on Safari. The identifier is used here as a marker for the events 745 * Feature on Safari. The identifier is used here as a marker for the events
946 * related to the top frame and the URL changes related to that top frame as 746 * related to the top frame and the URL changes related to that top frame as
947 * they should appear on the location bar of a browser. It is expected to reset 747 * they should appear on the location bar of a browser. It is expected to reset
948 * the identifier to 0 when the event didFinishLoadingFromDataSource related to 748 * the identifier to 0 when the event didFinishLoadingFromDataSource related to
949 * the identifierForInitialRequest event is received. However, Safari fires 749 * the identifierForInitialRequest event is received. However, Safari fires
950 * the didFinishLoadingFromDataSource event before the entire content of the 750 * the didFinishLoadingFromDataSource event before the entire content of the
951 * top frame is loaded. It is possible to receive multiple willSendRequest 751 * top frame is loaded. It is possible to receive multiple willSendRequest
952 * events in this interval, causing the Browser widget to send unwanted 752 * events in this interval, causing the Browser widget to send unwanted
953 * Location.changing events. For this reason, the identifier is reset to 0 753 * Location.changing events. For this reason, the identifier is reset to 0
954 * when the top frame has either finished loading (didFinishLoadForFrame 754 * when the top frame has either finished loading (didFinishLoadForFrame
955 * event) or failed (didFailProvisionalLoadWithError). 755 * event) or failed (didFailProvisionalLoadWithError).
956 */ 756 */
957 // this code is intentionally commented 757 // this code is intentionally commented
958 //if (this.identifier is identifier) this.identifier = 0; 758 //if (this.identifier is identifier) this.identifier = 0;
959 } 759 }
960 760
961 void webView_resource_didFailLoadingWithError_fromDataSource (int sender, int identifier, int error, int dataSource) 761 void webView_resource_didFailLoadingWithError_fromDataSource(int /*long*/ sender, int /*long*/ identifier, int /*long*/ error, int /*long*/ dataSource) {
962 {
963 /* 762 /*
964 * Feature on Safari. The identifier is used here as a marker for the events 763 * Feature on Safari. The identifier is used here as a marker for the events
965 * related to the top frame and the URL changes related to that top frame as 764 * related to the top frame and the URL changes related to that top frame as
966 * they should appear on the location bar of a browser. It is expected to reset 765 * they should appear on the location bar of a browser. It is expected to reset
967 * the identifier to 0 when the event didFinishLoadingFromDataSource related to 766 * the identifier to 0 when the event didFinishLoadingFromDataSource related to
968 * the identifierForInitialRequest event is received. However, Safari fires 767 * the identifierForInitialRequest event is received. However, Safari fires
969 * the didFinishLoadingFromDataSource event before the entire content of the 768 * the didFinishLoadingFromDataSource event before the entire content of the
970 * top frame is loaded. It is possible to receive multiple willSendRequest 769 * top frame is loaded. It is possible to receive multiple willSendRequest
971 * events in this interval, causing the Browser widget to send unwanted 770 * events in this interval, causing the Browser widget to send unwanted
972 * Location.changing events. For this reason, the identifier is reset to 0 771 * Location.changing events. For this reason, the identifier is reset to 0
973 * when the top frame has either finished loading (didFinishLoadForFrame 772 * when the top frame has either finished loading (didFinishLoadForFrame
974 * event) or failed (didFailProvisionalLoadWithError). 773 * event) or failed (didFailProvisionalLoadWithError).
975 */ 774 */
976 // this code is intentionally commented 775 // this code is intentionally commented
977 //if (this.identifier is identifier) this.identifier = 0; 776 //if (this.identifier is identifier) this.identifier = 0;
978 } 777 }
979 778
980 int webView_identifierForInitialRequest_fromDataSource (int sender, int request, int dataSourceID) 779 int /*long*/ webView_identifierForInitialRequest_fromDataSource(int /*long*/ sender, int /*long*/ request, int /*long*/ dataSourceID) {
981 { 780 final Display display = browser.getDisplay();
982 const Display display = browser.getDisplay(); 781 final ProgressEvent progress = new ProgressEvent(browser);
983 const ProgressEvent progress = new ProgressEvent(browser); 782 progress.display = display;
984 progress.display = display; 783 progress.widget = browser;
985 progress.widget = browser; 784 progress.current = resourceCount;
986 progress.current = resourceCount; 785 progress.total = Math.max(resourceCount, MAX_PROGRESS);
987 progress.total = Math.max(resourceCount, MAX_PROGRESS); 786 for (int i = 0; i < progressListeners.length; i++) {
988 for (int i = 0; i < progressListeners.length; i++) 787 final ProgressListener listener = progressListeners[i];
989 { 788 /*
990 const ProgressListener listener = progressListeners[i]; 789 * Note on WebKit. Running the event loop from a Browser
991 /* 790 * delegate callback breaks the WebKit (stop loading or
992 * Note on WebKit. Running the event loop from a Browser 791 * crash). The widget ProgressBar currently touches the
993 * delegatee callback breaks the WebKit (stop loading or 792 * event loop every time the method setSelection is called.
994 * crash). The widget ProgressBar currently touches the 793 * The workaround is to invoke Display.asyncexec so that
995 * event loop every time the method setSelection is called. 794 * the Browser does not crash when the user updates the
996 * The workaround is to invoke Display.asyncexec so that 795 * selection of the ProgressBar.
997 * the Browser does not crash when the user updates the 796 */
998 * selection of the ProgressBar. 797 display.asyncExec(
999 */ 798 new Runnable() {
1000 display.asyncExec(new class (display, listener) Runnable 799 public void run() {
1001 {
1002 Display display;
1003 ProgressListener listener;
1004
1005 this (Display display, ProgressListener listener)
1006 {
1007 this.display = display;
1008 this.listener = listener;
1009 }
1010
1011 public void run ()
1012 {
1013 if (!display.isDisposed() && !browser.isDisposed()) 800 if (!display.isDisposed() && !browser.isDisposed())
1014 listener.changed(progress); 801 listener.changed(progress);
1015 } 802 }
1016 });
1017 }
1018
1019 NSNumber identifier = NSNumber.numberWithInt(resourceCount++);
1020 if (this.identifier is 0)
1021 {
1022 WebDataSource dataSource = new WebDataSource(dataSourceID);
1023 WebFrame frame = dataSource.webFrame();
1024 if (frame.id is webView.mainFrame().id)
1025 this.identifier = identifier.id;
1026 }
1027 return identifier.id;
1028
1029 }
1030
1031 int webView_resource_willSendRequest_redirectResponse_fromDataSource (int sender, int identifier, int request, int redirectResponse,
1032 int dataSource)
1033 {
1034 return request;
1035 }
1036
1037 /* handleNotification */
1038
1039 void handleNotification (int notification)
1040 {
1041 }
1042
1043 /* UIDelegate */
1044 int webView_createWebViewWithRequest (int sender, int request)
1045 {
1046 WindowEvent newEvent = new WindowEvent(browser);
1047 newEvent.display = browser.getDisplay();
1048 newEvent.widget = browser;
1049 newEvent.required = true;
1050 if (openWindowListeners !is null)
1051 {
1052 for (int i = 0; i < openWindowListeners.length; i++)
1053 {
1054 openWindowListeners[i].open(newEvent);
1055 } 803 }
1056 } 804 );
1057 Browser browser = null; 805 }
1058 if (newEvent.browser !is null && cast(Safari) newEvent.browser.webBrowser) 806
1059 { 807 NSNumber identifier = NSNumber.numberWithInt(resourceCount++);
1060 browser = newEvent.browser; 808 if (this.identifier is 0) {
1061 } 809 WebDataSource dataSource = new WebDataSource(dataSourceID);
1062 if (browser !is null && !browser.isDisposed()) 810 WebFrame frame = dataSource.webFrame();
1063 { 811 if (frame.id is webView.mainFrame().id) this.identifier = identifier.id;
1064 if (request !is 0) 812 }
1065 { 813 return identifier.id;
1066 WebFrame mainFrame = webView.mainFrame(); 814
1067 mainFrame.loadRequest(new NSURLRequest(request)); 815 }
1068 } 816
1069 } 817 int /*long*/ webView_resource_willSendRequest_redirectResponse_fromDataSource(int /*long*/ sender, int /*long*/ identifier, int /*long*/ request, int /*long*/ redirectResponse, int /*long*/ dataSource) {
1070 return webView.id; 818 return request;
1071 } 819 }
1072 820
1073 void webViewShow (int sender) 821 /* handleNotification */
1074 { 822
1075 /* 823 void handleNotification(int /*long*/ notification) {
1076 * Feature on WebKit. The Safari WebKit expects the application 824 }
1077 * to create a new Window using the Objective C Cocoa API in response 825
1078 * to UIDelegate.createWebViewWithRequest. The application is then 826 /* UIDelegate */
1079 * expected to use Objective C Cocoa API to make this window visible 827
1080 * when receiving the UIDelegate.webViewShow message. For some reason, 828 int /*long*/ webView_createWebViewWithRequest(int /*long*/ sender, int /*long*/ request) {
1081 * a window created with the Carbon API hosting the new browser instance 829 WindowEvent newEvent = new WindowEvent(browser);
1082 * does not redraw until it has been resized. The fix is to increase the 830 newEvent.display = browser.getDisplay();
1083 * size of the Shell and restore it to its initial size. 831 newEvent.widget = browser;
1084 */ 832 newEvent.required = true;
1085 Shell parent = browser.getShell(); 833 if (openWindowListeners !is null) {
1086 Point pt = parent.getSize(); 834 for (int i = 0; i < openWindowListeners.length; i++) {
1087 parent.setSize(pt.x + 1, pt.y); 835 openWindowListeners[i].open(newEvent);
1088 parent.setSize(pt.x, pt.y); 836 }
1089 WindowEvent newEvent = new WindowEvent(browser); 837 }
1090 newEvent.display = browser.getDisplay(); 838 WebView result = null;
1091 newEvent.widget = browser; 839 Browser browser = null;
1092 if (location !is null) 840 if (newEvent.browser !is null && newEvent.browser.webBrowser instanceof Safari) {
1093 newEvent.location = location; 841 browser = newEvent.browser;
1094 if (size !is null) 842 }
1095 newEvent.size = size; 843 if (browser !is null && !browser.isDisposed()) {
1096 /* 844 result = ((Safari)browser.webBrowser).webView;
1097 * Feature in Safari. Safari's tool bar contains 845 if (request !is 0) {
1098 * the address bar. The address bar is displayed 846 WebFrame mainFrame = webView.mainFrame();
1099 * if the tool bar is displayed. There is no separate 847 mainFrame.loadRequest(new NSURLRequest(request));
1100 * notification for the address bar. 848 }
1101 * Feature in Safari. The menu bar is always 849 }
1102 * displayed. There is no notification to hide 850 return result !is null ? result.id : 0;
1103 * the menu bar. 851 }
1104 */ 852
1105 newEvent.addressBar = toolBar; 853 void webViewShow(int /*long*/ sender) {
1106 newEvent.menuBar = true; 854 /*
1107 newEvent.statusBar = statusBar; 855 * Feature on WebKit. The Safari WebKit expects the application
1108 newEvent.toolBar = toolBar; 856 * to create a new Window using the Objective C Cocoa API in response
1109 for (int i = 0; i < visibilityWindowListeners.length; i++) 857 * to UIDelegate.createWebViewWithRequest. The application is then
1110 { 858 * expected to use Objective C Cocoa API to make this window visible
1111 visibilityWindowListeners[i].show(newEvent); 859 * when receiving the UIDelegate.webViewShow message. For some reason,
1112 } 860 * a window created with the Carbon API hosting the new browser instance
1113 location = null; 861 * does not redraw until it has been resized. The fix is to increase the
1114 size = null; 862 * size of the Shell and restore it to its initial size.
1115 } 863 */
1116 864 Shell parent = browser.getShell();
1117 void webView_setFrame (int sender, int frame) 865 Point pt = parent.getSize();
1118 { 866 parent.setSize(pt.x+1, pt.y);
1119 float[] dest = new float[4]; 867 parent.setSize(pt.x, pt.y);
1120 OS.memmove(dest, frame, 16); 868 WindowEvent newEvent = new WindowEvent(browser);
1121 /* convert to DWT system coordinates */ 869 newEvent.display = browser.getDisplay();
1122 Rectangle bounds = browser.getDisplay().getBounds(); 870 newEvent.widget = browser;
1123 location = new Point(cast(int) dest[0], bounds.height - cast(int) dest[1] - cast(int) dest[3]); 871 if (location !is null) newEvent.location = location;
1124 size = new Point(cast(int) dest[2], cast(int) dest[3]); 872 if (size !is null) newEvent.size = size;
1125 } 873 /*
1126 874 * Feature in Safari. Safari's tool bar contains
1127 void webViewFocus (int sender) 875 * the address bar. The address bar is displayed
1128 { 876 * if the tool bar is displayed. There is no separate
1129 } 877 * notification for the address bar.
1130 878 * Feature in Safari. The menu bar is always
1131 void webViewUnfocus (int sender) 879 * displayed. There is no notification to hide
1132 { 880 * the menu bar.
1133 } 881 */
1134 882 newEvent.addressBar = toolBar;
1135 void webView_runJavaScriptAlertPanelWithMessage (int sender, int messageID) 883 newEvent.menuBar = true;
1136 { 884 newEvent.statusBar = statusBar;
1137 NSString message = new NSString(messageID); 885 newEvent.toolBar = toolBar;
1138 char[] buffer = new char[message.length()]; 886 for (int i = 0; i < visibilityWindowListeners.length; i++) {
1139 message.getCharacters_(buffer); 887 visibilityWindowListeners[i].show(newEvent);
1140 String text = new String(buffer); 888 }
1141 889 location = null;
1142 MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.ICON_WARNING); 890 size = null;
1143 messageBox.setText("Javascript"); //$NON-NLS-1$ 891 }
1144 messageBox.setMessage(text); 892
1145 messageBox.open(); 893 void webView_setFrame(int /*long*/ sender, int /*long*/ frame) {
1146 } 894 NSRect rect = new NSRect();
1147 895 OS.memmove(rect, frame, NSRect.sizeof);
1148 int webView_runJavaScriptConfirmPanelWithMessage (int sender, int messageID) 896 /* convert to DWT system coordinates */
1149 { 897 Rectangle bounds = browser.getDisplay().getBounds();
1150 NSString message = new NSString(messageID); 898 location = new Point((int)rect.x, bounds.height - (int)rect.y - (int)rect.height);
1151 char[] buffer = new char[message.length()]; 899 size = new Point((int)rect.width, (int)rect.height);
1152 message.getCharacters_(buffer); 900 }
1153 String text = new String(buffer); 901
1154 902 void webViewFocus(int /*long*/ sender) {
1155 MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.CANCEL | DWT.ICON_QUESTION); 903 }
1156 messageBox.setText("Javascript"); //$NON-NLS-1$ 904
1157 messageBox.setMessage(text); 905 void webViewUnfocus(int /*long*/ sender) {
1158 return messageBox.open() is DWT.OK ? 1 : 0; 906 }
1159 } 907
1160 908 void webView_runJavaScriptAlertPanelWithMessage(int /*long*/ sender, int /*long*/ messageID) {
1161 void webView_runOpenPanelForFileButtonWithResultListener (int sender, int resultListenerID) 909 NSString message = new NSString(messageID);
1162 { 910 String text = message.getString();
1163 FileDialog dialog = new FileDialog(browser.getShell(), DWT.NONE); 911
1164 String result = dialog.open(); 912 MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.ICON_WARNING);
1165 WebOpenPanelResultListener resultListener = new WebOpenPanelResultListener(resultListenerID); 913 messageBox.setText("Javascript"); //$NON-NLS-1$
1166 if (result is null) 914 messageBox.setMessage(text);
1167 { 915 messageBox.open();
1168 resultListener.cancel(); 916 }
1169 return; 917
1170 } 918 int webView_runJavaScriptConfirmPanelWithMessage(int /*long*/ sender, int /*long*/ messageID) {
1171 resultListener.chooseFilename(NSString.StringWith(result)); 919 NSString message = new NSString(messageID);
1172 } 920 String text = message.getString();
1173 921
1174 void webViewClose (int sender) 922 MessageBox messageBox = new MessageBox(browser.getShell(), DWT.OK | DWT.CANCEL | DWT.ICON_QUESTION);
1175 { 923 messageBox.setText("Javascript"); //$NON-NLS-1$
1176 Shell parent = browser.getShell(); 924 messageBox.setMessage(text);
1177 WindowEvent newEvent = new WindowEvent(browser); 925 return messageBox.open() is DWT.OK ? 1 : 0;
1178 newEvent.display = browser.getDisplay(); 926 }
1179 newEvent.widget = browser; 927
1180 for (int i = 0; i < closeWindowListeners.length; i++) 928 void webView_runOpenPanelForFileButtonWithResultListener(int /*long*/ sender, int /*long*/ resultListenerID) {
1181 { 929 FileDialog dialog = new FileDialog(browser.getShell(), DWT.NONE);
1182 closeWindowListeners[i].close(newEvent); 930 String result = dialog.open();
1183 } 931 WebOpenPanelResultListener resultListener = new WebOpenPanelResultListener(resultListenerID);
1184 browser.dispose(); 932 if (result is null) {
1185 if (parent.isDisposed()) 933 resultListener.cancel();
1186 return; 934 return;
1187 /* 935 }
1188 * Feature on WebKit. The Safari WebKit expects the application 936 resultListener.chooseFilename(NSString.stringWith(result));
1189 * to create a new Window using the Objective C Cocoa API in response 937 }
1190 * to UIDelegate.createWebViewWithRequest. The application is then 938
1191 * expected to use Objective C Cocoa API to make this window visible 939 void webViewClose(int /*long*/ sender) {
1192 * when receiving the UIDelegate.webViewShow message. For some reason, 940 Shell parent = browser.getShell();
1193 * a window created with the Carbon API hosting the new browser instance 941 WindowEvent newEvent = new WindowEvent(browser);
1194 * does not redraw until it has been resized. The fix is to increase the 942 newEvent.display = browser.getDisplay();
1195 * size of the Shell and restore it to its initial size. 943 newEvent.widget = browser;
1196 */ 944 for (int i = 0; i < closeWindowListeners.length; i++) {
1197 Point pt = parent.getSize(); 945 closeWindowListeners[i].close(newEvent);
1198 parent.setSize(pt.x + 1, pt.y); 946 }
1199 parent.setSize(pt.x, pt.y); 947 browser.dispose();
1200 } 948 if (parent.isDisposed()) return;
1201 949 /*
1202 int webView_contextMenuItemsForElement_defaultMenuItems (int sender, int element, int defaultMenuItems) 950 * Feature on WebKit. The Safari WebKit expects the application
1203 { 951 * to create a new Window using the Objective C Cocoa API in response
1204 Point pt = browser.getDisplay().getCursorLocation(); 952 * to UIDelegate.createWebViewWithRequest. The application is then
1205 Event event = new Event(); 953 * expected to use Objective C Cocoa API to make this window visible
1206 event.x = pt.x; 954 * when receiving the UIDelegate.webViewShow message. For some reason,
1207 event.y = pt.y; 955 * a window created with the Carbon API hosting the new browser instance
1208 browser.notifyListeners(DWT.MenuDetect, event); 956 * does not redraw until it has been resized. The fix is to increase the
1209 Menu menu = browser.getMenu(); 957 * size of the Shell and restore it to its initial size.
1210 if (!event.doit) 958 */
1211 return 0; 959 Point pt = parent.getSize();
1212 if (menu !is null && !menu.isDisposed()) 960 parent.setSize(pt.x+1, pt.y);
1213 { 961 parent.setSize(pt.x, pt.y);
1214 if (event.x !is pt.x || event.y !is pt.y) 962 }
1215 { 963
1216 menu.setLocation(event.x, event.y); 964 int /*long*/ webView_contextMenuItemsForElement_defaultMenuItems(int /*long*/ sender, int /*long*/ element, int /*long*/ defaultMenuItems) {
1217 } 965 Point pt = browser.getDisplay().getCursorLocation();
1218 menu.setVisible(true); 966 Event event = new Event();
1219 return 0; 967 event.x = pt.x;
1220 } 968 event.y = pt.y;
1221 return defaultMenuItems; 969 browser.notifyListeners(DWT.MenuDetect, event);
1222 } 970 Menu menu = browser.getMenu();
1223 971 if (!event.doit) return 0;
1224 void webView_setStatusBarVisible (int sender, int visible) 972 if (menu !is null && !menu.isDisposed()) {
1225 { 973 if (event.x !is pt.x || event.y !is pt.y) {
1226 /* Note. Webkit only emits the notification when the status bar should be hidden. */ 974 menu.setLocation(event.x, event.y);
1227 statusBar = visible !is 0; 975 }
1228 } 976 menu.setVisible(true);
1229 977 return 0;
1230 void webView_setStatusText (int sender, int textID) 978 }
1231 { 979 return defaultMenuItems;
1232 NSString text = new NSString(textID); 980 }
1233 int length = text.length(); 981
1234 if (length is 0) 982 void webView_setStatusBarVisible(int /*long*/ sender, bool visible) {
1235 return; 983 /* Note. Webkit only emits the notification when the status bar should be hidden. */
1236 char[] buffer = new char[length]; 984 statusBar = visible;
1237 text.getCharacters_(buffer); 985 }
1238 986
987 void webView_setStatusText(int /*long*/ sender, int /*long*/ textID) {
988 NSString text = new NSString(textID);
989 int length = (int)/*64*/text.length();
990 if (length is 0) return;
991
992 StatusTextEvent statusText = new StatusTextEvent(browser);
993 statusText.display = browser.getDisplay();
994 statusText.widget = browser;
995 statusText.text = text.getString();
996 for (int i = 0; i < statusTextListeners.length; i++) {
997 statusTextListeners[i].changed(statusText);
998 }
999 }
1000
1001 void webView_setResizable(int /*long*/ sender, bool visible) {
1002 }
1003
1004 void webView_setToolbarsVisible(int /*long*/ sender, bool visible) {
1005 /* Note. Webkit only emits the notification when the tool bar should be hidden. */
1006 toolBar = visible;
1007 }
1008
1009 void webView_mouseDidMoveOverElement_modifierFlags (int /*long*/ sender, int /*long*/ elementInformationID, int /*long*/ modifierFlags) {
1010 if (elementInformationID is 0) return;
1011
1012 NSString key = NSString.stringWith(WebElementLinkURLKey);
1013 NSDictionary elementInformation = new NSDictionary(elementInformationID);
1014 id value = elementInformation.valueForKey(key);
1015 if (value is null) {
1016 /* not currently over a link */
1017 if (lastHoveredLinkURL is null) return;
1018 lastHoveredLinkURL = null;
1239 StatusTextEvent statusText = new StatusTextEvent(browser); 1019 StatusTextEvent statusText = new StatusTextEvent(browser);
1240 statusText.display = browser.getDisplay(); 1020 statusText.display = browser.getDisplay();
1241 statusText.widget = browser; 1021 statusText.widget = browser;
1242 statusText.text = new String(buffer); 1022 statusText.text = ""; //$NON-NLS-1$
1243 for (int i = 0; i < statusTextListeners.length; i++) 1023 for (int i = 0; i < statusTextListeners.length; i++) {
1244 {
1245 statusTextListeners[i].changed(statusText); 1024 statusTextListeners[i].changed(statusText);
1246 } 1025 }
1247 } 1026 return;
1248 1027 }
1249 void webView_setResizable (int sender, int visible) 1028
1250 { 1029 NSString url = new NSURL(value.id).absoluteString();
1251 } 1030 int length = (int)/*64*/url.length();
1252 1031 String urlString;
1253 void webView_setToolbarsVisible (int sender, int visible) 1032 if (length is 0) {
1254 { 1033 urlString = ""; //$NON-NLS-1$
1255 /* Note. Webkit only emits the notification when the tool bar should be hidden. */ 1034 } else {
1256 toolBar = visible !is 0; 1035 urlString = url.getString();
1257 } 1036 }
1258 1037 if (urlString.equals(lastHoveredLinkURL)) return;
1259 void webView_mouseDidMoveOverElement_modifierFlags (int sender, int elementInformationID, int modifierFlags) 1038
1260 { 1039 lastHoveredLinkURL = urlString;
1261 if (elementInformationID is 0) 1040 StatusTextEvent statusText = new StatusTextEvent(browser);
1262 return; 1041 statusText.display = browser.getDisplay();
1263 1042 statusText.widget = browser;
1264 NSString key = NSString.StringWith(WebElementLinkURLKey); 1043 statusText.text = urlString;
1265 NSDictionary elementInformation = new NSDictionary(elementInformationID); 1044 for (int i = 0; i < statusTextListeners.length; i++) {
1266 id value = elementInformation.valueForKey(key); 1045 statusTextListeners[i].changed(statusText);
1267 if (value is null) 1046 }
1268 { 1047 }
1269 /* not currently over a link */ 1048
1270 if (lastHoveredLinkURL is null) 1049 void webView_printFrameView (int /*long*/ sender, int /*long*/ frameViewID) {
1271 return; 1050 WebFrameView view = new WebFrameView(frameViewID);
1272 lastHoveredLinkURL = null; 1051 bool viewPrint = view.documentViewShouldHandlePrint();
1273 StatusTextEvent statusText = new StatusTextEvent(browser); 1052 if (viewPrint) {
1274 statusText.display = browser.getDisplay(); 1053 view.printDocumentView();
1275 statusText.widget = browser; 1054 return;
1276 statusText.text = ""; //$NON-NLS-1$ 1055 }
1277 for (int i = 0; i < statusTextListeners.length; i++) 1056 NSPrintInfo info = NSPrintInfo.sharedPrintInfo();
1278 { 1057 NSPrintOperation operation = view.printOperationWithPrintInfo(info);
1279 statusTextListeners[i].changed(statusText); 1058 if (operation !is null) operation.runOperation();
1280 } 1059 }
1281 return; 1060
1282 } 1061 /* PolicyDelegate */
1283 1062
1284 NSString url = (new NSURL(value.id)).absoluteString(); 1063 void webView_decidePolicyForMIMEType_request_frame_decisionListener(int /*long*/ sender, int /*long*/ type, int /*long*/ request, int /*long*/ frame, int /*long*/ listenerID) {
1285 int length = url.length(); 1064 bool canShow = WebView.canShowMIMEType(new NSString(type));
1286 String urlString; 1065 WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID);
1287 if (length is 0) 1066 if (canShow) {
1288 {
1289 urlString = ""; //$NON-NLS-1$
1290 }
1291 else
1292 {
1293 char[] buffer = new char[length];
1294 url.getCharacters_(buffer);
1295 urlString = new String(buffer);
1296 }
1297 if (urlString.opEquals(lastHoveredLinkURL))
1298 return;
1299
1300 lastHoveredLinkURL = urlString;
1301 StatusTextEvent statusText = new StatusTextEvent(browser);
1302 statusText.display = browser.getDisplay();
1303 statusText.widget = browser;
1304 statusText.text = urlString;
1305 for (int i = 0; i < statusTextListeners.length; i++)
1306 {
1307 statusTextListeners[i].changed(statusText);
1308 }
1309 }
1310
1311 void webView_printFrameView (int sender, int frameViewID)
1312 {
1313 WebFrameView view = new WebFrameView(frameViewID);
1314 bool viewPrint = view.documentViewShouldHandlePrint();
1315 if (viewPrint)
1316 {
1317 view.printDocumentView();
1318 return;
1319 }
1320 NSPrintInfo info = NSPrintInfo.sharedPrintInfo();
1321 NSPrintOperation operation = view.printOperationWithPrintInfo(info);
1322 if (operation !is null)
1323 operation.runOperation();
1324 }
1325
1326 /* PolicyDelegate */
1327
1328 void webView_decidePolicyForMIMEType_request_frame_decisionListener (int sender, int type, int request, int frame, int listenerID)
1329 {
1330 bool canShow = WebView.canShowMIMEType(new NSString(type));
1331 WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID);
1332 if (canShow)
1333 {
1334 listener.use();
1335 }
1336 else
1337 {
1338 listener.download();
1339 }
1340 }
1341
1342 void webView_decidePolicyForNavigationAction_request_frame_decisionListener (int sender, int actionInformation, int request, int frame,
1343 int listenerID)
1344 {
1345 NSURL url = (new NSURLRequest(request)).URL();
1346 WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID);
1347 if (url is null)
1348 {
1349 /* indicates that a URL with an invalid format was specified */
1350 listener.ignore();
1351 return;
1352 }
1353 NSString s = url.absoluteString();
1354 char[] buffer = new char[s.length()];
1355 s.getCharacters_(buffer);
1356 String url2 = new String(buffer);
1357 /*
1358 * If the URI indicates that the page is being rendered from memory
1359 * (via setText()) then set it to about:blank to be consistent with IE.
1360 */
1361 if (url2.opEquals(URI_FROMMEMORY))
1362 url2 = ABOUT_BLANK;
1363
1364 LocationEvent newEvent = new LocationEvent(browser);
1365 newEvent.display = browser.getDisplay();
1366 newEvent.widget = browser;
1367 newEvent.location = url2;
1368 newEvent.doit = true;
1369 if (locationListeners !is null)
1370 {
1371 changingLocation = true;
1372 for (int i = 0; i < locationListeners.length; i++)
1373 {
1374 locationListeners[i].changing(newEvent);
1375 }
1376 changingLocation = false;
1377 }
1378 if (newEvent.doit)
1379 {
1380 listener.use();
1381 }
1382 else
1383 {
1384 listener.ignore();
1385 }
1386 if (html !is null && !browser.isDisposed())
1387 {
1388 String html = this.html;
1389 this.html = null;
1390 _setText(html);
1391 }
1392 }
1393
1394 void webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener (int sender, int actionInformation, int request, int frameName,
1395 int listenerID)
1396 {
1397 WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID);
1398 listener.use(); 1067 listener.use();
1399 } 1068 } else {
1400 1069 listener.download();
1401 void webView_unableToImplementPolicyWithError_frame (int sender, int error, int frame) 1070 }
1402 { 1071 }
1403 } 1072
1404 1073 void webView_decidePolicyForNavigationAction_request_frame_decisionListener(int /*long*/ sender, int /*long*/ actionInformation, int /*long*/ request, int /*long*/ frame, int /*long*/ listenerID) {
1405 /* WebDownload */ 1074 NSURL url = new NSURLRequest(request).URL();
1406 1075 WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID);
1407 void download_decideDestinationWithSuggestedFilename (int downloadId, int filename) 1076 if (url is null) {
1408 { 1077 /* indicates that a URL with an invalid format was specified */
1409 NSString String = new NSString(filename); 1078 listener.ignore();
1410 char[] buffer = new char[String.length()]; 1079 return;
1411 String.getCharacters_(buffer); 1080 }
1412 String name = new String(buffer); 1081 NSString s = url.absoluteString();
1413 FileDialog dialog = new FileDialog(browser.getShell(), DWT.SAVE); 1082 String url2 = s.getString();
1414 dialog.setText(DWT.getMessage("DWT_FileDownload")); //$NON-NLS-1$ 1083 /*
1415 dialog.setFileName(name); 1084 * If the URI indicates that the page is being rendered from memory
1416 String path = dialog.open(); 1085 * (via setText()) then set it to about:blank to be consistent with IE.
1417 NSURLDownload download = new NSURLDownload(downloadId); 1086 */
1418 if (path is null) 1087 if (url2.equals (URI_FROMMEMORY)) url2 = ABOUT_BLANK;
1419 { 1088
1420 /* cancel pressed */ 1089 LocationEvent newEvent = new LocationEvent(browser);
1421 download.cancel(); 1090 newEvent.display = browser.getDisplay();
1422 return; 1091 newEvent.widget = browser;
1423 } 1092 newEvent.location = url2;
1424 download.setDestination(NSString.StringWith(path), true); 1093 newEvent.doit = true;
1425 } 1094 if (locationListeners !is null) {
1426 1095 changingLocation = true;
1427 /* DOMEventListener */ 1096 for (int i = 0; i < locationListeners.length; i++) {
1428 1097 locationListeners[i].changing(newEvent);
1429 void handleEvent (int evtId) 1098 }
1430 { 1099 changingLocation = false;
1431 DOMEvent evt = new DOMEvent(evtId); 1100 }
1432 NSString String = evt.type(); 1101 if (newEvent.doit) {
1433 char[] buffer = new char[String.length()]; 1102 listener.use();
1434 String.getCharacters_(buffer); 1103 } else {
1435 String type = new String(buffer); 1104 listener.ignore();
1436 1105 }
1437 if (DOMEVENT_KEYDOWN.opEquals(type) || DOMEVENT_KEYUP.opEquals(type)) 1106 if (html !is null && !browser.isDisposed()) {
1438 { 1107 String html = this.html;
1439 DOMKeyboardEvent event = new DOMKeyboardEvent(evtId); 1108 this.html = null;
1440 1109 _setText(html);
1441 bool ctrl = event.ctrlKey(); 1110 }
1442 bool shift = event.shiftKey(); 1111 }
1443 bool alt = event.altKey(); 1112
1444 bool meta = event.metaKey(); 1113 void webView_decidePolicyForNewWindowAction_request_newFrameName_decisionListener(int /*long*/ sender, int /*long*/ actionInformation, int /*long*/ request, int /*long*/ frameName, int /*long*/ listenerID) {
1445 int keyCode = event.keyCode(); 1114 WebPolicyDecisionListener listener = new WebPolicyDecisionListener(listenerID);
1446 int charCode = event.charCode(); 1115 listener.use();
1447 1116 }
1448 Event keyEvent = new Event(); 1117
1449 keyEvent.widget = browser; 1118 void webView_unableToImplementPolicyWithError_frame(int /*long*/ sender, int /*long*/ error, int /*long*/ frame) {
1450 if (DOMEVENT_KEYDOWN.opEquals(type)) 1119 }
1451 { 1120
1452 keyEvent.type = DWT.KeyDown; 1121 /* WebDownload */
1453 } 1122
1454 else 1123 void download_decideDestinationWithSuggestedFilename(int /*long*/ downloadId, int /*long*/ filename) {
1455 { 1124 NSString string = new NSString(filename);
1456 keyEvent.type = DWT.KeyUp; 1125 String name = string.getString();
1457 } 1126 FileDialog dialog = new FileDialog(browser.getShell(), DWT.SAVE);
1458 keyEvent.keyCode = translateKey(keyCode); 1127 dialog.setText(DWT.getMessage ("DWT_FileDownload")); //$NON-NLS-1$
1459 keyEvent.character = cast(char) charCode; 1128 dialog.setFileName(name);
1460 keyEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); 1129 String path = dialog.open();
1461 browser.notifyListeners(keyEvent.type, keyEvent); 1130 NSURLDownload download = new NSURLDownload(downloadId);
1462 if (!keyEvent.doit) 1131 if (path is null) {
1463 { 1132 /* cancel pressed */
1464 event.preventDefault(); 1133 download.cancel();
1465 } 1134 return;
1466 return; 1135 }
1467 } 1136 download.setDestination(NSString.stringWith(path), true);
1468 1137 }
1469 if (DOMEVENT_MOUSEWHEEL.opEquals(type)) 1138
1470 { 1139 /* DOMEventListener */
1471 DOMWheelEvent event = new DOMWheelEvent(evtId); 1140
1472 int clientX = event.clientX(); 1141 void handleEvent(int /*long*/ evtId) {
1473 int clientY = event.clientY(); 1142 NSString string = new NSString(OS.objc_msgSend(evtId, OS.sel_type));
1474 int delta = event.wheelDelta(); 1143 String type = string.getString();
1475 bool ctrl = event.ctrlKey(); 1144
1476 bool shift = event.shiftKey(); 1145 if (DOMEVENT_KEYDOWN.equals(type) || DOMEVENT_KEYUP.equals(type)) {
1477 bool alt = event.altKey(); 1146 DOMKeyboardEvent event = new DOMKeyboardEvent(evtId);
1478 bool meta = event.metaKey(); 1147
1479 Event mouseEvent = new Event();
1480 mouseEvent.type = DWT.MouseWheel;
1481 mouseEvent.widget = browser;
1482 mouseEvent.x = clientX;
1483 mouseEvent.y = clientY;
1484 mouseEvent.count = delta / 120;
1485 mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0);
1486 browser.notifyListeners(mouseEvent.type, mouseEvent);
1487 return;
1488 }
1489
1490 /* mouse event */
1491
1492 DOMMouseEvent event = new DOMMouseEvent(evtId);
1493
1494 int clientX = event.clientX();
1495 int clientY = event.clientY();
1496 int detail = event.detail();
1497 int button = event.button();
1498 bool ctrl = event.ctrlKey(); 1148 bool ctrl = event.ctrlKey();
1499 bool shift = event.shiftKey(); 1149 bool shift = event.shiftKey();
1500 bool alt = event.altKey(); 1150 bool alt = event.altKey();
1501 bool meta = event.metaKey(); 1151 bool meta = event.metaKey();
1502 1152 int keyCode = event.keyCode();
1153 int charCode = event.charCode();
1154
1155 Event keyEvent = new Event();
1156 keyEvent.widget = browser;
1157 if (DOMEVENT_KEYDOWN.equals(type)) {
1158 keyEvent.type = DWT.KeyDown;
1159 } else {
1160 keyEvent.type = DWT.KeyUp;
1161 }
1162 keyEvent.keyCode = translateKey(keyCode);
1163 keyEvent.character = (char)charCode;
1164 keyEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0);
1165 browser.notifyListeners(keyEvent.type, keyEvent);
1166 if (!keyEvent.doit) {
1167 event.preventDefault();
1168 }
1169 return;
1170 }
1171
1172 if (DOMEVENT_MOUSEWHEEL.equals(type)) {
1173 DOMWheelEvent event = new DOMWheelEvent(evtId);
1174 int clientX = event.clientX();
1175 int clientY = event.clientY();
1176 int delta = event.wheelDelta();
1177 bool ctrl = event.ctrlKey();
1178 bool shift = event.shiftKey();
1179 bool alt = event.altKey();
1180 bool meta = event.metaKey();
1503 Event mouseEvent = new Event(); 1181 Event mouseEvent = new Event();
1182 mouseEvent.type = DWT.MouseWheel;
1504 mouseEvent.widget = browser; 1183 mouseEvent.widget = browser;
1505 mouseEvent.x = clientX; 1184 mouseEvent.x = clientX; mouseEvent.y = clientY;
1506 mouseEvent.y = clientY; 1185 mouseEvent.count = delta / 120;
1507 mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); 1186 mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0);
1508 if (DOMEVENT_MOUSEDOWN.opEquals(type)) 1187 browser.notifyListeners (mouseEvent.type, mouseEvent);
1509 { 1188 return;
1510 mouseEvent.type = DWT.MouseDown; 1189 }
1511 mouseEvent.button = button + 1; 1190
1512 mouseEvent.count = detail; 1191 /* mouse event */
1513 } 1192
1514 else if (DOMEVENT_MOUSEUP.opEquals(type)) 1193 DOMMouseEvent event = new DOMMouseEvent(evtId);
1515 { 1194
1516 mouseEvent.type = DWT.MouseUp; 1195 int clientX = event.clientX();
1517 mouseEvent.button = button + 1; 1196 int clientY = event.clientY();
1518 mouseEvent.count = detail; 1197 int detail = event.detail();
1519 switch (mouseEvent.button) 1198 int button = event.button();
1520 { 1199 bool ctrl = event.ctrlKey();
1521 case 1: 1200 bool shift = event.shiftKey();
1522 mouseEvent.stateMask |= DWT.BUTTON1; 1201 bool alt = event.altKey();
1523 break; 1202 bool meta = event.metaKey();
1524 case 2: 1203
1525 mouseEvent.stateMask |= DWT.BUTTON2; 1204 Event mouseEvent = new Event ();
1526 break; 1205 mouseEvent.widget = browser;
1527 case 3: 1206 mouseEvent.x = clientX; mouseEvent.y = clientY;
1528 mouseEvent.stateMask |= DWT.BUTTON3; 1207 mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0);
1529 break; 1208 if (DOMEVENT_MOUSEDOWN.equals (type)) {
1530 case 4: 1209 mouseEvent.type = DWT.MouseDown;
1531 mouseEvent.stateMask |= DWT.BUTTON4; 1210 mouseEvent.button = button + 1;
1532 break; 1211 mouseEvent.count = detail;
1533 case 5: 1212 } else if (DOMEVENT_MOUSEUP.equals (type)) {
1534 mouseEvent.stateMask |= DWT.BUTTON5; 1213 mouseEvent.type = DWT.MouseUp;
1535 break; 1214 mouseEvent.button = button + 1;
1536 } 1215 mouseEvent.count = detail;
1537 } 1216 switch (mouseEvent.button) {
1538 else if (DOMEVENT_MOUSEMOVE.opEquals(type)) 1217 case 1: mouseEvent.stateMask |= DWT.BUTTON1; break;
1539 { 1218 case 2: mouseEvent.stateMask |= DWT.BUTTON2; break;
1540 /* 1219 case 3: mouseEvent.stateMask |= DWT.BUTTON3; break;
1541 * Bug in Safari. Spurious and redundant mousemove events are received in 1220 case 4: mouseEvent.stateMask |= DWT.BUTTON4; break;
1542 * various contexts, including following every MouseUp. The workaround is 1221 case 5: mouseEvent.stateMask |= DWT.BUTTON5; break;
1543 * to not fire MouseMove events whose x and y values match the last MouseMove 1222 }
1544 */ 1223 } else if (DOMEVENT_MOUSEMOVE.equals (type)) {
1545 if (mouseEvent.x is lastMouseMoveX && mouseEvent.y is lastMouseMoveY) 1224 /*
1546 return; 1225 * Bug in Safari. Spurious and redundant mousemove events are received in
1547 mouseEvent.type = DWT.MouseMove; 1226 * various contexts, including following every MouseUp. The workaround is
1548 lastMouseMoveX = mouseEvent.x; 1227 * to not fire MouseMove events whose x and y values match the last MouseMove
1549 lastMouseMoveY = mouseEvent.y; 1228 */
1550 } 1229 if (mouseEvent.x is lastMouseMoveX && mouseEvent.y is lastMouseMoveY) return;
1551 1230 mouseEvent.type = DWT.MouseMove;
1552 browser.notifyListeners(mouseEvent.type, mouseEvent); 1231 lastMouseMoveX = mouseEvent.x; lastMouseMoveY = mouseEvent.y;
1553 if (detail is 2 && DOMEVENT_MOUSEDOWN.opEquals(type)) 1232 }
1554 { 1233
1555 mouseEvent = new Event(); 1234 browser.notifyListeners (mouseEvent.type, mouseEvent);
1556 mouseEvent.widget = browser; 1235 if (detail is 2 && DOMEVENT_MOUSEDOWN.equals (type)) {
1557 mouseEvent.x = clientX; 1236 mouseEvent = new Event ();
1558 mouseEvent.y = clientY; 1237 mouseEvent.widget = browser;
1559 mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0); 1238 mouseEvent.x = clientX; mouseEvent.y = clientY;
1560 mouseEvent.type = DWT.MouseDoubleClick; 1239 mouseEvent.stateMask = (alt ? DWT.ALT : 0) | (ctrl ? DWT.CTRL : 0) | (shift ? DWT.SHIFT : 0) | (meta ? DWT.COMMAND : 0);
1561 mouseEvent.button = button + 1; 1240 mouseEvent.type = DWT.MouseDoubleClick;
1562 mouseEvent.count = detail; 1241 mouseEvent.button = button + 1;
1563 browser.notifyListeners(mouseEvent.type, mouseEvent); 1242 mouseEvent.count = detail;
1564 } 1243 browser.notifyListeners (mouseEvent.type, mouseEvent);
1565 } 1244 }
1566 } 1245 }
1246 }