dom/base/nsDOMWindowUtils.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsDOMWindowUtils.h"
michael@0 7
michael@0 8 #include "mozilla/layers/CompositorChild.h"
michael@0 9 #include "mozilla/layers/LayerTransactionChild.h"
michael@0 10 #include "nsPresContext.h"
michael@0 11 #include "nsDOMClassInfoID.h"
michael@0 12 #include "nsError.h"
michael@0 13 #include "nsIDOMEvent.h"
michael@0 14 #include "nsQueryContentEventResult.h"
michael@0 15 #include "CompositionStringSynthesizer.h"
michael@0 16 #include "nsGlobalWindow.h"
michael@0 17 #include "nsIDocument.h"
michael@0 18 #include "nsFocusManager.h"
michael@0 19 #include "nsFrameManager.h"
michael@0 20 #include "nsRefreshDriver.h"
michael@0 21 #include "mozilla/dom/Touch.h"
michael@0 22 #include "nsIObjectLoadingContent.h"
michael@0 23 #include "nsFrame.h"
michael@0 24 #include "mozilla/layers/ShadowLayers.h"
michael@0 25
michael@0 26 #include "nsIScrollableFrame.h"
michael@0 27
michael@0 28 #include "nsContentUtils.h"
michael@0 29
michael@0 30 #include "nsIFrame.h"
michael@0 31 #include "nsIWidget.h"
michael@0 32 #include "nsCharsetSource.h"
michael@0 33 #include "nsJSEnvironment.h"
michael@0 34 #include "nsJSUtils.h"
michael@0 35
michael@0 36 #include "mozilla/EventStateManager.h"
michael@0 37 #include "mozilla/MiscEvents.h"
michael@0 38 #include "mozilla/MouseEvents.h"
michael@0 39 #include "mozilla/TextEvents.h"
michael@0 40 #include "mozilla/TouchEvents.h"
michael@0 41
michael@0 42 #include "nsViewManager.h"
michael@0 43
michael@0 44 #include "nsIDOMHTMLCanvasElement.h"
michael@0 45 #include "nsLayoutUtils.h"
michael@0 46 #include "nsComputedDOMStyle.h"
michael@0 47 #include "nsIPresShell.h"
michael@0 48 #include "nsStyleAnimation.h"
michael@0 49 #include "nsCSSProps.h"
michael@0 50 #include "nsDOMFile.h"
michael@0 51 #include "nsTArrayHelpers.h"
michael@0 52 #include "nsIDocShell.h"
michael@0 53 #include "nsIContentViewer.h"
michael@0 54 #include "nsIMarkupDocumentViewer.h"
michael@0 55 #include "mozilla/dom/DOMRect.h"
michael@0 56 #include <algorithm>
michael@0 57
michael@0 58 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
michael@0 59 #include <gdk/gdk.h>
michael@0 60 #include <gdk/gdkx.h>
michael@0 61 #endif
michael@0 62
michael@0 63 #include "Layers.h"
michael@0 64 #include "mozilla/layers/ShadowLayers.h"
michael@0 65
michael@0 66 #include "mozilla/dom/Element.h"
michael@0 67 #include "mozilla/dom/file/FileHandle.h"
michael@0 68 #include "mozilla/dom/FileHandleBinding.h"
michael@0 69 #include "mozilla/dom/TabChild.h"
michael@0 70 #include "mozilla/dom/IDBFactoryBinding.h"
michael@0 71 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
michael@0 72 #include "mozilla/dom/quota/PersistenceType.h"
michael@0 73 #include "mozilla/dom/quota/QuotaManager.h"
michael@0 74 #include "nsDOMBlobBuilder.h"
michael@0 75 #include "nsPrintfCString.h"
michael@0 76 #include "nsViewportInfo.h"
michael@0 77 #include "nsIFormControl.h"
michael@0 78 #include "nsIScriptError.h"
michael@0 79 #include "nsIAppShell.h"
michael@0 80 #include "nsWidgetsCID.h"
michael@0 81 #include "FrameLayerBuilder.h"
michael@0 82 #include "nsDisplayList.h"
michael@0 83 #include "nsROCSSPrimitiveValue.h"
michael@0 84 #include "nsIBaseWindow.h"
michael@0 85 #include "nsIDocShellTreeOwner.h"
michael@0 86 #include "nsIInterfaceRequestorUtils.h"
michael@0 87 #include "GeckoProfiler.h"
michael@0 88 #include "mozilla/Preferences.h"
michael@0 89 #include "nsIContentIterator.h"
michael@0 90
michael@0 91 #ifdef XP_WIN
michael@0 92 #undef GetClassName
michael@0 93 #endif
michael@0 94
michael@0 95 using namespace mozilla;
michael@0 96 using namespace mozilla::dom;
michael@0 97 using namespace mozilla::layers;
michael@0 98 using namespace mozilla::widget;
michael@0 99 using namespace mozilla::gfx;
michael@0 100
michael@0 101 class gfxContext;
michael@0 102
michael@0 103 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
michael@0 104
michael@0 105 DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
michael@0 106
michael@0 107 NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
michael@0 108 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
michael@0 109 NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
michael@0 110 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
michael@0 111 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils)
michael@0 112 NS_INTERFACE_MAP_END
michael@0 113
michael@0 114 NS_IMPL_ADDREF(nsDOMWindowUtils)
michael@0 115 NS_IMPL_RELEASE(nsDOMWindowUtils)
michael@0 116
michael@0 117 nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
michael@0 118 {
michael@0 119 nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow);
michael@0 120 mWindow = do_GetWeakReference(supports);
michael@0 121 NS_ASSERTION(aWindow->IsOuterWindow(), "How did that happen?");
michael@0 122 }
michael@0 123
michael@0 124 nsDOMWindowUtils::~nsDOMWindowUtils()
michael@0 125 {
michael@0 126 }
michael@0 127
michael@0 128 nsIPresShell*
michael@0 129 nsDOMWindowUtils::GetPresShell()
michael@0 130 {
michael@0 131 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 132 if (!window)
michael@0 133 return nullptr;
michael@0 134
michael@0 135 nsIDocShell *docShell = window->GetDocShell();
michael@0 136 if (!docShell)
michael@0 137 return nullptr;
michael@0 138
michael@0 139 return docShell->GetPresShell();
michael@0 140 }
michael@0 141
michael@0 142 nsPresContext*
michael@0 143 nsDOMWindowUtils::GetPresContext()
michael@0 144 {
michael@0 145 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 146 if (!window)
michael@0 147 return nullptr;
michael@0 148 nsIDocShell *docShell = window->GetDocShell();
michael@0 149 if (!docShell)
michael@0 150 return nullptr;
michael@0 151 nsRefPtr<nsPresContext> presContext;
michael@0 152 docShell->GetPresContext(getter_AddRefs(presContext));
michael@0 153 return presContext;
michael@0 154 }
michael@0 155
michael@0 156 nsIDocument*
michael@0 157 nsDOMWindowUtils::GetDocument()
michael@0 158 {
michael@0 159 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 160 if (!window) {
michael@0 161 return nullptr;
michael@0 162 }
michael@0 163 return window->GetExtantDoc();
michael@0 164 }
michael@0 165
michael@0 166 LayerTransactionChild*
michael@0 167 nsDOMWindowUtils::GetLayerTransaction()
michael@0 168 {
michael@0 169 nsIWidget* widget = GetWidget();
michael@0 170 if (!widget)
michael@0 171 return nullptr;
michael@0 172
michael@0 173 LayerManager* manager = widget->GetLayerManager();
michael@0 174 if (!manager)
michael@0 175 return nullptr;
michael@0 176
michael@0 177 ShadowLayerForwarder* forwarder = manager->AsShadowForwarder();
michael@0 178 return forwarder && forwarder->HasShadowManager() ?
michael@0 179 forwarder->GetShadowManager() :
michael@0 180 nullptr;
michael@0 181 }
michael@0 182
michael@0 183 NS_IMETHODIMP
michael@0 184 nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
michael@0 185 {
michael@0 186 if (!nsContentUtils::IsCallerChrome()) {
michael@0 187 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 188 }
michael@0 189
michael@0 190 NS_ENSURE_ARG_POINTER(aMode);
michael@0 191 *aMode = 0;
michael@0 192 nsPresContext* presContext = GetPresContext();
michael@0 193 if (presContext) {
michael@0 194 *aMode = presContext->ImageAnimationMode();
michael@0 195 return NS_OK;
michael@0 196 }
michael@0 197 return NS_ERROR_NOT_AVAILABLE;
michael@0 198 }
michael@0 199
michael@0 200 NS_IMETHODIMP
michael@0 201 nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode)
michael@0 202 {
michael@0 203 if (!nsContentUtils::IsCallerChrome()) {
michael@0 204 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 205 }
michael@0 206
michael@0 207 nsPresContext* presContext = GetPresContext();
michael@0 208 if (presContext) {
michael@0 209 presContext->SetImageAnimationMode(aMode);
michael@0 210 return NS_OK;
michael@0 211 }
michael@0 212 return NS_ERROR_NOT_AVAILABLE;
michael@0 213 }
michael@0 214
michael@0 215 NS_IMETHODIMP
michael@0 216 nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
michael@0 217 {
michael@0 218 *aIsForced = false;
michael@0 219
michael@0 220 if (!nsContentUtils::IsCallerChrome()) {
michael@0 221 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 222 }
michael@0 223
michael@0 224 nsIDocument* doc = GetDocument();
michael@0 225 *aIsForced = doc &&
michael@0 226 doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
michael@0 227 return NS_OK;
michael@0 228 }
michael@0 229
michael@0 230 NS_IMETHODIMP
michael@0 231 nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
michael@0 232 nsAString& aValue)
michael@0 233 {
michael@0 234 if (!nsContentUtils::IsCallerChrome()) {
michael@0 235 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 236 }
michael@0 237
michael@0 238 nsIDocument* doc = GetDocument();
michael@0 239 if (doc) {
michael@0 240 nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
michael@0 241 doc->GetHeaderData(name, aValue);
michael@0 242 return NS_OK;
michael@0 243 }
michael@0 244
michael@0 245 aValue.Truncate();
michael@0 246 return NS_OK;
michael@0 247 }
michael@0 248
michael@0 249 NS_IMETHODIMP
michael@0 250 nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
michael@0 251 {
michael@0 252 if (!nsContentUtils::IsCallerChrome()) {
michael@0 253 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 254 }
michael@0 255
michael@0 256 if (aCount == 0)
michael@0 257 aCount = 1;
michael@0 258
michael@0 259 if (nsIPresShell* presShell = GetPresShell()) {
michael@0 260 nsIFrame *rootFrame = presShell->GetRootFrame();
michael@0 261
michael@0 262 if (rootFrame) {
michael@0 263 PRIntervalTime iStart = PR_IntervalNow();
michael@0 264
michael@0 265 for (uint32_t i = 0; i < aCount; i++)
michael@0 266 rootFrame->InvalidateFrame();
michael@0 267
michael@0 268 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK)
michael@0 269 XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False);
michael@0 270 #endif
michael@0 271
michael@0 272 *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
michael@0 273
michael@0 274 return NS_OK;
michael@0 275 }
michael@0 276 }
michael@0 277 return NS_ERROR_FAILURE;
michael@0 278 }
michael@0 279
michael@0 280 NS_IMETHODIMP
michael@0 281 nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
michael@0 282 {
michael@0 283 if (!nsContentUtils::IsCallerChrome()) {
michael@0 284 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 285 }
michael@0 286
michael@0 287 if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) {
michael@0 288 return NS_ERROR_ILLEGAL_VALUE;
michael@0 289 }
michael@0 290
michael@0 291 nsIPresShell* presShell = GetPresShell();
michael@0 292 if (!presShell) {
michael@0 293 return NS_ERROR_FAILURE;
michael@0 294 }
michael@0 295
michael@0 296 nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
michael@0 297 nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
michael@0 298
michael@0 299 presShell->ResizeReflowOverride(width, height);
michael@0 300
michael@0 301 return NS_OK;
michael@0 302 }
michael@0 303
michael@0 304 NS_IMETHODIMP
michael@0 305 nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth,
michael@0 306 uint32_t aDisplayHeight,
michael@0 307 double *aDefaultZoom, bool *aAllowZoom,
michael@0 308 double *aMinZoom, double *aMaxZoom,
michael@0 309 uint32_t *aWidth, uint32_t *aHeight,
michael@0 310 bool *aAutoSize)
michael@0 311 {
michael@0 312 nsIDocument* doc = GetDocument();
michael@0 313 NS_ENSURE_STATE(doc);
michael@0 314
michael@0 315 nsViewportInfo info = nsContentUtils::GetViewportInfo(doc, ScreenIntSize(aDisplayWidth, aDisplayHeight));
michael@0 316 *aDefaultZoom = info.GetDefaultZoom().scale;
michael@0 317 *aAllowZoom = info.IsZoomAllowed();
michael@0 318 *aMinZoom = info.GetMinZoom().scale;
michael@0 319 *aMaxZoom = info.GetMaxZoom().scale;
michael@0 320 *aWidth = info.GetSize().width;
michael@0 321 *aHeight = info.GetSize().height;
michael@0 322 *aAutoSize = info.IsAutoSizeEnabled();
michael@0 323 return NS_OK;
michael@0 324 }
michael@0 325
michael@0 326 NS_IMETHODIMP
michael@0 327 nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
michael@0 328 float aWidthPx, float aHeightPx,
michael@0 329 nsIDOMElement* aElement,
michael@0 330 uint32_t aPriority)
michael@0 331 {
michael@0 332 if (!nsContentUtils::IsCallerChrome()) {
michael@0 333 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 334 }
michael@0 335
michael@0 336 nsIPresShell* presShell = GetPresShell();
michael@0 337 if (!presShell) {
michael@0 338 return NS_ERROR_FAILURE;
michael@0 339 }
michael@0 340
michael@0 341 if (!aElement) {
michael@0 342 return NS_ERROR_INVALID_ARG;
michael@0 343 }
michael@0 344
michael@0 345 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
michael@0 346
michael@0 347 if (!content) {
michael@0 348 return NS_ERROR_INVALID_ARG;
michael@0 349 }
michael@0 350
michael@0 351 if (content->GetCurrentDoc() != presShell->GetDocument()) {
michael@0 352 return NS_ERROR_INVALID_ARG;
michael@0 353 }
michael@0 354
michael@0 355 DisplayPortPropertyData* currentData =
michael@0 356 static_cast<DisplayPortPropertyData*>(content->GetProperty(nsGkAtoms::DisplayPort));
michael@0 357 if (currentData && currentData->mPriority > aPriority) {
michael@0 358 return NS_OK;
michael@0 359 }
michael@0 360
michael@0 361 nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
michael@0 362 nsPresContext::CSSPixelsToAppUnits(aYPx),
michael@0 363 nsPresContext::CSSPixelsToAppUnits(aWidthPx),
michael@0 364 nsPresContext::CSSPixelsToAppUnits(aHeightPx));
michael@0 365
michael@0 366 content->SetProperty(nsGkAtoms::DisplayPort,
michael@0 367 new DisplayPortPropertyData(displayport, aPriority),
michael@0 368 nsINode::DeleteProperty<DisplayPortPropertyData>);
michael@0 369
michael@0 370 nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
michael@0 371 if (rootScrollFrame && content == rootScrollFrame->GetContent()) {
michael@0 372 // We are setting a root displayport for a document.
michael@0 373 // The pres shell needs a special flag set.
michael@0 374 presShell->SetIgnoreViewportScrolling(true);
michael@0 375 }
michael@0 376
michael@0 377 nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
michael@0 378 if (rootFrame) {
michael@0 379 rootFrame->SchedulePaint();
michael@0 380
michael@0 381 // If we are hiding something that is a display root then send empty paint
michael@0 382 // transaction in order to release retained layers because it won't get
michael@0 383 // any more paint requests when it is hidden.
michael@0 384 if (displayport.IsEmpty() &&
michael@0 385 rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) {
michael@0 386 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 387 if (widget) {
michael@0 388 bool isRetainingManager;
michael@0 389 LayerManager* manager = widget->GetLayerManager(&isRetainingManager);
michael@0 390 if (isRetainingManager) {
michael@0 391 manager->BeginTransaction();
michael@0 392 nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(), NS_RGB(255, 255, 255),
michael@0 393 nsLayoutUtils::PAINT_WIDGET_LAYERS |
michael@0 394 nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
michael@0 395 }
michael@0 396 }
michael@0 397 }
michael@0 398 }
michael@0 399
michael@0 400 return NS_OK;
michael@0 401 }
michael@0 402
michael@0 403 NS_IMETHODIMP
michael@0 404 nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
michael@0 405 float aTopMargin,
michael@0 406 float aRightMargin,
michael@0 407 float aBottomMargin,
michael@0 408 uint32_t aAlignmentX,
michael@0 409 uint32_t aAlignmentY,
michael@0 410 nsIDOMElement* aElement,
michael@0 411 uint32_t aPriority)
michael@0 412 {
michael@0 413 if (!nsContentUtils::IsCallerChrome()) {
michael@0 414 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 415 }
michael@0 416
michael@0 417 nsIPresShell* presShell = GetPresShell();
michael@0 418 if (!presShell) {
michael@0 419 return NS_ERROR_FAILURE;
michael@0 420 }
michael@0 421
michael@0 422 if (!aElement) {
michael@0 423 return NS_ERROR_INVALID_ARG;
michael@0 424 }
michael@0 425
michael@0 426 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
michael@0 427
michael@0 428 if (!content) {
michael@0 429 return NS_ERROR_INVALID_ARG;
michael@0 430 }
michael@0 431
michael@0 432 if (content->GetCurrentDoc() != presShell->GetDocument()) {
michael@0 433 return NS_ERROR_INVALID_ARG;
michael@0 434 }
michael@0 435
michael@0 436 // Note order change of arguments between our function signature and
michael@0 437 // LayerMargin constructor.
michael@0 438 LayerMargin displayportMargins(aTopMargin,
michael@0 439 aRightMargin,
michael@0 440 aBottomMargin,
michael@0 441 aLeftMargin);
michael@0 442
michael@0 443 nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
michael@0 444 aAlignmentX, aAlignmentY, aPriority);
michael@0 445
michael@0 446 return NS_OK;
michael@0 447 }
michael@0 448
michael@0 449
michael@0 450 NS_IMETHODIMP
michael@0 451 nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX,
michael@0 452 int32_t aY,
michael@0 453 int32_t aWidth,
michael@0 454 int32_t aHeight,
michael@0 455 nsIDOMElement* aElement)
michael@0 456 {
michael@0 457 if (!nsContentUtils::IsCallerChrome()) {
michael@0 458 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 459 }
michael@0 460
michael@0 461 nsIPresShell* presShell = GetPresShell();
michael@0 462 if (!presShell) {
michael@0 463 return NS_ERROR_FAILURE;
michael@0 464 }
michael@0 465
michael@0 466 if (!aElement) {
michael@0 467 return NS_ERROR_INVALID_ARG;
michael@0 468 }
michael@0 469
michael@0 470 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
michael@0 471
michael@0 472 if (!content) {
michael@0 473 return NS_ERROR_INVALID_ARG;
michael@0 474 }
michael@0 475
michael@0 476 if (content->GetCurrentDoc() != presShell->GetDocument()) {
michael@0 477 return NS_ERROR_INVALID_ARG;
michael@0 478 }
michael@0 479
michael@0 480 nsLayoutUtils::SetDisplayPortBase(content, nsRect(aX, aY, aWidth, aHeight));
michael@0 481
michael@0 482 return NS_OK;
michael@0 483 }
michael@0 484
michael@0 485 NS_IMETHODIMP
michael@0 486 nsDOMWindowUtils::SetCriticalDisplayPortForElement(float aXPx, float aYPx,
michael@0 487 float aWidthPx, float aHeightPx,
michael@0 488 nsIDOMElement* aElement)
michael@0 489 {
michael@0 490 if (!nsContentUtils::IsCallerChrome()) {
michael@0 491 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 492 }
michael@0 493
michael@0 494 nsIPresShell* presShell = GetPresShell();
michael@0 495 if (!presShell) {
michael@0 496 return NS_ERROR_FAILURE;
michael@0 497 }
michael@0 498
michael@0 499 if (!aElement) {
michael@0 500 return NS_ERROR_INVALID_ARG;
michael@0 501 }
michael@0 502
michael@0 503 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
michael@0 504
michael@0 505 if (!content) {
michael@0 506 return NS_ERROR_INVALID_ARG;
michael@0 507 }
michael@0 508
michael@0 509 if (content->GetCurrentDoc() != presShell->GetDocument()) {
michael@0 510 return NS_ERROR_INVALID_ARG;
michael@0 511 }
michael@0 512
michael@0 513 nsRect displayport;
michael@0 514 if (!nsLayoutUtils::GetDisplayPort(content, &displayport)) {
michael@0 515 return NS_ERROR_INVALID_ARG;
michael@0 516 }
michael@0 517
michael@0 518 nsRect criticalDisplayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
michael@0 519 nsPresContext::CSSPixelsToAppUnits(aYPx),
michael@0 520 nsPresContext::CSSPixelsToAppUnits(aWidthPx),
michael@0 521 nsPresContext::CSSPixelsToAppUnits(aHeightPx));
michael@0 522 content->SetProperty(nsGkAtoms::CriticalDisplayPort, new nsRect(criticalDisplayport),
michael@0 523 nsINode::DeleteProperty<nsRect>);
michael@0 524
michael@0 525 nsIFrame* rootFrame = presShell->GetRootFrame();
michael@0 526 if (rootFrame) {
michael@0 527 rootFrame->InvalidateFrame();
michael@0 528 }
michael@0 529
michael@0 530 return NS_OK;
michael@0 531 }
michael@0 532
michael@0 533 NS_IMETHODIMP
michael@0 534 nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
michael@0 535 {
michael@0 536 if (!nsContentUtils::IsCallerChrome()) {
michael@0 537 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 538 }
michael@0 539
michael@0 540 nsIPresShell* presShell = GetPresShell();
michael@0 541 if (!presShell) {
michael@0 542 return NS_ERROR_FAILURE;
michael@0 543 }
michael@0 544
michael@0 545 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
michael@0 546 if (sf) {
michael@0 547 sf->SetResolution(gfxSize(aXResolution, aYResolution));
michael@0 548 presShell->SetResolution(aXResolution, aYResolution);
michael@0 549 }
michael@0 550
michael@0 551 return NS_OK;
michael@0 552 }
michael@0 553
michael@0 554 NS_IMETHODIMP
michael@0 555 nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
michael@0 556 {
michael@0 557 if (!nsContentUtils::IsCallerChrome()) {
michael@0 558 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 559 }
michael@0 560
michael@0 561 nsIPresShell* presShell = GetPresShell();
michael@0 562 if (!presShell) {
michael@0 563 return NS_ERROR_FAILURE;
michael@0 564 }
michael@0 565
michael@0 566 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
michael@0 567 if (sf) {
michael@0 568 const gfxSize& res = sf->GetResolution();
michael@0 569 *aXResolution = res.width;
michael@0 570 *aYResolution = res.height;
michael@0 571 } else {
michael@0 572 *aXResolution = presShell->GetXResolution();
michael@0 573 *aYResolution = presShell->GetYResolution();
michael@0 574 }
michael@0 575
michael@0 576 return NS_OK;
michael@0 577 }
michael@0 578
michael@0 579 NS_IMETHODIMP
michael@0 580 nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) {
michael@0 581 if (!nsContentUtils::IsCallerChrome()) {
michael@0 582 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 583 }
michael@0 584
michael@0 585 nsIPresShell* presShell = GetPresShell();
michael@0 586 if (!presShell) {
michael@0 587 return NS_ERROR_FAILURE;
michael@0 588 }
michael@0 589
michael@0 590 const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
michael@0 591 *aIsResolutionSet = sf && sf->IsResolutionSet();
michael@0 592
michael@0 593 return NS_OK;
michael@0 594 }
michael@0 595
michael@0 596 NS_IMETHODIMP
michael@0 597 nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
michael@0 598 {
michael@0 599 if (!nsContentUtils::IsCallerChrome()) {
michael@0 600 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 601 }
michael@0 602
michael@0 603 nsIPresShell* presShell = GetPresShell();
michael@0 604 if (presShell) {
michael@0 605 presShell->SetIsFirstPaint(aIsFirstPaint);
michael@0 606 return NS_OK;
michael@0 607 }
michael@0 608 return NS_ERROR_FAILURE;
michael@0 609 }
michael@0 610
michael@0 611 NS_IMETHODIMP
michael@0 612 nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint)
michael@0 613 {
michael@0 614 if (!nsContentUtils::IsCallerChrome()) {
michael@0 615 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 616 }
michael@0 617
michael@0 618 nsIPresShell* presShell = GetPresShell();
michael@0 619 if (presShell) {
michael@0 620 *aIsFirstPaint = presShell->GetIsFirstPaint();
michael@0 621 return NS_OK;
michael@0 622 }
michael@0 623 return NS_ERROR_FAILURE;
michael@0 624 }
michael@0 625
michael@0 626 NS_IMETHODIMP
michael@0 627 nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId)
michael@0 628 {
michael@0 629 if (!nsContentUtils::IsCallerChrome()) {
michael@0 630 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 631 }
michael@0 632
michael@0 633 nsIPresShell* presShell = GetPresShell();
michael@0 634 if (presShell) {
michael@0 635 *aPresShellId = presShell->GetPresShellId();
michael@0 636 return NS_OK;
michael@0 637 }
michael@0 638 return NS_ERROR_FAILURE;
michael@0 639 }
michael@0 640
michael@0 641 /* static */
michael@0 642 mozilla::Modifiers
michael@0 643 nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers)
michael@0 644 {
michael@0 645 Modifiers result = 0;
michael@0 646 if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) {
michael@0 647 result |= mozilla::MODIFIER_SHIFT;
michael@0 648 }
michael@0 649 if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) {
michael@0 650 result |= mozilla::MODIFIER_CONTROL;
michael@0 651 }
michael@0 652 if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) {
michael@0 653 result |= mozilla::MODIFIER_ALT;
michael@0 654 }
michael@0 655 if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) {
michael@0 656 result |= mozilla::MODIFIER_META;
michael@0 657 }
michael@0 658 if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) {
michael@0 659 result |= mozilla::MODIFIER_ALTGRAPH;
michael@0 660 }
michael@0 661 if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) {
michael@0 662 result |= mozilla::MODIFIER_CAPSLOCK;
michael@0 663 }
michael@0 664 if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) {
michael@0 665 result |= mozilla::MODIFIER_FN;
michael@0 666 }
michael@0 667 if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) {
michael@0 668 result |= mozilla::MODIFIER_NUMLOCK;
michael@0 669 }
michael@0 670 if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) {
michael@0 671 result |= mozilla::MODIFIER_SCROLLLOCK;
michael@0 672 }
michael@0 673 if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) {
michael@0 674 result |= mozilla::MODIFIER_SYMBOLLOCK;
michael@0 675 }
michael@0 676 if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) {
michael@0 677 result |= mozilla::MODIFIER_OS;
michael@0 678 }
michael@0 679 return result;
michael@0 680 }
michael@0 681
michael@0 682 NS_IMETHODIMP
michael@0 683 nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
michael@0 684 float aX,
michael@0 685 float aY,
michael@0 686 int32_t aButton,
michael@0 687 int32_t aClickCount,
michael@0 688 int32_t aModifiers,
michael@0 689 bool aIgnoreRootScrollFrame,
michael@0 690 float aPressure,
michael@0 691 unsigned short aInputSourceArg,
michael@0 692 bool aIsSynthesized,
michael@0 693 uint8_t aOptionalArgCount,
michael@0 694 bool *aPreventDefault)
michael@0 695 {
michael@0 696 return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
michael@0 697 aIgnoreRootScrollFrame, aPressure,
michael@0 698 aInputSourceArg, false, aPreventDefault,
michael@0 699 aOptionalArgCount >= 4 ? aIsSynthesized : true);
michael@0 700 }
michael@0 701
michael@0 702 NS_IMETHODIMP
michael@0 703 nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
michael@0 704 float aX,
michael@0 705 float aY,
michael@0 706 int32_t aButton,
michael@0 707 int32_t aClickCount,
michael@0 708 int32_t aModifiers,
michael@0 709 bool aIgnoreRootScrollFrame,
michael@0 710 float aPressure,
michael@0 711 unsigned short aInputSourceArg,
michael@0 712 bool aIsSynthesized,
michael@0 713 uint8_t aOptionalArgCount)
michael@0 714 {
michael@0 715 PROFILER_LABEL("nsDOMWindowUtils", "SendMouseEventToWindow");
michael@0 716 return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
michael@0 717 aIgnoreRootScrollFrame, aPressure,
michael@0 718 aInputSourceArg, true, nullptr,
michael@0 719 aOptionalArgCount >= 4 ? aIsSynthesized : true);
michael@0 720 }
michael@0 721
michael@0 722 static LayoutDeviceIntPoint
michael@0 723 ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset,
michael@0 724 nsPresContext* aPresContext)
michael@0 725 {
michael@0 726 return LayoutDeviceIntPoint::FromAppUnitsRounded(
michael@0 727 CSSPoint::ToAppUnits(aPoint) + aOffset,
michael@0 728 aPresContext->AppUnitsPerDevPixel());
michael@0 729 }
michael@0 730
michael@0 731 static inline int16_t
michael@0 732 GetButtonsFlagForButton(int32_t aButton)
michael@0 733 {
michael@0 734 switch (aButton) {
michael@0 735 case WidgetMouseEvent::eLeftButton:
michael@0 736 return WidgetMouseEvent::eLeftButtonFlag;
michael@0 737 case WidgetMouseEvent::eMiddleButton:
michael@0 738 return WidgetMouseEvent::eMiddleButtonFlag;
michael@0 739 case WidgetMouseEvent::eRightButton:
michael@0 740 return WidgetMouseEvent::eRightButtonFlag;
michael@0 741 case 4:
michael@0 742 return WidgetMouseEvent::e4thButtonFlag;
michael@0 743 case 5:
michael@0 744 return WidgetMouseEvent::e5thButtonFlag;
michael@0 745 default:
michael@0 746 NS_ERROR("Button not known.");
michael@0 747 return 0;
michael@0 748 }
michael@0 749 }
michael@0 750
michael@0 751 NS_IMETHODIMP
michael@0 752 nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
michael@0 753 float aX,
michael@0 754 float aY,
michael@0 755 int32_t aButton,
michael@0 756 int32_t aClickCount,
michael@0 757 int32_t aModifiers,
michael@0 758 bool aIgnoreRootScrollFrame,
michael@0 759 float aPressure,
michael@0 760 unsigned short aInputSourceArg,
michael@0 761 bool aToWindow,
michael@0 762 bool *aPreventDefault,
michael@0 763 bool aIsSynthesized)
michael@0 764 {
michael@0 765 if (!nsContentUtils::IsCallerChrome()) {
michael@0 766 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 767 }
michael@0 768
michael@0 769 // get the widget to send the event to
michael@0 770 nsPoint offset;
michael@0 771 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
michael@0 772 if (!widget)
michael@0 773 return NS_ERROR_FAILURE;
michael@0 774
michael@0 775 int32_t msg;
michael@0 776 bool contextMenuKey = false;
michael@0 777 if (aType.EqualsLiteral("mousedown"))
michael@0 778 msg = NS_MOUSE_BUTTON_DOWN;
michael@0 779 else if (aType.EqualsLiteral("mouseup"))
michael@0 780 msg = NS_MOUSE_BUTTON_UP;
michael@0 781 else if (aType.EqualsLiteral("mousemove"))
michael@0 782 msg = NS_MOUSE_MOVE;
michael@0 783 else if (aType.EqualsLiteral("mouseover"))
michael@0 784 msg = NS_MOUSE_ENTER;
michael@0 785 else if (aType.EqualsLiteral("mouseout"))
michael@0 786 msg = NS_MOUSE_EXIT;
michael@0 787 else if (aType.EqualsLiteral("contextmenu")) {
michael@0 788 msg = NS_CONTEXTMENU;
michael@0 789 contextMenuKey = (aButton == 0);
michael@0 790 } else if (aType.EqualsLiteral("MozMouseHittest"))
michael@0 791 msg = NS_MOUSE_MOZHITTEST;
michael@0 792 else
michael@0 793 return NS_ERROR_FAILURE;
michael@0 794
michael@0 795 if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
michael@0 796 aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
michael@0 797 }
michael@0 798
michael@0 799 WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal,
michael@0 800 contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
michael@0 801 WidgetMouseEvent::eNormal);
michael@0 802 event.modifiers = GetWidgetModifiers(aModifiers);
michael@0 803 event.button = aButton;
michael@0 804 event.buttons = GetButtonsFlagForButton(aButton);
michael@0 805 event.widget = widget;
michael@0 806 event.pressure = aPressure;
michael@0 807 event.inputSource = aInputSourceArg;
michael@0 808 event.clickCount = aClickCount;
michael@0 809 event.time = PR_IntervalNow();
michael@0 810 event.mFlags.mIsSynthesizedForTests = aIsSynthesized;
michael@0 811
michael@0 812 nsPresContext* presContext = GetPresContext();
michael@0 813 if (!presContext)
michael@0 814 return NS_ERROR_FAILURE;
michael@0 815
michael@0 816 event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
michael@0 817 event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
michael@0 818
michael@0 819 nsEventStatus status;
michael@0 820 if (aToWindow) {
michael@0 821 nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
michael@0 822 if (!presShell)
michael@0 823 return NS_ERROR_FAILURE;
michael@0 824 nsViewManager* viewManager = presShell->GetViewManager();
michael@0 825 if (!viewManager)
michael@0 826 return NS_ERROR_FAILURE;
michael@0 827 nsView* view = viewManager->GetRootView();
michael@0 828 if (!view)
michael@0 829 return NS_ERROR_FAILURE;
michael@0 830
michael@0 831 status = nsEventStatus_eIgnore;
michael@0 832 return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
michael@0 833 }
michael@0 834 nsresult rv = widget->DispatchEvent(&event, status);
michael@0 835 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
michael@0 836
michael@0 837 return rv;
michael@0 838 }
michael@0 839
michael@0 840 NS_IMETHODIMP
michael@0 841 nsDOMWindowUtils::SendPointerEvent(const nsAString& aType,
michael@0 842 float aX,
michael@0 843 float aY,
michael@0 844 int32_t aButton,
michael@0 845 int32_t aClickCount,
michael@0 846 int32_t aModifiers,
michael@0 847 bool aIgnoreRootScrollFrame,
michael@0 848 float aPressure,
michael@0 849 unsigned short aInputSourceArg,
michael@0 850 int32_t aPointerId,
michael@0 851 int32_t aWidth,
michael@0 852 int32_t aHeight,
michael@0 853 int32_t tiltX,
michael@0 854 int32_t tiltY,
michael@0 855 bool aIsPrimary,
michael@0 856 bool aIsSynthesized,
michael@0 857 uint8_t aOptionalArgCount,
michael@0 858 bool* aPreventDefault)
michael@0 859 {
michael@0 860 if (!nsContentUtils::IsCallerChrome()) {
michael@0 861 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 862 }
michael@0 863
michael@0 864 // get the widget to send the event to
michael@0 865 nsPoint offset;
michael@0 866 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
michael@0 867 if (!widget) {
michael@0 868 return NS_ERROR_FAILURE;
michael@0 869 }
michael@0 870
michael@0 871 int32_t msg;
michael@0 872 if (aType.EqualsLiteral("pointerdown")) {
michael@0 873 msg = NS_POINTER_DOWN;
michael@0 874 } else if (aType.EqualsLiteral("pointerup")) {
michael@0 875 msg = NS_POINTER_UP;
michael@0 876 } else if (aType.EqualsLiteral("pointermove")) {
michael@0 877 msg = NS_POINTER_MOVE;
michael@0 878 } else if (aType.EqualsLiteral("pointerover")) {
michael@0 879 msg = NS_POINTER_OVER;
michael@0 880 } else if (aType.EqualsLiteral("pointerout")) {
michael@0 881 msg = NS_POINTER_OUT;
michael@0 882 } else {
michael@0 883 return NS_ERROR_FAILURE;
michael@0 884 }
michael@0 885
michael@0 886 if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
michael@0 887 aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
michael@0 888 }
michael@0 889
michael@0 890 WidgetPointerEvent event(true, msg, widget);
michael@0 891 event.modifiers = GetWidgetModifiers(aModifiers);
michael@0 892 event.button = aButton;
michael@0 893 event.buttons = GetButtonsFlagForButton(aButton);
michael@0 894 event.widget = widget;
michael@0 895 event.pressure = aPressure;
michael@0 896 event.inputSource = aInputSourceArg;
michael@0 897 event.pointerId = aPointerId;
michael@0 898 event.width = aWidth;
michael@0 899 event.height = aHeight;
michael@0 900 event.tiltX = tiltX;
michael@0 901 event.tiltY = tiltY;
michael@0 902 event.isPrimary = aIsPrimary;
michael@0 903 event.clickCount = aClickCount;
michael@0 904 event.time = PR_IntervalNow();
michael@0 905 event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
michael@0 906
michael@0 907 nsPresContext* presContext = GetPresContext();
michael@0 908 if (!presContext) {
michael@0 909 return NS_ERROR_FAILURE;
michael@0 910 }
michael@0 911
michael@0 912 event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
michael@0 913 event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
michael@0 914
michael@0 915 nsEventStatus status;
michael@0 916 nsresult rv = widget->DispatchEvent(&event, status);
michael@0 917 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
michael@0 918
michael@0 919 return rv;
michael@0 920 }
michael@0 921
michael@0 922 NS_IMETHODIMP
michael@0 923 nsDOMWindowUtils::SendWheelEvent(float aX,
michael@0 924 float aY,
michael@0 925 double aDeltaX,
michael@0 926 double aDeltaY,
michael@0 927 double aDeltaZ,
michael@0 928 uint32_t aDeltaMode,
michael@0 929 int32_t aModifiers,
michael@0 930 int32_t aLineOrPageDeltaX,
michael@0 931 int32_t aLineOrPageDeltaY,
michael@0 932 uint32_t aOptions)
michael@0 933 {
michael@0 934 if (!nsContentUtils::IsCallerChrome()) {
michael@0 935 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 936 }
michael@0 937
michael@0 938 // get the widget to send the event to
michael@0 939 nsPoint offset;
michael@0 940 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
michael@0 941 if (!widget) {
michael@0 942 return NS_ERROR_NULL_POINTER;
michael@0 943 }
michael@0 944
michael@0 945 WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
michael@0 946 wheelEvent.modifiers = GetWidgetModifiers(aModifiers);
michael@0 947 wheelEvent.deltaX = aDeltaX;
michael@0 948 wheelEvent.deltaY = aDeltaY;
michael@0 949 wheelEvent.deltaZ = aDeltaZ;
michael@0 950 wheelEvent.deltaMode = aDeltaMode;
michael@0 951 wheelEvent.isMomentum =
michael@0 952 (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
michael@0 953 wheelEvent.isPixelOnlyDevice =
michael@0 954 (aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0;
michael@0 955 NS_ENSURE_TRUE(
michael@0 956 !wheelEvent.isPixelOnlyDevice ||
michael@0 957 aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL,
michael@0 958 NS_ERROR_INVALID_ARG);
michael@0 959 wheelEvent.customizedByUserPrefs =
michael@0 960 (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
michael@0 961 wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;
michael@0 962 wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY;
michael@0 963 wheelEvent.widget = widget;
michael@0 964
michael@0 965 wheelEvent.time = PR_Now() / 1000;
michael@0 966
michael@0 967 nsPresContext* presContext = GetPresContext();
michael@0 968 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
michael@0 969
michael@0 970 wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
michael@0 971
michael@0 972 nsEventStatus status;
michael@0 973 nsresult rv = widget->DispatchEvent(&wheelEvent, status);
michael@0 974 NS_ENSURE_SUCCESS(rv, rv);
michael@0 975
michael@0 976 bool failedX = false;
michael@0 977 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) &&
michael@0 978 wheelEvent.overflowDeltaX != 0) {
michael@0 979 failedX = true;
michael@0 980 }
michael@0 981 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) &&
michael@0 982 wheelEvent.overflowDeltaX <= 0) {
michael@0 983 failedX = true;
michael@0 984 }
michael@0 985 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) &&
michael@0 986 wheelEvent.overflowDeltaX >= 0) {
michael@0 987 failedX = true;
michael@0 988 }
michael@0 989 bool failedY = false;
michael@0 990 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) &&
michael@0 991 wheelEvent.overflowDeltaY != 0) {
michael@0 992 failedY = true;
michael@0 993 }
michael@0 994 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) &&
michael@0 995 wheelEvent.overflowDeltaY <= 0) {
michael@0 996 failedY = true;
michael@0 997 }
michael@0 998 if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) &&
michael@0 999 wheelEvent.overflowDeltaY >= 0) {
michael@0 1000 failedY = true;
michael@0 1001 }
michael@0 1002
michael@0 1003 #ifdef DEBUG
michael@0 1004 if (failedX) {
michael@0 1005 nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaX: %f",
michael@0 1006 wheelEvent.overflowDeltaX);
michael@0 1007 NS_WARNING(debugMsg.get());
michael@0 1008 }
michael@0 1009 if (failedY) {
michael@0 1010 nsPrintfCString debugMsg("SendWheelEvent(): unexpected overflowDeltaY: %f",
michael@0 1011 wheelEvent.overflowDeltaY);
michael@0 1012 NS_WARNING(debugMsg.get());
michael@0 1013 }
michael@0 1014 #endif
michael@0 1015
michael@0 1016 return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE;
michael@0 1017 }
michael@0 1018
michael@0 1019 NS_IMETHODIMP
michael@0 1020 nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
michael@0 1021 uint32_t *aIdentifiers,
michael@0 1022 int32_t *aXs,
michael@0 1023 int32_t *aYs,
michael@0 1024 uint32_t *aRxs,
michael@0 1025 uint32_t *aRys,
michael@0 1026 float *aRotationAngles,
michael@0 1027 float *aForces,
michael@0 1028 uint32_t aCount,
michael@0 1029 int32_t aModifiers,
michael@0 1030 bool aIgnoreRootScrollFrame,
michael@0 1031 bool *aPreventDefault)
michael@0 1032 {
michael@0 1033 return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
michael@0 1034 aRotationAngles, aForces, aCount, aModifiers,
michael@0 1035 aIgnoreRootScrollFrame, false, aPreventDefault);
michael@0 1036 }
michael@0 1037
michael@0 1038 NS_IMETHODIMP
michael@0 1039 nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType,
michael@0 1040 uint32_t* aIdentifiers,
michael@0 1041 int32_t* aXs,
michael@0 1042 int32_t* aYs,
michael@0 1043 uint32_t* aRxs,
michael@0 1044 uint32_t* aRys,
michael@0 1045 float* aRotationAngles,
michael@0 1046 float* aForces,
michael@0 1047 uint32_t aCount,
michael@0 1048 int32_t aModifiers,
michael@0 1049 bool aIgnoreRootScrollFrame,
michael@0 1050 bool* aPreventDefault)
michael@0 1051 {
michael@0 1052 return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys,
michael@0 1053 aRotationAngles, aForces, aCount, aModifiers,
michael@0 1054 aIgnoreRootScrollFrame, true, aPreventDefault);
michael@0 1055 }
michael@0 1056
michael@0 1057 NS_IMETHODIMP
michael@0 1058 nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType,
michael@0 1059 uint32_t* aIdentifiers,
michael@0 1060 int32_t* aXs,
michael@0 1061 int32_t* aYs,
michael@0 1062 uint32_t* aRxs,
michael@0 1063 uint32_t* aRys,
michael@0 1064 float* aRotationAngles,
michael@0 1065 float* aForces,
michael@0 1066 uint32_t aCount,
michael@0 1067 int32_t aModifiers,
michael@0 1068 bool aIgnoreRootScrollFrame,
michael@0 1069 bool aToWindow,
michael@0 1070 bool* aPreventDefault)
michael@0 1071 {
michael@0 1072 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1073 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1074 }
michael@0 1075
michael@0 1076 // get the widget to send the event to
michael@0 1077 nsPoint offset;
michael@0 1078 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
michael@0 1079 if (!widget) {
michael@0 1080 return NS_ERROR_NULL_POINTER;
michael@0 1081 }
michael@0 1082 int32_t msg;
michael@0 1083 if (aType.EqualsLiteral("touchstart")) {
michael@0 1084 msg = NS_TOUCH_START;
michael@0 1085 } else if (aType.EqualsLiteral("touchmove")) {
michael@0 1086 msg = NS_TOUCH_MOVE;
michael@0 1087 } else if (aType.EqualsLiteral("touchend")) {
michael@0 1088 msg = NS_TOUCH_END;
michael@0 1089 } else if (aType.EqualsLiteral("touchcancel")) {
michael@0 1090 msg = NS_TOUCH_CANCEL;
michael@0 1091 } else {
michael@0 1092 return NS_ERROR_UNEXPECTED;
michael@0 1093 }
michael@0 1094 WidgetTouchEvent event(true, msg, widget);
michael@0 1095 event.modifiers = GetWidgetModifiers(aModifiers);
michael@0 1096 event.widget = widget;
michael@0 1097 event.time = PR_Now();
michael@0 1098
michael@0 1099 nsPresContext* presContext = GetPresContext();
michael@0 1100 if (!presContext) {
michael@0 1101 return NS_ERROR_FAILURE;
michael@0 1102 }
michael@0 1103 event.touches.SetCapacity(aCount);
michael@0 1104 for (uint32_t i = 0; i < aCount; ++i) {
michael@0 1105 LayoutDeviceIntPoint pt =
michael@0 1106 ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
michael@0 1107 nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
michael@0 1108 LayoutDeviceIntPoint::ToUntyped(pt),
michael@0 1109 nsIntPoint(aRxs[i], aRys[i]),
michael@0 1110 aRotationAngles[i],
michael@0 1111 aForces[i]);
michael@0 1112 event.touches.AppendElement(t);
michael@0 1113 }
michael@0 1114
michael@0 1115 nsEventStatus status;
michael@0 1116 if (aToWindow) {
michael@0 1117 nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
michael@0 1118 if (!presShell) {
michael@0 1119 return NS_ERROR_FAILURE;
michael@0 1120 }
michael@0 1121
michael@0 1122 nsViewManager* viewManager = presShell->GetViewManager();
michael@0 1123 if (!viewManager) {
michael@0 1124 return NS_ERROR_FAILURE;
michael@0 1125 }
michael@0 1126
michael@0 1127 nsView* view = viewManager->GetRootView();
michael@0 1128 if (!view) {
michael@0 1129 return NS_ERROR_FAILURE;
michael@0 1130 }
michael@0 1131
michael@0 1132 status = nsEventStatus_eIgnore;
michael@0 1133 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
michael@0 1134 return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
michael@0 1135 }
michael@0 1136
michael@0 1137 nsresult rv = widget->DispatchEvent(&event, status);
michael@0 1138 *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
michael@0 1139 return rv;
michael@0 1140 }
michael@0 1141
michael@0 1142 NS_IMETHODIMP
michael@0 1143 nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
michael@0 1144 int32_t aKeyCode,
michael@0 1145 int32_t aCharCode,
michael@0 1146 int32_t aModifiers,
michael@0 1147 uint32_t aAdditionalFlags,
michael@0 1148 bool* aDefaultActionTaken)
michael@0 1149 {
michael@0 1150 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1151 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1152 }
michael@0 1153
michael@0 1154 // get the widget to send the event to
michael@0 1155 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1156 if (!widget)
michael@0 1157 return NS_ERROR_FAILURE;
michael@0 1158
michael@0 1159 int32_t msg;
michael@0 1160 if (aType.EqualsLiteral("keydown"))
michael@0 1161 msg = NS_KEY_DOWN;
michael@0 1162 else if (aType.EqualsLiteral("keyup"))
michael@0 1163 msg = NS_KEY_UP;
michael@0 1164 else if (aType.EqualsLiteral("keypress"))
michael@0 1165 msg = NS_KEY_PRESS;
michael@0 1166 else
michael@0 1167 return NS_ERROR_FAILURE;
michael@0 1168
michael@0 1169 WidgetKeyboardEvent event(true, msg, widget);
michael@0 1170 event.modifiers = GetWidgetModifiers(aModifiers);
michael@0 1171
michael@0 1172 if (msg == NS_KEY_PRESS) {
michael@0 1173 event.keyCode = aCharCode ? 0 : aKeyCode;
michael@0 1174 event.charCode = aCharCode;
michael@0 1175 } else {
michael@0 1176 event.keyCode = aKeyCode;
michael@0 1177 event.charCode = 0;
michael@0 1178 }
michael@0 1179
michael@0 1180 uint32_t locationFlag = (aAdditionalFlags &
michael@0 1181 (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT |
michael@0 1182 KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD |
michael@0 1183 KEY_FLAG_LOCATION_MOBILE | KEY_FLAG_LOCATION_JOYSTICK));
michael@0 1184 switch (locationFlag) {
michael@0 1185 case KEY_FLAG_LOCATION_STANDARD:
michael@0 1186 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
michael@0 1187 break;
michael@0 1188 case KEY_FLAG_LOCATION_LEFT:
michael@0 1189 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
michael@0 1190 break;
michael@0 1191 case KEY_FLAG_LOCATION_RIGHT:
michael@0 1192 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
michael@0 1193 break;
michael@0 1194 case KEY_FLAG_LOCATION_NUMPAD:
michael@0 1195 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
michael@0 1196 break;
michael@0 1197 case KEY_FLAG_LOCATION_MOBILE:
michael@0 1198 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_MOBILE;
michael@0 1199 break;
michael@0 1200 case KEY_FLAG_LOCATION_JOYSTICK:
michael@0 1201 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_JOYSTICK;
michael@0 1202 break;
michael@0 1203 default:
michael@0 1204 if (locationFlag != 0) {
michael@0 1205 return NS_ERROR_INVALID_ARG;
michael@0 1206 }
michael@0 1207 // If location flag isn't set, choose the location from keycode.
michael@0 1208 switch (aKeyCode) {
michael@0 1209 case nsIDOMKeyEvent::DOM_VK_NUMPAD0:
michael@0 1210 case nsIDOMKeyEvent::DOM_VK_NUMPAD1:
michael@0 1211 case nsIDOMKeyEvent::DOM_VK_NUMPAD2:
michael@0 1212 case nsIDOMKeyEvent::DOM_VK_NUMPAD3:
michael@0 1213 case nsIDOMKeyEvent::DOM_VK_NUMPAD4:
michael@0 1214 case nsIDOMKeyEvent::DOM_VK_NUMPAD5:
michael@0 1215 case nsIDOMKeyEvent::DOM_VK_NUMPAD6:
michael@0 1216 case nsIDOMKeyEvent::DOM_VK_NUMPAD7:
michael@0 1217 case nsIDOMKeyEvent::DOM_VK_NUMPAD8:
michael@0 1218 case nsIDOMKeyEvent::DOM_VK_NUMPAD9:
michael@0 1219 case nsIDOMKeyEvent::DOM_VK_MULTIPLY:
michael@0 1220 case nsIDOMKeyEvent::DOM_VK_ADD:
michael@0 1221 case nsIDOMKeyEvent::DOM_VK_SEPARATOR:
michael@0 1222 case nsIDOMKeyEvent::DOM_VK_SUBTRACT:
michael@0 1223 case nsIDOMKeyEvent::DOM_VK_DECIMAL:
michael@0 1224 case nsIDOMKeyEvent::DOM_VK_DIVIDE:
michael@0 1225 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
michael@0 1226 break;
michael@0 1227 case nsIDOMKeyEvent::DOM_VK_SHIFT:
michael@0 1228 case nsIDOMKeyEvent::DOM_VK_CONTROL:
michael@0 1229 case nsIDOMKeyEvent::DOM_VK_ALT:
michael@0 1230 case nsIDOMKeyEvent::DOM_VK_META:
michael@0 1231 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
michael@0 1232 break;
michael@0 1233 default:
michael@0 1234 event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
michael@0 1235 break;
michael@0 1236 }
michael@0 1237 break;
michael@0 1238 }
michael@0 1239
michael@0 1240 event.refPoint.x = event.refPoint.y = 0;
michael@0 1241 event.time = PR_IntervalNow();
michael@0 1242 event.mFlags.mIsSynthesizedForTests = true;
michael@0 1243
michael@0 1244 if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) {
michael@0 1245 event.mFlags.mDefaultPrevented = true;
michael@0 1246 }
michael@0 1247
michael@0 1248 nsEventStatus status;
michael@0 1249 nsresult rv = widget->DispatchEvent(&event, status);
michael@0 1250 NS_ENSURE_SUCCESS(rv, rv);
michael@0 1251
michael@0 1252 *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
michael@0 1253
michael@0 1254 return NS_OK;
michael@0 1255 }
michael@0 1256
michael@0 1257 NS_IMETHODIMP
michael@0 1258 nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout,
michael@0 1259 int32_t aNativeKeyCode,
michael@0 1260 int32_t aModifiers,
michael@0 1261 const nsAString& aCharacters,
michael@0 1262 const nsAString& aUnmodifiedCharacters)
michael@0 1263 {
michael@0 1264 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1265 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1266 }
michael@0 1267
michael@0 1268 // get the widget to send the event to
michael@0 1269 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1270 if (!widget)
michael@0 1271 return NS_ERROR_FAILURE;
michael@0 1272
michael@0 1273 return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
michael@0 1274 aModifiers, aCharacters, aUnmodifiedCharacters);
michael@0 1275 }
michael@0 1276
michael@0 1277 NS_IMETHODIMP
michael@0 1278 nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX,
michael@0 1279 int32_t aScreenY,
michael@0 1280 int32_t aNativeMessage,
michael@0 1281 int32_t aModifierFlags,
michael@0 1282 nsIDOMElement* aElement)
michael@0 1283 {
michael@0 1284 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1285 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1286 }
michael@0 1287
michael@0 1288 // get the widget to send the event to
michael@0 1289 nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
michael@0 1290 if (!widget)
michael@0 1291 return NS_ERROR_FAILURE;
michael@0 1292
michael@0 1293 return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY),
michael@0 1294 aNativeMessage, aModifierFlags);
michael@0 1295 }
michael@0 1296
michael@0 1297 NS_IMETHODIMP
michael@0 1298 nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX,
michael@0 1299 int32_t aScreenY,
michael@0 1300 uint32_t aNativeMessage,
michael@0 1301 double aDeltaX,
michael@0 1302 double aDeltaY,
michael@0 1303 double aDeltaZ,
michael@0 1304 uint32_t aModifierFlags,
michael@0 1305 uint32_t aAdditionalFlags,
michael@0 1306 nsIDOMElement* aElement)
michael@0 1307 {
michael@0 1308 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1309 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1310 }
michael@0 1311
michael@0 1312 // get the widget to send the event to
michael@0 1313 nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
michael@0 1314 if (!widget) {
michael@0 1315 return NS_ERROR_FAILURE;
michael@0 1316 }
michael@0 1317
michael@0 1318 return widget->SynthesizeNativeMouseScrollEvent(nsIntPoint(aScreenX,
michael@0 1319 aScreenY),
michael@0 1320 aNativeMessage,
michael@0 1321 aDeltaX, aDeltaY, aDeltaZ,
michael@0 1322 aModifierFlags,
michael@0 1323 aAdditionalFlags);
michael@0 1324 }
michael@0 1325
michael@0 1326 NS_IMETHODIMP
michael@0 1327 nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId,
michael@0 1328 uint32_t aTouchState,
michael@0 1329 int32_t aScreenX,
michael@0 1330 int32_t aScreenY,
michael@0 1331 double aPressure,
michael@0 1332 uint32_t aOrientation)
michael@0 1333 {
michael@0 1334 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1335 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1336 }
michael@0 1337
michael@0 1338 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1339 if (!widget) {
michael@0 1340 return NS_ERROR_FAILURE;
michael@0 1341 }
michael@0 1342
michael@0 1343 if (aPressure < 0 || aPressure > 1 || aOrientation > 359) {
michael@0 1344 return NS_ERROR_INVALID_ARG;
michael@0 1345 }
michael@0 1346
michael@0 1347 return widget->SynthesizeNativeTouchPoint(aPointerId,
michael@0 1348 (nsIWidget::TouchPointerState)aTouchState,
michael@0 1349 nsIntPoint(aScreenX, aScreenY),
michael@0 1350 aPressure, aOrientation);
michael@0 1351 }
michael@0 1352
michael@0 1353 NS_IMETHODIMP
michael@0 1354 nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX,
michael@0 1355 int32_t aScreenY,
michael@0 1356 bool aLongTap)
michael@0 1357 {
michael@0 1358 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1359 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1360 }
michael@0 1361
michael@0 1362 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1363 if (!widget) {
michael@0 1364 return NS_ERROR_FAILURE;
michael@0 1365 }
michael@0 1366 return widget->SynthesizeNativeTouchTap(nsIntPoint(aScreenX, aScreenY), aLongTap);
michael@0 1367 }
michael@0 1368
michael@0 1369 NS_IMETHODIMP
michael@0 1370 nsDOMWindowUtils::ClearNativeTouchSequence()
michael@0 1371 {
michael@0 1372 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1373 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1374 }
michael@0 1375
michael@0 1376 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1377 if (!widget) {
michael@0 1378 return NS_ERROR_FAILURE;
michael@0 1379 }
michael@0 1380 return widget->ClearNativeTouchSequence();
michael@0 1381 }
michael@0 1382
michael@0 1383 NS_IMETHODIMP
michael@0 1384 nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
michael@0 1385 {
michael@0 1386 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1387 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1388 }
michael@0 1389
michael@0 1390 // get the widget to send the event to
michael@0 1391 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1392 if (!widget)
michael@0 1393 return NS_ERROR_FAILURE;
michael@0 1394
michael@0 1395 return widget->ActivateNativeMenuItemAt(indexString);
michael@0 1396 }
michael@0 1397
michael@0 1398 NS_IMETHODIMP
michael@0 1399 nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
michael@0 1400 {
michael@0 1401 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1402 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1403 }
michael@0 1404
michael@0 1405 // get the widget to send the event to
michael@0 1406 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 1407 if (!widget)
michael@0 1408 return NS_ERROR_FAILURE;
michael@0 1409
michael@0 1410 return widget->ForceUpdateNativeMenuAt(indexString);
michael@0 1411 }
michael@0 1412
michael@0 1413 nsIWidget*
michael@0 1414 nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
michael@0 1415 {
michael@0 1416 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 1417 if (window) {
michael@0 1418 nsIDocShell *docShell = window->GetDocShell();
michael@0 1419 if (docShell) {
michael@0 1420 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
michael@0 1421 if (presShell) {
michael@0 1422 nsIFrame* frame = presShell->GetRootFrame();
michael@0 1423 if (frame)
michael@0 1424 return frame->GetView()->GetNearestWidget(aOffset);
michael@0 1425 }
michael@0 1426 }
michael@0 1427 }
michael@0 1428
michael@0 1429 return nullptr;
michael@0 1430 }
michael@0 1431
michael@0 1432 nsIWidget*
michael@0 1433 nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
michael@0 1434 {
michael@0 1435 if (!aElement)
michael@0 1436 return GetWidget();
michael@0 1437
michael@0 1438 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
michael@0 1439 nsIDocument* doc = content->GetCurrentDoc();
michael@0 1440 nsIPresShell* presShell = doc ? doc->GetShell() : nullptr;
michael@0 1441
michael@0 1442 if (presShell) {
michael@0 1443 nsIFrame* frame = content->GetPrimaryFrame();
michael@0 1444 if (!frame) {
michael@0 1445 frame = presShell->GetRootFrame();
michael@0 1446 }
michael@0 1447 if (frame)
michael@0 1448 return frame->GetNearestWidget();
michael@0 1449 }
michael@0 1450
michael@0 1451 return nullptr;
michael@0 1452 }
michael@0 1453
michael@0 1454 NS_IMETHODIMP
michael@0 1455 nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
michael@0 1456 {
michael@0 1457 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1458 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1459 }
michael@0 1460
michael@0 1461 nsCOMPtr<nsIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 1462 nsIFocusManager* fm = nsFocusManager::GetFocusManager();
michael@0 1463 if (fm) {
michael@0 1464 if (aElement)
michael@0 1465 fm->SetFocus(aElement, 0);
michael@0 1466 else
michael@0 1467 fm->ClearFocus(window);
michael@0 1468 }
michael@0 1469
michael@0 1470 return NS_OK;
michael@0 1471 }
michael@0 1472
michael@0 1473 NS_IMETHODIMP
michael@0 1474 nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
michael@0 1475 int32_t aExtraForgetSkippableCalls)
michael@0 1476 {
michael@0 1477 PROFILER_LABEL("GC", "GarbageCollect");
michael@0 1478 // Always permit this in debug builds.
michael@0 1479 #ifndef DEBUG
michael@0 1480 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1481 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1482 }
michael@0 1483 #endif
michael@0 1484
michael@0 1485 nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS);
michael@0 1486 nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
michael@0 1487
michael@0 1488 return NS_OK;
michael@0 1489 }
michael@0 1490
michael@0 1491 NS_IMETHODIMP
michael@0 1492 nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener,
michael@0 1493 int32_t aExtraForgetSkippableCalls)
michael@0 1494 {
michael@0 1495 // Always permit this in debug builds.
michael@0 1496 #ifndef DEBUG
michael@0 1497 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1498 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1499 }
michael@0 1500 #endif
michael@0 1501
michael@0 1502 nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
michael@0 1503 return NS_OK;
michael@0 1504 }
michael@0 1505
michael@0 1506 NS_IMETHODIMP
michael@0 1507 nsDOMWindowUtils::RunNextCollectorTimer()
michael@0 1508 {
michael@0 1509 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1510 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1511 }
michael@0 1512
michael@0 1513 nsJSContext::RunNextCollectorTimer();
michael@0 1514
michael@0 1515 return NS_OK;
michael@0 1516 }
michael@0 1517
michael@0 1518 NS_IMETHODIMP
michael@0 1519 nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
michael@0 1520 float aX,
michael@0 1521 float aY,
michael@0 1522 uint32_t aDirection,
michael@0 1523 double aDelta,
michael@0 1524 int32_t aModifiers,
michael@0 1525 uint32_t aClickCount)
michael@0 1526 {
michael@0 1527 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1528 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1529 }
michael@0 1530
michael@0 1531 // get the widget to send the event to
michael@0 1532 nsPoint offset;
michael@0 1533 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
michael@0 1534 if (!widget)
michael@0 1535 return NS_ERROR_FAILURE;
michael@0 1536
michael@0 1537 int32_t msg;
michael@0 1538 if (aType.EqualsLiteral("MozSwipeGestureStart"))
michael@0 1539 msg = NS_SIMPLE_GESTURE_SWIPE_START;
michael@0 1540 else if (aType.EqualsLiteral("MozSwipeGestureUpdate"))
michael@0 1541 msg = NS_SIMPLE_GESTURE_SWIPE_UPDATE;
michael@0 1542 else if (aType.EqualsLiteral("MozSwipeGestureEnd"))
michael@0 1543 msg = NS_SIMPLE_GESTURE_SWIPE_END;
michael@0 1544 else if (aType.EqualsLiteral("MozSwipeGesture"))
michael@0 1545 msg = NS_SIMPLE_GESTURE_SWIPE;
michael@0 1546 else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
michael@0 1547 msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
michael@0 1548 else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
michael@0 1549 msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
michael@0 1550 else if (aType.EqualsLiteral("MozMagnifyGesture"))
michael@0 1551 msg = NS_SIMPLE_GESTURE_MAGNIFY;
michael@0 1552 else if (aType.EqualsLiteral("MozRotateGestureStart"))
michael@0 1553 msg = NS_SIMPLE_GESTURE_ROTATE_START;
michael@0 1554 else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
michael@0 1555 msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
michael@0 1556 else if (aType.EqualsLiteral("MozRotateGesture"))
michael@0 1557 msg = NS_SIMPLE_GESTURE_ROTATE;
michael@0 1558 else if (aType.EqualsLiteral("MozTapGesture"))
michael@0 1559 msg = NS_SIMPLE_GESTURE_TAP;
michael@0 1560 else if (aType.EqualsLiteral("MozPressTapGesture"))
michael@0 1561 msg = NS_SIMPLE_GESTURE_PRESSTAP;
michael@0 1562 else if (aType.EqualsLiteral("MozEdgeUIStarted"))
michael@0 1563 msg = NS_SIMPLE_GESTURE_EDGE_STARTED;
michael@0 1564 else if (aType.EqualsLiteral("MozEdgeUICanceled"))
michael@0 1565 msg = NS_SIMPLE_GESTURE_EDGE_CANCELED;
michael@0 1566 else if (aType.EqualsLiteral("MozEdgeUICompleted"))
michael@0 1567 msg = NS_SIMPLE_GESTURE_EDGE_COMPLETED;
michael@0 1568 else
michael@0 1569 return NS_ERROR_FAILURE;
michael@0 1570
michael@0 1571 WidgetSimpleGestureEvent event(true, msg, widget);
michael@0 1572 event.modifiers = GetWidgetModifiers(aModifiers);
michael@0 1573 event.direction = aDirection;
michael@0 1574 event.delta = aDelta;
michael@0 1575 event.clickCount = aClickCount;
michael@0 1576 event.time = PR_IntervalNow();
michael@0 1577
michael@0 1578 nsPresContext* presContext = GetPresContext();
michael@0 1579 if (!presContext)
michael@0 1580 return NS_ERROR_FAILURE;
michael@0 1581
michael@0 1582 event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
michael@0 1583
michael@0 1584 nsEventStatus status;
michael@0 1585 return widget->DispatchEvent(&event, status);
michael@0 1586 }
michael@0 1587
michael@0 1588 NS_IMETHODIMP
michael@0 1589 nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
michael@0 1590 bool aIgnoreRootScrollFrame,
michael@0 1591 bool aFlushLayout,
michael@0 1592 nsIDOMElement** aReturn)
michael@0 1593 {
michael@0 1594 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1595 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1596 }
michael@0 1597
michael@0 1598 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 1599 NS_ENSURE_STATE(doc);
michael@0 1600
michael@0 1601 Element* el =
michael@0 1602 doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout);
michael@0 1603 nsCOMPtr<nsIDOMElement> retval = do_QueryInterface(el);
michael@0 1604 retval.forget(aReturn);
michael@0 1605 return NS_OK;
michael@0 1606 }
michael@0 1607
michael@0 1608 NS_IMETHODIMP
michael@0 1609 nsDOMWindowUtils::NodesFromRect(float aX, float aY,
michael@0 1610 float aTopSize, float aRightSize,
michael@0 1611 float aBottomSize, float aLeftSize,
michael@0 1612 bool aIgnoreRootScrollFrame,
michael@0 1613 bool aFlushLayout,
michael@0 1614 nsIDOMNodeList** aReturn)
michael@0 1615 {
michael@0 1616 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1617 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1618 }
michael@0 1619
michael@0 1620 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 1621 NS_ENSURE_STATE(doc);
michael@0 1622
michael@0 1623 return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize,
michael@0 1624 aIgnoreRootScrollFrame, aFlushLayout, aReturn);
michael@0 1625 }
michael@0 1626
michael@0 1627 NS_IMETHODIMP
michael@0 1628 nsDOMWindowUtils::GetTranslationNodes(nsIDOMNode* aRoot,
michael@0 1629 nsITranslationNodeList** aRetVal)
michael@0 1630 {
michael@0 1631 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1632 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1633 }
michael@0 1634
michael@0 1635 NS_ENSURE_ARG_POINTER(aRetVal);
michael@0 1636 nsCOMPtr<nsIContent> root = do_QueryInterface(aRoot);
michael@0 1637 NS_ENSURE_STATE(root);
michael@0 1638 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 1639 NS_ENSURE_STATE(doc);
michael@0 1640
michael@0 1641 if (root->OwnerDoc() != doc) {
michael@0 1642 return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
michael@0 1643 }
michael@0 1644
michael@0 1645 nsTHashtable<nsPtrHashKey<nsIContent>> translationNodesHash(1000);
michael@0 1646 nsRefPtr<nsTranslationNodeList> list = new nsTranslationNodeList;
michael@0 1647
michael@0 1648 uint32_t limit = 15000;
michael@0 1649
michael@0 1650 // We begin iteration with content->GetNextNode because we want to explictly
michael@0 1651 // skip the root tag from being a translation node.
michael@0 1652 nsIContent* content = root;
michael@0 1653 while ((limit > 0) && (content = content->GetNextNode(root))) {
michael@0 1654 if (!content->IsHTML()) {
michael@0 1655 continue;
michael@0 1656 }
michael@0 1657
michael@0 1658 nsIAtom* localName = content->Tag();
michael@0 1659
michael@0 1660 // Skip elements that usually contain non-translatable text content.
michael@0 1661 if (localName == nsGkAtoms::script ||
michael@0 1662 localName == nsGkAtoms::iframe ||
michael@0 1663 localName == nsGkAtoms::frameset ||
michael@0 1664 localName == nsGkAtoms::frame ||
michael@0 1665 localName == nsGkAtoms::code ||
michael@0 1666 localName == nsGkAtoms::noscript ||
michael@0 1667 localName == nsGkAtoms::style) {
michael@0 1668 continue;
michael@0 1669 }
michael@0 1670
michael@0 1671 // An element is a translation node if it contains
michael@0 1672 // at least one text node that has meaningful data
michael@0 1673 // for translation
michael@0 1674 for (nsIContent* child = content->GetFirstChild();
michael@0 1675 child;
michael@0 1676 child = child->GetNextSibling()) {
michael@0 1677
michael@0 1678 if (child->HasTextForTranslation()) {
michael@0 1679 translationNodesHash.PutEntry(content);
michael@0 1680
michael@0 1681 bool isBlockFrame = false;
michael@0 1682 nsIFrame* frame = content->GetPrimaryFrame();
michael@0 1683 if (frame) {
michael@0 1684 isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame);
michael@0 1685 }
michael@0 1686
michael@0 1687 bool isTranslationRoot = isBlockFrame;
michael@0 1688 if (!isBlockFrame) {
michael@0 1689 // If an element is not a block element, it still
michael@0 1690 // can be considered a translation root if the parent
michael@0 1691 // of this element didn't make into the list of nodes
michael@0 1692 // to be translated.
michael@0 1693 bool parentInList = false;
michael@0 1694 nsIContent* parent = content->GetParent();
michael@0 1695 if (parent) {
michael@0 1696 parentInList = translationNodesHash.Contains(parent);
michael@0 1697 }
michael@0 1698 isTranslationRoot = !parentInList;
michael@0 1699 }
michael@0 1700
michael@0 1701 list->AppendElement(content->AsDOMNode(), isTranslationRoot);
michael@0 1702 --limit;
michael@0 1703 break;
michael@0 1704 }
michael@0 1705 }
michael@0 1706 }
michael@0 1707
michael@0 1708 *aRetVal = list.forget().take();
michael@0 1709 return NS_OK;
michael@0 1710 }
michael@0 1711
michael@0 1712 static TemporaryRef<DataSourceSurface>
michael@0 1713 CanvasToDataSourceSurface(nsIDOMHTMLCanvasElement* aCanvas)
michael@0 1714 {
michael@0 1715 nsCOMPtr<nsINode> node = do_QueryInterface(aCanvas);
michael@0 1716 if (!node) {
michael@0 1717 return nullptr;
michael@0 1718 }
michael@0 1719
michael@0 1720 NS_ABORT_IF_FALSE(node->IsElement(),
michael@0 1721 "An nsINode that implements nsIDOMHTMLCanvasElement should "
michael@0 1722 "be an element.");
michael@0 1723 nsLayoutUtils::SurfaceFromElementResult result =
michael@0 1724 nsLayoutUtils::SurfaceFromElement(node->AsElement());
michael@0 1725 return result.mSourceSurface->GetDataSurface();
michael@0 1726 }
michael@0 1727
michael@0 1728 NS_IMETHODIMP
michael@0 1729 nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
michael@0 1730 nsIDOMHTMLCanvasElement *aCanvas2,
michael@0 1731 uint32_t* aMaxDifference,
michael@0 1732 uint32_t* retVal)
michael@0 1733 {
michael@0 1734 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1735 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1736 }
michael@0 1737
michael@0 1738 if (aCanvas1 == nullptr ||
michael@0 1739 aCanvas2 == nullptr ||
michael@0 1740 retVal == nullptr)
michael@0 1741 return NS_ERROR_FAILURE;
michael@0 1742
michael@0 1743 RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(aCanvas1);
michael@0 1744 RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(aCanvas2);
michael@0 1745
michael@0 1746 if (img1 == nullptr || img2 == nullptr ||
michael@0 1747 img1->GetSize() != img2->GetSize() ||
michael@0 1748 img1->Stride() != img2->Stride())
michael@0 1749 return NS_ERROR_FAILURE;
michael@0 1750
michael@0 1751 int v;
michael@0 1752 IntSize size = img1->GetSize();
michael@0 1753 uint32_t stride = img1->Stride();
michael@0 1754
michael@0 1755 // we can optimize for the common all-pass case
michael@0 1756 if (stride == (uint32_t) size.width * 4) {
michael@0 1757 v = memcmp(img1->GetData(), img2->GetData(), size.width * size.height * 4);
michael@0 1758 if (v == 0) {
michael@0 1759 if (aMaxDifference)
michael@0 1760 *aMaxDifference = 0;
michael@0 1761 *retVal = 0;
michael@0 1762 return NS_OK;
michael@0 1763 }
michael@0 1764 }
michael@0 1765
michael@0 1766 uint32_t dc = 0;
michael@0 1767 uint32_t different = 0;
michael@0 1768
michael@0 1769 for (int j = 0; j < size.height; j++) {
michael@0 1770 unsigned char *p1 = img1->GetData() + j*stride;
michael@0 1771 unsigned char *p2 = img2->GetData() + j*stride;
michael@0 1772 v = memcmp(p1, p2, stride);
michael@0 1773
michael@0 1774 if (v) {
michael@0 1775 for (int i = 0; i < size.width; i++) {
michael@0 1776 if (*(uint32_t*) p1 != *(uint32_t*) p2) {
michael@0 1777
michael@0 1778 different++;
michael@0 1779
michael@0 1780 dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc);
michael@0 1781 dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc);
michael@0 1782 dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc);
michael@0 1783 dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc);
michael@0 1784 }
michael@0 1785
michael@0 1786 p1 += 4;
michael@0 1787 p2 += 4;
michael@0 1788 }
michael@0 1789 }
michael@0 1790 }
michael@0 1791
michael@0 1792 if (aMaxDifference)
michael@0 1793 *aMaxDifference = dc;
michael@0 1794
michael@0 1795 *retVal = different;
michael@0 1796 return NS_OK;
michael@0 1797 }
michael@0 1798
michael@0 1799 NS_IMETHODIMP
michael@0 1800 nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
michael@0 1801 {
michael@0 1802 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1803 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1804 }
michael@0 1805
michael@0 1806 NS_ENSURE_ARG_POINTER(aResult);
michael@0 1807 *aResult = false;
michael@0 1808 nsPresContext* presContext = GetPresContext();
michael@0 1809 if (!presContext)
michael@0 1810 return NS_OK;
michael@0 1811 *aResult = presContext->IsDOMPaintEventPending();
michael@0 1812 return NS_OK;
michael@0 1813 }
michael@0 1814
michael@0 1815 NS_IMETHODIMP
michael@0 1816 nsDOMWindowUtils::ClearMozAfterPaintEvents()
michael@0 1817 {
michael@0 1818 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1819 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1820 }
michael@0 1821
michael@0 1822 nsPresContext* presContext = GetPresContext();
michael@0 1823 if (!presContext)
michael@0 1824 return NS_OK;
michael@0 1825 presContext->ClearMozAfterPaintEvents();
michael@0 1826 return NS_OK;
michael@0 1827 }
michael@0 1828
michael@0 1829 NS_IMETHODIMP
michael@0 1830 nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable)
michael@0 1831 {
michael@0 1832 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1833 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1834 }
michael@0 1835
michael@0 1836 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 1837 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 1838 nsIDocShell *docShell = window->GetDocShell();
michael@0 1839 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
michael@0 1840 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
michael@0 1841 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
michael@0 1842 presShell->DisableNonTestMouseEvents(aDisable);
michael@0 1843 return NS_OK;
michael@0 1844 }
michael@0 1845
michael@0 1846 NS_IMETHODIMP
michael@0 1847 nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
michael@0 1848 {
michael@0 1849 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1850 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1851 }
michael@0 1852
michael@0 1853 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 1854 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
michael@0 1855
michael@0 1856 if (aSuppress) {
michael@0 1857 doc->SuppressEventHandling(nsIDocument::eEvents);
michael@0 1858 } else {
michael@0 1859 doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true);
michael@0 1860 }
michael@0 1861
michael@0 1862 return NS_OK;
michael@0 1863 }
michael@0 1864
michael@0 1865 static nsresult
michael@0 1866 getScrollXYAppUnits(nsWeakPtr aWindow, bool aFlushLayout, nsPoint& aScrollPos) {
michael@0 1867 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1868 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1869 }
michael@0 1870
michael@0 1871 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(aWindow);
michael@0 1872 nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr;
michael@0 1873 NS_ENSURE_STATE(doc);
michael@0 1874
michael@0 1875 if (aFlushLayout) {
michael@0 1876 doc->FlushPendingNotifications(Flush_Layout);
michael@0 1877 }
michael@0 1878
michael@0 1879 nsIPresShell *presShell = doc->GetShell();
michael@0 1880 if (presShell) {
michael@0 1881 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
michael@0 1882 if (sf) {
michael@0 1883 aScrollPos = sf->GetScrollPosition();
michael@0 1884 }
michael@0 1885 }
michael@0 1886 return NS_OK;
michael@0 1887 }
michael@0 1888
michael@0 1889 NS_IMETHODIMP
michael@0 1890 nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
michael@0 1891 {
michael@0 1892 nsPoint scrollPos(0,0);
michael@0 1893 nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
michael@0 1894 NS_ENSURE_SUCCESS(rv, rv);
michael@0 1895 *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
michael@0 1896 *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
michael@0 1897
michael@0 1898 return NS_OK;
michael@0 1899 }
michael@0 1900
michael@0 1901 NS_IMETHODIMP
michael@0 1902 nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY)
michael@0 1903 {
michael@0 1904 nsPoint scrollPos(0,0);
michael@0 1905 nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos);
michael@0 1906 NS_ENSURE_SUCCESS(rv, rv);
michael@0 1907 *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x);
michael@0 1908 *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y);
michael@0 1909
michael@0 1910 return NS_OK;
michael@0 1911 }
michael@0 1912
michael@0 1913 NS_IMETHODIMP
michael@0 1914 nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth,
michael@0 1915 int32_t* aHeight)
michael@0 1916 {
michael@0 1917 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1918 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1919 }
michael@0 1920
michael@0 1921 *aWidth = 0;
michael@0 1922 *aHeight = 0;
michael@0 1923
michael@0 1924 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 1925 NS_ENSURE_STATE(doc);
michael@0 1926
michael@0 1927 if (aFlushLayout) {
michael@0 1928 doc->FlushPendingNotifications(Flush_Layout);
michael@0 1929 }
michael@0 1930
michael@0 1931 nsIPresShell* presShell = doc->GetShell();
michael@0 1932 NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);
michael@0 1933
michael@0 1934 nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable();
michael@0 1935 NS_ENSURE_TRUE(scrollFrame, NS_OK);
michael@0 1936
michael@0 1937 nsMargin sizes = scrollFrame->GetActualScrollbarSizes();
michael@0 1938 *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight());
michael@0 1939 *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom());
michael@0 1940
michael@0 1941 return NS_OK;
michael@0 1942 }
michael@0 1943
michael@0 1944 NS_IMETHODIMP
michael@0 1945 nsDOMWindowUtils::GetBoundsWithoutFlushing(nsIDOMElement *aElement,
michael@0 1946 nsIDOMClientRect** aResult)
michael@0 1947 {
michael@0 1948 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1949 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1950 }
michael@0 1951
michael@0 1952 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 1953 NS_ENSURE_STATE(window);
michael@0 1954
michael@0 1955 nsresult rv;
michael@0 1956 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
michael@0 1957 NS_ENSURE_SUCCESS(rv, rv);
michael@0 1958
michael@0 1959 nsRefPtr<DOMRect> rect = new DOMRect(window);
michael@0 1960 nsIFrame* frame = content->GetPrimaryFrame();
michael@0 1961
michael@0 1962 if (frame) {
michael@0 1963 nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame,
michael@0 1964 nsLayoutUtils::GetContainingBlockForClientRect(frame),
michael@0 1965 nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
michael@0 1966 rect->SetLayoutRect(r);
michael@0 1967 }
michael@0 1968
michael@0 1969 rect.forget(aResult);
michael@0 1970 return NS_OK;
michael@0 1971 }
michael@0 1972
michael@0 1973 NS_IMETHODIMP
michael@0 1974 nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
michael@0 1975 {
michael@0 1976 if (!nsContentUtils::IsCallerChrome()) {
michael@0 1977 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 1978 }
michael@0 1979
michael@0 1980 nsIDocument* doc = GetDocument();
michael@0 1981 NS_ENSURE_STATE(doc);
michael@0 1982
michael@0 1983 nsRect bounds(0, 0, 0, 0);
michael@0 1984 nsIPresShell* presShell = doc->GetShell();
michael@0 1985 if (presShell) {
michael@0 1986 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
michael@0 1987 if (sf) {
michael@0 1988 bounds = sf->GetScrollRange();
michael@0 1989 bounds.width += sf->GetScrollPortRect().width;
michael@0 1990 bounds.height += sf->GetScrollPortRect().height;
michael@0 1991 } else if (presShell->GetRootFrame()) {
michael@0 1992 bounds = presShell->GetRootFrame()->GetRect();
michael@0 1993 }
michael@0 1994 }
michael@0 1995
michael@0 1996 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 1997 nsRefPtr<DOMRect> rect = new DOMRect(window);
michael@0 1998 rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x),
michael@0 1999 nsPresContext::AppUnitsToFloatCSSPixels(bounds.y),
michael@0 2000 nsPresContext::AppUnitsToFloatCSSPixels(bounds.width),
michael@0 2001 nsPresContext::AppUnitsToFloatCSSPixels(bounds.height));
michael@0 2002 rect.forget(aResult);
michael@0 2003 return NS_OK;
michael@0 2004 }
michael@0 2005
michael@0 2006 NS_IMETHODIMP
michael@0 2007 nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
michael@0 2008 {
michael@0 2009 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2010 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2011 }
michael@0 2012
michael@0 2013 NS_ENSURE_ARG_POINTER(aState);
michael@0 2014
michael@0 2015 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2016 if (!widget)
michael@0 2017 return NS_ERROR_FAILURE;
michael@0 2018
michael@0 2019 // Open state should not be available when IME is not enabled.
michael@0 2020 InputContext context = widget->GetInputContext();
michael@0 2021 if (context.mIMEState.mEnabled != IMEState::ENABLED) {
michael@0 2022 return NS_ERROR_NOT_AVAILABLE;
michael@0 2023 }
michael@0 2024
michael@0 2025 if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
michael@0 2026 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 2027 }
michael@0 2028 *aState = (context.mIMEState.mOpen == IMEState::OPEN);
michael@0 2029 return NS_OK;
michael@0 2030 }
michael@0 2031
michael@0 2032 NS_IMETHODIMP
michael@0 2033 nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
michael@0 2034 {
michael@0 2035 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2036 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2037 }
michael@0 2038
michael@0 2039 NS_ENSURE_ARG_POINTER(aState);
michael@0 2040
michael@0 2041 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2042 if (!widget)
michael@0 2043 return NS_ERROR_FAILURE;
michael@0 2044
michael@0 2045 InputContext context = widget->GetInputContext();
michael@0 2046 *aState = static_cast<uint32_t>(context.mIMEState.mEnabled);
michael@0 2047 return NS_OK;
michael@0 2048 }
michael@0 2049
michael@0 2050 NS_IMETHODIMP
michael@0 2051 nsDOMWindowUtils::GetFocusedInputType(char** aType)
michael@0 2052 {
michael@0 2053 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2054 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2055 }
michael@0 2056
michael@0 2057 NS_ENSURE_ARG_POINTER(aType);
michael@0 2058
michael@0 2059 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2060 if (!widget) {
michael@0 2061 return NS_ERROR_FAILURE;
michael@0 2062 }
michael@0 2063
michael@0 2064 InputContext context = widget->GetInputContext();
michael@0 2065 *aType = ToNewCString(context.mHTMLInputType);
michael@0 2066 return NS_OK;
michael@0 2067 }
michael@0 2068
michael@0 2069 NS_IMETHODIMP
michael@0 2070 nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
michael@0 2071 nsIDOMElement** aResult)
michael@0 2072 {
michael@0 2073 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2074 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2075 }
michael@0 2076
michael@0 2077 nsRefPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aID);
michael@0 2078 return content ? CallQueryInterface(content, aResult) : NS_OK;
michael@0 2079 }
michael@0 2080
michael@0 2081 NS_IMETHODIMP
michael@0 2082 nsDOMWindowUtils::GetViewId(nsIDOMElement* aElement, nsViewID* aResult)
michael@0 2083 {
michael@0 2084 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
michael@0 2085 if (content && nsLayoutUtils::FindIDFor(content, aResult)) {
michael@0 2086 return NS_OK;
michael@0 2087 }
michael@0 2088 return NS_ERROR_NOT_AVAILABLE;
michael@0 2089 }
michael@0 2090
michael@0 2091 NS_IMETHODIMP
michael@0 2092 nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
michael@0 2093 {
michael@0 2094 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2095 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 2096 return window->GetDevicePixelRatio(aScreenPixels);
michael@0 2097 }
michael@0 2098
michael@0 2099 NS_IMETHODIMP
michael@0 2100 nsDOMWindowUtils::GetFullZoom(float* aFullZoom)
michael@0 2101 {
michael@0 2102 *aFullZoom = 1.0f;
michael@0 2103
michael@0 2104 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2105 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2106 }
michael@0 2107
michael@0 2108 nsPresContext* presContext = GetPresContext();
michael@0 2109 if (!presContext) {
michael@0 2110 return NS_OK;
michael@0 2111 }
michael@0 2112
michael@0 2113 *aFullZoom = presContext->DeviceContext()->GetPixelScale();
michael@0 2114
michael@0 2115 return NS_OK;
michael@0 2116 }
michael@0 2117
michael@0 2118 NS_IMETHODIMP
michael@0 2119 nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
michael@0 2120 nsIDOMEvent* aEvent,
michael@0 2121 bool aTrusted,
michael@0 2122 bool* aRetVal)
michael@0 2123 {
michael@0 2124 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2125 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2126 }
michael@0 2127
michael@0 2128 NS_ENSURE_STATE(aEvent);
michael@0 2129 aEvent->SetTrusted(aTrusted);
michael@0 2130 WidgetEvent* internalEvent = aEvent->GetInternalNSEvent();
michael@0 2131 NS_ENSURE_STATE(internalEvent);
michael@0 2132 nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
michael@0 2133 NS_ENSURE_STATE(content);
michael@0 2134 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2135 if (content->OwnerDoc()->GetWindow() != window) {
michael@0 2136 return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
michael@0 2137 }
michael@0 2138 nsCOMPtr<nsIDocument> targetDoc = content->GetCurrentDoc();
michael@0 2139 NS_ENSURE_STATE(targetDoc);
michael@0 2140 nsRefPtr<nsIPresShell> targetShell = targetDoc->GetShell();
michael@0 2141 NS_ENSURE_STATE(targetShell);
michael@0 2142
michael@0 2143 targetDoc->FlushPendingNotifications(Flush_Layout);
michael@0 2144
michael@0 2145 nsEventStatus status = nsEventStatus_eIgnore;
michael@0 2146 targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status);
michael@0 2147 *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
michael@0 2148 return NS_OK;
michael@0 2149 }
michael@0 2150
michael@0 2151 static void
michael@0 2152 InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr)
michael@0 2153 {
michael@0 2154 if (aPt) {
michael@0 2155 aEvent.refPoint = *aPt;
michael@0 2156 }
michael@0 2157 aEvent.time = PR_IntervalNow();
michael@0 2158 }
michael@0 2159
michael@0 2160 NS_IMETHODIMP
michael@0 2161 nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType,
michael@0 2162 const nsAString& aData,
michael@0 2163 const nsAString& aLocale)
michael@0 2164 {
michael@0 2165 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2166 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2167 }
michael@0 2168
michael@0 2169 // get the widget to send the event to
michael@0 2170 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2171 if (!widget) {
michael@0 2172 return NS_ERROR_FAILURE;
michael@0 2173 }
michael@0 2174
michael@0 2175 uint32_t msg;
michael@0 2176 if (aType.EqualsLiteral("compositionstart")) {
michael@0 2177 msg = NS_COMPOSITION_START;
michael@0 2178 } else if (aType.EqualsLiteral("compositionend")) {
michael@0 2179 msg = NS_COMPOSITION_END;
michael@0 2180 } else if (aType.EqualsLiteral("compositionupdate")) {
michael@0 2181 msg = NS_COMPOSITION_UPDATE;
michael@0 2182 } else {
michael@0 2183 return NS_ERROR_FAILURE;
michael@0 2184 }
michael@0 2185
michael@0 2186 WidgetCompositionEvent compositionEvent(true, msg, widget);
michael@0 2187 InitEvent(compositionEvent);
michael@0 2188 if (msg != NS_COMPOSITION_START) {
michael@0 2189 compositionEvent.data = aData;
michael@0 2190 }
michael@0 2191
michael@0 2192 compositionEvent.mFlags.mIsSynthesizedForTests = true;
michael@0 2193
michael@0 2194 nsEventStatus status;
michael@0 2195 nsresult rv = widget->DispatchEvent(&compositionEvent, status);
michael@0 2196 NS_ENSURE_SUCCESS(rv, rv);
michael@0 2197
michael@0 2198 return NS_OK;
michael@0 2199 }
michael@0 2200
michael@0 2201 NS_IMETHODIMP
michael@0 2202 nsDOMWindowUtils::CreateCompositionStringSynthesizer(
michael@0 2203 nsICompositionStringSynthesizer** aResult)
michael@0 2204 {
michael@0 2205 NS_ENSURE_ARG_POINTER(aResult);
michael@0 2206 *aResult = nullptr;
michael@0 2207
michael@0 2208 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2209 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2210 }
michael@0 2211
michael@0 2212 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2213 NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
michael@0 2214
michael@0 2215 NS_ADDREF(*aResult = new CompositionStringSynthesizer(window));
michael@0 2216 return NS_OK;
michael@0 2217 }
michael@0 2218
michael@0 2219 NS_IMETHODIMP
michael@0 2220 nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
michael@0 2221 uint32_t aOffset, uint32_t aLength,
michael@0 2222 int32_t aX, int32_t aY,
michael@0 2223 uint32_t aAdditionalFlags,
michael@0 2224 nsIQueryContentEventResult **aResult)
michael@0 2225 {
michael@0 2226 *aResult = nullptr;
michael@0 2227
michael@0 2228 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2229 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2230 }
michael@0 2231
michael@0 2232 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2233 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 2234
michael@0 2235 nsIDocShell *docShell = window->GetDocShell();
michael@0 2236 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
michael@0 2237
michael@0 2238 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
michael@0 2239 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
michael@0 2240
michael@0 2241 nsPresContext* presContext = presShell->GetPresContext();
michael@0 2242 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
michael@0 2243
michael@0 2244 // get the widget to send the event to
michael@0 2245 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2246 if (!widget) {
michael@0 2247 return NS_ERROR_FAILURE;
michael@0 2248 }
michael@0 2249
michael@0 2250 if (aType != NS_QUERY_SELECTED_TEXT &&
michael@0 2251 aType != NS_QUERY_TEXT_CONTENT &&
michael@0 2252 aType != NS_QUERY_CARET_RECT &&
michael@0 2253 aType != NS_QUERY_TEXT_RECT &&
michael@0 2254 aType != NS_QUERY_EDITOR_RECT &&
michael@0 2255 aType != NS_QUERY_CHARACTER_AT_POINT) {
michael@0 2256 return NS_ERROR_INVALID_ARG;
michael@0 2257 }
michael@0 2258
michael@0 2259 nsCOMPtr<nsIWidget> targetWidget = widget;
michael@0 2260 LayoutDeviceIntPoint pt(aX, aY);
michael@0 2261
michael@0 2262 bool useNativeLineBreak =
michael@0 2263 !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
michael@0 2264
michael@0 2265 if (aType == QUERY_CHARACTER_AT_POINT) {
michael@0 2266 // Looking for the widget at the point.
michael@0 2267 WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
michael@0 2268 dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
michael@0 2269 InitEvent(dummyEvent, &pt);
michael@0 2270 nsIFrame* popupFrame =
michael@0 2271 nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
michael@0 2272
michael@0 2273 nsIntRect widgetBounds;
michael@0 2274 nsresult rv = widget->GetClientBounds(widgetBounds);
michael@0 2275 NS_ENSURE_SUCCESS(rv, rv);
michael@0 2276 widgetBounds.MoveTo(0, 0);
michael@0 2277
michael@0 2278 // There is no popup frame at the point and the point isn't in our widget,
michael@0 2279 // we cannot process this request.
michael@0 2280 NS_ENSURE_TRUE(popupFrame ||
michael@0 2281 widgetBounds.Contains(LayoutDeviceIntPoint::ToUntyped(pt)),
michael@0 2282 NS_ERROR_FAILURE);
michael@0 2283
michael@0 2284 // Fire the event on the widget at the point
michael@0 2285 if (popupFrame) {
michael@0 2286 targetWidget = popupFrame->GetNearestWidget();
michael@0 2287 }
michael@0 2288 }
michael@0 2289
michael@0 2290 pt += LayoutDeviceIntPoint::FromUntyped(
michael@0 2291 widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset());
michael@0 2292
michael@0 2293 WidgetQueryContentEvent queryEvent(true, aType, targetWidget);
michael@0 2294 InitEvent(queryEvent, &pt);
michael@0 2295
michael@0 2296 switch (aType) {
michael@0 2297 case NS_QUERY_TEXT_CONTENT:
michael@0 2298 queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
michael@0 2299 break;
michael@0 2300 case NS_QUERY_CARET_RECT:
michael@0 2301 queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
michael@0 2302 break;
michael@0 2303 case NS_QUERY_TEXT_RECT:
michael@0 2304 queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak);
michael@0 2305 break;
michael@0 2306 default:
michael@0 2307 queryEvent.mUseNativeLineBreak = useNativeLineBreak;
michael@0 2308 break;
michael@0 2309 }
michael@0 2310
michael@0 2311 nsEventStatus status;
michael@0 2312 nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
michael@0 2313 NS_ENSURE_SUCCESS(rv, rv);
michael@0 2314
michael@0 2315 nsQueryContentEventResult* result = new nsQueryContentEventResult();
michael@0 2316 NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
michael@0 2317 result->SetEventResult(widget, queryEvent);
michael@0 2318 NS_ADDREF(*aResult = result);
michael@0 2319 return NS_OK;
michael@0 2320 }
michael@0 2321
michael@0 2322 NS_IMETHODIMP
michael@0 2323 nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
michael@0 2324 uint32_t aLength,
michael@0 2325 uint32_t aAdditionalFlags,
michael@0 2326 bool *aResult)
michael@0 2327 {
michael@0 2328 *aResult = false;
michael@0 2329
michael@0 2330 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2331 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2332 }
michael@0 2333
michael@0 2334 // get the widget to send the event to
michael@0 2335 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2336 if (!widget) {
michael@0 2337 return NS_ERROR_FAILURE;
michael@0 2338 }
michael@0 2339
michael@0 2340 WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
michael@0 2341 InitEvent(selectionEvent);
michael@0 2342
michael@0 2343 selectionEvent.mOffset = aOffset;
michael@0 2344 selectionEvent.mLength = aLength;
michael@0 2345 selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
michael@0 2346 selectionEvent.mUseNativeLineBreak =
michael@0 2347 !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
michael@0 2348
michael@0 2349 nsEventStatus status;
michael@0 2350 nsresult rv = widget->DispatchEvent(&selectionEvent, status);
michael@0 2351 NS_ENSURE_SUCCESS(rv, rv);
michael@0 2352
michael@0 2353 *aResult = selectionEvent.mSucceeded;
michael@0 2354 return NS_OK;
michael@0 2355 }
michael@0 2356
michael@0 2357 NS_IMETHODIMP
michael@0 2358 nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
michael@0 2359 nsITransferable * aTransferable)
michael@0 2360 {
michael@0 2361 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2362 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2363 }
michael@0 2364
michael@0 2365 // get the widget to send the event to
michael@0 2366 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2367 if (!widget)
michael@0 2368 return NS_ERROR_FAILURE;
michael@0 2369
michael@0 2370 int32_t msg;
michael@0 2371 if (aType.EqualsLiteral("cut"))
michael@0 2372 msg = NS_CONTENT_COMMAND_CUT;
michael@0 2373 else if (aType.EqualsLiteral("copy"))
michael@0 2374 msg = NS_CONTENT_COMMAND_COPY;
michael@0 2375 else if (aType.EqualsLiteral("paste"))
michael@0 2376 msg = NS_CONTENT_COMMAND_PASTE;
michael@0 2377 else if (aType.EqualsLiteral("delete"))
michael@0 2378 msg = NS_CONTENT_COMMAND_DELETE;
michael@0 2379 else if (aType.EqualsLiteral("undo"))
michael@0 2380 msg = NS_CONTENT_COMMAND_UNDO;
michael@0 2381 else if (aType.EqualsLiteral("redo"))
michael@0 2382 msg = NS_CONTENT_COMMAND_REDO;
michael@0 2383 else if (aType.EqualsLiteral("pasteTransferable"))
michael@0 2384 msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
michael@0 2385 else
michael@0 2386 return NS_ERROR_FAILURE;
michael@0 2387
michael@0 2388 WidgetContentCommandEvent event(true, msg, widget);
michael@0 2389 if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
michael@0 2390 event.mTransferable = aTransferable;
michael@0 2391 }
michael@0 2392
michael@0 2393 nsEventStatus status;
michael@0 2394 return widget->DispatchEvent(&event, status);
michael@0 2395 }
michael@0 2396
michael@0 2397 NS_IMETHODIMP
michael@0 2398 nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx,
michael@0 2399 char** aName)
michael@0 2400 {
michael@0 2401 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2402 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2403 }
michael@0 2404
michael@0 2405 // Our argument must be a non-null object.
michael@0 2406 if (JSVAL_IS_PRIMITIVE(aObject)) {
michael@0 2407 return NS_ERROR_XPC_BAD_CONVERT_JS;
michael@0 2408 }
michael@0 2409
michael@0 2410 *aName = NS_strdup(JS_GetClass(JSVAL_TO_OBJECT(aObject))->name);
michael@0 2411 NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
michael@0 2412 return NS_OK;
michael@0 2413 }
michael@0 2414
michael@0 2415 NS_IMETHODIMP
michael@0 2416 nsDOMWindowUtils::GetVisitedDependentComputedStyle(
michael@0 2417 nsIDOMElement *aElement, const nsAString& aPseudoElement,
michael@0 2418 const nsAString& aPropertyName, nsAString& aResult)
michael@0 2419 {
michael@0 2420 aResult.Truncate();
michael@0 2421
michael@0 2422 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2423 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2424 }
michael@0 2425
michael@0 2426 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2427 NS_ENSURE_STATE(window);
michael@0 2428
michael@0 2429 nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
michael@0 2430 nsresult rv =
michael@0 2431 window->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
michael@0 2432 NS_ENSURE_SUCCESS(rv, rv);
michael@0 2433
michael@0 2434 static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
michael@0 2435 rv = decl->GetPropertyValue(aPropertyName, aResult);
michael@0 2436 static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
michael@0 2437
michael@0 2438 return rv;
michael@0 2439 }
michael@0 2440
michael@0 2441 NS_IMETHODIMP
michael@0 2442 nsDOMWindowUtils::EnterModalState()
michael@0 2443 {
michael@0 2444 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2445 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2446 }
michael@0 2447
michael@0 2448 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2449 NS_ENSURE_STATE(window);
michael@0 2450
michael@0 2451 window->EnterModalState();
michael@0 2452 return NS_OK;
michael@0 2453 }
michael@0 2454
michael@0 2455 NS_IMETHODIMP
michael@0 2456 nsDOMWindowUtils::LeaveModalState()
michael@0 2457 {
michael@0 2458 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2459 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2460 }
michael@0 2461
michael@0 2462 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2463 NS_ENSURE_STATE(window);
michael@0 2464
michael@0 2465 window->LeaveModalState();
michael@0 2466 return NS_OK;
michael@0 2467 }
michael@0 2468
michael@0 2469 NS_IMETHODIMP
michael@0 2470 nsDOMWindowUtils::IsInModalState(bool *retval)
michael@0 2471 {
michael@0 2472 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2473 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2474 }
michael@0 2475
michael@0 2476 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2477 NS_ENSURE_STATE(window);
michael@0 2478
michael@0 2479 *retval = static_cast<nsGlobalWindow*>(window.get())->IsInModalState();
michael@0 2480 return NS_OK;
michael@0 2481 }
michael@0 2482
michael@0 2483 NS_IMETHODIMP
michael@0 2484 nsDOMWindowUtils::GetParent(JS::Handle<JS::Value> aObject,
michael@0 2485 JSContext* aCx,
michael@0 2486 JS::MutableHandle<JS::Value> aParent)
michael@0 2487 {
michael@0 2488 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2489 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2490 }
michael@0 2491
michael@0 2492 // First argument must be an object.
michael@0 2493 if (aObject.isPrimitive()) {
michael@0 2494 return NS_ERROR_XPC_BAD_CONVERT_JS;
michael@0 2495 }
michael@0 2496
michael@0 2497 JS::Rooted<JSObject*> parent(aCx, JS_GetParent(&aObject.toObject()));
michael@0 2498
michael@0 2499 // Outerize if necessary.
michael@0 2500 if (parent) {
michael@0 2501 if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
michael@0 2502 parent = outerize(aCx, parent);
michael@0 2503 }
michael@0 2504 }
michael@0 2505
michael@0 2506 aParent.setObject(*parent);
michael@0 2507 return NS_OK;
michael@0 2508 }
michael@0 2509
michael@0 2510 NS_IMETHODIMP
michael@0 2511 nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
michael@0 2512 {
michael@0 2513 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2514 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2515 }
michael@0 2516
michael@0 2517 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2518 NS_ENSURE_STATE(window);
michael@0 2519
michael@0 2520 NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
michael@0 2521 *aWindowID = window->WindowID();
michael@0 2522 return NS_OK;
michael@0 2523 }
michael@0 2524
michael@0 2525 NS_IMETHODIMP
michael@0 2526 nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID)
michael@0 2527 {
michael@0 2528 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2529 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2530 }
michael@0 2531
michael@0 2532 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2533 NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
michael@0 2534
michael@0 2535 NS_ASSERTION(window->IsOuterWindow(), "How did that happen?");
michael@0 2536 nsGlobalWindow* inner =
michael@0 2537 static_cast<nsGlobalWindow*>(window.get())->GetCurrentInnerWindowInternal();
michael@0 2538 if (!inner) {
michael@0 2539 return NS_ERROR_NOT_AVAILABLE;
michael@0 2540 }
michael@0 2541 *aWindowID = inner->WindowID();
michael@0 2542 return NS_OK;
michael@0 2543 }
michael@0 2544
michael@0 2545 NS_IMETHODIMP
michael@0 2546 nsDOMWindowUtils::SuspendTimeouts()
michael@0 2547 {
michael@0 2548 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2549 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2550 }
michael@0 2551
michael@0 2552 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2553 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 2554
michael@0 2555 window->SuspendTimeouts();
michael@0 2556
michael@0 2557 return NS_OK;
michael@0 2558 }
michael@0 2559
michael@0 2560 NS_IMETHODIMP
michael@0 2561 nsDOMWindowUtils::ResumeTimeouts()
michael@0 2562 {
michael@0 2563 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2564 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2565 }
michael@0 2566
michael@0 2567 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2568 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 2569
michael@0 2570 window->ResumeTimeouts();
michael@0 2571
michael@0 2572 return NS_OK;
michael@0 2573 }
michael@0 2574
michael@0 2575 NS_IMETHODIMP
michael@0 2576 nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
michael@0 2577 {
michael@0 2578 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2579 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2580 }
michael@0 2581
michael@0 2582 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2583 if (!widget)
michael@0 2584 return NS_ERROR_FAILURE;
michael@0 2585
michael@0 2586 LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT);
michael@0 2587 if (!mgr)
michael@0 2588 return NS_ERROR_FAILURE;
michael@0 2589
michael@0 2590 mgr->GetBackendName(aType);
michael@0 2591
michael@0 2592 return NS_OK;
michael@0 2593 }
michael@0 2594
michael@0 2595 NS_IMETHODIMP
michael@0 2596 nsDOMWindowUtils::GetLayerManagerRemote(bool* retval)
michael@0 2597 {
michael@0 2598 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2599 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2600 }
michael@0 2601
michael@0 2602 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2603 if (!widget)
michael@0 2604 return NS_ERROR_FAILURE;
michael@0 2605
michael@0 2606 LayerManager *mgr = widget->GetLayerManager();
michael@0 2607 if (!mgr)
michael@0 2608 return NS_ERROR_FAILURE;
michael@0 2609
michael@0 2610 *retval = !!mgr->AsShadowForwarder();
michael@0 2611 return NS_OK;
michael@0 2612 }
michael@0 2613
michael@0 2614 NS_IMETHODIMP
michael@0 2615 nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
michael@0 2616 {
michael@0 2617 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2618 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2619 }
michael@0 2620
michael@0 2621 NS_ENSURE_ARG_POINTER(startIndex);
michael@0 2622
michael@0 2623 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2624 if (!widget)
michael@0 2625 return NS_ERROR_FAILURE;
michael@0 2626
michael@0 2627 LayerManager *mgr = widget->GetLayerManager();
michael@0 2628 if (!mgr)
michael@0 2629 return NS_ERROR_FAILURE;
michael@0 2630
michael@0 2631 const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps.
michael@0 2632 const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour
michael@0 2633 uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0));
michael@0 2634 bufferSize = std::min(bufferSize, kRecordingMaxSize);
michael@0 2635 bufferSize = std::max(bufferSize, kRecordingMinSize);
michael@0 2636 *startIndex = mgr->StartFrameTimeRecording(bufferSize);
michael@0 2637
michael@0 2638 return NS_OK;
michael@0 2639 }
michael@0 2640
michael@0 2641 NS_IMETHODIMP
michael@0 2642 nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex,
michael@0 2643 uint32_t *frameCount,
michael@0 2644 float **frameIntervals)
michael@0 2645 {
michael@0 2646 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2647 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2648 }
michael@0 2649
michael@0 2650 NS_ENSURE_ARG_POINTER(frameCount);
michael@0 2651 NS_ENSURE_ARG_POINTER(frameIntervals);
michael@0 2652
michael@0 2653 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2654 if (!widget)
michael@0 2655 return NS_ERROR_FAILURE;
michael@0 2656
michael@0 2657 LayerManager *mgr = widget->GetLayerManager();
michael@0 2658 if (!mgr)
michael@0 2659 return NS_ERROR_FAILURE;
michael@0 2660
michael@0 2661 nsTArray<float> tmpFrameIntervals;
michael@0 2662 mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals);
michael@0 2663 *frameCount = tmpFrameIntervals.Length();
michael@0 2664
michael@0 2665 *frameIntervals = (float*)nsMemory::Alloc(*frameCount * sizeof(float));
michael@0 2666
michael@0 2667 /* copy over the frame intervals and paint times into the arrays we just allocated */
michael@0 2668 for (uint32_t i = 0; i < *frameCount; i++) {
michael@0 2669 (*frameIntervals)[i] = tmpFrameIntervals[i];
michael@0 2670 }
michael@0 2671
michael@0 2672 return NS_OK;
michael@0 2673 }
michael@0 2674
michael@0 2675 NS_IMETHODIMP
michael@0 2676 nsDOMWindowUtils::BeginTabSwitch()
michael@0 2677 {
michael@0 2678 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2679 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2680 }
michael@0 2681
michael@0 2682 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2683 if (!widget)
michael@0 2684 return NS_ERROR_FAILURE;
michael@0 2685
michael@0 2686 LayerManager *mgr = widget->GetLayerManager();
michael@0 2687 if (!mgr)
michael@0 2688 return NS_ERROR_FAILURE;
michael@0 2689
michael@0 2690 mgr->BeginTabSwitch();
michael@0 2691
michael@0 2692 return NS_OK;
michael@0 2693 }
michael@0 2694
michael@0 2695 static bool
michael@0 2696 ComputeAnimationValue(nsCSSProperty aProperty,
michael@0 2697 Element* aElement,
michael@0 2698 const nsAString& aInput,
michael@0 2699 nsStyleAnimation::Value& aOutput)
michael@0 2700 {
michael@0 2701
michael@0 2702 if (!nsStyleAnimation::ComputeValue(aProperty, aElement, aInput,
michael@0 2703 false, aOutput)) {
michael@0 2704 return false;
michael@0 2705 }
michael@0 2706
michael@0 2707 // This matches TransExtractComputedValue in nsTransitionManager.cpp.
michael@0 2708 if (aProperty == eCSSProperty_visibility) {
michael@0 2709 NS_ABORT_IF_FALSE(aOutput.GetUnit() == nsStyleAnimation::eUnit_Enumerated,
michael@0 2710 "unexpected unit");
michael@0 2711 aOutput.SetIntValue(aOutput.GetIntValue(),
michael@0 2712 nsStyleAnimation::eUnit_Visibility);
michael@0 2713 }
michael@0 2714
michael@0 2715 return true;
michael@0 2716 }
michael@0 2717
michael@0 2718 NS_IMETHODIMP
michael@0 2719 nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds)
michael@0 2720 {
michael@0 2721 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2722 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2723 }
michael@0 2724
michael@0 2725 nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
michael@0 2726 driver->AdvanceTimeAndRefresh(aMilliseconds);
michael@0 2727
michael@0 2728 LayerTransactionChild* transaction = GetLayerTransaction();
michael@0 2729 if (transaction) {
michael@0 2730 transaction->SendSetTestSampleTime(driver->MostRecentRefresh());
michael@0 2731 }
michael@0 2732
michael@0 2733 return NS_OK;
michael@0 2734 }
michael@0 2735
michael@0 2736 NS_IMETHODIMP
michael@0 2737 nsDOMWindowUtils::RestoreNormalRefresh()
michael@0 2738 {
michael@0 2739 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2740 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2741 }
michael@0 2742
michael@0 2743 // Kick the compositor out of test mode before the refresh driver, so that
michael@0 2744 // the refresh driver doesn't send an update that gets ignored by the
michael@0 2745 // compositor.
michael@0 2746 LayerTransactionChild* transaction = GetLayerTransaction();
michael@0 2747 if (transaction) {
michael@0 2748 transaction->SendLeaveTestMode();
michael@0 2749 }
michael@0 2750
michael@0 2751 nsRefreshDriver* driver = GetPresContext()->RefreshDriver();
michael@0 2752 driver->RestoreNormalRefresh();
michael@0 2753
michael@0 2754 return NS_OK;
michael@0 2755 }
michael@0 2756
michael@0 2757 NS_IMETHODIMP
michael@0 2758 nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult)
michael@0 2759 {
michael@0 2760 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2761 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2762 }
michael@0 2763
michael@0 2764 nsPresContext* pc = GetPresContext();
michael@0 2765 *aResult =
michael@0 2766 pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false;
michael@0 2767
michael@0 2768 return NS_OK;
michael@0 2769 }
michael@0 2770
michael@0 2771 NS_IMETHODIMP
michael@0 2772 nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode,
michael@0 2773 int32_t aX, int32_t aY)
michael@0 2774 {
michael@0 2775 nsCOMPtr<Element> element = do_QueryInterface(aNode);
michael@0 2776 if (!element) {
michael@0 2777 return NS_ERROR_INVALID_ARG;
michael@0 2778 }
michael@0 2779 nsIFrame* frame = element->GetPrimaryFrame();
michael@0 2780 if (!frame) {
michael@0 2781 return NS_ERROR_UNEXPECTED;
michael@0 2782 }
michael@0 2783 nsIScrollableFrame* scrollable = do_QueryFrame(frame);
michael@0 2784 nsPresContext* presContext = frame->PresContext();
michael@0 2785 nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
michael@0 2786 if (!scrollable) {
michael@0 2787 if (rootScrollFrame && rootScrollFrame->GetContent() == element) {
michael@0 2788 frame = rootScrollFrame;
michael@0 2789 scrollable = do_QueryFrame(frame);
michael@0 2790 }
michael@0 2791 }
michael@0 2792 if (!scrollable) {
michael@0 2793 return NS_ERROR_UNEXPECTED;
michael@0 2794 }
michael@0 2795 Layer* layer = FrameLayerBuilder::GetDedicatedLayer(scrollable->GetScrolledFrame(),
michael@0 2796 nsDisplayItem::TYPE_SCROLL_LAYER);
michael@0 2797 if (!layer) {
michael@0 2798 if (rootScrollFrame == frame && !presContext->GetParentPresContext()) {
michael@0 2799 nsIWidget* widget = GetWidget();
michael@0 2800 if (widget) {
michael@0 2801 LayerManager* manager = widget->GetLayerManager();
michael@0 2802 if (manager) {
michael@0 2803 layer = manager->GetRoot();
michael@0 2804 }
michael@0 2805 }
michael@0 2806 }
michael@0 2807 if (!layer) {
michael@0 2808 return NS_ERROR_UNEXPECTED;
michael@0 2809 }
michael@0 2810 }
michael@0 2811 ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
michael@0 2812 if (!forwarder || !forwarder->HasShadowManager()) {
michael@0 2813 return NS_ERROR_UNEXPECTED;
michael@0 2814 }
michael@0 2815 forwarder->GetShadowManager()->SendSetAsyncScrollOffset(
michael@0 2816 layer->AsShadowableLayer()->GetShadow(), aX, aY);
michael@0 2817 return NS_OK;
michael@0 2818 }
michael@0 2819
michael@0 2820 NS_IMETHODIMP
michael@0 2821 nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
michael@0 2822 const nsAString& aProperty,
michael@0 2823 const nsAString& aValue1,
michael@0 2824 const nsAString& aValue2,
michael@0 2825 double* aResult)
michael@0 2826 {
michael@0 2827 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2828 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2829 }
michael@0 2830
michael@0 2831 nsresult rv;
michael@0 2832 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
michael@0 2833 NS_ENSURE_SUCCESS(rv, rv);
michael@0 2834
michael@0 2835 // Convert direction-dependent properties as appropriate, e.g.,
michael@0 2836 // border-left to border-left-value.
michael@0 2837 nsCSSProperty property =
michael@0 2838 nsCSSProps::LookupProperty(aProperty, nsCSSProps::eIgnoreEnabledState);
michael@0 2839 if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
michael@0 2840 nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
michael@0 2841 if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
michael@0 2842 nsCSSProps::OtherNameFor(subprop0) == property) {
michael@0 2843 property = subprop0;
michael@0 2844 } else {
michael@0 2845 property = eCSSProperty_UNKNOWN;
michael@0 2846 }
michael@0 2847 }
michael@0 2848
michael@0 2849 NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
michael@0 2850 !nsCSSProps::IsShorthand(property),
michael@0 2851 "should not have shorthand");
michael@0 2852
michael@0 2853 nsStyleAnimation::Value v1, v2;
michael@0 2854 if (property == eCSSProperty_UNKNOWN ||
michael@0 2855 !ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
michael@0 2856 !ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
michael@0 2857 return NS_ERROR_ILLEGAL_VALUE;
michael@0 2858 }
michael@0 2859
michael@0 2860 if (!nsStyleAnimation::ComputeDistance(property, v1, v2, *aResult)) {
michael@0 2861 return NS_ERROR_FAILURE;
michael@0 2862 }
michael@0 2863
michael@0 2864 return NS_OK;
michael@0 2865 }
michael@0 2866
michael@0 2867 nsresult
michael@0 2868 nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
michael@0 2869 uint32_t aFlags,
michael@0 2870 nscolor aBackgroundColor,
michael@0 2871 gfxContext* aThebesContext)
michael@0 2872 {
michael@0 2873 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2874 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2875 }
michael@0 2876
michael@0 2877 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 2878 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
michael@0 2879
michael@0 2880 // Get Primary Shell
michael@0 2881 nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
michael@0 2882 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
michael@0 2883
michael@0 2884 // Render Document
michael@0 2885 return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
michael@0 2886 }
michael@0 2887
michael@0 2888 NS_IMETHODIMP
michael@0 2889 nsDOMWindowUtils::GetCursorType(int16_t *aCursor)
michael@0 2890 {
michael@0 2891 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2892 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2893 }
michael@0 2894
michael@0 2895 NS_ENSURE_ARG_POINTER(aCursor);
michael@0 2896
michael@0 2897 nsIDocument* doc = GetDocument();
michael@0 2898 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
michael@0 2899
michael@0 2900 bool isSameDoc = false;
michael@0 2901 do {
michael@0 2902 if (EventStateManager::sMouseOverDocument == doc) {
michael@0 2903 isSameDoc = true;
michael@0 2904 break;
michael@0 2905 }
michael@0 2906 } while ((doc = doc->GetParentDocument()));
michael@0 2907
michael@0 2908 if (!isSameDoc) {
michael@0 2909 *aCursor = eCursor_none;
michael@0 2910 return NS_OK;
michael@0 2911 }
michael@0 2912
michael@0 2913 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2914 if (!widget)
michael@0 2915 return NS_ERROR_FAILURE;
michael@0 2916
michael@0 2917 // fetch cursor value from window's widget
michael@0 2918 *aCursor = widget->GetCursor();
michael@0 2919
michael@0 2920 return NS_OK;
michael@0 2921 }
michael@0 2922
michael@0 2923 NS_IMETHODIMP
michael@0 2924 nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
michael@0 2925 {
michael@0 2926 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2927 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2928 }
michael@0 2929
michael@0 2930 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 2931 if (!widget)
michael@0 2932 return NS_ERROR_FAILURE;
michael@0 2933
michael@0 2934 *aDPI = widget->GetDPI();
michael@0 2935
michael@0 2936 return NS_OK;
michael@0 2937 }
michael@0 2938
michael@0 2939
michael@0 2940 NS_IMETHODIMP
michael@0 2941 nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID,
michael@0 2942 nsIDOMWindow** aWindow)
michael@0 2943 {
michael@0 2944 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2945 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2946 }
michael@0 2947
michael@0 2948 // XXX This method is deprecated. See bug 865664.
michael@0 2949 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
michael@0 2950 NS_LITERAL_CSTRING("DOM"),
michael@0 2951 nsContentUtils::GetDocumentFromCaller(),
michael@0 2952 nsContentUtils::eDOM_PROPERTIES,
michael@0 2953 "GetWindowWithOuterIdWarning");
michael@0 2954
michael@0 2955 *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
michael@0 2956 NS_IF_ADDREF(*aWindow);
michael@0 2957 return NS_OK;
michael@0 2958 }
michael@0 2959
michael@0 2960 NS_IMETHODIMP
michael@0 2961 nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult)
michael@0 2962 {
michael@0 2963 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2964 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2965 }
michael@0 2966
michael@0 2967 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 2968 NS_ENSURE_STATE(window);
michael@0 2969
michael@0 2970 nsCOMPtr<nsIDOMElement> element =
michael@0 2971 do_QueryInterface(window->GetFrameElementInternal());
michael@0 2972
michael@0 2973 element.forget(aResult);
michael@0 2974 return NS_OK;
michael@0 2975 }
michael@0 2976
michael@0 2977 NS_IMETHODIMP
michael@0 2978 nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
michael@0 2979 nsIDOMFile **aDOMFile)
michael@0 2980 {
michael@0 2981 if (!nsContentUtils::IsCallerChrome()) {
michael@0 2982 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 2983 }
michael@0 2984
michael@0 2985 if (!aFile) {
michael@0 2986 return NS_ERROR_FAILURE;
michael@0 2987 }
michael@0 2988
michael@0 2989 NS_ADDREF(*aDOMFile = new nsDOMFileFile(aFile));
michael@0 2990 return NS_OK;
michael@0 2991 }
michael@0 2992
michael@0 2993 #ifdef DEBUG
michael@0 2994 static bool
michael@0 2995 CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
michael@0 2996 {
michael@0 2997 gfx::Matrix transform;
michael@0 2998 if (!aLayer->GetTransform().Is2D(&transform) ||
michael@0 2999 transform.HasNonIntegerTranslation())
michael@0 3000 return false;
michael@0 3001 transform.NudgeToIntegers();
michael@0 3002 nsIntPoint offset = aOffset + nsIntPoint(transform._31, transform._32);
michael@0 3003
michael@0 3004 Layer* child = aLayer->GetFirstChild();
michael@0 3005 if (child) {
michael@0 3006 while (child) {
michael@0 3007 if (!CheckLeafLayers(child, offset, aCoveredRegion))
michael@0 3008 return false;
michael@0 3009 child = child->GetNextSibling();
michael@0 3010 }
michael@0 3011 } else {
michael@0 3012 nsIntRegion rgn = aLayer->GetVisibleRegion();
michael@0 3013 rgn.MoveBy(offset);
michael@0 3014 nsIntRegion tmp;
michael@0 3015 tmp.And(rgn, *aCoveredRegion);
michael@0 3016 if (!tmp.IsEmpty())
michael@0 3017 return false;
michael@0 3018 aCoveredRegion->Or(*aCoveredRegion, rgn);
michael@0 3019 }
michael@0 3020
michael@0 3021 return true;
michael@0 3022 }
michael@0 3023 #endif
michael@0 3024
michael@0 3025 NS_IMETHODIMP
michael@0 3026 nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult)
michael@0 3027 {
michael@0 3028 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3029 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3030 }
michael@0 3031
michael@0 3032 *aResult = true;
michael@0 3033 #ifdef DEBUG
michael@0 3034 nsIWidget* widget = GetWidget();
michael@0 3035 if (!widget)
michael@0 3036 return NS_ERROR_FAILURE;
michael@0 3037 LayerManager* manager = widget->GetLayerManager();
michael@0 3038 if (!manager)
michael@0 3039 return NS_ERROR_FAILURE;
michael@0 3040 nsPresContext* presContext = GetPresContext();
michael@0 3041 if (!presContext)
michael@0 3042 return NS_ERROR_FAILURE;
michael@0 3043 Layer* root = manager->GetRoot();
michael@0 3044 if (!root)
michael@0 3045 return NS_ERROR_FAILURE;
michael@0 3046
michael@0 3047 nsIntPoint offset(0, 0);
michael@0 3048 nsIntRegion coveredRegion;
michael@0 3049 if (!CheckLeafLayers(root, offset, &coveredRegion)) {
michael@0 3050 *aResult = false;
michael@0 3051 }
michael@0 3052 if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
michael@0 3053 *aResult = false;
michael@0 3054 }
michael@0 3055 #endif
michael@0 3056 return NS_OK;
michael@0 3057 }
michael@0 3058
michael@0 3059 NS_IMETHODIMP
michael@0 3060 nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
michael@0 3061 {
michael@0 3062 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3063 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3064 }
michael@0 3065
michael@0 3066 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3067 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 3068
michael@0 3069 nsPIDOMWindow* innerWindow = window->GetCurrentInnerWindow();
michael@0 3070 *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
michael@0 3071 return NS_OK;
michael@0 3072 }
michael@0 3073
michael@0 3074 NS_IMETHODIMP
michael@0 3075 nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
michael@0 3076 {
michael@0 3077 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3078 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3079 }
michael@0 3080
michael@0 3081 if (!aElement) {
michael@0 3082 return NS_ERROR_INVALID_ARG;
michael@0 3083 }
michael@0 3084
michael@0 3085 nsresult rv;
michael@0 3086 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
michael@0 3087 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3088
michael@0 3089 nsIFrame* frame = content->GetPrimaryFrame();
michael@0 3090
michael@0 3091 if (!frame) {
michael@0 3092 *aResult = false;
michael@0 3093 return NS_OK;
michael@0 3094 }
michael@0 3095
michael@0 3096 *aResult = frame->CheckAndClearPaintedState();
michael@0 3097 return NS_OK;
michael@0 3098 }
michael@0 3099
michael@0 3100 NS_IMETHODIMP
michael@0 3101 nsDOMWindowUtils::EnableDialogs()
michael@0 3102 {
michael@0 3103 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3104 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3105 }
michael@0 3106
michael@0 3107 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3108 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 3109
michael@0 3110 static_cast<nsGlobalWindow*>(window.get())->EnableDialogs();
michael@0 3111 return NS_OK;
michael@0 3112 }
michael@0 3113
michael@0 3114 NS_IMETHODIMP
michael@0 3115 nsDOMWindowUtils::DisableDialogs()
michael@0 3116 {
michael@0 3117 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3118 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3119 }
michael@0 3120
michael@0 3121 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3122 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 3123
michael@0 3124 static_cast<nsGlobalWindow*>(window.get())->DisableDialogs();
michael@0 3125 return NS_OK;
michael@0 3126 }
michael@0 3127
michael@0 3128 NS_IMETHODIMP
michael@0 3129 nsDOMWindowUtils::AreDialogsEnabled(bool* aResult)
michael@0 3130 {
michael@0 3131 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3132 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3133 }
michael@0 3134
michael@0 3135 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3136 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 3137
michael@0 3138 *aResult = static_cast<nsGlobalWindow*>(window.get())->AreDialogsEnabled();
michael@0 3139 return NS_OK;
michael@0 3140 }
michael@0 3141
michael@0 3142 static nsIDOMBlob*
michael@0 3143 GetXPConnectNative(JSContext* aCx, JSObject* aObj) {
michael@0 3144 nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(
michael@0 3145 nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, aObj));
michael@0 3146 return blob;
michael@0 3147 }
michael@0 3148
michael@0 3149 static nsresult
michael@0 3150 GetFileOrBlob(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
michael@0 3151 JS::Handle<JS::Value> aParameters, JSContext* aCx,
michael@0 3152 uint8_t aOptionalArgCount, nsISupports** aResult)
michael@0 3153 {
michael@0 3154 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3155 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3156 }
michael@0 3157
michael@0 3158 nsresult rv;
michael@0 3159
michael@0 3160 nsCOMPtr<nsISupports> file;
michael@0 3161
michael@0 3162 if (aName.IsVoid()) {
michael@0 3163 rv = nsDOMMultipartFile::NewBlob(getter_AddRefs(file));
michael@0 3164 }
michael@0 3165 else {
michael@0 3166 rv = nsDOMMultipartFile::NewFile(aName, getter_AddRefs(file));
michael@0 3167 }
michael@0 3168 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3169
michael@0 3170 nsDOMMultipartFile* domFile =
michael@0 3171 static_cast<nsDOMMultipartFile*>(static_cast<nsIDOMFile*>(file.get()));
michael@0 3172
michael@0 3173 JS::AutoValueArray<2> args(aCx);
michael@0 3174 args[0].set(aBlobParts);
michael@0 3175 args[1].set(aParameters);
michael@0 3176
michael@0 3177 rv = domFile->InitBlob(aCx, aOptionalArgCount, args.begin(), GetXPConnectNative);
michael@0 3178 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3179
michael@0 3180 file.forget(aResult);
michael@0 3181 return NS_OK;
michael@0 3182 }
michael@0 3183
michael@0 3184 NS_IMETHODIMP
michael@0 3185 nsDOMWindowUtils::GetFile(const nsAString& aName, JS::Handle<JS::Value> aBlobParts,
michael@0 3186 JS::Handle<JS::Value> aParameters, JSContext* aCx,
michael@0 3187 uint8_t aOptionalArgCount, nsIDOMFile** aResult)
michael@0 3188 {
michael@0 3189 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3190 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3191 }
michael@0 3192
michael@0 3193 nsCOMPtr<nsISupports> file;
michael@0 3194 nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx,
michael@0 3195 aOptionalArgCount, getter_AddRefs(file));
michael@0 3196 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3197
michael@0 3198 nsCOMPtr<nsIDOMFile> result = do_QueryInterface(file);
michael@0 3199 result.forget(aResult);
michael@0 3200
michael@0 3201 return NS_OK;
michael@0 3202 }
michael@0 3203
michael@0 3204 NS_IMETHODIMP
michael@0 3205 nsDOMWindowUtils::GetBlob(JS::Handle<JS::Value> aBlobParts,
michael@0 3206 JS::Handle<JS::Value> aParameters, JSContext* aCx,
michael@0 3207 uint8_t aOptionalArgCount, nsIDOMBlob** aResult)
michael@0 3208 {
michael@0 3209 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3210 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3211 }
michael@0 3212
michael@0 3213 nsCOMPtr<nsISupports> blob;
michael@0 3214 nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx,
michael@0 3215 aOptionalArgCount, getter_AddRefs(blob));
michael@0 3216 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3217
michael@0 3218 nsCOMPtr<nsIDOMBlob> result = do_QueryInterface(blob);
michael@0 3219 result.forget(aResult);
michael@0 3220
michael@0 3221 return NS_OK;
michael@0 3222 }
michael@0 3223
michael@0 3224 NS_IMETHODIMP
michael@0 3225 nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx,
michael@0 3226 int64_t* aResult)
michael@0 3227 {
michael@0 3228 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3229 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3230 }
michael@0 3231
michael@0 3232 if (!JSVAL_IS_PRIMITIVE(aFile)) {
michael@0 3233 JSObject* obj = JSVAL_TO_OBJECT(aFile);
michael@0 3234
michael@0 3235 file::FileHandle* fileHandle;
michael@0 3236 if (NS_SUCCEEDED(UNWRAP_OBJECT(FileHandle, obj, fileHandle))) {
michael@0 3237 *aResult = fileHandle->GetFileId();
michael@0 3238 return NS_OK;
michael@0 3239 }
michael@0 3240
michael@0 3241 nsISupports* nativeObj =
michael@0 3242 nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
michael@0 3243
michael@0 3244 nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(nativeObj);
michael@0 3245 if (blob) {
michael@0 3246 *aResult = blob->GetFileId();
michael@0 3247 return NS_OK;
michael@0 3248 }
michael@0 3249 }
michael@0 3250
michael@0 3251 *aResult = -1;
michael@0 3252 return NS_OK;
michael@0 3253 }
michael@0 3254
michael@0 3255 NS_IMETHODIMP
michael@0 3256 nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
michael@0 3257 JS::Handle<JS::Value> aOptions,
michael@0 3258 int32_t* aRefCnt, int32_t* aDBRefCnt,
michael@0 3259 int32_t* aSliceRefCnt, JSContext* aCx,
michael@0 3260 bool* aResult)
michael@0 3261 {
michael@0 3262 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3263 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3264 }
michael@0 3265
michael@0 3266 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3267 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 3268
michael@0 3269 nsCString origin;
michael@0 3270 quota::PersistenceType defaultPersistenceType;
michael@0 3271 nsresult rv =
michael@0 3272 quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr,
michael@0 3273 &defaultPersistenceType);
michael@0 3274 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3275
michael@0 3276 IDBOpenDBOptions options;
michael@0 3277 JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
michael@0 3278 if (!options.Init(aCx, optionsVal)) {
michael@0 3279 return NS_ERROR_TYPE_ERR;
michael@0 3280 }
michael@0 3281
michael@0 3282 quota::PersistenceType persistenceType =
michael@0 3283 quota::PersistenceTypeFromStorage(options.mStorage, defaultPersistenceType);
michael@0 3284
michael@0 3285 nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
michael@0 3286 indexedDB::IndexedDatabaseManager::Get();
michael@0 3287
michael@0 3288 if (mgr) {
michael@0 3289 rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName,
michael@0 3290 aId, aRefCnt, aDBRefCnt, aSliceRefCnt,
michael@0 3291 aResult);
michael@0 3292 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3293 }
michael@0 3294 else {
michael@0 3295 *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;
michael@0 3296 *aResult = false;
michael@0 3297 }
michael@0 3298
michael@0 3299 return NS_OK;
michael@0 3300 }
michael@0 3301
michael@0 3302 NS_IMETHODIMP
michael@0 3303 nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
michael@0 3304 {
michael@0 3305 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3306 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3307 }
michael@0 3308
michael@0 3309 *aResult = JS::IsIncrementalGCEnabled(JS_GetRuntime(cx));
michael@0 3310 return NS_OK;
michael@0 3311 }
michael@0 3312
michael@0 3313 NS_IMETHODIMP
michael@0 3314 nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
michael@0 3315 {
michael@0 3316 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3317 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3318 }
michael@0 3319
michael@0 3320 js::StartPCCountProfiling(cx);
michael@0 3321 return NS_OK;
michael@0 3322 }
michael@0 3323
michael@0 3324 NS_IMETHODIMP
michael@0 3325 nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
michael@0 3326 {
michael@0 3327 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3328 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3329 }
michael@0 3330
michael@0 3331 js::StopPCCountProfiling(cx);
michael@0 3332 return NS_OK;
michael@0 3333 }
michael@0 3334
michael@0 3335 NS_IMETHODIMP
michael@0 3336 nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
michael@0 3337 {
michael@0 3338 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3339 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3340 }
michael@0 3341
michael@0 3342 js::PurgePCCounts(cx);
michael@0 3343 return NS_OK;
michael@0 3344 }
michael@0 3345
michael@0 3346 NS_IMETHODIMP
michael@0 3347 nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
michael@0 3348 {
michael@0 3349 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3350 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3351 }
michael@0 3352
michael@0 3353 *result = js::GetPCCountScriptCount(cx);
michael@0 3354 return NS_OK;
michael@0 3355 }
michael@0 3356
michael@0 3357 NS_IMETHODIMP
michael@0 3358 nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result)
michael@0 3359 {
michael@0 3360 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3361 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3362 }
michael@0 3363
michael@0 3364 JSString *text = js::GetPCCountScriptSummary(cx, script);
michael@0 3365 if (!text)
michael@0 3366 return NS_ERROR_FAILURE;
michael@0 3367
michael@0 3368 nsDependentJSString str;
michael@0 3369 if (!str.init(cx, text))
michael@0 3370 return NS_ERROR_FAILURE;
michael@0 3371
michael@0 3372 result = str;
michael@0 3373 return NS_OK;
michael@0 3374 }
michael@0 3375
michael@0 3376 NS_IMETHODIMP
michael@0 3377 nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result)
michael@0 3378 {
michael@0 3379 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3380 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3381 }
michael@0 3382
michael@0 3383 JSString *text = js::GetPCCountScriptContents(cx, script);
michael@0 3384 if (!text)
michael@0 3385 return NS_ERROR_FAILURE;
michael@0 3386
michael@0 3387 nsDependentJSString str;
michael@0 3388 if (!str.init(cx, text))
michael@0 3389 return NS_ERROR_FAILURE;
michael@0 3390
michael@0 3391 result = str;
michael@0 3392 return NS_OK;
michael@0 3393 }
michael@0 3394
michael@0 3395 NS_IMETHODIMP
michael@0 3396 nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
michael@0 3397 {
michael@0 3398 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3399 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3400 }
michael@0 3401
michael@0 3402 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3403 NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
michael@0 3404 nsIDocShell *docShell = window->GetDocShell();
michael@0 3405 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
michael@0 3406
michael@0 3407 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
michael@0 3408 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
michael@0 3409
michael@0 3410 *aPaintingSuppressed = presShell->IsPaintingSuppressed();
michael@0 3411 return NS_OK;
michael@0 3412 }
michael@0 3413
michael@0 3414 NS_IMETHODIMP
michael@0 3415 nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins)
michael@0 3416 {
michael@0 3417 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3418 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3419 }
michael@0 3420
michael@0 3421 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 3422 NS_ENSURE_STATE(doc);
michael@0 3423
michael@0 3424 nsTArray<nsIObjectLoadingContent*> plugins;
michael@0 3425 doc->GetPlugins(plugins);
michael@0 3426
michael@0 3427 JS::Rooted<JSObject*> jsPlugins(cx);
michael@0 3428 nsresult rv = nsTArrayToJSArray(cx, plugins, jsPlugins.address());
michael@0 3429 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3430
michael@0 3431 aPlugins.setObject(*jsPlugins);
michael@0 3432 return NS_OK;
michael@0 3433 }
michael@0 3434
michael@0 3435 static void
michael@0 3436 MaybeReflowForInflationScreenWidthChange(nsPresContext *aPresContext)
michael@0 3437 {
michael@0 3438 if (aPresContext) {
michael@0 3439 nsIPresShell* presShell = aPresContext->GetPresShell();
michael@0 3440 bool fontInflationWasEnabled = presShell->FontSizeInflationEnabled();
michael@0 3441 presShell->NotifyFontSizeInflationEnabledIsDirty();
michael@0 3442 bool changed = false;
michael@0 3443 if (presShell && presShell->FontSizeInflationEnabled() &&
michael@0 3444 presShell->FontSizeInflationMinTwips() != 0) {
michael@0 3445 aPresContext->ScreenWidthInchesForFontInflation(&changed);
michael@0 3446 }
michael@0 3447
michael@0 3448 changed = changed ||
michael@0 3449 (fontInflationWasEnabled != presShell->FontSizeInflationEnabled());
michael@0 3450 if (changed) {
michael@0 3451 nsCOMPtr<nsIDocShell> docShell = aPresContext->GetDocShell();
michael@0 3452 if (docShell) {
michael@0 3453 nsCOMPtr<nsIContentViewer> cv;
michael@0 3454 docShell->GetContentViewer(getter_AddRefs(cv));
michael@0 3455 nsCOMPtr<nsIMarkupDocumentViewer> mudv = do_QueryInterface(cv);
michael@0 3456 if (mudv) {
michael@0 3457 nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> > array;
michael@0 3458 mudv->AppendSubtree(array);
michael@0 3459 for (uint32_t i = 0, iEnd = array.Length(); i < iEnd; ++i) {
michael@0 3460 nsCOMPtr<nsIPresShell> shell;
michael@0 3461 nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(array[i]);
michael@0 3462 cv->GetPresShell(getter_AddRefs(shell));
michael@0 3463 if (shell) {
michael@0 3464 nsIFrame *rootFrame = shell->GetRootFrame();
michael@0 3465 if (rootFrame) {
michael@0 3466 shell->FrameNeedsReflow(rootFrame,
michael@0 3467 nsIPresShell::eStyleChange,
michael@0 3468 NS_FRAME_IS_DIRTY);
michael@0 3469 }
michael@0 3470 }
michael@0 3471 }
michael@0 3472 }
michael@0 3473 }
michael@0 3474 }
michael@0 3475 }
michael@0 3476 }
michael@0 3477
michael@0 3478 NS_IMETHODIMP
michael@0 3479 nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
michael@0 3480 {
michael@0 3481 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3482 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3483 }
michael@0 3484
michael@0 3485 if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
michael@0 3486 return NS_ERROR_ILLEGAL_VALUE;
michael@0 3487 }
michael@0 3488
michael@0 3489 nsIPresShell* presShell = GetPresShell();
michael@0 3490 if (!presShell) {
michael@0 3491 return NS_ERROR_FAILURE;
michael@0 3492 }
michael@0 3493
michael@0 3494 presShell->SetScrollPositionClampingScrollPortSize(
michael@0 3495 nsPresContext::CSSPixelsToAppUnits(aWidth),
michael@0 3496 nsPresContext::CSSPixelsToAppUnits(aHeight));
michael@0 3497
michael@0 3498 // When the "font.size.inflation.minTwips" preference is set, the
michael@0 3499 // layout depends on the size of the screen. Since when the size
michael@0 3500 // of the screen changes, the scroll position clamping scroll port
michael@0 3501 // size also changes, we hook in the needed updates here rather
michael@0 3502 // than adding a separate notification just for this change.
michael@0 3503 nsPresContext* presContext = GetPresContext();
michael@0 3504 MaybeReflowForInflationScreenWidthChange(presContext);
michael@0 3505
michael@0 3506 return NS_OK;
michael@0 3507 }
michael@0 3508
michael@0 3509 NS_IMETHODIMP
michael@0 3510 nsDOMWindowUtils::SetContentDocumentFixedPositionMargins(float aTop, float aRight,
michael@0 3511 float aBottom, float aLeft)
michael@0 3512 {
michael@0 3513 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3514 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3515 }
michael@0 3516
michael@0 3517 if (!(aTop >= 0.0f && aRight >= 0.0f && aBottom >= 0.0f && aLeft >= 0.0f)) {
michael@0 3518 return NS_ERROR_ILLEGAL_VALUE;
michael@0 3519 }
michael@0 3520
michael@0 3521 nsIPresShell* presShell = GetPresShell();
michael@0 3522 if (!presShell) {
michael@0 3523 return NS_ERROR_FAILURE;
michael@0 3524 }
michael@0 3525
michael@0 3526 nsMargin margins(nsPresContext::CSSPixelsToAppUnits(aTop),
michael@0 3527 nsPresContext::CSSPixelsToAppUnits(aRight),
michael@0 3528 nsPresContext::CSSPixelsToAppUnits(aBottom),
michael@0 3529 nsPresContext::CSSPixelsToAppUnits(aLeft));
michael@0 3530 presShell->SetContentDocumentFixedPositionMargins(margins);
michael@0 3531
michael@0 3532 return NS_OK;
michael@0 3533 }
michael@0 3534
michael@0 3535 nsresult
michael@0 3536 nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
michael@0 3537 const nsAString& aNewOrigin)
michael@0 3538 {
michael@0 3539 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3540 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3541 }
michael@0 3542
michael@0 3543 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 3544 NS_ENSURE_STATE(doc);
michael@0 3545
michael@0 3546 doc->RemoteFrameFullscreenChanged(aFrameElement, aNewOrigin);
michael@0 3547 return NS_OK;
michael@0 3548 }
michael@0 3549
michael@0 3550 nsresult
michael@0 3551 nsDOMWindowUtils::RemoteFrameFullscreenReverted()
michael@0 3552 {
michael@0 3553 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3554 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3555 }
michael@0 3556
michael@0 3557 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 3558 NS_ENSURE_STATE(doc);
michael@0 3559
michael@0 3560 doc->RemoteFrameFullscreenReverted();
michael@0 3561 return NS_OK;
michael@0 3562 }
michael@0 3563
michael@0 3564 nsresult
michael@0 3565 nsDOMWindowUtils::ExitFullscreen()
michael@0 3566 {
michael@0 3567 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3568 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3569 }
michael@0 3570
michael@0 3571 nsIDocument::ExitFullscreen(nullptr, /* async */ false);
michael@0 3572 return NS_OK;
michael@0 3573 }
michael@0 3574
michael@0 3575 NS_IMETHODIMP
michael@0 3576 nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior,
michael@0 3577 bool *_retval)
michael@0 3578 {
michael@0 3579 *_retval = false;
michael@0 3580 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3581 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3582 }
michael@0 3583
michael@0 3584 nsSelectionAmount amount;
michael@0 3585 switch (aSelectBehavior) {
michael@0 3586 case nsIDOMWindowUtils::SELECT_CHARACTER:
michael@0 3587 amount = eSelectCharacter;
michael@0 3588 break;
michael@0 3589 case nsIDOMWindowUtils::SELECT_CLUSTER:
michael@0 3590 amount = eSelectCluster;
michael@0 3591 break;
michael@0 3592 case nsIDOMWindowUtils::SELECT_WORD:
michael@0 3593 amount = eSelectWord;
michael@0 3594 break;
michael@0 3595 case nsIDOMWindowUtils::SELECT_LINE:
michael@0 3596 amount = eSelectLine;
michael@0 3597 break;
michael@0 3598 case nsIDOMWindowUtils::SELECT_BEGINLINE:
michael@0 3599 amount = eSelectBeginLine;
michael@0 3600 break;
michael@0 3601 case nsIDOMWindowUtils::SELECT_ENDLINE:
michael@0 3602 amount = eSelectEndLine;
michael@0 3603 break;
michael@0 3604 case nsIDOMWindowUtils::SELECT_PARAGRAPH:
michael@0 3605 amount = eSelectParagraph;
michael@0 3606 break;
michael@0 3607 case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
michael@0 3608 amount = eSelectWordNoSpace;
michael@0 3609 break;
michael@0 3610 default:
michael@0 3611 return NS_ERROR_INVALID_ARG;
michael@0 3612 }
michael@0 3613
michael@0 3614 nsIPresShell* presShell = GetPresShell();
michael@0 3615 if (!presShell) {
michael@0 3616 return NS_ERROR_UNEXPECTED;
michael@0 3617 }
michael@0 3618
michael@0 3619 // The root frame for this content window
michael@0 3620 nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
michael@0 3621 if (!rootFrame) {
michael@0 3622 return NS_ERROR_UNEXPECTED;
michael@0 3623 }
michael@0 3624
michael@0 3625 // Get the target frame at the client coordinates passed to us
michael@0 3626 nsPoint offset;
michael@0 3627 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
michael@0 3628 nsIntPoint pt = LayoutDeviceIntPoint::ToUntyped(
michael@0 3629 ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()));
michael@0 3630 nsPoint ptInRoot =
michael@0 3631 nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
michael@0 3632 nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
michael@0 3633 // This can happen if the page hasn't loaded yet or if the point
michael@0 3634 // is outside the frame.
michael@0 3635 if (!targetFrame) {
michael@0 3636 return NS_ERROR_INVALID_ARG;
michael@0 3637 }
michael@0 3638
michael@0 3639 // Convert point to coordinates relative to the target frame, which is
michael@0 3640 // what targetFrame's SelectByTypeAtPoint expects.
michael@0 3641 nsPoint relPoint =
michael@0 3642 nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
michael@0 3643
michael@0 3644 nsresult rv =
michael@0 3645 static_cast<nsFrame*>(targetFrame)->
michael@0 3646 SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
michael@0 3647 nsFrame::SELECT_ACCUMULATE);
michael@0 3648 *_retval = !NS_FAILED(rv);
michael@0 3649 return NS_OK;
michael@0 3650 }
michael@0 3651
michael@0 3652 static nsIDocument::additionalSheetType
michael@0 3653 convertSheetType(uint32_t aSheetType)
michael@0 3654 {
michael@0 3655 switch(aSheetType) {
michael@0 3656 case nsDOMWindowUtils::AGENT_SHEET:
michael@0 3657 return nsIDocument::eAgentSheet;
michael@0 3658 case nsDOMWindowUtils::USER_SHEET:
michael@0 3659 return nsIDocument::eUserSheet;
michael@0 3660 case nsDOMWindowUtils::AUTHOR_SHEET:
michael@0 3661 return nsIDocument::eAuthorSheet;
michael@0 3662 default:
michael@0 3663 NS_ASSERTION(false, "wrong type");
michael@0 3664 // we must return something although this should never happen
michael@0 3665 return nsIDocument::SheetTypeCount;
michael@0 3666 }
michael@0 3667 }
michael@0 3668
michael@0 3669 NS_IMETHODIMP
michael@0 3670 nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType)
michael@0 3671 {
michael@0 3672 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3673 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3674 }
michael@0 3675
michael@0 3676 NS_ENSURE_ARG_POINTER(aSheetURI);
michael@0 3677 NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
michael@0 3678 aSheetType == USER_SHEET ||
michael@0 3679 aSheetType == AUTHOR_SHEET);
michael@0 3680
michael@0 3681 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 3682 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
michael@0 3683
michael@0 3684 nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
michael@0 3685
michael@0 3686 return doc->LoadAdditionalStyleSheet(type, aSheetURI);
michael@0 3687 }
michael@0 3688
michael@0 3689 NS_IMETHODIMP
michael@0 3690 nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
michael@0 3691 {
michael@0 3692 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3693 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3694 }
michael@0 3695
michael@0 3696 NS_ENSURE_ARG_POINTER(aSheetURI);
michael@0 3697 NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
michael@0 3698 aSheetType == USER_SHEET ||
michael@0 3699 aSheetType == AUTHOR_SHEET);
michael@0 3700
michael@0 3701 nsCOMPtr<nsIDocument> doc = GetDocument();
michael@0 3702 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
michael@0 3703
michael@0 3704 nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
michael@0 3705
michael@0 3706 doc->RemoveAdditionalStyleSheet(type, aSheetURI);
michael@0 3707 return NS_OK;
michael@0 3708 }
michael@0 3709
michael@0 3710 NS_IMETHODIMP
michael@0 3711 nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput)
michael@0 3712 {
michael@0 3713 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3714 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3715 }
michael@0 3716
michael@0 3717 *aHandlingUserInput = EventStateManager::IsHandlingUserInput();
michael@0 3718
michael@0 3719 return NS_OK;
michael@0 3720 }
michael@0 3721
michael@0 3722 NS_IMETHODIMP
michael@0 3723 nsDOMWindowUtils::AllowScriptsToClose()
michael@0 3724 {
michael@0 3725 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3726 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3727 }
michael@0 3728 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3729 NS_ENSURE_STATE(window);
michael@0 3730 static_cast<nsGlobalWindow*>(window.get())->AllowScriptsToClose();
michael@0 3731 return NS_OK;
michael@0 3732 }
michael@0 3733
michael@0 3734 NS_IMETHODIMP
michael@0 3735 nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible)
michael@0 3736 {
michael@0 3737 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3738 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3739 }
michael@0 3740
michael@0 3741 // this should reflect the "is parent window visible" logic in
michael@0 3742 // nsWindowWatcher::OpenWindowInternal()
michael@0 3743 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3744 NS_ENSURE_STATE(window);
michael@0 3745
michael@0 3746 nsCOMPtr<nsIWidget> parentWidget;
michael@0 3747 nsIDocShell *docShell = window->GetDocShell();
michael@0 3748 if (docShell) {
michael@0 3749 if (TabChild *tabChild = TabChild::GetFrom(docShell)) {
michael@0 3750 if (!tabChild->SendIsParentWindowMainWidgetVisible(aIsVisible))
michael@0 3751 return NS_ERROR_FAILURE;
michael@0 3752 return NS_OK;
michael@0 3753 }
michael@0 3754
michael@0 3755 nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
michael@0 3756 docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner));
michael@0 3757 nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner));
michael@0 3758 if (parentWindow) {
michael@0 3759 parentWindow->GetMainWidget(getter_AddRefs(parentWidget));
michael@0 3760 }
michael@0 3761 }
michael@0 3762 if (!parentWidget) {
michael@0 3763 return NS_ERROR_NOT_AVAILABLE;
michael@0 3764 }
michael@0 3765
michael@0 3766 *aIsVisible = parentWidget->IsVisible();
michael@0 3767 return NS_OK;
michael@0 3768 }
michael@0 3769
michael@0 3770 NS_IMETHODIMP
michael@0 3771 nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal)
michael@0 3772 {
michael@0 3773 *aRetVal = false;
michael@0 3774 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3775 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3776 }
michael@0 3777 nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
michael@0 3778 nsINode* node = n;
michael@0 3779 while (node) {
michael@0 3780 if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
michael@0 3781 nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
michael@0 3782 if (fc && fc->IsDisabledForEvents(NS_EVENT_NULL)) {
michael@0 3783 *aRetVal = true;
michael@0 3784 break;
michael@0 3785 }
michael@0 3786 }
michael@0 3787 node = node->GetParentNode();
michael@0 3788 }
michael@0 3789
michael@0 3790 return NS_OK;
michael@0 3791 }
michael@0 3792
michael@0 3793 NS_IMETHODIMP
michael@0 3794 nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing)
michael@0 3795 {
michael@0 3796 nsPresContext* presContext = GetPresContext();
michael@0 3797 if (presContext) {
michael@0 3798 presContext->SetPaintFlashing(aPaintFlashing);
michael@0 3799 // Clear paint flashing colors
michael@0 3800 nsIPresShell* presShell = GetPresShell();
michael@0 3801 if (!aPaintFlashing && presShell) {
michael@0 3802 nsIFrame* rootFrame = presShell->GetRootFrame();
michael@0 3803 if (rootFrame) {
michael@0 3804 rootFrame->InvalidateFrameSubtree();
michael@0 3805 }
michael@0 3806 }
michael@0 3807 }
michael@0 3808 return NS_OK;
michael@0 3809 }
michael@0 3810
michael@0 3811 NS_IMETHODIMP
michael@0 3812 nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal)
michael@0 3813 {
michael@0 3814 *aRetVal = false;
michael@0 3815 nsPresContext* presContext = GetPresContext();
michael@0 3816 if (presContext) {
michael@0 3817 *aRetVal = presContext->GetPaintFlashing();
michael@0 3818 }
michael@0 3819 return NS_OK;
michael@0 3820 }
michael@0 3821
michael@0 3822 NS_IMETHODIMP
michael@0 3823 nsDOMWindowUtils::DispatchEventToChromeOnly(nsIDOMEventTarget* aTarget,
michael@0 3824 nsIDOMEvent* aEvent,
michael@0 3825 bool* aRetVal)
michael@0 3826 {
michael@0 3827 *aRetVal = false;
michael@0 3828 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3829 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3830 }
michael@0 3831 NS_ENSURE_STATE(aTarget && aEvent);
michael@0 3832 aEvent->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
michael@0 3833 aTarget->DispatchEvent(aEvent, aRetVal);
michael@0 3834 return NS_OK;
michael@0 3835 }
michael@0 3836
michael@0 3837 NS_IMETHODIMP
michael@0 3838 nsDOMWindowUtils::RunInStableState(nsIRunnable *runnable)
michael@0 3839 {
michael@0 3840 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3841 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3842 }
michael@0 3843
michael@0 3844 nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
michael@0 3845 if (!appShell) {
michael@0 3846 return NS_ERROR_NOT_AVAILABLE;
michael@0 3847 }
michael@0 3848
michael@0 3849 return appShell->RunInStableState(runnable);
michael@0 3850 }
michael@0 3851
michael@0 3852 NS_IMETHODIMP
michael@0 3853 nsDOMWindowUtils::RunBeforeNextEvent(nsIRunnable *runnable)
michael@0 3854 {
michael@0 3855 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3856 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3857 }
michael@0 3858
michael@0 3859 nsCOMPtr<nsIAppShell> appShell(do_GetService(kAppShellCID));
michael@0 3860 if (!appShell) {
michael@0 3861 return NS_ERROR_NOT_AVAILABLE;
michael@0 3862 }
michael@0 3863
michael@0 3864 return appShell->RunBeforeNextEvent(runnable);
michael@0 3865 }
michael@0 3866
michael@0 3867 NS_IMETHODIMP
michael@0 3868 nsDOMWindowUtils::GetOMTAStyle(nsIDOMElement* aElement,
michael@0 3869 const nsAString& aProperty,
michael@0 3870 nsAString& aResult)
michael@0 3871 {
michael@0 3872 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3873 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3874 }
michael@0 3875
michael@0 3876 nsCOMPtr<Element> element = do_QueryInterface(aElement);
michael@0 3877 if (!element) {
michael@0 3878 return NS_ERROR_INVALID_ARG;
michael@0 3879 }
michael@0 3880
michael@0 3881 nsRefPtr<nsROCSSPrimitiveValue> cssValue = nullptr;
michael@0 3882 nsIFrame* frame = element->GetPrimaryFrame();
michael@0 3883 if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) {
michael@0 3884 if (aProperty.EqualsLiteral("opacity")) {
michael@0 3885 Layer* layer =
michael@0 3886 FrameLayerBuilder::GetDedicatedLayer(frame,
michael@0 3887 nsDisplayItem::TYPE_OPACITY);
michael@0 3888 if (layer) {
michael@0 3889 float value;
michael@0 3890 ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
michael@0 3891 if (forwarder && forwarder->HasShadowManager()) {
michael@0 3892 forwarder->GetShadowManager()->SendGetOpacity(
michael@0 3893 layer->AsShadowableLayer()->GetShadow(), &value);
michael@0 3894 cssValue = new nsROCSSPrimitiveValue;
michael@0 3895 cssValue->SetNumber(value);
michael@0 3896 }
michael@0 3897 }
michael@0 3898 } else if (aProperty.EqualsLiteral("transform")) {
michael@0 3899 Layer* layer =
michael@0 3900 FrameLayerBuilder::GetDedicatedLayer(frame,
michael@0 3901 nsDisplayItem::TYPE_TRANSFORM);
michael@0 3902 if (layer) {
michael@0 3903 ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder();
michael@0 3904 if (forwarder && forwarder->HasShadowManager()) {
michael@0 3905 MaybeTransform transform;
michael@0 3906 forwarder->GetShadowManager()->SendGetAnimationTransform(
michael@0 3907 layer->AsShadowableLayer()->GetShadow(), &transform);
michael@0 3908 if (transform.type() == MaybeTransform::Tgfx3DMatrix) {
michael@0 3909 cssValue =
michael@0 3910 nsComputedDOMStyle::MatrixToCSSValue(transform.get_gfx3DMatrix());
michael@0 3911 }
michael@0 3912 }
michael@0 3913 }
michael@0 3914 }
michael@0 3915 }
michael@0 3916
michael@0 3917 if (cssValue) {
michael@0 3918 nsString text;
michael@0 3919 ErrorResult rv;
michael@0 3920 cssValue->GetCssText(text, rv);
michael@0 3921 aResult.Assign(text);
michael@0 3922 return rv.ErrorCode();
michael@0 3923 } else {
michael@0 3924 aResult.Truncate();
michael@0 3925 }
michael@0 3926
michael@0 3927 return NS_OK;
michael@0 3928 }
michael@0 3929
michael@0 3930 NS_IMETHODIMP
michael@0 3931 nsDOMWindowUtils::GetOMTAOrComputedStyle(nsIDOMElement* aElement,
michael@0 3932 const nsAString& aProperty,
michael@0 3933 nsAString& aResult)
michael@0 3934 {
michael@0 3935 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3936 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3937 }
michael@0 3938
michael@0 3939 // Try to get OMTA style
michael@0 3940 nsresult rv = GetOMTAStyle(aElement, aProperty, aResult);
michael@0 3941 if (NS_FAILED(rv) || !aResult.IsEmpty()) {
michael@0 3942 return rv;
michael@0 3943 }
michael@0 3944
michael@0 3945 // Otherwise, fall back to computed style
michael@0 3946 nsCOMPtr<Element> element = do_QueryInterface(aElement);
michael@0 3947 if (!element) {
michael@0 3948 return NS_ERROR_INVALID_ARG;
michael@0 3949 }
michael@0 3950 nsCOMPtr<nsIDOMCSSStyleDeclaration> style;
michael@0 3951 rv = element->GetCurrentDoc()->GetWindow()->
michael@0 3952 GetComputedStyle(aElement, aProperty, getter_AddRefs(style));
michael@0 3953 NS_ENSURE_SUCCESS(rv, rv);
michael@0 3954
michael@0 3955 return style->GetPropertyValue(aProperty, aResult);
michael@0 3956 }
michael@0 3957
michael@0 3958 NS_IMETHODIMP
michael@0 3959 nsDOMWindowUtils::GetAudioMuted(bool* aMuted)
michael@0 3960 {
michael@0 3961 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3962 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3963 }
michael@0 3964 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3965 NS_ENSURE_STATE(window);
michael@0 3966
michael@0 3967 *aMuted = window->GetAudioMuted();
michael@0 3968 return NS_OK;
michael@0 3969 }
michael@0 3970
michael@0 3971 NS_IMETHODIMP
michael@0 3972 nsDOMWindowUtils::SetAudioMuted(bool aMuted)
michael@0 3973 {
michael@0 3974 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3975 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3976 }
michael@0 3977 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3978 NS_ENSURE_STATE(window);
michael@0 3979
michael@0 3980 window->SetAudioMuted(aMuted);
michael@0 3981 return NS_OK;
michael@0 3982 }
michael@0 3983
michael@0 3984 NS_IMETHODIMP
michael@0 3985 nsDOMWindowUtils::GetAudioVolume(float* aVolume)
michael@0 3986 {
michael@0 3987 if (!nsContentUtils::IsCallerChrome()) {
michael@0 3988 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 3989 }
michael@0 3990 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 3991 NS_ENSURE_STATE(window);
michael@0 3992
michael@0 3993 *aVolume = window->GetAudioVolume();
michael@0 3994 return NS_OK;
michael@0 3995 }
michael@0 3996
michael@0 3997 NS_IMETHODIMP
michael@0 3998 nsDOMWindowUtils::SetAudioVolume(float aVolume)
michael@0 3999 {
michael@0 4000 if (!nsContentUtils::IsCallerChrome()) {
michael@0 4001 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 4002 }
michael@0 4003 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 4004 NS_ENSURE_STATE(window);
michael@0 4005
michael@0 4006 return window->SetAudioVolume(aVolume);
michael@0 4007 }
michael@0 4008
michael@0 4009 NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)
michael@0 4010 NS_INTERFACE_MAP_ENTRY(nsISupports)
michael@0 4011 NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList)
michael@0 4012 NS_INTERFACE_MAP_END
michael@0 4013
michael@0 4014 NS_IMPL_ADDREF(nsTranslationNodeList)
michael@0 4015 NS_IMPL_RELEASE(nsTranslationNodeList)
michael@0 4016
michael@0 4017 NS_IMETHODIMP
michael@0 4018 nsTranslationNodeList::Item(uint32_t aIndex, nsIDOMNode** aRetVal)
michael@0 4019 {
michael@0 4020 NS_ENSURE_ARG_POINTER(aRetVal);
michael@0 4021 NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex));
michael@0 4022 return NS_OK;
michael@0 4023 }
michael@0 4024
michael@0 4025 NS_IMETHODIMP
michael@0 4026 nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal)
michael@0 4027 {
michael@0 4028 NS_ENSURE_ARG_POINTER(aRetVal);
michael@0 4029 if (aIndex >= mLength) {
michael@0 4030 *aRetVal = false;
michael@0 4031 return NS_OK;
michael@0 4032 }
michael@0 4033
michael@0 4034 *aRetVal = mNodeIsRoot.ElementAt(aIndex);
michael@0 4035 return NS_OK;
michael@0 4036 }
michael@0 4037
michael@0 4038 NS_IMETHODIMP
michael@0 4039 nsTranslationNodeList::GetLength(uint32_t* aRetVal)
michael@0 4040 {
michael@0 4041 NS_ENSURE_ARG_POINTER(aRetVal);
michael@0 4042 *aRetVal = mLength;
michael@0 4043 return NS_OK;
michael@0 4044 }

mercurial