Fix register allocation bug in return values (bug 604996, r=dmandelin).
[mozilla-central.git] / dom / base / nsDOMWindowUtils.cpp
blobf7ebd0a45fa1be681bb671d2e00660bd176e5d31
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsIDocShell.h"
39 #include "nsPresContext.h"
40 #include "nsDOMClassInfo.h"
41 #include "nsDOMError.h"
42 #include "nsIDOMNSEvent.h"
43 #include "nsIPrivateDOMEvent.h"
44 #include "nsDOMWindowUtils.h"
45 #include "nsQueryContentEventResult.h"
46 #include "nsGlobalWindow.h"
47 #include "nsIDocument.h"
48 #include "nsFocusManager.h"
49 #include "nsIEventStateManager.h"
50 #include "nsEventStateManager.h"
52 #include "nsIScrollableFrame.h"
54 #include "nsContentUtils.h"
55 #include "nsLayoutUtils.h"
57 #include "nsIFrame.h"
58 #include "nsIWidget.h"
59 #include "nsGUIEvent.h"
60 #include "nsIParser.h"
61 #include "nsJSEnvironment.h"
63 #include "nsIViewManager.h"
65 #include "nsIDOMHTMLCanvasElement.h"
66 #include "gfxContext.h"
67 #include "gfxImageSurface.h"
68 #include "nsLayoutUtils.h"
69 #include "nsComputedDOMStyle.h"
70 #include "nsIViewObserver.h"
71 #include "nsIPresShell.h"
73 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
74 #include <gdk/gdk.h>
75 #include <gdk/gdkx.h>
76 #endif
78 #include "jsobj.h"
80 #include "Layers.h"
82 using namespace mozilla::layers;
84 static PRBool IsUniversalXPConnectCapable()
86 PRBool hasCap = PR_FALSE;
87 nsresult rv = nsContentUtils::GetSecurityManager()->
88 IsCapabilityEnabled("UniversalXPConnect", &hasCap);
89 NS_ENSURE_SUCCESS(rv, PR_FALSE);
90 return hasCap;
93 DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
95 NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils)
96 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
97 NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
98 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
99 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils)
100 NS_INTERFACE_MAP_END
102 NS_IMPL_ADDREF(nsDOMWindowUtils)
103 NS_IMPL_RELEASE(nsDOMWindowUtils)
105 nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
106 : mWindow(aWindow)
108 NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
111 nsDOMWindowUtils::~nsDOMWindowUtils()
115 nsIPresShell*
116 nsDOMWindowUtils::GetPresShell()
118 if (!mWindow)
119 return nsnull;
121 nsIDocShell *docShell = mWindow->GetDocShell();
122 if (!docShell)
123 return nsnull;
125 nsCOMPtr<nsIPresShell> presShell;
126 docShell->GetPresShell(getter_AddRefs(presShell));
127 return presShell;
130 nsPresContext*
131 nsDOMWindowUtils::GetPresContext()
133 if (!mWindow)
134 return nsnull;
135 nsIDocShell *docShell = mWindow->GetDocShell();
136 if (!docShell)
137 return nsnull;
138 nsRefPtr<nsPresContext> presContext;
139 docShell->GetPresContext(getter_AddRefs(presContext));
140 return presContext;
143 NS_IMETHODIMP
144 nsDOMWindowUtils::GetImageAnimationMode(PRUint16 *aMode)
146 NS_ENSURE_ARG_POINTER(aMode);
147 *aMode = 0;
148 nsPresContext* presContext = GetPresContext();
149 if (presContext) {
150 *aMode = presContext->ImageAnimationMode();
151 return NS_OK;
153 return NS_ERROR_NOT_AVAILABLE;
156 NS_IMETHODIMP
157 nsDOMWindowUtils::SetImageAnimationMode(PRUint16 aMode)
159 nsPresContext* presContext = GetPresContext();
160 if (presContext) {
161 presContext->SetImageAnimationMode(aMode);
162 return NS_OK;
164 return NS_ERROR_NOT_AVAILABLE;
167 NS_IMETHODIMP
168 nsDOMWindowUtils::GetDocCharsetIsForced(PRBool *aIsForced)
170 *aIsForced = PR_FALSE;
172 if (!IsUniversalXPConnectCapable()) {
173 return NS_ERROR_DOM_SECURITY_ERR;
176 if (mWindow) {
177 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
178 *aIsForced = doc &&
179 doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
181 return NS_OK;
184 NS_IMETHODIMP
185 nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
186 nsAString& aValue)
188 if (!IsUniversalXPConnectCapable()) {
189 return NS_ERROR_DOM_SECURITY_ERR;
192 if (mWindow) {
193 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
194 if (doc) {
195 nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
196 doc->GetHeaderData(name, aValue);
197 return NS_OK;
201 aValue.Truncate();
202 return NS_OK;
205 NS_IMETHODIMP
206 nsDOMWindowUtils::Redraw(PRUint32 aCount, PRUint32 *aDurationOut)
208 if (aCount == 0)
209 aCount = 1;
211 if (nsIPresShell* presShell = GetPresShell()) {
212 nsIFrame *rootFrame = presShell->GetRootFrame();
214 if (rootFrame) {
215 nsRect r(nsPoint(0, 0), rootFrame->GetSize());
217 PRIntervalTime iStart = PR_IntervalNow();
219 for (PRUint32 i = 0; i < aCount; i++)
220 rootFrame->InvalidateWithFlags(r, nsIFrame::INVALIDATE_IMMEDIATE);
222 #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
223 XSync(GDK_DISPLAY(), False);
224 #endif
226 *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
228 return NS_OK;
231 return NS_ERROR_FAILURE;
234 NS_IMETHODIMP
235 nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
237 if (!IsUniversalXPConnectCapable()) {
238 return NS_ERROR_DOM_SECURITY_ERR;
241 if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) {
242 return NS_ERROR_ILLEGAL_VALUE;
245 nsIPresShell* presShell = GetPresShell();
246 if (!presShell) {
247 return NS_ERROR_FAILURE;
250 nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
251 nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
253 presShell->ResizeReflowOverride(width, height);
255 return NS_OK;
258 NS_IMETHODIMP
259 nsDOMWindowUtils::SetDisplayPort(float aXPx, float aYPx,
260 float aWidthPx, float aHeightPx)
262 if (!IsUniversalXPConnectCapable()) {
263 return NS_ERROR_DOM_SECURITY_ERR;
266 nsIPresShell* presShell = GetPresShell();
267 if (!presShell) {
268 return NS_ERROR_FAILURE;
271 nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
272 nsPresContext::CSSPixelsToAppUnits(aYPx),
273 nsPresContext::CSSPixelsToAppUnits(aWidthPx),
274 nsPresContext::CSSPixelsToAppUnits(aHeightPx));
275 presShell->SetDisplayPort(displayport);
277 presShell->SetIgnoreViewportScrolling(PR_TRUE);
279 return NS_OK;
282 NS_IMETHODIMP
283 nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
285 if (!IsUniversalXPConnectCapable()) {
286 return NS_ERROR_DOM_SECURITY_ERR;
289 nsIPresShell* presShell = GetPresShell();
290 return presShell ? presShell->SetResolution(aXResolution, aYResolution)
291 : NS_ERROR_FAILURE;
294 NS_IMETHODIMP
295 nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
296 float aX,
297 float aY,
298 PRInt32 aButton,
299 PRInt32 aClickCount,
300 PRInt32 aModifiers,
301 PRBool aIgnoreRootScrollFrame)
303 return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
304 aIgnoreRootScrollFrame, PR_FALSE);
307 NS_IMETHODIMP
308 nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
309 float aX,
310 float aY,
311 PRInt32 aButton,
312 PRInt32 aClickCount,
313 PRInt32 aModifiers,
314 PRBool aIgnoreRootScrollFrame)
316 return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
317 aIgnoreRootScrollFrame, PR_TRUE);
320 NS_IMETHODIMP
321 nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
322 float aX,
323 float aY,
324 PRInt32 aButton,
325 PRInt32 aClickCount,
326 PRInt32 aModifiers,
327 PRBool aIgnoreRootScrollFrame,
328 PRBool aToWindow)
330 if (!IsUniversalXPConnectCapable()) {
331 return NS_ERROR_DOM_SECURITY_ERR;
334 // get the widget to send the event to
335 nsPoint offset;
336 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
337 if (!widget)
338 return NS_ERROR_FAILURE;
340 PRInt32 msg;
341 PRBool contextMenuKey = PR_FALSE;
342 if (aType.EqualsLiteral("mousedown"))
343 msg = NS_MOUSE_BUTTON_DOWN;
344 else if (aType.EqualsLiteral("mouseup"))
345 msg = NS_MOUSE_BUTTON_UP;
346 else if (aType.EqualsLiteral("mousemove"))
347 msg = NS_MOUSE_MOVE;
348 else if (aType.EqualsLiteral("mouseover"))
349 msg = NS_MOUSE_ENTER;
350 else if (aType.EqualsLiteral("mouseout"))
351 msg = NS_MOUSE_EXIT;
352 else if (aType.EqualsLiteral("contextmenu")) {
353 msg = NS_CONTEXTMENU;
354 contextMenuKey = (aButton == 0);
355 } else
356 return NS_ERROR_FAILURE;
358 nsMouseEvent event(PR_TRUE, msg, widget, nsMouseEvent::eReal,
359 contextMenuKey ?
360 nsMouseEvent::eContextMenuKey : nsMouseEvent::eNormal);
361 event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
362 event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
363 event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
364 event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
365 event.button = aButton;
366 event.widget = widget;
368 event.clickCount = aClickCount;
369 event.time = PR_IntervalNow();
370 event.flags |= NS_EVENT_FLAG_SYNTHETIC_TEST_EVENT;
372 nsPresContext* presContext = GetPresContext();
373 if (!presContext)
374 return NS_ERROR_FAILURE;
376 PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
377 event.refPoint.x =
378 NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aX) + offset.x,
379 appPerDev);
380 event.refPoint.y =
381 NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aY) + offset.y,
382 appPerDev);
383 event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
385 nsresult rv;
386 nsEventStatus status;
387 if (aToWindow) {
388 nsIPresShell* presShell = presContext->PresShell();
389 if (!presShell)
390 return NS_ERROR_FAILURE;
391 nsCOMPtr<nsIViewObserver> vo = do_QueryInterface(presShell);
392 if (!vo)
393 return NS_ERROR_FAILURE;
394 nsIViewManager* viewManager = presShell->GetViewManager();
395 if (!viewManager)
396 return NS_ERROR_FAILURE;
397 nsIView* view = nsnull;
398 rv = viewManager->GetRootView(view);
399 if (NS_FAILED(rv) || !view)
400 return NS_ERROR_FAILURE;
402 status = nsEventStatus_eIgnore;
403 rv = vo->HandleEvent(view, &event, &status);
404 } else {
405 rv = widget->DispatchEvent(&event, status);
407 return rv;
410 NS_IMETHODIMP
411 nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
412 float aX,
413 float aY,
414 PRInt32 aButton,
415 PRInt32 aScrollFlags,
416 PRInt32 aDelta,
417 PRInt32 aModifiers)
419 if (!IsUniversalXPConnectCapable()) {
420 return NS_ERROR_DOM_SECURITY_ERR;
423 // get the widget to send the event to
424 nsPoint offset;
425 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
426 if (!widget)
427 return NS_ERROR_NULL_POINTER;
429 PRInt32 msg;
430 if (aType.EqualsLiteral("DOMMouseScroll"))
431 msg = NS_MOUSE_SCROLL;
432 else if (aType.EqualsLiteral("MozMousePixelScroll"))
433 msg = NS_MOUSE_PIXEL_SCROLL;
434 else
435 return NS_ERROR_UNEXPECTED;
437 nsMouseScrollEvent event(PR_TRUE, msg, widget);
438 event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
439 event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
440 event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
441 event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
442 event.button = aButton;
443 event.widget = widget;
444 event.delta = aDelta;
445 event.scrollFlags = aScrollFlags;
447 event.time = PR_IntervalNow();
449 nsPresContext* presContext = GetPresContext();
450 if (!presContext)
451 return NS_ERROR_FAILURE;
453 PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
454 event.refPoint.x =
455 NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aX) + offset.x,
456 appPerDev);
457 event.refPoint.y =
458 NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aY) + offset.y,
459 appPerDev);
461 nsEventStatus status;
462 return widget->DispatchEvent(&event, status);
465 NS_IMETHODIMP
466 nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
467 PRInt32 aKeyCode,
468 PRInt32 aCharCode,
469 PRInt32 aModifiers,
470 PRBool aPreventDefault,
471 PRBool* aDefaultActionTaken)
473 if (!IsUniversalXPConnectCapable()) {
474 return NS_ERROR_DOM_SECURITY_ERR;
477 // get the widget to send the event to
478 nsCOMPtr<nsIWidget> widget = GetWidget();
479 if (!widget)
480 return NS_ERROR_FAILURE;
482 PRInt32 msg;
483 if (aType.EqualsLiteral("keydown"))
484 msg = NS_KEY_DOWN;
485 else if (aType.EqualsLiteral("keyup"))
486 msg = NS_KEY_UP;
487 else if (aType.EqualsLiteral("keypress"))
488 msg = NS_KEY_PRESS;
489 else
490 return NS_ERROR_FAILURE;
492 nsKeyEvent event(PR_TRUE, msg, widget);
493 event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
494 event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
495 event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
496 event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
498 event.keyCode = aKeyCode;
499 event.charCode = aCharCode;
500 event.refPoint.x = event.refPoint.y = 0;
501 event.time = PR_IntervalNow();
503 if (aPreventDefault) {
504 event.flags |= NS_EVENT_FLAG_NO_DEFAULT;
507 nsEventStatus status;
508 nsresult rv = widget->DispatchEvent(&event, status);
509 NS_ENSURE_SUCCESS(rv, rv);
511 *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
513 return NS_OK;
516 NS_IMETHODIMP
517 nsDOMWindowUtils::SendNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
518 PRInt32 aNativeKeyCode,
519 PRInt32 aModifiers,
520 const nsAString& aCharacters,
521 const nsAString& aUnmodifiedCharacters)
523 if (!IsUniversalXPConnectCapable()) {
524 return NS_ERROR_DOM_SECURITY_ERR;
527 // get the widget to send the event to
528 nsCOMPtr<nsIWidget> widget = GetWidget();
529 if (!widget)
530 return NS_ERROR_FAILURE;
532 return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
533 aModifiers, aCharacters, aUnmodifiedCharacters);
536 NS_IMETHODIMP
537 nsDOMWindowUtils::SendNativeMouseEvent(PRInt32 aScreenX,
538 PRInt32 aScreenY,
539 PRInt32 aNativeMessage,
540 PRInt32 aModifierFlags,
541 nsIDOMElement* aElement)
543 if (!IsUniversalXPConnectCapable()) {
544 return NS_ERROR_DOM_SECURITY_ERR;
547 // get the widget to send the event to
548 nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
549 if (!widget)
550 return NS_ERROR_FAILURE;
552 return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY),
553 aNativeMessage, aModifierFlags);
556 NS_IMETHODIMP
557 nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
559 if (!IsUniversalXPConnectCapable()) {
560 return NS_ERROR_DOM_SECURITY_ERR;
563 // get the widget to send the event to
564 nsCOMPtr<nsIWidget> widget = GetWidget();
565 if (!widget)
566 return NS_ERROR_FAILURE;
568 return widget->ActivateNativeMenuItemAt(indexString);
571 NS_IMETHODIMP
572 nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
574 if (!IsUniversalXPConnectCapable()) {
575 return NS_ERROR_DOM_SECURITY_ERR;
578 // get the widget to send the event to
579 nsCOMPtr<nsIWidget> widget = GetWidget();
580 if (!widget)
581 return NS_ERROR_FAILURE;
583 return widget->ForceUpdateNativeMenuAt(indexString);
586 nsIWidget*
587 nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
589 if (mWindow) {
590 nsIDocShell *docShell = mWindow->GetDocShell();
591 if (docShell) {
592 nsCOMPtr<nsIPresShell> presShell;
593 docShell->GetPresShell(getter_AddRefs(presShell));
594 if (presShell) {
595 nsIFrame* frame = presShell->GetRootFrame();
596 if (frame)
597 return frame->GetView()->GetNearestWidget(aOffset);
602 return nsnull;
605 nsIWidget*
606 nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
608 if (!aElement)
609 return GetWidget();
611 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
612 nsIDocument* doc = content->GetCurrentDoc();
613 nsIPresShell* presShell = doc ? doc->GetShell() : nsnull;
615 if (presShell) {
616 nsIFrame* frame = content->GetPrimaryFrame();
617 if (!frame) {
618 frame = presShell->GetRootFrame();
620 if (frame)
621 return frame->GetNearestWidget();
624 return nsnull;
627 NS_IMETHODIMP
628 nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
630 if (!IsUniversalXPConnectCapable()) {
631 return NS_ERROR_DOM_SECURITY_ERR;
634 nsIFocusManager* fm = nsFocusManager::GetFocusManager();
635 if (fm) {
636 if (aElement)
637 fm->SetFocus(aElement, 0);
638 else
639 fm->ClearFocus(mWindow);
642 return NS_OK;
645 NS_IMETHODIMP
646 nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener)
648 // Always permit this in debug builds.
649 #ifndef DEBUG
650 if (!IsUniversalXPConnectCapable()) {
651 return NS_ERROR_DOM_SECURITY_ERR;
653 #endif
655 nsJSContext::CC(aListener);
657 return NS_OK;
661 NS_IMETHODIMP
662 nsDOMWindowUtils::ProcessUpdates()
664 nsPresContext* presContext = GetPresContext();
665 if (!presContext)
666 return NS_ERROR_UNEXPECTED;
668 nsIPresShell* shell = presContext->GetPresShell();
669 if (!shell)
670 return NS_ERROR_UNEXPECTED;
672 nsIViewManager *viewManager = shell->GetViewManager();
673 if (!viewManager)
674 return NS_ERROR_UNEXPECTED;
676 nsIViewManager::UpdateViewBatch batch;
677 batch.BeginUpdateViewBatch(viewManager);
678 batch.EndUpdateViewBatch(NS_VMREFRESH_IMMEDIATE);
679 return NS_OK;
682 NS_IMETHODIMP
683 nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
684 float aX,
685 float aY,
686 PRUint32 aDirection,
687 PRFloat64 aDelta,
688 PRInt32 aModifiers)
690 if (!IsUniversalXPConnectCapable()) {
691 return NS_ERROR_DOM_SECURITY_ERR;
694 // get the widget to send the event to
695 nsPoint offset;
696 nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
697 if (!widget)
698 return NS_ERROR_FAILURE;
700 PRInt32 msg;
701 if (aType.EqualsLiteral("MozSwipeGesture"))
702 msg = NS_SIMPLE_GESTURE_SWIPE;
703 else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
704 msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
705 else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
706 msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
707 else if (aType.EqualsLiteral("MozMagnifyGesture"))
708 msg = NS_SIMPLE_GESTURE_MAGNIFY;
709 else if (aType.EqualsLiteral("MozRotateGestureStart"))
710 msg = NS_SIMPLE_GESTURE_ROTATE_START;
711 else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
712 msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
713 else if (aType.EqualsLiteral("MozRotateGesture"))
714 msg = NS_SIMPLE_GESTURE_ROTATE;
715 else if (aType.EqualsLiteral("MozTapGesture"))
716 msg = NS_SIMPLE_GESTURE_TAP;
717 else if (aType.EqualsLiteral("MozPressTapGesture"))
718 msg = NS_SIMPLE_GESTURE_PRESSTAP;
719 else
720 return NS_ERROR_FAILURE;
722 nsSimpleGestureEvent event(PR_TRUE, msg, widget, aDirection, aDelta);
723 event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? PR_TRUE : PR_FALSE;
724 event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? PR_TRUE : PR_FALSE;
725 event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? PR_TRUE : PR_FALSE;
726 event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? PR_TRUE : PR_FALSE;
727 event.time = PR_IntervalNow();
729 nsPresContext* presContext = GetPresContext();
730 if (!presContext)
731 return NS_ERROR_FAILURE;
733 PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
734 event.refPoint.x =
735 NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aX) + offset.x,
736 appPerDev);
737 event.refPoint.y =
738 NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aY) + offset.y,
739 appPerDev);
741 nsEventStatus status;
742 return widget->DispatchEvent(&event, status);
745 NS_IMETHODIMP
746 nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
747 PRBool aIgnoreRootScrollFrame,
748 PRBool aFlushLayout,
749 nsIDOMElement** aReturn)
751 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
752 NS_ENSURE_STATE(doc);
754 return doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout,
755 aReturn);
758 NS_IMETHODIMP
759 nsDOMWindowUtils::NodesFromRect(float aX, float aY,
760 float aTopSize, float aRightSize,
761 float aBottomSize, float aLeftSize,
762 PRBool aIgnoreRootScrollFrame,
763 PRBool aFlushLayout,
764 nsIDOMNodeList** aReturn)
766 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
767 NS_ENSURE_STATE(doc);
769 return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize,
770 aIgnoreRootScrollFrame, aFlushLayout, aReturn);
773 static already_AddRefed<gfxImageSurface>
774 CanvasToImageSurface(nsIDOMHTMLCanvasElement *canvas)
776 nsLayoutUtils::SurfaceFromElementResult result =
777 nsLayoutUtils::SurfaceFromElement(canvas,
778 nsLayoutUtils::SFE_WANT_IMAGE_SURFACE);
779 return static_cast<gfxImageSurface*>(result.mSurface.forget().get());
782 NS_IMETHODIMP
783 nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
784 nsIDOMHTMLCanvasElement *aCanvas2,
785 PRUint32* aMaxDifference,
786 PRUint32* retVal)
788 if (!IsUniversalXPConnectCapable()) {
789 return NS_ERROR_DOM_SECURITY_ERR;
792 if (aCanvas1 == nsnull ||
793 aCanvas2 == nsnull ||
794 retVal == nsnull)
795 return NS_ERROR_FAILURE;
797 nsRefPtr<gfxImageSurface> img1 = CanvasToImageSurface(aCanvas1);
798 nsRefPtr<gfxImageSurface> img2 = CanvasToImageSurface(aCanvas2);
800 if (img1 == nsnull || img2 == nsnull ||
801 img1->GetSize() != img2->GetSize() ||
802 img1->Stride() != img2->Stride())
803 return NS_ERROR_FAILURE;
805 int v;
806 gfxIntSize size = img1->GetSize();
807 PRUint32 stride = img1->Stride();
809 // we can optimize for the common all-pass case
810 if (stride == (PRUint32) size.width * 4) {
811 v = memcmp(img1->Data(), img2->Data(), size.width * size.height * 4);
812 if (v == 0) {
813 if (aMaxDifference)
814 *aMaxDifference = 0;
815 *retVal = 0;
816 return NS_OK;
820 PRUint32 dc = 0;
821 PRUint32 different = 0;
823 for (int j = 0; j < size.height; j++) {
824 unsigned char *p1 = img1->Data() + j*stride;
825 unsigned char *p2 = img2->Data() + j*stride;
826 v = memcmp(p1, p2, stride);
828 if (v) {
829 for (int i = 0; i < size.width; i++) {
830 if (*(PRUint32*) p1 != *(PRUint32*) p2) {
832 different++;
834 dc = NS_MAX((PRUint32)abs(p1[0] - p2[0]), dc);
835 dc = NS_MAX((PRUint32)abs(p1[1] - p2[1]), dc);
836 dc = NS_MAX((PRUint32)abs(p1[2] - p2[2]), dc);
837 dc = NS_MAX((PRUint32)abs(p1[3] - p2[3]), dc);
840 p1 += 4;
841 p2 += 4;
846 if (aMaxDifference)
847 *aMaxDifference = dc;
849 *retVal = different;
850 return NS_OK;
853 NS_IMETHODIMP
854 nsDOMWindowUtils::GetIsMozAfterPaintPending(PRBool *aResult)
856 *aResult = PR_FALSE;
857 nsPresContext* presContext = GetPresContext();
858 if (!presContext)
859 return NS_OK;
860 *aResult = presContext->IsDOMPaintEventPending();
861 return NS_OK;
864 NS_IMETHODIMP
865 nsDOMWindowUtils::ClearMozAfterPaintEvents()
867 nsPresContext* presContext = GetPresContext();
868 if (!presContext)
869 return NS_OK;
870 presContext->ClearMozAfterPaintEvents();
871 return NS_OK;
874 NS_IMETHODIMP
875 nsDOMWindowUtils::DisableNonTestMouseEvents(PRBool aDisable)
877 if (!IsUniversalXPConnectCapable()) {
878 return NS_ERROR_DOM_SECURITY_ERR;
881 NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
882 nsIDocShell *docShell = mWindow->GetDocShell();
883 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
884 nsCOMPtr<nsIPresShell> presShell;
885 docShell->GetPresShell(getter_AddRefs(presShell));
886 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
887 presShell->DisableNonTestMouseEvents(aDisable);
888 return NS_OK;
891 NS_IMETHODIMP
892 nsDOMWindowUtils::SuppressEventHandling(PRBool aSuppress)
894 if (!IsUniversalXPConnectCapable()) {
895 return NS_ERROR_DOM_SECURITY_ERR;
898 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
899 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
901 if (aSuppress) {
902 doc->SuppressEventHandling();
903 } else {
904 doc->UnsuppressEventHandlingAndFireEvents(PR_TRUE);
907 return NS_OK;
910 NS_IMETHODIMP
911 nsDOMWindowUtils::GetScrollXY(PRBool aFlushLayout, PRInt32* aScrollX, PRInt32* aScrollY)
913 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
914 NS_ENSURE_STATE(doc);
916 if (aFlushLayout) {
917 doc->FlushPendingNotifications(Flush_Layout);
920 nsPoint scrollPos(0,0);
921 nsIPresShell *presShell = doc->GetShell();
922 if (presShell) {
923 nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
924 if (sf) {
925 scrollPos = sf->GetScrollPosition();
929 *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
930 *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
932 return NS_OK;
935 NS_IMETHODIMP
936 nsDOMWindowUtils::GetIMEIsOpen(PRBool *aState)
938 NS_ENSURE_ARG_POINTER(aState);
940 nsCOMPtr<nsIWidget> widget = GetWidget();
941 if (!widget)
942 return NS_ERROR_FAILURE;
944 // Open state should not be available when IME is not enabled.
945 PRUint32 enabled;
946 nsresult rv = widget->GetIMEEnabled(&enabled);
947 NS_ENSURE_SUCCESS(rv, rv);
948 if (enabled != nsIWidget::IME_STATUS_ENABLED)
949 return NS_ERROR_NOT_AVAILABLE;
951 return widget->GetIMEOpenState(aState);
954 NS_IMETHODIMP
955 nsDOMWindowUtils::GetIMEStatus(PRUint32 *aState)
957 NS_ENSURE_ARG_POINTER(aState);
959 nsCOMPtr<nsIWidget> widget = GetWidget();
960 if (!widget)
961 return NS_ERROR_FAILURE;
963 return widget->GetIMEEnabled(aState);
966 NS_IMETHODIMP
967 nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
969 *aScreenPixels = 1;
971 if (!nsContentUtils::IsCallerTrustedForRead())
972 return NS_ERROR_DOM_SECURITY_ERR;
973 nsPresContext* presContext = GetPresContext();
974 if (!presContext)
975 return NS_OK;
977 *aScreenPixels = float(nsPresContext::AppUnitsPerCSSPixel())/
978 presContext->AppUnitsPerDevPixel();
979 return NS_OK;
982 NS_IMETHODIMP
983 nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
984 nsIDOMEvent* aEvent,
985 PRBool aTrusted,
986 PRBool* aRetVal)
988 if (!nsContentUtils::IsCallerTrustedForRead()) {
989 return NS_ERROR_DOM_SECURITY_ERR;
992 nsPresContext* presContext = GetPresContext();
993 NS_ENSURE_STATE(presContext);
994 nsCOMPtr<nsIPresShell> shell = presContext->GetPresShell();
995 NS_ENSURE_STATE(shell);
996 nsCOMPtr<nsIPrivateDOMEvent> event = do_QueryInterface(aEvent);
997 NS_ENSURE_STATE(event);
998 event->SetTrusted(aTrusted);
999 nsEvent* internalEvent = event->GetInternalNSEvent();
1000 NS_ENSURE_STATE(internalEvent);
1001 nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
1002 NS_ENSURE_STATE(content);
1004 nsEventStatus status = nsEventStatus_eIgnore;
1005 shell->HandleEventWithTarget(internalEvent, nsnull, content,
1006 &status);
1007 *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
1008 return NS_OK;
1011 static void
1012 InitEvent(nsGUIEvent &aEvent, nsIntPoint *aPt = nsnull)
1014 if (aPt) {
1015 aEvent.refPoint = *aPt;
1017 aEvent.time = PR_IntervalNow();
1020 NS_IMETHODIMP
1021 nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType)
1023 if (!IsUniversalXPConnectCapable()) {
1024 return NS_ERROR_DOM_SECURITY_ERR;
1027 // get the widget to send the event to
1028 nsCOMPtr<nsIWidget> widget = GetWidget();
1029 if (!widget) {
1030 return NS_ERROR_FAILURE;
1033 PRUint32 msg;
1034 if (aType.EqualsLiteral("compositionstart")) {
1035 msg = NS_COMPOSITION_START;
1036 } else if (aType.EqualsLiteral("compositionend")) {
1037 msg = NS_COMPOSITION_END;
1038 } else {
1039 return NS_ERROR_FAILURE;
1042 nsCompositionEvent compositionEvent(PR_TRUE, msg, widget);
1043 InitEvent(compositionEvent);
1045 nsEventStatus status;
1046 nsresult rv = widget->DispatchEvent(&compositionEvent, status);
1047 NS_ENSURE_SUCCESS(rv, rv);
1049 return NS_OK;
1052 static void
1053 AppendClause(PRInt32 aClauseLength, PRUint32 aClauseAttr,
1054 nsTArray<nsTextRange>* aRanges)
1056 NS_PRECONDITION(aRanges, "aRange is null");
1057 if (aClauseLength == 0) {
1058 return;
1060 nsTextRange range;
1061 range.mStartOffset = aRanges->Length() == 0 ? 0 :
1062 aRanges->ElementAt(aRanges->Length() - 1).mEndOffset + 1;
1063 range.mEndOffset = range.mStartOffset + aClauseLength;
1064 NS_ASSERTION(range.mStartOffset <= range.mEndOffset, "range is invalid");
1065 NS_PRECONDITION(aClauseAttr == NS_TEXTRANGE_RAWINPUT ||
1066 aClauseAttr == NS_TEXTRANGE_SELECTEDRAWTEXT ||
1067 aClauseAttr == NS_TEXTRANGE_CONVERTEDTEXT ||
1068 aClauseAttr == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT,
1069 "aClauseAttr is invalid value");
1070 range.mRangeType = aClauseAttr;
1071 aRanges->AppendElement(range);
1074 NS_IMETHODIMP
1075 nsDOMWindowUtils::SendTextEvent(const nsAString& aCompositionString,
1076 PRInt32 aFirstClauseLength,
1077 PRUint32 aFirstClauseAttr,
1078 PRInt32 aSecondClauseLength,
1079 PRUint32 aSecondClauseAttr,
1080 PRInt32 aThirdClauseLength,
1081 PRUint32 aThirdClauseAttr,
1082 PRInt32 aCaretStart,
1083 PRInt32 aCaretLength)
1085 if (!IsUniversalXPConnectCapable()) {
1086 return NS_ERROR_DOM_SECURITY_ERR;
1089 // get the widget to send the event to
1090 nsCOMPtr<nsIWidget> widget = GetWidget();
1091 if (!widget) {
1092 return NS_ERROR_FAILURE;
1095 nsTextEvent textEvent(PR_TRUE, NS_TEXT_TEXT, widget);
1096 InitEvent(textEvent);
1098 nsAutoTArray<nsTextRange, 4> textRanges;
1099 NS_ENSURE_TRUE(aFirstClauseLength >= 0, NS_ERROR_INVALID_ARG);
1100 NS_ENSURE_TRUE(aSecondClauseLength >= 0, NS_ERROR_INVALID_ARG);
1101 NS_ENSURE_TRUE(aThirdClauseLength >= 0, NS_ERROR_INVALID_ARG);
1102 AppendClause(aFirstClauseLength, aFirstClauseAttr, &textRanges);
1103 AppendClause(aSecondClauseLength, aSecondClauseAttr, &textRanges);
1104 AppendClause(aThirdClauseLength, aThirdClauseAttr, &textRanges);
1105 PRInt32 len = aFirstClauseLength + aSecondClauseLength + aThirdClauseLength;
1106 NS_ENSURE_TRUE(len == 0 || PRUint32(len) == aCompositionString.Length(),
1107 NS_ERROR_FAILURE);
1109 if (aCaretStart >= 0) {
1110 nsTextRange range;
1111 range.mStartOffset = aCaretStart;
1112 range.mEndOffset = range.mStartOffset + aCaretLength;
1113 range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
1114 textRanges.AppendElement(range);
1117 textEvent.theText = aCompositionString;
1119 textEvent.rangeCount = textRanges.Length();
1120 textEvent.rangeArray = textRanges.Elements();
1122 nsEventStatus status;
1123 nsresult rv = widget->DispatchEvent(&textEvent, status);
1124 NS_ENSURE_SUCCESS(rv, rv);
1126 return NS_OK;
1129 NS_IMETHODIMP
1130 nsDOMWindowUtils::SendQueryContentEvent(PRUint32 aType,
1131 PRUint32 aOffset, PRUint32 aLength,
1132 PRInt32 aX, PRInt32 aY,
1133 nsIQueryContentEventResult **aResult)
1135 *aResult = nsnull;
1137 if (!IsUniversalXPConnectCapable()) {
1138 return NS_ERROR_DOM_SECURITY_ERR;
1141 NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
1143 nsIDocShell *docShell = mWindow->GetDocShell();
1144 NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1146 nsCOMPtr<nsIPresShell> presShell;
1147 docShell->GetPresShell(getter_AddRefs(presShell));
1148 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1150 nsPresContext* presContext = presShell->GetPresContext();
1151 NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
1153 // get the widget to send the event to
1154 nsCOMPtr<nsIWidget> widget = GetWidget();
1155 if (!widget) {
1156 return NS_ERROR_FAILURE;
1159 if (aType != NS_QUERY_SELECTED_TEXT &&
1160 aType != NS_QUERY_TEXT_CONTENT &&
1161 aType != NS_QUERY_CARET_RECT &&
1162 aType != NS_QUERY_TEXT_RECT &&
1163 aType != NS_QUERY_EDITOR_RECT &&
1164 aType != NS_QUERY_CHARACTER_AT_POINT) {
1165 return NS_ERROR_INVALID_ARG;
1168 nsCOMPtr<nsIWidget> targetWidget = widget;
1169 nsIntPoint pt(aX, aY);
1171 if (aType == QUERY_CHARACTER_AT_POINT) {
1172 // Looking for the widget at the point.
1173 nsQueryContentEvent dummyEvent(PR_TRUE, NS_QUERY_CONTENT_STATE, widget);
1174 InitEvent(dummyEvent, &pt);
1175 nsIFrame* popupFrame =
1176 nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
1178 nsIntRect widgetBounds;
1179 nsresult rv = widget->GetClientBounds(widgetBounds);
1180 NS_ENSURE_SUCCESS(rv, rv);
1182 // There is no popup frame at the point and the point isn't in our widget,
1183 // we cannot process this request.
1184 NS_ENSURE_TRUE(popupFrame || widgetBounds.Contains(pt),
1185 NS_ERROR_FAILURE);
1187 // Fire the event on the widget at the point
1188 if (popupFrame) {
1189 targetWidget = popupFrame->GetNearestWidget();
1193 pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset();
1195 nsQueryContentEvent queryEvent(PR_TRUE, aType, targetWidget);
1196 InitEvent(queryEvent, &pt);
1198 switch (aType) {
1199 case NS_QUERY_TEXT_CONTENT:
1200 queryEvent.InitForQueryTextContent(aOffset, aLength);
1201 break;
1202 case NS_QUERY_CARET_RECT:
1203 queryEvent.InitForQueryCaretRect(aOffset);
1204 break;
1205 case NS_QUERY_TEXT_RECT:
1206 queryEvent.InitForQueryTextRect(aOffset, aLength);
1207 break;
1210 nsEventStatus status;
1211 nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
1212 NS_ENSURE_SUCCESS(rv, rv);
1214 nsQueryContentEventResult* result = new nsQueryContentEventResult();
1215 NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
1216 result->SetEventResult(widget, queryEvent);
1217 NS_ADDREF(*aResult = result);
1218 return NS_OK;
1221 NS_IMETHODIMP
1222 nsDOMWindowUtils::SendSelectionSetEvent(PRUint32 aOffset,
1223 PRUint32 aLength,
1224 PRBool aReverse,
1225 PRBool *aResult)
1227 *aResult = PR_FALSE;
1229 if (!IsUniversalXPConnectCapable()) {
1230 return NS_ERROR_DOM_SECURITY_ERR;
1233 // get the widget to send the event to
1234 nsCOMPtr<nsIWidget> widget = GetWidget();
1235 if (!widget) {
1236 return NS_ERROR_FAILURE;
1239 nsSelectionEvent selectionEvent(PR_TRUE, NS_SELECTION_SET, widget);
1240 InitEvent(selectionEvent);
1242 selectionEvent.mOffset = aOffset;
1243 selectionEvent.mLength = aLength;
1244 selectionEvent.mReversed = aReverse;
1246 nsEventStatus status;
1247 nsresult rv = widget->DispatchEvent(&selectionEvent, status);
1248 NS_ENSURE_SUCCESS(rv, rv);
1250 *aResult = selectionEvent.mSucceeded;
1251 return NS_OK;
1254 NS_IMETHODIMP
1255 nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
1256 nsITransferable * aTransferable)
1258 if (!IsUniversalXPConnectCapable()) {
1259 return NS_ERROR_DOM_SECURITY_ERR;
1262 // get the widget to send the event to
1263 nsCOMPtr<nsIWidget> widget = GetWidget();
1264 if (!widget)
1265 return NS_ERROR_FAILURE;
1267 PRInt32 msg;
1268 if (aType.EqualsLiteral("cut"))
1269 msg = NS_CONTENT_COMMAND_CUT;
1270 else if (aType.EqualsLiteral("copy"))
1271 msg = NS_CONTENT_COMMAND_COPY;
1272 else if (aType.EqualsLiteral("paste"))
1273 msg = NS_CONTENT_COMMAND_PASTE;
1274 else if (aType.EqualsLiteral("delete"))
1275 msg = NS_CONTENT_COMMAND_DELETE;
1276 else if (aType.EqualsLiteral("undo"))
1277 msg = NS_CONTENT_COMMAND_UNDO;
1278 else if (aType.EqualsLiteral("redo"))
1279 msg = NS_CONTENT_COMMAND_REDO;
1280 else if (aType.EqualsLiteral("pasteTransferable"))
1281 msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
1282 else
1283 return NS_ERROR_FAILURE;
1285 nsContentCommandEvent event(PR_TRUE, msg, widget);
1286 if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
1287 event.mTransferable = aTransferable;
1290 nsEventStatus status;
1291 return widget->DispatchEvent(&event, status);
1294 NS_IMETHODIMP
1295 nsDOMWindowUtils::GetClassName(char **aName)
1297 if (!nsContentUtils::IsCallerTrustedForRead()) {
1298 return NS_ERROR_DOM_SECURITY_ERR;
1301 // get the xpconnect native call context
1302 nsAXPCNativeCallContext *cc = nsnull;
1303 nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&cc);
1304 if(!cc)
1305 return NS_ERROR_FAILURE;
1307 // Get JSContext of current call
1308 JSContext* cx;
1309 nsresult rv = cc->GetJSContext(&cx);
1310 if(NS_FAILED(rv) || !cx)
1311 return NS_ERROR_FAILURE;
1313 // get argc and argv and verify arg count
1314 PRUint32 argc;
1315 rv = cc->GetArgc(&argc);
1316 if(NS_FAILED(rv))
1317 return NS_ERROR_FAILURE;
1319 if(argc < 1)
1320 return NS_ERROR_XPC_NOT_ENOUGH_ARGS;
1322 jsval* argv;
1323 rv = cc->GetArgvPtr(&argv);
1324 if(NS_FAILED(rv) || !argv)
1325 return NS_ERROR_FAILURE;
1327 // Our argument must be a non-null object.
1328 if(JSVAL_IS_PRIMITIVE(argv[0]))
1329 return NS_ERROR_XPC_BAD_CONVERT_JS;
1331 *aName = NS_strdup(JS_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0]))->name);
1332 return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1335 NS_IMETHODIMP
1336 nsDOMWindowUtils::GetVisitedDependentComputedStyle(
1337 nsIDOMElement *aElement, const nsAString& aPseudoElement,
1338 const nsAString& aPropertyName, nsAString& aResult)
1340 aResult.Truncate();
1342 if (!IsUniversalXPConnectCapable()) {
1343 return NS_ERROR_DOM_SECURITY_ERR;
1346 nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
1347 nsresult rv =
1348 mWindow->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
1349 NS_ENSURE_SUCCESS(rv, rv);
1351 static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(PR_TRUE);
1352 rv = decl->GetPropertyValue(aPropertyName, aResult);
1353 static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(PR_FALSE);
1355 return rv;
1358 NS_IMETHODIMP
1359 nsDOMWindowUtils::EnterModalState()
1361 mWindow->EnterModalState();
1362 return NS_OK;
1365 NS_IMETHODIMP
1366 nsDOMWindowUtils::LeaveModalState()
1368 mWindow->LeaveModalState();
1369 return NS_OK;
1372 NS_IMETHODIMP
1373 nsDOMWindowUtils::IsInModalState(PRBool *retval)
1375 *retval = mWindow->IsInModalState();
1376 return NS_OK;
1379 NS_IMETHODIMP
1380 nsDOMWindowUtils::GetParent()
1382 // This wasn't privileged in the past, but better to expose less than more.
1383 if (!IsUniversalXPConnectCapable()) {
1384 return NS_ERROR_DOM_SECURITY_ERR;
1387 nsCOMPtr<nsIXPConnect> xpc = nsContentUtils::XPConnect();
1389 // get the xpconnect native call context
1390 nsAXPCNativeCallContext *cc = nsnull;
1391 xpc->GetCurrentNativeCallContext(&cc);
1392 if(!cc)
1393 return NS_ERROR_FAILURE;
1395 // Get JSContext of current call
1396 JSContext* cx;
1397 nsresult rv = cc->GetJSContext(&cx);
1398 if(NS_FAILED(rv) || !cx)
1399 return NS_ERROR_FAILURE;
1401 // get place for return value
1402 jsval *rval = nsnull;
1403 rv = cc->GetRetValPtr(&rval);
1404 if(NS_FAILED(rv) || !rval)
1405 return NS_ERROR_FAILURE;
1407 // get argc and argv and verify arg count
1408 PRUint32 argc;
1409 rv = cc->GetArgc(&argc);
1410 if(NS_FAILED(rv))
1411 return NS_ERROR_FAILURE;
1413 if(argc != 1)
1414 return NS_ERROR_XPC_NOT_ENOUGH_ARGS;
1416 jsval* argv;
1417 rv = cc->GetArgvPtr(&argv);
1418 if(NS_FAILED(rv) || !argv)
1419 return NS_ERROR_FAILURE;
1421 // first argument must be an object
1422 if(JSVAL_IS_PRIMITIVE(argv[0]))
1423 return NS_ERROR_XPC_BAD_CONVERT_JS;
1425 JSObject *parent = JS_GetParent(cx, JSVAL_TO_OBJECT(argv[0]));
1426 *rval = OBJECT_TO_JSVAL(parent);
1428 // Outerize if necessary.
1429 if (parent) {
1430 if (JSObjectOp outerize = parent->getClass()->ext.outerObject)
1431 *rval = OBJECT_TO_JSVAL(outerize(cx, parent));
1434 cc->SetReturnValueWasSet(PR_TRUE);
1435 return NS_OK;
1438 NS_IMETHODIMP
1439 nsDOMWindowUtils::GetOuterWindowID(PRUint64 *aWindowID)
1441 NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
1442 *aWindowID = mWindow->WindowID();
1443 return NS_OK;
1446 NS_IMETHODIMP
1447 nsDOMWindowUtils::GetCurrentInnerWindowID(PRUint64 *aWindowID)
1449 NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
1450 nsGlobalWindow* inner = mWindow->GetCurrentInnerWindowInternal();
1451 if (!inner) {
1452 return NS_ERROR_NOT_AVAILABLE;
1454 *aWindowID = inner->WindowID();
1455 return NS_OK;
1458 NS_IMETHODIMP
1459 nsDOMWindowUtils::SuspendTimeouts()
1461 if (!IsUniversalXPConnectCapable()) {
1462 return NS_ERROR_DOM_SECURITY_ERR;
1465 mWindow->SuspendTimeouts();
1467 return NS_OK;
1470 NS_IMETHODIMP
1471 nsDOMWindowUtils::ResumeTimeouts()
1473 if (!IsUniversalXPConnectCapable()) {
1474 return NS_ERROR_DOM_SECURITY_ERR;
1477 mWindow->ResumeTimeouts();
1479 return NS_OK;
1482 NS_IMETHODIMP
1483 nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
1485 nsCOMPtr<nsIWidget> widget = GetWidget();
1486 if (!widget)
1487 return NS_ERROR_FAILURE;
1489 LayerManager *mgr = widget->GetLayerManager();
1490 if (!mgr)
1491 return NS_ERROR_FAILURE;
1493 mgr->GetBackendName(aType);
1495 return NS_OK;
1498 nsresult
1499 nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
1500 PRUint32 aFlags,
1501 nscolor aBackgroundColor,
1502 gfxContext* aThebesContext)
1504 // Get DOM Document
1505 nsresult rv;
1506 nsCOMPtr<nsIDOMDocument> ddoc;
1507 rv = mWindow->GetDocument(getter_AddRefs(ddoc));
1508 NS_ENSURE_SUCCESS(rv, rv);
1510 // Get Document
1511 nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc, &rv);
1512 NS_ENSURE_SUCCESS(rv, rv);
1514 // Get Primary Shell
1515 nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
1516 NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1518 // Render Document
1519 return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
1522 NS_IMETHODIMP
1523 nsDOMWindowUtils::GetCursorType(PRInt16 *aCursor)
1525 NS_ENSURE_ARG_POINTER(aCursor);
1527 PRBool isSameDoc = PR_FALSE;
1528 nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
1530 NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
1532 do {
1533 if (nsEventStateManager::sMouseOverDocument == doc.get()) {
1534 isSameDoc = PR_TRUE;
1535 break;
1537 } while ((doc = doc->GetParentDocument()));
1539 if (!isSameDoc) {
1540 *aCursor = eCursor_none;
1541 return NS_OK;
1544 nsCOMPtr<nsIWidget> widget = GetWidget();
1545 if (!widget)
1546 return NS_ERROR_FAILURE;
1548 // fetch cursor value from window's widget
1549 *aCursor = widget->GetCursor();
1551 return NS_OK;
1554 NS_IMETHODIMP
1555 nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
1557 nsCOMPtr<nsIWidget> widget = GetWidget();
1558 if (!widget)
1559 return NS_ERROR_FAILURE;
1561 *aDPI = widget->GetDPI();
1563 return NS_OK;
1567 NS_IMETHODIMP
1568 nsDOMWindowUtils::GetOuterWindowWithId(PRUint64 aWindowID,
1569 nsIDOMWindow** aWindow)
1571 if (!IsUniversalXPConnectCapable()) {
1572 return NS_ERROR_DOM_SECURITY_ERR;
1575 *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
1576 NS_IF_ADDREF(*aWindow);
1577 return NS_OK;