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