WebCore:
[WebKit-https.git] / WebCore / bridge / mac / BrowserExtensionMac.mm
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "config.h"
27 #import "BrowserExtensionMac.h"
28
29 #import "FrameTree.h"
30 #import "KWQExceptions.h"
31 #import "MacFrame.h"
32 #import "WebCoreFrameBridge.h"
33 #import "WebCorePageBridge.h"
34 #import <kxmlcore/Assertions.h>
35
36 namespace WebCore {
37
38 BrowserExtensionMac::BrowserExtensionMac(Frame *frame)
39     : m_frame(Mac(frame))
40 {
41 }
42
43 void BrowserExtensionMac::openURLRequest(const KURL& url, const URLArgs& args)
44 {
45     if (url.protocol().lower() == "javascript") {
46         m_frame->createEmptyDocument();
47         m_frame->replaceContentsWithScriptResult(url);
48      } else {
49         m_frame->openURLRequest(url, args);
50     }
51 }
52
53 void BrowserExtensionMac::openURLNotify()
54 {
55 }
56
57 void BrowserExtensionMac::createNewWindow(const KURL &url, const URLArgs &urlArgs) 
58 {
59     createNewWindow(url, urlArgs, WindowArgs(), NULL);
60 }
61
62 void BrowserExtensionMac::createNewWindow(const KURL &url, 
63                                                 const URLArgs &urlArgs, 
64                                                 const WindowArgs &winArgs, 
65                                                 Frame*& part)
66 {
67     createNewWindow(url, urlArgs, winArgs, &part);
68 }
69
70 void BrowserExtensionMac::createNewWindow(const KURL &url, 
71                                                 const URLArgs &urlArgs, 
72                                                 const WindowArgs &winArgs, 
73                                                 Frame** partResult)
74
75     KWQ_BLOCK_EXCEPTIONS;
76
77     ASSERT(!winArgs.dialog || urlArgs.frameName.isEmpty());
78
79     if (partResult)
80         *partResult = NULL;
81
82     NSString *frameName = urlArgs.frameName.length() == 0 ? nil : urlArgs.frameName.getNSString();
83     if (frameName) {
84         // FIXME: Can't we just use m_frame->findFrame?
85         if (WebCoreFrameBridge *bridge = [m_frame->bridge() findFrameNamed:frameName]) {
86             if (!url.isEmpty()) {
87                 DOMString argsReferrer = urlArgs.metaData().get("referrer");
88                 NSString *referrer;
89                 if (!argsReferrer.isEmpty())
90                     referrer = argsReferrer;
91                 else
92                     referrer = [m_frame->bridge() referrer];
93
94                 [bridge loadURL:url.getNSURL() 
95                        referrer:referrer 
96                          reload:urlArgs.reload 
97                     userGesture:true 
98                          target:nil 
99                 triggeringEvent:nil 
100                            form:nil 
101                      formValues:nil];
102             }
103
104             [bridge focusWindow];
105
106             if (partResult)
107                 *partResult = [bridge impl];
108
109             return;
110         }
111     }
112     
113     WebCorePageBridge *page;
114     if (winArgs.dialog)
115         page = [m_frame->bridge() createModalDialogWithURL:url.getNSURL()];
116     else
117         page = [m_frame->bridge() createWindowWithURL:url.getNSURL()];
118     if (!page)
119         return;
120     
121     WebCoreFrameBridge *bridge = [page mainFrame];
122     if ([bridge impl])
123         [bridge impl]->tree()->setName(urlArgs.frameName);
124     
125     if (partResult)
126         *partResult = [bridge impl];
127     
128     [bridge setToolbarsVisible:winArgs.toolBarVisible || winArgs.locationBarVisible];
129     [bridge setStatusbarVisible:winArgs.statusBarVisible];
130     [bridge setScrollbarsVisible:winArgs.scrollBarsVisible];
131     [bridge setWindowIsResizable:winArgs.resizable];
132     
133     NSRect windowFrame = [bridge windowFrame];
134
135     NSSize size = { 1, 1 }; // workaround for 4213314
136     NSSize scaleRect = [[page outerView] convertSize:size toView:nil];
137     float scaleX = scaleRect.width;
138     float scaleY = scaleRect.height;
139
140     // In JavaScript, the coordinate system of the window is the same as the coordinate system
141     // of the WebView, so we translate 'left' and 'top' from WebView coordinates to window coordinates.
142     // (If the screen resolution is scaled, window coordinates won't match WebView coordinates.)
143     if (winArgs.xSet)
144         windowFrame.origin.x = winArgs.x * scaleX;
145     if (winArgs.ySet) {
146         // In JavaScript, (0, 0) is the top left corner of the screen.
147         float screenTop = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]);
148         windowFrame.origin.y = screenTop - (winArgs.y * scaleY) - windowFrame.size.height;
149     }
150
151     // 'width' and 'height' specify the dimensions of the WebView, but we can only resize the window, 
152     // so we compute a delta, translate it to window coordinates, and use the translated delta 
153     // to resize the window.
154     NSRect webViewFrame = [[page outerView] frame];
155     if (winArgs.widthSet) {
156         float widthDelta = (winArgs.width - webViewFrame.size.width) * scaleX;
157         windowFrame.size.width += widthDelta;
158     }
159     if (winArgs.heightSet) {
160         float heightDelta = (winArgs.height - webViewFrame.size.height) * scaleY;
161         windowFrame.size.height += heightDelta;
162         windowFrame.origin.y -= heightDelta;
163     }
164     
165     [bridge setWindowFrame:windowFrame];
166     
167     [bridge showWindow];
168     
169     KWQ_UNBLOCK_EXCEPTIONS;
170 }
171
172 void BrowserExtensionMac::setIconURL(const KURL &url)
173 {
174     KWQ_BLOCK_EXCEPTIONS;
175     [m_frame->bridge() setIconURL:url.getNSURL()];
176     KWQ_UNBLOCK_EXCEPTIONS;
177 }
178
179 void BrowserExtensionMac::setTypedIconURL(const KURL &url, const QString &type)
180 {
181     KWQ_BLOCK_EXCEPTIONS;
182     [m_frame->bridge() setIconURL:url.getNSURL() withType:type.getNSString()];
183     KWQ_UNBLOCK_EXCEPTIONS;
184 }
185
186 int BrowserExtensionMac::getHistoryLength()
187 {
188     return [m_frame->bridge() historyLength];
189 }
190
191 void BrowserExtensionMac::goBackOrForward(int distance)
192 {
193     KWQ_BLOCK_EXCEPTIONS;
194     [m_frame->bridge() goBackOrForward:distance];
195     KWQ_UNBLOCK_EXCEPTIONS;
196 }
197
198 bool BrowserExtensionMac::canRunModal()
199 {
200     KWQ_BLOCK_EXCEPTIONS;
201     return [m_frame->bridge() canRunModal];
202     KWQ_UNBLOCK_EXCEPTIONS;
203     return false;
204 }
205
206 bool BrowserExtensionMac::canRunModalNow()
207 {
208     KWQ_BLOCK_EXCEPTIONS;
209     return [m_frame->bridge() canRunModalNow];
210     KWQ_UNBLOCK_EXCEPTIONS;
211     return false;
212 }
213
214 void BrowserExtensionMac::runModal()
215 {
216     KWQ_BLOCK_EXCEPTIONS;
217     [m_frame->bridge() runModal];
218     KWQ_UNBLOCK_EXCEPTIONS;
219 }
220
221 }