Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/browser/nsWebBrowser.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
// Local Includes
8
#include "nsWebBrowser.h"
9
10
// Helper Classes
11
#include "nsGfxCIID.h"
12
#include "nsWidgetsCID.h"
13
14
#include "gfxUtils.h"
15
#include "mozilla/gfx/2D.h"
16
17
// Interfaces Needed
18
#include "gfxContext.h"
19
#include "nsReadableUtils.h"
20
#include "nsIComponentManager.h"
21
#include "nsIDOMWindow.h"
22
#include "nsIInterfaceRequestor.h"
23
#include "nsIInterfaceRequestorUtils.h"
24
#include "nsIWebBrowserChrome.h"
25
#include "nsPIDOMWindow.h"
26
#include "nsIWebProgress.h"
27
#include "nsIWebProgressListener.h"
28
#include "nsIPresShell.h"
29
#include "nsIURIContentListener.h"
30
#include "nsISHistoryListener.h"
31
#include "nsIURI.h"
32
#include "nsIWebBrowserPersist.h"
33
#include "nsIServiceManager.h"
34
#include "nsFocusManager.h"
35
#include "Layers.h"
36
#include "nsILoadContext.h"
37
#include "nsDocShell.h"
38
39
#include "mozilla/dom/Element.h"
40
41
// for painting the background window
42
#include "mozilla/LookAndFeel.h"
43
44
// Printing Includes
45
#ifdef NS_PRINTING
46
#include "nsIWebBrowserPrint.h"
47
#include "nsIContentViewer.h"
48
#endif
49
50
// PSM2 includes
51
#include "nsISecureBrowserUI.h"
52
#include "nsXULAppAPI.h"
53
54
using namespace mozilla;
55
using namespace mozilla::gfx;
56
using namespace mozilla::layers;
57
58
nsWebBrowser::nsWebBrowser()
59
  : mInitInfo(new nsWebBrowserInitInfo())
60
  , mContentType(typeContentWrapper)
61
  , mActivating(false)
62
  , mShouldEnableHistory(true)
63
  , mIsActive(true)
64
  , mParentNativeWindow(nullptr)
65
  , mProgressListener(nullptr)
66
  , mWidgetListenerDelegate(this)
67
  , mBackgroundColor(0)
68
  , mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY)
69
  , mPersistResult(NS_OK)
70
  , mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE)
71
  , mParentWidget(nullptr)
72
0
{
73
0
  mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
74
0
  NS_ASSERTION(mWWatch, "failed to get WindowWatcher");
75
0
}
76
77
nsWebBrowser::~nsWebBrowser()
78
0
{
79
0
  InternalDestroy();
80
0
}
81
82
NS_IMETHODIMP
83
nsWebBrowser::InternalDestroy()
84
0
{
85
0
  if (mInternalWidget) {
86
0
    mInternalWidget->SetWidgetListener(nullptr);
87
0
    mInternalWidget->Destroy();
88
0
    mInternalWidget = nullptr; // Force release here.
89
0
  }
90
0
91
0
  SetDocShell(nullptr);
92
0
93
0
  if (mDocShellTreeOwner) {
94
0
    mDocShellTreeOwner->WebBrowser(nullptr);
95
0
    mDocShellTreeOwner = nullptr;
96
0
  }
97
0
98
0
  mInitInfo = nullptr;
99
0
100
0
  mListenerArray = nullptr;
101
0
102
0
  return NS_OK;
103
0
}
104
105
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsWebBrowser)
106
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsWebBrowser)
107
108
NS_IMPL_CYCLE_COLLECTION(nsWebBrowser,
109
                         mDocShell,
110
                         mDocShellAsReq,
111
                         mDocShellAsWin,
112
                         mDocShellAsNav,
113
                         mDocShellAsScrollable,
114
                         mWebProgress)
115
116
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsWebBrowser)
117
0
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser)
118
0
  NS_INTERFACE_MAP_ENTRY(nsIWebBrowser)
119
0
  NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
120
0
  NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
121
0
  NS_INTERFACE_MAP_ENTRY(nsIScrollable)
122
0
  NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
123
0
  NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
124
0
  NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist)
125
0
  NS_INTERFACE_MAP_ENTRY(nsICancelable)
126
0
  NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
127
0
  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
128
0
NS_INTERFACE_MAP_END
129
130
///*****************************************************************************
131
// nsWebBrowser::nsIInterfaceRequestor
132
//*****************************************************************************
133
134
NS_IMETHODIMP
135
nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink)
136
0
{
137
0
  NS_ENSURE_ARG_POINTER(aSink);
138
0
139
0
  if (NS_SUCCEEDED(QueryInterface(aIID, aSink))) {
140
0
    return NS_OK;
141
0
  }
142
0
143
0
  if (mDocShell) {
144
0
#ifdef NS_PRINTING
145
0
    if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
146
0
      nsCOMPtr<nsIContentViewer> viewer;
147
0
      mDocShell->GetContentViewer(getter_AddRefs(viewer));
148
0
      if (!viewer) {
149
0
        return NS_NOINTERFACE;
150
0
      }
151
0
152
0
      nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
153
0
      nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get();
154
0
      NS_ASSERTION(print, "This MUST support this interface!");
155
0
      NS_ADDREF(print);
156
0
      *aSink = print;
157
0
      return NS_OK;
158
0
    }
159
0
#endif
160
0
    return mDocShellAsReq->GetInterface(aIID, aSink);
161
0
  }
162
0
163
0
  return NS_NOINTERFACE;
164
0
}
165
166
//*****************************************************************************
167
// nsWebBrowser::nsIWebBrowser
168
//*****************************************************************************
169
170
// listeners that currently support registration through AddWebBrowserListener:
171
//  - nsIWebProgressListener
172
NS_IMETHODIMP
173
nsWebBrowser::AddWebBrowserListener(nsIWeakReference* aListener,
174
                                    const nsIID& aIID)
175
0
{
176
0
  NS_ENSURE_ARG_POINTER(aListener);
177
0
178
0
  nsresult rv = NS_OK;
179
0
  if (!mWebProgress) {
180
0
    // The window hasn't been created yet, so queue up the listener. They'll be
181
0
    // registered when the window gets created.
182
0
    if (!mListenerArray) {
183
0
      mListenerArray = new nsTArray<nsWebBrowserListenerState>();
184
0
    }
185
0
186
0
    nsWebBrowserListenerState* state = mListenerArray->AppendElement();
187
0
    state->mWeakPtr = aListener;
188
0
    state->mID = aIID;
189
0
  } else {
190
0
    nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
191
0
    if (!supports) {
192
0
      return NS_ERROR_INVALID_ARG;
193
0
    }
194
0
    rv = BindListener(supports, aIID);
195
0
  }
196
0
197
0
  return rv;
198
0
}
199
200
NS_IMETHODIMP
201
nsWebBrowser::BindListener(nsISupports* aListener, const nsIID& aIID)
202
0
{
203
0
  NS_ENSURE_ARG_POINTER(aListener);
204
0
  NS_ASSERTION(mWebProgress,
205
0
               "this should only be called after we've retrieved a progress iface");
206
0
  nsresult rv = NS_OK;
207
0
208
0
  // register this listener for the specified interface id
209
0
  if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
210
0
    nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
211
0
    if (NS_FAILED(rv)) {
212
0
      return rv;
213
0
    }
214
0
    NS_ENSURE_STATE(mWebProgress);
215
0
    rv = mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL);
216
0
  } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
217
0
    nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
218
0
    if (NS_FAILED(rv)) {
219
0
      return rv;
220
0
    }
221
0
    nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
222
0
    if (NS_FAILED(rv)) {
223
0
      return rv;
224
0
    }
225
0
    rv = shistory->AddSHistoryListener(listener);
226
0
  }
227
0
  return rv;
228
0
}
229
230
NS_IMETHODIMP
231
nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference* aListener,
232
                                       const nsIID& aIID)
