1 | /*
|
---|
2 | * Copyright (C) 2012 Google Inc. All rights reserved.
|
---|
3 | * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
|
---|
4 | *
|
---|
5 | * Redistribution and use in source and binary forms, with or without
|
---|
6 | * modification, are permitted provided that the following conditions
|
---|
7 | * are met:
|
---|
8 | *
|
---|
9 | * 1. Redistributions of source code must retain the above copyright
|
---|
10 | * notice, this list of conditions and the following disclaimer.
|
---|
11 | * 2. Redistributions in binary form must reproduce the above copyright
|
---|
12 | * notice, this list of conditions and the following disclaimer in the
|
---|
13 | * documentation and/or other materials provided with the distribution.
|
---|
14 | *
|
---|
15 | * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
---|
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
---|
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
---|
18 | * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
---|
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
---|
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
---|
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
---|
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
---|
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
---|
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
25 | */
|
---|
26 |
|
---|
27 | #include "config.h"
|
---|
28 | #include "Internals.h"
|
---|
29 |
|
---|
30 | #include "AXObjectCache.h"
|
---|
31 | #include "AddEventListenerOptions.h"
|
---|
32 | #include "AnimationTimeline.h"
|
---|
33 | #include "ApplicationCacheStorage.h"
|
---|
34 | #include "AudioSession.h"
|
---|
35 | #include "AudioTrackPrivateMediaStream.h"
|
---|
36 | #include "Autofill.h"
|
---|
37 | #include "BackForwardCache.h"
|
---|
38 | #include "BackForwardController.h"
|
---|
39 | #include "BitmapImage.h"
|
---|
40 | #include "Blob.h"
|
---|
41 | #include "CSSKeyframesRule.h"
|
---|
42 | #include "CSSMediaRule.h"
|
---|
43 | #include "CSSPropertyParser.h"
|
---|
44 | #include "CSSStyleRule.h"
|
---|
45 | #include "CSSSupportsRule.h"
|
---|
46 | #include "CacheStorageConnection.h"
|
---|
47 | #include "CacheStorageProvider.h"
|
---|
48 | #include "CachedImage.h"
|
---|
49 | #include "CachedResourceLoader.h"
|
---|
50 | #include "CertificateInfo.h"
|
---|
51 | #include "Chrome.h"
|
---|
52 | #include "ChromeClient.h"
|
---|
53 | #include "ClientOrigin.h"
|
---|
54 | #include "ColorSerialization.h"
|
---|
55 | #include "ComposedTreeIterator.h"
|
---|
56 | #include "CookieJar.h"
|
---|
57 | #include "CrossOriginPreflightResultCache.h"
|
---|
58 | #include "Cursor.h"
|
---|
59 | #include "DOMPointReadOnly.h"
|
---|
60 | #include "DOMRect.h"
|
---|
61 | #include "DOMRectList.h"
|
---|
62 | #include "DOMStringList.h"
|
---|
63 | #include "DOMURL.h"
|
---|
64 | #include "DOMWindow.h"
|
---|
65 | #include "DeprecatedGlobalSettings.h"
|
---|
66 | #include "DiagnosticLoggingClient.h"
|
---|
67 | #include "DisabledAdaptations.h"
|
---|
68 | #include "DisplayList.h"
|
---|
69 | #include "Document.h"
|
---|
70 | #include "DocumentLoader.h"
|
---|
71 | #include "DocumentMarkerController.h"
|
---|
72 | #include "DocumentTimeline.h"
|
---|
73 | #include "DocumentTimelinesController.h"
|
---|
74 | #include "Editor.h"
|
---|
75 | #include "Element.h"
|
---|
76 | #include "ElementRareData.h"
|
---|
77 | #include "EventHandler.h"
|
---|
78 | #include "EventListener.h"
|
---|
79 | #include "EventLoop.h"
|
---|
80 | #include "EventNames.h"
|
---|
81 | #include "ExtendableEvent.h"
|
---|
82 | #include "ExtensionStyleSheets.h"
|
---|
83 | #include "FetchRequest.h"
|
---|
84 | #include "FetchResponse.h"
|
---|
85 | #include "File.h"
|
---|
86 | #include "FloatQuad.h"
|
---|
87 | #include "FontCache.h"
|
---|
88 | #include "FormController.h"
|
---|
89 | #include "Frame.h"
|
---|
90 | #include "FrameLoader.h"
|
---|
91 | #include "FrameView.h"
|
---|
92 | #include "FullscreenManager.h"
|
---|
93 | #include "GCObservation.h"
|
---|
94 | #include "GridPosition.h"
|
---|
95 | #include "HEVCUtilities.h"
|
---|
96 | #include "HTMLAnchorElement.h"
|
---|
97 | #include "HTMLAttachmentElement.h"
|
---|
98 | #include "HTMLCanvasElement.h"
|
---|
99 | #include "HTMLIFrameElement.h"
|
---|
100 | #include "HTMLImageElement.h"
|
---|
101 | #include "HTMLInputElement.h"
|
---|
102 | #include "HTMLLinkElement.h"
|
---|
103 | #include "HTMLNames.h"
|
---|
104 | #include "HTMLPictureElement.h"
|
---|
105 | #include "HTMLPlugInElement.h"
|
---|
106 | #include "HTMLPreloadScanner.h"
|
---|
107 | #include "HTMLSelectElement.h"
|
---|
108 | #include "HTMLTextAreaElement.h"
|
---|
109 | #include "HTMLVideoElement.h"
|
---|
110 | #include "HighlightRegister.h"
|
---|
111 | #include "HistoryController.h"
|
---|
112 | #include "HistoryItem.h"
|
---|
113 | #include "HitTestResult.h"
|
---|
114 | #include "IDBRequest.h"
|
---|
115 | #include "IDBTransaction.h"
|
---|
116 | #include "ImageOverlay.h"
|
---|
117 | #include "ImageOverlayController.h"
|
---|
118 | #include "InlineIteratorLineBox.h"
|
---|
119 | #include "InspectorClient.h"
|
---|
120 | #include "InspectorController.h"
|
---|
121 | #include "InspectorDebuggableType.h"
|
---|
122 | #include "InspectorFrontendClientLocal.h"
|
---|
123 | #include "InspectorOverlay.h"
|
---|
124 | #include "InstrumentingAgents.h"
|
---|
125 | #include "IntRect.h"
|
---|
126 | #include "InternalSettings.h"
|
---|
127 | #include "InternalsMapLike.h"
|
---|
128 | #include "InternalsSetLike.h"
|
---|
129 | #include "JSDOMPromiseDeferred.h"
|
---|
130 | #include "JSImageData.h"
|
---|
131 | #include "LegacySchemeRegistry.h"
|
---|
132 | #include "LibWebRTCProvider.h"
|
---|
133 | #include "LoaderStrategy.h"
|
---|
134 | #include "LocalizedStrings.h"
|
---|
135 | #include "Location.h"
|
---|
136 | #include "MallocStatistics.h"
|
---|
137 | #include "MediaDevices.h"
|
---|
138 | #include "MediaEngineConfigurationFactory.h"
|
---|
139 | #include "MediaKeySession.h"
|
---|
140 | #include "MediaKeys.h"
|
---|
141 | #include "MediaMetadata.h"
|
---|
142 | #include "MediaPlayer.h"
|
---|
143 | #include "MediaProducer.h"
|
---|
144 | #include "MediaRecorderProvider.h"
|
---|
145 | #include "MediaResourceLoader.h"
|
---|
146 | #include "MediaSession.h"
|
---|
147 | #include "MediaSessionActionDetails.h"
|
---|
148 | #include "MediaStreamTrack.h"
|
---|
149 | #include "MediaUsageInfo.h"
|
---|
150 | #include "MemoryCache.h"
|
---|
151 | #include "MemoryInfo.h"
|
---|
152 | #include "MockAudioDestinationCocoa.h"
|
---|
153 | #include "MockLibWebRTCPeerConnection.h"
|
---|
154 | #include "MockPageOverlay.h"
|
---|
155 | #include "MockPageOverlayClient.h"
|
---|
156 | #include "ModalContainerObserver.h"
|
---|
157 | #include "NavigatorBeacon.h"
|
---|
158 | #include "NavigatorMediaDevices.h"
|
---|
159 | #include "NetworkLoadInformation.h"
|
---|
160 | #include "Page.h"
|
---|
161 | #include "PageOverlay.h"
|
---|
162 | #include "PathUtilities.h"
|
---|
163 | #include "PictureInPictureSupport.h"
|
---|
164 | #include "PlatformKeyboardEvent.h"
|
---|
165 | #include "PlatformMediaSession.h"
|
---|
166 | #include "PlatformMediaSessionManager.h"
|
---|
167 | #include "PlatformScreen.h"
|
---|
168 | #include "PlatformStrategies.h"
|
---|
169 | #include "PluginData.h"
|
---|
170 | #include "PrintContext.h"
|
---|
171 | #include "PseudoElement.h"
|
---|
172 | #include "PushSubscription.h"
|
---|
173 | #include "PushSubscriptionData.h"
|
---|
174 | #include "RTCRtpSFrameTransform.h"
|
---|
175 | #include "Range.h"
|
---|
176 | #include "ReadableStream.h"
|
---|
177 | #include "RenderEmbeddedObject.h"
|
---|
178 | #include "RenderLayerBacking.h"
|
---|
179 | #include "RenderLayerCompositor.h"
|
---|
180 | #include "RenderLayerScrollableArea.h"
|
---|
181 | #include "RenderListBox.h"
|
---|
182 | #include "RenderMenuList.h"
|
---|
183 | #include "RenderTheme.h"
|
---|
184 | #include "RenderThemeIOS.h"
|
---|
185 | #include "RenderTreeAsText.h"
|
---|
186 | #include "RenderView.h"
|
---|
187 | #include "RenderedDocumentMarker.h"
|
---|
188 | #include "ResourceLoadObserver.h"
|
---|
189 | #include "RuntimeEnabledFeatures.h"
|
---|
190 | #include "SMILTimeContainer.h"
|
---|
191 | #include "SVGDocumentExtensions.h"
|
---|
192 | #include "SVGPathStringBuilder.h"
|
---|
193 | #include "SVGSVGElement.h"
|
---|
194 | #include "SWClientConnection.h"
|
---|
195 | #include "ScriptController.h"
|
---|
196 | #include "ScriptedAnimationController.h"
|
---|
197 | #include "ScrollingCoordinator.h"
|
---|
198 | #include "ScrollingMomentumCalculator.h"
|
---|
199 | #include "SecurityOrigin.h"
|
---|
200 | #include "SerializedScriptValue.h"
|
---|
201 | #include "ServiceWorker.h"
|
---|
202 | #include "ServiceWorkerProvider.h"
|
---|
203 | #include "ServiceWorkerRegistration.h"
|
---|
204 | #include "ServiceWorkerRegistrationData.h"
|
---|
205 | #include "Settings.h"
|
---|
206 | #include "ShadowRoot.h"
|
---|
207 | #include "SourceBuffer.h"
|
---|
208 | #include "SpellChecker.h"
|
---|
209 | #include "StaticNodeList.h"
|
---|
210 | #include "StorageNamespace.h"
|
---|
211 | #include "StorageNamespaceProvider.h"
|
---|
212 | #include "StringCallback.h"
|
---|
213 | #include "StyleResolver.h"
|
---|
214 | #include "StyleRule.h"
|
---|
215 | #include "StyleScope.h"
|
---|
216 | #include "StyleSheetContents.h"
|
---|
217 | #include "SystemSoundManager.h"
|
---|
218 | #include "TextIterator.h"
|
---|
219 | #include "TextPainter.h"
|
---|
220 | #include "TextPlaceholderElement.h"
|
---|
221 | #include "TextRecognitionOptions.h"
|
---|
222 | #include "ThreadableBlobRegistry.h"
|
---|
223 | #include "TreeScope.h"
|
---|
224 | #include "TypeConversions.h"
|
---|
225 | #include "UserGestureIndicator.h"
|
---|
226 | #include "UserMediaController.h"
|
---|
227 | #include "ViewportArguments.h"
|
---|
228 | #include "VoidCallback.h"
|
---|
229 | #include "WebAnimation.h"
|
---|
230 | #include "WebAnimationUtilities.h"
|
---|
231 | #include "WebCoreJSClientData.h"
|
---|
232 | #include "WindowProxy.h"
|
---|
233 | #include "WorkerThread.h"
|
---|
234 | #include "WorkletGlobalScope.h"
|
---|
235 | #include "WritingDirection.h"
|
---|
236 | #include "XMLHttpRequest.h"
|
---|
237 | #include <JavaScriptCore/CodeBlock.h>
|
---|
238 | #include <JavaScriptCore/InspectorAgentBase.h>
|
---|
239 | #include <JavaScriptCore/InspectorFrontendChannel.h>
|
---|
240 | #include <JavaScriptCore/JSCInlines.h>
|
---|
241 | #include <JavaScriptCore/JSCJSValue.h>
|
---|
242 | #include <wtf/FileSystem.h>
|
---|
243 | #include <wtf/HexNumber.h>
|
---|
244 | #include <wtf/JSONValues.h>
|
---|
245 | #include <wtf/Language.h>
|
---|
246 | #include <wtf/MemoryPressureHandler.h>
|
---|
247 | #include <wtf/MonotonicTime.h>
|
---|
248 | #include <wtf/ProcessID.h>
|
---|
249 | #include <wtf/URLHelpers.h>
|
---|
250 | #include <wtf/text/StringBuilder.h>
|
---|
251 | #include <wtf/text/StringConcatenateNumbers.h>
|
---|
252 | #include <wtf/text/StringToIntegerConversion.h>
|
---|
253 |
|
---|
254 | #if USE(CG)
|
---|
255 | #include "PDFDocumentImage.h"
|
---|
256 | #endif
|
---|
257 |
|
---|
258 | #if ENABLE(INPUT_TYPE_COLOR)
|
---|
259 | #include "ColorChooser.h"
|
---|
260 | #endif
|
---|
261 |
|
---|
262 | #if ENABLE(MOUSE_CURSOR_SCALE)
|
---|
263 | #include <wtf/dtoa.h>
|
---|
264 | #endif
|
---|
265 |
|
---|
266 | #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
|
---|
267 | #include "LegacyCDM.h"
|
---|
268 | #include "LegacyMockCDM.h"
|
---|
269 | #endif
|
---|
270 |
|
---|
271 | #if ENABLE(ENCRYPTED_MEDIA)
|
---|
272 | #include "MockCDMFactory.h"
|
---|
273 | #endif
|
---|
274 |
|
---|
275 | #if ENABLE(VIDEO)
|
---|
276 | #include "CaptionUserPreferences.h"
|
---|
277 | #include "HTMLMediaElement.h"
|
---|
278 | #include "PageGroup.h"
|
---|
279 | #include "TextTrack.h"
|
---|
280 | #include "TextTrackCueGeneric.h"
|
---|
281 | #include "TimeRanges.h"
|
---|
282 | #endif
|
---|
283 |
|
---|
284 | #if ENABLE(WEBGL)
|
---|
285 | #include "WebGLRenderingContext.h"
|
---|
286 | #endif
|
---|
287 |
|
---|
288 | #if ENABLE(SPEECH_SYNTHESIS)
|
---|
289 | #include "DOMWindowSpeechSynthesis.h"
|
---|
290 | #include "PlatformSpeechSynthesizerMock.h"
|
---|
291 | #include "SpeechSynthesis.h"
|
---|
292 | #endif
|
---|
293 |
|
---|
294 | #if ENABLE(MEDIA_STREAM)
|
---|
295 | #include "MediaStream.h"
|
---|
296 | #include "MockRealtimeMediaSourceCenter.h"
|
---|
297 | #endif
|
---|
298 |
|
---|
299 | #if ENABLE(MEDIA_RECORDER)
|
---|
300 | #include "MediaRecorder.h"
|
---|
301 | #include "MediaRecorderPrivateMock.h"
|
---|
302 | #endif
|
---|
303 |
|
---|
304 | #if ENABLE(WEB_RTC)
|
---|
305 | #include "RTCPeerConnection.h"
|
---|
306 | #endif
|
---|
307 |
|
---|
308 | #if ENABLE(MEDIA_SOURCE)
|
---|
309 | #include "MockMediaPlayerMediaSource.h"
|
---|
310 | #endif
|
---|
311 |
|
---|
312 | #if ENABLE(CONTENT_FILTERING)
|
---|
313 | #include "MockContentFilterSettings.h"
|
---|
314 | #endif
|
---|
315 |
|
---|
316 | #if ENABLE(WEB_AUDIO)
|
---|
317 | #include "AudioContext.h"
|
---|
318 | #endif
|
---|
319 |
|
---|
320 | #if ENABLE(WIRELESS_PLAYBACK_TARGET)
|
---|
321 | #include "MediaPlaybackTargetContext.h"
|
---|
322 | #endif
|
---|
323 |
|
---|
324 | #if ENABLE(POINTER_LOCK)
|
---|
325 | #include "PointerLockController.h"
|
---|
326 | #endif
|
---|
327 |
|
---|
328 | #if USE(QUICK_LOOK)
|
---|
329 | #include "LegacyPreviewLoader.h"
|
---|
330 | #include "MockPreviewLoaderClient.h"
|
---|
331 | #endif
|
---|
332 |
|
---|
333 | #if ENABLE(APPLE_PAY)
|
---|
334 | #include "MockPaymentCoordinator.h"
|
---|
335 | #include "PaymentCoordinator.h"
|
---|
336 | #endif
|
---|
337 |
|
---|
338 | #if ENABLE(WEBXR)
|
---|
339 | #include "NavigatorWebXR.h"
|
---|
340 | #include "WebXRSystem.h"
|
---|
341 | #include "WebXRTest.h"
|
---|
342 | #endif
|
---|
343 |
|
---|
344 | #if PLATFORM(MAC)
|
---|
345 | #include "GraphicsChecksMac.h"
|
---|
346 | #include "NSScrollerImpDetails.h"
|
---|
347 | #include "ScrollbarThemeMac.h"
|
---|
348 | #endif
|
---|
349 |
|
---|
350 | #if PLATFORM(IOS_FAMILY)
|
---|
351 | #include "FontCacheCoreText.h"
|
---|
352 | #include "MediaSessionHelperIOS.h"
|
---|
353 | #endif
|
---|
354 |
|
---|
355 | #if PLATFORM(COCOA)
|
---|
356 | #include "SystemBattery.h"
|
---|
357 | #include "VP9UtilitiesCocoa.h"
|
---|
358 | #include <pal/spi/cf/CoreTextSPI.h>
|
---|
359 | #include <wtf/spi/darwin/SandboxSPI.h>
|
---|
360 | #endif
|
---|
361 |
|
---|
362 | #if ENABLE(MEDIA_SESSION_COORDINATOR)
|
---|
363 | #include "MediaSessionCoordinator.h"
|
---|
364 | #include "MockMediaSessionCoordinator.h"
|
---|
365 | #include "NavigatorMediaSession.h"
|
---|
366 | #endif
|
---|
367 |
|
---|
368 | #if ENABLE(MEDIA_SESSION) && USE(GLIB)
|
---|
369 | #include "MediaSessionManagerGLib.h"
|
---|
370 | #endif
|
---|
371 |
|
---|
372 | #if ENABLE(IMAGE_ANALYSIS)
|
---|
373 | #include "TextRecognitionResult.h"
|
---|
374 | #endif
|
---|
375 |
|
---|
376 | #if ENABLE(ARKIT_INLINE_PREVIEW_MAC)
|
---|
377 | #include "HTMLModelElement.h"
|
---|
378 | #endif
|
---|
379 |
|
---|
380 | #if ENABLE(SERVICE_CONTROLS)
|
---|
381 | #include "ImageControlsMac.h"
|
---|
382 | #endif
|
---|
383 |
|
---|
384 | using JSC::CallData;
|
---|
385 | using JSC::CodeBlock;
|
---|
386 | using JSC::FunctionExecutable;
|
---|
387 | using JSC::Identifier;
|
---|
388 | using JSC::JSFunction;
|
---|
389 | using JSC::JSGlobalObject;
|
---|
390 | using JSC::JSObject;
|
---|
391 | using JSC::JSValue;
|
---|
392 | using JSC::MarkedArgumentBuffer;
|
---|
393 | using JSC::PropertySlot;
|
---|
394 | using JSC::ScriptExecutable;
|
---|
395 | using JSC::StackVisitor;
|
---|
396 |
|
---|
397 | namespace WebCore {
|
---|
398 |
|
---|
399 | using namespace Inspector;
|
---|
400 | using namespace HTMLNames;
|
---|
401 |
|
---|
402 | class InspectorStubFrontend final : public InspectorFrontendClientLocal, public FrontendChannel {
|
---|
403 | public:
|
---|
404 | InspectorStubFrontend(Page& inspectedPage, RefPtr<DOMWindow>&& frontendWindow);
|
---|
405 | virtual ~InspectorStubFrontend();
|
---|
406 |
|
---|
407 | private:
|
---|
408 | bool supportsDockSide(DockSide) final { return false; }
|
---|
409 | void attachWindow(DockSide) final { }
|
---|
410 | void detachWindow() final { }
|
---|
411 | void closeWindow() final;
|
---|
412 | void reopen() final { }
|
---|
413 | void bringToFront() final { }
|
---|
414 | void setForcedAppearance(InspectorFrontendClient::Appearance) final { }
|
---|
415 | String localizedStringsURL() const final { return String(); }
|
---|
416 | DebuggableType debuggableType() const final { return DebuggableType::Page; }
|
---|
417 | String targetPlatformName() const { return "Unknown"_s; }
|
---|
418 | String targetBuildVersion() const { return "Unknown"_s; }
|
---|
419 | String targetProductVersion() const { return "Unknown"_s; }
|
---|
420 | bool targetIsSimulator() const { return false; }
|
---|
421 | void inspectedURLChanged(const String&) final { }
|
---|
422 | void showCertificate(const CertificateInfo&) final { }
|
---|
423 | void setAttachedWindowHeight(unsigned) final { }
|
---|
424 | void setAttachedWindowWidth(unsigned) final { }
|
---|
425 | void setSheetRect(const FloatRect&) final { }
|
---|
426 |
|
---|
427 | void sendMessageToFrontend(const String& message) final;
|
---|
428 | ConnectionType connectionType() const final { return ConnectionType::Local; }
|
---|
429 |
|
---|
430 | RefPtr<DOMWindow> m_frontendWindow;
|
---|
431 | };
|
---|
432 |
|
---|
433 | InspectorStubFrontend::InspectorStubFrontend(Page& inspectedPage, RefPtr<DOMWindow>&& frontendWindow)
|
---|
434 | : InspectorFrontendClientLocal(&inspectedPage.inspectorController(), frontendWindow->document()->page(), makeUnique<InspectorFrontendClientLocal::Settings>())
|
---|
435 | , m_frontendWindow(frontendWindow.copyRef())
|
---|
436 | {
|
---|
437 | ASSERT_ARG(frontendWindow, frontendWindow);
|
---|
438 |
|
---|
439 | frontendPage()->inspectorController().setInspectorFrontendClient(this);
|
---|
440 | inspectedPage.inspectorController().connectFrontend(*this);
|
---|
441 | }
|
---|
442 |
|
---|
443 | InspectorStubFrontend::~InspectorStubFrontend()
|
---|
444 | {
|
---|
445 | closeWindow();
|
---|
446 | }
|
---|
447 |
|
---|
448 | void InspectorStubFrontend::closeWindow()
|
---|
449 | {
|
---|
450 | if (!m_frontendWindow)
|
---|
451 | return;
|
---|
452 |
|
---|
453 | frontendPage()->inspectorController().setInspectorFrontendClient(nullptr);
|
---|
454 | inspectedPage()->inspectorController().disconnectFrontend(*this);
|
---|
455 |
|
---|
456 | m_frontendWindow->close();
|
---|
457 | m_frontendWindow = nullptr;
|
---|
458 | }
|
---|
459 |
|
---|
460 | void InspectorStubFrontend::sendMessageToFrontend(const String& message)
|
---|
461 | {
|
---|
462 | frontendAPIDispatcher().dispatchMessageAsync(message);
|
---|
463 | }
|
---|
464 |
|
---|
465 | static bool markerTypeFrom(const String& markerType, DocumentMarker::MarkerType& result)
|
---|
466 | {
|
---|
467 | if (equalLettersIgnoringASCIICase(markerType, "spelling"_s))
|
---|
468 | result = DocumentMarker::Spelling;
|
---|
469 | else if (equalLettersIgnoringASCIICase(markerType, "grammar"_s))
|
---|
470 | result = DocumentMarker::Grammar;
|
---|
471 | else if (equalLettersIgnoringASCIICase(markerType, "textmatch"_s))
|
---|
472 | result = DocumentMarker::TextMatch;
|
---|
473 | else if (equalLettersIgnoringASCIICase(markerType, "replacement"_s))
|
---|
474 | result = DocumentMarker::Replacement;
|
---|
475 | else if (equalLettersIgnoringASCIICase(markerType, "correctionindicator"_s))
|
---|
476 | result = DocumentMarker::CorrectionIndicator;
|
---|
477 | else if (equalLettersIgnoringASCIICase(markerType, "rejectedcorrection"_s))
|
---|
478 | result = DocumentMarker::RejectedCorrection;
|
---|
479 | else if (equalLettersIgnoringASCIICase(markerType, "autocorrected"_s))
|
---|
480 | result = DocumentMarker::Autocorrected;
|
---|
481 | else if (equalLettersIgnoringASCIICase(markerType, "spellcheckingexemption"_s))
|
---|
482 | result = DocumentMarker::SpellCheckingExemption;
|
---|
483 | else if (equalLettersIgnoringASCIICase(markerType, "deletedautocorrection"_s))
|
---|
484 | result = DocumentMarker::DeletedAutocorrection;
|
---|
485 | else if (equalLettersIgnoringASCIICase(markerType, "dictationalternatives"_s))
|
---|
486 | result = DocumentMarker::DictationAlternatives;
|
---|
487 | #if ENABLE(TELEPHONE_NUMBER_DETECTION)
|
---|
488 | else if (equalLettersIgnoringASCIICase(markerType, "telephonenumber"_s))
|
---|
489 | result = DocumentMarker::TelephoneNumber;
|
---|
490 | #endif
|
---|
491 | else
|
---|
492 | return false;
|
---|
493 |
|
---|
494 | return true;
|
---|
495 | }
|
---|
496 |
|
---|
497 | static bool markerTypesFrom(const String& markerType, OptionSet<DocumentMarker::MarkerType>& result)
|
---|
498 | {
|
---|
499 | DocumentMarker::MarkerType singularResult;
|
---|
500 |
|
---|
501 | if (markerType.isEmpty() || equalLettersIgnoringASCIICase(markerType, "all"_s))
|
---|
502 | result = DocumentMarker::allMarkers();
|
---|
503 | else if (markerTypeFrom(markerType, singularResult))
|
---|
504 | result = singularResult;
|
---|
505 | else
|
---|
506 | return false;
|
---|
507 |
|
---|
508 | return true;
|
---|
509 | }
|
---|
510 |
|
---|
511 | static std::unique_ptr<PrintContext>& printContextForTesting()
|
---|
512 | {
|
---|
513 | static NeverDestroyed<std::unique_ptr<PrintContext>> context;
|
---|
514 | return context;
|
---|
515 | }
|
---|
516 |
|
---|
517 | Ref<Internals> Internals::create(Document& document)
|
---|
518 | {
|
---|
519 | return adoptRef(*new Internals(document));
|
---|
520 | }
|
---|
521 |
|
---|
522 | Internals::~Internals()
|
---|
523 | {
|
---|
524 | #if ENABLE(MEDIA_STREAM)
|
---|
525 | stopObservingRealtimeMediaSource();
|
---|
526 | #endif
|
---|
527 | #if ENABLE(MEDIA_SESSION)
|
---|
528 | if (m_artworkImagePromise)
|
---|
529 | m_artworkImagePromise->reject(Exception { InvalidStateError });
|
---|
530 | #endif
|
---|
531 | }
|
---|
532 |
|
---|
533 | void Internals::resetToConsistentState(Page& page)
|
---|
534 | {
|
---|
535 | page.setPageScaleFactor(1, IntPoint(0, 0));
|
---|
536 | page.setPagination(Pagination());
|
---|
537 | page.setPaginationLineGridEnabled(false);
|
---|
538 |
|
---|
539 | page.setDefersLoading(false);
|
---|
540 |
|
---|
541 | page.mainFrame().setTextZoomFactor(1.0f);
|
---|
542 |
|
---|
543 | page.setCompositingPolicyOverride(WebCore::CompositingPolicy::Normal);
|
---|
544 |
|
---|
545 | FrameView* mainFrameView = page.mainFrame().view();
|
---|
546 | if (mainFrameView) {
|
---|
547 | page.setHeaderHeight(0);
|
---|
548 | page.setFooterHeight(0);
|
---|
549 | page.setTopContentInset(0);
|
---|
550 | mainFrameView->setUseFixedLayout(false);
|
---|
551 | mainFrameView->setFixedLayoutSize(IntSize());
|
---|
552 | mainFrameView->enableFixedWidthAutoSizeMode(false, { });
|
---|
553 | #if USE(COORDINATED_GRAPHICS)
|
---|
554 | mainFrameView->setFixedVisibleContentRect(IntRect());
|
---|
555 | #endif
|
---|
556 | if (auto* backing = mainFrameView->tiledBacking())
|
---|
557 | backing->setTileSizeUpdateDelayDisabledForTesting(false);
|
---|
558 | }
|
---|
559 |
|
---|
560 | WTF::clearDefaultPortForProtocolMapForTesting();
|
---|
561 | overrideUserPreferredLanguages(Vector<String>());
|
---|
562 | WebCore::DeprecatedGlobalSettings::setUsesOverlayScrollbars(false);
|
---|
563 | if (!page.mainFrame().editor().isContinuousSpellCheckingEnabled())
|
---|
564 | page.mainFrame().editor().toggleContinuousSpellChecking();
|
---|
565 | if (page.mainFrame().editor().isOverwriteModeEnabled())
|
---|
566 | page.mainFrame().editor().toggleOverwriteModeEnabled();
|
---|
567 | page.mainFrame().loader().clearTestingOverrides();
|
---|
568 | page.applicationCacheStorage().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
|
---|
569 | #if ENABLE(VIDEO)
|
---|
570 | page.group().ensureCaptionPreferences().setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
|
---|
571 | page.group().ensureCaptionPreferences().setCaptionsStyleSheetOverride(emptyString());
|
---|
572 | PlatformMediaSessionManager::sharedManager().resetHaveEverRegisteredAsNowPlayingApplicationForTesting();
|
---|
573 | PlatformMediaSessionManager::sharedManager().resetRestrictions();
|
---|
574 | PlatformMediaSessionManager::sharedManager().resetSessionState();
|
---|
575 | PlatformMediaSessionManager::sharedManager().setWillIgnoreSystemInterruptions(true);
|
---|
576 | PlatformMediaSessionManager::sharedManager().applicationWillEnterForeground(false);
|
---|
577 | #endif
|
---|
578 | #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
|
---|
579 | PlatformMediaSessionManager::sharedManager().setIsPlayingToAutomotiveHeadUnit(false);
|
---|
580 | #endif
|
---|
581 | #if ENABLE(ACCESSIBILITY)
|
---|
582 | AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
|
---|
583 | AXObjectCache::disableAccessibility();
|
---|
584 | #endif
|
---|
585 |
|
---|
586 | MockPageOverlayClient::singleton().uninstallAllOverlays();
|
---|
587 |
|
---|
588 | #if ENABLE(CONTENT_FILTERING)
|
---|
589 | MockContentFilterSettings::reset();
|
---|
590 | #endif
|
---|
591 |
|
---|
592 | #if ENABLE(WIRELESS_PLAYBACK_TARGET)
|
---|
593 | page.setMockMediaPlaybackTargetPickerEnabled(true);
|
---|
594 | page.setMockMediaPlaybackTargetPickerState(emptyString(), MediaPlaybackTargetContext::MockState::Unknown);
|
---|
595 | #endif
|
---|
596 |
|
---|
597 | #if ENABLE(VIDEO)
|
---|
598 | MediaResourceLoader::recordResponsesForTesting();
|
---|
599 | #endif
|
---|
600 |
|
---|
601 | page.setShowAllPlugins(false);
|
---|
602 | page.setLowPowerModeEnabledOverrideForTesting(std::nullopt);
|
---|
603 | page.setOutsideViewportThrottlingEnabledForTesting(false);
|
---|
604 |
|
---|
605 | #if USE(QUICK_LOOK)
|
---|
606 | MockPreviewLoaderClient::singleton().setPassword(emptyString());
|
---|
607 | LegacyPreviewLoader::setClientForTesting(nullptr);
|
---|
608 | #endif
|
---|
609 |
|
---|
610 | printContextForTesting() = nullptr;
|
---|
611 |
|
---|
612 | #if USE(LIBWEBRTC)
|
---|
613 | auto& rtcProvider = page.libWebRTCProvider();
|
---|
614 | WebCore::useRealRTCPeerConnectionFactory(rtcProvider);
|
---|
615 | LibWebRTCProvider::setH264HardwareEncoderAllowed(true);
|
---|
616 | page.settings().setWebRTCEncryptionEnabled(true);
|
---|
617 | rtcProvider.disableNonLocalhostConnections();
|
---|
618 | rtcProvider.setH265Support(true);
|
---|
619 | rtcProvider.setVP9Support(true, true);
|
---|
620 | rtcProvider.clearFactory();
|
---|
621 | #elif USE(GSTREAMER_WEBRTC)
|
---|
622 | page.settings().setWebRTCEncryptionEnabled(true);
|
---|
623 | page.settings().setPeerConnectionEnabled(true);
|
---|
624 | #endif
|
---|
625 |
|
---|
626 | page.setFullscreenAutoHideDuration(0_s);
|
---|
627 | page.setFullscreenInsets({ });
|
---|
628 | page.setFullscreenControlsHidden(false);
|
---|
629 |
|
---|
630 | MediaEngineConfigurationFactory::disableMock();
|
---|
631 |
|
---|
632 | #if ENABLE(MEDIA_STREAM)
|
---|
633 | page.settings().setInterruptAudioOnPageVisibilityChangeEnabled(false);
|
---|
634 | #endif
|
---|
635 |
|
---|
636 | #if ENABLE(MEDIA_RECORDER)
|
---|
637 | WebCore::MediaRecorder::setCustomPrivateRecorderCreator(nullptr);
|
---|
638 | #endif
|
---|
639 |
|
---|
640 | HTMLCanvasElement::setMaxPixelMemoryForTesting(std::nullopt);
|
---|
641 | HTMLCanvasElement::setMaxCanvasAreaForTesting(std::nullopt);
|
---|
642 | DOMWindow::overrideTransientActivationDurationForTesting(std::nullopt);
|
---|
643 |
|
---|
644 | #if PLATFORM(IOS)
|
---|
645 | WebCore::setContentSizeCategory(kCTFontContentSizeCategoryL);
|
---|
646 | #endif
|
---|
647 |
|
---|
648 | #if ENABLE(MEDIA_SESSION) && USE(GLIB)
|
---|
649 | auto& sessionManager = reinterpret_cast<MediaSessionManagerGLib&>(PlatformMediaSessionManager::sharedManager());
|
---|
650 | sessionManager.setDBusNotificationsEnabled(false);
|
---|
651 | #endif
|
---|
652 |
|
---|
653 | TextPainter::setForceUseGlyphDisplayListForTesting(false);
|
---|
654 | }
|
---|
655 |
|
---|
656 | Internals::Internals(Document& document)
|
---|
657 | : ContextDestructionObserver(&document)
|
---|
658 | #if ENABLE(MEDIA_STREAM)
|
---|
659 | , m_orientationNotifier(0)
|
---|
660 | #endif
|
---|
661 | {
|
---|
662 | #if ENABLE(WIRELESS_PLAYBACK_TARGET)
|
---|
663 | if (document.page())
|
---|
664 | document.page()->setMockMediaPlaybackTargetPickerEnabled(true);
|
---|
665 | #endif
|
---|
666 |
|
---|
667 | #if ENABLE(VIDEO)
|
---|
668 | if (document.page())
|
---|
669 | m_testingModeToken = document.page()->group().ensureCaptionPreferences().createTestingModeToken().moveToUniquePtr();
|
---|
670 | #endif
|
---|
671 |
|
---|
672 | if (contextDocument() && contextDocument()->frame()) {
|
---|
673 | setAutomaticSpellingCorrectionEnabled(true);
|
---|
674 | setAutomaticQuoteSubstitutionEnabled(false);
|
---|
675 | setAutomaticDashSubstitutionEnabled(false);
|
---|
676 | setAutomaticLinkDetectionEnabled(false);
|
---|
677 | setAutomaticTextReplacementEnabled(true);
|
---|
678 | }
|
---|
679 |
|
---|
680 | setConsoleMessageListener(nullptr);
|
---|
681 |
|
---|
682 | #if ENABLE(APPLE_PAY)
|
---|
683 | auto* frame = document.frame();
|
---|
684 | if (frame && frame->page() && frame->isMainFrame()) {
|
---|
685 | auto mockPaymentCoordinator = new MockPaymentCoordinator(*frame->page());
|
---|
686 | frame->page()->setPaymentCoordinator(makeUnique<PaymentCoordinator>(*mockPaymentCoordinator));
|
---|
687 | }
|
---|
688 | #endif
|
---|
689 |
|
---|
690 | #if PLATFORM(COCOA) && ENABLE(WEB_AUDIO)
|
---|
691 | AudioDestinationCocoa::createOverride = nullptr;
|
---|
692 | #endif
|
---|
693 |
|
---|
694 | #if PLATFORM(COCOA)
|
---|
695 | SystemBatteryStatusTestingOverrides::singleton().setHasAC(std::nullopt);
|
---|
696 | SystemBatteryStatusTestingOverrides::singleton().setHasBattery(std::nullopt);
|
---|
697 | #endif
|
---|
698 |
|
---|
699 | #if ENABLE(VP9) && PLATFORM(COCOA)
|
---|
700 | VP9TestingOverrides::singleton().setHardwareDecoderDisabled(std::nullopt);
|
---|
701 | VP9TestingOverrides::singleton().setVP9ScreenSizeAndScale(std::nullopt);
|
---|
702 | #endif
|
---|
703 | }
|
---|
704 |
|
---|
705 | Document* Internals::contextDocument() const
|
---|
706 | {
|
---|
707 | return downcast<Document>(scriptExecutionContext());
|
---|
708 | }
|
---|
709 |
|
---|
710 | Frame* Internals::frame() const
|
---|
711 | {
|
---|
712 | if (!contextDocument())
|
---|
713 | return nullptr;
|
---|
714 | return contextDocument()->frame();
|
---|
715 | }
|
---|
716 |
|
---|
717 | InternalSettings* Internals::settings() const
|
---|
718 | {
|
---|
719 | Document* document = contextDocument();
|
---|
720 | if (!document)
|
---|
721 | return nullptr;
|
---|
722 | Page* page = document->page();
|
---|
723 | if (!page)
|
---|
724 | return nullptr;
|
---|
725 | return InternalSettings::from(page);
|
---|
726 | }
|
---|
727 |
|
---|
728 | unsigned Internals::inflightBeaconsCount() const
|
---|
729 | {
|
---|
730 | auto* document = contextDocument();
|
---|
731 | if (!document)
|
---|
732 | return 0;
|
---|
733 |
|
---|
734 | auto* window = document->domWindow();
|
---|
735 | if (!window)
|
---|
736 | return 0;
|
---|
737 |
|
---|
738 | auto* navigator = window->optionalNavigator();
|
---|
739 | if (!navigator)
|
---|
740 | return 0;
|
---|
741 |
|
---|
742 | return NavigatorBeacon::from(*navigator)->inflightBeaconsCount();
|
---|
743 | }
|
---|
744 |
|
---|
745 | unsigned Internals::workerThreadCount() const
|
---|
746 | {
|
---|
747 | return WorkerThread::workerThreadCount();
|
---|
748 | }
|
---|
749 |
|
---|
750 | ExceptionOr<bool> Internals::areSVGAnimationsPaused() const
|
---|
751 | {
|
---|
752 | auto* document = contextDocument();
|
---|
753 | if (!document)
|
---|
754 | return Exception { InvalidAccessError, "No context document"_s };
|
---|
755 |
|
---|
756 | if (!document->svgExtensions())
|
---|
757 | return Exception { NotFoundError, "No SVG animations"_s };
|
---|
758 |
|
---|
759 | return document->accessSVGExtensions().areAnimationsPaused();
|
---|
760 | }
|
---|
761 |
|
---|
762 | ExceptionOr<double> Internals::svgAnimationsInterval(SVGSVGElement& element) const
|
---|
763 | {
|
---|
764 | auto* document = contextDocument();
|
---|
765 | if (!document)
|
---|
766 | return 0;
|
---|
767 |
|
---|
768 | if (!document->svgExtensions())
|
---|
769 | return 0;
|
---|
770 |
|
---|
771 | if (document->accessSVGExtensions().areAnimationsPaused())
|
---|
772 | return 0;
|
---|
773 |
|
---|
774 | return element.timeContainer().animationFrameDelay().value();
|
---|
775 | }
|
---|
776 |
|
---|
777 | String Internals::address(Node& node)
|
---|
778 | {
|
---|
779 | return makeString("0x", hex(reinterpret_cast<uintptr_t>(&node)));
|
---|
780 | }
|
---|
781 |
|
---|
782 | bool Internals::nodeNeedsStyleRecalc(Node& node)
|
---|
783 | {
|
---|
784 | return node.needsStyleRecalc();
|
---|
785 | }
|
---|
786 |
|
---|
787 | static String styleValidityToToString(Style::Validity validity)
|
---|
788 | {
|
---|
789 | switch (validity) {
|
---|
790 | case Style::Validity::Valid:
|
---|
791 | return "NoStyleChange"_s;
|
---|
792 | case Style::Validity::ElementInvalid:
|
---|
793 | return "InlineStyleChange"_s;
|
---|
794 | case Style::Validity::SubtreeInvalid:
|
---|
795 | return "FullStyleChange"_s;
|
---|
796 | case Style::Validity::SubtreeAndRenderersInvalid:
|
---|
797 | return "ReconstructRenderTree"_s;
|
---|
798 | }
|
---|
799 | ASSERT_NOT_REACHED();
|
---|
800 | return emptyString();
|
---|
801 | }
|
---|
802 |
|
---|
803 | String Internals::styleChangeType(Node& node)
|
---|
804 | {
|
---|
805 | node.document().styleScope().flushPendingUpdate();
|
---|
806 |
|
---|
807 | return styleValidityToToString(node.styleValidity());
|
---|
808 | }
|
---|
809 |
|
---|
810 | String Internals::description(JSC::JSValue value)
|
---|
811 | {
|
---|
812 | return toString(value);
|
---|
813 | }
|
---|
814 |
|
---|
815 | void Internals::log(const String& value)
|
---|
816 | {
|
---|
817 | WTFLogAlways("%s", value.utf8().data());
|
---|
818 | }
|
---|
819 |
|
---|
820 | bool Internals::isPreloaded(const String& url)
|
---|
821 | {
|
---|
822 | Document* document = contextDocument();
|
---|
823 | return document->cachedResourceLoader().isPreloaded(url);
|
---|
824 | }
|
---|
825 |
|
---|
826 | bool Internals::isLoadingFromMemoryCache(const String& url)
|
---|
827 | {
|
---|
828 | if (!contextDocument() || !contextDocument()->page())
|
---|
829 | return false;
|
---|
830 |
|
---|
831 | ResourceRequest request(contextDocument()->completeURL(url));
|
---|
832 | request.setDomainForCachePartition(contextDocument()->domainForCachePartition());
|
---|
833 |
|
---|
834 | CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
|
---|
835 | return resource && resource->status() == CachedResource::Cached;
|
---|
836 | }
|
---|
837 |
|
---|
838 | static String responseSourceToString(const ResourceResponse& response)
|
---|
839 | {
|
---|
840 | if (response.isNull())
|
---|
841 | return "Null response"_s;
|
---|
842 | switch (response.source()) {
|
---|
843 | case ResourceResponse::Source::Unknown:
|
---|
844 | return "Unknown"_s;
|
---|
845 | case ResourceResponse::Source::Network:
|
---|
846 | return "Network"_s;
|
---|
847 | case ResourceResponse::Source::ServiceWorker:
|
---|
848 | return "Service worker"_s;
|
---|
849 | case ResourceResponse::Source::DiskCache:
|
---|
850 | return "Disk cache"_s;
|
---|
851 | case ResourceResponse::Source::DiskCacheAfterValidation:
|
---|
852 | return "Disk cache after validation"_s;
|
---|
853 | case ResourceResponse::Source::MemoryCache:
|
---|
854 | return "Memory cache"_s;
|
---|
855 | case ResourceResponse::Source::MemoryCacheAfterValidation:
|
---|
856 | return "Memory cache after validation"_s;
|
---|
857 | case ResourceResponse::Source::ApplicationCache:
|
---|
858 | return "Application cache"_s;
|
---|
859 | case ResourceResponse::Source::DOMCache:
|
---|
860 | return "DOM cache"_s;
|
---|
861 | case ResourceResponse::Source::InspectorOverride:
|
---|
862 | return "Inspector override"_s;
|
---|
863 | }
|
---|
864 | ASSERT_NOT_REACHED();
|
---|
865 | return "Error"_s;
|
---|
866 | }
|
---|
867 |
|
---|
868 | String Internals::xhrResponseSource(XMLHttpRequest& request)
|
---|
869 | {
|
---|
870 | return responseSourceToString(request.resourceResponse());
|
---|
871 | }
|
---|
872 |
|
---|
873 | String Internals::fetchResponseSource(FetchResponse& response)
|
---|
874 | {
|
---|
875 | return responseSourceToString(response.resourceResponse());
|
---|
876 | }
|
---|
877 |
|
---|
878 | String Internals::blobInternalURL(const Blob& blob)
|
---|
879 | {
|
---|
880 | return blob.url().string();
|
---|
881 | }
|
---|
882 |
|
---|
883 | void Internals::isBlobInternalURLRegistered(const String& url, DOMPromiseDeferred<IDLBoolean>&& promise)
|
---|
884 | {
|
---|
885 | promise.resolve(!!ThreadableBlobRegistry::blobSize(URL { url }));
|
---|
886 | }
|
---|
887 |
|
---|
888 | bool Internals::isSharingStyleSheetContents(HTMLLinkElement& a, HTMLLinkElement& b)
|
---|
889 | {
|
---|
890 | if (!a.sheet() || !b.sheet())
|
---|
891 | return false;
|
---|
892 | return &a.sheet()->contents() == &b.sheet()->contents();
|
---|
893 | }
|
---|
894 |
|
---|
895 | bool Internals::isStyleSheetLoadingSubresources(HTMLLinkElement& link)
|
---|
896 | {
|
---|
897 | return link.sheet() && link.sheet()->contents().isLoadingSubresources();
|
---|
898 | }
|
---|
899 |
|
---|
900 | static ResourceRequestCachePolicy toResourceRequestCachePolicy(Internals::CachePolicy policy)
|
---|
901 | {
|
---|
902 | switch (policy) {
|
---|
903 | case Internals::CachePolicy::UseProtocolCachePolicy:
|
---|
904 | return ResourceRequestCachePolicy::UseProtocolCachePolicy;
|
---|
905 | case Internals::CachePolicy::ReloadIgnoringCacheData:
|
---|
906 | return ResourceRequestCachePolicy::ReloadIgnoringCacheData;
|
---|
907 | case Internals::CachePolicy::ReturnCacheDataElseLoad:
|
---|
908 | return ResourceRequestCachePolicy::ReturnCacheDataElseLoad;
|
---|
909 | case Internals::CachePolicy::ReturnCacheDataDontLoad:
|
---|
910 | return ResourceRequestCachePolicy::ReturnCacheDataDontLoad;
|
---|
911 | }
|
---|
912 | ASSERT_NOT_REACHED();
|
---|
913 | return ResourceRequestCachePolicy::UseProtocolCachePolicy;
|
---|
914 | }
|
---|
915 |
|
---|
916 | void Internals::setOverrideCachePolicy(CachePolicy policy)
|
---|
917 | {
|
---|
918 | frame()->loader().setOverrideCachePolicyForTesting(toResourceRequestCachePolicy(policy));
|
---|
919 | }
|
---|
920 |
|
---|
921 | ExceptionOr<void> Internals::setCanShowModalDialogOverride(bool allow)
|
---|
922 | {
|
---|
923 | if (!contextDocument() || !contextDocument()->domWindow())
|
---|
924 | return Exception { InvalidAccessError };
|
---|
925 |
|
---|
926 | contextDocument()->domWindow()->setCanShowModalDialogOverride(allow);
|
---|
927 | return { };
|
---|
928 | }
|
---|
929 |
|
---|
930 | static ResourceLoadPriority toResourceLoadPriority(Internals::ResourceLoadPriority priority)
|
---|
931 | {
|
---|
932 | switch (priority) {
|
---|
933 | case Internals::ResourceLoadPriority::ResourceLoadPriorityVeryLow:
|
---|
934 | return ResourceLoadPriority::VeryLow;
|
---|
935 | case Internals::ResourceLoadPriority::ResourceLoadPriorityLow:
|
---|
936 | return ResourceLoadPriority::Low;
|
---|
937 | case Internals::ResourceLoadPriority::ResourceLoadPriorityMedium:
|
---|
938 | return ResourceLoadPriority::Medium;
|
---|
939 | case Internals::ResourceLoadPriority::ResourceLoadPriorityHigh:
|
---|
940 | return ResourceLoadPriority::High;
|
---|
941 | case Internals::ResourceLoadPriority::ResourceLoadPriorityVeryHigh:
|
---|
942 | return ResourceLoadPriority::VeryHigh;
|
---|
943 | }
|
---|
944 | ASSERT_NOT_REACHED();
|
---|
945 | return ResourceLoadPriority::Low;
|
---|
946 | }
|
---|
947 |
|
---|
948 | void Internals::setOverrideResourceLoadPriority(ResourceLoadPriority priority)
|
---|
949 | {
|
---|
950 | frame()->loader().setOverrideResourceLoadPriorityForTesting(toResourceLoadPriority(priority));
|
---|
951 | }
|
---|
952 |
|
---|
953 | void Internals::setStrictRawResourceValidationPolicyDisabled(bool disabled)
|
---|
954 | {
|
---|
955 | frame()->loader().setStrictRawResourceValidationPolicyDisabledForTesting(disabled);
|
---|
956 | }
|
---|
957 |
|
---|
958 | bool Internals::isFetchObjectContextStopped(const FetchObject& object)
|
---|
959 | {
|
---|
960 | return switchOn(object, [](const RefPtr<FetchRequest>& request) {
|
---|
961 | return request->isContextStopped();
|
---|
962 | }, [](auto& response) {
|
---|
963 | return response->isContextStopped();
|
---|
964 | });
|
---|
965 | }
|
---|
966 |
|
---|
967 | void Internals::clearMemoryCache()
|
---|
968 | {
|
---|
969 | MemoryCache::singleton().evictResources();
|
---|
970 | CrossOriginPreflightResultCache::singleton().clear();
|
---|
971 | }
|
---|
972 |
|
---|
973 | void Internals::pruneMemoryCacheToSize(unsigned size)
|
---|
974 | {
|
---|
975 | MemoryCache::singleton().pruneDeadResourcesToSize(size);
|
---|
976 | MemoryCache::singleton().pruneLiveResourcesToSize(size, true);
|
---|
977 | }
|
---|
978 |
|
---|
979 | void Internals::destroyDecodedDataForAllImages()
|
---|
980 | {
|
---|
981 | MemoryCache::singleton().destroyDecodedDataForAllImages();
|
---|
982 | }
|
---|
983 |
|
---|
984 | unsigned Internals::memoryCacheSize() const
|
---|
985 | {
|
---|
986 | return MemoryCache::singleton().size();
|
---|
987 | }
|
---|
988 |
|
---|
989 | static Image* imageFromImageElement(HTMLImageElement& element)
|
---|
990 | {
|
---|
991 | auto* cachedImage = element.cachedImage();
|
---|
992 | return cachedImage ? cachedImage->image() : nullptr;
|
---|
993 | }
|
---|
994 |
|
---|
995 | static BitmapImage* bitmapImageFromImageElement(HTMLImageElement& element)
|
---|
996 | {
|
---|
997 | return dynamicDowncast<BitmapImage>(imageFromImageElement(element));
|
---|
998 | }
|
---|
999 |
|
---|
1000 | #if USE(CG)
|
---|
1001 | static PDFDocumentImage* pdfDocumentImageFromImageElement(HTMLImageElement& element)
|
---|
1002 | {
|
---|
1003 | return dynamicDowncast<PDFDocumentImage>(imageFromImageElement(element));
|
---|
1004 | }
|
---|
1005 | #endif
|
---|
1006 |
|
---|
1007 | unsigned Internals::imageFrameIndex(HTMLImageElement& element)
|
---|
1008 | {
|
---|
1009 | auto* bitmapImage = bitmapImageFromImageElement(element);
|
---|
1010 | return bitmapImage ? bitmapImage->currentFrame() : 0;
|
---|
1011 | }
|
---|
1012 |
|
---|
1013 | unsigned Internals::imageFrameCount(HTMLImageElement& element)
|
---|
1014 | {
|
---|
1015 | auto* bitmapImage = bitmapImageFromImageElement(element);
|
---|
1016 | return bitmapImage ? bitmapImage->frameCount() : 0;
|
---|
1017 | }
|
---|
1018 |
|
---|
1019 | float Internals::imageFrameDurationAtIndex(HTMLImageElement& element, unsigned index)
|
---|
1020 | {
|
---|
1021 | auto* bitmapImage = bitmapImageFromImageElement(element);
|
---|
1022 | return bitmapImage ? bitmapImage->frameDurationAtIndex(index).value() : 0;
|
---|
1023 | }
|
---|
1024 |
|
---|
1025 | void Internals::setImageFrameDecodingDuration(HTMLImageElement& element, float duration)
|
---|
1026 | {
|
---|
1027 | if (auto* bitmapImage = bitmapImageFromImageElement(element))
|
---|
1028 | bitmapImage->setFrameDecodingDurationForTesting(Seconds { duration });
|
---|
1029 | }
|
---|
1030 |
|
---|
1031 | void Internals::resetImageAnimation(HTMLImageElement& element)
|
---|
1032 | {
|
---|
1033 | if (auto* image = imageFromImageElement(element))
|
---|
1034 | image->resetAnimation();
|
---|
1035 | }
|
---|
1036 |
|
---|
1037 | bool Internals::isImageAnimating(HTMLImageElement& element)
|
---|
1038 | {
|
---|
1039 | auto* image = imageFromImageElement(element);
|
---|
1040 | return image && (image->isAnimating() || image->animationPending());
|
---|
1041 | }
|
---|
1042 |
|
---|
1043 | unsigned Internals::imagePendingDecodePromisesCountForTesting(HTMLImageElement& element)
|
---|
1044 | {
|
---|
1045 | return element.pendingDecodePromisesCountForTesting();
|
---|
1046 | }
|
---|
1047 |
|
---|
1048 | void Internals::setClearDecoderAfterAsyncFrameRequestForTesting(HTMLImageElement& element, bool enabled)
|
---|
1049 | {
|
---|
1050 | if (auto* bitmapImage = bitmapImageFromImageElement(element))
|
---|
1051 | bitmapImage->setClearDecoderAfterAsyncFrameRequestForTesting(enabled);
|
---|
1052 | }
|
---|
1053 |
|
---|
1054 | unsigned Internals::imageDecodeCount(HTMLImageElement& element)
|
---|
1055 | {
|
---|
1056 | auto* bitmapImage = bitmapImageFromImageElement(element);
|
---|
1057 | return bitmapImage ? bitmapImage->decodeCountForTesting() : 0;
|
---|
1058 | }
|
---|
1059 |
|
---|
1060 | unsigned Internals::pdfDocumentCachingCount(HTMLImageElement& element)
|
---|
1061 | {
|
---|
1062 | #if USE(CG)
|
---|
1063 | auto* pdfDocumentImage = pdfDocumentImageFromImageElement(element);
|
---|
1064 | return pdfDocumentImage ? pdfDocumentImage->cachingCountForTesting() : 0;
|
---|
1065 | #else
|
---|
1066 | UNUSED_PARAM(element);
|
---|
1067 | return 0;
|
---|
1068 | #endif
|
---|
1069 | }
|
---|
1070 |
|
---|
1071 | unsigned Internals::remoteImagesCountForTesting() const
|
---|
1072 | {
|
---|
1073 | Document* document = contextDocument();
|
---|
1074 | if (!document || !document->page())
|
---|
1075 | return 0;
|
---|
1076 |
|
---|
1077 | return document->page()->chrome().client().remoteImagesCountForTesting();
|
---|
1078 | }
|
---|
1079 |
|
---|
1080 | void Internals::setLargeImageAsyncDecodingEnabledForTesting(HTMLImageElement& element, bool enabled)
|
---|
1081 | {
|
---|
1082 | if (auto* bitmapImage = bitmapImageFromImageElement(element))
|
---|
1083 | bitmapImage->setLargeImageAsyncDecodingEnabledForTesting(enabled);
|
---|
1084 | }
|
---|
1085 |
|
---|
1086 | void Internals::setForceUpdateImageDataEnabledForTesting(HTMLImageElement& element, bool enabled)
|
---|
1087 | {
|
---|
1088 | if (auto* cachedImage = element.cachedImage())
|
---|
1089 | cachedImage->setForceUpdateImageDataEnabledForTesting(enabled);
|
---|
1090 | }
|
---|
1091 |
|
---|
1092 | void Internals::setGridMaxTracksLimit(unsigned maxTrackLimit)
|
---|
1093 | {
|
---|
1094 | GridPosition::setMaxPositionForTesting(maxTrackLimit);
|
---|
1095 | }
|
---|
1096 |
|
---|
1097 | void Internals::clearBackForwardCache()
|
---|
1098 | {
|
---|
1099 | BackForwardCache::singleton().pruneToSizeNow(0, PruningReason::None);
|
---|
1100 | }
|
---|
1101 |
|
---|
1102 | unsigned Internals::backForwardCacheSize() const
|
---|
1103 | {
|
---|
1104 | return BackForwardCache::singleton().pageCount();
|
---|
1105 | }
|
---|
1106 |
|
---|
1107 | void Internals::preventDocumentFromEnteringBackForwardCache()
|
---|
1108 | {
|
---|
1109 | if (auto* document = contextDocument())
|
---|
1110 | document->preventEnteringBackForwardCacheForTesting();
|
---|
1111 | }
|
---|
1112 |
|
---|
1113 | void Internals::disableTileSizeUpdateDelay()
|
---|
1114 | {
|
---|
1115 | Document* document = contextDocument();
|
---|
1116 | if (!document || !document->frame())
|
---|
1117 | return;
|
---|
1118 |
|
---|
1119 | auto* view = document->frame()->view();
|
---|
1120 | if (!view)
|
---|
1121 | return;
|
---|
1122 |
|
---|
1123 | if (auto* backing = view->tiledBacking())
|
---|
1124 | backing->setTileSizeUpdateDelayDisabledForTesting(true);
|
---|
1125 | }
|
---|
1126 |
|
---|
1127 | void Internals::setSpeculativeTilingDelayDisabledForTesting(bool disabled)
|
---|
1128 | {
|
---|
1129 | Document* document = contextDocument();
|
---|
1130 | if (!document || !document->frame())
|
---|
1131 | return;
|
---|
1132 |
|
---|
1133 | if (auto* frameView = document->frame()->view())
|
---|
1134 | frameView->setSpeculativeTilingDelayDisabledForTesting(disabled);
|
---|
1135 | }
|
---|
1136 |
|
---|
1137 |
|
---|
1138 | Node* Internals::treeScopeRootNode(Node& node)
|
---|
1139 | {
|
---|
1140 | return &node.treeScope().rootNode();
|
---|
1141 | }
|
---|
1142 |
|
---|
1143 | Node* Internals::parentTreeScope(Node& node)
|
---|
1144 | {
|
---|
1145 | const TreeScope* parentTreeScope = node.treeScope().parentTreeScope();
|
---|
1146 | return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
|
---|
1147 | }
|
---|
1148 |
|
---|
1149 | ExceptionOr<unsigned> Internals::lastSpatialNavigationCandidateCount() const
|
---|
1150 | {
|
---|
1151 | if (!contextDocument() || !contextDocument()->page())
|
---|
1152 | return Exception { InvalidAccessError };
|
---|
1153 |
|
---|
1154 | return contextDocument()->page()->lastSpatialNavigationCandidateCount();
|
---|
1155 | }
|
---|
1156 |
|
---|
1157 | bool Internals::animationWithIdExists(const String& id) const
|
---|
1158 | {
|
---|
1159 | for (auto* animation : WebAnimation::instances()) {
|
---|
1160 | if (animation->id() == id)
|
---|
1161 | return true;
|
---|
1162 | }
|
---|
1163 | return false;
|
---|
1164 | }
|
---|
1165 |
|
---|
1166 | unsigned Internals::numberOfActiveAnimations() const
|
---|
1167 | {
|
---|
1168 | return frame()->document()->timeline().numberOfActiveAnimationsForTesting();
|
---|
1169 | }
|
---|
1170 |
|
---|
1171 | ExceptionOr<bool> Internals::animationsAreSuspended() const
|
---|
1172 | {
|
---|
1173 | Document* document = contextDocument();
|
---|
1174 | if (!document || !document->frame())
|
---|
1175 | return Exception { InvalidAccessError };
|
---|
1176 |
|
---|
1177 | return document->ensureTimelinesController().animationsAreSuspended();
|
---|
1178 | }
|
---|
1179 |
|
---|
1180 | double Internals::animationsInterval() const
|
---|
1181 | {
|
---|
1182 | Document* document = contextDocument();
|
---|
1183 | if (!document)
|
---|
1184 | return INFINITY;
|
---|
1185 |
|
---|
1186 | if (auto timeline = document->existingTimeline())
|
---|
1187 | return timeline->animationInterval().seconds();
|
---|
1188 | return INFINITY;
|
---|
1189 | }
|
---|
1190 |
|
---|
1191 | ExceptionOr<void> Internals::suspendAnimations() const
|
---|
1192 | {
|
---|
1193 | Document* document = contextDocument();
|
---|
1194 | if (!document || !document->frame())
|
---|
1195 | return Exception { InvalidAccessError };
|
---|
1196 |
|
---|
1197 | document->ensureTimelinesController().suspendAnimations();
|
---|
1198 | for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
|
---|
1199 | if (Document* document = frame->document())
|
---|
1200 | document->ensureTimelinesController().suspendAnimations();
|
---|
1201 | }
|
---|
1202 |
|
---|
1203 | return { };
|
---|
1204 | }
|
---|
1205 |
|
---|
1206 | ExceptionOr<void> Internals::resumeAnimations() const
|
---|
1207 | {
|
---|
1208 | Document* document = contextDocument();
|
---|
1209 | if (!document || !document->frame())
|
---|
1210 | return Exception { InvalidAccessError };
|
---|
1211 |
|
---|
1212 | document->ensureTimelinesController().resumeAnimations();
|
---|
1213 | for (Frame* frame = document->frame(); frame; frame = frame->tree().traverseNext()) {
|
---|
1214 | if (Document* document = frame->document())
|
---|
1215 | document->ensureTimelinesController().resumeAnimations();
|
---|
1216 | }
|
---|
1217 |
|
---|
1218 | return { };
|
---|
1219 | }
|
---|
1220 |
|
---|
1221 | Vector<Internals::AcceleratedAnimation> Internals::acceleratedAnimationsForElement(Element& element)
|
---|
1222 | {
|
---|
1223 | Vector<Internals::AcceleratedAnimation> animations;
|
---|
1224 | for (const auto& animationAsPair : element.document().timeline().acceleratedAnimationsForElement(element))
|
---|
1225 | animations.append({ animationAsPair.first, animationAsPair.second });
|
---|
1226 | return animations;
|
---|
1227 | }
|
---|
1228 |
|
---|
1229 | unsigned Internals::numberOfAnimationTimelineInvalidations() const
|
---|
1230 | {
|
---|
1231 | return frame()->document()->timeline().numberOfAnimationTimelineInvalidationsForTesting();
|
---|
1232 | }
|
---|
1233 |
|
---|
1234 | double Internals::timeToNextAnimationTick(WebAnimation& animation) const
|
---|
1235 | {
|
---|
1236 | return secondsToWebAnimationsAPITime(animation.timeToNextTick());
|
---|
1237 | }
|
---|
1238 |
|
---|
1239 | ExceptionOr<RefPtr<Element>> Internals::pseudoElement(Element& element, const String& pseudoId)
|
---|
1240 | {
|
---|
1241 | if (pseudoId != "before"_s && pseudoId != "after"_s)
|
---|
1242 | return Exception { InvalidAccessError };
|
---|
1243 |
|
---|
1244 | return pseudoId == "before"_s ? element.beforePseudoElement() : element.afterPseudoElement();
|
---|
1245 | }
|
---|
1246 |
|
---|
1247 | ExceptionOr<String> Internals::elementRenderTreeAsText(Element& element)
|
---|
1248 | {
|
---|
1249 | element.document().updateStyleIfNeeded();
|
---|
1250 |
|
---|
1251 | String representation = externalRepresentation(&element);
|
---|
1252 | if (representation.isEmpty())
|
---|
1253 | return Exception { InvalidAccessError };
|
---|
1254 |
|
---|
1255 | return representation;
|
---|
1256 | }
|
---|
1257 |
|
---|
1258 | bool Internals::hasPausedImageAnimations(Element& element)
|
---|
1259 | {
|
---|
1260 | return element.renderer() && element.renderer()->hasPausedImageAnimations();
|
---|
1261 | }
|
---|
1262 |
|
---|
1263 | bool Internals::isPaintingFrequently(Element& element)
|
---|
1264 | {
|
---|
1265 | return element.renderer() && element.renderer()->enclosingLayer() && element.renderer()->enclosingLayer()->paintingFrequently();
|
---|
1266 | }
|
---|
1267 |
|
---|
1268 | void Internals::incrementFrequentPaintCounter(Element& element)
|
---|
1269 | {
|
---|
1270 | if (element.renderer() && element.renderer()->enclosingLayer())
|
---|
1271 | element.renderer()->enclosingLayer()->simulateFrequentPaint();
|
---|
1272 | }
|
---|
1273 |
|
---|
1274 | Ref<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Element& element) const
|
---|
1275 | {
|
---|
1276 | bool allowVisitedStyle = true;
|
---|
1277 | return CSSComputedStyleDeclaration::create(element, allowVisitedStyle);
|
---|
1278 | }
|
---|
1279 |
|
---|
1280 | Node* Internals::ensureUserAgentShadowRoot(Element& host)
|
---|
1281 | {
|
---|
1282 | return &host.ensureUserAgentShadowRoot();
|
---|
1283 | }
|
---|
1284 |
|
---|
1285 | Node* Internals::shadowRoot(Element& host)
|
---|
1286 | {
|
---|
1287 | if (host.document().hasElementWithPendingUserAgentShadowTreeUpdate(host)) {
|
---|
1288 | host.updateUserAgentShadowTree();
|
---|
1289 | host.document().removeElementWithPendingUserAgentShadowTreeUpdate(host);
|
---|
1290 | }
|
---|
1291 | return host.shadowRoot();
|
---|
1292 | }
|
---|
1293 |
|
---|
1294 | ExceptionOr<String> Internals::shadowRootType(const Node& root) const
|
---|
1295 | {
|
---|
1296 | if (!is<ShadowRoot>(root))
|
---|
1297 | return Exception { InvalidAccessError };
|
---|
1298 |
|
---|
1299 | switch (downcast<ShadowRoot>(root).mode()) {
|
---|
1300 | case ShadowRootMode::UserAgent:
|
---|
1301 | return "UserAgentShadowRoot"_str;
|
---|
1302 | case ShadowRootMode::Closed:
|
---|
1303 | return "ClosedShadowRoot"_str;
|
---|
1304 | case ShadowRootMode::Open:
|
---|
1305 | return "OpenShadowRoot"_str;
|
---|
1306 | default:
|
---|
1307 | ASSERT_NOT_REACHED();
|
---|
1308 | return "Unknown"_str;
|
---|
1309 | }
|
---|
1310 | }
|
---|
1311 |
|
---|
1312 | const AtomString& Internals::shadowPseudoId(Element& element)
|
---|
1313 | {
|
---|
1314 | return element.shadowPseudoId();
|
---|
1315 | }
|
---|
1316 |
|
---|
1317 | void Internals::setShadowPseudoId(Element& element, const AtomString& id)
|
---|
1318 | {
|
---|
1319 | return element.setPseudo(id);
|
---|
1320 | }
|
---|
1321 |
|
---|
1322 | ExceptionOr<bool> Internals::isTimerThrottled(int timeoutId)
|
---|
1323 | {
|
---|
1324 | auto* timer = scriptExecutionContext()->findTimeout(timeoutId);
|
---|
1325 | if (!timer)
|
---|
1326 | return Exception { NotFoundError };
|
---|
1327 |
|
---|
1328 | if (timer->intervalClampedToMinimum() > timer->m_originalInterval)
|
---|
1329 | return true;
|
---|
1330 |
|
---|
1331 | return !!timer->alignedFireTime(MonotonicTime { });
|
---|
1332 | }
|
---|
1333 |
|
---|
1334 | String Internals::requestAnimationFrameThrottlingReasons() const
|
---|
1335 | {
|
---|
1336 | auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
|
---|
1337 | if (!scriptedAnimationController)
|
---|
1338 | return String();
|
---|
1339 |
|
---|
1340 | TextStream ts;
|
---|
1341 | ts << scriptedAnimationController->throttlingReasons();
|
---|
1342 | return ts.release();
|
---|
1343 | }
|
---|
1344 |
|
---|
1345 | double Internals::requestAnimationFrameInterval() const
|
---|
1346 | {
|
---|
1347 | auto* scriptedAnimationController = contextDocument()->scriptedAnimationController();
|
---|
1348 | if (!scriptedAnimationController)
|
---|
1349 | return INFINITY;
|
---|
1350 | return scriptedAnimationController->interval().value();
|
---|
1351 | }
|
---|
1352 |
|
---|
1353 | bool Internals::scriptedAnimationsAreSuspended() const
|
---|
1354 | {
|
---|
1355 | Document* document = contextDocument();
|
---|
1356 | if (!document || !document->page())
|
---|
1357 | return true;
|
---|
1358 |
|
---|
1359 | return document->page()->scriptedAnimationsSuspended();
|
---|
1360 | }
|
---|
1361 |
|
---|
1362 | bool Internals::areTimersThrottled() const
|
---|
1363 | {
|
---|
1364 | return contextDocument()->isTimerThrottlingEnabled();
|
---|
1365 | }
|
---|
1366 |
|
---|
1367 | void Internals::setEventThrottlingBehaviorOverride(std::optional<EventThrottlingBehavior> value)
|
---|
1368 | {
|
---|
1369 | Document* document = contextDocument();
|
---|
1370 | if (!document || !document->page())
|
---|
1371 | return;
|
---|
1372 |
|
---|
1373 | if (!value) {
|
---|
1374 | document->page()->setEventThrottlingBehaviorOverride(std::nullopt);
|
---|
1375 | return;
|
---|
1376 | }
|
---|
1377 |
|
---|
1378 | switch (value.value()) {
|
---|
1379 | case Internals::EventThrottlingBehavior::Responsive:
|
---|
1380 | document->page()->setEventThrottlingBehaviorOverride(WebCore::EventThrottlingBehavior::Responsive);
|
---|
1381 | break;
|
---|
1382 | case Internals::EventThrottlingBehavior::Unresponsive:
|
---|
1383 | document->page()->setEventThrottlingBehaviorOverride(WebCore::EventThrottlingBehavior::Unresponsive);
|
---|
1384 | break;
|
---|
1385 | }
|
---|
1386 | }
|
---|
1387 |
|
---|
1388 | std::optional<Internals::EventThrottlingBehavior> Internals::eventThrottlingBehaviorOverride() const
|
---|
1389 | {
|
---|
1390 | Document* document = contextDocument();
|
---|
1391 | if (!document || !document->page())
|
---|
1392 | return std::nullopt;
|
---|
1393 |
|
---|
1394 | auto behavior = document->page()->eventThrottlingBehaviorOverride();
|
---|
1395 | if (!behavior)
|
---|
1396 | return std::nullopt;
|
---|
1397 |
|
---|
1398 | switch (behavior.value()) {
|
---|
1399 | case WebCore::EventThrottlingBehavior::Responsive:
|
---|
1400 | return Internals::EventThrottlingBehavior::Responsive;
|
---|
1401 | case WebCore::EventThrottlingBehavior::Unresponsive:
|
---|
1402 | return Internals::EventThrottlingBehavior::Unresponsive;
|
---|
1403 | }
|
---|
1404 |
|
---|
1405 | return std::nullopt;
|
---|
1406 | }
|
---|
1407 |
|
---|
1408 | String Internals::visiblePlaceholder(Element& element)
|
---|
1409 | {
|
---|
1410 | if (is<HTMLTextFormControlElement>(element)) {
|
---|
1411 | const HTMLTextFormControlElement& textFormControlElement = downcast<HTMLTextFormControlElement>(element);
|
---|
1412 | if (!textFormControlElement.isPlaceholderVisible())
|
---|
1413 | return String();
|
---|
1414 | if (HTMLElement* placeholderElement = textFormControlElement.placeholderElement())
|
---|
1415 | return placeholderElement->textContent();
|
---|
1416 | }
|
---|
1417 |
|
---|
1418 | return String();
|
---|
1419 | }
|
---|
1420 |
|
---|
1421 | void Internals::setCanShowPlaceholder(Element& element, bool canShowPlaceholder)
|
---|
1422 | {
|
---|
1423 | if (is<HTMLTextFormControlElement>(element))
|
---|
1424 | downcast<HTMLTextFormControlElement>(element).setCanShowPlaceholder(canShowPlaceholder);
|
---|
1425 | }
|
---|
1426 |
|
---|
1427 | Element* Internals::insertTextPlaceholder(int width, int height)
|
---|
1428 | {
|
---|
1429 | return frame()->editor().insertTextPlaceholder(IntSize { width, height }).get();
|
---|
1430 | }
|
---|
1431 |
|
---|
1432 | void Internals::removeTextPlaceholder(Element& element)
|
---|
1433 | {
|
---|
1434 | if (is<TextPlaceholderElement>(element))
|
---|
1435 | frame()->editor().removeTextPlaceholder(downcast<TextPlaceholderElement>(element));
|
---|
1436 | }
|
---|
1437 |
|
---|
1438 | void Internals::selectColorInColorChooser(HTMLInputElement& element, const String& colorValue)
|
---|
1439 | {
|
---|
1440 | element.selectColor(colorValue);
|
---|
1441 | }
|
---|
1442 |
|
---|
1443 | ExceptionOr<Vector<AtomString>> Internals::formControlStateOfPreviousHistoryItem()
|
---|
1444 | {
|
---|
1445 | HistoryItem* mainItem = frame()->loader().history().previousItem();
|
---|
1446 | if (!mainItem)
|
---|
1447 | return Exception { InvalidAccessError };
|
---|
1448 | auto uniqueName = frame()->tree().uniqueName();
|
---|
1449 | if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName))
|
---|
1450 | return Exception { InvalidAccessError };
|
---|
1451 | return Vector<AtomString> { mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState() };
|
---|
1452 | }
|
---|
1453 |
|
---|
1454 | ExceptionOr<void> Internals::setFormControlStateOfPreviousHistoryItem(const Vector<AtomString>& state)
|
---|
1455 | {
|
---|
1456 | HistoryItem* mainItem = frame()->loader().history().previousItem();
|
---|
1457 | if (!mainItem)
|
---|
1458 | return Exception { InvalidAccessError };
|
---|
1459 | auto uniqueName = frame()->tree().uniqueName();
|
---|
1460 | if (mainItem->target() == uniqueName)
|
---|
1461 | mainItem->setDocumentState(state);
|
---|
1462 | else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
|
---|
1463 | subItem->setDocumentState(state);
|
---|
1464 | else
|
---|
1465 | return Exception { InvalidAccessError };
|
---|
1466 | return { };
|
---|
1467 | }
|
---|
1468 |
|
---|
1469 | #if ENABLE(SPEECH_SYNTHESIS)
|
---|
1470 |
|
---|
1471 | void Internals::enableMockSpeechSynthesizer()
|
---|
1472 | {
|
---|
1473 | Document* document = contextDocument();
|
---|
1474 | if (!document || !document->domWindow())
|
---|
1475 | return;
|
---|
1476 | SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(*document->domWindow());
|
---|
1477 | if (!synthesis)
|
---|
1478 | return;
|
---|
1479 |
|
---|
1480 | synthesis->setPlatformSynthesizer(makeUnique<PlatformSpeechSynthesizerMock>(synthesis));
|
---|
1481 | }
|
---|
1482 |
|
---|
1483 | #endif
|
---|
1484 |
|
---|
1485 | #if ENABLE(WEB_RTC)
|
---|
1486 |
|
---|
1487 | void Internals::emulateRTCPeerConnectionPlatformEvent(RTCPeerConnection& connection, const String& action)
|
---|
1488 | {
|
---|
1489 | if (!LibWebRTCProvider::webRTCAvailable())
|
---|
1490 | return;
|
---|
1491 |
|
---|
1492 | connection.emulatePlatformEvent(action);
|
---|
1493 | }
|
---|
1494 |
|
---|
1495 | void Internals::useMockRTCPeerConnectionFactory(const String& testCase)
|
---|
1496 | {
|
---|
1497 | if (!LibWebRTCProvider::webRTCAvailable())
|
---|
1498 | return;
|
---|
1499 |
|
---|
1500 | #if USE(LIBWEBRTC)
|
---|
1501 | Document* document = contextDocument();
|
---|
1502 | LibWebRTCProvider* provider = (document && document->page()) ? &document->page()->libWebRTCProvider() : nullptr;
|
---|
1503 | WebCore::useMockRTCPeerConnectionFactory(provider, testCase);
|
---|
1504 | #else
|
---|
1505 | UNUSED_PARAM(testCase);
|
---|
1506 | #endif
|
---|
1507 | }
|
---|
1508 |
|
---|
1509 | void Internals::setICECandidateFiltering(bool enabled)
|
---|
1510 | {
|
---|
1511 | auto* page = contextDocument()->page();
|
---|
1512 | if (!page)
|
---|
1513 | return;
|
---|
1514 |
|
---|
1515 | auto& rtcController = page->rtcController();
|
---|
1516 | if (enabled)
|
---|
1517 | rtcController.enableICECandidateFiltering();
|
---|
1518 | else
|
---|
1519 | rtcController.disableICECandidateFilteringForAllOrigins();
|
---|
1520 | }
|
---|
1521 |
|
---|
1522 | void Internals::setEnumeratingAllNetworkInterfacesEnabled(bool enabled)
|
---|
1523 | {
|
---|
1524 | #if USE(LIBWEBRTC)
|
---|
1525 | Document* document = contextDocument();
|
---|
1526 | auto* page = document->page();
|
---|
1527 | if (!page)
|
---|
1528 | return;
|
---|
1529 | auto& rtcProvider = page->libWebRTCProvider();
|
---|
1530 | if (enabled)
|
---|
1531 | rtcProvider.enableEnumeratingAllNetworkInterfaces();
|
---|
1532 | else
|
---|
1533 | rtcProvider.disableEnumeratingAllNetworkInterfaces();
|
---|
1534 | #else
|
---|
1535 | UNUSED_PARAM(enabled);
|
---|
1536 | #endif
|
---|
1537 | }
|
---|
1538 |
|
---|
1539 | void Internals::stopPeerConnection(RTCPeerConnection& connection)
|
---|
1540 | {
|
---|
1541 | ActiveDOMObject& object = connection;
|
---|
1542 | object.stop();
|
---|
1543 | }
|
---|
1544 |
|
---|
1545 | void Internals::clearPeerConnectionFactory()
|
---|
1546 | {
|
---|
1547 | #if USE(LIBWEBRTC)
|
---|
1548 | if (auto* page = contextDocument()->page())
|
---|
1549 | page->libWebRTCProvider().clearFactory();
|
---|
1550 | #endif
|
---|
1551 | }
|
---|
1552 |
|
---|
1553 | void Internals::applyRotationForOutgoingVideoSources(RTCPeerConnection& connection)
|
---|
1554 | {
|
---|
1555 | connection.applyRotationForOutgoingVideoSources();
|
---|
1556 | }
|
---|
1557 |
|
---|
1558 | void Internals::setWebRTCH265Support(bool value)
|
---|
1559 | {
|
---|
1560 | #if USE(LIBWEBRTC)
|
---|
1561 | if (auto* page = contextDocument()->page()) {
|
---|
1562 | page->libWebRTCProvider().setH265Support(value);
|
---|
1563 | page->libWebRTCProvider().clearFactory();
|
---|
1564 | }
|
---|
1565 | #else
|
---|
1566 | UNUSED_PARAM(value);
|
---|
1567 | #endif
|
---|
1568 | }
|
---|
1569 |
|
---|
1570 | void Internals::setWebRTCVP9Support(bool supportVP9Profile0, bool supportVP9Profile2)
|
---|
1571 | {
|
---|
1572 | #if USE(LIBWEBRTC)
|
---|
1573 | if (auto* page = contextDocument()->page()) {
|
---|
1574 | page->libWebRTCProvider().setVP9Support(supportVP9Profile0, supportVP9Profile2);
|
---|
1575 | page->libWebRTCProvider().clearFactory();
|
---|
1576 | }
|
---|
1577 | #else
|
---|
1578 | UNUSED_PARAM(supportVP9Profile0);
|
---|
1579 | UNUSED_PARAM(supportVP9Profile2);
|
---|
1580 | #endif
|
---|
1581 | }
|
---|
1582 |
|
---|
1583 | void Internals::setWebRTCVP9VTBSupport(bool value)
|
---|
1584 | {
|
---|
1585 | #if USE(LIBWEBRTC)
|
---|
1586 | if (auto* page = contextDocument()->page()) {
|
---|
1587 | page->libWebRTCProvider().setVP9VTBSupport(value);
|
---|
1588 | page->libWebRTCProvider().clearFactory();
|
---|
1589 | }
|
---|
1590 | #else
|
---|
1591 | UNUSED_PARAM(value);
|
---|
1592 | #endif
|
---|
1593 | }
|
---|
1594 |
|
---|
1595 | bool Internals::isSupportingVP9VTB() const
|
---|
1596 | {
|
---|
1597 | #if USE(LIBWEBRTC)
|
---|
1598 | if (auto* page = contextDocument()->page())
|
---|
1599 | return page->libWebRTCProvider().isSupportingVP9VTB();
|
---|
1600 | #endif
|
---|
1601 | return false;
|
---|
1602 | }
|
---|
1603 |
|
---|
1604 | void Internals::isVP9VTBDeccoderUsed(RTCPeerConnection& connection, DOMPromiseDeferred<IDLBoolean>&& promise)
|
---|
1605 | {
|
---|
1606 | connection.gatherDecoderImplementationName([promise = WTFMove(promise)](auto&& name) mutable {
|
---|
1607 | promise.resolve(name.contains("VideoToolBox"_s));
|
---|
1608 | });
|
---|
1609 | }
|
---|
1610 |
|
---|
1611 | void Internals::setSFrameCounter(RTCRtpSFrameTransform& transform, const String& counter)
|
---|
1612 | {
|
---|
1613 | if (auto value = parseInteger<uint64_t>(counter))
|
---|
1614 | transform.setCounterForTesting(*value);
|
---|
1615 | }
|
---|
1616 |
|
---|
1617 | uint64_t Internals::sframeCounter(const RTCRtpSFrameTransform& transform)
|
---|
1618 | {
|
---|
1619 | return transform.counterForTesting();
|
---|
1620 | }
|
---|
1621 |
|
---|
1622 | uint64_t Internals::sframeKeyId(const RTCRtpSFrameTransform& transform)
|
---|
1623 | {
|
---|
1624 | return transform.keyIdForTesting();
|
---|
1625 | }
|
---|
1626 |
|
---|
1627 | void Internals::setEnableWebRTCEncryption(bool value)
|
---|
1628 | {
|
---|
1629 | #if USE(LIBWEBRTC)
|
---|
1630 | if (auto* page = contextDocument()->page())
|
---|
1631 | page->settings().setWebRTCEncryptionEnabled(value);
|
---|
1632 | #else
|
---|
1633 | UNUSED_PARAM(value);
|
---|
1634 | #endif
|
---|
1635 | }
|
---|
1636 |
|
---|
1637 | void Internals::setUseDTLS10(bool useDTLS10)
|
---|
1638 | {
|
---|
1639 | #if USE(LIBWEBRTC)
|
---|
1640 | auto* document = contextDocument();
|
---|
1641 | if (!document || !document->page())
|
---|
1642 | return;
|
---|
1643 | document->page()->libWebRTCProvider().setUseDTLS10(useDTLS10);
|
---|
1644 | #else
|
---|
1645 | UNUSED_PARAM(useDTLS10);
|
---|
1646 | #endif
|
---|
1647 | }
|
---|
1648 |
|
---|
1649 | #endif
|
---|
1650 |
|
---|
1651 | #if ENABLE(MEDIA_STREAM)
|
---|
1652 | void Internals::setShouldInterruptAudioOnPageVisibilityChange(bool shouldInterrupt)
|
---|
1653 | {
|
---|
1654 | Document* document = contextDocument();
|
---|
1655 | if (auto* page = document->page())
|
---|
1656 | page->settings().setInterruptAudioOnPageVisibilityChangeEnabled(shouldInterrupt);
|
---|
1657 | }
|
---|
1658 | #endif // ENABLE(MEDIA_STREAM)
|
---|
1659 |
|
---|
1660 | #if ENABLE(MEDIA_RECORDER)
|
---|
1661 | static ExceptionOr<std::unique_ptr<MediaRecorderPrivate>> createRecorderMockSource(MediaStreamPrivate& stream, const MediaRecorderPrivateOptions&)
|
---|
1662 | {
|
---|
1663 | return std::unique_ptr<MediaRecorderPrivate>(new MediaRecorderPrivateMock(stream));
|
---|
1664 | }
|
---|
1665 |
|
---|
1666 | void Internals::setCustomPrivateRecorderCreator()
|
---|
1667 | {
|
---|
1668 | WebCore::MediaRecorder::setCustomPrivateRecorderCreator(createRecorderMockSource);
|
---|
1669 | }
|
---|
1670 | #endif // ENABLE(MEDIA_RECORDER)
|
---|
1671 |
|
---|
1672 | ExceptionOr<Ref<DOMRect>> Internals::absoluteLineRectFromPoint(int x, int y)
|
---|
1673 | {
|
---|
1674 | if (!contextDocument() || !contextDocument()->page())
|
---|
1675 | return Exception { InvalidAccessError };
|
---|
1676 |
|
---|
1677 | auto& document = *contextDocument();
|
---|
1678 | if (!document.frame() || !document.view())
|
---|
1679 | return Exception { InvalidAccessError };
|
---|
1680 |
|
---|
1681 | auto& frame = *document.frame();
|
---|
1682 | auto& view = *document.view();
|
---|
1683 | document.updateLayoutIgnorePendingStylesheets();
|
---|
1684 |
|
---|
1685 | auto position = frame.visiblePositionForPoint(view.rootViewToContents(IntPoint { x, y }));
|
---|
1686 | return DOMRect::create(position.absoluteSelectionBoundsForLine());
|
---|
1687 | }
|
---|
1688 |
|
---|
1689 | ExceptionOr<Ref<DOMRect>> Internals::absoluteCaretBounds()
|
---|
1690 | {
|
---|
1691 | Document* document = contextDocument();
|
---|
1692 | if (!document || !document->frame())
|
---|
1693 | return Exception { InvalidAccessError };
|
---|
1694 |
|
---|
1695 | return DOMRect::create(document->frame()->selection().absoluteCaretBounds());
|
---|
1696 | }
|
---|
1697 |
|
---|
1698 | ExceptionOr<bool> Internals::isCaretBlinkingSuspended()
|
---|
1699 | {
|
---|
1700 | Document* document = contextDocument();
|
---|
1701 | if (!document || !document->frame())
|
---|
1702 | return Exception { InvalidAccessError };
|
---|
1703 |
|
---|
1704 | return document->frame()->selection().isCaretBlinkingSuspended();
|
---|
1705 | }
|
---|
1706 |
|
---|
1707 | Ref<DOMRect> Internals::boundingBox(Element& element)
|
---|
1708 | {
|
---|
1709 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
1710 | auto renderer = element.renderer();
|
---|
1711 | if (!renderer)
|
---|
1712 | return DOMRect::create();
|
---|
1713 | return DOMRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
|
---|
1714 | }
|
---|
1715 |
|
---|
1716 | ExceptionOr<unsigned> Internals::inspectorGridOverlayCount()
|
---|
1717 | {
|
---|
1718 | Document* document = contextDocument();
|
---|
1719 | if (!document || !document->page())
|
---|
1720 | return Exception { InvalidAccessError };
|
---|
1721 |
|
---|
1722 | return document->page()->inspectorController().gridOverlayCount();
|
---|
1723 | }
|
---|
1724 |
|
---|
1725 | ExceptionOr<unsigned> Internals::inspectorFlexOverlayCount()
|
---|
1726 | {
|
---|
1727 | Document* document = contextDocument();
|
---|
1728 | if (!document || !document->page())
|
---|
1729 | return Exception { InvalidAccessError };
|
---|
1730 |
|
---|
1731 | return document->page()->inspectorController().flexOverlayCount();
|
---|
1732 | }
|
---|
1733 |
|
---|
1734 | ExceptionOr<Ref<DOMRectList>> Internals::inspectorHighlightRects()
|
---|
1735 | {
|
---|
1736 | Document* document = contextDocument();
|
---|
1737 | if (!document || !document->page())
|
---|
1738 | return Exception { InvalidAccessError };
|
---|
1739 |
|
---|
1740 | InspectorOverlay::Highlight highlight;
|
---|
1741 | document->page()->inspectorController().getHighlight(highlight, InspectorOverlay::CoordinateSystem::View);
|
---|
1742 | return DOMRectList::create(highlight.quads);
|
---|
1743 | }
|
---|
1744 |
|
---|
1745 | ExceptionOr<unsigned> Internals::inspectorPaintRectCount()
|
---|
1746 | {
|
---|
1747 | auto document = contextDocument();
|
---|
1748 | if (!document || !document->page())
|
---|
1749 | return Exception { InvalidAccessError };
|
---|
1750 |
|
---|
1751 | return document->page()->inspectorController().paintRectCount();
|
---|
1752 | }
|
---|
1753 |
|
---|
1754 | ExceptionOr<unsigned> Internals::markerCountForNode(Node& node, const String& markerType)
|
---|
1755 | {
|
---|
1756 | OptionSet<DocumentMarker::MarkerType> markerTypes;
|
---|
1757 | if (!markerTypesFrom(markerType, markerTypes))
|
---|
1758 | return Exception { SyntaxError };
|
---|
1759 |
|
---|
1760 | node.document().editor().updateEditorUINowIfScheduled();
|
---|
1761 | return node.document().markers().markersFor(node, markerTypes).size();
|
---|
1762 | }
|
---|
1763 |
|
---|
1764 | ExceptionOr<RenderedDocumentMarker*> Internals::markerAt(Node& node, const String& markerType, unsigned index)
|
---|
1765 | {
|
---|
1766 | node.document().updateLayoutIgnorePendingStylesheets();
|
---|
1767 |
|
---|
1768 | OptionSet<DocumentMarker::MarkerType> markerTypes;
|
---|
1769 | if (!markerTypesFrom(markerType, markerTypes))
|
---|
1770 | return Exception { SyntaxError };
|
---|
1771 |
|
---|
1772 | node.document().editor().updateEditorUINowIfScheduled();
|
---|
1773 |
|
---|
1774 | Vector<RenderedDocumentMarker*> markers = node.document().markers().markersFor(node, markerTypes);
|
---|
1775 | if (markers.size() <= index)
|
---|
1776 | return nullptr;
|
---|
1777 | return markers[index];
|
---|
1778 | }
|
---|
1779 |
|
---|
1780 | ExceptionOr<RefPtr<Range>> Internals::markerRangeForNode(Node& node, const String& markerType, unsigned index)
|
---|
1781 | {
|
---|
1782 | auto result = markerAt(node, markerType, index);
|
---|
1783 | if (result.hasException())
|
---|
1784 | return result.releaseException();
|
---|
1785 | auto marker = result.releaseReturnValue();
|
---|
1786 | if (!marker)
|
---|
1787 | return nullptr;
|
---|
1788 | return { createLiveRange(makeSimpleRange(node, *marker)) };
|
---|
1789 | }
|
---|
1790 |
|
---|
1791 | ExceptionOr<String> Internals::markerDescriptionForNode(Node& node, const String& markerType, unsigned index)
|
---|
1792 | {
|
---|
1793 | auto result = markerAt(node, markerType, index);
|
---|
1794 | if (result.hasException())
|
---|
1795 | return result.releaseException();
|
---|
1796 | auto marker = result.releaseReturnValue();
|
---|
1797 | if (!marker)
|
---|
1798 | return String();
|
---|
1799 | return String { marker->description() };
|
---|
1800 | }
|
---|
1801 |
|
---|
1802 | ExceptionOr<String> Internals::dumpMarkerRects(const String& markerTypeString)
|
---|
1803 | {
|
---|
1804 | DocumentMarker::MarkerType markerType;
|
---|
1805 | if (!markerTypeFrom(markerTypeString, markerType))
|
---|
1806 | return Exception { SyntaxError };
|
---|
1807 |
|
---|
1808 | contextDocument()->markers().updateRectsForInvalidatedMarkersOfType(markerType);
|
---|
1809 | auto rects = contextDocument()->markers().renderedRectsForMarkers(markerType);
|
---|
1810 |
|
---|
1811 | // FIXME: Using fixed precision here for width because of test results that contain numbers with specific precision. Would be nice to update the test results and move to default formatting.
|
---|
1812 | StringBuilder rectString;
|
---|
1813 | rectString.append("marker rects: ");
|
---|
1814 | for (const auto& rect : rects)
|
---|
1815 | rectString.append('(', rect.x(), ", ", rect.y(), ", ", FormattedNumber::fixedPrecision(rect.width()), ", ", rect.height(), ") ");
|
---|
1816 | return rectString.toString();
|
---|
1817 | }
|
---|
1818 |
|
---|
1819 | ExceptionOr<void> Internals::setMarkedTextMatchesAreHighlighted(bool flag)
|
---|
1820 | {
|
---|
1821 | Document* document = contextDocument();
|
---|
1822 | if (!document || !document->frame())
|
---|
1823 | return Exception { InvalidAccessError };
|
---|
1824 | document->editor().setMarkedTextMatchesAreHighlighted(flag);
|
---|
1825 | return { };
|
---|
1826 | }
|
---|
1827 |
|
---|
1828 | void Internals::invalidateFontCache()
|
---|
1829 | {
|
---|
1830 | FontCache::invalidateAllFontCaches();
|
---|
1831 | }
|
---|
1832 |
|
---|
1833 | void Internals::setFontSmoothingEnabled(bool enabled)
|
---|
1834 | {
|
---|
1835 | FontCascade::setShouldUseSmoothing(enabled);
|
---|
1836 | }
|
---|
1837 |
|
---|
1838 | ExceptionOr<void> Internals::setLowPowerModeEnabled(bool isEnabled)
|
---|
1839 | {
|
---|
1840 | auto* document = contextDocument();
|
---|
1841 | if (!document)
|
---|
1842 | return Exception { InvalidAccessError };
|
---|
1843 | auto* page = document->page();
|
---|
1844 | if (!page)
|
---|
1845 | return Exception { InvalidAccessError };
|
---|
1846 |
|
---|
1847 | page->setLowPowerModeEnabledOverrideForTesting(isEnabled);
|
---|
1848 | return { };
|
---|
1849 | }
|
---|
1850 |
|
---|
1851 | ExceptionOr<void> Internals::setOutsideViewportThrottlingEnabled(bool isEnabled)
|
---|
1852 | {
|
---|
1853 | auto* document = contextDocument();
|
---|
1854 | if (!document)
|
---|
1855 | return Exception { InvalidAccessError };
|
---|
1856 | auto* page = document->page();
|
---|
1857 | if (!page)
|
---|
1858 | return Exception { InvalidAccessError };
|
---|
1859 |
|
---|
1860 | page->setOutsideViewportThrottlingEnabledForTesting(isEnabled);
|
---|
1861 | return { };
|
---|
1862 | }
|
---|
1863 |
|
---|
1864 | ExceptionOr<void> Internals::setScrollViewPosition(int x, int y)
|
---|
1865 | {
|
---|
1866 | Document* document = contextDocument();
|
---|
1867 | if (!document || !document->view())
|
---|
1868 | return Exception { InvalidAccessError };
|
---|
1869 |
|
---|
1870 | auto& frameView = *document->view();
|
---|
1871 | auto oldClamping = frameView.scrollClamping();
|
---|
1872 | bool scrollbarsSuppressedOldValue = frameView.scrollbarsSuppressed();
|
---|
1873 |
|
---|
1874 | frameView.setScrollClamping(ScrollClamping::Unclamped);
|
---|
1875 | frameView.setScrollbarsSuppressed(false);
|
---|
1876 | frameView.setScrollOffsetFromInternals({ x, y });
|
---|
1877 | frameView.setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
|
---|
1878 | frameView.setScrollClamping(oldClamping);
|
---|
1879 |
|
---|
1880 | return { };
|
---|
1881 | }
|
---|
1882 |
|
---|
1883 | ExceptionOr<void> Internals::unconstrainedScrollTo(Element& element, double x, double y)
|
---|
1884 | {
|
---|
1885 | Document* document = contextDocument();
|
---|
1886 | if (!document || !document->view())
|
---|
1887 | return Exception { InvalidAccessError };
|
---|
1888 |
|
---|
1889 | element.scrollTo(ScrollToOptions(x, y), ScrollClamping::Unclamped);
|
---|
1890 |
|
---|
1891 | auto& frameView = *document->view();
|
---|
1892 | frameView.setViewportConstrainedObjectsNeedLayout();
|
---|
1893 |
|
---|
1894 | return { };
|
---|
1895 | }
|
---|
1896 |
|
---|
1897 | ExceptionOr<void> Internals::scrollBySimulatingWheelEvent(Element& element, double deltaX, double deltaY)
|
---|
1898 | {
|
---|
1899 | Document* document = contextDocument();
|
---|
1900 | if (!document || !document->view())
|
---|
1901 | return Exception { InvalidAccessError };
|
---|
1902 |
|
---|
1903 | if (!element.renderBox())
|
---|
1904 | return Exception { InvalidAccessError };
|
---|
1905 |
|
---|
1906 | RenderBox& box = *element.renderBox();
|
---|
1907 | ScrollableArea* scrollableArea;
|
---|
1908 |
|
---|
1909 | if (&element == document->scrollingElementForAPI()) {
|
---|
1910 | FrameView* frameView = box.frame().mainFrame().view();
|
---|
1911 | if (!frameView || !frameView->isScrollable())
|
---|
1912 | return Exception { InvalidAccessError };
|
---|
1913 |
|
---|
1914 | scrollableArea = frameView;
|
---|
1915 | } else {
|
---|
1916 | if (!box.canBeScrolledAndHasScrollableArea())
|
---|
1917 | return Exception { InvalidAccessError };
|
---|
1918 |
|
---|
1919 | ASSERT(box.layer());
|
---|
1920 | scrollableArea = box.layer()->scrollableArea();
|
---|
1921 | }
|
---|
1922 |
|
---|
1923 | if (!scrollableArea)
|
---|
1924 | return Exception { InvalidAccessError };
|
---|
1925 |
|
---|
1926 | auto scrollingNodeID = scrollableArea->scrollingNodeID();
|
---|
1927 | if (!scrollingNodeID)
|
---|
1928 | return Exception { InvalidAccessError };
|
---|
1929 |
|
---|
1930 | auto page = document->page();
|
---|
1931 | if (!page)
|
---|
1932 | return Exception { InvalidAccessError };
|
---|
1933 |
|
---|
1934 | auto scrollingCoordinator = page->scrollingCoordinator();
|
---|
1935 | if (!scrollingCoordinator)
|
---|
1936 | return Exception { InvalidAccessError };
|
---|
1937 |
|
---|
1938 | scrollingCoordinator->scrollBySimulatingWheelEventForTesting(scrollingNodeID, FloatSize(deltaX, deltaY));
|
---|
1939 |
|
---|
1940 | return { };
|
---|
1941 | }
|
---|
1942 |
|
---|
1943 | ExceptionOr<Ref<DOMRect>> Internals::layoutViewportRect()
|
---|
1944 | {
|
---|
1945 | Document* document = contextDocument();
|
---|
1946 | if (!document || !document->frame())
|
---|
1947 | return Exception { InvalidAccessError };
|
---|
1948 |
|
---|
1949 | document->updateLayoutIgnorePendingStylesheets();
|
---|
1950 |
|
---|
1951 | auto& frameView = *document->view();
|
---|
1952 | return DOMRect::create(frameView.layoutViewportRect());
|
---|
1953 | }
|
---|
1954 |
|
---|
1955 | ExceptionOr<Ref<DOMRect>> Internals::visualViewportRect()
|
---|
1956 | {
|
---|
1957 | Document* document = contextDocument();
|
---|
1958 | if (!document || !document->frame())
|
---|
1959 | return Exception { InvalidAccessError };
|
---|
1960 |
|
---|
1961 | document->updateLayoutIgnorePendingStylesheets();
|
---|
1962 |
|
---|
1963 | auto& frameView = *document->view();
|
---|
1964 | return DOMRect::create(frameView.visualViewportRect());
|
---|
1965 | }
|
---|
1966 |
|
---|
1967 | ExceptionOr<void> Internals::setViewIsTransparent(bool transparent)
|
---|
1968 | {
|
---|
1969 | Document* document = contextDocument();
|
---|
1970 | if (!document || !document->view())
|
---|
1971 | return Exception { InvalidAccessError };
|
---|
1972 | std::optional<Color> backgroundColor;
|
---|
1973 | if (transparent)
|
---|
1974 | backgroundColor = Color(Color::transparentBlack);
|
---|
1975 | document->view()->updateBackgroundRecursively(backgroundColor);
|
---|
1976 | return { };
|
---|
1977 | }
|
---|
1978 |
|
---|
1979 | ExceptionOr<String> Internals::viewBaseBackgroundColor()
|
---|
1980 | {
|
---|
1981 | Document* document = contextDocument();
|
---|
1982 | if (!document || !document->view())
|
---|
1983 | return Exception { InvalidAccessError };
|
---|
1984 | return serializationForCSS(document->view()->baseBackgroundColor());
|
---|
1985 | }
|
---|
1986 |
|
---|
1987 | ExceptionOr<void> Internals::setViewBaseBackgroundColor(const String& colorValue)
|
---|
1988 | {
|
---|
1989 | Document* document = contextDocument();
|
---|
1990 | if (!document || !document->view())
|
---|
1991 | return Exception { InvalidAccessError };
|
---|
1992 |
|
---|
1993 | if (colorValue == "transparent"_s) {
|
---|
1994 | document->view()->setBaseBackgroundColor(Color::transparentBlack);
|
---|
1995 | return { };
|
---|
1996 | }
|
---|
1997 | if (colorValue == "white"_s) {
|
---|
1998 | document->view()->setBaseBackgroundColor(Color::white);
|
---|
1999 | return { };
|
---|
2000 | }
|
---|
2001 | return Exception { SyntaxError };
|
---|
2002 | }
|
---|
2003 |
|
---|
2004 | ExceptionOr<void> Internals::setPagination(const String& mode, int gap, int pageLength)
|
---|
2005 | {
|
---|
2006 | Document* document = contextDocument();
|
---|
2007 | if (!document || !document->page())
|
---|
2008 | return Exception { InvalidAccessError };
|
---|
2009 |
|
---|
2010 | Pagination pagination;
|
---|
2011 | if (mode == "Unpaginated"_s)
|
---|
2012 | pagination.mode = Pagination::Unpaginated;
|
---|
2013 | else if (mode == "LeftToRightPaginated"_s)
|
---|
2014 | pagination.mode = Pagination::LeftToRightPaginated;
|
---|
2015 | else if (mode == "RightToLeftPaginated"_s)
|
---|
2016 | pagination.mode = Pagination::RightToLeftPaginated;
|
---|
2017 | else if (mode == "TopToBottomPaginated"_s)
|
---|
2018 | pagination.mode = Pagination::TopToBottomPaginated;
|
---|
2019 | else if (mode == "BottomToTopPaginated"_s)
|
---|
2020 | pagination.mode = Pagination::BottomToTopPaginated;
|
---|
2021 | else
|
---|
2022 | return Exception { SyntaxError };
|
---|
2023 |
|
---|
2024 | pagination.gap = gap;
|
---|
2025 | pagination.pageLength = pageLength;
|
---|
2026 | document->page()->setPagination(pagination);
|
---|
2027 |
|
---|
2028 | return { };
|
---|
2029 | }
|
---|
2030 |
|
---|
2031 | ExceptionOr<void> Internals::setPaginationLineGridEnabled(bool enabled)
|
---|
2032 | {
|
---|
2033 | Document* document = contextDocument();
|
---|
2034 | if (!document || !document->page())
|
---|
2035 | return Exception { InvalidAccessError };
|
---|
2036 | document->page()->setPaginationLineGridEnabled(enabled);
|
---|
2037 | return { };
|
---|
2038 | }
|
---|
2039 |
|
---|
2040 | ExceptionOr<uint64_t> Internals::lineIndexAfterPageBreak(Element& element)
|
---|
2041 | {
|
---|
2042 | Document* document = contextDocument();
|
---|
2043 | if (!document || !document->frame())
|
---|
2044 | return Exception { InvalidAccessError };
|
---|
2045 |
|
---|
2046 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
2047 |
|
---|
2048 | if (!element.renderer() || !is<RenderBlockFlow>(element.renderer()))
|
---|
2049 | return Exception { NotFoundError };
|
---|
2050 | auto& blockFlow = downcast<RenderBlockFlow>(*element.renderer());
|
---|
2051 | if (!blockFlow.childrenInline())
|
---|
2052 | return Exception { NotFoundError };
|
---|
2053 |
|
---|
2054 | size_t lineIndex = 0;
|
---|
2055 | for (auto lineBox = InlineIterator::firstLineBoxFor(blockFlow); lineBox; lineBox.traverseNext(), ++lineIndex) {
|
---|
2056 | if (lineBox->isFirstAfterPageBreak())
|
---|
2057 | return lineIndex;
|
---|
2058 | }
|
---|
2059 | return Exception { NotFoundError };
|
---|
2060 | }
|
---|
2061 |
|
---|
2062 | ExceptionOr<String> Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight)
|
---|
2063 | {
|
---|
2064 | Document* document = contextDocument();
|
---|
2065 | if (!document || !document->page())
|
---|
2066 | return Exception { InvalidAccessError };
|
---|
2067 |
|
---|
2068 | const int defaultLayoutWidthForNonMobilePages = 980;
|
---|
2069 |
|
---|
2070 | ViewportArguments arguments = document->page()->viewportArguments();
|
---|
2071 | ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
|
---|
2072 | restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
|
---|
2073 | restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
|
---|
2074 |
|
---|
2075 | // FIXME: Using fixed precision here because of test results that contain numbers with specific precision. Would be nice to update the test results and move to default formatting.
|
---|
2076 | return makeString("viewport size ", FormattedNumber::fixedPrecision(attributes.layoutSize.width()), 'x', FormattedNumber::fixedPrecision(attributes.layoutSize.height()), " scale ", FormattedNumber::fixedPrecision(attributes.initialScale), " with limits [", FormattedNumber::fixedPrecision(attributes.minimumScale), ", ", FormattedNumber::fixedPrecision(attributes.maximumScale), "] and userScalable ", (attributes.userScalable ? "true" : "false"));
|
---|
2077 | }
|
---|
2078 |
|
---|
2079 | ExceptionOr<bool> Internals::wasLastChangeUserEdit(Element& textField)
|
---|
2080 | {
|
---|
2081 | if (is<HTMLInputElement>(textField))
|
---|
2082 | return downcast<HTMLInputElement>(textField).lastChangeWasUserEdit();
|
---|
2083 |
|
---|
2084 | if (is<HTMLTextAreaElement>(textField))
|
---|
2085 | return downcast<HTMLTextAreaElement>(textField).lastChangeWasUserEdit();
|
---|
2086 |
|
---|
2087 | return Exception { InvalidNodeTypeError };
|
---|
2088 | }
|
---|
2089 |
|
---|
2090 | bool Internals::elementShouldAutoComplete(HTMLInputElement& element)
|
---|
2091 | {
|
---|
2092 | return element.shouldAutocomplete();
|
---|
2093 | }
|
---|
2094 |
|
---|
2095 | void Internals::setAutofilled(HTMLInputElement& element, bool enabled)
|
---|
2096 | {
|
---|
2097 | element.setAutoFilled(enabled);
|
---|
2098 | }
|
---|
2099 |
|
---|
2100 | void Internals::setAutoFilledAndViewable(HTMLInputElement& element, bool enabled)
|
---|
2101 | {
|
---|
2102 | element.setAutoFilledAndViewable(enabled);
|
---|
2103 | }
|
---|
2104 |
|
---|
2105 | void Internals::setAutoFilledAndObscured(HTMLInputElement& element, bool enabled)
|
---|
2106 | {
|
---|
2107 | element.setAutoFilledAndObscured(enabled);
|
---|
2108 | }
|
---|
2109 |
|
---|
2110 | static AutoFillButtonType toAutoFillButtonType(Internals::AutoFillButtonType type)
|
---|
2111 | {
|
---|
2112 | switch (type) {
|
---|
2113 | case Internals::AutoFillButtonType::None:
|
---|
2114 | return AutoFillButtonType::None;
|
---|
2115 | case Internals::AutoFillButtonType::Credentials:
|
---|
2116 | return AutoFillButtonType::Credentials;
|
---|
2117 | case Internals::AutoFillButtonType::Contacts:
|
---|
2118 | return AutoFillButtonType::Contacts;
|
---|
2119 | case Internals::AutoFillButtonType::StrongPassword:
|
---|
2120 | return AutoFillButtonType::StrongPassword;
|
---|
2121 | case Internals::AutoFillButtonType::CreditCard:
|
---|
2122 | return AutoFillButtonType::CreditCard;
|
---|
2123 | }
|
---|
2124 | ASSERT_NOT_REACHED();
|
---|
2125 | return AutoFillButtonType::None;
|
---|
2126 | }
|
---|
2127 |
|
---|
2128 | static Internals::AutoFillButtonType toInternalsAutoFillButtonType(AutoFillButtonType type)
|
---|
2129 | {
|
---|
2130 | switch (type) {
|
---|
2131 | case AutoFillButtonType::None:
|
---|
2132 | return Internals::AutoFillButtonType::None;
|
---|
2133 | case AutoFillButtonType::Credentials:
|
---|
2134 | return Internals::AutoFillButtonType::Credentials;
|
---|
2135 | case AutoFillButtonType::Contacts:
|
---|
2136 | return Internals::AutoFillButtonType::Contacts;
|
---|
2137 | case AutoFillButtonType::StrongPassword:
|
---|
2138 | return Internals::AutoFillButtonType::StrongPassword;
|
---|
2139 | case AutoFillButtonType::CreditCard:
|
---|
2140 | return Internals::AutoFillButtonType::CreditCard;
|
---|
2141 | }
|
---|
2142 | ASSERT_NOT_REACHED();
|
---|
2143 | return Internals::AutoFillButtonType::None;
|
---|
2144 | }
|
---|
2145 |
|
---|
2146 | void Internals::setShowAutoFillButton(HTMLInputElement& element, AutoFillButtonType type)
|
---|
2147 | {
|
---|
2148 | element.setShowAutoFillButton(toAutoFillButtonType(type));
|
---|
2149 | }
|
---|
2150 |
|
---|
2151 | auto Internals::autoFillButtonType(const HTMLInputElement& element) -> AutoFillButtonType
|
---|
2152 | {
|
---|
2153 | return toInternalsAutoFillButtonType(element.autoFillButtonType());
|
---|
2154 | }
|
---|
2155 |
|
---|
2156 | auto Internals::lastAutoFillButtonType(const HTMLInputElement& element) -> AutoFillButtonType
|
---|
2157 | {
|
---|
2158 | return toInternalsAutoFillButtonType(element.lastAutoFillButtonType());
|
---|
2159 | }
|
---|
2160 |
|
---|
2161 | ExceptionOr<void> Internals::scrollElementToRect(Element& element, int x, int y, int w, int h)
|
---|
2162 | {
|
---|
2163 | FrameView* frameView = element.document().view();
|
---|
2164 | if (!frameView)
|
---|
2165 | return Exception { InvalidAccessError };
|
---|
2166 | frameView->scrollElementToRect(element, { x, y, w, h });
|
---|
2167 | return { };
|
---|
2168 | }
|
---|
2169 |
|
---|
2170 | ExceptionOr<String> Internals::autofillFieldName(Element& element)
|
---|
2171 | {
|
---|
2172 | if (!is<HTMLFormControlElement>(element))
|
---|
2173 | return Exception { InvalidNodeTypeError };
|
---|
2174 |
|
---|
2175 | return String { downcast<HTMLFormControlElement>(element).autofillData().fieldName };
|
---|
2176 | }
|
---|
2177 |
|
---|
2178 | ExceptionOr<void> Internals::invalidateControlTints()
|
---|
2179 | {
|
---|
2180 | Document* document = contextDocument();
|
---|
2181 | if (!document || !document->view())
|
---|
2182 | return Exception { InvalidAccessError };
|
---|
2183 |
|
---|
2184 | document->view()->invalidateControlTints();
|
---|
2185 | return { };
|
---|
2186 | }
|
---|
2187 |
|
---|
2188 | static TextIteratorBehaviors toTextIteratorBehaviors(const Vector<String>& stringBehaviors)
|
---|
2189 | {
|
---|
2190 | TextIteratorBehaviors behaviors;
|
---|
2191 | for (const auto& stringBehavior : stringBehaviors) {
|
---|
2192 | if (stringBehavior == "IgnoresWhiteSpaceAtEndOfRun"_s)
|
---|
2193 | behaviors.add(TextIteratorBehavior::IgnoresWhiteSpaceAtEndOfRun);
|
---|
2194 | }
|
---|
2195 | return behaviors;
|
---|
2196 | }
|
---|
2197 |
|
---|
2198 | RefPtr<Range> Internals::rangeFromLocationAndLength(Element& scope, unsigned rangeLocation, unsigned rangeLength)
|
---|
2199 | {
|
---|
2200 | return createLiveRange(resolveCharacterRange(makeRangeSelectingNodeContents(scope), { rangeLocation, rangeLength }));
|
---|
2201 | }
|
---|
2202 |
|
---|
2203 | unsigned Internals::locationFromRange(Element& scope, const Range& range, const Vector<String>& stringBehaviors)
|
---|
2204 | {
|
---|
2205 | return clampTo<unsigned>(characterRange(makeBoundaryPointBeforeNodeContents(scope), makeSimpleRange(range), toTextIteratorBehaviors(stringBehaviors)).location);
|
---|
2206 | }
|
---|
2207 |
|
---|
2208 | unsigned Internals::lengthFromRange(Element& scope, const Range& range, const Vector<String>& stringBehaviors)
|
---|
2209 | {
|
---|
2210 | return clampTo<unsigned>(characterRange(makeBoundaryPointBeforeNodeContents(scope), makeSimpleRange(range), toTextIteratorBehaviors(stringBehaviors)).length);
|
---|
2211 | }
|
---|
2212 |
|
---|
2213 | String Internals::rangeAsText(const Range& liveRange)
|
---|
2214 | {
|
---|
2215 | auto range = makeSimpleRange(liveRange);
|
---|
2216 | range.start.document().updateLayout();
|
---|
2217 | return plainText(range);
|
---|
2218 | }
|
---|
2219 |
|
---|
2220 | // FIXME: Move this to StringConcatenate.h.
|
---|
2221 | static String join(Vector<String>&& strings)
|
---|
2222 | {
|
---|
2223 | StringBuilder result;
|
---|
2224 | for (auto& string : strings)
|
---|
2225 | result.append(WTFMove(string));
|
---|
2226 | return result.toString();
|
---|
2227 | }
|
---|
2228 |
|
---|
2229 | String Internals::rangeAsTextUsingBackwardsTextIterator(const Range& liveRange)
|
---|
2230 | {
|
---|
2231 | auto range = makeSimpleRange(liveRange);
|
---|
2232 | range.start.document().updateLayout();
|
---|
2233 | Vector<String> strings;
|
---|
2234 | for (SimplifiedBackwardsTextIterator backwardsIterator(range); !backwardsIterator.atEnd(); backwardsIterator.advance())
|
---|
2235 | strings.append(backwardsIterator.text().toString());
|
---|
2236 | strings.reverse();
|
---|
2237 | return join(WTFMove(strings));
|
---|
2238 | }
|
---|
2239 |
|
---|
2240 | Ref<Range> Internals::subrange(Range& liveRange, unsigned rangeLocation, unsigned rangeLength)
|
---|
2241 | {
|
---|
2242 | auto range = makeSimpleRange(liveRange);
|
---|
2243 | range.start.document().updateLayout();
|
---|
2244 | return createLiveRange(resolveCharacterRange(range, { rangeLocation, rangeLength }));
|
---|
2245 | }
|
---|
2246 |
|
---|
2247 | RefPtr<Range> Internals::rangeOfStringNearLocation(const Range& liveRange, const String& text, unsigned targetOffset)
|
---|
2248 | {
|
---|
2249 | auto range = makeSimpleRange(liveRange);
|
---|
2250 | range.start.document().updateLayout();
|
---|
2251 | return createLiveRange(findClosestPlainText(range, text, { }, targetOffset));
|
---|
2252 | }
|
---|
2253 |
|
---|
2254 | Vector<Internals::TextIteratorState> Internals::statesOfTextIterator(const Range& liveRange, const Vector<String>& stringBehaviors)
|
---|
2255 | {
|
---|
2256 | auto simpleRange = makeSimpleRange(liveRange);
|
---|
2257 | simpleRange.start.document().updateLayout();
|
---|
2258 |
|
---|
2259 | Vector<TextIteratorState> states;
|
---|
2260 | for (TextIterator it(simpleRange, toTextIteratorBehaviors(stringBehaviors)); !it.atEnd(); it.advance())
|
---|
2261 | states.append({ it.text().toString(), createLiveRange(it.range()) });
|
---|
2262 | return states;
|
---|
2263 | }
|
---|
2264 |
|
---|
2265 | #if !PLATFORM(MAC)
|
---|
2266 | ExceptionOr<RefPtr<Range>> Internals::rangeForDictionaryLookupAtLocation(int, int)
|
---|
2267 | {
|
---|
2268 | return Exception { InvalidAccessError };
|
---|
2269 | }
|
---|
2270 | #endif
|
---|
2271 |
|
---|
2272 | ExceptionOr<void> Internals::setDelegatesScrolling(bool enabled)
|
---|
2273 | {
|
---|
2274 | Document* document = contextDocument();
|
---|
2275 | // Delegate scrolling is valid only on mainframe's view.
|
---|
2276 | if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame())
|
---|
2277 | return Exception { InvalidAccessError };
|
---|
2278 |
|
---|
2279 | document->view()->setDelegatesScrolling(enabled);
|
---|
2280 | return { };
|
---|
2281 | }
|
---|
2282 |
|
---|
2283 | ExceptionOr<uint64_t> Internals::lastSpellCheckRequestSequence()
|
---|
2284 | {
|
---|
2285 | Document* document = contextDocument();
|
---|
2286 | if (!document || !document->frame())
|
---|
2287 | return Exception { InvalidAccessError };
|
---|
2288 |
|
---|
2289 | return document->editor().spellChecker().lastRequestIdentifier().toUInt64();
|
---|
2290 | }
|
---|
2291 |
|
---|
2292 | ExceptionOr<uint64_t> Internals::lastSpellCheckProcessedSequence()
|
---|
2293 | {
|
---|
2294 | Document* document = contextDocument();
|
---|
2295 | if (!document || !document->frame())
|
---|
2296 | return Exception { InvalidAccessError };
|
---|
2297 |
|
---|
2298 | return document->editor().spellChecker().lastProcessedIdentifier().toUInt64();
|
---|
2299 | }
|
---|
2300 |
|
---|
2301 | void Internals::advanceToNextMisspelling()
|
---|
2302 | {
|
---|
2303 | #if !PLATFORM(IOS_FAMILY)
|
---|
2304 | if (auto* document = contextDocument())
|
---|
2305 | document->editor().advanceToNextMisspelling();
|
---|
2306 | #endif
|
---|
2307 | }
|
---|
2308 |
|
---|
2309 | Vector<String> Internals::userPreferredLanguages() const
|
---|
2310 | {
|
---|
2311 | return WTF::userPreferredLanguages(ShouldMinimizeLanguages::No);
|
---|
2312 | }
|
---|
2313 |
|
---|
2314 | void Internals::setUserPreferredLanguages(const Vector<String>& languages)
|
---|
2315 | {
|
---|
2316 | overrideUserPreferredLanguages(languages);
|
---|
2317 | }
|
---|
2318 |
|
---|
2319 | Vector<String> Internals::userPreferredAudioCharacteristics() const
|
---|
2320 | {
|
---|
2321 | Document* document = contextDocument();
|
---|
2322 | if (!document || !document->page())
|
---|
2323 | return Vector<String>();
|
---|
2324 | #if ENABLE(VIDEO)
|
---|
2325 | return document->page()->group().ensureCaptionPreferences().preferredAudioCharacteristics();
|
---|
2326 | #else
|
---|
2327 | return Vector<String>();
|
---|
2328 | #endif
|
---|
2329 | }
|
---|
2330 |
|
---|
2331 | void Internals::setUserPreferredAudioCharacteristic(const String& characteristic)
|
---|
2332 | {
|
---|
2333 | Document* document = contextDocument();
|
---|
2334 | if (!document || !document->page())
|
---|
2335 | return;
|
---|
2336 | #if ENABLE(VIDEO)
|
---|
2337 | document->page()->group().ensureCaptionPreferences().setPreferredAudioCharacteristic(characteristic);
|
---|
2338 | #else
|
---|
2339 | UNUSED_PARAM(characteristic);
|
---|
2340 | #endif
|
---|
2341 | }
|
---|
2342 |
|
---|
2343 | ExceptionOr<unsigned> Internals::wheelEventHandlerCount()
|
---|
2344 | {
|
---|
2345 | Document* document = contextDocument();
|
---|
2346 | if (!document)
|
---|
2347 | return Exception { InvalidAccessError };
|
---|
2348 |
|
---|
2349 | return document->wheelEventHandlerCount();
|
---|
2350 | }
|
---|
2351 |
|
---|
2352 | ExceptionOr<unsigned> Internals::touchEventHandlerCount()
|
---|
2353 | {
|
---|
2354 | Document* document = contextDocument();
|
---|
2355 | if (!document)
|
---|
2356 | return Exception { InvalidAccessError };
|
---|
2357 |
|
---|
2358 | return document->touchEventHandlerCount();
|
---|
2359 | }
|
---|
2360 |
|
---|
2361 | ExceptionOr<Ref<DOMRectList>> Internals::touchEventRectsForEvent(const String& eventName)
|
---|
2362 | {
|
---|
2363 | Document* document = contextDocument();
|
---|
2364 | if (!document || !document->page())
|
---|
2365 | return Exception { InvalidAccessError };
|
---|
2366 |
|
---|
2367 | std::array<EventTrackingRegions::EventType, 4> touchEvents = { {
|
---|
2368 | EventTrackingRegions::EventType::Touchstart,
|
---|
2369 | EventTrackingRegions::EventType::Touchmove,
|
---|
2370 | EventTrackingRegions::EventType::Touchend,
|
---|
2371 | EventTrackingRegions::EventType::Touchforcechange,
|
---|
2372 | } };
|
---|
2373 |
|
---|
2374 | std::optional<EventTrackingRegions::EventType> touchEvent;
|
---|
2375 | for (auto event : touchEvents) {
|
---|
2376 | if (eventName == EventTrackingRegions::eventName(event)) {
|
---|
2377 | touchEvent = event;
|
---|
2378 | break;
|
---|
2379 | }
|
---|
2380 | }
|
---|
2381 |
|
---|
2382 | if (!touchEvent)
|
---|
2383 | return Exception { InvalidAccessError };
|
---|
2384 |
|
---|
2385 | return document->page()->touchEventRectsForEventForTesting(touchEvent.value());
|
---|
2386 | }
|
---|
2387 |
|
---|
2388 | ExceptionOr<Ref<DOMRectList>> Internals::passiveTouchEventListenerRects()
|
---|
2389 | {
|
---|
2390 | Document* document = contextDocument();
|
---|
2391 | if (!document || !document->page())
|
---|
2392 | return Exception { InvalidAccessError };
|
---|
2393 |
|
---|
2394 | return document->page()->passiveTouchEventListenerRectsForTesting();
|
---|
2395 | }
|
---|
2396 |
|
---|
2397 | // FIXME: Remove the document argument. It is almost always the same as
|
---|
2398 | // contextDocument(), with the exception of a few tests that pass a
|
---|
2399 | // different document, and could just make the call through another Internals
|
---|
2400 | // instance instead.
|
---|
2401 | ExceptionOr<RefPtr<NodeList>> Internals::nodesFromRect(Document& document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowUserAgentShadowContent, bool allowChildFrameContent) const
|
---|
2402 | {
|
---|
2403 | if (!document.frame() || !document.frame()->view())
|
---|
2404 | return Exception { InvalidAccessError };
|
---|
2405 |
|
---|
2406 | Frame* frame = document.frame();
|
---|
2407 | FrameView* frameView = document.view();
|
---|
2408 | RenderView* renderView = document.renderView();
|
---|
2409 | if (!renderView)
|
---|
2410 | return nullptr;
|
---|
2411 |
|
---|
2412 | document.updateLayoutIgnorePendingStylesheets();
|
---|
2413 |
|
---|
2414 | float zoomFactor = frame->pageZoomFactor();
|
---|
2415 | LayoutPoint point(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY());
|
---|
2416 |
|
---|
2417 | OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::CollectMultipleElements };
|
---|
2418 | if (ignoreClipping)
|
---|
2419 | hitType.add(HitTestRequest::Type::IgnoreClipping);
|
---|
2420 | if (!allowUserAgentShadowContent)
|
---|
2421 | hitType.add(HitTestRequest::Type::DisallowUserAgentShadowContent);
|
---|
2422 | if (allowChildFrameContent)
|
---|
2423 | hitType.add(HitTestRequest::Type::AllowChildFrameContent);
|
---|
2424 |
|
---|
2425 | HitTestRequest request(hitType);
|
---|
2426 |
|
---|
2427 | auto hitTestResult = [&] {
|
---|
2428 | auto size = LayoutSize { leftPadding + rightPadding + 1, topPadding + bottomPadding + 1 };
|
---|
2429 | if (size.isEmpty())
|
---|
2430 | return HitTestResult { point };
|
---|
2431 | auto adjustedPosition = LayoutPoint { flooredIntPoint(point) } - LayoutSize { leftPadding, topPadding };
|
---|
2432 | return HitTestResult { LayoutRect { adjustedPosition, size } };
|
---|
2433 | }();
|
---|
2434 | // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
|
---|
2435 | if (!request.ignoreClipping() && !hitTestResult.hitTestLocation().intersects(LayoutRect { frameView->visibleContentRect() }))
|
---|
2436 | return nullptr;
|
---|
2437 |
|
---|
2438 | document.hitTest(request, hitTestResult);
|
---|
2439 | auto matches = WTF::map(hitTestResult.listBasedTestResult(), [](const auto& node) { return node.copyRef(); });
|
---|
2440 | return RefPtr<NodeList> { StaticNodeList::create(WTFMove(matches)) };
|
---|
2441 | }
|
---|
2442 |
|
---|
2443 | class GetCallerCodeBlockFunctor {
|
---|
2444 | public:
|
---|
2445 | GetCallerCodeBlockFunctor()
|
---|
2446 | : m_iterations(0)
|
---|
2447 | , m_codeBlock(0)
|
---|
2448 | {
|
---|
2449 | }
|
---|
2450 |
|
---|
2451 | IterationStatus operator()(StackVisitor& visitor) const
|
---|
2452 | {
|
---|
2453 | ++m_iterations;
|
---|
2454 | if (m_iterations < 2)
|
---|
2455 | return IterationStatus::Continue;
|
---|
2456 |
|
---|
2457 | m_codeBlock = visitor->codeBlock();
|
---|
2458 | return IterationStatus::Done;
|
---|
2459 | }
|
---|
2460 |
|
---|
2461 | CodeBlock* codeBlock() const { return m_codeBlock; }
|
---|
2462 |
|
---|
2463 | private:
|
---|
2464 | mutable int m_iterations;
|
---|
2465 | mutable CodeBlock* m_codeBlock;
|
---|
2466 | };
|
---|
2467 |
|
---|
2468 | String Internals::parserMetaData(JSC::JSValue code)
|
---|
2469 | {
|
---|
2470 | auto& vm = contextDocument()->vm();
|
---|
2471 | auto callFrame = vm.topCallFrame;
|
---|
2472 | auto* globalObject = callFrame->lexicalGlobalObject(vm);
|
---|
2473 |
|
---|
2474 | ScriptExecutable* executable;
|
---|
2475 | if (!code || code.isNull() || code.isUndefined()) {
|
---|
2476 | GetCallerCodeBlockFunctor iter;
|
---|
2477 | callFrame->iterate(vm, iter);
|
---|
2478 | executable = iter.codeBlock()->ownerExecutable();
|
---|
2479 | } else if (code.isCallable())
|
---|
2480 | executable = JSC::jsCast<JSFunction*>(code.toObject(globalObject))->jsExecutable();
|
---|
2481 | else
|
---|
2482 | return String();
|
---|
2483 |
|
---|
2484 | const char* prefix = "";
|
---|
2485 | String functionName;
|
---|
2486 | const char* suffix = "";
|
---|
2487 |
|
---|
2488 | if (executable->isFunctionExecutable()) {
|
---|
2489 | prefix = "function \"";
|
---|
2490 | functionName = static_cast<FunctionExecutable*>(executable)->ecmaName().string();
|
---|
2491 | suffix = "\"";
|
---|
2492 | } else if (executable->isEvalExecutable())
|
---|
2493 | prefix = "eval";
|
---|
2494 | else if (executable->isModuleProgramExecutable())
|
---|
2495 | prefix = "module";
|
---|
2496 | else if (executable->isProgramExecutable())
|
---|
2497 | prefix = "program";
|
---|
2498 | else
|
---|
2499 | ASSERT_NOT_REACHED();
|
---|
2500 |
|
---|
2501 | return makeString(prefix, functionName, suffix, " { ",
|
---|
2502 | executable->firstLine(), ':', executable->startColumn(), " - ",
|
---|
2503 | executable->lastLine(), ':', executable->endColumn(), " }");
|
---|
2504 | }
|
---|
2505 |
|
---|
2506 | void Internals::updateEditorUINowIfScheduled()
|
---|
2507 | {
|
---|
2508 | if (Document* document = contextDocument()) {
|
---|
2509 | if (Frame* frame = document->frame())
|
---|
2510 | frame->editor().updateEditorUINowIfScheduled();
|
---|
2511 | }
|
---|
2512 | }
|
---|
2513 |
|
---|
2514 | bool Internals::hasSpellingMarker(int from, int length)
|
---|
2515 | {
|
---|
2516 | Document* document = contextDocument();
|
---|
2517 | if (!document || !document->frame())
|
---|
2518 | return false;
|
---|
2519 |
|
---|
2520 | updateEditorUINowIfScheduled();
|
---|
2521 |
|
---|
2522 | return document->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
|
---|
2523 | }
|
---|
2524 |
|
---|
2525 | bool Internals::hasAutocorrectedMarker(int from, int length)
|
---|
2526 | {
|
---|
2527 | Document* document = contextDocument();
|
---|
2528 | if (!document || !document->frame())
|
---|
2529 | return false;
|
---|
2530 |
|
---|
2531 | updateEditorUINowIfScheduled();
|
---|
2532 |
|
---|
2533 | return document->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
|
---|
2534 | }
|
---|
2535 |
|
---|
2536 | bool Internals::hasDictationAlternativesMarker(int from, int length)
|
---|
2537 | {
|
---|
2538 | auto* document = contextDocument();
|
---|
2539 | if (!document || !document->frame())
|
---|
2540 | return false;
|
---|
2541 |
|
---|
2542 | updateEditorUINowIfScheduled();
|
---|
2543 |
|
---|
2544 | return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::DictationAlternatives, from, length);
|
---|
2545 | }
|
---|
2546 |
|
---|
2547 | void Internals::setContinuousSpellCheckingEnabled(bool enabled)
|
---|
2548 | {
|
---|
2549 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2550 | return;
|
---|
2551 |
|
---|
2552 | if (enabled != contextDocument()->editor().isContinuousSpellCheckingEnabled())
|
---|
2553 | contextDocument()->editor().toggleContinuousSpellChecking();
|
---|
2554 | }
|
---|
2555 |
|
---|
2556 | void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled)
|
---|
2557 | {
|
---|
2558 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2559 | return;
|
---|
2560 |
|
---|
2561 | #if USE(AUTOMATIC_TEXT_REPLACEMENT)
|
---|
2562 | if (enabled != contextDocument()->editor().isAutomaticQuoteSubstitutionEnabled())
|
---|
2563 | contextDocument()->editor().toggleAutomaticQuoteSubstitution();
|
---|
2564 | #else
|
---|
2565 | UNUSED_PARAM(enabled);
|
---|
2566 | #endif
|
---|
2567 | }
|
---|
2568 |
|
---|
2569 | void Internals::setAutomaticLinkDetectionEnabled(bool enabled)
|
---|
2570 | {
|
---|
2571 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2572 | return;
|
---|
2573 |
|
---|
2574 | #if USE(AUTOMATIC_TEXT_REPLACEMENT)
|
---|
2575 | if (enabled != contextDocument()->editor().isAutomaticLinkDetectionEnabled())
|
---|
2576 | contextDocument()->editor().toggleAutomaticLinkDetection();
|
---|
2577 | #else
|
---|
2578 | UNUSED_PARAM(enabled);
|
---|
2579 | #endif
|
---|
2580 | }
|
---|
2581 |
|
---|
2582 | bool Internals::testProcessIncomingSyncMessagesWhenWaitingForSyncReply()
|
---|
2583 | {
|
---|
2584 | ASSERT(contextDocument());
|
---|
2585 | ASSERT(contextDocument()->page());
|
---|
2586 | return contextDocument()->page()->chrome().client().testProcessIncomingSyncMessagesWhenWaitingForSyncReply();
|
---|
2587 | }
|
---|
2588 |
|
---|
2589 | void Internals::setAutomaticDashSubstitutionEnabled(bool enabled)
|
---|
2590 | {
|
---|
2591 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2592 | return;
|
---|
2593 |
|
---|
2594 | #if USE(AUTOMATIC_TEXT_REPLACEMENT)
|
---|
2595 | if (enabled != contextDocument()->editor().isAutomaticDashSubstitutionEnabled())
|
---|
2596 | contextDocument()->editor().toggleAutomaticDashSubstitution();
|
---|
2597 | #else
|
---|
2598 | UNUSED_PARAM(enabled);
|
---|
2599 | #endif
|
---|
2600 | }
|
---|
2601 |
|
---|
2602 | void Internals::setAutomaticTextReplacementEnabled(bool enabled)
|
---|
2603 | {
|
---|
2604 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2605 | return;
|
---|
2606 |
|
---|
2607 | #if USE(AUTOMATIC_TEXT_REPLACEMENT)
|
---|
2608 | if (enabled != contextDocument()->editor().isAutomaticTextReplacementEnabled())
|
---|
2609 | contextDocument()->editor().toggleAutomaticTextReplacement();
|
---|
2610 | #else
|
---|
2611 | UNUSED_PARAM(enabled);
|
---|
2612 | #endif
|
---|
2613 | }
|
---|
2614 |
|
---|
2615 | void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled)
|
---|
2616 | {
|
---|
2617 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2618 | return;
|
---|
2619 |
|
---|
2620 | #if USE(AUTOMATIC_TEXT_REPLACEMENT)
|
---|
2621 | if (enabled != contextDocument()->editor().isAutomaticSpellingCorrectionEnabled())
|
---|
2622 | contextDocument()->editor().toggleAutomaticSpellingCorrection();
|
---|
2623 | #else
|
---|
2624 | UNUSED_PARAM(enabled);
|
---|
2625 | #endif
|
---|
2626 | }
|
---|
2627 |
|
---|
2628 | bool Internals::isSpellcheckDisabledExceptTextReplacement(const HTMLInputElement& element) const
|
---|
2629 | {
|
---|
2630 | return element.isSpellcheckDisabledExceptTextReplacement();
|
---|
2631 | }
|
---|
2632 |
|
---|
2633 | void Internals::handleAcceptedCandidate(const String& candidate, unsigned location, unsigned length)
|
---|
2634 | {
|
---|
2635 | if (!contextDocument() || !contextDocument()->frame())
|
---|
2636 | return;
|
---|
2637 |
|
---|
2638 | TextCheckingResult result;
|
---|
2639 | result.type = TextCheckingType::None;
|
---|
2640 | result.range = { location, length };
|
---|
2641 | result.replacement = candidate;
|
---|
2642 | contextDocument()->editor().handleAcceptedCandidate(result);
|
---|
2643 | }
|
---|
2644 |
|
---|
2645 | void Internals::changeSelectionListType()
|
---|
2646 | {
|
---|
2647 | if (RefPtr frame = this->frame())
|
---|
2648 | frame->editor().changeSelectionListType();
|
---|
2649 | }
|
---|
2650 |
|
---|
2651 | void Internals::changeBackToReplacedString(const String& replacedString)
|
---|
2652 | {
|
---|
2653 | if (RefPtr frame = this->frame())
|
---|
2654 | frame->editor().changeBackToReplacedString(replacedString);
|
---|
2655 | }
|
---|
2656 |
|
---|
2657 | bool Internals::isOverwriteModeEnabled()
|
---|
2658 | {
|
---|
2659 | Document* document = contextDocument();
|
---|
2660 | if (!document || !document->frame())
|
---|
2661 | return false;
|
---|
2662 |
|
---|
2663 | return document->editor().isOverwriteModeEnabled();
|
---|
2664 | }
|
---|
2665 |
|
---|
2666 | void Internals::toggleOverwriteModeEnabled()
|
---|
2667 | {
|
---|
2668 | Document* document = contextDocument();
|
---|
2669 | if (!document || !document->frame())
|
---|
2670 | return;
|
---|
2671 |
|
---|
2672 | document->editor().toggleOverwriteModeEnabled();
|
---|
2673 | }
|
---|
2674 |
|
---|
2675 | static ExceptionOr<FindOptions> parseFindOptions(const Vector<String>& optionList)
|
---|
2676 | {
|
---|
2677 | const struct {
|
---|
2678 | ASCIILiteral name;
|
---|
2679 | FindOptionFlag value;
|
---|
2680 | } flagList[] = {
|
---|
2681 | { "CaseInsensitive"_s, CaseInsensitive },
|
---|
2682 | { "AtWordStarts"_s, AtWordStarts },
|
---|
2683 | { "TreatMedialCapitalAsWordStart"_s, TreatMedialCapitalAsWordStart },
|
---|
2684 | { "Backwards"_s, Backwards },
|
---|
2685 | { "WrapAround"_s, WrapAround },
|
---|
2686 | { "StartInSelection"_s, StartInSelection },
|
---|
2687 | { "DoNotRevealSelection"_s, DoNotRevealSelection },
|
---|
2688 | { "AtWordEnds"_s, AtWordEnds },
|
---|
2689 | { "DoNotTraverseFlatTree"_s, DoNotTraverseFlatTree },
|
---|
2690 | };
|
---|
2691 | FindOptions result;
|
---|
2692 | for (auto& option : optionList) {
|
---|
2693 | bool found = false;
|
---|
2694 | for (auto& flag : flagList) {
|
---|
2695 | if (flag.name == option) {
|
---|
2696 | result.add(flag.value);
|
---|
2697 | found = true;
|
---|
2698 | break;
|
---|
2699 | }
|
---|
2700 | }
|
---|
2701 | if (!found)
|
---|
2702 | return Exception { SyntaxError };
|
---|
2703 | }
|
---|
2704 | return result;
|
---|
2705 | }
|
---|
2706 |
|
---|
2707 | ExceptionOr<RefPtr<Range>> Internals::rangeOfString(const String& text, RefPtr<Range>&& referenceRange, const Vector<String>& findOptions)
|
---|
2708 | {
|
---|
2709 | Document* document = contextDocument();
|
---|
2710 | if (!document || !document->frame())
|
---|
2711 | return Exception { InvalidAccessError };
|
---|
2712 |
|
---|
2713 | auto parsedOptions = parseFindOptions(findOptions);
|
---|
2714 | if (parsedOptions.hasException())
|
---|
2715 | return parsedOptions.releaseException();
|
---|
2716 |
|
---|
2717 | return createLiveRange(document->editor().rangeOfString(text, makeSimpleRange(referenceRange), parsedOptions.releaseReturnValue()));
|
---|
2718 | }
|
---|
2719 |
|
---|
2720 | ExceptionOr<unsigned> Internals::countMatchesForText(const String& text, const Vector<String>& findOptions, const String& markMatches)
|
---|
2721 | {
|
---|
2722 | Document* document = contextDocument();
|
---|
2723 | if (!document || !document->frame())
|
---|
2724 | return Exception { InvalidAccessError };
|
---|
2725 |
|
---|
2726 | auto parsedOptions = parseFindOptions(findOptions);
|
---|
2727 | if (parsedOptions.hasException())
|
---|
2728 | return parsedOptions.releaseException();
|
---|
2729 |
|
---|
2730 | bool mark = markMatches == "mark"_s;
|
---|
2731 | return document->editor().countMatchesForText(text, std::nullopt, parsedOptions.releaseReturnValue(), 1000, mark, nullptr);
|
---|
2732 | }
|
---|
2733 |
|
---|
2734 | ExceptionOr<unsigned> Internals::countFindMatches(const String& text, const Vector<String>& findOptions)
|
---|
2735 | {
|
---|
2736 | Document* document = contextDocument();
|
---|
2737 | if (!document || !document->page())
|
---|
2738 | return Exception { InvalidAccessError };
|
---|
2739 |
|
---|
2740 | auto parsedOptions = parseFindOptions(findOptions);
|
---|
2741 | if (parsedOptions.hasException())
|
---|
2742 | return parsedOptions.releaseException();
|
---|
2743 |
|
---|
2744 | return document->page()->countFindMatches(text, parsedOptions.releaseReturnValue(), 1000);
|
---|
2745 | }
|
---|
2746 |
|
---|
2747 | unsigned Internals::numberOfIDBTransactions() const
|
---|
2748 | {
|
---|
2749 | return IDBTransaction::numberOfIDBTransactions;
|
---|
2750 | }
|
---|
2751 |
|
---|
2752 | unsigned Internals::numberOfLiveNodes() const
|
---|
2753 | {
|
---|
2754 | unsigned nodeCount = 0;
|
---|
2755 | for (auto* document : Document::allDocuments())
|
---|
2756 | nodeCount += document->referencingNodeCount();
|
---|
2757 | return nodeCount;
|
---|
2758 | }
|
---|
2759 |
|
---|
2760 | unsigned Internals::numberOfLiveDocuments() const
|
---|
2761 | {
|
---|
2762 | return Document::allDocuments().size();
|
---|
2763 | }
|
---|
2764 |
|
---|
2765 | unsigned Internals::referencingNodeCount(const Document& document) const
|
---|
2766 | {
|
---|
2767 | return document.referencingNodeCount();
|
---|
2768 | }
|
---|
2769 |
|
---|
2770 | #if ENABLE(WEB_AUDIO)
|
---|
2771 | uint64_t Internals::baseAudioContextIdentifier(const BaseAudioContext& context)
|
---|
2772 | {
|
---|
2773 | return context.contextID();
|
---|
2774 | }
|
---|
2775 |
|
---|
2776 | bool Internals::isBaseAudioContextAlive(uint64_t contextID)
|
---|
2777 | {
|
---|
2778 | ASSERT(contextID);
|
---|
2779 | return BaseAudioContext::isContextAlive(contextID);
|
---|
2780 | }
|
---|
2781 | #endif // ENABLE(WEB_AUDIO)
|
---|
2782 |
|
---|
2783 | unsigned Internals::numberOfIntersectionObservers(const Document& document) const
|
---|
2784 | {
|
---|
2785 | return document.numberOfIntersectionObservers();
|
---|
2786 | }
|
---|
2787 |
|
---|
2788 | unsigned Internals::numberOfResizeObservers(const Document& document) const
|
---|
2789 | {
|
---|
2790 | return document.numberOfResizeObservers();
|
---|
2791 | }
|
---|
2792 |
|
---|
2793 | String Internals::documentIdentifier(const Document& document) const
|
---|
2794 | {
|
---|
2795 | return document.identifier().object().toString();
|
---|
2796 | }
|
---|
2797 |
|
---|
2798 | bool Internals::isDocumentAlive(const String& documentIdentifier) const
|
---|
2799 | {
|
---|
2800 | auto uuid = UUID::parseVersion4(documentIdentifier);
|
---|
2801 | ASSERT(uuid);
|
---|
2802 | return uuid ? Document::allDocumentsMap().contains({ *uuid, Process::identifier() }) : false;
|
---|
2803 | }
|
---|
2804 |
|
---|
2805 | uint64_t Internals::storageAreaMapCount() const
|
---|
2806 | {
|
---|
2807 | auto* page = contextDocument() ? contextDocument()->page() : nullptr;
|
---|
2808 | if (!page)
|
---|
2809 | return 0;
|
---|
2810 |
|
---|
2811 | return page->storageNamespaceProvider().localStorageNamespace(page->sessionID()).storageAreaMapCountForTesting();
|
---|
2812 | }
|
---|
2813 |
|
---|
2814 | uint64_t Internals::elementIdentifier(Element& element) const
|
---|
2815 | {
|
---|
2816 | return element.identifier().toUInt64();
|
---|
2817 | }
|
---|
2818 |
|
---|
2819 | bool Internals::isElementAlive(uint64_t elementIdentifier) const
|
---|
2820 | {
|
---|
2821 | return Element::fromIdentifier(makeObjectIdentifier<ElementIdentifierType>(elementIdentifier));
|
---|
2822 | }
|
---|
2823 |
|
---|
2824 | uint64_t Internals::frameIdentifier(const Document& document) const
|
---|
2825 | {
|
---|
2826 | if (auto* page = document.page())
|
---|
2827 | return valueOrDefault(page->mainFrame().loader().frameID()).toUInt64();
|
---|
2828 | return 0;
|
---|
2829 | }
|
---|
2830 |
|
---|
2831 | uint64_t Internals::pageIdentifier(const Document& document) const
|
---|
2832 | {
|
---|
2833 | return valueOrDefault(document.pageID()).toUInt64();
|
---|
2834 | }
|
---|
2835 |
|
---|
2836 | bool Internals::isAnyWorkletGlobalScopeAlive() const
|
---|
2837 | {
|
---|
2838 | return WorkletGlobalScope::numberOfWorkletGlobalScopes();
|
---|
2839 | }
|
---|
2840 |
|
---|
2841 | String Internals::serviceWorkerClientInternalIdentifier(const Document& document) const
|
---|
2842 | {
|
---|
2843 | return document.identifier().toString();
|
---|
2844 | }
|
---|
2845 |
|
---|
2846 | RefPtr<WindowProxy> Internals::openDummyInspectorFrontend(const String& url)
|
---|
2847 | {
|
---|
2848 | auto* inspectedPage = contextDocument()->frame()->page();
|
---|
2849 | auto* window = inspectedPage->mainFrame().document()->domWindow();
|
---|
2850 | auto frontendWindowProxy = window->open(*window, *window, url, emptyAtom(), emptyString()).releaseReturnValue();
|
---|
2851 | m_inspectorFrontend = makeUnique<InspectorStubFrontend>(*inspectedPage, downcast<DOMWindow>(frontendWindowProxy->window()));
|
---|
2852 | return frontendWindowProxy;
|
---|
2853 | }
|
---|
2854 |
|
---|
2855 | void Internals::closeDummyInspectorFrontend()
|
---|
2856 | {
|
---|
2857 | m_inspectorFrontend = nullptr;
|
---|
2858 | }
|
---|
2859 |
|
---|
2860 | ExceptionOr<void> Internals::setInspectorIsUnderTest(bool isUnderTest)
|
---|
2861 | {
|
---|
2862 | Page* page = contextDocument()->frame()->page();
|
---|
2863 | if (!page)
|
---|
2864 | return Exception { InvalidAccessError };
|
---|
2865 |
|
---|
2866 | page->inspectorController().setIsUnderTest(isUnderTest);
|
---|
2867 | return { };
|
---|
2868 | }
|
---|
2869 |
|
---|
2870 | bool Internals::hasGrammarMarker(int from, int length)
|
---|
2871 | {
|
---|
2872 | Document* document = contextDocument();
|
---|
2873 | if (!document || !document->frame())
|
---|
2874 | return false;
|
---|
2875 |
|
---|
2876 | return document->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
|
---|
2877 | }
|
---|
2878 |
|
---|
2879 | unsigned Internals::numberOfScrollableAreas()
|
---|
2880 | {
|
---|
2881 | Document* document = contextDocument();
|
---|
2882 | if (!document || !document->frame())
|
---|
2883 | return 0;
|
---|
2884 |
|
---|
2885 | unsigned count = 0;
|
---|
2886 | Frame* frame = document->frame();
|
---|
2887 | if (frame->view()->scrollableAreas())
|
---|
2888 | count += frame->view()->scrollableAreas()->size();
|
---|
2889 |
|
---|
2890 | for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
|
---|
2891 | if (child->view() && child->view()->scrollableAreas())
|
---|
2892 | count += child->view()->scrollableAreas()->size();
|
---|
2893 | }
|
---|
2894 |
|
---|
2895 | return count;
|
---|
2896 | }
|
---|
2897 |
|
---|
2898 | ExceptionOr<bool> Internals::isPageBoxVisible(int pageNumber)
|
---|
2899 | {
|
---|
2900 | Document* document = contextDocument();
|
---|
2901 | if (!document)
|
---|
2902 | return Exception { InvalidAccessError };
|
---|
2903 |
|
---|
2904 | return document->isPageBoxVisible(pageNumber);
|
---|
2905 | }
|
---|
2906 |
|
---|
2907 | static OptionSet<LayerTreeAsTextOptions> toLayerTreeAsTextOptions(unsigned short flags)
|
---|
2908 | {
|
---|
2909 | OptionSet<LayerTreeAsTextOptions> layerTreeFlags;
|
---|
2910 | if (flags & Internals::LAYER_TREE_INCLUDES_VISIBLE_RECTS)
|
---|
2911 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeVisibleRects);
|
---|
2912 | if (flags & Internals::LAYER_TREE_INCLUDES_TILE_CACHES)
|
---|
2913 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeTileCaches);
|
---|
2914 | if (flags & Internals::LAYER_TREE_INCLUDES_REPAINT_RECTS)
|
---|
2915 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeRepaintRects);
|
---|
2916 | if (flags & Internals::LAYER_TREE_INCLUDES_PAINTING_PHASES)
|
---|
2917 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludePaintingPhases);
|
---|
2918 | if (flags & Internals::LAYER_TREE_INCLUDES_CONTENT_LAYERS)
|
---|
2919 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeContentLayers);
|
---|
2920 | if (flags & Internals::LAYER_TREE_INCLUDES_ACCELERATES_DRAWING)
|
---|
2921 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeAcceleratesDrawing);
|
---|
2922 | if (flags & Internals::LAYER_TREE_INCLUDES_CLIPPING)
|
---|
2923 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeClipping);
|
---|
2924 | if (flags & Internals::LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED)
|
---|
2925 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeBackingStoreAttached);
|
---|
2926 | if (flags & Internals::LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES)
|
---|
2927 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeRootLayerProperties);
|
---|
2928 | if (flags & Internals::LAYER_TREE_INCLUDES_EVENT_REGION)
|
---|
2929 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeEventRegion);
|
---|
2930 | if (flags & Internals::LAYER_TREE_INCLUDES_DEEP_COLOR)
|
---|
2931 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeDeepColor);
|
---|
2932 | if (flags & Internals::LAYER_TREE_INCLUDES_DEVICE_SCALE)
|
---|
2933 | layerTreeFlags.add(LayerTreeAsTextOptions::IncludeDeviceScale);
|
---|
2934 |
|
---|
2935 | return layerTreeFlags;
|
---|
2936 | }
|
---|
2937 |
|
---|
2938 | // FIXME: Remove the document argument. It is almost always the same as
|
---|
2939 | // contextDocument(), with the exception of a few tests that pass a
|
---|
2940 | // different document, and could just make the call through another Internals
|
---|
2941 | // instance instead.
|
---|
2942 | ExceptionOr<String> Internals::layerTreeAsText(Document& document, unsigned short flags) const
|
---|
2943 | {
|
---|
2944 | if (!document.frame() || !document.frame()->contentRenderer())
|
---|
2945 | return Exception { InvalidAccessError };
|
---|
2946 | return document.frame()->contentRenderer()->compositor().layerTreeAsText(toLayerTreeAsTextOptions(flags));
|
---|
2947 | }
|
---|
2948 |
|
---|
2949 | ExceptionOr<uint64_t> Internals::layerIDForElement(Element& element)
|
---|
2950 | {
|
---|
2951 | Document* document = contextDocument();
|
---|
2952 | if (!document || !document->frame())
|
---|
2953 | return Exception { InvalidAccessError };
|
---|
2954 |
|
---|
2955 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
2956 |
|
---|
2957 | if (!element.renderer() || !element.renderer()->hasLayer())
|
---|
2958 | return Exception { NotFoundError };
|
---|
2959 |
|
---|
2960 | auto& layerModelObject = downcast<RenderLayerModelObject>(*element.renderer());
|
---|
2961 | if (!layerModelObject.layer()->isComposited())
|
---|
2962 | return Exception { NotFoundError };
|
---|
2963 |
|
---|
2964 | auto* backing = layerModelObject.layer()->backing();
|
---|
2965 | return backing->graphicsLayer()->primaryLayerID();
|
---|
2966 | }
|
---|
2967 |
|
---|
2968 | static OptionSet<PlatformLayerTreeAsTextFlags> toPlatformLayerTreeFlags(unsigned short flags)
|
---|
2969 | {
|
---|
2970 | OptionSet<PlatformLayerTreeAsTextFlags> platformLayerTreeFlags = { };
|
---|
2971 | if (flags & Internals::PLATFORM_LAYER_TREE_DEBUG)
|
---|
2972 | platformLayerTreeFlags.add(PlatformLayerTreeAsTextFlags::Debug);
|
---|
2973 | if (flags & Internals::PLATFORM_LAYER_TREE_IGNORES_CHILDREN)
|
---|
2974 | platformLayerTreeFlags.add(PlatformLayerTreeAsTextFlags::IgnoreChildren);
|
---|
2975 | if (flags & Internals::PLATFORM_LAYER_TREE_INCLUDE_MODELS)
|
---|
2976 | platformLayerTreeFlags.add(PlatformLayerTreeAsTextFlags::IncludeModels);
|
---|
2977 | return platformLayerTreeFlags;
|
---|
2978 | }
|
---|
2979 |
|
---|
2980 | ExceptionOr<String> Internals::platformLayerTreeAsText(Element& element, unsigned short flags) const
|
---|
2981 | {
|
---|
2982 | Document& document = element.document();
|
---|
2983 | if (!document.frame() || !document.frame()->contentRenderer())
|
---|
2984 | return Exception { InvalidAccessError };
|
---|
2985 |
|
---|
2986 | auto text = document.frame()->contentRenderer()->compositor().platformLayerTreeAsText(element, toPlatformLayerTreeFlags(flags));
|
---|
2987 | if (!text)
|
---|
2988 | return Exception { NotFoundError };
|
---|
2989 |
|
---|
2990 | return String { text.value() };
|
---|
2991 | }
|
---|
2992 |
|
---|
2993 | ExceptionOr<String> Internals::repaintRectsAsText() const
|
---|
2994 | {
|
---|
2995 | Document* document = contextDocument();
|
---|
2996 | if (!document || !document->frame())
|
---|
2997 | return Exception { InvalidAccessError };
|
---|
2998 |
|
---|
2999 | return document->frame()->trackedRepaintRectsAsText();
|
---|
3000 | }
|
---|
3001 |
|
---|
3002 | ExceptionOr<ScrollableArea*> Internals::scrollableAreaForNode(Node* node) const
|
---|
3003 | {
|
---|
3004 | if (!node)
|
---|
3005 | node = contextDocument();
|
---|
3006 |
|
---|
3007 | if (!node)
|
---|
3008 | return Exception { InvalidAccessError };
|
---|
3009 |
|
---|
3010 | Ref nodeRef { *node };
|
---|
3011 | nodeRef->document().updateLayoutIgnorePendingStylesheets();
|
---|
3012 |
|
---|
3013 | ScrollableArea* scrollableArea = nullptr;
|
---|
3014 | if (is<Document>(nodeRef)) {
|
---|
3015 | auto* frameView = downcast<Document>(nodeRef.get()).view();
|
---|
3016 | if (!frameView)
|
---|
3017 | return Exception { InvalidAccessError };
|
---|
3018 |
|
---|
3019 | scrollableArea = frameView;
|
---|
3020 | } else if (node == nodeRef->document().scrollingElement()) {
|
---|
3021 | auto* frameView = nodeRef->document().view();
|
---|
3022 | if (!frameView)
|
---|
3023 | return Exception { InvalidAccessError };
|
---|
3024 |
|
---|
3025 | scrollableArea = frameView;
|
---|
3026 | } else if (is<Element>(nodeRef)) {
|
---|
3027 | auto& element = downcast<Element>(nodeRef.get());
|
---|
3028 | if (!element.renderBox())
|
---|
3029 | return Exception { InvalidAccessError };
|
---|
3030 |
|
---|
3031 | auto& renderBox = *element.renderBox();
|
---|
3032 | if (!renderBox.canBeScrolledAndHasScrollableArea())
|
---|
3033 | return Exception { InvalidAccessError };
|
---|
3034 |
|
---|
3035 | if (is<RenderListBox>(renderBox))
|
---|
3036 | scrollableArea = &downcast<RenderListBox>(renderBox);
|
---|
3037 | else {
|
---|
3038 | ASSERT(renderBox.layer());
|
---|
3039 | scrollableArea = renderBox.layer()->scrollableArea();
|
---|
3040 | }
|
---|
3041 | } else
|
---|
3042 | return Exception { InvalidNodeTypeError };
|
---|
3043 |
|
---|
3044 | if (!scrollableArea)
|
---|
3045 | return Exception { InvalidNodeTypeError };
|
---|
3046 |
|
---|
3047 | return scrollableArea;
|
---|
3048 | }
|
---|
3049 |
|
---|
3050 | ExceptionOr<String> Internals::scrollbarOverlayStyle(Node* node) const
|
---|
3051 | {
|
---|
3052 | auto areaOrException = scrollableAreaForNode(node);
|
---|
3053 | if (areaOrException.hasException())
|
---|
3054 | return areaOrException.releaseException();
|
---|
3055 |
|
---|
3056 | auto* scrollableArea = areaOrException.releaseReturnValue();
|
---|
3057 | switch (scrollableArea->scrollbarOverlayStyle()) {
|
---|
3058 | case ScrollbarOverlayStyleDefault:
|
---|
3059 | return "default"_str;
|
---|
3060 | case ScrollbarOverlayStyleDark:
|
---|
3061 | return "dark"_str;
|
---|
3062 | case ScrollbarOverlayStyleLight:
|
---|
3063 | return "light"_str;
|
---|
3064 | }
|
---|
3065 |
|
---|
3066 | ASSERT_NOT_REACHED();
|
---|
3067 | return "unknown"_str;
|
---|
3068 | }
|
---|
3069 |
|
---|
3070 | ExceptionOr<bool> Internals::scrollbarUsingDarkAppearance(Node* node) const
|
---|
3071 | {
|
---|
3072 | auto areaOrException = scrollableAreaForNode(node);
|
---|
3073 | if (areaOrException.hasException())
|
---|
3074 | return areaOrException.releaseException();
|
---|
3075 |
|
---|
3076 | auto* scrollableArea = areaOrException.releaseReturnValue();
|
---|
3077 | return scrollableArea->useDarkAppearance();
|
---|
3078 | }
|
---|
3079 |
|
---|
3080 | ExceptionOr<String> Internals::horizontalScrollbarState(Node* node) const
|
---|
3081 | {
|
---|
3082 | auto areaOrException = scrollableAreaForNode(node);
|
---|
3083 | if (areaOrException.hasException())
|
---|
3084 | return areaOrException.releaseException();
|
---|
3085 |
|
---|
3086 | auto* scrollableArea = areaOrException.releaseReturnValue();
|
---|
3087 | return scrollableArea->horizontalScrollbarStateForTesting();
|
---|
3088 | }
|
---|
3089 |
|
---|
3090 | ExceptionOr<String> Internals::verticalScrollbarState(Node* node) const
|
---|
3091 | {
|
---|
3092 | auto areaOrException = scrollableAreaForNode(node);
|
---|
3093 | if (areaOrException.hasException())
|
---|
3094 | return areaOrException.releaseException();
|
---|
3095 |
|
---|
3096 | auto* scrollableArea = areaOrException.releaseReturnValue();
|
---|
3097 | return scrollableArea->verticalScrollbarStateForTesting();
|
---|
3098 | }
|
---|
3099 |
|
---|
3100 | ExceptionOr<String> Internals::scrollingStateTreeAsText() const
|
---|
3101 | {
|
---|
3102 | Document* document = contextDocument();
|
---|
3103 | if (!document || !document->frame())
|
---|
3104 | return Exception { InvalidAccessError };
|
---|
3105 |
|
---|
3106 | document->updateLayoutIgnorePendingStylesheets();
|
---|
3107 |
|
---|
3108 | Page* page = document->page();
|
---|
3109 | if (!page)
|
---|
3110 | return String();
|
---|
3111 |
|
---|
3112 | return page->scrollingStateTreeAsText();
|
---|
3113 | }
|
---|
3114 |
|
---|
3115 | ExceptionOr<String> Internals::scrollingTreeAsText() const
|
---|
3116 | {
|
---|
3117 | Document* document = contextDocument();
|
---|
3118 | if (!document || !document->frame())
|
---|
3119 | return Exception { InvalidAccessError };
|
---|
3120 |
|
---|
3121 | document->updateLayoutIgnorePendingStylesheets();
|
---|
3122 |
|
---|
3123 | auto page = document->page();
|
---|
3124 | if (!page)
|
---|
3125 | return String();
|
---|
3126 |
|
---|
3127 | auto scrollingCoordinator = page->scrollingCoordinator();
|
---|
3128 | if (!scrollingCoordinator)
|
---|
3129 | return String();
|
---|
3130 |
|
---|
3131 | scrollingCoordinator->commitTreeStateIfNeeded();
|
---|
3132 | return scrollingCoordinator->scrollingTreeAsText();
|
---|
3133 | }
|
---|
3134 |
|
---|
3135 | ExceptionOr<String> Internals::synchronousScrollingReasons() const
|
---|
3136 | {
|
---|
3137 | Document* document = contextDocument();
|
---|
3138 | if (!document || !document->frame())
|
---|
3139 | return Exception { InvalidAccessError };
|
---|
3140 |
|
---|
3141 | Page* page = document->page();
|
---|
3142 | if (!page)
|
---|
3143 | return String();
|
---|
3144 |
|
---|
3145 | return page->synchronousScrollingReasonsAsText();
|
---|
3146 | }
|
---|
3147 |
|
---|
3148 | ExceptionOr<Ref<DOMRectList>> Internals::nonFastScrollableRects() const
|
---|
3149 | {
|
---|
3150 | Document* document = contextDocument();
|
---|
3151 | if (!document || !document->frame())
|
---|
3152 | return Exception { InvalidAccessError };
|
---|
3153 |
|
---|
3154 | Page* page = document->page();
|
---|
3155 | if (!page)
|
---|
3156 | return DOMRectList::create();
|
---|
3157 |
|
---|
3158 | return page->nonFastScrollableRectsForTesting();
|
---|
3159 | }
|
---|
3160 |
|
---|
3161 | ExceptionOr<void> Internals::setElementUsesDisplayListDrawing(Element& element, bool usesDisplayListDrawing)
|
---|
3162 | {
|
---|
3163 | Document* document = contextDocument();
|
---|
3164 | if (!document || !document->renderView())
|
---|
3165 | return Exception { InvalidAccessError };
|
---|
3166 |
|
---|
3167 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
3168 |
|
---|
3169 | if (!element.renderer())
|
---|
3170 | return Exception { InvalidAccessError };
|
---|
3171 |
|
---|
3172 | if (is<HTMLCanvasElement>(element)) {
|
---|
3173 | downcast<HTMLCanvasElement>(element).setUsesDisplayListDrawing(usesDisplayListDrawing);
|
---|
3174 | return { };
|
---|
3175 | }
|
---|
3176 |
|
---|
3177 | if (!element.renderer()->hasLayer())
|
---|
3178 | return Exception { InvalidAccessError };
|
---|
3179 |
|
---|
3180 | RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
|
---|
3181 | if (!layer->isComposited())
|
---|
3182 | return Exception { InvalidAccessError };
|
---|
3183 |
|
---|
3184 | layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
|
---|
3185 | return { };
|
---|
3186 | }
|
---|
3187 |
|
---|
3188 | ExceptionOr<void> Internals::setElementTracksDisplayListReplay(Element& element, bool isTrackingReplay)
|
---|
3189 | {
|
---|
3190 | Document* document = contextDocument();
|
---|
3191 | if (!document || !document->renderView())
|
---|
3192 | return Exception { InvalidAccessError };
|
---|
3193 |
|
---|
3194 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
3195 |
|
---|
3196 | if (!element.renderer())
|
---|
3197 | return Exception { InvalidAccessError };
|
---|
3198 |
|
---|
3199 | if (!element.renderer()->hasLayer())
|
---|
3200 | return Exception { InvalidAccessError };
|
---|
3201 |
|
---|
3202 | RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
|
---|
3203 | if (!layer->isComposited())
|
---|
3204 | return Exception { InvalidAccessError };
|
---|
3205 |
|
---|
3206 | layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay);
|
---|
3207 | return { };
|
---|
3208 | }
|
---|
3209 |
|
---|
3210 | static OptionSet<DisplayList::AsTextFlag> toDisplayListFlags(unsigned short flags)
|
---|
3211 | {
|
---|
3212 | OptionSet<DisplayList::AsTextFlag> displayListFlags;
|
---|
3213 | if (flags & Internals::DISPLAY_LIST_INCLUDE_PLATFORM_OPERATIONS)
|
---|
3214 | displayListFlags.add(DisplayList::AsTextFlag::IncludePlatformOperations);
|
---|
3215 | if (flags & Internals::DISPLAY_LIST_INCLUDE_RESOURCE_IDENTIFIERS)
|
---|
3216 | displayListFlags.add(DisplayList::AsTextFlag::IncludeResourceIdentifiers);
|
---|
3217 | return displayListFlags;
|
---|
3218 | }
|
---|
3219 |
|
---|
3220 | ExceptionOr<String> Internals::displayListForElement(Element& element, unsigned short flags)
|
---|
3221 | {
|
---|
3222 | Document* document = contextDocument();
|
---|
3223 | if (!document || !document->renderView())
|
---|
3224 | return Exception { InvalidAccessError };
|
---|
3225 |
|
---|
3226 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
3227 |
|
---|
3228 | if (!element.renderer())
|
---|
3229 | return Exception { InvalidAccessError };
|
---|
3230 |
|
---|
3231 | if (!element.renderer()->hasLayer())
|
---|
3232 | return Exception { InvalidAccessError };
|
---|
3233 |
|
---|
3234 | RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
|
---|
3235 | if (!layer->isComposited())
|
---|
3236 | return Exception { InvalidAccessError };
|
---|
3237 |
|
---|
3238 | return layer->backing()->displayListAsText(toDisplayListFlags(flags));
|
---|
3239 | }
|
---|
3240 |
|
---|
3241 | ExceptionOr<String> Internals::replayDisplayListForElement(Element& element, unsigned short flags)
|
---|
3242 | {
|
---|
3243 | Document* document = contextDocument();
|
---|
3244 | if (!document || !document->renderView())
|
---|
3245 | return Exception { InvalidAccessError };
|
---|
3246 |
|
---|
3247 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
3248 |
|
---|
3249 | if (!element.renderer())
|
---|
3250 | return Exception { InvalidAccessError };
|
---|
3251 |
|
---|
3252 | if (!element.renderer()->hasLayer())
|
---|
3253 | return Exception { InvalidAccessError };
|
---|
3254 |
|
---|
3255 | RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
|
---|
3256 | if (!layer->isComposited())
|
---|
3257 | return Exception { InvalidAccessError };
|
---|
3258 |
|
---|
3259 | return layer->backing()->replayDisplayListAsText(toDisplayListFlags(flags));
|
---|
3260 | }
|
---|
3261 |
|
---|
3262 | void Internals::setForceUseGlyphDisplayListForTesting(bool enabled)
|
---|
3263 | {
|
---|
3264 | TextPainter::setForceUseGlyphDisplayListForTesting(enabled);
|
---|
3265 | }
|
---|
3266 |
|
---|
3267 | ExceptionOr<String> Internals::cachedGlyphDisplayListsForTextNode(Node& node, unsigned short flags)
|
---|
3268 | {
|
---|
3269 | Document* document = contextDocument();
|
---|
3270 | if (!document || !document->renderView())
|
---|
3271 | return Exception { InvalidAccessError };
|
---|
3272 |
|
---|
3273 | if (!is<Text>(node))
|
---|
3274 | return Exception { InvalidAccessError };
|
---|
3275 |
|
---|
3276 | node.document().updateLayoutIgnorePendingStylesheets();
|
---|
3277 |
|
---|
3278 | if (!node.renderer())
|
---|
3279 | return Exception { InvalidAccessError };
|
---|
3280 |
|
---|
3281 | return TextPainter::cachedGlyphDisplayListsForTextNodeAsText(downcast<Text>(node), toDisplayListFlags(flags));
|
---|
3282 | }
|
---|
3283 |
|
---|
3284 | ExceptionOr<void> Internals::garbageCollectDocumentResources() const
|
---|
3285 | {
|
---|
3286 | Document* document = contextDocument();
|
---|
3287 | if (!document)
|
---|
3288 | return Exception { InvalidAccessError };
|
---|
3289 | document->cachedResourceLoader().garbageCollectDocumentResources();
|
---|
3290 | return { };
|
---|
3291 | }
|
---|
3292 |
|
---|
3293 | bool Internals::isUnderMemoryPressure()
|
---|
3294 | {
|
---|
3295 | return MemoryPressureHandler::singleton().isUnderMemoryPressure();
|
---|
3296 | }
|
---|
3297 |
|
---|
3298 | void Internals::beginSimulatedMemoryPressure()
|
---|
3299 | {
|
---|
3300 | MemoryPressureHandler::singleton().beginSimulatedMemoryPressure();
|
---|
3301 | }
|
---|
3302 |
|
---|
3303 | void Internals::endSimulatedMemoryPressure()
|
---|
3304 | {
|
---|
3305 | MemoryPressureHandler::singleton().endSimulatedMemoryPressure();
|
---|
3306 | }
|
---|
3307 |
|
---|
3308 | ExceptionOr<void> Internals::insertAuthorCSS(const String& css) const
|
---|
3309 | {
|
---|
3310 | Document* document = contextDocument();
|
---|
3311 | if (!document)
|
---|
3312 | return Exception { InvalidAccessError };
|
---|
3313 |
|
---|
3314 | auto parsedSheet = StyleSheetContents::create(*document);
|
---|
3315 | parsedSheet.get().setIsUserStyleSheet(false);
|
---|
3316 | parsedSheet.get().parseString(css);
|
---|
3317 | document->extensionStyleSheets().addAuthorStyleSheetForTesting(WTFMove(parsedSheet));
|
---|
3318 | return { };
|
---|
3319 | }
|
---|
3320 |
|
---|
3321 | ExceptionOr<void> Internals::insertUserCSS(const String& css) const
|
---|
3322 | {
|
---|
3323 | Document* document = contextDocument();
|
---|
3324 | if (!document)
|
---|
3325 | return Exception { InvalidAccessError };
|
---|
3326 |
|
---|
3327 | auto parsedSheet = StyleSheetContents::create(*document);
|
---|
3328 | parsedSheet.get().setIsUserStyleSheet(true);
|
---|
3329 | parsedSheet.get().parseString(css);
|
---|
3330 | document->extensionStyleSheets().addUserStyleSheet(WTFMove(parsedSheet));
|
---|
3331 | return { };
|
---|
3332 | }
|
---|
3333 |
|
---|
3334 | String Internals::counterValue(Element& element)
|
---|
3335 | {
|
---|
3336 | return counterValueForElement(&element);
|
---|
3337 | }
|
---|
3338 |
|
---|
3339 | int Internals::pageNumber(Element& element, float pageWidth, float pageHeight)
|
---|
3340 | {
|
---|
3341 | return PrintContext::pageNumberForElement(&element, { pageWidth, pageHeight });
|
---|
3342 | }
|
---|
3343 |
|
---|
3344 | Vector<String> Internals::shortcutIconURLs() const
|
---|
3345 | {
|
---|
3346 | if (!frame())
|
---|
3347 | return { };
|
---|
3348 |
|
---|
3349 | auto* documentLoader = frame()->loader().documentLoader();
|
---|
3350 | if (!documentLoader)
|
---|
3351 | return { };
|
---|
3352 |
|
---|
3353 | Vector<String> result;
|
---|
3354 | for (auto& linkIcon : documentLoader->linkIcons())
|
---|
3355 | result.append(linkIcon.url.string());
|
---|
3356 |
|
---|
3357 | return result;
|
---|
3358 | }
|
---|
3359 |
|
---|
3360 | int Internals::numberOfPages(float pageWidth, float pageHeight)
|
---|
3361 | {
|
---|
3362 | if (!frame())
|
---|
3363 | return -1;
|
---|
3364 |
|
---|
3365 | return PrintContext::numberOfPages(*frame(), FloatSize(pageWidth, pageHeight));
|
---|
3366 | }
|
---|
3367 |
|
---|
3368 | ExceptionOr<String> Internals::pageProperty(const String& propertyName, int pageNumber) const
|
---|
3369 | {
|
---|
3370 | if (!frame())
|
---|
3371 | return Exception { InvalidAccessError };
|
---|
3372 |
|
---|
3373 | return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
|
---|
3374 | }
|
---|
3375 |
|
---|
3376 | ExceptionOr<String> Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const
|
---|
3377 | {
|
---|
3378 | if (!frame())
|
---|
3379 | return Exception { InvalidAccessError };
|
---|
3380 |
|
---|
3381 | return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
|
---|
3382 | }
|
---|
3383 |
|
---|
3384 | ExceptionOr<float> Internals::pageScaleFactor() const
|
---|
3385 | {
|
---|
3386 | Document* document = contextDocument();
|
---|
3387 | if (!document || !document->page())
|
---|
3388 | return Exception { InvalidAccessError };
|
---|
3389 |
|
---|
3390 | return document->page()->pageScaleFactor();
|
---|
3391 | }
|
---|
3392 |
|
---|
3393 | ExceptionOr<void> Internals::setPageScaleFactor(float scaleFactor, int x, int y)
|
---|
3394 | {
|
---|
3395 | Document* document = contextDocument();
|
---|
3396 | if (!document || !document->page())
|
---|
3397 | return Exception { InvalidAccessError };
|
---|
3398 |
|
---|
3399 | document->page()->setPageScaleFactor(scaleFactor, IntPoint(x, y));
|
---|
3400 | return { };
|
---|
3401 | }
|
---|
3402 |
|
---|
3403 | ExceptionOr<void> Internals::setPageZoomFactor(float zoomFactor)
|
---|
3404 | {
|
---|
3405 | Document* document = contextDocument();
|
---|
3406 | if (!document || !document->frame())
|
---|
3407 | return Exception { InvalidAccessError };
|
---|
3408 |
|
---|
3409 | document->frame()->setPageZoomFactor(zoomFactor);
|
---|
3410 | return { };
|
---|
3411 | }
|
---|
3412 |
|
---|
3413 | ExceptionOr<void> Internals::setTextZoomFactor(float zoomFactor)
|
---|
3414 | {
|
---|
3415 | Document* document = contextDocument();
|
---|
3416 | if (!document || !document->frame())
|
---|
3417 | return Exception { InvalidAccessError };
|
---|
3418 |
|
---|
3419 | document->frame()->setTextZoomFactor(zoomFactor);
|
---|
3420 | return { };
|
---|
3421 | }
|
---|
3422 |
|
---|
3423 | ExceptionOr<void> Internals::setUseFixedLayout(bool useFixedLayout)
|
---|
3424 | {
|
---|
3425 | Document* document = contextDocument();
|
---|
3426 | if (!document || !document->view())
|
---|
3427 | return Exception { InvalidAccessError };
|
---|
3428 |
|
---|
3429 | document->view()->setUseFixedLayout(useFixedLayout);
|
---|
3430 | return { };
|
---|
3431 | }
|
---|
3432 |
|
---|
3433 | ExceptionOr<void> Internals::setFixedLayoutSize(int width, int height)
|
---|
3434 | {
|
---|
3435 | Document* document = contextDocument();
|
---|
3436 | if (!document || !document->view())
|
---|
3437 | return Exception { InvalidAccessError };
|
---|
3438 |
|
---|
3439 | document->view()->setFixedLayoutSize(IntSize(width, height));
|
---|
3440 | return { };
|
---|
3441 | }
|
---|
3442 |
|
---|
3443 | ExceptionOr<void> Internals::setViewExposedRect(float x, float y, float width, float height)
|
---|
3444 | {
|
---|
3445 | Document* document = contextDocument();
|
---|
3446 | if (!document || !document->view())
|
---|
3447 | return Exception { InvalidAccessError };
|
---|
3448 |
|
---|
3449 | document->view()->setViewExposedRect(FloatRect(x, y, width, height));
|
---|
3450 | return { };
|
---|
3451 | }
|
---|
3452 |
|
---|
3453 | void Internals::setPrinting(int width, int height)
|
---|
3454 | {
|
---|
3455 | printContextForTesting() = makeUnique<PrintContext>(frame());
|
---|
3456 | printContextForTesting()->begin(width, height);
|
---|
3457 | }
|
---|
3458 |
|
---|
3459 | void Internals::setHeaderHeight(float height)
|
---|
3460 | {
|
---|
3461 | Document* document = contextDocument();
|
---|
3462 | if (!document || !document->view())
|
---|
3463 | return;
|
---|
3464 |
|
---|
3465 | document->page()->setHeaderHeight(height);
|
---|
3466 | }
|
---|
3467 |
|
---|
3468 | void Internals::setFooterHeight(float height)
|
---|
3469 | {
|
---|
3470 | Document* document = contextDocument();
|
---|
3471 | if (!document || !document->view())
|
---|
3472 | return;
|
---|
3473 |
|
---|
3474 | document->page()->setFooterHeight(height);
|
---|
3475 | }
|
---|
3476 |
|
---|
3477 | void Internals::setTopContentInset(float contentInset)
|
---|
3478 | {
|
---|
3479 | Document* document = contextDocument();
|
---|
3480 | if (!document || !document->page())
|
---|
3481 | return;
|
---|
3482 |
|
---|
3483 | document->page()->setTopContentInset(contentInset);
|
---|
3484 | }
|
---|
3485 |
|
---|
3486 | #if ENABLE(FULLSCREEN_API)
|
---|
3487 |
|
---|
3488 | void Internals::webkitWillEnterFullScreenForElement(Element& element)
|
---|
3489 | {
|
---|
3490 | Document* document = contextDocument();
|
---|
3491 | if (!document)
|
---|
3492 | return;
|
---|
3493 | document->fullscreenManager().willEnterFullscreen(element);
|
---|
3494 | }
|
---|
3495 |
|
---|
3496 | void Internals::webkitDidEnterFullScreenForElement(Element&)
|
---|
3497 | {
|
---|
3498 | Document* document = contextDocument();
|
---|
3499 | if (!document)
|
---|
3500 | return;
|
---|
3501 | document->fullscreenManager().didEnterFullscreen();
|
---|
3502 | }
|
---|
3503 |
|
---|
3504 | void Internals::webkitWillExitFullScreenForElement(Element&)
|
---|
3505 | {
|
---|
3506 | Document* document = contextDocument();
|
---|
3507 | if (!document)
|
---|
3508 | return;
|
---|
3509 | document->fullscreenManager().willExitFullscreen();
|
---|
3510 | }
|
---|
3511 |
|
---|
3512 | void Internals::webkitDidExitFullScreenForElement(Element&)
|
---|
3513 | {
|
---|
3514 | Document* document = contextDocument();
|
---|
3515 | if (!document)
|
---|
3516 | return;
|
---|
3517 | document->fullscreenManager().didExitFullscreen();
|
---|
3518 | }
|
---|
3519 |
|
---|
3520 | bool Internals::isAnimatingFullScreen() const
|
---|
3521 | {
|
---|
3522 | Document* document = contextDocument();
|
---|
3523 | if (!document)
|
---|
3524 | return false;
|
---|
3525 | return document->fullscreenManager().isAnimatingFullscreen();
|
---|
3526 | }
|
---|
3527 |
|
---|
3528 | #endif
|
---|
3529 |
|
---|
3530 | void Internals::setFullscreenInsets(FullscreenInsets insets)
|
---|
3531 | {
|
---|
3532 | Page* page = contextDocument()->frame()->page();
|
---|
3533 | ASSERT(page);
|
---|
3534 |
|
---|
3535 | page->setFullscreenInsets(FloatBoxExtent(insets.top, insets.right, insets.bottom, insets.left));
|
---|
3536 | }
|
---|
3537 |
|
---|
3538 | void Internals::setFullscreenAutoHideDuration(double duration)
|
---|
3539 | {
|
---|
3540 | Page* page = contextDocument()->frame()->page();
|
---|
3541 | ASSERT(page);
|
---|
3542 |
|
---|
3543 | page->setFullscreenAutoHideDuration(Seconds(duration));
|
---|
3544 | }
|
---|
3545 |
|
---|
3546 | void Internals::setFullscreenControlsHidden(bool hidden)
|
---|
3547 | {
|
---|
3548 | Page* page = contextDocument()->frame()->page();
|
---|
3549 | ASSERT(page);
|
---|
3550 |
|
---|
3551 | page->setFullscreenControlsHidden(hidden);
|
---|
3552 | }
|
---|
3553 |
|
---|
3554 | #if ENABLE(VIDEO)
|
---|
3555 | bool Internals::isChangingPresentationMode(HTMLVideoElement& element) const
|
---|
3556 | {
|
---|
3557 | #if ENABLE(VIDEO_PRESENTATION_MODE)
|
---|
3558 | return element.isChangingPresentationMode();
|
---|
3559 | #else
|
---|
3560 | UNUSED_PARAM(element);
|
---|
3561 | return false;
|
---|
3562 | #endif
|
---|
3563 | }
|
---|
3564 | #endif
|
---|
3565 |
|
---|
3566 | #if ENABLE(VIDEO_PRESENTATION_MODE)
|
---|
3567 | void Internals::setMockVideoPresentationModeEnabled(bool enabled)
|
---|
3568 | {
|
---|
3569 | Document* document = contextDocument();
|
---|
3570 | if (!document || !document->page())
|
---|
3571 | return;
|
---|
3572 |
|
---|
3573 | document->page()->chrome().client().setMockVideoPresentationModeEnabled(enabled);
|
---|
3574 | }
|
---|
3575 | #endif
|
---|
3576 |
|
---|
3577 | void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
|
---|
3578 | {
|
---|
3579 | Document* document = contextDocument();
|
---|
3580 | if (!document || !document->page())
|
---|
3581 | return;
|
---|
3582 | document->page()->applicationCacheStorage().storeUpdatedQuotaForOrigin(&document->securityOrigin(), quota);
|
---|
3583 | }
|
---|
3584 |
|
---|
3585 | void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
|
---|
3586 | {
|
---|
3587 | LegacySchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
|
---|
3588 | }
|
---|
3589 |
|
---|
3590 | void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
|
---|
3591 | {
|
---|
3592 | LegacySchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
|
---|
3593 | }
|
---|
3594 |
|
---|
3595 | void Internals::registerDefaultPortForProtocol(unsigned short port, const String& protocol)
|
---|
3596 | {
|
---|
3597 | registerDefaultPortForProtocolForTesting(port, protocol);
|
---|
3598 | }
|
---|
3599 |
|
---|
3600 | Ref<MallocStatistics> Internals::mallocStatistics() const
|
---|
3601 | {
|
---|
3602 | return MallocStatistics::create();
|
---|
3603 | }
|
---|
3604 |
|
---|
3605 | Ref<TypeConversions> Internals::typeConversions() const
|
---|
3606 | {
|
---|
3607 | return TypeConversions::create();
|
---|
3608 | }
|
---|
3609 |
|
---|
3610 | Ref<MemoryInfo> Internals::memoryInfo() const
|
---|
3611 | {
|
---|
3612 | return MemoryInfo::create();
|
---|
3613 | }
|
---|
3614 |
|
---|
3615 | Vector<String> Internals::getReferencedFilePaths() const
|
---|
3616 | {
|
---|
3617 | frame()->loader().history().saveDocumentAndScrollState();
|
---|
3618 | return FormController::referencedFilePaths(frame()->loader().history().currentItem()->documentState());
|
---|
3619 | }
|
---|
3620 |
|
---|
3621 | ExceptionOr<void> Internals::startTrackingRepaints()
|
---|
3622 | {
|
---|
3623 | Document* document = contextDocument();
|
---|
3624 | if (!document || !document->view())
|
---|
3625 | return Exception { InvalidAccessError };
|
---|
3626 |
|
---|
3627 | document->view()->setTracksRepaints(true);
|
---|
3628 | return { };
|
---|
3629 | }
|
---|
3630 |
|
---|
3631 | ExceptionOr<void> Internals::stopTrackingRepaints()
|
---|
3632 | {
|
---|
3633 | Document* document = contextDocument();
|
---|
3634 | if (!document || !document->view())
|
---|
3635 | return Exception { InvalidAccessError };
|
---|
3636 |
|
---|
3637 | document->view()->setTracksRepaints(false);
|
---|
3638 | return { };
|
---|
3639 | }
|
---|
3640 |
|
---|
3641 | ExceptionOr<void> Internals::startTrackingLayerFlushes()
|
---|
3642 | {
|
---|
3643 | Document* document = contextDocument();
|
---|
3644 | if (!document || !document->renderView())
|
---|
3645 | return Exception { InvalidAccessError };
|
---|
3646 |
|
---|
3647 | document->renderView()->compositor().startTrackingLayerFlushes();
|
---|
3648 | return { };
|
---|
3649 | }
|
---|
3650 |
|
---|
3651 | ExceptionOr<unsigned> Internals::layerFlushCount()
|
---|
3652 | {
|
---|
3653 | Document* document = contextDocument();
|
---|
3654 | if (!document || !document->renderView())
|
---|
3655 | return Exception { InvalidAccessError };
|
---|
3656 |
|
---|
3657 | return document->renderView()->compositor().layerFlushCount();
|
---|
3658 | }
|
---|
3659 |
|
---|
3660 | ExceptionOr<void> Internals::startTrackingStyleRecalcs()
|
---|
3661 | {
|
---|
3662 | Document* document = contextDocument();
|
---|
3663 | if (!document)
|
---|
3664 | return Exception { InvalidAccessError };
|
---|
3665 |
|
---|
3666 | document->startTrackingStyleRecalcs();
|
---|
3667 | return { };
|
---|
3668 | }
|
---|
3669 |
|
---|
3670 | ExceptionOr<unsigned> Internals::styleRecalcCount()
|
---|
3671 | {
|
---|
3672 | Document* document = contextDocument();
|
---|
3673 | if (!document)
|
---|
3674 | return Exception { InvalidAccessError };
|
---|
3675 |
|
---|
3676 | return document->styleRecalcCount();
|
---|
3677 | }
|
---|
3678 |
|
---|
3679 | unsigned Internals::lastStyleUpdateSize() const
|
---|
3680 | {
|
---|
3681 | Document* document = contextDocument();
|
---|
3682 | if (!document)
|
---|
3683 | return 0;
|
---|
3684 | return document->lastStyleUpdateSizeForTesting();
|
---|
3685 | }
|
---|
3686 |
|
---|
3687 | ExceptionOr<void> Internals::startTrackingCompositingUpdates()
|
---|
3688 | {
|
---|
3689 | Document* document = contextDocument();
|
---|
3690 | if (!document || !document->renderView())
|
---|
3691 | return Exception { InvalidAccessError };
|
---|
3692 |
|
---|
3693 | document->renderView()->compositor().startTrackingCompositingUpdates();
|
---|
3694 | return { };
|
---|
3695 | }
|
---|
3696 |
|
---|
3697 | ExceptionOr<unsigned> Internals::compositingUpdateCount()
|
---|
3698 | {
|
---|
3699 | Document* document = contextDocument();
|
---|
3700 | if (!document || !document->renderView())
|
---|
3701 | return Exception { InvalidAccessError };
|
---|
3702 |
|
---|
3703 | return document->renderView()->compositor().compositingUpdateCount();
|
---|
3704 | }
|
---|
3705 |
|
---|
3706 | ExceptionOr<void> Internals::startTrackingRenderingUpdates()
|
---|
3707 | {
|
---|
3708 | Document* document = contextDocument();
|
---|
3709 | if (!document)
|
---|
3710 | return Exception { InvalidAccessError };
|
---|
3711 |
|
---|
3712 | document->page()->startTrackingRenderingUpdates();
|
---|
3713 | return { };
|
---|
3714 | }
|
---|
3715 |
|
---|
3716 | ExceptionOr<unsigned> Internals::renderingUpdateCount()
|
---|
3717 | {
|
---|
3718 | Document* document = contextDocument();
|
---|
3719 | if (!document)
|
---|
3720 | return Exception { InvalidAccessError };
|
---|
3721 |
|
---|
3722 | return document->page()->renderingUpdateCount();
|
---|
3723 | }
|
---|
3724 |
|
---|
3725 | ExceptionOr<void> Internals::setCompositingPolicyOverride(std::optional<CompositingPolicy> policyOverride)
|
---|
3726 | {
|
---|
3727 | Document* document = contextDocument();
|
---|
3728 | if (!document)
|
---|
3729 | return Exception { InvalidAccessError };
|
---|
3730 |
|
---|
3731 | if (!policyOverride) {
|
---|
3732 | document->page()->setCompositingPolicyOverride(std::nullopt);
|
---|
3733 | return { };
|
---|
3734 | }
|
---|
3735 |
|
---|
3736 | switch (policyOverride.value()) {
|
---|
3737 | case Internals::CompositingPolicy::Normal:
|
---|
3738 | document->page()->setCompositingPolicyOverride(WebCore::CompositingPolicy::Normal);
|
---|
3739 | break;
|
---|
3740 | case Internals::CompositingPolicy::Conservative:
|
---|
3741 | document->page()->setCompositingPolicyOverride(WebCore::CompositingPolicy::Conservative);
|
---|
3742 | break;
|
---|
3743 | }
|
---|
3744 |
|
---|
3745 | return { };
|
---|
3746 | }
|
---|
3747 |
|
---|
3748 | ExceptionOr<std::optional<Internals::CompositingPolicy>> Internals::compositingPolicyOverride() const
|
---|
3749 | {
|
---|
3750 | Document* document = contextDocument();
|
---|
3751 | if (!document)
|
---|
3752 | return Exception { InvalidAccessError };
|
---|
3753 |
|
---|
3754 | auto policyOverride = document->page()->compositingPolicyOverride();
|
---|
3755 | if (!policyOverride)
|
---|
3756 | return { std::nullopt };
|
---|
3757 |
|
---|
3758 | switch (policyOverride.value()) {
|
---|
3759 | case WebCore::CompositingPolicy::Normal:
|
---|
3760 | return { Internals::CompositingPolicy::Normal };
|
---|
3761 | case WebCore::CompositingPolicy::Conservative:
|
---|
3762 | return { Internals::CompositingPolicy::Conservative };
|
---|
3763 | }
|
---|
3764 |
|
---|
3765 | return { Internals::CompositingPolicy::Normal };
|
---|
3766 | }
|
---|
3767 |
|
---|
3768 | void Internals::updateLayoutAndStyleForAllFrames()
|
---|
3769 | {
|
---|
3770 | auto* document = contextDocument();
|
---|
3771 | if (!document || !document->view())
|
---|
3772 | return;
|
---|
3773 | document->view()->updateLayoutAndStyleIfNeededRecursive();
|
---|
3774 | }
|
---|
3775 |
|
---|
3776 | ExceptionOr<void> Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node)
|
---|
3777 | {
|
---|
3778 | Document* document;
|
---|
3779 | if (!node)
|
---|
3780 | document = contextDocument();
|
---|
3781 | else if (is<Document>(*node))
|
---|
3782 | document = downcast<Document>(node);
|
---|
3783 | else if (is<HTMLIFrameElement>(*node))
|
---|
3784 | document = downcast<HTMLIFrameElement>(*node).contentDocument();
|
---|
3785 | else
|
---|
3786 | return Exception { TypeError };
|
---|
3787 |
|
---|
3788 | document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
|
---|
3789 | return { };
|
---|
3790 | }
|
---|
3791 |
|
---|
3792 | unsigned Internals::layoutCount() const
|
---|
3793 | {
|
---|
3794 | Document* document = contextDocument();
|
---|
3795 | if (!document || !document->view())
|
---|
3796 | return 0;
|
---|
3797 | return document->view()->layoutContext().layoutCount();
|
---|
3798 | }
|
---|
3799 |
|
---|
3800 | #if !PLATFORM(IOS_FAMILY)
|
---|
3801 | static const char* cursorTypeToString(Cursor::Type cursorType)
|
---|
3802 | {
|
---|
3803 | switch (cursorType) {
|
---|
3804 | case Cursor::Pointer: return "Pointer";
|
---|
3805 | case Cursor::Cross: return "Cross";
|
---|
3806 | case Cursor::Hand: return "Hand";
|
---|
3807 | case Cursor::IBeam: return "IBeam";
|
---|
3808 | case Cursor::Wait: return "Wait";
|
---|
3809 | case Cursor::Help: return "Help";
|
---|
3810 | case Cursor::EastResize: return "EastResize";
|
---|
3811 | case Cursor::NorthResize: return "NorthResize";
|
---|
3812 | case Cursor::NorthEastResize: return "NorthEastResize";
|
---|
3813 | case Cursor::NorthWestResize: return "NorthWestResize";
|
---|
3814 | case Cursor::SouthResize: return "SouthResize";
|
---|
3815 | case Cursor::SouthEastResize: return "SouthEastResize";
|
---|
3816 | case Cursor::SouthWestResize: return "SouthWestResize";
|
---|
3817 | case Cursor::WestResize: return "WestResize";
|
---|
3818 | case Cursor::NorthSouthResize: return "NorthSouthResize";
|
---|
3819 | case Cursor::EastWestResize: return "EastWestResize";
|
---|
3820 | case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
|
---|
3821 | case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
|
---|
3822 | case Cursor::ColumnResize: return "ColumnResize";
|
---|
3823 | case Cursor::RowResize: return "RowResize";
|
---|
3824 | case Cursor::MiddlePanning: return "MiddlePanning";
|
---|
3825 | case Cursor::EastPanning: return "EastPanning";
|
---|
3826 | case Cursor::NorthPanning: return "NorthPanning";
|
---|
3827 | case Cursor::NorthEastPanning: return "NorthEastPanning";
|
---|
3828 | case Cursor::NorthWestPanning: return "NorthWestPanning";
|
---|
3829 | case Cursor::SouthPanning: return "SouthPanning";
|
---|
3830 | case Cursor::SouthEastPanning: return "SouthEastPanning";
|
---|
3831 | case Cursor::SouthWestPanning: return "SouthWestPanning";
|
---|
3832 | case Cursor::WestPanning: return "WestPanning";
|
---|
3833 | case Cursor::Move: return "Move";
|
---|
3834 | case Cursor::VerticalText: return "VerticalText";
|
---|
3835 | case Cursor::Cell: return "Cell";
|
---|
3836 | case Cursor::ContextMenu: return "ContextMenu";
|
---|
3837 | case Cursor::Alias: return "Alias";
|
---|
3838 | case Cursor::Progress: return "Progress";
|
---|
3839 | case Cursor::NoDrop: return "NoDrop";
|
---|
3840 | case Cursor::Copy: return "Copy";
|
---|
3841 | case Cursor::None: return "None";
|
---|
3842 | case Cursor::NotAllowed: return "NotAllowed";
|
---|
3843 | case Cursor::ZoomIn: return "ZoomIn";
|
---|
3844 | case Cursor::ZoomOut: return "ZoomOut";
|
---|
3845 | case Cursor::Grab: return "Grab";
|
---|
3846 | case Cursor::Grabbing: return "Grabbing";
|
---|
3847 | case Cursor::Custom: return "Custom";
|
---|
3848 | }
|
---|
3849 |
|
---|
3850 | ASSERT_NOT_REACHED();
|
---|
3851 | return "UNKNOWN";
|
---|
3852 | }
|
---|
3853 | #endif
|
---|
3854 |
|
---|
3855 | ExceptionOr<String> Internals::getCurrentCursorInfo()
|
---|
3856 | {
|
---|
3857 | Document* document = contextDocument();
|
---|
3858 | if (!document || !document->frame())
|
---|
3859 | return Exception { InvalidAccessError };
|
---|
3860 |
|
---|
3861 | #if !PLATFORM(IOS_FAMILY)
|
---|
3862 | Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
|
---|
3863 |
|
---|
3864 | StringBuilder result;
|
---|
3865 | result.append("type=", cursorTypeToString(cursor.type()), " hotSpot=", cursor.hotSpot().x(), ',', cursor.hotSpot().y());
|
---|
3866 | if (cursor.image()) {
|
---|
3867 | FloatSize size = cursor.image()->size();
|
---|
3868 | result.append(" image=", size.width(), 'x', size.height());
|
---|
3869 | }
|
---|
3870 | #if ENABLE(MOUSE_CURSOR_SCALE)
|
---|
3871 | if (cursor.imageScaleFactor() != 1)
|
---|
3872 | result.append(" scale=", cursor.imageScaleFactor());
|
---|
3873 | #endif
|
---|
3874 | return result.toString();
|
---|
3875 | #else
|
---|
3876 | return "FAIL: Cursor details not available on this platform."_str;
|
---|
3877 | #endif
|
---|
3878 | }
|
---|
3879 |
|
---|
3880 | Ref<ArrayBuffer> Internals::serializeObject(const RefPtr<SerializedScriptValue>& value) const
|
---|
3881 | {
|
---|
3882 | auto& bytes = value->wireBytes();
|
---|
3883 | return ArrayBuffer::create(bytes.data(), bytes.size());
|
---|
3884 | }
|
---|
3885 |
|
---|
3886 | Ref<SerializedScriptValue> Internals::deserializeBuffer(ArrayBuffer& buffer) const
|
---|
3887 | {
|
---|
3888 | Vector<uint8_t> bytes { static_cast<const uint8_t*>(buffer.data()), buffer.byteLength() };
|
---|
3889 | return SerializedScriptValue::createFromWireBytes(WTFMove(bytes));
|
---|
3890 | }
|
---|
3891 |
|
---|
3892 | bool Internals::isFromCurrentWorld(JSC::JSValue value) const
|
---|
3893 | {
|
---|
3894 | JSC::VM& vm = contextDocument()->vm();
|
---|
3895 | return isWorldCompatible(*vm.topCallFrame->lexicalGlobalObject(vm), value);
|
---|
3896 | }
|
---|
3897 |
|
---|
3898 | JSC::JSValue Internals::evaluateInWorldIgnoringException(const String& name, const String& source)
|
---|
3899 | {
|
---|
3900 | auto* document = contextDocument();
|
---|
3901 | auto& scriptController = document->frame()->script();
|
---|
3902 | auto world = ScriptController::createWorld(name);
|
---|
3903 | return scriptController.executeScriptInWorldIgnoringException(world, source);
|
---|
3904 | }
|
---|
3905 |
|
---|
3906 | void Internals::setUsesOverlayScrollbars(bool enabled)
|
---|
3907 | {
|
---|
3908 | WebCore::DeprecatedGlobalSettings::setUsesOverlayScrollbars(enabled);
|
---|
3909 | #if PLATFORM(MAC)
|
---|
3910 | ScrollerStyle::setUseOverlayScrollbars(enabled);
|
---|
3911 | ScrollbarTheme& theme = ScrollbarTheme::theme();
|
---|
3912 | if (theme.isMockTheme())
|
---|
3913 | return;
|
---|
3914 |
|
---|
3915 | static_cast<ScrollbarThemeMac&>(theme).preferencesChanged();
|
---|
3916 | #endif
|
---|
3917 | }
|
---|
3918 |
|
---|
3919 | void Internals::forceReload(bool endToEnd)
|
---|
3920 | {
|
---|
3921 | OptionSet<ReloadOption> reloadOptions;
|
---|
3922 | if (endToEnd)
|
---|
3923 | reloadOptions.add(ReloadOption::FromOrigin);
|
---|
3924 |
|
---|
3925 | frame()->loader().reload(reloadOptions);
|
---|
3926 | }
|
---|
3927 |
|
---|
3928 | void Internals::reloadExpiredOnly()
|
---|
3929 | {
|
---|
3930 | frame()->loader().reload(ReloadOption::ExpiredOnly);
|
---|
3931 | }
|
---|
3932 |
|
---|
3933 | void Internals::enableFixedWidthAutoSizeMode(bool enabled, int width, int height)
|
---|
3934 | {
|
---|
3935 | auto* document = contextDocument();
|
---|
3936 | if (!document || !document->view())
|
---|
3937 | return;
|
---|
3938 | document->view()->enableFixedWidthAutoSizeMode(enabled, { width, height });
|
---|
3939 | }
|
---|
3940 |
|
---|
3941 | void Internals::enableSizeToContentAutoSizeMode(bool enabled, int width, int height)
|
---|
3942 | {
|
---|
3943 | auto* document = contextDocument();
|
---|
3944 | if (!document || !document->view())
|
---|
3945 | return;
|
---|
3946 | document->view()->enableSizeToContentAutoSizeMode(enabled, { width, height });
|
---|
3947 | }
|
---|
3948 |
|
---|
3949 | #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
|
---|
3950 |
|
---|
3951 | void Internals::initializeMockCDM()
|
---|
3952 | {
|
---|
3953 | LegacyCDM::registerCDMFactory([] (LegacyCDM* cdm) { return makeUnique<LegacyMockCDM>(cdm); },
|
---|
3954 | LegacyMockCDM::supportsKeySystem, LegacyMockCDM::supportsKeySystemAndMimeType);
|
---|
3955 | }
|
---|
3956 |
|
---|
3957 | #endif
|
---|
3958 |
|
---|
3959 | #if ENABLE(ENCRYPTED_MEDIA)
|
---|
3960 |
|
---|
3961 | Ref<MockCDMFactory> Internals::registerMockCDM()
|
---|
3962 | {
|
---|
3963 | return MockCDMFactory::create();
|
---|
3964 | }
|
---|
3965 |
|
---|
3966 | #endif
|
---|
3967 |
|
---|
3968 | String Internals::markerTextForListItem(Element& element)
|
---|
3969 | {
|
---|
3970 | return WebCore::markerTextForListItem(&element);
|
---|
3971 | }
|
---|
3972 |
|
---|
3973 | String Internals::toolTipFromElement(Element& element) const
|
---|
3974 | {
|
---|
3975 | HitTestResult result;
|
---|
3976 | result.setInnerNode(&element);
|
---|
3977 | TextDirection direction;
|
---|
3978 | return result.title(direction);
|
---|
3979 | }
|
---|
3980 |
|
---|
3981 | String Internals::getImageSourceURL(Element& element)
|
---|
3982 | {
|
---|
3983 | return element.imageSourceURL();
|
---|
3984 | }
|
---|
3985 |
|
---|
3986 | #if ENABLE(VIDEO)
|
---|
3987 |
|
---|
3988 | unsigned Internals::mediaElementCount()
|
---|
3989 | {
|
---|
3990 | Document* document = contextDocument();
|
---|
3991 | if (!document)
|
---|
3992 | return 0;
|
---|
3993 |
|
---|
3994 | unsigned number = 0;
|
---|
3995 | for (auto* mediaElement : HTMLMediaElement::allMediaElements()) {
|
---|
3996 | if (&mediaElement->document() == document)
|
---|
3997 | ++number;
|
---|
3998 | }
|
---|
3999 |
|
---|
4000 | return number;
|
---|
4001 | }
|
---|
4002 |
|
---|
4003 | Vector<String> Internals::mediaResponseSources(HTMLMediaElement& media)
|
---|
4004 | {
|
---|
4005 | auto* resourceLoader = media.lastMediaResourceLoaderForTesting();
|
---|
4006 | if (!resourceLoader)
|
---|
4007 | return { };
|
---|
4008 | Vector<String> result;
|
---|
4009 | auto responses = resourceLoader->responsesForTesting();
|
---|
4010 | for (auto& response : responses)
|
---|
4011 | result.append(responseSourceToString(response));
|
---|
4012 | return result;
|
---|
4013 | }
|
---|
4014 |
|
---|
4015 | Vector<String> Internals::mediaResponseContentRanges(HTMLMediaElement& media)
|
---|
4016 | {
|
---|
4017 | auto* resourceLoader = media.lastMediaResourceLoaderForTesting();
|
---|
4018 | if (!resourceLoader)
|
---|
4019 | return { };
|
---|
4020 | Vector<String> result;
|
---|
4021 | auto responses = resourceLoader->responsesForTesting();
|
---|
4022 | for (auto& response : responses)
|
---|
4023 | result.append(response.httpHeaderField(HTTPHeaderName::ContentRange));
|
---|
4024 | return result;
|
---|
4025 | }
|
---|
4026 |
|
---|
4027 | void Internals::simulateAudioInterruption(HTMLMediaElement& element)
|
---|
4028 | {
|
---|
4029 | #if USE(GSTREAMER)
|
---|
4030 | element.player()->simulateAudioInterruption();
|
---|
4031 | #else
|
---|
4032 | UNUSED_PARAM(element);
|
---|
4033 | #endif
|
---|
4034 | }
|
---|
4035 |
|
---|
4036 | ExceptionOr<bool> Internals::mediaElementHasCharacteristic(HTMLMediaElement& element, const String& characteristic)
|
---|
4037 | {
|
---|
4038 | if (equalLettersIgnoringASCIICase(characteristic, "audible"_s))
|
---|
4039 | return element.hasAudio();
|
---|
4040 | if (equalLettersIgnoringASCIICase(characteristic, "visual"_s))
|
---|
4041 | return element.hasVideo();
|
---|
4042 | if (equalLettersIgnoringASCIICase(characteristic, "legible"_s))
|
---|
4043 | return element.hasClosedCaptions();
|
---|
4044 |
|
---|
4045 | return Exception { SyntaxError };
|
---|
4046 | }
|
---|
4047 |
|
---|
4048 | void Internals::beginSimulatedHDCPError(HTMLMediaElement& element)
|
---|
4049 | {
|
---|
4050 | if (auto player = element.player())
|
---|
4051 | player->beginSimulatedHDCPError();
|
---|
4052 | }
|
---|
4053 |
|
---|
4054 | void Internals::endSimulatedHDCPError(HTMLMediaElement& element)
|
---|
4055 | {
|
---|
4056 | if (auto player = element.player())
|
---|
4057 | player->endSimulatedHDCPError();
|
---|
4058 | }
|
---|
4059 |
|
---|
4060 | ExceptionOr<bool> Internals::mediaPlayerRenderingCanBeAccelerated(HTMLMediaElement& element)
|
---|
4061 | {
|
---|
4062 | return element.mediaPlayerRenderingCanBeAccelerated();
|
---|
4063 | }
|
---|
4064 |
|
---|
4065 | bool Internals::elementShouldBufferData(HTMLMediaElement& element)
|
---|
4066 | {
|
---|
4067 | return element.bufferingPolicy() < MediaPlayer::BufferingPolicy::LimitReadAhead;
|
---|
4068 | }
|
---|
4069 |
|
---|
4070 | String Internals::elementBufferingPolicy(HTMLMediaElement& element)
|
---|
4071 | {
|
---|
4072 | switch (element.bufferingPolicy()) {
|
---|
4073 | case MediaPlayer::BufferingPolicy::Default:
|
---|
4074 | return "Default"_s;
|
---|
4075 | case MediaPlayer::BufferingPolicy::LimitReadAhead:
|
---|
4076 | return "LimitReadAhead"_s;
|
---|
4077 | case MediaPlayer::BufferingPolicy::MakeResourcesPurgeable:
|
---|
4078 | return "MakeResourcesPurgeable"_s;
|
---|
4079 | case MediaPlayer::BufferingPolicy::PurgeResources:
|
---|
4080 | return "PurgeResources"_s;
|
---|
4081 | }
|
---|
4082 |
|
---|
4083 | ASSERT_NOT_REACHED();
|
---|
4084 | return "UNKNOWN"_s;
|
---|
4085 | }
|
---|
4086 |
|
---|
4087 | ExceptionOr<void> Internals::setOverridePreferredDynamicRangeMode(HTMLMediaElement& element, const String& modeString)
|
---|
4088 | {
|
---|
4089 | DynamicRangeMode mode;
|
---|
4090 | if (modeString == "None"_s)
|
---|
4091 | mode = DynamicRangeMode::None;
|
---|
4092 | else if (modeString == "Standard"_s)
|
---|
4093 | mode = DynamicRangeMode::Standard;
|
---|
4094 | else if (modeString == "HLG"_s)
|
---|
4095 | mode = DynamicRangeMode::HLG;
|
---|
4096 | else if (modeString == "HDR10"_s)
|
---|
4097 | mode = DynamicRangeMode::HDR10;
|
---|
4098 | else if (modeString == "DolbyVisionPQ"_s)
|
---|
4099 | mode = DynamicRangeMode::DolbyVisionPQ;
|
---|
4100 | else
|
---|
4101 | return Exception { SyntaxError };
|
---|
4102 |
|
---|
4103 | element.setOverridePreferredDynamicRangeMode(mode);
|
---|
4104 | return { };
|
---|
4105 | }
|
---|
4106 |
|
---|
4107 | #endif
|
---|
4108 |
|
---|
4109 | bool Internals::isSelectPopupVisible(HTMLSelectElement& element)
|
---|
4110 | {
|
---|
4111 | element.document().updateLayoutIgnorePendingStylesheets();
|
---|
4112 |
|
---|
4113 | auto* renderer = element.renderer();
|
---|
4114 | if (!is<RenderMenuList>(renderer))
|
---|
4115 | return false;
|
---|
4116 |
|
---|
4117 | #if !PLATFORM(IOS_FAMILY)
|
---|
4118 | return downcast<RenderMenuList>(*renderer).popupIsVisible();
|
---|
4119 | #else
|
---|
4120 | return false;
|
---|
4121 | #endif
|
---|
4122 | }
|
---|
4123 |
|
---|
4124 | ExceptionOr<String> Internals::captionsStyleSheetOverride()
|
---|
4125 | {
|
---|
4126 | Document* document = contextDocument();
|
---|
4127 | if (!document || !document->page())
|
---|
4128 | return Exception { InvalidAccessError };
|
---|
4129 |
|
---|
4130 | #if ENABLE(VIDEO)
|
---|
4131 | return document->page()->group().ensureCaptionPreferences().captionsStyleSheetOverride();
|
---|
4132 | #else
|
---|
4133 | return String { emptyString() };
|
---|
4134 | #endif
|
---|
4135 | }
|
---|
4136 |
|
---|
4137 | ExceptionOr<void> Internals::setCaptionsStyleSheetOverride(const String& override)
|
---|
4138 | {
|
---|
4139 | Document* document = contextDocument();
|
---|
4140 | if (!document || !document->page())
|
---|
4141 | return Exception { InvalidAccessError };
|
---|
4142 |
|
---|
4143 | #if ENABLE(VIDEO)
|
---|
4144 | document->page()->group().ensureCaptionPreferences().setCaptionsStyleSheetOverride(override);
|
---|
4145 | #else
|
---|
4146 | UNUSED_PARAM(override);
|
---|
4147 | #endif
|
---|
4148 | return { };
|
---|
4149 | }
|
---|
4150 |
|
---|
4151 | ExceptionOr<void> Internals::setPrimaryAudioTrackLanguageOverride(const String& language)
|
---|
4152 | {
|
---|
4153 | Document* document = contextDocument();
|
---|
4154 | if (!document || !document->page())
|
---|
4155 | return Exception { InvalidAccessError };
|
---|
4156 |
|
---|
4157 | #if ENABLE(VIDEO)
|
---|
4158 | document->page()->group().ensureCaptionPreferences().setPrimaryAudioTrackLanguageOverride(language);
|
---|
4159 | #else
|
---|
4160 | UNUSED_PARAM(language);
|
---|
4161 | #endif
|
---|
4162 | return { };
|
---|
4163 | }
|
---|
4164 |
|
---|
4165 | ExceptionOr<void> Internals::setCaptionDisplayMode(const String& mode)
|
---|
4166 | {
|
---|
4167 | Document* document = contextDocument();
|
---|
4168 | if (!document || !document->page())
|
---|
4169 | return Exception { InvalidAccessError };
|
---|
4170 |
|
---|
4171 | #if ENABLE(VIDEO)
|
---|
4172 | auto& captionPreferences = document->page()->group().ensureCaptionPreferences();
|
---|
4173 |
|
---|
4174 | if (equalLettersIgnoringASCIICase(mode, "automatic"_s))
|
---|
4175 | captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Automatic);
|
---|
4176 | else if (equalLettersIgnoringASCIICase(mode, "forcedonly"_s))
|
---|
4177 | captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
|
---|
4178 | else if (equalLettersIgnoringASCIICase(mode, "alwayson"_s))
|
---|
4179 | captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
|
---|
4180 | else if (equalLettersIgnoringASCIICase(mode, "manual"_s))
|
---|
4181 | captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Manual);
|
---|
4182 | else
|
---|
4183 | return Exception { SyntaxError };
|
---|
4184 | #else
|
---|
4185 | UNUSED_PARAM(mode);
|
---|
4186 | #endif
|
---|
4187 | return { };
|
---|
4188 | }
|
---|
4189 |
|
---|
4190 | #if ENABLE(VIDEO)
|
---|
4191 | RefPtr<TextTrackCueGeneric> Internals::createGenericCue(double startTime, double endTime, String text)
|
---|
4192 | {
|
---|
4193 | Document* document = contextDocument();
|
---|
4194 | if (!document || !document->page())
|
---|
4195 | return nullptr;
|
---|
4196 | return TextTrackCueGeneric::create(*document, MediaTime::createWithDouble(startTime), MediaTime::createWithDouble(endTime), text);
|
---|
4197 | }
|
---|
4198 |
|
---|
4199 | ExceptionOr<String> Internals::textTrackBCP47Language(TextTrack& track)
|
---|
4200 | {
|
---|
4201 | return String { track.validBCP47Language() };
|
---|
4202 | }
|
---|
4203 |
|
---|
4204 | Ref<TimeRanges> Internals::createTimeRanges(Float32Array& startTimes, Float32Array& endTimes)
|
---|
4205 | {
|
---|
4206 | ASSERT(startTimes.length() == endTimes.length());
|
---|
4207 | Ref<TimeRanges> ranges = TimeRanges::create();
|
---|
4208 |
|
---|
4209 | unsigned count = std::min(startTimes.length(), endTimes.length());
|
---|
4210 | for (unsigned i = 0; i < count; ++i)
|
---|
4211 | ranges->add(startTimes.item(i), endTimes.item(i));
|
---|
4212 | return ranges;
|
---|
4213 | }
|
---|
4214 |
|
---|
4215 | double Internals::closestTimeToTimeRanges(double time, TimeRanges& ranges)
|
---|
4216 | {
|
---|
4217 | return ranges.nearest(time);
|
---|
4218 | }
|
---|
4219 |
|
---|
4220 | #endif
|
---|
4221 |
|
---|
4222 | ExceptionOr<Ref<DOMRect>> Internals::selectionBounds()
|
---|
4223 | {
|
---|
4224 | Document* document = contextDocument();
|
---|
4225 | if (!document || !document->frame())
|
---|
4226 | return Exception { InvalidAccessError };
|
---|
4227 |
|
---|
4228 | return DOMRect::create(document->frame()->selection().selectionBounds());
|
---|
4229 | }
|
---|
4230 |
|
---|
4231 | void Internals::setSelectionWithoutValidation(Ref<Node> baseNode, unsigned baseOffset, RefPtr<Node> extentNode, unsigned extentOffset)
|
---|
4232 | {
|
---|
4233 | contextDocument()->frame()->selection().moveTo(
|
---|
4234 | VisiblePosition { makeDeprecatedLegacyPosition(baseNode.ptr(), baseOffset) },
|
---|
4235 | VisiblePosition { makeDeprecatedLegacyPosition(extentNode.get(), extentOffset) });
|
---|
4236 | }
|
---|
4237 |
|
---|
4238 | ExceptionOr<bool> Internals::isPluginUnavailabilityIndicatorObscured(Element& element)
|
---|
4239 | {
|
---|
4240 | if (!is<HTMLPlugInElement>(element))
|
---|
4241 | return Exception { InvalidAccessError };
|
---|
4242 |
|
---|
4243 | return downcast<HTMLPlugInElement>(element).isReplacementObscured();
|
---|
4244 | }
|
---|
4245 |
|
---|
4246 | ExceptionOr<String> Internals::unavailablePluginReplacementText(Element& element)
|
---|
4247 | {
|
---|
4248 | if (!is<HTMLPlugInElement>(element))
|
---|
4249 | return Exception { InvalidAccessError };
|
---|
4250 |
|
---|
4251 | auto* renderer = element.renderer();
|
---|
4252 | if (!is<RenderEmbeddedObject>(renderer))
|
---|
4253 | return String { };
|
---|
4254 |
|
---|
4255 | return String { downcast<RenderEmbeddedObject>(*renderer).pluginReplacementTextIfUnavailable() };
|
---|
4256 | }
|
---|
4257 |
|
---|
4258 | bool Internals::isPluginSnapshotted(Element&)
|
---|
4259 | {
|
---|
4260 | return false;
|
---|
4261 | }
|
---|
4262 |
|
---|
4263 | #if ENABLE(MEDIA_SOURCE)
|
---|
4264 |
|
---|
4265 | void Internals::initializeMockMediaSource()
|
---|
4266 | {
|
---|
4267 | #if USE(AVFOUNDATION)
|
---|
4268 | WebCore::DeprecatedGlobalSettings::setAVFoundationEnabled(false);
|
---|
4269 | #endif
|
---|
4270 | #if USE(GSTREAMER)
|
---|
4271 | WebCore::DeprecatedGlobalSettings::setGStreamerEnabled(false);
|
---|
4272 | #endif
|
---|
4273 | MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
|
---|
4274 | }
|
---|
4275 |
|
---|
4276 | void Internals::bufferedSamplesForTrackId(SourceBuffer& buffer, const AtomString& trackId, BufferedSamplesPromise&& promise)
|
---|
4277 | {
|
---|
4278 | buffer.bufferedSamplesForTrackId(trackId, [promise = WTFMove(promise)](auto&& samples) mutable {
|
---|
4279 | promise.resolve(WTFMove(samples));
|
---|
4280 | });
|
---|
4281 | }
|
---|
4282 |
|
---|
4283 | void Internals::enqueuedSamplesForTrackID(SourceBuffer& buffer, const AtomString& trackID, BufferedSamplesPromise&& promise)
|
---|
4284 | {
|
---|
4285 | return buffer.enqueuedSamplesForTrackID(trackID, [promise = WTFMove(promise)](auto&& samples) mutable {
|
---|
4286 | promise.resolve(WTFMove(samples));
|
---|
4287 | });
|
---|
4288 | }
|
---|
4289 |
|
---|
4290 | double Internals::minimumUpcomingPresentationTimeForTrackID(SourceBuffer& buffer, const AtomString& trackID)
|
---|
4291 | {
|
---|
4292 | return buffer.minimumUpcomingPresentationTimeForTrackID(trackID).toDouble();
|
---|
4293 | }
|
---|
4294 |
|
---|
4295 | void Internals::setShouldGenerateTimestamps(SourceBuffer& buffer, bool flag)
|
---|
4296 | {
|
---|
4297 | buffer.setShouldGenerateTimestamps(flag);
|
---|
4298 | }
|
---|
4299 |
|
---|
4300 | void Internals::setMaximumQueueDepthForTrackID(SourceBuffer& buffer, const AtomString& trackID, size_t maxQueueDepth)
|
---|
4301 | {
|
---|
4302 | buffer.setMaximumQueueDepthForTrackID(trackID, maxQueueDepth);
|
---|
4303 | }
|
---|
4304 |
|
---|
4305 | #endif
|
---|
4306 |
|
---|
4307 | void Internals::enableMockMediaCapabilities()
|
---|
4308 | {
|
---|
4309 | MediaEngineConfigurationFactory::enableMock();
|
---|
4310 | }
|
---|
4311 |
|
---|
4312 | #if ENABLE(VIDEO)
|
---|
4313 |
|
---|
4314 | ExceptionOr<void> Internals::beginMediaSessionInterruption(const String& interruptionString)
|
---|
4315 | {
|
---|
4316 | PlatformMediaSession::InterruptionType interruption = PlatformMediaSession::SystemInterruption;
|
---|
4317 |
|
---|
4318 | if (equalLettersIgnoringASCIICase(interruptionString, "system"_s))
|
---|
4319 | interruption = PlatformMediaSession::SystemInterruption;
|
---|
4320 | else if (equalLettersIgnoringASCIICase(interruptionString, "systemsleep"_s))
|
---|
4321 | interruption = PlatformMediaSession::SystemSleep;
|
---|
4322 | else if (equalLettersIgnoringASCIICase(interruptionString, "enteringbackground"_s))
|
---|
4323 | interruption = PlatformMediaSession::EnteringBackground;
|
---|
4324 | else if (equalLettersIgnoringASCIICase(interruptionString, "suspendedunderlock"_s))
|
---|
4325 | interruption = PlatformMediaSession::SuspendedUnderLock;
|
---|
4326 | else
|
---|
4327 | return Exception { InvalidAccessError };
|
---|
4328 |
|
---|
4329 | PlatformMediaSessionManager::sharedManager().beginInterruption(interruption);
|
---|
4330 | return { };
|
---|
4331 | }
|
---|
4332 |
|
---|
4333 | void Internals::endMediaSessionInterruption(const String& flagsString)
|
---|
4334 | {
|
---|
4335 | PlatformMediaSession::EndInterruptionFlags flags = PlatformMediaSession::NoFlags;
|
---|
4336 |
|
---|
4337 | if (equalLettersIgnoringASCIICase(flagsString, "mayresumeplaying"_s))
|
---|
4338 | flags = PlatformMediaSession::MayResumePlaying;
|
---|
4339 |
|
---|
4340 | PlatformMediaSessionManager::sharedManager().endInterruption(flags);
|
---|
4341 | }
|
---|
4342 |
|
---|
4343 | void Internals::applicationWillBecomeInactive()
|
---|
4344 | {
|
---|
4345 | PlatformMediaSessionManager::sharedManager().applicationWillBecomeInactive();
|
---|
4346 | }
|
---|
4347 |
|
---|
4348 | void Internals::applicationDidBecomeActive()
|
---|
4349 | {
|
---|
4350 | PlatformMediaSessionManager::sharedManager().applicationDidBecomeActive();
|
---|
4351 | }
|
---|
4352 |
|
---|
4353 | void Internals::applicationWillEnterForeground(bool suspendedUnderLock) const
|
---|
4354 | {
|
---|
4355 | PlatformMediaSessionManager::sharedManager().applicationWillEnterForeground(suspendedUnderLock);
|
---|
4356 | }
|
---|
4357 |
|
---|
4358 | void Internals::applicationDidEnterBackground(bool suspendedUnderLock) const
|
---|
4359 | {
|
---|
4360 | PlatformMediaSessionManager::sharedManager().applicationDidEnterBackground(suspendedUnderLock);
|
---|
4361 | }
|
---|
4362 |
|
---|
4363 | static PlatformMediaSession::MediaType mediaTypeFromString(const String& mediaTypeString)
|
---|
4364 | {
|
---|
4365 | if (equalLettersIgnoringASCIICase(mediaTypeString, "video"_s))
|
---|
4366 | return PlatformMediaSession::MediaType::Video;
|
---|
4367 | if (equalLettersIgnoringASCIICase(mediaTypeString, "audio"_s))
|
---|
4368 | return PlatformMediaSession::MediaType::Audio;
|
---|
4369 | if (equalLettersIgnoringASCIICase(mediaTypeString, "videoaudio"_s))
|
---|
4370 | return PlatformMediaSession::MediaType::VideoAudio;
|
---|
4371 | if (equalLettersIgnoringASCIICase(mediaTypeString, "webaudio"_s))
|
---|
4372 | return PlatformMediaSession::MediaType::WebAudio;
|
---|
4373 |
|
---|
4374 | return PlatformMediaSession::MediaType::None;
|
---|
4375 | }
|
---|
4376 |
|
---|
4377 | ExceptionOr<void> Internals::setMediaSessionRestrictions(const String& mediaTypeString, StringView restrictionsString)
|
---|
4378 | {
|
---|
4379 | auto mediaType = mediaTypeFromString(mediaTypeString);
|
---|
4380 | if (mediaType == PlatformMediaSession::MediaType::None)
|
---|
4381 | return Exception { InvalidAccessError };
|
---|
4382 |
|
---|
4383 | auto restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType);
|
---|
4384 | PlatformMediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
|
---|
4385 |
|
---|
4386 | restrictions = PlatformMediaSessionManager::NoRestrictions;
|
---|
4387 |
|
---|
4388 | for (StringView restrictionString : restrictionsString.split(',')) {
|
---|
4389 | if (equalLettersIgnoringASCIICase(restrictionString, "concurrentplaybacknotpermitted"_s))
|
---|
4390 | restrictions |= PlatformMediaSessionManager::ConcurrentPlaybackNotPermitted;
|
---|
4391 | if (equalLettersIgnoringASCIICase(restrictionString, "backgroundprocessplaybackrestricted"_s))
|
---|
4392 | restrictions |= PlatformMediaSessionManager::BackgroundProcessPlaybackRestricted;
|
---|
4393 | if (equalLettersIgnoringASCIICase(restrictionString, "backgroundtabplaybackrestricted"_s))
|
---|
4394 | restrictions |= PlatformMediaSessionManager::BackgroundTabPlaybackRestricted;
|
---|
4395 | if (equalLettersIgnoringASCIICase(restrictionString, "interruptedplaybacknotpermitted"_s))
|
---|
4396 | restrictions |= PlatformMediaSessionManager::InterruptedPlaybackNotPermitted;
|
---|
4397 | if (equalLettersIgnoringASCIICase(restrictionString, "inactiveprocessplaybackrestricted"_s))
|
---|
4398 | restrictions |= PlatformMediaSessionManager::InactiveProcessPlaybackRestricted;
|
---|
4399 | if (equalLettersIgnoringASCIICase(restrictionString, "suspendedunderlockplaybackrestricted"_s))
|
---|
4400 | restrictions |= PlatformMediaSessionManager::SuspendedUnderLockPlaybackRestricted;
|
---|
4401 | }
|
---|
4402 | PlatformMediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
|
---|
4403 | return { };
|
---|
4404 | }
|
---|
4405 |
|
---|
4406 | ExceptionOr<String> Internals::mediaSessionRestrictions(const String& mediaTypeString) const
|
---|
4407 | {
|
---|
4408 | PlatformMediaSession::MediaType mediaType = mediaTypeFromString(mediaTypeString);
|
---|
4409 | if (mediaType == PlatformMediaSession::MediaType::None)
|
---|
4410 | return Exception { InvalidAccessError };
|
---|
4411 |
|
---|
4412 | PlatformMediaSessionManager::SessionRestrictions restrictions = PlatformMediaSessionManager::sharedManager().restrictions(mediaType);
|
---|
4413 | if (restrictions == PlatformMediaSessionManager::NoRestrictions)
|
---|
4414 | return String();
|
---|
4415 |
|
---|
4416 | StringBuilder builder;
|
---|
4417 | if (restrictions & PlatformMediaSessionManager::ConcurrentPlaybackNotPermitted)
|
---|
4418 | builder.append("concurrentplaybacknotpermitted");
|
---|
4419 | if (restrictions & PlatformMediaSessionManager::BackgroundProcessPlaybackRestricted) {
|
---|
4420 | if (!builder.isEmpty())
|
---|
4421 | builder.append(',');
|
---|
4422 | builder.append("backgroundprocessplaybackrestricted");
|
---|
4423 | }
|
---|
4424 | if (restrictions & PlatformMediaSessionManager::BackgroundTabPlaybackRestricted) {
|
---|
4425 | if (!builder.isEmpty())
|
---|
4426 | builder.append(',');
|
---|
4427 | builder.append("backgroundtabplaybackrestricted");
|
---|
4428 | }
|
---|
4429 | if (restrictions & PlatformMediaSessionManager::InterruptedPlaybackNotPermitted) {
|
---|
4430 | if (!builder.isEmpty())
|
---|
4431 | builder.append(',');
|
---|
4432 | builder.append("interruptedplaybacknotpermitted");
|
---|
4433 | }
|
---|
4434 | return builder.toString();
|
---|
4435 | }
|
---|
4436 |
|
---|
4437 | void Internals::setMediaElementRestrictions(HTMLMediaElement& element, StringView restrictionsString)
|
---|
4438 | {
|
---|
4439 | MediaElementSession::BehaviorRestrictions restrictions = element.mediaSession().behaviorRestrictions();
|
---|
4440 | element.mediaSession().removeBehaviorRestriction(restrictions);
|
---|
4441 |
|
---|
4442 | restrictions = MediaElementSession::NoRestrictions;
|
---|
4443 |
|
---|
4444 | for (StringView restrictionString : restrictionsString.split(',')) {
|
---|
4445 | if (equalLettersIgnoringASCIICase(restrictionString, "norestrictions"_s))
|
---|
4446 | restrictions |= MediaElementSession::NoRestrictions;
|
---|
4447 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforload"_s))
|
---|
4448 | restrictions |= MediaElementSession::RequireUserGestureForLoad;
|
---|
4449 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforvideoratechange"_s))
|
---|
4450 | restrictions |= MediaElementSession::RequireUserGestureForVideoRateChange;
|
---|
4451 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforfullscreen"_s))
|
---|
4452 | restrictions |= MediaElementSession::RequireUserGestureForFullscreen;
|
---|
4453 | if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsenttoloadmedia"_s))
|
---|
4454 | restrictions |= MediaElementSession::RequirePageConsentToLoadMedia;
|
---|
4455 | if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsenttoresumemedia"_s))
|
---|
4456 | restrictions |= MediaElementSession::RequirePageConsentToResumeMedia;
|
---|
4457 | #if ENABLE(WIRELESS_PLAYBACK_TARGET)
|
---|
4458 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergesturetoshowplaybacktargetpicker"_s))
|
---|
4459 | restrictions |= MediaElementSession::RequireUserGestureToShowPlaybackTargetPicker;
|
---|
4460 | if (equalLettersIgnoringASCIICase(restrictionString, "wirelessvideoplaybackdisabled"_s))
|
---|
4461 | restrictions |= MediaElementSession::WirelessVideoPlaybackDisabled;
|
---|
4462 | #endif
|
---|
4463 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforaudioratechange"_s))
|
---|
4464 | restrictions |= MediaElementSession::RequireUserGestureForAudioRateChange;
|
---|
4465 | if (equalLettersIgnoringASCIICase(restrictionString, "autopreloadingnotpermitted"_s))
|
---|
4466 | restrictions |= MediaElementSession::AutoPreloadingNotPermitted;
|
---|
4467 | if (equalLettersIgnoringASCIICase(restrictionString, "invisibleautoplaynotpermitted"_s))
|
---|
4468 | restrictions |= MediaElementSession::InvisibleAutoplayNotPermitted;
|
---|
4469 | if (equalLettersIgnoringASCIICase(restrictionString, "overrideusergesturerequirementformaincontent"_s))
|
---|
4470 | restrictions |= MediaElementSession::OverrideUserGestureRequirementForMainContent;
|
---|
4471 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergesturetocontrolcontrolsmanager"_s))
|
---|
4472 | restrictions |= MediaElementSession::RequireUserGestureToControlControlsManager;
|
---|
4473 | if (equalLettersIgnoringASCIICase(restrictionString, "requireplaybackTocontrolcontrolsmanager"_s))
|
---|
4474 | restrictions |= MediaElementSession::RequirePlaybackToControlControlsManager;
|
---|
4475 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforvideoduetolowpowermode"_s))
|
---|
4476 | restrictions |= MediaElementSession::RequireUserGestureForVideoDueToLowPowerMode;
|
---|
4477 | if (equalLettersIgnoringASCIICase(restrictionString, "requirepagevisibilitytoplayaudio"_s))
|
---|
4478 | restrictions |= MediaElementSession::RequirePageVisibilityToPlayAudio;
|
---|
4479 | }
|
---|
4480 | element.mediaSession().addBehaviorRestriction(restrictions);
|
---|
4481 | }
|
---|
4482 |
|
---|
4483 | ExceptionOr<void> Internals::postRemoteControlCommand(const String& commandString, float argument)
|
---|
4484 | {
|
---|
4485 | PlatformMediaSession::RemoteControlCommandType command;
|
---|
4486 | PlatformMediaSession::RemoteCommandArgument parameter { argument, { } };
|
---|
4487 |
|
---|
4488 | if (equalLettersIgnoringASCIICase(commandString, "play"_s))
|
---|
4489 | command = PlatformMediaSession::PlayCommand;
|
---|
4490 | else if (equalLettersIgnoringASCIICase(commandString, "pause"_s))
|
---|
4491 | command = PlatformMediaSession::PauseCommand;
|
---|
4492 | else if (equalLettersIgnoringASCIICase(commandString, "stop"_s))
|
---|
4493 | command = PlatformMediaSession::StopCommand;
|
---|
4494 | else if (equalLettersIgnoringASCIICase(commandString, "toggleplaypause"_s))
|
---|
4495 | command = PlatformMediaSession::TogglePlayPauseCommand;
|
---|
4496 | else if (equalLettersIgnoringASCIICase(commandString, "beginseekingbackward"_s))
|
---|
4497 | command = PlatformMediaSession::BeginSeekingBackwardCommand;
|
---|
4498 | else if (equalLettersIgnoringASCIICase(commandString, "endseekingbackward"_s))
|
---|
4499 | command = PlatformMediaSession::EndSeekingBackwardCommand;
|
---|
4500 | else if (equalLettersIgnoringASCIICase(commandString, "beginseekingforward"_s))
|
---|
4501 | command = PlatformMediaSession::BeginSeekingForwardCommand;
|
---|
4502 | else if (equalLettersIgnoringASCIICase(commandString, "endseekingforward"_s))
|
---|
4503 | command = PlatformMediaSession::EndSeekingForwardCommand;
|
---|
4504 | else if (equalLettersIgnoringASCIICase(commandString, "seektoplaybackposition"_s))
|
---|
4505 | command = PlatformMediaSession::SeekToPlaybackPositionCommand;
|
---|
4506 | else if (equalLettersIgnoringASCIICase(commandString, "beginscrubbing"_s))
|
---|
4507 | command = PlatformMediaSession::BeginScrubbingCommand;
|
---|
4508 | else if (equalLettersIgnoringASCIICase(commandString, "endscrubbing"_s))
|
---|
4509 | command = PlatformMediaSession::EndScrubbingCommand;
|
---|
4510 | else
|
---|
4511 | return Exception { InvalidAccessError };
|
---|
4512 |
|
---|
4513 | PlatformMediaSessionManager::sharedManager().processDidReceiveRemoteControlCommand(command, parameter);
|
---|
4514 | return { };
|
---|
4515 | }
|
---|
4516 |
|
---|
4517 | void Internals::activeAudioRouteDidChange(bool shouldPause)
|
---|
4518 | {
|
---|
4519 | #if PLATFORM(IOS)
|
---|
4520 | MediaSessionHelper::sharedHelper().activeAudioRouteDidChange(shouldPause ? MediaSessionHelperClient::ShouldPause::Yes : MediaSessionHelperClient::ShouldPause::No);
|
---|
4521 | #else
|
---|
4522 | UNUSED_PARAM(shouldPause);
|
---|
4523 | #endif
|
---|
4524 | }
|
---|
4525 |
|
---|
4526 | bool Internals::elementIsBlockingDisplaySleep(const HTMLMediaElement& element) const
|
---|
4527 | {
|
---|
4528 | return element.isDisablingSleep();
|
---|
4529 | }
|
---|
4530 |
|
---|
4531 | bool Internals::isPlayerVisibleInViewport(const HTMLMediaElement& element) const
|
---|
4532 | {
|
---|
4533 | auto player = element.player();
|
---|
4534 | return player && player->isVisibleInViewport();
|
---|
4535 | }
|
---|
4536 |
|
---|
4537 | bool Internals::isPlayerMuted(const HTMLMediaElement& element) const
|
---|
4538 | {
|
---|
4539 | auto player = element.player();
|
---|
4540 | return player && player->muted();
|
---|
4541 | }
|
---|
4542 |
|
---|
4543 | void Internals::beginAudioSessionInterruption()
|
---|
4544 | {
|
---|
4545 | #if USE(AUDIO_SESSION)
|
---|
4546 | AudioSession::sharedSession().beginInterruption();
|
---|
4547 | #endif
|
---|
4548 | }
|
---|
4549 | #endif // ENABLE(VIDEO)
|
---|
4550 |
|
---|
4551 | #if ENABLE(WEB_AUDIO)
|
---|
4552 | void Internals::setAudioContextRestrictions(AudioContext& context, StringView restrictionsString)
|
---|
4553 | {
|
---|
4554 | auto restrictions = context.behaviorRestrictions();
|
---|
4555 | context.removeBehaviorRestriction(restrictions);
|
---|
4556 |
|
---|
4557 | restrictions = AudioContext::NoRestrictions;
|
---|
4558 |
|
---|
4559 | for (StringView restrictionString : restrictionsString.split(',')) {
|
---|
4560 | if (equalLettersIgnoringASCIICase(restrictionString, "norestrictions"_s))
|
---|
4561 | restrictions |= AudioContext::NoRestrictions;
|
---|
4562 | if (equalLettersIgnoringASCIICase(restrictionString, "requireusergestureforaudiostart"_s))
|
---|
4563 | restrictions |= AudioContext::RequireUserGestureForAudioStartRestriction;
|
---|
4564 | if (equalLettersIgnoringASCIICase(restrictionString, "requirepageconsentforaudiostart"_s))
|
---|
4565 | restrictions |= AudioContext::RequirePageConsentForAudioStartRestriction;
|
---|
4566 | }
|
---|
4567 | context.addBehaviorRestriction(restrictions);
|
---|
4568 | }
|
---|
4569 |
|
---|
4570 | void Internals::useMockAudioDestinationCocoa()
|
---|
4571 | {
|
---|
4572 | #if PLATFORM(COCOA)
|
---|
4573 | AudioDestinationCocoa::createOverride = MockAudioDestinationCocoa::create;
|
---|
4574 | #endif
|
---|
4575 | }
|
---|
4576 | #endif
|
---|
4577 |
|
---|
4578 | void Internals::simulateSystemSleep() const
|
---|
4579 | {
|
---|
4580 | #if ENABLE(VIDEO)
|
---|
4581 | PlatformMediaSessionManager::sharedManager().processSystemWillSleep();
|
---|
4582 | #endif
|
---|
4583 | }
|
---|
4584 |
|
---|
4585 | void Internals::simulateSystemWake() const
|
---|
4586 | {
|
---|
4587 | #if ENABLE(VIDEO)
|
---|
4588 | PlatformMediaSessionManager::sharedManager().processSystemDidWake();
|
---|
4589 | #endif
|
---|
4590 | }
|
---|
4591 |
|
---|
4592 | ExceptionOr<Internals::NowPlayingState> Internals::nowPlayingState() const
|
---|
4593 | {
|
---|
4594 | #if ENABLE(VIDEO)
|
---|
4595 | return { { PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingTitle(),
|
---|
4596 | PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingDuration(),
|
---|
4597 | PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingElapsedTime(),
|
---|
4598 | PlatformMediaSessionManager::sharedManager().lastUpdatedNowPlayingInfoUniqueIdentifier().toUInt64(),
|
---|
4599 | PlatformMediaSessionManager::sharedManager().hasActiveNowPlayingSession(),
|
---|
4600 | PlatformMediaSessionManager::sharedManager().registeredAsNowPlayingApplication(),
|
---|
4601 | PlatformMediaSessionManager::sharedManager().haveEverRegisteredAsNowPlayingApplication()
|
---|
4602 | } };
|
---|
4603 | #else
|
---|
4604 | return Exception { InvalidAccessError };
|
---|
4605 | #endif
|
---|
4606 | }
|
---|
4607 |
|
---|
4608 | #if ENABLE(VIDEO)
|
---|
4609 | RefPtr<HTMLMediaElement> Internals::bestMediaElementForRemoteControls(Internals::PlaybackControlsPurpose purpose)
|
---|
4610 | {
|
---|
4611 | return HTMLMediaElement::bestMediaElementForRemoteControls(purpose);
|
---|
4612 | }
|
---|
4613 |
|
---|
4614 | Internals::MediaSessionState Internals::mediaSessionState(HTMLMediaElement& element)
|
---|
4615 | {
|
---|
4616 | return static_cast<Internals::MediaSessionState>(element.mediaSession().state());
|
---|
4617 | }
|
---|
4618 | #endif
|
---|
4619 |
|
---|
4620 | ExceptionOr<Internals::MediaUsageState> Internals::mediaUsageState(HTMLMediaElement& element) const
|
---|
4621 | {
|
---|
4622 | #if ENABLE(VIDEO)
|
---|
4623 | element.mediaSession().updateMediaUsageIfChanged();
|
---|
4624 | auto info = element.mediaSession().mediaUsageInfo();
|
---|
4625 | if (!info)
|
---|
4626 | return Exception { NotSupportedError };
|
---|
4627 |
|
---|
4628 | return { { info.value().mediaURL.string(),
|
---|
4629 | info.value().isPlaying,
|
---|
4630 | info.value().canShowControlsManager,
|
---|
4631 | info.value().canShowNowPlayingControls,
|
---|
4632 | info.value().isSuspended,
|
---|
4633 | info.value().isInActiveDocument,
|
---|
4634 | info.value().isFullscreen,
|
---|
4635 | info.value().isMuted,
|
---|
4636 | info.value().isMediaDocumentInMainFrame,
|
---|
4637 | info.value().isVideo,
|
---|
4638 | info.value().isAudio,
|
---|
4639 | info.value().hasVideo,
|
---|
4640 | info.value().hasAudio,
|
---|
4641 | info.value().hasRenderer,
|
---|
4642 | info.value().audioElementWithUserGesture,
|
---|
4643 | info.value().userHasPlayedAudioBefore,
|
---|
4644 | info.value().isElementRectMostlyInMainFrame,
|
---|
4645 | info.value().playbackPermitted,
|
---|
4646 | info.value().pageMediaPlaybackSuspended,
|
---|
4647 | info.value().isMediaDocumentAndNotOwnerElement,
|
---|
4648 | info.value().pageExplicitlyAllowsElementToAutoplayInline,
|
---|
4649 | info.value().requiresFullscreenForVideoPlaybackAndFullscreenNotPermitted,
|
---|
4650 | info.value().hasHadUserInteractionAndQuirksContainsShouldAutoplayForArbitraryUserGesture,
|
---|
4651 | info.value().isVideoAndRequiresUserGestureForVideoRateChange,
|
---|
4652 | info.value().isAudioAndRequiresUserGestureForAudioRateChange,
|
---|
4653 | info.value().isVideoAndRequiresUserGestureForVideoDueToLowPowerMode,
|
---|
4654 | info.value().noUserGestureRequired,
|
---|
4655 | info.value().requiresPlaybackAndIsNotPlaying,
|
---|
4656 | info.value().hasEverNotifiedAboutPlaying,
|
---|
4657 | info.value().outsideOfFullscreen,
|
---|
4658 | info.value().isLargeEnoughForMainContent,
|
---|
4659 | } };
|
---|
4660 |
|
---|
4661 | #else
|
---|
4662 | UNUSED_PARAM(element);
|
---|
4663 | return Exception { InvalidAccessError };
|
---|
4664 | #endif
|
---|
4665 | }
|
---|
4666 |
|
---|
4667 | ExceptionOr<bool> Internals::elementShouldDisplayPosterImage(HTMLVideoElement& element) const
|
---|
4668 | {
|
---|
4669 | #if ENABLE(VIDEO)
|
---|
4670 | return element.shouldDisplayPosterImage();
|
---|
4671 | #else
|
---|
4672 | UNUSED_PARAM(element);
|
---|
4673 | return Exception { InvalidAccessError };
|
---|
4674 | #endif
|
---|
4675 | }
|
---|
4676 |
|
---|
4677 | #if ENABLE(VIDEO)
|
---|
4678 | size_t Internals::mediaElementCount() const
|
---|
4679 | {
|
---|
4680 | return HTMLMediaElement::allMediaElements().size();
|
---|
4681 | }
|
---|
4682 |
|
---|
4683 | void Internals::setMediaElementVolumeLocked(HTMLMediaElement& element, bool volumeLocked)
|
---|
4684 | {
|
---|
4685 | element.setVolumeLocked(volumeLocked);
|
---|
4686 | }
|
---|
4687 | #endif
|
---|
4688 |
|
---|
4689 | #if ENABLE(WIRELESS_PLAYBACK_TARGET)
|
---|
4690 |
|
---|
4691 | void Internals::setMockMediaPlaybackTargetPickerEnabled(bool enabled)
|
---|
4692 | {
|
---|
4693 | Page* page = contextDocument()->frame()->page();
|
---|
4694 | ASSERT(page);
|
---|
4695 |
|
---|
4696 | page->setMockMediaPlaybackTargetPickerEnabled(enabled);
|
---|
4697 | }
|
---|
4698 |
|
---|
4699 | ExceptionOr<void> Internals::setMockMediaPlaybackTargetPickerState(const String& deviceName, const String& deviceState)
|
---|
4700 | {
|
---|
4701 | Page* page = contextDocument()->frame()->page();
|
---|
4702 | ASSERT(page);
|
---|
4703 |
|
---|
4704 | MediaPlaybackTargetContext::MockState state = MediaPlaybackTargetContext::MockState::Unknown;
|
---|
4705 |
|
---|
4706 | if (equalLettersIgnoringASCIICase(deviceState, "deviceavailable"_s))
|
---|
4707 | state = MediaPlaybackTargetContext::MockState::OutputDeviceAvailable;
|
---|
4708 | else if (equalLettersIgnoringASCIICase(deviceState, "deviceunavailable"_s))
|
---|
4709 | state = MediaPlaybackTargetContext::MockState::OutputDeviceUnavailable;
|
---|
4710 | else if (equalLettersIgnoringASCIICase(deviceState, "unknown"_s))
|
---|
4711 | state = MediaPlaybackTargetContext::MockState::Unknown;
|
---|
4712 | else
|
---|
4713 | return Exception { InvalidAccessError };
|
---|
4714 |
|
---|
4715 | page->setMockMediaPlaybackTargetPickerState(deviceName, state);
|
---|
4716 | return { };
|
---|
4717 | }
|
---|
4718 |
|
---|
4719 | void Internals::mockMediaPlaybackTargetPickerDismissPopup()
|
---|
4720 | {
|
---|
4721 | auto* page = contextDocument()->frame()->page();
|
---|
4722 | ASSERT(page);
|
---|
4723 |
|
---|
4724 | page->mockMediaPlaybackTargetPickerDismissPopup();
|
---|
4725 | }
|
---|
4726 |
|
---|
4727 | #endif
|
---|
4728 |
|
---|
4729 | ExceptionOr<Ref<MockPageOverlay>> Internals::installMockPageOverlay(PageOverlayType type)
|
---|
4730 | {
|
---|
4731 | Document* document = contextDocument();
|
---|
4732 | if (!document || !document->page())
|
---|
4733 | return Exception { InvalidAccessError };
|
---|
4734 |
|
---|
4735 | return MockPageOverlayClient::singleton().installOverlay(*document->page(), type == PageOverlayType::View ? PageOverlay::OverlayType::View : PageOverlay::OverlayType::Document);
|
---|
4736 | }
|
---|
4737 |
|
---|
4738 | ExceptionOr<String> Internals::pageOverlayLayerTreeAsText(unsigned short flags) const
|
---|
4739 | {
|
---|
4740 | Document* document = contextDocument();
|
---|
4741 | if (!document || !document->page())
|
---|
4742 | return Exception { InvalidAccessError };
|
---|
4743 |
|
---|
4744 | document->updateLayoutIgnorePendingStylesheets();
|
---|
4745 |
|
---|
4746 | return MockPageOverlayClient::singleton().layerTreeAsText(*document->page(), toLayerTreeAsTextOptions(flags));
|
---|
4747 | }
|
---|
4748 |
|
---|
4749 | void Internals::setPageMuted(StringView statesString)
|
---|
4750 | {
|
---|
4751 | Document* document = contextDocument();
|
---|
4752 | if (!document)
|
---|
4753 | return;
|
---|
4754 |
|
---|
4755 | WebCore::MediaProducerMutedStateFlags state;
|
---|
4756 | for (StringView stateString : statesString.split(',')) {
|
---|
4757 | if (equalLettersIgnoringASCIICase(stateString, "audio"_s))
|
---|
4758 | state.add(MediaProducerMutedState::AudioIsMuted);
|
---|
4759 | if (equalLettersIgnoringASCIICase(stateString, "capturedevices"_s))
|
---|
4760 | state.add(MediaProducer::AudioAndVideoCaptureIsMuted);
|
---|
4761 | if (equalLettersIgnoringASCIICase(stateString, "screencapture"_s))
|
---|
4762 | state.add(MediaProducerMutedState::ScreenCaptureIsMuted);
|
---|
4763 | }
|
---|
4764 |
|
---|
4765 | if (Page* page = document->page())
|
---|
4766 | page->setMuted(state);
|
---|
4767 | }
|
---|
4768 |
|
---|
4769 | String Internals::pageMediaState()
|
---|
4770 | {
|
---|
4771 | Document* document = contextDocument();
|
---|
4772 | if (!document || !document->page())
|
---|
4773 | return emptyString();
|
---|
4774 |
|
---|
4775 | auto state = document->page()->mediaState();
|
---|
4776 | StringBuilder string;
|
---|
4777 | if (state.containsAny(MediaProducerMediaState::IsPlayingAudio))
|
---|
4778 | string.append("IsPlayingAudio,");
|
---|
4779 | if (state.containsAny(MediaProducerMediaState::IsPlayingVideo))
|
---|
4780 | string.append("IsPlayingVideo,");
|
---|
4781 | if (state.containsAny(MediaProducerMediaState::IsPlayingToExternalDevice))
|
---|
4782 | string.append("IsPlayingToExternalDevice,");
|
---|
4783 | if (state.containsAny(MediaProducerMediaState::RequiresPlaybackTargetMonitoring))
|
---|
4784 | string.append("RequiresPlaybackTargetMonitoring,");
|
---|
4785 | if (state.containsAny(MediaProducerMediaState::ExternalDeviceAutoPlayCandidate))
|
---|
4786 | string.append("ExternalDeviceAutoPlayCandidate,");
|
---|
4787 | if (state.containsAny(MediaProducerMediaState::DidPlayToEnd))
|
---|
4788 | string.append("DidPlayToEnd,");
|
---|
4789 | if (state.containsAny(MediaProducerMediaState::IsSourceElementPlaying))
|
---|
4790 | string.append("IsSourceElementPlaying,");
|
---|
4791 |
|
---|
4792 | if (state.containsAny(MediaProducerMediaState::IsNextTrackControlEnabled))
|
---|
4793 | string.append("IsNextTrackControlEnabled,");
|
---|
4794 | if (state.containsAny(MediaProducerMediaState::IsPreviousTrackControlEnabled))
|
---|
4795 | string.append("IsPreviousTrackControlEnabled,");
|
---|
4796 |
|
---|
4797 | if (state.containsAny(MediaProducerMediaState::HasPlaybackTargetAvailabilityListener))
|
---|
4798 | string.append("HasPlaybackTargetAvailabilityListener,");
|
---|
4799 | if (state.containsAny(MediaProducerMediaState::HasAudioOrVideo))
|
---|
4800 | string.append("HasAudioOrVideo,");
|
---|
4801 |
|
---|
4802 | if (state.containsAny(MediaProducerMediaState::HasActiveAudioCaptureDevice))
|
---|
4803 | string.append("HasActiveAudioCaptureDevice,");
|
---|
4804 | if (state.containsAny(MediaProducerMediaState::HasMutedAudioCaptureDevice))
|
---|
4805 | string.append("HasMutedAudioCaptureDevice,");
|
---|
4806 | if (state.containsAny(MediaProducerMediaState::HasInterruptedAudioCaptureDevice))
|
---|
4807 | string.append("HasInterruptedAudioCaptureDevice,");
|
---|
4808 |
|
---|
4809 | if (state.containsAny(MediaProducerMediaState::HasActiveVideoCaptureDevice))
|
---|
4810 | string.append("HasActiveVideoCaptureDevice,");
|
---|
4811 | if (state.containsAny(MediaProducerMediaState::HasMutedVideoCaptureDevice))
|
---|
4812 | string.append("HasMutedVideoCaptureDevice,");
|
---|
4813 | if (state.containsAny(MediaProducerMediaState::HasInterruptedVideoCaptureDevice))
|
---|
4814 | string.append("HasInterruptedVideoCaptureDevice,");
|
---|
4815 |
|
---|
4816 | if (state.containsAny(MediaProducerMediaState::HasUserInteractedWithMediaElement))
|
---|
4817 | string.append("HasUserInteractedWithMediaElement,");
|
---|
4818 |
|
---|
4819 | if (state.containsAny(MediaProducerMediaState::HasActiveScreenCaptureDevice))
|
---|
4820 | string.append("HasActiveScreenCaptureDevice,");
|
---|
4821 | if (state.containsAny(MediaProducerMediaState::HasMutedScreenCaptureDevice))
|
---|
4822 | string.append("HasMutedScreenCaptureDevice,");
|
---|
4823 |
|
---|
4824 | if (state.containsAny(MediaProducerMediaState::HasActiveWindowCaptureDevice))
|
---|
4825 | string.append("HasActiveWindowCaptureDevice,");
|
---|
4826 | if (state.containsAny(MediaProducerMediaState::HasMutedWindowCaptureDevice))
|
---|
4827 | string.append("HasMutedWindowCaptureDevice,");
|
---|
4828 | if (state.containsAny(MediaProducerMediaState::HasInterruptedWindowCaptureDevice))
|
---|
4829 | string.append("HasInterruptedWindowCaptureDevice,");
|
---|
4830 |
|
---|
4831 | if (state.containsAny(MediaProducerMediaState::HasActiveSystemAudioCaptureDevice))
|
---|
4832 | string.append("HasActiveSystemAudioCaptureDevice,");
|
---|
4833 | if (state.containsAny(MediaProducerMediaState::HasMutedSystemAudioCaptureDevice))
|
---|
4834 | string.append("HasMutedSystemAudioCaptureDevice,");
|
---|
4835 | if (state.containsAny(MediaProducerMediaState::HasInterruptedSystemAudioCaptureDevice))
|
---|
4836 | string.append("HasInterruptedSystemAudioCaptureDevice,");
|
---|
4837 |
|
---|
4838 | if (string.isEmpty())
|
---|
4839 | string.append("IsNotPlaying");
|
---|
4840 | else
|
---|
4841 | string.shrink(string.length() - 1);
|
---|
4842 |
|
---|
4843 | return string.toString();
|
---|
4844 | }
|
---|
4845 |
|
---|
4846 | void Internals::setPageDefersLoading(bool defersLoading)
|
---|
4847 | {
|
---|
4848 | Document* document = contextDocument();
|
---|
4849 | if (!document)
|
---|
4850 | return;
|
---|
4851 | if (Page* page = document->page())
|
---|
4852 | page->setDefersLoading(defersLoading);
|
---|
4853 | }
|
---|
4854 |
|
---|
4855 | ExceptionOr<bool> Internals::pageDefersLoading()
|
---|
4856 | {
|
---|
4857 | Document* document = contextDocument();
|
---|
4858 | if (!document || !document->page())
|
---|
4859 | return Exception { InvalidAccessError };
|
---|
4860 | return document->page()->defersLoading();
|
---|
4861 | }
|
---|
4862 |
|
---|
4863 | RefPtr<File> Internals::createFile(const String& path)
|
---|
4864 | {
|
---|
4865 | Document* document = contextDocument();
|
---|
4866 | if (!document)
|
---|
4867 | return nullptr;
|
---|
4868 |
|
---|
4869 | URL url = document->completeURL(path);
|
---|
4870 | if (!url.isLocalFile())
|
---|
4871 | return nullptr;
|
---|
4872 |
|
---|
4873 | return File::create(document, url.fileSystemPath());
|
---|
4874 | }
|
---|
4875 |
|
---|
4876 | String Internals::createTemporaryFile(const String& name, const String& contents)
|
---|
4877 | {
|
---|
4878 | if (name.isEmpty())
|
---|
4879 | return nullString();
|
---|
4880 |
|
---|
4881 | auto file = FileSystem::invalidPlatformFileHandle;
|
---|
4882 | auto path = FileSystem::openTemporaryFile(makeString("WebCoreTesting-", name), file);
|
---|
4883 | if (!FileSystem::isHandleValid(file))
|
---|
4884 | return nullString();
|
---|
4885 |
|
---|
4886 | auto contentsUTF8 = contents.utf8();
|
---|
4887 | FileSystem::writeToFile(file, contentsUTF8.data(), contentsUTF8.length());
|
---|
4888 |
|
---|
4889 | FileSystem::closeFile(file);
|
---|
4890 |
|
---|
4891 | return path;
|
---|
4892 | }
|
---|
4893 |
|
---|
4894 | void Internals::queueMicroTask(int testNumber)
|
---|
4895 | {
|
---|
4896 | Document* document = contextDocument();
|
---|
4897 | if (!document)
|
---|
4898 | return;
|
---|
4899 |
|
---|
4900 | ScriptExecutionContext* context = document;
|
---|
4901 | auto& eventLoop = context->eventLoop();
|
---|
4902 | eventLoop.queueMicrotask([document = Ref { *document }, testNumber]() {
|
---|
4903 | document->addConsoleMessage(MessageSource::JS, MessageLevel::Debug, makeString("MicroTask #", testNumber, " has run."));
|
---|
4904 | });
|
---|
4905 | }
|
---|
4906 |
|
---|
4907 | #if ENABLE(CONTENT_FILTERING)
|
---|
4908 |
|
---|
4909 | MockContentFilterSettings& Internals::mockContentFilterSettings()
|
---|
4910 | {
|
---|
4911 | return MockContentFilterSettings::singleton();
|
---|
4912 | }
|
---|
4913 |
|
---|
4914 | #endif
|
---|
4915 |
|
---|
4916 | static void appendOffsets(StringBuilder& builder, const Vector<SnapOffset<LayoutUnit>>& snapOffsets)
|
---|
4917 | {
|
---|
4918 | bool justStarting = true;
|
---|
4919 |
|
---|
4920 | builder.append("{ ");
|
---|
4921 | for (auto& coordinate : snapOffsets) {
|
---|
4922 | if (!justStarting)
|
---|
4923 | builder.append(", ");
|
---|
4924 | else
|
---|
4925 | justStarting = false;
|
---|
4926 | builder.append(coordinate.offset.toUnsigned());
|
---|
4927 | if (coordinate.stop == ScrollSnapStop::Always)
|
---|
4928 | builder.append(" (always)");
|
---|
4929 |
|
---|
4930 | }
|
---|
4931 | builder.append(" }");
|
---|
4932 | }
|
---|
4933 |
|
---|
4934 | void Internals::setPlatformMomentumScrollingPredictionEnabled(bool enabled)
|
---|
4935 | {
|
---|
4936 | ScrollingMomentumCalculator::setPlatformMomentumScrollingPredictionEnabled(enabled);
|
---|
4937 | }
|
---|
4938 |
|
---|
4939 | ExceptionOr<String> Internals::scrollSnapOffsets(Element& element)
|
---|
4940 | {
|
---|
4941 | auto areaOrException = scrollableAreaForNode(&element);
|
---|
4942 | if (areaOrException.hasException())
|
---|
4943 | return areaOrException.releaseException();
|
---|
4944 |
|
---|
4945 | auto* scrollableArea = areaOrException.releaseReturnValue();
|
---|
4946 | if (!scrollableArea)
|
---|
4947 | return Exception { InvalidAccessError };
|
---|
4948 |
|
---|
4949 | auto* offsetInfo = scrollableArea->snapOffsetsInfo();
|
---|
4950 | StringBuilder result;
|
---|
4951 | if (offsetInfo && !offsetInfo->horizontalSnapOffsets.isEmpty()) {
|
---|
4952 | result.append("horizontal = ");
|
---|
4953 | appendOffsets(result, offsetInfo->horizontalSnapOffsets);
|
---|
4954 | }
|
---|
4955 |
|
---|
4956 | if (offsetInfo && !offsetInfo->verticalSnapOffsets.isEmpty()) {
|
---|
4957 | if (result.length())
|
---|
4958 | result.append(", ");
|
---|
4959 | result.append("vertical = ");
|
---|
4960 | appendOffsets(result, offsetInfo->verticalSnapOffsets);
|
---|
4961 | }
|
---|
4962 |
|
---|
4963 | return result.toString();
|
---|
4964 | }
|
---|
4965 |
|
---|
4966 | ExceptionOr<bool> Internals::isScrollSnapInProgress(Element& element)
|
---|
4967 | {
|
---|
4968 | auto areaOrException = scrollableAreaForNode(&element);
|
---|
4969 | if (areaOrException.hasException())
|
---|
4970 | return areaOrException.releaseException();
|
---|
4971 |
|
---|
4972 | auto* scrollableArea = areaOrException.releaseReturnValue();
|
---|
4973 | if (!scrollableArea)
|
---|
4974 | return Exception { InvalidAccessError };
|
---|
4975 |
|
---|
4976 | return scrollableArea->isScrollSnapInProgress();
|
---|
4977 | }
|
---|
4978 |
|
---|
4979 | bool Internals::testPreloaderSettingViewport()
|
---|
4980 | {
|
---|
4981 | return testPreloadScannerViewportSupport(contextDocument());
|
---|
4982 | }
|
---|
4983 |
|
---|
4984 | ExceptionOr<String> Internals::pathStringWithShrinkWrappedRects(const Vector<double>& rectComponents, double radius)
|
---|
4985 | {
|
---|
4986 | if (rectComponents.size() % 4)
|
---|
4987 | return Exception { InvalidAccessError };
|
---|
4988 |
|
---|
4989 | Vector<FloatRect> rects;
|
---|
4990 | for (unsigned i = 0; i < rectComponents.size(); i += 4)
|
---|
4991 | rects.append(FloatRect(rectComponents[i], rectComponents[i + 1], rectComponents[i + 2], rectComponents[i + 3]));
|
---|
4992 |
|
---|
4993 | SVGPathStringBuilder builder;
|
---|
4994 | PathUtilities::pathWithShrinkWrappedRects(rects, radius).apply([&builder](const PathElement& element) {
|
---|
4995 | switch (element.type) {
|
---|
4996 | case PathElement::Type::MoveToPoint:
|
---|
4997 | builder.moveTo(element.points[0], false, AbsoluteCoordinates);
|
---|
4998 | return;
|
---|
4999 | case PathElement::Type::AddLineToPoint:
|
---|
5000 | builder.lineTo(element.points[0], AbsoluteCoordinates);
|
---|
5001 | return;
|
---|
5002 | case PathElement::Type::AddQuadCurveToPoint:
|
---|
5003 | builder.curveToQuadratic(element.points[0], element.points[1], AbsoluteCoordinates);
|
---|
5004 | return;
|
---|
5005 | case PathElement::Type::AddCurveToPoint:
|
---|
5006 | builder.curveToCubic(element.points[0], element.points[1], element.points[2], AbsoluteCoordinates);
|
---|
5007 | return;
|
---|
5008 | case PathElement::Type::CloseSubpath:
|
---|
5009 | builder.closePath();
|
---|
5010 | return;
|
---|
5011 | }
|
---|
5012 | ASSERT_NOT_REACHED();
|
---|
5013 | });
|
---|
5014 | return builder.result();
|
---|
5015 | }
|
---|
5016 |
|
---|
5017 | void Internals::systemBeep()
|
---|
5018 | {
|
---|
5019 | SystemSoundManager::singleton().systemBeep();
|
---|
5020 | }
|
---|
5021 |
|
---|
5022 | #if ENABLE(VIDEO)
|
---|
5023 |
|
---|
5024 | String Internals::getCurrentMediaControlsStatusForElement(HTMLMediaElement& mediaElement)
|
---|
5025 | {
|
---|
5026 | return mediaElement.getCurrentMediaControlsStatus();
|
---|
5027 | }
|
---|
5028 |
|
---|
5029 | void Internals::setMediaControlsMaximumRightContainerButtonCountOverride(HTMLMediaElement& mediaElement, size_t count)
|
---|
5030 | {
|
---|
5031 | mediaElement.setMediaControlsMaximumRightContainerButtonCountOverride(count);
|
---|
5032 | }
|
---|
5033 |
|
---|
5034 | void Internals::setMediaControlsHidePlaybackRates(HTMLMediaElement& mediaElement, bool hidePlaybackRates)
|
---|
5035 | {
|
---|
5036 | mediaElement.setMediaControlsHidePlaybackRates(hidePlaybackRates);
|
---|
5037 | }
|
---|
5038 |
|
---|
5039 | #endif // ENABLE(VIDEO)
|
---|
5040 |
|
---|
5041 | void Internals::setPageMediaVolume(float volume)
|
---|
5042 | {
|
---|
5043 | Document* document = contextDocument();
|
---|
5044 | if (!document)
|
---|
5045 | return;
|
---|
5046 |
|
---|
5047 | Page* page = document->page();
|
---|
5048 | if (!page)
|
---|
5049 | return;
|
---|
5050 |
|
---|
5051 | page->setMediaVolume(volume);
|
---|
5052 | }
|
---|
5053 |
|
---|
5054 | #if !PLATFORM(COCOA)
|
---|
5055 |
|
---|
5056 | String Internals::userVisibleString(const DOMURL& url)
|
---|
5057 | {
|
---|
5058 | return WTF::URLHelpers::userVisibleURL(url.href().string().utf8());
|
---|
5059 | }
|
---|
5060 |
|
---|
5061 | #endif
|
---|
5062 |
|
---|
5063 | void Internals::setShowAllPlugins(bool show)
|
---|
5064 | {
|
---|
5065 | Document* document = contextDocument();
|
---|
5066 | if (!document)
|
---|
5067 | return;
|
---|
5068 |
|
---|
5069 | Page* page = document->page();
|
---|
5070 | if (!page)
|
---|
5071 | return;
|
---|
5072 |
|
---|
5073 | page->setShowAllPlugins(show);
|
---|
5074 | }
|
---|
5075 |
|
---|
5076 | bool Internals::isReadableStreamDisturbed(JSC::JSGlobalObject& lexicalGlobalObject, JSValue stream)
|
---|
5077 | {
|
---|
5078 | return ReadableStream::isDisturbed(lexicalGlobalObject, stream);
|
---|
5079 | }
|
---|
5080 |
|
---|
5081 | JSValue Internals::cloneArrayBuffer(JSC::JSGlobalObject& lexicalGlobalObject, JSValue buffer, JSValue srcByteOffset, JSValue srcLength)
|
---|
5082 | {
|
---|
5083 | auto& vm = lexicalGlobalObject.vm();
|
---|
5084 | const Identifier& privateName = builtinNames(vm).cloneArrayBufferPrivateName();
|
---|
5085 | JSValue value;
|
---|
5086 | PropertySlot propertySlot(value, PropertySlot::InternalMethodType::Get);
|
---|
5087 | lexicalGlobalObject.methodTable()->getOwnPropertySlot(&lexicalGlobalObject, &lexicalGlobalObject, privateName, propertySlot);
|
---|
5088 | value = propertySlot.getValue(&lexicalGlobalObject, privateName);
|
---|
5089 | ASSERT(value.isCallable());
|
---|
5090 |
|
---|
5091 | JSObject* function = value.getObject();
|
---|
5092 | auto callData = JSC::getCallData(function);
|
---|
5093 | ASSERT(callData.type != JSC::CallData::Type::None);
|
---|
5094 | MarkedArgumentBuffer arguments;
|
---|
5095 | arguments.append(buffer);
|
---|
5096 | arguments.append(srcByteOffset);
|
---|
5097 | arguments.append(srcLength);
|
---|
5098 | ASSERT(!arguments.hasOverflowed());
|
---|
5099 |
|
---|
5100 | return JSC::call(&lexicalGlobalObject, function, callData, JSC::jsUndefined(), arguments);
|
---|
5101 | }
|
---|
5102 |
|
---|
5103 | String Internals::resourceLoadStatisticsForURL(const DOMURL& url)
|
---|
5104 | {
|
---|
5105 | return ResourceLoadObserver::shared().statisticsForURL(url.href());
|
---|
5106 | }
|
---|
5107 |
|
---|
5108 | void Internals::setResourceLoadStatisticsEnabled(bool enable)
|
---|
5109 | {
|
---|
5110 | DeprecatedGlobalSettings::setResourceLoadStatisticsEnabled(enable);
|
---|
5111 | }
|
---|
5112 |
|
---|
5113 | String Internals::composedTreeAsText(Node& node)
|
---|
5114 | {
|
---|
5115 | if (!is<ContainerNode>(node))
|
---|
5116 | return emptyString();
|
---|
5117 | return WebCore::composedTreeAsText(downcast<ContainerNode>(node));
|
---|
5118 | }
|
---|
5119 |
|
---|
5120 | bool Internals::isProcessingUserGesture()
|
---|
5121 | {
|
---|
5122 | return UserGestureIndicator::processingUserGesture();
|
---|
5123 | }
|
---|
5124 |
|
---|
5125 | void Internals::withUserGesture(RefPtr<VoidCallback>&& callback)
|
---|
5126 | {
|
---|
5127 | UserGestureIndicator gestureIndicator(ProcessingUserGesture, contextDocument());
|
---|
5128 | callback->handleEvent();
|
---|
5129 | }
|
---|
5130 |
|
---|
5131 | void Internals::withoutUserGesture(RefPtr<VoidCallback>&& callback)
|
---|
5132 | {
|
---|
5133 | UserGestureIndicator gestureIndicator(NotProcessingUserGesture, contextDocument());
|
---|
5134 | callback->handleEvent();
|
---|
5135 | }
|
---|
5136 |
|
---|
5137 | bool Internals::userIsInteracting()
|
---|
5138 | {
|
---|
5139 | if (auto* document = contextDocument()) {
|
---|
5140 | if (auto* page = document->page())
|
---|
5141 | return page->chrome().client().userIsInteracting();
|
---|
5142 | }
|
---|
5143 | return false;
|
---|
5144 | }
|
---|
5145 |
|
---|
5146 | bool Internals::hasTransientActivation()
|
---|
5147 | {
|
---|
5148 | if (auto* document = contextDocument()) {
|
---|
5149 | if (auto* window = document->domWindow())
|
---|
5150 | return window->hasTransientActivation();
|
---|
5151 | }
|
---|
5152 | return false;
|
---|
5153 | }
|
---|
5154 |
|
---|
5155 | double Internals::lastHandledUserGestureTimestamp()
|
---|
5156 | {
|
---|
5157 | Document* document = contextDocument();
|
---|
5158 | if (!document)
|
---|
5159 | return 0;
|
---|
5160 |
|
---|
5161 | return document->lastHandledUserGestureTimestamp().secondsSinceEpoch().value();
|
---|
5162 | }
|
---|
5163 |
|
---|
5164 | RefPtr<GCObservation> Internals::observeGC(JSC::JSValue value)
|
---|
5165 | {
|
---|
5166 | if (!value.isObject())
|
---|
5167 | return nullptr;
|
---|
5168 | return GCObservation::create(asObject(value));
|
---|
5169 | }
|
---|
5170 |
|
---|
5171 | void Internals::setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection userInterfaceLayoutDirection)
|
---|
5172 | {
|
---|
5173 | Document* document = contextDocument();
|
---|
5174 | if (!document)
|
---|
5175 | return;
|
---|
5176 |
|
---|
5177 | Page* page = document->page();
|
---|
5178 | if (!page)
|
---|
5179 | return;
|
---|
5180 |
|
---|
5181 | page->setUserInterfaceLayoutDirection(userInterfaceLayoutDirection == UserInterfaceLayoutDirection::LTR ? WebCore::UserInterfaceLayoutDirection::LTR : WebCore::UserInterfaceLayoutDirection::RTL);
|
---|
5182 | }
|
---|
5183 |
|
---|
5184 | #if !PLATFORM(COCOA)
|
---|
5185 |
|
---|
5186 | bool Internals::userPrefersReducedMotion() const
|
---|
5187 | {
|
---|
5188 | return false;
|
---|
5189 | }
|
---|
5190 |
|
---|
5191 | bool Internals::userPrefersContrast() const
|
---|
5192 | {
|
---|
5193 | return false;
|
---|
5194 | }
|
---|
5195 |
|
---|
5196 | #if ENABLE(VIDEO)
|
---|
5197 | double Internals::privatePlayerVolume(const HTMLMediaElement&)
|
---|
5198 | {
|
---|
5199 | return 0;
|
---|
5200 | }
|
---|
5201 |
|
---|
5202 | bool Internals::privatePlayerMuted(const HTMLMediaElement&)
|
---|
5203 | {
|
---|
5204 | return false;
|
---|
5205 | }
|
---|
5206 | #endif
|
---|
5207 |
|
---|
5208 | RefPtr<SharedBuffer> Internals::pngDataForTesting()
|
---|
5209 | {
|
---|
5210 | return nullptr;
|
---|
5211 | }
|
---|
5212 |
|
---|
5213 | #endif // !PLATFORM(COCOA)
|
---|
5214 |
|
---|
5215 | #if ENABLE(VIDEO)
|
---|
5216 | bool Internals::isMediaElementHidden(const HTMLMediaElement& media)
|
---|
5217 | {
|
---|
5218 | return media.elementIsHidden();
|
---|
5219 | }
|
---|
5220 |
|
---|
5221 | double Internals::elementEffectivePlaybackRate(const HTMLMediaElement& media)
|
---|
5222 | {
|
---|
5223 | return media.effectivePlaybackRate();
|
---|
5224 | }
|
---|
5225 | #endif
|
---|
5226 |
|
---|
5227 | ExceptionOr<void> Internals::setIsPlayingToBluetoothOverride(std::optional<bool> isPlaying)
|
---|
5228 | {
|
---|
5229 | #if ENABLE(ROUTING_ARBITRATION)
|
---|
5230 | AudioSession::sharedSession().setIsPlayingToBluetoothOverride(isPlaying);
|
---|
5231 | return { };
|
---|
5232 | #else
|
---|
5233 | UNUSED_PARAM(isPlaying);
|
---|
5234 | return Exception { NotSupportedError };
|
---|
5235 | #endif
|
---|
5236 | }
|
---|
5237 |
|
---|
5238 | void Internals::reportBacktrace()
|
---|
5239 | {
|
---|
5240 | WTFReportBacktrace();
|
---|
5241 | }
|
---|
5242 |
|
---|
5243 | void Internals::setBaseWritingDirection(BaseWritingDirection direction)
|
---|
5244 | {
|
---|
5245 | if (auto* document = contextDocument()) {
|
---|
5246 | if (auto* frame = document->frame()) {
|
---|
5247 | switch (direction) {
|
---|
5248 | case BaseWritingDirection::Ltr:
|
---|
5249 | frame->editor().setBaseWritingDirection(WritingDirection::LeftToRight);
|
---|
5250 | break;
|
---|
5251 | case BaseWritingDirection::Rtl:
|
---|
5252 | frame->editor().setBaseWritingDirection(WritingDirection::RightToLeft);
|
---|
5253 | break;
|
---|
5254 | case BaseWritingDirection::Natural:
|
---|
5255 | frame->editor().setBaseWritingDirection(WritingDirection::Natural);
|
---|
5256 | break;
|
---|
5257 | }
|
---|
5258 | }
|
---|
5259 | }
|
---|
5260 | }
|
---|
5261 |
|
---|
5262 | #if ENABLE(POINTER_LOCK)
|
---|
5263 | bool Internals::pageHasPendingPointerLock() const
|
---|
5264 | {
|
---|
5265 | Document* document = contextDocument();
|
---|
5266 | if (!document)
|
---|
5267 | return false;
|
---|
5268 |
|
---|
5269 | Page* page = document->page();
|
---|
5270 | if (!page)
|
---|
5271 | return false;
|
---|
5272 |
|
---|
5273 | return page->pointerLockController().lockPending();
|
---|
5274 | }
|
---|
5275 |
|
---|
5276 | bool Internals::pageHasPointerLock() const
|
---|
5277 | {
|
---|
5278 | Document* document = contextDocument();
|
---|
5279 | if (!document)
|
---|
5280 | return false;
|
---|
5281 |
|
---|
5282 | Page* page = document->page();
|
---|
5283 | if (!page)
|
---|
5284 | return false;
|
---|
5285 |
|
---|
5286 | auto& controller = page->pointerLockController();
|
---|
5287 | return controller.element() && !controller.lockPending();
|
---|
5288 | }
|
---|
5289 | #endif
|
---|
5290 |
|
---|
5291 | void Internals::markContextAsInsecure()
|
---|
5292 | {
|
---|
5293 | auto* document = contextDocument();
|
---|
5294 | if (!document)
|
---|
5295 | return;
|
---|
5296 |
|
---|
5297 | document->securityOrigin().setIsPotentiallyTrustworthy(false);
|
---|
5298 | }
|
---|
5299 |
|
---|
5300 | void Internals::postTask(RefPtr<VoidCallback>&& callback)
|
---|
5301 | {
|
---|
5302 | auto* document = contextDocument();
|
---|
5303 | if (!document) {
|
---|
5304 | callback->handleEvent();
|
---|
5305 | return;
|
---|
5306 | }
|
---|
5307 |
|
---|
5308 | document->postTask([callback = WTFMove(callback)](ScriptExecutionContext&) {
|
---|
5309 | callback->handleEvent();
|
---|
5310 | });
|
---|
5311 | }
|
---|
5312 |
|
---|
5313 | static std::optional<TaskSource> taskSourceFromString(const String& taskSourceName)
|
---|
5314 | {
|
---|
5315 | if (taskSourceName == "DOMManipulation"_s)
|
---|
5316 | return TaskSource::DOMManipulation;
|
---|
5317 | return std::nullopt;
|
---|
5318 | }
|
---|
5319 |
|
---|
5320 | ExceptionOr<void> Internals::queueTask(ScriptExecutionContext& context, const String& taskSourceName, RefPtr<VoidCallback>&& callback)
|
---|
5321 | {
|
---|
5322 | auto source = taskSourceFromString(taskSourceName);
|
---|
5323 | if (!source)
|
---|
5324 | return Exception { NotSupportedError };
|
---|
5325 |
|
---|
5326 | context.eventLoop().queueTask(*source, [callback = WTFMove(callback)] {
|
---|
5327 | callback->handleEvent();
|
---|
5328 | });
|
---|
5329 |
|
---|
5330 | return { };
|
---|
5331 | }
|
---|
5332 |
|
---|
5333 | ExceptionOr<void> Internals::queueTaskToQueueMicrotask(Document& document, const String& taskSourceName, RefPtr<VoidCallback>&& callback)
|
---|
5334 | {
|
---|
5335 | auto source = taskSourceFromString(taskSourceName);
|
---|
5336 | if (!source)
|
---|
5337 | return Exception { NotSupportedError };
|
---|
5338 |
|
---|
5339 | ScriptExecutionContext& context = document; // This avoids unnecessarily exporting Document::eventLoop.
|
---|
5340 | context.eventLoop().queueTask(*source, [movedCallback = WTFMove(callback), protectedDocument = Ref { document }]() mutable {
|
---|
5341 | ScriptExecutionContext& context = protectedDocument.get();
|
---|
5342 | context.eventLoop().queueMicrotask([callback = WTFMove(movedCallback)] {
|
---|
5343 | callback->handleEvent();
|
---|
5344 | });
|
---|
5345 | });
|
---|
5346 |
|
---|
5347 | return { };
|
---|
5348 | }
|
---|
5349 |
|
---|
5350 | ExceptionOr<bool> Internals::hasSameEventLoopAs(WindowProxy& proxy)
|
---|
5351 | {
|
---|
5352 | RefPtr<ScriptExecutionContext> context = contextDocument();
|
---|
5353 | if (!context || !proxy.frame())
|
---|
5354 | return Exception { InvalidStateError };
|
---|
5355 |
|
---|
5356 | auto& proxyFrame = *proxy.frame();
|
---|
5357 | if (!is<Frame>(proxyFrame))
|
---|
5358 | return false;
|
---|
5359 | RefPtr<ScriptExecutionContext> proxyContext = downcast<Frame>(proxyFrame).document();
|
---|
5360 | if (!proxyContext)
|
---|
5361 | return Exception { InvalidStateError };
|
---|
5362 |
|
---|
5363 | return context->eventLoop().hasSameEventLoopAs(proxyContext->eventLoop());
|
---|
5364 | }
|
---|
5365 |
|
---|
5366 | Vector<String> Internals::accessKeyModifiers() const
|
---|
5367 | {
|
---|
5368 | Vector<String> accessKeyModifierStrings;
|
---|
5369 |
|
---|
5370 | for (auto modifier : EventHandler::accessKeyModifiers()) {
|
---|
5371 | switch (modifier) {
|
---|
5372 | case PlatformEvent::Modifier::AltKey:
|
---|
5373 | accessKeyModifierStrings.append("altKey"_s);
|
---|
5374 | break;
|
---|
5375 | case PlatformEvent::Modifier::ControlKey:
|
---|
5376 | accessKeyModifierStrings.append("ctrlKey"_s);
|
---|
5377 | break;
|
---|
5378 | case PlatformEvent::Modifier::MetaKey:
|
---|
5379 | accessKeyModifierStrings.append("metaKey"_s);
|
---|
5380 | break;
|
---|
5381 | case PlatformEvent::Modifier::ShiftKey:
|
---|
5382 | accessKeyModifierStrings.append("shiftKey"_s);
|
---|
5383 | break;
|
---|
5384 | case PlatformEvent::Modifier::CapsLockKey:
|
---|
5385 | accessKeyModifierStrings.append("capsLockKey"_s);
|
---|
5386 | break;
|
---|
5387 | case PlatformEvent::Modifier::AltGraphKey:
|
---|
5388 | ASSERT_NOT_REACHED(); // AltGraph is only for DOM API.
|
---|
5389 | break;
|
---|
5390 | }
|
---|
5391 | }
|
---|
5392 |
|
---|
5393 | return accessKeyModifierStrings;
|
---|
5394 | }
|
---|
5395 |
|
---|
5396 | void Internals::setQuickLookPassword(const String& password)
|
---|
5397 | {
|
---|
5398 | #if PLATFORM(IOS_FAMILY) && USE(QUICK_LOOK)
|
---|
5399 | auto& quickLookHandleClient = MockPreviewLoaderClient::singleton();
|
---|
5400 | LegacyPreviewLoader::setClientForTesting(&quickLookHandleClient);
|
---|
5401 | quickLookHandleClient.setPassword(password);
|
---|
5402 | #else
|
---|
5403 | UNUSED_PARAM(password);
|
---|
5404 | #endif
|
---|
5405 | }
|
---|
5406 |
|
---|
5407 | void Internals::setAsRunningUserScripts(Document& document)
|
---|
5408 | {
|
---|
5409 | document.setAsRunningUserScripts();
|
---|
5410 | }
|
---|
5411 |
|
---|
5412 | #if ENABLE(WEBGL)
|
---|
5413 | void Internals::simulateEventForWebGLContext(SimulatedWebGLContextEvent event, WebGLRenderingContext& context)
|
---|
5414 | {
|
---|
5415 | WebGLRenderingContext::SimulatedEventForTesting contextEvent;
|
---|
5416 | switch (event) {
|
---|
5417 | case SimulatedWebGLContextEvent::ContextChange:
|
---|
5418 | contextEvent = WebGLRenderingContext::SimulatedEventForTesting::ContextChange;
|
---|
5419 | break;
|
---|
5420 | case SimulatedWebGLContextEvent::GPUStatusFailure:
|
---|
5421 | contextEvent = WebGLRenderingContext::SimulatedEventForTesting::GPUStatusFailure;
|
---|
5422 | break;
|
---|
5423 | case SimulatedWebGLContextEvent::Timeout:
|
---|
5424 | contextEvent = WebGLRenderingContext::SimulatedEventForTesting::Timeout;
|
---|
5425 | break;
|
---|
5426 | default:
|
---|
5427 | ASSERT_NOT_REACHED();
|
---|
5428 | return;
|
---|
5429 | }
|
---|
5430 | context.simulateEventForTesting(contextEvent);
|
---|
5431 | }
|
---|
5432 |
|
---|
5433 | bool Internals::hasLowAndHighPowerGPUs()
|
---|
5434 | {
|
---|
5435 | #if PLATFORM(MAC)
|
---|
5436 | return WebCore::hasLowAndHighPowerGPUs();
|
---|
5437 | #else
|
---|
5438 | return false;
|
---|
5439 | #endif
|
---|
5440 | }
|
---|
5441 |
|
---|
5442 | Internals::RequestedGPU Internals::requestedGPU(WebGLRenderingContext& context)
|
---|
5443 | {
|
---|
5444 | UNUSED_PARAM(context);
|
---|
5445 | if (auto optionalAttributes = context.getContextAttributes()) {
|
---|
5446 | auto attributes = *optionalAttributes;
|
---|
5447 | if (attributes.forceRequestForHighPerformanceGPU)
|
---|
5448 | return RequestedGPU::HighPerformance;
|
---|
5449 | switch (attributes.powerPreference) {
|
---|
5450 | case GraphicsContextGLPowerPreference::Default:
|
---|
5451 | return RequestedGPU::Default;
|
---|
5452 | case GraphicsContextGLPowerPreference::LowPower:
|
---|
5453 | return RequestedGPU::LowPower;
|
---|
5454 | case GraphicsContextGLPowerPreference::HighPerformance:
|
---|
5455 | return RequestedGPU::HighPerformance;
|
---|
5456 | }
|
---|
5457 | }
|
---|
5458 |
|
---|
5459 | return RequestedGPU::Default;
|
---|
5460 | }
|
---|
5461 |
|
---|
5462 | bool Internals::requestedMetal(WebGLRenderingContext& context)
|
---|
5463 | {
|
---|
5464 | UNUSED_PARAM(context);
|
---|
5465 | #if PLATFORM(COCOA)
|
---|
5466 | if (auto optionalAttributes = context.getContextAttributes()) {
|
---|
5467 | auto attributes = *optionalAttributes;
|
---|
5468 |
|
---|
5469 | return attributes.useMetal;
|
---|
5470 | }
|
---|
5471 | #endif
|
---|
5472 |
|
---|
5473 | return false;
|
---|
5474 | }
|
---|
5475 | #endif
|
---|
5476 |
|
---|
5477 | void Internals::setPageVisibility(bool isVisible)
|
---|
5478 | {
|
---|
5479 | updatePageActivityState(ActivityState::IsVisible, isVisible);
|
---|
5480 | }
|
---|
5481 |
|
---|
5482 | void Internals::setPageIsFocused(bool isFocused)
|
---|
5483 | {
|
---|
5484 | updatePageActivityState(ActivityState::IsFocused, isFocused);
|
---|
5485 | }
|
---|
5486 |
|
---|
5487 | void Internals::setPageIsFocusedAndActive(bool isFocusedAndActive)
|
---|
5488 | {
|
---|
5489 | updatePageActivityState({ ActivityState::IsFocused, ActivityState::WindowIsActive }, isFocusedAndActive);
|
---|
5490 | }
|
---|
5491 |
|
---|
5492 | void Internals::setPageIsInWindow(bool isInWindow)
|
---|
5493 | {
|
---|
5494 | updatePageActivityState(ActivityState::IsInWindow, isInWindow);
|
---|
5495 | }
|
---|
5496 |
|
---|
5497 | void Internals::updatePageActivityState(OptionSet<ActivityState::Flag> statesToChange, bool newValue)
|
---|
5498 | {
|
---|
5499 | auto* page = contextDocument() ? contextDocument()->page() : nullptr;
|
---|
5500 | if (!page)
|
---|
5501 | return;
|
---|
5502 | auto state = page->activityState();
|
---|
5503 |
|
---|
5504 | if (!newValue)
|
---|
5505 | state.remove(statesToChange);
|
---|
5506 | else
|
---|
5507 | state.add(statesToChange);
|
---|
5508 |
|
---|
5509 | page->setActivityState(state);
|
---|
5510 | }
|
---|
5511 |
|
---|
5512 | bool Internals::isPageActive() const
|
---|
5513 | {
|
---|
5514 | auto* document = contextDocument();
|
---|
5515 | if (!document || !document->page())
|
---|
5516 | return false;
|
---|
5517 | auto& page = *document->page();
|
---|
5518 | return page.activityState().contains(ActivityState::WindowIsActive);
|
---|
5519 | }
|
---|
5520 |
|
---|
5521 | #if ENABLE(WEB_RTC)
|
---|
5522 | void Internals::setH264HardwareEncoderAllowed(bool allowed)
|
---|
5523 | {
|
---|
5524 | LibWebRTCProvider::setH264HardwareEncoderAllowed(allowed);
|
---|
5525 | }
|
---|
5526 | #endif
|
---|
5527 |
|
---|
5528 | #if ENABLE(MEDIA_STREAM)
|
---|
5529 | void Internals::setMockAudioTrackChannelNumber(MediaStreamTrack& track, unsigned short channelNumber)
|
---|
5530 | {
|
---|
5531 | auto& source = track.source();
|
---|
5532 | if (!is<MockRealtimeAudioSource>(source))
|
---|
5533 | return;
|
---|
5534 | downcast<MockRealtimeAudioSource>(source).setChannelCount(channelNumber);
|
---|
5535 | }
|
---|
5536 |
|
---|
5537 | void Internals::setCameraMediaStreamTrackOrientation(MediaStreamTrack& track, int orientation)
|
---|
5538 | {
|
---|
5539 | auto& source = track.source();
|
---|
5540 | if (!source.isCaptureSource())
|
---|
5541 | return;
|
---|
5542 | m_orientationNotifier.orientationChanged(orientation);
|
---|
5543 | source.monitorOrientation(m_orientationNotifier);
|
---|
5544 | }
|
---|
5545 |
|
---|
5546 | void Internals::stopObservingRealtimeMediaSource()
|
---|
5547 | {
|
---|
5548 | if (!m_trackSource)
|
---|
5549 | return;
|
---|
5550 |
|
---|
5551 | switch (m_trackSource->type()) {
|
---|
5552 | case RealtimeMediaSource::Type::Audio:
|
---|
5553 | m_trackSource->removeAudioSampleObserver(*this);
|
---|
5554 | break;
|
---|
5555 | case RealtimeMediaSource::Type::Video:
|
---|
5556 | m_trackSource->removeVideoFrameObserver(*this);
|
---|
5557 | break;
|
---|
5558 | }
|
---|
5559 | m_trackSource->removeObserver(*this);
|
---|
5560 |
|
---|
5561 | m_trackSource = nullptr;
|
---|
5562 | m_trackAudioSampleCount = 0;
|
---|
5563 | m_trackVideoSampleCount = 0;
|
---|
5564 | }
|
---|
5565 |
|
---|
5566 | void Internals::observeMediaStreamTrack(MediaStreamTrack& track)
|
---|
5567 | {
|
---|
5568 | stopObservingRealtimeMediaSource();
|
---|
5569 |
|
---|
5570 | m_trackVideoRotation = -1;
|
---|
5571 | m_trackSource = &track.source();
|
---|
5572 | m_trackSource->addObserver(*this);
|
---|
5573 | switch (m_trackSource->type()) {
|
---|
5574 | case RealtimeMediaSource::Type::Audio:
|
---|
5575 | m_trackSource->addAudioSampleObserver(*this);
|
---|
5576 | break;
|
---|
5577 | case RealtimeMediaSource::Type::Video:
|
---|
5578 | m_trackSource->addVideoFrameObserver(*this);
|
---|
5579 | break;
|
---|
5580 | }
|
---|
5581 | }
|
---|
5582 |
|
---|
5583 | void Internals::grabNextMediaStreamTrackFrame(TrackFramePromise&& promise)
|
---|
5584 | {
|
---|
5585 | m_nextTrackFramePromise = makeUnique<TrackFramePromise>(WTFMove(promise));
|
---|
5586 | }
|
---|
5587 |
|
---|
5588 | void Internals::mediaStreamTrackVideoFrameRotation(DOMPromiseDeferred<IDLShort>&& promise)
|
---|
5589 | {
|
---|
5590 | promise.resolve(m_trackVideoRotation);
|
---|
5591 | }
|
---|
5592 |
|
---|
5593 | void Internals::videoFrameAvailable(VideoFrame& videoFrame, VideoFrameTimeMetadata)
|
---|
5594 | {
|
---|
5595 | callOnMainThread([this, weakThis = WeakPtr { *this }, videoFrame = Ref { videoFrame }] {
|
---|
5596 | if (!weakThis)
|
---|
5597 | return;
|
---|
5598 | m_trackVideoSampleCount++;
|
---|
5599 | m_trackVideoRotation = static_cast<int>(videoFrame->rotation());
|
---|
5600 | if (!m_nextTrackFramePromise)
|
---|
5601 | return;
|
---|
5602 |
|
---|
5603 | auto& videoSettings = m_trackSource->settings();
|
---|
5604 | if (!videoSettings.width() || !videoSettings.height())
|
---|
5605 | return;
|
---|
5606 |
|
---|
5607 | auto rgba = videoFrame->getRGBAImageData();
|
---|
5608 | if (!rgba)
|
---|
5609 | return;
|
---|
5610 |
|
---|
5611 | auto imageData = ImageData::create(rgba.releaseNonNull(), videoSettings.width(), videoSettings.height(), { { PredefinedColorSpace::SRGB } });
|
---|
5612 | if (!imageData.hasException())
|
---|
5613 | m_nextTrackFramePromise->resolve(imageData.releaseReturnValue());
|
---|
5614 | else
|
---|
5615 | m_nextTrackFramePromise->reject(imageData.exception().code());
|
---|
5616 | m_nextTrackFramePromise = nullptr;
|
---|
5617 | });
|
---|
5618 | }
|
---|
5619 |
|
---|
5620 | void Internals::delayMediaStreamTrackSamples(MediaStreamTrack& track, float delay)
|
---|
5621 | {
|
---|
5622 | track.source().delaySamples(Seconds { delay });
|
---|
5623 | }
|
---|
5624 |
|
---|
5625 | void Internals::setMediaStreamTrackMuted(MediaStreamTrack& track, bool muted)
|
---|
5626 | {
|
---|
5627 | track.source().setMuted(muted);
|
---|
5628 | }
|
---|
5629 |
|
---|
5630 | void Internals::removeMediaStreamTrack(MediaStream& stream, MediaStreamTrack& track)
|
---|
5631 | {
|
---|
5632 | stream.privateStream().removeTrack(track.privateTrack());
|
---|
5633 | }
|
---|
5634 |
|
---|
5635 | void Internals::simulateMediaStreamTrackCaptureSourceFailure(MediaStreamTrack& track)
|
---|
5636 | {
|
---|
5637 | track.source().captureFailed();
|
---|
5638 | }
|
---|
5639 |
|
---|
5640 | void Internals::setMediaStreamTrackIdentifier(MediaStreamTrack& track, String&& id)
|
---|
5641 | {
|
---|
5642 | track.setIdForTesting(WTFMove(id));
|
---|
5643 | }
|
---|
5644 |
|
---|
5645 | void Internals::setMediaStreamSourceInterrupted(MediaStreamTrack& track, bool interrupted)
|
---|
5646 | {
|
---|
5647 | track.source().setInterruptedForTesting(interrupted);
|
---|
5648 | }
|
---|
5649 |
|
---|
5650 | bool Internals::isMediaStreamSourceInterrupted(MediaStreamTrack& track) const
|
---|
5651 | {
|
---|
5652 | return track.source().interrupted();
|
---|
5653 | }
|
---|
5654 |
|
---|
5655 | bool Internals::isMediaStreamSourceEnded(MediaStreamTrack& track) const
|
---|
5656 | {
|
---|
5657 | return track.source().isEnded();
|
---|
5658 | }
|
---|
5659 |
|
---|
5660 | bool Internals::isMockRealtimeMediaSourceCenterEnabled()
|
---|
5661 | {
|
---|
5662 | return MockRealtimeMediaSourceCenter::mockRealtimeMediaSourceCenterEnabled();
|
---|
5663 | }
|
---|
5664 |
|
---|
5665 | bool Internals::shouldAudioTrackPlay(const AudioTrack& track)
|
---|
5666 | {
|
---|
5667 | if (!is<AudioTrackPrivateMediaStream>(track.privateTrack()))
|
---|
5668 | return false;
|
---|
5669 | return downcast<AudioTrackPrivateMediaStream>(track.privateTrack()).shouldPlay();
|
---|
5670 | }
|
---|
5671 | #endif
|
---|
5672 |
|
---|
5673 | bool Internals::supportsAudioSession() const
|
---|
5674 | {
|
---|
5675 | #if USE(AUDIO_SESSION)
|
---|
5676 | return true;
|
---|
5677 | #else
|
---|
5678 | return false;
|
---|
5679 | #endif
|
---|
5680 | }
|
---|
5681 |
|
---|
5682 | auto Internals::audioSessionCategory() const -> AudioSessionCategory
|
---|
5683 | {
|
---|
5684 | #if USE(AUDIO_SESSION)
|
---|
5685 | return AudioSession::sharedSession().category();
|
---|
5686 | #else
|
---|
5687 | return AudioSessionCategory::None;
|
---|
5688 | #endif
|
---|
5689 | }
|
---|
5690 |
|
---|
5691 | auto Internals::routeSharingPolicy() const -> RouteSharingPolicy
|
---|
5692 | {
|
---|
5693 | #if USE(AUDIO_SESSION)
|
---|
5694 | return AudioSession::sharedSession().routeSharingPolicy();
|
---|
5695 | #else
|
---|
5696 | return RouteSharingPolicy::Default;
|
---|
5697 | #endif
|
---|
5698 | }
|
---|
5699 |
|
---|
5700 | #if ENABLE(VIDEO)
|
---|
5701 | auto Internals::categoryAtMostRecentPlayback(HTMLMediaElement& element) const -> AudioSessionCategory
|
---|
5702 | {
|
---|
5703 | #if USE(AUDIO_SESSION)
|
---|
5704 | return element.categoryAtMostRecentPlayback();
|
---|
5705 | #else
|
---|
5706 | UNUSED_PARAM(element);
|
---|
5707 | return AudioSessionCategory::None;
|
---|
5708 | #endif
|
---|
5709 | }
|
---|
5710 | #endif
|
---|
5711 |
|
---|
5712 | double Internals::preferredAudioBufferSize() const
|
---|
5713 | {
|
---|
5714 | #if USE(AUDIO_SESSION)
|
---|
5715 | return AudioSession::sharedSession().preferredBufferSize();
|
---|
5716 | #endif
|
---|
5717 | return 0;
|
---|
5718 | }
|
---|
5719 |
|
---|
5720 | double Internals::currentAudioBufferSize() const
|
---|
5721 | {
|
---|
5722 | #if USE(AUDIO_SESSION)
|
---|
5723 | return AudioSession::sharedSession().bufferSize();
|
---|
5724 | #endif
|
---|
5725 | return 0;
|
---|
5726 | }
|
---|
5727 |
|
---|
5728 |
|
---|
5729 | bool Internals::audioSessionActive() const
|
---|
5730 | {
|
---|
5731 | #if USE(AUDIO_SESSION)
|
---|
5732 | return AudioSession::sharedSession().isActive();
|
---|
5733 | #endif
|
---|
5734 | return false;
|
---|
5735 | }
|
---|
5736 |
|
---|
5737 | void Internals::storeRegistrationsOnDisk(DOMPromiseDeferred<void>&& promise)
|
---|
5738 | {
|
---|
5739 | #if ENABLE(SERVICE_WORKER)
|
---|
5740 | if (!contextDocument())
|
---|
5741 | return;
|
---|
5742 |
|
---|
5743 | auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
|
---|
5744 | connection.storeRegistrationsOnDiskForTesting([promise = WTFMove(promise)]() mutable {
|
---|
5745 | promise.resolve();
|
---|
5746 | });
|
---|
5747 | #else
|
---|
5748 | promise.resolve();
|
---|
5749 | #endif
|
---|
5750 | }
|
---|
5751 |
|
---|
5752 | void Internals::sendH2Ping(String url, DOMPromiseDeferred<IDLDouble>&& promise)
|
---|
5753 | {
|
---|
5754 | auto* document = contextDocument();
|
---|
5755 | if (!document) {
|
---|
5756 | promise.reject(InvalidStateError);
|
---|
5757 | return;
|
---|
5758 | }
|
---|
5759 |
|
---|
5760 | auto* frame = document->frame();
|
---|
5761 | if (!frame) {
|
---|
5762 | promise.reject(InvalidStateError);
|
---|
5763 | return;
|
---|
5764 | }
|
---|
5765 |
|
---|
5766 | frame->loader().client().sendH2Ping(URL { url }, [promise = WTFMove(promise)] (Expected<Seconds, ResourceError>&& result) mutable {
|
---|
5767 | if (result.has_value())
|
---|
5768 | promise.resolve(result.value().value());
|
---|
5769 | else
|
---|
5770 | promise.reject(InvalidStateError);
|
---|
5771 | });
|
---|
5772 | }
|
---|
5773 |
|
---|
5774 | void Internals::clearCacheStorageMemoryRepresentation(DOMPromiseDeferred<void>&& promise)
|
---|
5775 | {
|
---|
5776 | auto* document = contextDocument();
|
---|
5777 | if (!document)
|
---|
5778 | return;
|
---|
5779 |
|
---|
5780 | if (!m_cacheStorageConnection) {
|
---|
5781 | if (auto* page = contextDocument()->page())
|
---|
5782 | m_cacheStorageConnection = page->cacheStorageProvider().createCacheStorageConnection();
|
---|
5783 | if (!m_cacheStorageConnection)
|
---|
5784 | return;
|
---|
5785 | }
|
---|
5786 | m_cacheStorageConnection->clearMemoryRepresentation(ClientOrigin { document->topOrigin().data(), document->securityOrigin().data() }, [promise = WTFMove(promise)] (auto && result) mutable {
|
---|
5787 | ASSERT_UNUSED(result, !result);
|
---|
5788 | promise.resolve();
|
---|
5789 | });
|
---|
5790 | }
|
---|
5791 |
|
---|
5792 | void Internals::cacheStorageEngineRepresentation(DOMPromiseDeferred<IDLDOMString>&& promise)
|
---|
5793 | {
|
---|
5794 | auto* document = contextDocument();
|
---|
5795 | if (!document)
|
---|
5796 | return;
|
---|
5797 |
|
---|
5798 | if (!m_cacheStorageConnection) {
|
---|
5799 | if (auto* page = contextDocument()->page())
|
---|
5800 | m_cacheStorageConnection = page->cacheStorageProvider().createCacheStorageConnection();
|
---|
5801 | if (!m_cacheStorageConnection)
|
---|
5802 | return;
|
---|
5803 | }
|
---|
5804 | m_cacheStorageConnection->engineRepresentation([promise = WTFMove(promise)](const String& result) mutable {
|
---|
5805 | promise.resolve(result);
|
---|
5806 | });
|
---|
5807 | }
|
---|
5808 |
|
---|
5809 | void Internals::updateQuotaBasedOnSpaceUsage()
|
---|
5810 | {
|
---|
5811 | auto* document = contextDocument();
|
---|
5812 | if (!document)
|
---|
5813 | return;
|
---|
5814 |
|
---|
5815 | if (!m_cacheStorageConnection) {
|
---|
5816 | if (auto* page = contextDocument()->page())
|
---|
5817 | m_cacheStorageConnection = page->cacheStorageProvider().createCacheStorageConnection();
|
---|
5818 | if (!m_cacheStorageConnection)
|
---|
5819 | return;
|
---|
5820 | }
|
---|
5821 |
|
---|
5822 | m_cacheStorageConnection->updateQuotaBasedOnSpaceUsage(ClientOrigin { document->topOrigin().data(), document->securityOrigin().data() });
|
---|
5823 | }
|
---|
5824 |
|
---|
5825 | void Internals::setConsoleMessageListener(RefPtr<StringCallback>&& listener)
|
---|
5826 | {
|
---|
5827 | if (!contextDocument())
|
---|
5828 | return;
|
---|
5829 |
|
---|
5830 | contextDocument()->setConsoleMessageListener(WTFMove(listener));
|
---|
5831 | }
|
---|
5832 |
|
---|
5833 | void Internals::setResponseSizeWithPadding(FetchResponse& response, uint64_t size)
|
---|
5834 | {
|
---|
5835 | response.setBodySizeWithPadding(size);
|
---|
5836 | }
|
---|
5837 |
|
---|
5838 | uint64_t Internals::responseSizeWithPadding(FetchResponse& response) const
|
---|
5839 | {
|
---|
5840 | return response.bodySizeWithPadding();
|
---|
5841 | }
|
---|
5842 |
|
---|
5843 | const String& Internals::responseNetworkLoadMetricsProtocol(const FetchResponse& response)
|
---|
5844 | {
|
---|
5845 | return response.networkLoadMetrics().protocol;
|
---|
5846 | }
|
---|
5847 |
|
---|
5848 | #if ENABLE(SERVICE_WORKER)
|
---|
5849 | void Internals::hasServiceWorkerRegistration(const String& clientURL, HasRegistrationPromise&& promise)
|
---|
5850 | {
|
---|
5851 | if (!contextDocument())
|
---|
5852 | return;
|
---|
5853 |
|
---|
5854 | URL parsedURL = contextDocument()->completeURL(clientURL);
|
---|
5855 |
|
---|
5856 | return ServiceWorkerProvider::singleton().serviceWorkerConnection().matchRegistration(SecurityOriginData { contextDocument()->topOrigin().data() }, parsedURL, [promise = WTFMove(promise)] (auto&& result) mutable {
|
---|
5857 | promise.resolve(!!result);
|
---|
5858 | });
|
---|
5859 | }
|
---|
5860 |
|
---|
5861 | void Internals::terminateServiceWorker(ServiceWorker& worker, DOMPromiseDeferred<void>&& promise)
|
---|
5862 | {
|
---|
5863 | ServiceWorkerProvider::singleton().terminateWorkerForTesting(worker.identifier(), [promise = WTFMove(promise)]() mutable {
|
---|
5864 | promise.resolve();
|
---|
5865 | });
|
---|
5866 | }
|
---|
5867 |
|
---|
5868 | void Internals::whenServiceWorkerIsTerminated(ServiceWorker& worker, DOMPromiseDeferred<void>&& promise)
|
---|
5869 | {
|
---|
5870 | return ServiceWorkerProvider::singleton().serviceWorkerConnection().whenServiceWorkerIsTerminatedForTesting(worker.identifier(), [promise = WTFMove(promise)]() mutable {
|
---|
5871 | promise.resolve();
|
---|
5872 | });
|
---|
5873 | }
|
---|
5874 | #endif
|
---|
5875 |
|
---|
5876 | #if ENABLE(APPLE_PAY)
|
---|
5877 | MockPaymentCoordinator& Internals::mockPaymentCoordinator(Document& document)
|
---|
5878 | {
|
---|
5879 | return downcast<MockPaymentCoordinator>(document.frame()->page()->paymentCoordinator().client());
|
---|
5880 | }
|
---|
5881 | #endif
|
---|
5882 |
|
---|
5883 | Internals::ImageOverlayLine::~ImageOverlayLine() = default;
|
---|
5884 | Internals::ImageOverlayText::~ImageOverlayText() = default;
|
---|
5885 | Internals::ImageOverlayBlock::~ImageOverlayBlock() = default;
|
---|
5886 | Internals::ImageOverlayDataDetector::~ImageOverlayDataDetector() = default;
|
---|
5887 |
|
---|
5888 | #if ENABLE(IMAGE_ANALYSIS)
|
---|
5889 |
|
---|
5890 | template<typename T>
|
---|
5891 | static FloatQuad getQuad(const T& overlayTextOrLine)
|
---|
5892 | {
|
---|
5893 | return {
|
---|
5894 | FloatPoint(overlayTextOrLine.topLeft->x(), overlayTextOrLine.topLeft->y()),
|
---|
5895 | FloatPoint(overlayTextOrLine.topRight->x(), overlayTextOrLine.topRight->y()),
|
---|
5896 | FloatPoint(overlayTextOrLine.bottomRight->x(), overlayTextOrLine.bottomRight->y()),
|
---|
5897 | FloatPoint(overlayTextOrLine.bottomLeft->x(), overlayTextOrLine.bottomLeft->y()),
|
---|
5898 | };
|
---|
5899 | }
|
---|
5900 |
|
---|
5901 | static TextRecognitionLineData makeDataForLine(const Internals::ImageOverlayLine& line)
|
---|
5902 | {
|
---|
5903 | return {
|
---|
5904 | getQuad<Internals::ImageOverlayLine>(line),
|
---|
5905 | line.children.map([](auto& textChild) -> TextRecognitionWordData {
|
---|
5906 | return { textChild.text, getQuad(textChild), textChild.hasLeadingWhitespace };
|
---|
5907 | }),
|
---|
5908 | line.hasTrailingNewline
|
---|
5909 | };
|
---|
5910 | }
|
---|
5911 |
|
---|
5912 | void Internals::requestTextRecognition(Element& element, RefPtr<VoidCallback>&& callback)
|
---|
5913 | {
|
---|
5914 | auto page = contextDocument()->page();
|
---|
5915 | if (!page) {
|
---|
5916 | if (callback)
|
---|
5917 | callback->handleEvent();
|
---|
5918 | }
|
---|
5919 |
|
---|
5920 | page->chrome().client().requestTextRecognition(element, { }, [callback = WTFMove(callback)] (auto&&) {
|
---|
5921 | if (callback)
|
---|
5922 | callback->handleEvent();
|
---|
5923 | });
|
---|
5924 | }
|
---|
5925 |
|
---|
5926 | RefPtr<Element> Internals::textRecognitionCandidate() const
|
---|
5927 | {
|
---|
5928 | if (RefPtr frame = contextDocument()->frame())
|
---|
5929 | return frame->eventHandler().textRecognitionCandidateElement();
|
---|
5930 |
|
---|
5931 | return nullptr;
|
---|
5932 | }
|
---|
5933 |
|
---|
5934 | #endif // ENABLE(IMAGE_ANALYSIS)
|
---|
5935 |
|
---|
5936 | void Internals::installImageOverlay(Element& element, Vector<ImageOverlayLine>&& lines, Vector<ImageOverlayBlock>&& blocks, Vector<ImageOverlayDataDetector>&& dataDetectors)
|
---|
5937 | {
|
---|
5938 | if (!is<HTMLElement>(element))
|
---|
5939 | return;
|
---|
5940 |
|
---|
5941 | #if ENABLE(IMAGE_ANALYSIS)
|
---|
5942 | ImageOverlay::updateWithTextRecognitionResult(downcast<HTMLElement>(element), TextRecognitionResult {
|
---|
5943 | lines.map([] (auto& line) -> TextRecognitionLineData {
|
---|
5944 | return makeDataForLine(line);
|
---|
5945 | })
|
---|
5946 | #if ENABLE(DATA_DETECTION)
|
---|
5947 | , dataDetectors.map([](auto& dataDetector) -> TextRecognitionDataDetector {
|
---|
5948 | return { fakeDataDetectorResultForTesting(), { getQuad(dataDetector) } };
|
---|
5949 | })
|
---|
5950 | #endif // ENABLE(DATA_DETECTION)
|
---|
5951 | , blocks.map([] (auto& block) {
|
---|
5952 | return TextRecognitionBlockData { block.text, getQuad(block) };
|
---|
5953 | })
|
---|
5954 | #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)
|
---|
5955 | , fakeImageAnalysisResultForTesting(lines)
|
---|
5956 | #endif
|
---|
5957 | });
|
---|
5958 | #else
|
---|
5959 | UNUSED_PARAM(blocks);
|
---|
5960 | UNUSED_PARAM(dataDetectors);
|
---|
5961 | UNUSED_PARAM(lines);
|
---|
5962 | #endif
|
---|
5963 | }
|
---|
5964 |
|
---|
5965 | bool Internals::hasActiveDataDetectorHighlight() const
|
---|
5966 | {
|
---|
5967 | #if ENABLE(DATA_DETECTION) && ENABLE(IMAGE_ANALYSIS)
|
---|
5968 | if (auto* controller = contextDocument()->page()->imageOverlayControllerIfExists())
|
---|
5969 | return controller->hasActiveDataDetectorHighlightForTesting();
|
---|
5970 | #endif
|
---|
5971 | return false;
|
---|
5972 | }
|
---|
5973 |
|
---|
5974 | bool Internals::isSystemPreviewLink(Element& element) const
|
---|
5975 | {
|
---|
5976 | #if USE(SYSTEM_PREVIEW)
|
---|
5977 | return is<HTMLAnchorElement>(element) && downcast<HTMLAnchorElement>(element).isSystemPreviewLink();
|
---|
5978 | #else
|
---|
5979 | UNUSED_PARAM(element);
|
---|
5980 | return false;
|
---|
5981 | #endif
|
---|
5982 | }
|
---|
5983 |
|
---|
5984 | bool Internals::isSystemPreviewImage(Element& element) const
|
---|
5985 | {
|
---|
5986 | #if USE(SYSTEM_PREVIEW)
|
---|
5987 | if (is<HTMLImageElement>(element))
|
---|
5988 | return downcast<HTMLImageElement>(element).isSystemPreviewImage();
|
---|
5989 | if (is<HTMLPictureElement>(element))
|
---|
5990 | return downcast<HTMLPictureElement>(element).isSystemPreviewImage();
|
---|
5991 | return false;
|
---|
5992 | #else
|
---|
5993 | UNUSED_PARAM(element);
|
---|
5994 | return false;
|
---|
5995 | #endif
|
---|
5996 | }
|
---|
5997 |
|
---|
5998 | bool Internals::usingAppleInternalSDK() const
|
---|
5999 | {
|
---|
6000 | #if USE(APPLE_INTERNAL_SDK)
|
---|
6001 | return true;
|
---|
6002 | #else
|
---|
6003 | return false;
|
---|
6004 | #endif
|
---|
6005 | }
|
---|
6006 |
|
---|
6007 | bool Internals::usingGStreamer() const
|
---|
6008 | {
|
---|
6009 | #if USE(GSTREAMER)
|
---|
6010 | return true;
|
---|
6011 | #else
|
---|
6012 | return false;
|
---|
6013 | #endif
|
---|
6014 | }
|
---|
6015 |
|
---|
6016 | void Internals::setCaptureExtraNetworkLoadMetricsEnabled(bool value)
|
---|
6017 | {
|
---|
6018 | platformStrategies()->loaderStrategy()->setCaptureExtraNetworkLoadMetricsEnabled(value);
|
---|
6019 | }
|
---|
6020 |
|
---|
6021 | String Internals::ongoingLoadsDescriptions() const
|
---|
6022 | {
|
---|
6023 | StringBuilder builder;
|
---|
6024 | builder.append('[');
|
---|
6025 | bool isStarting = true;
|
---|
6026 | for (auto& identifier : platformStrategies()->loaderStrategy()->ongoingLoads()) {
|
---|
6027 | if (isStarting)
|
---|
6028 | isStarting = false;
|
---|
6029 | else
|
---|
6030 | builder.append(',');
|
---|
6031 |
|
---|
6032 | builder.append('[');
|
---|
6033 |
|
---|
6034 | for (auto& info : platformStrategies()->loaderStrategy()->intermediateLoadInformationFromResourceLoadIdentifier(identifier))
|
---|
6035 | builder.append('[', (int)info.type, ",\"", info.request.url().string(), "\",\"", info.request.httpMethod(), "\",", info.response.httpStatusCode(), ']');
|
---|
6036 |
|
---|
6037 | builder.append(']');
|
---|
6038 | }
|
---|
6039 | builder.append(']');
|
---|
6040 | return builder.toString();
|
---|
6041 | }
|
---|
6042 |
|
---|
6043 | void Internals::reloadWithoutContentExtensions()
|
---|
6044 | {
|
---|
6045 | if (auto* frame = this->frame())
|
---|
6046 | frame->loader().reload(ReloadOption::DisableContentBlockers);
|
---|
6047 | }
|
---|
6048 |
|
---|
6049 | void Internals::setUseSystemAppearance(bool value)
|
---|
6050 | {
|
---|
6051 | if (!contextDocument() || !contextDocument()->page())
|
---|
6052 | return;
|
---|
6053 | contextDocument()->page()->setUseSystemAppearance(value);
|
---|
6054 | }
|
---|
6055 |
|
---|
6056 | size_t Internals::pluginCount()
|
---|
6057 | {
|
---|
6058 | if (!contextDocument() || !contextDocument()->page())
|
---|
6059 | return 0;
|
---|
6060 |
|
---|
6061 | return contextDocument()->page()->pluginData().webVisiblePlugins().size();
|
---|
6062 | }
|
---|
6063 |
|
---|
6064 | void Internals::notifyResourceLoadObserver()
|
---|
6065 | {
|
---|
6066 | ResourceLoadObserver::shared().updateCentralStatisticsStore([] { });
|
---|
6067 | }
|
---|
6068 |
|
---|
6069 | unsigned Internals::primaryScreenDisplayID()
|
---|
6070 | {
|
---|
6071 | #if PLATFORM(COCOA)
|
---|
6072 | return WebCore::primaryScreenDisplayID();
|
---|
6073 | #else
|
---|
6074 | return 0;
|
---|
6075 | #endif
|
---|
6076 | }
|
---|
6077 |
|
---|
6078 | bool Internals::capsLockIsOn()
|
---|
6079 | {
|
---|
6080 | return WebCore::PlatformKeyboardEvent::currentCapsLockState();
|
---|
6081 | }
|
---|
6082 |
|
---|
6083 | auto Internals::parseHEVCCodecParameters(StringView string) -> std::optional<HEVCParameterSet>
|
---|
6084 | {
|
---|
6085 | return WebCore::parseHEVCCodecParameters(string);
|
---|
6086 | }
|
---|
6087 |
|
---|
6088 | String Internals::createHEVCCodecParametersString(const HEVCParameterSet& parameters)
|
---|
6089 | {
|
---|
6090 | return WebCore::createHEVCCodecParametersString(parameters);
|
---|
6091 | }
|
---|
6092 |
|
---|
6093 | auto Internals::parseDoViCodecParameters(StringView string) -> std::optional<DoViParameterSet>
|
---|
6094 | {
|
---|
6095 | auto parseResult = WebCore::parseDoViCodecParameters(string);
|
---|
6096 | if (!parseResult)
|
---|
6097 | return std::nullopt;
|
---|
6098 | DoViParameterSet convertedResult;
|
---|
6099 | switch (parseResult->codec) {
|
---|
6100 | case DoViParameters::Codec::AVC1:
|
---|
6101 | convertedResult.codecName = "avc1"_s;
|
---|
6102 | break;
|
---|
6103 | case DoViParameters::Codec::AVC3:
|
---|
6104 | convertedResult.codecName = "avc3"_s;
|
---|
6105 | break;
|
---|
6106 | case DoViParameters::Codec::HEV1:
|
---|
6107 | convertedResult.codecName = "hev1"_s;
|
---|
6108 | break;
|
---|
6109 | case DoViParameters::Codec::HVC1:
|
---|
6110 | convertedResult.codecName = "hvc1"_s;
|
---|
6111 | break;
|
---|
6112 | }
|
---|
6113 | convertedResult.bitstreamProfileID = parseResult->bitstreamProfileID;
|
---|
6114 | convertedResult.bitstreamLevelID = parseResult->bitstreamLevelID;
|
---|
6115 | return convertedResult;
|
---|
6116 | }
|
---|
6117 |
|
---|
6118 | String Internals::createDoViCodecParametersString(const DoViParameterSet& parameterSet)
|
---|
6119 | {
|
---|
6120 | DoViParameters::Codec codec;
|
---|
6121 | if (parameterSet.codecName == "avc1"_s)
|
---|
6122 | codec = DoViParameters::Codec::AVC1;
|
---|
6123 | else if (parameterSet.codecName == "avc3"_s)
|
---|
6124 | codec = DoViParameters::Codec::AVC3;
|
---|
6125 | else if (parameterSet.codecName == "hev1"_s)
|
---|
6126 | codec = DoViParameters::Codec::HEV1;
|
---|
6127 | else if (parameterSet.codecName == "hvc1"_s)
|
---|
6128 | codec = DoViParameters::Codec::HVC1;
|
---|
6129 | else
|
---|
6130 | return emptyString();
|
---|
6131 |
|
---|
6132 | return WebCore::createDoViCodecParametersString({ codec, parameterSet.bitstreamProfileID, parameterSet.bitstreamLevelID });
|
---|
6133 | }
|
---|
6134 |
|
---|
6135 | std::optional<VPCodecConfigurationRecord> Internals::parseVPCodecParameters(StringView string)
|
---|
6136 | {
|
---|
6137 | return WebCore::parseVPCodecParameters(string);
|
---|
6138 | }
|
---|
6139 |
|
---|
6140 | auto Internals::getCookies() const -> Vector<CookieData>
|
---|
6141 | {
|
---|
6142 | auto* document = contextDocument();
|
---|
6143 | if (!document)
|
---|
6144 | return { };
|
---|
6145 |
|
---|
6146 | auto* page = document->page();
|
---|
6147 | if (!page)
|
---|
6148 | return { };
|
---|
6149 |
|
---|
6150 | Vector<Cookie> cookies;
|
---|
6151 | page->cookieJar().getRawCookies(*document, document->cookieURL(), cookies);
|
---|
6152 | return WTF::map(cookies, [](auto& cookie) {
|
---|
6153 | return CookieData { cookie };
|
---|
6154 | });
|
---|
6155 | }
|
---|
6156 |
|
---|
6157 | void Internals::setAlwaysAllowLocalWebarchive(bool alwaysAllowLocalWebarchive)
|
---|
6158 | {
|
---|
6159 | auto* localFrame = frame();
|
---|
6160 | if (!localFrame)
|
---|
6161 | return;
|
---|
6162 | localFrame->loader().setAlwaysAllowLocalWebarchive(alwaysAllowLocalWebarchive);
|
---|
6163 | }
|
---|
6164 |
|
---|
6165 | void Internals::processWillSuspend()
|
---|
6166 | {
|
---|
6167 | #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
|
---|
6168 | PlatformMediaSessionManager::sharedManager().processWillSuspend();
|
---|
6169 | #endif
|
---|
6170 | }
|
---|
6171 |
|
---|
6172 | void Internals::processDidResume()
|
---|
6173 | {
|
---|
6174 | #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
|
---|
6175 | PlatformMediaSessionManager::sharedManager().processDidResume();
|
---|
6176 | #endif
|
---|
6177 | }
|
---|
6178 |
|
---|
6179 | void Internals::testDictionaryLogging()
|
---|
6180 | {
|
---|
6181 | auto* document = contextDocument();
|
---|
6182 | if (!document)
|
---|
6183 | return;
|
---|
6184 |
|
---|
6185 | auto* page = document->page();
|
---|
6186 | if (!page)
|
---|
6187 | return;
|
---|
6188 |
|
---|
6189 | DiagnosticLoggingClient::ValueDictionary dictionary;
|
---|
6190 | dictionary.set("stringKey"_s, String("stringValue"_s));
|
---|
6191 | dictionary.set("uint64Key"_s, std::numeric_limits<uint64_t>::max());
|
---|
6192 | dictionary.set("int64Key"_s, std::numeric_limits<int64_t>::min());
|
---|
6193 | dictionary.set("boolKey"_s, true);
|
---|
6194 | dictionary.set("doubleKey"_s, 2.7182818284590452353602874);
|
---|
6195 |
|
---|
6196 | page->diagnosticLoggingClient().logDiagnosticMessageWithValueDictionary("testMessage"_s, "testDescription"_s, dictionary, ShouldSample::No);
|
---|
6197 | }
|
---|
6198 |
|
---|
6199 | void Internals::setMaximumIntervalForUserGestureForwardingForFetch(double interval)
|
---|
6200 | {
|
---|
6201 | UserGestureToken::setMaximumIntervalForUserGestureForwardingForFetchForTesting(Seconds(interval));
|
---|
6202 | }
|
---|
6203 |
|
---|
6204 | void Internals::setTransientActivationDuration(double seconds)
|
---|
6205 | {
|
---|
6206 | DOMWindow::overrideTransientActivationDurationForTesting(Seconds { seconds });
|
---|
6207 | }
|
---|
6208 |
|
---|
6209 | void Internals::setIsPlayingToAutomotiveHeadUnit(bool isPlaying)
|
---|
6210 | {
|
---|
6211 | #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
|
---|
6212 | PlatformMediaSessionManager::sharedManager().setIsPlayingToAutomotiveHeadUnit(isPlaying);
|
---|
6213 | #endif
|
---|
6214 | }
|
---|
6215 |
|
---|
6216 | String Internals::highlightPseudoElementColor(const AtomString& highlightName, Element& element)
|
---|
6217 | {
|
---|
6218 | element.document().updateStyleIfNeeded();
|
---|
6219 |
|
---|
6220 | auto& styleResolver = element.document().styleScope().resolver();
|
---|
6221 | auto* parentStyle = element.computedStyle();
|
---|
6222 | if (!parentStyle)
|
---|
6223 | return { };
|
---|
6224 |
|
---|
6225 | auto style = styleResolver.pseudoStyleForElement(element, { PseudoId::Highlight, highlightName }, { parentStyle });
|
---|
6226 | if (!style)
|
---|
6227 | return { };
|
---|
6228 |
|
---|
6229 | return serializationForCSS(style->color());
|
---|
6230 | }
|
---|
6231 |
|
---|
6232 | Internals::TextIndicatorInfo::TextIndicatorInfo()
|
---|
6233 | {
|
---|
6234 | }
|
---|
6235 |
|
---|
6236 | Internals::TextIndicatorInfo::TextIndicatorInfo(const WebCore::TextIndicatorData& data)
|
---|
6237 | : textBoundingRectInRootViewCoordinates(DOMRect::create(data.textBoundingRectInRootViewCoordinates))
|
---|
6238 | , textRectsInBoundingRectCoordinates(DOMRectList::create(data.textRectsInBoundingRectCoordinates))
|
---|
6239 | {
|
---|
6240 | }
|
---|
6241 |
|
---|
6242 | Internals::TextIndicatorInfo::~TextIndicatorInfo() = default;
|
---|
6243 |
|
---|
6244 | Internals::TextIndicatorInfo Internals::textIndicatorForRange(const Range& range, TextIndicatorOptions options)
|
---|
6245 | {
|
---|
6246 | auto indicator = TextIndicator::createWithRange(makeSimpleRange(range), options.coreOptions(), TextIndicatorPresentationTransition::None);
|
---|
6247 | return indicator->data();
|
---|
6248 | }
|
---|
6249 |
|
---|
6250 | void Internals::addPrefetchLoadEventListener(HTMLLinkElement& link, RefPtr<EventListener>&& listener)
|
---|
6251 | {
|
---|
6252 | if (link.document().settings().linkPrefetchEnabled() && equalLettersIgnoringASCIICase(link.rel(), "prefetch"_s)) {
|
---|
6253 | link.allowPrefetchLoadAndErrorForTesting();
|
---|
6254 | link.addEventListener(eventNames().loadEvent, listener.releaseNonNull(), false);
|
---|
6255 | }
|
---|
6256 | }
|
---|
6257 |
|
---|
6258 | #if ENABLE(WEB_AUTHN)
|
---|
6259 | void Internals::setMockWebAuthenticationConfiguration(const MockWebAuthenticationConfiguration& configuration)
|
---|
6260 | {
|
---|
6261 | auto* document = contextDocument();
|
---|
6262 | if (!document)
|
---|
6263 | return;
|
---|
6264 | auto* page = document->page();
|
---|
6265 | if (!page)
|
---|
6266 | return;
|
---|
6267 | page->chrome().client().setMockWebAuthenticationConfiguration(configuration);
|
---|
6268 | }
|
---|
6269 | #endif
|
---|
6270 |
|
---|
6271 | void Internals::setMaxCanvasPixelMemory(unsigned size)
|
---|
6272 | {
|
---|
6273 | HTMLCanvasElement::setMaxPixelMemoryForTesting(size);
|
---|
6274 | }
|
---|
6275 |
|
---|
6276 | void Internals::setMaxCanvasArea(unsigned size)
|
---|
6277 | {
|
---|
6278 | HTMLCanvasElement::setMaxCanvasAreaForTesting(size);
|
---|
6279 | }
|
---|
6280 |
|
---|
6281 | int Internals::processIdentifier() const
|
---|
6282 | {
|
---|
6283 | return getCurrentProcessID();
|
---|
6284 | }
|
---|
6285 |
|
---|
6286 | Ref<InternalsMapLike> Internals::createInternalsMapLike()
|
---|
6287 | {
|
---|
6288 | return InternalsMapLike::create();
|
---|
6289 | }
|
---|
6290 |
|
---|
6291 | Ref<InternalsSetLike> Internals::createInternalsSetLike()
|
---|
6292 | {
|
---|
6293 | return InternalsSetLike::create();
|
---|
6294 | }
|
---|
6295 |
|
---|
6296 | bool Internals::hasSandboxMachLookupAccessToGlobalName(const String& process, const String& service)
|
---|
6297 | {
|
---|
6298 | #if PLATFORM(COCOA)
|
---|
6299 | pid_t pid;
|
---|
6300 | if (process == "com.apple.WebKit.WebContent"_s)
|
---|
6301 | pid = getpid();
|
---|
6302 | else
|
---|
6303 | RELEASE_ASSERT_NOT_REACHED();
|
---|
6304 |
|
---|
6305 | return !sandbox_check(pid, "mach-lookup", static_cast<enum sandbox_filter_type>(SANDBOX_FILTER_GLOBAL_NAME | SANDBOX_CHECK_NO_REPORT), service.utf8().data());
|
---|
6306 | #else
|
---|
6307 | UNUSED_PARAM(process);
|
---|
6308 | UNUSED_PARAM(service);
|
---|
6309 | return false;
|
---|
6310 | #endif
|
---|
6311 | }
|
---|
6312 |
|
---|
6313 | bool Internals::hasSandboxMachLookupAccessToXPCServiceName(const String& process, const String& service)
|
---|
6314 | {
|
---|
6315 | #if PLATFORM(COCOA)
|
---|
6316 | pid_t pid;
|
---|
6317 | if (process == "com.apple.WebKit.WebContent"_s)
|
---|
6318 | pid = getpid();
|
---|
6319 | else
|
---|
6320 | RELEASE_ASSERT_NOT_REACHED();
|
---|
6321 |
|
---|
6322 | return !sandbox_check(pid, "mach-lookup", static_cast<enum sandbox_filter_type>(SANDBOX_FILTER_XPC_SERVICE_NAME | SANDBOX_CHECK_NO_REPORT), service.utf8().data());
|
---|
6323 | #else
|
---|
6324 | UNUSED_PARAM(process);
|
---|
6325 | UNUSED_PARAM(service);
|
---|
6326 | return false;
|
---|
6327 | #endif
|
---|
6328 | }
|
---|
6329 |
|
---|
6330 | String Internals::windowLocationHost(DOMWindow& window)
|
---|
6331 | {
|
---|
6332 | return window.location().host();
|
---|
6333 | }
|
---|
6334 |
|
---|
6335 | String Internals::systemColorForCSSValue(const String& cssValue, bool useDarkModeAppearance, bool useElevatedUserInterfaceLevel)
|
---|
6336 | {
|
---|
6337 | CSSValueID id = cssValueKeywordID(cssValue);
|
---|
6338 | RELEASE_ASSERT(StyleColor::isSystemColorKeyword(id));
|
---|
6339 |
|
---|
6340 | OptionSet<StyleColorOptions> options;
|
---|
6341 | if (useDarkModeAppearance)
|
---|
6342 | options.add(StyleColorOptions::UseDarkAppearance);
|
---|
6343 | if (useElevatedUserInterfaceLevel)
|
---|
6344 | options.add(StyleColorOptions::UseElevatedUserInterfaceLevel);
|
---|
6345 |
|
---|
6346 | return serializationForCSS(RenderTheme::singleton().systemColor(id, options));
|
---|
6347 | }
|
---|
6348 |
|
---|
6349 | bool Internals::systemHasBattery() const
|
---|
6350 | {
|
---|
6351 | #if PLATFORM(COCOA)
|
---|
6352 | return WebCore::systemHasBattery();
|
---|
6353 | #else
|
---|
6354 | return false;
|
---|
6355 | #endif
|
---|
6356 | }
|
---|
6357 |
|
---|
6358 | void Internals::setSystemHasBatteryForTesting(bool hasBattery)
|
---|
6359 | {
|
---|
6360 | #if PLATFORM(COCOA)
|
---|
6361 | SystemBatteryStatusTestingOverrides::singleton().setHasBattery(hasBattery);
|
---|
6362 | #else
|
---|
6363 | UNUSED_PARAM(hasBattery);
|
---|
6364 | #endif
|
---|
6365 | }
|
---|
6366 |
|
---|
6367 | void Internals::setSystemHasACForTesting(bool hasAC)
|
---|
6368 | {
|
---|
6369 | #if PLATFORM(COCOA)
|
---|
6370 | SystemBatteryStatusTestingOverrides::singleton().setHasAC(hasAC);
|
---|
6371 | #else
|
---|
6372 | UNUSED_PARAM(hasAC);
|
---|
6373 | #endif
|
---|
6374 | }
|
---|
6375 |
|
---|
6376 | void Internals::setHardwareVP9DecoderDisabledForTesting(bool disabled)
|
---|
6377 | {
|
---|
6378 | #if ENABLE(VP9) && PLATFORM(COCOA)
|
---|
6379 | VP9TestingOverrides::singleton().setHardwareDecoderDisabled(disabled);
|
---|
6380 | #else
|
---|
6381 | UNUSED_PARAM(disabled);
|
---|
6382 | #endif
|
---|
6383 | }
|
---|
6384 |
|
---|
6385 | void Internals::setVP9ScreenSizeAndScaleForTesting(double width, double height, double scale)
|
---|
6386 | {
|
---|
6387 | #if ENABLE(VP9) && PLATFORM(COCOA)
|
---|
6388 | VP9TestingOverrides::singleton().setVP9ScreenSizeAndScale(ScreenDataOverrides { width, height, scale });
|
---|
6389 | #else
|
---|
6390 | UNUSED_PARAM(width);
|
---|
6391 | UNUSED_PARAM(height);
|
---|
6392 | UNUSED_PARAM(scale);
|
---|
6393 | #endif
|
---|
6394 | }
|
---|
6395 |
|
---|
6396 | int Internals::readPreferenceInteger(const String& domain, const String& key)
|
---|
6397 | {
|
---|
6398 | #if PLATFORM(COCOA)
|
---|
6399 | Boolean keyExistsAndHasValidFormat = false;
|
---|
6400 | return CFPreferencesGetAppIntegerValue(key.createCFString().get(), domain.createCFString().get(), &keyExistsAndHasValidFormat);
|
---|
6401 | #else
|
---|
6402 | UNUSED_PARAM(domain);
|
---|
6403 | UNUSED_PARAM(key);
|
---|
6404 | return -1;
|
---|
6405 | #endif
|
---|
6406 | }
|
---|
6407 |
|
---|
6408 | #if !PLATFORM(COCOA)
|
---|
6409 | String Internals::encodedPreferenceValue(const String&, const String&)
|
---|
6410 | {
|
---|
6411 | return emptyString();
|
---|
6412 | }
|
---|
6413 |
|
---|
6414 | String Internals::getUTIFromTag(const String&, const String&, const String&)
|
---|
6415 | {
|
---|
6416 | return emptyString();
|
---|
6417 | }
|
---|
6418 |
|
---|
6419 | bool Internals::isRemoteUIAppForAccessibility()
|
---|
6420 | {
|
---|
6421 | return false;
|
---|
6422 | }
|
---|
6423 |
|
---|
6424 | bool Internals::hasSandboxIOKitOpenAccessToClass(const String& process, const String& ioKitClass)
|
---|
6425 | {
|
---|
6426 | UNUSED_PARAM(process);
|
---|
6427 | UNUSED_PARAM(ioKitClass);
|
---|
6428 | return false;
|
---|
6429 | }
|
---|
6430 | #endif
|
---|
6431 |
|
---|
6432 | #if ENABLE(APP_HIGHLIGHTS)
|
---|
6433 | Vector<String> Internals::appHighlightContextMenuItemTitles() const
|
---|
6434 | {
|
---|
6435 | return {{
|
---|
6436 | contextMenuItemTagAddHighlightToCurrentQuickNote(),
|
---|
6437 | contextMenuItemTagAddHighlightToNewQuickNote(),
|
---|
6438 | }};
|
---|
6439 | }
|
---|
6440 |
|
---|
6441 | unsigned Internals::numberOfAppHighlights()
|
---|
6442 | {
|
---|
6443 | Document* document = contextDocument();
|
---|
6444 | if (!document)
|
---|
6445 | return 0;
|
---|
6446 | auto appHighlightRegister = document->appHighlightRegisterIfExists();
|
---|
6447 | if (!appHighlightRegister)
|
---|
6448 | return 0;
|
---|
6449 | unsigned numHighlights = 0;
|
---|
6450 | for (auto& highlight : appHighlightRegister->map())
|
---|
6451 | numHighlights += highlight.value->rangesData().size();
|
---|
6452 | return numHighlights;
|
---|
6453 | }
|
---|
6454 | #endif
|
---|
6455 |
|
---|
6456 | bool Internals::supportsPictureInPicture()
|
---|
6457 | {
|
---|
6458 | return WebCore::supportsPictureInPicture();
|
---|
6459 | }
|
---|
6460 |
|
---|
6461 | String Internals::focusRingColor()
|
---|
6462 | {
|
---|
6463 | return serializationForCSS(RenderTheme::singleton().focusRingColor({ }));
|
---|
6464 | }
|
---|
6465 |
|
---|
6466 | unsigned Internals::createSleepDisabler(const String& reason, bool display)
|
---|
6467 | {
|
---|
6468 | static unsigned lastUsedIdentifier = 0;
|
---|
6469 | auto sleepDisabler = makeUnique<WebCore::SleepDisabler>(reason, display ? PAL::SleepDisabler::Type::Display : PAL::SleepDisabler::Type::System);
|
---|
6470 | m_sleepDisablers.add(++lastUsedIdentifier, WTFMove(sleepDisabler));
|
---|
6471 | return lastUsedIdentifier;
|
---|
6472 | }
|
---|
6473 |
|
---|
6474 | bool Internals::destroySleepDisabler(unsigned identifier)
|
---|
6475 | {
|
---|
6476 | return m_sleepDisablers.remove(identifier);
|
---|
6477 | }
|
---|
6478 |
|
---|
6479 | #if ENABLE(WEBXR)
|
---|
6480 |
|
---|
6481 | ExceptionOr<RefPtr<WebXRTest>> Internals::xrTest()
|
---|
6482 | {
|
---|
6483 | auto* document = contextDocument();
|
---|
6484 | if (!document || !document->domWindow() || !document->settings().webXREnabled())
|
---|
6485 | return Exception { InvalidAccessError };
|
---|
6486 |
|
---|
6487 | if (!m_xrTest) {
|
---|
6488 | auto* navigator = contextDocument()->domWindow()->optionalNavigator();
|
---|
6489 | if (!navigator)
|
---|
6490 | return Exception { InvalidAccessError };
|
---|
6491 |
|
---|
6492 | m_xrTest = WebXRTest::create(NavigatorWebXR::xr(*navigator));
|
---|
6493 | }
|
---|
6494 | return m_xrTest.get();
|
---|
6495 | }
|
---|
6496 |
|
---|
6497 | #endif
|
---|
6498 |
|
---|
6499 | #if ENABLE(ENCRYPTED_MEDIA)
|
---|
6500 | unsigned Internals::mediaKeysInternalInstanceObjectRefCount(const MediaKeys& mediaKeys) const
|
---|
6501 | {
|
---|
6502 | return mediaKeys.internalInstanceObjectRefCount();
|
---|
6503 | }
|
---|
6504 |
|
---|
6505 | unsigned Internals::mediaKeySessionInternalInstanceSessionObjectRefCount(const MediaKeySession& mediaKeySession) const
|
---|
6506 | {
|
---|
6507 | return mediaKeySession.internalInstanceSessionObjectRefCount();
|
---|
6508 | }
|
---|
6509 | #endif
|
---|
6510 |
|
---|
6511 | void Internals::setContentSizeCategory(Internals::ContentSizeCategory category)
|
---|
6512 | {
|
---|
6513 | #if PLATFORM(IOS)
|
---|
6514 | CFStringRef ctCategory = nil;
|
---|
6515 | switch (category) {
|
---|
6516 | case Internals::ContentSizeCategory::L:
|
---|
6517 | ctCategory = kCTFontContentSizeCategoryL;
|
---|
6518 | break;
|
---|
6519 | case Internals::ContentSizeCategory::XXXL:
|
---|
6520 | ctCategory = kCTFontContentSizeCategoryXXXL;
|
---|
6521 | break;
|
---|
6522 | }
|
---|
6523 | WebCore::setContentSizeCategory(ctCategory);
|
---|
6524 | Page::updateStyleForAllPagesAfterGlobalChangeInEnvironment();
|
---|
6525 | #else
|
---|
6526 | UNUSED_PARAM(category);
|
---|
6527 | #endif
|
---|
6528 | }
|
---|
6529 |
|
---|
6530 | #if ENABLE(ATTACHMENT_ELEMENT)
|
---|
6531 |
|
---|
6532 | ExceptionOr<Internals::AttachmentThumbnailInfo> Internals::attachmentThumbnailInfo(const HTMLAttachmentElement& element)
|
---|
6533 | {
|
---|
6534 | #if HAVE(QUICKLOOK_THUMBNAILING)
|
---|
6535 | AttachmentThumbnailInfo info;
|
---|
6536 | if (auto image = element.thumbnail()) {
|
---|
6537 | auto size = image->size();
|
---|
6538 | info.width = size.width();
|
---|
6539 | info.height = size.height();
|
---|
6540 | }
|
---|
6541 | return info;
|
---|
6542 | #else
|
---|
6543 | UNUSED_PARAM(element);
|
---|
6544 | return Exception { InvalidAccessError };
|
---|
6545 | #endif
|
---|
6546 | }
|
---|
6547 |
|
---|
6548 | #if ENABLE(SERVICE_CONTROLS)
|
---|
6549 | bool Internals::hasImageControls(const HTMLImageElement& element) const
|
---|
6550 | {
|
---|
6551 | return ImageControlsMac::hasImageControls(element);
|
---|
6552 | }
|
---|
6553 | #endif
|
---|
6554 |
|
---|
6555 | #endif // ENABLE(ATTACHMENT_ELEMENT)
|
---|
6556 |
|
---|
6557 | #if ENABLE(MEDIA_SESSION)
|
---|
6558 | ExceptionOr<double> Internals::currentMediaSessionPosition(const MediaSession& session)
|
---|
6559 | {
|
---|
6560 | if (auto currentPosition = session.currentPosition())
|
---|
6561 | return *currentPosition;
|
---|
6562 | return Exception { InvalidStateError };
|
---|
6563 | }
|
---|
6564 |
|
---|
6565 | ExceptionOr<void> Internals::sendMediaSessionAction(MediaSession& session, const MediaSessionActionDetails& actionDetails)
|
---|
6566 | {
|
---|
6567 | if (session.callActionHandler(actionDetails))
|
---|
6568 | return { };
|
---|
6569 |
|
---|
6570 | return Exception { InvalidStateError };
|
---|
6571 | }
|
---|
6572 |
|
---|
6573 | void Internals::loadArtworkImage(String&& url, ArtworkImagePromise&& promise)
|
---|
6574 | {
|
---|
6575 | if (!contextDocument()) {
|
---|
6576 | promise.reject(Exception { InvalidStateError, "No document."_s });
|
---|
6577 | return;
|
---|
6578 | }
|
---|
6579 | if (m_artworkImagePromise) {
|
---|
6580 | promise.reject(Exception { InvalidStateError, "Another download is currently pending."_s });
|
---|
6581 | return;
|
---|
6582 | }
|
---|
6583 | m_artworkImagePromise = makeUnique<ArtworkImagePromise>(WTFMove(promise));
|
---|
6584 | m_artworkLoader = makeUnique<ArtworkImageLoader>(*contextDocument(), url, [this](Image* image) {
|
---|
6585 | if (image) {
|
---|
6586 | auto imageData = ImageData::create(image->width(), image->height(), { { PredefinedColorSpace::SRGB } });
|
---|
6587 | if (!imageData.hasException())
|
---|
6588 | m_artworkImagePromise->resolve(imageData.releaseReturnValue());
|
---|
6589 | else
|
---|
6590 | m_artworkImagePromise->reject(imageData.exception().code());
|
---|
6591 | } else
|
---|
6592 | m_artworkImagePromise->reject(Exception { InvalidAccessError, "No image retrieved."_s });
|
---|
6593 | m_artworkImagePromise = nullptr;
|
---|
6594 | });
|
---|
6595 | m_artworkLoader->requestImageResource();
|
---|
6596 | }
|
---|
6597 |
|
---|
6598 | ExceptionOr<Vector<String>> Internals::platformSupportedCommands() const
|
---|
6599 | {
|
---|
6600 | if (!contextDocument())
|
---|
6601 | return Exception { InvalidAccessError };
|
---|
6602 | auto commands = PlatformMediaSessionManager::sharedManager().supportedCommands();
|
---|
6603 | Vector<String> commandStrings;
|
---|
6604 | for (auto command : commands)
|
---|
6605 | commandStrings.append(convertEnumerationToString(command));
|
---|
6606 |
|
---|
6607 | return commandStrings;
|
---|
6608 | }
|
---|
6609 |
|
---|
6610 | #endif
|
---|
6611 |
|
---|
6612 | #if ENABLE(MEDIA_SESSION_COORDINATOR)
|
---|
6613 | ExceptionOr<void> Internals::registerMockMediaSessionCoordinator(ScriptExecutionContext& context, RefPtr<StringCallback>&& listener)
|
---|
6614 | {
|
---|
6615 | if (m_mockMediaSessionCoordinator)
|
---|
6616 | return { };
|
---|
6617 |
|
---|
6618 | auto* document = contextDocument();
|
---|
6619 | if (!document || !document->domWindow())
|
---|
6620 | return Exception { InvalidAccessError };
|
---|
6621 |
|
---|
6622 | if (!document->settings().mediaSessionCoordinatorEnabled())
|
---|
6623 | return Exception { InvalidAccessError };
|
---|
6624 |
|
---|
6625 | auto& session = NavigatorMediaSession::mediaSession(document->domWindow()->navigator());
|
---|
6626 | auto mock = MockMediaSessionCoordinator::create(context, WTFMove(listener));
|
---|
6627 | m_mockMediaSessionCoordinator = mock.ptr();
|
---|
6628 | session.coordinator().setMediaSessionCoordinatorPrivate(WTFMove(mock));
|
---|
6629 |
|
---|
6630 | return { };
|
---|
6631 | }
|
---|
6632 |
|
---|
6633 | ExceptionOr<void> Internals::setMockMediaSessionCoordinatorCommandsShouldFail(bool shouldFail)
|
---|
6634 | {
|
---|
6635 | if (!m_mockMediaSessionCoordinator)
|
---|
6636 | return Exception { InvalidStateError };
|
---|
6637 |
|
---|
6638 | m_mockMediaSessionCoordinator->setCommandsShouldFail(shouldFail);
|
---|
6639 | return { };
|
---|
6640 | }
|
---|
6641 | #endif // ENABLE(MEDIA_SESSION)
|
---|
6642 |
|
---|
6643 | constexpr ASCIILiteral string(PartialOrdering ordering)
|
---|
6644 | {
|
---|
6645 | if (is_lt(ordering))
|
---|
6646 | return "less"_s;
|
---|
6647 | if (is_gt(ordering))
|
---|
6648 | return "greater"_s;
|
---|
6649 | if (is_eq(ordering))
|
---|
6650 | return "equivalent"_s;
|
---|
6651 | return "unordered"_s;
|
---|
6652 | }
|
---|
6653 |
|
---|
6654 | constexpr TreeType convertType(Internals::TreeType type)
|
---|
6655 | {
|
---|
6656 | switch (type) {
|
---|
6657 | case Internals::Tree:
|
---|
6658 | return Tree;
|
---|
6659 | case Internals::ShadowIncludingTree:
|
---|
6660 | return ShadowIncludingTree;
|
---|
6661 | case Internals::ComposedTree:
|
---|
6662 | return ComposedTree;
|
---|
6663 | }
|
---|
6664 | ASSERT_NOT_REACHED();
|
---|
6665 | return Tree;
|
---|
6666 | }
|
---|
6667 |
|
---|
6668 | String Internals::treeOrder(Node& a, Node& b, TreeType type)
|
---|
6669 | {
|
---|
6670 | return string(treeOrderForTesting(convertType(type), a, b));
|
---|
6671 | }
|
---|
6672 |
|
---|
6673 | String Internals::treeOrderBoundaryPoints(Node& containerA, unsigned offsetA, Node& containerB, unsigned offsetB, TreeType type)
|
---|
6674 | {
|
---|
6675 | return string(treeOrderForTesting(convertType(type), { containerA, offsetA }, { containerB, offsetB }));
|
---|
6676 | }
|
---|
6677 |
|
---|
6678 | bool Internals::rangeContainsNode(const AbstractRange& range, Node& node, TreeType type)
|
---|
6679 | {
|
---|
6680 | return containsForTesting(convertType(type), makeSimpleRange(range), node);
|
---|
6681 | }
|
---|
6682 |
|
---|
6683 | bool Internals::rangeContainsBoundaryPoint(const AbstractRange& range, Node& container, unsigned offset, TreeType type)
|
---|
6684 | {
|
---|
6685 | return containsForTesting(convertType(type), makeSimpleRange(range), { container, offset });
|
---|
6686 | }
|
---|
6687 |
|
---|
6688 | bool Internals::rangeContainsRange(const AbstractRange& outerRange, const AbstractRange& innerRange, TreeType type)
|
---|
6689 | {
|
---|
6690 | return containsForTesting(convertType(type), makeSimpleRange(outerRange), makeSimpleRange(innerRange));
|
---|
6691 | }
|
---|
6692 |
|
---|
6693 | bool Internals::rangeIntersectsNode(const AbstractRange& range, Node& node, TreeType type)
|
---|
6694 | {
|
---|
6695 | return intersectsForTesting(convertType(type), makeSimpleRange(range), node);
|
---|
6696 | }
|
---|
6697 |
|
---|
6698 | bool Internals::rangeIntersectsRange(const AbstractRange& a, const AbstractRange& b, TreeType type)
|
---|
6699 | {
|
---|
6700 | return intersectsForTesting(convertType(type), makeSimpleRange(a), makeSimpleRange(b));
|
---|
6701 | }
|
---|
6702 |
|
---|
6703 | String Internals::dumpStyleResolvers()
|
---|
6704 | {
|
---|
6705 | auto* document = contextDocument();
|
---|
6706 | if (!document || !document->domWindow())
|
---|
6707 | return { };
|
---|
6708 |
|
---|
6709 | document->updateStyleIfNeeded();
|
---|
6710 |
|
---|
6711 | unsigned currentIdentifier = 0;
|
---|
6712 | HashMap<Style::Resolver*, unsigned> resolverIdentifiers;
|
---|
6713 |
|
---|
6714 | StringBuilder result;
|
---|
6715 |
|
---|
6716 | auto dumpResolver = [&](auto name, auto& resolver) {
|
---|
6717 | auto identifier = resolverIdentifiers.ensure(&resolver, [&] {
|
---|
6718 | return currentIdentifier++;
|
---|
6719 | }).iterator->value;
|
---|
6720 |
|
---|
6721 | result.append("(", name, " ");
|
---|
6722 | result.append("(identifier=", identifier, ") ");
|
---|
6723 | result.append("(author rule count=", resolver.ruleSets().authorStyle().ruleCount(), ")");
|
---|
6724 | result.append(")\n");
|
---|
6725 | };
|
---|
6726 |
|
---|
6727 | dumpResolver("document resolver", document->styleScope().resolver());
|
---|
6728 |
|
---|
6729 | for (auto* shadowRoot : document->inDocumentShadowRoots()) {
|
---|
6730 | auto* name = shadowRoot->mode() == ShadowRootMode::UserAgent ? "shadow root resolver (user agent)" : "shadow root resolver (author)";
|
---|
6731 | dumpResolver(name, shadowRoot->styleScope().resolver());
|
---|
6732 | }
|
---|
6733 |
|
---|
6734 | return result.toString();
|
---|
6735 | }
|
---|
6736 |
|
---|
6737 | ExceptionOr<void> Internals::setDocumentAutoplayPolicy(Document& document, Internals::AutoplayPolicy policy)
|
---|
6738 | {
|
---|
6739 | static_assert(static_cast<uint8_t>(WebCore::AutoplayPolicy::Default) == static_cast<uint8_t>(Internals::AutoplayPolicy::Default), "Internals::Default != WebCore::Default");
|
---|
6740 | static_assert(static_cast<uint8_t>(WebCore::AutoplayPolicy::Allow) == static_cast<uint8_t>(Internals::AutoplayPolicy::Allow), "Internals::Allow != WebCore::Allow");
|
---|
6741 | static_assert(static_cast<uint8_t>(WebCore::AutoplayPolicy::AllowWithoutSound) == static_cast<uint8_t>(Internals::AutoplayPolicy::AllowWithoutSound), "Internals::AllowWithoutSound != WebCore::AllowWithoutSound");
|
---|
6742 | static_assert(static_cast<uint8_t>(WebCore::AutoplayPolicy::Deny) == static_cast<uint8_t>(Internals::AutoplayPolicy::Deny), "Internals::Deny != WebCore::Deny");
|
---|
6743 |
|
---|
6744 | auto* loader = document.loader();
|
---|
6745 | if (!loader)
|
---|
6746 | return Exception { InvalidStateError };
|
---|
6747 |
|
---|
6748 | loader->setAutoplayPolicy(static_cast<WebCore::AutoplayPolicy>(policy));
|
---|
6749 |
|
---|
6750 | return { };
|
---|
6751 | }
|
---|
6752 |
|
---|
6753 | #if ENABLE(WEBGL) && !PLATFORM(COCOA)
|
---|
6754 | bool Internals::platformSupportsMetal(bool)
|
---|
6755 | {
|
---|
6756 | return false;
|
---|
6757 | }
|
---|
6758 | #endif
|
---|
6759 |
|
---|
6760 | void Internals::retainTextIteratorForDocumentContent()
|
---|
6761 | {
|
---|
6762 | auto* document = contextDocument();
|
---|
6763 | if (!document)
|
---|
6764 | return;
|
---|
6765 |
|
---|
6766 | auto range = makeRangeSelectingNodeContents(*document);
|
---|
6767 | m_textIterator = makeUnique<TextIterator>(range);
|
---|
6768 | }
|
---|
6769 |
|
---|
6770 | #if ENABLE(SERVICE_WORKER)
|
---|
6771 | RefPtr<PushSubscription> Internals::createPushSubscription(const String& endpoint, std::optional<EpochTimeStamp> expirationTime, const ArrayBuffer& serverVAPIDPublicKey, const ArrayBuffer& clientECDHPublicKey, const ArrayBuffer& auth)
|
---|
6772 | {
|
---|
6773 | auto myEndpoint = endpoint;
|
---|
6774 | Vector<uint8_t> myServerVAPIDPublicKey { static_cast<const uint8_t*>(serverVAPIDPublicKey.data()), serverVAPIDPublicKey.byteLength() };
|
---|
6775 | Vector<uint8_t> myClientECDHPublicKey { static_cast<const uint8_t*>(clientECDHPublicKey.data()), clientECDHPublicKey.byteLength() };
|
---|
6776 | Vector<uint8_t> myAuth { static_cast<const uint8_t*>(auth.data()), auth.byteLength() };
|
---|
6777 |
|
---|
6778 | return PushSubscription::create(PushSubscriptionData { { }, WTFMove(myEndpoint), expirationTime, WTFMove(myServerVAPIDPublicKey), WTFMove(myClientECDHPublicKey), WTFMove(myAuth) });
|
---|
6779 | }
|
---|
6780 | #endif
|
---|
6781 |
|
---|
6782 | void Internals::overrideModalContainerSearchTermForTesting(AtomString&& term)
|
---|
6783 | {
|
---|
6784 | if (auto observer = contextDocument()->modalContainerObserver())
|
---|
6785 | observer->overrideSearchTermForTesting(WTFMove(term));
|
---|
6786 | }
|
---|
6787 |
|
---|
6788 | #if ENABLE(ARKIT_INLINE_PREVIEW_MAC)
|
---|
6789 |
|
---|
6790 | void Internals::modelInlinePreviewUUIDs(ModelInlinePreviewUUIDsPromise&& promise) const
|
---|
6791 | {
|
---|
6792 | auto* document = contextDocument();
|
---|
6793 | if (!document) {
|
---|
6794 | promise.reject(InvalidStateError);
|
---|
6795 | return;
|
---|
6796 | }
|
---|
6797 |
|
---|
6798 | auto* frame = document->frame();
|
---|
6799 | if (!frame) {
|
---|
6800 | promise.reject(InvalidStateError);
|
---|
6801 | return;
|
---|
6802 | }
|
---|
6803 |
|
---|
6804 | CompletionHandler<void(Vector<String>&&)> completionHandler = [promise = WTFMove(promise)] (Vector<String> uuids) mutable {
|
---|
6805 | promise.resolve(uuids);
|
---|
6806 | };
|
---|
6807 |
|
---|
6808 | frame->loader().client().modelInlinePreviewUUIDs(WTFMove(completionHandler));
|
---|
6809 | }
|
---|
6810 |
|
---|
6811 | String Internals::modelInlinePreviewUUIDForModelElement(const HTMLModelElement& modelElement) const
|
---|
6812 | {
|
---|
6813 | return modelElement.inlinePreviewUUIDForTesting();
|
---|
6814 | }
|
---|
6815 |
|
---|
6816 | #endif
|
---|
6817 |
|
---|
6818 | } // namespace WebCore
|
---|