dom/base/nsDOMWindowUtils.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/base/nsDOMWindowUtils.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,4044 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#include "nsDOMWindowUtils.h"
    1.10 +
    1.11 +#include "mozilla/layers/CompositorChild.h"
    1.12 +#include "mozilla/layers/LayerTransactionChild.h"
    1.13 +#include "nsPresContext.h"
    1.14 +#include "nsDOMClassInfoID.h"
    1.15 +#include "nsError.h"
    1.16 +#include "nsIDOMEvent.h"
    1.17 +#include "nsQueryContentEventResult.h"
    1.18 +#include "CompositionStringSynthesizer.h"
    1.19 +#include "nsGlobalWindow.h"
    1.20 +#include "nsIDocument.h"
    1.21 +#include "nsFocusManager.h"
    1.22 +#include "nsFrameManager.h"
    1.23 +#include "nsRefreshDriver.h"
    1.24 +#include "mozilla/dom/Touch.h"
    1.25 +#include "nsIObjectLoadingContent.h"
    1.26 +#include "nsFrame.h"
    1.27 +#include "mozilla/layers/ShadowLayers.h"
    1.28 +
    1.29 +#include "nsIScrollableFrame.h"
    1.30 +
    1.31 +#include "nsContentUtils.h"
    1.32 +
    1.33 +#include "nsIFrame.h"
    1.34 +#include "nsIWidget.h"
    1.35 +#include "nsCharsetSource.h"
    1.36 +#include "nsJSEnvironment.h"
    1.37 +#include "nsJSUtils.h"
    1.38 +
    1.39 +#include "mozilla/EventStateManager.h"
    1.40 +#include "mozilla/MiscEvents.h"
    1.41 +#include "mozilla/MouseEvents.h"
    1.42 +#include "mozilla/TextEvents.h"
    1.43 +#include "mozilla/TouchEvents.h"
    1.44 +
    1.45 +#include "nsViewManager.h"
    1.46 +
    1.47 +#include "nsIDOMHTMLCanvasElement.h"
    1.48 +#include "nsLayoutUtils.h"
    1.49 +#include "nsComputedDOMStyle.h"
    1.50 +#include "nsIPresShell.h"
    1.51 +#include "nsStyleAnimation.h"
    1.52 +#include "nsCSSProps.h"
    1.53 +#include "nsDOMFile.h"
    1.54 +#include "nsTArrayHelpers.h"
    1.55 +#include "nsIDocShell.h"
    1.56 +#include "nsIContentViewer.h"
    1.57 +#include "nsIMarkupDocumentViewer.h"
    1.58 +#include "mozilla/dom/DOMRect.h"
    1.59 +#include <algorithm>
    1.60 +
    1.61 +#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
    1.62 +#include <gdk/gdk.h>
    1.63 +#include <gdk/gdkx.h>
    1.64 +#endif
    1.65 +
    1.66 +#include "Layers.h"
    1.67 +#include "mozilla/layers/ShadowLayers.h"
    1.68 +
    1.69 +#include "mozilla/dom/Element.h"
    1.70 +#include "mozilla/dom/file/FileHandle.h"
    1.71 +#include "mozilla/dom/FileHandleBinding.h"
    1.72 +#include "mozilla/dom/TabChild.h"
    1.73 +#include "mozilla/dom/IDBFactoryBinding.h"
    1.74 +#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
    1.75 +#include "mozilla/dom/quota/PersistenceType.h"
    1.76 +#include "mozilla/dom/quota/QuotaManager.h"
    1.77 +#include "nsDOMBlobBuilder.h"
    1.78 +#include "nsPrintfCString.h"
    1.79 +#include "nsViewportInfo.h"
    1.80 +#include "nsIFormControl.h"
    1.81 +#include "nsIScriptError.h"
    1.82 +#include "nsIAppShell.h"
    1.83 +#include "nsWidgetsCID.h"
    1.84 +#include "FrameLayerBuilder.h"
    1.85 +#include "nsDisplayList.h"
    1.86 +#include "nsROCSSPrimitiveValue.h"
    1.87 +#include "nsIBaseWindow.h"
    1.88 +#include "nsIDocShellTreeOwner.h"
    1.89 +#include "nsIInterfaceRequestorUtils.h"
    1.90 +#include "GeckoProfiler.h"
    1.91 +#include "mozilla/Preferences.h"
    1.92 +#include "nsIContentIterator.h"
    1.93 +
    1.94 +#ifdef XP_WIN
    1.95 +#undef GetClassName
    1.96 +#endif
    1.97 +
    1.98 +using namespace mozilla;
    1.99 +using namespace mozilla::dom;
   1.100 +using namespace mozilla::layers;
   1.101 +using namespace mozilla::widget;
   1.102 +using namespace mozilla::gfx;
   1.103 +
   1.104 +class gfxContext;
   1.105 +
   1.106 +static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
   1.107 +
   1.108 +DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
   1.109 +
   1.110 +NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
   1.111 +  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
   1.112 +  NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
   1.113 +  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   1.114 +  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils)
   1.115 +NS_INTERFACE_MAP_END
   1.116 +
   1.117 +NS_IMPL_ADDREF(nsDOMWindowUtils)
   1.118 +NS_IMPL_RELEASE(nsDOMWindowUtils)
   1.119 +
   1.120 +nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
   1.121 +{
   1.122 +  nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow);
   1.123 +  mWindow = do_GetWeakReference(supports);
   1.124 +  NS_ASSERTION(aWindow->IsOuterWindow(), "How did that happen?");
   1.125 +}
   1.126 +
   1.127 +nsDOMWindowUtils::~nsDOMWindowUtils()
   1.128 +{
   1.129 +}
   1.130 +
   1.131 +nsIPresShell*
   1.132 +nsDOMWindowUtils::GetPresShell()
   1.133 +{
   1.134 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   1.135 +  if (!window)
   1.136 +    return nullptr;
   1.137 +
   1.138 +  nsIDocShell *docShell = window->GetDocShell();
   1.139 +  if (!docShell)
   1.140 +    return nullptr;
   1.141 +
   1.142 +  return docShell->GetPresShell();
   1.143 +}
   1.144 +
   1.145 +nsPresContext*
   1.146 +nsDOMWindowUtils::GetPresContext()
   1.147 +{
   1.148 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   1.149 +  if (!window)
   1.150 +    return nullptr;
   1.151 +  nsIDocShell *docShell = window->GetDocShell();
   1.152 +  if (!docShell)
   1.153 +    return nullptr;
   1.154 +  nsRefPtr<nsPresContext> presContext;
   1.155 +  docShell->GetPresContext(getter_AddRefs(presContext));
   1.156 +  return presContext;
   1.157 +}
   1.158 +
   1.159 +nsIDocument*
   1.160 +nsDOMWindowUtils::GetDocument()
   1.161 +{
   1.162 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   1.163 +  if (!window) {
   1.164 +    return nullptr;
   1.165 +  }
   1.166 +  return window->GetExtantDoc();
   1.167 +}
   1.168 +
   1.169 +LayerTransactionChild*
   1.170 +nsDOMWindowUtils::GetLayerTransaction()
   1.171 +{
   1.172 +  nsIWidget* widget = GetWidget();
   1.173 +  if (!widget)
   1.174 +    return nullptr;
   1.175 +
   1.176 +  LayerManager* manager = widget->GetLayerManager();
   1.177 +  if (!manager)
   1.178 +    return nullptr;
   1.179 +
   1.180 +  ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
   1.181 +  return forwarder && forwarder->HasShadowManager() ?
   1.182 +         forwarder->GetShadowManager() :
   1.183 +         nullptr;
   1.184 +}
   1.185 +
   1.186 +NS_IMETHODIMP
   1.187 +nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
   1.188 +{
   1.189 +  if (!nsContentUtils::IsCallerChrome()) {
   1.190 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.191 +  }
   1.192 +
   1.193 +  NS_ENSURE_ARG_POINTER(aMode);
   1.194 +  *aMode = 0;
   1.195 +  nsPresContext* presContext = GetPresContext();
   1.196 +  if (presContext) {
   1.197 +    *aMode = presContext->ImageAnimationMode();
   1.198 +    return NS_OK;
   1.199 +  }
   1.200 +  return NS_ERROR_NOT_AVAILABLE;
   1.201 +}
   1.202 +
   1.203 +NS_IMETHODIMP
   1.204 +nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode)
   1.205 +{
   1.206 +  if (!nsContentUtils::IsCallerChrome()) {
   1.207 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.208 +  }
   1.209 +
   1.210 +  nsPresContext* presContext = GetPresContext();
   1.211 +  if (presContext) {
   1.212 +    presContext->SetImageAnimationMode(aMode);
   1.213 +    return NS_OK;
   1.214 +  }
   1.215 +  return NS_ERROR_NOT_AVAILABLE;
   1.216 +}
   1.217 +
   1.218 +NS_IMETHODIMP
   1.219 +nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
   1.220 +{
   1.221 +  *aIsForced = false;
   1.222 +
   1.223 +  if (!nsContentUtils::IsCallerChrome()) {
   1.224 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.225 +  }
   1.226 +
   1.227 +  nsIDocument* doc = GetDocument();
   1.228 +  *aIsForced = doc &&
   1.229 +    doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
   1.230 +  return NS_OK;
   1.231 +}
   1.232 +
   1.233 +NS_IMETHODIMP
   1.234 +nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
   1.235 +                                      nsAString& aValue)
   1.236 +{
   1.237 +  if (!nsContentUtils::IsCallerChrome()) {
   1.238 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.239 +  }
   1.240 +
   1.241 +  nsIDocument* doc = GetDocument();
   1.242 +  if (doc) {
   1.243 +    nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
   1.244 +    doc->GetHeaderData(name, aValue);
   1.245 +    return NS_OK;
   1.246 +  }
   1.247 +
   1.248 +  aValue.Truncate();
   1.249 +  return NS_OK;
   1.250 +}
   1.251 +
   1.252 +NS_IMETHODIMP
   1.253 +nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
   1.254 +{
   1.255 +  if (!nsContentUtils::IsCallerChrome()) {
   1.256 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.257 +  }
   1.258 +
   1.259 +  if (aCount == 0)
   1.260 +    aCount = 1;
   1.261 +
   1.262 +  if (nsIPresShell* presShell = GetPresShell()) {
   1.263 +    nsIFrame *rootFrame = presShell->GetRootFrame();
   1.264 +
   1.265 +    if (rootFrame) {
   1.266 +      PRIntervalTime iStart = PR_IntervalNow();
   1.267 +
   1.268 +      for (uint32_t i = 0; i < aCount; i++)
   1.269 +        rootFrame->InvalidateFrame();
   1.270 +
   1.271 +#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
   1.272 +      XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
   1.273 +#endif
   1.274 +
   1.275 +      *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
   1.276 +
   1.277 +      return NS_OK;
   1.278 +    }
   1.279 +  }
   1.280 +  return NS_ERROR_FAILURE;
   1.281 +}
   1.282 +
   1.283 +NS_IMETHODIMP
   1.284 +nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
   1.285 +{
   1.286 +  if (!nsContentUtils::IsCallerChrome()) {
   1.287 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.288 +  }
   1.289 +
   1.290 +  if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) {
   1.291 +    return NS_ERROR_ILLEGAL_VALUE;
   1.292 +  }
   1.293 +
   1.294 +  nsIPresShell* presShell = GetPresShell();
   1.295 +  if (!presShell) {
   1.296 +    return NS_ERROR_FAILURE;
   1.297 +  }
   1.298 +
   1.299 +  nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
   1.300 +  nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
   1.301 +
   1.302 +  presShell->ResizeReflowOverride(width, height);
   1.303 +
   1.304 +  return NS_OK;
   1.305 +}
   1.306 +
   1.307 +NS_IMETHODIMP
   1.308 +nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
   1.309 +                                  uint32_t aDisplayHeight,
   1.310 +                                  double *aDefaultZoom, bool *aAllowZoom,
   1.311 +                                  double *aMinZoom, double *aMaxZoom,
   1.312 +                                  uint32_t *aWidth, uint32_t *aHeight,
   1.313 +                                  bool *aAutoSize)
   1.314 +{
   1.315 +  nsIDocument* doc = GetDocument();
   1.316 +  NS_ENSURE_STATE(doc);
   1.317 +
   1.318 +  nsViewportInfo info = nsContentUtils::GetViewportInfo(doc, ScreenIntSize(aDisplayWidth, aDisplayHeight));
   1.319 +  *aDefaultZoom = info.GetDefaultZoom().scale;
   1.320 +  *aAllowZoom = info.IsZoomAllowed();
   1.321 +  *aMinZoom = info.GetMinZoom().scale;
   1.322 +  *aMaxZoom = info.GetMaxZoom().scale;
   1.323 +  *aWidth = info.GetSize().width;
   1.324 +  *aHeight = info.GetSize().height;
   1.325 +  *aAutoSize = info.IsAutoSizeEnabled();
   1.326 +  return NS_OK;
   1.327 +}
   1.328 +
   1.329 +NS_IMETHODIMP
   1.330 +nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
   1.331 +                                           float aWidthPx, float aHeightPx,
   1.332 +                                           nsIDOMElement* aElement,
   1.333 +                                           uint32_t aPriority)
   1.334 +{
   1.335 +  if (!nsContentUtils::IsCallerChrome()) {
   1.336 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.337 +  }
   1.338 +
   1.339 +  nsIPresShell* presShell = GetPresShell();
   1.340 +  if (!presShell) {
   1.341 +    return NS_ERROR_FAILURE;
   1.342 +  }
   1.343 +
   1.344 +  if (!aElement) {
   1.345 +    return NS_ERROR_INVALID_ARG;
   1.346 +  }
   1.347 +
   1.348 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   1.349 +
   1.350 +  if (!content) {
   1.351 +    return NS_ERROR_INVALID_ARG;
   1.352 +  }
   1.353 +
   1.354 +  if (content->GetCurrentDoc() != presShell->GetDocument()) {
   1.355 +    return NS_ERROR_INVALID_ARG;
   1.356 +  }
   1.357 +
   1.358 +  DisplayPortPropertyData* currentData =
   1.359 +    static_cast<DisplayPortPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPort));
   1.360 +  if (currentData && currentData->mPriority > aPriority) {
   1.361 +    return NS_OK;
   1.362 +  }
   1.363 +
   1.364 +  nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
   1.365 +                     nsPresContext::CSSPixelsToAppUnits(aYPx),
   1.366 +                     nsPresContext::CSSPixelsToAppUnits(aWidthPx),
   1.367 +                     nsPresContext::CSSPixelsToAppUnits(aHeightPx));
   1.368 +
   1.369 +  content->SetProperty(nsGkAtoms::DisplayPort,
   1.370 +                       new DisplayPortPropertyData(displayport, aPriority),
   1.371 +                       nsINode::DeleteProperty<DisplayPortPropertyData>);
   1.372 +
   1.373 +  nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
   1.374 +  if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
   1.375 +    // We are setting a root displayport for a document.
   1.376 +    // The pres shell needs a special flag set.
   1.377 +    presShell->SetIgnoreViewportScrolling(true);
   1.378 +  }
   1.379 +
   1.380 +  nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
   1.381 +  if (rootFrame) {
   1.382 +    rootFrame->SchedulePaint();
   1.383 +
   1.384 +    // If we are hiding something that is a display root then send empty paint
   1.385 +    // transaction in order to release retained layers because it won't get
   1.386 +    // any more paint requests when it is hidden.
   1.387 +    if (displayport.IsEmpty() &&
   1.388 +        rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) {
   1.389 +      nsCOMPtr<nsIWidget> widget = GetWidget();
   1.390 +      if (widget) {
   1.391 +        bool isRetainingManager;
   1.392 +        LayerManager* manager = widget->GetLayerManager(&isRetainingManager);
   1.393 +        if (isRetainingManager) {
   1.394 +          manager->BeginTransaction();
   1.395 +          nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(), NS_RGB(255, 255, 255),
   1.396 +                                    nsLayoutUtils::PAINT_WIDGET_LAYERS |
   1.397 +                                    nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
   1.398 +        }
   1.399 +      }
   1.400 +    }
   1.401 +  }
   1.402 +
   1.403 +  return NS_OK;
   1.404 +}
   1.405 +
   1.406 +NS_IMETHODIMP
   1.407 +nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
   1.408 +                                                  float aTopMargin,
   1.409 +                                                  float aRightMargin,
   1.410 +                                                  float aBottomMargin,
   1.411 +                                                  uint32_t aAlignmentX,
   1.412 +                                                  uint32_t aAlignmentY,
   1.413 +                                                  nsIDOMElement* aElement,
   1.414 +                                                  uint32_t aPriority)
   1.415 +{
   1.416 +  if (!nsContentUtils::IsCallerChrome()) {
   1.417 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.418 +  }
   1.419 +
   1.420 +  nsIPresShell* presShell = GetPresShell();
   1.421 +  if (!presShell) {
   1.422 +    return NS_ERROR_FAILURE;
   1.423 +  }
   1.424 +
   1.425 +  if (!aElement) {
   1.426 +    return NS_ERROR_INVALID_ARG;
   1.427 +  }
   1.428 +
   1.429 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   1.430 +
   1.431 +  if (!content) {
   1.432 +    return NS_ERROR_INVALID_ARG;
   1.433 +  }
   1.434 +
   1.435 +  if (content->GetCurrentDoc() != presShell->GetDocument()) {
   1.436 +    return NS_ERROR_INVALID_ARG;
   1.437 +  }
   1.438 +
   1.439 +  // Note order change of arguments between our function signature and
   1.440 +  // LayerMargin constructor.
   1.441 +  LayerMargin displayportMargins(aTopMargin,
   1.442 +                                 aRightMargin,
   1.443 +                                 aBottomMargin,
   1.444 +                                 aLeftMargin);
   1.445 +
   1.446 +  nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
   1.447 +                                       aAlignmentX, aAlignmentY, aPriority);
   1.448 +
   1.449 +  return NS_OK;
   1.450 +}
   1.451 +
   1.452 +
   1.453 +NS_IMETHODIMP
   1.454 +nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
   1.455 +                                               int32_t aY,
   1.456 +                                               int32_t aWidth,
   1.457 +                                               int32_t aHeight,
   1.458 +                                               nsIDOMElement* aElement)
   1.459 +{
   1.460 +  if (!nsContentUtils::IsCallerChrome()) {
   1.461 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.462 +  }
   1.463 +
   1.464 +  nsIPresShell* presShell = GetPresShell();
   1.465 +  if (!presShell) {
   1.466 +    return NS_ERROR_FAILURE;
   1.467 +  }
   1.468 +
   1.469 +  if (!aElement) {
   1.470 +    return NS_ERROR_INVALID_ARG;
   1.471 +  }
   1.472 +
   1.473 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   1.474 +
   1.475 +  if (!content) {
   1.476 +    return NS_ERROR_INVALID_ARG;
   1.477 +  }
   1.478 +
   1.479 +  if (content->GetCurrentDoc() != presShell->GetDocument()) {
   1.480 +    return NS_ERROR_INVALID_ARG;
   1.481 +  }
   1.482 +
   1.483 +  nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight));
   1.484 +
   1.485 +  return NS_OK;
   1.486 +}
   1.487 +
   1.488 +NS_IMETHODIMP
   1.489 +nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
   1.490 +                                                   float aWidthPx, float aHeightPx,
   1.491 +                                                   nsIDOMElement* aElement)
   1.492 +{
   1.493 +  if (!nsContentUtils::IsCallerChrome()) {
   1.494 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.495 +  }
   1.496 +
   1.497 +  nsIPresShell* presShell = GetPresShell();
   1.498 +  if (!presShell) {
   1.499 +    return NS_ERROR_FAILURE;
   1.500 +  }
   1.501 +
   1.502 +  if (!aElement) {
   1.503 +    return NS_ERROR_INVALID_ARG;
   1.504 +  }
   1.505 +
   1.506 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
   1.507 +
   1.508 +  if (!content) {
   1.509 +    return NS_ERROR_INVALID_ARG;
   1.510 +  }
   1.511 +
   1.512 +  if (content->GetCurrentDoc() != presShell->GetDocument()) {
   1.513 +    return NS_ERROR_INVALID_ARG;
   1.514 +  }
   1.515 +
   1.516 +  nsRect displayport;
   1.517 +  if (!nsLayoutUtils::GetDisplayPort(content, &displayport)) {
   1.518 +    return NS_ERROR_INVALID_ARG;
   1.519 +  }
   1.520 +
   1.521 +  nsRect criticalDisplayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
   1.522 +                             nsPresContext::CSSPixelsToAppUnits(aYPx),
   1.523 +                             nsPresContext::CSSPixelsToAppUnits(aWidthPx),
   1.524 +                             nsPresContext::CSSPixelsToAppUnits(aHeightPx));
   1.525 +  content->SetProperty(nsGkAtoms::CriticalDisplayPort, new nsRect(criticalDisplayport),
   1.526 +                       nsINode::DeleteProperty<nsRect>);
   1.527 +
   1.528 +  nsIFrame* rootFrame = presShell->GetRootFrame();
   1.529 +  if (rootFrame) {
   1.530 +    rootFrame->InvalidateFrame();
   1.531 +  }
   1.532 +
   1.533 +  return NS_OK;
   1.534 +}
   1.535 +
   1.536 +NS_IMETHODIMP
   1.537 +nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
   1.538 +{
   1.539 +  if (!nsContentUtils::IsCallerChrome()) {
   1.540 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.541 +  }
   1.542 +
   1.543 +  nsIPresShell* presShell = GetPresShell();
   1.544 +  if (!presShell) {
   1.545 +    return NS_ERROR_FAILURE;
   1.546 +  }
   1.547 +
   1.548 +  nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   1.549 +  if (sf) {
   1.550 +    sf->SetResolution(gfxSize(aXResolution, aYResolution));
   1.551 +    presShell->SetResolution(aXResolution, aYResolution);
   1.552 +  }
   1.553 +
   1.554 +  return NS_OK;
   1.555 +}
   1.556 +
   1.557 +NS_IMETHODIMP
   1.558 +nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
   1.559 +{
   1.560 +  if (!nsContentUtils::IsCallerChrome()) {
   1.561 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.562 +  }
   1.563 +
   1.564 +  nsIPresShell* presShell = GetPresShell();
   1.565 +  if (!presShell) {
   1.566 +    return NS_ERROR_FAILURE;
   1.567 +  }
   1.568 +
   1.569 +  nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   1.570 +  if (sf) {
   1.571 +    const gfxSize& res = sf->GetResolution();
   1.572 +    *aXResolution = res.width;
   1.573 +    *aYResolution = res.height;
   1.574 +  } else {
   1.575 +    *aXResolution = presShell->GetXResolution();
   1.576 +    *aYResolution = presShell->GetYResolution();
   1.577 +  }
   1.578 +
   1.579 +  return NS_OK;
   1.580 +}
   1.581 +
   1.582 +NS_IMETHODIMP
   1.583 +nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) {
   1.584 +  if (!nsContentUtils::IsCallerChrome()) {
   1.585 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.586 +  }
   1.587 +
   1.588 +  nsIPresShell* presShell = GetPresShell();
   1.589 +  if (!presShell) {
   1.590 +    return NS_ERROR_FAILURE;
   1.591 +  }
   1.592 +
   1.593 +  const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
   1.594 +  *aIsResolutionSet = sf && sf->IsResolutionSet();
   1.595 +
   1.596 +  return NS_OK;
   1.597 +}
   1.598 +
   1.599 +NS_IMETHODIMP
   1.600 +nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
   1.601 +{
   1.602 +  if (!nsContentUtils::IsCallerChrome()) {
   1.603 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.604 +  }
   1.605 +
   1.606 +  nsIPresShell* presShell = GetPresShell();
   1.607 +  if (presShell) {
   1.608 +    presShell->SetIsFirstPaint(aIsFirstPaint);
   1.609 +    return NS_OK;
   1.610 +  }
   1.611 +  return NS_ERROR_FAILURE;
   1.612 +}
   1.613 +
   1.614 +NS_IMETHODIMP
   1.615 +nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint)
   1.616 +{
   1.617 +  if (!nsContentUtils::IsCallerChrome()) {
   1.618 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.619 +  }
   1.620 +
   1.621 +  nsIPresShell* presShell = GetPresShell();
   1.622 +  if (presShell) {
   1.623 +    *aIsFirstPaint = presShell->GetIsFirstPaint();
   1.624 +    return NS_OK;
   1.625 +  }
   1.626 +  return NS_ERROR_FAILURE;
   1.627 +}
   1.628 +
   1.629 +NS_IMETHODIMP
   1.630 +nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId)
   1.631 +{
   1.632 +  if (!nsContentUtils::IsCallerChrome()) {
   1.633 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.634 +  }
   1.635 +
   1.636 +  nsIPresShell* presShell = GetPresShell();
   1.637 +  if (presShell) {
   1.638 +    *aPresShellId = presShell->GetPresShellId();
   1.639 +    return NS_OK;
   1.640 +  }
   1.641 +  return NS_ERROR_FAILURE;
   1.642 +}
   1.643 +
   1.644 +/* static */
   1.645 +mozilla::Modifiers
   1.646 +nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers)
   1.647 +{
   1.648 +  Modifiers result = 0;
   1.649 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) {
   1.650 +    result |= mozilla::MODIFIER_SHIFT;
   1.651 +  }
   1.652 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) {
   1.653 +    result |= mozilla::MODIFIER_CONTROL;
   1.654 +  }
   1.655 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) {
   1.656 +    result |= mozilla::MODIFIER_ALT;
   1.657 +  }
   1.658 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) {
   1.659 +    result |= mozilla::MODIFIER_META;
   1.660 +  }
   1.661 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) {
   1.662 +    result |= mozilla::MODIFIER_ALTGRAPH;
   1.663 +  }
   1.664 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) {
   1.665 +    result |= mozilla::MODIFIER_CAPSLOCK;
   1.666 +  }
   1.667 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) {
   1.668 +    result |= mozilla::MODIFIER_FN;
   1.669 +  }
   1.670 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) {
   1.671 +    result |= mozilla::MODIFIER_NUMLOCK;
   1.672 +  }
   1.673 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) {
   1.674 +    result |= mozilla::MODIFIER_SCROLLLOCK;
   1.675 +  }
   1.676 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) {
   1.677 +    result |= mozilla::MODIFIER_SYMBOLLOCK;
   1.678 +  }
   1.679 +  if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) {
   1.680 +    result |= mozilla::MODIFIER_OS;
   1.681 +  }
   1.682 +  return result;
   1.683 +}
   1.684 +
   1.685 +NS_IMETHODIMP
   1.686 +nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
   1.687 +                                 float aX,
   1.688 +                                 float aY,
   1.689 +                                 int32_t aButton,
   1.690 +                                 int32_t aClickCount,
   1.691 +                                 int32_t aModifiers,
   1.692 +                                 bool aIgnoreRootScrollFrame,
   1.693 +                                 float aPressure,
   1.694 +                                 unsigned short aInputSourceArg,
   1.695 +                                 bool aIsSynthesized,
   1.696 +                                 uint8_t aOptionalArgCount,
   1.697 +                                 bool *aPreventDefault)
   1.698 +{
   1.699 +  return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
   1.700 +                              aIgnoreRootScrollFrame, aPressure,
   1.701 +                              aInputSourceArg, false, aPreventDefault,
   1.702 +                              aOptionalArgCount >= 4 ? aIsSynthesized : true);
   1.703 +}
   1.704 +
   1.705 +NS_IMETHODIMP
   1.706 +nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
   1.707 +                                         float aX,
   1.708 +                                         float aY,
   1.709 +                                         int32_t aButton,
   1.710 +                                         int32_t aClickCount,
   1.711 +                                         int32_t aModifiers,
   1.712 +                                         bool aIgnoreRootScrollFrame,
   1.713 +                                         float aPressure,
   1.714 +                                         unsigned short aInputSourceArg,
   1.715 +                                         bool aIsSynthesized,
   1.716 +                                         uint8_t aOptionalArgCount)
   1.717 +{
   1.718 +  PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow");
   1.719 +  return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
   1.720 +                              aIgnoreRootScrollFrame, aPressure,
   1.721 +                              aInputSourceArg, true, nullptr,
   1.722 +                              aOptionalArgCount >= 4 ? aIsSynthesized : true);
   1.723 +}
   1.724 +
   1.725 +static LayoutDeviceIntPoint
   1.726 +ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset,
   1.727 +              nsPresContext* aPresContext)
   1.728 +{
   1.729 +  return LayoutDeviceIntPoint::FromAppUnitsRounded(
   1.730 +    CSSPoint::ToAppUnits(aPoint) + aOffset,
   1.731 +    aPresContext->AppUnitsPerDevPixel());
   1.732 +}
   1.733 +
   1.734 +static inline int16_t
   1.735 +GetButtonsFlagForButton(int32_t aButton)
   1.736 +{
   1.737 +  switch (aButton) {
   1.738 +    case WidgetMouseEvent::eLeftButton:
   1.739 +      return WidgetMouseEvent::eLeftButtonFlag;
   1.740 +    case WidgetMouseEvent::eMiddleButton:
   1.741 +      return WidgetMouseEvent::eMiddleButtonFlag;
   1.742 +    case WidgetMouseEvent::eRightButton:
   1.743 +      return WidgetMouseEvent::eRightButtonFlag;
   1.744 +    case 4:
   1.745 +      return WidgetMouseEvent::e4thButtonFlag;
   1.746 +    case 5:
   1.747 +      return WidgetMouseEvent::e5thButtonFlag;
   1.748 +    default:
   1.749 +      NS_ERROR("Button not known.");
   1.750 +      return 0;
   1.751 +  }
   1.752 +}
   1.753 +
   1.754 +NS_IMETHODIMP
   1.755 +nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
   1.756 +                                       float aX,
   1.757 +                                       float aY,
   1.758 +                                       int32_t aButton,
   1.759 +                                       int32_t aClickCount,
   1.760 +                                       int32_t aModifiers,
   1.761 +                                       bool aIgnoreRootScrollFrame,
   1.762 +                                       float aPressure,
   1.763 +                                       unsigned short aInputSourceArg,
   1.764 +                                       bool aToWindow,
   1.765 +                                       bool *aPreventDefault,
   1.766 +                                       bool aIsSynthesized)
   1.767 +{
   1.768 +  if (!nsContentUtils::IsCallerChrome()) {
   1.769 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.770 +  }
   1.771 +
   1.772 +  // get the widget to send the event to
   1.773 +  nsPoint offset;
   1.774 +  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   1.775 +  if (!widget)
   1.776 +    return NS_ERROR_FAILURE;
   1.777 +
   1.778 +  int32_t msg;
   1.779 +  bool contextMenuKey = false;
   1.780 +  if (aType.EqualsLiteral("mousedown"))
   1.781 +    msg = NS_MOUSE_BUTTON_DOWN;
   1.782 +  else if (aType.EqualsLiteral("mouseup"))
   1.783 +    msg = NS_MOUSE_BUTTON_UP;
   1.784 +  else if (aType.EqualsLiteral("mousemove"))
   1.785 +    msg = NS_MOUSE_MOVE;
   1.786 +  else if (aType.EqualsLiteral("mouseover"))
   1.787 +    msg = NS_MOUSE_ENTER;
   1.788 +  else if (aType.EqualsLiteral("mouseout"))
   1.789 +    msg = NS_MOUSE_EXIT;
   1.790 +  else if (aType.EqualsLiteral("contextmenu")) {
   1.791 +    msg = NS_CONTEXTMENU;
   1.792 +    contextMenuKey = (aButton == 0);
   1.793 +  } else if (aType.EqualsLiteral("MozMouseHittest"))
   1.794 +    msg = NS_MOUSE_MOZHITTEST;
   1.795 +  else
   1.796 +    return NS_ERROR_FAILURE;
   1.797 +
   1.798 +  if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
   1.799 +    aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
   1.800 +  }
   1.801 +
   1.802 +  WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal,
   1.803 +                         contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
   1.804 +                                          WidgetMouseEvent::eNormal);
   1.805 +  event.modifiers = GetWidgetModifiers(aModifiers);
   1.806 +  event.button = aButton;
   1.807 +  event.buttons = GetButtonsFlagForButton(aButton);
   1.808 +  event.widget = widget;
   1.809 +  event.pressure = aPressure;
   1.810 +  event.inputSource = aInputSourceArg;
   1.811 +  event.clickCount = aClickCount;
   1.812 +  event.time = PR_IntervalNow();
   1.813 +  event.mFlags.mIsSynthesizedForTests = aIsSynthesized;
   1.814 +
   1.815 +  nsPresContext* presContext = GetPresContext();
   1.816 +  if (!presContext)
   1.817 +    return NS_ERROR_FAILURE;
   1.818 +
   1.819 +  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   1.820 +  event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
   1.821 +
   1.822 +  nsEventStatus status;
   1.823 +  if (aToWindow) {
   1.824 +    nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
   1.825 +    if (!presShell)
   1.826 +      return NS_ERROR_FAILURE;
   1.827 +    nsViewManager* viewManager = presShell->GetViewManager();
   1.828 +    if (!viewManager)
   1.829 +      return NS_ERROR_FAILURE;
   1.830 +    nsView* view = viewManager->GetRootView();
   1.831 +    if (!view)
   1.832 +      return NS_ERROR_FAILURE;
   1.833 +
   1.834 +    status = nsEventStatus_eIgnore;
   1.835 +    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
   1.836 +  }
   1.837 +  nsresult rv = widget->DispatchEvent(&event, status);
   1.838 +  *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
   1.839 +
   1.840 +  return rv;
   1.841 +}
   1.842 +
   1.843 +NS_IMETHODIMP
   1.844 +nsDOMWindowUtils::SendPointerEvent(const nsAString& aType,
   1.845 +                                   float aX,
   1.846 +                                   float aY,
   1.847 +                                   int32_t aButton,
   1.848 +                                   int32_t aClickCount,
   1.849 +                                   int32_t aModifiers,
   1.850 +                                   bool aIgnoreRootScrollFrame,
   1.851 +                                   float aPressure,
   1.852 +                                   unsigned short aInputSourceArg,
   1.853 +                                   int32_t aPointerId,
   1.854 +                                   int32_t aWidth,
   1.855 +                                   int32_t aHeight,
   1.856 +                                   int32_t tiltX,
   1.857 +                                   int32_t tiltY,
   1.858 +                                   bool aIsPrimary,
   1.859 +                                   bool aIsSynthesized,
   1.860 +                                   uint8_t aOptionalArgCount,
   1.861 +                                   bool* aPreventDefault)
   1.862 +{
   1.863 +  if (!nsContentUtils::IsCallerChrome()) {
   1.864 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.865 +  }
   1.866 +
   1.867 +  // get the widget to send the event to
   1.868 +  nsPoint offset;
   1.869 +  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   1.870 +  if (!widget) {
   1.871 +    return NS_ERROR_FAILURE;
   1.872 +  }
   1.873 +
   1.874 +  int32_t msg;
   1.875 +  if (aType.EqualsLiteral("pointerdown")) {
   1.876 +    msg = NS_POINTER_DOWN;
   1.877 +  } else if (aType.EqualsLiteral("pointerup")) {
   1.878 +    msg = NS_POINTER_UP;
   1.879 +  } else if (aType.EqualsLiteral("pointermove")) {
   1.880 +    msg = NS_POINTER_MOVE;
   1.881 +  } else if (aType.EqualsLiteral("pointerover")) {
   1.882 +    msg = NS_POINTER_OVER;
   1.883 +  } else if (aType.EqualsLiteral("pointerout")) {
   1.884 +    msg = NS_POINTER_OUT;
   1.885 +  } else {
   1.886 +    return NS_ERROR_FAILURE;
   1.887 +  }
   1.888 +
   1.889 +  if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
   1.890 +    aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
   1.891 +  }
   1.892 +
   1.893 +  WidgetPointerEvent event(true, msg, widget);
   1.894 +  event.modifiers = GetWidgetModifiers(aModifiers);
   1.895 +  event.button = aButton;
   1.896 +  event.buttons = GetButtonsFlagForButton(aButton);
   1.897 +  event.widget = widget;
   1.898 +  event.pressure = aPressure;
   1.899 +  event.inputSource = aInputSourceArg;
   1.900 +  event.pointerId = aPointerId;
   1.901 +  event.width = aWidth;
   1.902 +  event.height = aHeight;
   1.903 +  event.tiltX = tiltX;
   1.904 +  event.tiltY = tiltY;
   1.905 +  event.isPrimary = aIsPrimary;
   1.906 +  event.clickCount = aClickCount;
   1.907 +  event.time = PR_IntervalNow();
   1.908 +  event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
   1.909 +
   1.910 +  nsPresContext* presContext = GetPresContext();
   1.911 +  if (!presContext) {
   1.912 +    return NS_ERROR_FAILURE;
   1.913 +  }
   1.914 +
   1.915 +  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   1.916 +  event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
   1.917 +
   1.918 +  nsEventStatus status;
   1.919 +  nsresult rv = widget->DispatchEvent(&event, status);
   1.920 +  *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
   1.921 +
   1.922 +  return rv;
   1.923 +}
   1.924 +
   1.925 +NS_IMETHODIMP
   1.926 +nsDOMWindowUtils::SendWheelEvent(float aX,
   1.927 +                                 float aY,
   1.928 +                                 double aDeltaX,
   1.929 +                                 double aDeltaY,
   1.930 +                                 double aDeltaZ,
   1.931 +                                 uint32_t aDeltaMode,
   1.932 +                                 int32_t aModifiers,
   1.933 +                                 int32_t aLineOrPageDeltaX,
   1.934 +                                 int32_t aLineOrPageDeltaY,
   1.935 +                                 uint32_t aOptions)
   1.936 +{
   1.937 +  if (!nsContentUtils::IsCallerChrome()) {
   1.938 +    return NS_ERROR_DOM_SECURITY_ERR;
   1.939 +  }
   1.940 +
   1.941 +  // get the widget to send the event to
   1.942 +  nsPoint offset;
   1.943 +  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   1.944 +  if (!widget) {
   1.945 +    return NS_ERROR_NULL_POINTER;
   1.946 +  }
   1.947 +
   1.948 +  WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
   1.949 +  wheelEvent.modifiers = GetWidgetModifiers(aModifiers);
   1.950 +  wheelEvent.deltaX = aDeltaX;
   1.951 +  wheelEvent.deltaY = aDeltaY;
   1.952 +  wheelEvent.deltaZ = aDeltaZ;
   1.953 +  wheelEvent.deltaMode = aDeltaMode;
   1.954 +  wheelEvent.isMomentum =
   1.955 +    (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
   1.956 +  wheelEvent.isPixelOnlyDevice =
   1.957 +    (aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0;
   1.958 +  NS_ENSURE_TRUE(
   1.959 +    !wheelEvent.isPixelOnlyDevice ||
   1.960 +      aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL,
   1.961 +    NS_ERROR_INVALID_ARG);
   1.962 +  wheelEvent.customizedByUserPrefs =
   1.963 +    (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
   1.964 +  wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;
   1.965 +  wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY;
   1.966 +  wheelEvent.widget = widget;
   1.967 +
   1.968 +  wheelEvent.time = PR_Now() / 1000;
   1.969 +
   1.970 +  nsPresContext* presContext = GetPresContext();
   1.971 +  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
   1.972 +
   1.973 +  wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   1.974 +
   1.975 +  nsEventStatus status;
   1.976 +  nsresult rv = widget->DispatchEvent(&wheelEvent, status);
   1.977 +  NS_ENSURE_SUCCESS(rv, rv);
   1.978 +
   1.979 +  bool failedX = false;
   1.980 +  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
   1.981 +      wheelEvent.overflowDeltaX != 0) {
   1.982 +    failedX = true;
   1.983 +  }
   1.984 +  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) &&
   1.985 +      wheelEvent.overflowDeltaX <= 0) {
   1.986 +    failedX = true;
   1.987 +  }
   1.988 +  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) &&
   1.989 +      wheelEvent.overflowDeltaX >= 0) {
   1.990 +    failedX = true;
   1.991 +  }
   1.992 +  bool failedY = false;
   1.993 +  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) &&
   1.994 +      wheelEvent.overflowDeltaY != 0) {
   1.995 +    failedY = true;
   1.996 +  }
   1.997 +  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) &&
   1.998 +      wheelEvent.overflowDeltaY <= 0) {
   1.999 +    failedY = true;
  1.1000 +  }
  1.1001 +  if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) &&
  1.1002 +      wheelEvent.overflowDeltaY >= 0) {
  1.1003 +    failedY = true;
  1.1004 +  }
  1.1005 +
  1.1006 +#ifdef DEBUG
  1.1007 +  if (failedX) {
  1.1008 +    nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaX: %f",
  1.1009 +                             wheelEvent.overflowDeltaX);
  1.1010 +    NS_WARNING(debugMsg.get());
  1.1011 +  }
  1.1012 +  if (failedY) {
  1.1013 +    nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaY: %f",
  1.1014 +                             wheelEvent.overflowDeltaY);
  1.1015 +    NS_WARNING(debugMsg.get());
  1.1016 +  }
  1.1017 +#endif
  1.1018 +
  1.1019 +  return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE;
  1.1020 +}
  1.1021 +
  1.1022 +NS_IMETHODIMP
  1.1023 +nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
  1.1024 +                                 uint32_t *aIdentifiers,
  1.1025 +                                 int32_t *aXs,
  1.1026 +                                 int32_t *aYs,
  1.1027 +                                 uint32_t *aRxs,
  1.1028 +                                 uint32_t *aRys,
  1.1029 +                                 float *aRotationAngles,
  1.1030 +                                 float *aForces,
  1.1031 +                                 uint32_t aCount,
  1.1032 +                                 int32_t aModifiers,
  1.1033 +                                 bool aIgnoreRootScrollFrame,
  1.1034 +                                 bool *aPreventDefault)
  1.1035 +{
  1.1036 +  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
  1.1037 +                              aRotationAngles, aForces, aCount, aModifiers,
  1.1038 +                              aIgnoreRootScrollFrame, false, aPreventDefault);
  1.1039 +}
  1.1040 +
  1.1041 +NS_IMETHODIMP
  1.1042 +nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
  1.1043 +                                         uint32_t* aIdentifiers,
  1.1044 +                                         int32_t* aXs,
  1.1045 +                                         int32_t* aYs,
  1.1046 +                                         uint32_t* aRxs,
  1.1047 +                                         uint32_t* aRys,
  1.1048 +                                         float* aRotationAngles,
  1.1049 +                                         float* aForces,
  1.1050 +                                         uint32_t aCount,
  1.1051 +                                         int32_t aModifiers,
  1.1052 +                                         bool aIgnoreRootScrollFrame,
  1.1053 +                                         bool* aPreventDefault)
  1.1054 +{
  1.1055 +  return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
  1.1056 +                              aRotationAngles, aForces, aCount, aModifiers,
  1.1057 +                              aIgnoreRootScrollFrame, true, aPreventDefault);
  1.1058 +}
  1.1059 +
  1.1060 +NS_IMETHODIMP
  1.1061 +nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
  1.1062 +                                       uint32_t* aIdentifiers,
  1.1063 +                                       int32_t* aXs,
  1.1064 +                                       int32_t* aYs,
  1.1065 +                                       uint32_t* aRxs,
  1.1066 +                                       uint32_t* aRys,
  1.1067 +                                       float* aRotationAngles,
  1.1068 +                                       float* aForces,
  1.1069 +                                       uint32_t aCount,
  1.1070 +                                       int32_t aModifiers,
  1.1071 +                                       bool aIgnoreRootScrollFrame,
  1.1072 +                                       bool aToWindow,
  1.1073 +                                       bool* aPreventDefault)
  1.1074 +{
  1.1075 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1076 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1077 +  }
  1.1078 +
  1.1079 +  // get the widget to send the event to
  1.1080 +  nsPoint offset;
  1.1081 +  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
  1.1082 +  if (!widget) {
  1.1083 +    return NS_ERROR_NULL_POINTER;
  1.1084 +  }
  1.1085 +  int32_t msg;
  1.1086 +  if (aType.EqualsLiteral("touchstart")) {
  1.1087 +    msg = NS_TOUCH_START;
  1.1088 +  } else if (aType.EqualsLiteral("touchmove")) {
  1.1089 +    msg = NS_TOUCH_MOVE;
  1.1090 +  } else if (aType.EqualsLiteral("touchend")) {
  1.1091 +    msg = NS_TOUCH_END;
  1.1092 +  } else if (aType.EqualsLiteral("touchcancel")) {
  1.1093 +    msg = NS_TOUCH_CANCEL;
  1.1094 +  } else {
  1.1095 +    return NS_ERROR_UNEXPECTED;
  1.1096 +  }
  1.1097 +  WidgetTouchEvent event(true, msg, widget);
  1.1098 +  event.modifiers = GetWidgetModifiers(aModifiers);
  1.1099 +  event.widget = widget;
  1.1100 +  event.time = PR_Now();
  1.1101 +
  1.1102 +  nsPresContext* presContext = GetPresContext();
  1.1103 +  if (!presContext) {
  1.1104 +    return NS_ERROR_FAILURE;
  1.1105 +  }
  1.1106 +  event.touches.SetCapacity(aCount);
  1.1107 +  for (uint32_t i = 0; i < aCount; ++i) {
  1.1108 +    LayoutDeviceIntPoint pt =
  1.1109 +      ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
  1.1110 +    nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
  1.1111 +                                  LayoutDeviceIntPoint::ToUntyped(pt),
  1.1112 +                                  nsIntPoint(aRxs[i], aRys[i]),
  1.1113 +                                  aRotationAngles[i],
  1.1114 +                                  aForces[i]);
  1.1115 +    event.touches.AppendElement(t);
  1.1116 +  }
  1.1117 +
  1.1118 +  nsEventStatus status;
  1.1119 +  if (aToWindow) {
  1.1120 +    nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
  1.1121 +    if (!presShell) {
  1.1122 +      return NS_ERROR_FAILURE;
  1.1123 +    }
  1.1124 +
  1.1125 +    nsViewManager* viewManager = presShell->GetViewManager();
  1.1126 +    if (!viewManager) {
  1.1127 +      return NS_ERROR_FAILURE;
  1.1128 +    }
  1.1129 +
  1.1130 +    nsView* view = viewManager->GetRootView();
  1.1131 +    if (!view) {
  1.1132 +      return NS_ERROR_FAILURE;
  1.1133 +    }
  1.1134 +
  1.1135 +    status = nsEventStatus_eIgnore;
  1.1136 +    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
  1.1137 +    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
  1.1138 +  }
  1.1139 +
  1.1140 +  nsresult rv = widget->DispatchEvent(&event, status);
  1.1141 +  *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
  1.1142 +  return rv;
  1.1143 +}
  1.1144 +
  1.1145 +NS_IMETHODIMP
  1.1146 +nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
  1.1147 +                               int32_t aKeyCode,
  1.1148 +                               int32_t aCharCode,
  1.1149 +                               int32_t aModifiers,
  1.1150 +                               uint32_t aAdditionalFlags,
  1.1151 +                               bool* aDefaultActionTaken)
  1.1152 +{
  1.1153 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1154 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1155 +  }
  1.1156 +
  1.1157 +  // get the widget to send the event to
  1.1158 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1159 +  if (!widget)
  1.1160 +    return NS_ERROR_FAILURE;
  1.1161 +
  1.1162 +  int32_t msg;
  1.1163 +  if (aType.EqualsLiteral("keydown"))
  1.1164 +    msg = NS_KEY_DOWN;
  1.1165 +  else if (aType.EqualsLiteral("keyup"))
  1.1166 +    msg = NS_KEY_UP;
  1.1167 +  else if (aType.EqualsLiteral("keypress"))
  1.1168 +    msg = NS_KEY_PRESS;
  1.1169 +  else
  1.1170 +    return NS_ERROR_FAILURE;
  1.1171 +
  1.1172 +  WidgetKeyboardEvent event(true, msg, widget);
  1.1173 +  event.modifiers = GetWidgetModifiers(aModifiers);
  1.1174 +
  1.1175 +  if (msg == NS_KEY_PRESS) {
  1.1176 +    event.keyCode = aCharCode ? 0 : aKeyCode;
  1.1177 +    event.charCode = aCharCode;
  1.1178 +  } else {
  1.1179 +    event.keyCode = aKeyCode;
  1.1180 +    event.charCode = 0;
  1.1181 +  }
  1.1182 +
  1.1183 +  uint32_t locationFlag = (aAdditionalFlags &
  1.1184 +    (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT |
  1.1185 +     KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD |
  1.1186 +     KEY_FLAG_LOCATION_MOBILE | KEY_FLAG_LOCATION_JOYSTICK));
  1.1187 +  switch (locationFlag) {
  1.1188 +    case KEY_FLAG_LOCATION_STANDARD:
  1.1189 +      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
  1.1190 +      break;
  1.1191 +    case KEY_FLAG_LOCATION_LEFT:
  1.1192 +      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
  1.1193 +      break;
  1.1194 +    case KEY_FLAG_LOCATION_RIGHT:
  1.1195 +      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
  1.1196 +      break;
  1.1197 +    case KEY_FLAG_LOCATION_NUMPAD:
  1.1198 +      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
  1.1199 +      break;
  1.1200 +    case KEY_FLAG_LOCATION_MOBILE:
  1.1201 +      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
  1.1202 +      break;
  1.1203 +    case KEY_FLAG_LOCATION_JOYSTICK:
  1.1204 +      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_JOYSTICK;
  1.1205 +      break;
  1.1206 +    default:
  1.1207 +      if (locationFlag != 0) {
  1.1208 +        return NS_ERROR_INVALID_ARG;
  1.1209 +      }
  1.1210 +      // If location flag isn't set, choose the location from keycode.
  1.1211 +      switch (aKeyCode) {
  1.1212 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD0:
  1.1213 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD1:
  1.1214 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD2:
  1.1215 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD3:
  1.1216 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD4:
  1.1217 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD5:
  1.1218 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD6:
  1.1219 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD7:
  1.1220 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD8:
  1.1221 +        case nsIDOMKeyEvent::DOM_VK_NUMPAD9:
  1.1222 +        case nsIDOMKeyEvent::DOM_VK_MULTIPLY:
  1.1223 +        case nsIDOMKeyEvent::DOM_VK_ADD:
  1.1224 +        case nsIDOMKeyEvent::DOM_VK_SEPARATOR:
  1.1225 +        case nsIDOMKeyEvent::DOM_VK_SUBTRACT:
  1.1226 +        case nsIDOMKeyEvent::DOM_VK_DECIMAL:
  1.1227 +        case nsIDOMKeyEvent::DOM_VK_DIVIDE:
  1.1228 +          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
  1.1229 +          break;
  1.1230 +        case nsIDOMKeyEvent::DOM_VK_SHIFT:
  1.1231 +        case nsIDOMKeyEvent::DOM_VK_CONTROL:
  1.1232 +        case nsIDOMKeyEvent::DOM_VK_ALT:
  1.1233 +        case nsIDOMKeyEvent::DOM_VK_META:
  1.1234 +          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
  1.1235 +          break;
  1.1236 +        default:
  1.1237 +          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
  1.1238 +          break;
  1.1239 +      }
  1.1240 +      break;
  1.1241 +  }
  1.1242 +
  1.1243 +  event.refPoint.x = event.refPoint.y = 0;
  1.1244 +  event.time = PR_IntervalNow();
  1.1245 +  event.mFlags.mIsSynthesizedForTests = true;
  1.1246 +
  1.1247 +  if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) {
  1.1248 +    event.mFlags.mDefaultPrevented = true;
  1.1249 +  }
  1.1250 +
  1.1251 +  nsEventStatus status;
  1.1252 +  nsresult rv = widget->DispatchEvent(&event, status);
  1.1253 +  NS_ENSURE_SUCCESS(rv, rv);
  1.1254 +
  1.1255 +  *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
  1.1256 +  
  1.1257 +  return NS_OK;
  1.1258 +}
  1.1259 +
  1.1260 +NS_IMETHODIMP
  1.1261 +nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout,
  1.1262 +                                     int32_t aNativeKeyCode,
  1.1263 +                                     int32_t aModifiers,
  1.1264 +                                     const nsAString& aCharacters,
  1.1265 +                                     const nsAString& aUnmodifiedCharacters)
  1.1266 +{
  1.1267 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1268 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1269 +  }
  1.1270 +
  1.1271 +  // get the widget to send the event to
  1.1272 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1273 +  if (!widget)
  1.1274 +    return NS_ERROR_FAILURE;
  1.1275 +
  1.1276 +  return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
  1.1277 +                                          aModifiers, aCharacters, aUnmodifiedCharacters);
  1.1278 +}
  1.1279 +
  1.1280 +NS_IMETHODIMP
  1.1281 +nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX,
  1.1282 +                                       int32_t aScreenY,
  1.1283 +                                       int32_t aNativeMessage,
  1.1284 +                                       int32_t aModifierFlags,
  1.1285 +                                       nsIDOMElement* aElement)
  1.1286 +{
  1.1287 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1288 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1289 +  }
  1.1290 +
  1.1291 +  // get the widget to send the event to
  1.1292 +  nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
  1.1293 +  if (!widget)
  1.1294 +    return NS_ERROR_FAILURE;
  1.1295 +
  1.1296 +  return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY),
  1.1297 +                                            aNativeMessage, aModifierFlags);
  1.1298 +}
  1.1299 +
  1.1300 +NS_IMETHODIMP
  1.1301 +nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX,
  1.1302 +                                             int32_t aScreenY,
  1.1303 +                                             uint32_t aNativeMessage,
  1.1304 +                                             double aDeltaX,
  1.1305 +                                             double aDeltaY,
  1.1306 +                                             double aDeltaZ,
  1.1307 +                                             uint32_t aModifierFlags,
  1.1308 +                                             uint32_t aAdditionalFlags,
  1.1309 +                                             nsIDOMElement* aElement)
  1.1310 +{
  1.1311 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1312 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1313 +  }
  1.1314 +
  1.1315 +  // get the widget to send the event to
  1.1316 +  nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
  1.1317 +  if (!widget) {
  1.1318 +    return NS_ERROR_FAILURE;
  1.1319 +  }
  1.1320 +
  1.1321 +  return widget->SynthesizeNativeMouseScrollEvent(nsIntPoint(aScreenX,
  1.1322 +                                                             aScreenY),
  1.1323 +                                                  aNativeMessage,
  1.1324 +                                                  aDeltaX, aDeltaY, aDeltaZ,
  1.1325 +                                                  aModifierFlags,
  1.1326 +                                                  aAdditionalFlags);
  1.1327 +}
  1.1328 +
  1.1329 +NS_IMETHODIMP
  1.1330 +nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId,
  1.1331 +                                       uint32_t aTouchState,
  1.1332 +                                       int32_t aScreenX,
  1.1333 +                                       int32_t aScreenY,
  1.1334 +                                       double aPressure,
  1.1335 +                                       uint32_t aOrientation)
  1.1336 +{
  1.1337 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1338 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1339 +  }
  1.1340 +
  1.1341 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1342 +  if (!widget) {
  1.1343 +    return NS_ERROR_FAILURE;
  1.1344 +  }
  1.1345 +
  1.1346 +  if (aPressure < 0 || aPressure > 1 || aOrientation > 359) {
  1.1347 +    return NS_ERROR_INVALID_ARG;
  1.1348 +  }
  1.1349 +
  1.1350 +  return widget->SynthesizeNativeTouchPoint(aPointerId,
  1.1351 +                                            (nsIWidget::TouchPointerState)aTouchState,
  1.1352 +                                            nsIntPoint(aScreenX, aScreenY),
  1.1353 +                                            aPressure, aOrientation);
  1.1354 +}
  1.1355 +
  1.1356 +NS_IMETHODIMP
  1.1357 +nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX,
  1.1358 +                                     int32_t aScreenY,
  1.1359 +                                     bool aLongTap)
  1.1360 +{
  1.1361 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1362 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1363 +  }
  1.1364 +
  1.1365 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1366 +  if (!widget) {
  1.1367 +    return NS_ERROR_FAILURE;
  1.1368 +  }
  1.1369 +  return widget->SynthesizeNativeTouchTap(nsIntPoint(aScreenX, aScreenY), aLongTap);
  1.1370 +}
  1.1371 +
  1.1372 +NS_IMETHODIMP
  1.1373 +nsDOMWindowUtils::ClearNativeTouchSequence()
  1.1374 +{
  1.1375 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1376 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1377 +  }
  1.1378 +
  1.1379 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1380 +  if (!widget) {
  1.1381 +    return NS_ERROR_FAILURE;
  1.1382 +  }
  1.1383 +  return widget->ClearNativeTouchSequence();
  1.1384 +}
  1.1385 +
  1.1386 +NS_IMETHODIMP
  1.1387 +nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
  1.1388 +{
  1.1389 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1390 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1391 +  }
  1.1392 +
  1.1393 +  // get the widget to send the event to
  1.1394 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1395 +  if (!widget)
  1.1396 +    return NS_ERROR_FAILURE;
  1.1397 +
  1.1398 +  return widget->ActivateNativeMenuItemAt(indexString);
  1.1399 +}
  1.1400 +
  1.1401 +NS_IMETHODIMP
  1.1402 +nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
  1.1403 +{
  1.1404 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1405 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1406 +  }
  1.1407 +
  1.1408 +  // get the widget to send the event to
  1.1409 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1410 +  if (!widget)
  1.1411 +    return NS_ERROR_FAILURE;
  1.1412 +
  1.1413 +  return widget->ForceUpdateNativeMenuAt(indexString);
  1.1414 +}
  1.1415 +
  1.1416 +nsIWidget*
  1.1417 +nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
  1.1418 +{
  1.1419 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.1420 +  if (window) {
  1.1421 +    nsIDocShell *docShell = window->GetDocShell();
  1.1422 +    if (docShell) {
  1.1423 +      nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  1.1424 +      if (presShell) {
  1.1425 +        nsIFrame* frame = presShell->GetRootFrame();
  1.1426 +        if (frame)
  1.1427 +          return frame->GetView()->GetNearestWidget(aOffset);
  1.1428 +      }
  1.1429 +    }
  1.1430 +  }
  1.1431 +
  1.1432 +  return nullptr;
  1.1433 +}
  1.1434 +
  1.1435 +nsIWidget*
  1.1436 +nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
  1.1437 +{
  1.1438 +  if (!aElement)
  1.1439 +    return GetWidget();
  1.1440 +
  1.1441 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  1.1442 +  nsIDocument* doc = content->GetCurrentDoc();
  1.1443 +  nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
  1.1444 +
  1.1445 +  if (presShell) {
  1.1446 +    nsIFrame* frame = content->GetPrimaryFrame();
  1.1447 +    if (!frame) {
  1.1448 +      frame = presShell->GetRootFrame();
  1.1449 +    }
  1.1450 +    if (frame)
  1.1451 +      return frame->GetNearestWidget();
  1.1452 +  }
  1.1453 +
  1.1454 +  return nullptr;
  1.1455 +}
  1.1456 +
  1.1457 +NS_IMETHODIMP
  1.1458 +nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
  1.1459 +{
  1.1460 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1461 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1462 +  }
  1.1463 +
  1.1464 +  nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
  1.1465 +  nsIFocusManager* fm = nsFocusManager::GetFocusManager();
  1.1466 +  if (fm) {
  1.1467 +    if (aElement)
  1.1468 +      fm->SetFocus(aElement, 0);
  1.1469 +    else
  1.1470 +      fm->ClearFocus(window);
  1.1471 +  }
  1.1472 +
  1.1473 +  return NS_OK;
  1.1474 +}
  1.1475 +
  1.1476 +NS_IMETHODIMP
  1.1477 +nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
  1.1478 +                                 int32_t aExtraForgetSkippableCalls)
  1.1479 +{
  1.1480 +  PROFILER_LABEL("GC", "GarbageCollect");
  1.1481 +  // Always permit this in debug builds.
  1.1482 +#ifndef DEBUG
  1.1483 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1484 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1485 +  }
  1.1486 +#endif
  1.1487 +
  1.1488 +  nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
  1.1489 +  nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
  1.1490 +
  1.1491 +  return NS_OK;
  1.1492 +}
  1.1493 +
  1.1494 +NS_IMETHODIMP
  1.1495 +nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener,
  1.1496 +                               int32_t aExtraForgetSkippableCalls)
  1.1497 +{
  1.1498 +  // Always permit this in debug builds.
  1.1499 +#ifndef DEBUG
  1.1500 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1501 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1502 +  }
  1.1503 +#endif
  1.1504 +
  1.1505 +  nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
  1.1506 +  return NS_OK;
  1.1507 +}
  1.1508 +
  1.1509 +NS_IMETHODIMP
  1.1510 +nsDOMWindowUtils::RunNextCollectorTimer()
  1.1511 +{
  1.1512 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1513 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1514 +  }
  1.1515 +
  1.1516 +  nsJSContext::RunNextCollectorTimer();
  1.1517 +
  1.1518 +  return NS_OK;
  1.1519 +}
  1.1520 +
  1.1521 +NS_IMETHODIMP
  1.1522 +nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
  1.1523 +                                         float aX,
  1.1524 +                                         float aY,
  1.1525 +                                         uint32_t aDirection,
  1.1526 +                                         double aDelta,
  1.1527 +                                         int32_t aModifiers,
  1.1528 +                                         uint32_t aClickCount)
  1.1529 +{
  1.1530 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1531 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1532 +  }
  1.1533 +
  1.1534 +  // get the widget to send the event to
  1.1535 +  nsPoint offset;
  1.1536 +  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
  1.1537 +  if (!widget)
  1.1538 +    return NS_ERROR_FAILURE;
  1.1539 +
  1.1540 +  int32_t msg;
  1.1541 +  if (aType.EqualsLiteral("MozSwipeGestureStart"))
  1.1542 +    msg = NS_SIMPLE_GESTURE_SWIPE_START;
  1.1543 +  else if (aType.EqualsLiteral("MozSwipeGestureUpdate"))
  1.1544 +    msg = NS_SIMPLE_GESTURE_SWIPE_UPDATE;
  1.1545 +  else if (aType.EqualsLiteral("MozSwipeGestureEnd"))
  1.1546 +    msg = NS_SIMPLE_GESTURE_SWIPE_END;
  1.1547 +  else if (aType.EqualsLiteral("MozSwipeGesture"))
  1.1548 +    msg = NS_SIMPLE_GESTURE_SWIPE;
  1.1549 +  else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
  1.1550 +    msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
  1.1551 +  else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
  1.1552 +    msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
  1.1553 +  else if (aType.EqualsLiteral("MozMagnifyGesture"))
  1.1554 +    msg = NS_SIMPLE_GESTURE_MAGNIFY;
  1.1555 +  else if (aType.EqualsLiteral("MozRotateGestureStart"))
  1.1556 +    msg = NS_SIMPLE_GESTURE_ROTATE_START;
  1.1557 +  else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
  1.1558 +    msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
  1.1559 +  else if (aType.EqualsLiteral("MozRotateGesture"))
  1.1560 +    msg = NS_SIMPLE_GESTURE_ROTATE;
  1.1561 +  else if (aType.EqualsLiteral("MozTapGesture"))
  1.1562 +    msg = NS_SIMPLE_GESTURE_TAP;
  1.1563 +  else if (aType.EqualsLiteral("MozPressTapGesture"))
  1.1564 +    msg = NS_SIMPLE_GESTURE_PRESSTAP;
  1.1565 +  else if (aType.EqualsLiteral("MozEdgeUIStarted"))
  1.1566 +    msg = NS_SIMPLE_GESTURE_EDGE_STARTED;
  1.1567 +  else if (aType.EqualsLiteral("MozEdgeUICanceled"))
  1.1568 +    msg = NS_SIMPLE_GESTURE_EDGE_CANCELED;
  1.1569 +  else if (aType.EqualsLiteral("MozEdgeUICompleted"))
  1.1570 +    msg = NS_SIMPLE_GESTURE_EDGE_COMPLETED;
  1.1571 +  else
  1.1572 +    return NS_ERROR_FAILURE;
  1.1573 + 
  1.1574 +  WidgetSimpleGestureEvent event(true, msg, widget);
  1.1575 +  event.modifiers = GetWidgetModifiers(aModifiers);
  1.1576 +  event.direction = aDirection;
  1.1577 +  event.delta = aDelta;
  1.1578 +  event.clickCount = aClickCount;
  1.1579 +  event.time = PR_IntervalNow();
  1.1580 +
  1.1581 +  nsPresContext* presContext = GetPresContext();
  1.1582 +  if (!presContext)
  1.1583 +    return NS_ERROR_FAILURE;
  1.1584 +
  1.1585 +  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
  1.1586 +
  1.1587 +  nsEventStatus status;
  1.1588 +  return widget->DispatchEvent(&event, status);
  1.1589 +}
  1.1590 +
  1.1591 +NS_IMETHODIMP
  1.1592 +nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
  1.1593 +                                   bool aIgnoreRootScrollFrame,
  1.1594 +                                   bool aFlushLayout,
  1.1595 +                                   nsIDOMElement** aReturn)
  1.1596 +{
  1.1597 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1598 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1599 +  }
  1.1600 +
  1.1601 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.1602 +  NS_ENSURE_STATE(doc);
  1.1603 +
  1.1604 +  Element* el =
  1.1605 +    doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
  1.1606 +  nsCOMPtr<nsIDOMElement> retval = do_QueryInterface(el);
  1.1607 +  retval.forget(aReturn);
  1.1608 +  return NS_OK;
  1.1609 +}
  1.1610 +
  1.1611 +NS_IMETHODIMP
  1.1612 +nsDOMWindowUtils::NodesFromRect(float aX, float aY,
  1.1613 +                                float aTopSize, float aRightSize,
  1.1614 +                                float aBottomSize, float aLeftSize,
  1.1615 +                                bool aIgnoreRootScrollFrame,
  1.1616 +                                bool aFlushLayout,
  1.1617 +                                nsIDOMNodeList** aReturn)
  1.1618 +{
  1.1619 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1620 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1621 +  }
  1.1622 +
  1.1623 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.1624 +  NS_ENSURE_STATE(doc);
  1.1625 +
  1.1626 +  return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize, 
  1.1627 +                                  aIgnoreRootScrollFrame, aFlushLayout, aReturn);
  1.1628 +}
  1.1629 +
  1.1630 +NS_IMETHODIMP
  1.1631 +nsDOMWindowUtils::GetTranslationNodes(nsIDOMNode* aRoot,
  1.1632 +                                      nsITranslationNodeList** aRetVal)
  1.1633 +{
  1.1634 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1635 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1636 +  }
  1.1637 +
  1.1638 +  NS_ENSURE_ARG_POINTER(aRetVal);
  1.1639 +  nsCOMPtr<nsIContent> root = do_QueryInterface(aRoot);
  1.1640 +  NS_ENSURE_STATE(root);
  1.1641 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.1642 +  NS_ENSURE_STATE(doc);
  1.1643 +
  1.1644 +  if (root->OwnerDoc() != doc) {
  1.1645 +    return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
  1.1646 +  }
  1.1647 +
  1.1648 +  nsTHashtable<nsPtrHashKey<nsIContent>> translationNodesHash(1000);
  1.1649 +  nsRefPtr<nsTranslationNodeList> list = new nsTranslationNodeList;
  1.1650 +
  1.1651 +  uint32_t limit = 15000;
  1.1652 +
  1.1653 +  // We begin iteration with content->GetNextNode because we want to explictly
  1.1654 +  // skip the root tag from being a translation node.
  1.1655 +  nsIContent* content = root;
  1.1656 +  while ((limit > 0) && (content = content->GetNextNode(root))) {
  1.1657 +    if (!content->IsHTML()) {
  1.1658 +      continue;
  1.1659 +    }
  1.1660 +
  1.1661 +    nsIAtom* localName = content->Tag();
  1.1662 +
  1.1663 +    // Skip elements that usually contain non-translatable text content.
  1.1664 +    if (localName == nsGkAtoms::script ||
  1.1665 +        localName == nsGkAtoms::iframe ||
  1.1666 +        localName == nsGkAtoms::frameset ||
  1.1667 +        localName == nsGkAtoms::frame ||
  1.1668 +        localName == nsGkAtoms::code ||
  1.1669 +        localName == nsGkAtoms::noscript ||
  1.1670 +        localName == nsGkAtoms::style) {
  1.1671 +      continue;
  1.1672 +    }
  1.1673 +
  1.1674 +    // An element is a translation node if it contains
  1.1675 +    // at least one text node that has meaningful data
  1.1676 +    // for translation
  1.1677 +    for (nsIContent* child = content->GetFirstChild();
  1.1678 +         child;
  1.1679 +         child = child->GetNextSibling()) {
  1.1680 +
  1.1681 +      if (child->HasTextForTranslation()) {
  1.1682 +        translationNodesHash.PutEntry(content);
  1.1683 +
  1.1684 +        bool isBlockFrame = false;
  1.1685 +        nsIFrame* frame = content->GetPrimaryFrame();
  1.1686 +        if (frame) {
  1.1687 +          isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame);
  1.1688 +        }
  1.1689 +
  1.1690 +        bool isTranslationRoot = isBlockFrame;
  1.1691 +        if (!isBlockFrame) {
  1.1692 +          // If an element is not a block element, it still
  1.1693 +          // can be considered a translation root if the parent
  1.1694 +          // of this element didn't make into the list of nodes
  1.1695 +          // to be translated.
  1.1696 +          bool parentInList = false;
  1.1697 +          nsIContent* parent = content->GetParent();
  1.1698 +          if (parent) {
  1.1699 +            parentInList = translationNodesHash.Contains(parent);
  1.1700 +          }
  1.1701 +          isTranslationRoot = !parentInList;
  1.1702 +        }
  1.1703 +
  1.1704 +        list->AppendElement(content->AsDOMNode(), isTranslationRoot);
  1.1705 +        --limit;
  1.1706 +        break;
  1.1707 +      }
  1.1708 +    }
  1.1709 +  }
  1.1710 +
  1.1711 +  *aRetVal = list.forget().take();
  1.1712 +  return NS_OK;
  1.1713 +}
  1.1714 +
  1.1715 +static TemporaryRef<DataSourceSurface>
  1.1716 +CanvasToDataSourceSurface(nsIDOMHTMLCanvasElement* aCanvas)
  1.1717 +{
  1.1718 +  nsCOMPtr<nsINode> node = do_QueryInterface(aCanvas);
  1.1719 +  if (!node) {
  1.1720 +    return nullptr;
  1.1721 +  }
  1.1722 +
  1.1723 +  NS_ABORT_IF_FALSE(node->IsElement(),
  1.1724 +                    "An nsINode that implements nsIDOMHTMLCanvasElement should "
  1.1725 +                    "be an element.");
  1.1726 +  nsLayoutUtils::SurfaceFromElementResult result =
  1.1727 +    nsLayoutUtils::SurfaceFromElement(node->AsElement());
  1.1728 +  return result.mSourceSurface->GetDataSurface();
  1.1729 +}
  1.1730 +
  1.1731 +NS_IMETHODIMP
  1.1732 +nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
  1.1733 +                                  nsIDOMHTMLCanvasElement *aCanvas2,
  1.1734 +                                  uint32_t* aMaxDifference,
  1.1735 +                                  uint32_t* retVal)
  1.1736 +{
  1.1737 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1738 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1739 +  }
  1.1740 +
  1.1741 +  if (aCanvas1 == nullptr ||
  1.1742 +      aCanvas2 == nullptr ||
  1.1743 +      retVal == nullptr)
  1.1744 +    return NS_ERROR_FAILURE;
  1.1745 +
  1.1746 +  RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(aCanvas1);
  1.1747 +  RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(aCanvas2);
  1.1748 +
  1.1749 +  if (img1 == nullptr || img2 == nullptr ||
  1.1750 +      img1->GetSize() != img2->GetSize() ||
  1.1751 +      img1->Stride() != img2->Stride())
  1.1752 +    return NS_ERROR_FAILURE;
  1.1753 +
  1.1754 +  int v;
  1.1755 +  IntSize size = img1->GetSize();
  1.1756 +  uint32_t stride = img1->Stride();
  1.1757 +
  1.1758 +  // we can optimize for the common all-pass case
  1.1759 +  if (stride == (uint32_t) size.width * 4) {
  1.1760 +    v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4);
  1.1761 +    if (v == 0) {
  1.1762 +      if (aMaxDifference)
  1.1763 +        *aMaxDifference = 0;
  1.1764 +      *retVal = 0;
  1.1765 +      return NS_OK;
  1.1766 +    }
  1.1767 +  }
  1.1768 +
  1.1769 +  uint32_t dc = 0;
  1.1770 +  uint32_t different = 0;
  1.1771 +
  1.1772 +  for (int j = 0; j < size.height; j++) {
  1.1773 +    unsigned char *p1 = img1->GetData() + j*stride;
  1.1774 +    unsigned char *p2 = img2->GetData() + j*stride;
  1.1775 +    v = memcmp(p1, p2, stride);
  1.1776 +
  1.1777 +    if (v) {
  1.1778 +      for (int i = 0; i < size.width; i++) {
  1.1779 +        if (*(uint32_t*) p1 != *(uint32_t*) p2) {
  1.1780 +
  1.1781 +          different++;
  1.1782 +
  1.1783 +          dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc);
  1.1784 +          dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc);
  1.1785 +          dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc);
  1.1786 +          dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc);
  1.1787 +        }
  1.1788 +
  1.1789 +        p1 += 4;
  1.1790 +        p2 += 4;
  1.1791 +      }
  1.1792 +    }
  1.1793 +  }
  1.1794 +
  1.1795 +  if (aMaxDifference)
  1.1796 +    *aMaxDifference = dc;
  1.1797 +
  1.1798 +  *retVal = different;
  1.1799 +  return NS_OK;
  1.1800 +}
  1.1801 +
  1.1802 +NS_IMETHODIMP
  1.1803 +nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
  1.1804 +{
  1.1805 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1806 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1807 +  }
  1.1808 +
  1.1809 +  NS_ENSURE_ARG_POINTER(aResult);
  1.1810 +  *aResult = false;
  1.1811 +  nsPresContext* presContext = GetPresContext();
  1.1812 +  if (!presContext)
  1.1813 +    return NS_OK;
  1.1814 +  *aResult = presContext->IsDOMPaintEventPending();
  1.1815 +  return NS_OK;
  1.1816 +}
  1.1817 +
  1.1818 +NS_IMETHODIMP
  1.1819 +nsDOMWindowUtils::ClearMozAfterPaintEvents()
  1.1820 +{
  1.1821 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1822 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1823 +  }
  1.1824 +
  1.1825 +  nsPresContext* presContext = GetPresContext();
  1.1826 +  if (!presContext)
  1.1827 +    return NS_OK;
  1.1828 +  presContext->ClearMozAfterPaintEvents();
  1.1829 +  return NS_OK;
  1.1830 +}
  1.1831 +
  1.1832 +NS_IMETHODIMP
  1.1833 +nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable)
  1.1834 +{
  1.1835 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1836 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1837 +  }
  1.1838 +
  1.1839 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.1840 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.1841 +  nsIDocShell *docShell = window->GetDocShell();
  1.1842 +  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
  1.1843 +  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  1.1844 +  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  1.1845 +  presShell->DisableNonTestMouseEvents(aDisable);
  1.1846 +  return NS_OK;
  1.1847 +}
  1.1848 +
  1.1849 +NS_IMETHODIMP
  1.1850 +nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
  1.1851 +{
  1.1852 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1853 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1854 +  }
  1.1855 +
  1.1856 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.1857 +  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  1.1858 +
  1.1859 +  if (aSuppress) {
  1.1860 +    doc->SuppressEventHandling(nsIDocument::eEvents);
  1.1861 +  } else {
  1.1862 +    doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true);
  1.1863 +  }
  1.1864 +
  1.1865 +  return NS_OK;
  1.1866 +}
  1.1867 +
  1.1868 +static nsresult
  1.1869 +getScrollXYAppUnits(nsWeakPtr aWindow, bool aFlushLayout, nsPoint& aScrollPos) {
  1.1870 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1871 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1872 +  }
  1.1873 +
  1.1874 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(aWindow);
  1.1875 +  nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr;
  1.1876 +  NS_ENSURE_STATE(doc);
  1.1877 +
  1.1878 +  if (aFlushLayout) {
  1.1879 +    doc->FlushPendingNotifications(Flush_Layout);
  1.1880 +  }
  1.1881 +
  1.1882 +  nsIPresShell *presShell = doc->GetShell();
  1.1883 +  if (presShell) {
  1.1884 +    nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
  1.1885 +    if (sf) {
  1.1886 +      aScrollPos = sf->GetScrollPosition();
  1.1887 +    }
  1.1888 +  }
  1.1889 +  return NS_OK;
  1.1890 +}
  1.1891 +
  1.1892 +NS_IMETHODIMP
  1.1893 +nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
  1.1894 +{
  1.1895 +  nsPoint scrollPos(0,0);
  1.1896 +  nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
  1.1897 +  NS_ENSURE_SUCCESS(rv, rv);
  1.1898 +  *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
  1.1899 +  *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
  1.1900 +
  1.1901 +  return NS_OK;
  1.1902 +}
  1.1903 +
  1.1904 +NS_IMETHODIMP
  1.1905 +nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY)
  1.1906 +{
  1.1907 +  nsPoint scrollPos(0,0);
  1.1908 +  nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
  1.1909 +  NS_ENSURE_SUCCESS(rv, rv);
  1.1910 +  *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x);
  1.1911 +  *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y);
  1.1912 +
  1.1913 +  return NS_OK;
  1.1914 +}
  1.1915 +
  1.1916 +NS_IMETHODIMP
  1.1917 +nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
  1.1918 +                                                      int32_t* aHeight)
  1.1919 +{
  1.1920 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1921 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1922 +  }
  1.1923 +
  1.1924 +  *aWidth = 0;
  1.1925 +  *aHeight = 0;
  1.1926 +
  1.1927 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.1928 +  NS_ENSURE_STATE(doc);
  1.1929 +
  1.1930 +  if (aFlushLayout) {
  1.1931 +    doc->FlushPendingNotifications(Flush_Layout);
  1.1932 +  }
  1.1933 +
  1.1934 +  nsIPresShell* presShell = doc->GetShell();
  1.1935 +  NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
  1.1936 +
  1.1937 +  nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
  1.1938 +  NS_ENSURE_TRUE(scrollFrame, NS_OK);
  1.1939 +
  1.1940 +  nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
  1.1941 +  *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
  1.1942 +  *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
  1.1943 +
  1.1944 +  return NS_OK;
  1.1945 +}
  1.1946 +
  1.1947 +NS_IMETHODIMP
  1.1948 +nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement,
  1.1949 +                                           nsIDOMClientRect** aResult)
  1.1950 +{
  1.1951 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1952 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1953 +  }
  1.1954 +
  1.1955 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.1956 +  NS_ENSURE_STATE(window);
  1.1957 +
  1.1958 +  nsresult rv;
  1.1959 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  1.1960 +  NS_ENSURE_SUCCESS(rv, rv);
  1.1961 +
  1.1962 +  nsRefPtr<DOMRect> rect = new DOMRect(window);
  1.1963 +  nsIFrame* frame = content->GetPrimaryFrame();
  1.1964 +
  1.1965 +  if (frame) {
  1.1966 +    nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
  1.1967 +               nsLayoutUtils::GetContainingBlockForClientRect(frame),
  1.1968 +               nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
  1.1969 +    rect->SetLayoutRect(r);
  1.1970 +  }
  1.1971 +
  1.1972 +  rect.forget(aResult);
  1.1973 +  return NS_OK;
  1.1974 +}
  1.1975 +
  1.1976 +NS_IMETHODIMP
  1.1977 +nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
  1.1978 +{
  1.1979 +  if (!nsContentUtils::IsCallerChrome()) {
  1.1980 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.1981 +  }
  1.1982 +
  1.1983 +  nsIDocument* doc = GetDocument();
  1.1984 +  NS_ENSURE_STATE(doc);
  1.1985 +
  1.1986 +  nsRect bounds(0, 0, 0, 0);
  1.1987 +  nsIPresShell* presShell = doc->GetShell();
  1.1988 +  if (presShell) {
  1.1989 +    nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
  1.1990 +    if (sf) {
  1.1991 +      bounds = sf->GetScrollRange();
  1.1992 +      bounds.width += sf->GetScrollPortRect().width;
  1.1993 +      bounds.height += sf->GetScrollPortRect().height;
  1.1994 +    } else if (presShell->GetRootFrame()) {
  1.1995 +      bounds = presShell->GetRootFrame()->GetRect();
  1.1996 +    }
  1.1997 +  }
  1.1998 +
  1.1999 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2000 +  nsRefPtr<DOMRect> rect = new DOMRect(window);
  1.2001 +  rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x),
  1.2002 +                nsPresContext::AppUnitsToFloatCSSPixels(bounds.y),
  1.2003 +                nsPresContext::AppUnitsToFloatCSSPixels(bounds.width),
  1.2004 +                nsPresContext::AppUnitsToFloatCSSPixels(bounds.height));
  1.2005 +  rect.forget(aResult);
  1.2006 +  return NS_OK;
  1.2007 +}
  1.2008 +
  1.2009 +NS_IMETHODIMP
  1.2010 +nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
  1.2011 +{
  1.2012 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2013 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2014 +  }
  1.2015 +
  1.2016 +  NS_ENSURE_ARG_POINTER(aState);
  1.2017 +
  1.2018 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2019 +  if (!widget)
  1.2020 +    return NS_ERROR_FAILURE;
  1.2021 +
  1.2022 +  // Open state should not be available when IME is not enabled.
  1.2023 +  InputContext context = widget->GetInputContext();
  1.2024 +  if (context.mIMEState.mEnabled != IMEState::ENABLED) {
  1.2025 +    return NS_ERROR_NOT_AVAILABLE;
  1.2026 +  }
  1.2027 +
  1.2028 +  if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
  1.2029 +    return NS_ERROR_NOT_IMPLEMENTED;
  1.2030 +  }
  1.2031 +  *aState = (context.mIMEState.mOpen == IMEState::OPEN);
  1.2032 +  return NS_OK;
  1.2033 +}
  1.2034 +
  1.2035 +NS_IMETHODIMP
  1.2036 +nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
  1.2037 +{
  1.2038 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2039 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2040 +  }
  1.2041 +
  1.2042 +  NS_ENSURE_ARG_POINTER(aState);
  1.2043 +
  1.2044 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2045 +  if (!widget)
  1.2046 +    return NS_ERROR_FAILURE;
  1.2047 +
  1.2048 +  InputContext context = widget->GetInputContext();
  1.2049 +  *aState = static_cast<uint32_t>(context.mIMEState.mEnabled);
  1.2050 +  return NS_OK;
  1.2051 +}
  1.2052 +
  1.2053 +NS_IMETHODIMP
  1.2054 +nsDOMWindowUtils::GetFocusedInputType(char** aType)
  1.2055 +{
  1.2056 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2057 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2058 +  }
  1.2059 +
  1.2060 +  NS_ENSURE_ARG_POINTER(aType);
  1.2061 +
  1.2062 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2063 +  if (!widget) {
  1.2064 +    return NS_ERROR_FAILURE;
  1.2065 +  }
  1.2066 +
  1.2067 +  InputContext context = widget->GetInputContext();
  1.2068 +  *aType = ToNewCString(context.mHTMLInputType);
  1.2069 +  return NS_OK;
  1.2070 +}
  1.2071 +
  1.2072 +NS_IMETHODIMP
  1.2073 +nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
  1.2074 +                                        nsIDOMElement** aResult)
  1.2075 +{
  1.2076 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2077 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2078 +  }
  1.2079 +
  1.2080 +  nsRefPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aID);
  1.2081 +  return content ? CallQueryInterface(content, aResult) : NS_OK;
  1.2082 +}
  1.2083 +
  1.2084 +NS_IMETHODIMP
  1.2085 +nsDOMWindowUtils::GetViewId(nsIDOMElement* aElement, nsViewID* aResult)
  1.2086 +{
  1.2087 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
  1.2088 +  if (content && nsLayoutUtils::FindIDFor(content, aResult)) {
  1.2089 +    return NS_OK;
  1.2090 +  }
  1.2091 +  return NS_ERROR_NOT_AVAILABLE;
  1.2092 +}
  1.2093 +
  1.2094 +NS_IMETHODIMP
  1.2095 +nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
  1.2096 +{
  1.2097 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2098 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.2099 +  return window->GetDevicePixelRatio(aScreenPixels);
  1.2100 +}
  1.2101 +
  1.2102 +NS_IMETHODIMP
  1.2103 +nsDOMWindowUtils::GetFullZoom(float* aFullZoom)
  1.2104 +{
  1.2105 +  *aFullZoom = 1.0f;
  1.2106 +
  1.2107 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2108 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2109 +  }
  1.2110 +
  1.2111 +  nsPresContext* presContext = GetPresContext();
  1.2112 +  if (!presContext) {
  1.2113 +    return NS_OK;
  1.2114 +  }
  1.2115 +
  1.2116 +  *aFullZoom = presContext->DeviceContext()->GetPixelScale();
  1.2117 +
  1.2118 +  return NS_OK;
  1.2119 +}
  1.2120 + 
  1.2121 +NS_IMETHODIMP
  1.2122 +nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
  1.2123 +                                               nsIDOMEvent* aEvent,
  1.2124 +                                               bool aTrusted,
  1.2125 +                                               bool* aRetVal)
  1.2126 +{
  1.2127 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2128 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2129 +  }
  1.2130 +
  1.2131 +  NS_ENSURE_STATE(aEvent);
  1.2132 +  aEvent->SetTrusted(aTrusted);
  1.2133 +  WidgetEvent* internalEvent = aEvent->GetInternalNSEvent();
  1.2134 +  NS_ENSURE_STATE(internalEvent);
  1.2135 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
  1.2136 +  NS_ENSURE_STATE(content);
  1.2137 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2138 +  if (content->OwnerDoc()->GetWindow() != window) {
  1.2139 +    return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
  1.2140 +  }
  1.2141 +  nsCOMPtr<nsIDocument> targetDoc = content->GetCurrentDoc();
  1.2142 +  NS_ENSURE_STATE(targetDoc);
  1.2143 +  nsRefPtr<nsIPresShell> targetShell = targetDoc->GetShell();
  1.2144 +  NS_ENSURE_STATE(targetShell);
  1.2145 +
  1.2146 +  targetDoc->FlushPendingNotifications(Flush_Layout);
  1.2147 +
  1.2148 +  nsEventStatus status = nsEventStatus_eIgnore;
  1.2149 +  targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status);
  1.2150 +  *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
  1.2151 +  return NS_OK;
  1.2152 +}
  1.2153 +
  1.2154 +static void
  1.2155 +InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr)
  1.2156 +{
  1.2157 +  if (aPt) {
  1.2158 +    aEvent.refPoint = *aPt;
  1.2159 +  }
  1.2160 +  aEvent.time = PR_IntervalNow();
  1.2161 +}
  1.2162 +
  1.2163 +NS_IMETHODIMP
  1.2164 +nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType,
  1.2165 +                                       const nsAString& aData,
  1.2166 +                                       const nsAString& aLocale)
  1.2167 +{
  1.2168 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2169 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2170 +  }
  1.2171 +
  1.2172 +  // get the widget to send the event to
  1.2173 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2174 +  if (!widget) {
  1.2175 +    return NS_ERROR_FAILURE;
  1.2176 +  }
  1.2177 +
  1.2178 +  uint32_t msg;
  1.2179 +  if (aType.EqualsLiteral("compositionstart")) {
  1.2180 +    msg = NS_COMPOSITION_START;
  1.2181 +  } else if (aType.EqualsLiteral("compositionend")) {
  1.2182 +    msg = NS_COMPOSITION_END;
  1.2183 +  } else if (aType.EqualsLiteral("compositionupdate")) {
  1.2184 +    msg = NS_COMPOSITION_UPDATE;
  1.2185 +  } else {
  1.2186 +    return NS_ERROR_FAILURE;
  1.2187 +  }
  1.2188 +
  1.2189 +  WidgetCompositionEvent compositionEvent(true, msg, widget);
  1.2190 +  InitEvent(compositionEvent);
  1.2191 +  if (msg != NS_COMPOSITION_START) {
  1.2192 +    compositionEvent.data = aData;
  1.2193 +  }
  1.2194 +
  1.2195 +  compositionEvent.mFlags.mIsSynthesizedForTests = true;
  1.2196 +
  1.2197 +  nsEventStatus status;
  1.2198 +  nsresult rv = widget->DispatchEvent(&compositionEvent, status);
  1.2199 +  NS_ENSURE_SUCCESS(rv, rv);
  1.2200 +
  1.2201 +  return NS_OK;
  1.2202 +}
  1.2203 +
  1.2204 +NS_IMETHODIMP
  1.2205 +nsDOMWindowUtils::CreateCompositionStringSynthesizer(
  1.2206 +                    nsICompositionStringSynthesizer** aResult)
  1.2207 +{
  1.2208 +  NS_ENSURE_ARG_POINTER(aResult);
  1.2209 +  *aResult = nullptr;
  1.2210 +
  1.2211 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2212 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2213 +  }
  1.2214 +
  1.2215 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2216 +  NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
  1.2217 +
  1.2218 +  NS_ADDREF(*aResult = new CompositionStringSynthesizer(window));
  1.2219 +  return NS_OK;
  1.2220 +}
  1.2221 +
  1.2222 +NS_IMETHODIMP
  1.2223 +nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
  1.2224 +                                        uint32_t aOffset, uint32_t aLength,
  1.2225 +                                        int32_t aX, int32_t aY,
  1.2226 +                                        uint32_t aAdditionalFlags,
  1.2227 +                                        nsIQueryContentEventResult **aResult)
  1.2228 +{
  1.2229 +  *aResult = nullptr;
  1.2230 +
  1.2231 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2232 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2233 +  }
  1.2234 +
  1.2235 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2236 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.2237 +
  1.2238 +  nsIDocShell *docShell = window->GetDocShell();
  1.2239 +  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
  1.2240 +
  1.2241 +  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  1.2242 +  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  1.2243 +
  1.2244 +  nsPresContext* presContext = presShell->GetPresContext();
  1.2245 +  NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
  1.2246 +
  1.2247 +  // get the widget to send the event to
  1.2248 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2249 +  if (!widget) {
  1.2250 +    return NS_ERROR_FAILURE;
  1.2251 +  }
  1.2252 +
  1.2253 +  if (aType != NS_QUERY_SELECTED_TEXT &&
  1.2254 +      aType != NS_QUERY_TEXT_CONTENT &&
  1.2255 +      aType != NS_QUERY_CARET_RECT &&
  1.2256 +      aType != NS_QUERY_TEXT_RECT &&
  1.2257 +      aType != NS_QUERY_EDITOR_RECT &&
  1.2258 +      aType != NS_QUERY_CHARACTER_AT_POINT) {
  1.2259 +    return NS_ERROR_INVALID_ARG;
  1.2260 +  }
  1.2261 +
  1.2262 +  nsCOMPtr<nsIWidget> targetWidget = widget;
  1.2263 +  LayoutDeviceIntPoint pt(aX, aY);
  1.2264 +
  1.2265 +  bool useNativeLineBreak =
  1.2266 +    !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
  1.2267 +
  1.2268 +  if (aType == QUERY_CHARACTER_AT_POINT) {
  1.2269 +    // Looking for the widget at the point.
  1.2270 +    WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
  1.2271 +    dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
  1.2272 +    InitEvent(dummyEvent, &pt);
  1.2273 +    nsIFrame* popupFrame =
  1.2274 +      nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
  1.2275 +
  1.2276 +    nsIntRect widgetBounds;
  1.2277 +    nsresult rv = widget->GetClientBounds(widgetBounds);
  1.2278 +    NS_ENSURE_SUCCESS(rv, rv);
  1.2279 +    widgetBounds.MoveTo(0, 0);
  1.2280 +
  1.2281 +    // There is no popup frame at the point and the point isn't in our widget,
  1.2282 +    // we cannot process this request.
  1.2283 +    NS_ENSURE_TRUE(popupFrame ||
  1.2284 +                   widgetBounds.Contains(LayoutDeviceIntPoint::ToUntyped(pt)),
  1.2285 +                   NS_ERROR_FAILURE);
  1.2286 +
  1.2287 +    // Fire the event on the widget at the point
  1.2288 +    if (popupFrame) {
  1.2289 +      targetWidget = popupFrame->GetNearestWidget();
  1.2290 +    }
  1.2291 +  }
  1.2292 +
  1.2293 +  pt += LayoutDeviceIntPoint::FromUntyped(
  1.2294 +    widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset());
  1.2295 +
  1.2296 +  WidgetQueryContentEvent queryEvent(true, aType, targetWidget);
  1.2297 +  InitEvent(queryEvent, &pt);
  1.2298 +
  1.2299 +  switch (aType) {
  1.2300 +    case NS_QUERY_TEXT_CONTENT:
  1.2301 +      queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
  1.2302 +      break;
  1.2303 +    case NS_QUERY_CARET_RECT:
  1.2304 +      queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
  1.2305 +      break;
  1.2306 +    case NS_QUERY_TEXT_RECT:
  1.2307 +      queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak);
  1.2308 +      break;
  1.2309 +    default:
  1.2310 +      queryEvent.mUseNativeLineBreak = useNativeLineBreak;
  1.2311 +      break;
  1.2312 +  }
  1.2313 +
  1.2314 +  nsEventStatus status;
  1.2315 +  nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
  1.2316 +  NS_ENSURE_SUCCESS(rv, rv);
  1.2317 +
  1.2318 +  nsQueryContentEventResult* result = new nsQueryContentEventResult();
  1.2319 +  NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
  1.2320 +  result->SetEventResult(widget, queryEvent);
  1.2321 +  NS_ADDREF(*aResult = result);
  1.2322 +  return NS_OK;
  1.2323 +}
  1.2324 +
  1.2325 +NS_IMETHODIMP
  1.2326 +nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
  1.2327 +                                        uint32_t aLength,
  1.2328 +                                        uint32_t aAdditionalFlags,
  1.2329 +                                        bool *aResult)
  1.2330 +{
  1.2331 +  *aResult = false;
  1.2332 +
  1.2333 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2334 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2335 +  }
  1.2336 +
  1.2337 +  // get the widget to send the event to
  1.2338 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2339 +  if (!widget) {
  1.2340 +    return NS_ERROR_FAILURE;
  1.2341 +  }
  1.2342 +
  1.2343 +  WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
  1.2344 +  InitEvent(selectionEvent);
  1.2345 +
  1.2346 +  selectionEvent.mOffset = aOffset;
  1.2347 +  selectionEvent.mLength = aLength;
  1.2348 +  selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
  1.2349 +  selectionEvent.mUseNativeLineBreak =
  1.2350 +    !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
  1.2351 +
  1.2352 +  nsEventStatus status;
  1.2353 +  nsresult rv = widget->DispatchEvent(&selectionEvent, status);
  1.2354 +  NS_ENSURE_SUCCESS(rv, rv);
  1.2355 +
  1.2356 +  *aResult = selectionEvent.mSucceeded;
  1.2357 +  return NS_OK;
  1.2358 +}
  1.2359 +
  1.2360 +NS_IMETHODIMP
  1.2361 +nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
  1.2362 +                                          nsITransferable * aTransferable)
  1.2363 +{
  1.2364 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2365 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2366 +  }
  1.2367 +
  1.2368 +  // get the widget to send the event to
  1.2369 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2370 +  if (!widget)
  1.2371 +    return NS_ERROR_FAILURE;
  1.2372 +
  1.2373 +  int32_t msg;
  1.2374 +  if (aType.EqualsLiteral("cut"))
  1.2375 +    msg = NS_CONTENT_COMMAND_CUT;
  1.2376 +  else if (aType.EqualsLiteral("copy"))
  1.2377 +    msg = NS_CONTENT_COMMAND_COPY;
  1.2378 +  else if (aType.EqualsLiteral("paste"))
  1.2379 +    msg = NS_CONTENT_COMMAND_PASTE;
  1.2380 +  else if (aType.EqualsLiteral("delete"))
  1.2381 +    msg = NS_CONTENT_COMMAND_DELETE;
  1.2382 +  else if (aType.EqualsLiteral("undo"))
  1.2383 +    msg = NS_CONTENT_COMMAND_UNDO;
  1.2384 +  else if (aType.EqualsLiteral("redo"))
  1.2385 +    msg = NS_CONTENT_COMMAND_REDO;
  1.2386 +  else if (aType.EqualsLiteral("pasteTransferable"))
  1.2387 +    msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
  1.2388 +  else
  1.2389 +    return NS_ERROR_FAILURE;
  1.2390 +
  1.2391 +  WidgetContentCommandEvent event(true, msg, widget);
  1.2392 +  if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
  1.2393 +    event.mTransferable = aTransferable;
  1.2394 +  }
  1.2395 +
  1.2396 +  nsEventStatus status;
  1.2397 +  return widget->DispatchEvent(&event, status);
  1.2398 +}
  1.2399 +
  1.2400 +NS_IMETHODIMP
  1.2401 +nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
  1.2402 +                               char** aName)
  1.2403 +{
  1.2404 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2405 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2406 +  }
  1.2407 +
  1.2408 +  // Our argument must be a non-null object.
  1.2409 +  if (JSVAL_IS_PRIMITIVE(aObject)) {
  1.2410 +    return NS_ERROR_XPC_BAD_CONVERT_JS;
  1.2411 +  }
  1.2412 +
  1.2413 +  *aName = NS_strdup(JS_GetClass(JSVAL_TO_OBJECT(aObject))->name);
  1.2414 +  NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
  1.2415 +  return NS_OK;
  1.2416 +}
  1.2417 +
  1.2418 +NS_IMETHODIMP
  1.2419 +nsDOMWindowUtils::GetVisitedDependentComputedStyle(
  1.2420 +                    nsIDOMElement *aElement, const nsAString& aPseudoElement,
  1.2421 +                    const nsAString& aPropertyName, nsAString& aResult)
  1.2422 +{
  1.2423 +  aResult.Truncate();
  1.2424 +
  1.2425 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2426 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2427 +  }
  1.2428 +
  1.2429 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2430 +  NS_ENSURE_STATE(window);
  1.2431 +
  1.2432 +  nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
  1.2433 +  nsresult rv =
  1.2434 +    window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
  1.2435 +  NS_ENSURE_SUCCESS(rv, rv);
  1.2436 +
  1.2437 +  static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
  1.2438 +  rv = decl->GetPropertyValue(aPropertyName, aResult);
  1.2439 +  static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
  1.2440 +
  1.2441 +  return rv;
  1.2442 +}
  1.2443 +
  1.2444 +NS_IMETHODIMP
  1.2445 +nsDOMWindowUtils::EnterModalState()
  1.2446 +{
  1.2447 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2448 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2449 +  }
  1.2450 +
  1.2451 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2452 +  NS_ENSURE_STATE(window);
  1.2453 +
  1.2454 +  window->EnterModalState();
  1.2455 +  return NS_OK;
  1.2456 +}
  1.2457 +
  1.2458 +NS_IMETHODIMP
  1.2459 +nsDOMWindowUtils::LeaveModalState()
  1.2460 +{
  1.2461 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2462 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2463 +  }
  1.2464 +
  1.2465 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2466 +  NS_ENSURE_STATE(window);
  1.2467 +
  1.2468 +  window->LeaveModalState();
  1.2469 +  return NS_OK;
  1.2470 +}
  1.2471 +
  1.2472 +NS_IMETHODIMP
  1.2473 +nsDOMWindowUtils::IsInModalState(bool *retval)
  1.2474 +{
  1.2475 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2476 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2477 +  }
  1.2478 +
  1.2479 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2480 +  NS_ENSURE_STATE(window);
  1.2481 +
  1.2482 +  *retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
  1.2483 +  return NS_OK;
  1.2484 +}
  1.2485 +
  1.2486 +NS_IMETHODIMP
  1.2487 +nsDOMWindowUtils::GetParent(JS::Handle<JS::Value> aObject,
  1.2488 +                            JSContext* aCx,
  1.2489 +                            JS::MutableHandle<JS::Value> aParent)
  1.2490 +{
  1.2491 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2492 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2493 +  }
  1.2494 +
  1.2495 +  // First argument must be an object.
  1.2496 +  if (aObject.isPrimitive()) {
  1.2497 +    return NS_ERROR_XPC_BAD_CONVERT_JS;
  1.2498 +  }
  1.2499 +
  1.2500 +  JS::Rooted<JSObject*> parent(aCx, JS_GetParent(&aObject.toObject()));
  1.2501 +
  1.2502 +  // Outerize if necessary.
  1.2503 +  if (parent) {
  1.2504 +    if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
  1.2505 +      parent = outerize(aCx, parent);
  1.2506 +    }
  1.2507 +  }
  1.2508 +
  1.2509 +  aParent.setObject(*parent);
  1.2510 +  return NS_OK;
  1.2511 +}
  1.2512 +
  1.2513 +NS_IMETHODIMP
  1.2514 +nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
  1.2515 +{
  1.2516 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2517 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2518 +  }
  1.2519 +
  1.2520 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2521 +  NS_ENSURE_STATE(window);
  1.2522 +
  1.2523 +  NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
  1.2524 +  *aWindowID = window->WindowID();
  1.2525 +  return NS_OK;
  1.2526 +}
  1.2527 +
  1.2528 +NS_IMETHODIMP
  1.2529 +nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID)
  1.2530 +{
  1.2531 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2532 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2533 +  }
  1.2534 +
  1.2535 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2536 +  NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
  1.2537 +
  1.2538 +  NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
  1.2539 +  nsGlobalWindow* inner =
  1.2540 +    static_cast<nsGlobalWindow*>(window.get())->GetCurrentInnerWindowInternal();
  1.2541 +  if (!inner) {
  1.2542 +    return NS_ERROR_NOT_AVAILABLE;
  1.2543 +  }
  1.2544 +  *aWindowID = inner->WindowID();
  1.2545 +  return NS_OK;
  1.2546 +}
  1.2547 +
  1.2548 +NS_IMETHODIMP
  1.2549 +nsDOMWindowUtils::SuspendTimeouts()
  1.2550 +{
  1.2551 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2552 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2553 +  }
  1.2554 +
  1.2555 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2556 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.2557 +
  1.2558 +  window->SuspendTimeouts();
  1.2559 +
  1.2560 +  return NS_OK;
  1.2561 +}
  1.2562 +
  1.2563 +NS_IMETHODIMP
  1.2564 +nsDOMWindowUtils::ResumeTimeouts()
  1.2565 +{
  1.2566 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2567 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2568 +  }
  1.2569 +
  1.2570 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2571 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.2572 +
  1.2573 +  window->ResumeTimeouts();
  1.2574 +
  1.2575 +  return NS_OK;
  1.2576 +}
  1.2577 +
  1.2578 +NS_IMETHODIMP
  1.2579 +nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
  1.2580 +{
  1.2581 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2582 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2583 +  }
  1.2584 +
  1.2585 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2586 +  if (!widget)
  1.2587 +    return NS_ERROR_FAILURE;
  1.2588 +
  1.2589 +  LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT);
  1.2590 +  if (!mgr)
  1.2591 +    return NS_ERROR_FAILURE;
  1.2592 +
  1.2593 +  mgr->GetBackendName(aType);
  1.2594 +
  1.2595 +  return NS_OK;
  1.2596 +}
  1.2597 +
  1.2598 +NS_IMETHODIMP
  1.2599 +nsDOMWindowUtils::GetLayerManagerRemote(bool* retval)
  1.2600 +{
  1.2601 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2602 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2603 +  }
  1.2604 +
  1.2605 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2606 +  if (!widget)
  1.2607 +    return NS_ERROR_FAILURE;
  1.2608 +
  1.2609 +  LayerManager *mgr = widget->GetLayerManager();
  1.2610 +  if (!mgr)
  1.2611 +    return NS_ERROR_FAILURE;
  1.2612 +
  1.2613 +  *retval = !!mgr->AsShadowForwarder();
  1.2614 +  return NS_OK;
  1.2615 +}
  1.2616 +
  1.2617 +NS_IMETHODIMP
  1.2618 +nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
  1.2619 +{
  1.2620 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2621 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2622 +  }
  1.2623 +
  1.2624 +  NS_ENSURE_ARG_POINTER(startIndex);
  1.2625 +
  1.2626 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2627 +  if (!widget)
  1.2628 +    return NS_ERROR_FAILURE;
  1.2629 +
  1.2630 +  LayerManager *mgr = widget->GetLayerManager();
  1.2631 +  if (!mgr)
  1.2632 +    return NS_ERROR_FAILURE;
  1.2633 +
  1.2634 +  const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
  1.2635 +  const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
  1.2636 +  uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
  1.2637 +  bufferSize = std::min(bufferSize, kRecordingMaxSize);
  1.2638 +  bufferSize = std::max(bufferSize, kRecordingMinSize);
  1.2639 +  *startIndex = mgr->StartFrameTimeRecording(bufferSize);
  1.2640 +
  1.2641 +  return NS_OK;
  1.2642 +}
  1.2643 +
  1.2644 +NS_IMETHODIMP
  1.2645 +nsDOMWindowUtils::StopFrameTimeRecording(uint32_t   startIndex,
  1.2646 +                                         uint32_t  *frameCount,
  1.2647 +                                         float    **frameIntervals)
  1.2648 +{
  1.2649 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2650 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2651 +  }
  1.2652 +
  1.2653 +  NS_ENSURE_ARG_POINTER(frameCount);
  1.2654 +  NS_ENSURE_ARG_POINTER(frameIntervals);
  1.2655 +
  1.2656 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2657 +  if (!widget)
  1.2658 +    return NS_ERROR_FAILURE;
  1.2659 +
  1.2660 +  LayerManager *mgr = widget->GetLayerManager();
  1.2661 +  if (!mgr)
  1.2662 +    return NS_ERROR_FAILURE;
  1.2663 +
  1.2664 +  nsTArray<float> tmpFrameIntervals;
  1.2665 +  mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
  1.2666 +  *frameCount = tmpFrameIntervals.Length();
  1.2667 +
  1.2668 +  *frameIntervals = (float*)nsMemory::Alloc(*frameCount * sizeof(float));
  1.2669 +
  1.2670 +  /* copy over the frame intervals and paint times into the arrays we just allocated */
  1.2671 +  for (uint32_t i = 0; i < *frameCount; i++) {
  1.2672 +    (*frameIntervals)[i] = tmpFrameIntervals[i];
  1.2673 +  }
  1.2674 +
  1.2675 +  return NS_OK;
  1.2676 +}
  1.2677 +
  1.2678 +NS_IMETHODIMP
  1.2679 +nsDOMWindowUtils::BeginTabSwitch()
  1.2680 +{
  1.2681 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2682 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2683 +  }
  1.2684 +
  1.2685 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2686 +  if (!widget)
  1.2687 +    return NS_ERROR_FAILURE;
  1.2688 +
  1.2689 +  LayerManager *mgr = widget->GetLayerManager();
  1.2690 +  if (!mgr)
  1.2691 +    return NS_ERROR_FAILURE;
  1.2692 +
  1.2693 +  mgr->BeginTabSwitch();
  1.2694 +
  1.2695 +  return NS_OK;
  1.2696 +}
  1.2697 +
  1.2698 +static bool
  1.2699 +ComputeAnimationValue(nsCSSProperty aProperty,
  1.2700 +                      Element* aElement,
  1.2701 +                      const nsAString& aInput,
  1.2702 +                      nsStyleAnimation::Value& aOutput)
  1.2703 +{
  1.2704 +
  1.2705 +  if (!nsStyleAnimation::ComputeValue(aProperty, aElement, aInput,
  1.2706 +                                      false, aOutput)) {
  1.2707 +    return false;
  1.2708 +  }
  1.2709 +
  1.2710 +  // This matches TransExtractComputedValue in nsTransitionManager.cpp.
  1.2711 +  if (aProperty == eCSSProperty_visibility) {
  1.2712 +    NS_ABORT_IF_FALSE(aOutput.GetUnit() == nsStyleAnimation::eUnit_Enumerated,
  1.2713 +                      "unexpected unit");
  1.2714 +    aOutput.SetIntValue(aOutput.GetIntValue(),
  1.2715 +                        nsStyleAnimation::eUnit_Visibility);
  1.2716 +  }
  1.2717 +
  1.2718 +  return true;
  1.2719 +}
  1.2720 +
  1.2721 +NS_IMETHODIMP
  1.2722 +nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
  1.2723 +{
  1.2724 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2725 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2726 +  }
  1.2727 +
  1.2728 +  nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
  1.2729 +  driver->AdvanceTimeAndRefresh(aMilliseconds);
  1.2730 +
  1.2731 +  LayerTransactionChild* transaction = GetLayerTransaction();
  1.2732 +  if (transaction) {
  1.2733 +    transaction->SendSetTestSampleTime(driver->MostRecentRefresh());
  1.2734 +  }
  1.2735 +
  1.2736 +  return NS_OK;
  1.2737 +}
  1.2738 +
  1.2739 +NS_IMETHODIMP
  1.2740 +nsDOMWindowUtils::RestoreNormalRefresh()
  1.2741 +{
  1.2742 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2743 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2744 +  }
  1.2745 +
  1.2746 +  // Kick the compositor out of test mode before the refresh driver, so that
  1.2747 +  // the refresh driver doesn't send an update that gets ignored by the
  1.2748 +  // compositor.
  1.2749 +  LayerTransactionChild* transaction = GetLayerTransaction();
  1.2750 +  if (transaction) {
  1.2751 +    transaction->SendLeaveTestMode();
  1.2752 +  }
  1.2753 +
  1.2754 +  nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
  1.2755 +  driver->RestoreNormalRefresh();
  1.2756 +
  1.2757 +  return NS_OK;
  1.2758 +}
  1.2759 +
  1.2760 +NS_IMETHODIMP
  1.2761 +nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult)
  1.2762 +{
  1.2763 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2764 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2765 +  }
  1.2766 +
  1.2767 +  nsPresContext* pc = GetPresContext();
  1.2768 +  *aResult =
  1.2769 +    pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
  1.2770 +
  1.2771 +  return NS_OK;
  1.2772 +}
  1.2773 +
  1.2774 +NS_IMETHODIMP
  1.2775 +nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
  1.2776 +                                       int32_t aX, int32_t aY)
  1.2777 +{
  1.2778 +  nsCOMPtr<Element> element = do_QueryInterface(aNode);
  1.2779 +  if (!element) {
  1.2780 +    return NS_ERROR_INVALID_ARG;
  1.2781 +  }
  1.2782 +  nsIFrame* frame = element->GetPrimaryFrame();
  1.2783 +  if (!frame) {
  1.2784 +    return NS_ERROR_UNEXPECTED;
  1.2785 +  }
  1.2786 +  nsIScrollableFrame* scrollable = do_QueryFrame(frame);
  1.2787 +  nsPresContext* presContext = frame->PresContext();
  1.2788 +  nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
  1.2789 +  if (!scrollable) {
  1.2790 +    if (rootScrollFrame && rootScrollFrame->GetContent() == element) {
  1.2791 +      frame = rootScrollFrame;
  1.2792 +      scrollable = do_QueryFrame(frame);
  1.2793 +    }
  1.2794 +  }
  1.2795 +  if (!scrollable) {
  1.2796 +    return NS_ERROR_UNEXPECTED;
  1.2797 +  }
  1.2798 +  Layer* layer = FrameLayerBuilder::GetDedicatedLayer(scrollable->GetScrolledFrame(),
  1.2799 +    nsDisplayItem::TYPE_SCROLL_LAYER);
  1.2800 +  if (!layer) {
  1.2801 +    if (rootScrollFrame == frame && !presContext->GetParentPresContext()) {
  1.2802 +      nsIWidget* widget = GetWidget();
  1.2803 +      if (widget) {
  1.2804 +        LayerManager* manager = widget->GetLayerManager();
  1.2805 +        if (manager) {
  1.2806 +          layer = manager->GetRoot();
  1.2807 +        }
  1.2808 +      }
  1.2809 +    }
  1.2810 +    if (!layer) {
  1.2811 +      return NS_ERROR_UNEXPECTED;
  1.2812 +    }
  1.2813 +  }
  1.2814 +  ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
  1.2815 +  if (!forwarder || !forwarder->HasShadowManager()) {
  1.2816 +    return NS_ERROR_UNEXPECTED;
  1.2817 +  }
  1.2818 +  forwarder->GetShadowManager()->SendSetAsyncScrollOffset(
  1.2819 +    layer->AsShadowableLayer()->GetShadow(), aX, aY);
  1.2820 +  return NS_OK;
  1.2821 +}
  1.2822 +
  1.2823 +NS_IMETHODIMP
  1.2824 +nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
  1.2825 +                                           const nsAString& aProperty,
  1.2826 +                                           const nsAString& aValue1,
  1.2827 +                                           const nsAString& aValue2,
  1.2828 +                                           double* aResult)
  1.2829 +{
  1.2830 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2831 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2832 +  }
  1.2833 +
  1.2834 +  nsresult rv;
  1.2835 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  1.2836 +  NS_ENSURE_SUCCESS(rv, rv);
  1.2837 +
  1.2838 +  // Convert direction-dependent properties as appropriate, e.g.,
  1.2839 +  // border-left to border-left-value.
  1.2840 +  nsCSSProperty property =
  1.2841 +    nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState);
  1.2842 +  if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
  1.2843 +    nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
  1.2844 +    if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
  1.2845 +        nsCSSProps::OtherNameFor(subprop0) == property) {
  1.2846 +      property = subprop0;
  1.2847 +    } else {
  1.2848 +      property = eCSSProperty_UNKNOWN;
  1.2849 +    }
  1.2850 +  }
  1.2851 +
  1.2852 +  NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
  1.2853 +                    !nsCSSProps::IsShorthand(property),
  1.2854 +                    "should not have shorthand");
  1.2855 +
  1.2856 +  nsStyleAnimation::Value v1, v2;
  1.2857 +  if (property == eCSSProperty_UNKNOWN ||
  1.2858 +      !ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
  1.2859 +      !ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
  1.2860 +    return NS_ERROR_ILLEGAL_VALUE;
  1.2861 +  }
  1.2862 +
  1.2863 +  if (!nsStyleAnimation::ComputeDistance(property, v1, v2, *aResult)) {
  1.2864 +    return NS_ERROR_FAILURE;
  1.2865 +  }
  1.2866 +
  1.2867 +  return NS_OK;
  1.2868 +}
  1.2869 +
  1.2870 +nsresult
  1.2871 +nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
  1.2872 +                                 uint32_t aFlags,
  1.2873 +                                 nscolor aBackgroundColor,
  1.2874 +                                 gfxContext* aThebesContext)
  1.2875 +{
  1.2876 +    if (!nsContentUtils::IsCallerChrome()) {
  1.2877 +      return NS_ERROR_DOM_SECURITY_ERR;
  1.2878 +    }
  1.2879 +
  1.2880 +    nsCOMPtr<nsIDocument> doc = GetDocument();
  1.2881 +    NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  1.2882 +
  1.2883 +    // Get Primary Shell
  1.2884 +    nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
  1.2885 +    NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  1.2886 +
  1.2887 +    // Render Document
  1.2888 +    return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
  1.2889 +}
  1.2890 +
  1.2891 +NS_IMETHODIMP 
  1.2892 +nsDOMWindowUtils::GetCursorType(int16_t *aCursor)
  1.2893 +{
  1.2894 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2895 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2896 +  }
  1.2897 +
  1.2898 +  NS_ENSURE_ARG_POINTER(aCursor);
  1.2899 +
  1.2900 +  nsIDocument* doc = GetDocument();
  1.2901 +  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  1.2902 +
  1.2903 +  bool isSameDoc = false;
  1.2904 +  do {
  1.2905 +    if (EventStateManager::sMouseOverDocument == doc) {
  1.2906 +      isSameDoc = true;
  1.2907 +      break;
  1.2908 +    }
  1.2909 +  } while ((doc = doc->GetParentDocument()));
  1.2910 +
  1.2911 +  if (!isSameDoc) {
  1.2912 +    *aCursor = eCursor_none;
  1.2913 +    return NS_OK;
  1.2914 +  }
  1.2915 +
  1.2916 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2917 +  if (!widget)
  1.2918 +    return NS_ERROR_FAILURE;
  1.2919 +
  1.2920 +  // fetch cursor value from window's widget
  1.2921 +  *aCursor = widget->GetCursor();
  1.2922 +
  1.2923 +  return NS_OK;
  1.2924 +}
  1.2925 +
  1.2926 +NS_IMETHODIMP
  1.2927 +nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
  1.2928 +{
  1.2929 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2930 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2931 +  }
  1.2932 +
  1.2933 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2934 +  if (!widget)
  1.2935 +    return NS_ERROR_FAILURE;
  1.2936 +
  1.2937 +  *aDPI = widget->GetDPI();
  1.2938 +
  1.2939 +  return NS_OK;
  1.2940 +}
  1.2941 +
  1.2942 +
  1.2943 +NS_IMETHODIMP
  1.2944 +nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID,
  1.2945 +                                       nsIDOMWindow** aWindow)
  1.2946 +{
  1.2947 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2948 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2949 +  }
  1.2950 +
  1.2951 +  // XXX This method is deprecated.  See bug 865664.
  1.2952 +  nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
  1.2953 +                                  NS_LITERAL_CSTRING("DOM"),
  1.2954 +                                  nsContentUtils::GetDocumentFromCaller(),
  1.2955 +                                  nsContentUtils::eDOM_PROPERTIES,
  1.2956 +                                  "GetWindowWithOuterIdWarning");
  1.2957 +
  1.2958 +  *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
  1.2959 +  NS_IF_ADDREF(*aWindow);
  1.2960 +  return NS_OK;
  1.2961 +}
  1.2962 +
  1.2963 +NS_IMETHODIMP
  1.2964 +nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult)
  1.2965 +{
  1.2966 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2967 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2968 +  }
  1.2969 +
  1.2970 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.2971 +  NS_ENSURE_STATE(window);
  1.2972 +
  1.2973 +  nsCOMPtr<nsIDOMElement> element =
  1.2974 +    do_QueryInterface(window->GetFrameElementInternal());
  1.2975 +
  1.2976 +  element.forget(aResult);
  1.2977 +  return NS_OK;
  1.2978 +}
  1.2979 +
  1.2980 +NS_IMETHODIMP
  1.2981 +nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
  1.2982 +                              nsIDOMFile **aDOMFile)
  1.2983 +{
  1.2984 +  if (!nsContentUtils::IsCallerChrome()) {
  1.2985 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.2986 +  }
  1.2987 +
  1.2988 +  if (!aFile) {
  1.2989 +    return NS_ERROR_FAILURE;
  1.2990 +  }
  1.2991 +
  1.2992 +  NS_ADDREF(*aDOMFile = new nsDOMFileFile(aFile));
  1.2993 +  return NS_OK;
  1.2994 +}
  1.2995 +
  1.2996 +#ifdef DEBUG
  1.2997 +static bool
  1.2998 +CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
  1.2999 +{
  1.3000 +  gfx::Matrix transform;
  1.3001 +  if (!aLayer->GetTransform().Is2D(&transform) ||
  1.3002 +      transform.HasNonIntegerTranslation())
  1.3003 +    return false;
  1.3004 +  transform.NudgeToIntegers();
  1.3005 +  nsIntPoint offset = aOffset + nsIntPoint(transform._31, transform._32);
  1.3006 +
  1.3007 +  Layer* child = aLayer->GetFirstChild();
  1.3008 +  if (child) {
  1.3009 +    while (child) {
  1.3010 +      if (!CheckLeafLayers(child, offset, aCoveredRegion))
  1.3011 +        return false;
  1.3012 +      child = child->GetNextSibling();
  1.3013 +    }
  1.3014 +  } else {
  1.3015 +    nsIntRegion rgn = aLayer->GetVisibleRegion();
  1.3016 +    rgn.MoveBy(offset);
  1.3017 +    nsIntRegion tmp;
  1.3018 +    tmp.And(rgn, *aCoveredRegion);
  1.3019 +    if (!tmp.IsEmpty())
  1.3020 +      return false;
  1.3021 +    aCoveredRegion->Or(*aCoveredRegion, rgn);
  1.3022 +  }
  1.3023 +
  1.3024 +  return true;
  1.3025 +}
  1.3026 +#endif
  1.3027 +
  1.3028 +NS_IMETHODIMP
  1.3029 +nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult)
  1.3030 +{
  1.3031 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3032 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3033 +  }
  1.3034 +
  1.3035 +  *aResult = true;
  1.3036 +#ifdef DEBUG
  1.3037 +  nsIWidget* widget = GetWidget();
  1.3038 +  if (!widget)
  1.3039 +    return NS_ERROR_FAILURE;
  1.3040 +  LayerManager* manager = widget->GetLayerManager();
  1.3041 +  if (!manager)
  1.3042 +    return NS_ERROR_FAILURE;
  1.3043 +  nsPresContext* presContext = GetPresContext();
  1.3044 +  if (!presContext)
  1.3045 +    return NS_ERROR_FAILURE;
  1.3046 +  Layer* root = manager->GetRoot();
  1.3047 +  if (!root)
  1.3048 +    return NS_ERROR_FAILURE;
  1.3049 +
  1.3050 +  nsIntPoint offset(0, 0);
  1.3051 +  nsIntRegion coveredRegion;
  1.3052 +  if (!CheckLeafLayers(root, offset, &coveredRegion)) {
  1.3053 +    *aResult = false;
  1.3054 +  }
  1.3055 +  if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
  1.3056 +    *aResult = false;
  1.3057 +  }
  1.3058 +#endif
  1.3059 +  return NS_OK;
  1.3060 +}
  1.3061 +
  1.3062 +NS_IMETHODIMP
  1.3063 +nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
  1.3064 +{
  1.3065 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3066 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3067 +  }
  1.3068 +
  1.3069 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3070 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.3071 +
  1.3072 +  nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
  1.3073 +  *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
  1.3074 +  return NS_OK;
  1.3075 +}
  1.3076 +
  1.3077 +NS_IMETHODIMP
  1.3078 +nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
  1.3079 +{
  1.3080 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3081 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3082 +  }
  1.3083 +
  1.3084 +  if (!aElement) {
  1.3085 +    return NS_ERROR_INVALID_ARG;
  1.3086 +  }
  1.3087 +
  1.3088 +  nsresult rv;
  1.3089 +  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
  1.3090 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3091 +
  1.3092 +  nsIFrame* frame = content->GetPrimaryFrame();
  1.3093 +
  1.3094 +  if (!frame) {
  1.3095 +    *aResult = false;
  1.3096 +    return NS_OK;
  1.3097 +  }
  1.3098 +
  1.3099 +  *aResult = frame->CheckAndClearPaintedState();
  1.3100 +  return NS_OK;
  1.3101 +}
  1.3102 +
  1.3103 +NS_IMETHODIMP
  1.3104 +nsDOMWindowUtils::EnableDialogs()
  1.3105 +{
  1.3106 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3107 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3108 +  }
  1.3109 +
  1.3110 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3111 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.3112 +
  1.3113 +  static_cast<nsGlobalWindow*>(window.get())->EnableDialogs();
  1.3114 +  return NS_OK;
  1.3115 +}
  1.3116 +
  1.3117 +NS_IMETHODIMP
  1.3118 +nsDOMWindowUtils::DisableDialogs()
  1.3119 +{
  1.3120 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3121 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3122 +  }
  1.3123 +
  1.3124 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3125 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.3126 +
  1.3127 +  static_cast<nsGlobalWindow*>(window.get())->DisableDialogs();
  1.3128 +  return NS_OK;
  1.3129 +}
  1.3130 +
  1.3131 +NS_IMETHODIMP
  1.3132 +nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
  1.3133 +{
  1.3134 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3135 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3136 +  }
  1.3137 +
  1.3138 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3139 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.3140 +
  1.3141 +  *aResult = static_cast<nsGlobalWindow*>(window.get())->AreDialogsEnabled();
  1.3142 +  return NS_OK;
  1.3143 +}
  1.3144 +
  1.3145 +static nsIDOMBlob*
  1.3146 +GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
  1.3147 +  nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
  1.3148 +    nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
  1.3149 +  return blob;
  1.3150 +}
  1.3151 +
  1.3152 +static nsresult
  1.3153 +GetFileOrBlob(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
  1.3154 +              JS::Handle<JS::Value> aParameters, JSContext* aCx,
  1.3155 +              uint8_t aOptionalArgCount, nsISupports** aResult)
  1.3156 +{
  1.3157 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3158 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3159 +  }
  1.3160 +
  1.3161 +  nsresult rv;
  1.3162 +
  1.3163 +  nsCOMPtr<nsISupports> file;
  1.3164 +
  1.3165 +  if (aName.IsVoid()) {
  1.3166 +    rv = nsDOMMultipartFile::NewBlob(getter_AddRefs(file));
  1.3167 +  }
  1.3168 +  else {
  1.3169 +    rv = nsDOMMultipartFile::NewFile(aName, getter_AddRefs(file));
  1.3170 +  }
  1.3171 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3172 +
  1.3173 +  nsDOMMultipartFile* domFile =
  1.3174 +    static_cast<nsDOMMultipartFile*>(static_cast<nsIDOMFile*>(file.get()));
  1.3175 +
  1.3176 +  JS::AutoValueArray<2> args(aCx);
  1.3177 +  args[0].set(aBlobParts);
  1.3178 +  args[1].set(aParameters);
  1.3179 +
  1.3180 +  rv = domFile->InitBlob(aCx, aOptionalArgCount, args.begin(), GetXPConnectNative);
  1.3181 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3182 +
  1.3183 +  file.forget(aResult);
  1.3184 +  return NS_OK;
  1.3185 +}
  1.3186 +
  1.3187 +NS_IMETHODIMP
  1.3188 +nsDOMWindowUtils::GetFile(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
  1.3189 +                          JS::Handle<JS::Value> aParameters, JSContext* aCx,
  1.3190 +                          uint8_t aOptionalArgCount, nsIDOMFile** aResult)
  1.3191 +{
  1.3192 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3193 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3194 +  }
  1.3195 +
  1.3196 +  nsCOMPtr<nsISupports> file;
  1.3197 +  nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx,
  1.3198 +                              aOptionalArgCount, getter_AddRefs(file));
  1.3199 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3200 +
  1.3201 +  nsCOMPtr<nsIDOMFile> result = do_QueryInterface(file);
  1.3202 +  result.forget(aResult);
  1.3203 +
  1.3204 +  return NS_OK;
  1.3205 +}
  1.3206 +
  1.3207 +NS_IMETHODIMP
  1.3208 +nsDOMWindowUtils::GetBlob(JS::Handle<JS::Value> aBlobParts,
  1.3209 +                          JS::Handle<JS::Value> aParameters, JSContext* aCx,
  1.3210 +                          uint8_t aOptionalArgCount, nsIDOMBlob** aResult)
  1.3211 +{
  1.3212 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3213 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3214 +  }
  1.3215 +
  1.3216 +  nsCOMPtr<nsISupports> blob;
  1.3217 +  nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx,
  1.3218 +                              aOptionalArgCount, getter_AddRefs(blob));
  1.3219 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3220 +
  1.3221 +  nsCOMPtr<nsIDOMBlob> result = do_QueryInterface(blob);
  1.3222 +  result.forget(aResult);
  1.3223 +
  1.3224 +  return NS_OK;
  1.3225 +}
  1.3226 +
  1.3227 +NS_IMETHODIMP
  1.3228 +nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
  1.3229 +                            int64_t* aResult)
  1.3230 +{
  1.3231 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3232 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3233 +  }
  1.3234 +
  1.3235 +  if (!JSVAL_IS_PRIMITIVE(aFile)) {
  1.3236 +    JSObject* obj = JSVAL_TO_OBJECT(aFile);
  1.3237 +
  1.3238 +    file::FileHandle* fileHandle;
  1.3239 +    if (NS_SUCCEEDED(UNWRAP_OBJECT(FileHandle, obj, fileHandle))) {
  1.3240 +      *aResult = fileHandle->GetFileId();
  1.3241 +      return NS_OK;
  1.3242 +    }
  1.3243 +
  1.3244 +    nsISupports* nativeObj =
  1.3245 +      nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
  1.3246 +
  1.3247 +    nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
  1.3248 +    if (blob) {
  1.3249 +      *aResult = blob->GetFileId();
  1.3250 +      return NS_OK;
  1.3251 +    }
  1.3252 +  }
  1.3253 +
  1.3254 +  *aResult = -1;
  1.3255 +  return NS_OK;
  1.3256 +}
  1.3257 +
  1.3258 +NS_IMETHODIMP
  1.3259 +nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
  1.3260 +                                    JS::Handle<JS::Value> aOptions,
  1.3261 +                                    int32_t* aRefCnt, int32_t* aDBRefCnt,
  1.3262 +                                    int32_t* aSliceRefCnt, JSContext* aCx,
  1.3263 +                                    bool* aResult)
  1.3264 +{
  1.3265 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3266 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3267 +  }
  1.3268 +
  1.3269 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3270 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.3271 +
  1.3272 +  nsCString origin;
  1.3273 +  quota::PersistenceType defaultPersistenceType;
  1.3274 +  nsresult rv =
  1.3275 +    quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr,
  1.3276 +                                           &defaultPersistenceType);
  1.3277 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3278 +
  1.3279 +  IDBOpenDBOptions options;
  1.3280 +  JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
  1.3281 +  if (!options.Init(aCx, optionsVal)) {
  1.3282 +    return NS_ERROR_TYPE_ERR;
  1.3283 +  }
  1.3284 +
  1.3285 +  quota::PersistenceType persistenceType =
  1.3286 +    quota::PersistenceTypeFromStorage(options.mStorage, defaultPersistenceType);
  1.3287 +
  1.3288 +  nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
  1.3289 +    indexedDB::IndexedDatabaseManager::Get();
  1.3290 +
  1.3291 +  if (mgr) {
  1.3292 +    rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
  1.3293 +                                        aId, aRefCnt, aDBRefCnt, aSliceRefCnt,
  1.3294 +                                        aResult);
  1.3295 +    NS_ENSURE_SUCCESS(rv, rv);
  1.3296 +  }
  1.3297 +  else {
  1.3298 +    *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;
  1.3299 +    *aResult = false;
  1.3300 +  }
  1.3301 +
  1.3302 +  return NS_OK;
  1.3303 +}
  1.3304 +
  1.3305 +NS_IMETHODIMP
  1.3306 +nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
  1.3307 +{
  1.3308 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3309 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3310 +  }
  1.3311 +
  1.3312 +  *aResult = JS::IsIncrementalGCEnabled(JS_GetRuntime(cx));
  1.3313 +  return NS_OK;
  1.3314 +}
  1.3315 +
  1.3316 +NS_IMETHODIMP
  1.3317 +nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
  1.3318 +{
  1.3319 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3320 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3321 +  }
  1.3322 +
  1.3323 +  js::StartPCCountProfiling(cx);
  1.3324 +  return NS_OK;
  1.3325 +}
  1.3326 +
  1.3327 +NS_IMETHODIMP
  1.3328 +nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
  1.3329 +{
  1.3330 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3331 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3332 +  }
  1.3333 +
  1.3334 +  js::StopPCCountProfiling(cx);
  1.3335 +  return NS_OK;
  1.3336 +}
  1.3337 +
  1.3338 +NS_IMETHODIMP
  1.3339 +nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
  1.3340 +{
  1.3341 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3342 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3343 +  }
  1.3344 +
  1.3345 +  js::PurgePCCounts(cx);
  1.3346 +  return NS_OK;
  1.3347 +}
  1.3348 +
  1.3349 +NS_IMETHODIMP
  1.3350 +nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
  1.3351 +{
  1.3352 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3353 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3354 +  }
  1.3355 +
  1.3356 +  *result = js::GetPCCountScriptCount(cx);
  1.3357 +  return NS_OK;
  1.3358 +}
  1.3359 +
  1.3360 +NS_IMETHODIMP
  1.3361 +nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result)
  1.3362 +{
  1.3363 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3364 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3365 +  }
  1.3366 +
  1.3367 +  JSString *text = js::GetPCCountScriptSummary(cx, script);
  1.3368 +  if (!text)
  1.3369 +    return NS_ERROR_FAILURE;
  1.3370 +
  1.3371 +  nsDependentJSString str;
  1.3372 +  if (!str.init(cx, text))
  1.3373 +    return NS_ERROR_FAILURE;
  1.3374 +
  1.3375 +  result = str;
  1.3376 +  return NS_OK;
  1.3377 +}
  1.3378 +
  1.3379 +NS_IMETHODIMP
  1.3380 +nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result)
  1.3381 +{
  1.3382 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3383 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3384 +  }
  1.3385 +
  1.3386 +  JSString *text = js::GetPCCountScriptContents(cx, script);
  1.3387 +  if (!text)
  1.3388 +    return NS_ERROR_FAILURE;
  1.3389 +
  1.3390 +  nsDependentJSString str;
  1.3391 +  if (!str.init(cx, text))
  1.3392 +    return NS_ERROR_FAILURE;
  1.3393 +
  1.3394 +  result = str;
  1.3395 +  return NS_OK;
  1.3396 +}
  1.3397 +
  1.3398 +NS_IMETHODIMP
  1.3399 +nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
  1.3400 +{
  1.3401 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3402 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3403 +  }
  1.3404 +
  1.3405 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3406 +  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
  1.3407 +  nsIDocShell *docShell = window->GetDocShell();
  1.3408 +  NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
  1.3409 +
  1.3410 +  nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
  1.3411 +  NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
  1.3412 +
  1.3413 +  *aPaintingSuppressed = presShell->IsPaintingSuppressed();
  1.3414 +  return NS_OK;
  1.3415 +}
  1.3416 +
  1.3417 +NS_IMETHODIMP
  1.3418 +nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
  1.3419 +{
  1.3420 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3421 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3422 +  }
  1.3423 +
  1.3424 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.3425 +  NS_ENSURE_STATE(doc);
  1.3426 +
  1.3427 +  nsTArray<nsIObjectLoadingContent*> plugins;
  1.3428 +  doc->GetPlugins(plugins);
  1.3429 +
  1.3430 +  JS::Rooted<JSObject*> jsPlugins(cx);
  1.3431 +  nsresult rv = nsTArrayToJSArray(cx, plugins, jsPlugins.address());
  1.3432 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3433 +
  1.3434 +  aPlugins.setObject(*jsPlugins);
  1.3435 +  return NS_OK;
  1.3436 +}
  1.3437 +
  1.3438 +static void
  1.3439 +MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
  1.3440 +{
  1.3441 +  if (aPresContext) {
  1.3442 +    nsIPresShell* presShell = aPresContext->GetPresShell();
  1.3443 +    bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
  1.3444 +    presShell->NotifyFontSizeInflationEnabledIsDirty();
  1.3445 +    bool changed = false;
  1.3446 +    if (presShell && presShell->FontSizeInflationEnabled() &&
  1.3447 +        presShell->FontSizeInflationMinTwips() != 0) {
  1.3448 +      aPresContext->ScreenWidthInchesForFontInflation(&changed);
  1.3449 +    }
  1.3450 +
  1.3451 +    changed = changed ||
  1.3452 +      (fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
  1.3453 +    if (changed) {
  1.3454 +      nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
  1.3455 +      if (docShell) {
  1.3456 +        nsCOMPtr<nsIContentViewer> cv;
  1.3457 +        docShell->GetContentViewer(getter_AddRefs(cv));
  1.3458 +        nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
  1.3459 +        if (mudv) {
  1.3460 +          nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
  1.3461 +          mudv->AppendSubtree(array);
  1.3462 +          for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
  1.3463 +            nsCOMPtr<nsIPresShell> shell;
  1.3464 +            nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
  1.3465 +            cv->GetPresShell(getter_AddRefs(shell));
  1.3466 +            if (shell) {
  1.3467 +              nsIFrame *rootFrame = shell->GetRootFrame();
  1.3468 +              if (rootFrame) {
  1.3469 +                shell->FrameNeedsReflow(rootFrame,
  1.3470 +                                        nsIPresShell::eStyleChange,
  1.3471 +                                        NS_FRAME_IS_DIRTY);
  1.3472 +              }
  1.3473 +            }
  1.3474 +          }
  1.3475 +        }
  1.3476 +      }
  1.3477 +    }
  1.3478 +  }
  1.3479 +}
  1.3480 +
  1.3481 +NS_IMETHODIMP
  1.3482 +nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
  1.3483 +{
  1.3484 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3485 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3486 +  }
  1.3487 +
  1.3488 +  if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
  1.3489 +    return NS_ERROR_ILLEGAL_VALUE;
  1.3490 +  }
  1.3491 +
  1.3492 +  nsIPresShell* presShell = GetPresShell();
  1.3493 +  if (!presShell) {
  1.3494 +    return NS_ERROR_FAILURE;
  1.3495 +  }
  1.3496 +
  1.3497 +  presShell->SetScrollPositionClampingScrollPortSize(
  1.3498 +    nsPresContext::CSSPixelsToAppUnits(aWidth),
  1.3499 +    nsPresContext::CSSPixelsToAppUnits(aHeight));
  1.3500 +
  1.3501 +  // When the "font.size.inflation.minTwips" preference is set, the
  1.3502 +  // layout depends on the size of the screen.  Since when the size
  1.3503 +  // of the screen changes, the scroll position clamping scroll port
  1.3504 +  // size also changes, we hook in the needed updates here rather
  1.3505 +  // than adding a separate notification just for this change.
  1.3506 +  nsPresContext* presContext = GetPresContext();
  1.3507 +  MaybeReflowForInflationScreenWidthChange(presContext);
  1.3508 +
  1.3509 +  return NS_OK;
  1.3510 +}
  1.3511 +
  1.3512 +NS_IMETHODIMP
  1.3513 +nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight,
  1.3514 +                                                         float aBottom, float aLeft)
  1.3515 +{
  1.3516 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3517 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3518 +  }
  1.3519 +
  1.3520 +  if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) {
  1.3521 +    return NS_ERROR_ILLEGAL_VALUE;
  1.3522 +  }
  1.3523 +
  1.3524 +  nsIPresShell* presShell = GetPresShell();
  1.3525 +  if (!presShell) {
  1.3526 +    return NS_ERROR_FAILURE;
  1.3527 +  }
  1.3528 +
  1.3529 +  nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop),
  1.3530 +                   nsPresContext::CSSPixelsToAppUnits(aRight),
  1.3531 +                   nsPresContext::CSSPixelsToAppUnits(aBottom),
  1.3532 +                   nsPresContext::CSSPixelsToAppUnits(aLeft));
  1.3533 +  presShell->SetContentDocumentFixedPositionMargins(margins);
  1.3534 +
  1.3535 +  return NS_OK;
  1.3536 +}
  1.3537 +
  1.3538 +nsresult
  1.3539 +nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
  1.3540 +                                            const nsAString& aNewOrigin)
  1.3541 +{
  1.3542 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3543 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3544 +  }
  1.3545 +
  1.3546 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.3547 +  NS_ENSURE_STATE(doc);
  1.3548 +
  1.3549 +  doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin);
  1.3550 +  return NS_OK;
  1.3551 +}
  1.3552 +
  1.3553 +nsresult
  1.3554 +nsDOMWindowUtils::RemoteFrameFullscreenReverted()
  1.3555 +{
  1.3556 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3557 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3558 +  }
  1.3559 +
  1.3560 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.3561 +  NS_ENSURE_STATE(doc);
  1.3562 +
  1.3563 +  doc->RemoteFrameFullscreenReverted();
  1.3564 +  return NS_OK;
  1.3565 +}
  1.3566 +
  1.3567 +nsresult
  1.3568 +nsDOMWindowUtils::ExitFullscreen()
  1.3569 +{
  1.3570 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3571 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3572 +  }
  1.3573 +
  1.3574 +  nsIDocument::ExitFullscreen(nullptr, /* async */ false);
  1.3575 +  return NS_OK;
  1.3576 +}
  1.3577 +
  1.3578 +NS_IMETHODIMP
  1.3579 +nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
  1.3580 +                                bool *_retval)
  1.3581 +{
  1.3582 +  *_retval = false;
  1.3583 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3584 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3585 +  }
  1.3586 +
  1.3587 +  nsSelectionAmount amount;
  1.3588 +  switch (aSelectBehavior) {
  1.3589 +    case nsIDOMWindowUtils::SELECT_CHARACTER:
  1.3590 +      amount = eSelectCharacter;
  1.3591 +    break;
  1.3592 +    case nsIDOMWindowUtils::SELECT_CLUSTER:
  1.3593 +      amount = eSelectCluster;
  1.3594 +    break;
  1.3595 +    case nsIDOMWindowUtils::SELECT_WORD:
  1.3596 +      amount = eSelectWord;
  1.3597 +    break;
  1.3598 +    case nsIDOMWindowUtils::SELECT_LINE:
  1.3599 +      amount = eSelectLine;
  1.3600 +    break;
  1.3601 +    case nsIDOMWindowUtils::SELECT_BEGINLINE:
  1.3602 +      amount = eSelectBeginLine;
  1.3603 +    break;
  1.3604 +    case nsIDOMWindowUtils::SELECT_ENDLINE:
  1.3605 +      amount = eSelectEndLine;
  1.3606 +    break;
  1.3607 +    case nsIDOMWindowUtils::SELECT_PARAGRAPH:
  1.3608 +      amount = eSelectParagraph;
  1.3609 +    break;
  1.3610 +    case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
  1.3611 +      amount = eSelectWordNoSpace;
  1.3612 +    break;
  1.3613 +    default:
  1.3614 +      return NS_ERROR_INVALID_ARG;
  1.3615 +  }
  1.3616 +
  1.3617 +  nsIPresShell* presShell = GetPresShell();
  1.3618 +  if (!presShell) {
  1.3619 +    return NS_ERROR_UNEXPECTED;
  1.3620 +  }
  1.3621 +
  1.3622 +  // The root frame for this content window
  1.3623 +  nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
  1.3624 +  if (!rootFrame) {
  1.3625 +    return NS_ERROR_UNEXPECTED;
  1.3626 +  }
  1.3627 +
  1.3628 +  // Get the target frame at the client coordinates passed to us
  1.3629 +  nsPoint offset;
  1.3630 +  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
  1.3631 +  nsIntPoint pt = LayoutDeviceIntPoint::ToUntyped(
  1.3632 +    ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()));
  1.3633 +  nsPoint ptInRoot =
  1.3634 +    nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
  1.3635 +  nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
  1.3636 +  // This can happen if the page hasn't loaded yet or if the point
  1.3637 +  // is outside the frame.
  1.3638 +  if (!targetFrame) {
  1.3639 +    return NS_ERROR_INVALID_ARG;
  1.3640 +  }
  1.3641 +
  1.3642 +  // Convert point to coordinates relative to the target frame, which is
  1.3643 +  // what targetFrame's SelectByTypeAtPoint expects.
  1.3644 +  nsPoint relPoint =
  1.3645 +    nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
  1.3646 +
  1.3647 +  nsresult rv =
  1.3648 +    static_cast<nsFrame*>(targetFrame)->
  1.3649 +      SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
  1.3650 +                          nsFrame::SELECT_ACCUMULATE);
  1.3651 +  *_retval = !NS_FAILED(rv);
  1.3652 +  return NS_OK;
  1.3653 +}
  1.3654 +
  1.3655 +static nsIDocument::additionalSheetType
  1.3656 +convertSheetType(uint32_t aSheetType)
  1.3657 +{
  1.3658 +  switch(aSheetType) {
  1.3659 +    case nsDOMWindowUtils::AGENT_SHEET:
  1.3660 +      return nsIDocument::eAgentSheet;
  1.3661 +    case nsDOMWindowUtils::USER_SHEET:
  1.3662 +      return nsIDocument::eUserSheet;
  1.3663 +    case nsDOMWindowUtils::AUTHOR_SHEET:
  1.3664 +      return nsIDocument::eAuthorSheet;
  1.3665 +    default:
  1.3666 +      NS_ASSERTION(false, "wrong type");
  1.3667 +      // we must return something although this should never happen
  1.3668 +      return nsIDocument::SheetTypeCount;
  1.3669 +  }
  1.3670 +}
  1.3671 +
  1.3672 +NS_IMETHODIMP
  1.3673 +nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
  1.3674 +{
  1.3675 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3676 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3677 +  }
  1.3678 +
  1.3679 +  NS_ENSURE_ARG_POINTER(aSheetURI);
  1.3680 +  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
  1.3681 +                aSheetType == USER_SHEET ||
  1.3682 +                aSheetType == AUTHOR_SHEET);
  1.3683 +
  1.3684 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.3685 +  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  1.3686 +
  1.3687 +  nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
  1.3688 +
  1.3689 +  return doc->LoadAdditionalStyleSheet(type, aSheetURI);
  1.3690 +}
  1.3691 +
  1.3692 +NS_IMETHODIMP
  1.3693 +nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
  1.3694 +{
  1.3695 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3696 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3697 +  }
  1.3698 +
  1.3699 +  NS_ENSURE_ARG_POINTER(aSheetURI);
  1.3700 +  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
  1.3701 +                aSheetType == USER_SHEET ||
  1.3702 +                aSheetType == AUTHOR_SHEET);
  1.3703 +
  1.3704 +  nsCOMPtr<nsIDocument> doc = GetDocument();
  1.3705 +  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
  1.3706 +
  1.3707 +  nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
  1.3708 +
  1.3709 +  doc->RemoveAdditionalStyleSheet(type, aSheetURI);
  1.3710 +  return NS_OK;
  1.3711 +}
  1.3712 +
  1.3713 +NS_IMETHODIMP
  1.3714 +nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput)
  1.3715 +{
  1.3716 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3717 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3718 +  }
  1.3719 +
  1.3720 +  *aHandlingUserInput = EventStateManager::IsHandlingUserInput();
  1.3721 +
  1.3722 +  return NS_OK;
  1.3723 +}
  1.3724 +
  1.3725 +NS_IMETHODIMP
  1.3726 +nsDOMWindowUtils::AllowScriptsToClose()
  1.3727 +{
  1.3728 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3729 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3730 +  }
  1.3731 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3732 +  NS_ENSURE_STATE(window);
  1.3733 +  static_cast<nsGlobalWindow*>(window.get())->AllowScriptsToClose();
  1.3734 +  return NS_OK;
  1.3735 +}
  1.3736 +
  1.3737 +NS_IMETHODIMP
  1.3738 +nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible)
  1.3739 +{
  1.3740 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3741 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3742 +  }
  1.3743 +
  1.3744 +  // this should reflect the "is parent window visible" logic in
  1.3745 +  // nsWindowWatcher::OpenWindowInternal()
  1.3746 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3747 +  NS_ENSURE_STATE(window);
  1.3748 +
  1.3749 +  nsCOMPtr<nsIWidget> parentWidget;
  1.3750 +  nsIDocShell *docShell = window->GetDocShell();
  1.3751 +  if (docShell) {
  1.3752 +    if (TabChild *tabChild = TabChild::GetFrom(docShell)) {
  1.3753 +      if (!tabChild->SendIsParentWindowMainWidgetVisible(aIsVisible))
  1.3754 +        return NS_ERROR_FAILURE;
  1.3755 +      return NS_OK;
  1.3756 +    }
  1.3757 +
  1.3758 +    nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
  1.3759 +    docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
  1.3760 +    nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
  1.3761 +    if (parentWindow) {
  1.3762 +        parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
  1.3763 +    }
  1.3764 +  }
  1.3765 +  if (!parentWidget) {
  1.3766 +    return NS_ERROR_NOT_AVAILABLE;
  1.3767 +  }
  1.3768 +
  1.3769 +  *aIsVisible = parentWidget->IsVisible();
  1.3770 +  return NS_OK;
  1.3771 +}
  1.3772 +
  1.3773 +NS_IMETHODIMP
  1.3774 +nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal)
  1.3775 +{
  1.3776 +  *aRetVal = false;
  1.3777 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3778 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3779 +  }
  1.3780 +  nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
  1.3781 +  nsINode* node = n;
  1.3782 +  while (node) {
  1.3783 +    if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
  1.3784 +      nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
  1.3785 +      if (fc && fc->IsDisabledForEvents(NS_EVENT_NULL)) {
  1.3786 +        *aRetVal = true;
  1.3787 +        break;
  1.3788 +      }
  1.3789 +    }
  1.3790 +    node = node->GetParentNode();
  1.3791 +  }
  1.3792 +
  1.3793 +  return NS_OK;
  1.3794 +}
  1.3795 +
  1.3796 +NS_IMETHODIMP
  1.3797 +nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing)
  1.3798 +{
  1.3799 +  nsPresContext* presContext = GetPresContext();
  1.3800 +  if (presContext) {
  1.3801 +    presContext->SetPaintFlashing(aPaintFlashing);
  1.3802 +    // Clear paint flashing colors
  1.3803 +    nsIPresShell* presShell = GetPresShell();
  1.3804 +    if (!aPaintFlashing && presShell) {
  1.3805 +      nsIFrame* rootFrame = presShell->GetRootFrame();
  1.3806 +      if (rootFrame) {
  1.3807 +        rootFrame->InvalidateFrameSubtree();
  1.3808 +      }
  1.3809 +    }
  1.3810 +  }
  1.3811 +  return NS_OK;
  1.3812 +}
  1.3813 +
  1.3814 +NS_IMETHODIMP
  1.3815 +nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal)
  1.3816 +{
  1.3817 +  *aRetVal = false;
  1.3818 +  nsPresContext* presContext = GetPresContext();
  1.3819 +  if (presContext) {
  1.3820 +    *aRetVal = presContext->GetPaintFlashing();
  1.3821 +  }
  1.3822 +  return NS_OK;
  1.3823 +}
  1.3824 +
  1.3825 +NS_IMETHODIMP
  1.3826 +nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
  1.3827 +                                            nsIDOMEvent* aEvent,
  1.3828 +                                            bool* aRetVal)
  1.3829 +{
  1.3830 +  *aRetVal = false;
  1.3831 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3832 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3833 +  }
  1.3834 +  NS_ENSURE_STATE(aTarget && aEvent);
  1.3835 +  aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
  1.3836 +  aTarget->DispatchEvent(aEvent, aRetVal);
  1.3837 +  return NS_OK;
  1.3838 +}
  1.3839 +
  1.3840 +NS_IMETHODIMP
  1.3841 +nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable)
  1.3842 +{
  1.3843 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3844 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3845 +  }
  1.3846 +
  1.3847 +  nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
  1.3848 +  if (!appShell) {
  1.3849 +    return NS_ERROR_NOT_AVAILABLE;
  1.3850 +  }
  1.3851 +
  1.3852 +  return appShell->RunInStableState(runnable);
  1.3853 +}
  1.3854 +
  1.3855 +NS_IMETHODIMP
  1.3856 +nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable)
  1.3857 +{
  1.3858 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3859 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3860 +  }
  1.3861 +
  1.3862 +  nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
  1.3863 +  if (!appShell) {
  1.3864 +    return NS_ERROR_NOT_AVAILABLE;
  1.3865 +  }
  1.3866 +
  1.3867 +  return appShell->RunBeforeNextEvent(runnable);
  1.3868 +}
  1.3869 +
  1.3870 +NS_IMETHODIMP
  1.3871 +nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
  1.3872 +                               const nsAString& aProperty,
  1.3873 +                               nsAString& aResult)
  1.3874 +{
  1.3875 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3876 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3877 +  }
  1.3878 +
  1.3879 +  nsCOMPtr<Element> element = do_QueryInterface(aElement);
  1.3880 +  if (!element) {
  1.3881 +    return NS_ERROR_INVALID_ARG;
  1.3882 +  }
  1.3883 +
  1.3884 +  nsRefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
  1.3885 +  nsIFrame* frame = element->GetPrimaryFrame();
  1.3886 +  if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
  1.3887 +    if (aProperty.EqualsLiteral("opacity")) {
  1.3888 +      Layer* layer =
  1.3889 +        FrameLayerBuilder::GetDedicatedLayer(frame,
  1.3890 +                                             nsDisplayItem::TYPE_OPACITY);
  1.3891 +      if (layer) {
  1.3892 +        float value;
  1.3893 +        ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
  1.3894 +        if (forwarder && forwarder->HasShadowManager()) {
  1.3895 +          forwarder->GetShadowManager()->SendGetOpacity(
  1.3896 +            layer->AsShadowableLayer()->GetShadow(), &value);
  1.3897 +          cssValue = new nsROCSSPrimitiveValue;
  1.3898 +          cssValue->SetNumber(value);
  1.3899 +        }
  1.3900 +      }
  1.3901 +    } else if (aProperty.EqualsLiteral("transform")) {
  1.3902 +      Layer* layer =
  1.3903 +        FrameLayerBuilder::GetDedicatedLayer(frame,
  1.3904 +                                             nsDisplayItem::TYPE_TRANSFORM);
  1.3905 +      if (layer) {
  1.3906 +        ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
  1.3907 +        if (forwarder && forwarder->HasShadowManager()) {
  1.3908 +          MaybeTransform transform;
  1.3909 +          forwarder->GetShadowManager()->SendGetAnimationTransform(
  1.3910 +            layer->AsShadowableLayer()->GetShadow(), &transform);
  1.3911 +          if (transform.type() == MaybeTransform::Tgfx3DMatrix) {
  1.3912 +            cssValue =
  1.3913 +              nsComputedDOMStyle::MatrixToCSSValue(transform.get_gfx3DMatrix());
  1.3914 +          }
  1.3915 +        }
  1.3916 +      }
  1.3917 +    }
  1.3918 +  }
  1.3919 +
  1.3920 +  if (cssValue) {
  1.3921 +    nsString text;
  1.3922 +    ErrorResult rv;
  1.3923 +    cssValue->GetCssText(text, rv);
  1.3924 +    aResult.Assign(text);
  1.3925 +    return rv.ErrorCode();
  1.3926 +  } else {
  1.3927 +    aResult.Truncate();
  1.3928 +  }
  1.3929 +
  1.3930 +  return NS_OK;
  1.3931 +}
  1.3932 +
  1.3933 +NS_IMETHODIMP
  1.3934 +nsDOMWindowUtils::GetOMTAOrComputedStyle(nsIDOMElement* aElement,
  1.3935 +                                         const nsAString& aProperty,
  1.3936 +                                         nsAString& aResult)
  1.3937 +{
  1.3938 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3939 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3940 +  }
  1.3941 +
  1.3942 +  // Try to get OMTA style
  1.3943 +  nsresult rv = GetOMTAStyle(aElement, aProperty, aResult);
  1.3944 +  if (NS_FAILED(rv) || !aResult.IsEmpty()) {
  1.3945 +    return rv;
  1.3946 +  }
  1.3947 +
  1.3948 +  // Otherwise, fall back to computed style
  1.3949 +  nsCOMPtr<Element> element = do_QueryInterface(aElement);
  1.3950 +  if (!element) {
  1.3951 +    return NS_ERROR_INVALID_ARG;
  1.3952 +  }
  1.3953 +  nsCOMPtr<nsIDOMCSSStyleDeclaration> style;
  1.3954 +  rv = element->GetCurrentDoc()->GetWindow()->
  1.3955 +    GetComputedStyle(aElement, aProperty, getter_AddRefs(style));
  1.3956 +  NS_ENSURE_SUCCESS(rv, rv);
  1.3957 +
  1.3958 +  return style->GetPropertyValue(aProperty, aResult);
  1.3959 +}
  1.3960 +
  1.3961 +NS_IMETHODIMP
  1.3962 +nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
  1.3963 +{
  1.3964 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3965 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3966 +  }
  1.3967 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3968 +  NS_ENSURE_STATE(window);
  1.3969 +
  1.3970 +  *aMuted = window->GetAudioMuted();
  1.3971 +  return NS_OK;
  1.3972 +}
  1.3973 +
  1.3974 +NS_IMETHODIMP
  1.3975 +nsDOMWindowUtils::SetAudioMuted(bool aMuted)
  1.3976 +{
  1.3977 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3978 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3979 +  }
  1.3980 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3981 +  NS_ENSURE_STATE(window);
  1.3982 +
  1.3983 +  window->SetAudioMuted(aMuted);
  1.3984 +  return NS_OK;
  1.3985 +}
  1.3986 +
  1.3987 +NS_IMETHODIMP
  1.3988 +nsDOMWindowUtils::GetAudioVolume(float* aVolume)
  1.3989 +{
  1.3990 +  if (!nsContentUtils::IsCallerChrome()) {
  1.3991 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.3992 +  }
  1.3993 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.3994 +  NS_ENSURE_STATE(window);
  1.3995 +
  1.3996 +  *aVolume = window->GetAudioVolume();
  1.3997 +  return NS_OK;
  1.3998 +}
  1.3999 +
  1.4000 +NS_IMETHODIMP
  1.4001 +nsDOMWindowUtils::SetAudioVolume(float aVolume)
  1.4002 +{
  1.4003 +  if (!nsContentUtils::IsCallerChrome()) {
  1.4004 +    return NS_ERROR_DOM_SECURITY_ERR;
  1.4005 +  }
  1.4006 +  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
  1.4007 +  NS_ENSURE_STATE(window);
  1.4008 +
  1.4009 +  return window->SetAudioVolume(aVolume);
  1.4010 +}
  1.4011 +
  1.4012 +NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
  1.4013 +  NS_INTERFACE_MAP_ENTRY(nsISupports)
  1.4014 +  NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
  1.4015 +NS_INTERFACE_MAP_END
  1.4016 +
  1.4017 +NS_IMPL_ADDREF(nsTranslationNodeList)
  1.4018 +NS_IMPL_RELEASE(nsTranslationNodeList)
  1.4019 +
  1.4020 +NS_IMETHODIMP
  1.4021 +nsTranslationNodeList::Item(uint32_t aIndex, nsIDOMNode** aRetVal)
  1.4022 +{
  1.4023 +  NS_ENSURE_ARG_POINTER(aRetVal);
  1.4024 +  NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex));
  1.4025 +  return NS_OK;
  1.4026 +}
  1.4027 +
  1.4028 +NS_IMETHODIMP
  1.4029 +nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal)
  1.4030 +{
  1.4031 +  NS_ENSURE_ARG_POINTER(aRetVal);
  1.4032 +  if (aIndex >= mLength) {
  1.4033 +    *aRetVal = false;
  1.4034 +    return NS_OK;
  1.4035 +  }
  1.4036 +
  1.4037 +  *aRetVal = mNodeIsRoot.ElementAt(aIndex);
  1.4038 +  return NS_OK;
  1.4039 +}
  1.4040 +
  1.4041 +NS_IMETHODIMP
  1.4042 +nsTranslationNodeList::GetLength(uint32_t* aRetVal)
  1.4043 +{
  1.4044 +  NS_ENSURE_ARG_POINTER(aRetVal);
  1.4045 +  *aRetVal = mLength;
  1.4046 +  return NS_OK;
  1.4047 +}

mercurial