233
0
{
234
0
  NS_ENSURE_ARG_POINTER(aListener);
235
0
236
0
  nsresult rv = NS_OK;
237
0
  if (!mWebProgress) {
238
0
    // if there's no-one to register the listener w/, and we don't have a queue
239
0
    // going, the the called is calling Remove before an Add which doesn't make
240
0
    // sense.
241
0
    if (!mListenerArray) {
242
0
      return NS_ERROR_FAILURE;
243
0
    }
244
0
245
0
    // iterate the array and remove the queued listener
246
0
    int32_t count = mListenerArray->Length();
247
0
    while (count > 0) {
248
0
      if (mListenerArray->ElementAt(count-1).Equals(aListener, aIID)) {
249
0
        mListenerArray->RemoveElementAt(count-1);
250
0
        break;
251
0
      }
252
0
      count--;
253
0
    }
254
0
255
0
    // if we've emptied the array, get rid of it.
256
0
    if (0 >= mListenerArray->Length()) {
257
0
      mListenerArray = nullptr;
258
0
    }
259
0
260
0
  } else {
261
0
    nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
262
0
    if (!supports) {
263
0
      return NS_ERROR_INVALID_ARG;
264
0
    }
265
0
    rv = UnBindListener(supports, aIID);
266
0
  }
267
0
268
0
  return rv;
269
0
}
270
271
NS_IMETHODIMP
272
nsWebBrowser::UnBindListener(nsISupports* aListener, const nsIID& aIID)
273
0
{
274
0
  NS_ENSURE_ARG_POINTER(aListener);
275
0
  NS_ASSERTION(mWebProgress,
276
0
               "this should only be called after we've retrieved a progress iface");
277
0
  nsresult rv = NS_OK;
278
0
279
0
  // remove the listener for the specified interface id
280
0
  if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
281
0
    nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
282
0
    if (NS_FAILED(rv)) {
283
0
      return rv;
284
0
    }
285
0
    NS_ENSURE_STATE(mWebProgress);
286
0
    rv = mWebProgress->RemoveProgressListener(listener);
287
0
  } else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
288
0
    nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
289
0
    if (NS_FAILED(rv)) {
290
0
      return rv;
291
0
    }
292
0
    nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
293
0
    if (NS_FAILED(rv)) {
294
0
      return rv;
295
0
    }
296
0
    rv = shistory->RemoveSHistoryListener(listener);
297
0
  }
298
0
  return rv;
299
0
}
300
301
NS_IMETHODIMP
302
nsWebBrowser::EnableGlobalHistory(bool aEnable)
303
0
{
304
0
  NS_ENSURE_STATE(mDocShell);
305
0
306
0
  return mDocShell->SetUseGlobalHistory(aEnable);
307
0
}
308
309
NS_IMETHODIMP
310
nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow)
311
0
{
312
0
  NS_ENSURE_ARG_POINTER(aTopWindow);
313
0
314
0
  nsCOMPtr<nsIWebBrowserChrome> top;
315
0
  if (mDocShellTreeOwner) {
316
0
    top = mDocShellTreeOwner->GetWebBrowserChrome();
317
0
  }
318
0
319
0
  top.forget(aTopWindow);
320
0
321
0
  return NS_OK;
322
0
}
323
324
NS_IMETHODIMP
325
nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow)
326
0
{
327
0
  NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
328
0
  return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow);
329
0
}
330
331
NS_IMETHODIMP
332
nsWebBrowser::GetParentURIContentListener(
333
    nsIURIContentListener** aParentContentListener)
334
0
{
335
0
  NS_ENSURE_ARG_POINTER(aParentContentListener);
336
0
  *aParentContentListener = nullptr;
337
0
338
0
  // get the interface from the docshell
339
0
  nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
340
0
341
0
  if (listener) {
342
0
    return listener->GetParentContentListener(aParentContentListener);
343
0
  }
344
0
  return NS_OK;
345
0
}
346
347
NS_IMETHODIMP
348
nsWebBrowser::SetParentURIContentListener(
349
    nsIURIContentListener* aParentContentListener)
350
0
{
351
0
  // get the interface from the docshell
352
0
  nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
353
0
354
0
  if (listener) {
355
0
    return listener->SetParentContentListener(aParentContentListener);
356
0
  }
357
0
  return NS_ERROR_FAILURE;
358
0
}
359
360
NS_IMETHODIMP
361
nsWebBrowser::GetContentDOMWindow(mozIDOMWindowProxy** aResult)
362
0
{
363
0
  if (!mDocShell) {
364
0
    return NS_ERROR_UNEXPECTED;
365
0
  }
366
0
367
0
  nsCOMPtr<nsPIDOMWindowOuter> retval = mDocShell->GetWindow();
368
0
  retval.forget(aResult);
369
0
  return *aResult ? NS_OK : NS_ERROR_FAILURE;
370
0
}
371
372
NS_IMETHODIMP
373
nsWebBrowser::GetIsActive(bool* aResult)
374
0
{
375
0
  *aResult = mIsActive;
376
0
  return NS_OK;
377
0
}
378
379
NS_IMETHODIMP
380
nsWebBrowser::SetIsActive(bool aIsActive)
381
0
{
382
0
  // Set our copy of the value
383
0
  mIsActive = aIsActive;
384
0
385
0
  // If we have a docshell, pass on the request
386
0
  if (mDocShell) {
387
0
    return mDocShell->SetIsActive(aIsActive);
388
0
  }
389
0
  return NS_OK;
390
0
}
391
392
void
393
nsWebBrowser::SetOriginAttributes(const OriginAttributes& aAttrs)
394
0
{
395
0
  mOriginAttributes = aAttrs;
396
0
}
397
398
//*****************************************************************************
399
// nsWebBrowser::nsIDocShellTreeItem
400
//*****************************************************************************
401
402
NS_IMETHODIMP
403
nsWebBrowser::GetName(nsAString& aName)
404
0
{
405
0
  if (mDocShell) {
406
0
    mDocShell->GetName(aName);
407
0
  } else {
408
0
    aName = mInitInfo->name;
409
0
  }
410
0
411
0
  return NS_OK;
412
0
}
413
414
NS_IMETHODIMP
415
nsWebBrowser::SetName(const nsAString& aName)
416
0
{
417
0
  if (mDocShell) {
418
0
    return mDocShell->SetName(aName);
419
0
  } else {
420
0
    mInitInfo->name = aName;
421
0
  }
422
0
423
0
  return NS_OK;
424
0
}
425
426
NS_IMETHODIMP
427
nsWebBrowser::NameEquals(const nsAString& aName, bool* aResult)
428
0
{
429
0
  NS_ENSURE_ARG_POINTER(aResult);
430
0
  if (mDocShell) {
431
0
    return mDocShell->NameEquals(aName, aResult);
432
0
  } else {
433
0
    *aResult = mInitInfo->name.Equals(aName);
434
0
  }
435
0
436
0
  return NS_OK;
437
0
}
438
439
/* virtual */ int32_t
440
nsWebBrowser::ItemType()
441
0
{
442
0
  return mContentType;
443
0
}
444
445
NS_IMETHODIMP
446
nsWebBrowser::GetItemType(int32_t* aItemType)
447
0
{
448
0
  NS_ENSURE_ARG_POINTER(aItemType);
449
0
450
0
  *aItemType = ItemType();
451
0
  return NS_OK;
452
0
}
453
454
NS_IMETHODIMP
455
nsWebBrowser::SetItemType(int32_t aItemType)
456
0
{
457
0
  NS_ENSURE_TRUE(
458
0
    aItemType == typeContentWrapper || aItemType == typeChromeWrapper,
459
0
    NS_ERROR_FAILURE);
460
0
  mContentType = aItemType;
461
0
  if (mDocShell) {
462
0
    mDocShell->SetItemType(mContentType == typeChromeWrapper ?
463
0
                             static_cast<int32_t>(typeChrome) :
464
0
                             static_cast<int32_t>(typeContent));
465
0
  }
466
0
467
0
  return NS_OK;
468
0
}
469
470
NS_IMETHODIMP
471
nsWebBrowser::GetParent(nsIDocShellTreeItem** aParent)
472
0
{
473
0
  *aParent = nullptr;
474
0
  return NS_OK;
475
0
}
476
477
NS_IMETHODIMP
478
nsWebBrowser::GetSameTypeParent(nsIDocShellTreeItem** aParent)
479
0
{
480
0
  *aParent = nullptr;
481
0
482
0
  return NS_OK;
483
0
}
484
485
NS_IMETHODIMP
486
nsWebBrowser::GetRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
487
0
{
488
0
  NS_ENSURE_ARG_POINTER(aRootTreeItem);
489
0
  *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
490
0
491
0
  nsCOMPtr<nsIDocShellTreeItem> parent;
492
0
  NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
493
0
  while (parent) {
494
0
    *aRootTreeItem = parent;
495
0
    NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)),
