Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsDOMWindowUtils.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
#include "nsDOMWindowUtils.h"
8
9
#include "mozilla/layers/CompositorBridgeChild.h"
10
#include "mozilla/layers/LayerTransactionChild.h"
11
#include "nsPresContext.h"
12
#include "nsError.h"
13
#include "nsQueryContentEventResult.h"
14
#include "nsGlobalWindow.h"
15
#include "nsIDocument.h"
16
#include "nsFocusManager.h"
17
#include "nsFrameManager.h"
18
#include "nsRefreshDriver.h"
19
#include "mozilla/dom/Animation.h"
20
#include "mozilla/dom/BindingDeclarations.h"
21
#include "mozilla/dom/BlobBinding.h"
22
#include "mozilla/dom/Event.h"
23
#include "mozilla/dom/Touch.h"
24
#include "mozilla/PendingAnimationTracker.h"
25
#include "nsIObjectLoadingContent.h"
26
#include "nsFrame.h"
27
#include "mozilla/layers/ShadowLayers.h"
28
#include "mozilla/layers/APZCCallbackHelper.h"
29
#include "ClientLayerManager.h"
30
#include "nsQueryObject.h"
31
#include "CubebUtils.h"
32
33
#include "nsIScrollableFrame.h"
34
35
#include "nsContentUtils.h"
36
37
#include "nsIFrame.h"
38
#include "nsIWidget.h"
39
#include "nsCharsetSource.h"
40
#include "nsJSEnvironment.h"
41
#include "nsJSUtils.h"
42
43
#include "mozilla/ChaosMode.h"
44
#include "mozilla/EventStateManager.h"
45
#include "mozilla/MiscEvents.h"
46
#include "mozilla/MouseEvents.h"
47
#include "mozilla/TextEvents.h"
48
#include "mozilla/TextEventDispatcher.h"
49
#include "mozilla/TouchEvents.h"
50
51
#include "nsViewManager.h"
52
53
#include "nsLayoutUtils.h"
54
#include "nsComputedDOMStyle.h"
55
#include "nsIPresShell.h"
56
#include "nsCSSProps.h"
57
#include "nsTArrayHelpers.h"
58
#include "nsIDocShell.h"
59
#include "nsIContentViewer.h"
60
#include "mozilla/StyleAnimationValue.h"
61
#include "mozilla/dom/File.h"
62
#include "mozilla/dom/FileBinding.h"
63
#include "mozilla/dom/DOMRect.h"
64
#include <algorithm>
65
66
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
67
#include <gdk/gdk.h>
68
#include <gdk/gdkx.h>
69
#endif
70
71
#include "Layers.h"
72
#include "gfxPrefs.h"
73
74
#include "mozilla/dom/AudioDeviceInfo.h"
75
#include "mozilla/dom/Element.h"
76
#include "mozilla/dom/TabChild.h"
77
#include "mozilla/dom/IDBFactoryBinding.h"
78
#include "mozilla/dom/IDBMutableFileBinding.h"
79
#include "mozilla/dom/IDBMutableFile.h"
80
#include "mozilla/dom/IndexedDatabaseManager.h"
81
#include "mozilla/dom/PermissionMessageUtils.h"
82
#include "mozilla/dom/Text.h"
83
#include "mozilla/dom/quota/PersistenceType.h"
84
#include "mozilla/dom/quota/QuotaManager.h"
85
#include "mozilla/dom/ContentChild.h"
86
#include "mozilla/layers/FrameUniformityData.h"
87
#include "mozilla/layers/ShadowLayers.h"
88
#include "nsPrintfCString.h"
89
#include "nsViewportInfo.h"
90
#include "nsIFormControl.h"
91
#include "nsIScriptError.h"
92
//#include "nsWidgetsCID.h"
93
#include "FrameLayerBuilder.h"
94
#include "nsDisplayList.h"
95
#include "nsROCSSPrimitiveValue.h"
96
#include "nsIBaseWindow.h"
97
#include "nsIDocShellTreeOwner.h"
98
#include "nsIInterfaceRequestorUtils.h"
99
#include "GeckoProfiler.h"
100
#include "mozilla/Preferences.h"
101
#include "nsIContentIterator.h"
102
#include "nsIStyleSheetService.h"
103
#include "nsContentPermissionHelper.h"
104
#include "nsCSSPseudoElements.h"            // for CSSPseudoElementType
105
#include "nsNetUtil.h"
106
#include "nsDocument.h"
107
#include "HTMLImageElement.h"
108
#include "HTMLCanvasElement.h"
109
#include "mozilla/css/ImageLoader.h"
110
#include "mozilla/layers/IAPZCTreeManager.h" // for layers::ZoomToRectBehavior
111
#include "mozilla/dom/Promise.h"
112
#include "mozilla/ServoBindings.h"
113
#include "mozilla/StyleSheetInlines.h"
114
#include "mozilla/gfx/GPUProcessManager.h"
115
#include "mozilla/dom/TimeoutManager.h"
116
#include "mozilla/PreloadedStyleSheet.h"
117
#include "mozilla/layers/WebRenderBridgeChild.h"
118
#include "mozilla/layers/WebRenderLayerManager.h"
119
120
#ifdef XP_WIN
121
#undef GetClassName
122
#endif
123
124
using namespace mozilla;
125
using namespace mozilla::dom;
126
using namespace mozilla::ipc;
127
using namespace mozilla::layers;
128
using namespace mozilla::widget;
129
using namespace mozilla::gfx;
130
131
class gfxContext;
132
133
class OldWindowSize : public LinkedListElement<OldWindowSize>
134
{
135
public:
136
  static void Set(nsIWeakReference* aWindowRef, const nsSize& aSize)
137
0
  {
138
0
    OldWindowSize* item = GetItem(aWindowRef);
139
0
    if (item) {
140
0
      item->mSize = aSize;
141
0
    } else {
142
0
      item = new OldWindowSize(aWindowRef, aSize);
143
0
      sList.insertBack(item);
144
0
    }
145
0
  }
146
147
  static nsSize GetAndRemove(nsIWeakReference* aWindowRef)
148
0
  {
149
0
    nsSize result;
150
0
    if (OldWindowSize* item = GetItem(aWindowRef)) {
151
0
      result = item->mSize;
152
0
      delete item;
153
0
    }
154
0
    return result;
155
0
  }
156
157
private:
158
  explicit OldWindowSize(nsIWeakReference* aWindowRef, const nsSize& aSize)
159
0
    : mWindowRef(aWindowRef), mSize(aSize) { }
160
0
  ~OldWindowSize() = default;;
161
162
  static OldWindowSize* GetItem(nsIWeakReference* aWindowRef)
163
0
  {
164
0
    OldWindowSize* item = sList.getFirst();
165
0
    while (item && item->mWindowRef != aWindowRef) {
166
0
      item = item->getNext();
167
0
    }
168
0
    return item;
169
0
  }
170
171
  static LinkedList<OldWindowSize> sList;
172
  nsWeakPtr mWindowRef;
173
  nsSize mSize;
174
};
175
176
namespace {
177
178
class NativeInputRunnable final : public PrioritizableRunnable
179
{
180
  explicit NativeInputRunnable(already_AddRefed<nsIRunnable>&& aEvent);
181
0
  ~NativeInputRunnable() {}
182
public:
183
  static already_AddRefed<nsIRunnable> Create(already_AddRefed<nsIRunnable>&& aEvent);
184
};
185
186
NativeInputRunnable::NativeInputRunnable(already_AddRefed<nsIRunnable>&& aEvent)
187
  : PrioritizableRunnable(std::move(aEvent), nsIRunnablePriority::PRIORITY_INPUT)
188
0
{
189
0
}
190
191
/* static */ already_AddRefed<nsIRunnable>
192
NativeInputRunnable::Create(already_AddRefed<nsIRunnable>&& aEvent)
193
0
{
194
0
  MOZ_ASSERT(NS_IsMainThread());
195
0
  nsCOMPtr<nsIRunnable> event(new NativeInputRunnable(std::move(aEvent)));
196
0
  return event.forget();
197
0
}
198
199
} // unnamed namespace
200
201
LinkedList<OldWindowSize> OldWindowSize::sList;
202
203
0
NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
204
0
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
205
0
  NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
206
0
  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
207
0
NS_INTERFACE_MAP_END
208
209
NS_IMPL_ADDREF(nsDOMWindowUtils)
210
NS_IMPL_RELEASE(nsDOMWindowUtils)
211
212
nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindowOuter *aWindow)
213
0
{
214
0
  nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow);
215
0
  mWindow = do_GetWeakReference(supports);
216
0
}
217
218
nsDOMWindowUtils::~nsDOMWindowUtils()
219
0
{
220
0
  OldWindowSize::GetAndRemove(mWindow);
221
0
}
222
223
nsIPresShell*
224
nsDOMWindowUtils::GetPresShell()
225
0
{
226
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
227
0
  if (!window)
228
0
    return nullptr;
229
0
230
0
  nsIDocShell *docShell = window->GetDocShell();
231
0
  if (!docShell)
232
0
    return nullptr;
233
0
234
0
  return docShell->GetPresShell();
235
0
}
236
237
nsPresContext*
238
nsDOMWindowUtils::GetPresContext()
239
0
{
240
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
241
0
  if (!window)
242
0
    return nullptr;
243
0
  nsIDocShell *docShell = window->GetDocShell();
244
0
  if (!docShell)
245
0
    return nullptr;
246
0
  RefPtr<nsPresContext> presContext;
247
0
  docShell->GetPresContext(getter_AddRefs(presContext));
248
0
  return presContext;
249
0
}
250
251
nsIDocument*
252
nsDOMWindowUtils::GetDocument()
253
0
{
254
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
255
0
  if (!window) {
256
0
    return nullptr;
257
0
  }
258
0
  return window->GetExtantDoc();
259
0
}
260
261
LayerTransactionChild*
262
nsDOMWindowUtils::GetLayerTransaction()
263
0
{
264
0
  nsIWidget* widget = GetWidget();
265
0
  if (!widget)
266
0
    return nullptr;
267
0
268
0
  LayerManager* manager = widget->GetLayerManager();
269
0
  if (!manager)
270
0
    return nullptr;
271
0
272
0
  ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
273
0
  return forwarder && forwarder->HasShadowManager() ?
274
0
         forwarder->GetShadowManager() :
275
0
         nullptr;
276
0
}
277
278
WebRenderBridgeChild*
279
nsDOMWindowUtils::GetWebRenderBridge()
280
0
{
281
0
  if (nsIWidget* widget = GetWidget()) {
282
0
    if (LayerManager* lm = widget->GetLayerManager()) {
283
0
      if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) {
284
0
        return wrlm->WrBridge();
285
0
      }
286
0
    }
287
0
  }
288
0
  return nullptr;
289
0
}
290
291
NS_IMETHODIMP
292
nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
293
0
{
294
0
  NS_ENSURE_ARG_POINTER(aMode);
295
0
  *aMode = 0;
296
0
  nsPresContext* presContext = GetPresContext();
297
0
  if (presContext) {
298
0
    *aMode = presContext->ImageAnimationMode();
299
0
    return NS_OK;
300
0
  }
301
0
  return NS_ERROR_NOT_AVAILABLE;
302
0
}
303
304
NS_IMETHODIMP
305
nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode)
306
0
{
307
0
  nsPresContext* presContext = GetPresContext();
308
0
  if (presContext) {
309
0
    presContext->SetImageAnimationMode(aMode);
310
0
    return NS_OK;
311
0
  }
312
0
  return NS_ERROR_NOT_AVAILABLE;
313
0
}
314
315
NS_IMETHODIMP
316
nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
317
0
{
318
0
  *aIsForced = false;
319
0
320
0
  nsIDocument* doc = GetDocument();
321
0
  *aIsForced = doc &&
322
0
    doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
323
0
  return NS_OK;
324
0
}
325
326
NS_IMETHODIMP
327
nsDOMWindowUtils::GetPhysicalMillimeterInCSSPixels(float* aPhysicalMillimeter)
328
0
{
329
0
  nsPresContext* presContext = GetPresContext();
330
0
  if (!presContext) {
331
0
    return NS_ERROR_NOT_AVAILABLE;
332
0
  }
333
0
334
0
  *aPhysicalMillimeter = nsPresContext::AppUnitsToFloatCSSPixels(
335
0
    presContext->PhysicalMillimetersToAppUnits(1));
336
0
  return NS_OK;
337
0
}
338
339
NS_IMETHODIMP
340
nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
341
                                      nsAString& aValue)
342
0
{
343
0
  nsIDocument* doc = GetDocument();
344
0
  if (doc) {
345
0
    RefPtr<nsAtom> name = NS_Atomize(aName);
346
0
    doc->GetHeaderData(name, aValue);
347
0
    return NS_OK;
348
0
  }
349
0
350
0
  aValue.Truncate();
351
0
  return NS_OK;
352
0
}
353
354
NS_IMETHODIMP
355
nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
356
0
{
357
0
  if (aCount == 0)
358
0
    aCount = 1;
359
0
360
0
  if (nsIPresShell* presShell = GetPresShell()) {
361
0
    nsIFrame *rootFrame = presShell->GetRootFrame();
362
0
363
0
    if (rootFrame) {
364
0
      PRIntervalTime iStart = PR_IntervalNow();
365
0
366
0
      for (uint32_t i = 0; i < aCount; i++)
367
0
        rootFrame->InvalidateFrame();
368
0
369
0
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
370
0
      if (!gfxPlatform::IsHeadless()) {
371
0
        XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
372
0
      }
373
0
#endif
374
0
375
0
      *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
376
0
377
0
      return NS_OK;
378
0
    }
379
0
  }
380
0
  return NS_ERROR_FAILURE;
381
0
}
382
383
NS_IMETHODIMP
384
nsDOMWindowUtils::UpdateLayerTree()
385
0
{
386
0
  if (nsIPresShell* presShell = GetPresShell()) {
387
0
    // Don't flush throttled animations since it might fire MozAfterPaint event
388
0
    // (in WebRender it constantly does), thus the reftest harness can't take
389
0
    // any snapshot until the throttled animations finished.
390
0
    presShell->FlushPendingNotifications(
391
0
      ChangesToFlush(FlushType::Display, false /* flush animations */));
392
0
    RefPtr<nsViewManager> vm = presShell->GetViewManager();
393
0
    nsView* view = vm->GetRootView();
394
0
    if (view) {
395
0
      nsAutoScriptBlocker scriptBlocker;
396
0
      presShell->Paint(view, view->GetBounds(),
397
0
          nsIPresShell::PAINT_LAYERS | nsIPresShell::PAINT_SYNC_DECODE_IMAGES);
398
0
      presShell->GetLayerManager()->WaitOnTransactionProcessed();
399
0
    }
400
0
  }
401
0
  return NS_OK;
402
0
}
403
404
NS_IMETHODIMP
405
nsDOMWindowUtils::GetContentViewerSize(uint32_t *aDisplayWidth, uint32_t *aDisplayHeight)
406
0
{
407
0
  nsIPresShell* presShell = GetPresShell();
408
0
  LayoutDeviceIntSize displaySize;
409
0
410
0
  if (!presShell || !nsLayoutUtils::GetContentViewerSize(presShell->GetPresContext(), displaySize)) {
411
0
    return NS_ERROR_FAILURE;
412
0
  }
413
0
414
0
  *aDisplayWidth = displaySize.width;
415
0
  *aDisplayHeight = displaySize.height;
416
0
417
0
  return NS_OK;
418
0
}
419
420
NS_IMETHODIMP
421
nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
422
                                  uint32_t aDisplayHeight,
423
                                  double *aDefaultZoom, bool *aAllowZoom,
424
                                  double *aMinZoom, double *aMaxZoom,
425
                                  uint32_t *aWidth, uint32_t *aHeight,
426
                                  bool *aAutoSize)
427
0
{
428
0
  nsIDocument* doc = GetDocument();
429
0
  NS_ENSURE_STATE(doc);
430
0
431
0
  nsViewportInfo info = doc->GetViewportInfo(ScreenIntSize(aDisplayWidth, aDisplayHeight));
432
0
  *aDefaultZoom = info.GetDefaultZoom().scale;
433
0
  *aAllowZoom = info.IsZoomAllowed();
434
0
  *aMinZoom = info.GetMinZoom().scale;
435
0
  *aMaxZoom = info.GetMaxZoom().scale;
436
0
  CSSIntSize size = gfx::RoundedToInt(info.GetSize());
437
0
  *aWidth = size.width;
438
0
  *aHeight = size.height;
439
0
  *aAutoSize = info.IsAutoSizeEnabled();
440
0
  return NS_OK;
441
0
}
442
443
NS_IMETHODIMP
444
nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
445
                                           float aWidthPx, float aHeightPx,
446
                                           Element* aElement,
447
                                           uint32_t aPriority)
448
0
{
449
0
  nsIPresShell* presShell = GetPresShell();
450
0
  if (!presShell) {
451
0
    return NS_ERROR_FAILURE;
452
0
  }
453
0
454
0
  if (!aElement) {
455
0
    return NS_ERROR_INVALID_ARG;
456
0
  }
457
0
458
0
  if (aElement->GetUncomposedDoc() != presShell->GetDocument()) {
459
0
    return NS_ERROR_INVALID_ARG;
460
0
  }
461
0
462
0
  DisplayPortPropertyData* currentData =
463
0
    static_cast<DisplayPortPropertyData*>(aElement->GetProperty(nsGkAtoms::DisplayPort));
464
0
  if (currentData && currentData->mPriority > aPriority) {
465
0
    return NS_OK;
466
0
  }
467
0
468
0
  nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
469
0
                     nsPresContext::CSSPixelsToAppUnits(aYPx),
470
0
                     nsPresContext::CSSPixelsToAppUnits(aWidthPx),
471
0
                     nsPresContext::CSSPixelsToAppUnits(aHeightPx));
472
0
473
0
  aElement->SetProperty(nsGkAtoms::DisplayPort,
474
0
                        new DisplayPortPropertyData(displayport, aPriority),
475
0
                        nsINode::DeleteProperty<DisplayPortPropertyData>);
476
0
477
0
  if (gfxPrefs::LayoutUseContainersForRootFrames()) {
478
0
    nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
479
0
    if (rootScrollFrame &&
480
0
        aElement == rootScrollFrame->GetContent() &&
481
0
        nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame))
482
0
    {
483
0
      // We are setting a root displayport for a document.
484
0
      // The pres shell needs a special flag set.
485
0
      presShell->SetIgnoreViewportScrolling(true);
486
0
    }
487
0
  }
488
0
489
0
  nsLayoutUtils::InvalidateForDisplayPortChange(aElement, !!currentData,
490
0
    currentData ? currentData->mRect : nsRect(), displayport);
491
0
492
0
  nsIFrame* rootFrame = presShell->GetRootFrame();
493
0
  if (rootFrame) {
494
0
    rootFrame->SchedulePaint();
495
0
496
0
    // If we are hiding something that is a display root then send empty paint
497
0
    // transaction in order to release retained layers because it won't get
498
0
    // any more paint requests when it is hidden.
499
0
    if (displayport.IsEmpty() &&
500
0
        rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) {
501
0
      nsCOMPtr<nsIWidget> widget = GetWidget();
502
0
      if (widget) {
503
0
        LayerManager* manager = widget->GetLayerManager();
504
0
        manager->BeginTransaction();
505
0
        using PaintFrameFlags = nsLayoutUtils::PaintFrameFlags;
506
0
        nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(),
507
0
                                  NS_RGB(255, 255, 255),
508
0
                                  nsDisplayListBuilderMode::PAINTING,
509
0
                                  PaintFrameFlags::PAINT_WIDGET_LAYERS |
510
0
                                  PaintFrameFlags::PAINT_EXISTING_TRANSACTION);
511
0
      }
512
0
    }
513
0
  }
514
0
515
0
  return NS_OK;
516
0
}
517
518
NS_IMETHODIMP
519
nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
520
                                                  float aTopMargin,
521
                                                  float aRightMargin,
522
                                                  float aBottomMargin,
523
                                                  Element* aElement,
524
                                                  uint32_t aPriority)
525
0
{
526
0
  nsIPresShell* presShell = GetPresShell();
527
0
  if (!presShell) {
528
0
    return NS_ERROR_FAILURE;
529
0
  }
530
0
531
0
  if (!aElement) {
532
0
    return NS_ERROR_INVALID_ARG;
533
0
  }
534
0
535
0
  if (aElement->GetUncomposedDoc() != presShell->GetDocument()) {
536
0
    return NS_ERROR_INVALID_ARG;
537
0
  }
538
0
539
0
  // Note order change of arguments between our function signature and
540
0
  // ScreenMargin constructor.
541
0
  ScreenMargin displayportMargins(aTopMargin,
542
0
                                  aRightMargin,
543
0
                                  aBottomMargin,
544
0
                                  aLeftMargin);
545
0
546
0
  nsLayoutUtils::SetDisplayPortMargins(aElement, presShell, displayportMargins,
547
0
                                       aPriority);
548
0
549
0
  return NS_OK;
550
0
}
551
552
553
NS_IMETHODIMP
554
nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
555
                                               int32_t aY,
556
                                               int32_t aWidth,
557
                                               int32_t aHeight,
558
                                               Element* aElement)
