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