496
0
                      NS_ERROR_FAILURE);
497
0
  }
498
0
  NS_ADDREF(*aRootTreeItem);
499
0
  return NS_OK;
500
0
}
501
502
NS_IMETHODIMP
503
nsWebBrowser::GetSameTypeRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
504
0
{
505
0
  NS_ENSURE_ARG_POINTER(aRootTreeItem);
506
0
  *aRootTreeItem = static_cast<nsIDocShellTreeItem*>(this);
507
0
508
0
  nsCOMPtr<nsIDocShellTreeItem> parent;
509
0
  NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)),
510
0
                    NS_ERROR_FAILURE);
511
0
  while (parent) {
512
0
    *aRootTreeItem = parent;
513
0
    NS_ENSURE_SUCCESS((*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)),
514
0
                      NS_ERROR_FAILURE);
515
0
  }
516
0
  NS_ADDREF(*aRootTreeItem);
517
0
  return NS_OK;
518
0
}
519
520
NS_IMETHODIMP
521
nsWebBrowser::FindItemWithName(const nsAString& aName,
522
                               nsIDocShellTreeItem* aRequestor,
523
                               nsIDocShellTreeItem* aOriginalRequestor,
524
                               bool aSkipTabGroup,
525
                               nsIDocShellTreeItem** aResult)
526
0
{
527
0
  NS_ENSURE_STATE(mDocShell);
528
0
  NS_ASSERTION(mDocShellTreeOwner,
529
0
               "This should always be set when in this situation");
530
0
531
0
  return mDocShell->FindItemWithName(
532
0
    aName, aRequestor, aOriginalRequestor, aSkipTabGroup, aResult);
533
0
}
534
535
nsIDocument*
536
nsWebBrowser::GetDocument()
537
0
{
538
0
  return mDocShell ? mDocShell->GetDocument() : nullptr;
539
0
}
540
541
nsPIDOMWindowOuter*
542
nsWebBrowser::GetWindow()
543
0
{
544
0
  return mDocShell ? mDocShell->GetWindow() : nullptr;
545
0
}
546
547
NS_IMETHODIMP
548
nsWebBrowser::GetDomWindow(mozIDOMWindowProxy** aWindow)
549
0
{
550
0
  if (!mDocShell)
551
0
    return NS_ERROR_NOT_INITIALIZED;
552
0
  return mDocShell->GetDomWindow(aWindow);
553
0
}
554
555
NS_IMETHODIMP
556
nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
557
0
{
558
0
  NS_ENSURE_ARG_POINTER(aTreeOwner);
559
0
  *aTreeOwner = nullptr;
560
0
  if (mDocShellTreeOwner) {
561
0
    if (mDocShellTreeOwner->mTreeOwner) {
562
0
      *aTreeOwner = mDocShellTreeOwner->mTreeOwner;
563
0
    } else {
564
0
      *aTreeOwner = mDocShellTreeOwner;
565
0
    }
566
0
  }
567
0
  NS_IF_ADDREF(*aTreeOwner);
568
0
  return NS_OK;
569
0
}
570
571
NS_IMETHODIMP
572
nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
573
0
{
574
0
  NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
575
0
  return mDocShellTreeOwner->SetTreeOwner(aTreeOwner);
576
0
}
577
578
//*****************************************************************************
579
// nsWebBrowser::nsIDocShellTreeItem
580
//*****************************************************************************
581
582
NS_IMETHODIMP
583
nsWebBrowser::GetChildCount(int32_t* aChildCount)
584
0
{
585
0
  NS_ENSURE_ARG_POINTER(aChildCount);
586
0
  *aChildCount = 0;
587
0
  return NS_OK;
588
0
}
589
590
NS_IMETHODIMP
591
nsWebBrowser::AddChild(nsIDocShellTreeItem* aChild)
592
0
{
593
0
  return NS_ERROR_UNEXPECTED;
594
0
}
595
596
NS_IMETHODIMP
597
nsWebBrowser::RemoveChild(nsIDocShellTreeItem* aChild)
598
0
{
599
0
  return NS_ERROR_UNEXPECTED;
600
0
}
601
602
NS_IMETHODIMP
603
nsWebBrowser::GetChildAt(int32_t aIndex, nsIDocShellTreeItem** aChild)
604
0
{
605
0
  return NS_ERROR_UNEXPECTED;
606
0
}
607
608
NS_IMETHODIMP
609
nsWebBrowser::FindChildWithName(const nsAString& aName,
610
                                bool aRecurse,
611
                                bool aSameType,
612
                                nsIDocShellTreeItem* aRequestor,
613
                                nsIDocShellTreeItem* aOriginalRequestor,
614
                                nsIDocShellTreeItem** aResult)
615
0
{
616
0
  NS_ENSURE_ARG_POINTER(aResult);
617
0
618
0
  *aResult = nullptr;
619
0
  return NS_OK;
620
0
}
621
622
//*****************************************************************************
623
// nsWebBrowser::nsIWebNavigation
624
//*****************************************************************************
625
626
NS_IMETHODIMP
627
nsWebBrowser::GetCanGoBack(bool* aCanGoBack)
628
0
{
629
0
  NS_ENSURE_STATE(mDocShell);
630
0
631
0
  return mDocShellAsNav->GetCanGoBack(aCanGoBack);
632
0
}
633
634
NS_IMETHODIMP
635
nsWebBrowser::GetCanGoForward(bool* aCanGoForward)
636
0
{
637
0
  NS_ENSURE_STATE(mDocShell);
638
0
639
0
  return mDocShellAsNav->GetCanGoForward(aCanGoForward);
640
0
}
641
642
NS_IMETHODIMP
643
nsWebBrowser::GoBack()
644
0
{
645
0
  NS_ENSURE_STATE(mDocShell);
646
0
647
0
  return mDocShellAsNav->GoBack();
648
0
}
649
650
NS_IMETHODIMP
651
nsWebBrowser::GoForward()
652
0
{
653
0
  NS_ENSURE_STATE(mDocShell);
654
0
655
0
  return mDocShellAsNav->GoForward();
656
0
}
657
658
NS_IMETHODIMP
659
nsWebBrowser::LoadURIWithOptions(const nsAString& aURI, uint32_t aLoadFlags,
660
                                 nsIURI* aReferringURI,
661
                                 uint32_t aReferrerPolicy,
662
                                 nsIInputStream* aPostDataStream,
663
                                 nsIInputStream* aExtraHeaderStream,
664
                                 nsIURI* aBaseURI,
665
                                 nsIPrincipal* aTriggeringPrincipal)
666
0
{
667
0
  NS_ENSURE_STATE(mDocShell);
668
0
669
0
  return mDocShellAsNav->LoadURIWithOptions(
670
0
    aURI, aLoadFlags, aReferringURI, aReferrerPolicy, aPostDataStream,
671
0
    aExtraHeaderStream, aBaseURI, aTriggeringPrincipal);
672
0
}
673
674
NS_IMETHODIMP
675
nsWebBrowser::SetOriginAttributesBeforeLoading(JS::Handle<JS::Value> aOriginAttributes,
676
                                               JSContext* aCx)
677
0
{
678
0
  return mDocShellAsNav->SetOriginAttributesBeforeLoading(aOriginAttributes, aCx);
679
0
}
680
681
NS_IMETHODIMP
682
nsWebBrowser::LoadURI(const nsAString& aURI, uint32_t aLoadFlags,
683
                      nsIURI* aReferringURI,
684
                      nsIInputStream* aPostDataStream,
685
                      nsIInputStream* aExtraHeaderStream,
686
                      nsIPrincipal* aTriggeringPrincipal)