559
0
{
560
0
  nsIPresShell* presShell = GetPresShell();
561
0
  if (!presShell) {
562
0
    return NS_ERROR_FAILURE;
563
0
  }
564
0
565
0
  if (!aElement) {
566
0
    return NS_ERROR_INVALID_ARG;
567
0
  }
568
0
569
0
  if (aElement->GetUncomposedDoc() != presShell->GetDocument()) {
570
0
    return NS_ERROR_INVALID_ARG;
571
0
  }
572
0
573
0
  nsLayoutUtils::SetDisplayPortBase(aElement, nsRect(aX, aY, aWidth, aHeight));
574
0
575
0
  return NS_OK;
576
0
}
577
578
NS_IMETHODIMP
579
nsDOMWindowUtils::SetResolution(float aResolution)
580
0
{
581
0
  nsIPresShell* presShell = GetPresShell();
582
0
  if (!presShell) {
583
0
    return NS_ERROR_FAILURE;
584
0
  }
585
0
586
0
  presShell->SetResolution(aResolution);
587
0
588
0
  return NS_OK;
589
0
}
590
591
NS_IMETHODIMP
592
nsDOMWindowUtils::SetResolutionAndScaleTo(float aResolution)
593
0
{
594
0
  nsIPresShell* presShell = GetPresShell();
595
0
  if (!presShell) {
596
0
    return NS_ERROR_FAILURE;
597
0
  }
598
0
599
0
  presShell->SetResolutionAndScaleTo(aResolution);
600
0
601
0
  return NS_OK;
602
0
}
603
604
NS_IMETHODIMP
605
nsDOMWindowUtils::SetRestoreResolution(float aResolution,
606
                                       uint32_t aDisplayWidth,
607
                                       uint32_t aDisplayHeight)
608
0
{
609
0
  nsIPresShell* presShell = GetPresShell();
610
0
  if (!presShell) {
611
0
    return NS_ERROR_FAILURE;
612
0
  }
613
0
614
0
  presShell->SetRestoreResolution(aResolution,
615
0
    LayoutDeviceIntSize(aDisplayWidth, aDisplayHeight));
616
0
617
0
  return NS_OK;
618
0
}
619
620
NS_IMETHODIMP
621
nsDOMWindowUtils::GetResolution(float* aResolution)
622
0
{
623
0
  nsIPresShell* presShell = GetPresShell();
624
0
  if (!presShell) {
625
0
    return NS_ERROR_FAILURE;
626
0
  }
627
0
628
0
  *aResolution = presShell->GetResolution();
629
0
630
0
  return NS_OK;
631
0
}
632
633
NS_IMETHODIMP
634
0
nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) {
635
0
  nsIPresShell* presShell = GetPresShell();
636
0
  if (!presShell) {
637
0
    return NS_ERROR_FAILURE;
638
0
  }
639
0
640
0
  *aIsResolutionSet = presShell->IsResolutionSet();
641
0
642
0
  return NS_OK;
643
0
}
644
645
NS_IMETHODIMP
646
nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
647
0
{
648
0
  nsIPresShell* presShell = GetPresShell();
649
0
  if (presShell) {
650
0
    presShell->SetIsFirstPaint(aIsFirstPaint);
651
0
    return NS_OK;
652
0
  }
653
0
  return NS_ERROR_FAILURE;
654
0
}
655
656
NS_IMETHODIMP
657
nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint)
658
0
{
659
0
  nsIPresShell* presShell = GetPresShell();
660
0
  if (presShell) {
661
0
    *aIsFirstPaint = presShell->GetIsFirstPaint();
662
0
    return NS_OK;
663
0
  }
664
0
  return NS_ERROR_FAILURE;
665
0
}
666
667
NS_IMETHODIMP
668
nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId)
669
0
{
670
0
  nsIPresShell* presShell = GetPresShell();
671
0
  if (presShell) {
672
0
    *aPresShellId = presShell->GetPresShellId();
673
0
    return NS_OK;
674
0
  }
675
0
  return NS_ERROR_FAILURE;
676
0
}
677
678
NS_IMETHODIMP
679
nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
680
                                 float aX,
681
                                 float aY,
682
                                 int32_t aButton,
683
                                 int32_t aClickCount,
684
                                 int32_t aModifiers,
685
                                 bool aIgnoreRootScrollFrame,
686
                                 float aPressure,
687
                                 unsigned short aInputSourceArg,
688
                                 bool aIsDOMEventSynthesized,
689
                                 bool aIsWidgetEventSynthesized,
690
                                 int32_t aButtons,
691
                                 uint32_t aIdentifier,
692
                                 uint8_t aOptionalArgCount,
693
                                 bool *aPreventDefault)
694
0
{
695
0
  return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
696
0
                              aIgnoreRootScrollFrame, aPressure,
697
0
                              aInputSourceArg,
698
0
                              aOptionalArgCount >= 7 ?
699
0
                                aIdentifier : DEFAULT_MOUSE_POINTER_ID,
700
0
                              false, aPreventDefault,
701
0
                              aOptionalArgCount >= 4 ?
702
0
                                aIsDOMEventSynthesized : true,
703
0
                              aOptionalArgCount >= 5 ?
704
0
                                aIsWidgetEventSynthesized : false,
705
0
                              aOptionalArgCount >= 6 ?
706
0
                              aButtons : MOUSE_BUTTONS_NOT_SPECIFIED);
707
0
}
708
709
NS_IMETHODIMP
710
nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
711
                                         float aX,
712
                                         float aY,
713
                                         int32_t aButton,
714
                                         int32_t aClickCount,
715
                                         int32_t aModifiers,
716
                                         bool aIgnoreRootScrollFrame,
717
                                         float aPressure,
718
                                         unsigned short aInputSourceArg,
719
                                         bool aIsDOMEventSynthesized,
720
                                         bool aIsWidgetEventSynthesized,
721
                                         int32_t aButtons,
722
                                         uint32_t aIdentifier,
723
                                         uint8_t aOptionalArgCount)
724
0
{
725
0
  AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendMouseEventToWindow", OTHER);
726
0
727
0
  return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
728
0
                              aIgnoreRootScrollFrame, aPressure,
729
0
                              aInputSourceArg,
730
0
                              aOptionalArgCount >= 7 ?
731
0
                                aIdentifier : DEFAULT_MOUSE_POINTER_ID,
732
0
                              true, nullptr,
733
0
                              aOptionalArgCount >= 4 ?
734
0
                                aIsDOMEventSynthesized : true,
735
0
                              aOptionalArgCount >= 5 ?
736
0
                                aIsWidgetEventSynthesized : false,
737
0
                              aOptionalArgCount >= 6 ?
738
0
                              aButtons : MOUSE_BUTTONS_NOT_SPECIFIED);
739
0
}
740
741
NS_IMETHODIMP
742
nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
743
                                       float aX,
744
                                       float aY,
745
                                       int32_t aButton,
746
                                       int32_t aClickCount,
747
                                       int32_t aModifiers,
748
                                       bool aIgnoreRootScrollFrame,
749
                                       float aPressure,
750
                                       unsigned short aInputSourceArg,
751
                                       uint32_t aPointerId,
752
                                       bool aToWindow,
753
                                       bool *aPreventDefault,
754
                                       bool aIsDOMEventSynthesized,
755
                                       bool aIsWidgetEventSynthesized,
756
                                       int32_t aButtons)
757
0
{
758
0
  nsCOMPtr<nsIPresShell> presShell = GetPresShell();
759
0
  return nsContentUtils::SendMouseEvent(presShell, aType, aX, aY, aButton,
760
0
      aButtons, aClickCount, aModifiers, aIgnoreRootScrollFrame, aPressure,
761
0
      aInputSourceArg, aPointerId, aToWindow, aPreventDefault,
762
0
      aIsDOMEventSynthesized, aIsWidgetEventSynthesized);
763
0
}
764
765
NS_IMETHODIMP
766
nsDOMWindowUtils::SendWheelEvent(float aX,
767
                                 float aY,
768
                                 double aDeltaX,
769
                                 double aDeltaY,
770
                                 double aDeltaZ,
771
                                 uint32_t aDeltaMode,
772
                                 int32_t aModifiers,
773
                                 int32_t aLineOrPageDeltaX,
774
                                 int32_t aLineOrPageDeltaY,
775
                                 uint32_t aOptions)
776
0
{
777
0
  // get the widget to send the event to
778
0
  nsPoint offset;
779
0
  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
780
0
  if (!widget) {
781
0
    return NS_ERROR_NULL_POINTER;
782
0
  }
783
0
784
0
  WidgetWheelEvent wheelEvent(true, eWheel, widget);
785
0
  wheelEvent.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
786
0
  wheelEvent.mDeltaX = aDeltaX;
787
0
  wheelEvent.mDeltaY = aDeltaY;
788
0
  wheelEvent.mDeltaZ = aDeltaZ;
789
0
  wheelEvent.mDeltaMode = aDeltaMode;
790
0
  wheelEvent.mIsMomentum =
791
0
    (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
792
0
  wheelEvent.mIsNoLineOrPageDelta =
793
0
    (aOptions & WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE) != 0;
794
0
  wheelEvent.mCustomizedByUserPrefs =
795
0
    (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
796
0
  wheelEvent.mLineOrPageDeltaX = aLineOrPageDeltaX;
797
0
  wheelEvent.mLineOrPageDeltaY = aLineOrPageDeltaY;
798
0
799
0
  wheelEvent.mTime = PR_Now() / 1000;
800
0
801
0
  nsPresContext* presContext = GetPresContext();
802
0
  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
803
0
804
0
  wheelEvent.mRefPoint =
805
0
    nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
806
0
807
0
  widget->DispatchInputEvent(&wheelEvent);
808
0
809
0
  if (widget->AsyncPanZoomEnabled()) {
810
0
    // Computing overflow deltas is not compatible with APZ, so if APZ is
811
0
    // enabled, we skip testing it.
812
0
    return NS_OK;
813
0
  }
814
0
815
0
  bool failedX = false;
816
0
  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
817
0
      wheelEvent.mOverflowDeltaX != 0) {
818
0
    failedX = true;
819
0
  }
820
0
  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) &&
821
0
      wheelEvent.mOverflowDeltaX <= 0) {
822
0
    failedX = true;
823
0
  }
824
0
  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) &&
825
0
      wheelEvent.mOverflowDeltaX >= 0) {
826
0
    failedX = true;
827
0
  }
828
0
  bool failedY = false;
829
0
  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) &&
830
0
      wheelEvent.mOverflowDeltaY != 0) {
831
0
    failedY = true;
832
0
  }
833
0
  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) &&
834
0
      wheelEvent.mOverflowDeltaY <= 0) {
835
0
    failedY = true;
836
0
  }
837
0
  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) &&
838
0
      wheelEvent.mOverflowDeltaY >= 0) {
839
0
    failedY = true;
840
0
  }
841
0
842
#ifdef DEBUG
843
  if (failedX) {
844
    nsPrintfCString debugMsg("SendWheelEvent(): unexpected mOverflowDeltaX: %f",
845
                             wheelEvent.mOverflowDeltaX);
846
    NS_WARNING(debugMsg.get());
847
  }
848
  if (failedY) {
849
    nsPrintfCString debugMsg("SendWheelEvent(): unexpected mOverflowDeltaY: %f",
850
                             wheelEvent.mOverflowDeltaY);
851
    NS_WARNING(debugMsg.get());
852
  }
853
#endif
854
855
0
  return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE;
856
0
}
857
858
NS_IMETHODIMP
859
nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
860
                                 uint32_t *aIdentifiers,
861
                                 int32_t *aXs,
862
                                 int32_t *aYs,
863
                                 uint32_t *aRxs,
864
                                 uint32_t *aRys,
865
                                 float *aRotationAngles,
866
                                 float *aForces,
867
                                 uint32_t aCount,
868
                                 int32_t aModifiers,
869
                                 bool aIgnoreRootScrollFrame,
870
                                 bool *aPreventDefault)
871
0
{
872
0
  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
873
0
                              aRotationAngles, aForces, aCount, aModifiers,
874
0
                              aIgnoreRootScrollFrame, false, aPreventDefault);
875
0
}
876
877
NS_IMETHODIMP
878
nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
879
                                         uint32_t* aIdentifiers,
880
                                         int32_t* aXs,
881
                                         int32_t* aYs,
882
                                         uint32_t* aRxs,
883
                                         uint32_t* aRys,
884
                                         float* aRotationAngles,
885
                                         float* aForces,
886
                                         uint32_t aCount,
887
                                         int32_t aModifiers,
888
                                         bool aIgnoreRootScrollFrame,
889
                                         bool* aPreventDefault)
890
0
{
891
0
  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
892
0
                              aRotationAngles, aForces, aCount, aModifiers,
893
0
                              aIgnoreRootScrollFrame, true, aPreventDefault);
894
0
}
895
896
NS_IMETHODIMP
897
nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
898
                                       uint32_t* aIdentifiers,
899
                                       int32_t* aXs,
900
                                       int32_t* aYs,
901
                                       uint32_t* aRxs,
902
                                       uint32_t* aRys,
903
                                       float* aRotationAngles,
904
                                       float* aForces,
905
                                       uint32_t aCount,
906
                                       int32_t aModifiers,
907
                                       bool aIgnoreRootScrollFrame,
908
                                       bool aToWindow,
909
                                       bool* aPreventDefault)
910
0
{
911
0
  // get the widget to send the event to
912
0
  nsPoint offset;
913
0
  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
914
0
  if (!widget) {
915
0
    return NS_ERROR_NULL_POINTER;
916
0
  }
917
0
  EventMessage msg;
918
0
  if (aType.EqualsLiteral("touchstart")) {
919
0
    msg = eTouchStart;
920
0
  } else if (aType.EqualsLiteral("touchmove")) {
921
0
    msg = eTouchMove;
922
0
  } else if (aType.EqualsLiteral("touchend")) {
923
0
    msg = eTouchEnd;
924
0
  } else if (aType.EqualsLiteral("touchcancel")) {
925
0
    msg = eTouchCancel;
926
0
  } else {
927
0
    return NS_ERROR_UNEXPECTED;
928
0
  }
929
0
  WidgetTouchEvent event(true, msg, widget);
930
0
  event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
931
0
  event.mTime = PR_Now();
932
0
933
0
  nsPresContext* presContext = GetPresContext();
934
0
  if (!presContext) {
935
0
    return NS_ERROR_FAILURE;
936
0
  }
937
0
  event.mTouches.SetCapacity(aCount);
938
0
  for (uint32_t i = 0; i < aCount; ++i) {
939
0
    LayoutDeviceIntPoint pt =
940
0
      nsContentUtils::ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
941
0
    LayoutDeviceIntPoint radius =
942
0
      LayoutDeviceIntPoint::FromAppUnitsRounded(
943
0
        CSSPoint::ToAppUnits(CSSPoint(aRxs[i], aRys[i])),
944
0
        presContext->AppUnitsPerDevPixel());
945
0
946
0
    RefPtr<Touch> t =
947
0
      new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], aForces[i]);
948
0
949
0
    event.mTouches.AppendElement(t);
950
0
  }
951
0
952
0
  nsEventStatus status;
953
0
  if (aToWindow) {
954
0
    nsCOMPtr<nsIPresShell> presShell;
955
0
    nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
956
0
    if (!presShell || !view) {
957
0
      return NS_ERROR_FAILURE;
958
0
    }
959
0
    status = nsEventStatus_eIgnore;
960
0
    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
961
0
    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
962
0
  }
963
0
964
0
  nsresult rv = widget->DispatchEvent(&event, status);
965
0
  *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
966
0
  return rv;
967
0
}
968
969
NS_IMETHODIMP
970
nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout,
971
                                     int32_t aNativeKeyCode,
972
                                     int32_t aModifiers,
973
                                     const nsAString& aCharacters,
974
                                     const nsAString& aUnmodifiedCharacters,
975
                                     nsIObserver* aObserver)
976
0
{
977
0
  // get the widget to send the event to
978
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
979
0
  if (!widget)
980
0
    return NS_ERROR_FAILURE;
981
0
982
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
983
0
    NewRunnableMethod<int32_t,
984
0
                      int32_t,
985
0
                      uint32_t,
986
0
                      nsString,
987
0
                      nsString,
988
0
                      nsIObserver*>("nsIWidget::SynthesizeNativeKeyEvent",
989
0
                                    widget,
990
0
                                    &nsIWidget::SynthesizeNativeKeyEvent,
991
0
                                    aNativeKeyboardLayout,
992
0
                                    aNativeKeyCode,
993
0
                                    aModifiers,
994
0
                                    aCharacters,
995
0
                                    aUnmodifiedCharacters,
996
0
                                    aObserver)));
997
0
  return NS_OK;
998
0
}
999
1000
NS_IMETHODIMP
1001
nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX,
1002
                                       int32_t aScreenY,
1003
                                       int32_t aNativeMessage,
1004
                                       int32_t aModifierFlags,
1005
                                       Element* aElement,
1006
                                       nsIObserver* aObserver)
1007
0
{
1008
0
  // get the widget to send the event to
1009
0
  nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
1010
0
  if (!widget)
1011
0
    return NS_ERROR_FAILURE;
1012
0
1013
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
1014
0
    NewRunnableMethod<LayoutDeviceIntPoint, int32_t, int32_t, nsIObserver*>(
1015
0
      "nsIWidget::SynthesizeNativeMouseEvent",
1016
0
      widget,
1017
0
      &nsIWidget::SynthesizeNativeMouseEvent,
1018
0
      LayoutDeviceIntPoint(aScreenX, aScreenY),
1019
0
      aNativeMessage,
1020
0
      aModifierFlags,
1021
0
      aObserver)));
1022
0
  return NS_OK;
1023
0
}
1024
1025
NS_IMETHODIMP
1026
nsDOMWindowUtils::SendNativeMouseMove(int32_t aScreenX,
1027
                                      int32_t aScreenY,
1028
                                      Element* aElement,
1029
                                      nsIObserver* aObserver)
1030
0
{
1031
0
  // get the widget to send the event to
1032
0
  nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
1033
0
  if (!widget)
1034
0
    return NS_ERROR_FAILURE;
1035
0
1036
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
1037
0
    NewRunnableMethod<LayoutDeviceIntPoint, nsIObserver*>(
1038
0
      "nsIWidget::SynthesizeNativeMouseMove",
1039
0
      widget,
1040
0
      &nsIWidget::SynthesizeNativeMouseMove,
1041
0
      LayoutDeviceIntPoint(aScreenX, aScreenY),
1042
0
      aObserver)));
1043
0
  return NS_OK;
1044
0
}
1045
1046
NS_IMETHODIMP
1047
nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX,
1048
                                             int32_t aScreenY,
1049
                                             uint32_t aNativeMessage,
1050
                                             double aDeltaX,
1051
                                             double aDeltaY,
1052
                                             double aDeltaZ,
1053
                                             uint32_t aModifierFlags,
1054
                                             uint32_t aAdditionalFlags,
1055
                                             Element* aElement,
1056
                                             nsIObserver* aObserver)
1057
0
{
1058
0
  // get the widget to send the event to
1059
0
  nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
1060
0
  if (!widget) {
1061
0
    return NS_ERROR_FAILURE;
1062
0
  }
1063
0
1064
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
1065
0
    NewRunnableMethod<mozilla::LayoutDeviceIntPoint,
1066
0
                      uint32_t,
1067
0
                      double,
1068
0
                      double,
1069
0
                      double,
1070
0
                      uint32_t,
1071
0
                      uint32_t,
1072
0
                      nsIObserver*>(
1073
0
      "nsIWidget::SynthesizeNativeMouseScrollEvent",
1074
0
      widget,
1075
0
      &nsIWidget::SynthesizeNativeMouseScrollEvent,
1076
0
      LayoutDeviceIntPoint(aScreenX, aScreenY),
1077
0
      aNativeMessage,
1078
0
      aDeltaX,
1079
0
      aDeltaY,
1080
0
      aDeltaZ,
1081
0
      aModifierFlags,
1082
0
      aAdditionalFlags,
1083
0
      aObserver)));
1084
0
  return NS_OK;
1085
0
}
1086
1087
NS_IMETHODIMP
1088
nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId,
1089
                                       uint32_t aTouchState,
1090
                                       int32_t aScreenX,
1091
                                       int32_t aScreenY,
1092
                                       double aPressure,
1093
                                       uint32_t aOrientation,
1094
                                       nsIObserver* aObserver)
1095
0
{
1096
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1097
0
  if (!widget) {
1098
0
    return NS_ERROR_FAILURE;
1099
0
  }
1100
0
1101
0
  if (aPressure < 0 || aPressure > 1 || aOrientation > 359) {
1102
0
    return NS_ERROR_INVALID_ARG;
1103
0
  }
1104
0
1105
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
1106
0
    NewRunnableMethod<uint32_t,
1107
0
                      nsIWidget::TouchPointerState,
1108
0
                      LayoutDeviceIntPoint,
1109
0
                      double,
1110
0
                      uint32_t,
1111
0
                      nsIObserver*>("nsIWidget::SynthesizeNativeTouchPoint",
1112
0
                                    widget,
1113
0
                                    &nsIWidget::SynthesizeNativeTouchPoint,
1114
0
                                    aPointerId,
1115
0
                                    (nsIWidget::TouchPointerState)aTouchState,
1116
0
                                    LayoutDeviceIntPoint(aScreenX, aScreenY),
1117
0
                                    aPressure,
1118
0
                                    aOrientation,
1119
0
                                    aObserver)));
1120
0
  return NS_OK;
1121
0
}
1122
1123
NS_IMETHODIMP
1124
nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX,
1125
                                     int32_t aScreenY,
1126
                                     bool aLongTap,
1127
                                     nsIObserver* aObserver)
1128
0
{
1129
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1130
0
  if (!widget) {
1131
0
    return NS_ERROR_FAILURE;
1132
0
  }
1133
0
1134
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
1135
0
    NewRunnableMethod<LayoutDeviceIntPoint, bool, nsIObserver*>(
1136
0
      "nsIWidget::SynthesizeNativeTouchTap",
1137
0
      widget,
1138
0
      &nsIWidget::SynthesizeNativeTouchTap,
1139
0
      LayoutDeviceIntPoint(aScreenX, aScreenY),
1140
0
      aLongTap,
1141
0
      aObserver)));
