dom/base/nsDOMWindowUtils.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsDOMWindowUtils.h"
     8 #include "mozilla/layers/CompositorChild.h"
     9 #include "mozilla/layers/LayerTransactionChild.h"
    10 #include "nsPresContext.h"
    11 #include "nsDOMClassInfoID.h"
    12 #include "nsError.h"
    13 #include "nsIDOMEvent.h"
    14 #include "nsQueryContentEventResult.h"
    15 #include "CompositionStringSynthesizer.h"
    16 #include "nsGlobalWindow.h"
    17 #include "nsIDocument.h"
    18 #include "nsFocusManager.h"
    19 #include "nsFrameManager.h"
    20 #include "nsRefreshDriver.h"
    21 #include "mozilla/dom/Touch.h"
    22 #include "nsIObjectLoadingContent.h"
    23 #include "nsFrame.h"
    24 #include "mozilla/layers/ShadowLayers.h"
    26 #include "nsIScrollableFrame.h"
    28 #include "nsContentUtils.h"
    30 #include "nsIFrame.h"
    31 #include "nsIWidget.h"
    32 #include "nsCharsetSource.h"
    33 #include "nsJSEnvironment.h"
    34 #include "nsJSUtils.h"
    36 #include "mozilla/EventStateManager.h"
    37 #include "mozilla/MiscEvents.h"
    38 #include "mozilla/MouseEvents.h"
    39 #include "mozilla/TextEvents.h"
    40 #include "mozilla/TouchEvents.h"
    42 #include "nsViewManager.h"
    44 #include "nsIDOMHTMLCanvasElement.h"
    45 #include "nsLayoutUtils.h"
    46 #include "nsComputedDOMStyle.h"
    47 #include "nsIPresShell.h"
    48 #include "nsStyleAnimation.h"
    49 #include "nsCSSProps.h"
    50 #include "nsDOMFile.h"
    51 #include "nsTArrayHelpers.h"
    52 #include "nsIDocShell.h"
    53 #include "nsIContentViewer.h"
    54 #include "nsIMarkupDocumentViewer.h"
    55 #include "mozilla/dom/DOMRect.h"
    56 #include <algorithm>
    58 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
    59 #include <gdk/gdk.h>
    60 #include <gdk/gdkx.h>
    61 #endif
    63 #include "Layers.h"
    64 #include "mozilla/layers/ShadowLayers.h"
    66 #include "mozilla/dom/Element.h"
    67 #include "mozilla/dom/file/FileHandle.h"
    68 #include "mozilla/dom/FileHandleBinding.h"
    69 #include "mozilla/dom/TabChild.h"
    70 #include "mozilla/dom/IDBFactoryBinding.h"
    71 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
    72 #include "mozilla/dom/quota/PersistenceType.h"
    73 #include "mozilla/dom/quota/QuotaManager.h"
    74 #include "nsDOMBlobBuilder.h"
    75 #include "nsPrintfCString.h"
    76 #include "nsViewportInfo.h"
    77 #include "nsIFormControl.h"
    78 #include "nsIScriptError.h"
    79 #include "nsIAppShell.h"
    80 #include "nsWidgetsCID.h"
    81 #include "FrameLayerBuilder.h"
    82 #include "nsDisplayList.h"
    83 #include "nsROCSSPrimitiveValue.h"
    84 #include "nsIBaseWindow.h"
    85 #include "nsIDocShellTreeOwner.h"
    86 #include "nsIInterfaceRequestorUtils.h"
    87 #include "GeckoProfiler.h"
    88 #include "mozilla/Preferences.h"
    89 #include "nsIContentIterator.h"
    91 #ifdef XP_WIN
    92 #undef GetClassName
    93 #endif
    95 using namespace mozilla;
    96 using namespace mozilla::dom;
    97 using namespace mozilla::layers;
    98 using namespace mozilla::widget;
    99 using namespace mozilla::gfx;
   101 class gfxContext;
   103 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
   105 DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
   107 NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
   108   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
   109   NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
   110   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   111   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils)
   112 NS_INTERFACE_MAP_END
   114 NS_IMPL_ADDREF(nsDOMWindowUtils)
   115 NS_IMPL_RELEASE(nsDOMWindowUtils)
   117 nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
   118 {
   119   nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow);
   120   mWindow = do_GetWeakReference(supports);
   121   NS_ASSERTION(aWindow->IsOuterWindow(), "How did that happen?");
   122 }
   124 nsDOMWindowUtils::~nsDOMWindowUtils()
   125 {
   126 }
   128 nsIPresShell*
   129 nsDOMWindowUtils::GetPresShell()
   130 {
   131   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   132   if (!window)
   133     return nullptr;
   135   nsIDocShell *docShell = window->GetDocShell();
   136   if (!docShell)
   137     return nullptr;
   139   return docShell->GetPresShell();
   140 }
   142 nsPresContext*
   143 nsDOMWindowUtils::GetPresContext()
   144 {
   145   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   146   if (!window)
   147     return nullptr;
   148   nsIDocShell *docShell = window->GetDocShell();
   149   if (!docShell)
   150     return nullptr;
   151   nsRefPtr<nsPresContext> presContext;
   152   docShell->GetPresContext(getter_AddRefs(presContext));
   153   return presContext;
   154 }
   156 nsIDocument*
   157 nsDOMWindowUtils::GetDocument()
   158 {
   159   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   160   if (!window) {
   161     return nullptr;
   162   }
   163   return window->GetExtantDoc();
   164 }
   166 LayerTransactionChild*
   167 nsDOMWindowUtils::GetLayerTransaction()
   168 {
   169   nsIWidget* widget = GetWidget();
   170   if (!widget)
   171     return nullptr;
   173   LayerManager* manager = widget->GetLayerManager();
   174   if (!manager)
   175     return nullptr;
   177   ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
   178   return forwarder && forwarder->HasShadowManager() ?
   179          forwarder->GetShadowManager() :
   180          nullptr;
   181 }
   183 NS_IMETHODIMP
   184 nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
   185 {
   186   if (!nsContentUtils::IsCallerChrome()) {
   187     return NS_ERROR_DOM_SECURITY_ERR;
   188   }
   190   NS_ENSURE_ARG_POINTER(aMode);
   191   *aMode = 0;
   192   nsPresContext* presContext = GetPresContext();
   193   if (presContext) {
   194     *aMode = presContext->ImageAnimationMode();
   195     return NS_OK;
   196   }
   197   return NS_ERROR_NOT_AVAILABLE;
   198 }
   200 NS_IMETHODIMP
   201 nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode)
   202 {
   203   if (!nsContentUtils::IsCallerChrome()) {
   204     return NS_ERROR_DOM_SECURITY_ERR;
   205   }
   207   nsPresContext* presContext = GetPresContext();
   208   if (presContext) {
   209     presContext->SetImageAnimationMode(aMode);
   210     return NS_OK;
   211   }
   212   return NS_ERROR_NOT_AVAILABLE;
   213 }
   215 NS_IMETHODIMP
   216 nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
   217 {
   218   *aIsForced = false;
   220   if (!nsContentUtils::IsCallerChrome()) {
   221     return NS_ERROR_DOM_SECURITY_ERR;
   222   }
   224   nsIDocument* doc = GetDocument();
   225   *aIsForced = doc &&
   226     doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
   227   return NS_OK;
   228 }
   230 NS_IMETHODIMP
   231 nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
   232                                       nsAString& aValue)
   233 {
   234   if (!nsContentUtils::IsCallerChrome()) {
   235     return NS_ERROR_DOM_SECURITY_ERR;
   236   }
   238   nsIDocument* doc = GetDocument();
   239   if (doc) {
   240     nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
   241     doc->GetHeaderData(name, aValue);
   242     return NS_OK;
   243   }
   245   aValue.Truncate();
   246   return NS_OK;
   247 }
   249 NS_IMETHODIMP
   250 nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
   251 {
   252   if (!nsContentUtils::IsCallerChrome()) {
   253     return NS_ERROR_DOM_SECURITY_ERR;
   254   }
   256   if (aCount == 0)
   257     aCount = 1;
   259   if (nsIPresShell* presShell = GetPresShell()) {
   260     nsIFrame *rootFrame = presShell->GetRootFrame();
   262     if (rootFrame) {
   263       PRIntervalTime iStart = PR_IntervalNow();
   265       for (uint32_t i = 0; i < aCount; i++)
   266         rootFrame->InvalidateFrame();
   268 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
   269       XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
   270 #endif
   272       *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
   274       return NS_OK;
   275     }
   276   }
   277   return NS_ERROR_FAILURE;
   278 }
   280 NS_IMETHODIMP
   281 nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
   282 {
   283   if (!nsContentUtils::IsCallerChrome()) {
   284     return NS_ERROR_DOM_SECURITY_ERR;
   285   }
   287   if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) {
   288     return NS_ERROR_ILLEGAL_VALUE;
   289   }
   291   nsIPresShell* presShell = GetPresShell();
   292   if (!presShell) {
   293     return NS_ERROR_FAILURE;
   294   }
   296   nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
   297   nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
   299   presShell->ResizeReflowOverride(width, height);
   301   return NS_OK;
   302 }
   304 NS_IMETHODIMP
   305 nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
   306                                   uint32_t aDisplayHeight,
   307                                   double *aDefaultZoom, bool *aAllowZoom,
   308                                   double *aMinZoom, double *aMaxZoom,
   309                                   uint32_t *aWidth, uint32_t *aHeight,
   310                                   bool *aAutoSize)
   311 {
   312   nsIDocument* doc = GetDocument();
   313   NS_ENSURE_STATE(doc);
   315   nsViewportInfo info = nsContentUtils::GetViewportInfo(doc, ScreenIntSize(aDisplayWidth, aDisplayHeight));
   316   *aDefaultZoom = info.GetDefaultZoom().scale;
   317   *aAllowZoom = info.IsZoomAllowed();
   318   *aMinZoom = info.GetMinZoom().scale;
   319   *aMaxZoom = info.GetMaxZoom().scale;
   320   *aWidth = info.GetSize().width;
   321   *aHeight = info.GetSize().height;
   322   *aAutoSize = info.IsAutoSizeEnabled();
   323   return NS_OK;
   324 }
   326 NS_IMETHODIMP
   327 nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
   328                                            float aWidthPx, float aHeightPx,
   329                                            nsIDOMElement* aElement,
   330                                            uint32_t aPriority)
   331 {
   332   if (!nsContentUtils::IsCallerChrome()) {
   333     return NS_ERROR_DOM_SECURITY_ERR;
   334   }
   336   nsIPresShell* presShell = GetPresShell();
   337   if (!presShell) {
   338     return NS_ERROR_FAILURE;
   339   }
   341   if (!aElement) {
   342     return NS_ERROR_INVALID_ARG;
   343   }
   345   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   347   if (!content) {
   348     return NS_ERROR_INVALID_ARG;
   349   }
   351   if (content->GetCurrentDoc() != presShell->GetDocument()) {
   352     return NS_ERROR_INVALID_ARG;
   353   }
   355   DisplayPortPropertyData* currentData =
   356     static_cast<DisplayPortPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPort));
   357   if (currentData && currentData->mPriority > aPriority) {
   358     return NS_OK;
   359   }
   361   nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
   362                      nsPresContext::CSSPixelsToAppUnits(aYPx),
   363                      nsPresContext::CSSPixelsToAppUnits(aWidthPx),
   364                      nsPresContext::CSSPixelsToAppUnits(aHeightPx));
   366   content->SetProperty(nsGkAtoms::DisplayPort,
   367                        new DisplayPortPropertyData(displayport, aPriority),
   368                        nsINode::DeleteProperty<DisplayPortPropertyData>);
   370   nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
   371   if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
   372     // We are setting a root displayport for a document.
   373     // The pres shell needs a special flag set.
   374     presShell->SetIgnoreViewportScrolling(true);
   375   }
   377   nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
   378   if (rootFrame) {
   379     rootFrame->SchedulePaint();
   381     // If we are hiding something that is a display root then send empty paint
   382     // transaction in order to release retained layers because it won't get
   383     // any more paint requests when it is hidden.
   384     if (displayport.IsEmpty() &&
   385         rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) {
   386       nsCOMPtr<nsIWidget> widget = GetWidget();
   387       if (widget) {
   388         bool isRetainingManager;
   389         LayerManager* manager = widget->GetLayerManager(&isRetainingManager);
   390         if (isRetainingManager) {
   391           manager->BeginTransaction();
   392           nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(), NS_RGB(255, 255, 255),
   393                                     nsLayoutUtils::PAINT_WIDGET_LAYERS |
   394                                     nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
   395         }
   396       }
   397     }
   398   }
   400   return NS_OK;
   401 }
   403 NS_IMETHODIMP
   404 nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
   405                                                   float aTopMargin,
   406                                                   float aRightMargin,
   407                                                   float aBottomMargin,
   408                                                   uint32_t aAlignmentX,
   409                                                   uint32_t aAlignmentY,
   410                                                   nsIDOMElement* aElement,
   411                                                   uint32_t aPriority)
   412 {
   413   if (!nsContentUtils::IsCallerChrome()) {
   414     return NS_ERROR_DOM_SECURITY_ERR;
   415   }
   417   nsIPresShell* presShell = GetPresShell();
   418   if (!presShell) {
   419     return NS_ERROR_FAILURE;
   420   }
   422   if (!aElement) {
   423     return NS_ERROR_INVALID_ARG;
   424   }
   426   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   428   if (!content) {
   429     return NS_ERROR_INVALID_ARG;
   430   }
   432   if (content->GetCurrentDoc() != presShell->GetDocument()) {
   433     return NS_ERROR_INVALID_ARG;
   434   }
   436   // Note order change of arguments between our function signature and
   437   // LayerMargin constructor.
   438   LayerMargin displayportMargins(aTopMargin,
   439                                  aRightMargin,
   440                                  aBottomMargin,
   441                                  aLeftMargin);
   443   nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
   444                                        aAlignmentX, aAlignmentY, aPriority);
   446   return NS_OK;
   447 }
   450 NS_IMETHODIMP
   451 nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
   452                                                int32_t aY,
   453                                                int32_t aWidth,
   454                                                int32_t aHeight,
   455                                                nsIDOMElement* aElement)
   456 {
   457   if (!nsContentUtils::IsCallerChrome()) {
   458     return NS_ERROR_DOM_SECURITY_ERR;
   459   }
   461   nsIPresShell* presShell = GetPresShell();
   462   if (!presShell) {
   463     return NS_ERROR_FAILURE;
   464   }
   466   if (!aElement) {
   467     return NS_ERROR_INVALID_ARG;
   468   }
   470   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   472   if (!content) {
   473     return NS_ERROR_INVALID_ARG;
   474   }
   476   if (content->GetCurrentDoc() != presShell->GetDocument()) {
   477     return NS_ERROR_INVALID_ARG;
   478   }
   480   nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight));
   482   return NS_OK;
   483 }
   485 NS_IMETHODIMP
   486 nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
   487                                                    float aWidthPx, float aHeightPx,
   488                                                    nsIDOMElement* aElement)
   489 {
   490   if (!nsContentUtils::IsCallerChrome()) {
   491     return NS_ERROR_DOM_SECURITY_ERR;
   492   }
   494   nsIPresShell* presShell = GetPresShell();
   495   if (!presShell) {
   496     return NS_ERROR_FAILURE;
   497   }
   499   if (!aElement) {
   500     return NS_ERROR_INVALID_ARG;
   501   }
   503   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   505   if (!content) {
   506     return NS_ERROR_INVALID_ARG;
   507   }
   509   if (content->GetCurrentDoc() != presShell->GetDocument()) {
   510     return NS_ERROR_INVALID_ARG;
   511   }
   513   nsRect displayport;
   514   if (!nsLayoutUtils::GetDisplayPort(content, &displayport)) {
   515     return NS_ERROR_INVALID_ARG;
   516   }
   518   nsRect criticalDisplayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
   519                              nsPresContext::CSSPixelsToAppUnits(aYPx),
   520                              nsPresContext::CSSPixelsToAppUnits(aWidthPx),
   521                              nsPresContext::CSSPixelsToAppUnits(aHeightPx));
   522   content->SetProperty(nsGkAtoms::CriticalDisplayPort, new nsRect(criticalDisplayport),
   523                        nsINode::DeleteProperty<nsRect>);
   525   nsIFrame* rootFrame = presShell->GetRootFrame();
   526   if (rootFrame) {
   527     rootFrame->InvalidateFrame();
   528   }
   530   return NS_OK;
   531 }
   533 NS_IMETHODIMP
   534 nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
   535 {
   536   if (!nsContentUtils::IsCallerChrome()) {
   537     return NS_ERROR_DOM_SECURITY_ERR;
   538   }
   540   nsIPresShell* presShell = GetPresShell();
   541   if (!presShell) {
   542     return NS_ERROR_FAILURE;
   543   }
   545   nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   546   if (sf) {
   547     sf->SetResolution(gfxSize(aXResolution, aYResolution));
   548     presShell->SetResolution(aXResolution, aYResolution);
   549   }
   551   return NS_OK;
   552 }
   554 NS_IMETHODIMP
   555 nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
   556 {
   557   if (!nsContentUtils::IsCallerChrome()) {
   558     return NS_ERROR_DOM_SECURITY_ERR;
   559   }
   561   nsIPresShell* presShell = GetPresShell();
   562   if (!presShell) {
   563     return NS_ERROR_FAILURE;
   564   }
   566   nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   567   if (sf) {
   568     const gfxSize& res = sf->GetResolution();
   569     *aXResolution = res.width;
   570     *aYResolution = res.height;
   571   } else {
   572     *aXResolution = presShell->GetXResolution();
   573     *aYResolution = presShell->GetYResolution();
   574   }
   576   return NS_OK;
   577 }
   579 NS_IMETHODIMP
   580 nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) {
   581   if (!nsContentUtils::IsCallerChrome()) {
   582     return NS_ERROR_DOM_SECURITY_ERR;
   583   }
   585   nsIPresShell* presShell = GetPresShell();
   586   if (!presShell) {
   587     return NS_ERROR_FAILURE;
   588   }
   590   const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   591   *aIsResolutionSet = sf && sf->IsResolutionSet();
   593   return NS_OK;
   594 }
   596 NS_IMETHODIMP
   597 nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
   598 {
   599   if (!nsContentUtils::IsCallerChrome()) {
   600     return NS_ERROR_DOM_SECURITY_ERR;
   601   }
   603   nsIPresShell* presShell = GetPresShell();
   604   if (presShell) {
   605     presShell->SetIsFirstPaint(aIsFirstPaint);
   606     return NS_OK;
   607   }
   608   return NS_ERROR_FAILURE;
   609 }
   611 NS_IMETHODIMP
   612 nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint)
   613 {
   614   if (!nsContentUtils::IsCallerChrome()) {
   615     return NS_ERROR_DOM_SECURITY_ERR;
   616   }
   618   nsIPresShell* presShell = GetPresShell();
   619   if (presShell) {
   620     *aIsFirstPaint = presShell->GetIsFirstPaint();
   621     return NS_OK;
   622   }
   623   return NS_ERROR_FAILURE;
   624 }
   626 NS_IMETHODIMP
   627 nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId)
   628 {
   629   if (!nsContentUtils::IsCallerChrome()) {
   630     return NS_ERROR_DOM_SECURITY_ERR;
   631   }
   633   nsIPresShell* presShell = GetPresShell();
   634   if (presShell) {
   635     *aPresShellId = presShell->GetPresShellId();
   636     return NS_OK;
   637   }
   638   return NS_ERROR_FAILURE;
   639 }
   641 /* static */
   642 mozilla::Modifiers
   643 nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers)
   644 {
   645   Modifiers result = 0;
   646   if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) {
   647     result |= mozilla::MODIFIER_SHIFT;
   648   }
   649   if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) {
   650     result |= mozilla::MODIFIER_CONTROL;
   651   }
   652   if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) {
   653     result |= mozilla::MODIFIER_ALT;
   654   }
   655   if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) {
   656     result |= mozilla::MODIFIER_META;
   657   }
   658   if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) {
   659     result |= mozilla::MODIFIER_ALTGRAPH;
   660   }
   661   if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) {
   662     result |= mozilla::MODIFIER_CAPSLOCK;
   663   }
   664   if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) {
   665     result |= mozilla::MODIFIER_FN;
   666   }
   667   if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) {
   668     result |= mozilla::MODIFIER_NUMLOCK;
   669   }
   670   if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) {
   671     result |= mozilla::MODIFIER_SCROLLLOCK;
   672   }
   673   if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) {
   674     result |= mozilla::MODIFIER_SYMBOLLOCK;
   675   }
   676   if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) {
   677     result |= mozilla::MODIFIER_OS;
   678   }
   679   return result;
   680 }
   682 NS_IMETHODIMP
   683 nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
   684                                  float aX,
   685                                  float aY,
   686                                  int32_t aButton,
   687                                  int32_t aClickCount,
   688                                  int32_t aModifiers,
   689                                  bool aIgnoreRootScrollFrame,
   690                                  float aPressure,
   691                                  unsigned short aInputSourceArg,
   692                                  bool aIsSynthesized,
   693                                  uint8_t aOptionalArgCount,
   694                                  bool *aPreventDefault)
   695 {
   696   return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
   697                               aIgnoreRootScrollFrame, aPressure,
   698                               aInputSourceArg, false, aPreventDefault,
   699                               aOptionalArgCount >= 4 ? aIsSynthesized : true);
   700 }
   702 NS_IMETHODIMP
   703 nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
   704                                          float aX,
   705                                          float aY,
   706                                          int32_t aButton,
   707                                          int32_t aClickCount,
   708                                          int32_t aModifiers,
   709                                          bool aIgnoreRootScrollFrame,
   710                                          float aPressure,
   711                                          unsigned short aInputSourceArg,
   712                                          bool aIsSynthesized,
   713                                          uint8_t aOptionalArgCount)
   714 {
   715   PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow");
   716   return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
   717                               aIgnoreRootScrollFrame, aPressure,
   718                               aInputSourceArg, true, nullptr,
   719                               aOptionalArgCount >= 4 ? aIsSynthesized : true);
   720 }
   722 static LayoutDeviceIntPoint
   723 ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset,
   724               nsPresContext* aPresContext)
   725 {
   726   return LayoutDeviceIntPoint::FromAppUnitsRounded(
   727     CSSPoint::ToAppUnits(aPoint) + aOffset,
   728     aPresContext->AppUnitsPerDevPixel());
   729 }
   731 static inline int16_t
   732 GetButtonsFlagForButton(int32_t aButton)
   733 {
   734   switch (aButton) {
   735     case WidgetMouseEvent::eLeftButton:
   736       return WidgetMouseEvent::eLeftButtonFlag;
   737     case WidgetMouseEvent::eMiddleButton:
   738       return WidgetMouseEvent::eMiddleButtonFlag;
   739     case WidgetMouseEvent::eRightButton:
   740       return WidgetMouseEvent::eRightButtonFlag;
   741     case 4:
   742       return WidgetMouseEvent::e4thButtonFlag;
   743     case 5:
   744       return WidgetMouseEvent::e5thButtonFlag;
   745     default:
   746       NS_ERROR("Button not known.");
   747       return 0;
   748   }
   749 }
   751 NS_IMETHODIMP
   752 nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
   753                                        float aX,
   754                                        float aY,
   755                                        int32_t aButton,
   756                                        int32_t aClickCount,
   757                                        int32_t aModifiers,
   758                                        bool aIgnoreRootScrollFrame,
   759                                        float aPressure,
   760                                        unsigned short aInputSourceArg,
   761                                        bool aToWindow,
   762                                        bool *aPreventDefault,
   763                                        bool aIsSynthesized)
   764 {
   765   if (!nsContentUtils::IsCallerChrome()) {
   766     return NS_ERROR_DOM_SECURITY_ERR;
   767   }
   769   // get the widget to send the event to
   770   nsPoint offset;
   771   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   772   if (!widget)
   773     return NS_ERROR_FAILURE;
   775   int32_t msg;
   776   bool contextMenuKey = false;
   777   if (aType.EqualsLiteral("mousedown"))
   778     msg = NS_MOUSE_BUTTON_DOWN;
   779   else if (aType.EqualsLiteral("mouseup"))
   780     msg = NS_MOUSE_BUTTON_UP;
   781   else if (aType.EqualsLiteral("mousemove"))
   782     msg = NS_MOUSE_MOVE;
   783   else if (aType.EqualsLiteral("mouseover"))
   784     msg = NS_MOUSE_ENTER;
   785   else if (aType.EqualsLiteral("mouseout"))
   786     msg = NS_MOUSE_EXIT;
   787   else if (aType.EqualsLiteral("contextmenu")) {
   788     msg = NS_CONTEXTMENU;
   789     contextMenuKey = (aButton == 0);
   790   } else if (aType.EqualsLiteral("MozMouseHittest"))
   791     msg = NS_MOUSE_MOZHITTEST;
   792   else
   793     return NS_ERROR_FAILURE;
   795   if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
   796     aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
   797   }
   799   WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal,
   800                          contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
   801                                           WidgetMouseEvent::eNormal);
   802   event.modifiers = GetWidgetModifiers(aModifiers);
   803   event.button = aButton;
   804   event.buttons = GetButtonsFlagForButton(aButton);
   805   event.widget = widget;
   806   event.pressure = aPressure;
   807   event.inputSource = aInputSourceArg;
   808   event.clickCount = aClickCount;
   809   event.time = PR_IntervalNow();
   810   event.mFlags.mIsSynthesizedForTests = aIsSynthesized;
   812   nsPresContext* presContext = GetPresContext();
   813   if (!presContext)
   814     return NS_ERROR_FAILURE;
   816   event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   817   event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
   819   nsEventStatus status;
   820   if (aToWindow) {
   821     nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
   822     if (!presShell)
   823       return NS_ERROR_FAILURE;
   824     nsViewManager* viewManager = presShell->GetViewManager();
   825     if (!viewManager)
   826       return NS_ERROR_FAILURE;
   827     nsView* view = viewManager->GetRootView();
   828     if (!view)
   829       return NS_ERROR_FAILURE;
   831     status = nsEventStatus_eIgnore;
   832     return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
   833   }
   834   nsresult rv = widget->DispatchEvent(&event, status);
   835   *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
   837   return rv;
   838 }
   840 NS_IMETHODIMP
   841 nsDOMWindowUtils::SendPointerEvent(const nsAString& aType,
   842                                    float aX,
   843                                    float aY,
   844                                    int32_t aButton,
   845                                    int32_t aClickCount,
   846                                    int32_t aModifiers,
   847                                    bool aIgnoreRootScrollFrame,
   848                                    float aPressure,
   849                                    unsigned short aInputSourceArg,
   850                                    int32_t aPointerId,
   851                                    int32_t aWidth,
   852                                    int32_t aHeight,
   853                                    int32_t tiltX,
   854                                    int32_t tiltY,
   855                                    bool aIsPrimary,
   856                                    bool aIsSynthesized,
   857                                    uint8_t aOptionalArgCount,
   858                                    bool* aPreventDefault)
   859 {
   860   if (!nsContentUtils::IsCallerChrome()) {
   861     return NS_ERROR_DOM_SECURITY_ERR;
   862   }
   864   // get the widget to send the event to
   865   nsPoint offset;
   866   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   867   if (!widget) {
   868     return NS_ERROR_FAILURE;
   869   }
   871   int32_t msg;
   872   if (aType.EqualsLiteral("pointerdown")) {
   873     msg = NS_POINTER_DOWN;
   874   } else if (aType.EqualsLiteral("pointerup")) {
   875     msg = NS_POINTER_UP;
   876   } else if (aType.EqualsLiteral("pointermove")) {
   877     msg = NS_POINTER_MOVE;
   878   } else if (aType.EqualsLiteral("pointerover")) {
   879     msg = NS_POINTER_OVER;
   880   } else if (aType.EqualsLiteral("pointerout")) {
   881     msg = NS_POINTER_OUT;
   882   } else {
   883     return NS_ERROR_FAILURE;
   884   }
   886   if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
   887     aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
   888   }
   890   WidgetPointerEvent event(true, msg, widget);
   891   event.modifiers = GetWidgetModifiers(aModifiers);
   892   event.button = aButton;
   893   event.buttons = GetButtonsFlagForButton(aButton);
   894   event.widget = widget;
   895   event.pressure = aPressure;
   896   event.inputSource = aInputSourceArg;
   897   event.pointerId = aPointerId;
   898   event.width = aWidth;
   899   event.height = aHeight;
   900   event.tiltX = tiltX;
   901   event.tiltY = tiltY;
   902   event.isPrimary = aIsPrimary;
   903   event.clickCount = aClickCount;
   904   event.time = PR_IntervalNow();
   905   event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
   907   nsPresContext* presContext = GetPresContext();
   908   if (!presContext) {
   909     return NS_ERROR_FAILURE;
   910   }
   912   event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   913   event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
   915   nsEventStatus status;
   916   nsresult rv = widget->DispatchEvent(&event, status);
   917   *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
   919   return rv;
   920 }
   922 NS_IMETHODIMP
   923 nsDOMWindowUtils::SendWheelEvent(float aX,
   924                                  float aY,
   925                                  double aDeltaX,
   926                                  double aDeltaY,
   927                                  double aDeltaZ,
   928                                  uint32_t aDeltaMode,
   929                                  int32_t aModifiers,
   930                                  int32_t aLineOrPageDeltaX,
   931                                  int32_t aLineOrPageDeltaY,
   932                                  uint32_t aOptions)
   933 {
   934   if (!nsContentUtils::IsCallerChrome()) {
   935     return NS_ERROR_DOM_SECURITY_ERR;
   936   }
   938   // get the widget to send the event to
   939   nsPoint offset;
   940   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   941   if (!widget) {
   942     return NS_ERROR_NULL_POINTER;
   943   }
   945   WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
   946   wheelEvent.modifiers = GetWidgetModifiers(aModifiers);
   947   wheelEvent.deltaX = aDeltaX;
   948   wheelEvent.deltaY = aDeltaY;
   949   wheelEvent.deltaZ = aDeltaZ;
   950   wheelEvent.deltaMode = aDeltaMode;
   951   wheelEvent.isMomentum =
   952     (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
   953   wheelEvent.isPixelOnlyDevice =
   954     (aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0;
   955   NS_ENSURE_TRUE(
   956     !wheelEvent.isPixelOnlyDevice ||
   957       aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL,
   958     NS_ERROR_INVALID_ARG);
   959   wheelEvent.customizedByUserPrefs =
   960     (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
   961   wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;
   962   wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY;
   963   wheelEvent.widget = widget;
   965   wheelEvent.time = PR_Now() / 1000;
   967   nsPresContext* presContext = GetPresContext();
   968   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
   970   wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   972   nsEventStatus status;
   973   nsresult rv = widget->DispatchEvent(&wheelEvent, status);
   974   NS_ENSURE_SUCCESS(rv, rv);
   976   bool failedX = false;
   977   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
   978       wheelEvent.overflowDeltaX != 0) {
   979     failedX = true;
   980   }
   981   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) &&
   982       wheelEvent.overflowDeltaX <= 0) {
   983     failedX = true;
   984   }
   985   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) &&
   986       wheelEvent.overflowDeltaX >= 0) {
   987     failedX = true;
   988   }
   989   bool failedY = false;
   990   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) &&
   991       wheelEvent.overflowDeltaY != 0) {
   992     failedY = true;
   993   }
   994   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) &&
   995       wheelEvent.overflowDeltaY <= 0) {
   996     failedY = true;
   997   }
   998   if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) &&
   999       wheelEvent.overflowDeltaY >= 0) {
  1000     failedY = true;
  1003 #ifdef DEBUG
  1004   if (failedX) {
  1005     nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaX: %f",
  1006                              wheelEvent.overflowDeltaX);
  1007     NS_WARNING(debugMsg.get());
  1009   if (failedY) {
  1010     nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaY: %f",
  1011                              wheelEvent.overflowDeltaY);
  1012     NS_WARNING(debugMsg.get());
  1014 #endif
  1016   return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE;
  1019 NS_IMETHODIMP
  1020 nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
  1021                                  uint32_t *aIdentifiers,
  1022                                  int32_t *aXs,
  1023                                  int32_t *aYs,
  1024                                  uint32_t *aRxs,
  1025                                  uint32_t *aRys,
  1026                                  float *aRotationAngles,
  1027                                  float *aForces,
  1028                                  uint32_t aCount,
  1029                                  int32_t aModifiers,
  1030                                  bool aIgnoreRootScrollFrame,
  1031                                  bool *aPreventDefault)
  1033   return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
  1034                               aRotationAngles, aForces, aCount, aModifiers,
  1035                               aIgnoreRootScrollFrame, false, aPreventDefault);
  1038 NS_IMETHODIMP
  1039 nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
  1040                                          uint32_t* aIdentifiers,
  1041                                          int32_t* aXs,
  1042                                          int32_t* aYs,
  1043                                          uint32_t* aRxs,
  1044                                          uint32_t* aRys,
  1045                                          float* aRotationAngles,
  1046                                          float* aForces,
  1047                                          uint32_t aCount,
  1048                                          int32_t aModifiers,
  1049                                          bool aIgnoreRootScrollFrame,
  1050                                          bool* aPreventDefault)
  1052   return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
  1053                               aRotationAngles, aForces, aCount, aModifiers,
  1054                               aIgnoreRootScrollFrame, true, aPreventDefault);
  1057 NS_IMETHODIMP
  1058 nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
  1059                                        uint32_t* aIdentifiers,
  1060                                        int32_t* aXs,
  1061                                        int32_t* aYs,
  1062                                        uint32_t* aRxs,
  1063                                        uint32_t* aRys,
  1064                                        float* aRotationAngles,
  1065                                        float* aForces,
  1066                                        uint32_t aCount,
  1067                                        int32_t aModifiers,
  1068                                        bool aIgnoreRootScrollFrame,
  1069                                        bool aToWindow,
  1070                                        bool* aPreventDefault)
  1072   if (!nsContentUtils::IsCallerChrome()) {
  1073     return NS_ERROR_DOM_SECURITY_ERR;
  1076   // get the widget to send the event to
  1077   nsPoint offset;
  1078   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
  1079   if (!widget) {
  1080     return NS_ERROR_NULL_POINTER;
  1082   int32_t msg;
  1083   if (aType.EqualsLiteral("touchstart")) {
  1084     msg = NS_TOUCH_START;
  1085   } else if (aType.EqualsLiteral("touchmove")) {
  1086     msg = NS_TOUCH_MOVE;
  1087   } else if (aType.EqualsLiteral("touchend")) {
  1088     msg = NS_TOUCH_END;
  1089   } else if (aType.EqualsLiteral("touchcancel")) {
  1090     msg = NS_TOUCH_CANCEL;
  1091   } else {
  1092     return NS_ERROR_UNEXPECTED;
  1094   WidgetTouchEvent event(true, msg, widget);
  1095   event.modifiers = GetWidgetModifiers(aModifiers);
  1096   event.widget = widget;
  1097   event.time = PR_Now();
  1099   nsPresContext* presContext = GetPresContext();
  1100   if (!presContext) {
  1101     return NS_ERROR_FAILURE;
  1103   event.touches.SetCapacity(aCount);
  1104   for (uint32_t i = 0; i < aCount; ++i) {
  1105     LayoutDeviceIntPoint pt =
  1106       ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
  1107     nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
  1108                                   LayoutDeviceIntPoint::ToUntyped(pt),
  1109                                   nsIntPoint(aRxs[i], aRys[i]),
  1110                                   aRotationAngles[i],
  1111                                   aForces[i]);
  1112     event.touches.AppendElement(t);
  1115   nsEventStatus status;
  1116   if (aToWindow) {
  1117     nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
  1118     if (!presShell) {
  1119       return NS_ERROR_FAILURE;
  1122     nsViewManager* viewManager = presShell->GetViewManager();
  1123     if (!viewManager) {
  1124       return NS_ERROR_FAILURE;
  1127     nsView* view = viewManager->GetRootView();
  1128     if (!view) {
  1129       return NS_ERROR_FAILURE;
  1132     status = nsEventStatus_eIgnore;
  1133     *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
  1134     return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
  1137   nsresult rv = widget->DispatchEvent(&event, status);
  1138   *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
  1139   return rv;
  1142 NS_IMETHODIMP
  1143 nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
  1144                                int32_t aKeyCode,
  1145                                int32_t aCharCode,
  1146                                int32_t aModifiers,
  1147                                uint32_t aAdditionalFlags,
  1148                                bool* aDefaultActionTaken)
  1150   if (!nsContentUtils::IsCallerChrome()) {
  1151     return NS_ERROR_DOM_SECURITY_ERR;
  1154   // get the widget to send the event to
  1155   nsCOMPtr<nsIWidget> widget = GetWidget();
  1156   if (!widget)
  1157     return NS_ERROR_FAILURE;
  1159   int32_t msg;
  1160   if (aType.EqualsLiteral("keydown"))
  1161     msg = NS_KEY_DOWN;
  1162   else if (aType.EqualsLiteral("keyup"))
  1163     msg = NS_KEY_UP;
  1164   else if (aType.EqualsLiteral("keypress"))
  1165     msg = NS_KEY_PRESS;
  1166   else
  1167     return NS_ERROR_FAILURE;
  1169   WidgetKeyboardEvent event(true, msg, widget);
  1170   event.modifiers = GetWidgetModifiers(aModifiers);
  1172   if (msg == NS_KEY_PRESS) {
  1173     event.keyCode = aCharCode ? 0 : aKeyCode;
  1174     event.charCode = aCharCode;
  1175   } else {
  1176     event.keyCode = aKeyCode;
  1177     event.charCode = 0;
  1180   uint32_t locationFlag = (aAdditionalFlags &
  1181     (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT |
  1182      KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD |
  1183      KEY_FLAG_LOCATION_MOBILE | KEY_FLAG_LOCATION_JOYSTICK));
  1184   switch (locationFlag) {
  1185     case KEY_FLAG_LOCATION_STANDARD:
  1186       event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
  1187       break;
  1188     case KEY_FLAG_LOCATION_LEFT:
  1189       event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
  1190       break;
  1191     case KEY_FLAG_LOCATION_RIGHT:
  1192       event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
  1193       break;
  1194     case KEY_FLAG_LOCATION_NUMPAD:
  1195       event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
  1196       break;
  1197     case KEY_FLAG_LOCATION_MOBILE:
  1198       event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
  1199       break;
  1200     case KEY_FLAG_LOCATION_JOYSTICK:
  1201       event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_JOYSTICK;
  1202       break;
  1203     default:
  1204       if (locationFlag != 0) {
  1205         return NS_ERROR_INVALID_ARG;
  1207       // If location flag isn't set, choose the location from keycode.
  1208       switch (aKeyCode) {
  1209         case nsIDOMKeyEvent::DOM_VK_NUMPAD0:
  1210         case nsIDOMKeyEvent::DOM_VK_NUMPAD1:
  1211         case nsIDOMKeyEvent::DOM_VK_NUMPAD2:
  1212         case nsIDOMKeyEvent::DOM_VK_NUMPAD3:
  1213         case nsIDOMKeyEvent::DOM_VK_NUMPAD4:
  1214         case nsIDOMKeyEvent::DOM_VK_NUMPAD5:
  1215         case nsIDOMKeyEvent::DOM_VK_NUMPAD6:
  1216         case nsIDOMKeyEvent::DOM_VK_NUMPAD7:
  1217         case nsIDOMKeyEvent::DOM_VK_NUMPAD8:
  1218         case nsIDOMKeyEvent::DOM_VK_NUMPAD9:
  1219         case nsIDOMKeyEvent::DOM_VK_MULTIPLY:
  1220         case nsIDOMKeyEvent::DOM_VK_ADD:
  1221         case nsIDOMKeyEvent::DOM_VK_SEPARATOR:
  1222         case nsIDOMKeyEvent::DOM_VK_SUBTRACT:
  1223         case nsIDOMKeyEvent::DOM_VK_DECIMAL:
  1224         case nsIDOMKeyEvent::DOM_VK_DIVIDE:
  1225           event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
  1226           break;
  1227         case nsIDOMKeyEvent::DOM_VK_SHIFT:
  1228         case nsIDOMKeyEvent::DOM_VK_CONTROL:
  1229         case nsIDOMKeyEvent::DOM_VK_ALT:
  1230         case nsIDOMKeyEvent::DOM_VK_META:
  1231           event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
  1232           break;
  1233         default:
  1234           event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
  1235           break;
  1237       break;
  1240   event.refPoint.x = event.refPoint.y = 0;
  1241   event.time = PR_IntervalNow();
  1242   event.mFlags.mIsSynthesizedForTests = true;
  1244   if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) {
  1245     event.mFlags.mDefaultPrevented = true;
  1248   nsEventStatus status;
  1249   nsresult rv = widget->DispatchEvent(&event, status);
  1250   NS_ENSURE_SUCCESS(rv, rv);
  1252   *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
  1254   return NS_OK;
  1257 NS_IMETHODIMP
  1258 nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout,
  1259                                      int32_t aNativeKeyCode,
  1260                                      int32_t aModifiers,
  1261                                      const nsAString& aCharacters,
  1262                                      const nsAString& aUnmodifiedCharacters)
  1264   if (!nsContentUtils::IsCallerChrome()) {
  1265     return NS_ERROR_DOM_SECURITY_ERR;
  1268   // get the widget to send the event to
  1269   nsCOMPtr<nsIWidget> widget = GetWidget();
  1270   if (!widget)
  1271     return NS_ERROR_FAILURE;
  1273   return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
  1274                                           aModifiers, aCharacters, aUnmodifiedCharacters);
  1277 NS_IMETHODIMP
  1278 nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX,
  1279                                        int32_t aScreenY,
  1280                                        int32_t aNativeMessage,
  1281                                        int32_t aModifierFlags,
  1282                                        nsIDOMElement* aElement)
  1284   if (!nsContentUtils::IsCallerChrome()) {
  1285     return NS_ERROR_DOM_SECURITY_ERR;
  1288   // get the widget to send the event to
  1289   nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
  1290   if (!widget)
  1291     return NS_ERROR_FAILURE;
  1293   return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY),
  1294                                             aNativeMessage, aModifierFlags);
  1297 NS_IMETHODIMP
  1298 nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX,
  1299                                              int32_t aScreenY,
  1300                                              uint32_t aNativeMessage,
  1301                                              double aDeltaX,
  1302                                              double aDeltaY,
  1303                                              double aDeltaZ,
  1304                                              uint32_t aModifierFlags,
  1305                                              uint32_t aAdditionalFlags,
  1306                                              nsIDOMElement* aElement)
  1308   if (!nsContentUtils::IsCallerChrome()) {
  1309     return NS_ERROR_DOM_SECURITY_ERR;
  1312   // get the widget to send the event to
  1313   nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
  1314   if (!widget) {
  1315     return NS_ERROR_FAILURE;
  1318   return widget->SynthesizeNativeMouseScrollEvent(nsIntPoint(aScreenX,
  1319                                                              aScreenY),
  1320                                                   aNativeMessage,
  1321                                                   aDeltaX, aDeltaY, aDeltaZ,
  1322                                                   aModifierFlags,
  1323                                                   aAdditionalFlags);
  1326 NS_IMETHODIMP
  1327 nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId,
  1328                                        uint32_t aTouchState,
  1329                                        int32_t aScreenX,
  1330                                        int32_t aScreenY,
  1331                                        double aPressure,
  1332                                        uint32_t aOrientation)
  1334   if (!nsContentUtils::IsCallerChrome()) {
  1335     return NS_ERROR_DOM_SECURITY_ERR;
  1338   nsCOMPtr<nsIWidget> widget = GetWidget();
  1339   if (!widget) {
  1340     return NS_ERROR_FAILURE;
  1343   if (aPressure < 0 || aPressure > 1 || aOrientation > 359) {
  1344     return NS_ERROR_INVALID_ARG;
  1347   return widget->SynthesizeNativeTouchPoint(aPointerId,
  1348                                             (nsIWidget::TouchPointerState)aTouchState,
  1349                                             nsIntPoint(aScreenX, aScreenY),
  1350                                             aPressure, aOrientation);
  1353 NS_IMETHODIMP
  1354 nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX,
  1355                                      int32_t aScreenY,
  1356                                      bool aLongTap)
  1358   if (!nsContentUtils::IsCallerChrome()) {
  1359     return NS_ERROR_DOM_SECURITY_ERR;
  1362   nsCOMPtr<nsIWidget> widget = GetWidget();
  1363   if (!widget) {
  1364     return NS_ERROR_FAILURE;
  1366   return widget->SynthesizeNativeTouchTap(nsIntPoint(aScreenX, aScreenY), aLongTap);
  1369 NS_IMETHODIMP
  1370 nsDOMWindowUtils::ClearNativeTouchSequence()
  1372   if (!nsContentUtils::IsCallerChrome()) {
  1373     return NS_ERROR_DOM_SECURITY_ERR;
  1376   nsCOMPtr<nsIWidget> widget = GetWidget();
  1377   if (!widget) {
  1378     return NS_ERROR_FAILURE;
  1380   return widget->ClearNativeTouchSequence();
  1383 NS_IMETHODIMP
  1384 nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
  1386   if (!nsContentUtils::IsCallerChrome()) {
  1387     return NS_ERROR_DOM_SECURITY_ERR;
  1390   // get the widget to send the event to
  1391   nsCOMPtr<nsIWidget> widget = GetWidget();
  1392   if (!widget)
  1393     return NS_ERROR_FAILURE;
  1395   return widget->ActivateNativeMenuItemAt(indexString);
  1398 NS_IMETHODIMP
  1399 nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
  1401   if (!nsContentUtils::IsCallerChrome()) {
  1402     return NS_ERROR_DOM_SECURITY_ERR;
  1405   // get the widget to send the event to
  1406   nsCOMPtr<nsIWidget> widget = GetWidget();
  1407   if (!widget)
  1408     return NS_ERROR_FAILURE;
  1410   return widget->ForceUpdateNativeMenuAt(indexString);
  1413 nsIWidget*
  1414 nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
  1416   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1417   if (window) {
  1418     nsIDocShell *docShell = window->GetDocShell();
  1419     if (docShell) {
  1420       nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  1421       if (presShell) {
  1422         nsIFrame* frame = presShell->GetRootFrame();
  1423         if (frame)
  1424           return frame->GetView()->GetNearestWidget(aOffset);
  1429   return nullptr;
  1432 nsIWidget*
  1433 nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
  1435   if (!aElement)
  1436     return GetWidget();
  1438   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  1439   nsIDocument* doc = content->GetCurrentDoc();
  1440   nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
  1442   if (presShell) {
  1443     nsIFrame* frame = content->GetPrimaryFrame();
  1444     if (!frame) {
  1445       frame = presShell->GetRootFrame();
  1447     if (frame)
  1448       return frame->GetNearestWidget();
  1451   return nullptr;
  1454 NS_IMETHODIMP
  1455 nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
  1457   if (!nsContentUtils::IsCallerChrome()) {
  1458     return NS_ERROR_DOM_SECURITY_ERR;
  1461   nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
  1462   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
  1463   if (fm) {
  1464     if (aElement)
  1465       fm->SetFocus(aElement, 0);
  1466     else
  1467       fm->ClearFocus(window);
  1470   return NS_OK;
  1473 NS_IMETHODIMP
  1474 nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
  1475                                  int32_t aExtraForgetSkippableCalls)
  1477   PROFILER_LABEL("GC", "GarbageCollect");
  1478   // Always permit this in debug builds.
  1479 #ifndef DEBUG
  1480   if (!nsContentUtils::IsCallerChrome()) {
  1481     return NS_ERROR_DOM_SECURITY_ERR;
  1483 #endif
  1485   nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
  1486   nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
  1488   return NS_OK;
  1491 NS_IMETHODIMP
  1492 nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener,
  1493                                int32_t aExtraForgetSkippableCalls)
  1495   // Always permit this in debug builds.
  1496 #ifndef DEBUG
  1497   if (!nsContentUtils::IsCallerChrome()) {
  1498     return NS_ERROR_DOM_SECURITY_ERR;
  1500 #endif
  1502   nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
  1503   return NS_OK;
  1506 NS_IMETHODIMP
  1507 nsDOMWindowUtils::RunNextCollectorTimer()
  1509   if (!nsContentUtils::IsCallerChrome()) {
  1510     return NS_ERROR_DOM_SECURITY_ERR;
  1513   nsJSContext::RunNextCollectorTimer();
  1515   return NS_OK;
  1518 NS_IMETHODIMP
  1519 nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
  1520                                          float aX,
  1521                                          float aY,
  1522                                          uint32_t aDirection,
  1523                                          double aDelta,
  1524                                          int32_t aModifiers,
  1525                                          uint32_t aClickCount)
  1527   if (!nsContentUtils::IsCallerChrome()) {
  1528     return NS_ERROR_DOM_SECURITY_ERR;
  1531   // get the widget to send the event to
  1532   nsPoint offset;
  1533   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
  1534   if (!widget)
  1535     return NS_ERROR_FAILURE;
  1537   int32_t msg;
  1538   if (aType.EqualsLiteral("MozSwipeGestureStart"))
  1539     msg = NS_SIMPLE_GESTURE_SWIPE_START;
  1540   else if (aType.EqualsLiteral("MozSwipeGestureUpdate"))
  1541     msg = NS_SIMPLE_GESTURE_SWIPE_UPDATE;
  1542   else if (aType.EqualsLiteral("MozSwipeGestureEnd"))
  1543     msg = NS_SIMPLE_GESTURE_SWIPE_END;
  1544   else if (aType.EqualsLiteral("MozSwipeGesture"))
  1545     msg = NS_SIMPLE_GESTURE_SWIPE;
  1546   else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
  1547     msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
  1548   else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
  1549     msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
  1550   else if (aType.EqualsLiteral("MozMagnifyGesture"))
  1551     msg = NS_SIMPLE_GESTURE_MAGNIFY;
  1552   else if (aType.EqualsLiteral("MozRotateGestureStart"))
  1553     msg = NS_SIMPLE_GESTURE_ROTATE_START;
  1554   else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
  1555     msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
  1556   else if (aType.EqualsLiteral("MozRotateGesture"))
  1557     msg = NS_SIMPLE_GESTURE_ROTATE;
  1558   else if (aType.EqualsLiteral("MozTapGesture"))
  1559     msg = NS_SIMPLE_GESTURE_TAP;
  1560   else if (aType.EqualsLiteral("MozPressTapGesture"))
  1561     msg = NS_SIMPLE_GESTURE_PRESSTAP;
  1562   else if (aType.EqualsLiteral("MozEdgeUIStarted"))
  1563     msg = NS_SIMPLE_GESTURE_EDGE_STARTED;
  1564   else if (aType.EqualsLiteral("MozEdgeUICanceled"))
  1565     msg = NS_SIMPLE_GESTURE_EDGE_CANCELED;
  1566   else if (aType.EqualsLiteral("MozEdgeUICompleted"))
  1567     msg = NS_SIMPLE_GESTURE_EDGE_COMPLETED;
  1568   else
  1569     return NS_ERROR_FAILURE;
  1571   WidgetSimpleGestureEvent event(true, msg, widget);
  1572   event.modifiers = GetWidgetModifiers(aModifiers);
  1573   event.direction = aDirection;
  1574   event.delta = aDelta;
  1575   event.clickCount = aClickCount;
  1576   event.time = PR_IntervalNow();
  1578   nsPresContext* presContext = GetPresContext();
  1579   if (!presContext)
  1580     return NS_ERROR_FAILURE;
  1582   event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
  1584   nsEventStatus status;
  1585   return widget->DispatchEvent(&event, status);
  1588 NS_IMETHODIMP
  1589 nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
  1590                                    bool aIgnoreRootScrollFrame,
  1591                                    bool aFlushLayout,
  1592                                    nsIDOMElement** aReturn)
  1594   if (!nsContentUtils::IsCallerChrome()) {
  1595     return NS_ERROR_DOM_SECURITY_ERR;
  1598   nsCOMPtr<nsIDocument> doc = GetDocument();
  1599   NS_ENSURE_STATE(doc);
  1601   Element* el =
  1602     doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
  1603   nsCOMPtr<nsIDOMElement> retval = do_QueryInterface(el);
  1604   retval.forget(aReturn);
  1605   return NS_OK;
  1608 NS_IMETHODIMP
  1609 nsDOMWindowUtils::NodesFromRect(float aX, float aY,
  1610                                 float aTopSize, float aRightSize,
  1611                                 float aBottomSize, float aLeftSize,
  1612                                 bool aIgnoreRootScrollFrame,
  1613                                 bool aFlushLayout,
  1614                                 nsIDOMNodeList** aReturn)
  1616   if (!nsContentUtils::IsCallerChrome()) {
  1617     return NS_ERROR_DOM_SECURITY_ERR;
  1620   nsCOMPtr<nsIDocument> doc = GetDocument();
  1621   NS_ENSURE_STATE(doc);
  1623   return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize, 
  1624                                   aIgnoreRootScrollFrame, aFlushLayout, aReturn);
  1627 NS_IMETHODIMP
  1628 nsDOMWindowUtils::GetTranslationNodes(nsIDOMNode* aRoot,
  1629                                       nsITranslationNodeList** aRetVal)
  1631   if (!nsContentUtils::IsCallerChrome()) {
  1632     return NS_ERROR_DOM_SECURITY_ERR;
  1635   NS_ENSURE_ARG_POINTER(aRetVal);
  1636   nsCOMPtr<nsIContent> root = do_QueryInterface(aRoot);
  1637   NS_ENSURE_STATE(root);
  1638   nsCOMPtr<nsIDocument> doc = GetDocument();
  1639   NS_ENSURE_STATE(doc);
  1641   if (root->OwnerDoc() != doc) {
  1642     return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
  1645   nsTHashtable<nsPtrHashKey<nsIContent>> translationNodesHash(1000);
  1646   nsRefPtr<nsTranslationNodeList> list = new nsTranslationNodeList;
  1648   uint32_t limit = 15000;
  1650   // We begin iteration with content->GetNextNode because we want to explictly
  1651   // skip the root tag from being a translation node.
  1652   nsIContent* content = root;
  1653   while ((limit > 0) && (content = content->GetNextNode(root))) {
  1654     if (!content->IsHTML()) {
  1655       continue;
  1658     nsIAtom* localName = content->Tag();
  1660     // Skip elements that usually contain non-translatable text content.
  1661     if (localName == nsGkAtoms::script ||
  1662         localName == nsGkAtoms::iframe ||
  1663         localName == nsGkAtoms::frameset ||
  1664         localName == nsGkAtoms::frame ||
  1665         localName == nsGkAtoms::code ||
  1666         localName == nsGkAtoms::noscript ||
  1667         localName == nsGkAtoms::style) {
  1668       continue;
  1671     // An element is a translation node if it contains
  1672     // at least one text node that has meaningful data
  1673     // for translation
  1674     for (nsIContent* child = content->GetFirstChild();
  1675          child;
  1676          child = child->GetNextSibling()) {
  1678       if (child->HasTextForTranslation()) {
  1679         translationNodesHash.PutEntry(content);
  1681         bool isBlockFrame = false;
  1682         nsIFrame* frame = content->GetPrimaryFrame();
  1683         if (frame) {
  1684           isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame);
  1687         bool isTranslationRoot = isBlockFrame;
  1688         if (!isBlockFrame) {
  1689           // If an element is not a block element, it still
  1690           // can be considered a translation root if the parent
  1691           // of this element didn't make into the list of nodes
  1692           // to be translated.
  1693           bool parentInList = false;
  1694           nsIContent* parent = content->GetParent();
  1695           if (parent) {
  1696             parentInList = translationNodesHash.Contains(parent);
  1698           isTranslationRoot = !parentInList;
  1701         list->AppendElement(content->AsDOMNode(), isTranslationRoot);
  1702         --limit;
  1703         break;
  1708   *aRetVal = list.forget().take();
  1709   return NS_OK;
  1712 static TemporaryRef<DataSourceSurface>
  1713 CanvasToDataSourceSurface(nsIDOMHTMLCanvasElement* aCanvas)
  1715   nsCOMPtr<nsINode> node = do_QueryInterface(aCanvas);
  1716   if (!node) {
  1717     return nullptr;
  1720   NS_ABORT_IF_FALSE(node->IsElement(),
  1721                     "An nsINode that implements nsIDOMHTMLCanvasElement should "
  1722                     "be an element.");
  1723   nsLayoutUtils::SurfaceFromElementResult result =
  1724     nsLayoutUtils::SurfaceFromElement(node->AsElement());
  1725   return result.mSourceSurface->GetDataSurface();
  1728 NS_IMETHODIMP
  1729 nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
  1730                                   nsIDOMHTMLCanvasElement *aCanvas2,
  1731                                   uint32_t* aMaxDifference,
  1732                                   uint32_t* retVal)
  1734   if (!nsContentUtils::IsCallerChrome()) {
  1735     return NS_ERROR_DOM_SECURITY_ERR;
  1738   if (aCanvas1 == nullptr ||
  1739       aCanvas2 == nullptr ||
  1740       retVal == nullptr)
  1741     return NS_ERROR_FAILURE;
  1743   RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(aCanvas1);
  1744   RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(aCanvas2);
  1746   if (img1 == nullptr || img2 == nullptr ||
  1747       img1->GetSize() != img2->GetSize() ||
  1748       img1->Stride() != img2->Stride())
  1749     return NS_ERROR_FAILURE;
  1751   int v;
  1752   IntSize size = img1->GetSize();
  1753   uint32_t stride = img1->Stride();
  1755   // we can optimize for the common all-pass case
  1756   if (stride == (uint32_t) size.width * 4) {
  1757     v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4);
  1758     if (v == 0) {
  1759       if (aMaxDifference)
  1760         *aMaxDifference = 0;
  1761       *retVal = 0;
  1762       return NS_OK;
  1766   uint32_t dc = 0;
  1767   uint32_t different = 0;
  1769   for (int j = 0; j < size.height; j++) {
  1770     unsigned char *p1 = img1->GetData() + j*stride;
  1771     unsigned char *p2 = img2->GetData() + j*stride;
  1772     v = memcmp(p1, p2, stride);
  1774     if (v) {
  1775       for (int i = 0; i < size.width; i++) {
  1776         if (*(uint32_t*) p1 != *(uint32_t*) p2) {
  1778           different++;
  1780           dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc);
  1781           dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc);
  1782           dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc);
  1783           dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc);
  1786         p1 += 4;
  1787         p2 += 4;
  1792   if (aMaxDifference)
  1793     *aMaxDifference = dc;
  1795   *retVal = different;
  1796   return NS_OK;
  1799 NS_IMETHODIMP
  1800 nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
  1802   if (!nsContentUtils::IsCallerChrome()) {
  1803     return NS_ERROR_DOM_SECURITY_ERR;
  1806   NS_ENSURE_ARG_POINTER(aResult);
  1807   *aResult = false;
  1808   nsPresContext* presContext = GetPresContext();
  1809   if (!presContext)
  1810     return NS_OK;
  1811   *aResult = presContext->IsDOMPaintEventPending();
  1812   return NS_OK;
  1815 NS_IMETHODIMP
  1816 nsDOMWindowUtils::ClearMozAfterPaintEvents()
  1818   if (!nsContentUtils::IsCallerChrome()) {
  1819     return NS_ERROR_DOM_SECURITY_ERR;
  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   if (!nsContentUtils::IsCallerChrome()) {
  1833     return NS_ERROR_DOM_SECURITY_ERR;
  1836   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1837   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1838   nsIDocShell *docShell = window->GetDocShell();
  1839   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
  1840   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  1841   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  1842   presShell->DisableNonTestMouseEvents(aDisable);
  1843   return NS_OK;
  1846 NS_IMETHODIMP
  1847 nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
  1849   if (!nsContentUtils::IsCallerChrome()) {
  1850     return NS_ERROR_DOM_SECURITY_ERR;
  1853   nsCOMPtr<nsIDocument> doc = GetDocument();
  1854   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  1856   if (aSuppress) {
  1857     doc->SuppressEventHandling(nsIDocument::eEvents);
  1858   } else {
  1859     doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true);
  1862   return NS_OK;
  1865 static nsresult
  1866 getScrollXYAppUnits(nsWeakPtr aWindow, bool aFlushLayout, nsPoint& aScrollPos) {
  1867   if (!nsContentUtils::IsCallerChrome()) {
  1868     return NS_ERROR_DOM_SECURITY_ERR;
  1871   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(aWindow);
  1872   nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr;
  1873   NS_ENSURE_STATE(doc);
  1875   if (aFlushLayout) {
  1876     doc->FlushPendingNotifications(Flush_Layout);
  1879   nsIPresShell *presShell = doc->GetShell();
  1880   if (presShell) {
  1881     nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
  1882     if (sf) {
  1883       aScrollPos = sf->GetScrollPosition();
  1886   return NS_OK;
  1889 NS_IMETHODIMP
  1890 nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
  1892   nsPoint scrollPos(0,0);
  1893   nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
  1894   NS_ENSURE_SUCCESS(rv, rv);
  1895   *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
  1896   *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
  1898   return NS_OK;
  1901 NS_IMETHODIMP
  1902 nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY)
  1904   nsPoint scrollPos(0,0);
  1905   nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
  1906   NS_ENSURE_SUCCESS(rv, rv);
  1907   *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x);
  1908   *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y);
  1910   return NS_OK;
  1913 NS_IMETHODIMP
  1914 nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
  1915                                                       int32_t* aHeight)
  1917   if (!nsContentUtils::IsCallerChrome()) {
  1918     return NS_ERROR_DOM_SECURITY_ERR;
  1921   *aWidth = 0;
  1922   *aHeight = 0;
  1924   nsCOMPtr<nsIDocument> doc = GetDocument();
  1925   NS_ENSURE_STATE(doc);
  1927   if (aFlushLayout) {
  1928     doc->FlushPendingNotifications(Flush_Layout);
  1931   nsIPresShell* presShell = doc->GetShell();
  1932   NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
  1934   nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
  1935   NS_ENSURE_TRUE(scrollFrame, NS_OK);
  1937   nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
  1938   *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
  1939   *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
  1941   return NS_OK;
  1944 NS_IMETHODIMP
  1945 nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement,
  1946                                            nsIDOMClientRect** aResult)
  1948   if (!nsContentUtils::IsCallerChrome()) {
  1949     return NS_ERROR_DOM_SECURITY_ERR;
  1952   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1953   NS_ENSURE_STATE(window);
  1955   nsresult rv;
  1956   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  1957   NS_ENSURE_SUCCESS(rv, rv);
  1959   nsRefPtr<DOMRect> rect = new DOMRect(window);
  1960   nsIFrame* frame = content->GetPrimaryFrame();
  1962   if (frame) {
  1963     nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
  1964                nsLayoutUtils::GetContainingBlockForClientRect(frame),
  1965                nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
  1966     rect->SetLayoutRect(r);
  1969   rect.forget(aResult);
  1970   return NS_OK;
  1973 NS_IMETHODIMP
  1974 nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
  1976   if (!nsContentUtils::IsCallerChrome()) {
  1977     return NS_ERROR_DOM_SECURITY_ERR;
  1980   nsIDocument* doc = GetDocument();
  1981   NS_ENSURE_STATE(doc);
  1983   nsRect bounds(0, 0, 0, 0);
  1984   nsIPresShell* presShell = doc->GetShell();
  1985   if (presShell) {
  1986     nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
  1987     if (sf) {
  1988       bounds = sf->GetScrollRange();
  1989       bounds.width += sf->GetScrollPortRect().width;
  1990       bounds.height += sf->GetScrollPortRect().height;
  1991     } else if (presShell->GetRootFrame()) {
  1992       bounds = presShell->GetRootFrame()->GetRect();
  1996   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1997   nsRefPtr<DOMRect> rect = new DOMRect(window);
  1998   rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x),
  1999                 nsPresContext::AppUnitsToFloatCSSPixels(bounds.y),
  2000                 nsPresContext::AppUnitsToFloatCSSPixels(bounds.width),
  2001                 nsPresContext::AppUnitsToFloatCSSPixels(bounds.height));
  2002   rect.forget(aResult);
  2003   return NS_OK;
  2006 NS_IMETHODIMP
  2007 nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
  2009   if (!nsContentUtils::IsCallerChrome()) {
  2010     return NS_ERROR_DOM_SECURITY_ERR;
  2013   NS_ENSURE_ARG_POINTER(aState);
  2015   nsCOMPtr<nsIWidget> widget = GetWidget();
  2016   if (!widget)
  2017     return NS_ERROR_FAILURE;
  2019   // Open state should not be available when IME is not enabled.
  2020   InputContext context = widget->GetInputContext();
  2021   if (context.mIMEState.mEnabled != IMEState::ENABLED) {
  2022     return NS_ERROR_NOT_AVAILABLE;
  2025   if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
  2026     return NS_ERROR_NOT_IMPLEMENTED;
  2028   *aState = (context.mIMEState.mOpen == IMEState::OPEN);
  2029   return NS_OK;
  2032 NS_IMETHODIMP
  2033 nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
  2035   if (!nsContentUtils::IsCallerChrome()) {
  2036     return NS_ERROR_DOM_SECURITY_ERR;
  2039   NS_ENSURE_ARG_POINTER(aState);
  2041   nsCOMPtr<nsIWidget> widget = GetWidget();
  2042   if (!widget)
  2043     return NS_ERROR_FAILURE;
  2045   InputContext context = widget->GetInputContext();
  2046   *aState = static_cast<uint32_t>(context.mIMEState.mEnabled);
  2047   return NS_OK;
  2050 NS_IMETHODIMP
  2051 nsDOMWindowUtils::GetFocusedInputType(char** aType)
  2053   if (!nsContentUtils::IsCallerChrome()) {
  2054     return NS_ERROR_DOM_SECURITY_ERR;
  2057   NS_ENSURE_ARG_POINTER(aType);
  2059   nsCOMPtr<nsIWidget> widget = GetWidget();
  2060   if (!widget) {
  2061     return NS_ERROR_FAILURE;
  2064   InputContext context = widget->GetInputContext();
  2065   *aType = ToNewCString(context.mHTMLInputType);
  2066   return NS_OK;
  2069 NS_IMETHODIMP
  2070 nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
  2071                                         nsIDOMElement** aResult)
  2073   if (!nsContentUtils::IsCallerChrome()) {
  2074     return NS_ERROR_DOM_SECURITY_ERR;
  2077   nsRefPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aID);
  2078   return content ? CallQueryInterface(content, aResult) : NS_OK;
  2081 NS_IMETHODIMP
  2082 nsDOMWindowUtils::GetViewId(nsIDOMElement* aElement, nsViewID* aResult)
  2084   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  2085   if (content && nsLayoutUtils::FindIDFor(content, aResult)) {
  2086     return NS_OK;
  2088   return NS_ERROR_NOT_AVAILABLE;
  2091 NS_IMETHODIMP
  2092 nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
  2094   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2095   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  2096   return window->GetDevicePixelRatio(aScreenPixels);
  2099 NS_IMETHODIMP
  2100 nsDOMWindowUtils::GetFullZoom(float* aFullZoom)
  2102   *aFullZoom = 1.0f;
  2104   if (!nsContentUtils::IsCallerChrome()) {
  2105     return NS_ERROR_DOM_SECURITY_ERR;
  2108   nsPresContext* presContext = GetPresContext();
  2109   if (!presContext) {
  2110     return NS_OK;
  2113   *aFullZoom = presContext->DeviceContext()->GetPixelScale();
  2115   return NS_OK;
  2118 NS_IMETHODIMP
  2119 nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
  2120                                                nsIDOMEvent* aEvent,
  2121                                                bool aTrusted,
  2122                                                bool* aRetVal)
  2124   if (!nsContentUtils::IsCallerChrome()) {
  2125     return NS_ERROR_DOM_SECURITY_ERR;
  2128   NS_ENSURE_STATE(aEvent);
  2129   aEvent->SetTrusted(aTrusted);
  2130   WidgetEvent* internalEvent = aEvent->GetInternalNSEvent();
  2131   NS_ENSURE_STATE(internalEvent);
  2132   nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
  2133   NS_ENSURE_STATE(content);
  2134   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2135   if (content->OwnerDoc()->GetWindow() != window) {
  2136     return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
  2138   nsCOMPtr<nsIDocument> targetDoc = content->GetCurrentDoc();
  2139   NS_ENSURE_STATE(targetDoc);
  2140   nsRefPtr<nsIPresShell> targetShell = targetDoc->GetShell();
  2141   NS_ENSURE_STATE(targetShell);
  2143   targetDoc->FlushPendingNotifications(Flush_Layout);
  2145   nsEventStatus status = nsEventStatus_eIgnore;
  2146   targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status);
  2147   *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
  2148   return NS_OK;
  2151 static void
  2152 InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr)
  2154   if (aPt) {
  2155     aEvent.refPoint = *aPt;
  2157   aEvent.time = PR_IntervalNow();
  2160 NS_IMETHODIMP
  2161 nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType,
  2162                                        const nsAString& aData,
  2163                                        const nsAString& aLocale)
  2165   if (!nsContentUtils::IsCallerChrome()) {
  2166     return NS_ERROR_DOM_SECURITY_ERR;
  2169   // get the widget to send the event to
  2170   nsCOMPtr<nsIWidget> widget = GetWidget();
  2171   if (!widget) {
  2172     return NS_ERROR_FAILURE;
  2175   uint32_t msg;
  2176   if (aType.EqualsLiteral("compositionstart")) {
  2177     msg = NS_COMPOSITION_START;
  2178   } else if (aType.EqualsLiteral("compositionend")) {
  2179     msg = NS_COMPOSITION_END;
  2180   } else if (aType.EqualsLiteral("compositionupdate")) {
  2181     msg = NS_COMPOSITION_UPDATE;
  2182   } else {
  2183     return NS_ERROR_FAILURE;
  2186   WidgetCompositionEvent compositionEvent(true, msg, widget);
  2187   InitEvent(compositionEvent);
  2188   if (msg != NS_COMPOSITION_START) {
  2189     compositionEvent.data = aData;
  2192   compositionEvent.mFlags.mIsSynthesizedForTests = true;
  2194   nsEventStatus status;
  2195   nsresult rv = widget->DispatchEvent(&compositionEvent, status);
  2196   NS_ENSURE_SUCCESS(rv, rv);
  2198   return NS_OK;
  2201 NS_IMETHODIMP
  2202 nsDOMWindowUtils::CreateCompositionStringSynthesizer(
  2203                     nsICompositionStringSynthesizer** aResult)
  2205   NS_ENSURE_ARG_POINTER(aResult);
  2206   *aResult = nullptr;
  2208   if (!nsContentUtils::IsCallerChrome()) {
  2209     return NS_ERROR_DOM_SECURITY_ERR;
  2212   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2213   NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
  2215   NS_ADDREF(*aResult = new CompositionStringSynthesizer(window));
  2216   return NS_OK;
  2219 NS_IMETHODIMP
  2220 nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
  2221                                         uint32_t aOffset, uint32_t aLength,
  2222                                         int32_t aX, int32_t aY,
  2223                                         uint32_t aAdditionalFlags,
  2224                                         nsIQueryContentEventResult **aResult)
  2226   *aResult = nullptr;
  2228   if (!nsContentUtils::IsCallerChrome()) {
  2229     return NS_ERROR_DOM_SECURITY_ERR;
  2232   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2233   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  2235   nsIDocShell *docShell = window->GetDocShell();
  2236   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
  2238   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  2239   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  2241   nsPresContext* presContext = presShell->GetPresContext();
  2242   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
  2244   // get the widget to send the event to
  2245   nsCOMPtr<nsIWidget> widget = GetWidget();
  2246   if (!widget) {
  2247     return NS_ERROR_FAILURE;
  2250   if (aType != NS_QUERY_SELECTED_TEXT &&
  2251       aType != NS_QUERY_TEXT_CONTENT &&
  2252       aType != NS_QUERY_CARET_RECT &&
  2253       aType != NS_QUERY_TEXT_RECT &&
  2254       aType != NS_QUERY_EDITOR_RECT &&
  2255       aType != NS_QUERY_CHARACTER_AT_POINT) {
  2256     return NS_ERROR_INVALID_ARG;
  2259   nsCOMPtr<nsIWidget> targetWidget = widget;
  2260   LayoutDeviceIntPoint pt(aX, aY);
  2262   bool useNativeLineBreak =
  2263     !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
  2265   if (aType == QUERY_CHARACTER_AT_POINT) {
  2266     // Looking for the widget at the point.
  2267     WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
  2268     dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
  2269     InitEvent(dummyEvent, &pt);
  2270     nsIFrame* popupFrame =
  2271       nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
  2273     nsIntRect widgetBounds;
  2274     nsresult rv = widget->GetClientBounds(widgetBounds);
  2275     NS_ENSURE_SUCCESS(rv, rv);
  2276     widgetBounds.MoveTo(0, 0);
  2278     // There is no popup frame at the point and the point isn't in our widget,
  2279     // we cannot process this request.
  2280     NS_ENSURE_TRUE(popupFrame ||
  2281                    widgetBounds.Contains(LayoutDeviceIntPoint::ToUntyped(pt)),
  2282                    NS_ERROR_FAILURE);
  2284     // Fire the event on the widget at the point
  2285     if (popupFrame) {
  2286       targetWidget = popupFrame->GetNearestWidget();
  2290   pt += LayoutDeviceIntPoint::FromUntyped(
  2291     widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset());
  2293   WidgetQueryContentEvent queryEvent(true, aType, targetWidget);
  2294   InitEvent(queryEvent, &pt);
  2296   switch (aType) {
  2297     case NS_QUERY_TEXT_CONTENT:
  2298       queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
  2299       break;
  2300     case NS_QUERY_CARET_RECT:
  2301       queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
  2302       break;
  2303     case NS_QUERY_TEXT_RECT:
  2304       queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak);
  2305       break;
  2306     default:
  2307       queryEvent.mUseNativeLineBreak = useNativeLineBreak;
  2308       break;
  2311   nsEventStatus status;
  2312   nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
  2313   NS_ENSURE_SUCCESS(rv, rv);
  2315   nsQueryContentEventResult* result = new nsQueryContentEventResult();
  2316   NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
  2317   result->SetEventResult(widget, queryEvent);
  2318   NS_ADDREF(*aResult = result);
  2319   return NS_OK;
  2322 NS_IMETHODIMP
  2323 nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
  2324                                         uint32_t aLength,
  2325                                         uint32_t aAdditionalFlags,
  2326                                         bool *aResult)
  2328   *aResult = false;
  2330   if (!nsContentUtils::IsCallerChrome()) {
  2331     return NS_ERROR_DOM_SECURITY_ERR;
  2334   // get the widget to send the event to
  2335   nsCOMPtr<nsIWidget> widget = GetWidget();
  2336   if (!widget) {
  2337     return NS_ERROR_FAILURE;
  2340   WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
  2341   InitEvent(selectionEvent);
  2343   selectionEvent.mOffset = aOffset;
  2344   selectionEvent.mLength = aLength;
  2345   selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
  2346   selectionEvent.mUseNativeLineBreak =
  2347     !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
  2349   nsEventStatus status;
  2350   nsresult rv = widget->DispatchEvent(&selectionEvent, status);
  2351   NS_ENSURE_SUCCESS(rv, rv);
  2353   *aResult = selectionEvent.mSucceeded;
  2354   return NS_OK;
  2357 NS_IMETHODIMP
  2358 nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
  2359                                           nsITransferable * aTransferable)
  2361   if (!nsContentUtils::IsCallerChrome()) {
  2362     return NS_ERROR_DOM_SECURITY_ERR;
  2365   // get the widget to send the event to
  2366   nsCOMPtr<nsIWidget> widget = GetWidget();
  2367   if (!widget)
  2368     return NS_ERROR_FAILURE;
  2370   int32_t msg;
  2371   if (aType.EqualsLiteral("cut"))
  2372     msg = NS_CONTENT_COMMAND_CUT;
  2373   else if (aType.EqualsLiteral("copy"))
  2374     msg = NS_CONTENT_COMMAND_COPY;
  2375   else if (aType.EqualsLiteral("paste"))
  2376     msg = NS_CONTENT_COMMAND_PASTE;
  2377   else if (aType.EqualsLiteral("delete"))
  2378     msg = NS_CONTENT_COMMAND_DELETE;
  2379   else if (aType.EqualsLiteral("undo"))
  2380     msg = NS_CONTENT_COMMAND_UNDO;
  2381   else if (aType.EqualsLiteral("redo"))
  2382     msg = NS_CONTENT_COMMAND_REDO;
  2383   else if (aType.EqualsLiteral("pasteTransferable"))
  2384     msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
  2385   else
  2386     return NS_ERROR_FAILURE;
  2388   WidgetContentCommandEvent event(true, msg, widget);
  2389   if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
  2390     event.mTransferable = aTransferable;
  2393   nsEventStatus status;
  2394   return widget->DispatchEvent(&event, status);
  2397 NS_IMETHODIMP
  2398 nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
  2399                                char** aName)
  2401   if (!nsContentUtils::IsCallerChrome()) {
  2402     return NS_ERROR_DOM_SECURITY_ERR;
  2405   // Our argument must be a non-null object.
  2406   if (JSVAL_IS_PRIMITIVE(aObject)) {
  2407     return NS_ERROR_XPC_BAD_CONVERT_JS;
  2410   *aName = NS_strdup(JS_GetClass(JSVAL_TO_OBJECT(aObject))->name);
  2411   NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
  2412   return NS_OK;
  2415 NS_IMETHODIMP
  2416 nsDOMWindowUtils::GetVisitedDependentComputedStyle(
  2417                     nsIDOMElement *aElement, const nsAString& aPseudoElement,
  2418                     const nsAString& aPropertyName, nsAString& aResult)
  2420   aResult.Truncate();
  2422   if (!nsContentUtils::IsCallerChrome()) {
  2423     return NS_ERROR_DOM_SECURITY_ERR;
  2426   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2427   NS_ENSURE_STATE(window);
  2429   nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
  2430   nsresult rv =
  2431     window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
  2432   NS_ENSURE_SUCCESS(rv, rv);
  2434   static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
  2435   rv = decl->GetPropertyValue(aPropertyName, aResult);
  2436   static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
  2438   return rv;
  2441 NS_IMETHODIMP
  2442 nsDOMWindowUtils::EnterModalState()
  2444   if (!nsContentUtils::IsCallerChrome()) {
  2445     return NS_ERROR_DOM_SECURITY_ERR;
  2448   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2449   NS_ENSURE_STATE(window);
  2451   window->EnterModalState();
  2452   return NS_OK;
  2455 NS_IMETHODIMP
  2456 nsDOMWindowUtils::LeaveModalState()
  2458   if (!nsContentUtils::IsCallerChrome()) {
  2459     return NS_ERROR_DOM_SECURITY_ERR;
  2462   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2463   NS_ENSURE_STATE(window);
  2465   window->LeaveModalState();
  2466   return NS_OK;
  2469 NS_IMETHODIMP
  2470 nsDOMWindowUtils::IsInModalState(bool *retval)
  2472   if (!nsContentUtils::IsCallerChrome()) {
  2473     return NS_ERROR_DOM_SECURITY_ERR;
  2476   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2477   NS_ENSURE_STATE(window);
  2479   *retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
  2480   return NS_OK;
  2483 NS_IMETHODIMP
  2484 nsDOMWindowUtils::GetParent(JS::Handle<JS::Value> aObject,
  2485                             JSContext* aCx,
  2486                             JS::MutableHandle<JS::Value> aParent)
  2488   if (!nsContentUtils::IsCallerChrome()) {
  2489     return NS_ERROR_DOM_SECURITY_ERR;
  2492   // First argument must be an object.
  2493   if (aObject.isPrimitive()) {
  2494     return NS_ERROR_XPC_BAD_CONVERT_JS;
  2497   JS::Rooted<JSObject*> parent(aCx, JS_GetParent(&aObject.toObject()));
  2499   // Outerize if necessary.
  2500   if (parent) {
  2501     if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
  2502       parent = outerize(aCx, parent);
  2506   aParent.setObject(*parent);
  2507   return NS_OK;
  2510 NS_IMETHODIMP
  2511 nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
  2513   if (!nsContentUtils::IsCallerChrome()) {
  2514     return NS_ERROR_DOM_SECURITY_ERR;
  2517   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2518   NS_ENSURE_STATE(window);
  2520   NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
  2521   *aWindowID = window->WindowID();
  2522   return NS_OK;
  2525 NS_IMETHODIMP
  2526 nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID)
  2528   if (!nsContentUtils::IsCallerChrome()) {
  2529     return NS_ERROR_DOM_SECURITY_ERR;
  2532   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2533   NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
  2535   NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
  2536   nsGlobalWindow* inner =
  2537     static_cast<nsGlobalWindow*>(window.get())->GetCurrentInnerWindowInternal();
  2538   if (!inner) {
  2539     return NS_ERROR_NOT_AVAILABLE;
  2541   *aWindowID = inner->WindowID();
  2542   return NS_OK;
  2545 NS_IMETHODIMP
  2546 nsDOMWindowUtils::SuspendTimeouts()
  2548   if (!nsContentUtils::IsCallerChrome()) {
  2549     return NS_ERROR_DOM_SECURITY_ERR;
  2552   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2553   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  2555   window->SuspendTimeouts();
  2557   return NS_OK;
  2560 NS_IMETHODIMP
  2561 nsDOMWindowUtils::ResumeTimeouts()
  2563   if (!nsContentUtils::IsCallerChrome()) {
  2564     return NS_ERROR_DOM_SECURITY_ERR;
  2567   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2568   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  2570   window->ResumeTimeouts();
  2572   return NS_OK;
  2575 NS_IMETHODIMP
  2576 nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
  2578   if (!nsContentUtils::IsCallerChrome()) {
  2579     return NS_ERROR_DOM_SECURITY_ERR;
  2582   nsCOMPtr<nsIWidget> widget = GetWidget();
  2583   if (!widget)
  2584     return NS_ERROR_FAILURE;
  2586   LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT);
  2587   if (!mgr)
  2588     return NS_ERROR_FAILURE;
  2590   mgr->GetBackendName(aType);
  2592   return NS_OK;
  2595 NS_IMETHODIMP
  2596 nsDOMWindowUtils::GetLayerManagerRemote(bool* retval)
  2598   if (!nsContentUtils::IsCallerChrome()) {
  2599     return NS_ERROR_DOM_SECURITY_ERR;
  2602   nsCOMPtr<nsIWidget> widget = GetWidget();
  2603   if (!widget)
  2604     return NS_ERROR_FAILURE;
  2606   LayerManager *mgr = widget->GetLayerManager();
  2607   if (!mgr)
  2608     return NS_ERROR_FAILURE;
  2610   *retval = !!mgr->AsShadowForwarder();
  2611   return NS_OK;
  2614 NS_IMETHODIMP
  2615 nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
  2617   if (!nsContentUtils::IsCallerChrome()) {
  2618     return NS_ERROR_DOM_SECURITY_ERR;
  2621   NS_ENSURE_ARG_POINTER(startIndex);
  2623   nsCOMPtr<nsIWidget> widget = GetWidget();
  2624   if (!widget)
  2625     return NS_ERROR_FAILURE;
  2627   LayerManager *mgr = widget->GetLayerManager();
  2628   if (!mgr)
  2629     return NS_ERROR_FAILURE;
  2631   const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
  2632   const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
  2633   uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
  2634   bufferSize = std::min(bufferSize, kRecordingMaxSize);
  2635   bufferSize = std::max(bufferSize, kRecordingMinSize);
  2636   *startIndex = mgr->StartFrameTimeRecording(bufferSize);
  2638   return NS_OK;
  2641 NS_IMETHODIMP
  2642 nsDOMWindowUtils::StopFrameTimeRecording(uint32_t   startIndex,
  2643                                          uint32_t  *frameCount,
  2644                                          float    **frameIntervals)
  2646   if (!nsContentUtils::IsCallerChrome()) {
  2647     return NS_ERROR_DOM_SECURITY_ERR;
  2650   NS_ENSURE_ARG_POINTER(frameCount);
  2651   NS_ENSURE_ARG_POINTER(frameIntervals);
  2653   nsCOMPtr<nsIWidget> widget = GetWidget();
  2654   if (!widget)
  2655     return NS_ERROR_FAILURE;
  2657   LayerManager *mgr = widget->GetLayerManager();
  2658   if (!mgr)
  2659     return NS_ERROR_FAILURE;
  2661   nsTArray<float> tmpFrameIntervals;
  2662   mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
  2663   *frameCount = tmpFrameIntervals.Length();
  2665   *frameIntervals = (float*)nsMemory::Alloc(*frameCount * sizeof(float));
  2667   /* copy over the frame intervals and paint times into the arrays we just allocated */
  2668   for (uint32_t i = 0; i < *frameCount; i++) {
  2669     (*frameIntervals)[i] = tmpFrameIntervals[i];
  2672   return NS_OK;
  2675 NS_IMETHODIMP
  2676 nsDOMWindowUtils::BeginTabSwitch()
  2678   if (!nsContentUtils::IsCallerChrome()) {
  2679     return NS_ERROR_DOM_SECURITY_ERR;
  2682   nsCOMPtr<nsIWidget> widget = GetWidget();
  2683   if (!widget)
  2684     return NS_ERROR_FAILURE;
  2686   LayerManager *mgr = widget->GetLayerManager();
  2687   if (!mgr)
  2688     return NS_ERROR_FAILURE;
  2690   mgr->BeginTabSwitch();
  2692   return NS_OK;
  2695 static bool
  2696 ComputeAnimationValue(nsCSSProperty aProperty,
  2697                       Element* aElement,
  2698                       const nsAString& aInput,
  2699                       nsStyleAnimation::Value& aOutput)
  2702   if (!nsStyleAnimation::ComputeValue(aProperty, aElement, aInput,
  2703                                       false, aOutput)) {
  2704     return false;
  2707   // This matches TransExtractComputedValue in nsTransitionManager.cpp.
  2708   if (aProperty == eCSSProperty_visibility) {
  2709     NS_ABORT_IF_FALSE(aOutput.GetUnit() == nsStyleAnimation::eUnit_Enumerated,
  2710                       "unexpected unit");
  2711     aOutput.SetIntValue(aOutput.GetIntValue(),
  2712                         nsStyleAnimation::eUnit_Visibility);
  2715   return true;
  2718 NS_IMETHODIMP
  2719 nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
  2721   if (!nsContentUtils::IsCallerChrome()) {
  2722     return NS_ERROR_DOM_SECURITY_ERR;
  2725   nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
  2726   driver->AdvanceTimeAndRefresh(aMilliseconds);
  2728   LayerTransactionChild* transaction = GetLayerTransaction();
  2729   if (transaction) {
  2730     transaction->SendSetTestSampleTime(driver->MostRecentRefresh());
  2733   return NS_OK;
  2736 NS_IMETHODIMP
  2737 nsDOMWindowUtils::RestoreNormalRefresh()
  2739   if (!nsContentUtils::IsCallerChrome()) {
  2740     return NS_ERROR_DOM_SECURITY_ERR;
  2743   // Kick the compositor out of test mode before the refresh driver, so that
  2744   // the refresh driver doesn't send an update that gets ignored by the
  2745   // compositor.
  2746   LayerTransactionChild* transaction = GetLayerTransaction();
  2747   if (transaction) {
  2748     transaction->SendLeaveTestMode();
  2751   nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
  2752   driver->RestoreNormalRefresh();
  2754   return NS_OK;
  2757 NS_IMETHODIMP
  2758 nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult)
  2760   if (!nsContentUtils::IsCallerChrome()) {
  2761     return NS_ERROR_DOM_SECURITY_ERR;
  2764   nsPresContext* pc = GetPresContext();
  2765   *aResult =
  2766     pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
  2768   return NS_OK;
  2771 NS_IMETHODIMP
  2772 nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
  2773                                        int32_t aX, int32_t aY)
  2775   nsCOMPtr<Element> element = do_QueryInterface(aNode);
  2776   if (!element) {
  2777     return NS_ERROR_INVALID_ARG;
  2779   nsIFrame* frame = element->GetPrimaryFrame();
  2780   if (!frame) {
  2781     return NS_ERROR_UNEXPECTED;
  2783   nsIScrollableFrame* scrollable = do_QueryFrame(frame);
  2784   nsPresContext* presContext = frame->PresContext();
  2785   nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
  2786   if (!scrollable) {
  2787     if (rootScrollFrame && rootScrollFrame->GetContent() == element) {
  2788       frame = rootScrollFrame;
  2789       scrollable = do_QueryFrame(frame);
  2792   if (!scrollable) {
  2793     return NS_ERROR_UNEXPECTED;
  2795   Layer* layer = FrameLayerBuilder::GetDedicatedLayer(scrollable->GetScrolledFrame(),
  2796     nsDisplayItem::TYPE_SCROLL_LAYER);
  2797   if (!layer) {
  2798     if (rootScrollFrame == frame && !presContext->GetParentPresContext()) {
  2799       nsIWidget* widget = GetWidget();
  2800       if (widget) {
  2801         LayerManager* manager = widget->GetLayerManager();
  2802         if (manager) {
  2803           layer = manager->GetRoot();
  2807     if (!layer) {
  2808       return NS_ERROR_UNEXPECTED;
  2811   ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
  2812   if (!forwarder || !forwarder->HasShadowManager()) {
  2813     return NS_ERROR_UNEXPECTED;
  2815   forwarder->GetShadowManager()->SendSetAsyncScrollOffset(
  2816     layer->AsShadowableLayer()->GetShadow(), aX, aY);
  2817   return NS_OK;
  2820 NS_IMETHODIMP
  2821 nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
  2822                                            const nsAString& aProperty,
  2823                                            const nsAString& aValue1,
  2824                                            const nsAString& aValue2,
  2825                                            double* aResult)
  2827   if (!nsContentUtils::IsCallerChrome()) {
  2828     return NS_ERROR_DOM_SECURITY_ERR;
  2831   nsresult rv;
  2832   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  2833   NS_ENSURE_SUCCESS(rv, rv);
  2835   // Convert direction-dependent properties as appropriate, e.g.,
  2836   // border-left to border-left-value.
  2837   nsCSSProperty property =
  2838     nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState);
  2839   if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
  2840     nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
  2841     if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
  2842         nsCSSProps::OtherNameFor(subprop0) == property) {
  2843       property = subprop0;
  2844     } else {
  2845       property = eCSSProperty_UNKNOWN;
  2849   NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
  2850                     !nsCSSProps::IsShorthand(property),
  2851                     "should not have shorthand");
  2853   nsStyleAnimation::Value v1, v2;
  2854   if (property == eCSSProperty_UNKNOWN ||
  2855       !ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
  2856       !ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
  2857     return NS_ERROR_ILLEGAL_VALUE;
  2860   if (!nsStyleAnimation::ComputeDistance(property, v1, v2, *aResult)) {
  2861     return NS_ERROR_FAILURE;
  2864   return NS_OK;
  2867 nsresult
  2868 nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
  2869                                  uint32_t aFlags,
  2870                                  nscolor aBackgroundColor,
  2871                                  gfxContext* aThebesContext)
  2873     if (!nsContentUtils::IsCallerChrome()) {
  2874       return NS_ERROR_DOM_SECURITY_ERR;
  2877     nsCOMPtr<nsIDocument> doc = GetDocument();
  2878     NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  2880     // Get Primary Shell
  2881     nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
  2882     NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  2884     // Render Document
  2885     return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
  2888 NS_IMETHODIMP 
  2889 nsDOMWindowUtils::GetCursorType(int16_t *aCursor)
  2891   if (!nsContentUtils::IsCallerChrome()) {
  2892     return NS_ERROR_DOM_SECURITY_ERR;
  2895   NS_ENSURE_ARG_POINTER(aCursor);
  2897   nsIDocument* doc = GetDocument();
  2898   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  2900   bool isSameDoc = false;
  2901   do {
  2902     if (EventStateManager::sMouseOverDocument == doc) {
  2903       isSameDoc = true;
  2904       break;
  2906   } while ((doc = doc->GetParentDocument()));
  2908   if (!isSameDoc) {
  2909     *aCursor = eCursor_none;
  2910     return NS_OK;
  2913   nsCOMPtr<nsIWidget> widget = GetWidget();
  2914   if (!widget)
  2915     return NS_ERROR_FAILURE;
  2917   // fetch cursor value from window's widget
  2918   *aCursor = widget->GetCursor();
  2920   return NS_OK;
  2923 NS_IMETHODIMP
  2924 nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
  2926   if (!nsContentUtils::IsCallerChrome()) {
  2927     return NS_ERROR_DOM_SECURITY_ERR;
  2930   nsCOMPtr<nsIWidget> widget = GetWidget();
  2931   if (!widget)
  2932     return NS_ERROR_FAILURE;
  2934   *aDPI = widget->GetDPI();
  2936   return NS_OK;
  2940 NS_IMETHODIMP
  2941 nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID,
  2942                                        nsIDOMWindow** aWindow)
  2944   if (!nsContentUtils::IsCallerChrome()) {
  2945     return NS_ERROR_DOM_SECURITY_ERR;
  2948   // XXX This method is deprecated.  See bug 865664.
  2949   nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
  2950                                   NS_LITERAL_CSTRING("DOM"),
  2951                                   nsContentUtils::GetDocumentFromCaller(),
  2952                                   nsContentUtils::eDOM_PROPERTIES,
  2953                                   "GetWindowWithOuterIdWarning");
  2955   *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
  2956   NS_IF_ADDREF(*aWindow);
  2957   return NS_OK;
  2960 NS_IMETHODIMP
  2961 nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult)
  2963   if (!nsContentUtils::IsCallerChrome()) {
  2964     return NS_ERROR_DOM_SECURITY_ERR;
  2967   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  2968   NS_ENSURE_STATE(window);
  2970   nsCOMPtr<nsIDOMElement> element =
  2971     do_QueryInterface(window->GetFrameElementInternal());
  2973   element.forget(aResult);
  2974   return NS_OK;
  2977 NS_IMETHODIMP
  2978 nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
  2979                               nsIDOMFile **aDOMFile)
  2981   if (!nsContentUtils::IsCallerChrome()) {
  2982     return NS_ERROR_DOM_SECURITY_ERR;
  2985   if (!aFile) {
  2986     return NS_ERROR_FAILURE;
  2989   NS_ADDREF(*aDOMFile = new nsDOMFileFile(aFile));
  2990   return NS_OK;
  2993 #ifdef DEBUG
  2994 static bool
  2995 CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
  2997   gfx::Matrix transform;
  2998   if (!aLayer->GetTransform().Is2D(&transform) ||
  2999       transform.HasNonIntegerTranslation())
  3000     return false;
  3001   transform.NudgeToIntegers();
  3002   nsIntPoint offset = aOffset + nsIntPoint(transform._31, transform._32);
  3004   Layer* child = aLayer->GetFirstChild();
  3005   if (child) {
  3006     while (child) {
  3007       if (!CheckLeafLayers(child, offset, aCoveredRegion))
  3008         return false;
  3009       child = child->GetNextSibling();
  3011   } else {
  3012     nsIntRegion rgn = aLayer->GetVisibleRegion();
  3013     rgn.MoveBy(offset);
  3014     nsIntRegion tmp;
  3015     tmp.And(rgn, *aCoveredRegion);
  3016     if (!tmp.IsEmpty())
  3017       return false;
  3018     aCoveredRegion->Or(*aCoveredRegion, rgn);
  3021   return true;
  3023 #endif
  3025 NS_IMETHODIMP
  3026 nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult)
  3028   if (!nsContentUtils::IsCallerChrome()) {
  3029     return NS_ERROR_DOM_SECURITY_ERR;
  3032   *aResult = true;
  3033 #ifdef DEBUG
  3034   nsIWidget* widget = GetWidget();
  3035   if (!widget)
  3036     return NS_ERROR_FAILURE;
  3037   LayerManager* manager = widget->GetLayerManager();
  3038   if (!manager)
  3039     return NS_ERROR_FAILURE;
  3040   nsPresContext* presContext = GetPresContext();
  3041   if (!presContext)
  3042     return NS_ERROR_FAILURE;
  3043   Layer* root = manager->GetRoot();
  3044   if (!root)
  3045     return NS_ERROR_FAILURE;
  3047   nsIntPoint offset(0, 0);
  3048   nsIntRegion coveredRegion;
  3049   if (!CheckLeafLayers(root, offset, &coveredRegion)) {
  3050     *aResult = false;
  3052   if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
  3053     *aResult = false;
  3055 #endif
  3056   return NS_OK;
  3059 NS_IMETHODIMP
  3060 nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
  3062   if (!nsContentUtils::IsCallerChrome()) {
  3063     return NS_ERROR_DOM_SECURITY_ERR;
  3066   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3067   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  3069   nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
  3070   *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
  3071   return NS_OK;
  3074 NS_IMETHODIMP
  3075 nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
  3077   if (!nsContentUtils::IsCallerChrome()) {
  3078     return NS_ERROR_DOM_SECURITY_ERR;
  3081   if (!aElement) {
  3082     return NS_ERROR_INVALID_ARG;
  3085   nsresult rv;
  3086   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  3087   NS_ENSURE_SUCCESS(rv, rv);
  3089   nsIFrame* frame = content->GetPrimaryFrame();
  3091   if (!frame) {
  3092     *aResult = false;
  3093     return NS_OK;
  3096   *aResult = frame->CheckAndClearPaintedState();
  3097   return NS_OK;
  3100 NS_IMETHODIMP
  3101 nsDOMWindowUtils::EnableDialogs()
  3103   if (!nsContentUtils::IsCallerChrome()) {
  3104     return NS_ERROR_DOM_SECURITY_ERR;
  3107   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3108   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  3110   static_cast<nsGlobalWindow*>(window.get())->EnableDialogs();
  3111   return NS_OK;
  3114 NS_IMETHODIMP
  3115 nsDOMWindowUtils::DisableDialogs()
  3117   if (!nsContentUtils::IsCallerChrome()) {
  3118     return NS_ERROR_DOM_SECURITY_ERR;
  3121   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3122   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  3124   static_cast<nsGlobalWindow*>(window.get())->DisableDialogs();
  3125   return NS_OK;
  3128 NS_IMETHODIMP
  3129 nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
  3131   if (!nsContentUtils::IsCallerChrome()) {
  3132     return NS_ERROR_DOM_SECURITY_ERR;
  3135   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3136   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  3138   *aResult = static_cast<nsGlobalWindow*>(window.get())->AreDialogsEnabled();
  3139   return NS_OK;
  3142 static nsIDOMBlob*
  3143 GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
  3144   nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
  3145     nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
  3146   return blob;
  3149 static nsresult
  3150 GetFileOrBlob(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
  3151               JS::Handle<JS::Value> aParameters, JSContext* aCx,
  3152               uint8_t aOptionalArgCount, nsISupports** aResult)
  3154   if (!nsContentUtils::IsCallerChrome()) {
  3155     return NS_ERROR_DOM_SECURITY_ERR;
  3158   nsresult rv;
  3160   nsCOMPtr<nsISupports> file;
  3162   if (aName.IsVoid()) {
  3163     rv = nsDOMMultipartFile::NewBlob(getter_AddRefs(file));
  3165   else {
  3166     rv = nsDOMMultipartFile::NewFile(aName, getter_AddRefs(file));
  3168   NS_ENSURE_SUCCESS(rv, rv);
  3170   nsDOMMultipartFile* domFile =
  3171     static_cast<nsDOMMultipartFile*>(static_cast<nsIDOMFile*>(file.get()));
  3173   JS::AutoValueArray<2> args(aCx);
  3174   args[0].set(aBlobParts);
  3175   args[1].set(aParameters);
  3177   rv = domFile->InitBlob(aCx, aOptionalArgCount, args.begin(), GetXPConnectNative);
  3178   NS_ENSURE_SUCCESS(rv, rv);
  3180   file.forget(aResult);
  3181   return NS_OK;
  3184 NS_IMETHODIMP
  3185 nsDOMWindowUtils::GetFile(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
  3186                           JS::Handle<JS::Value> aParameters, JSContext* aCx,
  3187                           uint8_t aOptionalArgCount, nsIDOMFile** aResult)
  3189   if (!nsContentUtils::IsCallerChrome()) {
  3190     return NS_ERROR_DOM_SECURITY_ERR;
  3193   nsCOMPtr<nsISupports> file;
  3194   nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx,
  3195                               aOptionalArgCount, getter_AddRefs(file));
  3196   NS_ENSURE_SUCCESS(rv, rv);
  3198   nsCOMPtr<nsIDOMFile> result = do_QueryInterface(file);
  3199   result.forget(aResult);
  3201   return NS_OK;
  3204 NS_IMETHODIMP
  3205 nsDOMWindowUtils::GetBlob(JS::Handle<JS::Value> aBlobParts,
  3206                           JS::Handle<JS::Value> aParameters, JSContext* aCx,
  3207                           uint8_t aOptionalArgCount, nsIDOMBlob** aResult)
  3209   if (!nsContentUtils::IsCallerChrome()) {
  3210     return NS_ERROR_DOM_SECURITY_ERR;
  3213   nsCOMPtr<nsISupports> blob;
  3214   nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx,
  3215                               aOptionalArgCount, getter_AddRefs(blob));
  3216   NS_ENSURE_SUCCESS(rv, rv);
  3218   nsCOMPtr<nsIDOMBlob> result = do_QueryInterface(blob);
  3219   result.forget(aResult);
  3221   return NS_OK;
  3224 NS_IMETHODIMP
  3225 nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
  3226                             int64_t* aResult)
  3228   if (!nsContentUtils::IsCallerChrome()) {
  3229     return NS_ERROR_DOM_SECURITY_ERR;
  3232   if (!JSVAL_IS_PRIMITIVE(aFile)) {
  3233     JSObject* obj = JSVAL_TO_OBJECT(aFile);
  3235     file::FileHandle* fileHandle;
  3236     if (NS_SUCCEEDED(UNWRAP_OBJECT(FileHandle, obj, fileHandle))) {
  3237       *aResult = fileHandle->GetFileId();
  3238       return NS_OK;
  3241     nsISupports* nativeObj =
  3242       nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
  3244     nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
  3245     if (blob) {
  3246       *aResult = blob->GetFileId();
  3247       return NS_OK;
  3251   *aResult = -1;
  3252   return NS_OK;
  3255 NS_IMETHODIMP
  3256 nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
  3257                                     JS::Handle<JS::Value> aOptions,
  3258                                     int32_t* aRefCnt, int32_t* aDBRefCnt,
  3259                                     int32_t* aSliceRefCnt, JSContext* aCx,
  3260                                     bool* aResult)
  3262   if (!nsContentUtils::IsCallerChrome()) {
  3263     return NS_ERROR_DOM_SECURITY_ERR;
  3266   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3267   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  3269   nsCString origin;
  3270   quota::PersistenceType defaultPersistenceType;
  3271   nsresult rv =
  3272     quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr,
  3273                                            &defaultPersistenceType);
  3274   NS_ENSURE_SUCCESS(rv, rv);
  3276   IDBOpenDBOptions options;
  3277   JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
  3278   if (!options.Init(aCx, optionsVal)) {
  3279     return NS_ERROR_TYPE_ERR;
  3282   quota::PersistenceType persistenceType =
  3283     quota::PersistenceTypeFromStorage(options.mStorage, defaultPersistenceType);
  3285   nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
  3286     indexedDB::IndexedDatabaseManager::Get();
  3288   if (mgr) {
  3289     rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
  3290                                         aId, aRefCnt, aDBRefCnt, aSliceRefCnt,
  3291                                         aResult);
  3292     NS_ENSURE_SUCCESS(rv, rv);
  3294   else {
  3295     *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;
  3296     *aResult = false;
  3299   return NS_OK;
  3302 NS_IMETHODIMP
  3303 nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
  3305   if (!nsContentUtils::IsCallerChrome()) {
  3306     return NS_ERROR_DOM_SECURITY_ERR;
  3309   *aResult = JS::IsIncrementalGCEnabled(JS_GetRuntime(cx));
  3310   return NS_OK;
  3313 NS_IMETHODIMP
  3314 nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
  3316   if (!nsContentUtils::IsCallerChrome()) {
  3317     return NS_ERROR_DOM_SECURITY_ERR;
  3320   js::StartPCCountProfiling(cx);
  3321   return NS_OK;
  3324 NS_IMETHODIMP
  3325 nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
  3327   if (!nsContentUtils::IsCallerChrome()) {
  3328     return NS_ERROR_DOM_SECURITY_ERR;
  3331   js::StopPCCountProfiling(cx);
  3332   return NS_OK;
  3335 NS_IMETHODIMP
  3336 nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
  3338   if (!nsContentUtils::IsCallerChrome()) {
  3339     return NS_ERROR_DOM_SECURITY_ERR;
  3342   js::PurgePCCounts(cx);
  3343   return NS_OK;
  3346 NS_IMETHODIMP
  3347 nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
  3349   if (!nsContentUtils::IsCallerChrome()) {
  3350     return NS_ERROR_DOM_SECURITY_ERR;
  3353   *result = js::GetPCCountScriptCount(cx);
  3354   return NS_OK;
  3357 NS_IMETHODIMP
  3358 nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result)
  3360   if (!nsContentUtils::IsCallerChrome()) {
  3361     return NS_ERROR_DOM_SECURITY_ERR;
  3364   JSString *text = js::GetPCCountScriptSummary(cx, script);
  3365   if (!text)
  3366     return NS_ERROR_FAILURE;
  3368   nsDependentJSString str;
  3369   if (!str.init(cx, text))
  3370     return NS_ERROR_FAILURE;
  3372   result = str;
  3373   return NS_OK;
  3376 NS_IMETHODIMP
  3377 nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result)
  3379   if (!nsContentUtils::IsCallerChrome()) {
  3380     return NS_ERROR_DOM_SECURITY_ERR;
  3383   JSString *text = js::GetPCCountScriptContents(cx, script);
  3384   if (!text)
  3385     return NS_ERROR_FAILURE;
  3387   nsDependentJSString str;
  3388   if (!str.init(cx, text))
  3389     return NS_ERROR_FAILURE;
  3391   result = str;
  3392   return NS_OK;
  3395 NS_IMETHODIMP
  3396 nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
  3398   if (!nsContentUtils::IsCallerChrome()) {
  3399     return NS_ERROR_DOM_SECURITY_ERR;
  3402   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3403   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  3404   nsIDocShell *docShell = window->GetDocShell();
  3405   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
  3407   nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  3408   NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  3410   *aPaintingSuppressed = presShell->IsPaintingSuppressed();
  3411   return NS_OK;
  3414 NS_IMETHODIMP
  3415 nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
  3417   if (!nsContentUtils::IsCallerChrome()) {
  3418     return NS_ERROR_DOM_SECURITY_ERR;
  3421   nsCOMPtr<nsIDocument> doc = GetDocument();
  3422   NS_ENSURE_STATE(doc);
  3424   nsTArray<nsIObjectLoadingContent*> plugins;
  3425   doc->GetPlugins(plugins);
  3427   JS::Rooted<JSObject*> jsPlugins(cx);
  3428   nsresult rv = nsTArrayToJSArray(cx, plugins, jsPlugins.address());
  3429   NS_ENSURE_SUCCESS(rv, rv);
  3431   aPlugins.setObject(*jsPlugins);
  3432   return NS_OK;
  3435 static void
  3436 MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
  3438   if (aPresContext) {
  3439     nsIPresShell* presShell = aPresContext->GetPresShell();
  3440     bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
  3441     presShell->NotifyFontSizeInflationEnabledIsDirty();
  3442     bool changed = false;
  3443     if (presShell && presShell->FontSizeInflationEnabled() &&
  3444         presShell->FontSizeInflationMinTwips() != 0) {
  3445       aPresContext->ScreenWidthInchesForFontInflation(&changed);
  3448     changed = changed ||
  3449       (fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
  3450     if (changed) {
  3451       nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
  3452       if (docShell) {
  3453         nsCOMPtr<nsIContentViewer> cv;
  3454         docShell->GetContentViewer(getter_AddRefs(cv));
  3455         nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
  3456         if (mudv) {
  3457           nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
  3458           mudv->AppendSubtree(array);
  3459           for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
  3460             nsCOMPtr<nsIPresShell> shell;
  3461             nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
  3462             cv->GetPresShell(getter_AddRefs(shell));
  3463             if (shell) {
  3464               nsIFrame *rootFrame = shell->GetRootFrame();
  3465               if (rootFrame) {
  3466                 shell->FrameNeedsReflow(rootFrame,
  3467                                         nsIPresShell::eStyleChange,
  3468                                         NS_FRAME_IS_DIRTY);
  3478 NS_IMETHODIMP
  3479 nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
  3481   if (!nsContentUtils::IsCallerChrome()) {
  3482     return NS_ERROR_DOM_SECURITY_ERR;
  3485   if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
  3486     return NS_ERROR_ILLEGAL_VALUE;
  3489   nsIPresShell* presShell = GetPresShell();
  3490   if (!presShell) {
  3491     return NS_ERROR_FAILURE;
  3494   presShell->SetScrollPositionClampingScrollPortSize(
  3495     nsPresContext::CSSPixelsToAppUnits(aWidth),
  3496     nsPresContext::CSSPixelsToAppUnits(aHeight));
  3498   // When the "font.size.inflation.minTwips" preference is set, the
  3499   // layout depends on the size of the screen.  Since when the size
  3500   // of the screen changes, the scroll position clamping scroll port
  3501   // size also changes, we hook in the needed updates here rather
  3502   // than adding a separate notification just for this change.
  3503   nsPresContext* presContext = GetPresContext();
  3504   MaybeReflowForInflationScreenWidthChange(presContext);
  3506   return NS_OK;
  3509 NS_IMETHODIMP
  3510 nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight,
  3511                                                          float aBottom, float aLeft)
  3513   if (!nsContentUtils::IsCallerChrome()) {
  3514     return NS_ERROR_DOM_SECURITY_ERR;
  3517   if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) {
  3518     return NS_ERROR_ILLEGAL_VALUE;
  3521   nsIPresShell* presShell = GetPresShell();
  3522   if (!presShell) {
  3523     return NS_ERROR_FAILURE;
  3526   nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop),
  3527                    nsPresContext::CSSPixelsToAppUnits(aRight),
  3528                    nsPresContext::CSSPixelsToAppUnits(aBottom),
  3529                    nsPresContext::CSSPixelsToAppUnits(aLeft));
  3530   presShell->SetContentDocumentFixedPositionMargins(margins);
  3532   return NS_OK;
  3535 nsresult
  3536 nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
  3537                                             const nsAString& aNewOrigin)
  3539   if (!nsContentUtils::IsCallerChrome()) {
  3540     return NS_ERROR_DOM_SECURITY_ERR;
  3543   nsCOMPtr<nsIDocument> doc = GetDocument();
  3544   NS_ENSURE_STATE(doc);
  3546   doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin);
  3547   return NS_OK;
  3550 nsresult
  3551 nsDOMWindowUtils::RemoteFrameFullscreenReverted()
  3553   if (!nsContentUtils::IsCallerChrome()) {
  3554     return NS_ERROR_DOM_SECURITY_ERR;
  3557   nsCOMPtr<nsIDocument> doc = GetDocument();
  3558   NS_ENSURE_STATE(doc);
  3560   doc->RemoteFrameFullscreenReverted();
  3561   return NS_OK;
  3564 nsresult
  3565 nsDOMWindowUtils::ExitFullscreen()
  3567   if (!nsContentUtils::IsCallerChrome()) {
  3568     return NS_ERROR_DOM_SECURITY_ERR;
  3571   nsIDocument::ExitFullscreen(nullptr, /* async */ false);
  3572   return NS_OK;
  3575 NS_IMETHODIMP
  3576 nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
  3577                                 bool *_retval)
  3579   *_retval = false;
  3580   if (!nsContentUtils::IsCallerChrome()) {
  3581     return NS_ERROR_DOM_SECURITY_ERR;
  3584   nsSelectionAmount amount;
  3585   switch (aSelectBehavior) {
  3586     case nsIDOMWindowUtils::SELECT_CHARACTER:
  3587       amount = eSelectCharacter;
  3588     break;
  3589     case nsIDOMWindowUtils::SELECT_CLUSTER:
  3590       amount = eSelectCluster;
  3591     break;
  3592     case nsIDOMWindowUtils::SELECT_WORD:
  3593       amount = eSelectWord;
  3594     break;
  3595     case nsIDOMWindowUtils::SELECT_LINE:
  3596       amount = eSelectLine;
  3597     break;
  3598     case nsIDOMWindowUtils::SELECT_BEGINLINE:
  3599       amount = eSelectBeginLine;
  3600     break;
  3601     case nsIDOMWindowUtils::SELECT_ENDLINE:
  3602       amount = eSelectEndLine;
  3603     break;
  3604     case nsIDOMWindowUtils::SELECT_PARAGRAPH:
  3605       amount = eSelectParagraph;
  3606     break;
  3607     case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
  3608       amount = eSelectWordNoSpace;
  3609     break;
  3610     default:
  3611       return NS_ERROR_INVALID_ARG;
  3614   nsIPresShell* presShell = GetPresShell();
  3615   if (!presShell) {
  3616     return NS_ERROR_UNEXPECTED;
  3619   // The root frame for this content window
  3620   nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
  3621   if (!rootFrame) {
  3622     return NS_ERROR_UNEXPECTED;
  3625   // Get the target frame at the client coordinates passed to us
  3626   nsPoint offset;
  3627   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
  3628   nsIntPoint pt = LayoutDeviceIntPoint::ToUntyped(
  3629     ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()));
  3630   nsPoint ptInRoot =
  3631     nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
  3632   nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
  3633   // This can happen if the page hasn't loaded yet or if the point
  3634   // is outside the frame.
  3635   if (!targetFrame) {
  3636     return NS_ERROR_INVALID_ARG;
  3639   // Convert point to coordinates relative to the target frame, which is
  3640   // what targetFrame's SelectByTypeAtPoint expects.
  3641   nsPoint relPoint =
  3642     nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
  3644   nsresult rv =
  3645     static_cast<nsFrame*>(targetFrame)->
  3646       SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
  3647                           nsFrame::SELECT_ACCUMULATE);
  3648   *_retval = !NS_FAILED(rv);
  3649   return NS_OK;
  3652 static nsIDocument::additionalSheetType
  3653 convertSheetType(uint32_t aSheetType)
  3655   switch(aSheetType) {
  3656     case nsDOMWindowUtils::AGENT_SHEET:
  3657       return nsIDocument::eAgentSheet;
  3658     case nsDOMWindowUtils::USER_SHEET:
  3659       return nsIDocument::eUserSheet;
  3660     case nsDOMWindowUtils::AUTHOR_SHEET:
  3661       return nsIDocument::eAuthorSheet;
  3662     default:
  3663       NS_ASSERTION(false, "wrong type");
  3664       // we must return something although this should never happen
  3665       return nsIDocument::SheetTypeCount;
  3669 NS_IMETHODIMP
  3670 nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
  3672   if (!nsContentUtils::IsCallerChrome()) {
  3673     return NS_ERROR_DOM_SECURITY_ERR;
  3676   NS_ENSURE_ARG_POINTER(aSheetURI);
  3677   NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
  3678                 aSheetType == USER_SHEET ||
  3679                 aSheetType == AUTHOR_SHEET);
  3681   nsCOMPtr<nsIDocument> doc = GetDocument();
  3682   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  3684   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
  3686   return doc->LoadAdditionalStyleSheet(type, aSheetURI);
  3689 NS_IMETHODIMP
  3690 nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
  3692   if (!nsContentUtils::IsCallerChrome()) {
  3693     return NS_ERROR_DOM_SECURITY_ERR;
  3696   NS_ENSURE_ARG_POINTER(aSheetURI);
  3697   NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
  3698                 aSheetType == USER_SHEET ||
  3699                 aSheetType == AUTHOR_SHEET);
  3701   nsCOMPtr<nsIDocument> doc = GetDocument();
  3702   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  3704   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
  3706   doc->RemoveAdditionalStyleSheet(type, aSheetURI);
  3707   return NS_OK;
  3710 NS_IMETHODIMP
  3711 nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput)
  3713   if (!nsContentUtils::IsCallerChrome()) {
  3714     return NS_ERROR_DOM_SECURITY_ERR;
  3717   *aHandlingUserInput = EventStateManager::IsHandlingUserInput();
  3719   return NS_OK;
  3722 NS_IMETHODIMP
  3723 nsDOMWindowUtils::AllowScriptsToClose()
  3725   if (!nsContentUtils::IsCallerChrome()) {
  3726     return NS_ERROR_DOM_SECURITY_ERR;
  3728   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3729   NS_ENSURE_STATE(window);
  3730   static_cast<nsGlobalWindow*>(window.get())->AllowScriptsToClose();
  3731   return NS_OK;
  3734 NS_IMETHODIMP
  3735 nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible)
  3737   if (!nsContentUtils::IsCallerChrome()) {
  3738     return NS_ERROR_DOM_SECURITY_ERR;
  3741   // this should reflect the "is parent window visible" logic in
  3742   // nsWindowWatcher::OpenWindowInternal()
  3743   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3744   NS_ENSURE_STATE(window);
  3746   nsCOMPtr<nsIWidget> parentWidget;
  3747   nsIDocShell *docShell = window->GetDocShell();
  3748   if (docShell) {
  3749     if (TabChild *tabChild = TabChild::GetFrom(docShell)) {
  3750       if (!tabChild->SendIsParentWindowMainWidgetVisible(aIsVisible))
  3751         return NS_ERROR_FAILURE;
  3752       return NS_OK;
  3755     nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
  3756     docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
  3757     nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
  3758     if (parentWindow) {
  3759         parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
  3762   if (!parentWidget) {
  3763     return NS_ERROR_NOT_AVAILABLE;
  3766   *aIsVisible = parentWidget->IsVisible();
  3767   return NS_OK;
  3770 NS_IMETHODIMP
  3771 nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal)
  3773   *aRetVal = false;
  3774   if (!nsContentUtils::IsCallerChrome()) {
  3775     return NS_ERROR_DOM_SECURITY_ERR;
  3777   nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
  3778   nsINode* node = n;
  3779   while (node) {
  3780     if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
  3781       nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
  3782       if (fc && fc->IsDisabledForEvents(NS_EVENT_NULL)) {
  3783         *aRetVal = true;
  3784         break;
  3787     node = node->GetParentNode();
  3790   return NS_OK;
  3793 NS_IMETHODIMP
  3794 nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing)
  3796   nsPresContext* presContext = GetPresContext();
  3797   if (presContext) {
  3798     presContext->SetPaintFlashing(aPaintFlashing);
  3799     // Clear paint flashing colors
  3800     nsIPresShell* presShell = GetPresShell();
  3801     if (!aPaintFlashing && presShell) {
  3802       nsIFrame* rootFrame = presShell->GetRootFrame();
  3803       if (rootFrame) {
  3804         rootFrame->InvalidateFrameSubtree();
  3808   return NS_OK;
  3811 NS_IMETHODIMP
  3812 nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal)
  3814   *aRetVal = false;
  3815   nsPresContext* presContext = GetPresContext();
  3816   if (presContext) {
  3817     *aRetVal = presContext->GetPaintFlashing();
  3819   return NS_OK;
  3822 NS_IMETHODIMP
  3823 nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
  3824                                             nsIDOMEvent* aEvent,
  3825                                             bool* aRetVal)
  3827   *aRetVal = false;
  3828   if (!nsContentUtils::IsCallerChrome()) {
  3829     return NS_ERROR_DOM_SECURITY_ERR;
  3831   NS_ENSURE_STATE(aTarget && aEvent);
  3832   aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
  3833   aTarget->DispatchEvent(aEvent, aRetVal);
  3834   return NS_OK;
  3837 NS_IMETHODIMP
  3838 nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable)
  3840   if (!nsContentUtils::IsCallerChrome()) {
  3841     return NS_ERROR_DOM_SECURITY_ERR;
  3844   nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
  3845   if (!appShell) {
  3846     return NS_ERROR_NOT_AVAILABLE;
  3849   return appShell->RunInStableState(runnable);
  3852 NS_IMETHODIMP
  3853 nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable)
  3855   if (!nsContentUtils::IsCallerChrome()) {
  3856     return NS_ERROR_DOM_SECURITY_ERR;
  3859   nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
  3860   if (!appShell) {
  3861     return NS_ERROR_NOT_AVAILABLE;
  3864   return appShell->RunBeforeNextEvent(runnable);
  3867 NS_IMETHODIMP
  3868 nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
  3869                                const nsAString& aProperty,
  3870                                nsAString& aResult)
  3872   if (!nsContentUtils::IsCallerChrome()) {
  3873     return NS_ERROR_DOM_SECURITY_ERR;
  3876   nsCOMPtr<Element> element = do_QueryInterface(aElement);
  3877   if (!element) {
  3878     return NS_ERROR_INVALID_ARG;
  3881   nsRefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
  3882   nsIFrame* frame = element->GetPrimaryFrame();
  3883   if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
  3884     if (aProperty.EqualsLiteral("opacity")) {
  3885       Layer* layer =
  3886         FrameLayerBuilder::GetDedicatedLayer(frame,
  3887                                              nsDisplayItem::TYPE_OPACITY);
  3888       if (layer) {
  3889         float value;
  3890         ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
  3891         if (forwarder && forwarder->HasShadowManager()) {
  3892           forwarder->GetShadowManager()->SendGetOpacity(
  3893             layer->AsShadowableLayer()->GetShadow(), &value);
  3894           cssValue = new nsROCSSPrimitiveValue;
  3895           cssValue->SetNumber(value);
  3898     } else if (aProperty.EqualsLiteral("transform")) {
  3899       Layer* layer =
  3900         FrameLayerBuilder::GetDedicatedLayer(frame,
  3901                                              nsDisplayItem::TYPE_TRANSFORM);
  3902       if (layer) {
  3903         ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
  3904         if (forwarder && forwarder->HasShadowManager()) {
  3905           MaybeTransform transform;
  3906           forwarder->GetShadowManager()->SendGetAnimationTransform(
  3907             layer->AsShadowableLayer()->GetShadow(), &transform);
  3908           if (transform.type() == MaybeTransform::Tgfx3DMatrix) {
  3909             cssValue =
  3910               nsComputedDOMStyle::MatrixToCSSValue(transform.get_gfx3DMatrix());
  3917   if (cssValue) {
  3918     nsString text;
  3919     ErrorResult rv;
  3920     cssValue->GetCssText(text, rv);
  3921     aResult.Assign(text);
  3922     return rv.ErrorCode();
  3923   } else {
  3924     aResult.Truncate();
  3927   return NS_OK;
  3930 NS_IMETHODIMP
  3931 nsDOMWindowUtils::GetOMTAOrComputedStyle(nsIDOMElement* aElement,
  3932                                          const nsAString& aProperty,
  3933                                          nsAString& aResult)
  3935   if (!nsContentUtils::IsCallerChrome()) {
  3936     return NS_ERROR_DOM_SECURITY_ERR;
  3939   // Try to get OMTA style
  3940   nsresult rv = GetOMTAStyle(aElement, aProperty, aResult);
  3941   if (NS_FAILED(rv) || !aResult.IsEmpty()) {
  3942     return rv;
  3945   // Otherwise, fall back to computed style
  3946   nsCOMPtr<Element> element = do_QueryInterface(aElement);
  3947   if (!element) {
  3948     return NS_ERROR_INVALID_ARG;
  3950   nsCOMPtr<nsIDOMCSSStyleDeclaration> style;
  3951   rv = element->GetCurrentDoc()->GetWindow()->
  3952     GetComputedStyle(aElement, aProperty, getter_AddRefs(style));
  3953   NS_ENSURE_SUCCESS(rv, rv);
  3955   return style->GetPropertyValue(aProperty, aResult);
  3958 NS_IMETHODIMP
  3959 nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
  3961   if (!nsContentUtils::IsCallerChrome()) {
  3962     return NS_ERROR_DOM_SECURITY_ERR;
  3964   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3965   NS_ENSURE_STATE(window);
  3967   *aMuted = window->GetAudioMuted();
  3968   return NS_OK;
  3971 NS_IMETHODIMP
  3972 nsDOMWindowUtils::SetAudioMuted(bool aMuted)
  3974   if (!nsContentUtils::IsCallerChrome()) {
  3975     return NS_ERROR_DOM_SECURITY_ERR;
  3977   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3978   NS_ENSURE_STATE(window);
  3980   window->SetAudioMuted(aMuted);
  3981   return NS_OK;
  3984 NS_IMETHODIMP
  3985 nsDOMWindowUtils::GetAudioVolume(float* aVolume)
  3987   if (!nsContentUtils::IsCallerChrome()) {
  3988     return NS_ERROR_DOM_SECURITY_ERR;
  3990   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  3991   NS_ENSURE_STATE(window);
  3993   *aVolume = window->GetAudioVolume();
  3994   return NS_OK;
  3997 NS_IMETHODIMP
  3998 nsDOMWindowUtils::SetAudioVolume(float aVolume)
  4000   if (!nsContentUtils::IsCallerChrome()) {
  4001     return NS_ERROR_DOM_SECURITY_ERR;
  4003   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  4004   NS_ENSURE_STATE(window);
  4006   return window->SetAudioVolume(aVolume);
  4009 NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
  4010   NS_INTERFACE_MAP_ENTRY(nsISupports)
  4011   NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
  4012 NS_INTERFACE_MAP_END
  4014 NS_IMPL_ADDREF(nsTranslationNodeList)
  4015 NS_IMPL_RELEASE(nsTranslationNodeList)
  4017 NS_IMETHODIMP
  4018 nsTranslationNodeList::Item(uint32_t aIndex, nsIDOMNode** aRetVal)
  4020   NS_ENSURE_ARG_POINTER(aRetVal);
  4021   NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex));
  4022   return NS_OK;
  4025 NS_IMETHODIMP
  4026 nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal)
  4028   NS_ENSURE_ARG_POINTER(aRetVal);
  4029   if (aIndex >= mLength) {
  4030     *aRetVal = false;
  4031     return NS_OK;
  4034   *aRetVal = mNodeIsRoot.ElementAt(aIndex);
  4035   return NS_OK;
  4038 NS_IMETHODIMP
  4039 nsTranslationNodeList::GetLength(uint32_t* aRetVal)
  4041   NS_ENSURE_ARG_POINTER(aRetVal);
  4042   *aRetVal = mLength;
  4043   return NS_OK;

mercurial