687
0
{
688
0
  NS_ENSURE_STATE(mDocShell);
689
0
690
0
  return mDocShellAsNav->LoadURI(aURI, aLoadFlags, aReferringURI,
691
0
                                 aPostDataStream, aExtraHeaderStream,
692
0
                                 aTriggeringPrincipal);
693
0
}
694
695
NS_IMETHODIMP
696
nsWebBrowser::Reload(uint32_t aReloadFlags)
697
0
{
698
0
  NS_ENSURE_STATE(mDocShell);
699
0
700
0
  return mDocShellAsNav->Reload(aReloadFlags);
701
0
}
702
703
NS_IMETHODIMP
704
nsWebBrowser::GotoIndex(int32_t aIndex)
705
0
{
706
0
  NS_ENSURE_STATE(mDocShell);
707
0
708
0
  return mDocShellAsNav->GotoIndex(aIndex);
709
0
}
710
711
NS_IMETHODIMP
712
nsWebBrowser::Stop(uint32_t aStopFlags)
713
0
{
714
0
  NS_ENSURE_STATE(mDocShell);
715
0
716
0
  return mDocShellAsNav->Stop(aStopFlags);
717
0
}
718
719
NS_IMETHODIMP
720
nsWebBrowser::GetCurrentURI(nsIURI** aURI)
721
0
{
722
0
  NS_ENSURE_STATE(mDocShell);
723
0
724
0
  return mDocShellAsNav->GetCurrentURI(aURI);
725
0
}
726
727
NS_IMETHODIMP
728
nsWebBrowser::GetReferringURI(nsIURI** aURI)
729
0
{
730
0
  NS_ENSURE_STATE(mDocShell);
731
0
732
0
  return mDocShellAsNav->GetReferringURI(aURI);
733
0
}
734
735
// XXX(nika): Consider making the mozilla::dom::ChildSHistory version the
736
// canonical one?
737
NS_IMETHODIMP
738
nsWebBrowser::GetSessionHistoryXPCOM(nsISupports** aSessionHistory)
739
0
{
740
0
  NS_ENSURE_ARG_POINTER(aSessionHistory);
741
0
  *aSessionHistory = nullptr;
742
0
  if (mDocShell) {
743
0
    RefPtr<mozilla::dom::ChildSHistory> shistory =
744
0
      mDocShellAsNav->GetSessionHistory();
745
0
    shistory.forget(aSessionHistory);
746
0
  }
747
0
  return NS_OK;
748
0
}
749
750
NS_IMETHODIMP
751
nsWebBrowser::GetDocument(nsIDocument** aDocument)
752
0
{
753
0
  NS_ENSURE_STATE(mDocShell);
754
0
755
0
  return mDocShellAsNav->GetDocument(aDocument);
756
0
}
757
758
void
759
nsWebBrowser::SetAllowDNSPrefetch(bool aAllowPrefetch)
760
0
{
761
0
  MOZ_ASSERT(mDocShell);
762
0
  mDocShell->SetAllowDNSPrefetch(aAllowPrefetch);
763
0
}
764
765
//*****************************************************************************
766
// nsWebBrowser::nsIWebProgressListener
767
//*****************************************************************************
768
769
NS_IMETHODIMP
770
nsWebBrowser::OnStateChange(nsIWebProgress* aWebProgress,
771
                            nsIRequest* aRequest,
772
                            uint32_t aStateFlags,
773
                            nsresult aStatus)
774
0
{
775
0
  if (mPersist) {
776
0
    mPersist->GetCurrentState(&mPersistCurrentState);
777
0
  }
778
0
  if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP) {
779
0
    mPersist = nullptr;
780
0
  }
781
0
  if (mProgressListener) {
782
0
    return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
783
0
                                            aStatus);
784
0
  }
785
0
  return NS_OK;
786
0
}
787
788
NS_IMETHODIMP
789
nsWebBrowser::OnProgressChange(nsIWebProgress* aWebProgress,
790
                               nsIRequest* aRequest,
791
                               int32_t aCurSelfProgress,
792
                               int32_t aMaxSelfProgress,
793
                               int32_t aCurTotalProgress,
794
                               int32_t aMaxTotalProgress)
795
0
{
796
0
  if (mPersist) {
797
0
    mPersist->GetCurrentState(&mPersistCurrentState);
798
0
  }
799
0
  if (mProgressListener) {
800
0
    return mProgressListener->OnProgressChange(
801
0
      aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
802
0
      aCurTotalProgress, aMaxTotalProgress);
803
0
  }
804
0
  return NS_OK;
805
0
}
806
807
NS_IMETHODIMP
808
nsWebBrowser::OnLocationChange(nsIWebProgress* aWebProgress,
809
                               nsIRequest* aRequest,
810
                               nsIURI* aLocation,
811
                               uint32_t aFlags)
812
0
{
813
0
  if (mProgressListener) {
814
0
    return mProgressListener->OnLocationChange(aWebProgress, aRequest, aLocation,
815
0
                                               aFlags);
816
0
  }
817
0
  return NS_OK;
818
0
}
819
820
NS_IMETHODIMP
821
nsWebBrowser::OnStatusChange(nsIWebProgress* aWebProgress,
822
                             nsIRequest* aRequest,
823
                             nsresult aStatus,
824
                             const char16_t* aMessage)
825
0
{
826
0
  if (mProgressListener) {
827
0
    return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus,
828
0
                                             aMessage);
829
0
  }
830
0
  return NS_OK;
831
0
}
832
833
NS_IMETHODIMP
834
nsWebBrowser::OnSecurityChange(nsIWebProgress* aWebProgress,
835
                               nsIRequest* aRequest,
836
                               uint32_t aState)
837
0
{
838
0
  if (mProgressListener) {
839
0
    return mProgressListener->OnSecurityChange(aWebProgress, aRequest, aState);
840
0
  }
841
0
  return NS_OK;
842
0
}
843
844
//*****************************************************************************
845
// nsWebBrowser::nsIWebBrowserPersist
846
//*****************************************************************************
847
848
NS_IMETHODIMP
849
nsWebBrowser::GetPersistFlags(uint32_t* aPersistFlags)
850
0
{
851
0
  NS_ENSURE_ARG_POINTER(aPersistFlags);
852
0
  nsresult rv = NS_OK;
853
0
  if (mPersist) {
854
0
    rv = mPersist->GetPersistFlags(&mPersistFlags);
855
0
  }
856
0
  *aPersistFlags = mPersistFlags;
857
0
  return rv;
858
0
}
859
860
NS_IMETHODIMP
861
nsWebBrowser::SetPersistFlags(uint32_t aPersistFlags)
862
0
{
863
0
  nsresult rv = NS_OK;
864
0
  mPersistFlags = aPersistFlags;
865
0
  if (mPersist) {
866
0
    rv = mPersist->SetPersistFlags(mPersistFlags);
867
0
    mPersist->GetPersistFlags(&mPersistFlags);
868
0
  }
869
0
  return rv;
870
0
}
871
872
NS_IMETHODIMP
873
nsWebBrowser::GetCurrentState(uint32_t* aCurrentState)
874
0
{
875
0
  NS_ENSURE_ARG_POINTER(aCurrentState);
876
0
  if (mPersist) {
877
0
    mPersist->GetCurrentState(&mPersistCurrentState);
878
0
  }
879
0
  *aCurrentState = mPersistCurrentState;
880
0
  return NS_OK;
881
0
}
882
883
NS_IMETHODIMP
884
nsWebBrowser::GetResult(nsresult* aResult)
885
0
{
886
0
  NS_ENSURE_ARG_POINTER(aResult);
887
0
  if (mPersist) {
888
0
    mPersist->GetResult(&mPersistResult);
889
0
  }
890
0
  *aResult = mPersistResult;
891
0
  return NS_OK;
892
0
}
893
894
NS_IMETHODIMP
895
nsWebBrowser::GetProgressListener(nsIWebProgressListener** aProgressListener)
896
0
{
897
0
  NS_ENSURE_ARG_POINTER(aProgressListener);
898
0
  *aProgressListener = mProgressListener;
899
0
  NS_IF_ADDREF(*aProgressListener);
900
0
  return NS_OK;
901
0
}
902
903
NS_IMETHODIMP
904
nsWebBrowser::SetProgressListener(nsIWebProgressListener* aProgressListener)
905
0
{
906
0
  mProgressListener = aProgressListener;
907
0
  return NS_OK;
908
0
}
909
910
NS_IMETHODIMP
911
nsWebBrowser::SaveURI(nsIURI* aURI,
912
                      nsIPrincipal* aPrincipal,
913
                      uint32_t aCacheKey,
914
                      nsIURI* aReferrer,
915
                      uint32_t aReferrerPolicy,
916
                      nsIInputStream* aPostData,
917
                      const char* aExtraHeaders,
918
                      nsISupports* aFile,
919
                      nsILoadContext* aPrivacyContext)