1142
0
  return NS_OK;
1143
0
}
1144
1145
NS_IMETHODIMP
1146
nsDOMWindowUtils::SuppressAnimation(bool aSuppress)
1147
0
{
1148
0
  nsIWidget* widget = GetWidget();
1149
0
  if (widget) {
1150
0
    widget->SuppressAnimation(aSuppress);
1151
0
  }
1152
0
  return NS_OK;
1153
0
}
1154
1155
NS_IMETHODIMP
1156
nsDOMWindowUtils::ClearNativeTouchSequence(nsIObserver* aObserver)
1157
0
{
1158
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1159
0
  if (!widget) {
1160
0
    return NS_ERROR_FAILURE;
1161
0
  }
1162
0
1163
0
  NS_DispatchToMainThread(NativeInputRunnable::Create(
1164
0
    NewRunnableMethod<nsIObserver*>("nsIWidget::ClearNativeTouchSequence",
1165
0
                                    widget,
1166
0
                                    &nsIWidget::ClearNativeTouchSequence,
1167
0
                                    aObserver)));
1168
0
  return NS_OK;
1169
0
}
1170
1171
NS_IMETHODIMP
1172
nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
1173
0
{
1174
0
  // get the widget to send the event to
1175
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1176
0
  if (!widget)
1177
0
    return NS_ERROR_FAILURE;
1178
0
1179
0
  return widget->ActivateNativeMenuItemAt(indexString);
1180
0
}
1181
1182
NS_IMETHODIMP
1183
nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
1184
0
{
1185
0
  // get the widget to send the event to
1186
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1187
0
  if (!widget)
1188
0
    return NS_ERROR_FAILURE;
1189
0
1190
0
  return widget->ForceUpdateNativeMenuAt(indexString);
1191
0
}
1192
1193
NS_IMETHODIMP
1194
nsDOMWindowUtils::GetSelectionAsPlaintext(nsAString& aResult)
1195
0
{
1196
0
  // Get the widget to send the event to.
1197
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1198
0
  if (!widget) {
1199
0
    return NS_ERROR_FAILURE;
1200
0
  }
1201
0
1202
0
  return widget->GetSelectionAsPlaintext(aResult);
1203
0
}
1204
1205
nsIWidget*
1206
nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
1207
0
{
1208
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1209
0
  if (window) {
1210
0
    nsIDocShell *docShell = window->GetDocShell();
1211
0
    if (docShell) {
1212
0
      nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
1213
0
      return nsContentUtils::GetWidget(presShell, aOffset);
1214
0
    }
1215
0
  }
1216
0
1217
0
  return nullptr;
1218
0
}
1219
1220
nsIWidget*
1221
nsDOMWindowUtils::GetWidgetForElement(Element* aElement)
1222
0
{
1223
0
  if (!aElement)
1224
0
    return GetWidget();
1225
0
1226
0
  nsIDocument* doc = aElement->GetUncomposedDoc();
1227
0
  nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
1228
0
1229
0
  if (presShell) {
1230
0
    nsIFrame* frame = aElement->GetPrimaryFrame();
1231
0
    if (!frame) {
1232
0
      frame = presShell->GetRootFrame();
1233
0
    }
1234
0
    if (frame)
1235
0
      return frame->GetNearestWidget();
1236
0
  }
1237
0
1238
0
  return nullptr;
1239
0
}
1240
1241
NS_IMETHODIMP
1242
nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener)
1243
0
{
1244
0
  AUTO_PROFILER_LABEL("nsDOMWindowUtils::GarbageCollect", GCCC);
1245
0
1246
0
  nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
1247
0
  nsJSContext::CycleCollectNow(aListener);
1248
0
1249
0
  return NS_OK;
1250
0
}
1251
1252
NS_IMETHODIMP
1253
nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener)
1254
0
{
1255
0
  nsJSContext::CycleCollectNow(aListener);
1256
0
  return NS_OK;
1257
0
}
1258
1259
NS_IMETHODIMP
1260
nsDOMWindowUtils::RunNextCollectorTimer()
1261
0
{
1262
0
  nsJSContext::RunNextCollectorTimer(JS::gcreason::DOM_WINDOW_UTILS);
1263
0
1264
0
  return NS_OK;
1265
0
}
1266
1267
NS_IMETHODIMP
1268
nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
1269
                                         float aX,
1270
                                         float aY,
1271
                                         uint32_t aDirection,
1272
                                         double aDelta,
1273
                                         int32_t aModifiers,
1274
                                         uint32_t aClickCount)
1275
0
{
1276
0
  // get the widget to send the event to
1277
0
  nsPoint offset;
1278
0
  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
1279
0
  if (!widget)
1280
0
    return NS_ERROR_FAILURE;
1281
0
1282
0
  EventMessage msg;
1283
0
  if (aType.EqualsLiteral("MozSwipeGestureMayStart")) {
1284
0
    msg = eSwipeGestureMayStart;
1285
0
  } else if (aType.EqualsLiteral("MozSwipeGestureStart")) {
1286
0
    msg = eSwipeGestureStart;
1287
0
  } else if (aType.EqualsLiteral("MozSwipeGestureUpdate")) {
1288
0
    msg = eSwipeGestureUpdate;
1289
0
  } else if (aType.EqualsLiteral("MozSwipeGestureEnd")) {
1290
0
    msg = eSwipeGestureEnd;
1291
0
  } else if (aType.EqualsLiteral("MozSwipeGesture")) {
1292
0
    msg = eSwipeGesture;
1293
0
  } else if (aType.EqualsLiteral("MozMagnifyGestureStart")) {
1294
0
    msg = eMagnifyGestureStart;
1295
0
  } else if (aType.EqualsLiteral("MozMagnifyGestureUpdate")) {
1296
0
    msg = eMagnifyGestureUpdate;
1297
0
  } else if (aType.EqualsLiteral("MozMagnifyGesture")) {
1298
0
    msg = eMagnifyGesture;
1299
0
  } else if (aType.EqualsLiteral("MozRotateGestureStart")) {
1300
0
    msg = eRotateGestureStart;
1301
0
  } else if (aType.EqualsLiteral("MozRotateGestureUpdate")) {
1302
0
    msg = eRotateGestureUpdate;
1303
0
  } else if (aType.EqualsLiteral("MozRotateGesture")) {
1304
0
    msg = eRotateGesture;
1305
0
  } else if (aType.EqualsLiteral("MozTapGesture")) {
1306
0
    msg = eTapGesture;
1307
0
  } else if (aType.EqualsLiteral("MozPressTapGesture")) {
1308
0
    msg = ePressTapGesture;
1309
0
  } else if (aType.EqualsLiteral("MozEdgeUIStarted")) {
1310
0
    msg = eEdgeUIStarted;
1311
0
  } else if (aType.EqualsLiteral("MozEdgeUICanceled")) {
1312
0
    msg = eEdgeUICanceled;
1313
0
  } else if (aType.EqualsLiteral("MozEdgeUICompleted")) {
1314
0
    msg = eEdgeUICompleted;
1315
0
  } else {
1316
0
    return NS_ERROR_FAILURE;
1317
0
  }
1318
0
1319
0
  WidgetSimpleGestureEvent event(true, msg, widget);
1320
0
  event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
1321
0
  event.mDirection = aDirection;
1322
0
  event.mDelta = aDelta;
1323
0
  event.mClickCount = aClickCount;
1324
0
  event.mTime = PR_IntervalNow();
1325
0
1326
0
  nsPresContext* presContext = GetPresContext();
1327
0
  if (!presContext)
1328
0
    return NS_ERROR_FAILURE;
1329
0
1330
0
  event.mRefPoint =
1331
0
    nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
1332
0
1333
0
  nsEventStatus status;
1334
0
  return widget->DispatchEvent(&event, status);
1335
0
}
1336
1337
NS_IMETHODIMP
1338
nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
1339
                                   bool aIgnoreRootScrollFrame,
1340
                                   bool aFlushLayout,
1341
                                   Element** aReturn)
1342
0
{
1343
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1344
0
  NS_ENSURE_STATE(doc);
1345
0
1346
0
  RefPtr<Element> el =
1347
0
    doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
1348
0
  el.forget(aReturn);
1349
0
  return NS_OK;
1350
0
}
1351
1352
NS_IMETHODIMP
1353
nsDOMWindowUtils::NodesFromRect(float aX, float aY,
1354
                                float aTopSize, float aRightSize,
1355
                                float aBottomSize, float aLeftSize,
1356
                                bool aIgnoreRootScrollFrame,
1357
                                bool aFlushLayout,
1358
                                nsINodeList** aReturn)
1359
0
{
1360
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1361
0
  NS_ENSURE_STATE(doc);
1362
0
1363
0
  return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize,
1364
0
                                  aIgnoreRootScrollFrame, aFlushLayout, aReturn);
1365
0
}
1366
1367
NS_IMETHODIMP
1368
nsDOMWindowUtils::GetTranslationNodes(nsINode* aRoot,
1369
                                      nsITranslationNodeList** aRetVal)
1370
0
{
1371
0
  NS_ENSURE_ARG_POINTER(aRetVal);
1372
0
  nsCOMPtr<nsIContent> root = do_QueryInterface(aRoot);
1373
0
  NS_ENSURE_STATE(root);
1374
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1375
0
  NS_ENSURE_STATE(doc);
1376
0
1377
0
  if (root->OwnerDoc() != doc) {
1378
0
    return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
1379
0
  }
1380
0
1381
0
  nsTHashtable<nsPtrHashKey<nsIContent>> translationNodesHash(500);
1382
0
  RefPtr<nsTranslationNodeList> list = new nsTranslationNodeList;
1383
0
1384
0
  uint32_t limit = 15000;
1385
0
1386
0
  // We begin iteration with content->GetNextNode because we want to explictly
1387
0
  // skip the root tag from being a translation node.
1388
0
  nsIContent* content = root;
1389
0
  while ((limit > 0) && (content = content->GetNextNode(root))) {
1390
0
    if (!content->IsHTMLElement()) {
1391
0
      continue;
1392
0
    }
1393
0
1394
0
    // Skip elements that usually contain non-translatable text content.
1395
0
    if (content->IsAnyOfHTMLElements(nsGkAtoms::script,
1396
0
                                     nsGkAtoms::iframe,
1397
0
                                     nsGkAtoms::frameset,
1398
0
                                     nsGkAtoms::frame,
1399
0
                                     nsGkAtoms::code,
1400
0
                                     nsGkAtoms::noscript,
1401
0
                                     nsGkAtoms::style)) {
1402
0
      continue;
1403
0
    }
1404
0
1405
0
    // An element is a translation node if it contains
1406
0
    // at least one text node that has meaningful data
1407
0
    // for translation
1408
0
    for (nsIContent* child = content->GetFirstChild();
1409
0
         child;
1410
0
         child = child->GetNextSibling()) {
1411
0
1412
0
      if (child->IsText() && child->GetAsText()->HasTextForTranslation()) {
1413
0
        translationNodesHash.PutEntry(content);
1414
0
1415
0
        bool isBlockFrame = false;
1416
0
        nsIFrame* frame = content->GetPrimaryFrame();
1417
0
        if (frame) {
1418
0
          isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame);
1419
0
        }
1420
0
1421
0
        bool isTranslationRoot = isBlockFrame;
1422
0
        if (!isBlockFrame) {
1423
0
          // If an element is not a block element, it still
1424
0
          // can be considered a translation root if the parent
1425
0
          // of this element didn't make into the list of nodes
1426
0
          // to be translated.
1427
0
          bool parentInList = false;
1428
0
          nsIContent* parent = content->GetParent();
1429
0
          if (parent) {
1430
0
            parentInList = translationNodesHash.Contains(parent);
1431
0
          }
1432
0
          isTranslationRoot = !parentInList;
1433
0
        }
1434
0
1435
0
        list->AppendElement(content, isTranslationRoot);
1436
0
        --limit;
1437
0
        break;
1438
0
      }
1439
0
    }
1440
0
  }
1441
0
1442
0
  *aRetVal = list.forget().take();
1443
0
  return NS_OK;
1444
0
}
1445
1446
static already_AddRefed<DataSourceSurface>
1447
CanvasToDataSourceSurface(HTMLCanvasElement* aCanvas)
1448
0
{
1449
0
  MOZ_ASSERT(aCanvas);
1450
0
  nsLayoutUtils::SurfaceFromElementResult result =
1451
0
    nsLayoutUtils::SurfaceFromElement(aCanvas);
1452
0
1453
0
  MOZ_ASSERT(result.GetSourceSurface());
1454
0
  return result.GetSourceSurface()->GetDataSurface();
1455
0
}
1456
1457
NS_IMETHODIMP
1458
nsDOMWindowUtils::CompareCanvases(nsISupports *aCanvas1,
1459
                                  nsISupports *aCanvas2,
1460
                                  uint32_t* aMaxDifference,
1461
                                  uint32_t* retVal)
1462
0
{
1463
0
  if (aCanvas1 == nullptr ||
1464
0
      aCanvas2 == nullptr ||
1465
0
      retVal == nullptr)
1466
0
    return NS_ERROR_FAILURE;
1467
0
1468
0
  nsCOMPtr<nsIContent> contentCanvas1 = do_QueryInterface(aCanvas1);
1469
0
  nsCOMPtr<nsIContent> contentCanvas2 = do_QueryInterface(aCanvas2);
1470
0
  auto canvas1 = HTMLCanvasElement::FromNodeOrNull(contentCanvas1);
1471
0
  auto canvas2 = HTMLCanvasElement::FromNodeOrNull(contentCanvas2);
1472
0
1473
0
  if (!canvas1 || !canvas2) {
1474
0
    return NS_ERROR_FAILURE;
1475
0
  }
1476
0
1477
0
  RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(canvas1);
1478
0
  RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(canvas2);
1479
0
1480
0
  if (img1->Equals(img2)) {
1481
0
    // They point to the same underlying content.
1482
0
    return NS_OK;
1483
0
  }
1484
0
1485
0
  DataSourceSurface::ScopedMap map1(img1, DataSourceSurface::READ);
1486
0
  DataSourceSurface::ScopedMap map2(img2, DataSourceSurface::READ);
1487
0
1488
0
  if (img1 == nullptr || img2 == nullptr ||
1489
0
      !map1.IsMapped() || !map2.IsMapped() ||
1490
0
      img1->GetSize() != img2->GetSize() ||
1491
0
      map1.GetStride() != map2.GetStride()) {
1492
0
    return NS_ERROR_FAILURE;
1493
0
  }
1494
0
1495
0
  int v;
1496
0
  IntSize size = img1->GetSize();
1497
0
  int32_t stride = map1.GetStride();
1498
0
1499
0
  // we can optimize for the common all-pass case
1500
0
  if (stride == size.width * 4) {
1501
0
    v = memcmp(map1.GetData(), map2.GetData(), size.width * size.height * 4);
1502
0
    if (v == 0) {
1503
0
      if (aMaxDifference)
1504
0
        *aMaxDifference = 0;
1505
0
      *retVal = 0;
1506
0
      return NS_OK;
1507
0
    }
1508
0
  }
1509
0
1510
0
  uint32_t dc = 0;
1511
0
  uint32_t different = 0;
1512
0
1513
0
  for (int j = 0; j < size.height; j++) {
1514
0
    unsigned char *p1 = map1.GetData() + j*stride;
1515
0
    unsigned char *p2 = map2.GetData() + j*stride;
1516
0
    v = memcmp(p1, p2, stride);
1517
0
1518
0
    if (v) {
1519
0
      for (int i = 0; i < size.width; i++) {
1520
0
        if (*(uint32_t*) p1 != *(uint32_t*) p2) {
1521
0
1522
0
          different++;
1523
0
1524
0
          dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc);
1525
0
          dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc);
1526
0
          dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc);
1527
0
          dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc);
1528
0
        }
1529
0
1530
0
        p1 += 4;
1531
0
        p2 += 4;
1532
0
      }
1533
0
    }
1534
0
  }
1535
0
1536
0
  if (aMaxDifference)
1537
0
    *aMaxDifference = dc;
1538
0
1539
0
  *retVal = different;
1540
0
  return NS_OK;
1541
0
}
1542
1543
NS_IMETHODIMP
1544
nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
1545
0
{
1546
0
  NS_ENSURE_ARG_POINTER(aResult);
1547
0
  *aResult = false;
1548
0
  nsPresContext* presContext = GetPresContext();
1549
0
  if (!presContext)
1550
0
    return NS_OK;
1551
0
  *aResult = presContext->IsDOMPaintEventPending();
1552
0
  return NS_OK;
1553
0
}
1554
1555
NS_IMETHODIMP
1556
nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable)
1557
0
{
1558
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1559
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1560
0
  nsIDocShell *docShell = window->GetDocShell();
1561
0
  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1562
0
  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
1563
0
  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1564
0
  presShell->DisableNonTestMouseEvents(aDisable);
1565
0
  return NS_OK;
1566
0
}
1567
1568
NS_IMETHODIMP
1569
nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
1570
0
{
1571
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1572
0
  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
1573
0
1574
0
  if (aSuppress) {
1575
0
    doc->SuppressEventHandling();
1576
0
  } else {
1577
0
    doc->UnsuppressEventHandlingAndFireEvents(true);
1578
0
  }
1579
0
1580
0
  return NS_OK;
1581
0
}
1582
1583
static nsresult
1584
0
getScrollXYAppUnits(const nsWeakPtr& aWindow, bool aFlushLayout, nsPoint& aScrollPos) {
1585
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(aWindow);
1586
0
  nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr;
1587
0
  NS_ENSURE_STATE(doc);
1588
0
1589
0
  if (aFlushLayout) {
1590
0
    doc->FlushPendingNotifications(FlushType::Layout);
1591
0
  }
1592
0
1593
0
  nsIPresShell *presShell = doc->GetShell();
1594
0
  if (presShell) {
1595
0
    nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
1596
0
    if (sf) {
1597
0
      aScrollPos = sf->GetScrollPosition();
1598
0
    }
1599
0
  }
1600
0
  return NS_OK;
1601
0
}
1602
1603
NS_IMETHODIMP
1604
nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
1605
0
{
1606
0
  nsPoint scrollPos(0,0);
1607
0
  nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
1608
0
  NS_ENSURE_SUCCESS(rv, rv);
1609
0
  *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
1610
0
  *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
1611
0
1612
0
  return NS_OK;
1613
0
}
1614
1615
NS_IMETHODIMP
1616
nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY)
1617
0
{
1618
0
  nsPoint scrollPos(0,0);
1619
0
  nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
1620
0
  NS_ENSURE_SUCCESS(rv, rv);
1621
0
  *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x);
1622
0
  *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y);
1623
0
1624
0
  return NS_OK;
1625
0
}
1626
1627
NS_IMETHODIMP
1628
nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
1629
                                                      int32_t* aHeight)
1630
0
{
1631
0
  *aWidth = 0;
1632
0
  *aHeight = 0;
1633
0
1634
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1635
0
  NS_ENSURE_STATE(doc);
1636
0
1637
0
  if (aFlushLayout) {
1638
0
    doc->FlushPendingNotifications(FlushType::Layout);
1639
0
  }
1640
0
1641
0
  nsIPresShell* presShell = doc->GetShell();
1642
0
  NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
1643
0
1644
0
  nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
1645
0
  NS_ENSURE_TRUE(scrollFrame, NS_OK);
1646
0
1647
0
  nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
1648
0
  *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
1649
0
  *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
1650
0
1651
0
  return NS_OK;
1652
0
}
1653
1654
NS_IMETHODIMP
1655
nsDOMWindowUtils::GetBoundsWithoutFlushing(Element *aElement,
1656
                                           DOMRect** aResult)
1657
0
{
1658
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1659
0
  NS_ENSURE_STATE(window);
1660
0
1661
0
  NS_ENSURE_ARG_POINTER(aElement);
1662
0
1663
0
  RefPtr<DOMRect> rect = new DOMRect(window);
1664
0
  nsIFrame* frame = aElement->GetPrimaryFrame();
1665
0
1666
0
  if (frame) {
1667
0
    nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
1668
0
               nsLayoutUtils::GetContainingBlockForClientRect(frame),
1669
0
               nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
1670
0
    rect->SetLayoutRect(r);
1671
0
  }
1672
0
1673
0
  rect.forget(aResult);
1674
0
  return NS_OK;
1675
0
}
1676
1677
NS_IMETHODIMP
1678
nsDOMWindowUtils::NeedsFlush(int32_t aFlushType, bool* aResult)
1679
0
{
1680
0
  MOZ_ASSERT(aResult);
1681
0
1682
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1683
0
  NS_ENSURE_STATE(doc);
1684
0
1685
0
  nsIPresShell* presShell = doc->GetShell();
1686
0
  NS_ENSURE_STATE(presShell);
1687
0
1688
0
  FlushType flushType;
1689
0
  switch (aFlushType) {
1690
0
  case FLUSH_STYLE:
1691
0
    flushType = FlushType::Style;
1692
0
    break;
1693
0
1694
0
  case FLUSH_LAYOUT:
1695
0
    flushType = FlushType::Layout;
1696
0
    break;
1697
0
1698
0
  case FLUSH_DISPLAY:
1699
0
    flushType = FlushType::Display;
1700
0
    break;
1701
0
1702
0
  default:
1703
0
    return NS_ERROR_INVALID_ARG;
1704
0
  }
1705
0
1706
0
  *aResult = presShell->NeedFlush(flushType);
1707
0
  return NS_OK;
1708
0
}
1709
1710
NS_IMETHODIMP
1711
nsDOMWindowUtils::FlushLayoutWithoutThrottledAnimations()
1712
0
{
1713
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
1714
0
  if (doc) {
1715
0
    doc->FlushPendingNotifications(
1716
0
      ChangesToFlush(FlushType::Layout, false /* flush animations */));
1717
0
  }
1718
0
1719
0
  return NS_OK;
1720
0
}
1721
1722
NS_IMETHODIMP
1723
nsDOMWindowUtils::GetRootBounds(DOMRect** aResult)
1724
0
{
1725
0
  nsIDocument* doc = GetDocument();
1726
0
  NS_ENSURE_STATE(doc);
1727
0
1728
0
  nsRect bounds(0, 0, 0, 0);
1729
0
  nsIPresShell* presShell = doc->GetShell();
1730
0
  if (presShell) {
1731
0
    nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
1732
0
    if (sf) {
1733
0
      bounds = sf->GetScrollRange();
1734
0
      bounds.SetWidth(bounds.Width() + sf->GetScrollPortRect().Width());
1735
0
      bounds.SetHeight(bounds.Height() + sf->GetScrollPortRect().Height());
1736
0
    } else if (presShell->GetRootFrame()) {
1737
0
      bounds = presShell->GetRootFrame()->GetRect();
1738
0
    }
1739
0
  }
1740
0
1741
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1742
0
  RefPtr<DOMRect> rect = new DOMRect(window);
1743
0
  rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x),
