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