920
0
{
921
0
  return SavePrivacyAwareURI(
922
0
    aURI, aPrincipal, aCacheKey, aReferrer, aReferrerPolicy, aPostData,
923
0
    aExtraHeaders, aFile,
924
0
    aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
925
0
}
926
927
NS_IMETHODIMP
928
nsWebBrowser::SavePrivacyAwareURI(nsIURI* aURI,
929
                                  nsIPrincipal* aPrincipal,
930
                                  uint32_t aCacheKey,
931
                                  nsIURI* aReferrer,
932
                                  uint32_t aReferrerPolicy,
933
                                  nsIInputStream* aPostData,
934
                                  const char* aExtraHeaders,
935
                                  nsISupports* aFile,
936
                                  bool aIsPrivate)
937
0
{
938
0
  if (mPersist) {
939
0
    uint32_t currentState;
940
0
    mPersist->GetCurrentState(&currentState);
941
0
    if (currentState == PERSIST_STATE_FINISHED) {
942
0
      mPersist = nullptr;
943
0
    } else {
944
0
      // You can't save again until the last save has completed
945
0
      return NS_ERROR_FAILURE;
946
0
    }
947
0
  }
948
0
949
0
  nsCOMPtr<nsIURI> uri;
950
0
  if (aURI) {
951
0
    uri = aURI;
952
0
  } else {
953
0
    nsresult rv = GetCurrentURI(getter_AddRefs(uri));
954
0
    if (NS_FAILED(rv)) {
955
0
      return NS_ERROR_FAILURE;
956
0
    }
957
0
  }
958
0
959
0
  // Create a throwaway persistence object to do the work
960
0
  nsresult rv;
961
0
  mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
962
0
  NS_ENSURE_SUCCESS(rv, rv);
963
0
  mPersist->SetProgressListener(this);
964
0
  mPersist->SetPersistFlags(mPersistFlags);
965
0
  mPersist->GetCurrentState(&mPersistCurrentState);
966
0
967
0
  rv = mPersist->SavePrivacyAwareURI(uri, aPrincipal, aCacheKey,
968
0
                                     aReferrer, aReferrerPolicy, aPostData,
969
0
                                     aExtraHeaders, aFile, aIsPrivate);
970
0
  if (NS_FAILED(rv)) {
971
0
    mPersist = nullptr;
972
0
  }
973
0
  return rv;
974
0
}
975
976
NS_IMETHODIMP
977
nsWebBrowser::SaveChannel(nsIChannel* aChannel, nsISupports* aFile)
978
0
{
979
0
  if (mPersist) {
980
0
    uint32_t currentState;
981
0
    mPersist->GetCurrentState(&currentState);
982
0
    if (currentState == PERSIST_STATE_FINISHED) {
983
0
      mPersist = nullptr;
984
0
    } else {
985
0
      // You can't save again until the last save has completed
986
0
      return NS_ERROR_FAILURE;
987
0
    }
988
0
  }
989
0
990
0
  // Create a throwaway persistence object to do the work
991
0
  nsresult rv;
992
0
  mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
993
0
  NS_ENSURE_SUCCESS(rv, rv);
994
0
  mPersist->SetProgressListener(this);
995
0
  mPersist->SetPersistFlags(mPersistFlags);
996
0
  mPersist->GetCurrentState(&mPersistCurrentState);
997
0
  rv = mPersist->SaveChannel(aChannel, aFile);
998
0
  if (NS_FAILED(rv)) {
999
0
    mPersist = nullptr;
1000
0
  }
1001
0
  return rv;
1002
0
}
1003
1004
NS_IMETHODIMP
1005
nsWebBrowser::SaveDocument(nsISupports* aDocumentish,
1006
                           nsISupports* aFile,
1007
                           nsISupports* aDataPath,
1008
                           const char* aOutputContentType,
1009
                           uint32_t aEncodingFlags,
1010
                           uint32_t aWrapColumn)
1011
0
{
1012
0
  if (mPersist) {
1013
0
    uint32_t currentState;
1014
0
    mPersist->GetCurrentState(&currentState);
1015
0
    if (currentState == PERSIST_STATE_FINISHED) {
1016
0
      mPersist = nullptr;
1017
0
    } else {
1018
0
      // You can't save again until the last save has completed
1019
0
      return NS_ERROR_FAILURE;
1020
0
    }
1021
0
  }
1022
0
1023
0
  // Use the specified DOM document, or if none is specified, the one
1024
0
  // attached to the web browser.
1025
0
1026
0
  nsCOMPtr<nsISupports> doc;
1027
0
  if (aDocumentish) {
1028
0
    doc = aDocumentish;
1029
0
  } else {
1030
0
    nsCOMPtr<nsIDocument> domDoc;
1031
0
    GetDocument(getter_AddRefs(domDoc));
1032
0
    doc = domDoc.forget();
1033
0
  }
1034
0
  if (!doc) {
1035
0
    return NS_ERROR_FAILURE;
1036
0
  }
1037
0
1038
0
  // Create a throwaway persistence object to do the work
1039
0
  nsresult rv;
1040
0
  mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
1041
0
  NS_ENSURE_SUCCESS(rv, rv);
1042
0
  mPersist->SetProgressListener(this);
1043
0
  mPersist->SetPersistFlags(mPersistFlags);
1044
0
  mPersist->GetCurrentState(&mPersistCurrentState);
1045
0
  rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType,
1046
0
                              aEncodingFlags, aWrapColumn);
1047
0
  if (NS_FAILED(rv)) {
1048
0
    mPersist = nullptr;
1049
0
  }
1050
0
  return rv;
1051
0
}
1052
1053
NS_IMETHODIMP
1054
nsWebBrowser::CancelSave()
1055
0
{
1056
0
  if (mPersist) {
1057
0
    return mPersist->CancelSave();
1058
0
  }
1059
0
  return NS_OK;
1060
0
}
1061
1062
NS_IMETHODIMP
1063
nsWebBrowser::Cancel(nsresult aReason)
1064
0
{
1065
0
  if (mPersist) {
1066
0
    return mPersist->Cancel(aReason);
1067
0
  }
1068
0
  return NS_OK;
1069
0
}
1070
1071
//*****************************************************************************
1072
// nsWebBrowser::nsIBaseWindow
1073
//*****************************************************************************
1074
1075
NS_IMETHODIMP
1076
nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow,
1077
                         nsIWidget* aParentWidget,
1078
                         int32_t aX, int32_t aY,
1079
                         int32_t aCX, int32_t aCY)
1080
0
{
1081
0
  NS_ENSURE_ARG(aParentNativeWindow || aParentWidget);
1082
0
  NS_ENSURE_STATE(!mDocShell || mInitInfo);
1083
0
1084
0
  if (aParentWidget) {
1085
0
    NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE);
1086
0
  } else
1087
0
    NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow),
1088
0
                      NS_ERROR_FAILURE);
1089
0
1090
0
  NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, 0),
1091
0
                    NS_ERROR_FAILURE);
1092
0
1093
0
  return NS_OK;
1094
0
}
1095
1096
NS_IMETHODIMP
1097
nsWebBrowser::Create()
1098
0
{
1099
0
  NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget));
1100
0
1101
0
  nsresult rv = EnsureDocShellTreeOwner();
1102
0
  NS_ENSURE_SUCCESS(rv, rv);
1103
0
1104
0
  nsCOMPtr<nsIWidget> docShellParentWidget(mParentWidget);
1105
0
  if (!mParentWidget) {
1106
0
    // Create the widget
1107
0
    mInternalWidget = nsIWidget::CreateChildWindow();
1108
0
    NS_ENSURE_TRUE(mInternalWidget, NS_ERROR_FAILURE);
1109
0
1110
0
    docShellParentWidget = mInternalWidget;
1111
0
    nsWidgetInitData widgetInit;
1112
0
1113
0
    widgetInit.clipChildren = true;
1114
0
1115
0
    widgetInit.mWindowType = eWindowType_child;
1116
0
    LayoutDeviceIntRect bounds(mInitInfo->x, mInitInfo->y,
1117
0
                               mInitInfo->cx, mInitInfo->cy);
1118
0
1119
0
    mInternalWidget->SetWidgetListener(&mWidgetListenerDelegate);
1120
0
    rv = mInternalWidget->Create(nullptr, mParentNativeWindow, bounds,
1121
0
                                 &widgetInit);
1122
0
    NS_ENSURE_SUCCESS(rv, rv);
1123
0
  }