1744
0
                nsPresContext::AppUnitsToFloatCSSPixels(bounds.y),
1745
0
                nsPresContext::AppUnitsToFloatCSSPixels(bounds.Width()),
1746
0
                nsPresContext::AppUnitsToFloatCSSPixels(bounds.Height()));
1747
0
  rect.forget(aResult);
1748
0
  return NS_OK;
1749
0
}
1750
1751
NS_IMETHODIMP
1752
nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
1753
0
{
1754
0
  NS_ENSURE_ARG_POINTER(aState);
1755
0
1756
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1757
0
  if (!widget)
1758
0
    return NS_ERROR_FAILURE;
1759
0
1760
0
  // Open state should not be available when IME is not enabled.
1761
0
  InputContext context = widget->GetInputContext();
1762
0
  if (context.mIMEState.mEnabled != IMEState::ENABLED) {
1763
0
    return NS_ERROR_NOT_AVAILABLE;
1764
0
  }
1765
0
1766
0
  if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
1767
0
    return NS_ERROR_NOT_IMPLEMENTED;
1768
0
  }
1769
0
  *aState = (context.mIMEState.mOpen == IMEState::OPEN);
1770
0
  return NS_OK;
1771
0
}
1772
1773
NS_IMETHODIMP
1774
nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
1775
0
{
1776
0
  NS_ENSURE_ARG_POINTER(aState);
1777
0
1778
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1779
0
  if (!widget)
1780
0
    return NS_ERROR_FAILURE;
1781
0
1782
0
  InputContext context = widget->GetInputContext();
1783
0
  *aState = static_cast<uint32_t>(context.mIMEState.mEnabled);
1784
0
  return NS_OK;
1785
0
}
1786
1787
NS_IMETHODIMP
1788
nsDOMWindowUtils::GetFocusedInputType(nsAString& aType)
1789
0
{
1790
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1791
0
  if (!widget) {
1792
0
    return NS_ERROR_FAILURE;
1793
0
  }
1794
0
1795
0
  aType = widget->GetInputContext().mHTMLInputType;
1796
0
  return NS_OK;
1797
0
}
1798
1799
NS_IMETHODIMP
1800
nsDOMWindowUtils::GetViewId(Element* aElement, nsViewID* aResult)
1801
0
{
1802
0
  if (aElement && nsLayoutUtils::FindIDFor(aElement, aResult)) {
1803
0
    return NS_OK;
1804
0
  }
1805
0
  return NS_ERROR_NOT_AVAILABLE;
1806
0
}
1807
1808
NS_IMETHODIMP
1809
nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
1810
0
{
1811
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1812
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1813
0
  *aScreenPixels = window->GetDevicePixelRatio(CallerType::System);
1814
0
  return NS_OK;
1815
0
}
1816
1817
NS_IMETHODIMP
1818
nsDOMWindowUtils::GetFullZoom(float* aFullZoom)
1819
0
{
1820
0
  *aFullZoom = 1.0f;
1821
0
1822
0
  nsPresContext* presContext = GetPresContext();
1823
0
  if (!presContext) {
1824
0
    return NS_OK;
1825
0
  }
1826
0
1827
0
  *aFullZoom = presContext->DeviceContext()->GetFullZoom();
1828
0
1829
0
  return NS_OK;
1830
0
}
1831
1832
NS_IMETHODIMP
1833
nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsINode* aTarget,
1834
                                               Event* aEvent,
1835
                                               bool aTrusted,
1836
                                               bool* aRetVal)
1837
0
{
1838
0
  NS_ENSURE_STATE(aEvent);
1839
0
  aEvent->SetTrusted(aTrusted);
1840
0
  WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
1841
0
  NS_ENSURE_STATE(internalEvent);
1842
0
  nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
1843
0
  NS_ENSURE_STATE(content);
1844
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1845
0
  if (content->OwnerDoc()->GetWindow() != window) {
1846
0
    return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
1847
0
  }
1848
0
  nsCOMPtr<nsIDocument> targetDoc = content->GetUncomposedDoc();
1849
0
  NS_ENSURE_STATE(targetDoc);
1850
0
  RefPtr<nsIPresShell> targetShell = targetDoc->GetShell();
1851
0
  NS_ENSURE_STATE(targetShell);
1852
0
1853
0
  targetDoc->FlushPendingNotifications(FlushType::Layout);
1854
0
1855
0
  nsEventStatus status = nsEventStatus_eIgnore;
1856
0
  targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status);
1857
0
  *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
1858
0
  return NS_OK;
1859
0
}
1860
1861
static void
1862
InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr)
1863
0
{
1864
0
  if (aPt) {
1865
0
    aEvent.mRefPoint = *aPt;
1866
0
  }
1867
0
  aEvent.mTime = PR_IntervalNow();
1868
0
}
1869
1870
NS_IMETHODIMP
1871
nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
1872
                                        int64_t aOffset, uint32_t aLength,
1873
                                        int32_t aX, int32_t aY,
1874
                                        uint32_t aAdditionalFlags,
1875
                                        nsIQueryContentEventResult **aResult)
1876
0
{
1877
0
  *aResult = nullptr;
1878
0
1879
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
1880
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1881
0
1882
0
  nsIDocShell *docShell = window->GetDocShell();
1883
0
  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1884
0
1885
0
  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
1886
0
  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1887
0
1888
0
  nsPresContext* presContext = presShell->GetPresContext();
1889
0
  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
1890
0
1891
0
  // get the widget to send the event to
1892
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
1893
0
  if (!widget) {
1894
0
    return NS_ERROR_FAILURE;
1895
0
  }
1896
0
1897
0
  EventMessage message;
1898
0
  switch (aType) {
1899
0
    case QUERY_SELECTED_TEXT:
1900
0
      message = eQuerySelectedText;
1901
0
      break;
1902
0
    case QUERY_TEXT_CONTENT:
1903
0
      message = eQueryTextContent;
1904
0
      break;
1905
0
    case QUERY_CARET_RECT:
1906
0
      message = eQueryCaretRect;
1907
0
      break;
1908
0
    case QUERY_TEXT_RECT:
1909
0
      message = eQueryTextRect;
1910
0
      break;
1911
0
    case QUERY_EDITOR_RECT:
1912
0
      message = eQueryEditorRect;
1913
0
      break;
1914
0
    case QUERY_CHARACTER_AT_POINT:
1915
0
      message = eQueryCharacterAtPoint;
1916
0
      break;
1917
0
    case QUERY_TEXT_RECT_ARRAY:
1918
0
      message = eQueryTextRectArray;
1919
0
      break;
1920
0
    default:
1921
0
      return NS_ERROR_INVALID_ARG;
1922
0
  }
1923
0
1924
0
  SelectionType selectionType = SelectionType::eNormal;
1925
0
  static const uint32_t kSelectionFlags =
1926
0
    QUERY_CONTENT_FLAG_SELECTION_SPELLCHECK |
1927
0
    QUERY_CONTENT_FLAG_SELECTION_IME_RAWINPUT |
1928
0
    QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDRAWTEXT |
1929
0
    QUERY_CONTENT_FLAG_SELECTION_IME_CONVERTEDTEXT |
1930
0
    QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDCONVERTEDTEXT |
1931
0
    QUERY_CONTENT_FLAG_SELECTION_ACCESSIBILITY |
1932
0
    QUERY_CONTENT_FLAG_SELECTION_FIND |
1933
0
    QUERY_CONTENT_FLAG_SELECTION_URLSECONDARY |
1934
0
    QUERY_CONTENT_FLAG_SELECTION_URLSTRIKEOUT;
1935
0
  switch (aAdditionalFlags & kSelectionFlags) {
1936
0
    case QUERY_CONTENT_FLAG_SELECTION_SPELLCHECK:
1937
0
      selectionType = SelectionType::eSpellCheck;
1938
0
      break;
1939
0
    case QUERY_CONTENT_FLAG_SELECTION_IME_RAWINPUT:
1940
0
      selectionType = SelectionType::eIMERawClause;
1941
0
      break;
1942
0
    case QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDRAWTEXT:
1943
0
      selectionType = SelectionType::eIMESelectedRawClause;
1944
0
      break;
1945
0
    case QUERY_CONTENT_FLAG_SELECTION_IME_CONVERTEDTEXT:
1946
0
      selectionType = SelectionType::eIMEConvertedClause;
1947
0
      break;
1948
0
    case QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDCONVERTEDTEXT:
1949
0
      selectionType = SelectionType::eIMESelectedClause;
1950
0
      break;
1951
0
    case QUERY_CONTENT_FLAG_SELECTION_ACCESSIBILITY:
1952
0
      selectionType = SelectionType::eAccessibility;
1953
0
      break;
1954
0
    case QUERY_CONTENT_FLAG_SELECTION_FIND:
1955
0
      selectionType = SelectionType::eFind;
1956
0
      break;
1957
0
    case QUERY_CONTENT_FLAG_SELECTION_URLSECONDARY:
1958
0
      selectionType = SelectionType::eURLSecondary;
1959
0
      break;
1960
0
    case QUERY_CONTENT_FLAG_SELECTION_URLSTRIKEOUT:
1961
0
      selectionType = SelectionType::eURLStrikeout;
1962
0
      break;
1963
0
    case 0:
1964
0
      break;
1965
0
    default:
1966
0
      return NS_ERROR_INVALID_ARG;
1967
0
  }
1968
0
1969
0
  if (selectionType != SelectionType::eNormal &&
1970
0
      message != eQuerySelectedText) {
1971
0
    return NS_ERROR_INVALID_ARG;
1972
0
  }
1973
0
1974
0
  nsCOMPtr<nsIWidget> targetWidget = widget;
1975
0
  LayoutDeviceIntPoint pt(aX, aY);
1976
0
1977
0
  WidgetQueryContentEvent::Options options;
1978
0
  options.mUseNativeLineBreak =
1979
0
    !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
1980
0
  options.mRelativeToInsertionPoint =
1981
0
    (aAdditionalFlags &
1982
0
       QUERY_CONTENT_FLAG_OFFSET_RELATIVE_TO_INSERTION_POINT) != 0;
1983
0
  if (options.mRelativeToInsertionPoint) {
1984
0
    switch (message) {
1985
0
      case eQueryTextContent:
1986
0
      case eQueryCaretRect:
1987
0
      case eQueryTextRect:
1988
0
        break;
1989
0
      default:
1990
0
        return NS_ERROR_INVALID_ARG;
1991
0
    }
1992
0
  } else if (aOffset < 0) {
1993
0
    return NS_ERROR_INVALID_ARG;
1994
0
  }
1995
0
1996
0
  if (message == eQueryCharacterAtPoint) {
1997
0
    // Looking for the widget at the point.
1998
0
    WidgetQueryContentEvent dummyEvent(true, eQueryContentState, widget);
1999
0
    dummyEvent.Init(options);
2000
0
    InitEvent(dummyEvent, &pt);
2001
0
    nsIFrame* popupFrame =
2002
0
      nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
2003
0
2004
0
    LayoutDeviceIntRect widgetBounds = widget->GetClientBounds();
2005
0
    widgetBounds.MoveTo(0, 0);
2006
0
2007
0
    // There is no popup frame at the point and the point isn't in our widget,
2008
0
    // we cannot process this request.
2009
0
    NS_ENSURE_TRUE(popupFrame || widgetBounds.Contains(pt), NS_ERROR_FAILURE);
2010
0
2011
0
    // Fire the event on the widget at the point
2012
0
    if (popupFrame) {
2013
0
      targetWidget = popupFrame->GetNearestWidget();
2014
0
    }
2015
0
  }
2016
0
2017
0
  pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset();
2018
0
2019
0
  WidgetQueryContentEvent queryEvent(true, message, targetWidget);
2020
0
  InitEvent(queryEvent, &pt);
2021
0
2022
0
  switch (message) {
2023
0
    case eQueryTextContent:
2024
0
      queryEvent.InitForQueryTextContent(aOffset, aLength, options);
2025
0
      break;
2026
0
    case eQueryCaretRect:
2027
0
      queryEvent.InitForQueryCaretRect(aOffset, options);
2028
0
      break;
2029
0
    case eQueryTextRect:
2030
0
      queryEvent.InitForQueryTextRect(aOffset, aLength, options);
2031
0
      break;
2032
0
    case eQuerySelectedText:
2033
0
      queryEvent.InitForQuerySelectedText(selectionType, options);
2034
0
      break;
2035
0
    case eQueryTextRectArray:
2036
0
      queryEvent.InitForQueryTextRectArray(aOffset, aLength, options);
2037
0
      break;
2038
0
    default:
2039
0
      queryEvent.Init(options);
2040
0
      break;
2041
0
  }
2042
0
2043
0
  nsEventStatus status;
2044
0
  nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
2045
0
  NS_ENSURE_SUCCESS(rv, rv);
2046
0
2047
0
  auto* result = new nsQueryContentEventResult(queryEvent);
2048
0
  result->SetEventResult(widget);
2049
0
  NS_ADDREF(*aResult = result);
2050
0
  return NS_OK;
2051
0
}
2052
2053
NS_IMETHODIMP
2054
nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
2055
                                        uint32_t aLength,
2056
                                        uint32_t aAdditionalFlags,
2057
                                        bool *aResult)
2058
0
{
2059
0
  *aResult = false;
2060
0
2061
0
  // get the widget to send the event to
2062
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2063
0
  if (!widget) {
2064
0
    return NS_ERROR_FAILURE;
2065
0
  }
2066
0
2067
0
  WidgetSelectionEvent selectionEvent(true, eSetSelection, widget);
2068
0
  InitEvent(selectionEvent);
2069
0
2070
0
  selectionEvent.mOffset = aOffset;
2071
0
  selectionEvent.mLength = aLength;
2072
0
  selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
2073
0
  selectionEvent.mUseNativeLineBreak =
2074
0
    !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
2075
0
2076
0
  nsEventStatus status;
2077
0
  nsresult rv = widget->DispatchEvent(&selectionEvent, status);
2078
0
  NS_ENSURE_SUCCESS(rv, rv);
2079
0
2080
0
  *aResult = selectionEvent.mSucceeded;
2081
0
  return NS_OK;
2082
0
}
2083
2084
NS_IMETHODIMP
2085
nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
2086
                                          nsITransferable * aTransferable)
2087
0
{
2088
0
  // get the widget to send the event to
2089
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2090
0
  if (!widget)
2091
0
    return NS_ERROR_FAILURE;
2092
0
2093
0
  EventMessage msg;
2094
0
  if (aType.EqualsLiteral("cut")) {
2095
0
    msg = eContentCommandCut;
2096
0
  } else if (aType.EqualsLiteral("copy")) {
2097
0
    msg = eContentCommandCopy;
2098
0
  } else if (aType.EqualsLiteral("paste")) {
2099
0
    msg = eContentCommandPaste;
2100
0
  } else if (aType.EqualsLiteral("delete")) {
2101
0
    msg = eContentCommandDelete;
2102
0
  } else if (aType.EqualsLiteral("undo")) {
2103
0
    msg = eContentCommandUndo;
2104
0
  } else if (aType.EqualsLiteral("redo")) {
2105
0
    msg = eContentCommandRedo;
2106
0
  } else if (aType.EqualsLiteral("pasteTransferable")) {
2107
0
    msg = eContentCommandPasteTransferable;
2108
0
  } else {
2109
0
    return NS_ERROR_FAILURE;
2110
0
  }
2111
0
2112
0
  WidgetContentCommandEvent event(true, msg, widget);
2113
0
  if (msg == eContentCommandPasteTransferable) {
2114
0
    event.mTransferable = aTransferable;
2115
0
  }
2116
0
2117
0
  nsEventStatus status;
2118
0
  return widget->DispatchEvent(&event, status);
2119
0
}
2120
2121
NS_IMETHODIMP
2122
nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
2123
                               char** aName)
2124
0
{
2125
0
  // Our argument must be a non-null object.
2126
0
  if (aObject.isPrimitive()) {
2127
0
    return NS_ERROR_XPC_BAD_CONVERT_JS;
2128
0
  }
2129
0
2130
0
  *aName = NS_xstrdup(JS_GetClass(aObject.toObjectOrNull())->name);
2131
0
  return NS_OK;
2132
0
}
2133
2134
NS_IMETHODIMP
2135
nsDOMWindowUtils::GetVisitedDependentComputedStyle(
2136
                    Element *aElement, const nsAString& aPseudoElement,
2137
                    const nsAString& aPropertyName, nsAString& aResult)
2138
0
{
2139
0
  aResult.Truncate();
2140
0
2141
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2142
0
  NS_ENSURE_STATE(window && aElement);
2143
0
  nsCOMPtr<nsPIDOMWindowInner> innerWindow = window->GetCurrentInnerWindow();
2144
0
  NS_ENSURE_STATE(window);
2145
0
2146
0
  nsCOMPtr<nsICSSDeclaration> decl;
2147
0
  {
2148
0
    ErrorResult rv;
2149
0
    decl = innerWindow->GetComputedStyle(*aElement, aPseudoElement, rv);
2150
0
    ENSURE_SUCCESS(rv, rv.StealNSResult());
2151
0
  }
2152
0
2153
0
  static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
2154
0
  nsresult rv = decl->GetPropertyValue(aPropertyName, aResult);
2155
0
  static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
2156
0
2157
0
  return rv;
2158
0
}
2159
2160
NS_IMETHODIMP
2161
nsDOMWindowUtils::EnterModalState()
2162
0
{
2163
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2164
0
  NS_ENSURE_STATE(window);
2165
0
2166
0
  window->EnterModalState();
2167
0
  return NS_OK;
2168
0
}
2169
2170
NS_IMETHODIMP
2171
nsDOMWindowUtils::LeaveModalState()
2172
0
{
2173
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2174
0
  NS_ENSURE_STATE(window);
2175
0
2176
0
  window->LeaveModalState();
2177
0
  return NS_OK;
2178
0
}
2179
2180
NS_IMETHODIMP
2181
nsDOMWindowUtils::IsInModalState(bool *retval)
2182
0
{
2183
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2184
0
  NS_ENSURE_STATE(window);
2185
0
2186
0
  *retval = nsGlobalWindowOuter::Cast(window)->IsInModalState();
2187
0
  return NS_OK;
2188
0
}
2189
2190
NS_IMETHODIMP
2191
nsDOMWindowUtils::SetDesktopModeViewport(bool aDesktopMode)
2192
0
{
2193
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2194
0
  NS_ENSURE_STATE(window);
2195
0
2196
0
  window->SetDesktopModeViewport(aDesktopMode);
2197
0
  return NS_OK;
2198
0
}
2199
2200
NS_IMETHODIMP
2201
nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
2202
0
{
2203
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2204
0
  NS_ENSURE_STATE(window);
2205
0
2206
0
  *aWindowID = window->WindowID();
2207
0
  return NS_OK;
2208
0
}
2209
2210
NS_IMETHODIMP
2211
nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID)
2212
0
{
2213
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2214
0
  NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
2215
0
2216
0
  nsGlobalWindowInner* inner =
2217
0
    nsGlobalWindowOuter::Cast(window)->GetCurrentInnerWindowInternal();
2218
0
  if (!inner) {
2219
0
    return NS_ERROR_NOT_AVAILABLE;
2220
0
  }
2221
0
  *aWindowID = inner->WindowID();
2222
0
  return NS_OK;
2223
0
}
2224
2225
NS_IMETHODIMP
2226
nsDOMWindowUtils::SuspendTimeouts()
2227
0
{
2228
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2229
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
2230
0
2231
0
  nsCOMPtr<nsPIDOMWindowInner> inner = window->GetCurrentInnerWindow();
2232
0
  NS_ENSURE_TRUE(inner, NS_ERROR_FAILURE);
2233
0
2234
0
  inner->Suspend();
2235
0
2236
0
  return NS_OK;
2237
0
}
2238
2239
NS_IMETHODIMP
2240
nsDOMWindowUtils::ResumeTimeouts()
2241
0
{
2242
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2243
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
2244
0
2245
0
  nsCOMPtr<nsPIDOMWindowInner> inner = window->GetCurrentInnerWindow();
2246
0
  NS_ENSURE_TRUE(inner, NS_ERROR_FAILURE);
2247
0
2248
0
  inner->Resume();
2249
0
2250
0
  return NS_OK;
2251
0
}
2252
2253
NS_IMETHODIMP
2254
nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
2255
0
{
2256
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2257
0
  if (!widget)
2258
0
    return NS_ERROR_FAILURE;
2259
0
2260
0
  LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT);
