1 : /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
2 : /* vim: set sw=4 ts=8 et tw=80 : */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Content App.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * The Mozilla Foundation.
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "TabChild.h"
40 : #include "mozilla/IntentionalCrash.h"
41 : #include "mozilla/dom/PContentChild.h"
42 : #include "mozilla/dom/PContentDialogChild.h"
43 : #include "mozilla/layers/PLayersChild.h"
44 : #include "mozilla/layout/RenderFrameChild.h"
45 : #include "mozilla/docshell/OfflineCacheUpdateChild.h"
46 :
47 : #include "BasicLayers.h"
48 : #include "nsIWebBrowser.h"
49 : #include "nsIWebBrowserSetup.h"
50 : #include "nsEmbedCID.h"
51 : #include "nsComponentManagerUtils.h"
52 : #include "nsIBaseWindow.h"
53 : #include "nsIDOMWindow.h"
54 : #include "nsIWebProgress.h"
55 : #include "nsIDocShell.h"
56 : #include "nsIDocShellTreeItem.h"
57 : #include "nsThreadUtils.h"
58 : #include "nsIInterfaceRequestorUtils.h"
59 : #include "mozilla/ipc/DocumentRendererChild.h"
60 : #include "nsIInterfaceRequestorUtils.h"
61 : #include "nsPIDOMWindow.h"
62 : #include "nsIDOMWindowUtils.h"
63 : #include "nsISupportsImpl.h"
64 : #include "nsIURI.h"
65 : #include "nsIWebBrowserFocus.h"
66 : #include "nsIDOMEvent.h"
67 : #include "nsIPrivateDOMEvent.h"
68 : #include "nsIComponentManager.h"
69 : #include "nsIServiceManager.h"
70 : #include "nsIJSRuntimeService.h"
71 : #include "nsContentUtils.h"
72 : #include "nsIDOMClassInfo.h"
73 : #include "nsIXPCSecurityManager.h"
74 : #include "nsIJSContextStack.h"
75 : #include "nsComponentManagerUtils.h"
76 : #include "nsIScriptSecurityManager.h"
77 : #include "nsScriptLoader.h"
78 : #include "nsPIWindowRoot.h"
79 : #include "nsIScriptContext.h"
80 : #include "nsInterfaceHashtable.h"
81 : #include "nsPresContext.h"
82 : #include "nsIDocument.h"
83 : #include "nsIDOMDocument.h"
84 : #include "nsIScriptGlobalObject.h"
85 : #include "nsWeakReference.h"
86 : #include "nsISecureBrowserUI.h"
87 : #include "nsISSLStatusProvider.h"
88 : #include "nsSerializationHelper.h"
89 : #include "nsIFrame.h"
90 : #include "nsIView.h"
91 : #include "nsEventListenerManager.h"
92 : #include "PCOMContentPermissionRequestChild.h"
93 : #include "xpcpublic.h"
94 :
95 : using namespace mozilla::dom;
96 : using namespace mozilla::ipc;
97 : using namespace mozilla::layers;
98 : using namespace mozilla::layout;
99 : using namespace mozilla::docshell;
100 :
101 0 : NS_IMPL_ISUPPORTS1(ContentListener, nsIDOMEventListener)
102 :
103 : NS_IMETHODIMP
104 0 : ContentListener::HandleEvent(nsIDOMEvent* aEvent)
105 : {
106 0 : RemoteDOMEvent remoteEvent;
107 0 : remoteEvent.mEvent = do_QueryInterface(aEvent);
108 0 : NS_ENSURE_STATE(remoteEvent.mEvent);
109 0 : mTabChild->SendEvent(remoteEvent);
110 0 : return NS_OK;
111 : }
112 :
113 : class ContentDialogChild : public PContentDialogChild
114 0 : {
115 : public:
116 : virtual bool Recv__delete__(const InfallibleTArray<int>& aIntParams,
117 : const InfallibleTArray<nsString>& aStringParams);
118 : };
119 :
120 :
121 0 : TabChild::TabChild(PRUint32 aChromeFlags)
122 : : mRemoteFrame(nsnull)
123 : , mTabChildGlobal(nsnull)
124 : , mChromeFlags(aChromeFlags)
125 : , mOuterRect(0, 0, 0, 0)
126 0 : , mLastBackgroundColor(NS_RGB(255, 255, 255))
127 : {
128 0 : printf("creating %d!\n", NS_IsMainThread());
129 0 : }
130 :
131 : nsresult
132 0 : TabChild::Init()
133 : {
134 0 : nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
135 0 : if (!webBrowser) {
136 0 : NS_ERROR("Couldn't create a nsWebBrowser?");
137 0 : return NS_ERROR_FAILURE;
138 : }
139 :
140 0 : webBrowser->SetContainerWindow(this);
141 0 : mWebNav = do_QueryInterface(webBrowser);
142 0 : NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
143 :
144 0 : nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(mWebNav));
145 0 : docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
146 0 : return NS_OK;
147 : }
148 :
149 0 : NS_INTERFACE_MAP_BEGIN(TabChild)
150 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
151 0 : NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
152 0 : NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
153 0 : NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
154 0 : NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow2)
155 0 : NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
156 0 : NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
157 0 : NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
158 0 : NS_INTERFACE_MAP_ENTRY(nsITabChild)
159 0 : NS_INTERFACE_MAP_ENTRY(nsIDialogCreator)
160 0 : NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference)
161 0 : NS_INTERFACE_MAP_END
162 :
163 0 : NS_IMPL_ADDREF(TabChild)
164 0 : NS_IMPL_RELEASE(TabChild)
165 :
166 : NS_IMETHODIMP
167 0 : TabChild::SetStatus(PRUint32 aStatusType, const PRUnichar* aStatus)
168 : {
169 : // FIXME/bug 617804: should the platform support this?
170 0 : return NS_OK;
171 : }
172 :
173 : NS_IMETHODIMP
174 0 : TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
175 : {
176 0 : NS_NOTREACHED("TabChild::GetWebBrowser not supported in TabChild");
177 :
178 0 : return NS_ERROR_NOT_IMPLEMENTED;
179 : }
180 :
181 : NS_IMETHODIMP
182 0 : TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser)
183 : {
184 0 : NS_NOTREACHED("TabChild::SetWebBrowser not supported in TabChild");
185 :
186 0 : return NS_ERROR_NOT_IMPLEMENTED;
187 : }
188 :
189 : NS_IMETHODIMP
190 0 : TabChild::GetChromeFlags(PRUint32* aChromeFlags)
191 : {
192 0 : *aChromeFlags = mChromeFlags;
193 0 : return NS_OK;
194 : }
195 :
196 : NS_IMETHODIMP
197 0 : TabChild::SetChromeFlags(PRUint32 aChromeFlags)
198 : {
199 0 : NS_NOTREACHED("trying to SetChromeFlags from content process?");
200 :
201 0 : return NS_ERROR_NOT_IMPLEMENTED;
202 : }
203 :
204 : NS_IMETHODIMP
205 0 : TabChild::DestroyBrowserWindow()
206 : {
207 0 : NS_NOTREACHED("TabChild::SetWebBrowser not supported in TabChild");
208 :
209 0 : return NS_ERROR_NOT_IMPLEMENTED;
210 : }
211 :
212 : NS_IMETHODIMP
213 0 : TabChild::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
214 : {
215 0 : NS_NOTREACHED("TabChild::SizeBrowserTo not supported in TabChild");
216 :
217 0 : return NS_ERROR_NOT_IMPLEMENTED;
218 : }
219 :
220 : NS_IMETHODIMP
221 0 : TabChild::ShowAsModal()
222 : {
223 0 : NS_NOTREACHED("TabChild::ShowAsModal not supported in TabChild");
224 :
225 0 : return NS_ERROR_NOT_IMPLEMENTED;
226 : }
227 :
228 : NS_IMETHODIMP
229 0 : TabChild::IsWindowModal(bool* aRetVal)
230 : {
231 0 : *aRetVal = false;
232 0 : return NS_OK;
233 : }
234 :
235 : NS_IMETHODIMP
236 0 : TabChild::ExitModalEventLoop(nsresult aStatus)
237 : {
238 0 : NS_NOTREACHED("TabChild::ExitModalEventLoop not supported in TabChild");
239 :
240 0 : return NS_ERROR_NOT_IMPLEMENTED;
241 : }
242 :
243 : NS_IMETHODIMP
244 0 : TabChild::SetStatusWithContext(PRUint32 aStatusType,
245 : const nsAString& aStatusText,
246 : nsISupports* aStatusContext)
247 : {
248 : // FIXME/bug 617804: should the platform support this?
249 0 : return NS_OK;
250 : }
251 :
252 : NS_IMETHODIMP
253 0 : TabChild::SetDimensions(PRUint32 aFlags, PRInt32 aX, PRInt32 aY,
254 : PRInt32 aCx, PRInt32 aCy)
255 : {
256 0 : NS_NOTREACHED("TabChild::SetDimensions not supported in TabChild");
257 :
258 0 : return NS_ERROR_NOT_IMPLEMENTED;
259 : }
260 :
261 : NS_IMETHODIMP
262 0 : TabChild::GetDimensions(PRUint32 aFlags, PRInt32* aX,
263 : PRInt32* aY, PRInt32* aCx, PRInt32* aCy)
264 : {
265 0 : if (aX) {
266 0 : *aX = mOuterRect.x;
267 : }
268 0 : if (aY) {
269 0 : *aY = mOuterRect.y;
270 : }
271 0 : if (aCx) {
272 0 : *aCx = mOuterRect.width;
273 : }
274 0 : if (aCy) {
275 0 : *aCy = mOuterRect.height;
276 : }
277 :
278 0 : return NS_OK;
279 : }
280 :
281 : NS_IMETHODIMP
282 0 : TabChild::SetFocus()
283 : {
284 0 : NS_NOTREACHED("TabChild::SetFocus not supported in TabChild");
285 :
286 0 : return NS_ERROR_NOT_IMPLEMENTED;
287 : }
288 :
289 : NS_IMETHODIMP
290 0 : TabChild::GetVisibility(bool* aVisibility)
291 : {
292 0 : *aVisibility = true;
293 0 : return NS_OK;
294 : }
295 :
296 : NS_IMETHODIMP
297 0 : TabChild::SetVisibility(bool aVisibility)
298 : {
299 : // should the platform support this? Bug 666365
300 0 : return NS_OK;
301 : }
302 :
303 : NS_IMETHODIMP
304 0 : TabChild::GetTitle(PRUnichar** aTitle)
305 : {
306 0 : NS_NOTREACHED("TabChild::GetTitle not supported in TabChild");
307 :
308 0 : return NS_ERROR_NOT_IMPLEMENTED;
309 : }
310 :
311 : NS_IMETHODIMP
312 0 : TabChild::SetTitle(const PRUnichar* aTitle)
313 : {
314 : // FIXME/bug 617804: should the platform support this?
315 0 : return NS_OK;
316 : }
317 :
318 : NS_IMETHODIMP
319 0 : TabChild::GetSiteWindow(void** aSiteWindow)
320 : {
321 0 : NS_NOTREACHED("TabChild::GetSiteWindow not supported in TabChild");
322 :
323 0 : return NS_ERROR_NOT_IMPLEMENTED;
324 : }
325 :
326 : NS_IMETHODIMP
327 0 : TabChild::Blur()
328 : {
329 0 : NS_NOTREACHED("TabChild::Blur not supported in TabChild");
330 :
331 0 : return NS_ERROR_NOT_IMPLEMENTED;
332 : }
333 :
334 : NS_IMETHODIMP
335 0 : TabChild::FocusNextElement()
336 : {
337 0 : SendMoveFocus(true);
338 0 : return NS_OK;
339 : }
340 :
341 : NS_IMETHODIMP
342 0 : TabChild::FocusPrevElement()
343 : {
344 0 : SendMoveFocus(false);
345 0 : return NS_OK;
346 : }
347 :
348 : NS_IMETHODIMP
349 0 : TabChild::GetInterface(const nsIID & aIID, void **aSink)
350 : {
351 : // XXXbz should we restrict the set of interfaces we hand out here?
352 : // See bug 537429
353 0 : return QueryInterface(aIID, aSink);
354 : }
355 :
356 : NS_IMETHODIMP
357 0 : TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags,
358 : bool aCalledFromJS,
359 : bool aPositionSpecified, bool aSizeSpecified,
360 : nsIURI* aURI, const nsAString& aName,
361 : const nsACString& aFeatures, bool* aWindowIsNew,
362 : nsIDOMWindow** aReturn)
363 : {
364 0 : *aReturn = nsnull;
365 :
366 : PBrowserChild* newChild;
367 0 : if (!CallCreateWindow(&newChild)) {
368 0 : return NS_ERROR_NOT_AVAILABLE;
369 : }
370 :
371 0 : *aWindowIsNew = true;
372 : nsCOMPtr<nsIDOMWindow> win =
373 0 : do_GetInterface(static_cast<TabChild*>(newChild)->mWebNav);
374 0 : win.forget(aReturn);
375 0 : return NS_OK;
376 : }
377 :
378 1464 : static nsInterfaceHashtable<nsVoidPtrHashKey, nsIDialogParamBlock> gActiveDialogs;
379 :
380 : NS_IMETHODIMP
381 0 : TabChild::OpenDialog(PRUint32 aType, const nsACString& aName,
382 : const nsACString& aFeatures,
383 : nsIDialogParamBlock* aArguments,
384 : nsIDOMElement* aFrameElement)
385 : {
386 0 : if (!gActiveDialogs.IsInitialized()) {
387 0 : NS_ENSURE_STATE(gActiveDialogs.Init());
388 : }
389 0 : InfallibleTArray<PRInt32> intParams;
390 0 : InfallibleTArray<nsString> stringParams;
391 0 : ParamsToArrays(aArguments, intParams, stringParams);
392 : PContentDialogChild* dialog =
393 0 : SendPContentDialogConstructor(aType, nsCString(aName),
394 0 : nsCString(aFeatures), intParams, stringParams);
395 0 : NS_ENSURE_STATE(gActiveDialogs.Put(dialog, aArguments));
396 0 : nsIThread *thread = NS_GetCurrentThread();
397 0 : while (gActiveDialogs.GetWeak(dialog)) {
398 0 : if (!NS_ProcessNextEvent(thread)) {
399 0 : break;
400 : }
401 : }
402 0 : return NS_OK;
403 : }
404 :
405 : bool
406 0 : ContentDialogChild::Recv__delete__(const InfallibleTArray<int>& aIntParams,
407 : const InfallibleTArray<nsString>& aStringParams)
408 : {
409 0 : nsCOMPtr<nsIDialogParamBlock> params;
410 0 : if (gActiveDialogs.Get(this, getter_AddRefs(params))) {
411 0 : TabChild::ArraysToParams(aIntParams, aStringParams, params);
412 0 : gActiveDialogs.Remove(this);
413 : }
414 0 : return true;
415 : }
416 :
417 : void
418 0 : TabChild::ParamsToArrays(nsIDialogParamBlock* aParams,
419 : InfallibleTArray<int>& aIntParams,
420 : InfallibleTArray<nsString>& aStringParams)
421 : {
422 0 : if (aParams) {
423 0 : for (PRInt32 i = 0; i < 8; ++i) {
424 0 : PRInt32 val = 0;
425 0 : aParams->GetInt(i, &val);
426 0 : aIntParams.AppendElement(val);
427 : }
428 0 : PRInt32 j = 0;
429 0 : nsXPIDLString strVal;
430 0 : while (NS_SUCCEEDED(aParams->GetString(j, getter_Copies(strVal)))) {
431 0 : aStringParams.AppendElement(strVal);
432 0 : ++j;
433 : }
434 : }
435 0 : }
436 :
437 : void
438 0 : TabChild::ArraysToParams(const InfallibleTArray<int>& aIntParams,
439 : const InfallibleTArray<nsString>& aStringParams,
440 : nsIDialogParamBlock* aParams)
441 : {
442 0 : if (aParams) {
443 0 : for (PRInt32 i = 0; PRUint32(i) < aIntParams.Length(); ++i) {
444 0 : aParams->SetInt(i, aIntParams[i]);
445 : }
446 0 : for (PRInt32 j = 0; PRUint32(j) < aStringParams.Length(); ++j) {
447 0 : aParams->SetString(j, aStringParams[j].get());
448 : }
449 : }
450 0 : }
451 :
452 : void
453 0 : TabChild::DestroyWindow()
454 : {
455 0 : nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
456 0 : if (baseWindow)
457 0 : baseWindow->Destroy();
458 :
459 : // NB: the order of mWidget->Destroy() and mRemoteFrame->Destroy()
460 : // is important: we want to kill off remote layers before their
461 : // frames
462 0 : if (mWidget) {
463 0 : mWidget->Destroy();
464 : }
465 :
466 0 : if (mRemoteFrame) {
467 0 : mRemoteFrame->Destroy();
468 0 : mRemoteFrame = nsnull;
469 : }
470 0 : }
471 :
472 : void
473 0 : TabChild::ActorDestroy(ActorDestroyReason why)
474 : {
475 0 : if (mTabChildGlobal) {
476 : // The messageManager relays messages via the TabChild which
477 : // no longer exists.
478 : static_cast<nsFrameMessageManager*>
479 0 : (mTabChildGlobal->mMessageManager.get())->Disconnect();
480 0 : mTabChildGlobal->mMessageManager = nsnull;
481 : }
482 0 : }
483 :
484 0 : TabChild::~TabChild()
485 : {
486 0 : nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(mWebNav);
487 0 : if (webBrowser) {
488 0 : webBrowser->SetContainerWindow(nsnull);
489 : }
490 0 : if (mCx) {
491 0 : DestroyCx();
492 : }
493 :
494 0 : if (mTabChildGlobal) {
495 0 : nsEventListenerManager* elm = mTabChildGlobal->GetListenerManager(false);
496 0 : if (elm) {
497 0 : elm->Disconnect();
498 : }
499 0 : mTabChildGlobal->mTabChild = nsnull;
500 : }
501 0 : }
502 :
503 : bool
504 0 : TabChild::RecvLoadURL(const nsCString& uri)
505 : {
506 0 : printf("loading %s, %d\n", uri.get(), NS_IsMainThread());
507 :
508 0 : nsresult rv = mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri).get(),
509 : nsIWebNavigation::LOAD_FLAGS_NONE,
510 0 : NULL, NULL, NULL);
511 0 : if (NS_FAILED(rv)) {
512 0 : NS_WARNING("mWebNav->LoadURI failed. Eating exception, what else can I do?");
513 : }
514 :
515 0 : return true;
516 : }
517 :
518 : bool
519 0 : TabChild::RecvShow(const nsIntSize& size)
520 : {
521 0 : printf("[TabChild] SHOW (w,h)= (%d, %d)\n", size.width, size.height);
522 :
523 0 : nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
524 0 : if (!baseWindow) {
525 0 : NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
526 0 : return false;
527 : }
528 :
529 0 : if (!InitWidget(size)) {
530 : // We can fail to initialize our widget if the <browser
531 : // remote> has already been destroyed, and we couldn't hook
532 : // into the parent-process's layer system. That's not a fatal
533 : // error.
534 0 : return true;
535 : }
536 :
537 0 : baseWindow->InitWindow(0, mWidget,
538 0 : 0, 0, size.width, size.height);
539 0 : baseWindow->Create();
540 0 : baseWindow->SetVisibility(true);
541 :
542 : // IPC uses a WebBrowser object for which DNS prefetching is turned off
543 : // by default. But here we really want it, so enable it explicitly
544 0 : nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup = do_QueryInterface(baseWindow);
545 0 : if (webBrowserSetup) {
546 0 : webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH,
547 0 : true);
548 : } else {
549 : NS_WARNING("baseWindow doesn't QI to nsIWebBrowserSetup, skipping "
550 0 : "DNS prefetching enable step.");
551 : }
552 :
553 0 : return InitTabChildGlobal();
554 : }
555 :
556 : bool
557 0 : TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size)
558 : {
559 : #ifdef DEBUG
560 0 : printf("[TabChild] Update Dimensions to (x,y,w,h)= (%ud, %ud, %ud, %ud) and move to (w,h)= (%ud, %ud)\n", rect.x, rect.y, rect.width, rect.height, size.width, size.height);
561 : #endif
562 :
563 0 : if (!mRemoteFrame) {
564 0 : return true;
565 : }
566 :
567 0 : mOuterRect.x = rect.x;
568 0 : mOuterRect.y = rect.y;
569 0 : mOuterRect.width = rect.width;
570 0 : mOuterRect.height = rect.height;
571 :
572 0 : mWidget->Resize(0, 0, size.width, size.height,
573 0 : true);
574 :
575 0 : nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(mWebNav);
576 0 : baseWin->SetPositionAndSize(0, 0, size.width, size.height,
577 0 : true);
578 :
579 0 : return true;
580 : }
581 :
582 : bool
583 0 : TabChild::RecvActivate()
584 : {
585 0 : nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
586 0 : browser->Activate();
587 0 : return true;
588 : }
589 :
590 0 : bool TabChild::RecvDeactivate()
591 : {
592 0 : nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(mWebNav);
593 0 : browser->Deactivate();
594 0 : return true;
595 : }
596 :
597 : bool
598 0 : TabChild::RecvMouseEvent(const nsString& aType,
599 : const float& aX,
600 : const float& aY,
601 : const PRInt32& aButton,
602 : const PRInt32& aClickCount,
603 : const PRInt32& aModifiers,
604 : const bool& aIgnoreRootScrollFrame)
605 : {
606 0 : nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
607 0 : nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);
608 0 : NS_ENSURE_TRUE(utils, true);
609 0 : utils->SendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers,
610 0 : aIgnoreRootScrollFrame);
611 0 : return true;
612 : }
613 :
614 : bool
615 0 : TabChild::RecvRealMouseEvent(const nsMouseEvent& event)
616 : {
617 0 : nsMouseEvent localEvent(event);
618 0 : DispatchWidgetEvent(localEvent);
619 0 : return true;
620 : }
621 :
622 : bool
623 0 : TabChild::RecvMouseScrollEvent(const nsMouseScrollEvent& event)
624 : {
625 0 : nsMouseScrollEvent localEvent(event);
626 0 : DispatchWidgetEvent(localEvent);
627 0 : return true;
628 : }
629 :
630 :
631 : bool
632 0 : TabChild::RecvRealKeyEvent(const nsKeyEvent& event)
633 : {
634 0 : nsKeyEvent localEvent(event);
635 0 : DispatchWidgetEvent(localEvent);
636 0 : return true;
637 : }
638 :
639 : bool
640 0 : TabChild::RecvKeyEvent(const nsString& aType,
641 : const PRInt32& aKeyCode,
642 : const PRInt32& aCharCode,
643 : const PRInt32& aModifiers,
644 : const bool& aPreventDefault)
645 : {
646 0 : nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
647 0 : nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);
648 0 : NS_ENSURE_TRUE(utils, true);
649 0 : bool ignored = false;
650 0 : utils->SendKeyEvent(aType, aKeyCode, aCharCode,
651 0 : aModifiers, aPreventDefault, &ignored);
652 0 : return true;
653 : }
654 :
655 : bool
656 0 : TabChild::RecvCompositionEvent(const nsCompositionEvent& event)
657 : {
658 0 : nsCompositionEvent localEvent(event);
659 0 : DispatchWidgetEvent(localEvent);
660 0 : return true;
661 : }
662 :
663 : bool
664 0 : TabChild::RecvTextEvent(const nsTextEvent& event)
665 : {
666 0 : nsTextEvent localEvent(event);
667 0 : DispatchWidgetEvent(localEvent);
668 0 : IPC::ParamTraits<nsTextEvent>::Free(event);
669 0 : return true;
670 : }
671 :
672 : bool
673 0 : TabChild::RecvSelectionEvent(const nsSelectionEvent& event)
674 : {
675 0 : nsSelectionEvent localEvent(event);
676 0 : DispatchWidgetEvent(localEvent);
677 0 : return true;
678 : }
679 :
680 : bool
681 0 : TabChild::DispatchWidgetEvent(nsGUIEvent& event)
682 : {
683 0 : if (!mWidget)
684 0 : return false;
685 :
686 : nsEventStatus status;
687 0 : event.widget = mWidget;
688 0 : NS_ENSURE_SUCCESS(mWidget->DispatchEvent(&event, status), false);
689 0 : return true;
690 : }
691 :
692 : PDocumentRendererChild*
693 0 : TabChild::AllocPDocumentRenderer(const nsRect& documentRect,
694 : const gfxMatrix& transform,
695 : const nsString& bgcolor,
696 : const PRUint32& renderFlags,
697 : const bool& flushLayout,
698 : const nsIntSize& renderSize)
699 : {
700 0 : return new DocumentRendererChild();
701 : }
702 :
703 : bool
704 0 : TabChild::DeallocPDocumentRenderer(PDocumentRendererChild* actor)
705 : {
706 0 : delete actor;
707 0 : return true;
708 : }
709 :
710 : bool
711 0 : TabChild::RecvPDocumentRendererConstructor(PDocumentRendererChild* actor,
712 : const nsRect& documentRect,
713 : const gfxMatrix& transform,
714 : const nsString& bgcolor,
715 : const PRUint32& renderFlags,
716 : const bool& flushLayout,
717 : const nsIntSize& renderSize)
718 : {
719 0 : DocumentRendererChild *render = static_cast<DocumentRendererChild *>(actor);
720 :
721 0 : nsCOMPtr<nsIWebBrowser> browser = do_QueryInterface(mWebNav);
722 0 : if (!browser)
723 0 : return true; // silently ignore
724 0 : nsCOMPtr<nsIDOMWindow> window;
725 0 : if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) ||
726 0 : !window)
727 : {
728 0 : return true; // silently ignore
729 : }
730 :
731 0 : nsCString data;
732 : bool ret = render->RenderDocument(window,
733 : documentRect, transform,
734 : bgcolor,
735 : renderFlags, flushLayout,
736 0 : renderSize, data);
737 0 : if (!ret)
738 0 : return true; // silently ignore
739 :
740 0 : return PDocumentRendererChild::Send__delete__(actor, renderSize, data);
741 : }
742 :
743 : PContentDialogChild*
744 0 : TabChild::AllocPContentDialog(const PRUint32&,
745 : const nsCString&,
746 : const nsCString&,
747 : const InfallibleTArray<int>&,
748 : const InfallibleTArray<nsString>&)
749 : {
750 0 : return new ContentDialogChild();
751 : }
752 :
753 : bool
754 0 : TabChild::DeallocPContentDialog(PContentDialogChild* aDialog)
755 : {
756 0 : delete aDialog;
757 0 : return true;
758 : }
759 :
760 : PContentPermissionRequestChild*
761 0 : TabChild::AllocPContentPermissionRequest(const nsCString& aType, const IPC::URI&)
762 : {
763 0 : NS_RUNTIMEABORT("unused");
764 0 : return nsnull;
765 : }
766 :
767 : bool
768 0 : TabChild::DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor)
769 : {
770 0 : static_cast<PCOMContentPermissionRequestChild*>(actor)->IPDLRelease();
771 0 : return true;
772 : }
773 :
774 : bool
775 0 : TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
776 : {
777 0 : nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
778 0 : NS_ENSURE_TRUE(window, true);
779 : nsCOMPtr<nsIDOMEventTarget> chromeHandler =
780 0 : do_QueryInterface(window->GetChromeEventHandler());
781 0 : NS_ENSURE_TRUE(chromeHandler, true);
782 0 : nsRefPtr<ContentListener> listener = new ContentListener(this);
783 0 : NS_ENSURE_TRUE(listener, true);
784 0 : chromeHandler->AddEventListener(aType, listener, capture);
785 0 : return true;
786 : }
787 :
788 : POfflineCacheUpdateChild*
789 0 : TabChild::AllocPOfflineCacheUpdate(const URI& manifestURI,
790 : const URI& documentURI,
791 : const nsCString& clientID,
792 : const bool& stickDocument)
793 : {
794 0 : NS_RUNTIMEABORT("unused");
795 0 : return nsnull;
796 : }
797 :
798 : bool
799 0 : TabChild::DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* actor)
800 : {
801 0 : OfflineCacheUpdateChild* offlineCacheUpdate = static_cast<OfflineCacheUpdateChild*>(actor);
802 0 : delete offlineCacheUpdate;
803 0 : return true;
804 : }
805 :
806 : bool
807 0 : TabChild::RecvLoadRemoteScript(const nsString& aURL)
808 : {
809 0 : if (!mCx && !InitTabChildGlobal())
810 : // This can happen if we're half-destroyed. It's not a fatal
811 : // error.
812 0 : return true;
813 :
814 0 : LoadFrameScriptInternal(aURL);
815 0 : return true;
816 : }
817 :
818 : bool
819 0 : TabChild::RecvAsyncMessage(const nsString& aMessage,
820 : const nsString& aJSON)
821 : {
822 0 : if (mTabChildGlobal) {
823 0 : nsFrameScriptCx cx(static_cast<nsIWebBrowserChrome*>(this), this);
824 : nsRefPtr<nsFrameMessageManager> mm =
825 0 : static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
826 0 : mm->ReceiveMessage(static_cast<nsIDOMEventTarget*>(mTabChildGlobal),
827 0 : aMessage, false, aJSON, nsnull, nsnull);
828 : }
829 0 : return true;
830 : }
831 :
832 : class UnloadScriptEvent : public nsRunnable
833 0 : {
834 : public:
835 0 : UnloadScriptEvent(TabChild* aTabChild, TabChildGlobal* aTabChildGlobal)
836 0 : : mTabChild(aTabChild), mTabChildGlobal(aTabChildGlobal)
837 0 : { }
838 :
839 0 : NS_IMETHOD Run()
840 : {
841 0 : nsCOMPtr<nsIDOMEvent> event;
842 0 : NS_NewDOMEvent(getter_AddRefs(event), nsnull, nsnull);
843 0 : if (event) {
844 0 : event->InitEvent(NS_LITERAL_STRING("unload"), false, false);
845 0 : nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
846 0 : privateEvent->SetTrusted(true);
847 :
848 : bool dummy;
849 0 : mTabChildGlobal->DispatchEvent(event, &dummy);
850 : }
851 :
852 0 : return NS_OK;
853 : }
854 :
855 : nsRefPtr<TabChild> mTabChild;
856 : TabChildGlobal* mTabChildGlobal;
857 : };
858 :
859 : bool
860 0 : TabChild::RecvDestroy()
861 : {
862 0 : if (mTabChildGlobal) {
863 : // Let the frame scripts know the child is being closed
864 : nsContentUtils::AddScriptRunner(
865 0 : new UnloadScriptEvent(this, mTabChildGlobal)
866 0 : );
867 : }
868 :
869 : // XXX what other code in ~TabChild() should we be running here?
870 0 : DestroyWindow();
871 :
872 0 : return Send__delete__(this);
873 : }
874 :
875 : PRenderFrameChild*
876 0 : TabChild::AllocPRenderFrame()
877 : {
878 0 : return new RenderFrameChild();
879 : }
880 :
881 : bool
882 0 : TabChild::DeallocPRenderFrame(PRenderFrameChild* aFrame)
883 : {
884 0 : delete aFrame;
885 0 : return true;
886 : }
887 :
888 : bool
889 0 : TabChild::InitTabChildGlobal()
890 : {
891 0 : if (mCx && mTabChildGlobal)
892 0 : return true;
893 :
894 0 : nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mWebNav);
895 0 : NS_ENSURE_TRUE(window, false);
896 : nsCOMPtr<nsIDOMEventTarget> chromeHandler =
897 0 : do_QueryInterface(window->GetChromeEventHandler());
898 0 : NS_ENSURE_TRUE(chromeHandler, false);
899 :
900 0 : nsRefPtr<TabChildGlobal> scope = new TabChildGlobal(this);
901 0 : NS_ENSURE_TRUE(scope, false);
902 :
903 0 : mTabChildGlobal = scope;
904 :
905 : nsISupports* scopeSupports =
906 0 : NS_ISUPPORTS_CAST(nsIDOMEventTarget*, scope);
907 :
908 0 : NS_ENSURE_TRUE(InitTabChildGlobalInternal(scopeSupports), false);
909 :
910 0 : nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
911 0 : NS_ENSURE_TRUE(root, false);
912 0 : root->SetParentTarget(scope);
913 0 : return true;
914 : }
915 :
916 : bool
917 0 : TabChild::InitWidget(const nsIntSize& size)
918 : {
919 0 : NS_ABORT_IF_FALSE(!mWidget && !mRemoteFrame, "CreateWidget twice?");
920 :
921 0 : mWidget = nsIWidget::CreatePuppetWidget(this);
922 0 : if (!mWidget) {
923 0 : NS_ERROR("couldn't create fake widget");
924 0 : return false;
925 : }
926 0 : mWidget->Create(
927 : nsnull, 0, // no parents
928 : nsIntRect(nsIntPoint(0, 0), size),
929 : nsnull, // HandleWidgetEvent
930 : nsnull // nsDeviceContext
931 0 : );
932 :
933 : RenderFrameChild* remoteFrame =
934 0 : static_cast<RenderFrameChild*>(SendPRenderFrameConstructor());
935 0 : if (!remoteFrame) {
936 0 : NS_WARNING("failed to construct RenderFrame");
937 0 : return false;
938 : }
939 :
940 0 : NS_ABORT_IF_FALSE(0 == remoteFrame->ManagedPLayersChild().Length(),
941 : "shouldn't have a shadow manager yet");
942 : LayerManager::LayersBackend be;
943 0 : PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be);
944 0 : if (!shadowManager) {
945 0 : NS_WARNING("failed to construct LayersChild");
946 : // This results in |remoteFrame| being deleted.
947 0 : PRenderFrameChild::Send__delete__(remoteFrame);
948 0 : return false;
949 : }
950 :
951 : ShadowLayerForwarder* lf =
952 0 : mWidget->GetLayerManager(shadowManager, be)->AsShadowForwarder();
953 0 : NS_ABORT_IF_FALSE(lf && lf->HasShadowManager(),
954 : "PuppetWidget should have shadow manager");
955 0 : lf->SetParentBackendType(be);
956 :
957 0 : mRemoteFrame = remoteFrame;
958 0 : return true;
959 : }
960 :
961 : void
962 0 : TabChild::SetBackgroundColor(const nscolor& aColor)
963 : {
964 0 : if (mLastBackgroundColor != aColor) {
965 0 : mLastBackgroundColor = aColor;
966 0 : SendSetBackgroundColor(mLastBackgroundColor);
967 : }
968 0 : }
969 :
970 : static bool
971 0 : SendSyncMessageToParent(void* aCallbackData,
972 : const nsAString& aMessage,
973 : const nsAString& aJSON,
974 : InfallibleTArray<nsString>* aJSONRetVal)
975 : {
976 : return static_cast<TabChild*>(aCallbackData)->
977 0 : SendSyncMessage(nsString(aMessage), nsString(aJSON),
978 0 : aJSONRetVal);
979 : }
980 :
981 : static bool
982 0 : SendAsyncMessageToParent(void* aCallbackData,
983 : const nsAString& aMessage,
984 : const nsAString& aJSON)
985 : {
986 : return static_cast<TabChild*>(aCallbackData)->
987 0 : SendAsyncMessage(nsString(aMessage), nsString(aJSON));
988 : }
989 :
990 0 : TabChildGlobal::TabChildGlobal(TabChild* aTabChild)
991 0 : : mTabChild(aTabChild)
992 : {
993 : mMessageManager = new nsFrameMessageManager(false,
994 : SendSyncMessageToParent,
995 : SendAsyncMessageToParent,
996 : nsnull,
997 : mTabChild,
998 : nsnull,
999 0 : aTabChild->GetJSContext());
1000 0 : }
1001 :
1002 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildGlobal)
1003 :
1004 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
1005 : nsDOMEventTargetHelper)
1006 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mMessageManager)
1007 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
1008 :
1009 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
1010 : nsDOMEventTargetHelper)
1011 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mMessageManager)
1012 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
1013 :
1014 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
1015 0 : NS_INTERFACE_MAP_ENTRY(nsIFrameMessageManager)
1016 0 : NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
1017 0 : NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
1018 0 : NS_INTERFACE_MAP_ENTRY(nsIScriptContextPrincipal)
1019 0 : NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
1020 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
1021 0 : NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
1022 :
1023 0 : NS_IMPL_ADDREF_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
1024 0 : NS_IMPL_RELEASE_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
1025 :
1026 : NS_IMETHODIMP
1027 0 : TabChildGlobal::GetContent(nsIDOMWindow** aContent)
1028 : {
1029 0 : *aContent = nsnull;
1030 0 : if (!mTabChild)
1031 0 : return NS_ERROR_NULL_POINTER;
1032 0 : nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mTabChild->WebNavigation());
1033 0 : window.swap(*aContent);
1034 0 : return NS_OK;
1035 : }
1036 :
1037 : NS_IMETHODIMP
1038 0 : TabChildGlobal::PrivateNoteIntentionalCrash()
1039 : {
1040 0 : mozilla::NoteIntentionalCrash("tab");
1041 0 : return NS_OK;
1042 : }
1043 :
1044 : NS_IMETHODIMP
1045 0 : TabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
1046 : {
1047 0 : *aDocShell = nsnull;
1048 0 : if (!mTabChild)
1049 0 : return NS_ERROR_NULL_POINTER;
1050 0 : nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mTabChild->WebNavigation());
1051 0 : docShell.swap(*aDocShell);
1052 0 : return NS_OK;
1053 : }
1054 :
1055 : NS_IMETHODIMP
1056 0 : TabChildGlobal::Btoa(const nsAString& aBinaryData,
1057 : nsAString& aAsciiBase64String)
1058 : {
1059 0 : return nsContentUtils::Btoa(aBinaryData, aAsciiBase64String);
1060 : }
1061 :
1062 : NS_IMETHODIMP
1063 0 : TabChildGlobal::Atob(const nsAString& aAsciiString,
1064 : nsAString& aBinaryData)
1065 : {
1066 0 : return nsContentUtils::Atob(aAsciiString, aBinaryData);
1067 : }
1068 :
1069 : JSContext*
1070 0 : TabChildGlobal::GetJSContextForEventHandlers()
1071 : {
1072 0 : if (!mTabChild)
1073 0 : return nsnull;
1074 0 : return mTabChild->GetJSContext();
1075 : }
1076 :
1077 : nsIPrincipal*
1078 0 : TabChildGlobal::GetPrincipal()
1079 : {
1080 0 : if (!mTabChild)
1081 0 : return nsnull;
1082 0 : return mTabChild->GetPrincipal();
1083 4392 : }
|