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