2261
0
  if (!mgr)
2262
0
    return NS_ERROR_FAILURE;
2263
0
2264
0
  mgr->GetBackendName(aType);
2265
0
2266
0
  return NS_OK;
2267
0
}
2268
2269
NS_IMETHODIMP
2270
nsDOMWindowUtils::GetLayerManagerRemote(bool* retval)
2271
0
{
2272
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2273
0
  if (!widget)
2274
0
    return NS_ERROR_FAILURE;
2275
0
2276
0
  LayerManager *mgr = widget->GetLayerManager();
2277
0
  if (!mgr)
2278
0
    return NS_ERROR_FAILURE;
2279
0
2280
0
  *retval = !!mgr->AsKnowsCompositor();
2281
0
  return NS_OK;
2282
0
}
2283
2284
NS_IMETHODIMP
2285
nsDOMWindowUtils::GetUsingAdvancedLayers(bool* retval)
2286
0
{
2287
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2288
0
  if (!widget) {
2289
0
    return NS_ERROR_FAILURE;
2290
0
  }
2291
0
2292
0
  LayerManager *mgr = widget->GetLayerManager();
2293
0
  if (!mgr) {
2294
0
    return NS_ERROR_FAILURE;
2295
0
  }
2296
0
2297
0
  *retval = false;
2298
0
  if (KnowsCompositor* fwd = mgr->AsKnowsCompositor()) {
2299
0
    *retval = fwd->GetTextureFactoryIdentifier().mUsingAdvancedLayers;
2300
0
  }
2301
0
  return NS_OK;
2302
0
}
2303
2304
NS_IMETHODIMP
2305
nsDOMWindowUtils::GetIsWebRenderBuilt(bool* retval)
2306
0
{
2307
0
#ifdef MOZ_BUILD_WEBRENDER
2308
0
  *retval = true;
2309
#else
2310
  *retval = false;
2311
#endif
2312
  return NS_OK;
2313
0
}
2314
2315
NS_IMETHODIMP
2316
nsDOMWindowUtils::GetIsWebRenderRequested(bool* retval)
2317
0
{
2318
0
  *retval = gfxPlatform::WebRenderPrefEnabled() ||
2319
0
            gfxPlatform::WebRenderEnvvarEnabled();
2320
0
  return NS_OK;
2321
0
}
2322
2323
NS_IMETHODIMP
2324
nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend)
2325
0
{
2326
0
  CubebUtils::GetCurrentBackend(aBackend);
2327
0
  return NS_OK;
2328
0
}
2329
2330
NS_IMETHODIMP
2331
nsDOMWindowUtils::GetCurrentMaxAudioChannels(uint32_t* aChannels)
2332
0
{
2333
0
  *aChannels = CubebUtils::MaxNumberOfChannels();
2334
0
  return NS_OK;
2335
0
}
2336
2337
NS_IMETHODIMP
2338
nsDOMWindowUtils::GetCurrentPreferredSampleRate(uint32_t* aRate)
2339
0
{
2340
0
  *aRate = CubebUtils::PreferredSampleRate();
2341
0
  return NS_OK;
2342
0
}
2343
2344
NS_IMETHODIMP
2345
nsDOMWindowUtils::AudioDevices(uint16_t aSide, nsIArray** aDevices)
2346
0
{
2347
0
  NS_ENSURE_ARG_POINTER(aDevices);
2348
0
  NS_ENSURE_ARG((aSide == AUDIO_INPUT) || (aSide == AUDIO_OUTPUT));
2349
0
  *aDevices = nullptr;
2350
0
2351
0
  nsresult rv = NS_OK;
2352
0
  nsCOMPtr<nsIMutableArray> devices =
2353
0
    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
2354
0
  NS_ENSURE_SUCCESS(rv, rv);
2355
0
2356
0
  nsTArray<RefPtr<AudioDeviceInfo>> collection;
2357
0
  CubebUtils::GetDeviceCollection(collection,
2358
0
                                  aSide == AUDIO_INPUT
2359
0
                                    ? CubebUtils::Side::Input
2360
0
                                    : CubebUtils::Side::Output);
2361
0
  for (auto device: collection) {
2362
0
    devices->AppendElement(device);
2363
0
  }
2364
0
2365
0
  devices.forget(aDevices);
2366
0
2367
0
  return NS_OK;
2368
0
}
2369
2370
NS_IMETHODIMP
2371
nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
2372
0
{
2373
0
  NS_ENSURE_ARG_POINTER(startIndex);
2374
0
2375
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2376
0
  if (!widget)
2377
0
    return NS_ERROR_FAILURE;
2378
0
2379
0
  LayerManager *mgr = widget->GetLayerManager();
2380
0
  if (!mgr)
2381
0
    return NS_ERROR_FAILURE;
2382
0
2383
0
  const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
2384
0
  const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
2385
0
  uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
2386
0
  bufferSize = std::min(bufferSize, kRecordingMaxSize);
2387
0
  bufferSize = std::max(bufferSize, kRecordingMinSize);
2388
0
  *startIndex = mgr->StartFrameTimeRecording(bufferSize);
2389
0
2390
0
  return NS_OK;
2391
0
}
2392
2393
NS_IMETHODIMP
2394
nsDOMWindowUtils::StopFrameTimeRecording(uint32_t   startIndex,
2395
                                         uint32_t  *frameCount,
2396
                                         float    **frameIntervals)
2397
0
{
2398
0
  NS_ENSURE_ARG_POINTER(frameCount);
2399
0
  NS_ENSURE_ARG_POINTER(frameIntervals);
2400
0
2401
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2402
0
  if (!widget)
2403
0
    return NS_ERROR_FAILURE;
2404
0
2405
0
  LayerManager *mgr = widget->GetLayerManager();
2406
0
  if (!mgr)
2407
0
    return NS_ERROR_FAILURE;
2408
0
2409
0
  nsTArray<float> tmpFrameIntervals;
2410
0
  mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
2411
0
  *frameCount = tmpFrameIntervals.Length();
2412
0
2413
0
  *frameIntervals = (float*)moz_xmalloc(*frameCount * sizeof(float));
2414
0
2415
0
  /* copy over the frame intervals and paint times into the arrays we just allocated */
2416
0
  for (uint32_t i = 0; i < *frameCount; i++) {
2417
0
    (*frameIntervals)[i] = tmpFrameIntervals[i];
2418
0
  }
2419
0
2420
0
  return NS_OK;
2421
0
}
2422
2423
NS_IMETHODIMP
2424
nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
2425
0
{
2426
0
  // Before we advance the time, we should trigger any animations that are
2427
0
  // waiting to start. This is because there are many tests that call this
2428
0
  // which expect animations to start immediately. Ideally, we should make
2429
0
  // all these tests do an asynchronous wait on the corresponding animation's
2430
0
  // 'ready' promise before continuing. Then we could remove the special
2431
0
  // handling here and the code path followed when testing would more closely
2432
0
  // match the code path during regular operation. Filed as bug 1112957.
2433
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
2434
0
  if (doc) {
2435
0
    PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker();
2436
0
    if (tracker) {
2437
0
      tracker->TriggerPendingAnimationsNow();
2438
0
    }
2439
0
  }
2440
0
2441
0
  nsPresContext* presContext = GetPresContext();
2442
0
  if (presContext) {
2443
0
    nsRefreshDriver* driver = presContext->RefreshDriver();
2444
0
    driver->AdvanceTimeAndRefresh(aMilliseconds);
2445
0
2446
0
    RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
2447
0
    if (transaction && transaction->IPCOpen()) {
2448
0
      transaction->SendSetTestSampleTime(driver->MostRecentRefresh());
2449
0
    } else if (WebRenderBridgeChild* wrbc = GetWebRenderBridge()) {
2450
0
      wrbc->SendSetTestSampleTime(driver->MostRecentRefresh());
2451
0
    }
2452
0
  }
2453
0
2454
0
  return NS_OK;
2455
0
}
2456
2457
NS_IMETHODIMP
2458
nsDOMWindowUtils::GetLastTransactionId(uint64_t *aLastTransactionId)
2459
0
{
2460
0
  nsPresContext* presContext = GetPresContext();
2461
0
  if (!presContext) {
2462
0
    return NS_ERROR_UNEXPECTED;
2463
0
  }
2464
0
2465
0
  nsRefreshDriver* driver = presContext->GetRootPresContext()->RefreshDriver();
2466
0
  *aLastTransactionId = uint64_t(driver->LastTransactionId());
2467
0
  return NS_OK;
2468
0
}
2469
2470
NS_IMETHODIMP
2471
nsDOMWindowUtils::RestoreNormalRefresh()
2472
0
{
2473
0
  // Kick the compositor out of test mode before the refresh driver, so that
2474
0
  // the refresh driver doesn't send an update that gets ignored by the
2475
0
  // compositor.
2476
0
  RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
2477
0
  if (transaction && transaction->IPCOpen()) {
2478
0
    transaction->SendLeaveTestMode();
2479
0
  } else if (WebRenderBridgeChild* wrbc = GetWebRenderBridge()) {
2480
0
    wrbc->SendLeaveTestMode();
2481
0
  }
2482
0
2483
0
  if (nsPresContext* pc = GetPresContext()) {
2484
0
    nsRefreshDriver* driver = pc->RefreshDriver();
2485
0
    driver->RestoreNormalRefresh();
2486
0
  }
2487
0
2488
0
  return NS_OK;
2489
0
}
2490
2491
NS_IMETHODIMP
2492
nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult)
2493
0
{
2494
0
  nsPresContext* pc = GetPresContext();
2495
0
  *aResult =
2496
0
    pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
2497
0
2498
0
  return NS_OK;
2499
0
}
2500
2501
NS_IMETHODIMP
2502
nsDOMWindowUtils::GetAsyncPanZoomEnabled(bool *aResult)
2503
0
{
2504
0
  nsIWidget* widget = GetWidget();
2505
0
  if (widget) {
2506
0
    *aResult = widget->AsyncPanZoomEnabled();
2507
0
  } else {
2508
0
    *aResult = gfxPlatform::AsyncPanZoomEnabled();
2509
0
  }
2510
0
  return NS_OK;
2511
0
}
2512
2513
NS_IMETHODIMP
2514
nsDOMWindowUtils::SetAsyncScrollOffset(Element* aElement,
2515
                                       float aX, float aY)
2516
0
{
2517
0
  if (!aElement) {
2518
0
    return NS_ERROR_INVALID_ARG;
2519
0
  }
2520
0
  FrameMetrics::ViewID viewId;
2521
0
  if (!nsLayoutUtils::FindIDFor(aElement, &viewId)) {
2522
0
    return NS_ERROR_UNEXPECTED;
2523
0
  }
2524
0
  nsIWidget* widget = GetWidget();
2525
0
  if (!widget) {
2526
0
    return NS_ERROR_FAILURE;
2527
0
  }
2528
0
  LayerManager* manager = widget->GetLayerManager();
2529
0
  if (!manager) {
2530
0
    return NS_ERROR_FAILURE;
2531
0
  }
2532
0
  if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
2533
0
    WebRenderBridgeChild* wrbc = wrlm->WrBridge();
2534
0
    if (!wrbc) {
2535
0
      return NS_ERROR_UNEXPECTED;
2536
0
    }
2537
0
    wrbc->SendSetAsyncScrollOffset(viewId, aX, aY);
2538
0
    return NS_OK;
2539
0
  }
2540
0
  ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
2541
0
  if (!forwarder || !forwarder->HasShadowManager()) {
2542
0
    return NS_ERROR_UNEXPECTED;
2543
0
  }
2544
0
  forwarder->GetShadowManager()->SendSetAsyncScrollOffset(viewId, aX, aY);
2545
0
  return NS_OK;
2546
0
}
2547
2548
NS_IMETHODIMP
2549
nsDOMWindowUtils::SetAsyncZoom(Element* aRootElement, float aValue)
2550
0
{
2551
0
  if (!aRootElement) {
2552
0
    return NS_ERROR_INVALID_ARG;
2553
0
  }
2554
0
  FrameMetrics::ViewID viewId;
2555
0
  if (!nsLayoutUtils::FindIDFor(aRootElement, &viewId)) {
2556
0
    return NS_ERROR_UNEXPECTED;
2557
0
  }
2558
0
  nsIWidget* widget = GetWidget();
2559
0
  if (!widget) {
2560
0
    return NS_ERROR_FAILURE;
2561
0
  }
2562
0
  LayerManager* manager = widget->GetLayerManager();
2563
0
  if (!manager) {
2564
0
    return NS_ERROR_FAILURE;
2565
0
  }
2566
0
  if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
2567
0
    WebRenderBridgeChild* wrbc = wrlm->WrBridge();
2568
0
    if (!wrbc) {
2569
0
      return NS_ERROR_UNEXPECTED;
2570
0
    }
2571
0
    wrbc->SendSetAsyncZoom(viewId, aValue);
2572
0
    return NS_OK;
2573
0
  }
2574
0
  ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
2575
0
  if (!forwarder || !forwarder->HasShadowManager()) {
2576
0
    return NS_ERROR_UNEXPECTED;
2577
0
  }
2578
0
  forwarder->GetShadowManager()->SendSetAsyncZoom(viewId, aValue);
2579
0
  return NS_OK;
2580
0
}
2581
2582
NS_IMETHODIMP
2583
nsDOMWindowUtils::FlushApzRepaints(bool* aOutResult)
2584
0
{
2585
0
  nsIWidget* widget = GetWidget();
2586
0
  if (!widget) {
2587
0
    *aOutResult = false;
2588
0
    return NS_OK;
2589
0
  }
2590
0
  // If APZ is not enabled, this function is a no-op.
2591
0
  if (!widget->AsyncPanZoomEnabled()) {
2592
0
    *aOutResult = false;
2593
0
    return NS_OK;
2594
0
  }
2595
0
  LayerManager* manager = widget->GetLayerManager();
2596
0
  if (!manager) {
2597
0
    *aOutResult = false;
2598
0
    return NS_OK;
2599
0
  }
2600
0
  if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) {
2601
0
    WebRenderBridgeChild* wrbc = wrlm->WrBridge();
2602
0
    if (!wrbc) {
2603
0
      return NS_ERROR_UNEXPECTED;
2604
0
    }
2605
0
    wrbc->SendFlushApzRepaints();
2606
0
    *aOutResult = true;
2607
0
    return NS_OK;
2608
0
  }
2609
0
  ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
2610
0
  if (!forwarder || !forwarder->HasShadowManager()) {
2611
0
    *aOutResult = false;
2612
0
    return NS_OK;
2613
0
  }
2614
0
  forwarder->GetShadowManager()->SendFlushApzRepaints();
2615
0
  *aOutResult = true;
2616
0
  return NS_OK;
2617
0
}
2618
2619
NS_IMETHODIMP
2620
nsDOMWindowUtils::ZoomToFocusedInput()
2621
0
{
2622
0
  nsIWidget* widget = GetWidget();
2623
0
  if (!widget) {
2624
0
    return NS_OK;
2625
0
  }
2626
0
  // If APZ is not enabled, this function is a no-op.
2627
0
  if (!widget->AsyncPanZoomEnabled()) {
2628
0
    return NS_OK;
2629
0
  }
2630
0
2631
0
  nsFocusManager* fm = nsFocusManager::GetFocusManager();
2632
0
  if (!fm) {
2633
0
    return NS_OK;
2634
0
  }
2635
0
2636
0
  nsIContent* content = fm->GetFocusedElement();
2637
0
  if (!content) {
2638
0
    return NS_OK;
2639
0
  }
2640
0
2641
0
  nsIPresShell* shell = APZCCallbackHelper::GetRootContentDocumentPresShellForContent(content);
2642
0
  if (!shell) {
2643
0
    return NS_OK;
2644
0
  }
2645
0
2646
0
  nsIScrollableFrame* rootScrollFrame = shell->GetRootScrollFrameAsScrollable();
2647
0
  if (!rootScrollFrame) {
2648
0
    return NS_OK;
2649
0
  }
2650
0
2651
0
  nsIFrame* currentFrame = content->GetPrimaryFrame();
2652
0
  nsIFrame* rootFrame = shell->GetRootFrame();
2653
0
  nsIFrame* scrolledFrame = rootScrollFrame->GetScrolledFrame();
2654
0
  bool isFixedPos = true;
2655
0
2656
0
  while (currentFrame) {
2657
0
    if (currentFrame == rootFrame) {
2658
0
      break;
2659
0
    }
2660
0
    if (currentFrame == scrolledFrame) {
2661
0
      // we are in the rootScrollFrame so this element is not fixed
2662
0
      isFixedPos = false;
2663
0
      break;
2664
0
    }
2665
0
    currentFrame = nsLayoutUtils::GetCrossDocParentFrame(currentFrame);
2666
0
  }
2667
0
2668
0
  if (isFixedPos) {
2669
0
    // We didn't find the scrolledFrame in our parent frames so this content must be fixed position.
2670
0
    // Zooming into fixed position content doesn't make sense so just return with out panning and zooming.
2671
0
    return NS_OK;
2672
0
  }
2673
0
2674
0
  nsIDocument* document = shell->GetDocument();
2675
0
  if (!document) {
2676
0
    return NS_OK;
2677
0
  }
2678
0
2679
0
  uint32_t presShellId;
2680
0
  FrameMetrics::ViewID viewId;
2681
0
  if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(document->GetDocumentElement(), &presShellId, &viewId)) {
2682
0
    uint32_t flags = layers::DISABLE_ZOOM_OUT;
2683
0
    if (!Preferences::GetBool("formhelper.autozoom")) {
2684
0
      flags |= layers::PAN_INTO_VIEW_ONLY;
2685
0
    } else {
2686
0
      flags |= layers::ONLY_ZOOM_TO_DEFAULT_SCALE;
2687
0
    }
2688
0
2689
0
    CSSRect bounds = nsLayoutUtils::GetBoundingContentRect(content, rootScrollFrame);
2690
0
    if (bounds.IsEmpty()) {
2691
0
      // Do not zoom on empty bounds. Bail out.
2692
0
      return NS_OK;
2693
0
    }
2694
0
    bounds.Inflate(15.0f, 0.0f);
2695
0
    widget->ZoomToRect(presShellId, viewId, bounds, flags);
2696
0
  }
2697
0
2698
0
  return NS_OK;
2699
0
}
2700
2701
NS_IMETHODIMP
2702
nsDOMWindowUtils::ComputeAnimationDistance(Element* aElement,
2703
                                           const nsAString& aProperty,
2704
                                           const nsAString& aValue1,
2705
                                           const nsAString& aValue2,
2706
                                           double* aResult)
2707
0
{
2708
0
  NS_ENSURE_ARG_POINTER(aElement);
2709
0
2710
0
  nsCSSPropertyID property = nsCSSProps::LookupProperty(aProperty);
2711
0
  if (property == eCSSProperty_UNKNOWN || nsCSSProps::IsShorthand(property)) {
2712
0
    return NS_ERROR_ILLEGAL_VALUE;
2713
0
  }
2714
0
2715
0
  AnimationValue v1 = AnimationValue::FromString(property, aValue1, aElement);
2716
0
  AnimationValue v2 = AnimationValue::FromString(property, aValue2, aElement);
2717
0
  if (v1.IsNull() || v2.IsNull()) {
2718
0
    return NS_ERROR_ILLEGAL_VALUE;
2719
0
  }
2720
0
2721
0
  RefPtr<ComputedStyle> computedStyle =
2722
0
    nsComputedDOMStyle::GetComputedStyle(aElement, nullptr);
2723
0
  *aResult = v1.ComputeDistance(property, v2, computedStyle);
2724
0
  return NS_OK;
2725
0
}
2726
2727
NS_IMETHODIMP
2728
nsDOMWindowUtils::GetUnanimatedComputedStyle(Element* aElement,
2729
                                             const nsAString& aPseudoElement,
2730
                                             const nsAString& aProperty,
2731
                                             int32_t aFlushType,
2732
                                             nsAString& aResult)
2733
0
{
2734
0
  if (!aElement) {
2735
0
    return NS_ERROR_INVALID_ARG;
2736
0
  }
2737
0
2738
0
  nsCSSPropertyID propertyID = nsCSSProps::LookupProperty(aProperty);
2739
0
  if (propertyID == eCSSProperty_UNKNOWN ||
2740
0
      nsCSSProps::IsShorthand(propertyID)) {
2741
0
    return NS_ERROR_INVALID_ARG;
2742
0
  }
2743
0
2744
0
  switch (aFlushType) {
2745
0
    case FLUSH_NONE:
2746
0
      break;
2747
0
    case FLUSH_STYLE: {
2748
0
      if (nsIDocument* doc = aElement->GetComposedDoc()) {
2749
0
        doc->FlushPendingNotifications(FlushType::Style);
2750
0
      }
2751
0
      break;
2752
0
    }
2753
0
    default:
2754
0
      return NS_ERROR_INVALID_ARG;
2755
0
  }
2756
0
2757
0
  nsIPresShell* shell = GetPresShell();
2758
0
  if (!shell) {
2759
0
    return NS_ERROR_FAILURE;
2760
0
  }
2761
0
2762
0
  RefPtr<nsAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement);
2763
0
  RefPtr<ComputedStyle> computedStyle =
2764
0
    nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(aElement, pseudo);
2765
0
  if (!computedStyle) {
2766
0
    return NS_ERROR_FAILURE;
2767
0
  }
2768
0
2769
0
  RefPtr<RawServoAnimationValue> value =
2770
0
    Servo_ComputedValues_ExtractAnimationValue(computedStyle,
2771
0
                                               propertyID).Consume();
