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