Implement contentInset for Mac WebKit2
[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 void Internals::setTopContentInset(float contentInset)
1832 {
1833     Document* document = contextDocument();
1834     if (!document)
1835         return;
1836     
1837     Page* page = document->page();
1838     page->setTopContentInset(contentInset);
1839 }
1840
1841 #if ENABLE(FULLSCREEN_API)
1842 void Internals::webkitWillEnterFullScreenForElement(Element* element)
1843 {
1844     Document* document = contextDocument();
1845     if (!document)
1846         return;
1847     document->webkitWillEnterFullScreenForElement(element);
1848 }
1849
1850 void Internals::webkitDidEnterFullScreenForElement(Element* element)
1851 {
1852     Document* document = contextDocument();
1853     if (!document)
1854         return;
1855     document->webkitDidEnterFullScreenForElement(element);
1856 }
1857
1858 void Internals::webkitWillExitFullScreenForElement(Element* element)
1859 {
1860     Document* document = contextDocument();
1861     if (!document)
1862         return;
1863     document->webkitWillExitFullScreenForElement(element);
1864 }
1865
1866 void Internals::webkitDidExitFullScreenForElement(Element* element)
1867 {
1868     Document* document = contextDocument();
1869     if (!document)
1870         return;
1871     document->webkitDidExitFullScreenForElement(element);
1872 }
1873 #endif
1874
1875 void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
1876 {
1877     Document* document = contextDocument();
1878     if (!document)
1879         return;
1880     cacheStorage().storeUpdatedQuotaForOrigin(document->securityOrigin(), quota);
1881 }
1882
1883 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
1884 {
1885     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1886 }
1887
1888 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
1889 {
1890     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
1891 }
1892
1893 PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
1894 {
1895     return MallocStatistics::create();
1896 }
1897
1898 PassRefPtr<TypeConversions> Internals::typeConversions() const
1899 {
1900     return TypeConversions::create();
1901 }
1902
1903 PassRefPtr<MemoryInfo> Internals::memoryInfo() const
1904 {
1905     return MemoryInfo::create();
1906 }
1907
1908 Vector<String> Internals::getReferencedFilePaths() const
1909 {
1910     frame()->loader().history().saveDocumentAndScrollState();
1911     return FormController::getReferencedFilePaths(frame()->loader().history().currentItem()->documentState());
1912 }
1913
1914 void Internals::startTrackingRepaints(ExceptionCode& ec)
1915 {
1916     Document* document = contextDocument();
1917     if (!document || !document->view()) {
1918         ec = INVALID_ACCESS_ERR;
1919         return;
1920     }
1921
1922     FrameView* frameView = document->view();
1923     frameView->setTracksRepaints(true);
1924 }
1925
1926 void Internals::stopTrackingRepaints(ExceptionCode& ec)
1927 {
1928     Document* document = contextDocument();
1929     if (!document || !document->view()) {
1930         ec = INVALID_ACCESS_ERR;
1931         return;
1932     }
1933
1934     FrameView* frameView = document->view();
1935     frameView->setTracksRepaints(false);
1936 }
1937
1938 #if !PLATFORM(IOS)
1939 static const char* cursorTypeToString(Cursor::Type cursorType)
1940 {
1941     switch (cursorType) {
1942     case Cursor::Pointer: return "Pointer";
1943     case Cursor::Cross: return "Cross";
1944     case Cursor::Hand: return "Hand";
1945     case Cursor::IBeam: return "IBeam";
1946     case Cursor::Wait: return "Wait";
1947     case Cursor::Help: return "Help";
1948     case Cursor::EastResize: return "EastResize";
1949     case Cursor::NorthResize: return "NorthResize";
1950     case Cursor::NorthEastResize: return "NorthEastResize";
1951     case Cursor::NorthWestResize: return "NorthWestResize";
1952     case Cursor::SouthResize: return "SouthResize";
1953     case Cursor::SouthEastResize: return "SouthEastResize";
1954     case Cursor::SouthWestResize: return "SouthWestResize";
1955     case Cursor::WestResize: return "WestResize";
1956     case Cursor::NorthSouthResize: return "NorthSouthResize";
1957     case Cursor::EastWestResize: return "EastWestResize";
1958     case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
1959     case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
1960     case Cursor::ColumnResize: return "ColumnResize";
1961     case Cursor::RowResize: return "RowResize";
1962     case Cursor::MiddlePanning: return "MiddlePanning";
1963     case Cursor::EastPanning: return "EastPanning";
1964     case Cursor::NorthPanning: return "NorthPanning";
1965     case Cursor::NorthEastPanning: return "NorthEastPanning";
1966     case Cursor::NorthWestPanning: return "NorthWestPanning";
1967     case Cursor::SouthPanning: return "SouthPanning";
1968     case Cursor::SouthEastPanning: return "SouthEastPanning";
1969     case Cursor::SouthWestPanning: return "SouthWestPanning";
1970     case Cursor::WestPanning: return "WestPanning";
1971     case Cursor::Move: return "Move";
1972     case Cursor::VerticalText: return "VerticalText";
1973     case Cursor::Cell: return "Cell";
1974     case Cursor::ContextMenu: return "ContextMenu";
1975     case Cursor::Alias: return "Alias";
1976     case Cursor::Progress: return "Progress";
1977     case Cursor::NoDrop: return "NoDrop";
1978     case Cursor::Copy: return "Copy";
1979     case Cursor::None: return "None";
1980     case Cursor::NotAllowed: return "NotAllowed";
1981     case Cursor::ZoomIn: return "ZoomIn";
1982     case Cursor::ZoomOut: return "ZoomOut";
1983     case Cursor::Grab: return "Grab";
1984     case Cursor::Grabbing: return "Grabbing";
1985     case Cursor::Custom: return "Custom";
1986     }
1987
1988     ASSERT_NOT_REACHED();
1989     return "UNKNOWN";
1990 }
1991 #endif
1992
1993 String Internals::getCurrentCursorInfo(ExceptionCode& ec)
1994 {
1995     Document* document = contextDocument();
1996     if (!document || !document->frame()) {
1997         ec = INVALID_ACCESS_ERR;
1998         return String();
1999     }
2000
2001 #if !PLATFORM(IOS)
2002     Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
2003
2004     StringBuilder result;
2005     result.append("type=");
2006     result.append(cursorTypeToString(cursor.type()));
2007     result.append(" hotSpot=");
2008     result.appendNumber(cursor.hotSpot().x());
2009     result.append(",");
2010     result.appendNumber(cursor.hotSpot().y());
2011     if (cursor.image()) {
2012         IntSize size = cursor.image()->size();
2013         result.append(" image=");
2014         result.appendNumber(size.width());
2015         result.append("x");
2016         result.appendNumber(size.height());
2017     }
2018 #if ENABLE(MOUSE_CURSOR_SCALE)
2019     if (cursor.imageScaleFactor() != 1) {
2020         result.append(" scale=");
2021         NumberToStringBuffer buffer;
2022         result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
2023     }
2024 #endif
2025     return result.toString();
2026 #else
2027     return "FAIL: Cursor details not available on this platform.";
2028 #endif
2029 }
2030
2031 PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
2032 {
2033     Vector<uint8_t> bytes = value->data();
2034     return ArrayBuffer::create(bytes.data(), bytes.size());
2035 }
2036
2037 PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
2038 {
2039     Vector<uint8_t> bytes;
2040     bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
2041     return SerializedScriptValue::adopt(bytes);
2042 }
2043
2044 void Internals::setUsesOverlayScrollbars(bool enabled)
2045 {
2046     WebCore::Settings::setUsesOverlayScrollbars(enabled);
2047 }
2048
2049 void Internals::forceReload(bool endToEnd)
2050 {
2051     frame()->loader().reload(endToEnd);
2052 }
2053
2054 #if ENABLE(ENCRYPTED_MEDIA_V2)
2055 void Internals::initializeMockCDM()
2056 {
2057     CDM::registerCDMFactory(MockCDM::create, MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
2058 }
2059 #endif
2060
2061 String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
2062 {
2063     if (!element) {
2064         ec = INVALID_ACCESS_ERR;
2065         return String();
2066     }
2067     return WebCore::markerTextForListItem(element);
2068 }
2069
2070 String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
2071 {
2072     if (!element) {
2073         ec = INVALID_ACCESS_ERR;
2074         return String();
2075     }
2076     return element->imageSourceURL();
2077 }
2078
2079 #if ENABLE(VIDEO)
2080 void Internals::simulateAudioInterruption(Node* node)
2081 {
2082 #if USE(GSTREAMER)
2083     HTMLMediaElement* element = toHTMLMediaElement(node);
2084     element->player()->simulateAudioInterruption();
2085 #else
2086     UNUSED_PARAM(node);
2087 #endif
2088 }
2089 #endif
2090
2091 bool Internals::isSelectPopupVisible(Node* node)
2092 {
2093     if (!isHTMLSelectElement(node))
2094         return false;
2095
2096     HTMLSelectElement* select = toHTMLSelectElement(node);
2097
2098     auto renderer = select->renderer();
2099     if (!renderer->isMenuList())
2100         return false;
2101
2102 #if !PLATFORM(IOS)
2103     RenderMenuList* menuList = toRenderMenuList(renderer);
2104     return menuList->popupIsVisible();
2105 #else
2106     return false;
2107 #endif // !PLATFORM(IOS)
2108 }
2109
2110 String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
2111 {
2112     Document* document = contextDocument();
2113     if (!document || !document->page()) {
2114         ec = INVALID_ACCESS_ERR;
2115         return emptyString();
2116     }
2117
2118 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2119     return document->page()->group().captionPreferences()->captionsStyleSheetOverride();
2120 #else
2121     return emptyString();
2122 #endif
2123 }
2124
2125 void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionCode& ec)
2126 {
2127     Document* document = contextDocument();
2128     if (!document || !document->page()) {
2129         ec = INVALID_ACCESS_ERR;
2130         return;
2131     }
2132
2133 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2134     document->page()->group().captionPreferences()->setCaptionsStyleSheetOverride(override);
2135 #else
2136     UNUSED_PARAM(override);
2137 #endif
2138 }
2139
2140 void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, ExceptionCode& ec)
2141 {
2142     Document* document = contextDocument();
2143     if (!document || !document->page()) {
2144         ec = INVALID_ACCESS_ERR;
2145         return;
2146     }
2147
2148 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2149     document->page()->group().captionPreferences()->setPrimaryAudioTrackLanguageOverride(language);
2150 #else
2151     UNUSED_PARAM(language);
2152 #endif
2153 }
2154
2155 void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
2156 {
2157     Document* document = contextDocument();
2158     if (!document || !document->page()) {
2159         ec = INVALID_ACCESS_ERR;
2160         return;
2161     }
2162     
2163 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
2164     CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
2165     
2166     if (equalIgnoringCase(mode, "Automatic"))
2167         captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::Automatic);
2168     else if (equalIgnoringCase(mode, "ForcedOnly"))
2169         captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
2170     else if (equalIgnoringCase(mode, "AlwaysOn"))
2171         captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
2172     else
2173         ec = SYNTAX_ERR;
2174 #else
2175     UNUSED_PARAM(mode);
2176 #endif
2177 }
2178
2179 #if ENABLE(VIDEO)
2180 PassRefPtr<TimeRanges> Internals::createTimeRanges(Float32Array* startTimes, Float32Array* endTimes)
2181 {
2182     ASSERT(startTimes && endTimes);
2183     ASSERT(startTimes->length() == endTimes->length());
2184     RefPtr<TimeRanges> ranges = TimeRanges::create();
2185
2186     unsigned count = std::min(startTimes->length(), endTimes->length());
2187     for (unsigned i = 0; i < count; ++i)
2188         ranges->add(startTimes->item(i), endTimes->item(i));
2189     return ranges;
2190 }
2191
2192 double Internals::closestTimeToTimeRanges(double time, TimeRanges* ranges)
2193 {
2194     return ranges->nearest(time);
2195 }
2196 #endif
2197
2198 PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
2199 {
2200     Document* document = contextDocument();
2201     if (!document || !document->frame()) {
2202         ec = INVALID_ACCESS_ERR;
2203         return ClientRect::create();
2204     }
2205
2206     return ClientRect::create(document->frame()->selection().selectionBounds());
2207 }
2208
2209 #if ENABLE(VIBRATION)
2210 bool Internals::isVibrating()
2211 {
2212     Page* page = contextDocument()->page();
2213     ASSERT(page);
2214
2215     return Vibration::from(page)->isVibrating();
2216 }
2217 #endif
2218
2219 bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, ExceptionCode& ec)
2220 {
2221     if (!element) {
2222         ec = INVALID_ACCESS_ERR;
2223         return false;
2224     }
2225
2226     auto renderer = element->renderer();
2227     if (!renderer || !renderer->isEmbeddedObject()) {
2228         ec = INVALID_ACCESS_ERR;
2229         return false;
2230     }
2231
2232     RenderEmbeddedObject* embed = toRenderEmbeddedObject(renderer);
2233     return embed->isReplacementObscured();
2234 }
2235
2236 #if ENABLE(MEDIA_SOURCE)
2237 void Internals::initializeMockMediaSource()
2238 {
2239 #if USE(AVFOUNDATION)
2240     WebCore::Settings::setAVFoundationEnabled(false);
2241 #endif
2242     MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
2243 }
2244 #endif
2245
2246 void Internals::beginMediaSessionInterruption()
2247 {
2248     MediaSessionManager::sharedManager().beginInterruption();
2249 }
2250
2251 void Internals::endMediaSessionInterruption(const String& flagsString)
2252 {
2253     MediaSession::EndInterruptionFlags flags = MediaSession::NoFlags;
2254
2255     if (equalIgnoringCase(flagsString, "MayResumePlaying"))
2256         flags = MediaSession::MayResumePlaying;
2257     
2258     MediaSessionManager::sharedManager().endInterruption(flags);
2259 }
2260
2261 void Internals::applicationWillEnterForeground() const
2262 {
2263     MediaSessionManager::sharedManager().applicationWillEnterForeground();
2264 }
2265
2266 void Internals::applicationWillEnterBackground() const
2267 {
2268     MediaSessionManager::sharedManager().applicationWillEnterBackground();
2269 }
2270
2271 void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
2272 {
2273     MediaSession::MediaType mediaType = MediaSession::None;
2274     if (equalIgnoringCase(mediaTypeString, "Video"))
2275         mediaType = MediaSession::Video;
2276     else if (equalIgnoringCase(mediaTypeString, "Audio"))
2277         mediaType = MediaSession::Audio;
2278     else if (equalIgnoringCase(mediaTypeString, "WebAudio"))
2279         mediaType = MediaSession::WebAudio;
2280     else {
2281         ec = INVALID_ACCESS_ERR;
2282         return;
2283     }
2284
2285     MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType);
2286     MediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
2287
2288     restrictions = MediaSessionManager::NoRestrictions;
2289     
2290     if (equalIgnoringCase(restrictionsString, "ConcurrentPlaybackNotPermitted"))
2291         restrictions = MediaSessionManager::ConcurrentPlaybackNotPermitted;
2292     if (equalIgnoringCase(restrictionsString, "InlineVideoPlaybackRestricted"))
2293         restrictions += MediaSessionManager::InlineVideoPlaybackRestricted;
2294     if (equalIgnoringCase(restrictionsString, "MetadataPreloadingNotPermitted"))
2295         restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
2296     if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
2297         restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
2298     if (equalIgnoringCase(restrictionsString, "BackgroundPlaybackNotPermitted"))
2299         restrictions += MediaSessionManager::BackgroundPlaybackNotPermitted;
2300
2301     MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
2302 }
2303     
2304 void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
2305 {
2306     MediaSession::RemoteControlCommandType command;
2307     
2308     if (equalIgnoringCase(commandString, "Play"))
2309         command = MediaSession::PlayCommand;
2310     else if (equalIgnoringCase(commandString, "Pause"))
2311         command = MediaSession::PauseCommand;
2312     else if (equalIgnoringCase(commandString, "Stop"))
2313         command = MediaSession::StopCommand;
2314     else if (equalIgnoringCase(commandString, "TogglePlayPause"))
2315         command = MediaSession::TogglePlayPauseCommand;
2316     else if (equalIgnoringCase(commandString, "BeginSeekingBackward"))
2317         command = MediaSession::BeginSeekingBackwardCommand;
2318     else if (equalIgnoringCase(commandString, "EndSeekingBackward"))
2319         command = MediaSession::EndSeekingBackwardCommand;
2320     else if (equalIgnoringCase(commandString, "BeginSeekingForward"))
2321         command = MediaSession::BeginSeekingForwardCommand;
2322     else if (equalIgnoringCase(commandString, "EndSeekingForward"))
2323         command = MediaSession::EndSeekingForwardCommand;
2324     else {
2325         ec = INVALID_ACCESS_ERR;
2326         return;
2327     }
2328     
2329     MediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
2330 }
2331     
2332 }