2772
0
  if (!value) {
2773
0
    return NS_ERROR_FAILURE;
2774
0
  }
2775
0
  Servo_AnimationValue_Serialize(value, propertyID, &aResult);
2776
0
  return NS_OK;
2777
0
}
2778
2779
nsresult
2780
nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
2781
                                 uint32_t aFlags,
2782
                                 nscolor aBackgroundColor,
2783
                                 gfxContext* aThebesContext)
2784
0
{
2785
0
    nsCOMPtr<nsIDocument> doc = GetDocument();
2786
0
    NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
2787
0
2788
0
    // Get Primary Shell
2789
0
    nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
2790
0
    NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
2791
0
2792
0
    // Render Document
2793
0
    return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
2794
0
}
2795
2796
NS_IMETHODIMP
2797
nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
2798
0
{
2799
0
  nsCOMPtr<nsIWidget> widget = GetWidget();
2800
0
  if (!widget)
2801
0
    return NS_ERROR_FAILURE;
2802
0
2803
0
  *aDPI = widget->GetDPI();
2804
0
2805
0
  return NS_OK;
2806
0
}
2807
2808
NS_IMETHODIMP
2809
nsDOMWindowUtils::GetContainerElement(Element** aResult)
2810
0
{
2811
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
2812
0
  NS_ENSURE_STATE(window);
2813
0
2814
0
  RefPtr<Element> element = window->GetFrameElementInternal();
2815
0
  element.forget(aResult);
2816
0
  return NS_OK;
2817
0
}
2818
2819
#ifdef DEBUG
2820
static bool
2821
CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
2822
{
2823
  gfx::Matrix transform;
2824
  if (!aLayer->GetTransform().Is2D(&transform) ||
2825
      transform.HasNonIntegerTranslation())
2826
    return false;
2827
  transform.NudgeToIntegers();
2828
  IntPoint offset = aOffset + IntPoint::Truncate(transform._31, transform._32);
2829
2830
  Layer* child = aLayer->GetFirstChild();
2831
  if (child) {
2832
    while (child) {
2833
      if (!CheckLeafLayers(child, offset, aCoveredRegion))
2834
        return false;
2835
      child = child->GetNextSibling();
2836
    }
2837
  } else {
2838
    nsIntRegion rgn = aLayer->GetVisibleRegion().ToUnknownRegion();
2839
    rgn.MoveBy(offset);
2840
    nsIntRegion tmp;
2841
    tmp.And(rgn, *aCoveredRegion);
2842
    if (!tmp.IsEmpty())
2843
      return false;
2844
    aCoveredRegion->Or(*aCoveredRegion, rgn);
2845
  }
2846
2847
  return true;
2848
}
2849
#endif
2850
2851
NS_IMETHODIMP
2852
nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult)
2853
0
{
2854
0
  *aResult = true;
2855
#ifdef DEBUG
2856
  nsIWidget* widget = GetWidget();
2857
  if (!widget)
2858
    return NS_ERROR_FAILURE;
2859
  LayerManager* manager = widget->GetLayerManager();
2860
  if (!manager)
2861
    return NS_ERROR_FAILURE;
2862
  nsPresContext* presContext = GetPresContext();
2863
  if (!presContext)
2864
    return NS_ERROR_FAILURE;
2865
  Layer* root = manager->GetRoot();
2866
  if (!root)
2867
    return NS_ERROR_FAILURE;
2868
2869
  nsIntPoint offset(0, 0);
2870
  nsIntRegion coveredRegion;
2871
  if (!CheckLeafLayers(root, offset, &coveredRegion)) {
2872
    *aResult = false;
2873
  }
2874
  if (!coveredRegion.IsEqual(root->GetVisibleRegion().ToUnknownRegion())) {
2875
    *aResult = false;
2876
  }
2877
#endif
2878
  return NS_OK;
2879
0
}
2880
2881
NS_IMETHODIMP
2882
nsDOMWindowUtils::CheckAndClearPaintedState(Element* aElement, bool* aResult)
2883
0
{
2884
0
  if (!aElement) {
2885
0
    return NS_ERROR_INVALID_ARG;
2886
0
  }
2887
0
2888
0
  nsIFrame* frame = aElement->GetPrimaryFrame();
2889
0
2890
0
  if (!frame) {
2891
0
    *aResult = false;
2892
0
    return NS_OK;
2893
0
  }
2894
0
2895
0
  // Get the outermost frame for the content node, so that we can test
2896
0
  // canvasframe invalidations by observing the documentElement.
2897
0
  for (;;) {
2898
0
    nsIFrame* parentFrame = frame->GetParent();
2899
0
    if (parentFrame && parentFrame->GetContent() == aElement) {
2900
0
      frame = parentFrame;
2901
0
    } else {
2902
0
      break;
2903
0
    }
2904
0
  }
2905
0
2906
0
  while (frame) {
2907
0
    if (!frame->CheckAndClearPaintedState()) {
2908
0
      *aResult = false;
2909
0
      return NS_OK;
2910
0
    }
2911
0
    frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame);
2912
0
  }
2913
0
  *aResult = true;
2914
0
  return NS_OK;
2915
0
}
2916
2917
NS_IMETHODIMP
2918
nsDOMWindowUtils::CheckAndClearDisplayListState(Element* aElement, bool* aResult)
2919
0
{
2920
0
  if (!aElement) {
2921
0
    return NS_ERROR_INVALID_ARG;
2922
0
  }
2923
0
2924
0
  nsIFrame* frame = aElement->GetPrimaryFrame();
2925
0
2926
0
  if (!frame) {
2927
0
    *aResult = false;
2928
0
    return NS_OK;
2929
0
  }
2930
0
2931
0
  // Get the outermost frame for the content node, so that we can test
2932
0
  // canvasframe invalidations by observing the documentElement.
2933
0
  for (;;) {
2934
0
    nsIFrame* parentFrame = frame->GetParent();
2935
0
    if (parentFrame && parentFrame->GetContent() == aElement) {
2936
0
      frame = parentFrame;
2937
0
    } else {
2938
0
      break;
2939
0
    }
2940
0
  }
2941
0
2942
0
  while (frame) {
2943
0
    if (!frame->CheckAndClearDisplayListState()) {
2944
0
      *aResult = false;
2945
0
      return NS_OK;
2946
0
    }
2947
0
    frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame);
2948
0
  }
2949
0
  *aResult = true;
2950
0
  return NS_OK;
2951
0
2952
0
}
2953
2954
NS_IMETHODIMP
2955
nsDOMWindowUtils::IsPartOfOpaqueLayer(Element* aElement, bool* aResult)
2956
0
{
2957
0
  if (!aElement) {
2958
0
    return NS_ERROR_INVALID_ARG;
2959
0
  }
2960
0
2961
0
  nsIFrame* frame = aElement->GetPrimaryFrame();
2962
0
  if (!frame) {
2963
0
    return NS_ERROR_FAILURE;
2964
0
  }
2965
0
2966
0
  ColorLayer* colorLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<ColorLayer>(frame);
2967
0
  if (colorLayer) {
2968
0
    auto color = colorLayer->GetColor();
2969
0
    *aResult = color.a == 1.0f;
2970
0
    return NS_OK;
2971
0
  }
2972
0
2973
0
  PaintedLayer* paintedLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
2974
0
  if (paintedLayer) {
2975
0
    *aResult = paintedLayer->IsOpaque();
2976
0
    return NS_OK;
2977
0
  }
2978
0
2979
0
  return NS_ERROR_FAILURE;
2980
0
}
2981
2982
NS_IMETHODIMP
2983
nsDOMWindowUtils::NumberOfAssignedPaintedLayers(Element** aElements,
2984
                                                uint32_t aCount,
2985
                                                uint32_t* aResult)
2986
0
{
2987
0
  if (!aElements) {
2988
0
    return NS_ERROR_INVALID_ARG;
2989
0
  }
2990
0
2991
0
  nsTHashtable<nsPtrHashKey<PaintedLayer>> layers;
2992
0
  for (uint32_t i = 0; i < aCount; i++) {
2993
0
    nsIFrame* frame = aElements[i]->GetPrimaryFrame();
2994
0
    if (!frame) {
2995
0
      return NS_ERROR_FAILURE;
2996
0
    }
2997
0
2998
0
    PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame);
2999
0
    if (!layer) {
3000
0
      return NS_ERROR_FAILURE;
3001
0
    }
3002
0
3003
0
    layers.PutEntry(layer);
3004
0
  }
3005
0
3006
0
  *aResult = layers.Count();
3007
0
  return NS_OK;
3008
0
}
3009
3010
NS_IMETHODIMP
3011
nsDOMWindowUtils::EnableDialogs()
3012
0
{
3013
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3014
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3015
0
3016
0
  nsGlobalWindowOuter::Cast(window)->EnableDialogs();
3017
0
  return NS_OK;
3018
0
}
3019
3020
NS_IMETHODIMP
3021
nsDOMWindowUtils::DisableDialogs()
3022
0
{
3023
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3024
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3025
0
3026
0
  nsGlobalWindowOuter::Cast(window)->DisableDialogs();
3027
0
  return NS_OK;
3028
0
}
3029
3030
NS_IMETHODIMP
3031
nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
3032
0
{
3033
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3034
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3035
0
3036
0
  *aResult = nsGlobalWindowOuter::Cast(window)->AreDialogsEnabled();
3037
0
  return NS_OK;
3038
0
}
3039
3040
NS_IMETHODIMP
3041
nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
3042
                            int64_t* _retval)
3043
0
{
3044
0
  if (aFile.isPrimitive()) {
3045
0
    *_retval = -1;
3046
0
    return NS_OK;
3047
0
  }
3048
0
3049
0
  JS::Rooted<JSObject*> obj(aCx, aFile.toObjectOrNull());
3050
0
3051
0
  IDBMutableFile* mutableFile = nullptr;
3052
0
  if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, &obj, mutableFile))) {
3053
0
    *_retval = mutableFile->GetFileId();
3054
0
    return NS_OK;
3055
0
  }
3056
0
3057
0
  Blob* blob = nullptr;
3058
0
  if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) {
3059
0
    *_retval = blob->GetFileId();
3060
0
    return NS_OK;
3061
0
  }
3062
0
3063
0
  *_retval = -1;
3064
0
  return NS_OK;
3065
0
}
3066
3067
NS_IMETHODIMP
3068
nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx,
3069
                              nsAString& _retval)
3070
0
{
3071
0
  if (aFile.isPrimitive()) {
3072
0
    _retval.Truncate();
3073
0
    return NS_OK;
3074
0
  }
3075
0
3076
0
  JS::Rooted<JSObject*> obj(aCx, aFile.toObjectOrNull());
3077
0
3078
0
  File* file = nullptr;
3079
0
  if (NS_SUCCEEDED(UNWRAP_OBJECT(File, &obj, file))) {
3080
0
    nsString filePath;
3081
0
    ErrorResult rv;
3082
0
    file->GetMozFullPathInternal(filePath, rv);
3083
0
    if (NS_WARN_IF(rv.Failed())) {
3084
0
      return rv.StealNSResult();
3085
0
    }
3086
0
3087
0
    _retval = filePath;
3088
0
    return NS_OK;
3089
0
  }
3090
0
3091
0
  _retval.Truncate();
3092
0
  return NS_OK;
3093
0
}
3094
3095
NS_IMETHODIMP
3096
nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
3097
                                    JS::Handle<JS::Value> aOptions,
3098
                                    int32_t* aRefCnt, int32_t* aDBRefCnt,
3099
                                    int32_t* aSliceRefCnt, JSContext* aCx,
3100
                                    bool* aResult)
3101
0
{
3102
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3103
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3104
0
3105
0
  nsCString origin;
3106
0
  nsresult rv =
3107
0
    quota::QuotaManager::GetInfoFromWindow(window, nullptr, nullptr, &origin);
3108
0
  NS_ENSURE_SUCCESS(rv, rv);
3109
0
3110
0
  IDBOpenDBOptions options;
3111
0
  JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
3112
0
  if (!options.Init(aCx, optionsVal)) {
3113
0
    return NS_ERROR_TYPE_ERR;
3114
0
  }
3115
0
3116
0
  quota::PersistenceType persistenceType =
3117
0
    quota::PersistenceTypeFromStorage(options.mStorage);
3118
0
3119
0
  RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
3120
0
3121
0
  if (mgr) {
3122
0
    rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
3123
0
                                        aId, aRefCnt, aDBRefCnt, aSliceRefCnt,
3124
0
                                        aResult);
3125
0
    NS_ENSURE_SUCCESS(rv, rv);
3126
0
  }
3127
0
  else {
3128
0
    *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;
3129
0
    *aResult = false;
3130
0
  }
3131
0
3132
0
  return NS_OK;
3133
0
}
3134
3135
NS_IMETHODIMP
3136
nsDOMWindowUtils::FlushPendingFileDeletions()
3137
0
{
3138
0
  RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get();
3139
0
  if (mgr) {
3140
0
    nsresult rv = mgr->FlushPendingFileDeletions();
3141
0
    if (NS_WARN_IF(NS_FAILED(rv))) {
3142
0
      return rv;
3143
0
    }
3144
0
  }
3145
0
3146
0
  return NS_OK;
3147
0
}
3148
3149
NS_IMETHODIMP
3150
nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
3151
0
{
3152
0
  *aResult = JS::IsIncrementalGCEnabled(cx);
3153
0
  return NS_OK;
3154
0
}
3155
3156
NS_IMETHODIMP
3157
nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
3158
0
{
3159
0
  js::StartPCCountProfiling(cx);
3160
0
  return NS_OK;
3161
0
}
3162
3163
NS_IMETHODIMP
3164
nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
3165
0
{
3166
0
  js::StopPCCountProfiling(cx);
3167
0
  return NS_OK;
3168
0
}
3169
3170
NS_IMETHODIMP
3171
nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
3172
0
{
3173
0
  js::PurgePCCounts(cx);
3174
0
  return NS_OK;
3175
0
}
3176
3177
NS_IMETHODIMP
3178
nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
3179
0
{
3180
0
  *result = js::GetPCCountScriptCount(cx);
3181
0
  return NS_OK;
3182
0
}
3183
3184
NS_IMETHODIMP
3185
nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result)
3186
0
{
3187
0
  JSString *text = js::GetPCCountScriptSummary(cx, script);
3188
0
  if (!text)
3189
0
    return NS_ERROR_FAILURE;
3190
0
3191
0
  if (!AssignJSString(cx, result, text))
3192
0
    return NS_ERROR_FAILURE;
3193
0
3194
0
  return NS_OK;
3195
0
}
3196
3197
NS_IMETHODIMP
3198
nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result)
3199
0
{
3200
0
  JSString *text = js::GetPCCountScriptContents(cx, script);
3201
0
  if (!text)
3202
0
    return NS_ERROR_FAILURE;
3203
0
3204
0
  if (!AssignJSString(cx, result, text))
3205
0
    return NS_ERROR_FAILURE;
3206
0
3207
0
  return NS_OK;
3208
0
}
3209
3210
NS_IMETHODIMP
3211
nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
3212
0
{
3213
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3214
0
  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3215
0
  nsIDocShell *docShell = window->GetDocShell();
3216
0
  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
3217
0
3218
0
  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
3219
0
  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
3220
0
3221
0
  *aPaintingSuppressed = presShell->IsPaintingSuppressed();
3222
0
  return NS_OK;
3223
0
}
3224
3225
NS_IMETHODIMP
3226
nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
3227
0
{
3228
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3229
0
  NS_ENSURE_STATE(doc);
3230
0
3231
0
  nsTArray<nsIObjectLoadingContent*> plugins;
3232
0
  doc->GetPlugins(plugins);
3233
0
3234
0
  JS::Rooted<JSObject*> jsPlugins(cx);
3235
0
  nsresult rv = nsTArrayToJSArray(cx, plugins, &jsPlugins);
3236
0
  NS_ENSURE_SUCCESS(rv, rv);
3237
0
3238
0
  aPlugins.setObject(*jsPlugins);
3239
0
  return NS_OK;
3240
0
}
3241
3242
NS_IMETHODIMP
3243
nsDOMWindowUtils::SetVisualViewportSize(float aWidth, float aHeight)
3244
0
{
3245
0
  if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
3246
0
    return NS_ERROR_ILLEGAL_VALUE;
3247
0
  }
3248
0
3249
0
  nsIPresShell* presShell = GetPresShell();
3250
0
  if (!presShell) {
3251
0
    return NS_ERROR_FAILURE;
3252
0
  }
3253
0
3254
0
  nsLayoutUtils::SetVisualViewportSize(presShell, CSSSize(aWidth, aHeight));
3255
0
3256
0
  return NS_OK;
3257
0
}
3258
3259
nsresult
3260
nsDOMWindowUtils::RemoteFrameFullscreenChanged(Element* aFrameElement)
3261
0
{
3262
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3263
0
  NS_ENSURE_STATE(doc);
3264
0
3265
0
  doc->RemoteFrameFullscreenChanged(aFrameElement);
3266
0
  return NS_OK;
3267
0
}
3268
3269
nsresult
3270
nsDOMWindowUtils::RemoteFrameFullscreenReverted()
3271
0
{
3272
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3273
0
  NS_ENSURE_STATE(doc);
3274
0
3275
0
  doc->RemoteFrameFullscreenReverted();
3276
0
  return NS_OK;
3277
0
}
3278
3279
static void
3280
PrepareForFullscreenChange(nsIPresShell* aPresShell, const nsSize& aSize,
3281
                           nsSize* aOldSize = nullptr)
3282
0
{
3283
0
  if (!aPresShell) {
3284
0
    return;
3285
0
  }
3286
0
  if (nsRefreshDriver* rd = aPresShell->GetRefreshDriver()) {
3287
0
    rd->SetIsResizeSuppressed();
3288
0
    // Since we are suppressing the resize reflow which would originally
3289
0
    // be triggered by view manager, we need to ensure that the refresh
3290
0
    // driver actually schedules a flush, otherwise it may get stuck.
3291
0
    rd->ScheduleViewManagerFlush();
3292
0
  }
3293
0
  if (!aSize.IsEmpty()) {
3294
0
    if (nsViewManager* viewManager = aPresShell->GetViewManager()) {
3295
0
      if (aOldSize) {
3296
0
        viewManager->GetWindowDimensions(&aOldSize->width, &aOldSize->height);
3297
0
      }
3298
0
      viewManager->SetWindowDimensions(aSize.width, aSize.height);
3299
0
    }
3300
0
  }
3301
0
}
3302
3303
NS_IMETHODIMP
3304
nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal)
3305
0
{
3306
0
  PROFILER_ADD_MARKER("Enter fullscreen");
3307
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3308
0
  NS_ENSURE_STATE(doc);
3309
0
3310
0
  // Notify the pres shell that we are starting fullscreen change, and
3311
0
  // set the window dimensions in advance. Since the resize message
3312
0
  // comes after the fullscreen change call, doing so could avoid an
3313
0
  // extra resize reflow after this point.
3314
0
  nsRect screenRect;
3315
0
  if (nsPresContext* presContext = GetPresContext()) {
3316
0
    presContext->DeviceContext()->GetRect(screenRect);
3317
0
  }
3318
0
  nsSize oldSize;
3319
0
  PrepareForFullscreenChange(GetPresShell(), screenRect.Size(), &oldSize);
3320
0
  OldWindowSize::Set(mWindow, oldSize);
3321
0
3322
0
  *aRetVal = nsIDocument::HandlePendingFullscreenRequests(doc);
3323
0
  return NS_OK;
3324
0
}
3325
3326
nsresult
3327
nsDOMWindowUtils::ExitFullscreen()
3328
0
{
3329
0
  PROFILER_ADD_MARKER("Exit fullscreen");
3330
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3331
0
  NS_ENSURE_STATE(doc);
3332
0
3333
0
  // Although we would not use the old size if we have already exited
3334
0
  // fullscreen, we still want to cleanup in case we haven't.
3335
0
  nsSize oldSize = OldWindowSize::GetAndRemove(mWindow);
3336
0
  if (!doc->GetFullscreenElement()) {
3337
0
    return NS_OK;
3338
0
  }
3339
0
3340
0
  // Notify the pres shell that we are starting fullscreen change, and
3341
0
  // set the window dimensions in advance. Since the resize message
3342
0
  // comes after the fullscreen change call, doing so could avoid an
3343
0
  // extra resize reflow after this point.
3344
0
  PrepareForFullscreenChange(GetPresShell(), oldSize);
3345
0
  nsIDocument::ExitFullscreenInDocTree(doc);
3346
0
  return NS_OK;
3347
0
}
3348
3349
NS_IMETHODIMP
3350
nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
3351
                                bool *_retval)
