/src/mozilla-central/dom/base/nsDOMWindowUtils.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "nsDOMWindowUtils.h" |
8 | | |
9 | | #include "mozilla/layers/CompositorBridgeChild.h" |
10 | | #include "mozilla/layers/LayerTransactionChild.h" |
11 | | #include "nsPresContext.h" |
12 | | #include "nsError.h" |
13 | | #include "nsQueryContentEventResult.h" |
14 | | #include "nsGlobalWindow.h" |
15 | | #include "nsIDocument.h" |
16 | | #include "nsFocusManager.h" |
17 | | #include "nsFrameManager.h" |
18 | | #include "nsRefreshDriver.h" |
19 | | #include "mozilla/dom/Animation.h" |
20 | | #include "mozilla/dom/BindingDeclarations.h" |
21 | | #include "mozilla/dom/BlobBinding.h" |
22 | | #include "mozilla/dom/Event.h" |
23 | | #include "mozilla/dom/Touch.h" |
24 | | #include "mozilla/PendingAnimationTracker.h" |
25 | | #include "nsIObjectLoadingContent.h" |
26 | | #include "nsFrame.h" |
27 | | #include "mozilla/layers/ShadowLayers.h" |
28 | | #include "mozilla/layers/APZCCallbackHelper.h" |
29 | | #include "ClientLayerManager.h" |
30 | | #include "nsQueryObject.h" |
31 | | #include "CubebUtils.h" |
32 | | |
33 | | #include "nsIScrollableFrame.h" |
34 | | |
35 | | #include "nsContentUtils.h" |
36 | | |
37 | | #include "nsIFrame.h" |
38 | | #include "nsIWidget.h" |
39 | | #include "nsCharsetSource.h" |
40 | | #include "nsJSEnvironment.h" |
41 | | #include "nsJSUtils.h" |
42 | | |
43 | | #include "mozilla/ChaosMode.h" |
44 | | #include "mozilla/EventStateManager.h" |
45 | | #include "mozilla/MiscEvents.h" |
46 | | #include "mozilla/MouseEvents.h" |
47 | | #include "mozilla/TextEvents.h" |
48 | | #include "mozilla/TextEventDispatcher.h" |
49 | | #include "mozilla/TouchEvents.h" |
50 | | |
51 | | #include "nsViewManager.h" |
52 | | |
53 | | #include "nsLayoutUtils.h" |
54 | | #include "nsComputedDOMStyle.h" |
55 | | #include "nsIPresShell.h" |
56 | | #include "nsCSSProps.h" |
57 | | #include "nsTArrayHelpers.h" |
58 | | #include "nsIDocShell.h" |
59 | | #include "nsIContentViewer.h" |
60 | | #include "mozilla/StyleAnimationValue.h" |
61 | | #include "mozilla/dom/File.h" |
62 | | #include "mozilla/dom/FileBinding.h" |
63 | | #include "mozilla/dom/DOMRect.h" |
64 | | #include <algorithm> |
65 | | |
66 | | #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK) |
67 | | #include <gdk/gdk.h> |
68 | | #include <gdk/gdkx.h> |
69 | | #endif |
70 | | |
71 | | #include "Layers.h" |
72 | | #include "gfxPrefs.h" |
73 | | |
74 | | #include "mozilla/dom/AudioDeviceInfo.h" |
75 | | #include "mozilla/dom/Element.h" |
76 | | #include "mozilla/dom/TabChild.h" |
77 | | #include "mozilla/dom/IDBFactoryBinding.h" |
78 | | #include "mozilla/dom/IDBMutableFileBinding.h" |
79 | | #include "mozilla/dom/IDBMutableFile.h" |
80 | | #include "mozilla/dom/IndexedDatabaseManager.h" |
81 | | #include "mozilla/dom/PermissionMessageUtils.h" |
82 | | #include "mozilla/dom/Text.h" |
83 | | #include "mozilla/dom/quota/PersistenceType.h" |
84 | | #include "mozilla/dom/quota/QuotaManager.h" |
85 | | #include "mozilla/dom/ContentChild.h" |
86 | | #include "mozilla/layers/FrameUniformityData.h" |
87 | | #include "mozilla/layers/ShadowLayers.h" |
88 | | #include "nsPrintfCString.h" |
89 | | #include "nsViewportInfo.h" |
90 | | #include "nsIFormControl.h" |
91 | | #include "nsIScriptError.h" |
92 | | //#include "nsWidgetsCID.h" |
93 | | #include "FrameLayerBuilder.h" |
94 | | #include "nsDisplayList.h" |
95 | | #include "nsROCSSPrimitiveValue.h" |
96 | | #include "nsIBaseWindow.h" |
97 | | #include "nsIDocShellTreeOwner.h" |
98 | | #include "nsIInterfaceRequestorUtils.h" |
99 | | #include "GeckoProfiler.h" |
100 | | #include "mozilla/Preferences.h" |
101 | | #include "nsIContentIterator.h" |
102 | | #include "nsIStyleSheetService.h" |
103 | | #include "nsContentPermissionHelper.h" |
104 | | #include "nsCSSPseudoElements.h" // for CSSPseudoElementType |
105 | | #include "nsNetUtil.h" |
106 | | #include "nsDocument.h" |
107 | | #include "HTMLImageElement.h" |
108 | | #include "HTMLCanvasElement.h" |
109 | | #include "mozilla/css/ImageLoader.h" |
110 | | #include "mozilla/layers/IAPZCTreeManager.h" // for layers::ZoomToRectBehavior |
111 | | #include "mozilla/dom/Promise.h" |
112 | | #include "mozilla/ServoBindings.h" |
113 | | #include "mozilla/StyleSheetInlines.h" |
114 | | #include "mozilla/gfx/GPUProcessManager.h" |
115 | | #include "mozilla/dom/TimeoutManager.h" |
116 | | #include "mozilla/PreloadedStyleSheet.h" |
117 | | #include "mozilla/layers/WebRenderBridgeChild.h" |
118 | | #include "mozilla/layers/WebRenderLayerManager.h" |
119 | | |
120 | | #ifdef XP_WIN |
121 | | #undef GetClassName |
122 | | #endif |
123 | | |
124 | | using namespace mozilla; |
125 | | using namespace mozilla::dom; |
126 | | using namespace mozilla::ipc; |
127 | | using namespace mozilla::layers; |
128 | | using namespace mozilla::widget; |
129 | | using namespace mozilla::gfx; |
130 | | |
131 | | class gfxContext; |
132 | | |
133 | | class OldWindowSize : public LinkedListElement<OldWindowSize> |
134 | | { |
135 | | public: |
136 | | static void Set(nsIWeakReference* aWindowRef, const nsSize& aSize) |
137 | 0 | { |
138 | 0 | OldWindowSize* item = GetItem(aWindowRef); |
139 | 0 | if (item) { |
140 | 0 | item->mSize = aSize; |
141 | 0 | } else { |
142 | 0 | item = new OldWindowSize(aWindowRef, aSize); |
143 | 0 | sList.insertBack(item); |
144 | 0 | } |
145 | 0 | } |
146 | | |
147 | | static nsSize GetAndRemove(nsIWeakReference* aWindowRef) |
148 | 0 | { |
149 | 0 | nsSize result; |
150 | 0 | if (OldWindowSize* item = GetItem(aWindowRef)) { |
151 | 0 | result = item->mSize; |
152 | 0 | delete item; |
153 | 0 | } |
154 | 0 | return result; |
155 | 0 | } |
156 | | |
157 | | private: |
158 | | explicit OldWindowSize(nsIWeakReference* aWindowRef, const nsSize& aSize) |
159 | 0 | : mWindowRef(aWindowRef), mSize(aSize) { } |
160 | 0 | ~OldWindowSize() = default;; |
161 | | |
162 | | static OldWindowSize* GetItem(nsIWeakReference* aWindowRef) |
163 | 0 | { |
164 | 0 | OldWindowSize* item = sList.getFirst(); |
165 | 0 | while (item && item->mWindowRef != aWindowRef) { |
166 | 0 | item = item->getNext(); |
167 | 0 | } |
168 | 0 | return item; |
169 | 0 | } |
170 | | |
171 | | static LinkedList<OldWindowSize> sList; |
172 | | nsWeakPtr mWindowRef; |
173 | | nsSize mSize; |
174 | | }; |
175 | | |
176 | | namespace { |
177 | | |
178 | | class NativeInputRunnable final : public PrioritizableRunnable |
179 | | { |
180 | | explicit NativeInputRunnable(already_AddRefed<nsIRunnable>&& aEvent); |
181 | 0 | ~NativeInputRunnable() {} |
182 | | public: |
183 | | static already_AddRefed<nsIRunnable> Create(already_AddRefed<nsIRunnable>&& aEvent); |
184 | | }; |
185 | | |
186 | | NativeInputRunnable::NativeInputRunnable(already_AddRefed<nsIRunnable>&& aEvent) |
187 | | : PrioritizableRunnable(std::move(aEvent), nsIRunnablePriority::PRIORITY_INPUT) |
188 | 0 | { |
189 | 0 | } |
190 | | |
191 | | /* static */ already_AddRefed<nsIRunnable> |
192 | | NativeInputRunnable::Create(already_AddRefed<nsIRunnable>&& aEvent) |
193 | 0 | { |
194 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
195 | 0 | nsCOMPtr<nsIRunnable> event(new NativeInputRunnable(std::move(aEvent))); |
196 | 0 | return event.forget(); |
197 | 0 | } |
198 | | |
199 | | } // unnamed namespace |
200 | | |
201 | | LinkedList<OldWindowSize> OldWindowSize::sList; |
202 | | |
203 | 0 | NS_INTERFACE_MAP_BEGIN(nsDOMWindowUtils) |
204 | 0 | NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWindowUtils) |
205 | 0 | NS_INTERFACE_MAP_ENTRY(nsIDOMWindowUtils) |
206 | 0 | NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) |
207 | 0 | NS_INTERFACE_MAP_END |
208 | | |
209 | | NS_IMPL_ADDREF(nsDOMWindowUtils) |
210 | | NS_IMPL_RELEASE(nsDOMWindowUtils) |
211 | | |
212 | | nsDOMWindowUtils::nsDOMWindowUtils(nsGlobalWindowOuter *aWindow) |
213 | 0 | { |
214 | 0 | nsCOMPtr<nsISupports> supports = do_QueryObject(aWindow); |
215 | 0 | mWindow = do_GetWeakReference(supports); |
216 | 0 | } |
217 | | |
218 | | nsDOMWindowUtils::~nsDOMWindowUtils() |
219 | 0 | { |
220 | 0 | OldWindowSize::GetAndRemove(mWindow); |
221 | 0 | } |
222 | | |
223 | | nsIPresShell* |
224 | | nsDOMWindowUtils::GetPresShell() |
225 | 0 | { |
226 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
227 | 0 | if (!window) |
228 | 0 | return nullptr; |
229 | 0 | |
230 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
231 | 0 | if (!docShell) |
232 | 0 | return nullptr; |
233 | 0 | |
234 | 0 | return docShell->GetPresShell(); |
235 | 0 | } |
236 | | |
237 | | nsPresContext* |
238 | | nsDOMWindowUtils::GetPresContext() |
239 | 0 | { |
240 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
241 | 0 | if (!window) |
242 | 0 | return nullptr; |
243 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
244 | 0 | if (!docShell) |
245 | 0 | return nullptr; |
246 | 0 | RefPtr<nsPresContext> presContext; |
247 | 0 | docShell->GetPresContext(getter_AddRefs(presContext)); |
248 | 0 | return presContext; |
249 | 0 | } |
250 | | |
251 | | nsIDocument* |
252 | | nsDOMWindowUtils::GetDocument() |
253 | 0 | { |
254 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
255 | 0 | if (!window) { |
256 | 0 | return nullptr; |
257 | 0 | } |
258 | 0 | return window->GetExtantDoc(); |
259 | 0 | } |
260 | | |
261 | | LayerTransactionChild* |
262 | | nsDOMWindowUtils::GetLayerTransaction() |
263 | 0 | { |
264 | 0 | nsIWidget* widget = GetWidget(); |
265 | 0 | if (!widget) |
266 | 0 | return nullptr; |
267 | 0 | |
268 | 0 | LayerManager* manager = widget->GetLayerManager(); |
269 | 0 | if (!manager) |
270 | 0 | return nullptr; |
271 | 0 | |
272 | 0 | ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); |
273 | 0 | return forwarder && forwarder->HasShadowManager() ? |
274 | 0 | forwarder->GetShadowManager() : |
275 | 0 | nullptr; |
276 | 0 | } |
277 | | |
278 | | WebRenderBridgeChild* |
279 | | nsDOMWindowUtils::GetWebRenderBridge() |
280 | 0 | { |
281 | 0 | if (nsIWidget* widget = GetWidget()) { |
282 | 0 | if (LayerManager* lm = widget->GetLayerManager()) { |
283 | 0 | if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) { |
284 | 0 | return wrlm->WrBridge(); |
285 | 0 | } |
286 | 0 | } |
287 | 0 | } |
288 | 0 | return nullptr; |
289 | 0 | } |
290 | | |
291 | | NS_IMETHODIMP |
292 | | nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode) |
293 | 0 | { |
294 | 0 | NS_ENSURE_ARG_POINTER(aMode); |
295 | 0 | *aMode = 0; |
296 | 0 | nsPresContext* presContext = GetPresContext(); |
297 | 0 | if (presContext) { |
298 | 0 | *aMode = presContext->ImageAnimationMode(); |
299 | 0 | return NS_OK; |
300 | 0 | } |
301 | 0 | return NS_ERROR_NOT_AVAILABLE; |
302 | 0 | } |
303 | | |
304 | | NS_IMETHODIMP |
305 | | nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode) |
306 | 0 | { |
307 | 0 | nsPresContext* presContext = GetPresContext(); |
308 | 0 | if (presContext) { |
309 | 0 | presContext->SetImageAnimationMode(aMode); |
310 | 0 | return NS_OK; |
311 | 0 | } |
312 | 0 | return NS_ERROR_NOT_AVAILABLE; |
313 | 0 | } |
314 | | |
315 | | NS_IMETHODIMP |
316 | | nsDOMWindowUtils::GetDocCharsetIsForced(bool *aIsForced) |
317 | 0 | { |
318 | 0 | *aIsForced = false; |
319 | 0 |
|
320 | 0 | nsIDocument* doc = GetDocument(); |
321 | 0 | *aIsForced = doc && |
322 | 0 | doc->GetDocumentCharacterSetSource() >= kCharsetFromParentForced; |
323 | 0 | return NS_OK; |
324 | 0 | } |
325 | | |
326 | | NS_IMETHODIMP |
327 | | nsDOMWindowUtils::GetPhysicalMillimeterInCSSPixels(float* aPhysicalMillimeter) |
328 | 0 | { |
329 | 0 | nsPresContext* presContext = GetPresContext(); |
330 | 0 | if (!presContext) { |
331 | 0 | return NS_ERROR_NOT_AVAILABLE; |
332 | 0 | } |
333 | 0 | |
334 | 0 | *aPhysicalMillimeter = nsPresContext::AppUnitsToFloatCSSPixels( |
335 | 0 | presContext->PhysicalMillimetersToAppUnits(1)); |
336 | 0 | return NS_OK; |
337 | 0 | } |
338 | | |
339 | | NS_IMETHODIMP |
340 | | nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName, |
341 | | nsAString& aValue) |
342 | 0 | { |
343 | 0 | nsIDocument* doc = GetDocument(); |
344 | 0 | if (doc) { |
345 | 0 | RefPtr<nsAtom> name = NS_Atomize(aName); |
346 | 0 | doc->GetHeaderData(name, aValue); |
347 | 0 | return NS_OK; |
348 | 0 | } |
349 | 0 | |
350 | 0 | aValue.Truncate(); |
351 | 0 | return NS_OK; |
352 | 0 | } |
353 | | |
354 | | NS_IMETHODIMP |
355 | | nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut) |
356 | 0 | { |
357 | 0 | if (aCount == 0) |
358 | 0 | aCount = 1; |
359 | 0 |
|
360 | 0 | if (nsIPresShell* presShell = GetPresShell()) { |
361 | 0 | nsIFrame *rootFrame = presShell->GetRootFrame(); |
362 | 0 |
|
363 | 0 | if (rootFrame) { |
364 | 0 | PRIntervalTime iStart = PR_IntervalNow(); |
365 | 0 |
|
366 | 0 | for (uint32_t i = 0; i < aCount; i++) |
367 | 0 | rootFrame->InvalidateFrame(); |
368 | 0 |
|
369 | 0 | #if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK) |
370 | 0 | if (!gfxPlatform::IsHeadless()) { |
371 | 0 | XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), False); |
372 | 0 | } |
373 | 0 | #endif |
374 | 0 |
|
375 | 0 | *aDurationOut = PR_IntervalToMilliseconds(PR_IntervalNow() - iStart); |
376 | 0 |
|
377 | 0 | return NS_OK; |
378 | 0 | } |
379 | 0 | } |
380 | 0 | return NS_ERROR_FAILURE; |
381 | 0 | } |
382 | | |
383 | | NS_IMETHODIMP |
384 | | nsDOMWindowUtils::UpdateLayerTree() |
385 | 0 | { |
386 | 0 | if (nsIPresShell* presShell = GetPresShell()) { |
387 | 0 | // Don't flush throttled animations since it might fire MozAfterPaint event |
388 | 0 | // (in WebRender it constantly does), thus the reftest harness can't take |
389 | 0 | // any snapshot until the throttled animations finished. |
390 | 0 | presShell->FlushPendingNotifications( |
391 | 0 | ChangesToFlush(FlushType::Display, false /* flush animations */)); |
392 | 0 | RefPtr<nsViewManager> vm = presShell->GetViewManager(); |
393 | 0 | nsView* view = vm->GetRootView(); |
394 | 0 | if (view) { |
395 | 0 | nsAutoScriptBlocker scriptBlocker; |
396 | 0 | presShell->Paint(view, view->GetBounds(), |
397 | 0 | nsIPresShell::PAINT_LAYERS | nsIPresShell::PAINT_SYNC_DECODE_IMAGES); |
398 | 0 | presShell->GetLayerManager()->WaitOnTransactionProcessed(); |
399 | 0 | } |
400 | 0 | } |
401 | 0 | return NS_OK; |
402 | 0 | } |
403 | | |
404 | | NS_IMETHODIMP |
405 | | nsDOMWindowUtils::GetContentViewerSize(uint32_t *aDisplayWidth, uint32_t *aDisplayHeight) |
406 | 0 | { |
407 | 0 | nsIPresShell* presShell = GetPresShell(); |
408 | 0 | LayoutDeviceIntSize displaySize; |
409 | 0 |
|
410 | 0 | if (!presShell || !nsLayoutUtils::GetContentViewerSize(presShell->GetPresContext(), displaySize)) { |
411 | 0 | return NS_ERROR_FAILURE; |
412 | 0 | } |
413 | 0 | |
414 | 0 | *aDisplayWidth = displaySize.width; |
415 | 0 | *aDisplayHeight = displaySize.height; |
416 | 0 |
|
417 | 0 | return NS_OK; |
418 | 0 | } |
419 | | |
420 | | NS_IMETHODIMP |
421 | | nsDOMWindowUtils::GetViewportInfo(uint32_t aDisplayWidth, |
422 | | uint32_t aDisplayHeight, |
423 | | double *aDefaultZoom, bool *aAllowZoom, |
424 | | double *aMinZoom, double *aMaxZoom, |
425 | | uint32_t *aWidth, uint32_t *aHeight, |
426 | | bool *aAutoSize) |
427 | 0 | { |
428 | 0 | nsIDocument* doc = GetDocument(); |
429 | 0 | NS_ENSURE_STATE(doc); |
430 | 0 |
|
431 | 0 | nsViewportInfo info = doc->GetViewportInfo(ScreenIntSize(aDisplayWidth, aDisplayHeight)); |
432 | 0 | *aDefaultZoom = info.GetDefaultZoom().scale; |
433 | 0 | *aAllowZoom = info.IsZoomAllowed(); |
434 | 0 | *aMinZoom = info.GetMinZoom().scale; |
435 | 0 | *aMaxZoom = info.GetMaxZoom().scale; |
436 | 0 | CSSIntSize size = gfx::RoundedToInt(info.GetSize()); |
437 | 0 | *aWidth = size.width; |
438 | 0 | *aHeight = size.height; |
439 | 0 | *aAutoSize = info.IsAutoSizeEnabled(); |
440 | 0 | return NS_OK; |
441 | 0 | } |
442 | | |
443 | | NS_IMETHODIMP |
444 | | nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx, |
445 | | float aWidthPx, float aHeightPx, |
446 | | Element* aElement, |
447 | | uint32_t aPriority) |
448 | 0 | { |
449 | 0 | nsIPresShell* presShell = GetPresShell(); |
450 | 0 | if (!presShell) { |
451 | 0 | return NS_ERROR_FAILURE; |
452 | 0 | } |
453 | 0 | |
454 | 0 | if (!aElement) { |
455 | 0 | return NS_ERROR_INVALID_ARG; |
456 | 0 | } |
457 | 0 | |
458 | 0 | if (aElement->GetUncomposedDoc() != presShell->GetDocument()) { |
459 | 0 | return NS_ERROR_INVALID_ARG; |
460 | 0 | } |
461 | 0 | |
462 | 0 | DisplayPortPropertyData* currentData = |
463 | 0 | static_cast<DisplayPortPropertyData*>(aElement->GetProperty(nsGkAtoms::DisplayPort)); |
464 | 0 | if (currentData && currentData->mPriority > aPriority) { |
465 | 0 | return NS_OK; |
466 | 0 | } |
467 | 0 | |
468 | 0 | nsRect displayport(nsPresContext::CSSPixelsToAppUnits(aXPx), |
469 | 0 | nsPresContext::CSSPixelsToAppUnits(aYPx), |
470 | 0 | nsPresContext::CSSPixelsToAppUnits(aWidthPx), |
471 | 0 | nsPresContext::CSSPixelsToAppUnits(aHeightPx)); |
472 | 0 |
|
473 | 0 | aElement->SetProperty(nsGkAtoms::DisplayPort, |
474 | 0 | new DisplayPortPropertyData(displayport, aPriority), |
475 | 0 | nsINode::DeleteProperty<DisplayPortPropertyData>); |
476 | 0 |
|
477 | 0 | if (gfxPrefs::LayoutUseContainersForRootFrames()) { |
478 | 0 | nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame(); |
479 | 0 | if (rootScrollFrame && |
480 | 0 | aElement == rootScrollFrame->GetContent() && |
481 | 0 | nsLayoutUtils::UsesAsyncScrolling(rootScrollFrame)) |
482 | 0 | { |
483 | 0 | // We are setting a root displayport for a document. |
484 | 0 | // The pres shell needs a special flag set. |
485 | 0 | presShell->SetIgnoreViewportScrolling(true); |
486 | 0 | } |
487 | 0 | } |
488 | 0 |
|
489 | 0 | nsLayoutUtils::InvalidateForDisplayPortChange(aElement, !!currentData, |
490 | 0 | currentData ? currentData->mRect : nsRect(), displayport); |
491 | 0 |
|
492 | 0 | nsIFrame* rootFrame = presShell->GetRootFrame(); |
493 | 0 | if (rootFrame) { |
494 | 0 | rootFrame->SchedulePaint(); |
495 | 0 |
|
496 | 0 | // If we are hiding something that is a display root then send empty paint |
497 | 0 | // transaction in order to release retained layers because it won't get |
498 | 0 | // any more paint requests when it is hidden. |
499 | 0 | if (displayport.IsEmpty() && |
500 | 0 | rootFrame == nsLayoutUtils::GetDisplayRootFrame(rootFrame)) { |
501 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
502 | 0 | if (widget) { |
503 | 0 | LayerManager* manager = widget->GetLayerManager(); |
504 | 0 | manager->BeginTransaction(); |
505 | 0 | using PaintFrameFlags = nsLayoutUtils::PaintFrameFlags; |
506 | 0 | nsLayoutUtils::PaintFrame(nullptr, rootFrame, nsRegion(), |
507 | 0 | NS_RGB(255, 255, 255), |
508 | 0 | nsDisplayListBuilderMode::PAINTING, |
509 | 0 | PaintFrameFlags::PAINT_WIDGET_LAYERS | |
510 | 0 | PaintFrameFlags::PAINT_EXISTING_TRANSACTION); |
511 | 0 | } |
512 | 0 | } |
513 | 0 | } |
514 | 0 |
|
515 | 0 | return NS_OK; |
516 | 0 | } |
517 | | |
518 | | NS_IMETHODIMP |
519 | | nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin, |
520 | | float aTopMargin, |
521 | | float aRightMargin, |
522 | | float aBottomMargin, |
523 | | Element* aElement, |
524 | | uint32_t aPriority) |
525 | 0 | { |
526 | 0 | nsIPresShell* presShell = GetPresShell(); |
527 | 0 | if (!presShell) { |
528 | 0 | return NS_ERROR_FAILURE; |
529 | 0 | } |
530 | 0 | |
531 | 0 | if (!aElement) { |
532 | 0 | return NS_ERROR_INVALID_ARG; |
533 | 0 | } |
534 | 0 | |
535 | 0 | if (aElement->GetUncomposedDoc() != presShell->GetDocument()) { |
536 | 0 | return NS_ERROR_INVALID_ARG; |
537 | 0 | } |
538 | 0 | |
539 | 0 | // Note order change of arguments between our function signature and |
540 | 0 | // ScreenMargin constructor. |
541 | 0 | ScreenMargin displayportMargins(aTopMargin, |
542 | 0 | aRightMargin, |
543 | 0 | aBottomMargin, |
544 | 0 | aLeftMargin); |
545 | 0 |
|
546 | 0 | nsLayoutUtils::SetDisplayPortMargins(aElement, presShell, displayportMargins, |
547 | 0 | aPriority); |
548 | 0 |
|
549 | 0 | return NS_OK; |
550 | 0 | } |
551 | | |
552 | | |
553 | | NS_IMETHODIMP |
554 | | nsDOMWindowUtils::SetDisplayPortBaseForElement(int32_t aX, |
555 | | int32_t aY, |
556 | | int32_t aWidth, |
557 | | int32_t aHeight, |
558 | | Element* aElement) |
559 | 0 | { |
560 | 0 | nsIPresShell* presShell = GetPresShell(); |
561 | 0 | if (!presShell) { |
562 | 0 | return NS_ERROR_FAILURE; |
563 | 0 | } |
564 | 0 | |
565 | 0 | if (!aElement) { |
566 | 0 | return NS_ERROR_INVALID_ARG; |
567 | 0 | } |
568 | 0 | |
569 | 0 | if (aElement->GetUncomposedDoc() != presShell->GetDocument()) { |
570 | 0 | return NS_ERROR_INVALID_ARG; |
571 | 0 | } |
572 | 0 | |
573 | 0 | nsLayoutUtils::SetDisplayPortBase(aElement, nsRect(aX, aY, aWidth, aHeight)); |
574 | 0 |
|
575 | 0 | return NS_OK; |
576 | 0 | } |
577 | | |
578 | | NS_IMETHODIMP |
579 | | nsDOMWindowUtils::SetResolution(float aResolution) |
580 | 0 | { |
581 | 0 | nsIPresShell* presShell = GetPresShell(); |
582 | 0 | if (!presShell) { |
583 | 0 | return NS_ERROR_FAILURE; |
584 | 0 | } |
585 | 0 | |
586 | 0 | presShell->SetResolution(aResolution); |
587 | 0 |
|
588 | 0 | return NS_OK; |
589 | 0 | } |
590 | | |
591 | | NS_IMETHODIMP |
592 | | nsDOMWindowUtils::SetResolutionAndScaleTo(float aResolution) |
593 | 0 | { |
594 | 0 | nsIPresShell* presShell = GetPresShell(); |
595 | 0 | if (!presShell) { |
596 | 0 | return NS_ERROR_FAILURE; |
597 | 0 | } |
598 | 0 | |
599 | 0 | presShell->SetResolutionAndScaleTo(aResolution); |
600 | 0 |
|
601 | 0 | return NS_OK; |
602 | 0 | } |
603 | | |
604 | | NS_IMETHODIMP |
605 | | nsDOMWindowUtils::SetRestoreResolution(float aResolution, |
606 | | uint32_t aDisplayWidth, |
607 | | uint32_t aDisplayHeight) |
608 | 0 | { |
609 | 0 | nsIPresShell* presShell = GetPresShell(); |
610 | 0 | if (!presShell) { |
611 | 0 | return NS_ERROR_FAILURE; |
612 | 0 | } |
613 | 0 | |
614 | 0 | presShell->SetRestoreResolution(aResolution, |
615 | 0 | LayoutDeviceIntSize(aDisplayWidth, aDisplayHeight)); |
616 | 0 |
|
617 | 0 | return NS_OK; |
618 | 0 | } |
619 | | |
620 | | NS_IMETHODIMP |
621 | | nsDOMWindowUtils::GetResolution(float* aResolution) |
622 | 0 | { |
623 | 0 | nsIPresShell* presShell = GetPresShell(); |
624 | 0 | if (!presShell) { |
625 | 0 | return NS_ERROR_FAILURE; |
626 | 0 | } |
627 | 0 | |
628 | 0 | *aResolution = presShell->GetResolution(); |
629 | 0 |
|
630 | 0 | return NS_OK; |
631 | 0 | } |
632 | | |
633 | | NS_IMETHODIMP |
634 | 0 | nsDOMWindowUtils::GetIsResolutionSet(bool* aIsResolutionSet) { |
635 | 0 | nsIPresShell* presShell = GetPresShell(); |
636 | 0 | if (!presShell) { |
637 | 0 | return NS_ERROR_FAILURE; |
638 | 0 | } |
639 | 0 | |
640 | 0 | *aIsResolutionSet = presShell->IsResolutionSet(); |
641 | 0 |
|
642 | 0 | return NS_OK; |
643 | 0 | } |
644 | | |
645 | | NS_IMETHODIMP |
646 | | nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint) |
647 | 0 | { |
648 | 0 | nsIPresShell* presShell = GetPresShell(); |
649 | 0 | if (presShell) { |
650 | 0 | presShell->SetIsFirstPaint(aIsFirstPaint); |
651 | 0 | return NS_OK; |
652 | 0 | } |
653 | 0 | return NS_ERROR_FAILURE; |
654 | 0 | } |
655 | | |
656 | | NS_IMETHODIMP |
657 | | nsDOMWindowUtils::GetIsFirstPaint(bool *aIsFirstPaint) |
658 | 0 | { |
659 | 0 | nsIPresShell* presShell = GetPresShell(); |
660 | 0 | if (presShell) { |
661 | 0 | *aIsFirstPaint = presShell->GetIsFirstPaint(); |
662 | 0 | return NS_OK; |
663 | 0 | } |
664 | 0 | return NS_ERROR_FAILURE; |
665 | 0 | } |
666 | | |
667 | | NS_IMETHODIMP |
668 | | nsDOMWindowUtils::GetPresShellId(uint32_t *aPresShellId) |
669 | 0 | { |
670 | 0 | nsIPresShell* presShell = GetPresShell(); |
671 | 0 | if (presShell) { |
672 | 0 | *aPresShellId = presShell->GetPresShellId(); |
673 | 0 | return NS_OK; |
674 | 0 | } |
675 | 0 | return NS_ERROR_FAILURE; |
676 | 0 | } |
677 | | |
678 | | NS_IMETHODIMP |
679 | | nsDOMWindowUtils::SendMouseEvent(const nsAString& aType, |
680 | | float aX, |
681 | | float aY, |
682 | | int32_t aButton, |
683 | | int32_t aClickCount, |
684 | | int32_t aModifiers, |
685 | | bool aIgnoreRootScrollFrame, |
686 | | float aPressure, |
687 | | unsigned short aInputSourceArg, |
688 | | bool aIsDOMEventSynthesized, |
689 | | bool aIsWidgetEventSynthesized, |
690 | | int32_t aButtons, |
691 | | uint32_t aIdentifier, |
692 | | uint8_t aOptionalArgCount, |
693 | | bool *aPreventDefault) |
694 | 0 | { |
695 | 0 | return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers, |
696 | 0 | aIgnoreRootScrollFrame, aPressure, |
697 | 0 | aInputSourceArg, |
698 | 0 | aOptionalArgCount >= 7 ? |
699 | 0 | aIdentifier : DEFAULT_MOUSE_POINTER_ID, |
700 | 0 | false, aPreventDefault, |
701 | 0 | aOptionalArgCount >= 4 ? |
702 | 0 | aIsDOMEventSynthesized : true, |
703 | 0 | aOptionalArgCount >= 5 ? |
704 | 0 | aIsWidgetEventSynthesized : false, |
705 | 0 | aOptionalArgCount >= 6 ? |
706 | 0 | aButtons : MOUSE_BUTTONS_NOT_SPECIFIED); |
707 | 0 | } |
708 | | |
709 | | NS_IMETHODIMP |
710 | | nsDOMWindowUtils::SendMouseEventToWindow(const nsAString& aType, |
711 | | float aX, |
712 | | float aY, |
713 | | int32_t aButton, |
714 | | int32_t aClickCount, |
715 | | int32_t aModifiers, |
716 | | bool aIgnoreRootScrollFrame, |
717 | | float aPressure, |
718 | | unsigned short aInputSourceArg, |
719 | | bool aIsDOMEventSynthesized, |
720 | | bool aIsWidgetEventSynthesized, |
721 | | int32_t aButtons, |
722 | | uint32_t aIdentifier, |
723 | | uint8_t aOptionalArgCount) |
724 | 0 | { |
725 | 0 | AUTO_PROFILER_LABEL("nsDOMWindowUtils::SendMouseEventToWindow", OTHER); |
726 | 0 |
|
727 | 0 | return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers, |
728 | 0 | aIgnoreRootScrollFrame, aPressure, |
729 | 0 | aInputSourceArg, |
730 | 0 | aOptionalArgCount >= 7 ? |
731 | 0 | aIdentifier : DEFAULT_MOUSE_POINTER_ID, |
732 | 0 | true, nullptr, |
733 | 0 | aOptionalArgCount >= 4 ? |
734 | 0 | aIsDOMEventSynthesized : true, |
735 | 0 | aOptionalArgCount >= 5 ? |
736 | 0 | aIsWidgetEventSynthesized : false, |
737 | 0 | aOptionalArgCount >= 6 ? |
738 | 0 | aButtons : MOUSE_BUTTONS_NOT_SPECIFIED); |
739 | 0 | } |
740 | | |
741 | | NS_IMETHODIMP |
742 | | nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType, |
743 | | float aX, |
744 | | float aY, |
745 | | int32_t aButton, |
746 | | int32_t aClickCount, |
747 | | int32_t aModifiers, |
748 | | bool aIgnoreRootScrollFrame, |
749 | | float aPressure, |
750 | | unsigned short aInputSourceArg, |
751 | | uint32_t aPointerId, |
752 | | bool aToWindow, |
753 | | bool *aPreventDefault, |
754 | | bool aIsDOMEventSynthesized, |
755 | | bool aIsWidgetEventSynthesized, |
756 | | int32_t aButtons) |
757 | 0 | { |
758 | 0 | nsCOMPtr<nsIPresShell> presShell = GetPresShell(); |
759 | 0 | return nsContentUtils::SendMouseEvent(presShell, aType, aX, aY, aButton, |
760 | 0 | aButtons, aClickCount, aModifiers, aIgnoreRootScrollFrame, aPressure, |
761 | 0 | aInputSourceArg, aPointerId, aToWindow, aPreventDefault, |
762 | 0 | aIsDOMEventSynthesized, aIsWidgetEventSynthesized); |
763 | 0 | } |
764 | | |
765 | | NS_IMETHODIMP |
766 | | nsDOMWindowUtils::SendWheelEvent(float aX, |
767 | | float aY, |
768 | | double aDeltaX, |
769 | | double aDeltaY, |
770 | | double aDeltaZ, |
771 | | uint32_t aDeltaMode, |
772 | | int32_t aModifiers, |
773 | | int32_t aLineOrPageDeltaX, |
774 | | int32_t aLineOrPageDeltaY, |
775 | | uint32_t aOptions) |
776 | 0 | { |
777 | 0 | // get the widget to send the event to |
778 | 0 | nsPoint offset; |
779 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(&offset); |
780 | 0 | if (!widget) { |
781 | 0 | return NS_ERROR_NULL_POINTER; |
782 | 0 | } |
783 | 0 | |
784 | 0 | WidgetWheelEvent wheelEvent(true, eWheel, widget); |
785 | 0 | wheelEvent.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers); |
786 | 0 | wheelEvent.mDeltaX = aDeltaX; |
787 | 0 | wheelEvent.mDeltaY = aDeltaY; |
788 | 0 | wheelEvent.mDeltaZ = aDeltaZ; |
789 | 0 | wheelEvent.mDeltaMode = aDeltaMode; |
790 | 0 | wheelEvent.mIsMomentum = |
791 | 0 | (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0; |
792 | 0 | wheelEvent.mIsNoLineOrPageDelta = |
793 | 0 | (aOptions & WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE) != 0; |
794 | 0 | wheelEvent.mCustomizedByUserPrefs = |
795 | 0 | (aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0; |
796 | 0 | wheelEvent.mLineOrPageDeltaX = aLineOrPageDeltaX; |
797 | 0 | wheelEvent.mLineOrPageDeltaY = aLineOrPageDeltaY; |
798 | 0 |
|
799 | 0 | wheelEvent.mTime = PR_Now() / 1000; |
800 | 0 |
|
801 | 0 | nsPresContext* presContext = GetPresContext(); |
802 | 0 | NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); |
803 | 0 |
|
804 | 0 | wheelEvent.mRefPoint = |
805 | 0 | nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); |
806 | 0 |
|
807 | 0 | widget->DispatchInputEvent(&wheelEvent); |
808 | 0 |
|
809 | 0 | if (widget->AsyncPanZoomEnabled()) { |
810 | 0 | // Computing overflow deltas is not compatible with APZ, so if APZ is |
811 | 0 | // enabled, we skip testing it. |
812 | 0 | return NS_OK; |
813 | 0 | } |
814 | 0 | |
815 | 0 | bool failedX = false; |
816 | 0 | if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO) && |
817 | 0 | wheelEvent.mOverflowDeltaX != 0) { |
818 | 0 | failedX = true; |
819 | 0 | } |
820 | 0 | if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_POSITIVE) && |
821 | 0 | wheelEvent.mOverflowDeltaX <= 0) { |
822 | 0 | failedX = true; |
823 | 0 | } |
824 | 0 | if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_NEGATIVE) && |
825 | 0 | wheelEvent.mOverflowDeltaX >= 0) { |
826 | 0 | failedX = true; |
827 | 0 | } |
828 | 0 | bool failedY = false; |
829 | 0 | if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_ZERO) && |
830 | 0 | wheelEvent.mOverflowDeltaY != 0) { |
831 | 0 | failedY = true; |
832 | 0 | } |
833 | 0 | if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_POSITIVE) && |
834 | 0 | wheelEvent.mOverflowDeltaY <= 0) { |
835 | 0 | failedY = true; |
836 | 0 | } |
837 | 0 | if ((aOptions & WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_Y_NEGATIVE) && |
838 | 0 | wheelEvent.mOverflowDeltaY >= 0) { |
839 | 0 | failedY = true; |
840 | 0 | } |
841 | 0 |
|
842 | | #ifdef DEBUG |
843 | | if (failedX) { |
844 | | nsPrintfCString debugMsg("SendWheelEvent(): unexpected mOverflowDeltaX: %f", |
845 | | wheelEvent.mOverflowDeltaX); |
846 | | NS_WARNING(debugMsg.get()); |
847 | | } |
848 | | if (failedY) { |
849 | | nsPrintfCString debugMsg("SendWheelEvent(): unexpected mOverflowDeltaY: %f", |
850 | | wheelEvent.mOverflowDeltaY); |
851 | | NS_WARNING(debugMsg.get()); |
852 | | } |
853 | | #endif |
854 | |
|
855 | 0 | return (!failedX && !failedY) ? NS_OK : NS_ERROR_FAILURE; |
856 | 0 | } |
857 | | |
858 | | NS_IMETHODIMP |
859 | | nsDOMWindowUtils::SendTouchEvent(const nsAString& aType, |
860 | | uint32_t *aIdentifiers, |
861 | | int32_t *aXs, |
862 | | int32_t *aYs, |
863 | | uint32_t *aRxs, |
864 | | uint32_t *aRys, |
865 | | float *aRotationAngles, |
866 | | float *aForces, |
867 | | uint32_t aCount, |
868 | | int32_t aModifiers, |
869 | | bool aIgnoreRootScrollFrame, |
870 | | bool *aPreventDefault) |
871 | 0 | { |
872 | 0 | return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys, |
873 | 0 | aRotationAngles, aForces, aCount, aModifiers, |
874 | 0 | aIgnoreRootScrollFrame, false, aPreventDefault); |
875 | 0 | } |
876 | | |
877 | | NS_IMETHODIMP |
878 | | nsDOMWindowUtils::SendTouchEventToWindow(const nsAString& aType, |
879 | | uint32_t* aIdentifiers, |
880 | | int32_t* aXs, |
881 | | int32_t* aYs, |
882 | | uint32_t* aRxs, |
883 | | uint32_t* aRys, |
884 | | float* aRotationAngles, |
885 | | float* aForces, |
886 | | uint32_t aCount, |
887 | | int32_t aModifiers, |
888 | | bool aIgnoreRootScrollFrame, |
889 | | bool* aPreventDefault) |
890 | 0 | { |
891 | 0 | return SendTouchEventCommon(aType, aIdentifiers, aXs, aYs, aRxs, aRys, |
892 | 0 | aRotationAngles, aForces, aCount, aModifiers, |
893 | 0 | aIgnoreRootScrollFrame, true, aPreventDefault); |
894 | 0 | } |
895 | | |
896 | | NS_IMETHODIMP |
897 | | nsDOMWindowUtils::SendTouchEventCommon(const nsAString& aType, |
898 | | uint32_t* aIdentifiers, |
899 | | int32_t* aXs, |
900 | | int32_t* aYs, |
901 | | uint32_t* aRxs, |
902 | | uint32_t* aRys, |
903 | | float* aRotationAngles, |
904 | | float* aForces, |
905 | | uint32_t aCount, |
906 | | int32_t aModifiers, |
907 | | bool aIgnoreRootScrollFrame, |
908 | | bool aToWindow, |
909 | | bool* aPreventDefault) |
910 | 0 | { |
911 | 0 | // get the widget to send the event to |
912 | 0 | nsPoint offset; |
913 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(&offset); |
914 | 0 | if (!widget) { |
915 | 0 | return NS_ERROR_NULL_POINTER; |
916 | 0 | } |
917 | 0 | EventMessage msg; |
918 | 0 | if (aType.EqualsLiteral("touchstart")) { |
919 | 0 | msg = eTouchStart; |
920 | 0 | } else if (aType.EqualsLiteral("touchmove")) { |
921 | 0 | msg = eTouchMove; |
922 | 0 | } else if (aType.EqualsLiteral("touchend")) { |
923 | 0 | msg = eTouchEnd; |
924 | 0 | } else if (aType.EqualsLiteral("touchcancel")) { |
925 | 0 | msg = eTouchCancel; |
926 | 0 | } else { |
927 | 0 | return NS_ERROR_UNEXPECTED; |
928 | 0 | } |
929 | 0 | WidgetTouchEvent event(true, msg, widget); |
930 | 0 | event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers); |
931 | 0 | event.mTime = PR_Now(); |
932 | 0 |
|
933 | 0 | nsPresContext* presContext = GetPresContext(); |
934 | 0 | if (!presContext) { |
935 | 0 | return NS_ERROR_FAILURE; |
936 | 0 | } |
937 | 0 | event.mTouches.SetCapacity(aCount); |
938 | 0 | for (uint32_t i = 0; i < aCount; ++i) { |
939 | 0 | LayoutDeviceIntPoint pt = |
940 | 0 | nsContentUtils::ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext); |
941 | 0 | LayoutDeviceIntPoint radius = |
942 | 0 | LayoutDeviceIntPoint::FromAppUnitsRounded( |
943 | 0 | CSSPoint::ToAppUnits(CSSPoint(aRxs[i], aRys[i])), |
944 | 0 | presContext->AppUnitsPerDevPixel()); |
945 | 0 |
|
946 | 0 | RefPtr<Touch> t = |
947 | 0 | new Touch(aIdentifiers[i], pt, radius, aRotationAngles[i], aForces[i]); |
948 | 0 |
|
949 | 0 | event.mTouches.AppendElement(t); |
950 | 0 | } |
951 | 0 |
|
952 | 0 | nsEventStatus status; |
953 | 0 | if (aToWindow) { |
954 | 0 | nsCOMPtr<nsIPresShell> presShell; |
955 | 0 | nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell)); |
956 | 0 | if (!presShell || !view) { |
957 | 0 | return NS_ERROR_FAILURE; |
958 | 0 | } |
959 | 0 | status = nsEventStatus_eIgnore; |
960 | 0 | *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); |
961 | 0 | return presShell->HandleEvent(view->GetFrame(), &event, false, &status); |
962 | 0 | } |
963 | 0 | |
964 | 0 | nsresult rv = widget->DispatchEvent(&event, status); |
965 | 0 | *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault); |
966 | 0 | return rv; |
967 | 0 | } |
968 | | |
969 | | NS_IMETHODIMP |
970 | | nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout, |
971 | | int32_t aNativeKeyCode, |
972 | | int32_t aModifiers, |
973 | | const nsAString& aCharacters, |
974 | | const nsAString& aUnmodifiedCharacters, |
975 | | nsIObserver* aObserver) |
976 | 0 | { |
977 | 0 | // get the widget to send the event to |
978 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
979 | 0 | if (!widget) |
980 | 0 | return NS_ERROR_FAILURE; |
981 | 0 | |
982 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
983 | 0 | NewRunnableMethod<int32_t, |
984 | 0 | int32_t, |
985 | 0 | uint32_t, |
986 | 0 | nsString, |
987 | 0 | nsString, |
988 | 0 | nsIObserver*>("nsIWidget::SynthesizeNativeKeyEvent", |
989 | 0 | widget, |
990 | 0 | &nsIWidget::SynthesizeNativeKeyEvent, |
991 | 0 | aNativeKeyboardLayout, |
992 | 0 | aNativeKeyCode, |
993 | 0 | aModifiers, |
994 | 0 | aCharacters, |
995 | 0 | aUnmodifiedCharacters, |
996 | 0 | aObserver))); |
997 | 0 | return NS_OK; |
998 | 0 | } |
999 | | |
1000 | | NS_IMETHODIMP |
1001 | | nsDOMWindowUtils::SendNativeMouseEvent(int32_t aScreenX, |
1002 | | int32_t aScreenY, |
1003 | | int32_t aNativeMessage, |
1004 | | int32_t aModifierFlags, |
1005 | | Element* aElement, |
1006 | | nsIObserver* aObserver) |
1007 | 0 | { |
1008 | 0 | // get the widget to send the event to |
1009 | 0 | nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement); |
1010 | 0 | if (!widget) |
1011 | 0 | return NS_ERROR_FAILURE; |
1012 | 0 | |
1013 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
1014 | 0 | NewRunnableMethod<LayoutDeviceIntPoint, int32_t, int32_t, nsIObserver*>( |
1015 | 0 | "nsIWidget::SynthesizeNativeMouseEvent", |
1016 | 0 | widget, |
1017 | 0 | &nsIWidget::SynthesizeNativeMouseEvent, |
1018 | 0 | LayoutDeviceIntPoint(aScreenX, aScreenY), |
1019 | 0 | aNativeMessage, |
1020 | 0 | aModifierFlags, |
1021 | 0 | aObserver))); |
1022 | 0 | return NS_OK; |
1023 | 0 | } |
1024 | | |
1025 | | NS_IMETHODIMP |
1026 | | nsDOMWindowUtils::SendNativeMouseMove(int32_t aScreenX, |
1027 | | int32_t aScreenY, |
1028 | | Element* aElement, |
1029 | | nsIObserver* aObserver) |
1030 | 0 | { |
1031 | 0 | // get the widget to send the event to |
1032 | 0 | nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement); |
1033 | 0 | if (!widget) |
1034 | 0 | return NS_ERROR_FAILURE; |
1035 | 0 | |
1036 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
1037 | 0 | NewRunnableMethod<LayoutDeviceIntPoint, nsIObserver*>( |
1038 | 0 | "nsIWidget::SynthesizeNativeMouseMove", |
1039 | 0 | widget, |
1040 | 0 | &nsIWidget::SynthesizeNativeMouseMove, |
1041 | 0 | LayoutDeviceIntPoint(aScreenX, aScreenY), |
1042 | 0 | aObserver))); |
1043 | 0 | return NS_OK; |
1044 | 0 | } |
1045 | | |
1046 | | NS_IMETHODIMP |
1047 | | nsDOMWindowUtils::SendNativeMouseScrollEvent(int32_t aScreenX, |
1048 | | int32_t aScreenY, |
1049 | | uint32_t aNativeMessage, |
1050 | | double aDeltaX, |
1051 | | double aDeltaY, |
1052 | | double aDeltaZ, |
1053 | | uint32_t aModifierFlags, |
1054 | | uint32_t aAdditionalFlags, |
1055 | | Element* aElement, |
1056 | | nsIObserver* aObserver) |
1057 | 0 | { |
1058 | 0 | // get the widget to send the event to |
1059 | 0 | nsCOMPtr<nsIWidget> widget = GetWidgetForElement(aElement); |
1060 | 0 | if (!widget) { |
1061 | 0 | return NS_ERROR_FAILURE; |
1062 | 0 | } |
1063 | 0 | |
1064 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
1065 | 0 | NewRunnableMethod<mozilla::LayoutDeviceIntPoint, |
1066 | 0 | uint32_t, |
1067 | 0 | double, |
1068 | 0 | double, |
1069 | 0 | double, |
1070 | 0 | uint32_t, |
1071 | 0 | uint32_t, |
1072 | 0 | nsIObserver*>( |
1073 | 0 | "nsIWidget::SynthesizeNativeMouseScrollEvent", |
1074 | 0 | widget, |
1075 | 0 | &nsIWidget::SynthesizeNativeMouseScrollEvent, |
1076 | 0 | LayoutDeviceIntPoint(aScreenX, aScreenY), |
1077 | 0 | aNativeMessage, |
1078 | 0 | aDeltaX, |
1079 | 0 | aDeltaY, |
1080 | 0 | aDeltaZ, |
1081 | 0 | aModifierFlags, |
1082 | 0 | aAdditionalFlags, |
1083 | 0 | aObserver))); |
1084 | 0 | return NS_OK; |
1085 | 0 | } |
1086 | | |
1087 | | NS_IMETHODIMP |
1088 | | nsDOMWindowUtils::SendNativeTouchPoint(uint32_t aPointerId, |
1089 | | uint32_t aTouchState, |
1090 | | int32_t aScreenX, |
1091 | | int32_t aScreenY, |
1092 | | double aPressure, |
1093 | | uint32_t aOrientation, |
1094 | | nsIObserver* aObserver) |
1095 | 0 | { |
1096 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1097 | 0 | if (!widget) { |
1098 | 0 | return NS_ERROR_FAILURE; |
1099 | 0 | } |
1100 | 0 | |
1101 | 0 | if (aPressure < 0 || aPressure > 1 || aOrientation > 359) { |
1102 | 0 | return NS_ERROR_INVALID_ARG; |
1103 | 0 | } |
1104 | 0 | |
1105 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
1106 | 0 | NewRunnableMethod<uint32_t, |
1107 | 0 | nsIWidget::TouchPointerState, |
1108 | 0 | LayoutDeviceIntPoint, |
1109 | 0 | double, |
1110 | 0 | uint32_t, |
1111 | 0 | nsIObserver*>("nsIWidget::SynthesizeNativeTouchPoint", |
1112 | 0 | widget, |
1113 | 0 | &nsIWidget::SynthesizeNativeTouchPoint, |
1114 | 0 | aPointerId, |
1115 | 0 | (nsIWidget::TouchPointerState)aTouchState, |
1116 | 0 | LayoutDeviceIntPoint(aScreenX, aScreenY), |
1117 | 0 | aPressure, |
1118 | 0 | aOrientation, |
1119 | 0 | aObserver))); |
1120 | 0 | return NS_OK; |
1121 | 0 | } |
1122 | | |
1123 | | NS_IMETHODIMP |
1124 | | nsDOMWindowUtils::SendNativeTouchTap(int32_t aScreenX, |
1125 | | int32_t aScreenY, |
1126 | | bool aLongTap, |
1127 | | nsIObserver* aObserver) |
1128 | 0 | { |
1129 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1130 | 0 | if (!widget) { |
1131 | 0 | return NS_ERROR_FAILURE; |
1132 | 0 | } |
1133 | 0 | |
1134 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
1135 | 0 | NewRunnableMethod<LayoutDeviceIntPoint, bool, nsIObserver*>( |
1136 | 0 | "nsIWidget::SynthesizeNativeTouchTap", |
1137 | 0 | widget, |
1138 | 0 | &nsIWidget::SynthesizeNativeTouchTap, |
1139 | 0 | LayoutDeviceIntPoint(aScreenX, aScreenY), |
1140 | 0 | aLongTap, |
1141 | 0 | aObserver))); |
1142 | 0 | return NS_OK; |
1143 | 0 | } |
1144 | | |
1145 | | NS_IMETHODIMP |
1146 | | nsDOMWindowUtils::SuppressAnimation(bool aSuppress) |
1147 | 0 | { |
1148 | 0 | nsIWidget* widget = GetWidget(); |
1149 | 0 | if (widget) { |
1150 | 0 | widget->SuppressAnimation(aSuppress); |
1151 | 0 | } |
1152 | 0 | return NS_OK; |
1153 | 0 | } |
1154 | | |
1155 | | NS_IMETHODIMP |
1156 | | nsDOMWindowUtils::ClearNativeTouchSequence(nsIObserver* aObserver) |
1157 | 0 | { |
1158 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1159 | 0 | if (!widget) { |
1160 | 0 | return NS_ERROR_FAILURE; |
1161 | 0 | } |
1162 | 0 | |
1163 | 0 | NS_DispatchToMainThread(NativeInputRunnable::Create( |
1164 | 0 | NewRunnableMethod<nsIObserver*>("nsIWidget::ClearNativeTouchSequence", |
1165 | 0 | widget, |
1166 | 0 | &nsIWidget::ClearNativeTouchSequence, |
1167 | 0 | aObserver))); |
1168 | 0 | return NS_OK; |
1169 | 0 | } |
1170 | | |
1171 | | NS_IMETHODIMP |
1172 | | nsDOMWindowUtils::ActivateNativeMenuItemAt(const nsAString& indexString) |
1173 | 0 | { |
1174 | 0 | // get the widget to send the event to |
1175 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1176 | 0 | if (!widget) |
1177 | 0 | return NS_ERROR_FAILURE; |
1178 | 0 | |
1179 | 0 | return widget->ActivateNativeMenuItemAt(indexString); |
1180 | 0 | } |
1181 | | |
1182 | | NS_IMETHODIMP |
1183 | | nsDOMWindowUtils::ForceUpdateNativeMenuAt(const nsAString& indexString) |
1184 | 0 | { |
1185 | 0 | // get the widget to send the event to |
1186 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1187 | 0 | if (!widget) |
1188 | 0 | return NS_ERROR_FAILURE; |
1189 | 0 | |
1190 | 0 | return widget->ForceUpdateNativeMenuAt(indexString); |
1191 | 0 | } |
1192 | | |
1193 | | NS_IMETHODIMP |
1194 | | nsDOMWindowUtils::GetSelectionAsPlaintext(nsAString& aResult) |
1195 | 0 | { |
1196 | 0 | // Get the widget to send the event to. |
1197 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1198 | 0 | if (!widget) { |
1199 | 0 | return NS_ERROR_FAILURE; |
1200 | 0 | } |
1201 | 0 | |
1202 | 0 | return widget->GetSelectionAsPlaintext(aResult); |
1203 | 0 | } |
1204 | | |
1205 | | nsIWidget* |
1206 | | nsDOMWindowUtils::GetWidget(nsPoint* aOffset) |
1207 | 0 | { |
1208 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1209 | 0 | if (window) { |
1210 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
1211 | 0 | if (docShell) { |
1212 | 0 | nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell(); |
1213 | 0 | return nsContentUtils::GetWidget(presShell, aOffset); |
1214 | 0 | } |
1215 | 0 | } |
1216 | 0 | |
1217 | 0 | return nullptr; |
1218 | 0 | } |
1219 | | |
1220 | | nsIWidget* |
1221 | | nsDOMWindowUtils::GetWidgetForElement(Element* aElement) |
1222 | 0 | { |
1223 | 0 | if (!aElement) |
1224 | 0 | return GetWidget(); |
1225 | 0 | |
1226 | 0 | nsIDocument* doc = aElement->GetUncomposedDoc(); |
1227 | 0 | nsIPresShell* presShell = doc ? doc->GetShell() : nullptr; |
1228 | 0 |
|
1229 | 0 | if (presShell) { |
1230 | 0 | nsIFrame* frame = aElement->GetPrimaryFrame(); |
1231 | 0 | if (!frame) { |
1232 | 0 | frame = presShell->GetRootFrame(); |
1233 | 0 | } |
1234 | 0 | if (frame) |
1235 | 0 | return frame->GetNearestWidget(); |
1236 | 0 | } |
1237 | 0 | |
1238 | 0 | return nullptr; |
1239 | 0 | } |
1240 | | |
1241 | | NS_IMETHODIMP |
1242 | | nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener) |
1243 | 0 | { |
1244 | 0 | AUTO_PROFILER_LABEL("nsDOMWindowUtils::GarbageCollect", GCCC); |
1245 | 0 |
|
1246 | 0 | nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS); |
1247 | 0 | nsJSContext::CycleCollectNow(aListener); |
1248 | 0 |
|
1249 | 0 | return NS_OK; |
1250 | 0 | } |
1251 | | |
1252 | | NS_IMETHODIMP |
1253 | | nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener *aListener) |
1254 | 0 | { |
1255 | 0 | nsJSContext::CycleCollectNow(aListener); |
1256 | 0 | return NS_OK; |
1257 | 0 | } |
1258 | | |
1259 | | NS_IMETHODIMP |
1260 | | nsDOMWindowUtils::RunNextCollectorTimer() |
1261 | 0 | { |
1262 | 0 | nsJSContext::RunNextCollectorTimer(JS::gcreason::DOM_WINDOW_UTILS); |
1263 | 0 |
|
1264 | 0 | return NS_OK; |
1265 | 0 | } |
1266 | | |
1267 | | NS_IMETHODIMP |
1268 | | nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType, |
1269 | | float aX, |
1270 | | float aY, |
1271 | | uint32_t aDirection, |
1272 | | double aDelta, |
1273 | | int32_t aModifiers, |
1274 | | uint32_t aClickCount) |
1275 | 0 | { |
1276 | 0 | // get the widget to send the event to |
1277 | 0 | nsPoint offset; |
1278 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(&offset); |
1279 | 0 | if (!widget) |
1280 | 0 | return NS_ERROR_FAILURE; |
1281 | 0 | |
1282 | 0 | EventMessage msg; |
1283 | 0 | if (aType.EqualsLiteral("MozSwipeGestureMayStart")) { |
1284 | 0 | msg = eSwipeGestureMayStart; |
1285 | 0 | } else if (aType.EqualsLiteral("MozSwipeGestureStart")) { |
1286 | 0 | msg = eSwipeGestureStart; |
1287 | 0 | } else if (aType.EqualsLiteral("MozSwipeGestureUpdate")) { |
1288 | 0 | msg = eSwipeGestureUpdate; |
1289 | 0 | } else if (aType.EqualsLiteral("MozSwipeGestureEnd")) { |
1290 | 0 | msg = eSwipeGestureEnd; |
1291 | 0 | } else if (aType.EqualsLiteral("MozSwipeGesture")) { |
1292 | 0 | msg = eSwipeGesture; |
1293 | 0 | } else if (aType.EqualsLiteral("MozMagnifyGestureStart")) { |
1294 | 0 | msg = eMagnifyGestureStart; |
1295 | 0 | } else if (aType.EqualsLiteral("MozMagnifyGestureUpdate")) { |
1296 | 0 | msg = eMagnifyGestureUpdate; |
1297 | 0 | } else if (aType.EqualsLiteral("MozMagnifyGesture")) { |
1298 | 0 | msg = eMagnifyGesture; |
1299 | 0 | } else if (aType.EqualsLiteral("MozRotateGestureStart")) { |
1300 | 0 | msg = eRotateGestureStart; |
1301 | 0 | } else if (aType.EqualsLiteral("MozRotateGestureUpdate")) { |
1302 | 0 | msg = eRotateGestureUpdate; |
1303 | 0 | } else if (aType.EqualsLiteral("MozRotateGesture")) { |
1304 | 0 | msg = eRotateGesture; |
1305 | 0 | } else if (aType.EqualsLiteral("MozTapGesture")) { |
1306 | 0 | msg = eTapGesture; |
1307 | 0 | } else if (aType.EqualsLiteral("MozPressTapGesture")) { |
1308 | 0 | msg = ePressTapGesture; |
1309 | 0 | } else if (aType.EqualsLiteral("MozEdgeUIStarted")) { |
1310 | 0 | msg = eEdgeUIStarted; |
1311 | 0 | } else if (aType.EqualsLiteral("MozEdgeUICanceled")) { |
1312 | 0 | msg = eEdgeUICanceled; |
1313 | 0 | } else if (aType.EqualsLiteral("MozEdgeUICompleted")) { |
1314 | 0 | msg = eEdgeUICompleted; |
1315 | 0 | } else { |
1316 | 0 | return NS_ERROR_FAILURE; |
1317 | 0 | } |
1318 | 0 | |
1319 | 0 | WidgetSimpleGestureEvent event(true, msg, widget); |
1320 | 0 | event.mModifiers = nsContentUtils::GetWidgetModifiers(aModifiers); |
1321 | 0 | event.mDirection = aDirection; |
1322 | 0 | event.mDelta = aDelta; |
1323 | 0 | event.mClickCount = aClickCount; |
1324 | 0 | event.mTime = PR_IntervalNow(); |
1325 | 0 |
|
1326 | 0 | nsPresContext* presContext = GetPresContext(); |
1327 | 0 | if (!presContext) |
1328 | 0 | return NS_ERROR_FAILURE; |
1329 | 0 | |
1330 | 0 | event.mRefPoint = |
1331 | 0 | nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext); |
1332 | 0 |
|
1333 | 0 | nsEventStatus status; |
1334 | 0 | return widget->DispatchEvent(&event, status); |
1335 | 0 | } |
1336 | | |
1337 | | NS_IMETHODIMP |
1338 | | nsDOMWindowUtils::ElementFromPoint(float aX, float aY, |
1339 | | bool aIgnoreRootScrollFrame, |
1340 | | bool aFlushLayout, |
1341 | | Element** aReturn) |
1342 | 0 | { |
1343 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1344 | 0 | NS_ENSURE_STATE(doc); |
1345 | 0 |
|
1346 | 0 | RefPtr<Element> el = |
1347 | 0 | doc->ElementFromPointHelper(aX, aY, aIgnoreRootScrollFrame, aFlushLayout); |
1348 | 0 | el.forget(aReturn); |
1349 | 0 | return NS_OK; |
1350 | 0 | } |
1351 | | |
1352 | | NS_IMETHODIMP |
1353 | | nsDOMWindowUtils::NodesFromRect(float aX, float aY, |
1354 | | float aTopSize, float aRightSize, |
1355 | | float aBottomSize, float aLeftSize, |
1356 | | bool aIgnoreRootScrollFrame, |
1357 | | bool aFlushLayout, |
1358 | | nsINodeList** aReturn) |
1359 | 0 | { |
1360 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1361 | 0 | NS_ENSURE_STATE(doc); |
1362 | 0 |
|
1363 | 0 | return doc->NodesFromRectHelper(aX, aY, aTopSize, aRightSize, aBottomSize, aLeftSize, |
1364 | 0 | aIgnoreRootScrollFrame, aFlushLayout, aReturn); |
1365 | 0 | } |
1366 | | |
1367 | | NS_IMETHODIMP |
1368 | | nsDOMWindowUtils::GetTranslationNodes(nsINode* aRoot, |
1369 | | nsITranslationNodeList** aRetVal) |
1370 | 0 | { |
1371 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
1372 | 0 | nsCOMPtr<nsIContent> root = do_QueryInterface(aRoot); |
1373 | 0 | NS_ENSURE_STATE(root); |
1374 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1375 | 0 | NS_ENSURE_STATE(doc); |
1376 | 0 |
|
1377 | 0 | if (root->OwnerDoc() != doc) { |
1378 | 0 | return NS_ERROR_DOM_WRONG_DOCUMENT_ERR; |
1379 | 0 | } |
1380 | 0 | |
1381 | 0 | nsTHashtable<nsPtrHashKey<nsIContent>> translationNodesHash(500); |
1382 | 0 | RefPtr<nsTranslationNodeList> list = new nsTranslationNodeList; |
1383 | 0 |
|
1384 | 0 | uint32_t limit = 15000; |
1385 | 0 |
|
1386 | 0 | // We begin iteration with content->GetNextNode because we want to explictly |
1387 | 0 | // skip the root tag from being a translation node. |
1388 | 0 | nsIContent* content = root; |
1389 | 0 | while ((limit > 0) && (content = content->GetNextNode(root))) { |
1390 | 0 | if (!content->IsHTMLElement()) { |
1391 | 0 | continue; |
1392 | 0 | } |
1393 | 0 | |
1394 | 0 | // Skip elements that usually contain non-translatable text content. |
1395 | 0 | if (content->IsAnyOfHTMLElements(nsGkAtoms::script, |
1396 | 0 | nsGkAtoms::iframe, |
1397 | 0 | nsGkAtoms::frameset, |
1398 | 0 | nsGkAtoms::frame, |
1399 | 0 | nsGkAtoms::code, |
1400 | 0 | nsGkAtoms::noscript, |
1401 | 0 | nsGkAtoms::style)) { |
1402 | 0 | continue; |
1403 | 0 | } |
1404 | 0 | |
1405 | 0 | // An element is a translation node if it contains |
1406 | 0 | // at least one text node that has meaningful data |
1407 | 0 | // for translation |
1408 | 0 | for (nsIContent* child = content->GetFirstChild(); |
1409 | 0 | child; |
1410 | 0 | child = child->GetNextSibling()) { |
1411 | 0 |
|
1412 | 0 | if (child->IsText() && child->GetAsText()->HasTextForTranslation()) { |
1413 | 0 | translationNodesHash.PutEntry(content); |
1414 | 0 |
|
1415 | 0 | bool isBlockFrame = false; |
1416 | 0 | nsIFrame* frame = content->GetPrimaryFrame(); |
1417 | 0 | if (frame) { |
1418 | 0 | isBlockFrame = frame->IsFrameOfType(nsIFrame::eBlockFrame); |
1419 | 0 | } |
1420 | 0 |
|
1421 | 0 | bool isTranslationRoot = isBlockFrame; |
1422 | 0 | if (!isBlockFrame) { |
1423 | 0 | // If an element is not a block element, it still |
1424 | 0 | // can be considered a translation root if the parent |
1425 | 0 | // of this element didn't make into the list of nodes |
1426 | 0 | // to be translated. |
1427 | 0 | bool parentInList = false; |
1428 | 0 | nsIContent* parent = content->GetParent(); |
1429 | 0 | if (parent) { |
1430 | 0 | parentInList = translationNodesHash.Contains(parent); |
1431 | 0 | } |
1432 | 0 | isTranslationRoot = !parentInList; |
1433 | 0 | } |
1434 | 0 |
|
1435 | 0 | list->AppendElement(content, isTranslationRoot); |
1436 | 0 | --limit; |
1437 | 0 | break; |
1438 | 0 | } |
1439 | 0 | } |
1440 | 0 | } |
1441 | 0 |
|
1442 | 0 | *aRetVal = list.forget().take(); |
1443 | 0 | return NS_OK; |
1444 | 0 | } |
1445 | | |
1446 | | static already_AddRefed<DataSourceSurface> |
1447 | | CanvasToDataSourceSurface(HTMLCanvasElement* aCanvas) |
1448 | 0 | { |
1449 | 0 | MOZ_ASSERT(aCanvas); |
1450 | 0 | nsLayoutUtils::SurfaceFromElementResult result = |
1451 | 0 | nsLayoutUtils::SurfaceFromElement(aCanvas); |
1452 | 0 |
|
1453 | 0 | MOZ_ASSERT(result.GetSourceSurface()); |
1454 | 0 | return result.GetSourceSurface()->GetDataSurface(); |
1455 | 0 | } |
1456 | | |
1457 | | NS_IMETHODIMP |
1458 | | nsDOMWindowUtils::CompareCanvases(nsISupports *aCanvas1, |
1459 | | nsISupports *aCanvas2, |
1460 | | uint32_t* aMaxDifference, |
1461 | | uint32_t* retVal) |
1462 | 0 | { |
1463 | 0 | if (aCanvas1 == nullptr || |
1464 | 0 | aCanvas2 == nullptr || |
1465 | 0 | retVal == nullptr) |
1466 | 0 | return NS_ERROR_FAILURE; |
1467 | 0 | |
1468 | 0 | nsCOMPtr<nsIContent> contentCanvas1 = do_QueryInterface(aCanvas1); |
1469 | 0 | nsCOMPtr<nsIContent> contentCanvas2 = do_QueryInterface(aCanvas2); |
1470 | 0 | auto canvas1 = HTMLCanvasElement::FromNodeOrNull(contentCanvas1); |
1471 | 0 | auto canvas2 = HTMLCanvasElement::FromNodeOrNull(contentCanvas2); |
1472 | 0 |
|
1473 | 0 | if (!canvas1 || !canvas2) { |
1474 | 0 | return NS_ERROR_FAILURE; |
1475 | 0 | } |
1476 | 0 | |
1477 | 0 | RefPtr<DataSourceSurface> img1 = CanvasToDataSourceSurface(canvas1); |
1478 | 0 | RefPtr<DataSourceSurface> img2 = CanvasToDataSourceSurface(canvas2); |
1479 | 0 |
|
1480 | 0 | if (img1->Equals(img2)) { |
1481 | 0 | // They point to the same underlying content. |
1482 | 0 | return NS_OK; |
1483 | 0 | } |
1484 | 0 | |
1485 | 0 | DataSourceSurface::ScopedMap map1(img1, DataSourceSurface::READ); |
1486 | 0 | DataSourceSurface::ScopedMap map2(img2, DataSourceSurface::READ); |
1487 | 0 |
|
1488 | 0 | if (img1 == nullptr || img2 == nullptr || |
1489 | 0 | !map1.IsMapped() || !map2.IsMapped() || |
1490 | 0 | img1->GetSize() != img2->GetSize() || |
1491 | 0 | map1.GetStride() != map2.GetStride()) { |
1492 | 0 | return NS_ERROR_FAILURE; |
1493 | 0 | } |
1494 | 0 | |
1495 | 0 | int v; |
1496 | 0 | IntSize size = img1->GetSize(); |
1497 | 0 | int32_t stride = map1.GetStride(); |
1498 | 0 |
|
1499 | 0 | // we can optimize for the common all-pass case |
1500 | 0 | if (stride == size.width * 4) { |
1501 | 0 | v = memcmp(map1.GetData(), map2.GetData(), size.width * size.height * 4); |
1502 | 0 | if (v == 0) { |
1503 | 0 | if (aMaxDifference) |
1504 | 0 | *aMaxDifference = 0; |
1505 | 0 | *retVal = 0; |
1506 | 0 | return NS_OK; |
1507 | 0 | } |
1508 | 0 | } |
1509 | 0 |
|
1510 | 0 | uint32_t dc = 0; |
1511 | 0 | uint32_t different = 0; |
1512 | 0 |
|
1513 | 0 | for (int j = 0; j < size.height; j++) { |
1514 | 0 | unsigned char *p1 = map1.GetData() + j*stride; |
1515 | 0 | unsigned char *p2 = map2.GetData() + j*stride; |
1516 | 0 | v = memcmp(p1, p2, stride); |
1517 | 0 |
|
1518 | 0 | if (v) { |
1519 | 0 | for (int i = 0; i < size.width; i++) { |
1520 | 0 | if (*(uint32_t*) p1 != *(uint32_t*) p2) { |
1521 | 0 |
|
1522 | 0 | different++; |
1523 | 0 |
|
1524 | 0 | dc = std::max((uint32_t)abs(p1[0] - p2[0]), dc); |
1525 | 0 | dc = std::max((uint32_t)abs(p1[1] - p2[1]), dc); |
1526 | 0 | dc = std::max((uint32_t)abs(p1[2] - p2[2]), dc); |
1527 | 0 | dc = std::max((uint32_t)abs(p1[3] - p2[3]), dc); |
1528 | 0 | } |
1529 | 0 |
|
1530 | 0 | p1 += 4; |
1531 | 0 | p2 += 4; |
1532 | 0 | } |
1533 | 0 | } |
1534 | 0 | } |
1535 | 0 |
|
1536 | 0 | if (aMaxDifference) |
1537 | 0 | *aMaxDifference = dc; |
1538 | 0 |
|
1539 | 0 | *retVal = different; |
1540 | 0 | return NS_OK; |
1541 | 0 | } |
1542 | | |
1543 | | NS_IMETHODIMP |
1544 | | nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult) |
1545 | 0 | { |
1546 | 0 | NS_ENSURE_ARG_POINTER(aResult); |
1547 | 0 | *aResult = false; |
1548 | 0 | nsPresContext* presContext = GetPresContext(); |
1549 | 0 | if (!presContext) |
1550 | 0 | return NS_OK; |
1551 | 0 | *aResult = presContext->IsDOMPaintEventPending(); |
1552 | 0 | return NS_OK; |
1553 | 0 | } |
1554 | | |
1555 | | NS_IMETHODIMP |
1556 | | nsDOMWindowUtils::DisableNonTestMouseEvents(bool aDisable) |
1557 | 0 | { |
1558 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1559 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
1560 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
1561 | 0 | NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); |
1562 | 0 | nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell(); |
1563 | 0 | NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); |
1564 | 0 | presShell->DisableNonTestMouseEvents(aDisable); |
1565 | 0 | return NS_OK; |
1566 | 0 | } |
1567 | | |
1568 | | NS_IMETHODIMP |
1569 | | nsDOMWindowUtils::SuppressEventHandling(bool aSuppress) |
1570 | 0 | { |
1571 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1572 | 0 | NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); |
1573 | 0 |
|
1574 | 0 | if (aSuppress) { |
1575 | 0 | doc->SuppressEventHandling(); |
1576 | 0 | } else { |
1577 | 0 | doc->UnsuppressEventHandlingAndFireEvents(true); |
1578 | 0 | } |
1579 | 0 |
|
1580 | 0 | return NS_OK; |
1581 | 0 | } |
1582 | | |
1583 | | static nsresult |
1584 | 0 | getScrollXYAppUnits(const nsWeakPtr& aWindow, bool aFlushLayout, nsPoint& aScrollPos) { |
1585 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(aWindow); |
1586 | 0 | nsCOMPtr<nsIDocument> doc = window ? window->GetExtantDoc() : nullptr; |
1587 | 0 | NS_ENSURE_STATE(doc); |
1588 | 0 |
|
1589 | 0 | if (aFlushLayout) { |
1590 | 0 | doc->FlushPendingNotifications(FlushType::Layout); |
1591 | 0 | } |
1592 | 0 |
|
1593 | 0 | nsIPresShell *presShell = doc->GetShell(); |
1594 | 0 | if (presShell) { |
1595 | 0 | nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); |
1596 | 0 | if (sf) { |
1597 | 0 | aScrollPos = sf->GetScrollPosition(); |
1598 | 0 | } |
1599 | 0 | } |
1600 | 0 | return NS_OK; |
1601 | 0 | } |
1602 | | |
1603 | | NS_IMETHODIMP |
1604 | | nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY) |
1605 | 0 | { |
1606 | 0 | nsPoint scrollPos(0,0); |
1607 | 0 | nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos); |
1608 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1609 | 0 | *aScrollX = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.x); |
1610 | 0 | *aScrollY = nsPresContext::AppUnitsToIntCSSPixels(scrollPos.y); |
1611 | 0 |
|
1612 | 0 | return NS_OK; |
1613 | 0 | } |
1614 | | |
1615 | | NS_IMETHODIMP |
1616 | | nsDOMWindowUtils::GetScrollXYFloat(bool aFlushLayout, float* aScrollX, float* aScrollY) |
1617 | 0 | { |
1618 | 0 | nsPoint scrollPos(0,0); |
1619 | 0 | nsresult rv = getScrollXYAppUnits(mWindow, aFlushLayout, scrollPos); |
1620 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
1621 | 0 | *aScrollX = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.x); |
1622 | 0 | *aScrollY = nsPresContext::AppUnitsToFloatCSSPixels(scrollPos.y); |
1623 | 0 |
|
1624 | 0 | return NS_OK; |
1625 | 0 | } |
1626 | | |
1627 | | NS_IMETHODIMP |
1628 | | nsDOMWindowUtils::GetScrollbarSize(bool aFlushLayout, int32_t* aWidth, |
1629 | | int32_t* aHeight) |
1630 | 0 | { |
1631 | 0 | *aWidth = 0; |
1632 | 0 | *aHeight = 0; |
1633 | 0 |
|
1634 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1635 | 0 | NS_ENSURE_STATE(doc); |
1636 | 0 |
|
1637 | 0 | if (aFlushLayout) { |
1638 | 0 | doc->FlushPendingNotifications(FlushType::Layout); |
1639 | 0 | } |
1640 | 0 |
|
1641 | 0 | nsIPresShell* presShell = doc->GetShell(); |
1642 | 0 | NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE); |
1643 | 0 |
|
1644 | 0 | nsIScrollableFrame* scrollFrame = presShell->GetRootScrollFrameAsScrollable(); |
1645 | 0 | NS_ENSURE_TRUE(scrollFrame, NS_OK); |
1646 | 0 |
|
1647 | 0 | nsMargin sizes = scrollFrame->GetActualScrollbarSizes(); |
1648 | 0 | *aWidth = nsPresContext::AppUnitsToIntCSSPixels(sizes.LeftRight()); |
1649 | 0 | *aHeight = nsPresContext::AppUnitsToIntCSSPixels(sizes.TopBottom()); |
1650 | 0 |
|
1651 | 0 | return NS_OK; |
1652 | 0 | } |
1653 | | |
1654 | | NS_IMETHODIMP |
1655 | | nsDOMWindowUtils::GetBoundsWithoutFlushing(Element *aElement, |
1656 | | DOMRect** aResult) |
1657 | 0 | { |
1658 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1659 | 0 | NS_ENSURE_STATE(window); |
1660 | 0 |
|
1661 | 0 | NS_ENSURE_ARG_POINTER(aElement); |
1662 | 0 |
|
1663 | 0 | RefPtr<DOMRect> rect = new DOMRect(window); |
1664 | 0 | nsIFrame* frame = aElement->GetPrimaryFrame(); |
1665 | 0 |
|
1666 | 0 | if (frame) { |
1667 | 0 | nsRect r = nsLayoutUtils::GetAllInFlowRectsUnion(frame, |
1668 | 0 | nsLayoutUtils::GetContainingBlockForClientRect(frame), |
1669 | 0 | nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS); |
1670 | 0 | rect->SetLayoutRect(r); |
1671 | 0 | } |
1672 | 0 |
|
1673 | 0 | rect.forget(aResult); |
1674 | 0 | return NS_OK; |
1675 | 0 | } |
1676 | | |
1677 | | NS_IMETHODIMP |
1678 | | nsDOMWindowUtils::NeedsFlush(int32_t aFlushType, bool* aResult) |
1679 | 0 | { |
1680 | 0 | MOZ_ASSERT(aResult); |
1681 | 0 |
|
1682 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1683 | 0 | NS_ENSURE_STATE(doc); |
1684 | 0 |
|
1685 | 0 | nsIPresShell* presShell = doc->GetShell(); |
1686 | 0 | NS_ENSURE_STATE(presShell); |
1687 | 0 |
|
1688 | 0 | FlushType flushType; |
1689 | 0 | switch (aFlushType) { |
1690 | 0 | case FLUSH_STYLE: |
1691 | 0 | flushType = FlushType::Style; |
1692 | 0 | break; |
1693 | 0 |
|
1694 | 0 | case FLUSH_LAYOUT: |
1695 | 0 | flushType = FlushType::Layout; |
1696 | 0 | break; |
1697 | 0 |
|
1698 | 0 | case FLUSH_DISPLAY: |
1699 | 0 | flushType = FlushType::Display; |
1700 | 0 | break; |
1701 | 0 |
|
1702 | 0 | default: |
1703 | 0 | return NS_ERROR_INVALID_ARG; |
1704 | 0 | } |
1705 | 0 | |
1706 | 0 | *aResult = presShell->NeedFlush(flushType); |
1707 | 0 | return NS_OK; |
1708 | 0 | } |
1709 | | |
1710 | | NS_IMETHODIMP |
1711 | | nsDOMWindowUtils::FlushLayoutWithoutThrottledAnimations() |
1712 | 0 | { |
1713 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
1714 | 0 | if (doc) { |
1715 | 0 | doc->FlushPendingNotifications( |
1716 | 0 | ChangesToFlush(FlushType::Layout, false /* flush animations */)); |
1717 | 0 | } |
1718 | 0 |
|
1719 | 0 | return NS_OK; |
1720 | 0 | } |
1721 | | |
1722 | | NS_IMETHODIMP |
1723 | | nsDOMWindowUtils::GetRootBounds(DOMRect** aResult) |
1724 | 0 | { |
1725 | 0 | nsIDocument* doc = GetDocument(); |
1726 | 0 | NS_ENSURE_STATE(doc); |
1727 | 0 |
|
1728 | 0 | nsRect bounds(0, 0, 0, 0); |
1729 | 0 | nsIPresShell* presShell = doc->GetShell(); |
1730 | 0 | if (presShell) { |
1731 | 0 | nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable(); |
1732 | 0 | if (sf) { |
1733 | 0 | bounds = sf->GetScrollRange(); |
1734 | 0 | bounds.SetWidth(bounds.Width() + sf->GetScrollPortRect().Width()); |
1735 | 0 | bounds.SetHeight(bounds.Height() + sf->GetScrollPortRect().Height()); |
1736 | 0 | } else if (presShell->GetRootFrame()) { |
1737 | 0 | bounds = presShell->GetRootFrame()->GetRect(); |
1738 | 0 | } |
1739 | 0 | } |
1740 | 0 |
|
1741 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1742 | 0 | RefPtr<DOMRect> rect = new DOMRect(window); |
1743 | 0 | rect->SetRect(nsPresContext::AppUnitsToFloatCSSPixels(bounds.x), |
1744 | 0 | nsPresContext::AppUnitsToFloatCSSPixels(bounds.y), |
1745 | 0 | nsPresContext::AppUnitsToFloatCSSPixels(bounds.Width()), |
1746 | 0 | nsPresContext::AppUnitsToFloatCSSPixels(bounds.Height())); |
1747 | 0 | rect.forget(aResult); |
1748 | 0 | return NS_OK; |
1749 | 0 | } |
1750 | | |
1751 | | NS_IMETHODIMP |
1752 | | nsDOMWindowUtils::GetIMEIsOpen(bool *aState) |
1753 | 0 | { |
1754 | 0 | NS_ENSURE_ARG_POINTER(aState); |
1755 | 0 |
|
1756 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1757 | 0 | if (!widget) |
1758 | 0 | return NS_ERROR_FAILURE; |
1759 | 0 | |
1760 | 0 | // Open state should not be available when IME is not enabled. |
1761 | 0 | InputContext context = widget->GetInputContext(); |
1762 | 0 | if (context.mIMEState.mEnabled != IMEState::ENABLED) { |
1763 | 0 | return NS_ERROR_NOT_AVAILABLE; |
1764 | 0 | } |
1765 | 0 | |
1766 | 0 | if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) { |
1767 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
1768 | 0 | } |
1769 | 0 | *aState = (context.mIMEState.mOpen == IMEState::OPEN); |
1770 | 0 | return NS_OK; |
1771 | 0 | } |
1772 | | |
1773 | | NS_IMETHODIMP |
1774 | | nsDOMWindowUtils::GetIMEStatus(uint32_t *aState) |
1775 | 0 | { |
1776 | 0 | NS_ENSURE_ARG_POINTER(aState); |
1777 | 0 |
|
1778 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1779 | 0 | if (!widget) |
1780 | 0 | return NS_ERROR_FAILURE; |
1781 | 0 | |
1782 | 0 | InputContext context = widget->GetInputContext(); |
1783 | 0 | *aState = static_cast<uint32_t>(context.mIMEState.mEnabled); |
1784 | 0 | return NS_OK; |
1785 | 0 | } |
1786 | | |
1787 | | NS_IMETHODIMP |
1788 | | nsDOMWindowUtils::GetFocusedInputType(nsAString& aType) |
1789 | 0 | { |
1790 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1791 | 0 | if (!widget) { |
1792 | 0 | return NS_ERROR_FAILURE; |
1793 | 0 | } |
1794 | 0 | |
1795 | 0 | aType = widget->GetInputContext().mHTMLInputType; |
1796 | 0 | return NS_OK; |
1797 | 0 | } |
1798 | | |
1799 | | NS_IMETHODIMP |
1800 | | nsDOMWindowUtils::GetViewId(Element* aElement, nsViewID* aResult) |
1801 | 0 | { |
1802 | 0 | if (aElement && nsLayoutUtils::FindIDFor(aElement, aResult)) { |
1803 | 0 | return NS_OK; |
1804 | 0 | } |
1805 | 0 | return NS_ERROR_NOT_AVAILABLE; |
1806 | 0 | } |
1807 | | |
1808 | | NS_IMETHODIMP |
1809 | | nsDOMWindowUtils::GetScreenPixelsPerCSSPixel(float* aScreenPixels) |
1810 | 0 | { |
1811 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1812 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
1813 | 0 | *aScreenPixels = window->GetDevicePixelRatio(CallerType::System); |
1814 | 0 | return NS_OK; |
1815 | 0 | } |
1816 | | |
1817 | | NS_IMETHODIMP |
1818 | | nsDOMWindowUtils::GetFullZoom(float* aFullZoom) |
1819 | 0 | { |
1820 | 0 | *aFullZoom = 1.0f; |
1821 | 0 |
|
1822 | 0 | nsPresContext* presContext = GetPresContext(); |
1823 | 0 | if (!presContext) { |
1824 | 0 | return NS_OK; |
1825 | 0 | } |
1826 | 0 | |
1827 | 0 | *aFullZoom = presContext->DeviceContext()->GetFullZoom(); |
1828 | 0 |
|
1829 | 0 | return NS_OK; |
1830 | 0 | } |
1831 | | |
1832 | | NS_IMETHODIMP |
1833 | | nsDOMWindowUtils::DispatchDOMEventViaPresShell(nsINode* aTarget, |
1834 | | Event* aEvent, |
1835 | | bool aTrusted, |
1836 | | bool* aRetVal) |
1837 | 0 | { |
1838 | 0 | NS_ENSURE_STATE(aEvent); |
1839 | 0 | aEvent->SetTrusted(aTrusted); |
1840 | 0 | WidgetEvent* internalEvent = aEvent->WidgetEventPtr(); |
1841 | 0 | NS_ENSURE_STATE(internalEvent); |
1842 | 0 | nsCOMPtr<nsIContent> content = do_QueryInterface(aTarget); |
1843 | 0 | NS_ENSURE_STATE(content); |
1844 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1845 | 0 | if (content->OwnerDoc()->GetWindow() != window) { |
1846 | 0 | return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR; |
1847 | 0 | } |
1848 | 0 | nsCOMPtr<nsIDocument> targetDoc = content->GetUncomposedDoc(); |
1849 | 0 | NS_ENSURE_STATE(targetDoc); |
1850 | 0 | RefPtr<nsIPresShell> targetShell = targetDoc->GetShell(); |
1851 | 0 | NS_ENSURE_STATE(targetShell); |
1852 | 0 |
|
1853 | 0 | targetDoc->FlushPendingNotifications(FlushType::Layout); |
1854 | 0 |
|
1855 | 0 | nsEventStatus status = nsEventStatus_eIgnore; |
1856 | 0 | targetShell->HandleEventWithTarget(internalEvent, nullptr, content, &status); |
1857 | 0 | *aRetVal = (status != nsEventStatus_eConsumeNoDefault); |
1858 | 0 | return NS_OK; |
1859 | 0 | } |
1860 | | |
1861 | | static void |
1862 | | InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr) |
1863 | 0 | { |
1864 | 0 | if (aPt) { |
1865 | 0 | aEvent.mRefPoint = *aPt; |
1866 | 0 | } |
1867 | 0 | aEvent.mTime = PR_IntervalNow(); |
1868 | 0 | } |
1869 | | |
1870 | | NS_IMETHODIMP |
1871 | | nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType, |
1872 | | int64_t aOffset, uint32_t aLength, |
1873 | | int32_t aX, int32_t aY, |
1874 | | uint32_t aAdditionalFlags, |
1875 | | nsIQueryContentEventResult **aResult) |
1876 | 0 | { |
1877 | 0 | *aResult = nullptr; |
1878 | 0 |
|
1879 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
1880 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
1881 | 0 |
|
1882 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
1883 | 0 | NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); |
1884 | 0 |
|
1885 | 0 | nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell(); |
1886 | 0 | NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); |
1887 | 0 |
|
1888 | 0 | nsPresContext* presContext = presShell->GetPresContext(); |
1889 | 0 | NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE); |
1890 | 0 |
|
1891 | 0 | // get the widget to send the event to |
1892 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
1893 | 0 | if (!widget) { |
1894 | 0 | return NS_ERROR_FAILURE; |
1895 | 0 | } |
1896 | 0 | |
1897 | 0 | EventMessage message; |
1898 | 0 | switch (aType) { |
1899 | 0 | case QUERY_SELECTED_TEXT: |
1900 | 0 | message = eQuerySelectedText; |
1901 | 0 | break; |
1902 | 0 | case QUERY_TEXT_CONTENT: |
1903 | 0 | message = eQueryTextContent; |
1904 | 0 | break; |
1905 | 0 | case QUERY_CARET_RECT: |
1906 | 0 | message = eQueryCaretRect; |
1907 | 0 | break; |
1908 | 0 | case QUERY_TEXT_RECT: |
1909 | 0 | message = eQueryTextRect; |
1910 | 0 | break; |
1911 | 0 | case QUERY_EDITOR_RECT: |
1912 | 0 | message = eQueryEditorRect; |
1913 | 0 | break; |
1914 | 0 | case QUERY_CHARACTER_AT_POINT: |
1915 | 0 | message = eQueryCharacterAtPoint; |
1916 | 0 | break; |
1917 | 0 | case QUERY_TEXT_RECT_ARRAY: |
1918 | 0 | message = eQueryTextRectArray; |
1919 | 0 | break; |
1920 | 0 | default: |
1921 | 0 | return NS_ERROR_INVALID_ARG; |
1922 | 0 | } |
1923 | 0 | |
1924 | 0 | SelectionType selectionType = SelectionType::eNormal; |
1925 | 0 | static const uint32_t kSelectionFlags = |
1926 | 0 | QUERY_CONTENT_FLAG_SELECTION_SPELLCHECK | |
1927 | 0 | QUERY_CONTENT_FLAG_SELECTION_IME_RAWINPUT | |
1928 | 0 | QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDRAWTEXT | |
1929 | 0 | QUERY_CONTENT_FLAG_SELECTION_IME_CONVERTEDTEXT | |
1930 | 0 | QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDCONVERTEDTEXT | |
1931 | 0 | QUERY_CONTENT_FLAG_SELECTION_ACCESSIBILITY | |
1932 | 0 | QUERY_CONTENT_FLAG_SELECTION_FIND | |
1933 | 0 | QUERY_CONTENT_FLAG_SELECTION_URLSECONDARY | |
1934 | 0 | QUERY_CONTENT_FLAG_SELECTION_URLSTRIKEOUT; |
1935 | 0 | switch (aAdditionalFlags & kSelectionFlags) { |
1936 | 0 | case QUERY_CONTENT_FLAG_SELECTION_SPELLCHECK: |
1937 | 0 | selectionType = SelectionType::eSpellCheck; |
1938 | 0 | break; |
1939 | 0 | case QUERY_CONTENT_FLAG_SELECTION_IME_RAWINPUT: |
1940 | 0 | selectionType = SelectionType::eIMERawClause; |
1941 | 0 | break; |
1942 | 0 | case QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDRAWTEXT: |
1943 | 0 | selectionType = SelectionType::eIMESelectedRawClause; |
1944 | 0 | break; |
1945 | 0 | case QUERY_CONTENT_FLAG_SELECTION_IME_CONVERTEDTEXT: |
1946 | 0 | selectionType = SelectionType::eIMEConvertedClause; |
1947 | 0 | break; |
1948 | 0 | case QUERY_CONTENT_FLAG_SELECTION_IME_SELECTEDCONVERTEDTEXT: |
1949 | 0 | selectionType = SelectionType::eIMESelectedClause; |
1950 | 0 | break; |
1951 | 0 | case QUERY_CONTENT_FLAG_SELECTION_ACCESSIBILITY: |
1952 | 0 | selectionType = SelectionType::eAccessibility; |
1953 | 0 | break; |
1954 | 0 | case QUERY_CONTENT_FLAG_SELECTION_FIND: |
1955 | 0 | selectionType = SelectionType::eFind; |
1956 | 0 | break; |
1957 | 0 | case QUERY_CONTENT_FLAG_SELECTION_URLSECONDARY: |
1958 | 0 | selectionType = SelectionType::eURLSecondary; |
1959 | 0 | break; |
1960 | 0 | case QUERY_CONTENT_FLAG_SELECTION_URLSTRIKEOUT: |
1961 | 0 | selectionType = SelectionType::eURLStrikeout; |
1962 | 0 | break; |
1963 | 0 | case 0: |
1964 | 0 | break; |
1965 | 0 | default: |
1966 | 0 | return NS_ERROR_INVALID_ARG; |
1967 | 0 | } |
1968 | 0 | |
1969 | 0 | if (selectionType != SelectionType::eNormal && |
1970 | 0 | message != eQuerySelectedText) { |
1971 | 0 | return NS_ERROR_INVALID_ARG; |
1972 | 0 | } |
1973 | 0 | |
1974 | 0 | nsCOMPtr<nsIWidget> targetWidget = widget; |
1975 | 0 | LayoutDeviceIntPoint pt(aX, aY); |
1976 | 0 |
|
1977 | 0 | WidgetQueryContentEvent::Options options; |
1978 | 0 | options.mUseNativeLineBreak = |
1979 | 0 | !(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); |
1980 | 0 | options.mRelativeToInsertionPoint = |
1981 | 0 | (aAdditionalFlags & |
1982 | 0 | QUERY_CONTENT_FLAG_OFFSET_RELATIVE_TO_INSERTION_POINT) != 0; |
1983 | 0 | if (options.mRelativeToInsertionPoint) { |
1984 | 0 | switch (message) { |
1985 | 0 | case eQueryTextContent: |
1986 | 0 | case eQueryCaretRect: |
1987 | 0 | case eQueryTextRect: |
1988 | 0 | break; |
1989 | 0 | default: |
1990 | 0 | return NS_ERROR_INVALID_ARG; |
1991 | 0 | } |
1992 | 0 | } else if (aOffset < 0) { |
1993 | 0 | return NS_ERROR_INVALID_ARG; |
1994 | 0 | } |
1995 | 0 | |
1996 | 0 | if (message == eQueryCharacterAtPoint) { |
1997 | 0 | // Looking for the widget at the point. |
1998 | 0 | WidgetQueryContentEvent dummyEvent(true, eQueryContentState, widget); |
1999 | 0 | dummyEvent.Init(options); |
2000 | 0 | InitEvent(dummyEvent, &pt); |
2001 | 0 | nsIFrame* popupFrame = |
2002 | 0 | nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent); |
2003 | 0 |
|
2004 | 0 | LayoutDeviceIntRect widgetBounds = widget->GetClientBounds(); |
2005 | 0 | widgetBounds.MoveTo(0, 0); |
2006 | 0 |
|
2007 | 0 | // There is no popup frame at the point and the point isn't in our widget, |
2008 | 0 | // we cannot process this request. |
2009 | 0 | NS_ENSURE_TRUE(popupFrame || widgetBounds.Contains(pt), NS_ERROR_FAILURE); |
2010 | 0 |
|
2011 | 0 | // Fire the event on the widget at the point |
2012 | 0 | if (popupFrame) { |
2013 | 0 | targetWidget = popupFrame->GetNearestWidget(); |
2014 | 0 | } |
2015 | 0 | } |
2016 | 0 |
|
2017 | 0 | pt += widget->WidgetToScreenOffset() - targetWidget->WidgetToScreenOffset(); |
2018 | 0 |
|
2019 | 0 | WidgetQueryContentEvent queryEvent(true, message, targetWidget); |
2020 | 0 | InitEvent(queryEvent, &pt); |
2021 | 0 |
|
2022 | 0 | switch (message) { |
2023 | 0 | case eQueryTextContent: |
2024 | 0 | queryEvent.InitForQueryTextContent(aOffset, aLength, options); |
2025 | 0 | break; |
2026 | 0 | case eQueryCaretRect: |
2027 | 0 | queryEvent.InitForQueryCaretRect(aOffset, options); |
2028 | 0 | break; |
2029 | 0 | case eQueryTextRect: |
2030 | 0 | queryEvent.InitForQueryTextRect(aOffset, aLength, options); |
2031 | 0 | break; |
2032 | 0 | case eQuerySelectedText: |
2033 | 0 | queryEvent.InitForQuerySelectedText(selectionType, options); |
2034 | 0 | break; |
2035 | 0 | case eQueryTextRectArray: |
2036 | 0 | queryEvent.InitForQueryTextRectArray(aOffset, aLength, options); |
2037 | 0 | break; |
2038 | 0 | default: |
2039 | 0 | queryEvent.Init(options); |
2040 | 0 | break; |
2041 | 0 | } |
2042 | 0 | |
2043 | 0 | nsEventStatus status; |
2044 | 0 | nsresult rv = targetWidget->DispatchEvent(&queryEvent, status); |
2045 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
2046 | 0 |
|
2047 | 0 | auto* result = new nsQueryContentEventResult(queryEvent); |
2048 | 0 | result->SetEventResult(widget); |
2049 | 0 | NS_ADDREF(*aResult = result); |
2050 | 0 | return NS_OK; |
2051 | 0 | } |
2052 | | |
2053 | | NS_IMETHODIMP |
2054 | | nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset, |
2055 | | uint32_t aLength, |
2056 | | uint32_t aAdditionalFlags, |
2057 | | bool *aResult) |
2058 | 0 | { |
2059 | 0 | *aResult = false; |
2060 | 0 |
|
2061 | 0 | // get the widget to send the event to |
2062 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2063 | 0 | if (!widget) { |
2064 | 0 | return NS_ERROR_FAILURE; |
2065 | 0 | } |
2066 | 0 | |
2067 | 0 | WidgetSelectionEvent selectionEvent(true, eSetSelection, widget); |
2068 | 0 | InitEvent(selectionEvent); |
2069 | 0 |
|
2070 | 0 | selectionEvent.mOffset = aOffset; |
2071 | 0 | selectionEvent.mLength = aLength; |
2072 | 0 | selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE); |
2073 | 0 | selectionEvent.mUseNativeLineBreak = |
2074 | 0 | !(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK); |
2075 | 0 |
|
2076 | 0 | nsEventStatus status; |
2077 | 0 | nsresult rv = widget->DispatchEvent(&selectionEvent, status); |
2078 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
2079 | 0 |
|
2080 | 0 | *aResult = selectionEvent.mSucceeded; |
2081 | 0 | return NS_OK; |
2082 | 0 | } |
2083 | | |
2084 | | NS_IMETHODIMP |
2085 | | nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType, |
2086 | | nsITransferable * aTransferable) |
2087 | 0 | { |
2088 | 0 | // get the widget to send the event to |
2089 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2090 | 0 | if (!widget) |
2091 | 0 | return NS_ERROR_FAILURE; |
2092 | 0 | |
2093 | 0 | EventMessage msg; |
2094 | 0 | if (aType.EqualsLiteral("cut")) { |
2095 | 0 | msg = eContentCommandCut; |
2096 | 0 | } else if (aType.EqualsLiteral("copy")) { |
2097 | 0 | msg = eContentCommandCopy; |
2098 | 0 | } else if (aType.EqualsLiteral("paste")) { |
2099 | 0 | msg = eContentCommandPaste; |
2100 | 0 | } else if (aType.EqualsLiteral("delete")) { |
2101 | 0 | msg = eContentCommandDelete; |
2102 | 0 | } else if (aType.EqualsLiteral("undo")) { |
2103 | 0 | msg = eContentCommandUndo; |
2104 | 0 | } else if (aType.EqualsLiteral("redo")) { |
2105 | 0 | msg = eContentCommandRedo; |
2106 | 0 | } else if (aType.EqualsLiteral("pasteTransferable")) { |
2107 | 0 | msg = eContentCommandPasteTransferable; |
2108 | 0 | } else { |
2109 | 0 | return NS_ERROR_FAILURE; |
2110 | 0 | } |
2111 | 0 | |
2112 | 0 | WidgetContentCommandEvent event(true, msg, widget); |
2113 | 0 | if (msg == eContentCommandPasteTransferable) { |
2114 | 0 | event.mTransferable = aTransferable; |
2115 | 0 | } |
2116 | 0 |
|
2117 | 0 | nsEventStatus status; |
2118 | 0 | return widget->DispatchEvent(&event, status); |
2119 | 0 | } |
2120 | | |
2121 | | NS_IMETHODIMP |
2122 | | nsDOMWindowUtils::GetClassName(JS::Handle<JS::Value> aObject, JSContext* aCx, |
2123 | | char** aName) |
2124 | 0 | { |
2125 | 0 | // Our argument must be a non-null object. |
2126 | 0 | if (aObject.isPrimitive()) { |
2127 | 0 | return NS_ERROR_XPC_BAD_CONVERT_JS; |
2128 | 0 | } |
2129 | 0 | |
2130 | 0 | *aName = NS_xstrdup(JS_GetClass(aObject.toObjectOrNull())->name); |
2131 | 0 | return NS_OK; |
2132 | 0 | } |
2133 | | |
2134 | | NS_IMETHODIMP |
2135 | | nsDOMWindowUtils::GetVisitedDependentComputedStyle( |
2136 | | Element *aElement, const nsAString& aPseudoElement, |
2137 | | const nsAString& aPropertyName, nsAString& aResult) |
2138 | 0 | { |
2139 | 0 | aResult.Truncate(); |
2140 | 0 |
|
2141 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2142 | 0 | NS_ENSURE_STATE(window && aElement); |
2143 | 0 | nsCOMPtr<nsPIDOMWindowInner> innerWindow = window->GetCurrentInnerWindow(); |
2144 | 0 | NS_ENSURE_STATE(window); |
2145 | 0 |
|
2146 | 0 | nsCOMPtr<nsICSSDeclaration> decl; |
2147 | 0 | { |
2148 | 0 | ErrorResult rv; |
2149 | 0 | decl = innerWindow->GetComputedStyle(*aElement, aPseudoElement, rv); |
2150 | 0 | ENSURE_SUCCESS(rv, rv.StealNSResult()); |
2151 | 0 | } |
2152 | 0 |
|
2153 | 0 | static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(true); |
2154 | 0 | nsresult rv = decl->GetPropertyValue(aPropertyName, aResult); |
2155 | 0 | static_cast<nsComputedDOMStyle*>(decl.get())->SetExposeVisitedStyle(false); |
2156 | 0 |
|
2157 | 0 | return rv; |
2158 | 0 | } |
2159 | | |
2160 | | NS_IMETHODIMP |
2161 | | nsDOMWindowUtils::EnterModalState() |
2162 | 0 | { |
2163 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2164 | 0 | NS_ENSURE_STATE(window); |
2165 | 0 |
|
2166 | 0 | window->EnterModalState(); |
2167 | 0 | return NS_OK; |
2168 | 0 | } |
2169 | | |
2170 | | NS_IMETHODIMP |
2171 | | nsDOMWindowUtils::LeaveModalState() |
2172 | 0 | { |
2173 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2174 | 0 | NS_ENSURE_STATE(window); |
2175 | 0 |
|
2176 | 0 | window->LeaveModalState(); |
2177 | 0 | return NS_OK; |
2178 | 0 | } |
2179 | | |
2180 | | NS_IMETHODIMP |
2181 | | nsDOMWindowUtils::IsInModalState(bool *retval) |
2182 | 0 | { |
2183 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2184 | 0 | NS_ENSURE_STATE(window); |
2185 | 0 |
|
2186 | 0 | *retval = nsGlobalWindowOuter::Cast(window)->IsInModalState(); |
2187 | 0 | return NS_OK; |
2188 | 0 | } |
2189 | | |
2190 | | NS_IMETHODIMP |
2191 | | nsDOMWindowUtils::SetDesktopModeViewport(bool aDesktopMode) |
2192 | 0 | { |
2193 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2194 | 0 | NS_ENSURE_STATE(window); |
2195 | 0 |
|
2196 | 0 | window->SetDesktopModeViewport(aDesktopMode); |
2197 | 0 | return NS_OK; |
2198 | 0 | } |
2199 | | |
2200 | | NS_IMETHODIMP |
2201 | | nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID) |
2202 | 0 | { |
2203 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2204 | 0 | NS_ENSURE_STATE(window); |
2205 | 0 |
|
2206 | 0 | *aWindowID = window->WindowID(); |
2207 | 0 | return NS_OK; |
2208 | 0 | } |
2209 | | |
2210 | | NS_IMETHODIMP |
2211 | | nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID) |
2212 | 0 | { |
2213 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2214 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE); |
2215 | 0 |
|
2216 | 0 | nsGlobalWindowInner* inner = |
2217 | 0 | nsGlobalWindowOuter::Cast(window)->GetCurrentInnerWindowInternal(); |
2218 | 0 | if (!inner) { |
2219 | 0 | return NS_ERROR_NOT_AVAILABLE; |
2220 | 0 | } |
2221 | 0 | *aWindowID = inner->WindowID(); |
2222 | 0 | return NS_OK; |
2223 | 0 | } |
2224 | | |
2225 | | NS_IMETHODIMP |
2226 | | nsDOMWindowUtils::SuspendTimeouts() |
2227 | 0 | { |
2228 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2229 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
2230 | 0 |
|
2231 | 0 | nsCOMPtr<nsPIDOMWindowInner> inner = window->GetCurrentInnerWindow(); |
2232 | 0 | NS_ENSURE_TRUE(inner, NS_ERROR_FAILURE); |
2233 | 0 |
|
2234 | 0 | inner->Suspend(); |
2235 | 0 |
|
2236 | 0 | return NS_OK; |
2237 | 0 | } |
2238 | | |
2239 | | NS_IMETHODIMP |
2240 | | nsDOMWindowUtils::ResumeTimeouts() |
2241 | 0 | { |
2242 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2243 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
2244 | 0 |
|
2245 | 0 | nsCOMPtr<nsPIDOMWindowInner> inner = window->GetCurrentInnerWindow(); |
2246 | 0 | NS_ENSURE_TRUE(inner, NS_ERROR_FAILURE); |
2247 | 0 |
|
2248 | 0 | inner->Resume(); |
2249 | 0 |
|
2250 | 0 | return NS_OK; |
2251 | 0 | } |
2252 | | |
2253 | | NS_IMETHODIMP |
2254 | | nsDOMWindowUtils::GetLayerManagerType(nsAString& aType) |
2255 | 0 | { |
2256 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2257 | 0 | if (!widget) |
2258 | 0 | return NS_ERROR_FAILURE; |
2259 | 0 | |
2260 | 0 | LayerManager *mgr = widget->GetLayerManager(nsIWidget::LAYER_MANAGER_PERSISTENT); |
2261 | 0 | if (!mgr) |
2262 | 0 | return NS_ERROR_FAILURE; |
2263 | 0 | |
2264 | 0 | mgr->GetBackendName(aType); |
2265 | 0 |
|
2266 | 0 | return NS_OK; |
2267 | 0 | } |
2268 | | |
2269 | | NS_IMETHODIMP |
2270 | | nsDOMWindowUtils::GetLayerManagerRemote(bool* retval) |
2271 | 0 | { |
2272 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2273 | 0 | if (!widget) |
2274 | 0 | return NS_ERROR_FAILURE; |
2275 | 0 | |
2276 | 0 | LayerManager *mgr = widget->GetLayerManager(); |
2277 | 0 | if (!mgr) |
2278 | 0 | return NS_ERROR_FAILURE; |
2279 | 0 | |
2280 | 0 | *retval = !!mgr->AsKnowsCompositor(); |
2281 | 0 | return NS_OK; |
2282 | 0 | } |
2283 | | |
2284 | | NS_IMETHODIMP |
2285 | | nsDOMWindowUtils::GetUsingAdvancedLayers(bool* retval) |
2286 | 0 | { |
2287 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2288 | 0 | if (!widget) { |
2289 | 0 | return NS_ERROR_FAILURE; |
2290 | 0 | } |
2291 | 0 | |
2292 | 0 | LayerManager *mgr = widget->GetLayerManager(); |
2293 | 0 | if (!mgr) { |
2294 | 0 | return NS_ERROR_FAILURE; |
2295 | 0 | } |
2296 | 0 | |
2297 | 0 | *retval = false; |
2298 | 0 | if (KnowsCompositor* fwd = mgr->AsKnowsCompositor()) { |
2299 | 0 | *retval = fwd->GetTextureFactoryIdentifier().mUsingAdvancedLayers; |
2300 | 0 | } |
2301 | 0 | return NS_OK; |
2302 | 0 | } |
2303 | | |
2304 | | NS_IMETHODIMP |
2305 | | nsDOMWindowUtils::GetIsWebRenderBuilt(bool* retval) |
2306 | 0 | { |
2307 | 0 | #ifdef MOZ_BUILD_WEBRENDER |
2308 | 0 | *retval = true; |
2309 | | #else |
2310 | | *retval = false; |
2311 | | #endif |
2312 | | return NS_OK; |
2313 | 0 | } |
2314 | | |
2315 | | NS_IMETHODIMP |
2316 | | nsDOMWindowUtils::GetIsWebRenderRequested(bool* retval) |
2317 | 0 | { |
2318 | 0 | *retval = gfxPlatform::WebRenderPrefEnabled() || |
2319 | 0 | gfxPlatform::WebRenderEnvvarEnabled(); |
2320 | 0 | return NS_OK; |
2321 | 0 | } |
2322 | | |
2323 | | NS_IMETHODIMP |
2324 | | nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend) |
2325 | 0 | { |
2326 | 0 | CubebUtils::GetCurrentBackend(aBackend); |
2327 | 0 | return NS_OK; |
2328 | 0 | } |
2329 | | |
2330 | | NS_IMETHODIMP |
2331 | | nsDOMWindowUtils::GetCurrentMaxAudioChannels(uint32_t* aChannels) |
2332 | 0 | { |
2333 | 0 | *aChannels = CubebUtils::MaxNumberOfChannels(); |
2334 | 0 | return NS_OK; |
2335 | 0 | } |
2336 | | |
2337 | | NS_IMETHODIMP |
2338 | | nsDOMWindowUtils::GetCurrentPreferredSampleRate(uint32_t* aRate) |
2339 | 0 | { |
2340 | 0 | *aRate = CubebUtils::PreferredSampleRate(); |
2341 | 0 | return NS_OK; |
2342 | 0 | } |
2343 | | |
2344 | | NS_IMETHODIMP |
2345 | | nsDOMWindowUtils::AudioDevices(uint16_t aSide, nsIArray** aDevices) |
2346 | 0 | { |
2347 | 0 | NS_ENSURE_ARG_POINTER(aDevices); |
2348 | 0 | NS_ENSURE_ARG((aSide == AUDIO_INPUT) || (aSide == AUDIO_OUTPUT)); |
2349 | 0 | *aDevices = nullptr; |
2350 | 0 |
|
2351 | 0 | nsresult rv = NS_OK; |
2352 | 0 | nsCOMPtr<nsIMutableArray> devices = |
2353 | 0 | do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); |
2354 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
2355 | 0 |
|
2356 | 0 | nsTArray<RefPtr<AudioDeviceInfo>> collection; |
2357 | 0 | CubebUtils::GetDeviceCollection(collection, |
2358 | 0 | aSide == AUDIO_INPUT |
2359 | 0 | ? CubebUtils::Side::Input |
2360 | 0 | : CubebUtils::Side::Output); |
2361 | 0 | for (auto device: collection) { |
2362 | 0 | devices->AppendElement(device); |
2363 | 0 | } |
2364 | 0 |
|
2365 | 0 | devices.forget(aDevices); |
2366 | 0 |
|
2367 | 0 | return NS_OK; |
2368 | 0 | } |
2369 | | |
2370 | | NS_IMETHODIMP |
2371 | | nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex) |
2372 | 0 | { |
2373 | 0 | NS_ENSURE_ARG_POINTER(startIndex); |
2374 | 0 |
|
2375 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2376 | 0 | if (!widget) |
2377 | 0 | return NS_ERROR_FAILURE; |
2378 | 0 | |
2379 | 0 | LayerManager *mgr = widget->GetLayerManager(); |
2380 | 0 | if (!mgr) |
2381 | 0 | return NS_ERROR_FAILURE; |
2382 | 0 | |
2383 | 0 | const uint32_t kRecordingMinSize = 60 * 10; // 10 seconds @60 fps. |
2384 | 0 | const uint32_t kRecordingMaxSize = 60 * 60 * 60; // One hour |
2385 | 0 | uint32_t bufferSize = Preferences::GetUint("toolkit.framesRecording.bufferSize", uint32_t(0)); |
2386 | 0 | bufferSize = std::min(bufferSize, kRecordingMaxSize); |
2387 | 0 | bufferSize = std::max(bufferSize, kRecordingMinSize); |
2388 | 0 | *startIndex = mgr->StartFrameTimeRecording(bufferSize); |
2389 | 0 |
|
2390 | 0 | return NS_OK; |
2391 | 0 | } |
2392 | | |
2393 | | NS_IMETHODIMP |
2394 | | nsDOMWindowUtils::StopFrameTimeRecording(uint32_t startIndex, |
2395 | | uint32_t *frameCount, |
2396 | | float **frameIntervals) |
2397 | 0 | { |
2398 | 0 | NS_ENSURE_ARG_POINTER(frameCount); |
2399 | 0 | NS_ENSURE_ARG_POINTER(frameIntervals); |
2400 | 0 |
|
2401 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2402 | 0 | if (!widget) |
2403 | 0 | return NS_ERROR_FAILURE; |
2404 | 0 | |
2405 | 0 | LayerManager *mgr = widget->GetLayerManager(); |
2406 | 0 | if (!mgr) |
2407 | 0 | return NS_ERROR_FAILURE; |
2408 | 0 | |
2409 | 0 | nsTArray<float> tmpFrameIntervals; |
2410 | 0 | mgr->StopFrameTimeRecording(startIndex, tmpFrameIntervals); |
2411 | 0 | *frameCount = tmpFrameIntervals.Length(); |
2412 | 0 |
|
2413 | 0 | *frameIntervals = (float*)moz_xmalloc(*frameCount * sizeof(float)); |
2414 | 0 |
|
2415 | 0 | /* copy over the frame intervals and paint times into the arrays we just allocated */ |
2416 | 0 | for (uint32_t i = 0; i < *frameCount; i++) { |
2417 | 0 | (*frameIntervals)[i] = tmpFrameIntervals[i]; |
2418 | 0 | } |
2419 | 0 |
|
2420 | 0 | return NS_OK; |
2421 | 0 | } |
2422 | | |
2423 | | NS_IMETHODIMP |
2424 | | nsDOMWindowUtils::AdvanceTimeAndRefresh(int64_t aMilliseconds) |
2425 | 0 | { |
2426 | 0 | // Before we advance the time, we should trigger any animations that are |
2427 | 0 | // waiting to start. This is because there are many tests that call this |
2428 | 0 | // which expect animations to start immediately. Ideally, we should make |
2429 | 0 | // all these tests do an asynchronous wait on the corresponding animation's |
2430 | 0 | // 'ready' promise before continuing. Then we could remove the special |
2431 | 0 | // handling here and the code path followed when testing would more closely |
2432 | 0 | // match the code path during regular operation. Filed as bug 1112957. |
2433 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
2434 | 0 | if (doc) { |
2435 | 0 | PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker(); |
2436 | 0 | if (tracker) { |
2437 | 0 | tracker->TriggerPendingAnimationsNow(); |
2438 | 0 | } |
2439 | 0 | } |
2440 | 0 |
|
2441 | 0 | nsPresContext* presContext = GetPresContext(); |
2442 | 0 | if (presContext) { |
2443 | 0 | nsRefreshDriver* driver = presContext->RefreshDriver(); |
2444 | 0 | driver->AdvanceTimeAndRefresh(aMilliseconds); |
2445 | 0 |
|
2446 | 0 | RefPtr<LayerTransactionChild> transaction = GetLayerTransaction(); |
2447 | 0 | if (transaction && transaction->IPCOpen()) { |
2448 | 0 | transaction->SendSetTestSampleTime(driver->MostRecentRefresh()); |
2449 | 0 | } else if (WebRenderBridgeChild* wrbc = GetWebRenderBridge()) { |
2450 | 0 | wrbc->SendSetTestSampleTime(driver->MostRecentRefresh()); |
2451 | 0 | } |
2452 | 0 | } |
2453 | 0 |
|
2454 | 0 | return NS_OK; |
2455 | 0 | } |
2456 | | |
2457 | | NS_IMETHODIMP |
2458 | | nsDOMWindowUtils::GetLastTransactionId(uint64_t *aLastTransactionId) |
2459 | 0 | { |
2460 | 0 | nsPresContext* presContext = GetPresContext(); |
2461 | 0 | if (!presContext) { |
2462 | 0 | return NS_ERROR_UNEXPECTED; |
2463 | 0 | } |
2464 | 0 | |
2465 | 0 | nsRefreshDriver* driver = presContext->GetRootPresContext()->RefreshDriver(); |
2466 | 0 | *aLastTransactionId = uint64_t(driver->LastTransactionId()); |
2467 | 0 | return NS_OK; |
2468 | 0 | } |
2469 | | |
2470 | | NS_IMETHODIMP |
2471 | | nsDOMWindowUtils::RestoreNormalRefresh() |
2472 | 0 | { |
2473 | 0 | // Kick the compositor out of test mode before the refresh driver, so that |
2474 | 0 | // the refresh driver doesn't send an update that gets ignored by the |
2475 | 0 | // compositor. |
2476 | 0 | RefPtr<LayerTransactionChild> transaction = GetLayerTransaction(); |
2477 | 0 | if (transaction && transaction->IPCOpen()) { |
2478 | 0 | transaction->SendLeaveTestMode(); |
2479 | 0 | } else if (WebRenderBridgeChild* wrbc = GetWebRenderBridge()) { |
2480 | 0 | wrbc->SendLeaveTestMode(); |
2481 | 0 | } |
2482 | 0 |
|
2483 | 0 | if (nsPresContext* pc = GetPresContext()) { |
2484 | 0 | nsRefreshDriver* driver = pc->RefreshDriver(); |
2485 | 0 | driver->RestoreNormalRefresh(); |
2486 | 0 | } |
2487 | 0 |
|
2488 | 0 | return NS_OK; |
2489 | 0 | } |
2490 | | |
2491 | | NS_IMETHODIMP |
2492 | | nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult) |
2493 | 0 | { |
2494 | 0 | nsPresContext* pc = GetPresContext(); |
2495 | 0 | *aResult = |
2496 | 0 | pc ? pc->RefreshDriver()->IsTestControllingRefreshesEnabled() : false; |
2497 | 0 |
|
2498 | 0 | return NS_OK; |
2499 | 0 | } |
2500 | | |
2501 | | NS_IMETHODIMP |
2502 | | nsDOMWindowUtils::GetAsyncPanZoomEnabled(bool *aResult) |
2503 | 0 | { |
2504 | 0 | nsIWidget* widget = GetWidget(); |
2505 | 0 | if (widget) { |
2506 | 0 | *aResult = widget->AsyncPanZoomEnabled(); |
2507 | 0 | } else { |
2508 | 0 | *aResult = gfxPlatform::AsyncPanZoomEnabled(); |
2509 | 0 | } |
2510 | 0 | return NS_OK; |
2511 | 0 | } |
2512 | | |
2513 | | NS_IMETHODIMP |
2514 | | nsDOMWindowUtils::SetAsyncScrollOffset(Element* aElement, |
2515 | | float aX, float aY) |
2516 | 0 | { |
2517 | 0 | if (!aElement) { |
2518 | 0 | return NS_ERROR_INVALID_ARG; |
2519 | 0 | } |
2520 | 0 | FrameMetrics::ViewID viewId; |
2521 | 0 | if (!nsLayoutUtils::FindIDFor(aElement, &viewId)) { |
2522 | 0 | return NS_ERROR_UNEXPECTED; |
2523 | 0 | } |
2524 | 0 | nsIWidget* widget = GetWidget(); |
2525 | 0 | if (!widget) { |
2526 | 0 | return NS_ERROR_FAILURE; |
2527 | 0 | } |
2528 | 0 | LayerManager* manager = widget->GetLayerManager(); |
2529 | 0 | if (!manager) { |
2530 | 0 | return NS_ERROR_FAILURE; |
2531 | 0 | } |
2532 | 0 | if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) { |
2533 | 0 | WebRenderBridgeChild* wrbc = wrlm->WrBridge(); |
2534 | 0 | if (!wrbc) { |
2535 | 0 | return NS_ERROR_UNEXPECTED; |
2536 | 0 | } |
2537 | 0 | wrbc->SendSetAsyncScrollOffset(viewId, aX, aY); |
2538 | 0 | return NS_OK; |
2539 | 0 | } |
2540 | 0 | ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); |
2541 | 0 | if (!forwarder || !forwarder->HasShadowManager()) { |
2542 | 0 | return NS_ERROR_UNEXPECTED; |
2543 | 0 | } |
2544 | 0 | forwarder->GetShadowManager()->SendSetAsyncScrollOffset(viewId, aX, aY); |
2545 | 0 | return NS_OK; |
2546 | 0 | } |
2547 | | |
2548 | | NS_IMETHODIMP |
2549 | | nsDOMWindowUtils::SetAsyncZoom(Element* aRootElement, float aValue) |
2550 | 0 | { |
2551 | 0 | if (!aRootElement) { |
2552 | 0 | return NS_ERROR_INVALID_ARG; |
2553 | 0 | } |
2554 | 0 | FrameMetrics::ViewID viewId; |
2555 | 0 | if (!nsLayoutUtils::FindIDFor(aRootElement, &viewId)) { |
2556 | 0 | return NS_ERROR_UNEXPECTED; |
2557 | 0 | } |
2558 | 0 | nsIWidget* widget = GetWidget(); |
2559 | 0 | if (!widget) { |
2560 | 0 | return NS_ERROR_FAILURE; |
2561 | 0 | } |
2562 | 0 | LayerManager* manager = widget->GetLayerManager(); |
2563 | 0 | if (!manager) { |
2564 | 0 | return NS_ERROR_FAILURE; |
2565 | 0 | } |
2566 | 0 | if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) { |
2567 | 0 | WebRenderBridgeChild* wrbc = wrlm->WrBridge(); |
2568 | 0 | if (!wrbc) { |
2569 | 0 | return NS_ERROR_UNEXPECTED; |
2570 | 0 | } |
2571 | 0 | wrbc->SendSetAsyncZoom(viewId, aValue); |
2572 | 0 | return NS_OK; |
2573 | 0 | } |
2574 | 0 | ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); |
2575 | 0 | if (!forwarder || !forwarder->HasShadowManager()) { |
2576 | 0 | return NS_ERROR_UNEXPECTED; |
2577 | 0 | } |
2578 | 0 | forwarder->GetShadowManager()->SendSetAsyncZoom(viewId, aValue); |
2579 | 0 | return NS_OK; |
2580 | 0 | } |
2581 | | |
2582 | | NS_IMETHODIMP |
2583 | | nsDOMWindowUtils::FlushApzRepaints(bool* aOutResult) |
2584 | 0 | { |
2585 | 0 | nsIWidget* widget = GetWidget(); |
2586 | 0 | if (!widget) { |
2587 | 0 | *aOutResult = false; |
2588 | 0 | return NS_OK; |
2589 | 0 | } |
2590 | 0 | // If APZ is not enabled, this function is a no-op. |
2591 | 0 | if (!widget->AsyncPanZoomEnabled()) { |
2592 | 0 | *aOutResult = false; |
2593 | 0 | return NS_OK; |
2594 | 0 | } |
2595 | 0 | LayerManager* manager = widget->GetLayerManager(); |
2596 | 0 | if (!manager) { |
2597 | 0 | *aOutResult = false; |
2598 | 0 | return NS_OK; |
2599 | 0 | } |
2600 | 0 | if (WebRenderLayerManager* wrlm = manager->AsWebRenderLayerManager()) { |
2601 | 0 | WebRenderBridgeChild* wrbc = wrlm->WrBridge(); |
2602 | 0 | if (!wrbc) { |
2603 | 0 | return NS_ERROR_UNEXPECTED; |
2604 | 0 | } |
2605 | 0 | wrbc->SendFlushApzRepaints(); |
2606 | 0 | *aOutResult = true; |
2607 | 0 | return NS_OK; |
2608 | 0 | } |
2609 | 0 | ShadowLayerForwarder* forwarder = manager->AsShadowForwarder(); |
2610 | 0 | if (!forwarder || !forwarder->HasShadowManager()) { |
2611 | 0 | *aOutResult = false; |
2612 | 0 | return NS_OK; |
2613 | 0 | } |
2614 | 0 | forwarder->GetShadowManager()->SendFlushApzRepaints(); |
2615 | 0 | *aOutResult = true; |
2616 | 0 | return NS_OK; |
2617 | 0 | } |
2618 | | |
2619 | | NS_IMETHODIMP |
2620 | | nsDOMWindowUtils::ZoomToFocusedInput() |
2621 | 0 | { |
2622 | 0 | nsIWidget* widget = GetWidget(); |
2623 | 0 | if (!widget) { |
2624 | 0 | return NS_OK; |
2625 | 0 | } |
2626 | 0 | // If APZ is not enabled, this function is a no-op. |
2627 | 0 | if (!widget->AsyncPanZoomEnabled()) { |
2628 | 0 | return NS_OK; |
2629 | 0 | } |
2630 | 0 | |
2631 | 0 | nsFocusManager* fm = nsFocusManager::GetFocusManager(); |
2632 | 0 | if (!fm) { |
2633 | 0 | return NS_OK; |
2634 | 0 | } |
2635 | 0 | |
2636 | 0 | nsIContent* content = fm->GetFocusedElement(); |
2637 | 0 | if (!content) { |
2638 | 0 | return NS_OK; |
2639 | 0 | } |
2640 | 0 | |
2641 | 0 | nsIPresShell* shell = APZCCallbackHelper::GetRootContentDocumentPresShellForContent(content); |
2642 | 0 | if (!shell) { |
2643 | 0 | return NS_OK; |
2644 | 0 | } |
2645 | 0 | |
2646 | 0 | nsIScrollableFrame* rootScrollFrame = shell->GetRootScrollFrameAsScrollable(); |
2647 | 0 | if (!rootScrollFrame) { |
2648 | 0 | return NS_OK; |
2649 | 0 | } |
2650 | 0 | |
2651 | 0 | nsIFrame* currentFrame = content->GetPrimaryFrame(); |
2652 | 0 | nsIFrame* rootFrame = shell->GetRootFrame(); |
2653 | 0 | nsIFrame* scrolledFrame = rootScrollFrame->GetScrolledFrame(); |
2654 | 0 | bool isFixedPos = true; |
2655 | 0 |
|
2656 | 0 | while (currentFrame) { |
2657 | 0 | if (currentFrame == rootFrame) { |
2658 | 0 | break; |
2659 | 0 | } |
2660 | 0 | if (currentFrame == scrolledFrame) { |
2661 | 0 | // we are in the rootScrollFrame so this element is not fixed |
2662 | 0 | isFixedPos = false; |
2663 | 0 | break; |
2664 | 0 | } |
2665 | 0 | currentFrame = nsLayoutUtils::GetCrossDocParentFrame(currentFrame); |
2666 | 0 | } |
2667 | 0 |
|
2668 | 0 | if (isFixedPos) { |
2669 | 0 | // We didn't find the scrolledFrame in our parent frames so this content must be fixed position. |
2670 | 0 | // Zooming into fixed position content doesn't make sense so just return with out panning and zooming. |
2671 | 0 | return NS_OK; |
2672 | 0 | } |
2673 | 0 | |
2674 | 0 | nsIDocument* document = shell->GetDocument(); |
2675 | 0 | if (!document) { |
2676 | 0 | return NS_OK; |
2677 | 0 | } |
2678 | 0 | |
2679 | 0 | uint32_t presShellId; |
2680 | 0 | FrameMetrics::ViewID viewId; |
2681 | 0 | if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(document->GetDocumentElement(), &presShellId, &viewId)) { |
2682 | 0 | uint32_t flags = layers::DISABLE_ZOOM_OUT; |
2683 | 0 | if (!Preferences::GetBool("formhelper.autozoom")) { |
2684 | 0 | flags |= layers::PAN_INTO_VIEW_ONLY; |
2685 | 0 | } else { |
2686 | 0 | flags |= layers::ONLY_ZOOM_TO_DEFAULT_SCALE; |
2687 | 0 | } |
2688 | 0 |
|
2689 | 0 | CSSRect bounds = nsLayoutUtils::GetBoundingContentRect(content, rootScrollFrame); |
2690 | 0 | if (bounds.IsEmpty()) { |
2691 | 0 | // Do not zoom on empty bounds. Bail out. |
2692 | 0 | return NS_OK; |
2693 | 0 | } |
2694 | 0 | bounds.Inflate(15.0f, 0.0f); |
2695 | 0 | widget->ZoomToRect(presShellId, viewId, bounds, flags); |
2696 | 0 | } |
2697 | 0 |
|
2698 | 0 | return NS_OK; |
2699 | 0 | } |
2700 | | |
2701 | | NS_IMETHODIMP |
2702 | | nsDOMWindowUtils::ComputeAnimationDistance(Element* aElement, |
2703 | | const nsAString& aProperty, |
2704 | | const nsAString& aValue1, |
2705 | | const nsAString& aValue2, |
2706 | | double* aResult) |
2707 | 0 | { |
2708 | 0 | NS_ENSURE_ARG_POINTER(aElement); |
2709 | 0 |
|
2710 | 0 | nsCSSPropertyID property = nsCSSProps::LookupProperty(aProperty); |
2711 | 0 | if (property == eCSSProperty_UNKNOWN || nsCSSProps::IsShorthand(property)) { |
2712 | 0 | return NS_ERROR_ILLEGAL_VALUE; |
2713 | 0 | } |
2714 | 0 | |
2715 | 0 | AnimationValue v1 = AnimationValue::FromString(property, aValue1, aElement); |
2716 | 0 | AnimationValue v2 = AnimationValue::FromString(property, aValue2, aElement); |
2717 | 0 | if (v1.IsNull() || v2.IsNull()) { |
2718 | 0 | return NS_ERROR_ILLEGAL_VALUE; |
2719 | 0 | } |
2720 | 0 | |
2721 | 0 | RefPtr<ComputedStyle> computedStyle = |
2722 | 0 | nsComputedDOMStyle::GetComputedStyle(aElement, nullptr); |
2723 | 0 | *aResult = v1.ComputeDistance(property, v2, computedStyle); |
2724 | 0 | return NS_OK; |
2725 | 0 | } |
2726 | | |
2727 | | NS_IMETHODIMP |
2728 | | nsDOMWindowUtils::GetUnanimatedComputedStyle(Element* aElement, |
2729 | | const nsAString& aPseudoElement, |
2730 | | const nsAString& aProperty, |
2731 | | int32_t aFlushType, |
2732 | | nsAString& aResult) |
2733 | 0 | { |
2734 | 0 | if (!aElement) { |
2735 | 0 | return NS_ERROR_INVALID_ARG; |
2736 | 0 | } |
2737 | 0 | |
2738 | 0 | nsCSSPropertyID propertyID = nsCSSProps::LookupProperty(aProperty); |
2739 | 0 | if (propertyID == eCSSProperty_UNKNOWN || |
2740 | 0 | nsCSSProps::IsShorthand(propertyID)) { |
2741 | 0 | return NS_ERROR_INVALID_ARG; |
2742 | 0 | } |
2743 | 0 | |
2744 | 0 | switch (aFlushType) { |
2745 | 0 | case FLUSH_NONE: |
2746 | 0 | break; |
2747 | 0 | case FLUSH_STYLE: { |
2748 | 0 | if (nsIDocument* doc = aElement->GetComposedDoc()) { |
2749 | 0 | doc->FlushPendingNotifications(FlushType::Style); |
2750 | 0 | } |
2751 | 0 | break; |
2752 | 0 | } |
2753 | 0 | default: |
2754 | 0 | return NS_ERROR_INVALID_ARG; |
2755 | 0 | } |
2756 | 0 | |
2757 | 0 | nsIPresShell* shell = GetPresShell(); |
2758 | 0 | if (!shell) { |
2759 | 0 | return NS_ERROR_FAILURE; |
2760 | 0 | } |
2761 | 0 | |
2762 | 0 | RefPtr<nsAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement); |
2763 | 0 | RefPtr<ComputedStyle> computedStyle = |
2764 | 0 | nsComputedDOMStyle::GetUnanimatedComputedStyleNoFlush(aElement, pseudo); |
2765 | 0 | if (!computedStyle) { |
2766 | 0 | return NS_ERROR_FAILURE; |
2767 | 0 | } |
2768 | 0 | |
2769 | 0 | RefPtr<RawServoAnimationValue> value = |
2770 | 0 | Servo_ComputedValues_ExtractAnimationValue(computedStyle, |
2771 | 0 | propertyID).Consume(); |
2772 | 0 | if (!value) { |
2773 | 0 | return NS_ERROR_FAILURE; |
2774 | 0 | } |
2775 | 0 | Servo_AnimationValue_Serialize(value, propertyID, &aResult); |
2776 | 0 | return NS_OK; |
2777 | 0 | } |
2778 | | |
2779 | | nsresult |
2780 | | nsDOMWindowUtils::RenderDocument(const nsRect& aRect, |
2781 | | uint32_t aFlags, |
2782 | | nscolor aBackgroundColor, |
2783 | | gfxContext* aThebesContext) |
2784 | 0 | { |
2785 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
2786 | 0 | NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); |
2787 | 0 |
|
2788 | 0 | // Get Primary Shell |
2789 | 0 | nsCOMPtr<nsIPresShell> presShell = doc->GetShell(); |
2790 | 0 | NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); |
2791 | 0 |
|
2792 | 0 | // Render Document |
2793 | 0 | return presShell->RenderDocument(aRect, aFlags, aBackgroundColor, aThebesContext); |
2794 | 0 | } |
2795 | | |
2796 | | NS_IMETHODIMP |
2797 | | nsDOMWindowUtils::GetDisplayDPI(float *aDPI) |
2798 | 0 | { |
2799 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
2800 | 0 | if (!widget) |
2801 | 0 | return NS_ERROR_FAILURE; |
2802 | 0 | |
2803 | 0 | *aDPI = widget->GetDPI(); |
2804 | 0 |
|
2805 | 0 | return NS_OK; |
2806 | 0 | } |
2807 | | |
2808 | | NS_IMETHODIMP |
2809 | | nsDOMWindowUtils::GetContainerElement(Element** aResult) |
2810 | 0 | { |
2811 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
2812 | 0 | NS_ENSURE_STATE(window); |
2813 | 0 |
|
2814 | 0 | RefPtr<Element> element = window->GetFrameElementInternal(); |
2815 | 0 | element.forget(aResult); |
2816 | 0 | return NS_OK; |
2817 | 0 | } |
2818 | | |
2819 | | #ifdef DEBUG |
2820 | | static bool |
2821 | | CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion) |
2822 | | { |
2823 | | gfx::Matrix transform; |
2824 | | if (!aLayer->GetTransform().Is2D(&transform) || |
2825 | | transform.HasNonIntegerTranslation()) |
2826 | | return false; |
2827 | | transform.NudgeToIntegers(); |
2828 | | IntPoint offset = aOffset + IntPoint::Truncate(transform._31, transform._32); |
2829 | | |
2830 | | Layer* child = aLayer->GetFirstChild(); |
2831 | | if (child) { |
2832 | | while (child) { |
2833 | | if (!CheckLeafLayers(child, offset, aCoveredRegion)) |
2834 | | return false; |
2835 | | child = child->GetNextSibling(); |
2836 | | } |
2837 | | } else { |
2838 | | nsIntRegion rgn = aLayer->GetVisibleRegion().ToUnknownRegion(); |
2839 | | rgn.MoveBy(offset); |
2840 | | nsIntRegion tmp; |
2841 | | tmp.And(rgn, *aCoveredRegion); |
2842 | | if (!tmp.IsEmpty()) |
2843 | | return false; |
2844 | | aCoveredRegion->Or(*aCoveredRegion, rgn); |
2845 | | } |
2846 | | |
2847 | | return true; |
2848 | | } |
2849 | | #endif |
2850 | | |
2851 | | NS_IMETHODIMP |
2852 | | nsDOMWindowUtils::LeafLayersPartitionWindow(bool* aResult) |
2853 | 0 | { |
2854 | 0 | *aResult = true; |
2855 | | #ifdef DEBUG |
2856 | | nsIWidget* widget = GetWidget(); |
2857 | | if (!widget) |
2858 | | return NS_ERROR_FAILURE; |
2859 | | LayerManager* manager = widget->GetLayerManager(); |
2860 | | if (!manager) |
2861 | | return NS_ERROR_FAILURE; |
2862 | | nsPresContext* presContext = GetPresContext(); |
2863 | | if (!presContext) |
2864 | | return NS_ERROR_FAILURE; |
2865 | | Layer* root = manager->GetRoot(); |
2866 | | if (!root) |
2867 | | return NS_ERROR_FAILURE; |
2868 | | |
2869 | | nsIntPoint offset(0, 0); |
2870 | | nsIntRegion coveredRegion; |
2871 | | if (!CheckLeafLayers(root, offset, &coveredRegion)) { |
2872 | | *aResult = false; |
2873 | | } |
2874 | | if (!coveredRegion.IsEqual(root->GetVisibleRegion().ToUnknownRegion())) { |
2875 | | *aResult = false; |
2876 | | } |
2877 | | #endif |
2878 | | return NS_OK; |
2879 | 0 | } |
2880 | | |
2881 | | NS_IMETHODIMP |
2882 | | nsDOMWindowUtils::CheckAndClearPaintedState(Element* aElement, bool* aResult) |
2883 | 0 | { |
2884 | 0 | if (!aElement) { |
2885 | 0 | return NS_ERROR_INVALID_ARG; |
2886 | 0 | } |
2887 | 0 | |
2888 | 0 | nsIFrame* frame = aElement->GetPrimaryFrame(); |
2889 | 0 |
|
2890 | 0 | if (!frame) { |
2891 | 0 | *aResult = false; |
2892 | 0 | return NS_OK; |
2893 | 0 | } |
2894 | 0 | |
2895 | 0 | // Get the outermost frame for the content node, so that we can test |
2896 | 0 | // canvasframe invalidations by observing the documentElement. |
2897 | 0 | for (;;) { |
2898 | 0 | nsIFrame* parentFrame = frame->GetParent(); |
2899 | 0 | if (parentFrame && parentFrame->GetContent() == aElement) { |
2900 | 0 | frame = parentFrame; |
2901 | 0 | } else { |
2902 | 0 | break; |
2903 | 0 | } |
2904 | 0 | } |
2905 | 0 |
|
2906 | 0 | while (frame) { |
2907 | 0 | if (!frame->CheckAndClearPaintedState()) { |
2908 | 0 | *aResult = false; |
2909 | 0 | return NS_OK; |
2910 | 0 | } |
2911 | 0 | frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame); |
2912 | 0 | } |
2913 | 0 | *aResult = true; |
2914 | 0 | return NS_OK; |
2915 | 0 | } |
2916 | | |
2917 | | NS_IMETHODIMP |
2918 | | nsDOMWindowUtils::CheckAndClearDisplayListState(Element* aElement, bool* aResult) |
2919 | 0 | { |
2920 | 0 | if (!aElement) { |
2921 | 0 | return NS_ERROR_INVALID_ARG; |
2922 | 0 | } |
2923 | 0 | |
2924 | 0 | nsIFrame* frame = aElement->GetPrimaryFrame(); |
2925 | 0 |
|
2926 | 0 | if (!frame) { |
2927 | 0 | *aResult = false; |
2928 | 0 | return NS_OK; |
2929 | 0 | } |
2930 | 0 | |
2931 | 0 | // Get the outermost frame for the content node, so that we can test |
2932 | 0 | // canvasframe invalidations by observing the documentElement. |
2933 | 0 | for (;;) { |
2934 | 0 | nsIFrame* parentFrame = frame->GetParent(); |
2935 | 0 | if (parentFrame && parentFrame->GetContent() == aElement) { |
2936 | 0 | frame = parentFrame; |
2937 | 0 | } else { |
2938 | 0 | break; |
2939 | 0 | } |
2940 | 0 | } |
2941 | 0 |
|
2942 | 0 | while (frame) { |
2943 | 0 | if (!frame->CheckAndClearDisplayListState()) { |
2944 | 0 | *aResult = false; |
2945 | 0 | return NS_OK; |
2946 | 0 | } |
2947 | 0 | frame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(frame); |
2948 | 0 | } |
2949 | 0 | *aResult = true; |
2950 | 0 | return NS_OK; |
2951 | 0 |
|
2952 | 0 | } |
2953 | | |
2954 | | NS_IMETHODIMP |
2955 | | nsDOMWindowUtils::IsPartOfOpaqueLayer(Element* aElement, bool* aResult) |
2956 | 0 | { |
2957 | 0 | if (!aElement) { |
2958 | 0 | return NS_ERROR_INVALID_ARG; |
2959 | 0 | } |
2960 | 0 | |
2961 | 0 | nsIFrame* frame = aElement->GetPrimaryFrame(); |
2962 | 0 | if (!frame) { |
2963 | 0 | return NS_ERROR_FAILURE; |
2964 | 0 | } |
2965 | 0 | |
2966 | 0 | ColorLayer* colorLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<ColorLayer>(frame); |
2967 | 0 | if (colorLayer) { |
2968 | 0 | auto color = colorLayer->GetColor(); |
2969 | 0 | *aResult = color.a == 1.0f; |
2970 | 0 | return NS_OK; |
2971 | 0 | } |
2972 | 0 | |
2973 | 0 | PaintedLayer* paintedLayer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame); |
2974 | 0 | if (paintedLayer) { |
2975 | 0 | *aResult = paintedLayer->IsOpaque(); |
2976 | 0 | return NS_OK; |
2977 | 0 | } |
2978 | 0 | |
2979 | 0 | return NS_ERROR_FAILURE; |
2980 | 0 | } |
2981 | | |
2982 | | NS_IMETHODIMP |
2983 | | nsDOMWindowUtils::NumberOfAssignedPaintedLayers(Element** aElements, |
2984 | | uint32_t aCount, |
2985 | | uint32_t* aResult) |
2986 | 0 | { |
2987 | 0 | if (!aElements) { |
2988 | 0 | return NS_ERROR_INVALID_ARG; |
2989 | 0 | } |
2990 | 0 | |
2991 | 0 | nsTHashtable<nsPtrHashKey<PaintedLayer>> layers; |
2992 | 0 | for (uint32_t i = 0; i < aCount; i++) { |
2993 | 0 | nsIFrame* frame = aElements[i]->GetPrimaryFrame(); |
2994 | 0 | if (!frame) { |
2995 | 0 | return NS_ERROR_FAILURE; |
2996 | 0 | } |
2997 | 0 | |
2998 | 0 | PaintedLayer* layer = FrameLayerBuilder::GetDebugSingleOldLayerForFrame<PaintedLayer>(frame); |
2999 | 0 | if (!layer) { |
3000 | 0 | return NS_ERROR_FAILURE; |
3001 | 0 | } |
3002 | 0 | |
3003 | 0 | layers.PutEntry(layer); |
3004 | 0 | } |
3005 | 0 |
|
3006 | 0 | *aResult = layers.Count(); |
3007 | 0 | return NS_OK; |
3008 | 0 | } |
3009 | | |
3010 | | NS_IMETHODIMP |
3011 | | nsDOMWindowUtils::EnableDialogs() |
3012 | 0 | { |
3013 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3014 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
3015 | 0 |
|
3016 | 0 | nsGlobalWindowOuter::Cast(window)->EnableDialogs(); |
3017 | 0 | return NS_OK; |
3018 | 0 | } |
3019 | | |
3020 | | NS_IMETHODIMP |
3021 | | nsDOMWindowUtils::DisableDialogs() |
3022 | 0 | { |
3023 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3024 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
3025 | 0 |
|
3026 | 0 | nsGlobalWindowOuter::Cast(window)->DisableDialogs(); |
3027 | 0 | return NS_OK; |
3028 | 0 | } |
3029 | | |
3030 | | NS_IMETHODIMP |
3031 | | nsDOMWindowUtils::AreDialogsEnabled(bool* aResult) |
3032 | 0 | { |
3033 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3034 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
3035 | 0 |
|
3036 | 0 | *aResult = nsGlobalWindowOuter::Cast(window)->AreDialogsEnabled(); |
3037 | 0 | return NS_OK; |
3038 | 0 | } |
3039 | | |
3040 | | NS_IMETHODIMP |
3041 | | nsDOMWindowUtils::GetFileId(JS::Handle<JS::Value> aFile, JSContext* aCx, |
3042 | | int64_t* _retval) |
3043 | 0 | { |
3044 | 0 | if (aFile.isPrimitive()) { |
3045 | 0 | *_retval = -1; |
3046 | 0 | return NS_OK; |
3047 | 0 | } |
3048 | 0 | |
3049 | 0 | JS::Rooted<JSObject*> obj(aCx, aFile.toObjectOrNull()); |
3050 | 0 |
|
3051 | 0 | IDBMutableFile* mutableFile = nullptr; |
3052 | 0 | if (NS_SUCCEEDED(UNWRAP_OBJECT(IDBMutableFile, &obj, mutableFile))) { |
3053 | 0 | *_retval = mutableFile->GetFileId(); |
3054 | 0 | return NS_OK; |
3055 | 0 | } |
3056 | 0 | |
3057 | 0 | Blob* blob = nullptr; |
3058 | 0 | if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, &obj, blob))) { |
3059 | 0 | *_retval = blob->GetFileId(); |
3060 | 0 | return NS_OK; |
3061 | 0 | } |
3062 | 0 | |
3063 | 0 | *_retval = -1; |
3064 | 0 | return NS_OK; |
3065 | 0 | } |
3066 | | |
3067 | | NS_IMETHODIMP |
3068 | | nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx, |
3069 | | nsAString& _retval) |
3070 | 0 | { |
3071 | 0 | if (aFile.isPrimitive()) { |
3072 | 0 | _retval.Truncate(); |
3073 | 0 | return NS_OK; |
3074 | 0 | } |
3075 | 0 | |
3076 | 0 | JS::Rooted<JSObject*> obj(aCx, aFile.toObjectOrNull()); |
3077 | 0 |
|
3078 | 0 | File* file = nullptr; |
3079 | 0 | if (NS_SUCCEEDED(UNWRAP_OBJECT(File, &obj, file))) { |
3080 | 0 | nsString filePath; |
3081 | 0 | ErrorResult rv; |
3082 | 0 | file->GetMozFullPathInternal(filePath, rv); |
3083 | 0 | if (NS_WARN_IF(rv.Failed())) { |
3084 | 0 | return rv.StealNSResult(); |
3085 | 0 | } |
3086 | 0 | |
3087 | 0 | _retval = filePath; |
3088 | 0 | return NS_OK; |
3089 | 0 | } |
3090 | 0 | |
3091 | 0 | _retval.Truncate(); |
3092 | 0 | return NS_OK; |
3093 | 0 | } |
3094 | | |
3095 | | NS_IMETHODIMP |
3096 | | nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId, |
3097 | | JS::Handle<JS::Value> aOptions, |
3098 | | int32_t* aRefCnt, int32_t* aDBRefCnt, |
3099 | | int32_t* aSliceRefCnt, JSContext* aCx, |
3100 | | bool* aResult) |
3101 | 0 | { |
3102 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3103 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
3104 | 0 |
|
3105 | 0 | nsCString origin; |
3106 | 0 | nsresult rv = |
3107 | 0 | quota::QuotaManager::GetInfoFromWindow(window, nullptr, nullptr, &origin); |
3108 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
3109 | 0 |
|
3110 | 0 | IDBOpenDBOptions options; |
3111 | 0 | JS::Rooted<JS::Value> optionsVal(aCx, aOptions); |
3112 | 0 | if (!options.Init(aCx, optionsVal)) { |
3113 | 0 | return NS_ERROR_TYPE_ERR; |
3114 | 0 | } |
3115 | 0 | |
3116 | 0 | quota::PersistenceType persistenceType = |
3117 | 0 | quota::PersistenceTypeFromStorage(options.mStorage); |
3118 | 0 |
|
3119 | 0 | RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get(); |
3120 | 0 |
|
3121 | 0 | if (mgr) { |
3122 | 0 | rv = mgr->BlockAndGetFileReferences(persistenceType, origin, aDatabaseName, |
3123 | 0 | aId, aRefCnt, aDBRefCnt, aSliceRefCnt, |
3124 | 0 | aResult); |
3125 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
3126 | 0 | } |
3127 | 0 | else { |
3128 | 0 | *aRefCnt = *aDBRefCnt = *aSliceRefCnt = -1; |
3129 | 0 | *aResult = false; |
3130 | 0 | } |
3131 | 0 |
|
3132 | 0 | return NS_OK; |
3133 | 0 | } |
3134 | | |
3135 | | NS_IMETHODIMP |
3136 | | nsDOMWindowUtils::FlushPendingFileDeletions() |
3137 | 0 | { |
3138 | 0 | RefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::Get(); |
3139 | 0 | if (mgr) { |
3140 | 0 | nsresult rv = mgr->FlushPendingFileDeletions(); |
3141 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) { |
3142 | 0 | return rv; |
3143 | 0 | } |
3144 | 0 | } |
3145 | 0 | |
3146 | 0 | return NS_OK; |
3147 | 0 | } |
3148 | | |
3149 | | NS_IMETHODIMP |
3150 | | nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult) |
3151 | 0 | { |
3152 | 0 | *aResult = JS::IsIncrementalGCEnabled(cx); |
3153 | 0 | return NS_OK; |
3154 | 0 | } |
3155 | | |
3156 | | NS_IMETHODIMP |
3157 | | nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx) |
3158 | 0 | { |
3159 | 0 | js::StartPCCountProfiling(cx); |
3160 | 0 | return NS_OK; |
3161 | 0 | } |
3162 | | |
3163 | | NS_IMETHODIMP |
3164 | | nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx) |
3165 | 0 | { |
3166 | 0 | js::StopPCCountProfiling(cx); |
3167 | 0 | return NS_OK; |
3168 | 0 | } |
3169 | | |
3170 | | NS_IMETHODIMP |
3171 | | nsDOMWindowUtils::PurgePCCounts(JSContext* cx) |
3172 | 0 | { |
3173 | 0 | js::PurgePCCounts(cx); |
3174 | 0 | return NS_OK; |
3175 | 0 | } |
3176 | | |
3177 | | NS_IMETHODIMP |
3178 | | nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result) |
3179 | 0 | { |
3180 | 0 | *result = js::GetPCCountScriptCount(cx); |
3181 | 0 | return NS_OK; |
3182 | 0 | } |
3183 | | |
3184 | | NS_IMETHODIMP |
3185 | | nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result) |
3186 | 0 | { |
3187 | 0 | JSString *text = js::GetPCCountScriptSummary(cx, script); |
3188 | 0 | if (!text) |
3189 | 0 | return NS_ERROR_FAILURE; |
3190 | 0 | |
3191 | 0 | if (!AssignJSString(cx, result, text)) |
3192 | 0 | return NS_ERROR_FAILURE; |
3193 | 0 | |
3194 | 0 | return NS_OK; |
3195 | 0 | } |
3196 | | |
3197 | | NS_IMETHODIMP |
3198 | | nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result) |
3199 | 0 | { |
3200 | 0 | JSString *text = js::GetPCCountScriptContents(cx, script); |
3201 | 0 | if (!text) |
3202 | 0 | return NS_ERROR_FAILURE; |
3203 | 0 | |
3204 | 0 | if (!AssignJSString(cx, result, text)) |
3205 | 0 | return NS_ERROR_FAILURE; |
3206 | 0 | |
3207 | 0 | return NS_OK; |
3208 | 0 | } |
3209 | | |
3210 | | NS_IMETHODIMP |
3211 | | nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed) |
3212 | 0 | { |
3213 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3214 | 0 | NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); |
3215 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
3216 | 0 | NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); |
3217 | 0 |
|
3218 | 0 | nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell(); |
3219 | 0 | NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); |
3220 | 0 |
|
3221 | 0 | *aPaintingSuppressed = presShell->IsPaintingSuppressed(); |
3222 | 0 | return NS_OK; |
3223 | 0 | } |
3224 | | |
3225 | | NS_IMETHODIMP |
3226 | | nsDOMWindowUtils::GetPlugins(JSContext* cx, JS::MutableHandle<JS::Value> aPlugins) |
3227 | 0 | { |
3228 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3229 | 0 | NS_ENSURE_STATE(doc); |
3230 | 0 |
|
3231 | 0 | nsTArray<nsIObjectLoadingContent*> plugins; |
3232 | 0 | doc->GetPlugins(plugins); |
3233 | 0 |
|
3234 | 0 | JS::Rooted<JSObject*> jsPlugins(cx); |
3235 | 0 | nsresult rv = nsTArrayToJSArray(cx, plugins, &jsPlugins); |
3236 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
3237 | 0 |
|
3238 | 0 | aPlugins.setObject(*jsPlugins); |
3239 | 0 | return NS_OK; |
3240 | 0 | } |
3241 | | |
3242 | | NS_IMETHODIMP |
3243 | | nsDOMWindowUtils::SetVisualViewportSize(float aWidth, float aHeight) |
3244 | 0 | { |
3245 | 0 | if (!(aWidth >= 0.0 && aHeight >= 0.0)) { |
3246 | 0 | return NS_ERROR_ILLEGAL_VALUE; |
3247 | 0 | } |
3248 | 0 | |
3249 | 0 | nsIPresShell* presShell = GetPresShell(); |
3250 | 0 | if (!presShell) { |
3251 | 0 | return NS_ERROR_FAILURE; |
3252 | 0 | } |
3253 | 0 | |
3254 | 0 | nsLayoutUtils::SetVisualViewportSize(presShell, CSSSize(aWidth, aHeight)); |
3255 | 0 |
|
3256 | 0 | return NS_OK; |
3257 | 0 | } |
3258 | | |
3259 | | nsresult |
3260 | | nsDOMWindowUtils::RemoteFrameFullscreenChanged(Element* aFrameElement) |
3261 | 0 | { |
3262 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3263 | 0 | NS_ENSURE_STATE(doc); |
3264 | 0 |
|
3265 | 0 | doc->RemoteFrameFullscreenChanged(aFrameElement); |
3266 | 0 | return NS_OK; |
3267 | 0 | } |
3268 | | |
3269 | | nsresult |
3270 | | nsDOMWindowUtils::RemoteFrameFullscreenReverted() |
3271 | 0 | { |
3272 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3273 | 0 | NS_ENSURE_STATE(doc); |
3274 | 0 |
|
3275 | 0 | doc->RemoteFrameFullscreenReverted(); |
3276 | 0 | return NS_OK; |
3277 | 0 | } |
3278 | | |
3279 | | static void |
3280 | | PrepareForFullscreenChange(nsIPresShell* aPresShell, const nsSize& aSize, |
3281 | | nsSize* aOldSize = nullptr) |
3282 | 0 | { |
3283 | 0 | if (!aPresShell) { |
3284 | 0 | return; |
3285 | 0 | } |
3286 | 0 | if (nsRefreshDriver* rd = aPresShell->GetRefreshDriver()) { |
3287 | 0 | rd->SetIsResizeSuppressed(); |
3288 | 0 | // Since we are suppressing the resize reflow which would originally |
3289 | 0 | // be triggered by view manager, we need to ensure that the refresh |
3290 | 0 | // driver actually schedules a flush, otherwise it may get stuck. |
3291 | 0 | rd->ScheduleViewManagerFlush(); |
3292 | 0 | } |
3293 | 0 | if (!aSize.IsEmpty()) { |
3294 | 0 | if (nsViewManager* viewManager = aPresShell->GetViewManager()) { |
3295 | 0 | if (aOldSize) { |
3296 | 0 | viewManager->GetWindowDimensions(&aOldSize->width, &aOldSize->height); |
3297 | 0 | } |
3298 | 0 | viewManager->SetWindowDimensions(aSize.width, aSize.height); |
3299 | 0 | } |
3300 | 0 | } |
3301 | 0 | } |
3302 | | |
3303 | | NS_IMETHODIMP |
3304 | | nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal) |
3305 | 0 | { |
3306 | 0 | PROFILER_ADD_MARKER("Enter fullscreen"); |
3307 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3308 | 0 | NS_ENSURE_STATE(doc); |
3309 | 0 |
|
3310 | 0 | // Notify the pres shell that we are starting fullscreen change, and |
3311 | 0 | // set the window dimensions in advance. Since the resize message |
3312 | 0 | // comes after the fullscreen change call, doing so could avoid an |
3313 | 0 | // extra resize reflow after this point. |
3314 | 0 | nsRect screenRect; |
3315 | 0 | if (nsPresContext* presContext = GetPresContext()) { |
3316 | 0 | presContext->DeviceContext()->GetRect(screenRect); |
3317 | 0 | } |
3318 | 0 | nsSize oldSize; |
3319 | 0 | PrepareForFullscreenChange(GetPresShell(), screenRect.Size(), &oldSize); |
3320 | 0 | OldWindowSize::Set(mWindow, oldSize); |
3321 | 0 |
|
3322 | 0 | *aRetVal = nsIDocument::HandlePendingFullscreenRequests(doc); |
3323 | 0 | return NS_OK; |
3324 | 0 | } |
3325 | | |
3326 | | nsresult |
3327 | | nsDOMWindowUtils::ExitFullscreen() |
3328 | 0 | { |
3329 | 0 | PROFILER_ADD_MARKER("Exit fullscreen"); |
3330 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3331 | 0 | NS_ENSURE_STATE(doc); |
3332 | 0 |
|
3333 | 0 | // Although we would not use the old size if we have already exited |
3334 | 0 | // fullscreen, we still want to cleanup in case we haven't. |
3335 | 0 | nsSize oldSize = OldWindowSize::GetAndRemove(mWindow); |
3336 | 0 | if (!doc->GetFullscreenElement()) { |
3337 | 0 | return NS_OK; |
3338 | 0 | } |
3339 | 0 | |
3340 | 0 | // Notify the pres shell that we are starting fullscreen change, and |
3341 | 0 | // set the window dimensions in advance. Since the resize message |
3342 | 0 | // comes after the fullscreen change call, doing so could avoid an |
3343 | 0 | // extra resize reflow after this point. |
3344 | 0 | PrepareForFullscreenChange(GetPresShell(), oldSize); |
3345 | 0 | nsIDocument::ExitFullscreenInDocTree(doc); |
3346 | 0 | return NS_OK; |
3347 | 0 | } |
3348 | | |
3349 | | NS_IMETHODIMP |
3350 | | nsDOMWindowUtils::SelectAtPoint(float aX, float aY, uint32_t aSelectBehavior, |
3351 | | bool *_retval) |
3352 | 0 | { |
3353 | 0 | *_retval = false; |
3354 | 0 |
|
3355 | 0 | nsSelectionAmount amount; |
3356 | 0 | switch (aSelectBehavior) { |
3357 | 0 | case nsIDOMWindowUtils::SELECT_CHARACTER: |
3358 | 0 | amount = eSelectCharacter; |
3359 | 0 | break; |
3360 | 0 | case nsIDOMWindowUtils::SELECT_CLUSTER: |
3361 | 0 | amount = eSelectCluster; |
3362 | 0 | break; |
3363 | 0 | case nsIDOMWindowUtils::SELECT_WORD: |
3364 | 0 | amount = eSelectWord; |
3365 | 0 | break; |
3366 | 0 | case nsIDOMWindowUtils::SELECT_LINE: |
3367 | 0 | amount = eSelectLine; |
3368 | 0 | break; |
3369 | 0 | case nsIDOMWindowUtils::SELECT_BEGINLINE: |
3370 | 0 | amount = eSelectBeginLine; |
3371 | 0 | break; |
3372 | 0 | case nsIDOMWindowUtils::SELECT_ENDLINE: |
3373 | 0 | amount = eSelectEndLine; |
3374 | 0 | break; |
3375 | 0 | case nsIDOMWindowUtils::SELECT_PARAGRAPH: |
3376 | 0 | amount = eSelectParagraph; |
3377 | 0 | break; |
3378 | 0 | case nsIDOMWindowUtils::SELECT_WORDNOSPACE: |
3379 | 0 | amount = eSelectWordNoSpace; |
3380 | 0 | break; |
3381 | 0 | default: |
3382 | 0 | return NS_ERROR_INVALID_ARG; |
3383 | 0 | } |
3384 | 0 | |
3385 | 0 | nsIPresShell* presShell = GetPresShell(); |
3386 | 0 | if (!presShell) { |
3387 | 0 | return NS_ERROR_UNEXPECTED; |
3388 | 0 | } |
3389 | 0 | |
3390 | 0 | // The root frame for this content window |
3391 | 0 | nsIFrame* rootFrame = presShell->GetRootFrame(); |
3392 | 0 | if (!rootFrame) { |
3393 | 0 | return NS_ERROR_UNEXPECTED; |
3394 | 0 | } |
3395 | 0 | |
3396 | 0 | // Get the target frame at the client coordinates passed to us |
3397 | 0 | nsPoint offset; |
3398 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(&offset); |
3399 | 0 | LayoutDeviceIntPoint pt = |
3400 | 0 | nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext()); |
3401 | 0 | nsPoint ptInRoot = |
3402 | 0 | nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame); |
3403 | 0 | nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot); |
3404 | 0 | // This can happen if the page hasn't loaded yet or if the point |
3405 | 0 | // is outside the frame. |
3406 | 0 | if (!targetFrame) { |
3407 | 0 | return NS_ERROR_INVALID_ARG; |
3408 | 0 | } |
3409 | 0 | |
3410 | 0 | // Convert point to coordinates relative to the target frame, which is |
3411 | 0 | // what targetFrame's SelectByTypeAtPoint expects. |
3412 | 0 | nsPoint relPoint = |
3413 | 0 | nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame); |
3414 | 0 |
|
3415 | 0 | nsresult rv = |
3416 | 0 | static_cast<nsFrame*>(targetFrame)-> |
3417 | 0 | SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount, |
3418 | 0 | nsFrame::SELECT_ACCUMULATE); |
3419 | 0 | *_retval = !NS_FAILED(rv); |
3420 | 0 | return NS_OK; |
3421 | 0 | } |
3422 | | |
3423 | | static nsIDocument::additionalSheetType |
3424 | | convertSheetType(uint32_t aSheetType) |
3425 | 0 | { |
3426 | 0 | switch(aSheetType) { |
3427 | 0 | case nsDOMWindowUtils::AGENT_SHEET: |
3428 | 0 | return nsIDocument::eAgentSheet; |
3429 | 0 | case nsDOMWindowUtils::USER_SHEET: |
3430 | 0 | return nsIDocument::eUserSheet; |
3431 | 0 | case nsDOMWindowUtils::AUTHOR_SHEET: |
3432 | 0 | return nsIDocument::eAuthorSheet; |
3433 | 0 | default: |
3434 | 0 | NS_ASSERTION(false, "wrong type"); |
3435 | 0 | // we must return something although this should never happen |
3436 | 0 | return nsIDocument::AdditionalSheetTypeCount; |
3437 | 0 | } |
3438 | 0 | } |
3439 | | |
3440 | | NS_IMETHODIMP |
3441 | | nsDOMWindowUtils::LoadSheet(nsIURI *aSheetURI, uint32_t aSheetType) |
3442 | 0 | { |
3443 | 0 | NS_ENSURE_ARG_POINTER(aSheetURI); |
3444 | 0 | NS_ENSURE_ARG(aSheetType == AGENT_SHEET || |
3445 | 0 | aSheetType == USER_SHEET || |
3446 | 0 | aSheetType == AUTHOR_SHEET); |
3447 | 0 |
|
3448 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3449 | 0 | NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); |
3450 | 0 |
|
3451 | 0 | nsIDocument::additionalSheetType type = convertSheetType(aSheetType); |
3452 | 0 |
|
3453 | 0 | return doc->LoadAdditionalStyleSheet(type, aSheetURI); |
3454 | 0 | } |
3455 | | |
3456 | | NS_IMETHODIMP |
3457 | | nsDOMWindowUtils::LoadSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType) |
3458 | 0 | { |
3459 | 0 | nsCOMPtr<nsIURI> uri; |
3460 | 0 | nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI); |
3461 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
3462 | 0 |
|
3463 | 0 | return LoadSheet(uri, aSheetType); |
3464 | 0 | } |
3465 | | |
3466 | | NS_IMETHODIMP |
3467 | | nsDOMWindowUtils::AddSheet(nsIPreloadedStyleSheet* aSheet, uint32_t aSheetType) |
3468 | 0 | { |
3469 | 0 | NS_ENSURE_ARG_POINTER(aSheet); |
3470 | 0 | NS_ENSURE_ARG(aSheetType == AGENT_SHEET || |
3471 | 0 | aSheetType == USER_SHEET || |
3472 | 0 | aSheetType == AUTHOR_SHEET); |
3473 | 0 |
|
3474 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3475 | 0 | NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); |
3476 | 0 |
|
3477 | 0 | StyleSheet* sheet = nullptr; |
3478 | 0 | auto preloadedSheet = static_cast<PreloadedStyleSheet*>(aSheet); |
3479 | 0 | nsresult rv = preloadedSheet->GetSheet(&sheet); |
3480 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
3481 | 0 | NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE); |
3482 | 0 |
|
3483 | 0 | if (sheet->GetAssociatedDocumentOrShadowRoot()) { |
3484 | 0 | return NS_ERROR_INVALID_ARG; |
3485 | 0 | } |
3486 | 0 | |
3487 | 0 | nsIDocument::additionalSheetType type = convertSheetType(aSheetType); |
3488 | 0 | return doc->AddAdditionalStyleSheet(type, sheet); |
3489 | 0 | } |
3490 | | |
3491 | | NS_IMETHODIMP |
3492 | | nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType) |
3493 | 0 | { |
3494 | 0 | NS_ENSURE_ARG_POINTER(aSheetURI); |
3495 | 0 | NS_ENSURE_ARG(aSheetType == AGENT_SHEET || |
3496 | 0 | aSheetType == USER_SHEET || |
3497 | 0 | aSheetType == AUTHOR_SHEET); |
3498 | 0 |
|
3499 | 0 | nsCOMPtr<nsIDocument> doc = GetDocument(); |
3500 | 0 | NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); |
3501 | 0 |
|
3502 | 0 | nsIDocument::additionalSheetType type = convertSheetType(aSheetType); |
3503 | 0 |
|
3504 | 0 | doc->RemoveAdditionalStyleSheet(type, aSheetURI); |
3505 | 0 | return NS_OK; |
3506 | 0 | } |
3507 | | |
3508 | | NS_IMETHODIMP |
3509 | | nsDOMWindowUtils::RemoveSheetUsingURIString(const nsACString& aSheetURI, uint32_t aSheetType) |
3510 | 0 | { |
3511 | 0 | nsCOMPtr<nsIURI> uri; |
3512 | 0 | nsresult rv = NS_NewURI(getter_AddRefs(uri), aSheetURI); |
3513 | 0 | NS_ENSURE_SUCCESS(rv, rv); |
3514 | 0 |
|
3515 | 0 | return RemoveSheet(uri, aSheetType); |
3516 | 0 | } |
3517 | | |
3518 | | NS_IMETHODIMP |
3519 | | nsDOMWindowUtils::GetIsHandlingUserInput(bool* aHandlingUserInput) |
3520 | 0 | { |
3521 | 0 | *aHandlingUserInput = EventStateManager::IsHandlingUserInput(); |
3522 | 0 |
|
3523 | 0 | return NS_OK; |
3524 | 0 | } |
3525 | | |
3526 | | NS_IMETHODIMP |
3527 | | nsDOMWindowUtils::GetMillisSinceLastUserInput(double* aMillisSinceLastUserInput) |
3528 | 0 | { |
3529 | 0 | TimeStamp lastInput = EventStateManager::LatestUserInputStart(); |
3530 | 0 | if (lastInput.IsNull()) { |
3531 | 0 | *aMillisSinceLastUserInput = -1.0f; |
3532 | 0 | return NS_OK; |
3533 | 0 | } |
3534 | 0 | |
3535 | 0 | *aMillisSinceLastUserInput = (TimeStamp::Now() - lastInput).ToMilliseconds(); |
3536 | 0 | return NS_OK; |
3537 | 0 | } |
3538 | | |
3539 | | NS_IMETHODIMP |
3540 | | nsDOMWindowUtils::AllowScriptsToClose() |
3541 | 0 | { |
3542 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3543 | 0 | NS_ENSURE_STATE(window); |
3544 | 0 | nsGlobalWindowOuter::Cast(window)->AllowScriptsToClose(); |
3545 | 0 | return NS_OK; |
3546 | 0 | } |
3547 | | |
3548 | | NS_IMETHODIMP |
3549 | | nsDOMWindowUtils::GetIsParentWindowMainWidgetVisible(bool* aIsVisible) |
3550 | 0 | { |
3551 | 0 | if (!XRE_IsParentProcess()) { |
3552 | 0 | MOZ_CRASH("IsParentWindowMainWidgetVisible is only available in the parent process"); |
3553 | 0 | } |
3554 | 0 |
|
3555 | 0 | // this should reflect the "is parent window visible" logic in |
3556 | 0 | // nsWindowWatcher::OpenWindowInternal() |
3557 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3558 | 0 | NS_ENSURE_STATE(window); |
3559 | 0 |
|
3560 | 0 | nsCOMPtr<nsIWidget> parentWidget; |
3561 | 0 | nsIDocShell *docShell = window->GetDocShell(); |
3562 | 0 | if (docShell) { |
3563 | 0 | nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner; |
3564 | 0 | docShell->GetTreeOwner(getter_AddRefs(parentTreeOwner)); |
3565 | 0 | nsCOMPtr<nsIBaseWindow> parentWindow(do_GetInterface(parentTreeOwner)); |
3566 | 0 | if (parentWindow) { |
3567 | 0 | parentWindow->GetMainWidget(getter_AddRefs(parentWidget)); |
3568 | 0 | } |
3569 | 0 | } |
3570 | 0 | if (!parentWidget) { |
3571 | 0 | return NS_ERROR_NOT_AVAILABLE; |
3572 | 0 | } |
3573 | 0 | |
3574 | 0 | *aIsVisible = parentWidget->IsVisible(); |
3575 | 0 | return NS_OK; |
3576 | 0 | } |
3577 | | |
3578 | | NS_IMETHODIMP |
3579 | | nsDOMWindowUtils::IsNodeDisabledForEvents(nsINode* aNode, bool* aRetVal) |
3580 | 0 | { |
3581 | 0 | *aRetVal = false; |
3582 | 0 | nsINode* node = aNode; |
3583 | 0 | while (node) { |
3584 | 0 | if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) { |
3585 | 0 | nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node); |
3586 | 0 | if (fc && fc->IsDisabledForEvents(eVoidEvent)) { |
3587 | 0 | *aRetVal = true; |
3588 | 0 | break; |
3589 | 0 | } |
3590 | 0 | } |
3591 | 0 | node = node->GetParentNode(); |
3592 | 0 | } |
3593 | 0 |
|
3594 | 0 | return NS_OK; |
3595 | 0 | } |
3596 | | |
3597 | | NS_IMETHODIMP |
3598 | | nsDOMWindowUtils::SetPaintFlashing(bool aPaintFlashing) |
3599 | 0 | { |
3600 | 0 | nsPresContext* presContext = GetPresContext(); |
3601 | 0 | if (presContext) { |
3602 | 0 | presContext->SetPaintFlashing(aPaintFlashing); |
3603 | 0 | // Clear paint flashing colors |
3604 | 0 | nsIPresShell* presShell = GetPresShell(); |
3605 | 0 | if (!aPaintFlashing && presShell) { |
3606 | 0 | nsIFrame* rootFrame = presShell->GetRootFrame(); |
3607 | 0 | if (rootFrame) { |
3608 | 0 | rootFrame->InvalidateFrameSubtree(); |
3609 | 0 | } |
3610 | 0 | } |
3611 | 0 | } |
3612 | 0 | return NS_OK; |
3613 | 0 | } |
3614 | | |
3615 | | NS_IMETHODIMP |
3616 | | nsDOMWindowUtils::GetPaintFlashing(bool* aRetVal) |
3617 | 0 | { |
3618 | 0 | *aRetVal = false; |
3619 | 0 | nsPresContext* presContext = GetPresContext(); |
3620 | 0 | if (presContext) { |
3621 | 0 | *aRetVal = presContext->GetPaintFlashing(); |
3622 | 0 | } |
3623 | 0 | return NS_OK; |
3624 | 0 | } |
3625 | | |
3626 | | NS_IMETHODIMP |
3627 | | nsDOMWindowUtils::DispatchEventToChromeOnly(EventTarget* aTarget, |
3628 | | Event* aEvent, |
3629 | | bool* aRetVal) |
3630 | 0 | { |
3631 | 0 | *aRetVal = false; |
3632 | 0 | NS_ENSURE_STATE(aTarget && aEvent); |
3633 | 0 | aEvent->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true; |
3634 | 0 | *aRetVal = aTarget-> |
3635 | 0 | DispatchEvent(*aEvent, CallerType::System, IgnoreErrors()); |
3636 | 0 | return NS_OK; |
3637 | 0 | } |
3638 | | |
3639 | | static Result<nsIFrame*, nsresult> |
3640 | | GetTargetFrame(const Element* aElement, const nsAString& aPseudoElement) |
3641 | 0 | { |
3642 | 0 | nsIFrame* frame = aElement->GetPrimaryFrame(); |
3643 | 0 | if (!aPseudoElement.IsEmpty()) { |
3644 | 0 | if (aPseudoElement.EqualsLiteral("::before")) { |
3645 | 0 | frame = nsLayoutUtils::GetBeforeFrame(aElement); |
3646 | 0 | } else if (aPseudoElement.EqualsLiteral("::after")) { |
3647 | 0 | frame = nsLayoutUtils::GetAfterFrame(aElement); |
3648 | 0 | } else { |
3649 | 0 | return Err(NS_ERROR_INVALID_ARG); |
3650 | 0 | } |
3651 | 0 | } |
3652 | 0 | return frame; |
3653 | 0 | } |
3654 | | |
3655 | | static OMTAValue |
3656 | | GetOMTAValue(nsIFrame* aFrame, |
3657 | | DisplayItemType aDisplayItemKey, |
3658 | | WebRenderBridgeChild* aWebRenderBridgeChild) |
3659 | 0 | { |
3660 | 0 | OMTAValue value = mozilla::null_t(); |
3661 | 0 |
|
3662 | 0 | Layer* layer = |
3663 | 0 | FrameLayerBuilder::GetDedicatedLayer(aFrame, aDisplayItemKey); |
3664 | 0 | if (layer) { |
3665 | 0 | ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder(); |
3666 | 0 | if (forwarder && forwarder->HasShadowManager()) { |
3667 | 0 | forwarder->GetShadowManager()-> |
3668 | 0 | SendGetAnimationValue(layer->GetCompositorAnimationsId(), &value); |
3669 | 0 | } |
3670 | 0 | } else if (aWebRenderBridgeChild) { |
3671 | 0 | RefPtr<WebRenderAnimationData> animationData = |
3672 | 0 | GetWebRenderUserData<WebRenderAnimationData>(aFrame, |
3673 | 0 | (uint32_t)aDisplayItemKey); |
3674 | 0 | if (animationData) { |
3675 | 0 | aWebRenderBridgeChild->SendGetAnimationValue( |
3676 | 0 | animationData->GetAnimationInfo().GetCompositorAnimationsId(), |
3677 | 0 | &value); |
3678 | 0 | } |
3679 | 0 | } |
3680 | 0 | return value; |
3681 | 0 | } |
3682 | | |
3683 | | NS_IMETHODIMP |
3684 | | nsDOMWindowUtils::GetOMTAStyle(Element* aElement, |
3685 | | const nsAString& aProperty, |
3686 | | const nsAString& aPseudoElement, |
3687 | | nsAString& aResult) |
3688 | 0 | { |
3689 | 0 | if (!aElement) { |
3690 | 0 | return NS_ERROR_INVALID_ARG; |
3691 | 0 | } |
3692 | 0 | |
3693 | 0 | auto frameOrError = GetTargetFrame(aElement, aPseudoElement); |
3694 | 0 | if (frameOrError.isErr()) { |
3695 | 0 | return frameOrError.unwrapErr(); |
3696 | 0 | } |
3697 | 0 | nsIFrame* frame = frameOrError.unwrap(); |
3698 | 0 |
|
3699 | 0 | RefPtr<nsROCSSPrimitiveValue> cssValue = nullptr; |
3700 | 0 | if (frame && nsLayoutUtils::AreAsyncAnimationsEnabled()) { |
3701 | 0 | RefPtr<LayerManager> widgetLayerManager; |
3702 | 0 | if (nsIWidget* widget = GetWidget()) { |
3703 | 0 | widgetLayerManager = widget->GetLayerManager(); |
3704 | 0 | } |
3705 | 0 |
|
3706 | 0 | if (aProperty.EqualsLiteral("opacity")) { |
3707 | 0 | OMTAValue value = GetOMTAValue(frame, |
3708 | 0 | DisplayItemType::TYPE_OPACITY, |
3709 | 0 | GetWebRenderBridge()); |
3710 | 0 | if (value.type() == OMTAValue::Tfloat) { |
3711 | 0 | cssValue = new nsROCSSPrimitiveValue; |
3712 | 0 | cssValue->SetNumber(value.get_float()); |
3713 | 0 | } |
3714 | 0 | } else if (aProperty.EqualsLiteral("transform")) { |
3715 | 0 | OMTAValue value = GetOMTAValue(frame, |
3716 | 0 | DisplayItemType::TYPE_TRANSFORM, |
3717 | 0 | GetWebRenderBridge()); |
3718 | 0 | if (value.type() == OMTAValue::TMatrix4x4) { |
3719 | 0 | cssValue = nsComputedDOMStyle::MatrixToCSSValue(value.get_Matrix4x4()); |
3720 | 0 | } |
3721 | 0 | } |
3722 | 0 | } |
3723 | 0 |
|
3724 | 0 | if (cssValue) { |
3725 | 0 | nsString text; |
3726 | 0 | ErrorResult rv; |
3727 | 0 | cssValue->GetCssText(text, rv); |
3728 | 0 | aResult.Assign(text); |
3729 | 0 | return rv.StealNSResult(); |
3730 | 0 | } |
3731 | 0 | aResult.Truncate(); |
3732 | 0 | return NS_OK; |
3733 | 0 | } |
3734 | | |
3735 | | NS_IMETHODIMP |
3736 | | nsDOMWindowUtils::GetOMTCTransform(Element* aElement, |
3737 | | const nsAString& aPseudoElement, |
3738 | | nsAString& aResult) |
3739 | 0 | { |
3740 | 0 | if (!aElement) { |
3741 | 0 | return NS_ERROR_INVALID_ARG; |
3742 | 0 | } |
3743 | 0 | |
3744 | 0 | if (GetWebRenderBridge()) { |
3745 | 0 | return NS_ERROR_NOT_IMPLEMENTED; |
3746 | 0 | } |
3747 | 0 | |
3748 | 0 | auto frameOrError = GetTargetFrame(aElement, aPseudoElement); |
3749 | 0 | if (frameOrError.isErr()) { |
3750 | 0 | return frameOrError.unwrapErr(); |
3751 | 0 | } |
3752 | 0 | |
3753 | 0 | nsIFrame* frame = frameOrError.unwrap(); |
3754 | 0 | aResult.Truncate(); |
3755 | 0 | if (!frame) { |
3756 | 0 | return NS_OK; |
3757 | 0 | } |
3758 | 0 | |
3759 | 0 | DisplayItemType itemType = DisplayItemType::TYPE_TRANSFORM; |
3760 | 0 | if (nsLayoutUtils::HasEffectiveAnimation(frame, eCSSProperty_opacity) && |
3761 | 0 | !frame->IsTransformed()) { |
3762 | 0 | itemType = DisplayItemType::TYPE_OPACITY; |
3763 | 0 | } |
3764 | 0 |
|
3765 | 0 | Layer* layer = FrameLayerBuilder::GetDedicatedLayer(frame, itemType); |
3766 | 0 | if (!layer) { |
3767 | 0 | return NS_OK; |
3768 | 0 | } |
3769 | 0 | |
3770 | 0 | ShadowLayerForwarder* forwarder = layer->Manager()->AsShadowForwarder(); |
3771 | 0 | if (!forwarder || !forwarder->HasShadowManager()) { |
3772 | 0 | return NS_OK; |
3773 | 0 | } |
3774 | 0 | |
3775 | 0 | MaybeTransform transform; |
3776 | 0 | forwarder->GetShadowManager()-> |
3777 | 0 | SendGetTransform(layer->AsShadowableLayer()->GetShadow(), &transform); |
3778 | 0 | if (transform.type() != MaybeTransform::TMatrix4x4) { |
3779 | 0 | return NS_OK; |
3780 | 0 | } |
3781 | 0 | |
3782 | 0 | Matrix4x4 matrix = transform.get_Matrix4x4(); |
3783 | 0 | RefPtr<nsROCSSPrimitiveValue> cssValue = |
3784 | 0 | nsComputedDOMStyle::MatrixToCSSValue(matrix); |
3785 | 0 | if (!cssValue) { |
3786 | 0 | return NS_OK; |
3787 | 0 | } |
3788 | 0 | |
3789 | 0 | nsAutoString text; |
3790 | 0 | ErrorResult rv; |
3791 | 0 | cssValue->GetCssText(text, rv); |
3792 | 0 | aResult.Assign(text); |
3793 | 0 | return rv.StealNSResult(); |
3794 | 0 | } |
3795 | | |
3796 | | NS_IMETHODIMP |
3797 | | nsDOMWindowUtils::IsAnimationInPendingTracker(dom::Animation* aAnimation, |
3798 | | bool* aRetVal) |
3799 | 0 | { |
3800 | 0 | MOZ_ASSERT(aRetVal); |
3801 | 0 |
|
3802 | 0 | if (!aAnimation) { |
3803 | 0 | return NS_ERROR_INVALID_ARG; |
3804 | 0 | } |
3805 | 0 | |
3806 | 0 | nsIDocument* doc = GetDocument(); |
3807 | 0 | if (!doc) { |
3808 | 0 | *aRetVal = false; |
3809 | 0 | return NS_OK; |
3810 | 0 | } |
3811 | 0 | |
3812 | 0 | PendingAnimationTracker* tracker = doc->GetPendingAnimationTracker(); |
3813 | 0 | if (!tracker) { |
3814 | 0 | *aRetVal = false; |
3815 | 0 | return NS_OK; |
3816 | 0 | } |
3817 | 0 | |
3818 | 0 | *aRetVal = tracker->IsWaitingToPlay(*aAnimation) || |
3819 | 0 | tracker->IsWaitingToPause(*aAnimation); |
3820 | 0 | return NS_OK; |
3821 | 0 | } |
3822 | | |
3823 | | namespace { |
3824 | | |
3825 | | class HandlingUserInputHelper final : public nsIJSRAIIHelper |
3826 | | { |
3827 | | public: |
3828 | | explicit HandlingUserInputHelper(bool aHandlingUserInput); |
3829 | | |
3830 | | NS_DECL_ISUPPORTS |
3831 | | NS_DECL_NSIJSRAIIHELPER |
3832 | | |
3833 | | private: |
3834 | | ~HandlingUserInputHelper(); |
3835 | | |
3836 | | bool mHandlingUserInput; |
3837 | | bool mDestructCalled; |
3838 | | }; |
3839 | | |
3840 | | NS_IMPL_ISUPPORTS(HandlingUserInputHelper, nsIJSRAIIHelper) |
3841 | | |
3842 | | HandlingUserInputHelper::HandlingUserInputHelper(bool aHandlingUserInput) |
3843 | | : mHandlingUserInput(aHandlingUserInput), |
3844 | | mDestructCalled(false) |
3845 | 0 | { |
3846 | 0 | if (aHandlingUserInput) { |
3847 | 0 | EventStateManager::StartHandlingUserInput(eVoidEvent); |
3848 | 0 | } |
3849 | 0 | } |
3850 | | |
3851 | | HandlingUserInputHelper::~HandlingUserInputHelper() |
3852 | 0 | { |
3853 | 0 | // We assert, but just in case, make sure we notify the ESM. |
3854 | 0 | MOZ_ASSERT(mDestructCalled); |
3855 | 0 | if (!mDestructCalled) { |
3856 | 0 | Destruct(); |
3857 | 0 | } |
3858 | 0 | } |
3859 | | |
3860 | | NS_IMETHODIMP |
3861 | | HandlingUserInputHelper::Destruct() |
3862 | 0 | { |
3863 | 0 | if (NS_WARN_IF(mDestructCalled)) { |
3864 | 0 | return NS_ERROR_FAILURE; |
3865 | 0 | } |
3866 | 0 | |
3867 | 0 | mDestructCalled = true; |
3868 | 0 | if (mHandlingUserInput) { |
3869 | 0 | EventStateManager::StopHandlingUserInput(eVoidEvent); |
3870 | 0 | } |
3871 | 0 |
|
3872 | 0 | return NS_OK; |
3873 | 0 | } |
3874 | | |
3875 | | } // unnamed namespace |
3876 | | |
3877 | | NS_IMETHODIMP |
3878 | | nsDOMWindowUtils::SetHandlingUserInput(bool aHandlingUserInput, |
3879 | | nsIJSRAIIHelper** aHelper) |
3880 | 0 | { |
3881 | 0 | RefPtr<HandlingUserInputHelper> helper( |
3882 | 0 | new HandlingUserInputHelper(aHandlingUserInput)); |
3883 | 0 | helper.forget(aHelper); |
3884 | 0 | return NS_OK; |
3885 | 0 | } |
3886 | | |
3887 | | NS_IMETHODIMP |
3888 | | nsDOMWindowUtils::GetContentAPZTestData(JSContext* aContext, |
3889 | | JS::MutableHandleValue aOutContentTestData) |
3890 | 0 | { |
3891 | 0 | if (nsIWidget* widget = GetWidget()) { |
3892 | 0 | RefPtr<LayerManager> lm = widget->GetLayerManager(); |
3893 | 0 | if (!lm) { |
3894 | 0 | return NS_OK; |
3895 | 0 | } |
3896 | 0 | if (ClientLayerManager* clm = lm->AsClientLayerManager()) { |
3897 | 0 | if (!clm->GetAPZTestData().ToJS(aOutContentTestData, aContext)) { |
3898 | 0 | return NS_ERROR_FAILURE; |
3899 | 0 | } |
3900 | 0 | } else if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) { |
3901 | 0 | if (!wrlm->GetAPZTestData().ToJS(aOutContentTestData, aContext)) { |
3902 | 0 | return NS_ERROR_FAILURE; |
3903 | 0 | } |
3904 | 0 | } |
3905 | 0 | } |
3906 | 0 | |
3907 | 0 | return NS_OK; |
3908 | 0 | } |
3909 | | |
3910 | | NS_IMETHODIMP |
3911 | | nsDOMWindowUtils::GetCompositorAPZTestData(JSContext* aContext, |
3912 | | JS::MutableHandleValue aOutCompositorTestData) |
3913 | 0 | { |
3914 | 0 | if (nsIWidget* widget = GetWidget()) { |
3915 | 0 | RefPtr<LayerManager> lm = widget->GetLayerManager(); |
3916 | 0 | if (!lm) { |
3917 | 0 | return NS_OK; |
3918 | 0 | } |
3919 | 0 | APZTestData compositorSideData; |
3920 | 0 | if (ClientLayerManager* clm = lm->AsClientLayerManager()) { |
3921 | 0 | clm->GetCompositorSideAPZTestData(&compositorSideData); |
3922 | 0 | } else if (WebRenderLayerManager* wrlm = lm->AsWebRenderLayerManager()) { |
3923 | 0 | if (!wrlm->WrBridge()) { |
3924 | 0 | return NS_ERROR_UNEXPECTED; |
3925 | 0 | } |
3926 | 0 | if (!wrlm->WrBridge()->SendGetAPZTestData(&compositorSideData)) { |
3927 | 0 | return NS_ERROR_FAILURE; |
3928 | 0 | } |
3929 | 0 | } |
3930 | 0 | if (!compositorSideData.ToJS(aOutCompositorTestData, aContext)) { |
3931 | 0 | return NS_ERROR_FAILURE; |
3932 | 0 | } |
3933 | 0 | } |
3934 | 0 | |
3935 | 0 | return NS_OK; |
3936 | 0 | } |
3937 | | |
3938 | | NS_IMETHODIMP |
3939 | | nsDOMWindowUtils::PostRestyleSelfEvent(Element* aElement) |
3940 | 0 | { |
3941 | 0 | if (!aElement) { |
3942 | 0 | return NS_ERROR_INVALID_ARG; |
3943 | 0 | } |
3944 | 0 | |
3945 | 0 | nsLayoutUtils::PostRestyleEvent(aElement, eRestyle_Self, nsChangeHint(0)); |
3946 | 0 | return NS_OK; |
3947 | 0 | } |
3948 | | |
3949 | | NS_IMETHODIMP |
3950 | | nsDOMWindowUtils::GetMediaSuspend(uint32_t* aSuspend) |
3951 | 0 | { |
3952 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3953 | 0 | NS_ENSURE_STATE(window); |
3954 | 0 |
|
3955 | 0 | *aSuspend = window->GetMediaSuspend(); |
3956 | 0 | return NS_OK; |
3957 | 0 | } |
3958 | | |
3959 | | NS_IMETHODIMP |
3960 | | nsDOMWindowUtils::SetMediaSuspend(uint32_t aSuspend) |
3961 | 0 | { |
3962 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3963 | 0 | NS_ENSURE_STATE(window); |
3964 | 0 |
|
3965 | 0 | window->SetMediaSuspend(aSuspend); |
3966 | 0 | return NS_OK; |
3967 | 0 | } |
3968 | | |
3969 | | NS_IMETHODIMP |
3970 | | nsDOMWindowUtils::GetAudioMuted(bool* aMuted) |
3971 | 0 | { |
3972 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3973 | 0 | NS_ENSURE_STATE(window); |
3974 | 0 |
|
3975 | 0 | *aMuted = window->GetAudioMuted(); |
3976 | 0 | return NS_OK; |
3977 | 0 | } |
3978 | | |
3979 | | NS_IMETHODIMP |
3980 | | nsDOMWindowUtils::SetAudioMuted(bool aMuted) |
3981 | 0 | { |
3982 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3983 | 0 | NS_ENSURE_STATE(window); |
3984 | 0 |
|
3985 | 0 | window->SetAudioMuted(aMuted); |
3986 | 0 | return NS_OK; |
3987 | 0 | } |
3988 | | |
3989 | | NS_IMETHODIMP |
3990 | | nsDOMWindowUtils::GetAudioVolume(float* aVolume) |
3991 | 0 | { |
3992 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
3993 | 0 | NS_ENSURE_STATE(window); |
3994 | 0 |
|
3995 | 0 | *aVolume = window->GetAudioVolume(); |
3996 | 0 | return NS_OK; |
3997 | 0 | } |
3998 | | |
3999 | | NS_IMETHODIMP |
4000 | | nsDOMWindowUtils::SetAudioVolume(float aVolume) |
4001 | 0 | { |
4002 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
4003 | 0 | NS_ENSURE_STATE(window); |
4004 | 0 |
|
4005 | 0 | return window->SetAudioVolume(aVolume); |
4006 | 0 | } |
4007 | | |
4008 | | NS_IMETHODIMP |
4009 | | nsDOMWindowUtils::SetChromeMargin(int32_t aTop, |
4010 | | int32_t aRight, |
4011 | | int32_t aBottom, |
4012 | | int32_t aLeft) |
4013 | 0 | { |
4014 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
4015 | 0 | if (window) { |
4016 | 0 | nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(window->GetDocShell()); |
4017 | 0 | if (baseWindow) { |
4018 | 0 | nsCOMPtr<nsIWidget> widget; |
4019 | 0 | baseWindow->GetMainWidget(getter_AddRefs(widget)); |
4020 | 0 | if (widget) { |
4021 | 0 | LayoutDeviceIntMargin margins(aTop, aRight, aBottom, aLeft); |
4022 | 0 | return widget->SetNonClientMargins(margins); |
4023 | 0 | } |
4024 | 0 | } |
4025 | 0 | } |
4026 | 0 | |
4027 | 0 | return NS_OK; |
4028 | 0 | } |
4029 | | |
4030 | | NS_IMETHODIMP |
4031 | | nsDOMWindowUtils::GetFrameUniformityTestData(JSContext* aContext, |
4032 | | JS::MutableHandleValue aOutFrameUniformity) |
4033 | 0 | { |
4034 | 0 | nsIWidget* widget = GetWidget(); |
4035 | 0 | if (!widget) { |
4036 | 0 | return NS_ERROR_NOT_AVAILABLE; |
4037 | 0 | } |
4038 | 0 | |
4039 | 0 | RefPtr<LayerManager> manager = widget->GetLayerManager(); |
4040 | 0 | if (!manager) { |
4041 | 0 | return NS_ERROR_NOT_AVAILABLE; |
4042 | 0 | } |
4043 | 0 | |
4044 | 0 | FrameUniformityData outData; |
4045 | 0 | manager->GetFrameUniformity(&outData); |
4046 | 0 | outData.ToJS(aOutFrameUniformity, aContext); |
4047 | 0 | return NS_OK; |
4048 | 0 | } |
4049 | | |
4050 | | NS_IMETHODIMP |
4051 | | nsDOMWindowUtils::XpconnectArgument(nsIDOMWindowUtils* aThis) |
4052 | 0 | { |
4053 | 0 | // Do nothing. |
4054 | 0 | return NS_OK; |
4055 | 0 | } |
4056 | | |
4057 | | NS_IMETHODIMP |
4058 | | nsDOMWindowUtils::AskPermission(nsIContentPermissionRequest* aRequest) |
4059 | 0 | { |
4060 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
4061 | 0 | return nsContentPermissionUtils::AskPermission(aRequest, window->GetCurrentInnerWindow()); |
4062 | 0 | } |
4063 | | |
4064 | | NS_IMETHODIMP |
4065 | | nsDOMWindowUtils::GetRestyleGeneration(uint64_t* aResult) |
4066 | 0 | { |
4067 | 0 | nsPresContext* presContext = GetPresContext(); |
4068 | 0 | if (!presContext) { |
4069 | 0 | return NS_ERROR_NOT_AVAILABLE; |
4070 | 0 | } |
4071 | 0 | |
4072 | 0 | *aResult = presContext->GetRestyleGeneration(); |
4073 | 0 | return NS_OK; |
4074 | 0 | } |
4075 | | |
4076 | | NS_IMETHODIMP |
4077 | | nsDOMWindowUtils::GetFramesConstructed(uint64_t* aResult) |
4078 | 0 | { |
4079 | 0 | nsPresContext* presContext = GetPresContext(); |
4080 | 0 | if (!presContext) { |
4081 | 0 | return NS_ERROR_NOT_AVAILABLE; |
4082 | 0 | } |
4083 | 0 | |
4084 | 0 | *aResult = presContext->FramesConstructedCount(); |
4085 | 0 | return NS_OK; |
4086 | 0 | } |
4087 | | |
4088 | | NS_IMETHODIMP |
4089 | | nsDOMWindowUtils::GetFramesReflowed(uint64_t* aResult) |
4090 | 0 | { |
4091 | 0 | nsPresContext* presContext = GetPresContext(); |
4092 | 0 | if (!presContext) { |
4093 | 0 | return NS_ERROR_NOT_AVAILABLE; |
4094 | 0 | } |
4095 | 0 | |
4096 | 0 | *aResult = presContext->FramesReflowedCount(); |
4097 | 0 | return NS_OK; |
4098 | 0 | } |
4099 | | |
4100 | | NS_IMETHODIMP |
4101 | | nsDOMWindowUtils::SetServiceWorkersTestingEnabled(bool aEnabled) |
4102 | 0 | { |
4103 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
4104 | 0 | NS_ENSURE_STATE(window); |
4105 | 0 |
|
4106 | 0 | window->SetServiceWorkersTestingEnabled(aEnabled); |
4107 | 0 |
|
4108 | 0 | return NS_OK; |
4109 | 0 | } |
4110 | | |
4111 | | NS_IMETHODIMP |
4112 | | nsDOMWindowUtils::GetServiceWorkersTestingEnabled(bool *aEnabled) |
4113 | 0 | { |
4114 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
4115 | 0 | NS_ENSURE_STATE(window); |
4116 | 0 |
|
4117 | 0 | *aEnabled = window->GetServiceWorkersTestingEnabled(); |
4118 | 0 |
|
4119 | 0 | return NS_OK; |
4120 | 0 | } |
4121 | | |
4122 | | NS_IMETHODIMP |
4123 | | nsDOMWindowUtils::EnterChaosMode() |
4124 | 0 | { |
4125 | 0 | ChaosMode::enterChaosMode(); |
4126 | 0 | return NS_OK; |
4127 | 0 | } |
4128 | | |
4129 | | NS_IMETHODIMP |
4130 | | nsDOMWindowUtils::LeaveChaosMode() |
4131 | 0 | { |
4132 | 0 | ChaosMode::leaveChaosMode(); |
4133 | 0 | return NS_OK; |
4134 | 0 | } |
4135 | | |
4136 | | NS_IMETHODIMP |
4137 | | nsDOMWindowUtils::TriggerDeviceReset() |
4138 | 0 | { |
4139 | 0 | ContentChild* cc = ContentChild::GetSingleton(); |
4140 | 0 | if (cc) { |
4141 | 0 | cc->SendDeviceReset(); |
4142 | 0 | return NS_OK; |
4143 | 0 | } |
4144 | 0 | |
4145 | 0 | GPUProcessManager* pm = GPUProcessManager::Get(); |
4146 | 0 | if (pm) { |
4147 | 0 | pm->SimulateDeviceReset(); |
4148 | 0 | } |
4149 | 0 | return NS_OK; |
4150 | 0 | } |
4151 | | |
4152 | | NS_IMETHODIMP |
4153 | | nsDOMWindowUtils::ForceUseCounterFlush(nsINode *aNode) |
4154 | 0 | { |
4155 | 0 | NS_ENSURE_ARG_POINTER(aNode); |
4156 | 0 |
|
4157 | 0 | if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode)) { |
4158 | 0 | mozilla::css::ImageLoader* loader = doc->StyleImageLoader(); |
4159 | 0 | loader->FlushUseCounters(); |
4160 | 0 |
|
4161 | 0 | // Flush the document and any external documents that it depends on. |
4162 | 0 | const auto reportKind |
4163 | 0 | = nsDocument::UseCounterReportKind::eIncludeExternalResources; |
4164 | 0 | static_cast<nsDocument*>(doc.get())->ReportUseCounters(reportKind); |
4165 | 0 | return NS_OK; |
4166 | 0 | } |
4167 | 0 | |
4168 | 0 | if (nsCOMPtr<nsIContent> content = do_QueryInterface(aNode)) { |
4169 | 0 | if (HTMLImageElement* img = HTMLImageElement::FromNode(content)) { |
4170 | 0 | img->FlushUseCounters(); |
4171 | 0 | return NS_OK; |
4172 | 0 | } |
4173 | 0 | } |
4174 | 0 | |
4175 | 0 | return NS_OK; |
4176 | 0 | } |
4177 | | |
4178 | | NS_IMETHODIMP |
4179 | | nsDOMWindowUtils::HasRuleProcessorUsedByMultipleStyleSets(uint32_t aSheetType, |
4180 | | bool* aRetVal) |
4181 | 0 | { |
4182 | 0 | nsIPresShell* presShell = GetPresShell(); |
4183 | 0 | if (!presShell) { |
4184 | 0 | return NS_ERROR_FAILURE; |
4185 | 0 | } |
4186 | 0 | |
4187 | 0 | return presShell->HasRuleProcessorUsedByMultipleStyleSets(aSheetType, |
4188 | 0 | aRetVal); |
4189 | 0 | } |
4190 | | |
4191 | | NS_IMETHODIMP |
4192 | | nsDOMWindowUtils::RespectDisplayPortSuppression(bool aEnabled) |
4193 | 0 | { |
4194 | 0 | nsCOMPtr<nsIPresShell> shell(GetPresShell()); |
4195 | 0 | shell->RespectDisplayportSuppression(aEnabled); |
4196 | 0 | return NS_OK; |
4197 | 0 | } |
4198 | | |
4199 | | NS_IMETHODIMP |
4200 | | nsDOMWindowUtils::ForceReflowInterrupt() |
4201 | 0 | { |
4202 | 0 | nsPresContext* pc = GetPresContext(); |
4203 | 0 | if (!pc) { |
4204 | 0 | return NS_ERROR_NOT_AVAILABLE; |
4205 | 0 | } |
4206 | 0 | pc->SetPendingInterruptFromTest(); |
4207 | 0 | return NS_OK; |
4208 | 0 | } |
4209 | | |
4210 | | NS_IMETHODIMP |
4211 | | nsDOMWindowUtils::TerminateGPUProcess() |
4212 | 0 | { |
4213 | 0 | GPUProcessManager* pm = GPUProcessManager::Get(); |
4214 | 0 | if (pm) { |
4215 | 0 | pm->KillProcess(); |
4216 | 0 | } |
4217 | 0 | return NS_OK; |
4218 | 0 | } |
4219 | | |
4220 | | NS_IMETHODIMP |
4221 | | nsDOMWindowUtils::GetGpuProcessPid(int32_t* aPid) |
4222 | 0 | { |
4223 | 0 | GPUProcessManager* pm = GPUProcessManager::Get(); |
4224 | 0 | if (pm) { |
4225 | 0 | *aPid = pm->GPUProcessPid(); |
4226 | 0 | } else { |
4227 | 0 | *aPid = -1; |
4228 | 0 | } |
4229 | 0 |
|
4230 | 0 | return NS_OK; |
4231 | 0 | } |
4232 | | |
4233 | | NS_IMETHODIMP |
4234 | | nsDOMWindowUtils::IsTimeoutTracking(uint32_t aTimeoutId, bool* aResult) |
4235 | 0 | { |
4236 | 0 | NS_ENSURE_ARG_POINTER(aResult); |
4237 | 0 | *aResult = false; |
4238 | 0 |
|
4239 | 0 | nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow); |
4240 | 0 | NS_ENSURE_STATE(window); |
4241 | 0 | nsCOMPtr<nsPIDOMWindowInner> innerWindow = window->GetCurrentInnerWindow(); |
4242 | 0 | NS_ENSURE_STATE(innerWindow); |
4243 | 0 |
|
4244 | 0 | *aResult = innerWindow->TimeoutManager().IsTimeoutTracking(aTimeoutId); |
4245 | 0 | return NS_OK; |
4246 | 0 | } |
4247 | | |
4248 | | struct StateTableEntry |
4249 | | { |
4250 | | const char* mStateString; |
4251 | | EventStates mState; |
4252 | | }; |
4253 | | |
4254 | | static constexpr StateTableEntry kManuallyManagedStates[] = { |
4255 | | { "-moz-autofill", NS_EVENT_STATE_AUTOFILL }, |
4256 | | { "-moz-autofill-preview", NS_EVENT_STATE_AUTOFILL_PREVIEW }, |
4257 | | { nullptr, EventStates() }, |
4258 | | }; |
4259 | | |
4260 | | static_assert(!kManuallyManagedStates[ArrayLength(kManuallyManagedStates) - 1] |
4261 | | .mStateString, |
4262 | | "last kManuallyManagedStates entry must be a sentinel with " |
4263 | | "mStateString == nullptr"); |
4264 | | |
4265 | | static EventStates |
4266 | | GetEventStateForString(const nsAString& aStateString) |
4267 | 0 | { |
4268 | 0 | for (const StateTableEntry* entry = kManuallyManagedStates; |
4269 | 0 | entry->mStateString; ++entry) { |
4270 | 0 | if (aStateString.EqualsASCII(entry->mStateString)) { |
4271 | 0 | return entry->mState; |
4272 | 0 | } |
4273 | 0 | } |
4274 | 0 | return EventStates(); |
4275 | 0 | } |
4276 | | |
4277 | | NS_IMETHODIMP |
4278 | | nsDOMWindowUtils::AddManuallyManagedState(Element* aElement, |
4279 | | const nsAString& aStateString) |
4280 | 0 | { |
4281 | 0 | if (!aElement) { |
4282 | 0 | return NS_ERROR_INVALID_ARG; |
4283 | 0 | } |
4284 | 0 | |
4285 | 0 | EventStates state = GetEventStateForString(aStateString); |
4286 | 0 | if (state.IsEmpty()) { |
4287 | 0 | return NS_ERROR_INVALID_ARG; |
4288 | 0 | } |
4289 | 0 | |
4290 | 0 | aElement->AddManuallyManagedStates(state); |
4291 | 0 | return NS_OK; |
4292 | 0 | } |
4293 | | |
4294 | | NS_IMETHODIMP |
4295 | | nsDOMWindowUtils::RemoveManuallyManagedState(Element* aElement, |
4296 | | const nsAString& aStateString) |
4297 | 0 | { |
4298 | 0 | if (!aElement) { |
4299 | 0 | return NS_ERROR_INVALID_ARG; |
4300 | 0 | } |
4301 | 0 | |
4302 | 0 | EventStates state = GetEventStateForString(aStateString); |
4303 | 0 | if (state.IsEmpty()) { |
4304 | 0 | return NS_ERROR_INVALID_ARG; |
4305 | 0 | } |
4306 | 0 | |
4307 | 0 | aElement->RemoveManuallyManagedStates(state); |
4308 | 0 | return NS_OK; |
4309 | 0 | } |
4310 | | |
4311 | | NS_IMETHODIMP |
4312 | | nsDOMWindowUtils::GetStorageUsage(Storage* aStorage, int64_t* aRetval) |
4313 | 0 | { |
4314 | 0 | if (!aStorage) { |
4315 | 0 | return NS_ERROR_UNEXPECTED; |
4316 | 0 | } |
4317 | 0 | |
4318 | 0 | *aRetval = aStorage->GetOriginQuotaUsage(); |
4319 | 0 |
|
4320 | 0 | return NS_OK; |
4321 | 0 | } |
4322 | | |
4323 | | NS_IMETHODIMP |
4324 | | nsDOMWindowUtils::GetDirectionFromText(const nsAString& aString, int32_t* aRetval) |
4325 | 0 | { |
4326 | 0 | Directionality dir = ::GetDirectionFromText(aString.BeginReading(), aString.Length(), nullptr); |
4327 | 0 | switch (dir) { |
4328 | 0 | case eDir_NotSet: |
4329 | 0 | *aRetval = nsIDOMWindowUtils::DIRECTION_NOT_SET; |
4330 | 0 | break; |
4331 | 0 | case eDir_RTL: |
4332 | 0 | *aRetval = nsIDOMWindowUtils::DIRECTION_RTL; |
4333 | 0 | break; |
4334 | 0 | case eDir_LTR: |
4335 | 0 | *aRetval = nsIDOMWindowUtils::DIRECTION_LTR; |
4336 | 0 | break; |
4337 | 0 | case eDir_Auto: |
4338 | 0 | MOZ_ASSERT_UNREACHABLE("GetDirectionFromText should never return this value"); |
4339 | 0 | return NS_ERROR_FAILURE; |
4340 | 0 | } |
4341 | 0 | return NS_OK; |
4342 | 0 | } |
4343 | | |
4344 | | NS_IMETHODIMP |
4345 | | nsDOMWindowUtils::EnsureDirtyRootFrame() |
4346 | 0 | { |
4347 | 0 | nsIDocument* doc = GetDocument(); |
4348 | 0 | nsIPresShell* presShell = doc ? doc->GetShell() : nullptr; |
4349 | 0 |
|
4350 | 0 | if (!presShell) { |
4351 | 0 | return NS_ERROR_FAILURE; |
4352 | 0 | } |
4353 | 0 | |
4354 | 0 | nsIFrame* frame = presShell->GetRootFrame(); |
4355 | 0 | if (!frame) { |
4356 | 0 | return NS_ERROR_FAILURE; |
4357 | 0 | } |
4358 | 0 | |
4359 | 0 | presShell->FrameNeedsReflow(frame, nsIPresShell::eStyleChange, |
4360 | 0 | NS_FRAME_IS_DIRTY); |
4361 | 0 | return NS_OK; |
4362 | 0 | } |
4363 | | |
4364 | | NS_IMETHODIMP |
4365 | | nsDOMWindowUtils::SetPrefersReducedMotionOverrideForTest(bool aValue) |
4366 | 0 | { |
4367 | 0 | nsIWidget* widget = GetWidget(); |
4368 | 0 | if (!widget) { |
4369 | 0 | return NS_OK; |
4370 | 0 | } |
4371 | 0 | |
4372 | 0 | return widget->SetPrefersReducedMotionOverrideForTest(aValue); |
4373 | 0 | } |
4374 | | |
4375 | | NS_IMETHODIMP |
4376 | | nsDOMWindowUtils::ResetPrefersReducedMotionOverrideForTest() |
4377 | 0 | { |
4378 | 0 | nsIWidget* widget = GetWidget(); |
4379 | 0 | if (!widget) { |
4380 | 0 | return NS_OK; |
4381 | 0 | } |
4382 | 0 | |
4383 | 0 | return widget->ResetPrefersReducedMotionOverrideForTest(); |
4384 | 0 | } |
4385 | | |
4386 | 0 | NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList) |
4387 | 0 | NS_INTERFACE_MAP_ENTRY(nsISupports) |
4388 | 0 | NS_INTERFACE_MAP_ENTRY(nsITranslationNodeList) |
4389 | 0 | NS_INTERFACE_MAP_END |
4390 | | |
4391 | | NS_IMPL_ADDREF(nsTranslationNodeList) |
4392 | | NS_IMPL_RELEASE(nsTranslationNodeList) |
4393 | | |
4394 | | NS_IMETHODIMP |
4395 | | nsTranslationNodeList::Item(uint32_t aIndex, nsINode** aRetVal) |
4396 | 0 | { |
4397 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
4398 | 0 | NS_IF_ADDREF(*aRetVal = mNodes.SafeElementAt(aIndex)); |
4399 | 0 | return NS_OK; |
4400 | 0 | } |
4401 | | |
4402 | | NS_IMETHODIMP |
4403 | | nsTranslationNodeList::IsTranslationRootAtIndex(uint32_t aIndex, bool* aRetVal) |
4404 | 0 | { |
4405 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
4406 | 0 | if (aIndex >= mLength) { |
4407 | 0 | *aRetVal = false; |
4408 | 0 | return NS_OK; |
4409 | 0 | } |
4410 | 0 | |
4411 | 0 | *aRetVal = mNodeIsRoot.ElementAt(aIndex); |
4412 | 0 | return NS_OK; |
4413 | 0 | } |
4414 | | |
4415 | | NS_IMETHODIMP |
4416 | | nsTranslationNodeList::GetLength(uint32_t* aRetVal) |
4417 | 0 | { |
4418 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
4419 | 0 | *aRetVal = mLength; |
4420 | 0 | return NS_OK; |
4421 | 0 | } |
4422 | | |
4423 | | NS_IMETHODIMP |
4424 | | nsDOMWindowUtils::WrCapture() |
4425 | 0 | { |
4426 | 0 | if (WebRenderBridgeChild* wrbc = GetWebRenderBridge()) { |
4427 | 0 | wrbc->Capture(); |
4428 | 0 | } |
4429 | 0 | return NS_OK; |
4430 | 0 | } |
4431 | | |
4432 | | NS_IMETHODIMP |
4433 | | nsDOMWindowUtils::SetSystemFont(const nsACString& aFontName) |
4434 | 0 | { |
4435 | 0 | nsIWidget* widget = GetWidget(); |
4436 | 0 | if (!widget) { |
4437 | 0 | return NS_OK; |
4438 | 0 | } |
4439 | 0 | |
4440 | 0 | nsAutoCString fontName(aFontName); |
4441 | 0 | return widget->SetSystemFont(fontName); |
4442 | 0 | } |
4443 | | |
4444 | | NS_IMETHODIMP |
4445 | | nsDOMWindowUtils::GetSystemFont(nsACString& aFontName) |
4446 | 0 | { |
4447 | 0 | nsIWidget* widget = GetWidget(); |
4448 | 0 | if (!widget) { |
4449 | 0 | return NS_OK; |
4450 | 0 | } |
4451 | 0 | |
4452 | 0 | nsAutoCString fontName; |
4453 | 0 | widget->GetSystemFont(fontName); |
4454 | 0 | aFontName.Assign(fontName); |
4455 | 0 | return NS_OK; |
4456 | 0 | } |
4457 | | |
4458 | | NS_IMETHODIMP |
4459 | | nsDOMWindowUtils::IsCssPropertyRecordedInUseCounter(const nsACString& aPropName, |
4460 | | bool* aRecorded) |
4461 | 0 | { |
4462 | 0 | *aRecorded = false; |
4463 | 0 |
|
4464 | 0 | nsIDocument* doc = GetDocument(); |
4465 | 0 | if (!doc || !doc->GetStyleUseCounters()) { |
4466 | 0 | return NS_ERROR_FAILURE; |
4467 | 0 | } |
4468 | 0 | |
4469 | 0 | bool knownProp = false; |
4470 | 0 | *aRecorded = |
4471 | 0 | Servo_IsCssPropertyRecordedInUseCounter(doc->GetStyleUseCounters(), |
4472 | 0 | &aPropName, |
4473 | 0 | &knownProp); |
4474 | 0 | return knownProp ? NS_OK : NS_ERROR_FAILURE; |
4475 | 0 | } |
4476 | | |