Web Inspector: Add Console support to JSContext Inspection
[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 "InspectorCounters.h"
62 #include "InspectorForwarding.h"
63 #include "InspectorFrontendClientLocal.h"
64 #include "InspectorInstrumentation.h"
65 #include "InspectorOverlay.h"
66 #include "InstrumentingAgents.h"
67 #include "IntRect.h"
68 #include "InternalSettings.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 "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 #endif
157
158 #if ENABLE(MEDIA_SOURCE)
159 #include "MockMediaPlayerMediaSource.h"
160 #endif
161
162 using JSC::CodeBlock;
163 using JSC::FunctionExecutable;
164 using JSC::JSFunction;
165 using JSC::JSValue;
166 using JSC::ScriptExecutable;
167 using JSC::StackVisitor;
168
169 using namespace Inspector;
170
171 namespace WebCore {
172
173 using namespace HTMLNames;
174
175 #if ENABLE(INSPECTOR)
176 class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
177 public:
178     InspectorFrontendClientDummy(InspectorController*, Page*);
179     virtual ~InspectorFrontendClientDummy() { }
180     virtual void attachWindow(DockSide) override { }
181     virtual void detachWindow() override { }
182
183     virtual String localizedStringsURL() override { return String(); }
184
185     virtual void bringToFront() override { }
186     virtual void closeWindow() override { }
187
188     virtual void inspectedURLChanged(const String&) override { }
189
190 protected:
191     virtual void setAttachedWindowHeight(unsigned) override { }
192     virtual void setAttachedWindowWidth(unsigned) override { }
193     virtual void setToolbarHeight(unsigned) override { }
194 };
195
196 InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
197     : InspectorFrontendClientLocal(controller, page, adoptPtr(new InspectorFrontendClientLocal::Settings()))
198 {
199 }
200
201 class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
202 public:
203     explicit InspectorFrontendChannelDummy(Page*);
204     virtual ~InspectorFrontendChannelDummy() { }
205     virtual bool sendMessageToFrontend(const String& message) override;
206
207 private:
208     Page* m_frontendPage;
209 };
210
211 InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
212     : m_frontendPage(page)
213 {
214 }
215
216 bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
217 {
218     return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
219 }
220 #endif // ENABLE(INSPECTOR)
221
222 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
223 {
224     if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
225         result = DocumentMarker::AllMarkers();
226     else if (equalIgnoringCase(markerType, "Spelling"))
227         result =  DocumentMarker::Spelling;
228     else if (equalIgnoringCase(markerType, "Grammar"))
229         result =  DocumentMarker::Grammar;
230     else if (equalIgnoringCase(markerType, "TextMatch"))
231         result =  DocumentMarker::TextMatch;
232     else if (equalIgnoringCase(markerType, "Replacement"))
233         result =  DocumentMarker::Replacement;
234     else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
235         result =  DocumentMarker::CorrectionIndicator;
236     else if (equalIgnoringCase(markerType, "RejectedCorrection"))
237         result =  DocumentMarker::RejectedCorrection;
238     else if (equalIgnoringCase(markerType, "Autocorrected"))
239         result =  DocumentMarker::Autocorrected;
240     else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
241         result =  DocumentMarker::SpellCheckingExemption;
242     else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
243         result =  DocumentMarker::DeletedAutocorrection;
244     else if (equalIgnoringCase(markerType, "DictationAlternatives"))
245         result =  DocumentMarker::DictationAlternatives;
246     else
247         return false;
248
249     return true;
250 }
251
252 const char* Internals::internalsId = "internals";
253
254 PassRefPtr<Internals> Internals::create(Document* document)
255 {
256     return adoptRef(new Internals(document));
257 }
258
259 Internals::~Internals()
260 {
261 }
262
263 void Internals::resetToConsistentState(Page* page)
264 {
265     ASSERT(page);
266
267     page->setPageScaleFactor(1, IntPoint(0, 0));
268     page->setPagination(Pagination());
269
270     FrameView* mainFrameView = page->mainFrame().view();
271     if (mainFrameView) {
272         mainFrameView->setHeaderHeight(0);
273         mainFrameView->setFooterHeight(0);
274     }
275
276     TextRun::setAllowsRoundingHacks(false);
277     WebCore::overrideUserPreferredLanguages(Vector<String>());
278     WebCore::Settings::setUsesOverlayScrollbars(false);
279 #if ENABLE(INSPECTOR)
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 #if HAVE(ACCESSIBILITY)
295     AXObjectCache::disableAccessibility();
296 #endif
297 }
298
299 Internals::Internals(Document* document)
300     : ContextDestructionObserver(document)
301 {
302 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
303     if (document && document->page())
304         document->page()->group().captionPreferences()->setTestingMode(true);
305 #endif
306
307 #if ENABLE(MEDIA_STREAM)
308     MockMediaStreamCenter::registerMockMediaStreamCenter();
309     enableMockRTCPeerConnectionHandler();
310 #endif
311 }
312
313 Document* Internals::contextDocument() const
314 {
315     return toDocument(scriptExecutionContext());
316 }
317
318 Frame* Internals::frame() const
319 {
320     if (!contextDocument())
321         return 0;
322     return contextDocument()->frame();
323 }
324
325 InternalSettings* Internals::settings() const
326 {
327     Document* document = contextDocument();
328     if (!document)
329         return 0;
330     Page* page = document->page();
331     if (!page)
332         return 0;
333     return InternalSettings::from(page);
334 }
335
336 unsigned Internals::workerThreadCount() const
337 {
338     return WorkerThread::workerThreadCount();
339 }
340
341 String Internals::address(Node* node)
342 {
343     char buf[32];
344     sprintf(buf, "%p", node);
345
346     return String(buf);
347 }
348
349 bool Internals::isPreloaded(const String& url)
350 {
351     Document* document = contextDocument();
352     return document->cachedResourceLoader()->isPreloaded(url);
353 }
354
355 bool Internals::isLoadingFromMemoryCache(const String& url)
356 {
357     if (!contextDocument())
358         return false;
359     CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url));
360     return resource && resource->status() == CachedResource::Cached;
361 }
362
363
364 Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
365 {
366     if (!node) {
367         ec = INVALID_ACCESS_ERR;
368         return 0;
369     }
370
371     return node->treeScope().rootNode();
372 }
373
374 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
375 {
376     if (!node) {
377         ec = INVALID_ACCESS_ERR;
378         return 0;
379     }
380     const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
381     return parentTreeScope ? parentTreeScope->rootNode() : 0;
382 }
383
384 unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
385 {
386     if (!contextDocument() || !contextDocument()->page()) {
387         ec = INVALID_ACCESS_ERR;
388         return 0;
389     }
390
391     return contextDocument()->page()->lastSpatialNavigationCandidateCount();
392 }
393
394 unsigned Internals::numberOfActiveAnimations() const
395 {
396     return frame()->animation().numberOfActiveAnimations(frame()->document());
397 }
398
399 bool Internals::animationsAreSuspended(ExceptionCode& ec) const
400 {
401     Document* document = contextDocument();
402     if (!document || !document->frame()) {
403         ec = INVALID_ACCESS_ERR;
404         return false;
405     }
406
407     return document->frame()->animation().isSuspended();
408 }
409
410 void Internals::suspendAnimations(ExceptionCode& ec) const
411 {
412     Document* document = contextDocument();
413     if (!document || !document->frame()) {
414         ec = INVALID_ACCESS_ERR;
415         return;
416     }
417
418     document->frame()->animation().suspendAnimations();
419 }
420
421 void Internals::resumeAnimations(ExceptionCode& ec) const
422 {
423     Document* document = contextDocument();
424     if (!document || !document->frame()) {
425         ec = INVALID_ACCESS_ERR;
426         return;
427     }
428
429     document->frame()->animation().resumeAnimations();
430 }
431
432 bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
433 {
434     if (!element || pauseTime < 0) {
435         ec = INVALID_ACCESS_ERR;
436         return false;
437     }
438     return frame()->animation().pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
439 }
440
441 bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
442 {
443     if (!element || pauseTime < 0) {
444         ec = INVALID_ACCESS_ERR;
445         return false;
446     }
447
448     if (pseudoId != "before" && pseudoId != "after") {
449         ec = INVALID_ACCESS_ERR;
450         return false;
451     }
452
453     PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
454     if (!pseudoElement) {
455         ec = INVALID_ACCESS_ERR;
456         return false;
457     }
458
459     return frame()->animation().pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
460 }
461
462 bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
463 {
464     if (!element || pauseTime < 0) {
465         ec = INVALID_ACCESS_ERR;
466         return false;
467     }
468     return frame()->animation().pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
469 }
470
471 bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
472 {
473     if (!element || pauseTime < 0) {
474         ec = INVALID_ACCESS_ERR;
475         return false;
476     }
477
478     if (pseudoId != "before" && pseudoId != "after") {
479         ec = INVALID_ACCESS_ERR;
480         return false;
481     }
482
483     PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
484     if (!pseudoElement) {
485         ec = INVALID_ACCESS_ERR;
486         return false;
487     }
488
489     return frame()->animation().pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
490 }
491
492 // FIXME: Remove.
493 bool Internals::attached(Node* node, ExceptionCode& ec)
494 {
495     if (!node) {
496         ec = INVALID_ACCESS_ERR;
497         return false;
498     }
499
500     return true;
501 }
502
503 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
504 {
505     if (!element) {
506         ec = INVALID_ACCESS_ERR;
507         return String();
508     }
509
510     element->document().updateStyleIfNeeded();
511
512     String representation = externalRepresentation(element);
513     if (representation.isEmpty()) {
514         ec = INVALID_ACCESS_ERR;
515         return String();
516     }
517
518     return representation;
519 }
520
521 PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
522 {
523     if (!node) {
524         ec = INVALID_ACCESS_ERR;
525         return 0;
526     }
527
528     bool allowVisitedStyle = true;
529     return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
530 }
531
532 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
533 {
534     if (!host) {
535         ec = INVALID_ACCESS_ERR;
536         return 0;
537     }
538
539     if (ShadowRoot* shadowRoot = host->shadowRoot())
540         return shadowRoot;
541
542     return host->createShadowRoot(ec).get();
543 }
544
545 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
546 {
547     if (!host) {
548         ec = INVALID_ACCESS_ERR;
549         return 0;
550     }
551     return host->createShadowRoot(ec).get();
552 }
553
554 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::shadowRoot(Element* host, ExceptionCode& ec)
555 {
556     if (!host) {
557         ec = INVALID_ACCESS_ERR;
558         return 0;
559     }
560     return host->shadowRoot();
561 }
562
563 String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
564 {
565     if (!root || !root->isShadowRoot()) {
566         ec = INVALID_ACCESS_ERR;
567         return String();
568     }
569
570     switch (toShadowRoot(root)->type()) {
571     case ShadowRoot::UserAgentShadowRoot:
572         return String("UserAgentShadowRoot");
573     case ShadowRoot::AuthorShadowRoot:
574         return String("AuthorShadowRoot");
575     default:
576         ASSERT_NOT_REACHED();
577         return String("Unknown");
578     }
579 }
580
581 Element* Internals::includerFor(Node*, ExceptionCode& ec)
582 {
583     ec = INVALID_ACCESS_ERR;
584     return 0;
585 }
586
587 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
588 {
589     if (!element) {
590         ec = INVALID_ACCESS_ERR;
591         return String();
592     }
593
594     return element->shadowPseudoId().string();
595 }
596
597 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
598 {
599     if (!element) {
600         ec = INVALID_ACCESS_ERR;
601         return;
602     }
603
604     return element->setPseudo(id);
605 }
606
607 String Internals::visiblePlaceholder(Element* element)
608 {
609     if (element && isHTMLTextFormControlElement(*element)) {
610         if (toHTMLTextFormControlElement(*element).placeholderShouldBeVisible())
611             return toHTMLTextFormControlElement(*element).placeholderElement()->textContent();
612     }
613
614     return String();
615 }
616
617 #if ENABLE(INPUT_TYPE_COLOR)
618 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
619 {
620     if (!isHTMLInputElement(element))
621         return;
622     HTMLInputElement* inputElement = element->toInputElement();
623     if (!inputElement)
624         return;
625     inputElement->selectColorInColorChooser(Color(colorValue));
626 }
627 #endif
628
629 Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
630 {
631     HistoryItem* mainItem = frame()->loader().history().previousItem();
632     if (!mainItem) {
633         ec = INVALID_ACCESS_ERR;
634         return Vector<String>();
635     }
636     String uniqueName = frame()->tree().uniqueName();
637     if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
638         ec = INVALID_ACCESS_ERR;
639         return Vector<String>();
640     }
641     return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
642 }
643
644 void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
645 {
646     HistoryItem* mainItem = frame()->loader().history().previousItem();
647     if (!mainItem) {
648         ec = INVALID_ACCESS_ERR;
649         return;
650     }
651     String uniqueName = frame()->tree().uniqueName();
652     if (mainItem->target() == uniqueName)
653         mainItem->setDocumentState(state);
654     else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
655         subItem->setDocumentState(state);
656     else
657         ec = INVALID_ACCESS_ERR;
658 }
659
660 #if ENABLE(SPEECH_SYNTHESIS)
661 void Internals::enableMockSpeechSynthesizer()
662 {
663     Document* document = contextDocument();
664     if (!document || !document->domWindow())
665         return;
666     SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(document->domWindow());
667     if (!synthesis)
668         return;
669     
670     synthesis->setPlatformSynthesizer(PlatformSpeechSynthesizerMock::create(synthesis));
671 }
672 #endif
673
674 #if ENABLE(MEDIA_STREAM)
675 void Internals::enableMockRTCPeerConnectionHandler()
676 {
677     RTCPeerConnectionHandler::create = RTCPeerConnectionHandlerMock::create;
678 }
679 #endif
680
681 PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
682 {
683     Document* document = contextDocument();
684     if (!document || !document->frame()) {
685         ec = INVALID_ACCESS_ERR;
686         return ClientRect::create();
687     }
688
689     return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
690 }
691
692 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
693 {
694     if (!element) {
695         ec = INVALID_ACCESS_ERR;
696         return ClientRect::create();
697     }
698
699     element->document().updateLayoutIgnorePendingStylesheets();
700     auto renderer = element->renderer();
701     if (!renderer)
702         return ClientRect::create();
703     return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
704 }
705
706 PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
707 {
708 #if ENABLE(INSPECTOR)
709     Document* document = contextDocument();
710     if (!document || !document->page()) {
711         ec = INVALID_ACCESS_ERR;
712         return ClientRectList::create();
713     }
714
715     Highlight highlight;
716     document->page()->inspectorController().getHighlight(&highlight);
717     return ClientRectList::create(highlight.quads);
718 #else
719     UNUSED_PARAM(ec);
720     return ClientRectList::create();
721 #endif
722 }
723
724 String Internals::inspectorHighlightObject(ExceptionCode& ec)
725 {
726 #if ENABLE(INSPECTOR)
727     Document* document = contextDocument();
728     if (!document || !document->page()) {
729         ec = INVALID_ACCESS_ERR;
730         return String();
731     }
732     RefPtr<InspectorObject> object = document->page()->inspectorController().buildObjectForHighlightedNode();
733     return object ? object->toJSONString() : String();
734 #else
735     UNUSED_PARAM(ec);
736     return String();
737 #endif
738 }
739
740 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
741 {
742     if (!node) {
743         ec = INVALID_ACCESS_ERR;
744         return 0;
745     }
746
747     DocumentMarker::MarkerTypes markerTypes = 0;
748     if (!markerTypesFrom(markerType, markerTypes)) {
749         ec = SYNTAX_ERR;
750         return 0;
751     }
752
753     return node->document().markers().markersFor(node, markerTypes).size();
754 }
755
756 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
757 {
758     node->document().updateLayoutIgnorePendingStylesheets();
759     if (!node) {
760         ec = INVALID_ACCESS_ERR;
761         return 0;
762     }
763
764     DocumentMarker::MarkerTypes markerTypes = 0;
765     if (!markerTypesFrom(markerType, markerTypes)) {
766         ec = SYNTAX_ERR;
767         return 0;
768     }
769
770     Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
771     if (markers.size() <= index)
772         return 0;
773     return markers[index];
774 }
775
776 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
777 {
778     DocumentMarker* marker = markerAt(node, markerType, index, ec);
779     if (!marker)
780         return 0;
781     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
782 }
783
784 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
785 {
786     DocumentMarker* marker = markerAt(node, markerType, index, ec);
787     if (!marker)
788         return String();
789     return marker->description();
790 }
791
792 void Internals::addTextMatchMarker(const Range* range, bool isActive)
793 {
794     range->ownerDocument().updateLayoutIgnorePendingStylesheets();
795     range->ownerDocument().markers().addTextMatchMarker(range, isActive);
796 }
797
798 void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
799 {
800     Document* document = contextDocument();
801     if (!document || !document->view()) {
802         ec = INVALID_ACCESS_ERR;
803         return;
804     }
805
806     FrameView* frameView = document->view();
807     bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
808     bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
809
810     frameView->setConstrainsScrollingToContentEdge(false);
811     frameView->setScrollbarsSuppressed(false);
812     frameView->setScrollOffsetFromInternals(IntPoint(x, y));
813     frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
814     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
815 }
816
817 void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
818 {
819     Document* document = contextDocument();
820     if (!document || !document->page()) {
821         ec = INVALID_ACCESS_ERR;
822         return;
823     }
824     Page* page = document->page();
825
826     Pagination pagination;
827     if (mode == "Unpaginated")
828         pagination.mode = Pagination::Unpaginated;
829     else if (mode == "LeftToRightPaginated")
830         pagination.mode = Pagination::LeftToRightPaginated;
831     else if (mode == "RightToLeftPaginated")
832         pagination.mode = Pagination::RightToLeftPaginated;
833     else if (mode == "TopToBottomPaginated")
834         pagination.mode = Pagination::TopToBottomPaginated;
835     else if (mode == "BottomToTopPaginated")
836         pagination.mode = Pagination::BottomToTopPaginated;
837     else {
838         ec = SYNTAX_ERR;
839         return;
840     }
841
842     pagination.gap = gap;
843     pagination.pageLength = pageLength;
844     page->setPagination(pagination);
845 }
846
847 String Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
848 {
849     Document* document = contextDocument();
850     if (!document || !document->page()) {
851         ec = INVALID_ACCESS_ERR;
852         return String();
853     }
854     Page* page = document->page();
855
856     const int defaultLayoutWidthForNonMobilePages = 980;
857
858     ViewportArguments arguments = page->viewportArguments();
859     ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
860     restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
861     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
862
863     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");
864 }
865
866 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
867 {
868     if (!textField) {
869         ec = INVALID_ACCESS_ERR;
870         return false;
871     }
872
873     if (HTMLInputElement* inputElement = textField->toInputElement())
874         return inputElement->lastChangeWasUserEdit();
875
876     // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
877     if (textField->tagName() == "TEXTAREA")
878         return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
879
880     ec = INVALID_NODE_TYPE_ERR;
881     return false;
882 }
883
884 bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
885 {
886     if (!element) {
887         ec = INVALID_ACCESS_ERR;
888         return false;
889     }
890
891     if (HTMLInputElement* inputElement = element->toInputElement())
892         return inputElement->shouldAutocomplete();
893
894     ec = INVALID_NODE_TYPE_ERR;
895     return false;
896 }
897
898 String Internals::suggestedValue(Element* element, ExceptionCode& ec)
899 {
900     if (!element) {
901         ec = INVALID_ACCESS_ERR;
902         return String();
903     }
904
905     HTMLInputElement* inputElement = element->toInputElement();
906     if (!inputElement) {
907         ec = INVALID_NODE_TYPE_ERR;
908         return String();
909     }
910
911     return inputElement->suggestedValue();
912 }
913
914 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
915 {
916     if (!element) {
917         ec = INVALID_ACCESS_ERR;
918         return;
919     }
920
921     HTMLInputElement* inputElement = element->toInputElement();
922     if (!inputElement) {
923         ec = INVALID_NODE_TYPE_ERR;
924         return;
925     }
926
927     inputElement->setSuggestedValue(value);
928 }
929
930 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
931 {
932     if (!element) {
933         ec = INVALID_ACCESS_ERR;
934         return;
935     }
936
937     HTMLInputElement* inputElement = element->toInputElement();
938     if (!inputElement) {
939         ec = INVALID_NODE_TYPE_ERR;
940         return;
941     }
942
943     inputElement->setEditingValue(value);
944 }
945
946 void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
947 {
948     HTMLInputElement* inputElement = element->toInputElement();
949     if (!inputElement) {
950         ec = INVALID_ACCESS_ERR;
951         return;
952     }
953     inputElement->setAutofilled(enabled);
954 }
955
956 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
957 {
958     if (!element || !element->document().view()) {
959         ec = INVALID_ACCESS_ERR;
960         return;
961     }
962     FrameView* frameView = element->document().view();
963     frameView->scrollElementToRect(element, IntRect(x, y, w, h));
964 }
965
966 void Internals::paintControlTints(ExceptionCode& ec)
967 {
968     Document* document = contextDocument();
969     if (!document || !document->view()) {
970         ec = INVALID_ACCESS_ERR;
971         return;
972     }
973
974     FrameView* frameView = document->view();
975     frameView->paintControlTints();
976 }
977
978 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
979 {
980     if (!scope) {
981         ec = INVALID_ACCESS_ERR;
982         return 0;
983     }
984
985     return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
986 }
987
988 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
989 {
990     if (!scope || !range) {
991         ec = INVALID_ACCESS_ERR;
992         return 0;
993     }
994
995     size_t location = 0;
996     size_t unusedLength = 0;
997     TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
998     return location;
999 }
1000
1001 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1002 {
1003     if (!scope || !range) {
1004         ec = INVALID_ACCESS_ERR;
1005         return 0;
1006     }
1007
1008     size_t unusedLocation = 0;
1009     size_t length = 0;
1010     TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
1011     return length;
1012 }
1013
1014 String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
1015 {
1016     if (!range) {
1017         ec = INVALID_ACCESS_ERR;
1018         return String();
1019     }
1020
1021     return range->text();
1022 }
1023
1024 void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
1025 {
1026     Document* document = contextDocument();
1027     // Delegate scrolling is valid only on mainframe's view.
1028     if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame()) {
1029         ec = INVALID_ACCESS_ERR;
1030         return;
1031     }
1032
1033     document->view()->setDelegatesScrolling(enabled);
1034 }
1035
1036 int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
1037 {
1038     Document* document = contextDocument();
1039     if (!document || !document->frame()) {
1040         ec = INVALID_ACCESS_ERR;
1041         return -1;
1042     }
1043
1044     return document->frame()->editor().spellChecker().lastRequestSequence();
1045 }
1046
1047 int Internals::lastSpellCheckProcessedSequence(ExceptionCode& ec)
1048 {
1049     Document* document = contextDocument();
1050     if (!document || !document->frame()) {
1051         ec = INVALID_ACCESS_ERR;
1052         return -1;
1053     }
1054
1055     return document->frame()->editor().spellChecker().lastProcessedSequence();
1056 }
1057
1058 Vector<String> Internals::userPreferredLanguages() const
1059 {
1060     return WebCore::userPreferredLanguages();
1061 }
1062
1063 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
1064 {
1065     WebCore::overrideUserPreferredLanguages(languages);
1066 }
1067
1068 unsigned Internals::wheelEventHandlerCount(ExceptionCode& ec)
1069 {
1070     Document* document = contextDocument();
1071     if (!document) {
1072         ec = INVALID_ACCESS_ERR;
1073         return 0;
1074     }
1075
1076     return document->wheelEventHandlerCount();
1077 }
1078
1079 unsigned Internals::touchEventHandlerCount(ExceptionCode& ec)
1080 {
1081     Document* document = contextDocument();
1082     if (!document) {
1083         ec = INVALID_ACCESS_ERR;
1084         return 0;
1085     }
1086
1087     const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
1088     if (!touchHandlers)
1089         return 0;
1090
1091     unsigned count = 0;
1092     for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
1093         count += iter->value;
1094     return count;
1095 }
1096
1097 // FIXME: Remove the document argument. It is almost always the same as
1098 // contextDocument(), with the exception of a few tests that pass a
1099 // different document, and could just make the call through another Internals
1100 // instance instead.
1101 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
1102     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
1103 {
1104     if (!document || !document->frame() || !document->frame()->view()) {
1105         ec = INVALID_ACCESS_ERR;
1106         return 0;
1107     }
1108
1109     Frame* frame = document->frame();
1110     FrameView* frameView = document->view();
1111     RenderView* renderView = document->renderView();
1112     if (!renderView)
1113         return 0;
1114
1115     document->updateLayoutIgnorePendingStylesheets();
1116
1117     float zoomFactor = frame->pageZoomFactor();
1118     LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
1119
1120     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
1121     if (ignoreClipping)
1122         hitType |= HitTestRequest::IgnoreClipping;
1123     if (!allowShadowContent)
1124         hitType |= HitTestRequest::DisallowShadowContent;
1125     if (allowChildFrameContent)
1126         hitType |= HitTestRequest::AllowChildFrameContent;
1127
1128     HitTestRequest request(hitType);
1129
1130     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1131     if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1132         return 0;
1133
1134     Vector<Ref<Node>> matches;
1135
1136     // Need padding to trigger a rect based hit test, but we want to return a NodeList
1137     // so we special case this.
1138     if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1139         HitTestResult result(point);
1140         renderView->hitTest(request, result);
1141         if (result.innerNode())
1142             matches.append(*result.innerNode()->deprecatedShadowAncestorNode());
1143     } else {
1144         HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
1145         renderView->hitTest(request, result);
1146         
1147         const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
1148         matches.reserveInitialCapacity(nodeSet.size());
1149         for (auto it = nodeSet.begin(), end = nodeSet.end(); it != end; ++it)
1150             matches.uncheckedAppend(*it->get());
1151     }
1152
1153     return StaticNodeList::adopt(matches);
1154 }
1155
1156 void Internals::emitInspectorDidBeginFrame()
1157 {
1158 #if ENABLE(INSPECTOR)
1159     contextDocument()->frame()->page()->inspectorController().didBeginFrame();
1160 #endif
1161 }
1162
1163 void Internals::emitInspectorDidCancelFrame()
1164 {
1165 #if ENABLE(INSPECTOR)
1166     contextDocument()->frame()->page()->inspectorController().didCancelFrame();
1167 #endif
1168 }
1169
1170 class GetCallerCodeBlockFunctor {
1171 public:
1172     GetCallerCodeBlockFunctor()
1173         : m_iterations(0)
1174         , m_codeBlock(0)
1175     {
1176     }
1177
1178     StackVisitor::Status operator()(StackVisitor& visitor)
1179     {
1180         ++m_iterations;
1181         if (m_iterations < 2)
1182             return StackVisitor::Continue;
1183
1184         m_codeBlock = visitor->codeBlock();
1185         return StackVisitor::Done;
1186     }
1187
1188     CodeBlock* codeBlock() const { return m_codeBlock; }
1189
1190 private:
1191     int m_iterations;
1192     CodeBlock* m_codeBlock;
1193 };
1194
1195 String Internals::parserMetaData(Deprecated::ScriptValue value)
1196 {
1197     JSC::VM* vm = contextDocument()->vm();
1198     JSC::ExecState* exec = vm->topCallFrame;
1199     JSC::JSValue code = value.jsValue();
1200     ScriptExecutable* executable;
1201
1202     if (!code || code.isNull() || code.isUndefined()) {
1203         GetCallerCodeBlockFunctor iter;
1204         exec->iterate(iter);
1205         CodeBlock* codeBlock = iter.codeBlock();
1206         executable = codeBlock->ownerExecutable(); 
1207     } else if (code.isFunction()) {
1208         JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
1209         executable = funcObj->jsExecutable();
1210     } else
1211         return String();
1212
1213     unsigned startLine = executable->lineNo();
1214     unsigned startColumn = executable->startColumn();
1215     unsigned endLine = executable->lastLine();
1216     unsigned endColumn = executable->endColumn();
1217
1218     StringBuilder result;
1219
1220     if (executable->isFunctionExecutable()) {
1221         FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
1222         String inferredName = funcExecutable->inferredName().string();
1223         result.append("function \"");
1224         result.append(inferredName);
1225         result.append("\"");
1226     } else if (executable->isEvalExecutable())
1227         result.append("eval");
1228     else {
1229         ASSERT(executable->isProgramExecutable());
1230         result.append("program");
1231     }
1232
1233     result.append(" { ");
1234     result.appendNumber(startLine);
1235     result.append(":");
1236     result.appendNumber(startColumn);
1237     result.append(" - ");
1238     result.appendNumber(endLine);
1239     result.append(":");
1240     result.appendNumber(endColumn);
1241     result.append(" }");
1242
1243     return result.toString();
1244 }
1245
1246 void Internals::setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
1247 {
1248     Document* document = contextDocument();
1249     if (!document || !document->page()) {
1250         ec = INVALID_ACCESS_ERR;
1251         return;
1252     }
1253
1254 #if ENABLE(BATTERY_STATUS)
1255     BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
1256 #else
1257     UNUSED_PARAM(eventType);
1258     UNUSED_PARAM(charging);
1259     UNUSED_PARAM(chargingTime);
1260     UNUSED_PARAM(dischargingTime);
1261     UNUSED_PARAM(level);
1262 #endif
1263 }
1264
1265 void Internals::setNetworkInformation(const String& eventType, double bandwidth, bool metered, ExceptionCode& ec)
1266 {
1267     Document* document = contextDocument();
1268     if (!document || !document->page()) {
1269         ec = INVALID_ACCESS_ERR;
1270         return;
1271     }
1272
1273 #if ENABLE(NETWORK_INFO)
1274     NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered));
1275 #else
1276     UNUSED_PARAM(eventType);
1277     UNUSED_PARAM(bandwidth);
1278     UNUSED_PARAM(metered);
1279 #endif
1280 }
1281
1282 void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
1283 {
1284     Document* document = contextDocument();
1285     if (!document || !document->page()) {
1286         ec = INVALID_ACCESS_ERR;
1287         return;
1288     }
1289
1290 #if ENABLE(PROXIMITY_EVENTS)
1291     DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
1292 #else
1293     UNUSED_PARAM(eventType);
1294     UNUSED_PARAM(value);
1295     UNUSED_PARAM(min);
1296     UNUSED_PARAM(max);
1297 #endif
1298 }
1299
1300 bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
1301 {
1302     Document* document = contextDocument();
1303     if (!document || !document->frame())
1304         return 0;
1305
1306     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1307 }
1308     
1309 bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
1310 {
1311     Document* document = contextDocument();
1312     if (!document || !document->frame())
1313         return 0;
1314     
1315     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
1316 }
1317
1318 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
1319 {
1320     if (!contextDocument() || !contextDocument()->frame())
1321         return;
1322
1323     if (enabled != contextDocument()->frame()->editor().isContinuousSpellCheckingEnabled())
1324         contextDocument()->frame()->editor().toggleContinuousSpellChecking();
1325 }
1326
1327 void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&)
1328 {
1329     if (!contextDocument() || !contextDocument()->frame())
1330         return;
1331
1332 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1333     if (enabled != contextDocument()->frame()->editor().isAutomaticQuoteSubstitutionEnabled())
1334         contextDocument()->frame()->editor().toggleAutomaticQuoteSubstitution();
1335 #else
1336     UNUSED_PARAM(enabled);
1337 #endif
1338 }
1339
1340 void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
1341 {
1342     if (!contextDocument() || !contextDocument()->frame())
1343         return;
1344
1345 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1346     if (enabled != contextDocument()->frame()->editor().isAutomaticLinkDetectionEnabled())
1347         contextDocument()->frame()->editor().toggleAutomaticLinkDetection();
1348 #else
1349     UNUSED_PARAM(enabled);
1350 #endif
1351 }
1352
1353 void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&)
1354 {
1355     if (!contextDocument() || !contextDocument()->frame())
1356         return;
1357
1358 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1359     if (enabled != contextDocument()->frame()->editor().isAutomaticDashSubstitutionEnabled())
1360         contextDocument()->frame()->editor().toggleAutomaticDashSubstitution();
1361 #else
1362     UNUSED_PARAM(enabled);
1363 #endif
1364 }
1365
1366 void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
1367 {
1368     if (!contextDocument() || !contextDocument()->frame())
1369         return;
1370
1371 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1372     if (enabled != contextDocument()->frame()->editor().isAutomaticTextReplacementEnabled())
1373         contextDocument()->frame()->editor().toggleAutomaticTextReplacement();
1374 #else
1375     UNUSED_PARAM(enabled);
1376 #endif
1377 }
1378
1379 void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&)
1380 {
1381     if (!contextDocument() || !contextDocument()->frame())
1382         return;
1383
1384 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1385     if (enabled != contextDocument()->frame()->editor().isAutomaticSpellingCorrectionEnabled())
1386         contextDocument()->frame()->editor().toggleAutomaticSpellingCorrection();
1387 #else
1388     UNUSED_PARAM(enabled);
1389 #endif
1390 }
1391
1392 bool Internals::isOverwriteModeEnabled(ExceptionCode&)
1393 {
1394     Document* document = contextDocument();
1395     if (!document || !document->frame())
1396         return 0;
1397
1398     return document->frame()->editor().isOverwriteModeEnabled();
1399 }
1400
1401 void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
1402 {
1403     Document* document = contextDocument();
1404     if (!document || !document->frame())
1405         return;
1406
1407     document->frame()->editor().toggleOverwriteModeEnabled();
1408 }
1409
1410 #if ENABLE(INSPECTOR)
1411 unsigned Internals::numberOfLiveNodes() const
1412 {
1413     return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
1414 }
1415
1416 unsigned Internals::numberOfLiveDocuments() const
1417 {
1418     return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
1419 }
1420
1421 Vector<String> Internals::consoleMessageArgumentCounts() const
1422 {
1423     Document* document = contextDocument();
1424     if (!document || !document->page())
1425         return Vector<String>();
1426
1427     InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
1428     if (!instrumentingAgents)
1429         return Vector<String>();
1430
1431     InspectorConsoleAgent* consoleAgent = instrumentingAgents->webConsoleAgent();
1432     if (!consoleAgent)
1433         return Vector<String>();
1434
1435     Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
1436     Vector<String> result(counts.size());
1437     for (size_t i = 0; i < counts.size(); i++)
1438         result[i] = String::number(counts[i]);
1439     return result;
1440 }
1441
1442 PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
1443 {
1444     Page* page = contextDocument()->frame()->page();
1445     ASSERT(page);
1446
1447     DOMWindow* window = page->mainFrame().document()->domWindow();
1448     ASSERT(window);
1449
1450     m_frontendWindow = window->open(url, "", "", *window, *window);
1451     ASSERT(m_frontendWindow);
1452
1453     Page* frontendPage = m_frontendWindow->document()->page();
1454     ASSERT(frontendPage);
1455
1456     auto frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
1457
1458     frontendPage->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
1459
1460     m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
1461
1462     page->inspectorController().connectFrontend(m_frontendChannel.get());
1463
1464     return m_frontendWindow;
1465 }
1466
1467 void Internals::closeDummyInspectorFrontend()
1468 {
1469     Page* page = contextDocument()->frame()->page();
1470     ASSERT(page);
1471     ASSERT(m_frontendWindow);
1472
1473     page->inspectorController().disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
1474
1475     m_frontendChannel.release();
1476
1477     m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
1478     m_frontendWindow.release();
1479 }
1480
1481 void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec)
1482 {
1483     Page* page = contextDocument()->frame()->page();
1484     if (!page) {
1485         ec = INVALID_ACCESS_ERR;
1486         return;
1487     }
1488     page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
1489 }
1490
1491 void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
1492 {
1493     Page* page = contextDocument()->frame()->page();
1494     if (!page) {
1495         ec = INVALID_ACCESS_ERR;
1496         return;
1497     }
1498
1499     page->inspectorController().setProfilerEnabled(enabled);
1500 }
1501 #endif // ENABLE(INSPECTOR)
1502
1503 bool Internals::hasGrammarMarker(int from, int length, ExceptionCode&)
1504 {
1505     Document* document = contextDocument();
1506     if (!document || !document->frame())
1507         return 0;
1508
1509     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1510 }
1511
1512 unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
1513 {
1514     Document* document = contextDocument();
1515     if (!document || !document->frame())
1516         return 0;
1517
1518     unsigned count = 0;
1519     Frame* frame = document->frame();
1520     if (frame->view()->scrollableAreas())
1521         count += frame->view()->scrollableAreas()->size();
1522
1523     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1524         if (child->view() && child->view()->scrollableAreas())
1525             count += child->view()->scrollableAreas()->size();
1526     }
1527
1528     return count;
1529 }
1530     
1531 bool Internals::isPageBoxVisible(int pageNumber, ExceptionCode& ec)
1532 {
1533     Document* document = contextDocument();
1534     if (!document) {
1535         ec = INVALID_ACCESS_ERR;
1536         return false;
1537     }
1538
1539     return document->isPageBoxVisible(pageNumber);
1540 }
1541
1542 // FIXME: Remove the document argument. It is almost always the same as
1543 // contextDocument(), with the exception of a few tests that pass a
1544 // different document, and could just make the call through another Internals
1545 // instance instead.
1546 String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
1547 {
1548     return layerTreeAsText(document, 0, ec);
1549 }
1550
1551 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
1552 {
1553     if (!document || !document->frame()) {
1554         ec = INVALID_ACCESS_ERR;
1555         return String();
1556     }
1557
1558     LayerTreeFlags layerTreeFlags = 0;
1559     if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
1560         layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
1561     if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
1562         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
1563     if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
1564         layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
1565     if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
1566         layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
1567     if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
1568         layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
1569
1570     return document->frame()->layerTreeAsText(layerTreeFlags);
1571 }
1572
1573 String Internals::repaintRectsAsText(ExceptionCode& ec) const
1574 {
1575     Document* document = contextDocument();
1576     if (!document || !document->frame()) {
1577         ec = INVALID_ACCESS_ERR;
1578         return String();
1579     }
1580
1581     return document->frame()->trackedRepaintRectsAsText();
1582 }
1583
1584 String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
1585 {
1586     Document* document = contextDocument();
1587     if (!document || !document->frame()) {
1588         ec = INVALID_ACCESS_ERR;
1589         return String();
1590     }
1591
1592     Page* page = document->page();
1593     if (!page)
1594         return String();
1595
1596     return page->scrollingStateTreeAsText();
1597 }
1598
1599 String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
1600 {
1601     Document* document = contextDocument();
1602     if (!document || !document->frame()) {
1603         ec = INVALID_ACCESS_ERR;
1604         return String();
1605     }
1606
1607     Page* page = document->page();
1608     if (!page)
1609         return String();
1610
1611     return page->synchronousScrollingReasonsAsText();
1612 }
1613
1614 PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(ExceptionCode& ec) const
1615 {
1616     Document* document = contextDocument();
1617     if (!document || !document->frame()) {
1618         ec = INVALID_ACCESS_ERR;
1619         return 0;
1620     }
1621
1622     Page* page = document->page();
1623     if (!page)
1624         return 0;
1625
1626     return page->nonFastScrollableRects(document->frame());
1627 }
1628
1629 void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
1630 {
1631     Document* document = contextDocument();
1632     if (!document) {
1633         ec = INVALID_ACCESS_ERR;
1634         return;
1635     }
1636
1637     CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
1638     if (!cachedResourceLoader)
1639         return;
1640     cachedResourceLoader->garbageCollectDocumentResources();
1641 }
1642
1643 void Internals::allowRoundingHacks() const
1644 {
1645     TextRun::setAllowsRoundingHacks(true);
1646 }
1647
1648 void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
1649 {
1650     Document* document = contextDocument();
1651     if (!document) {
1652         ec = INVALID_ACCESS_ERR;
1653         return;
1654     }
1655
1656     auto parsedSheet = StyleSheetContents::create(*document);
1657     parsedSheet.get().setIsUserStyleSheet(false);
1658     parsedSheet.get().parseString(css);
1659     document->styleSheetCollection().addAuthorSheet(std::move(parsedSheet));
1660 }
1661
1662 void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
1663 {
1664     Document* document = contextDocument();
1665     if (!document) {
1666         ec = INVALID_ACCESS_ERR;
1667         return;
1668     }
1669
1670     auto parsedSheet = StyleSheetContents::create(*document);
1671     parsedSheet.get().setIsUserStyleSheet(true);
1672     parsedSheet.get().parseString(css);
1673     document->styleSheetCollection().addUserSheet(std::move(parsedSheet));
1674 }
1675
1676 String Internals::counterValue(Element* element)
1677 {
1678     if (!element)
1679         return String();
1680
1681     return counterValueForElement(element);
1682 }
1683
1684 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
1685 {
1686     if (!element)
1687         return 0;
1688
1689     return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
1690 }
1691
1692 Vector<String> Internals::iconURLs(Document* document, int iconTypesMask) const
1693 {
1694     Vector<IconURL> iconURLs = document->iconURLs(iconTypesMask);
1695     Vector<String> array;
1696
1697     Vector<IconURL>::const_iterator iter(iconURLs.begin());
1698     for (; iter != iconURLs.end(); ++iter)
1699         array.append(iter->m_iconURL.string());
1700
1701     return array;
1702 }
1703
1704 Vector<String> Internals::shortcutIconURLs() const
1705 {
1706     return iconURLs(contextDocument(), Favicon);
1707 }
1708
1709 Vector<String> Internals::allIconURLs() const
1710 {
1711     return iconURLs(contextDocument(), Favicon | TouchIcon | TouchPrecomposedIcon);
1712 }
1713
1714 int Internals::numberOfPages(float pageWidth, float pageHeight)
1715 {
1716     if (!frame())
1717         return -1;
1718
1719     return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
1720 }
1721
1722 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
1723 {
1724     if (!frame()) {
1725         ec = INVALID_ACCESS_ERR;
1726         return String();
1727     }
1728
1729     return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
1730 }
1731
1732 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
1733 {
1734     if (!frame()) {
1735         ec = INVALID_ACCESS_ERR;
1736         return String();
1737     }
1738
1739     return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
1740 }
1741
1742 void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec)
1743 {
1744     Document* document = contextDocument();
1745     if (!document || !document->page()) {
1746         ec = INVALID_ACCESS_ERR;
1747         return;
1748     }
1749     Page* page = document->page();
1750     page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
1751 }
1752
1753 void Internals::setHeaderHeight(float height)
1754 {
1755     Document* document = contextDocument();
1756     if (!document || !document->view())
1757         return;
1758
1759     FrameView* frameView = document->view();
1760     frameView->setHeaderHeight(height);
1761 }
1762
1763 void Internals::setFooterHeight(float height)
1764 {
1765     Document* document = contextDocument();
1766     if (!document || !document->view())
1767         return;
1768
1769     FrameView* frameView = document->view();
1770     frameView->setFooterHeight(height);
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::applicationWillEnterForeground() const
2194 {
2195     MediaSessionManager::sharedManager().applicationWillEnterForeground();
2196 }
2197
2198 void Internals::applicationWillEnterBackground() const
2199 {
2200     MediaSessionManager::sharedManager().applicationWillEnterBackground();
2201 }
2202
2203 void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
2204 {
2205     MediaSession::MediaType mediaType = MediaSession::None;
2206     if (equalIgnoringCase(mediaTypeString, "Video"))
2207         mediaType = MediaSession::Video;
2208     else if (equalIgnoringCase(mediaTypeString, "Audio"))
2209         mediaType = MediaSession::Audio;
2210     else if (equalIgnoringCase(mediaTypeString, "WebAudio"))
2211         mediaType = MediaSession::WebAudio;
2212     else {
2213         ec = INVALID_ACCESS_ERR;
2214         return;
2215     }
2216
2217     MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType);
2218     MediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
2219
2220     restrictions = MediaSessionManager::NoRestrictions;
2221     
2222     if (equalIgnoringCase(restrictionsString, "ConcurrentPlaybackNotPermitted"))
2223         restrictions = MediaSessionManager::ConcurrentPlaybackNotPermitted;
2224     if (equalIgnoringCase(restrictionsString, "InlineVideoPlaybackRestricted"))
2225         restrictions += MediaSessionManager::InlineVideoPlaybackRestricted;
2226     if (equalIgnoringCase(restrictionsString, "MetadataPreloadingNotPermitted"))
2227         restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
2228     if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
2229         restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
2230     if (equalIgnoringCase(restrictionsString, "BackgroundPlaybackNotPermitted"))
2231         restrictions += MediaSessionManager::BackgroundPlaybackNotPermitted;
2232
2233     MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
2234 }
2235
2236 }