Make Remote Control commands testable
[WebKit-https.git] / Source / WebCore / testing / Internals.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  * Copyright (C) 2013 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 "AnimationController.h"
32 #include "ApplicationCacheStorage.h"
33 #include "BackForwardController.h"
34 #include "CachedResourceLoader.h"
35 #include "Chrome.h"
36 #include "ChromeClient.h"
37 #include "ClientRect.h"
38 #include "ClientRectList.h"
39 #include "ContentDistributor.h"
40 #include "Cursor.h"
41 #include "DOMStringList.h"
42 #include "DOMWindow.h"
43 #include "Document.h"
44 #include "DocumentMarker.h"
45 #include "DocumentMarkerController.h"
46 #include "Editor.h"
47 #include "Element.h"
48 #include "EventHandler.h"
49 #include "ExceptionCode.h"
50 #include "FormController.h"
51 #include "FrameLoader.h"
52 #include "FrameView.h"
53 #include "HTMLInputElement.h"
54 #include "HTMLNames.h"
55 #include "HTMLSelectElement.h"
56 #include "HTMLTextAreaElement.h"
57 #include "HistoryController.h"
58 #include "HistoryItem.h"
59 #include "InspectorClient.h"
60 #include "InspectorController.h"
61 #include "InspectorForwarding.h"
62 #include "InspectorFrontendClientLocal.h"
63 #include "InspectorInstrumentation.h"
64 #include "InspectorOverlay.h"
65 #include "InstrumentingAgents.h"
66 #include "IntRect.h"
67 #include "InternalSettings.h"
68 #include "Language.h"
69 #include "MainFrame.h"
70 #include "MallocStatistics.h"
71 #include "MediaPlayer.h"
72 #include "MediaSessionManager.h"
73 #include "MemoryCache.h"
74 #include "MemoryInfo.h"
75 #include "Page.h"
76 #include "PageConsole.h"
77 #include "PrintContext.h"
78 #include "PseudoElement.h"
79 #include "Range.h"
80 #include "RenderEmbeddedObject.h"
81 #include "RenderMenuList.h"
82 #include "RenderTreeAsText.h"
83 #include "RenderView.h"
84 #include "RuntimeEnabledFeatures.h"
85 #include "SchemeRegistry.h"
86 #include "ScrollingCoordinator.h"
87 #include "SerializedScriptValue.h"
88 #include "Settings.h"
89 #include "ShadowRoot.h"
90 #include "SpellChecker.h"
91 #include "StaticNodeList.h"
92 #include "StyleSheetContents.h"
93 #include "TextIterator.h"
94 #include "TreeScope.h"
95 #include "TypeConversions.h"
96 #include "ViewportArguments.h"
97 #include "WebConsoleAgent.h"
98 #include "WorkerThread.h"
99 #include <bytecode/CodeBlock.h>
100 #include <inspector/InspectorAgentBase.h>
101 #include <inspector/InspectorValues.h>
102 #include <runtime/JSCJSValue.h>
103 #include <wtf/text/CString.h>
104 #include <wtf/text/StringBuffer.h>
105
106 #if ENABLE(INPUT_TYPE_COLOR)
107 #include "ColorChooser.h"
108 #endif
109
110 #if ENABLE(BATTERY_STATUS)
111 #include "BatteryController.h"
112 #endif
113
114 #if ENABLE(NETWORK_INFO)
115 #include "NetworkInfo.h"
116 #include "NetworkInfoController.h"
117 #endif
118
119 #if ENABLE(PROXIMITY_EVENTS)
120 #include "DeviceProximityController.h"
121 #endif
122
123 #if ENABLE(MOUSE_CURSOR_SCALE)
124 #include <wtf/dtoa.h>
125 #endif
126
127 #if ENABLE(ENCRYPTED_MEDIA_V2)
128 #include "CDM.h"
129 #include "MockCDM.h"
130 #endif
131
132 #if ENABLE(VIDEO_TRACK)
133 #include "CaptionUserPreferences.h"
134 #include "PageGroup.h"
135 #endif
136
137 #if ENABLE(VIDEO)
138 #include "HTMLMediaElement.h"
139 #include "TimeRanges.h"
140 #endif
141
142 #if ENABLE(SPEECH_SYNTHESIS)
143 #include "DOMWindowSpeechSynthesis.h"
144 #include "PlatformSpeechSynthesizerMock.h"
145 #include "SpeechSynthesis.h"
146 #endif
147
148 #if ENABLE(VIBRATION)
149 #include "Vibration.h"
150 #endif
151
152 #if ENABLE(MEDIA_STREAM)
153 #include "MockMediaStreamCenter.h"
154 #include "RTCPeerConnection.h"
155 #include "RTCPeerConnectionHandlerMock.h"
156 #include "UserMediaClientMock.h"
157 #endif
158
159 #if ENABLE(MEDIA_SOURCE)
160 #include "MockMediaPlayerMediaSource.h"
161 #endif
162
163 using JSC::CodeBlock;
164 using JSC::FunctionExecutable;
165 using JSC::JSFunction;
166 using JSC::JSValue;
167 using JSC::ScriptExecutable;
168 using JSC::StackVisitor;
169
170 using namespace Inspector;
171
172 namespace WebCore {
173
174 using namespace HTMLNames;
175
176 #if ENABLE(INSPECTOR)
177 class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
178 public:
179     InspectorFrontendClientDummy(InspectorController*, Page*);
180     virtual ~InspectorFrontendClientDummy() { }
181     virtual void attachWindow(DockSide) override { }
182     virtual void detachWindow() override { }
183
184     virtual String localizedStringsURL() override { return String(); }
185
186     virtual void bringToFront() override { }
187     virtual void closeWindow() override { }
188
189     virtual void inspectedURLChanged(const String&) override { }
190
191 protected:
192     virtual void setAttachedWindowHeight(unsigned) override { }
193     virtual void setAttachedWindowWidth(unsigned) override { }
194     virtual void setToolbarHeight(unsigned) override { }
195 };
196
197 InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
198     : InspectorFrontendClientLocal(controller, page, std::make_unique<InspectorFrontendClientLocal::Settings>())
199 {
200 }
201
202 class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
203 public:
204     explicit InspectorFrontendChannelDummy(Page*);
205     virtual ~InspectorFrontendChannelDummy() { }
206     virtual bool sendMessageToFrontend(const String& message) override;
207
208 private:
209     Page* m_frontendPage;
210 };
211
212 InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
213     : m_frontendPage(page)
214 {
215 }
216
217 bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
218 {
219     return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
220 }
221 #endif // ENABLE(INSPECTOR)
222
223 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
224 {
225     if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
226         result = DocumentMarker::AllMarkers();
227     else if (equalIgnoringCase(markerType, "Spelling"))
228         result =  DocumentMarker::Spelling;
229     else if (equalIgnoringCase(markerType, "Grammar"))
230         result =  DocumentMarker::Grammar;
231     else if (equalIgnoringCase(markerType, "TextMatch"))
232         result =  DocumentMarker::TextMatch;
233     else if (equalIgnoringCase(markerType, "Replacement"))
234         result =  DocumentMarker::Replacement;
235     else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
236         result =  DocumentMarker::CorrectionIndicator;
237     else if (equalIgnoringCase(markerType, "RejectedCorrection"))
238         result =  DocumentMarker::RejectedCorrection;
239     else if (equalIgnoringCase(markerType, "Autocorrected"))
240         result =  DocumentMarker::Autocorrected;
241     else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
242         result =  DocumentMarker::SpellCheckingExemption;
243     else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
244         result =  DocumentMarker::DeletedAutocorrection;
245     else if (equalIgnoringCase(markerType, "DictationAlternatives"))
246         result =  DocumentMarker::DictationAlternatives;
247     else
248         return false;
249
250     return true;
251 }
252
253 const char* Internals::internalsId = "internals";
254
255 PassRefPtr<Internals> Internals::create(Document* document)
256 {
257     return adoptRef(new Internals(document));
258 }
259
260 Internals::~Internals()
261 {
262 }
263
264 void Internals::resetToConsistentState(Page* page)
265 {
266     ASSERT(page);
267
268     page->setPageScaleFactor(1, IntPoint(0, 0));
269     page->setPagination(Pagination());
270
271     FrameView* mainFrameView = page->mainFrame().view();
272     if (mainFrameView) {
273         mainFrameView->setHeaderHeight(0);
274         mainFrameView->setFooterHeight(0);
275     }
276
277     TextRun::setAllowsRoundingHacks(false);
278     WebCore::overrideUserPreferredLanguages(Vector<String>());
279     WebCore::Settings::setUsesOverlayScrollbars(false);
280 #if ENABLE(INSPECTOR)
281     page->inspectorController().setProfilerEnabled(false);
282 #endif
283 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
284     page->group().captionPreferences()->setCaptionsStyleSheetOverride(emptyString());
285     page->group().captionPreferences()->setTestingMode(false);
286 #endif
287     if (!page->mainFrame().editor().isContinuousSpellCheckingEnabled())
288         page->mainFrame().editor().toggleContinuousSpellChecking();
289     if (page->mainFrame().editor().isOverwriteModeEnabled())
290         page->mainFrame().editor().toggleOverwriteModeEnabled();
291     cacheStorage().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
292 #if ENABLE(VIDEO)
293     MediaSessionManager::sharedManager().resetRestrictions();
294 #endif
295 #if HAVE(ACCESSIBILITY)
296     AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
297     AXObjectCache::disableAccessibility();
298 #endif
299 }
300
301 Internals::Internals(Document* document)
302     : ContextDestructionObserver(document)
303 {
304 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
305     if (document && document->page())
306         document->page()->group().captionPreferences()->setTestingMode(true);
307 #endif
308
309 #if ENABLE(MEDIA_STREAM)
310     MockMediaStreamCenter::registerMockMediaStreamCenter();
311     enableMockRTCPeerConnectionHandler();
312     WebCore::provideUserMediaTo(document->page(), new UserMediaClientMock());
313 #endif
314 }
315
316 Document* Internals::contextDocument() const
317 {
318     return toDocument(scriptExecutionContext());
319 }
320
321 Frame* Internals::frame() const
322 {
323     if (!contextDocument())
324         return 0;
325     return contextDocument()->frame();
326 }
327
328 InternalSettings* Internals::settings() const
329 {
330     Document* document = contextDocument();
331     if (!document)
332         return 0;
333     Page* page = document->page();
334     if (!page)
335         return 0;
336     return InternalSettings::from(page);
337 }
338
339 unsigned Internals::workerThreadCount() const
340 {
341     return WorkerThread::workerThreadCount();
342 }
343
344 String Internals::address(Node* node)
345 {
346     char buf[32];
347     sprintf(buf, "%p", node);
348
349     return String(buf);
350 }
351
352 bool Internals::isPreloaded(const String& url)
353 {
354     Document* document = contextDocument();
355     return document->cachedResourceLoader()->isPreloaded(url);
356 }
357
358 bool Internals::isLoadingFromMemoryCache(const String& url)
359 {
360     if (!contextDocument() || !contextDocument()->page())
361         return false;
362     CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url), contextDocument()->page()->sessionID());
363     return resource && resource->status() == CachedResource::Cached;
364 }
365
366
367 Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
368 {
369     if (!node) {
370         ec = INVALID_ACCESS_ERR;
371         return nullptr;
372     }
373
374     return &node->treeScope().rootNode();
375 }
376
377 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
378 {
379     if (!node) {
380         ec = INVALID_ACCESS_ERR;
381         return nullptr;
382     }
383     const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
384     return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
385 }
386
387 unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
388 {
389     if (!contextDocument() || !contextDocument()->page()) {
390         ec = INVALID_ACCESS_ERR;
391         return 0;
392     }
393
394     return contextDocument()->page()->lastSpatialNavigationCandidateCount();
395 }
396
397 unsigned Internals::numberOfActiveAnimations() const
398 {
399     return frame()->animation().numberOfActiveAnimations(frame()->document());
400 }
401
402 bool Internals::animationsAreSuspended(ExceptionCode& ec) const
403 {
404     Document* document = contextDocument();
405     if (!document || !document->frame()) {
406         ec = INVALID_ACCESS_ERR;
407         return false;
408     }
409
410     return document->frame()->animation().isSuspended();
411 }
412
413 void Internals::suspendAnimations(ExceptionCode& ec) const
414 {
415     Document* document = contextDocument();
416     if (!document || !document->frame()) {
417         ec = INVALID_ACCESS_ERR;
418         return;
419     }
420
421     document->frame()->animation().suspendAnimations();
422 }
423
424 void Internals::resumeAnimations(ExceptionCode& ec) const
425 {
426     Document* document = contextDocument();
427     if (!document || !document->frame()) {
428         ec = INVALID_ACCESS_ERR;
429         return;
430     }
431
432     document->frame()->animation().resumeAnimations();
433 }
434
435 bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
436 {
437     if (!element || pauseTime < 0) {
438         ec = INVALID_ACCESS_ERR;
439         return false;
440     }
441     return frame()->animation().pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
442 }
443
444 bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
445 {
446     if (!element || pauseTime < 0) {
447         ec = INVALID_ACCESS_ERR;
448         return false;
449     }
450
451     if (pseudoId != "before" && pseudoId != "after") {
452         ec = INVALID_ACCESS_ERR;
453         return false;
454     }
455
456     PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
457     if (!pseudoElement) {
458         ec = INVALID_ACCESS_ERR;
459         return false;
460     }
461
462     return frame()->animation().pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
463 }
464
465 bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
466 {
467     if (!element || pauseTime < 0) {
468         ec = INVALID_ACCESS_ERR;
469         return false;
470     }
471     return frame()->animation().pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
472 }
473
474 bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
475 {
476     if (!element || pauseTime < 0) {
477         ec = INVALID_ACCESS_ERR;
478         return false;
479     }
480
481     if (pseudoId != "before" && pseudoId != "after") {
482         ec = INVALID_ACCESS_ERR;
483         return false;
484     }
485
486     PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
487     if (!pseudoElement) {
488         ec = INVALID_ACCESS_ERR;
489         return false;
490     }
491
492     return frame()->animation().pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
493 }
494
495 // FIXME: Remove.
496 bool Internals::attached(Node* node, ExceptionCode& ec)
497 {
498     if (!node) {
499         ec = INVALID_ACCESS_ERR;
500         return false;
501     }
502
503     return true;
504 }
505
506 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
507 {
508     if (!element) {
509         ec = INVALID_ACCESS_ERR;
510         return String();
511     }
512
513     element->document().updateStyleIfNeeded();
514
515     String representation = externalRepresentation(element);
516     if (representation.isEmpty()) {
517         ec = INVALID_ACCESS_ERR;
518         return String();
519     }
520
521     return representation;
522 }
523
524 PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
525 {
526     if (!node) {
527         ec = INVALID_ACCESS_ERR;
528         return 0;
529     }
530
531     bool allowVisitedStyle = true;
532     return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
533 }
534
535 Node* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
536 {
537     if (!host) {
538         ec = INVALID_ACCESS_ERR;
539         return 0;
540     }
541
542     if (ShadowRoot* shadowRoot = host->shadowRoot())
543         return shadowRoot;
544
545     return host->createShadowRoot(ec).get();
546 }
547
548 Node* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
549 {
550     if (!host) {
551         ec = INVALID_ACCESS_ERR;
552         return 0;
553     }
554     return host->createShadowRoot(ec).get();
555 }
556
557 Node* Internals::shadowRoot(Element* host, ExceptionCode& ec)
558 {
559     if (!host) {
560         ec = INVALID_ACCESS_ERR;
561         return 0;
562     }
563     return host->shadowRoot();
564 }
565
566 String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
567 {
568     if (!root || !root->isShadowRoot()) {
569         ec = INVALID_ACCESS_ERR;
570         return String();
571     }
572
573     switch (toShadowRoot(root)->type()) {
574     case ShadowRoot::UserAgentShadowRoot:
575         return String("UserAgentShadowRoot");
576     default:
577         ASSERT_NOT_REACHED();
578         return String("Unknown");
579     }
580 }
581
582 Element* Internals::includerFor(Node*, ExceptionCode& ec)
583 {
584     ec = INVALID_ACCESS_ERR;
585     return 0;
586 }
587
588 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
589 {
590     if (!element) {
591         ec = INVALID_ACCESS_ERR;
592         return String();
593     }
594
595     return element->shadowPseudoId().string();
596 }
597
598 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
599 {
600     if (!element) {
601         ec = INVALID_ACCESS_ERR;
602         return;
603     }
604
605     return element->setPseudo(id);
606 }
607
608 String Internals::visiblePlaceholder(Element* element)
609 {
610     if (element && isHTMLTextFormControlElement(*element)) {
611         if (toHTMLTextFormControlElement(*element).placeholderShouldBeVisible())
612             return toHTMLTextFormControlElement(*element).placeholderElement()->textContent();
613     }
614
615     return String();
616 }
617
618 #if ENABLE(INPUT_TYPE_COLOR)
619 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
620 {
621     if (!isHTMLInputElement(element))
622         return;
623     HTMLInputElement* inputElement = element->toInputElement();
624     if (!inputElement)
625         return;
626     inputElement->selectColorInColorChooser(Color(colorValue));
627 }
628 #endif
629
630 Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
631 {
632     HistoryItem* mainItem = frame()->loader().history().previousItem();
633     if (!mainItem) {
634         ec = INVALID_ACCESS_ERR;
635         return Vector<String>();
636     }
637     String uniqueName = frame()->tree().uniqueName();
638     if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
639         ec = INVALID_ACCESS_ERR;
640         return Vector<String>();
641     }
642     return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
643 }
644
645 void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
646 {
647     HistoryItem* mainItem = frame()->loader().history().previousItem();
648     if (!mainItem) {
649         ec = INVALID_ACCESS_ERR;
650         return;
651     }
652     String uniqueName = frame()->tree().uniqueName();
653     if (mainItem->target() == uniqueName)
654         mainItem->setDocumentState(state);
655     else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
656         subItem->setDocumentState(state);
657     else
658         ec = INVALID_ACCESS_ERR;
659 }
660
661 #if ENABLE(SPEECH_SYNTHESIS)
662 void Internals::enableMockSpeechSynthesizer()
663 {
664     Document* document = contextDocument();
665     if (!document || !document->domWindow())
666         return;
667     SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(document->domWindow());
668     if (!synthesis)
669         return;
670     
671     synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
672 }
673 #endif
674
675 #if ENABLE(MEDIA_STREAM)
676 void Internals::enableMockRTCPeerConnectionHandler()
677 {
678     RTCPeerConnectionHandler::create = RTCPeerConnectionHandlerMock::create;
679 }
680 #endif
681
682 PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
683 {
684     Document* document = contextDocument();
685     if (!document || !document->frame()) {
686         ec = INVALID_ACCESS_ERR;
687         return ClientRect::create();
688     }
689
690     return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
691 }
692
693 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
694 {
695     if (!element) {
696         ec = INVALID_ACCESS_ERR;
697         return ClientRect::create();
698     }
699
700     element->document().updateLayoutIgnorePendingStylesheets();
701     auto renderer = element->renderer();
702     if (!renderer)
703         return ClientRect::create();
704     return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
705 }
706
707 PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
708 {
709 #if ENABLE(INSPECTOR)
710     Document* document = contextDocument();
711     if (!document || !document->page()) {
712         ec = INVALID_ACCESS_ERR;
713         return ClientRectList::create();
714     }
715
716     Highlight highlight;
717     document->page()->inspectorController().getHighlight(&highlight);
718     return ClientRectList::create(highlight.quads);
719 #else
720     UNUSED_PARAM(ec);
721     return ClientRectList::create();
722 #endif
723 }
724
725 String Internals::inspectorHighlightObject(ExceptionCode& ec)
726 {
727 #if ENABLE(INSPECTOR)
728     Document* document = contextDocument();
729     if (!document || !document->page()) {
730         ec = INVALID_ACCESS_ERR;
731         return String();
732     }
733     RefPtr<InspectorObject> object = document->page()->inspectorController().buildObjectForHighlightedNode();
734     return object ? object->toJSONString() : String();
735 #else
736     UNUSED_PARAM(ec);
737     return String();
738 #endif
739 }
740
741 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
742 {
743     if (!node) {
744         ec = INVALID_ACCESS_ERR;
745         return 0;
746     }
747
748     DocumentMarker::MarkerTypes markerTypes = 0;
749     if (!markerTypesFrom(markerType, markerTypes)) {
750         ec = SYNTAX_ERR;
751         return 0;
752     }
753
754     node->document().frame()->editor().updateEditorUINowIfScheduled();
755
756     return node->document().markers().markersFor(node, markerTypes).size();
757 }
758
759 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
760 {
761     node->document().updateLayoutIgnorePendingStylesheets();
762     if (!node) {
763         ec = INVALID_ACCESS_ERR;
764         return 0;
765     }
766
767     DocumentMarker::MarkerTypes markerTypes = 0;
768     if (!markerTypesFrom(markerType, markerTypes)) {
769         ec = SYNTAX_ERR;
770         return 0;
771     }
772
773     node->document().frame()->editor().updateEditorUINowIfScheduled();
774
775     Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
776     if (markers.size() <= index)
777         return 0;
778     return markers[index];
779 }
780
781 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
782 {
783     DocumentMarker* marker = markerAt(node, markerType, index, ec);
784     if (!marker)
785         return 0;
786     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
787 }
788
789 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
790 {
791     DocumentMarker* marker = markerAt(node, markerType, index, ec);
792     if (!marker)
793         return String();
794     return marker->description();
795 }
796
797 void Internals::addTextMatchMarker(const Range* range, bool isActive)
798 {
799     range->ownerDocument().updateLayoutIgnorePendingStylesheets();
800     range->ownerDocument().markers().addTextMatchMarker(range, isActive);
801 }
802
803 void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
804 {
805     Document* document = contextDocument();
806     if (!document || !document->view()) {
807         ec = INVALID_ACCESS_ERR;
808         return;
809     }
810
811     FrameView* frameView = document->view();
812     bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
813     bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
814
815     frameView->setConstrainsScrollingToContentEdge(false);
816     frameView->setScrollbarsSuppressed(false);
817     frameView->setScrollOffsetFromInternals(IntPoint(x, y));
818     frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
819     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
820 }
821
822 void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
823 {
824     Document* document = contextDocument();
825     if (!document || !document->page()) {
826         ec = INVALID_ACCESS_ERR;
827         return;
828     }
829     Page* page = document->page();
830
831     Pagination pagination;
832     if (mode == "Unpaginated")
833         pagination.mode = Pagination::Unpaginated;
834     else if (mode == "LeftToRightPaginated")
835         pagination.mode = Pagination::LeftToRightPaginated;
836     else if (mode == "RightToLeftPaginated")
837         pagination.mode = Pagination::RightToLeftPaginated;
838     else if (mode == "TopToBottomPaginated")
839         pagination.mode = Pagination::TopToBottomPaginated;
840     else if (mode == "BottomToTopPaginated")
841         pagination.mode = Pagination::BottomToTopPaginated;
842     else {
843         ec = SYNTAX_ERR;
844         return;
845     }
846
847     pagination.gap = gap;
848     pagination.pageLength = pageLength;
849     page->setPagination(pagination);
850 }
851
852 String Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
853 {
854     Document* document = contextDocument();
855     if (!document || !document->page()) {
856         ec = INVALID_ACCESS_ERR;
857         return String();
858     }
859     Page* page = document->page();
860
861     const int defaultLayoutWidthForNonMobilePages = 980;
862
863     ViewportArguments arguments = page->viewportArguments();
864     ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
865     restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
866     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
867
868     return "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false");
869 }
870
871 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
872 {
873     if (!textField) {
874         ec = INVALID_ACCESS_ERR;
875         return false;
876     }
877
878     if (HTMLInputElement* inputElement = textField->toInputElement())
879         return inputElement->lastChangeWasUserEdit();
880
881     // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
882     if (textField->tagName() == "TEXTAREA")
883         return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
884
885     ec = INVALID_NODE_TYPE_ERR;
886     return false;
887 }
888
889 bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
890 {
891     if (!element) {
892         ec = INVALID_ACCESS_ERR;
893         return false;
894     }
895
896     if (HTMLInputElement* inputElement = element->toInputElement())
897         return inputElement->shouldAutocomplete();
898
899     ec = INVALID_NODE_TYPE_ERR;
900     return false;
901 }
902
903 String Internals::suggestedValue(Element* element, ExceptionCode& ec)
904 {
905     if (!element) {
906         ec = INVALID_ACCESS_ERR;
907         return String();
908     }
909
910     HTMLInputElement* inputElement = element->toInputElement();
911     if (!inputElement) {
912         ec = INVALID_NODE_TYPE_ERR;
913         return String();
914     }
915
916     return inputElement->suggestedValue();
917 }
918
919 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
920 {
921     if (!element) {
922         ec = INVALID_ACCESS_ERR;
923         return;
924     }
925
926     HTMLInputElement* inputElement = element->toInputElement();
927     if (!inputElement) {
928         ec = INVALID_NODE_TYPE_ERR;
929         return;
930     }
931
932     inputElement->setSuggestedValue(value);
933 }
934
935 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
936 {
937     if (!element) {
938         ec = INVALID_ACCESS_ERR;
939         return;
940     }
941
942     HTMLInputElement* inputElement = element->toInputElement();
943     if (!inputElement) {
944         ec = INVALID_NODE_TYPE_ERR;
945         return;
946     }
947
948     inputElement->setEditingValue(value);
949 }
950
951 void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
952 {
953     HTMLInputElement* inputElement = element->toInputElement();
954     if (!inputElement) {
955         ec = INVALID_ACCESS_ERR;
956         return;
957     }
958     inputElement->setAutofilled(enabled);
959 }
960
961 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
962 {
963     if (!element || !element->document().view()) {
964         ec = INVALID_ACCESS_ERR;
965         return;
966     }
967     FrameView* frameView = element->document().view();
968     frameView->scrollElementToRect(element, IntRect(x, y, w, h));
969 }
970
971 void Internals::paintControlTints(ExceptionCode& ec)
972 {
973     Document* document = contextDocument();
974     if (!document || !document->view()) {
975         ec = INVALID_ACCESS_ERR;
976         return;
977     }
978
979     FrameView* frameView = document->view();
980     frameView->paintControlTints();
981 }
982
983 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
984 {
985     if (!scope) {
986         ec = INVALID_ACCESS_ERR;
987         return 0;
988     }
989
990     return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
991 }
992
993 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
994 {
995     if (!scope || !range) {
996         ec = INVALID_ACCESS_ERR;
997         return 0;
998     }
999
1000     size_t location = 0;
1001     size_t unusedLength = 0;
1002     TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
1003     return location;
1004 }
1005
1006 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1007 {
1008     if (!scope || !range) {
1009         ec = INVALID_ACCESS_ERR;
1010         return 0;
1011     }
1012
1013     size_t unusedLocation = 0;
1014     size_t length = 0;
1015     TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
1016     return length;
1017 }
1018
1019 String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
1020 {
1021     if (!range) {
1022         ec = INVALID_ACCESS_ERR;
1023         return String();
1024     }
1025
1026     return range->text();
1027 }
1028
1029 void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
1030 {
1031     Document* document = contextDocument();
1032     // Delegate scrolling is valid only on mainframe's view.
1033     if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame()) {
1034         ec = INVALID_ACCESS_ERR;
1035         return;
1036     }
1037
1038     document->view()->setDelegatesScrolling(enabled);
1039 }
1040
1041 int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
1042 {
1043     Document* document = contextDocument();
1044     if (!document || !document->frame()) {
1045         ec = INVALID_ACCESS_ERR;
1046         return -1;
1047     }
1048
1049     return document->frame()->editor().spellChecker().lastRequestSequence();
1050 }
1051
1052 int Internals::lastSpellCheckProcessedSequence(ExceptionCode& ec)
1053 {
1054     Document* document = contextDocument();
1055     if (!document || !document->frame()) {
1056         ec = INVALID_ACCESS_ERR;
1057         return -1;
1058     }
1059
1060     return document->frame()->editor().spellChecker().lastProcessedSequence();
1061 }
1062
1063 Vector<String> Internals::userPreferredLanguages() const
1064 {
1065     return WebCore::userPreferredLanguages();
1066 }
1067
1068 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
1069 {
1070     WebCore::overrideUserPreferredLanguages(languages);
1071 }
1072
1073 unsigned Internals::wheelEventHandlerCount(ExceptionCode& ec)
1074 {
1075     Document* document = contextDocument();
1076     if (!document) {
1077         ec = INVALID_ACCESS_ERR;
1078         return 0;
1079     }
1080
1081     return document->wheelEventHandlerCount();
1082 }
1083
1084 unsigned Internals::touchEventHandlerCount(ExceptionCode& ec)
1085 {
1086     Document* document = contextDocument();
1087     if (!document) {
1088         ec = INVALID_ACCESS_ERR;
1089         return 0;
1090     }
1091
1092     const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
1093     if (!touchHandlers)
1094         return 0;
1095
1096     unsigned count = 0;
1097     for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
1098         count += iter->value;
1099     return count;
1100 }
1101
1102 // FIXME: Remove the document argument. It is almost always the same as
1103 // contextDocument(), with the exception of a few tests that pass a
1104 // different document, and could just make the call through another Internals
1105 // instance instead.
1106 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
1107     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
1108 {
1109     if (!document || !document->frame() || !document->frame()->view()) {
1110         ec = INVALID_ACCESS_ERR;
1111         return 0;
1112     }
1113
1114     Frame* frame = document->frame();
1115     FrameView* frameView = document->view();
1116     RenderView* renderView = document->renderView();
1117     if (!renderView)
1118         return 0;
1119
1120     document->updateLayoutIgnorePendingStylesheets();
1121
1122     float zoomFactor = frame->pageZoomFactor();
1123     LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
1124
1125     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
1126     if (ignoreClipping)
1127         hitType |= HitTestRequest::IgnoreClipping;
1128     if (!allowShadowContent)
1129         hitType |= HitTestRequest::DisallowShadowContent;
1130     if (allowChildFrameContent)
1131         hitType |= HitTestRequest::AllowChildFrameContent;
1132
1133     HitTestRequest request(hitType);
1134
1135     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1136     if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1137         return 0;
1138
1139     Vector<Ref<Node>> matches;
1140
1141     // Need padding to trigger a rect based hit test, but we want to return a NodeList
1142     // so we special case this.
1143     if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1144         HitTestResult result(point);
1145         renderView->hitTest(request, result);
1146         if (result.innerNode())
1147             matches.append(*result.innerNode()->deprecatedShadowAncestorNode());
1148     } else {
1149         HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
1150         renderView->hitTest(request, result);
1151         
1152         const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
1153         matches.reserveInitialCapacity(nodeSet.size());
1154         for (auto it = nodeSet.begin(), end = nodeSet.end(); it != end; ++it)
1155             matches.uncheckedAppend(*it->get());
1156     }
1157
1158     return StaticNodeList::adopt(matches);
1159 }
1160
1161 void Internals::emitInspectorDidBeginFrame()
1162 {
1163 #if ENABLE(INSPECTOR)
1164     contextDocument()->frame()->page()->inspectorController().didBeginFrame();
1165 #endif
1166 }
1167
1168 void Internals::emitInspectorDidCancelFrame()
1169 {
1170 #if ENABLE(INSPECTOR)
1171     contextDocument()->frame()->page()->inspectorController().didCancelFrame();
1172 #endif
1173 }
1174
1175 class GetCallerCodeBlockFunctor {
1176 public:
1177     GetCallerCodeBlockFunctor()
1178         : m_iterations(0)
1179         , m_codeBlock(0)
1180     {
1181     }
1182
1183     StackVisitor::Status operator()(StackVisitor& visitor)
1184     {
1185         ++m_iterations;
1186         if (m_iterations < 2)
1187             return StackVisitor::Continue;
1188
1189         m_codeBlock = visitor->codeBlock();
1190         return StackVisitor::Done;
1191     }
1192
1193     CodeBlock* codeBlock() const { return m_codeBlock; }
1194
1195 private:
1196     int m_iterations;
1197     CodeBlock* m_codeBlock;
1198 };
1199
1200 String Internals::parserMetaData(Deprecated::ScriptValue value)
1201 {
1202     JSC::VM& vm = contextDocument()->vm();
1203     JSC::ExecState* exec = vm.topCallFrame;
1204     JSC::JSValue code = value.jsValue();
1205     ScriptExecutable* executable;
1206
1207     if (!code || code.isNull() || code.isUndefined()) {
1208         GetCallerCodeBlockFunctor iter;
1209         exec->iterate(iter);
1210         CodeBlock* codeBlock = iter.codeBlock();
1211         executable = codeBlock->ownerExecutable(); 
1212     } else if (code.isFunction()) {
1213         JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
1214         executable = funcObj->jsExecutable();
1215     } else
1216         return String();
1217
1218     unsigned startLine = executable->lineNo();
1219     unsigned startColumn = executable->startColumn();
1220     unsigned endLine = executable->lastLine();
1221     unsigned endColumn = executable->endColumn();
1222
1223     StringBuilder result;
1224
1225     if (executable->isFunctionExecutable()) {
1226         FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
1227         String inferredName = funcExecutable->inferredName().string();
1228         result.append("function \"");
1229         result.append(inferredName);
1230         result.append("\"");
1231     } else if (executable->isEvalExecutable())
1232         result.append("eval");
1233     else {
1234         ASSERT(executable->isProgramExecutable());
1235         result.append("program");
1236     }
1237
1238     result.append(" { ");
1239     result.appendNumber(startLine);
1240     result.append(":");
1241     result.appendNumber(startColumn);
1242     result.append(" - ");
1243     result.appendNumber(endLine);
1244     result.append(":");
1245     result.appendNumber(endColumn);
1246     result.append(" }");
1247
1248     return result.toString();
1249 }
1250
1251 void Internals::setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
1252 {
1253     Document* document = contextDocument();
1254     if (!document || !document->page()) {
1255         ec = INVALID_ACCESS_ERR;
1256         return;
1257     }
1258
1259 #if ENABLE(BATTERY_STATUS)
1260     BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
1261 #else
1262     UNUSED_PARAM(eventType);
1263     UNUSED_PARAM(charging);
1264     UNUSED_PARAM(chargingTime);
1265     UNUSED_PARAM(dischargingTime);
1266     UNUSED_PARAM(level);
1267 #endif
1268 }
1269
1270 void Internals::setNetworkInformation(const String& eventType, double bandwidth, bool metered, ExceptionCode& ec)
1271 {
1272     Document* document = contextDocument();
1273     if (!document || !document->page()) {
1274         ec = INVALID_ACCESS_ERR;
1275         return;
1276     }
1277
1278 #if ENABLE(NETWORK_INFO)
1279     NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered));
1280 #else
1281     UNUSED_PARAM(eventType);
1282     UNUSED_PARAM(bandwidth);
1283     UNUSED_PARAM(metered);
1284 #endif
1285 }
1286
1287 void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
1288 {
1289     Document* document = contextDocument();
1290     if (!document || !document->page()) {
1291         ec = INVALID_ACCESS_ERR;
1292         return;
1293     }
1294
1295 #if ENABLE(PROXIMITY_EVENTS)
1296     DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
1297 #else
1298     UNUSED_PARAM(eventType);
1299     UNUSED_PARAM(value);
1300     UNUSED_PARAM(min);
1301     UNUSED_PARAM(max);
1302 #endif
1303 }
1304
1305 void Internals::updateEditorUINowIfScheduled()
1306 {
1307     if (Document* document = contextDocument()) {
1308         if (Frame* frame = document->frame())
1309             frame->editor().updateEditorUINowIfScheduled();
1310     }
1311 }
1312
1313 Node* Internals::findEditingDeleteButton()
1314 {
1315     Document* document = contextDocument();
1316     if (!document || !document->frame())
1317         return 0;
1318
1319     updateEditorUINowIfScheduled();
1320
1321     // FIXME: We shouldn't pollute the id namespace with this name.
1322     return document->getElementById(String(ASCIILiteral("WebKit-Editing-Delete-Button")));
1323 }
1324
1325 bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
1326 {
1327     Document* document = contextDocument();
1328     if (!document || !document->frame())
1329         return 0;
1330
1331     updateEditorUINowIfScheduled();
1332
1333     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1334 }
1335     
1336 bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
1337 {
1338     Document* document = contextDocument();
1339     if (!document || !document->frame())
1340         return 0;
1341
1342     updateEditorUINowIfScheduled();
1343
1344     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
1345 }
1346
1347 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
1348 {
1349     if (!contextDocument() || !contextDocument()->frame())
1350         return;
1351
1352     if (enabled != contextDocument()->frame()->editor().isContinuousSpellCheckingEnabled())
1353         contextDocument()->frame()->editor().toggleContinuousSpellChecking();
1354 }
1355
1356 void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&)
1357 {
1358     if (!contextDocument() || !contextDocument()->frame())
1359         return;
1360
1361 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1362     if (enabled != contextDocument()->frame()->editor().isAutomaticQuoteSubstitutionEnabled())
1363         contextDocument()->frame()->editor().toggleAutomaticQuoteSubstitution();
1364 #else
1365     UNUSED_PARAM(enabled);
1366 #endif
1367 }
1368
1369 void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
1370 {
1371     if (!contextDocument() || !contextDocument()->frame())
1372         return;
1373
1374 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1375     if (enabled != contextDocument()->frame()->editor().isAutomaticLinkDetectionEnabled())
1376         contextDocument()->frame()->editor().toggleAutomaticLinkDetection();
1377 #else
1378     UNUSED_PARAM(enabled);
1379 #endif
1380 }
1381
1382 void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&)
1383 {
1384     if (!contextDocument() || !contextDocument()->frame())
1385         return;
1386
1387 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1388     if (enabled != contextDocument()->frame()->editor().isAutomaticDashSubstitutionEnabled())
1389         contextDocument()->frame()->editor().toggleAutomaticDashSubstitution();
1390 #else
1391     UNUSED_PARAM(enabled);
1392 #endif
1393 }
1394
1395 void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
1396 {
1397     if (!contextDocument() || !contextDocument()->frame())
1398         return;
1399
1400 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1401     if (enabled != contextDocument()->frame()->editor().isAutomaticTextReplacementEnabled())
1402         contextDocument()->frame()->editor().toggleAutomaticTextReplacement();
1403 #else
1404     UNUSED_PARAM(enabled);
1405 #endif
1406 }
1407
1408 void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&)
1409 {
1410     if (!contextDocument() || !contextDocument()->frame())
1411         return;
1412
1413 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1414     if (enabled != contextDocument()->frame()->editor().isAutomaticSpellingCorrectionEnabled())
1415         contextDocument()->frame()->editor().toggleAutomaticSpellingCorrection();
1416 #else
1417     UNUSED_PARAM(enabled);
1418 #endif
1419 }
1420
1421 bool Internals::isOverwriteModeEnabled(ExceptionCode&)
1422 {
1423     Document* document = contextDocument();
1424     if (!document || !document->frame())
1425         return 0;
1426
1427     return document->frame()->editor().isOverwriteModeEnabled();
1428 }
1429
1430 void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
1431 {
1432     Document* document = contextDocument();
1433     if (!document || !document->frame())
1434         return;
1435
1436     document->frame()->editor().toggleOverwriteModeEnabled();
1437 }
1438
1439 unsigned Internals::countMatchesForText(const String& text, unsigned findOptions, const String& markMatches, ExceptionCode&)
1440 {
1441     Document* document = contextDocument();
1442     if (!document || !document->frame())
1443         return 0;
1444
1445     bool mark = markMatches == "mark";
1446     return document->frame()->editor().countMatchesForText(text, nullptr, findOptions, std::numeric_limits<unsigned>::max(), mark, nullptr);
1447 }
1448
1449 const ProfilesArray& Internals::consoleProfiles() const
1450 {
1451     return contextDocument()->page()->console().profiles();
1452 }
1453
1454 unsigned Internals::numberOfLiveNodes() const
1455 {
1456     unsigned nodeCount = 0;
1457     for (auto* document : Document::allDocuments())
1458         nodeCount += document->referencingNodeCount();
1459     return nodeCount;
1460 }
1461
1462 unsigned Internals::numberOfLiveDocuments() const
1463 {
1464     return Document::allDocuments().size();
1465 }
1466
1467 #if ENABLE(INSPECTOR)
1468 Vector<String> Internals::consoleMessageArgumentCounts() const
1469 {
1470     Document* document = contextDocument();
1471     if (!document || !document->page())
1472         return Vector<String>();
1473
1474     InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
1475     if (!instrumentingAgents)
1476         return Vector<String>();
1477
1478     InspectorConsoleAgent* consoleAgent = instrumentingAgents->webConsoleAgent();
1479     if (!consoleAgent)
1480         return Vector<String>();
1481
1482     Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
1483     Vector<String> result(counts.size());
1484     for (size_t i = 0; i < counts.size(); i++)
1485         result[i] = String::number(counts[i]);
1486     return result;
1487 }
1488
1489 PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
1490 {
1491     Page* page = contextDocument()->frame()->page();
1492     ASSERT(page);
1493
1494     DOMWindow* window = page->mainFrame().document()->domWindow();
1495     ASSERT(window);
1496
1497     m_frontendWindow = window->open(url, "", "", *window, *window);
1498     ASSERT(m_frontendWindow);
1499
1500     Page* frontendPage = m_frontendWindow->document()->page();
1501     ASSERT(frontendPage);
1502
1503     auto frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
1504
1505     frontendPage->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
1506
1507     m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
1508
1509     page->inspectorController().connectFrontend(m_frontendChannel.get());
1510
1511     return m_frontendWindow;
1512 }
1513
1514 void Internals::closeDummyInspectorFrontend()
1515 {
1516     Page* page = contextDocument()->frame()->page();
1517     ASSERT(page);
1518     ASSERT(m_frontendWindow);
1519
1520     page->inspectorController().disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
1521
1522     m_frontendChannel.release();
1523
1524     m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
1525     m_frontendWindow.release();
1526 }
1527
1528 void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec)
1529 {
1530     Page* page = contextDocument()->frame()->page();
1531     if (!page) {
1532         ec = INVALID_ACCESS_ERR;
1533         return;
1534     }
1535     page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
1536 }
1537
1538 void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
1539 {
1540     Page* page = contextDocument()->frame()->page();
1541     if (!page) {
1542         ec = INVALID_ACCESS_ERR;
1543         return;
1544     }
1545
1546     page->inspectorController().setProfilerEnabled(enabled);
1547 }
1548
1549 void Internals::setInspectorIsUnderTest(bool isUnderTest, ExceptionCode& ec)
1550 {
1551     Page* page = contextDocument()->frame()->page();
1552     if (!page) {
1553         ec = INVALID_ACCESS_ERR;
1554         return;
1555     }
1556
1557     page->inspectorController().setIsUnderTest(isUnderTest);
1558 }
1559 #endif // ENABLE(INSPECTOR)
1560
1561 bool Internals::hasGrammarMarker(int from, int length, ExceptionCode&)
1562 {
1563     Document* document = contextDocument();
1564     if (!document || !document->frame())
1565         return 0;
1566
1567     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1568 }
1569
1570 unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
1571 {
1572     Document* document = contextDocument();
1573     if (!document || !document->frame())
1574         return 0;
1575
1576     unsigned count = 0;
1577     Frame* frame = document->frame();
1578     if (frame->view()->scrollableAreas())
1579         count += frame->view()->scrollableAreas()->size();
1580
1581     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1582         if (child->view() && child->view()->scrollableAreas())
1583             count += child->view()->scrollableAreas()->size();
1584     }
1585
1586     return count;
1587 }
1588     
1589 bool Internals::isPageBoxVisible(int pageNumber, ExceptionCode& ec)
1590 {
1591     Document* document = contextDocument();
1592     if (!document) {
1593         ec = INVALID_ACCESS_ERR;
1594         return false;
1595     }
1596
1597     return document->isPageBoxVisible(pageNumber);
1598 }
1599
1600 // FIXME: Remove the document argument. It is almost always the same as
1601 // contextDocument(), with the exception of a few tests that pass a
1602 // different document, and could just make the call through another Internals
1603 // instance instead.
1604 String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
1605 {
1606     return layerTreeAsText(document, 0, ec);
1607 }
1608
1609 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
1610 {
1611     if (!document || !document->frame()) {
1612         ec = INVALID_ACCESS_ERR;
1613         return String();
1614     }
1615
1616     LayerTreeFlags layerTreeFlags = 0;
1617     if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
1618         layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
1619     if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
1620         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
1621     if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
1622         layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
1623     if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
1624         layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
1625     if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
1626         layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
1627
1628     return document->frame()->layerTreeAsText(layerTreeFlags);
1629 }
1630
1631 String Internals::repaintRectsAsText(ExceptionCode& ec) const
1632 {
1633     Document* document = contextDocument();
1634     if (!document || !document->frame()) {
1635         ec = INVALID_ACCESS_ERR;
1636         return String();
1637     }
1638
1639     return document->frame()->trackedRepaintRectsAsText();
1640 }
1641
1642 String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
1643 {
1644     Document* document = contextDocument();
1645     if (!document || !document->frame()) {
1646         ec = INVALID_ACCESS_ERR;
1647         return String();
1648     }
1649
1650     Page* page = document->page();
1651     if (!page)
1652         return String();
1653
1654     return page->scrollingStateTreeAsText();
1655 }
1656
1657 String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
1658 {
1659     Document* document = contextDocument();
1660     if (!document || !document->frame()) {
1661         ec = INVALID_ACCESS_ERR;
1662         return String();
1663     }
1664
1665     Page* page = document->page();
1666     if (!page)
1667         return String();
1668
1669     return page->synchronousScrollingReasonsAsText();
1670 }
1671
1672 PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(ExceptionCode& ec) const
1673 {
1674     Document* document = contextDocument();
1675     if (!document || !document->frame()) {
1676         ec = INVALID_ACCESS_ERR;
1677         return 0;
1678     }
1679
1680     Page* page = document->page();
1681     if (!page)
1682         return 0;
1683
1684     return page->nonFastScrollableRects(document->frame());
1685 }
1686
1687 void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
1688 {
1689     Document* document = contextDocument();
1690     if (!document) {
1691         ec = INVALID_ACCESS_ERR;
1692         return;
1693     }
1694
1695     CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
1696     if (!cachedResourceLoader)
1697         return;
1698     cachedResourceLoader->garbageCollectDocumentResources();
1699 }
1700
1701 void Internals::allowRoundingHacks() const
1702 {
1703     TextRun::setAllowsRoundingHacks(true);
1704 }
1705
1706 void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
1707 {
1708     Document* document = contextDocument();
1709     if (!document) {
1710         ec = INVALID_ACCESS_ERR;
1711         return;
1712     }
1713
1714     auto parsedSheet = StyleSheetContents::create(*document);
1715     parsedSheet.get().setIsUserStyleSheet(false);
1716     parsedSheet.get().parseString(css);
1717     document->styleSheetCollection().addAuthorSheet(std::move(parsedSheet));
1718 }
1719
1720 void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
1721 {
1722     Document* document = contextDocument();
1723     if (!document) {
1724         ec = INVALID_ACCESS_ERR;
1725         return;
1726     }
1727
1728     auto parsedSheet = StyleSheetContents::create(*document);
1729     parsedSheet.get().setIsUserStyleSheet(true);
1730     parsedSheet.get().parseString(css);
1731     document->styleSheetCollection().addUserSheet(std::move(parsedSheet));
1732 }
1733
1734 String Internals::counterValue(Element* element)
1735 {
1736     if (!element)
1737         return String();
1738
1739     return counterValueForElement(element);
1740 }
1741
1742 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
1743 {
1744     if (!element)
1745         return 0;
1746
1747     return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
1748 }
1749
1750 Vector<String> Internals::iconURLs(Document* document, int iconTypesMask) const
1751 {
1752     Vector<IconURL> iconURLs = document->iconURLs(iconTypesMask);
1753     Vector<String> array;
1754
1755     Vector<IconURL>::const_iterator iter(iconURLs.begin());
1756     for (; iter != iconURLs.end(); ++iter)
1757         array.append(iter->m_iconURL.string());
1758
1759     return array;
1760 }
1761
1762 Vector<String> Internals::shortcutIconURLs() const
1763 {
1764     return iconURLs(contextDocument(), Favicon);
1765 }
1766
1767 Vector<String> Internals::allIconURLs() const
1768 {
1769     return iconURLs(contextDocument(), Favicon | TouchIcon | TouchPrecomposedIcon);
1770 }
1771
1772 int Internals::numberOfPages(float pageWidth, float pageHeight)
1773 {
1774     if (!frame())
1775         return -1;
1776
1777     return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
1778 }
1779
1780 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
1781 {
1782     if (!frame()) {
1783         ec = INVALID_ACCESS_ERR;
1784         return String();
1785     }
1786
1787     return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
1788 }
1789
1790 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
1791 {
1792     if (!frame()) {
1793         ec = INVALID_ACCESS_ERR;
1794         return String();
1795     }
1796
1797     return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
1798 }
1799
1800 void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec)
1801 {
1802     Document* document = contextDocument();
1803     if (!document || !document->page()) {
1804         ec = INVALID_ACCESS_ERR;
1805         return;
1806     }
1807     Page* page = document->page();
1808     page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
1809 }
1810
1811 void Internals::setHeaderHeight(float height)
1812 {
1813     Document* document = contextDocument();
1814     if (!document || !document->view())
1815         return;
1816
1817     FrameView* frameView = document->view();
1818     frameView->setHeaderHeight(height);
1819 }
1820
1821 void Internals::setFooterHeight(float height)
1822 {
1823     Document* document = contextDocument();
1824     if (!document || !document->view())
1825         return;
1826
1827     FrameView* frameView = document->view();
1828     frameView->setFooterHeight(height);
1829 }
1830
1831 #if ENABLE(FULLSCREEN_API)
1832 void Internals::webkitWillEnterFullScreenForElement(Element* element)
1833 {
1834     Document* document = contextDocument();
1835     if (!document)
1836         return;
1837     document->webkitWillEnterFullScreenForElement(element);
1838 }
1839
1840 void Internals::webkitDidEnterFullScreenForElement(Element* element)
1841 {
1842     Document* document = contextDocument();
1843     if (!document)
1844         return;
1845     document->webkitDidEnterFullScreenForElement(element);
1846 }
1847
1848 void Internals::webkitWillExitFullScreenForElement(Element* element)
1849 {
1850     Document* document = contextDocument();
1851     if (!document)
1852         return;
1853     document->webkitWillExitFullScreenForElement(element);
1854 }
1855
1856 void Internals::webkitDidExitFullScreenForElement(Element* element)
1857 {
1858     Document* document = contextDocument();
1859     if (!document)
1860         return;
1861     document->webkitDidExitFullScreenForElement(element);
1862 }
1863 #endif
1864
1865 void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
1866 {
1867     Document* document = contextDocument();
1868     if (!document)
1869         return;
1870     cacheStorage().storeUpdatedQuotaForOrigin(document->securityOrigin(), quota);
1871 }
1872
1873 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
1874 {
1875     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1876 }
1877
1878 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
1879 {
1880     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
1881 }
1882
1883 PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
1884 {
1885     return MallocStatistics::create();
1886 }
1887
1888 PassRefPtr<TypeConversions> Internals::typeConversions() const
1889 {
1890     return TypeConversions::create();
1891 }
1892
1893 PassRefPtr<MemoryInfo> Internals::memoryInfo() const
1894 {
1895     return MemoryInfo::create();
1896 }
1897
1898 Vector<String> Internals::getReferencedFilePaths() const
1899 {
1900     frame()->loader().history().saveDocumentAndScrollState();
1901     return FormController::getReferencedFilePaths(frame()->loader().history().currentItem()->documentState());
1902 }
1903
1904 void Internals::startTrackingRepaints(ExceptionCode& ec)
1905 {
1906     Document* document = contextDocument();
1907     if (!document || !document->view()) {
1908         ec = INVALID_ACCESS_ERR;
1909         return;
1910     }
1911
1912     FrameView* frameView = document->view();
1913     frameView->setTracksRepaints(true);
1914 }
1915
1916 void Internals::stopTrackingRepaints(ExceptionCode& ec)
1917 {
1918     Document* document = contextDocument();
1919     if (!document || !document->view()) {
1920         ec = INVALID_ACCESS_ERR;
1921         return;
1922     }
1923
1924     FrameView* frameView = document->view();
1925     frameView->setTracksRepaints(false);
1926 }
1927
1928 #if !PLATFORM(IOS)
1929 static const char* cursorTypeToString(Cursor::Type cursorType)
1930 {
1931     switch (cursorType) {
1932     case Cursor::Pointer: return "Pointer";
1933     case Cursor::Cross: return "Cross";
1934     case Cursor::Hand: return "Hand";
1935     case Cursor::IBeam: return "IBeam";
1936     case Cursor::Wait: return "Wait";
1937     case Cursor::Help: return "Help";
1938     case Cursor::EastResize: return "EastResize";
1939     case Cursor::NorthResize: return "NorthResize";
1940     case Cursor::NorthEastResize: return "NorthEastResize";
1941     case Cursor::NorthWestResize: return "NorthWestResize";
1942     case Cursor::SouthResize: return "SouthResize";
1943     case Cursor::SouthEastResize: return "SouthEastResize";
1944     case Cursor::SouthWestResize: return "SouthWestResize";
1945     case Cursor::WestResize: return "WestResize";
1946     case Cursor::NorthSouthResize: return "NorthSouthResize";
1947     case Cursor::EastWestResize: return "EastWestResize";
1948     case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
1949     case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
1950     case Cursor::ColumnResize: return "ColumnResize";
1951     case Cursor::RowResize: return "RowResize";
1952     case Cursor::MiddlePanning: return "MiddlePanning";
1953     case Cursor::EastPanning: return "EastPanning";
1954     case Cursor::NorthPanning: return "NorthPanning";
1955     case Cursor::NorthEastPanning: return "NorthEastPanning";
1956     case Cursor::NorthWestPanning: return "NorthWestPanning";
1957     case Cursor::SouthPanning: return "SouthPanning";
1958     case Cursor::SouthEastPanning: return "SouthEastPanning";
1959     case Cursor::SouthWestPanning: return "SouthWestPanning";
1960     case Cursor::WestPanning: return "WestPanning";
1961     case Cursor::Move: return "Move";
1962     case Cursor::VerticalText: return "VerticalText";
1963     case Cursor::Cell: return "Cell";
1964     case Cursor::ContextMenu: return "ContextMenu";
1965     case Cursor::Alias: return "Alias";
1966     case Cursor::Progress: return "Progress";
1967     case Cursor::NoDrop: return "NoDrop";
1968     case Cursor::Copy: return "Copy";
1969     case Cursor::None: return "None";
1970     case Cursor::NotAllowed: return "NotAllowed";
1971     case Cursor::ZoomIn: return "ZoomIn";
1972     case Cursor::ZoomOut: return "ZoomOut";
1973     case Cursor::Grab: return "Grab";
1974     case Cursor::Grabbing: return "Grabbing";
1975     case Cursor::Custom: return "Custom";
1976     }
1977
1978     ASSERT_NOT_REACHED();
1979     return "UNKNOWN";
1980 }
1981 #endif
1982
1983 String Internals::getCurrentCursorInfo(ExceptionCode& ec)
1984 {
1985     Document* document = contextDocument();
1986     if (!document || !document->frame()) {
1987         ec = INVALID_ACCESS_ERR;
1988         return String();
1989     }
1990
1991 #if !PLATFORM(IOS)
1992     Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
1993
1994     StringBuilder result;
1995     result.append("type=");
1996     result.append(cursorTypeToString(cursor.type()));
1997     result.append(" hotSpot=");
1998     result.appendNumber(cursor.hotSpot().x());
1999     result.append(",");
2000     result.appendNumber(cursor.hotSpot().y());
2001     if (cursor.image()) {
2002         IntSize size = cursor.image()->size();
2003         result.append(" image=");
2004         result.appendNumber(size.width());
2005         result.append("x");
2006         result.appendNumber(size.height());
2007     }
2008 #if ENABLE(MOUSE_CURSOR_SCALE)
2009     if (cursor.imageScaleFactor() != 1) {
2010         result.append(" scale=");
2011         NumberToStringBuffer buffer;
2012         result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
2013     }
2014 #endif
2015     return result.toString();
2016 #else
2017     return "FAIL: Cursor details not available on this platform.";
2018 #endif
2019 }
2020
2021 PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
2022 {
2023     Vector<uint8_t> bytes = value->data();
2024     return ArrayBuffer::create(bytes.data(), bytes.size());
2025 }
2026
2027 PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
2028 {
2029     Vector<uint8_t> bytes;
2030     bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
2031     return SerializedScriptValue::adopt(bytes);
2032 }
2033
2034 void Internals::setUsesOverlayScrollbars(bool enabled)
2035 {
2036     WebCore::Settings::setUsesOverlayScrollbars(enabled);
2037 }
2038
2039 void Internals::forceReload(bool endToEnd)
2040 {
2041     frame()->loader().reload(endToEnd);
2042 }
2043
2044 #if ENABLE(ENCRYPTED_MEDIA_V2)
2045 void Internals::initializeMockCDM()
2046 {
2047     CDM::registerCDMFactory(MockCDM::create, MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
2048 }
2049 #endif
2050
2051 String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
2052 {
2053     if (!element) {
2054         ec = INVALID_ACCESS_ERR;
2055         return String();
2056     }
2057     return WebCore::markerTextForListItem(element);
2058 }
2059
2060 String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
2061 {
2062     if (!element) {
2063         ec = INVALID_ACCESS_ERR;
2064         return String();
2065     }
2066     return element->imageSourceURL();
2067 }
2068
2069 #if ENABLE(VIDEO)
2070 void Internals::simulateAudioInterruption(Node* node)
2071 {
2072 #if USE(GSTREAMER)
2073     HTMLMediaElement* element = toHTMLMediaElement(node);
2074     element->player()->simulateAudioInterruption();
2075 #else
2076     UNUSED_PARAM(node);
2077 #endif
2078 }
2079 #endif
2080
2081 bool Internals::isSelectPopupVisible(Node* node)
2082 {
2083     if (!isHTMLSelectElement(node))
2084         return false;
2085
2086     HTMLSelectElement* select = toHTMLSelectElement(node);
2087
2088     auto renderer = select->renderer();
2089     if (!renderer->isMenuList())
2090         return false;
2091
2092 #if !PLATFORM(IOS)
2093     RenderMenuList* menuList = toRenderMenuList(renderer);
2094     return menuList->popupIsVisible();
2095 #else
2096     return false;
2097 #endif // !PLATFORM(IOS)
2098 }
2099
2100 String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
2101 {
2102     Document* document = contextDocument();
2103     if (!document || !document->page()) {
2104         ec = INVALID_ACCESS_ERR;
2105         return emptyString();
2106     }
2107
2108 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2109     return document->page()->group().captionPreferences()->captionsStyleSheetOverride();
2110 #else
2111     return emptyString();
2112 #endif
2113 }
2114
2115 void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionCode& ec)
2116 {
2117     Document* document = contextDocument();
2118     if (!document || !document->page()) {
2119         ec = INVALID_ACCESS_ERR;
2120         return;
2121     }
2122
2123 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2124     document->page()->group().captionPreferences()->setCaptionsStyleSheetOverride(override);
2125 #else
2126     UNUSED_PARAM(override);
2127 #endif
2128 }
2129
2130 void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, ExceptionCode& ec)
2131 {
2132     Document* document = contextDocument();
2133     if (!document || !document->page()) {
2134         ec = INVALID_ACCESS_ERR;
2135         return;
2136     }
2137
2138 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2139     document->page()->group().captionPreferences()->setPrimaryAudioTrackLanguageOverride(language);
2140 #else
2141     UNUSED_PARAM(language);
2142 #endif
2143 }
2144
2145 void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
2146 {
2147     Document* document = contextDocument();
2148     if (!document || !document->page()) {
2149         ec = INVALID_ACCESS_ERR;
2150         return;
2151     }
2152     
2153 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2154     CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
2155     
2156     if (equalIgnoringCase(mode, "Automatic"))
2157         captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::Automatic);
2158     else if (equalIgnoringCase(mode, "ForcedOnly"))
2159         captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
2160     else if (equalIgnoringCase(mode, "AlwaysOn"))
2161         captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
2162     else
2163         ec = SYNTAX_ERR;
2164 #else
2165     UNUSED_PARAM(mode);
2166 #endif
2167 }
2168
2169 #if ENABLE(VIDEO)
2170 PassRefPtr<TimeRanges> Internals::createTimeRanges(Float32Array* startTimes, Float32Array* endTimes)
2171 {
2172     ASSERT(startTimes && endTimes);
2173     ASSERT(startTimes->length() == endTimes->length());
2174     RefPtr<TimeRanges> ranges = TimeRanges::create();
2175
2176     unsigned count = std::min(startTimes->length(), endTimes->length());
2177     for (unsigned i = 0; i < count; ++i)
2178         ranges->add(startTimes->item(i), endTimes->item(i));
2179     return ranges;
2180 }
2181
2182 double Internals::closestTimeToTimeRanges(double time, TimeRanges* ranges)
2183 {
2184     return ranges->nearest(time);
2185 }
2186 #endif
2187
2188 PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
2189 {
2190     Document* document = contextDocument();
2191     if (!document || !document->frame()) {
2192         ec = INVALID_ACCESS_ERR;
2193         return ClientRect::create();
2194     }
2195
2196     return ClientRect::create(document->frame()->selection().selectionBounds());
2197 }
2198
2199 #if ENABLE(VIBRATION)
2200 bool Internals::isVibrating()
2201 {
2202     Page* page = contextDocument()->page();
2203     ASSERT(page);
2204
2205     return Vibration::from(page)->isVibrating();
2206 }
2207 #endif
2208
2209 bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, ExceptionCode& ec)
2210 {
2211     if (!element) {
2212         ec = INVALID_ACCESS_ERR;
2213         return false;
2214     }
2215
2216     auto renderer = element->renderer();
2217     if (!renderer || !renderer->isEmbeddedObject()) {
2218         ec = INVALID_ACCESS_ERR;
2219         return false;
2220     }
2221
2222     RenderEmbeddedObject* embed = toRenderEmbeddedObject(renderer);
2223     return embed->isReplacementObscured();
2224 }
2225
2226 #if ENABLE(MEDIA_SOURCE)
2227 void Internals::initializeMockMediaSource()
2228 {
2229 #if USE(AVFOUNDATION)
2230     WebCore::Settings::setAVFoundationEnabled(false);
2231 #endif
2232     MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
2233 }
2234 #endif
2235
2236 void Internals::beginMediaSessionInterruption()
2237 {
2238     MediaSessionManager::sharedManager().beginInterruption();
2239 }
2240
2241 void Internals::endMediaSessionInterruption(const String& flagsString)
2242 {
2243     MediaSession::EndInterruptionFlags flags = MediaSession::NoFlags;
2244
2245     if (equalIgnoringCase(flagsString, "MayResumePlaying"))
2246         flags = MediaSession::MayResumePlaying;
2247     
2248     MediaSessionManager::sharedManager().endInterruption(flags);
2249 }
2250
2251 void Internals::applicationWillEnterForeground() const
2252 {
2253     MediaSessionManager::sharedManager().applicationWillEnterForeground();
2254 }
2255
2256 void Internals::applicationWillEnterBackground() const
2257 {
2258     MediaSessionManager::sharedManager().applicationWillEnterBackground();
2259 }
2260
2261 void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
2262 {
2263     MediaSession::MediaType mediaType = MediaSession::None;
2264     if (equalIgnoringCase(mediaTypeString, "Video"))
2265         mediaType = MediaSession::Video;
2266     else if (equalIgnoringCase(mediaTypeString, "Audio"))
2267         mediaType = MediaSession::Audio;
2268     else if (equalIgnoringCase(mediaTypeString, "WebAudio"))
2269         mediaType = MediaSession::WebAudio;
2270     else {
2271         ec = INVALID_ACCESS_ERR;
2272         return;
2273     }
2274
2275     MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType);
2276     MediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
2277
2278     restrictions = MediaSessionManager::NoRestrictions;
2279     
2280     if (equalIgnoringCase(restrictionsString, "ConcurrentPlaybackNotPermitted"))
2281         restrictions = MediaSessionManager::ConcurrentPlaybackNotPermitted;
2282     if (equalIgnoringCase(restrictionsString, "InlineVideoPlaybackRestricted"))
2283         restrictions += MediaSessionManager::InlineVideoPlaybackRestricted;
2284     if (equalIgnoringCase(restrictionsString, "MetadataPreloadingNotPermitted"))
2285         restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
2286     if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
2287         restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
2288     if (equalIgnoringCase(restrictionsString, "BackgroundPlaybackNotPermitted"))
2289         restrictions += MediaSessionManager::BackgroundPlaybackNotPermitted;
2290
2291     MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
2292 }
2293     
2294 void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
2295 {
2296     MediaSession::RemoteControlCommandType command;
2297     
2298     if (equalIgnoringCase(commandString, "Play"))
2299         command = MediaSession::PlayCommand;
2300     else if (equalIgnoringCase(commandString, "Pause"))
2301         command = MediaSession::PauseCommand;
2302     else if (equalIgnoringCase(commandString, "Stop"))
2303         command = MediaSession::StopCommand;
2304     else if (equalIgnoringCase(commandString, "TogglePlayPause"))
2305         command = MediaSession::TogglePlayPauseCommand;
2306     else if (equalIgnoringCase(commandString, "BeginSeekingBackward"))
2307         command = MediaSession::BeginSeekingBackwardCommand;
2308     else if (equalIgnoringCase(commandString, "EndSeekingBackward"))
2309         command = MediaSession::EndSeekingBackwardCommand;
2310     else if (equalIgnoringCase(commandString, "BeginSeekingForward"))
2311         command = MediaSession::BeginSeekingForwardCommand;
2312     else if (equalIgnoringCase(commandString, "EndSeekingForward"))
2313         command = MediaSession::EndSeekingForwardCommand;
2314     else {
2315         ec = INVALID_ACCESS_ERR;
2316         return;
2317     }
2318     
2319     MediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
2320 }
2321     
2322 }