3352
0
{
3353
0
  *_retval = false;
3354
0
3355
0
  nsSelectionAmount amount;
3356
0
  switch (aSelectBehavior) {
3357
0
    case nsIDOMWindowUtils::SELECT_CHARACTER:
3358
0
      amount = eSelectCharacter;
3359
0
    break;
3360
0
    case nsIDOMWindowUtils::SELECT_CLUSTER:
3361
0
      amount = eSelectCluster;
3362
0
    break;
3363
0
    case nsIDOMWindowUtils::SELECT_WORD:
3364
0
      amount = eSelectWord;
3365
0
    break;
3366
0
    case nsIDOMWindowUtils::SELECT_LINE:
3367
0
      amount = eSelectLine;
3368
0
    break;
3369
0
    case nsIDOMWindowUtils::SELECT_BEGINLINE:
3370
0
      amount = eSelectBeginLine;
3371
0
    break;
3372
0
    case nsIDOMWindowUtils::SELECT_ENDLINE:
3373
0
      amount = eSelectEndLine;
3374
0
    break;
3375
0
    case nsIDOMWindowUtils::SELECT_PARAGRAPH:
3376
0
      amount = eSelectParagraph;
3377
0
    break;
3378
0
    case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
3379
0
      amount = eSelectWordNoSpace;
3380
0
    break;
3381
0
    default:
3382
0
      return NS_ERROR_INVALID_ARG;
3383
0
  }
3384
0
3385
0
  nsIPresShell* presShell = GetPresShell();
3386
0
  if (!presShell) {
3387
0
    return NS_ERROR_UNEXPECTED;
3388
0
  }
3389
0
3390
0
  // The root frame for this content window
3391
0
  nsIFrame* rootFrame = presShell->GetRootFrame();
3392
0
  if (!rootFrame) {
3393
0
    return NS_ERROR_UNEXPECTED;
3394
0
  }
3395
0
3396
0
  // Get the target frame at the client coordinates passed to us
3397
0
  nsPoint offset;
3398
0
  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
3399
0
  LayoutDeviceIntPoint pt =
3400
0
    nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext());
3401
0
  nsPoint ptInRoot =
3402
0
    nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
3403
0
  nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
3404
0
  // This can happen if the page hasn't loaded yet or if the point
3405
0
  // is outside the frame.
3406
0
  if (!targetFrame) {
3407
0
    return NS_ERROR_INVALID_ARG;
3408
0
  }
3409
0
3410
0
  // Convert point to coordinates relative to the target frame, which is
3411
0
  // what targetFrame's SelectByTypeAtPoint expects.
3412
0
  nsPoint relPoint =
3413
0
    nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
3414
0
3415
0
  nsresult rv =
3416
0
    static_cast<nsFrame*>(targetFrame)->
3417
0
      SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
3418
0
                          nsFrame::SELECT_ACCUMULATE);
3419
0
  *_retval = !NS_FAILED(rv);
3420
0
  return NS_OK;
3421
0
}
3422
3423
static nsIDocument::additionalSheetType
3424
convertSheetType(uint32_t aSheetType)
3425
0
{
3426
0
  switch(aSheetType) {
3427
0
    case nsDOMWindowUtils::AGENT_SHEET:
3428
0
      return nsIDocument::eAgentSheet;
3429
0
    case nsDOMWindowUtils::USER_SHEET:
3430
0
      return nsIDocument::eUserSheet;
3431
0
    case nsDOMWindowUtils::AUTHOR_SHEET:
3432
0
      return nsIDocument::eAuthorSheet;
3433
0
    default:
3434
0
      NS_ASSERTION(false, "wrong type");
3435
0
      // we must return something although this should never happen
3436
0
      return nsIDocument::AdditionalSheetTypeCount;
3437
0
  }
3438
0
}
3439
3440
NS_IMETHODIMP
3441
nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
3442
0
{
3443
0
  NS_ENSURE_ARG_POINTER(aSheetURI);
3444
0
  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
3445
0
                aSheetType == USER_SHEET ||
3446
0
                aSheetType == AUTHOR_SHEET);
3447
0
3448
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3449
0
  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
3450
0
3451
0
  nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
3452
0
3453
0
  return doc->LoadAdditionalStyleSheet(type, aSheetURI);
3454
0
}
3455
3456
NS_IMETHODIMP
3457
nsDOMWindowUtils::LoadSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType)
3458
0
{
3459
0
  nsCOMPtr<nsIURI> uri;
3460
0
  nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI);
3461
0
  NS_ENSURE_SUCCESS(rv, rv);
3462
0
3463
0
  return LoadSheet(uri, aSheetType);
3464
0
}
3465
3466
NS_IMETHODIMP
3467
nsDOMWindowUtils::AddSheet(nsIPreloadedStyleSheet* aSheet, uint32_t aSheetType)
3468
0
{
3469
0
  NS_ENSURE_ARG_POINTER(aSheet);
3470
0
  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
3471
0
                aSheetType == USER_SHEET ||
3472
0
                aSheetType == AUTHOR_SHEET);
3473
0
3474
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3475
0
  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
3476
0
3477
0
  StyleSheet* sheet = nullptr;
3478
0
  auto preloadedSheet = static_cast<PreloadedStyleSheet*>(aSheet);
3479
0
  nsresult rv = preloadedSheet->GetSheet(&sheet);
3480
0
  NS_ENSURE_SUCCESS(rv, rv);
3481
0
  NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
3482
0
3483
0
  if (sheet->GetAssociatedDocumentOrShadowRoot()) {
3484
0
    return NS_ERROR_INVALID_ARG;
3485
0
  }
3486
0
3487
0
  nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
3488
0
  return doc->AddAdditionalStyleSheet(type, sheet);
3489
0
}
3490
3491
NS_IMETHODIMP
3492
nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
3493
0
{
3494
0
  NS_ENSURE_ARG_POINTER(aSheetURI);
3495
0
  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
3496
0
                aSheetType == USER_SHEET ||
3497
0
                aSheetType == AUTHOR_SHEET);
3498
0
3499
0
  nsCOMPtr<nsIDocument> doc = GetDocument();
3500
0
  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
3501
0
3502
0
  nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
3503
0
3504
0
  doc->RemoveAdditionalStyleSheet(type, aSheetURI);
3505
0
  return NS_OK;
3506
0
}
3507
3508
NS_IMETHODIMP
3509
nsDOMWindowUtils::RemoveSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType)
3510
0
{
3511
0
  nsCOMPtr<nsIURI> uri;
3512
0
  nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI);
3513
0
  NS_ENSURE_SUCCESS(rv, rv);
3514
0
3515
0
  return RemoveSheet(uri, aSheetType);
3516
0
}
3517
3518
NS_IMETHODIMP
3519
nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput)
3520
0
{
3521
0
  *aHandlingUserInput = EventStateManager::IsHandlingUserInput();
3522
0
3523
0
  return NS_OK;
3524
0
}
3525
3526
NS_IMETHODIMP
3527
nsDOMWindowUtils::GetMillisSinceLastUserInput(double* aMillisSinceLastUserInput)
3528
0
{
3529
0
  TimeStamp lastInput = EventStateManager::LatestUserInputStart();
3530
0
  if (lastInput.IsNull()) {
3531
0
    *aMillisSinceLastUserInput = -1.0f;
3532
0
    return NS_OK;
3533
0
  }
3534
0
3535
0
  *aMillisSinceLastUserInput = (TimeStamp::Now() - lastInput).ToMilliseconds();
3536
0
  return NS_OK;
3537
0
}
3538
3539
NS_IMETHODIMP
3540
nsDOMWindowUtils::AllowScriptsToClose()
3541
0
{
3542
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3543
0
  NS_ENSURE_STATE(window);
3544
0
  nsGlobalWindowOuter::Cast(window)->AllowScriptsToClose();
3545
0
  return NS_OK;
3546
0
}
3547
3548
NS_IMETHODIMP
3549
nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible)
3550
0
{
3551
0
  if (!XRE_IsParentProcess()) {
3552
0
    MOZ_CRASH("IsParentWindowMainWidgetVisible is only available in the parent process");
3553
0
  }
3554
0
3555
0
  // this should reflect the "is parent window visible" logic in
3556
0
  // nsWindowWatcher::OpenWindowInternal()
3557
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3558
0
  NS_ENSURE_STATE(window);
3559
0
3560
0
  nsCOMPtr<nsIWidget> parentWidget;
3561
0
  nsIDocShell *docShell = window->GetDocShell();
3562
0
  if (docShell) {
3563
0
    nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
3564
0
    docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
3565
0
    nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
3566
0
    if (parentWindow) {
3567
0
        parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
3568
0
    }
3569
0
  }
3570
0
  if (!parentWidget) {
3571
0
    return NS_ERROR_NOT_AVAILABLE;
3572
0
  }
3573
0
3574
0
  *aIsVisible = parentWidget->IsVisible();
3575
0
  return NS_OK;
3576
0
}
3577
3578
NS_IMETHODIMP
3579
nsDOMWindowUtils::IsNodeDisabledForEvents(nsINode* aNode, bool* aRetVal)
3580
0
{
3581
0
  *aRetVal = false;
3582
0
  nsINode* node = aNode;
3583
0
  while (node) {
3584
0
    if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
3585
0
      nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
3586
0
      if (fc && fc->IsDisabledForEvents(eVoidEvent)) {
3587
0
        *aRetVal = true;
3588
0
        break;
3589
0
      }
3590
0
    }
3591
0
    node = node->GetParentNode();
3592
0
  }
3593
0
3594
0
  return NS_OK;
3595
0
}
3596
3597
NS_IMETHODIMP
3598
nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing)
3599
0
{
3600
0
  nsPresContext* presContext = GetPresContext();
3601
0
  if (presContext) {
3602
0
    presContext->SetPaintFlashing(aPaintFlashing);
3603
0
    // Clear paint flashing colors
3604
0
    nsIPresShell* presShell = GetPresShell();
3605
0
    if (!aPaintFlashing && presShell) {
3606
0
      nsIFrame* rootFrame = presShell->GetRootFrame();
3607
0
      if (rootFrame) {
3608
0
        rootFrame->InvalidateFrameSubtree();
3609
0
      }
3610
0
    }
3611
0
  }
3612
0
  return NS_OK;
3613
0
}
3614
3615
NS_IMETHODIMP
3616
nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal)
3617
0
{
3618
0
  *aRetVal = false;
3619
0
  nsPresContext* presContext = GetPresContext();
3620
0
  if (presContext) {
3621
0
    *aRetVal = presContext->GetPaintFlashing();
3622
0
  }
3623
0
  return NS_OK;
3624
0
}
3625
3626
NS_IMETHODIMP
3627
nsDOMWindowUtils::DispatchEventToChromeOnly(EventTarget* aTarget,
3628
                                            Event* aEvent,
3629
                                            bool* aRetVal)
3630
0
{
3631
0
  *aRetVal = false;
3632
0
  NS_ENSURE_STATE(aTarget && aEvent);
3633
0
  aEvent->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
3634
0
  *aRetVal = aTarget->
3635
0
    DispatchEvent(*aEvent, CallerType::System, IgnoreErrors());
3636
0
  return NS_OK;
3637
0
}
3638
3639
static Result<nsIFrame*, nsresult>
3640
GetTargetFrame(const Element* aElement, const nsAString& aPseudoElement)
3641
0
{
3642
0
  nsIFrame* frame = aElement->GetPrimaryFrame();
3643
0
  if (!aPseudoElement.IsEmpty()) {
3644
0
    if (aPseudoElement.EqualsLiteral("::before")) {
3645
0
      frame = nsLayoutUtils::GetBeforeFrame(aElement);
3646
0
    } else if (aPseudoElement.EqualsLiteral("::after")) {
3647
0
      frame = nsLayoutUtils::GetAfterFrame(aElement);
3648
0
    } else {
3649
0
      return Err(NS_ERROR_INVALID_ARG);
3650
0
    }
3651
0
  }
3652
0
  return frame;
3653
0
}
3654
3655
static OMTAValue
3656
GetOMTAValue(nsIFrame* aFrame,
3657
             DisplayItemType aDisplayItemKey,
3658
             WebRenderBridgeChild* aWebRenderBridgeChild)
3659
0
{
3660
0
  OMTAValue value = mozilla::null_t();
3661
0
3662
0
  Layer* layer =
3663
0
    FrameLayerBuilder::GetDedicatedLayer(aFrame, aDisplayItemKey);
3664
0
  if (layer) {
3665
0
    ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
3666
0
    if (forwarder && forwarder->HasShadowManager()) {
3667
0
      forwarder->GetShadowManager()->
3668
0
        SendGetAnimationValue(layer->GetCompositorAnimationsId(), &value);
3669
0
    }
3670
0
  } else if (aWebRenderBridgeChild) {
3671
0
    RefPtr<WebRenderAnimationData> animationData =
3672
0
      GetWebRenderUserData<WebRenderAnimationData>(aFrame,
3673
0
                                                   (uint32_t)aDisplayItemKey);
3674
0
    if (animationData) {
3675
0
      aWebRenderBridgeChild->SendGetAnimationValue(
3676
0
        animationData->GetAnimationInfo().GetCompositorAnimationsId(),
3677
0
        &value);
3678
0
    }
3679
0
  }
3680
0
  return value;
3681
0
}
3682
3683
NS_IMETHODIMP
3684
nsDOMWindowUtils::GetOMTAStyle(Element* aElement,
3685
                               const nsAString& aProperty,
3686
                               const nsAString& aPseudoElement,
3687
                               nsAString& aResult)
3688
0
{
3689
0
  if (!aElement) {
3690
0
    return NS_ERROR_INVALID_ARG;
3691
0
  }
3692
0
3693
0
  auto frameOrError = GetTargetFrame(aElement, aPseudoElement);
3694
0
  if (frameOrError.isErr()) {
3695
0
    return frameOrError.unwrapErr();
3696
0
  }
3697
0
  nsIFrame* frame = frameOrError.unwrap();
3698
0
3699
0
  RefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
3700
0
  if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
3701
0
    RefPtr<LayerManager> widgetLayerManager;
3702
0
    if (nsIWidget* widget = GetWidget()) {
3703
0
      widgetLayerManager = widget->GetLayerManager();
3704
0
    }
3705
0
3706
0
    if (aProperty.EqualsLiteral("opacity")) {
3707
0
      OMTAValue value = GetOMTAValue(frame,
3708
0
                                     DisplayItemType::TYPE_OPACITY,
3709
0
                                     GetWebRenderBridge());
3710
0
      if (value.type() == OMTAValue::Tfloat) {
3711
0
        cssValue = new nsROCSSPrimitiveValue;
3712
0
        cssValue->SetNumber(value.get_float());
3713
0
      }
3714
0
    } else if (aProperty.EqualsLiteral("transform")) {
3715
0
      OMTAValue value = GetOMTAValue(frame,
3716
0
                                     DisplayItemType::TYPE_TRANSFORM,
3717
0
                                     GetWebRenderBridge());
3718
0
      if (value.type() == OMTAValue::TMatrix4x4) {
3719
0
        cssValue = nsComputedDOMStyle::MatrixToCSSValue(value.get_Matrix4x4());
3720
0
      }
3721
0
    }
3722
0
  }
3723
0
3724
0
  if (cssValue) {
3725
0
    nsString text;
3726
0
    ErrorResult rv;
3727
0
    cssValue->GetCssText(text, rv);
3728
0
    aResult.Assign(text);
3729
0
    return rv.StealNSResult();
3730
0
  }
3731
0
  aResult.Truncate();
3732
0
  return NS_OK;
3733
0
}
3734
3735
NS_IMETHODIMP
3736
nsDOMWindowUtils::GetOMTCTransform(Element* aElement,
3737
                                   const nsAString& aPseudoElement,
3738
                                   nsAString& aResult)
3739
0
{
3740
0
  if (!aElement) {
3741
0
    return NS_ERROR_INVALID_ARG;
3742
0
  }
3743
0
3744
0
  if (GetWebRenderBridge()) {
3745
0
    return NS_ERROR_NOT_IMPLEMENTED;
3746
0
  }
3747
0
3748
0
  auto frameOrError = GetTargetFrame(aElement, aPseudoElement);
3749
0
  if (frameOrError.isErr()) {
3750
0
    return frameOrError.unwrapErr();
3751
0
  }
3752
0
3753
0
  nsIFrame* frame = frameOrError.unwrap();
3754
0
  aResult.Truncate();
3755
0
  if (!frame) {
3756
0
    return NS_OK;
3757
0
  }
3758
0
3759
0
  DisplayItemType itemType = DisplayItemType::TYPE_TRANSFORM;
3760
0
  if (nsLayoutUtils::HasEffectiveAnimation(frame, eCSSProperty_opacity) &&
3761
0
      !frame->IsTransformed()) {
3762
0
    itemType = DisplayItemType::TYPE_OPACITY;
3763
0
  }
3764
0
3765
0
  Layer* layer = FrameLayerBuilder::GetDedicatedLayer(frame, itemType);
3766
0
  if (!layer) {
3767
0
    return NS_OK;
3768
0
  }
3769
0
3770
0
  ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
3771
0
  if (!forwarder || !forwarder->HasShadowManager()) {
3772
0
    return NS_OK;
3773
0
  }
3774
0
3775
0
  MaybeTransform transform;
3776
0
  forwarder->GetShadowManager()->
3777
0
    SendGetTransform(layer->AsShadowableLayer()->GetShadow(), &transform);
3778
0
  if (transform.type() != MaybeTransform::TMatrix4x4) {
3779
0
    return NS_OK;
3780
0
  }
3781
0
3782
0
  Matrix4x4 matrix = transform.get_Matrix4x4();
3783
0
  RefPtr<nsROCSSPrimitiveValue> cssValue =
3784
0
    nsComputedDOMStyle::MatrixToCSSValue(matrix);
3785
0
  if (!cssValue) {
3786
0
    return NS_OK;
3787
0
  }
3788
0
3789
0
  nsAutoString text;
3790
0
  ErrorResult rv;
3791
0
  cssValue->GetCssText(text, rv);
3792
0
  aResult.Assign(text);
3793
0
  return rv.StealNSResult();
3794
0
}
3795
3796
NS_IMETHODIMP
3797
nsDOMWindowUtils::IsAnimationInPendingTracker(dom::Animation* aAnimation,
3798
                                              bool* aRetVal)
3799
0
{
3800
0
  MOZ_ASSERT(aRetVal);
3801
0
3802
0
  if (!aAnimation) {
3803
0
    return NS_ERROR_INVALID_ARG;
3804
0
  }
3805
0
3806
0
  nsIDocument* doc = GetDocument();
3807
0
  if (!doc) {
3808
0
    *aRetVal = false;
3809
0
    return NS_OK;
3810
0
  }
3811
0
3812
0
  PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker();
3813
0
  if (!tracker) {
3814
0
    *aRetVal = false;
3815
0
    return NS_OK;
3816
0
  }
3817
0
3818
0
  *aRetVal = tracker->IsWaitingToPlay(*aAnimation) ||
3819
0
             tracker->IsWaitingToPause(*aAnimation);
3820
0
  return NS_OK;
3821
0
}
3822
3823
namespace {
3824
3825
class HandlingUserInputHelper final : public nsIJSRAIIHelper
3826
{
3827
public:
3828
  explicit HandlingUserInputHelper(bool aHandlingUserInput);
3829
3830
  NS_DECL_ISUPPORTS
3831
  NS_DECL_NSIJSRAIIHELPER
3832
3833
private:
3834
  ~HandlingUserInputHelper();
3835
3836
  bool mHandlingUserInput;
3837
  bool mDestructCalled;
3838
};
3839
3840
NS_IMPL_ISUPPORTS(HandlingUserInputHelper, nsIJSRAIIHelper)
3841
3842
HandlingUserInputHelper::HandlingUserInputHelper(bool aHandlingUserInput)
3843
  : mHandlingUserInput(aHandlingUserInput),
3844
    mDestructCalled(false)
3845
0
{
3846
0
  if (aHandlingUserInput) {
3847
0
    EventStateManager::StartHandlingUserInput(eVoidEvent);
3848
0
  }
3849
0
}
3850
3851
HandlingUserInputHelper::~HandlingUserInputHelper()
3852
0
{
3853
0
  // We assert, but just in case, make sure we notify the ESM.
3854
0
  MOZ_ASSERT(mDestructCalled);
3855
0
  if (!mDestructCalled) {
3856
0
    Destruct();
3857
0
  }
3858
0
}
3859
3860
NS_IMETHODIMP
3861
HandlingUserInputHelper::Destruct()
3862
0
{
3863
0
  if (NS_WARN_IF(mDestructCalled)) {
3864
0
    return NS_ERROR_FAILURE;
3865
0
  }
3866
0
3867
0
  mDestructCalled = true;
3868
0
  if (mHandlingUserInput) {
3869
0
    EventStateManager::StopHandlingUserInput(eVoidEvent);
3870
0
  }
3871
0
3872
0
  return NS_OK;
3873
0
}
3874
3875
} // unnamed namespace
3876
3877
NS_IMETHODIMP
3878
nsDOMWindowUtils::SetHandlingUserInput(bool aHandlingUserInput,
3879
                                       nsIJSRAIIHelper** aHelper)
3880
0
{
3881
0
  RefPtr<HandlingUserInputHelper> helper(
3882
0
    new HandlingUserInputHelper(aHandlingUserInput));
3883
0
  helper.forget(aHelper);
3884
0
  return NS_OK;
3885
0
}
3886
3887
NS_IMETHODIMP
3888
nsDOMWindowUtils::GetContentAPZTestData(JSContext* aContext,
3889
                                        JS::MutableHandleValue aOutContentTestData)
3890
0
{
3891
0
  if (nsIWidget* widget = GetWidget()) {
3892
0
    RefPtr<LayerManager> lm = widget->GetLayerManager();
3893
0
    if (!lm) {
3894
0
      return NS_OK;
3895
0
    }
3896
0
    if (ClientLayerManager* clm = lm->AsClientLayerManager()) {
3897
0
      if (!clm->GetAPZTestData().ToJS(aOutContentTestData, aContext)) {
3898
0
        return NS_ERROR_FAILURE;
3899
0
      }
3900
0
    } else if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) {
3901
0
      if (!wrlm->GetAPZTestData().ToJS(aOutContentTestData, aContext)) {
3902
0
        return NS_ERROR_FAILURE;
3903
0
      }
3904
0
    }
3905
0
  }
3906
0
3907
0
  return NS_OK;
3908
0
}
3909
3910
NS_IMETHODIMP
3911
nsDOMWindowUtils::GetCompositorAPZTestData(JSContext* aContext,
3912
                                           JS::MutableHandleValue aOutCompositorTestData)