1124
0
1125
0
  nsCOMPtr<nsIDocShell> docShell(
1126
0
    do_CreateInstance("@mozilla.org/docshell;1", &rv));
1127
0
  NS_ENSURE_SUCCESS(rv, rv);
1128
0
  nsDocShell::Cast(docShell)->SetOriginAttributes(mOriginAttributes);
1129
0
  rv = SetDocShell(docShell);
1130
0
  NS_ENSURE_SUCCESS(rv, rv);
1131
0
1132
0
  // get the system default window background colour
1133
0
  LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground,
1134
0
                        &mBackgroundColor);
1135
0
1136
0
  // the docshell has been set so we now have our listener registrars.
1137
0
  if (mListenerArray) {
1138
0
    // we had queued up some listeners, let's register them now.
1139
0
    uint32_t count = mListenerArray->Length();
1140
0
    uint32_t i = 0;
1141
0
    NS_ASSERTION(count > 0, "array construction problem");
1142
0
    while (i < count) {
1143
0
      nsWebBrowserListenerState& state = mListenerArray->ElementAt(i);
1144
0
      nsCOMPtr<nsISupports> listener = do_QueryReferent(state.mWeakPtr);
1145
0
      NS_ASSERTION(listener, "bad listener");
1146
0
      (void)BindListener(listener, state.mID);
1147
0
      i++;
1148
0
    }
1149
0
    mListenerArray = nullptr;
1150
0
  }
1151
0
1152
0
  // HACK ALERT - this registration registers the nsDocShellTreeOwner as a
1153
0
  // nsIWebBrowserListener so it can setup its MouseListener in one of the
1154
0
  // progress callbacks. If we can register the MouseListener another way, this
1155
0
  // registration can go away, and nsDocShellTreeOwner can stop implementing
1156
0
  // nsIWebProgressListener.
1157
0
  nsCOMPtr<nsISupports> supports = nullptr;
1158
0
  (void)mDocShellTreeOwner->QueryInterface(
1159
0
    NS_GET_IID(nsIWebProgressListener),
1160
0
    static_cast<void**>(getter_AddRefs(supports)));
1161
0
  (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener));
1162
0
1163
0
  NS_ENSURE_SUCCESS(mDocShellAsWin->InitWindow(nullptr, docShellParentWidget,
1164
0
                                               mInitInfo->x, mInitInfo->y,
1165
0
                                               mInitInfo->cx, mInitInfo->cy),
1166
0
                    NS_ERROR_FAILURE);
1167
0
1168
0
  mDocShell->SetName(mInitInfo->name);
1169
0
  if (mContentType == typeChromeWrapper) {
1170
0
    mDocShell->SetItemType(nsIDocShellTreeItem::typeChrome);
1171
0
  } else {
1172
0
    mDocShell->SetItemType(nsIDocShellTreeItem::typeContent);
1173
0
  }
1174
0
  mDocShell->SetTreeOwner(mDocShellTreeOwner);
1175
0
  mDocShell->AttachBrowsingContext(nullptr);
1176
0
1177
0
  // If the webbrowser is a content docshell item then we won't hear any
1178
0
  // events from subframes. To solve that we install our own chrome event
1179
0
  // handler that always gets called (even for subframes) for any bubbling
1180
0
  // event.
1181
0
1182
0
  mDocShell->InitSessionHistory();
1183
0
1184
0
  if (XRE_IsParentProcess()) {
1185
0
    // Hook up global history. Do not fail if we can't - just warn.
1186
0
    rv = EnableGlobalHistory(mShouldEnableHistory);
1187
0
    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed");
1188
0
  }
1189
0
1190
0
  NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE);
1191
0
1192
0
  // Hook into the OnSecurityChange() notification for lock/unlock icon
1193
0
  // updates
1194
0
  nsCOMPtr<mozIDOMWindowProxy> domWindow;
1195
0
  rv = GetContentDOMWindow(getter_AddRefs(domWindow));
1196
0
  if (NS_SUCCEEDED(rv)) {
1197
0
    // this works because the implementation of nsISecureBrowserUI
1198
0
    // (nsSecureBrowserUIImpl) gets a docShell from the domWindow,
1199
0
    // and calls docShell->SetSecurityUI(this);
1200
0
    nsCOMPtr<nsISecureBrowserUI> securityUI =
1201
0
      do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv);
1202
0
    if (NS_SUCCEEDED(rv)) {
1203
0
      securityUI->Init(domWindow);
1204
0
    }
1205
0
  }
1206
0
1207
0
  mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
1208
0
  mDocShellTreeOwner->AddChromeListeners();
1209
0
1210
0
  mInitInfo = nullptr;
1211
0
1212
0
  return NS_OK;
1213
0
}
1214
1215
NS_IMETHODIMP
1216
nsWebBrowser::Destroy()
1217
0
{
1218
0
  InternalDestroy();
1219
0
1220
0
  if (!mInitInfo) {
1221
0
    mInitInfo = new nsWebBrowserInitInfo();
1222
0
  }
1223
0
1224
0
  return NS_OK;
1225
0
}
1226
1227
NS_IMETHODIMP
1228
nsWebBrowser::GetUnscaledDevicePixelsPerCSSPixel(double* aScale)
1229
0
{
1230
0
  *aScale = mParentWidget ? mParentWidget->GetDefaultScale().scale : 1.0;
1231
0
  return NS_OK;
1232
0
}
1233
1234
NS_IMETHODIMP
1235
nsWebBrowser::GetDevicePixelsPerDesktopPixel(double* aScale)
1236
0
{
1237
0
  *aScale = mParentWidget ? mParentWidget->GetDesktopToDeviceScale().scale
1238
0
                          : 1.0;
1239
0
  return NS_OK;
1240
0
}
1241
1242
NS_IMETHODIMP
1243
nsWebBrowser::SetPositionDesktopPix(int32_t aX, int32_t aY)
1244
0
{
1245
0
  // XXX jfkthame
1246
0
  // It's not clear to me whether this will be fully correct across
1247
0
  // potential multi-screen, mixed-DPI configurations for all platforms;
1248
0
  // we might need to add code paths that make it possible to pass the
1249
0
  // desktop-pix parameters all the way through to the native widget,
1250
0
  // to avoid the risk of device-pixel coords mapping to the wrong
1251
0
  // display on OS X with mixed retina/non-retina screens.
1252
0
  double scale = 1.0;
1253
0
  GetDevicePixelsPerDesktopPixel(&scale);
1254
0
  return SetPosition(NSToIntRound(aX * scale), NSToIntRound(aY * scale));
1255
0
}
1256
1257
NS_IMETHODIMP
1258
nsWebBrowser::SetPosition(int32_t aX, int32_t aY)
1259
0
{
1260
0
  int32_t cx = 0;
1261
0
  int32_t cy = 0;
1262
0
1263
0
  GetSize(&cx, &cy);
1264
0
1265
0
  return SetPositionAndSize(aX, aY, cx, cy, 0);
1266
0
}
1267
1268
NS_IMETHODIMP
1269
nsWebBrowser::GetPosition(int32_t* aX, int32_t* aY)
1270
0
{
1271
0
  return GetPositionAndSize(aX, aY, nullptr, nullptr);
1272
0
}
1273
1274
NS_IMETHODIMP
1275
nsWebBrowser::SetSize(int32_t aCX, int32_t aCY, bool aRepaint)
1276
0
{
1277
0
  int32_t x = 0;
1278
0
  int32_t y = 0;
1279
0
1280
0
  GetPosition(&x, &y);
1281
0
1282
0
  return SetPositionAndSize(x, y, aCX, aCY,
1283
0
                            aRepaint ? nsIBaseWindow::eRepaint : 0);
1284
0
}
1285
1286
NS_IMETHODIMP
1287
nsWebBrowser::GetSize(int32_t* aCX, int32_t* aCY)
1288
0
{
1289
0
  return GetPositionAndSize(nullptr, nullptr, aCX, aCY);
1290
0
}
1291
1292
NS_IMETHODIMP
1293
nsWebBrowser::SetPositionAndSize(int32_t aX, int32_t aY,
1294
                                 int32_t aCX, int32_t aCY, uint32_t aFlags)
