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