3913
0
{
3914
0
  if (nsIWidget* widget = GetWidget()) {
3915
0
    RefPtr<LayerManager> lm = widget->GetLayerManager();
3916
0
    if (!lm) {
3917
0
      return NS_OK;
3918
0
    }
3919
0
    APZTestData compositorSideData;
3920
0
    if (ClientLayerManager* clm = lm->AsClientLayerManager()) {
3921
0
      clm->GetCompositorSideAPZTestData(&compositorSideData);
3922
0
    } else if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) {
3923
0
      if (!wrlm->WrBridge()) {
3924
0
        return NS_ERROR_UNEXPECTED;
3925
0
      }
3926
0
      if (!wrlm->WrBridge()->SendGetAPZTestData(&compositorSideData)) {
3927
0
        return NS_ERROR_FAILURE;
3928
0
      }
3929
0
    }
3930
0
    if (!compositorSideData.ToJS(aOutCompositorTestData, aContext)) {
3931
0
      return NS_ERROR_FAILURE;
3932
0
    }
3933
0
  }
3934
0
3935
0
  return NS_OK;
3936
0
}
3937
3938
NS_IMETHODIMP
3939
nsDOMWindowUtils::PostRestyleSelfEvent(Element* aElement)
3940
0
{
3941
0
  if (!aElement) {
3942
0
    return NS_ERROR_INVALID_ARG;
3943
0
  }
3944
0
3945
0
  nsLayoutUtils::PostRestyleEvent(aElement, eRestyle_Self, nsChangeHint(0));
3946
0
  return NS_OK;
3947
0
}
3948
3949
NS_IMETHODIMP
3950
nsDOMWindowUtils::GetMediaSuspend(uint32_t* aSuspend)
3951
0
{
3952
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3953
0
  NS_ENSURE_STATE(window);
3954
0
3955
0
  *aSuspend = window->GetMediaSuspend();
3956
0
  return NS_OK;
3957
0
}
3958
3959
NS_IMETHODIMP
3960
nsDOMWindowUtils::SetMediaSuspend(uint32_t aSuspend)
3961
0
{
3962
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3963
0
  NS_ENSURE_STATE(window);
3964
0
3965
0
  window->SetMediaSuspend(aSuspend);
3966
0
  return NS_OK;
3967
0
}
3968
3969
NS_IMETHODIMP
3970
nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
3971
0
{
3972
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3973
0
  NS_ENSURE_STATE(window);
3974
0
3975
0
  *aMuted = window->GetAudioMuted();
3976
0
  return NS_OK;
3977
0
}
3978
3979
NS_IMETHODIMP
3980
nsDOMWindowUtils::SetAudioMuted(bool aMuted)
3981
0
{
3982
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3983
0
  NS_ENSURE_STATE(window);
3984
0
3985
0
  window->SetAudioMuted(aMuted);
3986
0
  return NS_OK;
3987
0
}
3988
3989
NS_IMETHODIMP
3990
nsDOMWindowUtils::GetAudioVolume(float* aVolume)
3991
0
{
3992
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
3993
0
  NS_ENSURE_STATE(window);
3994
0
3995
0
  *aVolume = window->GetAudioVolume();
3996
0
  return NS_OK;
3997
0
}
3998
3999
NS_IMETHODIMP
4000
nsDOMWindowUtils::SetAudioVolume(float aVolume)
4001
0
{
4002
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
4003
0
  NS_ENSURE_STATE(window);
4004
0
4005
0
  return window->SetAudioVolume(aVolume);
4006
0
}
4007
4008
NS_IMETHODIMP
4009
nsDOMWindowUtils::SetChromeMargin(int32_t aTop,
4010
                                  int32_t aRight,
4011
                                  int32_t aBottom,
4012
                                  int32_t aLeft)
4013
0
{
4014
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
4015
0
  if (window) {
4016
0
    nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(window->GetDocShell());
4017
0
    if (baseWindow) {
4018
0
      nsCOMPtr<nsIWidget> widget;
4019
0
      baseWindow->GetMainWidget(getter_AddRefs(widget));
4020
0
      if (widget) {
4021
0
        LayoutDeviceIntMargin margins(aTop, aRight, aBottom, aLeft);
4022
0
        return widget->SetNonClientMargins(margins);
4023
0
      }
4024
0
    }
4025
0
  }
4026
0
4027
0
  return NS_OK;
4028
0
}
4029
4030
NS_IMETHODIMP
4031
nsDOMWindowUtils::GetFrameUniformityTestData(JSContext* aContext,
4032
                                             JS::MutableHandleValue aOutFrameUniformity)
4033
0
{
4034
0
  nsIWidget* widget = GetWidget();
4035
0
  if (!widget) {
4036
0
    return NS_ERROR_NOT_AVAILABLE;
4037
0
  }
4038
0
4039
0
  RefPtr<LayerManager> manager = widget->GetLayerManager();
4040
0
  if (!manager) {
4041
0
    return NS_ERROR_NOT_AVAILABLE;
4042
0
  }
4043
0
4044
0
  FrameUniformityData outData;
4045
0
  manager->GetFrameUniformity(&outData);
4046
0
  outData.ToJS(aOutFrameUniformity, aContext);
4047
0
  return NS_OK;
4048
0
}
4049
4050
NS_IMETHODIMP
4051
nsDOMWindowUtils::XpconnectArgument(nsIDOMWindowUtils* aThis)
4052
0
{
4053
0
  // Do nothing.
4054
0
  return NS_OK;
4055
0
}
4056
4057
NS_IMETHODIMP
4058
nsDOMWindowUtils::AskPermission(nsIContentPermissionRequest* aRequest)
4059
0
{
4060
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
4061
0
  return nsContentPermissionUtils::AskPermission(aRequest, window->GetCurrentInnerWindow());
4062
0
}
4063
4064
NS_IMETHODIMP
4065
nsDOMWindowUtils::GetRestyleGeneration(uint64_t* aResult)
4066
0
{
4067
0
  nsPresContext* presContext = GetPresContext();
4068
0
  if (!presContext) {
4069
0
    return NS_ERROR_NOT_AVAILABLE;
4070
0
  }
4071
0
4072
0
  *aResult = presContext->GetRestyleGeneration();
4073
0
  return NS_OK;
4074
0
}
4075
4076
NS_IMETHODIMP
4077
nsDOMWindowUtils::GetFramesConstructed(uint64_t* aResult)
4078
0
{
4079
0
  nsPresContext* presContext = GetPresContext();
4080
0
  if (!presContext) {
4081
0
    return NS_ERROR_NOT_AVAILABLE;
4082
0
  }
4083
0
4084
0
  *aResult = presContext->FramesConstructedCount();
4085
0
  return NS_OK;
4086
0
}
4087
4088
NS_IMETHODIMP
4089
nsDOMWindowUtils::GetFramesReflowed(uint64_t* aResult)
4090
0
{
4091
0
  nsPresContext* presContext = GetPresContext();
4092
0
  if (!presContext) {
4093
0
    return NS_ERROR_NOT_AVAILABLE;
4094
0
  }
4095
0
4096
0
  *aResult = presContext->FramesReflowedCount();
4097
0
  return NS_OK;
4098
0
}
4099
4100
NS_IMETHODIMP
4101
nsDOMWindowUtils::SetServiceWorkersTestingEnabled(bool aEnabled)
4102
0
{
4103
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
4104
0
  NS_ENSURE_STATE(window);
4105
0
4106
0
  window->SetServiceWorkersTestingEnabled(aEnabled);
4107
0
4108
0
  return NS_OK;
4109
0
}
4110
4111
NS_IMETHODIMP
4112
nsDOMWindowUtils::GetServiceWorkersTestingEnabled(bool *aEnabled)
4113
0
{
4114
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
4115
0
  NS_ENSURE_STATE(window);
4116
0
4117
0
  *aEnabled = window->GetServiceWorkersTestingEnabled();
4118
0
4119
0
  return NS_OK;
4120
0
}
4121
4122
NS_IMETHODIMP
4123
nsDOMWindowUtils::EnterChaosMode()
4124
0
{
4125
0
  ChaosMode::enterChaosMode();
4126
0
  return NS_OK;
4127
0
}
4128
4129
NS_IMETHODIMP
4130
nsDOMWindowUtils::LeaveChaosMode()
4131
0
{
4132
0
  ChaosMode::leaveChaosMode();
4133
0
  return NS_OK;
4134
0
}
4135
4136
NS_IMETHODIMP
4137
nsDOMWindowUtils::TriggerDeviceReset()
4138
0
{
4139
0
  ContentChild* cc = ContentChild::GetSingleton();
4140
0
  if (cc) {
4141
0
    cc->SendDeviceReset();
4142
0
    return NS_OK;
4143
0
  }
4144
0
4145
0
  GPUProcessManager* pm = GPUProcessManager::Get();
4146
0
  if (pm) {
4147
0
    pm->SimulateDeviceReset();
4148
0
  }
4149
0
  return NS_OK;
4150
0
}
4151
4152
NS_IMETHODIMP
4153
nsDOMWindowUtils::ForceUseCounterFlush(nsINode *aNode)
4154
0
{
4155
0
  NS_ENSURE_ARG_POINTER(aNode);
4156
0
4157
0
  if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode)) {
4158
0
    mozilla::css::ImageLoader* loader = doc->StyleImageLoader();
4159
0
    loader->FlushUseCounters();
4160
0
4161
0
    // Flush the document and any external documents that it depends on.
4162
0
    const auto reportKind
4163
0
      = nsDocument::UseCounterReportKind::eIncludeExternalResources;
4164
0
    static_cast<nsDocument*>(doc.get())->ReportUseCounters(reportKind);
4165
0
    return NS_OK;
4166
0
  }
4167
0
4168
0
  if (nsCOMPtr<nsIContent> content = do_QueryInterface(aNode)) {
4169
0
    if (HTMLImageElement* img = HTMLImageElement::FromNode(content)) {
4170
0
      img->FlushUseCounters();
4171
0
      return NS_OK;
4172
0
    }
4173
0
  }
4174
0
4175
0
  return NS_OK;
4176
0
}
4177
4178
NS_IMETHODIMP
4179
nsDOMWindowUtils::HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType,
4180
                                                          bool* aRetVal)
4181
0
{
4182
0
  nsIPresShell* presShell = GetPresShell();
4183
0
  if (!presShell) {
4184
0
    return NS_ERROR_FAILURE;
4185
0
  }
4186
0
4187
0
  return presShell->HasRuleProcessorUsedByMultipleStyleSets(aSheetType,
4188
0
                                                            aRetVal);
4189
0
}
4190
4191
NS_IMETHODIMP
4192
nsDOMWindowUtils::RespectDisplayPortSuppression(bool aEnabled)
4193
0
{
4194
0
  nsCOMPtr<nsIPresShell> shell(GetPresShell());
4195
0
  shell->RespectDisplayportSuppression(aEnabled);
4196
0
  return NS_OK;
4197
0
}
4198
4199
NS_IMETHODIMP
4200
nsDOMWindowUtils::ForceReflowInterrupt()
4201
0
{
4202
0
  nsPresContext* pc = GetPresContext();
4203
0
  if (!pc) {
4204
0
    return NS_ERROR_NOT_AVAILABLE;
4205
0
  }
4206
0
  pc->SetPendingInterruptFromTest();
4207
0
  return NS_OK;
4208
0
}
4209
4210
NS_IMETHODIMP
4211
nsDOMWindowUtils::TerminateGPUProcess()
4212
0
{
4213
0
  GPUProcessManager* pm = GPUProcessManager::Get();
4214
0
  if (pm) {
4215
0
    pm->KillProcess();
4216
0
  }
4217
0
  return NS_OK;
4218
0
}
4219
4220
NS_IMETHODIMP
4221
nsDOMWindowUtils::GetGpuProcessPid(int32_t* aPid)
4222
0
{
4223
0
  GPUProcessManager* pm = GPUProcessManager::Get();
4224
0
  if (pm) {
4225
0
    *aPid = pm->GPUProcessPid();
4226
0
  } else {
4227
0
    *aPid = -1;
4228
0
  }
4229
0
4230
0
  return NS_OK;
4231
0
}
4232
4233
NS_IMETHODIMP
4234
nsDOMWindowUtils::IsTimeoutTracking(uint32_t aTimeoutId, bool* aResult)
4235
0
{
4236
0
  NS_ENSURE_ARG_POINTER(aResult);
4237
0
  *aResult = false;
4238
0
4239
0
  nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
4240
0
  NS_ENSURE_STATE(window);
4241
0
  nsCOMPtr<nsPIDOMWindowInner> innerWindow = window->GetCurrentInnerWindow();
4242
0
  NS_ENSURE_STATE(innerWindow);
4243
0
4244
0
  *aResult = innerWindow->TimeoutManager().IsTimeoutTracking(aTimeoutId);
4245
0
  return NS_OK;
4246
0
}
4247
4248
struct StateTableEntry
4249
{
4250
  const char* mStateString;
4251
  EventStates mState;
4252
};
4253
4254
static constexpr StateTableEntry kManuallyManagedStates[] = {
4255
  { "-moz-autofill", NS_EVENT_STATE_AUTOFILL },
4256
  { "-moz-autofill-preview", NS_EVENT_STATE_AUTOFILL_PREVIEW },
4257
  { nullptr, EventStates() },
4258
};
4259
4260
static_assert(!kManuallyManagedStates[ArrayLength(kManuallyManagedStates) - 1]
4261
               .mStateString,
4262
              "last kManuallyManagedStates entry must be a sentinel with "
4263
              "mStateString == nullptr");
4264
4265
static EventStates
4266
GetEventStateForString(const nsAString& aStateString)
4267
0
{
4268
0
  for (const StateTableEntry* entry = kManuallyManagedStates;
4269
0
       entry->mStateString; ++entry) {
4270
0
    if (aStateString.EqualsASCII(entry->mStateString)) {
4271
0
      return entry->mState;
4272
0
    }
4273
0
  }
4274
0
  return EventStates();
4275
0
}
4276
4277
NS_IMETHODIMP
4278
nsDOMWindowUtils::AddManuallyManagedState(Element* aElement,
4279
                                          const nsAString& aStateString)
4280
0
{
4281
0
  if (!aElement) {
4282
0
    return NS_ERROR_INVALID_ARG;
4283
0
  }
4284
0
4285
0
  EventStates state = GetEventStateForString(aStateString);
4286
0
  if (state.IsEmpty()) {
4287
0
    return NS_ERROR_INVALID_ARG;
4288
0
  }
4289
0
4290
0
  aElement->AddManuallyManagedStates(state);
4291
0
  return NS_OK;
4292
0
}
4293
4294
NS_IMETHODIMP
4295
nsDOMWindowUtils::RemoveManuallyManagedState(Element* aElement,
4296
                                             const nsAString& aStateString)
4297
0
{
4298
0
  if (!aElement) {
4299
0
    return NS_ERROR_INVALID_ARG;
4300
0
  }
4301
0
4302
0
  EventStates state = GetEventStateForString(aStateString);
4303
0
  if (state.IsEmpty()) {
4304
0
    return NS_ERROR_INVALID_ARG;
4305
0
  }
4306
0
4307
0
  aElement->RemoveManuallyManagedStates(state);
4308
0
  return NS_OK;
4309
0
}
4310
4311
NS_IMETHODIMP
4312
nsDOMWindowUtils::GetStorageUsage(Storage* aStorage, int64_t* aRetval)
4313
0
{
4314
0
  if (!aStorage) {
4315
0
    return NS_ERROR_UNEXPECTED;
4316
0
  }
4317
0
4318
0
  *aRetval = aStorage->GetOriginQuotaUsage();
4319
0
4320
0
  return NS_OK;
4321
0
}
4322
4323
NS_IMETHODIMP
4324
nsDOMWindowUtils::GetDirectionFromText(const nsAString& aString, int32_t* aRetval)
4325
0
{
4326
0
  Directionality dir = ::GetDirectionFromText(aString.BeginReading(), aString.Length(), nullptr);
4327
0
  switch (dir) {
4328
0
    case eDir_NotSet:
4329
0
      *aRetval = nsIDOMWindowUtils::DIRECTION_NOT_SET;
4330
0
      break;
4331
0
    case eDir_RTL:
4332
0
      *aRetval = nsIDOMWindowUtils::DIRECTION_RTL;
4333
0
      break;
4334
0
    case eDir_LTR:
4335
0
      *aRetval = nsIDOMWindowUtils::DIRECTION_LTR;
4336
0
      break;
4337
0
    case eDir_Auto:
4338
0
      MOZ_ASSERT_UNREACHABLE("GetDirectionFromText should never return this value");
4339
0
      return NS_ERROR_FAILURE;
4340
0
  }
4341
0
  return NS_OK;
4342
0
}
4343
4344
NS_IMETHODIMP
4345
nsDOMWindowUtils::EnsureDirtyRootFrame()
4346
0
{
4347
0
  nsIDocument* doc = GetDocument();
4348
0
  nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
4349
0
4350
0
  if (!presShell) {
4351
0
    return NS_ERROR_FAILURE;
4352
0
  }
4353
0
4354
0
  nsIFrame* frame = presShell->GetRootFrame();
4355
0
  if (!frame) {
4356
0
    return NS_ERROR_FAILURE;
4357
0
  }
4358
0
4359
0
  presShell->FrameNeedsReflow(frame, nsIPresShell::eStyleChange,
4360
0
                              NS_FRAME_IS_DIRTY);
4361
0
  return NS_OK;
4362
0
}
4363
4364
NS_IMETHODIMP
4365
nsDOMWindowUtils::SetPrefersReducedMotionOverrideForTest(bool aValue)
4366
0
{
4367
0
  nsIWidget* widget = GetWidget();
4368
0
  if (!widget) {
4369
0
    return NS_OK;
4370
0
  }
4371
0
4372
0
  return widget->SetPrefersReducedMotionOverrideForTest(aValue);
4373
0
}
4374
4375
NS_IMETHODIMP
4376
nsDOMWindowUtils::ResetPrefersReducedMotionOverrideForTest()
4377
0
{
4378
0
  nsIWidget* widget = GetWidget();
4379
0
  if (!widget) {
4380
0
    return NS_OK;
4381
0
  }
4382
0
4383
0
  return widget->ResetPrefersReducedMotionOverrideForTest();
4384
0
}
4385
4386
0
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
4387
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
4388
0
  NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
4389
0
NS_INTERFACE_MAP_END
4390
4391
NS_IMPL_ADDREF(nsTranslationNodeList)
4392
NS_IMPL_RELEASE(nsTranslationNodeList)
4393
4394
NS_IMETHODIMP
4395
nsTranslationNodeList::Item(uint32_t aIndex, nsINode** aRetVal)
4396
0
{
4397
0
  NS_ENSURE_ARG_POINTER(aRetVal);
4398
0
  NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex));
4399
0
  return NS_OK;
4400
0
}
4401
4402
NS_IMETHODIMP
4403
nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal)
4404
0
{
4405
0
  NS_ENSURE_ARG_POINTER(aRetVal);
4406
0
  if (aIndex >= mLength) {
4407
0
    *aRetVal = false;
4408
0
    return NS_OK;
4409
0
  }
4410
0
4411
0
  *aRetVal = mNodeIsRoot.ElementAt(aIndex);
4412
0
  return NS_OK;
4413
0
}
4414
4415
NS_IMETHODIMP
4416
nsTranslationNodeList::GetLength(uint32_t* aRetVal)
4417
0
{
4418
0
  NS_ENSURE_ARG_POINTER(aRetVal);
4419
0
  *aRetVal = mLength;
4420
0
  return NS_OK;
4421
0
}
4422
4423
NS_IMETHODIMP
4424
nsDOMWindowUtils::WrCapture()
4425
0
{
4426
0
  if (WebRenderBridgeChild* wrbc = GetWebRenderBridge()) {
4427
0
    wrbc->Capture();
4428
0
  }
4429
0
  return NS_OK;
4430
0
}
4431
4432
NS_IMETHODIMP
4433
nsDOMWindowUtils::SetSystemFont(const nsACString& aFontName)
4434
0
{
4435
0
  nsIWidget* widget = GetWidget();
4436
0
  if (!widget) {
4437
0
    return NS_OK;
4438
0
  }
4439
0
4440
0
  nsAutoCString fontName(aFontName);
4441
0
  return widget->SetSystemFont(fontName);
4442
0
}
4443
4444
NS_IMETHODIMP
4445
nsDOMWindowUtils::GetSystemFont(nsACString& aFontName)
4446
0
{
4447
0
  nsIWidget* widget = GetWidget();
4448
0
  if (!widget) {
4449
0
    return NS_OK;
4450
0
  }
4451
0
4452
0
  nsAutoCString fontName;
4453
0
  widget->GetSystemFont(fontName);
4454
0
  aFontName.Assign(fontName);
4455
0
  return NS_OK;
4456
0
}
4457
4458
NS_IMETHODIMP
4459
nsDOMWindowUtils::IsCssPropertyRecordedInUseCounter(const nsACString& aPropName,
4460
                                                    bool* aRecorded)
4461
0
{
4462
0
  *aRecorded = false;
4463
0
4464
0
  nsIDocument* doc = GetDocument();
4465
0
  if (!doc || !doc->GetStyleUseCounters()) {
4466
0
    return NS_ERROR_FAILURE;
4467
0
  }
4468
0
4469
0
  bool knownProp = false;
4470
0
  *aRecorded =
4471
0
    Servo_IsCssPropertyRecordedInUseCounter(doc->GetStyleUseCounters(),
4472
0
                                            &aPropName,
4473
0
                                            &knownProp);
4474
0
  return knownProp ? NS_OK : NS_ERROR_FAILURE;
4475
0
}
4476