1295
0
{
1296
0
  if (!mDocShell) {
1297
0
    mInitInfo->x = aX;
1298
0
    mInitInfo->y = aY;
1299
0
    mInitInfo->cx = aCX;
1300
0
    mInitInfo->cy = aCY;
1301
0
  } else {
1302
0
    int32_t doc_x = aX;
1303
0
    int32_t doc_y = aY;
1304
0
1305
0
    // If there is an internal widget we need to make the docShell coordinates
1306
0
    // relative to the internal widget rather than the calling app's parent.
1307
0
    // We also need to resize our widget then.
1308
0
    if (mInternalWidget) {
1309
0
      doc_x = doc_y = 0;
1310
0
      mInternalWidget->Resize(aX, aY, aCX, aCY,
1311
0
                              !!(aFlags & nsIBaseWindow::eRepaint));
1312
0
    }
1313
0
    // Now reposition/ resize the doc
1314
0
    NS_ENSURE_SUCCESS(
1315
0
      mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, aFlags),
1316
0
      NS_ERROR_FAILURE);
1317
0
  }
1318
0
1319
0
  return NS_OK;
1320
0
}
1321
1322
NS_IMETHODIMP
1323
nsWebBrowser::GetPositionAndSize(int32_t* aX, int32_t* aY,
1324
                                 int32_t* aCX, int32_t* aCY)
1325
0
{
1326
0
  if (!mDocShell) {
1327
0
    if (aX) {
1328
0
      *aX = mInitInfo->x;
1329
0
    }
1330
0
    if (aY) {
1331
0
      *aY = mInitInfo->y;
1332
0
    }
1333
0
    if (aCX) {
1334
0
      *aCX = mInitInfo->cx;
1335
0
    }
1336
0
    if (aCY) {
1337
0
      *aCY = mInitInfo->cy;
1338
0
    }
1339
0
  } else if (mInternalWidget) {
1340
0
    LayoutDeviceIntRect bounds = mInternalWidget->GetBounds();
1341
0
1342
0
    if (aX) {
1343
0
      *aX = bounds.X();
1344
0
    }
1345
0
    if (aY) {
1346
0
      *aY = bounds.Y();
1347
0
    }
1348
0
    if (aCX) {
1349
0
      *aCX = bounds.Width();
1350
0
    }
1351
0
    if (aCY) {
1352
0
      *aCY = bounds.Height();
1353
0
    }
1354
0
    return NS_OK;
1355
0
  } else {
1356
0
    // Can directly return this as it is the
1357
0
    // same interface, thus same returns.
1358
0
    return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY);
1359
0
  }
1360
0
  return NS_OK;
1361
0
}
1362
1363
NS_IMETHODIMP
1364
nsWebBrowser::Repaint(bool aForce)
1365
0
{
1366
0
  NS_ENSURE_STATE(mDocShell);
1367
0
  // Can directly return this as it is the
1368
0
  // same interface, thus same returns.
1369
0
  return mDocShellAsWin->Repaint(aForce);
1370
0
}
1371
1372
NS_IMETHODIMP
1373
nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget)
1374
0
{
1375
0
  NS_ENSURE_ARG_POINTER(aParentWidget);
1376
0
1377
0
  *aParentWidget = mParentWidget;
1378
0
1379
0
  NS_IF_ADDREF(*aParentWidget);
1380
0
1381
0
  return NS_OK;
1382
0
}
1383
1384
NS_IMETHODIMP
1385
nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget)
1386
0
{
1387
0
  NS_ENSURE_STATE(!mDocShell);
1388
0
1389
0
  mParentWidget = aParentWidget;
1390
0
  if (mParentWidget) {
1391
0
    mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
1392
0
  } else {
1393
0
    mParentNativeWindow = nullptr;
1394
0
  }
1395
0
1396
0
  return NS_OK;
1397
0
}
1398
1399
NS_IMETHODIMP
1400
nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
1401
0
{
1402
0
  NS_ENSURE_ARG_POINTER(aParentNativeWindow);
1403
0
1404
0
  *aParentNativeWindow = mParentNativeWindow;
1405
0
1406
0
  return NS_OK;
1407
0
}
1408
1409
NS_IMETHODIMP
1410
nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow)
1411
0
{
1412
0
  NS_ENSURE_STATE(!mDocShell);
1413
0
1414
0
  mParentNativeWindow = aParentNativeWindow;
1415
0
1416
0
  return NS_OK;
1417
0
}
1418
1419
NS_IMETHODIMP
1420
nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle)
1421
0
{
1422
0
  // the nativeHandle should be accessed from nsIXULWindow
1423
0
  return NS_ERROR_NOT_IMPLEMENTED;
1424
0
}
1425
1426
NS_IMETHODIMP
1427
nsWebBrowser::GetVisibility(bool* aVisibility)
1428
0
{
1429
0
  NS_ENSURE_ARG_POINTER(aVisibility);
1430
0
1431
0
  if (!mDocShell) {
1432
0
    *aVisibility = mInitInfo->visible;
1433
0
  } else {
1434
0
    NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(aVisibility),
1435
0
                      NS_ERROR_FAILURE);
1436
0
  }
1437
0
1438
0
  return NS_OK;
1439
0
}
1440
1441
NS_IMETHODIMP
1442
nsWebBrowser::SetVisibility(bool aVisibility)
1443
0
{
1444
0
  if (!mDocShell) {
1445
0
    mInitInfo->visible = aVisibility;
1446
0
  } else {
1447
0
    NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility),
1448
0
                      NS_ERROR_FAILURE);
1449
0
    if (mInternalWidget) {
1450
0
      mInternalWidget->Show(aVisibility);
1451
0
    }
1452
0
  }
1453
0
1454
0
  return NS_OK;
1455
0
}
1456
1457
NS_IMETHODIMP
1458
nsWebBrowser::GetEnabled(bool* aEnabled)
1459
0
{
1460
0
  if (mInternalWidget) {
1461
0
    *aEnabled = mInternalWidget->IsEnabled();
1462
0
    return NS_OK;
1463
0
  }
1464
0
1465
0
  return NS_ERROR_FAILURE;
1466
0
}
1467
1468
NS_IMETHODIMP
1469
nsWebBrowser::SetEnabled(bool aEnabled)
1470
0
{
1471
0
  if (mInternalWidget) {
1472
0
    mInternalWidget->Enable(aEnabled);
1473
0
    return NS_OK;
1474
0
  }
1475
0
  return NS_ERROR_FAILURE;
1476
0
}
1477
1478
NS_IMETHODIMP
1479
nsWebBrowser::GetMainWidget(nsIWidget** aMainWidget)
1480
0
{
1481
0
  NS_ENSURE_ARG_POINTER(aMainWidget);
1482
0
1483
0
  if (mInternalWidget) {
1484
0
    *aMainWidget = mInternalWidget;
1485
0
  } else {
1486
0
    *aMainWidget = mParentWidget;
1487
0
  }
1488
0
1489
0
  NS_IF_ADDREF(*aMainWidget);
1490
0
1491
0
  return NS_OK;
1492
0
}
1493
1494
NS_IMETHODIMP
1495
nsWebBrowser::SetFocus()
1496
0
{
1497
0
  nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1498
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1499
0
1500
0
  nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1501
0
  return fm ? fm->SetFocusedWindow(window) : NS_OK;
1502
0
}
1503
1504
NS_IMETHODIMP
1505
nsWebBrowser::GetTitle(nsAString& aTitle)
1506
0
{
1507
0
  NS_ENSURE_STATE(mDocShell);
1508
0
1509
0
  NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE);
1510
0
1511
0
  return NS_OK;
1512
0
}
1513
1514
NS_IMETHODIMP
1515
nsWebBrowser::SetTitle(const nsAString& aTitle)
1516
0
{
1517
0
  NS_ENSURE_STATE(mDocShell);
1518
0
1519
0
  NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE);
1520
0
1521
0
  return NS_OK;
1522
0
}
1523
1524
//*****************************************************************************
1525
// nsWebBrowser::nsIScrollable
1526
//*****************************************************************************
1527
1528
NS_IMETHODIMP
1529
nsWebBrowser::GetDefaultScrollbarPreferences(int32_t aScrollOrientation,
1530
                                             int32_t* aScrollbarPref)
