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
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : *
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.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "nsIDocShell.h"
39 : #include "nsPresContext.h"
40 : #include "nsDOMClassInfoID.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 "nsEventStateManager.h"
50 : #include "nsFrameManager.h"
51 : #include "nsRefreshDriver.h"
52 : #include "nsDOMTouchEvent.h"
53 : #include "nsIDOMTouchEvent.h"
54 :
55 : #include "nsIScrollableFrame.h"
56 :
57 : #include "nsContentUtils.h"
58 : #include "nsLayoutUtils.h"
59 :
60 : #include "nsIFrame.h"
61 : #include "nsIWidget.h"
62 : #include "nsGUIEvent.h"
63 : #include "nsIParser.h"
64 : #include "nsJSEnvironment.h"
65 : #include "nsJSUtils.h"
66 :
67 : #include "nsIViewManager.h"
68 :
69 : #include "nsIDOMHTMLCanvasElement.h"
70 : #include "gfxContext.h"
71 : #include "gfxImageSurface.h"
72 : #include "nsLayoutUtils.h"
73 : #include "nsComputedDOMStyle.h"
74 : #include "nsIPresShell.h"
75 : #include "nsStyleAnimation.h"
76 : #include "nsCSSProps.h"
77 : #include "nsDOMFile.h"
78 : #include "BasicLayers.h"
79 :
80 : #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
81 : #include <gdk/gdk.h>
82 : #include <gdk/gdkx.h>
83 : #endif
84 :
85 : #include "Layers.h"
86 : #include "nsIIOService.h"
87 :
88 : #include "mozilla/dom/Element.h"
89 : #include "mozilla/dom/indexedDB/FileInfo.h"
90 : #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
91 : #include "sampler.h"
92 :
93 : using namespace mozilla::dom;
94 : using namespace mozilla::layers;
95 : using namespace mozilla::widget;
96 :
97 0 : static bool IsUniversalXPConnectCapable()
98 : {
99 0 : bool hasCap = false;
100 0 : nsresult rv = nsContentUtils::GetSecurityManager()->
101 0 : IsCapabilityEnabled("UniversalXPConnect", &hasCap);
102 0 : NS_ENSURE_SUCCESS(rv, false);
103 0 : return hasCap;
104 : }
105 :
106 : DOMCI_DATA(WindowUtils, nsDOMWindowUtils)
107 :
108 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMWindowUtils)
109 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMWindowUtils)
110 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mWindow)
111 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
112 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMWindowUtils)
113 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mWindow,
114 : nsIScriptGlobalObject)
115 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
116 :
117 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMWindowUtils)
118 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils)
119 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils)
120 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
121 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WindowUtils)
122 0 : NS_INTERFACE_MAP_END
123 :
124 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMWindowUtils)
125 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMWindowUtils)
126 :
127 0 : nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindow *aWindow)
128 0 : : mWindow(aWindow)
129 : {
130 0 : NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
131 0 : }
132 :
133 0 : nsDOMWindowUtils::~nsDOMWindowUtils()
134 : {
135 0 : }
136 :
137 : nsIPresShell*
138 0 : nsDOMWindowUtils::GetPresShell()
139 : {
140 0 : if (!mWindow)
141 0 : return nsnull;
142 :
143 0 : nsIDocShell *docShell = mWindow->GetDocShell();
144 0 : if (!docShell)
145 0 : return nsnull;
146 :
147 0 : nsCOMPtr<nsIPresShell> presShell;
148 0 : docShell->GetPresShell(getter_AddRefs(presShell));
149 0 : return presShell;
150 : }
151 :
152 : nsPresContext*
153 0 : nsDOMWindowUtils::GetPresContext()
154 : {
155 0 : if (!mWindow)
156 0 : return nsnull;
157 0 : nsIDocShell *docShell = mWindow->GetDocShell();
158 0 : if (!docShell)
159 0 : return nsnull;
160 0 : nsRefPtr<nsPresContext> presContext;
161 0 : docShell->GetPresContext(getter_AddRefs(presContext));
162 0 : return presContext;
163 : }
164 :
165 : NS_IMETHODIMP
166 0 : nsDOMWindowUtils::GetImageAnimationMode(PRUint16 *aMode)
167 : {
168 0 : NS_ENSURE_ARG_POINTER(aMode);
169 0 : *aMode = 0;
170 0 : nsPresContext* presContext = GetPresContext();
171 0 : if (presContext) {
172 0 : *aMode = presContext->ImageAnimationMode();
173 0 : return NS_OK;
174 : }
175 0 : return NS_ERROR_NOT_AVAILABLE;
176 : }
177 :
178 : NS_IMETHODIMP
179 0 : nsDOMWindowUtils::SetImageAnimationMode(PRUint16 aMode)
180 : {
181 0 : nsPresContext* presContext = GetPresContext();
182 0 : if (presContext) {
183 0 : presContext->SetImageAnimationMode(aMode);
184 0 : return NS_OK;
185 : }
186 0 : return NS_ERROR_NOT_AVAILABLE;
187 : }
188 :
189 : NS_IMETHODIMP
190 0 : nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced)
191 : {
192 0 : *aIsForced = false;
193 :
194 0 : if (!IsUniversalXPConnectCapable()) {
195 0 : return NS_ERROR_DOM_SECURITY_ERR;
196 : }
197 :
198 0 : if (mWindow) {
199 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
200 : *aIsForced = doc &&
201 0 : doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced;
202 : }
203 0 : return NS_OK;
204 : }
205 :
206 : NS_IMETHODIMP
207 0 : nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
208 : nsAString& aValue)
209 : {
210 0 : if (!IsUniversalXPConnectCapable()) {
211 0 : return NS_ERROR_DOM_SECURITY_ERR;
212 : }
213 :
214 0 : if (mWindow) {
215 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
216 0 : if (doc) {
217 0 : nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
218 0 : doc->GetHeaderData(name, aValue);
219 0 : return NS_OK;
220 : }
221 : }
222 :
223 0 : aValue.Truncate();
224 0 : return NS_OK;
225 : }
226 :
227 : NS_IMETHODIMP
228 0 : nsDOMWindowUtils::Redraw(PRUint32 aCount, PRUint32 *aDurationOut)
229 : {
230 0 : if (aCount == 0)
231 0 : aCount = 1;
232 :
233 0 : if (nsIPresShell* presShell = GetPresShell()) {
234 0 : nsIFrame *rootFrame = presShell->GetRootFrame();
235 :
236 0 : if (rootFrame) {
237 0 : nsRect r(nsPoint(0, 0), rootFrame->GetSize());
238 :
239 0 : PRIntervalTime iStart = PR_IntervalNow();
240 :
241 0 : for (PRUint32 i = 0; i < aCount; i++)
242 0 : rootFrame->InvalidateWithFlags(r, nsIFrame::INVALIDATE_IMMEDIATE);
243 :
244 : #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
245 0 : XSync(GDK_DISPLAY(), False);
246 : #endif
247 :
248 0 : *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart);
249 :
250 0 : return NS_OK;
251 : }
252 : }
253 0 : return NS_ERROR_FAILURE;
254 : }
255 :
256 : NS_IMETHODIMP
257 0 : nsDOMWindowUtils::SetCSSViewport(float aWidthPx, float aHeightPx)
258 : {
259 0 : if (!IsUniversalXPConnectCapable()) {
260 0 : return NS_ERROR_DOM_SECURITY_ERR;
261 : }
262 :
263 0 : if (!(aWidthPx >= 0.0 && aHeightPx >= 0.0)) {
264 0 : return NS_ERROR_ILLEGAL_VALUE;
265 : }
266 :
267 0 : nsIPresShell* presShell = GetPresShell();
268 0 : if (!presShell) {
269 0 : return NS_ERROR_FAILURE;
270 : }
271 :
272 0 : nscoord width = nsPresContext::CSSPixelsToAppUnits(aWidthPx);
273 0 : nscoord height = nsPresContext::CSSPixelsToAppUnits(aHeightPx);
274 :
275 0 : presShell->ResizeReflowOverride(width, height);
276 :
277 0 : return NS_OK;
278 : }
279 :
280 0 : static void DestroyNsRect(void* aObject, nsIAtom* aPropertyName,
281 : void* aPropertyValue, void* aData)
282 : {
283 0 : nsRect* rect = static_cast<nsRect*>(aPropertyValue);
284 0 : delete rect;
285 0 : }
286 :
287 : NS_IMETHODIMP
288 0 : nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
289 : float aWidthPx, float aHeightPx,
290 : nsIDOMElement* aElement)
291 : {
292 0 : if (!IsUniversalXPConnectCapable()) {
293 0 : return NS_ERROR_DOM_SECURITY_ERR;
294 : }
295 :
296 0 : nsIPresShell* presShell = GetPresShell();
297 0 : if (!presShell) {
298 0 : return NS_ERROR_FAILURE;
299 : }
300 :
301 : nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx),
302 : nsPresContext::CSSPixelsToAppUnits(aYPx),
303 : nsPresContext::CSSPixelsToAppUnits(aWidthPx),
304 0 : nsPresContext::CSSPixelsToAppUnits(aHeightPx));
305 :
306 0 : if (!aElement) {
307 0 : return NS_ERROR_INVALID_ARG;
308 : }
309 :
310 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
311 :
312 0 : if (!content) {
313 0 : return NS_ERROR_INVALID_ARG;
314 : }
315 :
316 0 : nsRect lastDisplayPort;
317 0 : if (nsLayoutUtils::GetDisplayPort(content, &lastDisplayPort) &&
318 0 : displayport.IsEqualInterior(lastDisplayPort)) {
319 0 : return NS_OK;
320 : }
321 :
322 0 : content->SetProperty(nsGkAtoms::DisplayPort, new nsRect(displayport),
323 0 : DestroyNsRect);
324 :
325 0 : nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
326 0 : if (rootScrollFrame) {
327 0 : if (content == rootScrollFrame->GetContent()) {
328 : // We are setting a root displayport for a document.
329 : // The pres shell needs a special flag set.
330 0 : presShell->SetIgnoreViewportScrolling(true);
331 :
332 : // The root document currently has a widget, but we might end up
333 : // painting content inside the displayport but outside the widget
334 : // bounds. This ensures the document's view honors invalidations
335 : // within the displayport.
336 0 : nsPresContext* presContext = GetPresContext();
337 0 : if (presContext && presContext->IsRoot()) {
338 0 : nsIFrame* rootFrame = presShell->GetRootFrame();
339 0 : nsIView* view = rootFrame->GetView();
340 0 : if (view) {
341 0 : view->SetInvalidationDimensions(&displayport);
342 : }
343 : }
344 : }
345 : }
346 :
347 0 : if (presShell) {
348 0 : nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
349 0 : if (rootFrame) {
350 : nsIContent* rootContent =
351 0 : rootScrollFrame ? rootScrollFrame->GetContent() : nsnull;
352 0 : nsRect rootDisplayport;
353 : bool usingDisplayport = rootContent &&
354 0 : nsLayoutUtils::GetDisplayPort(rootContent, &rootDisplayport);
355 : rootFrame->InvalidateWithFlags(
356 0 : usingDisplayport ? rootDisplayport : rootFrame->GetVisualOverflowRect(),
357 0 : nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
358 :
359 : // Send empty paint transaction in order to release retained layers
360 0 : if (displayport.IsEmpty()) {
361 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
362 0 : if (widget) {
363 : bool isRetainingManager;
364 0 : LayerManager* manager = widget->GetLayerManager(&isRetainingManager);
365 0 : if (isRetainingManager) {
366 0 : manager->BeginTransaction();
367 0 : nsLayoutUtils::PaintFrame(nsnull, rootFrame, nsRegion(), NS_RGB(255, 255, 255),
368 : nsLayoutUtils::PAINT_WIDGET_LAYERS |
369 0 : nsLayoutUtils::PAINT_EXISTING_TRANSACTION);
370 : }
371 : }
372 : }
373 : }
374 : }
375 :
376 0 : return NS_OK;
377 : }
378 :
379 : NS_IMETHODIMP
380 0 : nsDOMWindowUtils::SetResolution(float aXResolution, float aYResolution)
381 : {
382 0 : if (!IsUniversalXPConnectCapable()) {
383 0 : return NS_ERROR_DOM_SECURITY_ERR;
384 : }
385 :
386 0 : nsIPresShell* presShell = GetPresShell();
387 0 : return presShell ? presShell->SetResolution(aXResolution, aYResolution)
388 0 : : NS_ERROR_FAILURE;
389 : }
390 :
391 : NS_IMETHODIMP
392 0 : nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
393 : float aX,
394 : float aY,
395 : PRInt32 aButton,
396 : PRInt32 aClickCount,
397 : PRInt32 aModifiers,
398 : bool aIgnoreRootScrollFrame)
399 : {
400 : return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
401 0 : aIgnoreRootScrollFrame, false);
402 : }
403 :
404 : NS_IMETHODIMP
405 0 : nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType,
406 : float aX,
407 : float aY,
408 : PRInt32 aButton,
409 : PRInt32 aClickCount,
410 : PRInt32 aModifiers,
411 : bool aIgnoreRootScrollFrame)
412 : {
413 : return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
414 0 : aIgnoreRootScrollFrame, true);
415 : }
416 :
417 : NS_IMETHODIMP
418 0 : nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
419 : float aX,
420 : float aY,
421 : PRInt32 aButton,
422 : PRInt32 aClickCount,
423 : PRInt32 aModifiers,
424 : bool aIgnoreRootScrollFrame,
425 : bool aToWindow)
426 : {
427 0 : if (!IsUniversalXPConnectCapable()) {
428 0 : return NS_ERROR_DOM_SECURITY_ERR;
429 : }
430 :
431 : // get the widget to send the event to
432 0 : nsPoint offset;
433 0 : nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
434 0 : if (!widget)
435 0 : return NS_ERROR_FAILURE;
436 :
437 : PRInt32 msg;
438 0 : bool contextMenuKey = false;
439 0 : if (aType.EqualsLiteral("mousedown"))
440 0 : msg = NS_MOUSE_BUTTON_DOWN;
441 0 : else if (aType.EqualsLiteral("mouseup"))
442 0 : msg = NS_MOUSE_BUTTON_UP;
443 0 : else if (aType.EqualsLiteral("mousemove"))
444 0 : msg = NS_MOUSE_MOVE;
445 0 : else if (aType.EqualsLiteral("mouseover"))
446 0 : msg = NS_MOUSE_ENTER;
447 0 : else if (aType.EqualsLiteral("mouseout"))
448 0 : msg = NS_MOUSE_EXIT;
449 0 : else if (aType.EqualsLiteral("contextmenu")) {
450 0 : msg = NS_CONTEXTMENU;
451 0 : contextMenuKey = (aButton == 0);
452 : } else
453 0 : return NS_ERROR_FAILURE;
454 :
455 : nsMouseEvent event(true, msg, widget, nsMouseEvent::eReal,
456 : contextMenuKey ?
457 0 : nsMouseEvent::eContextMenuKey : nsMouseEvent::eNormal);
458 0 : event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? true : false;
459 0 : event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? true : false;
460 0 : event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? true : false;
461 0 : event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? true : false;
462 0 : event.button = aButton;
463 0 : event.widget = widget;
464 :
465 0 : event.clickCount = aClickCount;
466 0 : event.time = PR_IntervalNow();
467 0 : event.flags |= NS_EVENT_FLAG_SYNTHETIC_TEST_EVENT;
468 :
469 0 : nsPresContext* presContext = GetPresContext();
470 0 : if (!presContext)
471 0 : return NS_ERROR_FAILURE;
472 :
473 0 : PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
474 : event.refPoint.x =
475 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aX) + offset.x,
476 0 : appPerDev);
477 : event.refPoint.y =
478 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aY) + offset.y,
479 0 : appPerDev);
480 0 : event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
481 :
482 : nsEventStatus status;
483 0 : if (aToWindow) {
484 0 : nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
485 0 : if (!presShell)
486 0 : return NS_ERROR_FAILURE;
487 0 : nsIViewManager* viewManager = presShell->GetViewManager();
488 0 : if (!viewManager)
489 0 : return NS_ERROR_FAILURE;
490 0 : nsIView* view = viewManager->GetRootView();
491 0 : if (!view)
492 0 : return NS_ERROR_FAILURE;
493 :
494 0 : status = nsEventStatus_eIgnore;
495 0 : return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
496 : }
497 0 : return widget->DispatchEvent(&event, status);
498 : }
499 :
500 : NS_IMETHODIMP
501 0 : nsDOMWindowUtils::SendMouseScrollEvent(const nsAString& aType,
502 : float aX,
503 : float aY,
504 : PRInt32 aButton,
505 : PRInt32 aScrollFlags,
506 : PRInt32 aDelta,
507 : PRInt32 aModifiers)
508 : {
509 0 : if (!IsUniversalXPConnectCapable()) {
510 0 : return NS_ERROR_DOM_SECURITY_ERR;
511 : }
512 :
513 : // get the widget to send the event to
514 0 : nsPoint offset;
515 0 : nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
516 0 : if (!widget)
517 0 : return NS_ERROR_NULL_POINTER;
518 :
519 : PRInt32 msg;
520 0 : if (aType.EqualsLiteral("DOMMouseScroll"))
521 0 : msg = NS_MOUSE_SCROLL;
522 0 : else if (aType.EqualsLiteral("MozMousePixelScroll"))
523 0 : msg = NS_MOUSE_PIXEL_SCROLL;
524 : else
525 0 : return NS_ERROR_UNEXPECTED;
526 :
527 0 : nsMouseScrollEvent event(true, msg, widget);
528 0 : event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? true : false;
529 0 : event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? true : false;
530 0 : event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? true : false;
531 0 : event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? true : false;
532 0 : event.button = aButton;
533 0 : event.widget = widget;
534 0 : event.delta = aDelta;
535 0 : event.scrollFlags = aScrollFlags;
536 :
537 0 : event.time = PR_IntervalNow();
538 :
539 0 : nsPresContext* presContext = GetPresContext();
540 0 : if (!presContext)
541 0 : return NS_ERROR_FAILURE;
542 :
543 0 : PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
544 : event.refPoint.x =
545 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aX) + offset.x,
546 0 : appPerDev);
547 : event.refPoint.y =
548 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aY) + offset.y,
549 0 : appPerDev);
550 :
551 : nsEventStatus status;
552 0 : return widget->DispatchEvent(&event, status);
553 : }
554 :
555 :
556 : NS_IMETHODIMP
557 0 : nsDOMWindowUtils::SendTouchEvent(const nsAString& aType,
558 : PRUint32 *aIdentifiers,
559 : PRInt32 *aXs,
560 : PRInt32 *aYs,
561 : PRUint32 *aRxs,
562 : PRUint32 *aRys,
563 : float *aRotationAngles,
564 : float *aForces,
565 : PRUint32 aCount,
566 : PRInt32 aModifiers,
567 : bool aIgnoreRootScrollFrame,
568 : bool *aPreventDefault)
569 : {
570 0 : if (!IsUniversalXPConnectCapable()) {
571 0 : return NS_ERROR_DOM_SECURITY_ERR;
572 : }
573 :
574 : // get the widget to send the event to
575 0 : nsPoint offset;
576 0 : nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
577 0 : if (!widget) {
578 0 : return NS_ERROR_NULL_POINTER;
579 : }
580 : PRInt32 msg;
581 0 : if (aType.EqualsLiteral("touchstart")) {
582 0 : msg = NS_TOUCH_START;
583 0 : } else if (aType.EqualsLiteral("touchmove")) {
584 0 : msg = NS_TOUCH_MOVE;
585 0 : } else if (aType.EqualsLiteral("touchend")) {
586 0 : msg = NS_TOUCH_END;
587 0 : } else if (aType.EqualsLiteral("touchcancel")) {
588 0 : msg = NS_TOUCH_CANCEL;
589 : } else {
590 0 : return NS_ERROR_UNEXPECTED;
591 : }
592 0 : nsTouchEvent event(true, msg, widget);
593 0 : event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? true : false;
594 0 : event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? true : false;
595 0 : event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? true : false;
596 0 : event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? true : false;
597 0 : event.widget = widget;
598 0 : event.time = PR_Now();
599 :
600 0 : nsPresContext* presContext = GetPresContext();
601 0 : if (!presContext) {
602 0 : return NS_ERROR_FAILURE;
603 : }
604 0 : event.touches.SetCapacity(aCount);
605 0 : PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
606 0 : for (PRUint32 i = 0; i < aCount; ++i) {
607 0 : nsIntPoint pt(0, 0);
608 : pt.x =
609 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aXs[i]) + offset.x,
610 0 : appPerDev);
611 : pt.y =
612 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aYs[i]) + offset.y,
613 0 : appPerDev);
614 0 : nsCOMPtr<nsIDOMTouch> t(new nsDOMTouch(aIdentifiers[i],
615 : pt,
616 0 : nsIntPoint(aRxs[i], aRys[i]),
617 0 : aRotationAngles[i],
618 0 : aForces[i]));
619 0 : event.touches.AppendElement(t);
620 : }
621 :
622 : nsEventStatus status;
623 0 : nsresult rv = widget->DispatchEvent(&event, status);
624 0 : *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
625 0 : return rv;
626 : }
627 :
628 : NS_IMETHODIMP
629 0 : nsDOMWindowUtils::SendKeyEvent(const nsAString& aType,
630 : PRInt32 aKeyCode,
631 : PRInt32 aCharCode,
632 : PRInt32 aModifiers,
633 : bool aPreventDefault,
634 : bool* aDefaultActionTaken)
635 : {
636 0 : if (!IsUniversalXPConnectCapable()) {
637 0 : return NS_ERROR_DOM_SECURITY_ERR;
638 : }
639 :
640 : // get the widget to send the event to
641 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
642 0 : if (!widget)
643 0 : return NS_ERROR_FAILURE;
644 :
645 : PRInt32 msg;
646 0 : if (aType.EqualsLiteral("keydown"))
647 0 : msg = NS_KEY_DOWN;
648 0 : else if (aType.EqualsLiteral("keyup"))
649 0 : msg = NS_KEY_UP;
650 0 : else if (aType.EqualsLiteral("keypress"))
651 0 : msg = NS_KEY_PRESS;
652 : else
653 0 : return NS_ERROR_FAILURE;
654 :
655 0 : nsKeyEvent event(true, msg, widget);
656 0 : event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? true : false;
657 0 : event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? true : false;
658 0 : event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? true : false;
659 0 : event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? true : false;
660 :
661 0 : event.keyCode = aKeyCode;
662 0 : event.charCode = aCharCode;
663 0 : event.refPoint.x = event.refPoint.y = 0;
664 0 : event.time = PR_IntervalNow();
665 :
666 0 : if (aPreventDefault) {
667 0 : event.flags |= NS_EVENT_FLAG_NO_DEFAULT;
668 : }
669 :
670 : nsEventStatus status;
671 0 : nsresult rv = widget->DispatchEvent(&event, status);
672 0 : NS_ENSURE_SUCCESS(rv, rv);
673 :
674 0 : *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
675 :
676 0 : return NS_OK;
677 : }
678 :
679 : NS_IMETHODIMP
680 0 : nsDOMWindowUtils::SendNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
681 : PRInt32 aNativeKeyCode,
682 : PRInt32 aModifiers,
683 : const nsAString& aCharacters,
684 : const nsAString& aUnmodifiedCharacters)
685 : {
686 0 : if (!IsUniversalXPConnectCapable()) {
687 0 : return NS_ERROR_DOM_SECURITY_ERR;
688 : }
689 :
690 : // get the widget to send the event to
691 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
692 0 : if (!widget)
693 0 : return NS_ERROR_FAILURE;
694 :
695 0 : return widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
696 0 : aModifiers, aCharacters, aUnmodifiedCharacters);
697 : }
698 :
699 : NS_IMETHODIMP
700 0 : nsDOMWindowUtils::SendNativeMouseEvent(PRInt32 aScreenX,
701 : PRInt32 aScreenY,
702 : PRInt32 aNativeMessage,
703 : PRInt32 aModifierFlags,
704 : nsIDOMElement* aElement)
705 : {
706 0 : if (!IsUniversalXPConnectCapable()) {
707 0 : return NS_ERROR_DOM_SECURITY_ERR;
708 : }
709 :
710 : // get the widget to send the event to
711 0 : nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement);
712 0 : if (!widget)
713 0 : return NS_ERROR_FAILURE;
714 :
715 0 : return widget->SynthesizeNativeMouseEvent(nsIntPoint(aScreenX, aScreenY),
716 0 : aNativeMessage, aModifierFlags);
717 : }
718 :
719 : NS_IMETHODIMP
720 0 : nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString)
721 : {
722 0 : if (!IsUniversalXPConnectCapable()) {
723 0 : return NS_ERROR_DOM_SECURITY_ERR;
724 : }
725 :
726 : // get the widget to send the event to
727 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
728 0 : if (!widget)
729 0 : return NS_ERROR_FAILURE;
730 :
731 0 : return widget->ActivateNativeMenuItemAt(indexString);
732 : }
733 :
734 : NS_IMETHODIMP
735 0 : nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString)
736 : {
737 0 : if (!IsUniversalXPConnectCapable()) {
738 0 : return NS_ERROR_DOM_SECURITY_ERR;
739 : }
740 :
741 : // get the widget to send the event to
742 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
743 0 : if (!widget)
744 0 : return NS_ERROR_FAILURE;
745 :
746 0 : return widget->ForceUpdateNativeMenuAt(indexString);
747 : }
748 :
749 : nsIWidget*
750 0 : nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
751 : {
752 0 : if (mWindow) {
753 0 : nsIDocShell *docShell = mWindow->GetDocShell();
754 0 : if (docShell) {
755 0 : nsCOMPtr<nsIPresShell> presShell;
756 0 : docShell->GetPresShell(getter_AddRefs(presShell));
757 0 : if (presShell) {
758 0 : nsIFrame* frame = presShell->GetRootFrame();
759 0 : if (frame)
760 0 : return frame->GetView()->GetNearestWidget(aOffset);
761 : }
762 : }
763 : }
764 :
765 0 : return nsnull;
766 : }
767 :
768 : nsIWidget*
769 0 : nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
770 : {
771 0 : if (!aElement)
772 0 : return GetWidget();
773 :
774 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
775 0 : nsIDocument* doc = content->GetCurrentDoc();
776 0 : nsIPresShell* presShell = doc ? doc->GetShell() : nsnull;
777 :
778 0 : if (presShell) {
779 0 : nsIFrame* frame = content->GetPrimaryFrame();
780 0 : if (!frame) {
781 0 : frame = presShell->GetRootFrame();
782 : }
783 0 : if (frame)
784 0 : return frame->GetNearestWidget();
785 : }
786 :
787 0 : return nsnull;
788 : }
789 :
790 : NS_IMETHODIMP
791 0 : nsDOMWindowUtils::Focus(nsIDOMElement* aElement)
792 : {
793 0 : if (!IsUniversalXPConnectCapable()) {
794 0 : return NS_ERROR_DOM_SECURITY_ERR;
795 : }
796 :
797 0 : nsIFocusManager* fm = nsFocusManager::GetFocusManager();
798 0 : if (fm) {
799 0 : if (aElement)
800 0 : fm->SetFocus(aElement, 0);
801 : else
802 0 : fm->ClearFocus(mWindow);
803 : }
804 :
805 0 : return NS_OK;
806 : }
807 :
808 : NS_IMETHODIMP
809 0 : nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
810 : PRInt32 aExtraForgetSkippableCalls)
811 : {
812 0 : SAMPLE_LABEL("GC", "GarbageCollect");
813 : // Always permit this in debug builds.
814 : #ifndef DEBUG
815 : if (!IsUniversalXPConnectCapable()) {
816 : return NS_ERROR_DOM_SECURITY_ERR;
817 : }
818 : #endif
819 :
820 0 : nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
821 0 : nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
822 :
823 0 : return NS_OK;
824 : }
825 :
826 : NS_IMETHODIMP
827 0 : nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener,
828 : PRInt32 aExtraForgetSkippableCalls)
829 : {
830 : // Always permit this in debug builds.
831 : #ifndef DEBUG
832 : if (!IsUniversalXPConnectCapable()) {
833 : return NS_ERROR_DOM_SECURITY_ERR;
834 : }
835 : #endif
836 :
837 0 : nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
838 0 : return NS_OK;
839 : }
840 :
841 : NS_IMETHODIMP
842 0 : nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
843 : float aX,
844 : float aY,
845 : PRUint32 aDirection,
846 : PRFloat64 aDelta,
847 : PRInt32 aModifiers)
848 : {
849 0 : if (!IsUniversalXPConnectCapable()) {
850 0 : return NS_ERROR_DOM_SECURITY_ERR;
851 : }
852 :
853 : // get the widget to send the event to
854 0 : nsPoint offset;
855 0 : nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
856 0 : if (!widget)
857 0 : return NS_ERROR_FAILURE;
858 :
859 : PRInt32 msg;
860 0 : if (aType.EqualsLiteral("MozSwipeGesture"))
861 0 : msg = NS_SIMPLE_GESTURE_SWIPE;
862 0 : else if (aType.EqualsLiteral("MozMagnifyGestureStart"))
863 0 : msg = NS_SIMPLE_GESTURE_MAGNIFY_START;
864 0 : else if (aType.EqualsLiteral("MozMagnifyGestureUpdate"))
865 0 : msg = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
866 0 : else if (aType.EqualsLiteral("MozMagnifyGesture"))
867 0 : msg = NS_SIMPLE_GESTURE_MAGNIFY;
868 0 : else if (aType.EqualsLiteral("MozRotateGestureStart"))
869 0 : msg = NS_SIMPLE_GESTURE_ROTATE_START;
870 0 : else if (aType.EqualsLiteral("MozRotateGestureUpdate"))
871 0 : msg = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
872 0 : else if (aType.EqualsLiteral("MozRotateGesture"))
873 0 : msg = NS_SIMPLE_GESTURE_ROTATE;
874 0 : else if (aType.EqualsLiteral("MozTapGesture"))
875 0 : msg = NS_SIMPLE_GESTURE_TAP;
876 0 : else if (aType.EqualsLiteral("MozPressTapGesture"))
877 0 : msg = NS_SIMPLE_GESTURE_PRESSTAP;
878 : else
879 0 : return NS_ERROR_FAILURE;
880 :
881 0 : nsSimpleGestureEvent event(true, msg, widget, aDirection, aDelta);
882 0 : event.isShift = (aModifiers & nsIDOMNSEvent::SHIFT_MASK) ? true : false;
883 0 : event.isControl = (aModifiers & nsIDOMNSEvent::CONTROL_MASK) ? true : false;
884 0 : event.isAlt = (aModifiers & nsIDOMNSEvent::ALT_MASK) ? true : false;
885 0 : event.isMeta = (aModifiers & nsIDOMNSEvent::META_MASK) ? true : false;
886 0 : event.time = PR_IntervalNow();
887 :
888 0 : nsPresContext* presContext = GetPresContext();
889 0 : if (!presContext)
890 0 : return NS_ERROR_FAILURE;
891 :
892 0 : PRInt32 appPerDev = presContext->AppUnitsPerDevPixel();
893 : event.refPoint.x =
894 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aX) + offset.x,
895 0 : appPerDev);
896 : event.refPoint.y =
897 0 : NSAppUnitsToIntPixels(nsPresContext::CSSPixelsToAppUnits(aY) + offset.y,
898 0 : appPerDev);
899 :
900 : nsEventStatus status;
901 0 : return widget->DispatchEvent(&event, status);
902 : }
903 :
904 : NS_IMETHODIMP
905 0 : nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
906 : bool aIgnoreRootScrollFrame,
907 : bool aFlushLayout,
908 : nsIDOMElement** aReturn)
909 : {
910 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
911 0 : NS_ENSURE_STATE(doc);
912 :
913 0 : return doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout,
914 0 : aReturn);
915 : }
916 :
917 : NS_IMETHODIMP
918 0 : nsDOMWindowUtils::NodesFromRect(float aX, float aY,
919 : float aTopSize, float aRightSize,
920 : float aBottomSize, float aLeftSize,
921 : bool aIgnoreRootScrollFrame,
922 : bool aFlushLayout,
923 : nsIDOMNodeList** aReturn)
924 : {
925 0 : if (!IsUniversalXPConnectCapable()) {
926 0 : return NS_ERROR_DOM_SECURITY_ERR;
927 : }
928 :
929 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
930 0 : NS_ENSURE_STATE(doc);
931 :
932 0 : return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize,
933 0 : aIgnoreRootScrollFrame, aFlushLayout, aReturn);
934 : }
935 :
936 : static already_AddRefed<gfxImageSurface>
937 0 : CanvasToImageSurface(nsIDOMHTMLCanvasElement* aCanvas)
938 : {
939 0 : nsCOMPtr<nsINode> node = do_QueryInterface(aCanvas);
940 0 : if (!node) {
941 0 : return nsnull;
942 : }
943 :
944 0 : NS_ABORT_IF_FALSE(node->IsElement(),
945 : "An nsINode that implements nsIDOMHTMLCanvasElement should "
946 : "be an element.");
947 : nsLayoutUtils::SurfaceFromElementResult result =
948 : nsLayoutUtils::SurfaceFromElement(node->AsElement(),
949 0 : nsLayoutUtils::SFE_WANT_IMAGE_SURFACE);
950 0 : return static_cast<gfxImageSurface*>(result.mSurface.forget().get());
951 : }
952 :
953 : NS_IMETHODIMP
954 0 : nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
955 : nsIDOMHTMLCanvasElement *aCanvas2,
956 : PRUint32* aMaxDifference,
957 : PRUint32* retVal)
958 : {
959 0 : if (!IsUniversalXPConnectCapable()) {
960 0 : return NS_ERROR_DOM_SECURITY_ERR;
961 : }
962 :
963 0 : if (aCanvas1 == nsnull ||
964 : aCanvas2 == nsnull ||
965 : retVal == nsnull)
966 0 : return NS_ERROR_FAILURE;
967 :
968 0 : nsRefPtr<gfxImageSurface> img1 = CanvasToImageSurface(aCanvas1);
969 0 : nsRefPtr<gfxImageSurface> img2 = CanvasToImageSurface(aCanvas2);
970 :
971 0 : if (img1 == nsnull || img2 == nsnull ||
972 0 : img1->GetSize() != img2->GetSize() ||
973 0 : img1->Stride() != img2->Stride())
974 0 : return NS_ERROR_FAILURE;
975 :
976 : int v;
977 0 : gfxIntSize size = img1->GetSize();
978 0 : PRUint32 stride = img1->Stride();
979 :
980 : // we can optimize for the common all-pass case
981 0 : if (stride == (PRUint32) size.width * 4) {
982 0 : v = memcmp(img1->Data(), img2->Data(), size.width * size.height * 4);
983 0 : if (v == 0) {
984 0 : if (aMaxDifference)
985 0 : *aMaxDifference = 0;
986 0 : *retVal = 0;
987 0 : return NS_OK;
988 : }
989 : }
990 :
991 0 : PRUint32 dc = 0;
992 0 : PRUint32 different = 0;
993 :
994 0 : for (int j = 0; j < size.height; j++) {
995 0 : unsigned char *p1 = img1->Data() + j*stride;
996 0 : unsigned char *p2 = img2->Data() + j*stride;
997 0 : v = memcmp(p1, p2, stride);
998 :
999 0 : if (v) {
1000 0 : for (int i = 0; i < size.width; i++) {
1001 0 : if (*(PRUint32*) p1 != *(PRUint32*) p2) {
1002 :
1003 0 : different++;
1004 :
1005 0 : dc = NS_MAX((PRUint32)abs(p1[0] - p2[0]), dc);
1006 0 : dc = NS_MAX((PRUint32)abs(p1[1] - p2[1]), dc);
1007 0 : dc = NS_MAX((PRUint32)abs(p1[2] - p2[2]), dc);
1008 0 : dc = NS_MAX((PRUint32)abs(p1[3] - p2[3]), dc);
1009 : }
1010 :
1011 0 : p1 += 4;
1012 0 : p2 += 4;
1013 : }
1014 : }
1015 : }
1016 :
1017 0 : if (aMaxDifference)
1018 0 : *aMaxDifference = dc;
1019 :
1020 0 : *retVal = different;
1021 0 : return NS_OK;
1022 : }
1023 :
1024 : NS_IMETHODIMP
1025 0 : nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
1026 : {
1027 0 : *aResult = false;
1028 0 : nsPresContext* presContext = GetPresContext();
1029 0 : if (!presContext)
1030 0 : return NS_OK;
1031 0 : *aResult = presContext->IsDOMPaintEventPending();
1032 0 : return NS_OK;
1033 : }
1034 :
1035 : NS_IMETHODIMP
1036 0 : nsDOMWindowUtils::ClearMozAfterPaintEvents()
1037 : {
1038 0 : nsPresContext* presContext = GetPresContext();
1039 0 : if (!presContext)
1040 0 : return NS_OK;
1041 0 : presContext->ClearMozAfterPaintEvents();
1042 0 : return NS_OK;
1043 : }
1044 :
1045 : NS_IMETHODIMP
1046 0 : nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable)
1047 : {
1048 0 : if (!IsUniversalXPConnectCapable()) {
1049 0 : return NS_ERROR_DOM_SECURITY_ERR;
1050 : }
1051 :
1052 0 : NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
1053 0 : nsIDocShell *docShell = mWindow->GetDocShell();
1054 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1055 0 : nsCOMPtr<nsIPresShell> presShell;
1056 0 : docShell->GetPresShell(getter_AddRefs(presShell));
1057 0 : NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1058 0 : presShell->DisableNonTestMouseEvents(aDisable);
1059 0 : return NS_OK;
1060 : }
1061 :
1062 : NS_IMETHODIMP
1063 0 : nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
1064 : {
1065 0 : if (!IsUniversalXPConnectCapable()) {
1066 0 : return NS_ERROR_DOM_SECURITY_ERR;
1067 : }
1068 :
1069 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
1070 0 : NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
1071 :
1072 0 : if (aSuppress) {
1073 0 : doc->SuppressEventHandling();
1074 : } else {
1075 0 : doc->UnsuppressEventHandlingAndFireEvents(true);
1076 : }
1077 :
1078 0 : return NS_OK;
1079 : }
1080 :
1081 : NS_IMETHODIMP
1082 0 : nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, PRInt32* aScrollX, PRInt32* aScrollY)
1083 : {
1084 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
1085 0 : NS_ENSURE_STATE(doc);
1086 :
1087 0 : if (aFlushLayout) {
1088 0 : doc->FlushPendingNotifications(Flush_Layout);
1089 : }
1090 :
1091 0 : nsPoint scrollPos(0,0);
1092 0 : nsIPresShell *presShell = doc->GetShell();
1093 0 : if (presShell) {
1094 0 : nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
1095 0 : if (sf) {
1096 0 : scrollPos = sf->GetScrollPosition();
1097 : }
1098 : }
1099 :
1100 0 : *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x);
1101 0 : *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y);
1102 :
1103 0 : return NS_OK;
1104 : }
1105 :
1106 : NS_IMETHODIMP
1107 0 : nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
1108 : {
1109 0 : NS_ENSURE_ARG_POINTER(aState);
1110 :
1111 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1112 0 : if (!widget)
1113 0 : return NS_ERROR_FAILURE;
1114 :
1115 : // Open state should not be available when IME is not enabled.
1116 0 : InputContext context = widget->GetInputContext();
1117 0 : if (context.mIMEState.mEnabled != IMEState::ENABLED) {
1118 0 : return NS_ERROR_NOT_AVAILABLE;
1119 : }
1120 :
1121 0 : if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
1122 0 : return NS_ERROR_NOT_IMPLEMENTED;
1123 : }
1124 0 : *aState = (context.mIMEState.mOpen == IMEState::OPEN);
1125 0 : return NS_OK;
1126 : }
1127 :
1128 : NS_IMETHODIMP
1129 0 : nsDOMWindowUtils::GetIMEStatus(PRUint32 *aState)
1130 : {
1131 0 : NS_ENSURE_ARG_POINTER(aState);
1132 :
1133 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1134 0 : if (!widget)
1135 0 : return NS_ERROR_FAILURE;
1136 :
1137 0 : InputContext context = widget->GetInputContext();
1138 0 : *aState = static_cast<PRUint32>(context.mIMEState.mEnabled);
1139 0 : return NS_OK;
1140 : }
1141 :
1142 : NS_IMETHODIMP
1143 0 : nsDOMWindowUtils::GetFocusedInputType(char** aType)
1144 : {
1145 0 : NS_ENSURE_ARG_POINTER(aType);
1146 :
1147 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1148 0 : if (!widget) {
1149 0 : return NS_ERROR_FAILURE;
1150 : }
1151 :
1152 0 : InputContext context = widget->GetInputContext();
1153 0 : *aType = ToNewCString(context.mHTMLInputType);
1154 0 : return NS_OK;
1155 : }
1156 :
1157 : NS_IMETHODIMP
1158 0 : nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
1159 : nsIDOMElement** aResult)
1160 : {
1161 0 : if (aID == FrameMetrics::ROOT_SCROLL_ID) {
1162 0 : nsPresContext* presContext = GetPresContext();
1163 0 : if (!presContext) {
1164 0 : return NS_ERROR_NOT_AVAILABLE;
1165 : }
1166 :
1167 0 : nsIDocument* document = presContext->Document();
1168 0 : mozilla::dom::Element* rootElement = document->GetRootElement();
1169 0 : if (!rootElement) {
1170 0 : return NS_ERROR_NOT_AVAILABLE;
1171 : }
1172 :
1173 0 : CallQueryInterface(rootElement, aResult);
1174 0 : return NS_OK;
1175 : }
1176 :
1177 0 : nsRefPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aID);
1178 0 : return content ? CallQueryInterface(content, aResult) : NS_OK;
1179 : }
1180 :
1181 : NS_IMETHODIMP
1182 0 : nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels)
1183 : {
1184 0 : *aScreenPixels = 1;
1185 :
1186 0 : if (!nsContentUtils::IsCallerTrustedForRead())
1187 0 : return NS_ERROR_DOM_SECURITY_ERR;
1188 0 : nsPresContext* presContext = GetPresContext();
1189 0 : if (!presContext)
1190 0 : return NS_OK;
1191 :
1192 0 : *aScreenPixels = float(nsPresContext::AppUnitsPerCSSPixel())/
1193 0 : presContext->AppUnitsPerDevPixel();
1194 0 : return NS_OK;
1195 : }
1196 :
1197 : NS_IMETHODIMP
1198 0 : nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsIDOMNode* aTarget,
1199 : nsIDOMEvent* aEvent,
1200 : bool aTrusted,
1201 : bool* aRetVal)
1202 : {
1203 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
1204 0 : return NS_ERROR_DOM_SECURITY_ERR;
1205 : }
1206 :
1207 0 : nsPresContext* presContext = GetPresContext();
1208 0 : NS_ENSURE_STATE(presContext);
1209 0 : nsCOMPtr<nsIPresShell> shell = presContext->GetPresShell();
1210 0 : NS_ENSURE_STATE(shell);
1211 0 : nsCOMPtr<nsIPrivateDOMEvent> event = do_QueryInterface(aEvent);
1212 0 : NS_ENSURE_STATE(event);
1213 0 : event->SetTrusted(aTrusted);
1214 0 : nsEvent* internalEvent = event->GetInternalNSEvent();
1215 0 : NS_ENSURE_STATE(internalEvent);
1216 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget);
1217 0 : NS_ENSURE_STATE(content);
1218 :
1219 0 : nsEventStatus status = nsEventStatus_eIgnore;
1220 0 : shell->HandleEventWithTarget(internalEvent, nsnull, content,
1221 0 : &status);
1222 0 : *aRetVal = (status != nsEventStatus_eConsumeNoDefault);
1223 0 : return NS_OK;
1224 : }
1225 :
1226 : static void
1227 0 : InitEvent(nsGUIEvent &aEvent, nsIntPoint *aPt = nsnull)
1228 : {
1229 0 : if (aPt) {
1230 0 : aEvent.refPoint = *aPt;
1231 : }
1232 0 : aEvent.time = PR_IntervalNow();
1233 0 : }
1234 :
1235 : NS_IMETHODIMP
1236 0 : nsDOMWindowUtils::SendCompositionEvent(const nsAString& aType,
1237 : const nsAString& aData,
1238 : const nsAString& aLocale)
1239 : {
1240 0 : if (!IsUniversalXPConnectCapable()) {
1241 0 : return NS_ERROR_DOM_SECURITY_ERR;
1242 : }
1243 :
1244 : // get the widget to send the event to
1245 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1246 0 : if (!widget) {
1247 0 : return NS_ERROR_FAILURE;
1248 : }
1249 :
1250 : PRUint32 msg;
1251 0 : if (aType.EqualsLiteral("compositionstart")) {
1252 0 : msg = NS_COMPOSITION_START;
1253 0 : } else if (aType.EqualsLiteral("compositionend")) {
1254 0 : msg = NS_COMPOSITION_END;
1255 0 : } else if (aType.EqualsLiteral("compositionupdate")) {
1256 0 : msg = NS_COMPOSITION_UPDATE;
1257 : } else {
1258 0 : return NS_ERROR_FAILURE;
1259 : }
1260 :
1261 0 : nsCompositionEvent compositionEvent(true, msg, widget);
1262 0 : InitEvent(compositionEvent);
1263 0 : if (msg != NS_COMPOSITION_START) {
1264 0 : compositionEvent.data = aData;
1265 : }
1266 :
1267 : nsEventStatus status;
1268 0 : nsresult rv = widget->DispatchEvent(&compositionEvent, status);
1269 0 : NS_ENSURE_SUCCESS(rv, rv);
1270 :
1271 0 : return NS_OK;
1272 : }
1273 :
1274 : static void
1275 0 : AppendClause(PRInt32 aClauseLength, PRUint32 aClauseAttr,
1276 : nsTArray<nsTextRange>* aRanges)
1277 : {
1278 0 : NS_PRECONDITION(aRanges, "aRange is null");
1279 0 : if (aClauseLength == 0) {
1280 0 : return;
1281 : }
1282 0 : nsTextRange range;
1283 0 : range.mStartOffset = aRanges->Length() == 0 ? 0 :
1284 0 : aRanges->ElementAt(aRanges->Length() - 1).mEndOffset + 1;
1285 0 : range.mEndOffset = range.mStartOffset + aClauseLength;
1286 0 : NS_ASSERTION(range.mStartOffset <= range.mEndOffset, "range is invalid");
1287 0 : NS_PRECONDITION(aClauseAttr == NS_TEXTRANGE_RAWINPUT ||
1288 : aClauseAttr == NS_TEXTRANGE_SELECTEDRAWTEXT ||
1289 : aClauseAttr == NS_TEXTRANGE_CONVERTEDTEXT ||
1290 : aClauseAttr == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT,
1291 : "aClauseAttr is invalid value");
1292 0 : range.mRangeType = aClauseAttr;
1293 0 : aRanges->AppendElement(range);
1294 : }
1295 :
1296 : NS_IMETHODIMP
1297 0 : nsDOMWindowUtils::SendTextEvent(const nsAString& aCompositionString,
1298 : PRInt32 aFirstClauseLength,
1299 : PRUint32 aFirstClauseAttr,
1300 : PRInt32 aSecondClauseLength,
1301 : PRUint32 aSecondClauseAttr,
1302 : PRInt32 aThirdClauseLength,
1303 : PRUint32 aThirdClauseAttr,
1304 : PRInt32 aCaretStart,
1305 : PRInt32 aCaretLength)
1306 : {
1307 0 : if (!IsUniversalXPConnectCapable()) {
1308 0 : return NS_ERROR_DOM_SECURITY_ERR;
1309 : }
1310 :
1311 : // get the widget to send the event to
1312 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1313 0 : if (!widget) {
1314 0 : return NS_ERROR_FAILURE;
1315 : }
1316 :
1317 0 : nsTextEvent textEvent(true, NS_TEXT_TEXT, widget);
1318 0 : InitEvent(textEvent);
1319 :
1320 0 : nsAutoTArray<nsTextRange, 4> textRanges;
1321 0 : NS_ENSURE_TRUE(aFirstClauseLength >= 0, NS_ERROR_INVALID_ARG);
1322 0 : NS_ENSURE_TRUE(aSecondClauseLength >= 0, NS_ERROR_INVALID_ARG);
1323 0 : NS_ENSURE_TRUE(aThirdClauseLength >= 0, NS_ERROR_INVALID_ARG);
1324 0 : AppendClause(aFirstClauseLength, aFirstClauseAttr, &textRanges);
1325 0 : AppendClause(aSecondClauseLength, aSecondClauseAttr, &textRanges);
1326 0 : AppendClause(aThirdClauseLength, aThirdClauseAttr, &textRanges);
1327 0 : PRInt32 len = aFirstClauseLength + aSecondClauseLength + aThirdClauseLength;
1328 0 : NS_ENSURE_TRUE(len == 0 || PRUint32(len) == aCompositionString.Length(),
1329 : NS_ERROR_FAILURE);
1330 :
1331 0 : if (aCaretStart >= 0) {
1332 0 : nsTextRange range;
1333 0 : range.mStartOffset = aCaretStart;
1334 0 : range.mEndOffset = range.mStartOffset + aCaretLength;
1335 0 : range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
1336 0 : textRanges.AppendElement(range);
1337 : }
1338 :
1339 0 : textEvent.theText = aCompositionString;
1340 :
1341 0 : textEvent.rangeCount = textRanges.Length();
1342 0 : textEvent.rangeArray = textRanges.Elements();
1343 :
1344 : nsEventStatus status;
1345 0 : nsresult rv = widget->DispatchEvent(&textEvent, status);
1346 0 : NS_ENSURE_SUCCESS(rv, rv);
1347 :
1348 0 : return NS_OK;
1349 : }
1350 :
1351 : NS_IMETHODIMP
1352 0 : nsDOMWindowUtils::SendQueryContentEvent(PRUint32 aType,
1353 : PRUint32 aOffset, PRUint32 aLength,
1354 : PRInt32 aX, PRInt32 aY,
1355 : nsIQueryContentEventResult **aResult)
1356 : {
1357 0 : *aResult = nsnull;
1358 :
1359 0 : if (!IsUniversalXPConnectCapable()) {
1360 0 : return NS_ERROR_DOM_SECURITY_ERR;
1361 : }
1362 :
1363 0 : NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
1364 :
1365 0 : nsIDocShell *docShell = mWindow->GetDocShell();
1366 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
1367 :
1368 0 : nsCOMPtr<nsIPresShell> presShell;
1369 0 : docShell->GetPresShell(getter_AddRefs(presShell));
1370 0 : NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1371 :
1372 0 : nsPresContext* presContext = presShell->GetPresContext();
1373 0 : NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
1374 :
1375 : // get the widget to send the event to
1376 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1377 0 : if (!widget) {
1378 0 : return NS_ERROR_FAILURE;
1379 : }
1380 :
1381 0 : if (aType != NS_QUERY_SELECTED_TEXT &&
1382 : aType != NS_QUERY_TEXT_CONTENT &&
1383 : aType != NS_QUERY_CARET_RECT &&
1384 : aType != NS_QUERY_TEXT_RECT &&
1385 : aType != NS_QUERY_EDITOR_RECT &&
1386 : aType != NS_QUERY_CHARACTER_AT_POINT) {
1387 0 : return NS_ERROR_INVALID_ARG;
1388 : }
1389 :
1390 0 : nsCOMPtr<nsIWidget> targetWidget = widget;
1391 0 : nsIntPoint pt(aX, aY);
1392 :
1393 0 : if (aType == QUERY_CHARACTER_AT_POINT) {
1394 : // Looking for the widget at the point.
1395 0 : nsQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
1396 0 : InitEvent(dummyEvent, &pt);
1397 : nsIFrame* popupFrame =
1398 0 : nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
1399 :
1400 0 : nsIntRect widgetBounds;
1401 0 : nsresult rv = widget->GetClientBounds(widgetBounds);
1402 0 : NS_ENSURE_SUCCESS(rv, rv);
1403 0 : widgetBounds.MoveTo(0, 0);
1404 :
1405 : // There is no popup frame at the point and the point isn't in our widget,
1406 : // we cannot process this request.
1407 0 : NS_ENSURE_TRUE(popupFrame || widgetBounds.Contains(pt),
1408 : NS_ERROR_FAILURE);
1409 :
1410 : // Fire the event on the widget at the point
1411 0 : if (popupFrame) {
1412 0 : targetWidget = popupFrame->GetNearestWidget();
1413 : }
1414 : }
1415 :
1416 0 : pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset();
1417 :
1418 0 : nsQueryContentEvent queryEvent(true, aType, targetWidget);
1419 0 : InitEvent(queryEvent, &pt);
1420 :
1421 0 : switch (aType) {
1422 : case NS_QUERY_TEXT_CONTENT:
1423 0 : queryEvent.InitForQueryTextContent(aOffset, aLength);
1424 0 : break;
1425 : case NS_QUERY_CARET_RECT:
1426 0 : queryEvent.InitForQueryCaretRect(aOffset);
1427 0 : break;
1428 : case NS_QUERY_TEXT_RECT:
1429 0 : queryEvent.InitForQueryTextRect(aOffset, aLength);
1430 0 : break;
1431 : }
1432 :
1433 : nsEventStatus status;
1434 0 : nsresult rv = targetWidget->DispatchEvent(&queryEvent, status);
1435 0 : NS_ENSURE_SUCCESS(rv, rv);
1436 :
1437 0 : nsQueryContentEventResult* result = new nsQueryContentEventResult();
1438 0 : NS_ENSURE_TRUE(result, NS_ERROR_OUT_OF_MEMORY);
1439 0 : result->SetEventResult(widget, queryEvent);
1440 0 : NS_ADDREF(*aResult = result);
1441 0 : return NS_OK;
1442 : }
1443 :
1444 : NS_IMETHODIMP
1445 0 : nsDOMWindowUtils::SendSelectionSetEvent(PRUint32 aOffset,
1446 : PRUint32 aLength,
1447 : bool aReverse,
1448 : bool *aResult)
1449 : {
1450 0 : *aResult = false;
1451 :
1452 0 : if (!IsUniversalXPConnectCapable()) {
1453 0 : return NS_ERROR_DOM_SECURITY_ERR;
1454 : }
1455 :
1456 : // get the widget to send the event to
1457 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1458 0 : if (!widget) {
1459 0 : return NS_ERROR_FAILURE;
1460 : }
1461 :
1462 0 : nsSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
1463 0 : InitEvent(selectionEvent);
1464 :
1465 0 : selectionEvent.mOffset = aOffset;
1466 0 : selectionEvent.mLength = aLength;
1467 0 : selectionEvent.mReversed = aReverse;
1468 :
1469 : nsEventStatus status;
1470 0 : nsresult rv = widget->DispatchEvent(&selectionEvent, status);
1471 0 : NS_ENSURE_SUCCESS(rv, rv);
1472 :
1473 0 : *aResult = selectionEvent.mSucceeded;
1474 0 : return NS_OK;
1475 : }
1476 :
1477 : NS_IMETHODIMP
1478 0 : nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
1479 : nsITransferable * aTransferable)
1480 : {
1481 0 : if (!IsUniversalXPConnectCapable()) {
1482 0 : return NS_ERROR_DOM_SECURITY_ERR;
1483 : }
1484 :
1485 : // get the widget to send the event to
1486 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1487 0 : if (!widget)
1488 0 : return NS_ERROR_FAILURE;
1489 :
1490 : PRInt32 msg;
1491 0 : if (aType.EqualsLiteral("cut"))
1492 0 : msg = NS_CONTENT_COMMAND_CUT;
1493 0 : else if (aType.EqualsLiteral("copy"))
1494 0 : msg = NS_CONTENT_COMMAND_COPY;
1495 0 : else if (aType.EqualsLiteral("paste"))
1496 0 : msg = NS_CONTENT_COMMAND_PASTE;
1497 0 : else if (aType.EqualsLiteral("delete"))
1498 0 : msg = NS_CONTENT_COMMAND_DELETE;
1499 0 : else if (aType.EqualsLiteral("undo"))
1500 0 : msg = NS_CONTENT_COMMAND_UNDO;
1501 0 : else if (aType.EqualsLiteral("redo"))
1502 0 : msg = NS_CONTENT_COMMAND_REDO;
1503 0 : else if (aType.EqualsLiteral("pasteTransferable"))
1504 0 : msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
1505 : else
1506 0 : return NS_ERROR_FAILURE;
1507 :
1508 0 : nsContentCommandEvent event(true, msg, widget);
1509 0 : if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
1510 0 : event.mTransferable = aTransferable;
1511 : }
1512 :
1513 : nsEventStatus status;
1514 0 : return widget->DispatchEvent(&event, status);
1515 : }
1516 :
1517 : NS_IMETHODIMP
1518 0 : nsDOMWindowUtils::GetClassName(const JS::Value& aObject, JSContext* aCx, char** aName)
1519 : {
1520 0 : if (!nsContentUtils::IsCallerTrustedForRead()) {
1521 0 : return NS_ERROR_DOM_SECURITY_ERR;
1522 : }
1523 :
1524 : // Our argument must be a non-null object.
1525 0 : if (JSVAL_IS_PRIMITIVE(aObject)) {
1526 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
1527 : }
1528 :
1529 0 : *aName = NS_strdup(JS_GetClass(JSVAL_TO_OBJECT(aObject))->name);
1530 0 : NS_ABORT_IF_FALSE(*aName, "NS_strdup should be infallible.");
1531 0 : return NS_OK;
1532 : }
1533 :
1534 : NS_IMETHODIMP
1535 0 : nsDOMWindowUtils::GetVisitedDependentComputedStyle(
1536 : nsIDOMElement *aElement, const nsAString& aPseudoElement,
1537 : const nsAString& aPropertyName, nsAString& aResult)
1538 : {
1539 0 : aResult.Truncate();
1540 :
1541 0 : if (!IsUniversalXPConnectCapable()) {
1542 0 : return NS_ERROR_DOM_SECURITY_ERR;
1543 : }
1544 :
1545 0 : nsCOMPtr<nsIDOMCSSStyleDeclaration> decl;
1546 : nsresult rv =
1547 0 : mWindow->GetComputedStyle(aElement, aPseudoElement, getter_AddRefs(decl));
1548 0 : NS_ENSURE_SUCCESS(rv, rv);
1549 :
1550 0 : static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true);
1551 0 : rv = decl->GetPropertyValue(aPropertyName, aResult);
1552 0 : static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false);
1553 :
1554 0 : return rv;
1555 : }
1556 :
1557 : NS_IMETHODIMP
1558 0 : nsDOMWindowUtils::EnterModalState()
1559 : {
1560 0 : mWindow->EnterModalState();
1561 0 : return NS_OK;
1562 : }
1563 :
1564 : NS_IMETHODIMP
1565 0 : nsDOMWindowUtils::LeaveModalState()
1566 : {
1567 0 : mWindow->LeaveModalState(nsnull);
1568 0 : return NS_OK;
1569 : }
1570 :
1571 : NS_IMETHODIMP
1572 0 : nsDOMWindowUtils::EnterModalStateWithWindow(nsIDOMWindow **aWindow)
1573 : {
1574 0 : *aWindow = mWindow->EnterModalState();
1575 0 : NS_IF_ADDREF(*aWindow);
1576 0 : return NS_OK;
1577 : }
1578 :
1579 : NS_IMETHODIMP
1580 0 : nsDOMWindowUtils::LeaveModalStateWithWindow(nsIDOMWindow *aWindow)
1581 : {
1582 0 : NS_ENSURE_ARG_POINTER(aWindow);
1583 0 : mWindow->LeaveModalState(aWindow);
1584 0 : return NS_OK;
1585 : }
1586 :
1587 : NS_IMETHODIMP
1588 0 : nsDOMWindowUtils::IsInModalState(bool *retval)
1589 : {
1590 0 : *retval = mWindow->IsInModalState();
1591 0 : return NS_OK;
1592 : }
1593 :
1594 : NS_IMETHODIMP
1595 0 : nsDOMWindowUtils::GetParent(const JS::Value& aObject,
1596 : JSContext* aCx,
1597 : JS::Value* aParent)
1598 : {
1599 : // This wasn't privileged in the past, but better to expose less than more.
1600 0 : if (!IsUniversalXPConnectCapable()) {
1601 0 : return NS_ERROR_DOM_SECURITY_ERR;
1602 : }
1603 :
1604 : // First argument must be an object.
1605 0 : if (JSVAL_IS_PRIMITIVE(aObject)) {
1606 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
1607 : }
1608 :
1609 0 : JSObject* parent = JS_GetParent(JSVAL_TO_OBJECT(aObject));
1610 0 : *aParent = OBJECT_TO_JSVAL(parent);
1611 :
1612 : // Outerize if necessary.
1613 0 : if (parent) {
1614 0 : if (JSObjectOp outerize = js::GetObjectClass(parent)->ext.outerObject) {
1615 0 : *aParent = OBJECT_TO_JSVAL(outerize(aCx, parent));
1616 : }
1617 : }
1618 :
1619 0 : return NS_OK;
1620 : }
1621 :
1622 : NS_IMETHODIMP
1623 0 : nsDOMWindowUtils::GetOuterWindowID(PRUint64 *aWindowID)
1624 : {
1625 0 : NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
1626 0 : *aWindowID = mWindow->WindowID();
1627 0 : return NS_OK;
1628 : }
1629 :
1630 : NS_IMETHODIMP
1631 0 : nsDOMWindowUtils::GetCurrentInnerWindowID(PRUint64 *aWindowID)
1632 : {
1633 0 : NS_ASSERTION(mWindow->IsOuterWindow(), "How did that happen?");
1634 0 : nsGlobalWindow* inner = mWindow->GetCurrentInnerWindowInternal();
1635 0 : if (!inner) {
1636 0 : return NS_ERROR_NOT_AVAILABLE;
1637 : }
1638 0 : *aWindowID = inner->WindowID();
1639 0 : return NS_OK;
1640 : }
1641 :
1642 : NS_IMETHODIMP
1643 0 : nsDOMWindowUtils::SuspendTimeouts()
1644 : {
1645 0 : if (!IsUniversalXPConnectCapable()) {
1646 0 : return NS_ERROR_DOM_SECURITY_ERR;
1647 : }
1648 :
1649 0 : mWindow->SuspendTimeouts();
1650 :
1651 0 : return NS_OK;
1652 : }
1653 :
1654 : NS_IMETHODIMP
1655 0 : nsDOMWindowUtils::ResumeTimeouts()
1656 : {
1657 0 : if (!IsUniversalXPConnectCapable()) {
1658 0 : return NS_ERROR_DOM_SECURITY_ERR;
1659 : }
1660 :
1661 0 : mWindow->ResumeTimeouts();
1662 :
1663 0 : return NS_OK;
1664 : }
1665 :
1666 : NS_IMETHODIMP
1667 0 : nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
1668 : {
1669 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1670 0 : if (!widget)
1671 0 : return NS_ERROR_FAILURE;
1672 :
1673 0 : LayerManager *mgr = widget->GetLayerManager();
1674 0 : if (!mgr)
1675 0 : return NS_ERROR_FAILURE;
1676 :
1677 0 : mgr->GetBackendName(aType);
1678 :
1679 0 : return NS_OK;
1680 : }
1681 :
1682 : NS_IMETHODIMP
1683 0 : nsDOMWindowUtils::StartFrameTimeRecording()
1684 : {
1685 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1686 0 : if (!widget)
1687 0 : return NS_ERROR_FAILURE;
1688 :
1689 0 : LayerManager *mgr = widget->GetLayerManager();
1690 0 : if (!mgr)
1691 0 : return NS_ERROR_FAILURE;
1692 :
1693 0 : mgr->StartFrameTimeRecording();
1694 :
1695 0 : return NS_OK;
1696 : }
1697 :
1698 : NS_IMETHODIMP
1699 0 : nsDOMWindowUtils::StopFrameTimeRecording(PRUint32 *frameCount NS_OUTPARAM, float **frames NS_OUTPARAM)
1700 : {
1701 0 : NS_ENSURE_ARG_POINTER(frameCount);
1702 0 : NS_ENSURE_ARG_POINTER(frames);
1703 :
1704 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1705 0 : if (!widget)
1706 0 : return NS_ERROR_FAILURE;
1707 :
1708 0 : LayerManager *mgr = widget->GetLayerManager();
1709 0 : if (!mgr)
1710 0 : return NS_ERROR_FAILURE;
1711 :
1712 0 : nsTArray<float> frameTimes = mgr->StopFrameTimeRecording();
1713 :
1714 0 : *frames = nsnull;
1715 0 : *frameCount = frameTimes.Length();
1716 :
1717 0 : if (*frameCount != 0) {
1718 0 : *frames = (float*)nsMemory::Alloc(*frameCount * sizeof(float*));
1719 0 : if (!*frames)
1720 0 : return NS_ERROR_OUT_OF_MEMORY;
1721 :
1722 : /* copy over the frame times into the array we just allocated */
1723 0 : for (PRUint32 i = 0; i < *frameCount; i++) {
1724 0 : (*frames)[i] = frameTimes[i];
1725 : }
1726 : }
1727 :
1728 0 : return NS_OK;
1729 : }
1730 :
1731 : static bool
1732 0 : ComputeAnimationValue(nsCSSProperty aProperty,
1733 : Element* aElement,
1734 : const nsAString& aInput,
1735 : nsStyleAnimation::Value& aOutput)
1736 : {
1737 :
1738 0 : if (!nsStyleAnimation::ComputeValue(aProperty, aElement, aInput,
1739 0 : false, aOutput)) {
1740 0 : return false;
1741 : }
1742 :
1743 : // This matches TransExtractComputedValue in nsTransitionManager.cpp.
1744 0 : if (aProperty == eCSSProperty_visibility) {
1745 0 : NS_ABORT_IF_FALSE(aOutput.GetUnit() == nsStyleAnimation::eUnit_Enumerated,
1746 : "unexpected unit");
1747 : aOutput.SetIntValue(aOutput.GetIntValue(),
1748 0 : nsStyleAnimation::eUnit_Visibility);
1749 : }
1750 :
1751 0 : return true;
1752 : }
1753 :
1754 : NS_IMETHODIMP
1755 0 : nsDOMWindowUtils::AdvanceTimeAndRefresh(PRInt64 aMilliseconds)
1756 : {
1757 0 : if (!IsUniversalXPConnectCapable()) {
1758 0 : return NS_ERROR_DOM_SECURITY_ERR;
1759 : }
1760 :
1761 0 : GetPresContext()->RefreshDriver()->AdvanceTimeAndRefresh(aMilliseconds);
1762 :
1763 0 : return NS_OK;
1764 : }
1765 :
1766 : NS_IMETHODIMP
1767 0 : nsDOMWindowUtils::RestoreNormalRefresh()
1768 : {
1769 0 : if (!IsUniversalXPConnectCapable()) {
1770 0 : return NS_ERROR_DOM_SECURITY_ERR;
1771 : }
1772 :
1773 0 : GetPresContext()->RefreshDriver()->RestoreNormalRefresh();
1774 :
1775 0 : return NS_OK;
1776 : }
1777 :
1778 : NS_IMETHODIMP
1779 0 : nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
1780 : const nsAString& aProperty,
1781 : const nsAString& aValue1,
1782 : const nsAString& aValue2,
1783 : double* aResult)
1784 : {
1785 0 : if (!IsUniversalXPConnectCapable()) {
1786 0 : return NS_ERROR_DOM_SECURITY_ERR;
1787 : }
1788 :
1789 : nsresult rv;
1790 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
1791 0 : NS_ENSURE_SUCCESS(rv, rv);
1792 :
1793 : // Convert direction-dependent properties as appropriate, e.g.,
1794 : // border-left to border-left-value.
1795 0 : nsCSSProperty property = nsCSSProps::LookupProperty(aProperty);
1796 0 : if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
1797 0 : nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
1798 0 : if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
1799 0 : nsCSSProps::OtherNameFor(subprop0) == property) {
1800 0 : property = subprop0;
1801 : } else {
1802 0 : property = eCSSProperty_UNKNOWN;
1803 : }
1804 : }
1805 :
1806 0 : NS_ABORT_IF_FALSE(property == eCSSProperty_UNKNOWN ||
1807 : !nsCSSProps::IsShorthand(property),
1808 : "should not have shorthand");
1809 :
1810 0 : nsStyleAnimation::Value v1, v2;
1811 0 : if (property == eCSSProperty_UNKNOWN ||
1812 0 : !ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
1813 0 : !ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
1814 0 : return NS_ERROR_ILLEGAL_VALUE;
1815 : }
1816 :
1817 0 : if (!nsStyleAnimation::ComputeDistance(property, v1, v2, *aResult)) {
1818 0 : return NS_ERROR_FAILURE;
1819 : }
1820 :
1821 0 : return NS_OK;
1822 : }
1823 :
1824 : nsresult
1825 0 : nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
1826 : PRUint32 aFlags,
1827 : nscolor aBackgroundColor,
1828 : gfxContext* aThebesContext)
1829 : {
1830 : // Get DOM Document
1831 : nsresult rv;
1832 0 : nsCOMPtr<nsIDOMDocument> ddoc;
1833 0 : rv = mWindow->GetDocument(getter_AddRefs(ddoc));
1834 0 : NS_ENSURE_SUCCESS(rv, rv);
1835 :
1836 : // Get Document
1837 0 : nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc, &rv);
1838 0 : NS_ENSURE_SUCCESS(rv, rv);
1839 :
1840 : // Get Primary Shell
1841 0 : nsCOMPtr<nsIPresShell> presShell = doc->GetShell();
1842 0 : NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
1843 :
1844 : // Render Document
1845 0 : return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext);
1846 : }
1847 :
1848 : NS_IMETHODIMP
1849 0 : nsDOMWindowUtils::GetCursorType(PRInt16 *aCursor)
1850 : {
1851 0 : NS_ENSURE_ARG_POINTER(aCursor);
1852 :
1853 0 : bool isSameDoc = false;
1854 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
1855 :
1856 0 : NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
1857 :
1858 0 : do {
1859 0 : if (nsEventStateManager::sMouseOverDocument == doc.get()) {
1860 0 : isSameDoc = true;
1861 0 : break;
1862 : }
1863 0 : } while ((doc = doc->GetParentDocument()));
1864 :
1865 0 : if (!isSameDoc) {
1866 0 : *aCursor = eCursor_none;
1867 0 : return NS_OK;
1868 : }
1869 :
1870 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1871 0 : if (!widget)
1872 0 : return NS_ERROR_FAILURE;
1873 :
1874 : // fetch cursor value from window's widget
1875 0 : *aCursor = widget->GetCursor();
1876 :
1877 0 : return NS_OK;
1878 : }
1879 :
1880 : NS_IMETHODIMP
1881 0 : nsDOMWindowUtils::GoOnline()
1882 : {
1883 : // This is only allowed from about:neterror, which is unprivileged, so it
1884 : // can't access the io-service itself.
1885 0 : NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
1886 0 : nsCOMPtr<nsIDocument> doc(do_QueryInterface(mWindow->GetExtantDocument()));
1887 0 : NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
1888 0 : nsCOMPtr<nsIURI> documentURI;
1889 0 : documentURI = doc->GetDocumentURI();
1890 :
1891 0 : nsCAutoString spec;
1892 0 : documentURI->GetSpec(spec);
1893 0 : if (!StringBeginsWith(spec, NS_LITERAL_CSTRING("about:neterror?")))
1894 0 : return NS_ERROR_DOM_SECURITY_ERR;
1895 :
1896 0 : nsCOMPtr<nsIIOService> ios = do_GetService("@mozilla.org/network/io-service;1");
1897 0 : if (ios) {
1898 0 : ios->SetOffline(false); // !offline
1899 0 : return NS_OK;
1900 : }
1901 0 : return NS_ERROR_NOT_AVAILABLE;
1902 : }
1903 :
1904 : NS_IMETHODIMP
1905 0 : nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
1906 : {
1907 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1908 0 : if (!widget)
1909 0 : return NS_ERROR_FAILURE;
1910 :
1911 0 : *aDPI = widget->GetDPI();
1912 :
1913 0 : return NS_OK;
1914 : }
1915 :
1916 :
1917 : NS_IMETHODIMP
1918 0 : nsDOMWindowUtils::GetOuterWindowWithId(PRUint64 aWindowID,
1919 : nsIDOMWindow** aWindow)
1920 : {
1921 0 : if (!IsUniversalXPConnectCapable()) {
1922 0 : return NS_ERROR_DOM_SECURITY_ERR;
1923 : }
1924 :
1925 0 : *aWindow = nsGlobalWindow::GetOuterWindowWithId(aWindowID);
1926 0 : NS_IF_ADDREF(*aWindow);
1927 0 : return NS_OK;
1928 : }
1929 :
1930 : NS_IMETHODIMP
1931 0 : nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
1932 : nsIDOMFile **aDOMFile) {
1933 0 : NS_ADDREF(*aDOMFile = new nsDOMFileFile(aFile));
1934 0 : return NS_OK;
1935 : }
1936 :
1937 : #ifdef DEBUG
1938 : static bool
1939 0 : CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
1940 : {
1941 0 : gfxMatrix transform;
1942 0 : if (!aLayer->GetTransform().Is2D(&transform) ||
1943 0 : transform.HasNonIntegerTranslation())
1944 0 : return false;
1945 0 : transform.NudgeToIntegers();
1946 0 : nsIntPoint offset = aOffset + nsIntPoint(transform.x0, transform.y0);
1947 :
1948 0 : Layer* child = aLayer->GetFirstChild();
1949 0 : if (child) {
1950 0 : while (child) {
1951 0 : if (!CheckLeafLayers(child, offset, aCoveredRegion))
1952 0 : return false;
1953 0 : child = child->GetNextSibling();
1954 : }
1955 : } else {
1956 0 : nsIntRegion rgn = aLayer->GetVisibleRegion();
1957 0 : rgn.MoveBy(offset);
1958 0 : nsIntRegion tmp;
1959 0 : tmp.And(rgn, *aCoveredRegion);
1960 0 : if (!tmp.IsEmpty())
1961 0 : return false;
1962 0 : aCoveredRegion->Or(*aCoveredRegion, rgn);
1963 : }
1964 :
1965 0 : return true;
1966 : }
1967 : #endif
1968 :
1969 : NS_IMETHODIMP
1970 0 : nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult)
1971 : {
1972 0 : if (!IsUniversalXPConnectCapable()) {
1973 0 : return NS_ERROR_DOM_SECURITY_ERR;
1974 : }
1975 :
1976 0 : *aResult = true;
1977 : #ifdef DEBUG
1978 0 : nsIWidget* widget = GetWidget();
1979 0 : if (!widget)
1980 0 : return NS_ERROR_FAILURE;
1981 0 : LayerManager* manager = widget->GetLayerManager();
1982 0 : if (!manager)
1983 0 : return NS_ERROR_FAILURE;
1984 0 : nsPresContext* presContext = GetPresContext();
1985 0 : if (!presContext)
1986 0 : return NS_ERROR_FAILURE;
1987 0 : Layer* root = manager->GetRoot();
1988 0 : if (!root)
1989 0 : return NS_ERROR_FAILURE;
1990 :
1991 0 : nsIntPoint offset(0, 0);
1992 0 : nsIntRegion coveredRegion;
1993 0 : if (!CheckLeafLayers(root, offset, &coveredRegion)) {
1994 0 : *aResult = false;
1995 : }
1996 0 : if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
1997 0 : *aResult = false;
1998 : }
1999 : #endif
2000 0 : return NS_OK;
2001 : }
2002 :
2003 : NS_IMETHODIMP
2004 0 : nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
2005 : {
2006 0 : if (!IsUniversalXPConnectCapable()) {
2007 0 : return NS_ERROR_DOM_SECURITY_ERR;
2008 : }
2009 :
2010 0 : nsPIDOMWindow* innerWindow = mWindow->GetCurrentInnerWindow();
2011 0 : *aResult = innerWindow ? innerWindow->HasTouchEventListeners() : false;
2012 0 : return NS_OK;
2013 : }
2014 :
2015 : NS_IMETHODIMP
2016 0 : nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
2017 : {
2018 0 : if (!aElement) {
2019 0 : return NS_ERROR_INVALID_ARG;
2020 : }
2021 :
2022 : nsresult rv;
2023 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
2024 0 : NS_ENSURE_SUCCESS(rv, rv);
2025 :
2026 0 : nsIFrame* frame = content->GetPrimaryFrame();
2027 :
2028 0 : if (!frame) {
2029 0 : *aResult = false;
2030 0 : return NS_OK;
2031 : }
2032 :
2033 0 : *aResult = frame->CheckAndClearPaintedState();
2034 0 : return NS_OK;
2035 : }
2036 :
2037 : NS_IMETHODIMP
2038 0 : nsDOMWindowUtils::GetFileId(nsIDOMBlob* aBlob, PRInt64* aResult)
2039 : {
2040 0 : if (!IsUniversalXPConnectCapable()) {
2041 0 : return NS_ERROR_DOM_SECURITY_ERR;
2042 : }
2043 :
2044 0 : *aResult = aBlob->GetFileId();
2045 0 : return NS_OK;
2046 : }
2047 :
2048 : NS_IMETHODIMP
2049 0 : nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName,
2050 : PRInt64 aId, PRInt32* aRefCnt,
2051 : PRInt32* aDBRefCnt, PRInt32* aSliceRefCnt,
2052 : bool* aResult)
2053 : {
2054 0 : if (!IsUniversalXPConnectCapable()) {
2055 0 : return NS_ERROR_DOM_SECURITY_ERR;
2056 : }
2057 :
2058 0 : NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
2059 :
2060 0 : nsCString origin;
2061 : nsresult rv = indexedDB::IndexedDatabaseManager::GetASCIIOriginFromWindow(
2062 0 : mWindow, origin);
2063 0 : NS_ENSURE_SUCCESS(rv, rv);
2064 :
2065 : nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
2066 0 : indexedDB::IndexedDatabaseManager::Get();
2067 :
2068 0 : if (mgr) {
2069 : nsRefPtr<indexedDB::FileManager> fileManager =
2070 0 : mgr->GetFileManager(origin, aDatabaseName);
2071 :
2072 0 : if (fileManager) {
2073 0 : nsRefPtr<indexedDB::FileInfo> fileInfo = fileManager->GetFileInfo(aId);
2074 :
2075 0 : if (fileInfo) {
2076 0 : fileInfo->GetReferences(aRefCnt, aDBRefCnt, aSliceRefCnt);
2077 :
2078 0 : if (*aRefCnt != -1) {
2079 : // We added an extra temp ref, so account for that accordingly.
2080 0 : (*aRefCnt)--;
2081 : }
2082 :
2083 0 : *aResult = true;
2084 0 : return NS_OK;
2085 : }
2086 : }
2087 : }
2088 :
2089 0 : *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1;
2090 0 : *aResult = false;
2091 0 : return NS_OK;
2092 : }
2093 :
2094 : NS_IMETHODIMP
2095 0 : nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
2096 : {
2097 0 : *aResult = js::IsIncrementalGCEnabled(JS_GetRuntime(cx));
2098 0 : return NS_OK;
2099 : }
2100 :
2101 : NS_IMETHODIMP
2102 0 : nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
2103 : {
2104 0 : js::StartPCCountProfiling(cx);
2105 0 : return NS_OK;
2106 : }
2107 :
2108 : NS_IMETHODIMP
2109 0 : nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
2110 : {
2111 0 : js::StopPCCountProfiling(cx);
2112 0 : return NS_OK;
2113 : }
2114 :
2115 : NS_IMETHODIMP
2116 0 : nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
2117 : {
2118 0 : js::PurgePCCounts(cx);
2119 0 : return NS_OK;
2120 : }
2121 :
2122 : NS_IMETHODIMP
2123 0 : nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, PRInt32 *result)
2124 : {
2125 0 : *result = js::GetPCCountScriptCount(cx);
2126 0 : return NS_OK;
2127 : }
2128 :
2129 : NS_IMETHODIMP
2130 0 : nsDOMWindowUtils::GetPCCountScriptSummary(PRInt32 script, JSContext* cx, nsAString& result)
2131 : {
2132 0 : JSString *text = js::GetPCCountScriptSummary(cx, script);
2133 0 : if (!text)
2134 0 : return NS_ERROR_FAILURE;
2135 :
2136 0 : nsDependentJSString str;
2137 0 : if (!str.init(cx, text))
2138 0 : return NS_ERROR_FAILURE;
2139 :
2140 0 : result = str;
2141 0 : return NS_OK;
2142 : }
2143 :
2144 : NS_IMETHODIMP
2145 0 : nsDOMWindowUtils::GetPCCountScriptContents(PRInt32 script, JSContext* cx, nsAString& result)
2146 : {
2147 0 : JSString *text = js::GetPCCountScriptContents(cx, script);
2148 0 : if (!text)
2149 0 : return NS_ERROR_FAILURE;
2150 :
2151 0 : nsDependentJSString str;
2152 0 : if (!str.init(cx, text))
2153 0 : return NS_ERROR_FAILURE;
2154 :
2155 0 : result = str;
2156 0 : return NS_OK;
2157 : }
2158 :
2159 : NS_IMETHODIMP
2160 0 : nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
2161 : {
2162 0 : NS_ENSURE_TRUE(mWindow, NS_ERROR_FAILURE);
2163 0 : nsIDocShell *docShell = mWindow->GetDocShell();
2164 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
2165 :
2166 0 : nsCOMPtr<nsIPresShell> presShell;
2167 0 : docShell->GetPresShell(getter_AddRefs(presShell));
2168 0 : NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
2169 :
2170 0 : *aPaintingSuppressed = presShell->IsPaintingSuppressed();
2171 0 : return NS_OK;
2172 4392 : }
2173 :
|