Bumping gaia.json for 8 gaia revision(s) a=gaia-bump
[gecko.git] / dom / base / nsDOMWindowUtils.cpp
blob36b32f05838607cef511cd1cb2418cffb6d4ee91
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sts=2 sw=2 et 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/. */
7 #include "nsDOMWindowUtils.h"
9 #include "mozilla/layers/CompositorChild.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 "CompositionStringSynthesizer.h"
17 #include "nsGlobalWindow.h"
18 #include "nsIDocument.h"
19 #include "nsFocusManager.h"
20 #include "nsFrameManager.h"
21 #include "nsRefreshDriver.h"
22 #include "mozilla/dom/Touch.h"
23 #include "mozilla/PendingPlayerTracker.h"
24 #include "nsIObjectLoadingContent.h"
25 #include "nsFrame.h"
26 #include "mozilla/layers/ShadowLayers.h"
27 #include "ClientLayerManager.h"
29 #include "nsIScrollableFrame.h"
31 #include "nsContentUtils.h"
33 #include "nsIFrame.h"
34 #include "nsIWidget.h"
35 #include "nsCharsetSource.h"
36 #include "nsJSEnvironment.h"
37 #include "nsJSUtils.h"
39 #include "mozilla/EventStateManager.h"
40 #include "mozilla/MiscEvents.h"
41 #include "mozilla/MouseEvents.h"
42 #include "mozilla/TextEvents.h"
43 #include "mozilla/TouchEvents.h"
45 #include "nsViewManager.h"
47 #include "nsIDOMHTMLCanvasElement.h"
48 #include "nsLayoutUtils.h"
49 #include "nsComputedDOMStyle.h"
50 #include "nsIPresShell.h"
51 #include "nsCSSProps.h"
52 #include "nsTArrayHelpers.h"
53 #include "nsIDocShell.h"
54 #include "nsIContentViewer.h"
55 #include "mozilla/StyleAnimationValue.h"
56 #include "mozilla/dom/File.h"
57 #include "mozilla/dom/DOMRect.h"
58 #include <algorithm>
60 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
61 #include <gdk/gdk.h>
62 #include <gdk/gdkx.h>
63 #endif
65 #include "Layers.h"
66 #include "mozilla/layers/ShadowLayers.h"
67 #include "gfxPrefs.h"
69 #include "mozilla/dom/Element.h"
70 #include "mozilla/dom/TabChild.h"
71 #include "mozilla/dom/IDBFactoryBinding.h"
72 #include "mozilla/dom/IDBMutableFileBinding.h"
73 #include "mozilla/dom/indexedDB/IDBMutableFile.h"
74 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
75 #include "mozilla/dom/PermissionMessageUtils.h"
76 #include "mozilla/dom/quota/PersistenceType.h"
77 #include "mozilla/dom/quota/QuotaManager.h"
78 #include "nsPrintfCString.h"
79 #include "nsViewportInfo.h"
80 #include "nsIFormControl.h"
81 #include "nsIScriptError.h"
82 #include "nsIAppShell.h"
83 #include "nsWidgetsCID.h"
84 #include "FrameLayerBuilder.h"
85 #include "nsDisplayList.h"
86 #include "nsROCSSPrimitiveValue.h"
87 #include "nsIBaseWindow.h"
88 #include "nsIDocShellTreeOwner.h"
89 #include "nsIInterfaceRequestorUtils.h"
90 #include "GeckoProfiler.h"
91 #include "mozilla/Preferences.h"
92 #include "nsIContentIterator.h"
93 #include "nsIDOMStyleSheet.h"
94 #include "nsIStyleSheet.h"
95 #include "nsContentPermissionHelper.h"
96 #include "nsNetUtil.h"
98 #ifdef XP_WIN
99 #undef GetClassName
100 #endif
102 using namespace mozilla;
103 using namespace mozilla::dom;
104 using namespace mozilla::ipc;
105 using namespace mozilla::layers;
106 using namespace mozilla::widget;
107 using namespace mozilla::gfx;
109 class gfxContext;
111 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
113 NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
114 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
115 NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
116 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
117 NS_INTERFACE_MAP_END
119 NS_IMPL_ADDREF(nsDOMWindowUtils)
120 NS_IMPL_RELEASE(nsDOMWindowUtils)
122 nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
124 nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow);
125 mWindow = do_GetWeakReference(supports);
126 NS_ASSERTION(aWindow->IsOuterWindow(), "How did that happen?");
129 nsDOMWindowUtils::~nsDOMWindowUtils()
133 nsIPresShell*
134 nsDOMWindowUtils::GetPresShell()
136 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
137 if (!window)
138 return nullptr;
140 nsIDocShell *docShell = window->GetDocShell();
141 if (!docShell)
142 return nullptr;
144 return docShell->GetPresShell();
147 nsPresContext*
148 nsDOMWindowUtils::GetPresContext()
150 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
151 if (!window)
152 return nullptr;
153 nsIDocShell *docShell = window->GetDocShell();
154 if (!docShell)
155 return nullptr;
156 nsRefPtr<nsPresContext> presContext;
157 docShell->GetPresContext(getter_AddRefs(presContext));
158 return presContext;
161 nsIDocument*
162 nsDOMWindowUtils::GetDocument()
164 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
165 if (!window) {
166 return nullptr;
168 return window->GetExtantDoc();
171 LayerTransactionChild*
172 nsDOMWindowUtils::GetLayerTransaction()
174 nsIWidget* widget = GetWidget();
175 if (!widget)
176 return nullptr;
178 LayerManager* manager = widget->GetLayerManager();
179 if (!manager)
180 return nullptr;
182 ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
183 return forwarder && forwarder->HasShadowManager() ?
184 forwarder->GetShadowManager() :
185 nullptr;
188 NS_IMETHODIMP
189 nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
191 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
193 NS_ENSURE_ARG_POINTER(aMode);
194 *aMode = 0;
195 nsPresContext* presContext = GetPresContext();
196 if (presContext) {
197 *aMode = presContext->ImageAnimationMode();
198 return NS_OK;
200 return NS_ERROR_NOT_AVAILABLE;
203 NS_IMETHODIMP
204 nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode)
206 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
208 nsPresContext* presContext = GetPresContext();
209 if (presContext) {
210 presContext->SetImageAnimationMode(aMode);
211 return NS_OK;
213 return NS_ERROR_NOT_AVAILABLE;
216 NS_IMETHODIMP
217 nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
219 *aIsForced = false;
221 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
223 nsIDocument* doc = GetDocument();
224 *aIsForced = doc &&
225 doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
226 return NS_OK;
229 NS_IMETHODIMP
230 nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
231 nsAString& aValue)
233 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
235 nsIDocument* doc = GetDocument();
236 if (doc) {
237 nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
238 doc->GetHeaderData(name, aValue);
239 return NS_OK;
242 aValue.Truncate();
243 return NS_OK;
246 NS_IMETHODIMP
247 nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
249 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
251 if (aCount == 0)
252 aCount = 1;
254 if (nsIPresShell* presShell = GetPresShell()) {
255 nsIFrame *rootFrame = presShell->GetRootFrame();
257 if (rootFrame) {
258 PRIntervalTime iStart = PR_IntervalNow();
260 for (uint32_t i = 0; i < aCount; i++)
261 rootFrame->InvalidateFrame();
263 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
264 XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
265 #endif
267 *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
269 return NS_OK;
272 return NS_ERROR_FAILURE;
275 NS_IMETHODIMP
276 nsDOMWindowUtils::UpdateLayerTree()
278 if (nsIPresShell* presShell = GetPresShell()) {
279 presShell->FlushPendingNotifications(Flush_Display);
280 nsRefPtr<nsViewManager> vm = presShell->GetViewManager();
281 nsView* view = vm->GetRootView();
282 if (view) {
283 presShell->Paint(view, view->GetBounds(),
284 nsIPresShell::PAINT_LAYERS | nsIPresShell::PAINT_SYNC_DECODE_IMAGES);
287 return NS_OK;
290 NS_IMETHODIMP
291 nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
293 if (!nsContentUtils::IsCallerChrome()) {
294 return NS_ERROR_DOM_SECURITY_ERR;
297 if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) {
298 return NS_ERROR_ILLEGAL_VALUE;
301 nsIPresShell* presShell = GetPresShell();
302 if (!presShell) {
303 return NS_ERROR_FAILURE;
306 nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
307 nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
309 presShell->ResizeReflowOverride(width, height);
311 return NS_OK;
314 NS_IMETHODIMP
315 nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
316 uint32_t aDisplayHeight,
317 double *aDefaultZoom, bool *aAllowZoom,
318 double *aMinZoom, double *aMaxZoom,
319 uint32_t *aWidth, uint32_t *aHeight,
320 bool *aAutoSize)
322 nsIDocument* doc = GetDocument();
323 NS_ENSURE_STATE(doc);
325 nsViewportInfo info = nsContentUtils::GetViewportInfo(doc, ScreenIntSize(aDisplayWidth, aDisplayHeight));
326 *aDefaultZoom = info.GetDefaultZoom().scale;
327 *aAllowZoom = info.IsZoomAllowed();
328 *aMinZoom = info.GetMinZoom().scale;
329 *aMaxZoom = info.GetMaxZoom().scale;
330 CSSIntSize size = gfx::RoundedToInt(info.GetSize());
331 *aWidth = size.width;
332 *aHeight = size.height;
333 *aAutoSize = info.IsAutoSizeEnabled();
334 return NS_OK;
337 NS_IMETHODIMP
338 nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
339 float aWidthPx, float aHeightPx,
340 nsIDOMElement* aElement,
341 uint32_t aPriority)
343 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
345 nsIPresShell* presShell = GetPresShell();
346 if (!presShell) {
347 return NS_ERROR_FAILURE;
350 if (!aElement) {
351 return NS_ERROR_INVALID_ARG;
354 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
356 if (!content) {
357 return NS_ERROR_INVALID_ARG;
360 if (content->GetCurrentDoc() != presShell->GetDocument()) {
361 return NS_ERROR_INVALID_ARG;
364 DisplayPortPropertyData* currentData =
365 static_cast<DisplayPortPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPort));
366 if (currentData && currentData->mPriority > aPriority) {
367 return NS_OK;
370 nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
371 nsPresContext::CSSPixelsToAppUnits(aYPx),
372 nsPresContext::CSSPixelsToAppUnits(aWidthPx),
373 nsPresContext::CSSPixelsToAppUnits(aHeightPx));
375 content->SetProperty(nsGkAtoms::DisplayPort,
376 new DisplayPortPropertyData(displayport, aPriority),
377 nsINode::DeleteProperty<DisplayPortPropertyData>);
379 if (nsLayoutUtils::UsesAsyncScrolling() && gfxPrefs::LayoutUseContainersForRootFrames()) {
380 nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
381 if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
382 // We are setting a root displayport for a document.
383 // The pres shell needs a special flag set.
384 presShell->SetIgnoreViewportScrolling(true);
388 nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
389 if (rootFrame) {
390 rootFrame->SchedulePaint();
392 // If we are hiding something that is a display root then send empty paint
393 // transaction in order to release retained layers because it won't get
394 // any more paint requests when it is hidden.
395 if (displayport.IsEmpty() &&
396 rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) {
397 nsCOMPtr<nsIWidget> widget = GetWidget();
398 if (widget) {
399 bool isRetainingManager;
400 LayerManager* manager = widget->GetLayerManager(&isRetainingManager);
401 if (isRetainingManager) {
402 manager->BeginTransaction();
403 nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(), NS_RGB(255, 255, 255),
404 nsLayoutUtils::PAINT_WIDGET_LAYERS |
405 nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
411 return NS_OK;
414 NS_IMETHODIMP
415 nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
416 float aTopMargin,
417 float aRightMargin,
418 float aBottomMargin,
419 nsIDOMElement* aElement,
420 uint32_t aPriority)
422 if (!nsContentUtils::IsCallerChrome()) {
423 return NS_ERROR_DOM_SECURITY_ERR;
426 nsIPresShell* presShell = GetPresShell();
427 if (!presShell) {
428 return NS_ERROR_FAILURE;
431 if (!aElement) {
432 return NS_ERROR_INVALID_ARG;
435 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
437 if (!content) {
438 return NS_ERROR_INVALID_ARG;
441 if (content->GetCurrentDoc() != presShell->GetDocument()) {
442 return NS_ERROR_INVALID_ARG;
445 // Note order change of arguments between our function signature and
446 // ScreenMargin constructor.
447 ScreenMargin displayportMargins(aTopMargin,
448 aRightMargin,
449 aBottomMargin,
450 aLeftMargin);
452 nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
453 aPriority);
455 return NS_OK;
459 NS_IMETHODIMP
460 nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
461 int32_t aY,
462 int32_t aWidth,
463 int32_t aHeight,
464 nsIDOMElement* aElement)
466 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
468 nsIPresShell* presShell = GetPresShell();
469 if (!presShell) {
470 return NS_ERROR_FAILURE;
473 if (!aElement) {
474 return NS_ERROR_INVALID_ARG;
477 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
479 if (!content) {
480 return NS_ERROR_INVALID_ARG;
483 if (content->GetCurrentDoc() != presShell->GetDocument()) {
484 return NS_ERROR_INVALID_ARG;
487 nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight));
489 return NS_OK;
492 NS_IMETHODIMP
493 nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
495 if (!nsContentUtils::IsCallerChrome()) {
496 return NS_ERROR_DOM_SECURITY_ERR;
499 nsIPresShell* presShell = GetPresShell();
500 if (!presShell) {
501 return NS_ERROR_FAILURE;
504 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
505 if (sf) {
506 sf->SetResolution(gfxSize(aXResolution, aYResolution));
507 presShell->SetResolution(aXResolution, aYResolution);
510 return NS_OK;
513 NS_IMETHODIMP
514 nsDOMWindowUtils::SetResolutionAndScaleTo(float aXResolution, float aYResolution)
516 if (!nsContentUtils::IsCallerChrome()) {
517 return NS_ERROR_DOM_SECURITY_ERR;
520 nsIPresShell* presShell = GetPresShell();
521 if (!presShell) {
522 return NS_ERROR_FAILURE;
525 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
526 if (sf) {
527 sf->SetResolutionAndScaleTo(gfxSize(aXResolution, aYResolution));
528 presShell->SetResolutionAndScaleTo(aXResolution, aYResolution);
531 return NS_OK;
534 NS_IMETHODIMP
535 nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
537 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
539 nsIPresShell* presShell = GetPresShell();
540 if (!presShell) {
541 return NS_ERROR_FAILURE;
544 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
545 if (sf) {
546 const gfxSize& res = sf->GetResolution();
547 *aXResolution = res.width;
548 *aYResolution = res.height;
549 } else {
550 *aXResolution = presShell->GetXResolution();
551 *aYResolution = presShell->GetYResolution();
554 return NS_OK;
557 NS_IMETHODIMP
558 nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) {
559 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
561 nsIPresShell* presShell = GetPresShell();
562 if (!presShell) {
563 return NS_ERROR_FAILURE;
566 const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
567 *aIsResolutionSet = sf && sf->IsResolutionSet();
569 return NS_OK;
572 NS_IMETHODIMP
573 nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
575 if (!nsContentUtils::IsCallerChrome()) {
576 return NS_ERROR_DOM_SECURITY_ERR;
579 nsIPresShell* presShell = GetPresShell();
580 if (presShell) {
581 presShell->SetIsFirstPaint(aIsFirstPaint);
582 return NS_OK;
584 return NS_ERROR_FAILURE;
587 NS_IMETHODIMP
588 nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint)
590 if (!nsContentUtils::IsCallerChrome()) {
591 return NS_ERROR_DOM_SECURITY_ERR;
594 nsIPresShell* presShell = GetPresShell();
595 if (presShell) {
596 *aIsFirstPaint = presShell->GetIsFirstPaint();
597 return NS_OK;
599 return NS_ERROR_FAILURE;
602 NS_IMETHODIMP
603 nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId)
605 if (!nsContentUtils::IsCallerChrome()) {
606 return NS_ERROR_DOM_SECURITY_ERR;
609 nsIPresShell* presShell = GetPresShell();
610 if (presShell) {
611 *aPresShellId = presShell->GetPresShellId();
612 return NS_OK;
614 return NS_ERROR_FAILURE;
617 /* static */
618 mozilla::Modifiers
619 nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers)
621 Modifiers result = 0;
622 if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) {
623 result |= mozilla::MODIFIER_SHIFT;
625 if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) {
626 result |= mozilla::MODIFIER_CONTROL;
628 if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) {
629 result |= mozilla::MODIFIER_ALT;
631 if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) {
632 result |= mozilla::MODIFIER_META;
634 if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) {
635 result |= mozilla::MODIFIER_ALTGRAPH;
637 if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) {
638 result |= mozilla::MODIFIER_CAPSLOCK;
640 if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) {
641 result |= mozilla::MODIFIER_FN;
643 if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) {
644 result |= mozilla::MODIFIER_NUMLOCK;
646 if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) {
647 result |= mozilla::MODIFIER_SCROLLLOCK;
649 if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) {
650 result |= mozilla::MODIFIER_SYMBOLLOCK;
652 if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) {
653 result |= mozilla::MODIFIER_OS;
655 return result;
658 NS_IMETHODIMP
659 nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
660 float aX,
661 float aY,
662 int32_t aButton,
663 int32_t aClickCount,
664 int32_t aModifiers,
665 bool aIgnoreRootScrollFrame,
666 float aPressure,
667 unsigned short aInputSourceArg,
668 bool aIsSynthesized,
669 uint8_t aOptionalArgCount,
670 bool *aPreventDefault)
672 return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
673 aIgnoreRootScrollFrame, aPressure,
674 aInputSourceArg, false, aPreventDefault,
675 aOptionalArgCount >= 4 ? aIsSynthesized : true);
678 NS_IMETHODIMP
679 nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
680 float aX,
681 float aY,
682 int32_t aButton,
683 int32_t aClickCount,
684 int32_t aModifiers,
685 bool aIgnoreRootScrollFrame,
686 float aPressure,
687 unsigned short aInputSourceArg,
688 bool aIsSynthesized,
689 uint8_t aOptionalArgCount)
691 PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow",
692 js::ProfileEntry::Category::EVENTS);
694 return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
695 aIgnoreRootScrollFrame, aPressure,
696 aInputSourceArg, true, nullptr,
697 aOptionalArgCount >= 4 ? aIsSynthesized : true);
700 static LayoutDeviceIntPoint
701 ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset,
702 nsPresContext* aPresContext)
704 return LayoutDeviceIntPoint::FromAppUnitsRounded(
705 CSSPoint::ToAppUnits(aPoint) + aOffset,
706 aPresContext->AppUnitsPerDevPixel());
709 static inline int16_t
710 GetButtonsFlagForButton(int32_t aButton)
712 switch (aButton) {
713 case WidgetMouseEvent::eLeftButton:
714 return WidgetMouseEvent::eLeftButtonFlag;
715 case WidgetMouseEvent::eMiddleButton:
716 return WidgetMouseEvent::eMiddleButtonFlag;
717 case WidgetMouseEvent::eRightButton:
718 return WidgetMouseEvent::eRightButtonFlag;
719 case 4:
720 return WidgetMouseEvent::e4thButtonFlag;
721 case 5:
722 return WidgetMouseEvent::e5thButtonFlag;
723 default:
724 NS_ERROR("Button not known.");
725 return 0;
729 nsView*
730 nsDOMWindowUtils::GetViewToDispatchEvent(nsPresContext* presContext, nsIPresShell** presShell)
732 if (presContext && presShell) {
733 *presShell = presContext->PresShell();
734 if (*presShell) {
735 NS_ADDREF(*presShell);
736 if (nsViewManager* viewManager = (*presShell)->GetViewManager()) {
737 if (nsView* view = viewManager->GetRootView()) {
738 return view;
743 return nullptr;
746 NS_IMETHODIMP
747 nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
748 float aX,
749 float aY,
750 int32_t aButton,
751 int32_t aClickCount,
752 int32_t aModifiers,
753 bool aIgnoreRootScrollFrame,
754 float aPressure,
755 unsigned short aInputSourceArg,
756 bool aToWindow,
757 bool *aPreventDefault,
758 bool aIsSynthesized)
760 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
762 // get the widget to send the event to
763 nsPoint offset;
764 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
765 if (!widget)
766 return NS_ERROR_FAILURE;
768 int32_t msg;
769 bool contextMenuKey = false;
770 if (aType.EqualsLiteral("mousedown"))
771 msg = NS_MOUSE_BUTTON_DOWN;
772 else if (aType.EqualsLiteral("mouseup"))
773 msg = NS_MOUSE_BUTTON_UP;
774 else if (aType.EqualsLiteral("mousemove"))
775 msg = NS_MOUSE_MOVE;
776 else if (aType.EqualsLiteral("mouseover"))
777 msg = NS_MOUSE_ENTER;
778 else if (aType.EqualsLiteral("mouseout"))
779 msg = NS_MOUSE_EXIT;
780 else if (aType.EqualsLiteral("contextmenu")) {
781 msg = NS_CONTEXTMENU;
782 contextMenuKey = (aButton == 0);
783 } else if (aType.EqualsLiteral("MozMouseHittest"))
784 msg = NS_MOUSE_MOZHITTEST;
785 else
786 return NS_ERROR_FAILURE;
788 if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
789 aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
792 WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal,
793 contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
794 WidgetMouseEvent::eNormal);
795 event.modifiers = GetWidgetModifiers(aModifiers);
796 event.button = aButton;
797 event.buttons = GetButtonsFlagForButton(aButton);
798 event.widget = widget;
799 event.pressure = aPressure;
800 event.inputSource = aInputSourceArg;
801 event.clickCount = aClickCount;
802 event.time = PR_IntervalNow();
803 event.mFlags.mIsSynthesizedForTests = aIsSynthesized;
805 nsPresContext* presContext = GetPresContext();
806 if (!presContext)
807 return NS_ERROR_FAILURE;
809 event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
810 event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
812 nsEventStatus status;
813 if (aToWindow) {
814 nsCOMPtr<nsIPresShell> presShell;
815 nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
816 if (!presShell || !view) {
817 return NS_ERROR_FAILURE;
819 status = nsEventStatus_eIgnore;
820 return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
822 nsresult rv = widget->DispatchEvent(&event, status);
823 if (aPreventDefault) {
824 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
827 return rv;
830 NS_IMETHODIMP
831 nsDOMWindowUtils::SendPointerEventCommon(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 aToWindow,
849 bool* aPreventDefault)
851 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
853 // get the widget to send the event to
854 nsPoint offset;
855 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
856 if (!widget) {
857 return NS_ERROR_FAILURE;
860 int32_t msg;
861 if (aType.EqualsLiteral("pointerdown")) {
862 msg = NS_POINTER_DOWN;
863 } else if (aType.EqualsLiteral("pointerup")) {
864 msg = NS_POINTER_UP;
865 } else if (aType.EqualsLiteral("pointermove")) {
866 msg = NS_POINTER_MOVE;
867 } else if (aType.EqualsLiteral("pointerover")) {
868 msg = NS_POINTER_OVER;
869 } else if (aType.EqualsLiteral("pointerout")) {
870 msg = NS_POINTER_OUT;
871 } else {
872 return NS_ERROR_FAILURE;
875 if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
876 aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
879 WidgetPointerEvent event(true, msg, widget);
880 event.modifiers = GetWidgetModifiers(aModifiers);
881 event.button = aButton;
882 event.buttons = GetButtonsFlagForButton(aButton);
883 event.widget = widget;
884 event.pressure = aPressure;
885 event.inputSource = aInputSourceArg;
886 event.pointerId = aPointerId;
887 event.width = aWidth;
888 event.height = aHeight;
889 event.tiltX = aTiltX;
890 event.tiltY = aTiltY;
891 event.isPrimary = (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
892 event.clickCount = aClickCount;
893 event.time = PR_IntervalNow();
894 event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
896 nsPresContext* presContext = GetPresContext();
897 if (!presContext) {
898 return NS_ERROR_FAILURE;
901 event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
902 event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
904 nsEventStatus status;
905 if (aToWindow) {
906 nsCOMPtr<nsIPresShell> presShell;
907 nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
908 if (!presShell || !view) {
909 return NS_ERROR_FAILURE;
911 status = nsEventStatus_eIgnore;
912 return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
914 nsresult rv = widget->DispatchEvent(&event, status);
915 if (aPreventDefault) {
916 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
919 return rv;
922 NS_IMETHODIMP
923 nsDOMWindowUtils::SendPointerEvent(const nsAString& aType,
924 float aX,
925 float aY,
926 int32_t aButton,
927 int32_t aClickCount,
928 int32_t aModifiers,
929 bool aIgnoreRootScrollFrame,
930 float aPressure,
931 unsigned short aInputSourceArg,
932 int32_t aPointerId,
933 int32_t aWidth,
934 int32_t aHeight,
935 int32_t aTiltX,
936 int32_t aTiltY,
937 bool aIsPrimary,
938 bool aIsSynthesized,
939 uint8_t aOptionalArgCount,
940 bool* aPreventDefault)
942 PROFILER_LABEL("nsDOMWindowUtils", "SendPointerEvent",
943 js::ProfileEntry::Category::EVENTS);
945 return SendPointerEventCommon(aType, aX, aY, aButton, aClickCount,
946 aModifiers, aIgnoreRootScrollFrame,
947 aPressure, aInputSourceArg, aPointerId,
948 aWidth, aHeight, aTiltX, aTiltY,
949 aIsPrimary, aIsSynthesized,
950 aOptionalArgCount, false, aPreventDefault);
953 NS_IMETHODIMP
954 nsDOMWindowUtils::SendPointerEventToWindow(const nsAString& aType,
955 float aX,
956 float aY,
957 int32_t aButton,
958 int32_t aClickCount,
959 int32_t aModifiers,
960 bool aIgnoreRootScrollFrame,
961 float aPressure,
962 unsigned short aInputSourceArg,
963 int32_t aPointerId,
964 int32_t aWidth,
965 int32_t aHeight,
966 int32_t aTiltX,
967 int32_t aTiltY,
968 bool aIsPrimary,
969 bool aIsSynthesized,
970 uint8_t aOptionalArgCount)
972 PROFILER_LABEL("nsDOMWindowUtils", "SendPointerEventToWindow",
973 js::ProfileEntry::Category::EVENTS);
975 return SendPointerEventCommon(aType, aX, aY, aButton, aClickCount,
976 aModifiers, aIgnoreRootScrollFrame,
977 aPressure, aInputSourceArg, aPointerId,
978 aWidth, aHeight, aTiltX, aTiltY,
979 aIsPrimary, aIsSynthesized,
980 aOptionalArgCount, true, nullptr);
983 NS_IMETHODIMP
984 nsDOMWindowUtils::SendWheelEvent(float aX,
985 float aY,
986 double aDeltaX,
987 double aDeltaY,
988 double aDeltaZ,
989 uint32_t aDeltaMode,
990 int32_t aModifiers,
991 int32_t aLineOrPageDeltaX,
992 int32_t aLineOrPageDeltaY,
993 uint32_t aOptions)
995 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
997 // get the widget to send the event to
998 nsPoint offset;
999 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
1000 if (!widget) {
1001 return NS_ERROR_NULL_POINTER;
1004 WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
1005 wheelEvent.modifiers = GetWidgetModifiers(aModifiers);
1006 wheelEvent.deltaX = aDeltaX;
1007 wheelEvent.deltaY = aDeltaY;
1008 wheelEvent.deltaZ = aDeltaZ;
1009 wheelEvent.deltaMode = aDeltaMode;
1010 wheelEvent.isMomentum =
1011 (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
1012 wheelEvent.mIsNoLineOrPageDelta =
1013 (aOptions & WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE) != 0;
1014 wheelEvent.customizedByUserPrefs =
1015 (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
1016 wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;
1017 wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY;
1018 wheelEvent.widget = widget;
1020 wheelEvent.time = PR_Now() / 1000;
1022 nsPresContext* presContext = GetPresContext();
1023 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
1025 wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
1027 nsEventStatus status;
1028 nsresult rv = widget->DispatchEvent(&wheelEvent, status);
1029 NS_ENSURE_SUCCESS(rv, rv);
1031 bool failedX = false;
1032 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
1033 wheelEvent.overflowDeltaX != 0) {
1034 failedX = true;
1036 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) &&
1037 wheelEvent.overflowDeltaX <= 0) {
1038 failedX = true;
1040 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) &&
1041 wheelEvent.overflowDeltaX >= 0) {
1042 failedX = true;
1044 bool failedY = false;
1045 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) &&
1046 wheelEvent.overflowDeltaY != 0) {
1047 failedY = true;
1049 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) &&
1050 wheelEvent.overflowDeltaY <= 0) {
1051 failedY = true;
1053 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) &&
1054 wheelEvent.overflowDeltaY >= 0) {
1055 failedY = true;
1058 #ifdef DEBUG
1059 if (failedX) {
1060 nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaX: %f",
1061 wheelEvent.overflowDeltaX);
1062 NS_WARNING(debugMsg.get());
1064 if (failedY) {
1065 nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaY: %f",
1066 wheelEvent.overflowDeltaY);
1067 NS_WARNING(debugMsg.get());
1069 #endif
1071 return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE;
1074 NS_IMETHODIMP
1075 nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
1076 uint32_t *aIdentifiers,
1077 int32_t *aXs,
1078 int32_t *aYs,
1079 uint32_t *aRxs,
1080 uint32_t *aRys,
1081 float *aRotationAngles,
1082 float *aForces,
1083 uint32_t aCount,
1084 int32_t aModifiers,
1085 bool aIgnoreRootScrollFrame,
1086 bool *aPreventDefault)
1088 return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
1089 aRotationAngles, aForces, aCount, aModifiers,
1090 aIgnoreRootScrollFrame, false, aPreventDefault);
1093 NS_IMETHODIMP
1094 nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
1095 uint32_t* aIdentifiers,
1096 int32_t* aXs,
1097 int32_t* aYs,
1098 uint32_t* aRxs,
1099 uint32_t* aRys,
1100 float* aRotationAngles,
1101 float* aForces,
1102 uint32_t aCount,
1103 int32_t aModifiers,
1104 bool aIgnoreRootScrollFrame,
1105 bool* aPreventDefault)
1107 return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
1108 aRotationAngles, aForces, aCount, aModifiers,
1109 aIgnoreRootScrollFrame, true, aPreventDefault);
1112 NS_IMETHODIMP
1113 nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
1114 uint32_t* aIdentifiers,
1115 int32_t* aXs,
1116 int32_t* aYs,
1117 uint32_t* aRxs,
1118 uint32_t* aRys,
1119 float* aRotationAngles,
1120 float* aForces,
1121 uint32_t aCount,
1122 int32_t aModifiers,
1123 bool aIgnoreRootScrollFrame,
1124 bool aToWindow,
1125 bool* aPreventDefault)
1127 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1129 // get the widget to send the event to
1130 nsPoint offset;
1131 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
1132 if (!widget) {
1133 return NS_ERROR_NULL_POINTER;
1135 int32_t msg;
1136 if (aType.EqualsLiteral("touchstart")) {
1137 msg = NS_TOUCH_START;
1138 } else if (aType.EqualsLiteral("touchmove")) {
1139 msg = NS_TOUCH_MOVE;
1140 } else if (aType.EqualsLiteral("touchend")) {
1141 msg = NS_TOUCH_END;
1142 } else if (aType.EqualsLiteral("touchcancel")) {
1143 msg = NS_TOUCH_CANCEL;
1144 } else {
1145 return NS_ERROR_UNEXPECTED;
1147 WidgetTouchEvent event(true, msg, widget);
1148 event.modifiers = GetWidgetModifiers(aModifiers);
1149 event.widget = widget;
1150 event.time = PR_Now();
1152 nsPresContext* presContext = GetPresContext();
1153 if (!presContext) {
1154 return NS_ERROR_FAILURE;
1156 event.touches.SetCapacity(aCount);
1157 for (uint32_t i = 0; i < aCount; ++i) {
1158 LayoutDeviceIntPoint pt =
1159 ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
1160 nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
1161 LayoutDeviceIntPoint::ToUntyped(pt),
1162 nsIntPoint(aRxs[i], aRys[i]),
1163 aRotationAngles[i],
1164 aForces[i]);
1165 event.touches.AppendElement(t);
1168 nsEventStatus status;
1169 if (aToWindow) {
1170 nsCOMPtr<nsIPresShell> presShell;
1171 nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
1172 if (!presShell || !view) {
1173 return NS_ERROR_FAILURE;
1175 status = nsEventStatus_eIgnore;
1176 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
1177 return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
1180 nsresult rv = widget->DispatchEvent(&event, status);
1181 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
1182 return rv;
1185 NS_IMETHODIMP
1186 nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
1187 int32_t aKeyCode,
1188 int32_t aCharCode,
1189 int32_t aModifiers,
1190 uint32_t aAdditionalFlags,
1191 bool* aDefaultActionTaken)
1193 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1195 // get the widget to send the event to
1196 nsCOMPtr<nsIWidget> widget = GetWidget();
1197 if (!widget)
1198 return NS_ERROR_FAILURE;
1200 int32_t msg;
1201 if (aType.EqualsLiteral("keydown"))
1202 msg = NS_KEY_DOWN;
1203 else if (aType.EqualsLiteral("keyup"))
1204 msg = NS_KEY_UP;
1205 else if (aType.EqualsLiteral("keypress"))
1206 msg = NS_KEY_PRESS;
1207 else
1208 return NS_ERROR_FAILURE;
1210 WidgetKeyboardEvent event(true, msg, widget);
1211 event.modifiers = GetWidgetModifiers(aModifiers);
1213 if (msg == NS_KEY_PRESS) {
1214 event.keyCode = aCharCode ? 0 : aKeyCode;
1215 event.charCode = aCharCode;
1216 } else {
1217 event.keyCode = aKeyCode;
1218 event.charCode = 0;
1221 uint32_t locationFlag = (aAdditionalFlags &
1222 (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT |
1223 KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD |
1224 KEY_FLAG_LOCATION_MOBILE | KEY_FLAG_LOCATION_JOYSTICK));
1225 switch (locationFlag) {
1226 case KEY_FLAG_LOCATION_STANDARD:
1227 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
1228 break;
1229 case KEY_FLAG_LOCATION_LEFT:
1230 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
1231 break;
1232 case KEY_FLAG_LOCATION_RIGHT:
1233 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
1234 break;
1235 case KEY_FLAG_LOCATION_NUMPAD:
1236 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
1237 break;
1238 case KEY_FLAG_LOCATION_MOBILE:
1239 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
1240 break;
1241 case KEY_FLAG_LOCATION_JOYSTICK:
1242 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_JOYSTICK;
1243 break;
1244 default:
1245 if (locationFlag != 0) {
1246 return NS_ERROR_INVALID_ARG;
1248 // If location flag isn't set, choose the location from keycode.
1249 switch (aKeyCode) {
1250 case nsIDOMKeyEvent::DOM_VK_NUMPAD0:
1251 case nsIDOMKeyEvent::DOM_VK_NUMPAD1:
1252 case nsIDOMKeyEvent::DOM_VK_NUMPAD2:
1253 case nsIDOMKeyEvent::DOM_VK_NUMPAD3:
1254 case nsIDOMKeyEvent::DOM_VK_NUMPAD4:
1255 case nsIDOMKeyEvent::DOM_VK_NUMPAD5:
1256 case nsIDOMKeyEvent::DOM_VK_NUMPAD6:
1257 case nsIDOMKeyEvent::DOM_VK_NUMPAD7:
1258 case nsIDOMKeyEvent::DOM_VK_NUMPAD8:
1259 case nsIDOMKeyEvent::DOM_VK_NUMPAD9:
1260 case nsIDOMKeyEvent::DOM_VK_MULTIPLY:
1261 case nsIDOMKeyEvent::DOM_VK_ADD:
1262 case nsIDOMKeyEvent::DOM_VK_SEPARATOR:
1263 case nsIDOMKeyEvent::DOM_VK_SUBTRACT:
1264 case nsIDOMKeyEvent::DOM_VK_DECIMAL:
1265 case nsIDOMKeyEvent::DOM_VK_DIVIDE:
1266 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
1267 break;
1268 case nsIDOMKeyEvent::DOM_VK_SHIFT:
1269 case nsIDOMKeyEvent::DOM_VK_CONTROL:
1270 case nsIDOMKeyEvent::DOM_VK_ALT:
1271 case nsIDOMKeyEvent::DOM_VK_META:
1272 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
1273 break;
1274 default:
1275 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
1276 break;
1278 break;
1281 event.refPoint.x = event.refPoint.y = 0;
1282 event.time = PR_IntervalNow();
1283 if (!(aAdditionalFlags & KEY_FLAG_NOT_SYNTHESIZED_FOR_TESTS)) {
1284 event.mFlags.mIsSynthesizedForTests = true;
1287 if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) {
1288 event.mFlags.mDefaultPrevented = true;
1291 nsEventStatus status;
1292 nsresult rv = widget->DispatchEvent(&event, status);
1293 NS_ENSURE_SUCCESS(rv, rv);
1295 *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
1297 return NS_OK;
1300 NS_IMETHODIMP
1301 nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout,
1302 int32_t aNativeKeyCode,
1303 int32_t aModifiers,
1304 const nsAString& aCharacters,
1305 const nsAString& aUnmodifiedCharacters)
1307 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1309 // get the widget to send the event to
1310 nsCOMPtr<nsIWidget> widget = GetWidget();
1311 if (!widget)
1312 return NS_ERROR_FAILURE;
1314 return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
1315 aModifiers, aCharacters, aUnmodifiedCharacters);
1318 NS_IMETHODIMP
1319 nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX,
1320 int32_t aScreenY,
1321 int32_t aNativeMessage,
1322 int32_t aModifierFlags,
1323 nsIDOMElement* aElement)
1325 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1327 // get the widget to send the event to
1328 nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
1329 if (!widget)
1330 return NS_ERROR_FAILURE;
1332 return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY),
1333 aNativeMessage, aModifierFlags);
1336 NS_IMETHODIMP
1337 nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX,
1338 int32_t aScreenY,
1339 uint32_t aNativeMessage,
1340 double aDeltaX,
1341 double aDeltaY,
1342 double aDeltaZ,
1343 uint32_t aModifierFlags,
1344 uint32_t aAdditionalFlags,
1345 nsIDOMElement* aElement)
1347 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1349 // get the widget to send the event to
1350 nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
1351 if (!widget) {
1352 return NS_ERROR_FAILURE;
1355 return widget->SynthesizeNativeMouseScrollEvent(nsIntPoint(aScreenX,
1356 aScreenY),
1357 aNativeMessage,
1358 aDeltaX, aDeltaY, aDeltaZ,
1359 aModifierFlags,
1360 aAdditionalFlags);
1363 NS_IMETHODIMP
1364 nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId,
1365 uint32_t aTouchState,
1366 int32_t aScreenX,
1367 int32_t aScreenY,
1368 double aPressure,
1369 uint32_t aOrientation)
1371 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1373 nsCOMPtr<nsIWidget> widget = GetWidget();
1374 if (!widget) {
1375 return NS_ERROR_FAILURE;
1378 if (aPressure < 0 || aPressure > 1 || aOrientation > 359) {
1379 return NS_ERROR_INVALID_ARG;
1382 return widget->SynthesizeNativeTouchPoint(aPointerId,
1383 (nsIWidget::TouchPointerState)aTouchState,
1384 nsIntPoint(aScreenX, aScreenY),
1385 aPressure, aOrientation);
1388 NS_IMETHODIMP
1389 nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX,
1390 int32_t aScreenY,
1391 bool aLongTap)
1393 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1395 nsCOMPtr<nsIWidget> widget = GetWidget();
1396 if (!widget) {
1397 return NS_ERROR_FAILURE;
1399 return widget->SynthesizeNativeTouchTap(nsIntPoint(aScreenX, aScreenY), aLongTap);
1402 NS_IMETHODIMP
1403 nsDOMWindowUtils::ClearNativeTouchSequence()
1405 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1407 nsCOMPtr<nsIWidget> widget = GetWidget();
1408 if (!widget) {
1409 return NS_ERROR_FAILURE;
1411 return widget->ClearNativeTouchSequence();
1414 NS_IMETHODIMP
1415 nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
1417 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1419 // get the widget to send the event to
1420 nsCOMPtr<nsIWidget> widget = GetWidget();
1421 if (!widget)
1422 return NS_ERROR_FAILURE;
1424 return widget->ActivateNativeMenuItemAt(indexString);
1427 NS_IMETHODIMP
1428 nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
1430 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1432 // get the widget to send the event to
1433 nsCOMPtr<nsIWidget> widget = GetWidget();
1434 if (!widget)
1435 return NS_ERROR_FAILURE;
1437 return widget->ForceUpdateNativeMenuAt(indexString);
1440 nsIWidget*
1441 nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
1443 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1444 if (window) {
1445 nsIDocShell *docShell = window->GetDocShell();
1446 if (docShell) {
1447 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
1448 if (presShell) {
1449 nsIFrame* frame = presShell->GetRootFrame();
1450 if (frame)
1451 return frame->GetView()->GetNearestWidget(aOffset);
1456 return nullptr;
1459 nsIWidget*
1460 nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
1462 if (!aElement)
1463 return GetWidget();
1465 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
1466 nsIDocument* doc = content->GetCurrentDoc();
1467 nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
1469 if (presShell) {
1470 nsIFrame* frame = content->GetPrimaryFrame();
1471 if (!frame) {
1472 frame = presShell->GetRootFrame();
1474 if (frame)
1475 return frame->GetNearestWidget();
1478 return nullptr;
1481 NS_IMETHODIMP
1482 nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
1484 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1486 nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
1487 nsIFocusManager* fm = nsFocusManager::GetFocusManager();
1488 if (fm) {
1489 if (aElement)
1490 fm->SetFocus(aElement, 0);
1491 else
1492 fm->ClearFocus(window);
1495 return NS_OK;
1498 NS_IMETHODIMP
1499 nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
1500 int32_t aExtraForgetSkippableCalls)
1502 PROFILER_LABEL("nsDOMWindowUtils", "GarbageCollect",
1503 js::ProfileEntry::Category::GC);
1504 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1506 nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
1507 nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
1509 return NS_OK;
1512 NS_IMETHODIMP
1513 nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener,
1514 int32_t aExtraForgetSkippableCalls)
1516 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1518 nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
1519 return NS_OK;
1522 NS_IMETHODIMP
1523 nsDOMWindowUtils::RunNextCollectorTimer()
1525 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1527 nsJSContext::RunNextCollectorTimer();
1529 return NS_OK;
1532 NS_IMETHODIMP
1533 nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
1534 float aX,
1535 float aY,
1536 uint32_t aDirection,
1537 double aDelta,
1538 int32_t aModifiers,
1539 uint32_t aClickCount)
1541 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1543 // get the widget to send the event to
1544 nsPoint offset;
1545 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
1546 if (!widget)
1547 return NS_ERROR_FAILURE;
1549 int32_t msg;
1550 if (aType.EqualsLiteral("MozSwipeGestureStart"))
1551 msg = NS_SIMPLE_GESTURE_SWIPE_START;
1552 else if (aType.EqualsLiteral("MozSwipeGestureUpdate"))
1553 msg = NS_SIMPLE_GESTURE_SWIPE_UPDATE;
1554 else if (aType.EqualsLiteral("MozSwipeGestureEnd"))
1555 msg = NS_SIMPLE_GESTURE_SWIPE_END;
1556 else if (aType.EqualsLiteral("MozSwipeGesture"))
1557 msg = NS_SIMPLE_GESTURE_SWIPE;
1558 else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
1559 msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
1560 else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
1561 msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
1562 else if (aType.EqualsLiteral("MozMagnifyGesture"))
1563 msg = NS_SIMPLE_GESTURE_MAGNIFY;
1564 else if (aType.EqualsLiteral("MozRotateGestureStart"))
1565 msg = NS_SIMPLE_GESTURE_ROTATE_START;
1566 else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
1567 msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
1568 else if (aType.EqualsLiteral("MozRotateGesture"))
1569 msg = NS_SIMPLE_GESTURE_ROTATE;
1570 else if (aType.EqualsLiteral("MozTapGesture"))
1571 msg = NS_SIMPLE_GESTURE_TAP;
1572 else if (aType.EqualsLiteral("MozPressTapGesture"))
1573 msg = NS_SIMPLE_GESTURE_PRESSTAP;
1574 else if (aType.EqualsLiteral("MozEdgeUIStarted"))
1575 msg = NS_SIMPLE_GESTURE_EDGE_STARTED;
1576 else if (aType.EqualsLiteral("MozEdgeUICanceled"))
1577 msg = NS_SIMPLE_GESTURE_EDGE_CANCELED;
1578 else if (aType.EqualsLiteral("MozEdgeUICompleted"))
1579 msg = NS_SIMPLE_GESTURE_EDGE_COMPLETED;
1580 else
1581 return NS_ERROR_FAILURE;
1583 WidgetSimpleGestureEvent event(true, msg, widget);
1584 event.modifiers = GetWidgetModifiers(aModifiers);
1585 event.direction = aDirection;
1586 event.delta = aDelta;
1587 event.clickCount = aClickCount;
1588 event.time = PR_IntervalNow();
1590 nsPresContext* presContext = GetPresContext();
1591 if (!presContext)
1592 return NS_ERROR_FAILURE;
1594 event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
1596 nsEventStatus status;
1597 return widget->DispatchEvent(&event, status);
1600 NS_IMETHODIMP
1601 nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
1602 bool aIgnoreRootScrollFrame,
1603 bool aFlushLayout,
1604 nsIDOMElement** aReturn)
1606 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1608 nsCOMPtr<nsIDocument> doc = GetDocument();
1609 NS_ENSURE_STATE(doc);
1611 Element* el =
1612 doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
1613 nsCOMPtr<nsIDOMElement> retval = do_QueryInterface(el);
1614 retval.forget(aReturn);
1615 return NS_OK;
1618 NS_IMETHODIMP
1619 nsDOMWindowUtils::NodesFromRect(float aX, float aY,
1620 float aTopSize, float aRightSize,
1621 float aBottomSize, float aLeftSize,
1622 bool aIgnoreRootScrollFrame,
1623 bool aFlushLayout,
1624 nsIDOMNodeList** aReturn)
1626 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1628 nsCOMPtr<nsIDocument> doc = GetDocument();
1629 NS_ENSURE_STATE(doc);
1631 return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize,
1632 aIgnoreRootScrollFrame, aFlushLayout, aReturn);
1635 NS_IMETHODIMP
1636 nsDOMWindowUtils::GetTranslationNodes(nsIDOMNode* aRoot,
1637 nsITranslationNodeList** aRetVal)
1639 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1641 NS_ENSURE_ARG_POINTER(aRetVal);
1642 nsCOMPtr<nsIContent> root = do_QueryInterface(aRoot);
1643 NS_ENSURE_STATE(root);
1644 nsCOMPtr<nsIDocument> doc = GetDocument();
1645 NS_ENSURE_STATE(doc);
1647 if (root->OwnerDoc() != doc) {
1648 return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
1651 nsTHashtable<nsPtrHashKey<nsIContent>> translationNodesHash(500);
1652 nsRefPtr<nsTranslationNodeList> list = new nsTranslationNodeList;
1654 uint32_t limit = 15000;
1656 // We begin iteration with content->GetNextNode because we want to explictly
1657 // skip the root tag from being a translation node.
1658 nsIContent* content = root;
1659 while ((limit > 0) && (content = content->GetNextNode(root))) {
1660 if (!content->IsHTML()) {
1661 continue;
1664 nsIAtom* localName = content->Tag();
1666 // Skip elements that usually contain non-translatable text content.
1667 if (localName == nsGkAtoms::script ||
1668 localName == nsGkAtoms::iframe ||
1669 localName == nsGkAtoms::frameset ||
1670 localName == nsGkAtoms::frame ||
1671 localName == nsGkAtoms::code ||
1672 localName == nsGkAtoms::noscript ||
1673 localName == nsGkAtoms::style) {
1674 continue;
1677 // An element is a translation node if it contains
1678 // at least one text node that has meaningful data
1679 // for translation
1680 for (nsIContent* child = content->GetFirstChild();
1681 child;
1682 child = child->GetNextSibling()) {
1684 if (child->HasTextForTranslation()) {
1685 translationNodesHash.PutEntry(content);
1687 bool isBlockFrame = false;
1688 nsIFrame* frame = content->GetPrimaryFrame();
1689 if (frame) {
1690 isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame);
1693 bool isTranslationRoot = isBlockFrame;
1694 if (!isBlockFrame) {
1695 // If an element is not a block element, it still
1696 // can be considered a translation root if the parent
1697 // of this element didn't make into the list of nodes
1698 // to be translated.
1699 bool parentInList = false;
1700 nsIContent* parent = content->GetParent();
1701 if (parent) {
1702 parentInList = translationNodesHash.Contains(parent);
1704 isTranslationRoot = !parentInList;
1707 list->AppendElement(content->AsDOMNode(), isTranslationRoot);
1708 --limit;
1709 break;
1714 *aRetVal = list.forget().take();
1715 return NS_OK;
1718 static TemporaryRef<DataSourceSurface>
1719 CanvasToDataSourceSurface(nsIDOMHTMLCanvasElement* aCanvas)
1721 nsCOMPtr<nsINode> node = do_QueryInterface(aCanvas);
1722 if (!node) {
1723 return nullptr;
1726 NS_ABORT_IF_FALSE(node->IsElement(),
1727 "An nsINode that implements nsIDOMHTMLCanvasElement should "
1728 "be an element.");
1729 nsLayoutUtils::SurfaceFromElementResult result =
1730 nsLayoutUtils::SurfaceFromElement(node->AsElement());
1731 return result.mSourceSurface->GetDataSurface();
1734 NS_IMETHODIMP
1735 nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
1736 nsIDOMHTMLCanvasElement *aCanvas2,
1737 uint32_t* aMaxDifference,
1738 uint32_t* retVal)
1740 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1742 if (aCanvas1 == nullptr ||
1743 aCanvas2 == nullptr ||
1744 retVal == nullptr)
1745 return NS_ERROR_FAILURE;
1747 RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(aCanvas1);
1748 RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(aCanvas2);
1750 if (img1 == nullptr || img2 == nullptr ||
1751 img1->GetSize() != img2->GetSize() ||
1752 img1->Stride() != img2->Stride())
1753 return NS_ERROR_FAILURE;
1755 int v;
1756 IntSize size = img1->GetSize();
1757 uint32_t stride = img1->Stride();
1759 // we can optimize for the common all-pass case
1760 if (stride == (uint32_t) size.width * 4) {
1761 v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4);
1762 if (v == 0) {
1763 if (aMaxDifference)
1764 *aMaxDifference = 0;
1765 *retVal = 0;
1766 return NS_OK;
1770 uint32_t dc = 0;
1771 uint32_t different = 0;
1773 for (int j = 0; j < size.height; j++) {
1774 unsigned char *p1 = img1->GetData() + j*stride;
1775 unsigned char *p2 = img2->GetData() + j*stride;
1776 v = memcmp(p1, p2, stride);
1778 if (v) {
1779 for (int i = 0; i < size.width; i++) {
1780 if (*(uint32_t*) p1 != *(uint32_t*) p2) {
1782 different++;
1784 dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc);
1785 dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc);
1786 dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc);
1787 dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc);
1790 p1 += 4;
1791 p2 += 4;
1796 if (aMaxDifference)
1797 *aMaxDifference = dc;
1799 *retVal = different;
1800 return NS_OK;
1803 NS_IMETHODIMP
1804 nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
1806 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1808 NS_ENSURE_ARG_POINTER(aResult);
1809 *aResult = false;
1810 nsPresContext* presContext = GetPresContext();
1811 if (!presContext)
1812 return NS_OK;
1813 *aResult = presContext->IsDOMPaintEventPending();
1814 return NS_OK;
1817 NS_IMETHODIMP
1818 nsDOMWindowUtils::ClearMozAfterPaintEvents()
1820 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1822 nsPresContext* presContext = GetPresContext();
1823 if (!presContext)
1824 return NS_OK;
1825 presContext->ClearMozAfterPaintEvents();
1826 return NS_OK;
1829 NS_IMETHODIMP
1830 nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable)
1832 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1834 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1835 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
1836 nsIDocShell *docShell = window->GetDocShell();
1837 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1838 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
1839 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1840 presShell->DisableNonTestMouseEvents(aDisable);
1841 return NS_OK;
1844 NS_IMETHODIMP
1845 nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
1847 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1849 nsCOMPtr<nsIDocument> doc = GetDocument();
1850 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
1852 if (aSuppress) {
1853 doc->SuppressEventHandling(nsIDocument::eEvents);
1854 } else {
1855 doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true);
1858 return NS_OK;
1861 static nsresult
1862 getScrollXYAppUnits(nsWeakPtr aWindow, bool aFlushLayout, nsPoint& aScrollPos) {
1863 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1865 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(aWindow);
1866 nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr;
1867 NS_ENSURE_STATE(doc);
1869 if (aFlushLayout) {
1870 doc->FlushPendingNotifications(Flush_Layout);
1873 nsIPresShell *presShell = doc->GetShell();
1874 if (presShell) {
1875 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
1876 if (sf) {
1877 aScrollPos = sf->GetScrollPosition();
1880 return NS_OK;
1883 NS_IMETHODIMP
1884 nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
1886 nsPoint scrollPos(0,0);
1887 nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
1888 NS_ENSURE_SUCCESS(rv, rv);
1889 *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
1890 *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
1892 return NS_OK;
1895 NS_IMETHODIMP
1896 nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY)
1898 nsPoint scrollPos(0,0);
1899 nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
1900 NS_ENSURE_SUCCESS(rv, rv);
1901 *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x);
1902 *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y);
1904 return NS_OK;
1907 NS_IMETHODIMP
1908 nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
1909 int32_t* aHeight)
1911 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1913 *aWidth = 0;
1914 *aHeight = 0;
1916 nsCOMPtr<nsIDocument> doc = GetDocument();
1917 NS_ENSURE_STATE(doc);
1919 if (aFlushLayout) {
1920 doc->FlushPendingNotifications(Flush_Layout);
1923 nsIPresShell* presShell = doc->GetShell();
1924 NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
1926 nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
1927 NS_ENSURE_TRUE(scrollFrame, NS_OK);
1929 nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
1930 *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
1931 *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
1933 return NS_OK;
1936 NS_IMETHODIMP
1937 nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement,
1938 nsIDOMClientRect** aResult)
1940 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1942 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1943 NS_ENSURE_STATE(window);
1945 nsresult rv;
1946 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
1947 NS_ENSURE_SUCCESS(rv, rv);
1949 nsRefPtr<DOMRect> rect = new DOMRect(window);
1950 nsIFrame* frame = content->GetPrimaryFrame();
1952 if (frame) {
1953 nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
1954 nsLayoutUtils::GetContainingBlockForClientRect(frame),
1955 nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
1956 rect->SetLayoutRect(r);
1959 rect.forget(aResult);
1960 return NS_OK;
1963 NS_IMETHODIMP
1964 nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
1966 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1968 nsIDocument* doc = GetDocument();
1969 NS_ENSURE_STATE(doc);
1971 nsRect bounds(0, 0, 0, 0);
1972 nsIPresShell* presShell = doc->GetShell();
1973 if (presShell) {
1974 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
1975 if (sf) {
1976 bounds = sf->GetScrollRange();
1977 bounds.width += sf->GetScrollPortRect().width;
1978 bounds.height += sf->GetScrollPortRect().height;
1979 } else if (presShell->GetRootFrame()) {
1980 bounds = presShell->GetRootFrame()->GetRect();
1984 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
1985 nsRefPtr<DOMRect> rect = new DOMRect(window);
1986 rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x),
1987 nsPresContext::AppUnitsToFloatCSSPixels(bounds.y),
1988 nsPresContext::AppUnitsToFloatCSSPixels(bounds.width),
1989 nsPresContext::AppUnitsToFloatCSSPixels(bounds.height));
1990 rect.forget(aResult);
1991 return NS_OK;
1994 NS_IMETHODIMP
1995 nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
1997 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
1999 NS_ENSURE_ARG_POINTER(aState);
2001 nsCOMPtr<nsIWidget> widget = GetWidget();
2002 if (!widget)
2003 return NS_ERROR_FAILURE;
2005 // Open state should not be available when IME is not enabled.
2006 InputContext context = widget->GetInputContext();
2007 if (context.mIMEState.mEnabled != IMEState::ENABLED) {
2008 return NS_ERROR_NOT_AVAILABLE;
2011 if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
2012 return NS_ERROR_NOT_IMPLEMENTED;
2014 *aState = (context.mIMEState.mOpen == IMEState::OPEN);
2015 return NS_OK;
2018 NS_IMETHODIMP
2019 nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
2021 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2023 NS_ENSURE_ARG_POINTER(aState);
2025 nsCOMPtr<nsIWidget> widget = GetWidget();
2026 if (!widget)
2027 return NS_ERROR_FAILURE;
2029 InputContext context = widget->GetInputContext();
2030 *aState = static_cast<uint32_t>(context.mIMEState.mEnabled);
2031 return NS_OK;
2034 NS_IMETHODIMP
2035 nsDOMWindowUtils::GetFocusedInputType(char** aType)
2037 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2039 NS_ENSURE_ARG_POINTER(aType);
2041 nsCOMPtr<nsIWidget> widget = GetWidget();
2042 if (!widget) {
2043 return NS_ERROR_FAILURE;
2046 InputContext context = widget->GetInputContext();
2047 *aType = ToNewCString(context.mHTMLInputType);
2048 return NS_OK;
2051 NS_IMETHODIMP
2052 nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
2053 nsIDOMElement** aResult)
2055 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2057 nsRefPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aID);
2058 return content ? CallQueryInterface(content, aResult) : NS_OK;
2061 NS_IMETHODIMP
2062 nsDOMWindowUtils::GetViewId(nsIDOMElement* aElement, nsViewID* aResult)
2064 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
2065 if (content && nsLayoutUtils::FindIDFor(content, aResult)) {
2066 return NS_OK;
2068 return NS_ERROR_NOT_AVAILABLE;
2071 NS_IMETHODIMP
2072 nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
2074 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2075 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
2076 return window->GetDevicePixelRatio(aScreenPixels);
2079 NS_IMETHODIMP
2080 nsDOMWindowUtils::GetFullZoom(float* aFullZoom)
2082 *aFullZoom = 1.0f;
2084 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2086 nsPresContext* presContext = GetPresContext();
2087 if (!presContext) {
2088 return NS_OK;
2091 *aFullZoom = presContext->DeviceContext()->GetFullZoom();
2093 return NS_OK;
2096 NS_IMETHODIMP
2097 nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
2098 nsIDOMEvent* aEvent,
2099 bool aTrusted,
2100 bool* aRetVal)
2102 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2104 NS_ENSURE_STATE(aEvent);
2105 aEvent->SetTrusted(aTrusted);
2106 WidgetEvent* internalEvent = aEvent->GetInternalNSEvent();
2107 NS_ENSURE_STATE(internalEvent);
2108 nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
2109 NS_ENSURE_STATE(content);
2110 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2111 if (content->OwnerDoc()->GetWindow() != window) {
2112 return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
2114 nsCOMPtr<nsIDocument> targetDoc = content->GetCurrentDoc();
2115 NS_ENSURE_STATE(targetDoc);
2116 nsRefPtr<nsIPresShell> targetShell = targetDoc->GetShell();
2117 NS_ENSURE_STATE(targetShell);
2119 targetDoc->FlushPendingNotifications(Flush_Layout);
2121 nsEventStatus status = nsEventStatus_eIgnore;
2122 targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status);
2123 *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
2124 return NS_OK;
2127 static void
2128 InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr)
2130 if (aPt) {
2131 aEvent.refPoint = *aPt;
2133 aEvent.time = PR_IntervalNow();
2136 NS_IMETHODIMP
2137 nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType,
2138 const nsAString& aData,
2139 const nsAString& aLocale)
2141 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2143 // get the widget to send the event to
2144 nsCOMPtr<nsIWidget> widget = GetWidget();
2145 if (!widget) {
2146 return NS_ERROR_FAILURE;
2149 uint32_t msg;
2150 if (aType.EqualsLiteral("compositionstart")) {
2151 msg = NS_COMPOSITION_START;
2152 } else if (aType.EqualsLiteral("compositionend")) {
2153 // Now we don't support manually dispatching composition end with this
2154 // API. A compositionend is dispatched when this is called with
2155 // compositioncommitasis or compositioncommit automatically. For backward
2156 // compatibility, this shouldn't return error in this case.
2157 NS_WARNING("Don't call nsIDOMWindowUtils.sendCompositionEvent() for "
2158 "compositionend. Instead, use it with compositioncommitasis or "
2159 "compositioncommit. Then, compositionend will be automatically "
2160 "dispatched.");
2161 return NS_OK;
2162 } else if (aType.EqualsLiteral("compositionupdate")) {
2163 // Now we don't support manually dispatching composition update with this
2164 // API. A compositionupdate is dispatched when a DOM text event modifies
2165 // composition string automatically. For backward compatibility, this
2166 // shouldn't return error in this case.
2167 NS_WARNING("Don't call nsIDOMWindowUtils.sendCompositionEvent() for "
2168 "compositionupdate since it's ignored and the event is "
2169 "fired automatically when it's necessary");
2170 return NS_OK;
2171 } else if (aType.EqualsLiteral("compositioncommitasis")) {
2172 msg = NS_COMPOSITION_COMMIT_AS_IS;
2173 } else if (aType.EqualsLiteral("compositioncommit")) {
2174 msg = NS_COMPOSITION_COMMIT;
2175 } else {
2176 return NS_ERROR_FAILURE;
2179 WidgetCompositionEvent compositionEvent(true, msg, widget);
2180 InitEvent(compositionEvent);
2181 if (msg != NS_COMPOSITION_START && msg != NS_COMPOSITION_COMMIT_AS_IS) {
2182 compositionEvent.mData = aData;
2185 compositionEvent.mFlags.mIsSynthesizedForTests = true;
2187 nsEventStatus status;
2188 nsresult rv = widget->DispatchEvent(&compositionEvent, status);
2189 NS_ENSURE_SUCCESS(rv, rv);
2191 return NS_OK;
2194 NS_IMETHODIMP
2195 nsDOMWindowUtils::CreateCompositionStringSynthesizer(
2196 nsICompositionStringSynthesizer** aResult)
2198 NS_ENSURE_ARG_POINTER(aResult);
2199 *aResult = nullptr;
2201 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2203 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2204 NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
2206 NS_ADDREF(*aResult = new CompositionStringSynthesizer(window));
2207 return NS_OK;
2210 NS_IMETHODIMP
2211 nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
2212 uint32_t aOffset, uint32_t aLength,
2213 int32_t aX, int32_t aY,
2214 uint32_t aAdditionalFlags,
2215 nsIQueryContentEventResult **aResult)
2217 *aResult = nullptr;
2219 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2221 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2222 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
2224 nsIDocShell *docShell = window->GetDocShell();
2225 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
2227 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
2228 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
2230 nsPresContext* presContext = presShell->GetPresContext();
2231 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
2233 // get the widget to send the event to
2234 nsCOMPtr<nsIWidget> widget = GetWidget();
2235 if (!widget) {
2236 return NS_ERROR_FAILURE;
2239 if (aType != NS_QUERY_SELECTED_TEXT &&
2240 aType != NS_QUERY_TEXT_CONTENT &&
2241 aType != NS_QUERY_CARET_RECT &&
2242 aType != NS_QUERY_TEXT_RECT &&
2243 aType != NS_QUERY_EDITOR_RECT &&
2244 aType != NS_QUERY_CHARACTER_AT_POINT) {
2245 return NS_ERROR_INVALID_ARG;
2248 nsCOMPtr<nsIWidget> targetWidget = widget;
2249 LayoutDeviceIntPoint pt(aX, aY);
2251 bool useNativeLineBreak =
2252 !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
2254 if (aType == QUERY_CHARACTER_AT_POINT) {
2255 // Looking for the widget at the point.
2256 WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
2257 dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
2258 InitEvent(dummyEvent, &pt);
2259 nsIFrame* popupFrame =
2260 nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
2262 nsIntRect widgetBounds;
2263 nsresult rv = widget->GetClientBounds(widgetBounds);
2264 NS_ENSURE_SUCCESS(rv, rv);
2265 widgetBounds.MoveTo(0, 0);
2267 // There is no popup frame at the point and the point isn't in our widget,
2268 // we cannot process this request.
2269 NS_ENSURE_TRUE(popupFrame ||
2270 widgetBounds.Contains(LayoutDeviceIntPoint::ToUntyped(pt)),
2271 NS_ERROR_FAILURE);
2273 // Fire the event on the widget at the point
2274 if (popupFrame) {
2275 targetWidget = popupFrame->GetNearestWidget();
2279 pt += LayoutDeviceIntPoint::FromUntyped(
2280 widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset());
2282 WidgetQueryContentEvent queryEvent(true, aType, targetWidget);
2283 InitEvent(queryEvent, &pt);
2285 switch (aType) {
2286 case NS_QUERY_TEXT_CONTENT:
2287 queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
2288 break;
2289 case NS_QUERY_CARET_RECT:
2290 queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
2291 break;
2292 case NS_QUERY_TEXT_RECT:
2293 queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak);
2294 break;
2295 default:
2296 queryEvent.mUseNativeLineBreak = useNativeLineBreak;
2297 break;
2300 nsEventStatus status;
2301 nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
2302 NS_ENSURE_SUCCESS(rv, rv);
2304 nsQueryContentEventResult* result = new nsQueryContentEventResult();
2305 NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
2306 result->SetEventResult(widget, queryEvent);
2307 NS_ADDREF(*aResult = result);
2308 return NS_OK;
2311 NS_IMETHODIMP
2312 nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
2313 uint32_t aLength,
2314 uint32_t aAdditionalFlags,
2315 bool *aResult)
2317 *aResult = false;
2319 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2321 // get the widget to send the event to
2322 nsCOMPtr<nsIWidget> widget = GetWidget();
2323 if (!widget) {
2324 return NS_ERROR_FAILURE;
2327 WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
2328 InitEvent(selectionEvent);
2330 selectionEvent.mOffset = aOffset;
2331 selectionEvent.mLength = aLength;
2332 selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
2333 selectionEvent.mUseNativeLineBreak =
2334 !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
2336 nsEventStatus status;
2337 nsresult rv = widget->DispatchEvent(&selectionEvent, status);
2338 NS_ENSURE_SUCCESS(rv, rv);
2340 *aResult = selectionEvent.mSucceeded;
2341 return NS_OK;
2344 NS_IMETHODIMP
2345 nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
2346 nsITransferable * aTransferable)
2348 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2350 // get the widget to send the event to
2351 nsCOMPtr<nsIWidget> widget = GetWidget();
2352 if (!widget)
2353 return NS_ERROR_FAILURE;
2355 int32_t msg;
2356 if (aType.EqualsLiteral("cut"))
2357 msg = NS_CONTENT_COMMAND_CUT;
2358 else if (aType.EqualsLiteral("copy"))
2359 msg = NS_CONTENT_COMMAND_COPY;
2360 else if (aType.EqualsLiteral("paste"))
2361 msg = NS_CONTENT_COMMAND_PASTE;
2362 else if (aType.EqualsLiteral("delete"))
2363 msg = NS_CONTENT_COMMAND_DELETE;
2364 else if (aType.EqualsLiteral("undo"))
2365 msg = NS_CONTENT_COMMAND_UNDO;
2366 else if (aType.EqualsLiteral("redo"))
2367 msg = NS_CONTENT_COMMAND_REDO;
2368 else if (aType.EqualsLiteral("pasteTransferable"))
2369 msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
2370 else
2371 return NS_ERROR_FAILURE;
2373 WidgetContentCommandEvent event(true, msg, widget);
2374 if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
2375 event.mTransferable = aTransferable;
2378 nsEventStatus status;
2379 return widget->DispatchEvent(&event, status);
2382 NS_IMETHODIMP
2383 nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
2384 char** aName)
2386 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2388 // Our argument must be a non-null object.
2389 if (aObject.isPrimitive()) {
2390 return NS_ERROR_XPC_BAD_CONVERT_JS;
2393 *aName = NS_strdup(JS_GetClass(aObject.toObjectOrNull())->name);
2394 NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
2395 return NS_OK;
2398 NS_IMETHODIMP
2399 nsDOMWindowUtils::GetVisitedDependentComputedStyle(
2400 nsIDOMElement *aElement, const nsAString& aPseudoElement,
2401 const nsAString& aPropertyName, nsAString& aResult)
2403 aResult.Truncate();
2405 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2407 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2408 NS_ENSURE_STATE(window);
2410 nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
2411 nsresult rv =
2412 window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
2413 NS_ENSURE_SUCCESS(rv, rv);
2415 static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
2416 rv = decl->GetPropertyValue(aPropertyName, aResult);
2417 static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
2419 return rv;
2422 NS_IMETHODIMP
2423 nsDOMWindowUtils::EnterModalState()
2425 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2427 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2428 NS_ENSURE_STATE(window);
2430 window->EnterModalState();
2431 return NS_OK;
2434 NS_IMETHODIMP
2435 nsDOMWindowUtils::LeaveModalState()
2437 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2439 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2440 NS_ENSURE_STATE(window);
2442 window->LeaveModalState();
2443 return NS_OK;
2446 NS_IMETHODIMP
2447 nsDOMWindowUtils::IsInModalState(bool *retval)
2449 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2451 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2452 NS_ENSURE_STATE(window);
2454 *retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
2455 return NS_OK;
2458 NS_IMETHODIMP
2459 nsDOMWindowUtils::GetParent(JS::Handle<JS::Value> aObject,
2460 JSContext* aCx,
2461 JS::MutableHandle<JS::Value> aParent)
2463 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2465 // First argument must be an object.
2466 if (aObject.isPrimitive()) {
2467 return NS_ERROR_XPC_BAD_CONVERT_JS;
2470 JS::Rooted<JSObject*> parent(aCx, JS_GetParent(&aObject.toObject()));
2472 // Outerize if necessary.
2473 if (parent) {
2474 if (js::ObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
2475 parent = outerize(aCx, parent);
2479 aParent.setObject(*parent);
2480 return NS_OK;
2483 NS_IMETHODIMP
2484 nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
2486 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2488 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2489 NS_ENSURE_STATE(window);
2491 NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
2492 *aWindowID = window->WindowID();
2493 return NS_OK;
2496 NS_IMETHODIMP
2497 nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID)
2499 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2501 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2502 NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
2504 NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
2505 nsGlobalWindow* inner =
2506 static_cast<nsGlobalWindow*>(window.get())->GetCurrentInnerWindowInternal();
2507 if (!inner) {
2508 return NS_ERROR_NOT_AVAILABLE;
2510 *aWindowID = inner->WindowID();
2511 return NS_OK;
2514 NS_IMETHODIMP
2515 nsDOMWindowUtils::SuspendTimeouts()
2517 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2519 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2520 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
2522 window->SuspendTimeouts();
2524 return NS_OK;
2527 NS_IMETHODIMP
2528 nsDOMWindowUtils::ResumeTimeouts()
2530 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2532 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2533 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
2535 window->ResumeTimeouts();
2537 return NS_OK;
2540 NS_IMETHODIMP
2541 nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
2543 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2545 nsCOMPtr<nsIWidget> widget = GetWidget();
2546 if (!widget)
2547 return NS_ERROR_FAILURE;
2549 LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT);
2550 if (!mgr)
2551 return NS_ERROR_FAILURE;
2553 mgr->GetBackendName(aType);
2555 return NS_OK;
2558 NS_IMETHODIMP
2559 nsDOMWindowUtils::GetLayerManagerRemote(bool* retval)
2561 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2563 nsCOMPtr<nsIWidget> widget = GetWidget();
2564 if (!widget)
2565 return NS_ERROR_FAILURE;
2567 LayerManager *mgr = widget->GetLayerManager();
2568 if (!mgr)
2569 return NS_ERROR_FAILURE;
2571 *retval = !!mgr->AsShadowForwarder();
2572 return NS_OK;
2575 NS_IMETHODIMP
2576 nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
2578 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2580 NS_ENSURE_ARG_POINTER(startIndex);
2582 nsCOMPtr<nsIWidget> widget = GetWidget();
2583 if (!widget)
2584 return NS_ERROR_FAILURE;
2586 LayerManager *mgr = widget->GetLayerManager();
2587 if (!mgr)
2588 return NS_ERROR_FAILURE;
2590 const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
2591 const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
2592 uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
2593 bufferSize = std::min(bufferSize, kRecordingMaxSize);
2594 bufferSize = std::max(bufferSize, kRecordingMinSize);
2595 *startIndex = mgr->StartFrameTimeRecording(bufferSize);
2597 return NS_OK;
2600 NS_IMETHODIMP
2601 nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex,
2602 uint32_t *frameCount,
2603 float **frameIntervals)
2605 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2607 NS_ENSURE_ARG_POINTER(frameCount);
2608 NS_ENSURE_ARG_POINTER(frameIntervals);
2610 nsCOMPtr<nsIWidget> widget = GetWidget();
2611 if (!widget)
2612 return NS_ERROR_FAILURE;
2614 LayerManager *mgr = widget->GetLayerManager();
2615 if (!mgr)
2616 return NS_ERROR_FAILURE;
2618 nsTArray<float> tmpFrameIntervals;
2619 mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
2620 *frameCount = tmpFrameIntervals.Length();
2622 *frameIntervals = (float*)nsMemory::Alloc(*frameCount * sizeof(float));
2624 /* copy over the frame intervals and paint times into the arrays we just allocated */
2625 for (uint32_t i = 0; i < *frameCount; i++) {
2626 (*frameIntervals)[i] = tmpFrameIntervals[i];
2629 return NS_OK;
2632 NS_IMETHODIMP
2633 nsDOMWindowUtils::BeginTabSwitch()
2635 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2637 nsCOMPtr<nsIWidget> widget = GetWidget();
2638 if (!widget)
2639 return NS_ERROR_FAILURE;
2641 LayerManager *mgr = widget->GetLayerManager();
2642 if (!mgr)
2643 return NS_ERROR_FAILURE;
2645 mgr->BeginTabSwitch();
2647 return NS_OK;
2650 static bool
2651 ComputeAnimationValue(nsCSSProperty aProperty,
2652 Element* aElement,
2653 const nsAString& aInput,
2654 StyleAnimationValue& aOutput)
2657 if (!StyleAnimationValue::ComputeValue(aProperty, aElement, aInput,
2658 false, aOutput)) {
2659 return false;
2662 // This matches TransExtractComputedValue in nsTransitionManager.cpp.
2663 if (aProperty == eCSSProperty_visibility) {
2664 MOZ_ASSERT(aOutput.GetUnit() == StyleAnimationValue::eUnit_Enumerated,
2665 "unexpected unit");
2666 aOutput.SetIntValue(aOutput.GetIntValue(),
2667 StyleAnimationValue::eUnit_Visibility);
2670 return true;
2673 NS_IMETHODIMP
2674 nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
2676 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2678 // Before we advance the time, we should trigger any animations that are
2679 // waiting to start. This is because there are many tests that call this
2680 // which expect animations to start immediately. Ideally, we should make
2681 // all these tests do an asynchronous wait on the corresponding animation
2682 // player's 'ready' promise before continuing. Then we could remove the
2683 // special handling here and the code path followed when testing would
2684 // more closely match the code path during regular operation. Filed as
2685 // bug 1112957.
2686 nsCOMPtr<nsIDocument> doc = GetDocument();
2687 if (doc) {
2688 PendingPlayerTracker* tracker = doc->GetPendingPlayerTracker();
2689 if (tracker) {
2690 tracker->StartPendingPlayersNow();
2694 nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
2695 driver->AdvanceTimeAndRefresh(aMilliseconds);
2697 RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
2698 if (transaction && transaction->IPCOpen()) {
2699 transaction->SendSetTestSampleTime(driver->MostRecentRefresh());
2702 return NS_OK;
2705 NS_IMETHODIMP
2706 nsDOMWindowUtils::RestoreNormalRefresh()
2708 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2710 // Kick the compositor out of test mode before the refresh driver, so that
2711 // the refresh driver doesn't send an update that gets ignored by the
2712 // compositor.
2713 RefPtr<LayerTransactionChild> transaction = GetLayerTransaction();
2714 if (transaction && transaction->IPCOpen()) {
2715 transaction->SendLeaveTestMode();
2718 nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
2719 driver->RestoreNormalRefresh();
2721 return NS_OK;
2724 NS_IMETHODIMP
2725 nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult)
2727 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2729 nsPresContext* pc = GetPresContext();
2730 *aResult =
2731 pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
2733 return NS_OK;
2736 NS_IMETHODIMP
2737 nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
2738 int32_t aX, int32_t aY)
2740 nsCOMPtr<Element> element = do_QueryInterface(aNode);
2741 if (!element) {
2742 return NS_ERROR_INVALID_ARG;
2744 FrameMetrics::ViewID viewId;
2745 if (!nsLayoutUtils::FindIDFor(element, &viewId)) {
2746 return NS_ERROR_UNEXPECTED;
2748 nsIWidget* widget = GetWidget();
2749 if (!widget) {
2750 return NS_ERROR_FAILURE;
2752 LayerManager* manager = widget->GetLayerManager();
2753 if (!manager) {
2754 return NS_ERROR_FAILURE;
2756 ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
2757 if (!forwarder || !forwarder->HasShadowManager()) {
2758 return NS_ERROR_UNEXPECTED;
2760 forwarder->GetShadowManager()->SendSetAsyncScrollOffset(viewId, aX, aY);
2761 return NS_OK;
2764 NS_IMETHODIMP
2765 nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
2766 const nsAString& aProperty,
2767 const nsAString& aValue1,
2768 const nsAString& aValue2,
2769 double* aResult)
2771 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2773 nsresult rv;
2774 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
2775 NS_ENSURE_SUCCESS(rv, rv);
2777 // Convert direction-dependent properties as appropriate, e.g.,
2778 // border-left to border-left-value.
2779 nsCSSProperty property =
2780 nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState);
2781 if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
2782 nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
2783 if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
2784 nsCSSProps::OtherNameFor(subprop0) == property) {
2785 property = subprop0;
2786 } else {
2787 property = eCSSProperty_UNKNOWN;
2791 NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
2792 !nsCSSProps::IsShorthand(property),
2793 "should not have shorthand");
2795 StyleAnimationValue v1, v2;
2796 if (property == eCSSProperty_UNKNOWN ||
2797 !ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
2798 !ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
2799 return NS_ERROR_ILLEGAL_VALUE;
2802 if (!StyleAnimationValue::ComputeDistance(property, v1, v2, *aResult)) {
2803 return NS_ERROR_FAILURE;
2806 return NS_OK;
2809 nsresult
2810 nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
2811 uint32_t aFlags,
2812 nscolor aBackgroundColor,
2813 gfxContext* aThebesContext)
2815 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2817 nsCOMPtr<nsIDocument> doc = GetDocument();
2818 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
2820 // Get Primary Shell
2821 nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
2822 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
2824 // Render Document
2825 return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
2828 NS_IMETHODIMP
2829 nsDOMWindowUtils::GetCursorType(int16_t *aCursor)
2831 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2833 NS_ENSURE_ARG_POINTER(aCursor);
2835 nsIDocument* doc = GetDocument();
2836 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
2838 bool isSameDoc = false;
2839 do {
2840 if (EventStateManager::sMouseOverDocument == doc) {
2841 isSameDoc = true;
2842 break;
2844 } while ((doc = doc->GetParentDocument()));
2846 if (!isSameDoc) {
2847 *aCursor = eCursor_none;
2848 return NS_OK;
2851 nsCOMPtr<nsIWidget> widget = GetWidget();
2852 if (!widget)
2853 return NS_ERROR_FAILURE;
2855 // fetch cursor value from window's widget
2856 *aCursor = widget->GetCursor();
2858 return NS_OK;
2861 NS_IMETHODIMP
2862 nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
2864 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2866 nsCOMPtr<nsIWidget> widget = GetWidget();
2867 if (!widget)
2868 return NS_ERROR_FAILURE;
2870 *aDPI = widget->GetDPI();
2872 return NS_OK;
2876 NS_IMETHODIMP
2877 nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID,
2878 nsIDOMWindow** aWindow)
2880 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2882 // XXX This method is deprecated. See bug 865664.
2883 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
2884 NS_LITERAL_CSTRING("DOM"),
2885 nsContentUtils::GetDocumentFromCaller(),
2886 nsContentUtils::eDOM_PROPERTIES,
2887 "GetWindowWithOuterIdWarning");
2889 *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
2890 NS_IF_ADDREF(*aWindow);
2891 return NS_OK;
2894 NS_IMETHODIMP
2895 nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult)
2897 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2899 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2900 NS_ENSURE_STATE(window);
2902 nsCOMPtr<nsIDOMElement> element =
2903 do_QueryInterface(window->GetFrameElementInternal());
2905 element.forget(aResult);
2906 return NS_OK;
2909 NS_IMETHODIMP
2910 nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
2911 nsIDOMFile **aDOMFile)
2913 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2915 if (!aFile) {
2916 return NS_ERROR_FAILURE;
2919 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
2920 NS_ENSURE_STATE(window);
2922 nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
2923 if (!innerWindow) {
2924 return NS_ERROR_FAILURE;
2927 nsRefPtr<File> file = File::CreateFromFile(innerWindow, aFile);
2928 file.forget(aDOMFile);
2929 return NS_OK;
2932 #ifdef DEBUG
2933 static bool
2934 CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
2936 gfx::Matrix transform;
2937 if (!aLayer->GetTransform().Is2D(&transform) ||
2938 transform.HasNonIntegerTranslation())
2939 return false;
2940 transform.NudgeToIntegers();
2941 nsIntPoint offset = aOffset + nsIntPoint(transform._31, transform._32);
2943 Layer* child = aLayer->GetFirstChild();
2944 if (child) {
2945 while (child) {
2946 if (!CheckLeafLayers(child, offset, aCoveredRegion))
2947 return false;
2948 child = child->GetNextSibling();
2950 } else {
2951 nsIntRegion rgn = aLayer->GetVisibleRegion();
2952 rgn.MoveBy(offset);
2953 nsIntRegion tmp;
2954 tmp.And(rgn, *aCoveredRegion);
2955 if (!tmp.IsEmpty())
2956 return false;
2957 aCoveredRegion->Or(*aCoveredRegion, rgn);
2960 return true;
2962 #endif
2964 NS_IMETHODIMP
2965 nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult)
2967 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
2969 *aResult = true;
2970 #ifdef DEBUG
2971 nsIWidget* widget = GetWidget();
2972 if (!widget)
2973 return NS_ERROR_FAILURE;
2974 LayerManager* manager = widget->GetLayerManager();
2975 if (!manager)
2976 return NS_ERROR_FAILURE;
2977 nsPresContext* presContext = GetPresContext();
2978 if (!presContext)
2979 return NS_ERROR_FAILURE;
2980 Layer* root = manager->GetRoot();
2981 if (!root)
2982 return NS_ERROR_FAILURE;
2984 nsIntPoint offset(0, 0);
2985 nsIntRegion coveredRegion;
2986 if (!CheckLeafLayers(root, offset, &coveredRegion)) {
2987 *aResult = false;
2989 if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
2990 *aResult = false;
2992 #endif
2993 return NS_OK;
2996 NS_IMETHODIMP
2997 nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
2999 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3001 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3002 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3004 nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
3005 *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
3006 return NS_OK;
3009 NS_IMETHODIMP
3010 nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
3012 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3014 if (!aElement) {
3015 return NS_ERROR_INVALID_ARG;
3018 nsresult rv;
3019 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
3020 NS_ENSURE_SUCCESS(rv, rv);
3022 nsIFrame* frame = content->GetPrimaryFrame();
3024 if (!frame) {
3025 *aResult = false;
3026 return NS_OK;
3029 // Get the outermost frame for the content node, so that we can test
3030 // canvasframe invalidations by observing the documentElement.
3031 for (;;) {
3032 nsIFrame* parentFrame = frame->GetParent();
3033 if (parentFrame && parentFrame->GetContent() == content) {
3034 frame = parentFrame;
3035 } else {
3036 break;
3040 *aResult = frame->CheckAndClearPaintedState();
3041 return NS_OK;
3044 NS_IMETHODIMP
3045 nsDOMWindowUtils::EnableDialogs()
3047 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3049 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3050 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3052 static_cast<nsGlobalWindow*>(window.get())->EnableDialogs();
3053 return NS_OK;
3056 NS_IMETHODIMP
3057 nsDOMWindowUtils::DisableDialogs()
3059 if (!nsContentUtils::IsCallerChrome()) {
3060 return NS_ERROR_DOM_SECURITY_ERR;
3063 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3064 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3066 static_cast<nsGlobalWindow*>(window.get())->DisableDialogs();
3067 return NS_OK;
3070 NS_IMETHODIMP
3071 nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
3073 if (!nsContentUtils::IsCallerChrome()) {
3074 return NS_ERROR_DOM_SECURITY_ERR;
3077 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3078 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3080 *aResult = static_cast<nsGlobalWindow*>(window.get())->AreDialogsEnabled();
3081 return NS_OK;
3084 NS_IMETHODIMP
3085 nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
3086 int64_t* _retval)
3088 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3090 if (aFile.isPrimitive()) {
3091 *_retval = -1;
3092 return NS_OK;
3095 JSObject* obj = aFile.toObjectOrNull();
3097 indexedDB::IDBMutableFile* mutableFile = nullptr;
3098 if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, obj, mutableFile))) {
3099 *_retval = mutableFile->GetFileId();
3100 return NS_OK;
3103 nsISupports* nativeObj =
3104 nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
3106 nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
3107 if (blob) {
3108 *_retval = blob->GetFileId();
3109 return NS_OK;
3112 *_retval = -1;
3113 return NS_OK;
3116 NS_IMETHODIMP
3117 nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx,
3118 nsAString& _retval)
3120 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3122 if (aFile.isPrimitive()) {
3123 _retval.Truncate();
3124 return NS_OK;
3127 JSObject* obj = aFile.toObjectOrNull();
3129 nsISupports* nativeObj =
3130 nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
3132 nsCOMPtr<nsIDOMFile> file = do_QueryInterface(nativeObj);
3133 if (file) {
3134 nsString filePath;
3135 nsresult rv = file->GetMozFullPathInternal(filePath);
3136 if (NS_WARN_IF(NS_FAILED(rv))) {
3137 return rv;
3140 _retval = filePath;
3141 return NS_OK;
3144 _retval.Truncate();
3145 return NS_OK;
3148 NS_IMETHODIMP
3149 nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
3150 JS::Handle<JS::Value> aOptions,
3151 int32_t* aRefCnt, int32_t* aDBRefCnt,
3152 int32_t* aSliceRefCnt, JSContext* aCx,
3153 bool* aResult)
3155 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3157 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3158 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3160 nsCString origin;
3161 nsresult rv =
3162 quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr,
3163 nullptr);
3164 NS_ENSURE_SUCCESS(rv, rv);
3166 IDBOpenDBOptions options;
3167 JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
3168 if (!options.Init(aCx, optionsVal)) {
3169 return NS_ERROR_TYPE_ERR;
3172 quota::PersistenceType persistenceType =
3173 quota::PersistenceTypeFromStorage(options.mStorage);
3175 nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
3176 indexedDB::IndexedDatabaseManager::Get();
3178 if (mgr) {
3179 rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
3180 aId, aRefCnt, aDBRefCnt, aSliceRefCnt,
3181 aResult);
3182 NS_ENSURE_SUCCESS(rv, rv);
3184 else {
3185 *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;
3186 *aResult = false;
3189 return NS_OK;
3192 NS_IMETHODIMP
3193 nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
3195 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3197 *aResult = JS::IsIncrementalGCEnabled(JS_GetRuntime(cx));
3198 return NS_OK;
3201 NS_IMETHODIMP
3202 nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
3204 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3206 js::StartPCCountProfiling(cx);
3207 return NS_OK;
3210 NS_IMETHODIMP
3211 nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
3213 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3215 js::StopPCCountProfiling(cx);
3216 return NS_OK;
3219 NS_IMETHODIMP
3220 nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
3222 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3224 js::PurgePCCounts(cx);
3225 return NS_OK;
3228 NS_IMETHODIMP
3229 nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
3231 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3233 *result = js::GetPCCountScriptCount(cx);
3234 return NS_OK;
3237 NS_IMETHODIMP
3238 nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result)
3240 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3242 JSString *text = js::GetPCCountScriptSummary(cx, script);
3243 if (!text)
3244 return NS_ERROR_FAILURE;
3246 if (!AssignJSString(cx, result, text))
3247 return NS_ERROR_FAILURE;
3249 return NS_OK;
3252 NS_IMETHODIMP
3253 nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result)
3255 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3257 JSString *text = js::GetPCCountScriptContents(cx, script);
3258 if (!text)
3259 return NS_ERROR_FAILURE;
3261 if (!AssignJSString(cx, result, text))
3262 return NS_ERROR_FAILURE;
3264 return NS_OK;
3267 NS_IMETHODIMP
3268 nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
3270 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3272 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3273 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
3274 nsIDocShell *docShell = window->GetDocShell();
3275 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
3277 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
3278 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
3280 *aPaintingSuppressed = presShell->IsPaintingSuppressed();
3281 return NS_OK;
3284 NS_IMETHODIMP
3285 nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
3287 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3289 nsCOMPtr<nsIDocument> doc = GetDocument();
3290 NS_ENSURE_STATE(doc);
3292 nsTArray<nsIObjectLoadingContent*> plugins;
3293 doc->GetPlugins(plugins);
3295 JS::Rooted<JSObject*> jsPlugins(cx);
3296 nsresult rv = nsTArrayToJSArray(cx, plugins, &jsPlugins);
3297 NS_ENSURE_SUCCESS(rv, rv);
3299 aPlugins.setObject(*jsPlugins);
3300 return NS_OK;
3303 static void
3304 MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
3306 if (aPresContext) {
3307 nsIPresShell* presShell = aPresContext->GetPresShell();
3308 bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
3309 presShell->NotifyFontSizeInflationEnabledIsDirty();
3310 bool changed = false;
3311 if (presShell && presShell->FontSizeInflationEnabled() &&
3312 presShell->FontSizeInflationMinTwips() != 0) {
3313 aPresContext->ScreenWidthInchesForFontInflation(&changed);
3316 changed = changed ||
3317 (fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
3318 if (changed) {
3319 nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
3320 if (docShell) {
3321 nsCOMPtr<nsIContentViewer> cv;
3322 docShell->GetContentViewer(getter_AddRefs(cv));
3323 if (cv) {
3324 nsTArray<nsCOMPtr<nsIContentViewer> > array;
3325 cv->AppendSubtree(array);
3326 for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
3327 nsCOMPtr<nsIPresShell> shell;
3328 nsCOMPtr<nsIContentViewer> cv = array[i];
3329 cv->GetPresShell(getter_AddRefs(shell));
3330 if (shell) {
3331 nsIFrame *rootFrame = shell->GetRootFrame();
3332 if (rootFrame) {
3333 shell->FrameNeedsReflow(rootFrame,
3334 nsIPresShell::eStyleChange,
3335 NS_FRAME_IS_DIRTY);
3345 NS_IMETHODIMP
3346 nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
3348 if (!nsContentUtils::IsCallerChrome()) {
3349 return NS_ERROR_DOM_SECURITY_ERR;
3352 if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
3353 return NS_ERROR_ILLEGAL_VALUE;
3356 nsIPresShell* presShell = GetPresShell();
3357 if (!presShell) {
3358 return NS_ERROR_FAILURE;
3361 presShell->SetScrollPositionClampingScrollPortSize(
3362 nsPresContext::CSSPixelsToAppUnits(aWidth),
3363 nsPresContext::CSSPixelsToAppUnits(aHeight));
3365 // When the "font.size.inflation.minTwips" preference is set, the
3366 // layout depends on the size of the screen. Since when the size
3367 // of the screen changes, the scroll position clamping scroll port
3368 // size also changes, we hook in the needed updates here rather
3369 // than adding a separate notification just for this change.
3370 nsPresContext* presContext = GetPresContext();
3371 MaybeReflowForInflationScreenWidthChange(presContext);
3373 return NS_OK;
3376 NS_IMETHODIMP
3377 nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight,
3378 float aBottom, float aLeft)
3380 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3382 if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) {
3383 return NS_ERROR_ILLEGAL_VALUE;
3386 nsIPresShell* presShell = GetPresShell();
3387 if (!presShell) {
3388 return NS_ERROR_FAILURE;
3391 nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop),
3392 nsPresContext::CSSPixelsToAppUnits(aRight),
3393 nsPresContext::CSSPixelsToAppUnits(aBottom),
3394 nsPresContext::CSSPixelsToAppUnits(aLeft));
3395 presShell->SetContentDocumentFixedPositionMargins(margins);
3397 return NS_OK;
3400 nsresult
3401 nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
3402 const nsAString& aNewOrigin)
3404 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3406 nsCOMPtr<nsIDocument> doc = GetDocument();
3407 NS_ENSURE_STATE(doc);
3409 doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin);
3410 return NS_OK;
3413 nsresult
3414 nsDOMWindowUtils::RemoteFrameFullscreenReverted()
3416 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3418 nsCOMPtr<nsIDocument> doc = GetDocument();
3419 NS_ENSURE_STATE(doc);
3421 doc->RemoteFrameFullscreenReverted();
3422 return NS_OK;
3425 nsresult
3426 nsDOMWindowUtils::ExitFullscreen()
3428 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3430 nsIDocument::ExitFullscreen(nullptr, /* async */ false);
3431 return NS_OK;
3434 NS_IMETHODIMP
3435 nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
3436 bool *_retval)
3438 *_retval = false;
3439 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3441 nsSelectionAmount amount;
3442 switch (aSelectBehavior) {
3443 case nsIDOMWindowUtils::SELECT_CHARACTER:
3444 amount = eSelectCharacter;
3445 break;
3446 case nsIDOMWindowUtils::SELECT_CLUSTER:
3447 amount = eSelectCluster;
3448 break;
3449 case nsIDOMWindowUtils::SELECT_WORD:
3450 amount = eSelectWord;
3451 break;
3452 case nsIDOMWindowUtils::SELECT_LINE:
3453 amount = eSelectLine;
3454 break;
3455 case nsIDOMWindowUtils::SELECT_BEGINLINE:
3456 amount = eSelectBeginLine;
3457 break;
3458 case nsIDOMWindowUtils::SELECT_ENDLINE:
3459 amount = eSelectEndLine;
3460 break;
3461 case nsIDOMWindowUtils::SELECT_PARAGRAPH:
3462 amount = eSelectParagraph;
3463 break;
3464 case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
3465 amount = eSelectWordNoSpace;
3466 break;
3467 default:
3468 return NS_ERROR_INVALID_ARG;
3471 nsIPresShell* presShell = GetPresShell();
3472 if (!presShell) {
3473 return NS_ERROR_UNEXPECTED;
3476 // The root frame for this content window
3477 nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
3478 if (!rootFrame) {
3479 return NS_ERROR_UNEXPECTED;
3482 // Get the target frame at the client coordinates passed to us
3483 nsPoint offset;
3484 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
3485 nsIntPoint pt = LayoutDeviceIntPoint::ToUntyped(
3486 ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()));
3487 nsPoint ptInRoot =
3488 nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
3489 nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
3490 // This can happen if the page hasn't loaded yet or if the point
3491 // is outside the frame.
3492 if (!targetFrame) {
3493 return NS_ERROR_INVALID_ARG;
3496 // Convert point to coordinates relative to the target frame, which is
3497 // what targetFrame's SelectByTypeAtPoint expects.
3498 nsPoint relPoint =
3499 nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
3501 nsresult rv =
3502 static_cast<nsFrame*>(targetFrame)->
3503 SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
3504 nsFrame::SELECT_ACCUMULATE);
3505 *_retval = !NS_FAILED(rv);
3506 return NS_OK;
3509 static nsIDocument::additionalSheetType
3510 convertSheetType(uint32_t aSheetType)
3512 switch(aSheetType) {
3513 case nsDOMWindowUtils::AGENT_SHEET:
3514 return nsIDocument::eAgentSheet;
3515 case nsDOMWindowUtils::USER_SHEET:
3516 return nsIDocument::eUserSheet;
3517 case nsDOMWindowUtils::AUTHOR_SHEET:
3518 return nsIDocument::eAuthorSheet;
3519 default:
3520 NS_ASSERTION(false, "wrong type");
3521 // we must return something although this should never happen
3522 return nsIDocument::SheetTypeCount;
3526 NS_IMETHODIMP
3527 nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
3529 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3531 NS_ENSURE_ARG_POINTER(aSheetURI);
3532 NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
3533 aSheetType == USER_SHEET ||
3534 aSheetType == AUTHOR_SHEET);
3536 nsCOMPtr<nsIDocument> doc = GetDocument();
3537 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
3539 nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
3541 return doc->LoadAdditionalStyleSheet(type, aSheetURI);
3544 NS_IMETHODIMP
3545 nsDOMWindowUtils::LoadSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType)
3547 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3549 nsCOMPtr<nsIURI> uri;
3550 nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI);
3551 NS_ENSURE_SUCCESS(rv, rv);
3553 return LoadSheet(uri, aSheetType);
3556 NS_IMETHODIMP
3557 nsDOMWindowUtils::AddSheet(nsIDOMStyleSheet *aSheet, uint32_t aSheetType)
3559 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3561 NS_ENSURE_ARG_POINTER(aSheet);
3562 NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
3563 aSheetType == USER_SHEET ||
3564 aSheetType == AUTHOR_SHEET);
3566 nsCOMPtr<nsIDocument> doc = GetDocument();
3567 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
3569 nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
3570 nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
3571 NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
3572 if (sheet->GetOwningDocument()) {
3573 return NS_ERROR_INVALID_ARG;
3575 return doc->AddAdditionalStyleSheet(type, sheet);
3578 NS_IMETHODIMP
3579 nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
3581 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3583 NS_ENSURE_ARG_POINTER(aSheetURI);
3584 NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
3585 aSheetType == USER_SHEET ||
3586 aSheetType == AUTHOR_SHEET);
3588 nsCOMPtr<nsIDocument> doc = GetDocument();
3589 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
3591 nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
3593 doc->RemoveAdditionalStyleSheet(type, aSheetURI);
3594 return NS_OK;
3597 NS_IMETHODIMP
3598 nsDOMWindowUtils::RemoveSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType)
3600 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3602 nsCOMPtr<nsIURI> uri;
3603 nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI);
3604 NS_ENSURE_SUCCESS(rv, rv);
3606 return RemoveSheet(uri, aSheetType);
3609 NS_IMETHODIMP
3610 nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput)
3612 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3614 *aHandlingUserInput = EventStateManager::IsHandlingUserInput();
3616 return NS_OK;
3619 NS_IMETHODIMP
3620 nsDOMWindowUtils::AllowScriptsToClose()
3622 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3623 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3624 NS_ENSURE_STATE(window);
3625 static_cast<nsGlobalWindow*>(window.get())->AllowScriptsToClose();
3626 return NS_OK;
3629 NS_IMETHODIMP
3630 nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible)
3632 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3634 // this should reflect the "is parent window visible" logic in
3635 // nsWindowWatcher::OpenWindowInternal()
3636 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3637 NS_ENSURE_STATE(window);
3639 nsCOMPtr<nsIWidget> parentWidget;
3640 nsIDocShell *docShell = window->GetDocShell();
3641 if (docShell) {
3642 if (TabChild *tabChild = TabChild::GetFrom(docShell)) {
3643 if (!tabChild->SendIsParentWindowMainWidgetVisible(aIsVisible))
3644 return NS_ERROR_FAILURE;
3645 return NS_OK;
3648 nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
3649 docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
3650 nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
3651 if (parentWindow) {
3652 parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
3655 if (!parentWidget) {
3656 return NS_ERROR_NOT_AVAILABLE;
3659 *aIsVisible = parentWidget->IsVisible();
3660 return NS_OK;
3663 NS_IMETHODIMP
3664 nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal)
3666 *aRetVal = false;
3667 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3668 nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
3669 nsINode* node = n;
3670 while (node) {
3671 if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
3672 nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
3673 if (fc && fc->IsDisabledForEvents(NS_EVENT_NULL)) {
3674 *aRetVal = true;
3675 break;
3678 node = node->GetParentNode();
3681 return NS_OK;
3684 NS_IMETHODIMP
3685 nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing)
3687 nsPresContext* presContext = GetPresContext();
3688 if (presContext) {
3689 presContext->SetPaintFlashing(aPaintFlashing);
3690 // Clear paint flashing colors
3691 nsIPresShell* presShell = GetPresShell();
3692 if (!aPaintFlashing && presShell) {
3693 nsIFrame* rootFrame = presShell->GetRootFrame();
3694 if (rootFrame) {
3695 rootFrame->InvalidateFrameSubtree();
3699 return NS_OK;
3702 NS_IMETHODIMP
3703 nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal)
3705 *aRetVal = false;
3706 nsPresContext* presContext = GetPresContext();
3707 if (presContext) {
3708 *aRetVal = presContext->GetPaintFlashing();
3710 return NS_OK;
3713 NS_IMETHODIMP
3714 nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
3715 nsIDOMEvent* aEvent,
3716 bool* aRetVal)
3718 *aRetVal = false;
3719 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3720 NS_ENSURE_STATE(aTarget && aEvent);
3721 aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
3722 aTarget->DispatchEvent(aEvent, aRetVal);
3723 return NS_OK;
3726 NS_IMETHODIMP
3727 nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable)
3729 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3731 nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
3732 if (!appShell) {
3733 return NS_ERROR_NOT_AVAILABLE;
3736 return appShell->RunInStableState(runnable);
3739 NS_IMETHODIMP
3740 nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable)
3742 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3744 nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
3745 if (!appShell) {
3746 return NS_ERROR_NOT_AVAILABLE;
3749 return appShell->RunBeforeNextEvent(runnable);
3752 NS_IMETHODIMP
3753 nsDOMWindowUtils::RequestCompositorProperty(const nsAString& property,
3754 float* aResult)
3756 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3758 if (nsIWidget* widget = GetWidget()) {
3759 mozilla::layers::LayerManager* manager = widget->GetLayerManager();
3760 if (manager) {
3761 *aResult = manager->RequestProperty(property);
3762 return NS_OK;
3766 return NS_ERROR_NOT_AVAILABLE;
3769 NS_IMETHODIMP
3770 nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
3771 const nsAString& aProperty,
3772 nsAString& aResult)
3774 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3776 nsCOMPtr<Element> element = do_QueryInterface(aElement);
3777 if (!element) {
3778 return NS_ERROR_INVALID_ARG;
3781 nsRefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
3782 nsIFrame* frame = element->GetPrimaryFrame();
3783 if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
3784 if (aProperty.EqualsLiteral("opacity")) {
3785 Layer* layer =
3786 FrameLayerBuilder::GetDedicatedLayer(frame,
3787 nsDisplayItem::TYPE_OPACITY);
3788 if (layer) {
3789 float value;
3790 ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
3791 if (forwarder && forwarder->HasShadowManager()) {
3792 forwarder->GetShadowManager()->SendGetOpacity(
3793 layer->AsShadowableLayer()->GetShadow(), &value);
3794 cssValue = new nsROCSSPrimitiveValue;
3795 cssValue->SetNumber(value);
3798 } else if (aProperty.EqualsLiteral("transform")) {
3799 Layer* layer =
3800 FrameLayerBuilder::GetDedicatedLayer(frame,
3801 nsDisplayItem::TYPE_TRANSFORM);
3802 if (layer) {
3803 ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
3804 if (forwarder && forwarder->HasShadowManager()) {
3805 MaybeTransform transform;
3806 forwarder->GetShadowManager()->SendGetAnimationTransform(
3807 layer->AsShadowableLayer()->GetShadow(), &transform);
3808 if (transform.type() == MaybeTransform::TMatrix4x4) {
3809 gfx3DMatrix matrix = To3DMatrix(transform.get_Matrix4x4());
3810 cssValue = nsComputedDOMStyle::MatrixToCSSValue(matrix);
3817 if (cssValue) {
3818 nsString text;
3819 ErrorResult rv;
3820 cssValue->GetCssText(text, rv);
3821 aResult.Assign(text);
3822 return rv.ErrorCode();
3823 } else {
3824 aResult.Truncate();
3827 return NS_OK;
3830 namespace {
3832 class HandlingUserInputHelper MOZ_FINAL : public nsIJSRAIIHelper
3834 public:
3835 explicit HandlingUserInputHelper(bool aHandlingUserInput);
3837 NS_DECL_ISUPPORTS
3838 NS_DECL_NSIJSRAIIHELPER
3840 private:
3841 ~HandlingUserInputHelper();
3843 bool mHandlingUserInput;
3844 bool mDestructCalled;
3847 NS_IMPL_ISUPPORTS(HandlingUserInputHelper, nsIJSRAIIHelper)
3849 HandlingUserInputHelper::HandlingUserInputHelper(bool aHandlingUserInput)
3850 : mHandlingUserInput(aHandlingUserInput),
3851 mDestructCalled(false)
3853 if (aHandlingUserInput) {
3854 EventStateManager::StartHandlingUserInput();
3858 HandlingUserInputHelper::~HandlingUserInputHelper()
3860 // We assert, but just in case, make sure we notify the ESM.
3861 MOZ_ASSERT(mDestructCalled);
3862 if (!mDestructCalled) {
3863 Destruct();
3867 NS_IMETHODIMP
3868 HandlingUserInputHelper::Destruct()
3870 if (NS_WARN_IF(mDestructCalled)) {
3871 return NS_ERROR_FAILURE;
3874 mDestructCalled = true;
3875 if (mHandlingUserInput) {
3876 EventStateManager::StopHandlingUserInput();
3879 return NS_OK;
3882 } // unnamed namespace
3884 NS_IMETHODIMP
3885 nsDOMWindowUtils::SetHandlingUserInput(bool aHandlingUserInput,
3886 nsIJSRAIIHelper** aHelper)
3888 if (!nsContentUtils::IsCallerChrome()) {
3889 return NS_ERROR_DOM_SECURITY_ERR;
3892 nsRefPtr<HandlingUserInputHelper> helper(
3893 new HandlingUserInputHelper(aHandlingUserInput));
3894 helper.forget(aHelper);
3895 return NS_OK;
3898 NS_IMETHODIMP
3899 nsDOMWindowUtils::GetContentAPZTestData(JSContext* aContext,
3900 JS::MutableHandleValue aOutContentTestData)
3902 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3904 if (nsIWidget* widget = GetWidget()) {
3905 nsRefPtr<LayerManager> lm = widget->GetLayerManager();
3906 if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
3907 ClientLayerManager* clm = static_cast<ClientLayerManager*>(lm.get());
3908 if (!clm->GetAPZTestData().ToJS(aOutContentTestData, aContext)) {
3909 return NS_ERROR_FAILURE;
3914 return NS_OK;
3917 NS_IMETHODIMP
3918 nsDOMWindowUtils::GetCompositorAPZTestData(JSContext* aContext,
3919 JS::MutableHandleValue aOutCompositorTestData)
3921 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3923 if (nsIWidget* widget = GetWidget()) {
3924 nsRefPtr<LayerManager> lm = widget->GetLayerManager();
3925 if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
3926 ClientLayerManager* clm = static_cast<ClientLayerManager*>(lm.get());
3927 APZTestData compositorSideData;
3928 clm->GetCompositorSideAPZTestData(&compositorSideData);
3929 if (!compositorSideData.ToJS(aOutCompositorTestData, aContext)) {
3930 return NS_ERROR_FAILURE;
3935 return NS_OK;
3938 NS_IMETHODIMP
3939 nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
3941 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3942 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3943 NS_ENSURE_STATE(window);
3945 *aMuted = window->GetAudioMuted();
3946 return NS_OK;
3949 NS_IMETHODIMP
3950 nsDOMWindowUtils::SetAudioMuted(bool aMuted)
3952 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3953 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3954 NS_ENSURE_STATE(window);
3956 window->SetAudioMuted(aMuted);
3957 return NS_OK;
3960 NS_IMETHODIMP
3961 nsDOMWindowUtils::GetAudioVolume(float* aVolume)
3963 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3964 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3965 NS_ENSURE_STATE(window);
3967 *aVolume = window->GetAudioVolume();
3968 return NS_OK;
3971 NS_IMETHODIMP
3972 nsDOMWindowUtils::SetAudioVolume(float aVolume)
3974 MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
3975 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3976 NS_ENSURE_STATE(window);
3978 return window->SetAudioVolume(aVolume);
3981 NS_IMETHODIMP
3982 nsDOMWindowUtils::XpconnectArgument(nsIDOMWindowUtils* aThis)
3984 // Do nothing.
3985 return NS_OK;
3988 NS_IMETHODIMP
3989 nsDOMWindowUtils::AskPermission(nsIContentPermissionRequest* aRequest)
3991 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
3992 return nsContentPermissionUtils::AskPermission(aRequest, window->GetCurrentInnerWindow());
3995 NS_IMETHODIMP
3996 nsDOMWindowUtils::GetFramesConstructed(uint64_t* aResult)
3998 nsPresContext* presContext = GetPresContext();
3999 if (!presContext) {
4000 return NS_ERROR_NOT_AVAILABLE;
4003 *aResult = presContext->FramesConstructedCount();
4004 return NS_OK;
4007 NS_IMETHODIMP
4008 nsDOMWindowUtils::GetFramesReflowed(uint64_t* aResult)
4010 nsPresContext* presContext = GetPresContext();
4011 if (!presContext) {
4012 return NS_ERROR_NOT_AVAILABLE;
4015 *aResult = presContext->FramesReflowedCount();
4016 return NS_OK;
4019 NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
4020 NS_INTERFACE_MAP_ENTRY(nsISupports)
4021 NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
4022 NS_INTERFACE_MAP_END
4024 NS_IMPL_ADDREF(nsTranslationNodeList)
4025 NS_IMPL_RELEASE(nsTranslationNodeList)
4027 NS_IMETHODIMP
4028 nsTranslationNodeList::Item(uint32_t aIndex, nsIDOMNode** aRetVal)
4030 NS_ENSURE_ARG_POINTER(aRetVal);
4031 NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex));
4032 return NS_OK;
4035 NS_IMETHODIMP
4036 nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal)
4038 NS_ENSURE_ARG_POINTER(aRetVal);
4039 if (aIndex >= mLength) {
4040 *aRetVal = false;
4041 return NS_OK;
4044 *aRetVal = mNodeIsRoot.ElementAt(aIndex);
4045 return NS_OK;
4048 NS_IMETHODIMP
4049 nsTranslationNodeList::GetLength(uint32_t* aRetVal)
4051 NS_ENSURE_ARG_POINTER(aRetVal);
4052 *aRetVal = mLength;
4053 return NS_OK;