1531
0
{
1532
0
  NS_ENSURE_STATE(mDocShell);
1533
0
1534
0
  return mDocShellAsScrollable->GetDefaultScrollbarPreferences(
1535
0
    aScrollOrientation, aScrollbarPref);
1536
0
}
1537
1538
NS_IMETHODIMP
1539
nsWebBrowser::SetDefaultScrollbarPreferences(int32_t aScrollOrientation,
1540
                                             int32_t aScrollbarPref)
1541
0
{
1542
0
  NS_ENSURE_STATE(mDocShell);
1543
0
1544
0
  return mDocShellAsScrollable->SetDefaultScrollbarPreferences(
1545
0
    aScrollOrientation, aScrollbarPref);
1546
0
}
1547
1548
NS_IMETHODIMP
1549
nsWebBrowser::GetScrollbarVisibility(bool* aVerticalVisible,
1550
                                     bool* aHorizontalVisible)
1551
0
{
1552
0
  NS_ENSURE_STATE(mDocShell);
1553
0
1554
0
  return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible,
1555
0
                                                       aHorizontalVisible);
1556
0
}
1557
1558
//*****************************************************************************
1559
// nsWebBrowser: Listener Helpers
1560
//*****************************************************************************
1561
1562
NS_IMETHODIMP
1563
nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
1564
0
{
1565
0
  // We need to keep the docshell alive while we perform the changes, but we
1566
0
  // don't need to call any methods on it.
1567
0
  nsCOMPtr<nsIDocShell> kungFuDeathGrip(mDocShell);
1568
0
  mozilla::Unused << kungFuDeathGrip;
1569
0
1570
0
  if (aDocShell) {
1571
0
    NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE);
1572
0
1573
0
    nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(aDocShell));
1574
0
    nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(aDocShell));
1575
0
    nsCOMPtr<nsIWebNavigation> nav(do_QueryInterface(aDocShell));
1576
0
    nsCOMPtr<nsIScrollable> scrollable(do_QueryInterface(aDocShell));
1577
0
    nsCOMPtr<nsIWebProgress> progress(do_GetInterface(aDocShell));
1578
0
    NS_ENSURE_TRUE(req && baseWin && nav && scrollable && progress,
1579
0
                   NS_ERROR_FAILURE);
1580
0
1581
0
    mDocShell = aDocShell;
1582
0
    mDocShellAsReq = req;
1583
0
    mDocShellAsWin = baseWin;
1584
0
    mDocShellAsNav = nav;
1585
0
    mDocShellAsScrollable = scrollable;
1586
0
    mWebProgress = progress;
1587
0
1588
0
    // By default, do not allow DNS prefetch, so we don't break our frozen
1589
0
    // API.  Embeddors who decide to enable it should do so manually.
1590
0
    mDocShell->SetAllowDNSPrefetch(false);
1591
0
1592
0
    // It's possible to call setIsActive() on us before we have a docshell.
1593
0
    // If we're getting a docshell now, pass along our desired value. The
1594
0
    // default here (true) matches the default of the docshell, so this is
1595
0
    // a no-op unless setIsActive(false) has been called on us.
1596
0
    mDocShell->SetIsActive(mIsActive);
1597
0
  } else {
1598
0
    if (mDocShellTreeOwner) {
1599
0
      mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create()
1600
0
    }
1601
0
    if (mDocShellAsWin) {
1602
0
      mDocShellAsWin->Destroy();
1603
0
    }
1604
0
1605
0
    mDocShell = nullptr;
1606
0
    mDocShellAsReq = nullptr;
1607
0
    mDocShellAsWin = nullptr;
1608
0
    mDocShellAsNav = nullptr;
1609
0
    mDocShellAsScrollable = nullptr;
1610
0
    mWebProgress = nullptr;
1611
0
  }
1612
0
1613
0
  return NS_OK;
1614
0
}
1615
1616
NS_IMETHODIMP
1617
nsWebBrowser::EnsureDocShellTreeOwner()
1618
0
{
1619
0
  if (mDocShellTreeOwner) {
1620
0
    return NS_OK;
1621
0
  }
1622
0
1623
0
  mDocShellTreeOwner = new nsDocShellTreeOwner();
1624
0
  mDocShellTreeOwner->WebBrowser(this);
1625
0
1626
0
  return NS_OK;
1627
0
}
1628
1629
static void
1630
DrawPaintedLayer(PaintedLayer* aLayer,
1631
                 gfxContext* aContext,
1632
                 const nsIntRegion& aRegionToDraw,
1633
                 const nsIntRegion& aDirtyRegion,
1634
                 DrawRegionClip aClip,
1635
                 const nsIntRegion& aRegionToInvalidate,
1636
                 void* aCallbackData)
1637
0
{
1638
0
  DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
1639
0
1640
0
  ColorPattern color(ToDeviceColor(*static_cast<nscolor*>(aCallbackData)));
1641
0
  nsIntRect dirtyRect = aRegionToDraw.GetBounds();
1642
0
  aDrawTarget.FillRect( Rect(dirtyRect.X(), dirtyRect.Y(),
1643
0
                             dirtyRect.Width(), dirtyRect.Height()), color);
1644
0
}
1645
1646
void
1647
nsWebBrowser::WindowActivated()
1648
0
{
1649
#if defined(DEBUG_smaug)
1650
  nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
1651
  nsAutoString documentURI;
1652
  document->GetDocumentURI(documentURI);
1653
  printf("nsWebBrowser::NS_ACTIVATE %p %s\n", (void*)this,
1654
         NS_ConvertUTF16toUTF8(documentURI).get());
1655
#endif
1656
  FocusActivate();
1657
0
}
1658
1659
void
1660
nsWebBrowser::WindowDeactivated()
1661
0
{
1662
#if defined(DEBUG_smaug)
1663
  nsCOMPtr<nsIDocument> document = mDocShell->GetDocument();
1664
  nsAutoString documentURI;
1665
  document->GetDocumentURI(documentURI);
1666
  printf("nsWebBrowser::NS_DEACTIVATE %p %s\n", (void*)this,
1667
         NS_ConvertUTF16toUTF8(documentURI).get());
1668
#endif
1669
  FocusDeactivate();
1670
0
}
1671
1672
bool
1673
nsWebBrowser::PaintWindow(nsIWidget* aWidget, LayoutDeviceIntRegion aRegion)
1674
0
{
1675
0
  LayerManager* layerManager = aWidget->GetLayerManager();
1676
0
  NS_ASSERTION(layerManager, "Must be in paint event");
1677
0
1678
0
  layerManager->BeginTransaction();
1679
0
  RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer();
1680
0
  if (root) {
1681
0
    nsIntRect dirtyRect = aRegion.GetBounds().ToUnknownRect();
1682
0
    root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect));
1683
0
    layerManager->SetRoot(root);
1684
0
  }
1685
0
1686
0
  layerManager->EndTransaction(DrawPaintedLayer, &mBackgroundColor);
1687
0
  return true;
1688
0
}
1689
1690
void
1691
nsWebBrowser::FocusActivate()
1692
0
{
1693
0
  nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1694
0
  nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1695
0
  if (fm && window) {
1696
0
    fm->WindowRaised(window);
1697
0
  }
1698
0
}
1699
1700
void
1701
nsWebBrowser::FocusDeactivate()
1702
0
{
1703
0
  nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
1704
0
  nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
1705
0
  if (fm && window) {
1706
0
    fm->WindowLowered(window);
1707
0
  }
1708
0
}
1709
1710
void
1711
nsWebBrowser::WidgetListenerDelegate::WindowActivated()
1712
0
{
1713
0
  RefPtr<nsWebBrowser> holder = mWebBrowser;
1714
0
  holder->WindowActivated();
1715
0
}
1716
1717
void
1718
nsWebBrowser::WidgetListenerDelegate::WindowDeactivated()
1719
0
{
1720
0
  RefPtr<nsWebBrowser> holder = mWebBrowser;
1721
0
  holder->WindowDeactivated();
1722
0
}
1723
1724
bool
1725
nsWebBrowser::WidgetListenerDelegate::PaintWindow(
1726
  nsIWidget* aWidget, mozilla::LayoutDeviceIntRegion aRegion)
1727
0
{
1728
0
  RefPtr<nsWebBrowser> holder = mWebBrowser;
1729
0
  return holder->PaintWindow(aWidget, aRegion);
1730
0
}