Remove remaining PLATFORM(CHROMIUM)-guarded code in WebCore
[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 "BackForwardController.h"
31 #include "CachedResourceLoader.h"
32 #include "Chrome.h"
33 #include "ChromeClient.h"
34 #include "ClientRect.h"
35 #include "ClientRectList.h"
36 #include "ComposedShadowTreeWalker.h"
37 #include "ContentDistributor.h"
38 #include "Cursor.h"
39 #include "DOMStringList.h"
40 #include "DOMWindow.h"
41 #include "Document.h"
42 #include "DocumentMarker.h"
43 #include "DocumentMarkerController.h"
44 #include "Element.h"
45 #include "ElementShadow.h"
46 #include "EventHandler.h"
47 #include "ExceptionCode.h"
48 #include "FormController.h"
49 #include "Frame.h"
50 #include "FrameLoader.h"
51 #include "FrameView.h"
52 #include "HTMLContentElement.h"
53 #include "HTMLInputElement.h"
54 #if ENABLE(VIDEO)
55 #include "HTMLMediaElement.h"
56 #endif
57 #include "HTMLNames.h"
58 #include "HTMLSelectElement.h"
59 #include "HTMLTextAreaElement.h"
60 #include "HistoryItem.h"
61 #include "InspectorClient.h"
62 #include "InspectorConsoleAgent.h"
63 #include "InspectorController.h"
64 #include "InspectorCounters.h"
65 #include "InspectorFrontendChannel.h"
66 #include "InspectorFrontendClientLocal.h"
67 #include "InspectorInstrumentation.h"
68 #include "InspectorOverlay.h"
69 #include "InstrumentingAgents.h"
70 #include "InternalSettings.h"
71 #include "IntRect.h"
72 #include "Language.h"
73 #include "MallocStatistics.h"
74 #include "MemoryCache.h"
75 #include "MockPagePopupDriver.h"
76 #include "NodeRenderingContext.h"
77 #include "Page.h"
78 #include "PrintContext.h"
79 #include "PseudoElement.h"
80 #include "Range.h"
81 #include "RenderMenuList.h"
82 #include "RenderObject.h"
83 #include "RenderTreeAsText.h"
84 #include "RuntimeEnabledFeatures.h"
85 #include "SchemeRegistry.h"
86 #include "ScrollingCoordinator.h"
87 #include "SelectRuleFeatureSet.h"
88 #include "SerializedScriptValue.h"
89 #include "Settings.h"
90 #include "ShadowRoot.h"
91 #include "SpellChecker.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 <wtf/text/StringBuffer.h>
99
100 #if ENABLE(INPUT_TYPE_COLOR)
101 #include "ColorChooser.h"
102 #endif
103
104 #if ENABLE(BATTERY_STATUS)
105 #include "BatteryController.h"
106 #endif
107
108 #if ENABLE(NETWORK_INFO)
109 #include "NetworkInfo.h"
110 #include "NetworkInfoController.h"
111 #endif
112
113 #if ENABLE(PROXIMITY_EVENTS)
114 #include "DeviceProximityController.h"
115 #endif
116
117 #if ENABLE(PAGE_POPUP)
118 #include "PagePopupController.h"
119 #endif
120
121 #if ENABLE(TOUCH_ADJUSTMENT)
122 #include "WebKitPoint.h"
123 #endif
124
125 #if ENABLE(MOUSE_CURSOR_SCALE)
126 #include <wtf/dtoa.h>
127 #endif
128
129 #if ENABLE(ENCRYPTED_MEDIA_V2)
130 #include "CDM.h"
131 #include "MockCDM.h"
132 #endif
133
134 #if ENABLE(VIDEO_TRACK)
135 #include "CaptionUserPreferences.h"
136 #include "PageGroup.h"
137 #endif
138
139 #if ENABLE(SPEECH_SYNTHESIS)
140 #include "DOMWindowSpeechSynthesis.h"
141 #include "PlatformSpeechSynthesizerMock.h"
142 #include "SpeechSynthesis.h"
143 #endif
144
145 namespace WebCore {
146
147 #if ENABLE(PAGE_POPUP)
148 static MockPagePopupDriver* s_pagePopupDriver = 0;
149 #endif
150
151 using namespace HTMLNames;
152
153 #if ENABLE(INSPECTOR)
154 class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
155 public:
156     InspectorFrontendClientDummy(InspectorController*, Page*);
157     virtual ~InspectorFrontendClientDummy() { }
158     virtual void attachWindow(DockSide) OVERRIDE { }
159     virtual void detachWindow() OVERRIDE { }
160
161     virtual String localizedStringsURL() OVERRIDE { return String(); }
162
163     virtual void bringToFront() OVERRIDE { }
164     virtual void closeWindow() OVERRIDE { }
165
166     virtual void inspectedURLChanged(const String&) OVERRIDE { }
167
168 protected:
169     virtual void setAttachedWindowHeight(unsigned) OVERRIDE { }
170     virtual void setAttachedWindowWidth(unsigned) OVERRIDE { }
171 };
172
173 InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
174     : InspectorFrontendClientLocal(controller, page, adoptPtr(new InspectorFrontendClientLocal::Settings()))
175 {
176 }
177
178 class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
179 public:
180     explicit InspectorFrontendChannelDummy(Page*);
181     virtual ~InspectorFrontendChannelDummy() { }
182     virtual bool sendMessageToFrontend(const String& message) OVERRIDE;
183
184 private:
185     Page* m_frontendPage;
186 };
187
188 InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
189     : m_frontendPage(page)
190 {
191 }
192
193 bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
194 {
195     return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
196 }
197 #endif // ENABLE(INSPECTOR)
198
199 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
200 {
201     if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
202         result = DocumentMarker::AllMarkers();
203     else if (equalIgnoringCase(markerType, "Spelling"))
204         result =  DocumentMarker::Spelling;
205     else if (equalIgnoringCase(markerType, "Grammar"))
206         result =  DocumentMarker::Grammar;
207     else if (equalIgnoringCase(markerType, "TextMatch"))
208         result =  DocumentMarker::TextMatch;
209     else if (equalIgnoringCase(markerType, "Replacement"))
210         result =  DocumentMarker::Replacement;
211     else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
212         result =  DocumentMarker::CorrectionIndicator;
213     else if (equalIgnoringCase(markerType, "RejectedCorrection"))
214         result =  DocumentMarker::RejectedCorrection;
215     else if (equalIgnoringCase(markerType, "Autocorrected"))
216         result =  DocumentMarker::Autocorrected;
217     else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
218         result =  DocumentMarker::SpellCheckingExemption;
219     else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
220         result =  DocumentMarker::DeletedAutocorrection;
221     else if (equalIgnoringCase(markerType, "DictationAlternatives"))
222         result =  DocumentMarker::DictationAlternatives;
223     else
224         return false;
225
226     return true;
227 }
228
229 static SpellChecker* spellchecker(Document* document)
230 {
231     if (!document || !document->frame() || !document->frame()->editor())
232         return 0;
233
234     return document->frame()->editor()->spellChecker();
235 }
236
237 const char* Internals::internalsId = "internals";
238
239 PassRefPtr<Internals> Internals::create(Document* document)
240 {
241     return adoptRef(new Internals(document));
242 }
243
244 Internals::~Internals()
245 {
246 }
247
248 void Internals::resetToConsistentState(Page* page)
249 {
250     ASSERT(page);
251
252     page->setPageScaleFactor(1, IntPoint(0, 0));
253     page->setPagination(Pagination());
254
255 #if USE(ACCELERATED_COMPOSITING)
256     FrameView* mainFrameView = page->mainFrame()->view();
257     if (mainFrameView) {
258         mainFrameView->setHeaderHeight(0);
259         mainFrameView->setFooterHeight(0);
260     }
261 #endif
262     TextRun::setAllowsRoundingHacks(false);
263     WebCore::overrideUserPreferredLanguages(Vector<String>());
264     WebCore::Settings::setUsesOverlayScrollbars(false);
265 #if ENABLE(PAGE_POPUP)
266     delete s_pagePopupDriver;
267     s_pagePopupDriver = 0;
268     if (page->chrome())
269         page->chrome()->client()->resetPagePopupDriver();
270 #endif
271 #if ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER)
272     if (page->inspectorController())
273         page->inspectorController()->setProfilerEnabled(false);
274 #endif
275 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
276     page->group().captionPreferences()->setTestingMode(false);
277 #endif
278     if (!page->mainFrame()->editor()->isContinuousSpellCheckingEnabled())
279         page->mainFrame()->editor()->toggleContinuousSpellChecking();
280     if (page->mainFrame()->editor()->isOverwriteModeEnabled())
281         page->mainFrame()->editor()->toggleOverwriteModeEnabled();
282 }
283
284 Internals::Internals(Document* document)
285     : ContextDestructionObserver(document)
286 {
287 #if ENABLE(VIDEO_TRACK) && !PLATFORM(WIN)
288     if (document && document->page())
289         document->page()->group().captionPreferences()->setTestingMode(true);
290 #endif
291 }
292
293 Document* Internals::contextDocument() const
294 {
295     return toDocument(scriptExecutionContext());
296 }
297
298 Frame* Internals::frame() const
299 {
300     if (!contextDocument())
301         return 0;
302     return contextDocument()->frame();
303 }
304
305 InternalSettings* Internals::settings() const
306 {
307     Document* document = contextDocument();
308     if (!document)
309         return 0;
310     Page* page = document->page();
311     if (!page)
312         return 0;
313     return InternalSettings::from(page);
314 }
315
316 unsigned Internals::workerThreadCount() const
317 {
318 #if ENABLE(WORKERS)
319     return WorkerThread::workerThreadCount();
320 #else
321     return 0;
322 #endif
323 }
324
325 String Internals::address(Node* node)
326 {
327     char buf[32];
328     sprintf(buf, "%p", node);
329
330     return String(buf);
331 }
332
333 bool Internals::isPreloaded(const String& url)
334 {
335     Document* document = contextDocument();
336     return document->cachedResourceLoader()->isPreloaded(url);
337 }
338
339 bool Internals::isLoadingFromMemoryCache(const String& url)
340 {
341     if (!contextDocument())
342         return false;
343     CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url));
344     return resource && resource->status() == CachedResource::Cached;
345 }
346
347 PassRefPtr<Element> Internals::createContentElement(ExceptionCode& ec)
348 {
349     Document* document = contextDocument();
350     if (!document) {
351         ec = INVALID_ACCESS_ERR;
352         return 0;
353     }
354
355 #if ENABLE(SHADOW_DOM)
356     return HTMLContentElement::create(document);
357 #else
358     return 0;
359 #endif
360 }
361
362 bool Internals::isValidContentSelect(Element* insertionPoint, ExceptionCode& ec)
363 {
364     if (!insertionPoint || !insertionPoint->isInsertionPoint()) {
365         ec = INVALID_ACCESS_ERR;
366         return false;
367     }
368
369 #if ENABLE(SHADOW_DOM)
370     return isHTMLContentElement(insertionPoint) && toHTMLContentElement(insertionPoint)->isSelectValid();
371 #else
372     return false;
373 #endif
374 }
375
376 Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
377 {
378     if (!node) {
379         ec = INVALID_ACCESS_ERR;
380         return 0;
381     }
382
383     return node->treeScope()->rootNode();
384 }
385
386 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
387 {
388     if (!node) {
389         ec = INVALID_ACCESS_ERR;
390         return 0;
391     }
392     const TreeScope* parentTreeScope = node->treeScope()->parentTreeScope();
393     return parentTreeScope ? parentTreeScope->rootNode() : 0;
394 }
395
396 bool Internals::hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionCode& ec)
397 {
398     if (!host || !host->shadow()) {
399         ec = INVALID_ACCESS_ERR;
400         return 0;
401     }
402
403     return host->shadow()->distributor().ensureSelectFeatureSet(host->shadow()).hasSelectorForId(idValue);
404 }
405
406 bool Internals::hasSelectorForClassInShadow(Element* host, const String& className, ExceptionCode& ec)
407 {
408     if (!host || !host->shadow()) {
409         ec = INVALID_ACCESS_ERR;
410         return 0;
411     }
412
413     return host->shadow()->distributor().ensureSelectFeatureSet(host->shadow()).hasSelectorForClass(className);
414 }
415
416 bool Internals::hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionCode& ec)
417 {
418     if (!host || !host->shadow()) {
419         ec = INVALID_ACCESS_ERR;
420         return 0;
421     }
422
423     return host->shadow()->distributor().ensureSelectFeatureSet(host->shadow()).hasSelectorForAttribute(attributeName);
424 }
425
426 bool Internals::hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionCode& ec)
427 {
428     if (!host || !host->shadow()) {
429         ec = INVALID_ACCESS_ERR;
430         return 0;
431     }
432
433     const SelectRuleFeatureSet& featureSet = host->shadow()->distributor().ensureSelectFeatureSet(host->shadow());
434     if (pseudoClass == "checked")
435         return featureSet.hasSelectorForChecked();
436     if (pseudoClass == "enabled")
437         return featureSet.hasSelectorForEnabled();
438     if (pseudoClass == "disabled")
439         return featureSet.hasSelectorForDisabled();
440     if (pseudoClass == "indeterminate")
441         return featureSet.hasSelectorForIndeterminate();
442     if (pseudoClass == "link")
443         return featureSet.hasSelectorForLink();
444     if (pseudoClass == "target")
445         return featureSet.hasSelectorForTarget();
446     if (pseudoClass == "visited")
447         return featureSet.hasSelectorForVisited();
448
449     ASSERT_NOT_REACHED();
450     return false;
451 }
452
453 unsigned Internals::numberOfActiveAnimations() const
454 {
455     Frame* contextFrame = frame();
456     if (AnimationController* controller = contextFrame->animation())
457         return controller->numberOfActiveAnimations(contextFrame->document());
458     return 0;
459 }
460
461 void Internals::suspendAnimations(Document* document, ExceptionCode& ec) const
462 {
463     if (!document || !document->frame()) {
464         ec = INVALID_ACCESS_ERR;
465         return;
466     }
467
468     AnimationController* controller = document->frame()->animation();
469     if (!controller)
470         return;
471
472     controller->suspendAnimations();
473 }
474
475 void Internals::resumeAnimations(Document* document, ExceptionCode& ec) const
476 {
477     if (!document || !document->frame()) {
478         ec = INVALID_ACCESS_ERR;
479         return;
480     }
481
482     AnimationController* controller = document->frame()->animation();
483     if (!controller)
484         return;
485
486     controller->resumeAnimations();
487 }
488
489 bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
490 {
491     if (!element || pauseTime < 0) {
492         ec = INVALID_ACCESS_ERR;
493         return false;
494     }
495     AnimationController* controller = frame()->animation();
496     return controller->pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
497 }
498
499 bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
500 {
501     if (!element || pauseTime < 0) {
502         ec = INVALID_ACCESS_ERR;
503         return false;
504     }
505
506     if (pseudoId != "before" && pseudoId != "after") {
507         ec = INVALID_ACCESS_ERR;
508         return false;
509     }
510
511     PseudoElement* pseudoElement = element->pseudoElement(pseudoId == "before" ? BEFORE : AFTER);
512     if (!pseudoElement) {
513         ec = INVALID_ACCESS_ERR;
514         return false;
515     }
516
517     return frame()->animation()->pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
518 }
519
520 bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
521 {
522     if (!element || pauseTime < 0) {
523         ec = INVALID_ACCESS_ERR;
524         return false;
525     }
526     AnimationController* controller = frame()->animation();
527     return controller->pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
528 }
529
530 bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
531 {
532     if (!element || pauseTime < 0) {
533         ec = INVALID_ACCESS_ERR;
534         return false;
535     }
536
537     if (pseudoId != "before" && pseudoId != "after") {
538         ec = INVALID_ACCESS_ERR;
539         return false;
540     }
541
542     PseudoElement* pseudoElement = element->pseudoElement(pseudoId == "before" ? BEFORE : AFTER);
543     if (!pseudoElement) {
544         ec = INVALID_ACCESS_ERR;
545         return false;
546     }
547
548     return frame()->animation()->pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
549 }
550
551 bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionCode& ec) const
552 {
553     if (root && root->isShadowRoot())
554         return ScopeContentDistribution::hasShadowElement(toShadowRoot(root));
555
556     ec = INVALID_ACCESS_ERR;
557     return 0;
558 }
559
560 bool Internals::hasContentElement(const Node* root, ExceptionCode& ec) const
561 {
562     if (root && root->isShadowRoot())
563         return ScopeContentDistribution::hasContentElement(toShadowRoot(root));
564
565     ec = INVALID_ACCESS_ERR;
566     return 0;
567 }
568
569 size_t Internals::countElementShadow(const Node* root, ExceptionCode& ec) const
570 {
571     if (!root || !root->isShadowRoot()) {
572         ec = INVALID_ACCESS_ERR;
573         return 0;
574     }
575
576     return ScopeContentDistribution::countElementShadow(toShadowRoot(root));
577 }
578
579 bool Internals::attached(Node* node, ExceptionCode& ec)
580 {
581     if (!node) {
582         ec = INVALID_ACCESS_ERR;
583         return false;
584     }
585
586     return node->attached();
587 }
588
589 Node* Internals::nextSiblingByWalker(Node* node, ExceptionCode& ec)
590 {
591     if (!node) {
592         ec = INVALID_ACCESS_ERR;
593         return 0;
594     }
595     ComposedShadowTreeWalker walker(node);
596     walker.nextSibling();
597     return walker.get();
598 }
599
600 Node* Internals::firstChildByWalker(Node* node, ExceptionCode& ec)
601 {
602     if (!node) {
603         ec = INVALID_ACCESS_ERR;
604         return 0;
605     }
606     ComposedShadowTreeWalker walker(node);
607     walker.firstChild();
608     return walker.get();
609 }
610
611 Node* Internals::lastChildByWalker(Node* node, ExceptionCode& ec)
612 {
613     if (!node) {
614         ec = INVALID_ACCESS_ERR;
615         return 0;
616     }
617     ComposedShadowTreeWalker walker(node);
618     walker.lastChild();
619     return walker.get();
620 }
621
622 Node* Internals::nextNodeByWalker(Node* node, ExceptionCode& ec)
623 {
624     if (!node) {
625         ec = INVALID_ACCESS_ERR;
626         return 0;
627     }
628     ComposedShadowTreeWalker walker(node);
629     walker.next();
630     return walker.get();
631 }
632
633 Node* Internals::previousNodeByWalker(Node* node, ExceptionCode& ec)
634 {
635     if (!node) {
636         ec = INVALID_ACCESS_ERR;
637         return 0;
638     }
639     ComposedShadowTreeWalker walker(node);
640     walker.previous();
641     return walker.get();
642 }
643
644 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
645 {
646     if (!element) {
647         ec = INVALID_ACCESS_ERR;
648         return String();
649     }
650
651     String representation = externalRepresentation(element);
652     if (representation.isEmpty()) {
653         ec = INVALID_ACCESS_ERR;
654         return String();
655     }
656
657     return representation;
658 }
659
660 size_t Internals::numberOfScopedHTMLStyleChildren(const Node* scope, ExceptionCode& ec) const
661 {
662     if (scope && (scope->isElementNode() || scope->isShadowRoot()))
663 #if ENABLE(STYLE_SCOPED)
664         return scope->numberOfScopedHTMLStyleChildren();
665 #else
666         return 0;
667 #endif
668
669     ec = INVALID_ACCESS_ERR;
670     return 0;
671 }
672
673 PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
674 {
675     if (!node) {
676         ec = INVALID_ACCESS_ERR;
677         return 0;
678     }
679
680     bool allowVisitedStyle = true;
681     return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
682 }
683
684 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
685 {
686     if (!host) {
687         ec = INVALID_ACCESS_ERR;
688         return 0;
689     }
690
691     if (ElementShadow* shadow = host->shadow())
692         return shadow->youngestShadowRoot();
693
694     return host->createShadowRoot(ec).get();
695 }
696
697 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
698 {
699     if (!host) {
700         ec = INVALID_ACCESS_ERR;
701         return 0;
702     }
703     return host->createShadowRoot(ec).get();
704 }
705
706 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::shadowRoot(Element* host, ExceptionCode& ec)
707 {
708     // FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot().
709     // https://bugs.webkit.org/show_bug.cgi?id=78465
710     return youngestShadowRoot(host, ec);
711 }
712
713 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::youngestShadowRoot(Element* host, ExceptionCode& ec)
714 {
715     if (!host) {
716         ec = INVALID_ACCESS_ERR;
717         return 0;
718     }
719
720     if (ElementShadow* shadow = host->shadow())
721         return shadow->youngestShadowRoot();
722     return 0;
723 }
724
725 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::oldestShadowRoot(Element* host, ExceptionCode& ec)
726 {
727     if (!host) {
728         ec = INVALID_ACCESS_ERR;
729         return 0;
730     }
731
732     if (ElementShadow* shadow = host->shadow())
733         return shadow->oldestShadowRoot();
734     return 0;
735 }
736
737 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::youngerShadowRoot(Node* shadow, ExceptionCode& ec)
738 {
739     if (!shadow || !shadow->isShadowRoot()) {
740         ec = INVALID_ACCESS_ERR;
741         return 0;
742     }
743
744     return toShadowRoot(shadow)->youngerShadowRoot();
745 }
746
747 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::olderShadowRoot(Node* shadow, ExceptionCode& ec)
748 {
749     if (!shadow || !shadow->isShadowRoot()) {
750         ec = INVALID_ACCESS_ERR;
751         return 0;
752     }
753
754     return toShadowRoot(shadow)->olderShadowRoot();
755 }
756
757 String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
758 {
759     if (!root || !root->isShadowRoot()) {
760         ec = INVALID_ACCESS_ERR;
761         return String();
762     }
763
764     switch (toShadowRoot(root)->type()) {
765     case ShadowRoot::UserAgentShadowRoot:
766         return String("UserAgentShadowRoot");
767     case ShadowRoot::AuthorShadowRoot:
768         return String("AuthorShadowRoot");
769     default:
770         ASSERT_NOT_REACHED();
771         return String("Unknown");
772     }
773 }
774
775 Element* Internals::includerFor(Node* node, ExceptionCode& ec)
776 {
777     if (!node) {
778         ec = INVALID_ACCESS_ERR;
779         return 0;
780     }
781
782     return NodeRenderingContext(node).insertionPoint();
783 }
784
785 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
786 {
787     if (!element) {
788         ec = INVALID_ACCESS_ERR;
789         return String();
790     }
791
792     return element->shadowPseudoId().string();
793 }
794
795 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
796 {
797     if (!element) {
798         ec = INVALID_ACCESS_ERR;
799         return;
800     }
801
802     return element->setPseudo(id);
803 }
804
805 String Internals::visiblePlaceholder(Element* element)
806 {
807     if (element && isHTMLTextFormControlElement(element)) {
808         if (toHTMLTextFormControlElement(element)->placeholderShouldBeVisible())
809             return toHTMLTextFormControlElement(element)->placeholderElement()->textContent();
810     }
811
812     return String();
813 }
814
815 #if ENABLE(INPUT_TYPE_COLOR)
816 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
817 {
818     if (!element->hasTagName(inputTag))
819         return;
820     HTMLInputElement* inputElement = element->toInputElement();
821     if (!inputElement)
822         return;
823     inputElement->selectColorInColorChooser(Color(colorValue));
824 }
825 #endif
826
827 Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
828 {
829     HistoryItem* mainItem = frame()->loader()->history()->previousItem();
830     if (!mainItem) {
831         ec = INVALID_ACCESS_ERR;
832         return Vector<String>();
833     }
834     String uniqueName = frame()->tree()->uniqueName();
835     if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
836         ec = INVALID_ACCESS_ERR;
837         return Vector<String>();
838     }
839     return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
840 }
841
842 void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
843 {
844     HistoryItem* mainItem = frame()->loader()->history()->previousItem();
845     if (!mainItem) {
846         ec = INVALID_ACCESS_ERR;
847         return;
848     }
849     String uniqueName = frame()->tree()->uniqueName();
850     if (mainItem->target() == uniqueName)
851         mainItem->setDocumentState(state);
852     else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
853         subItem->setDocumentState(state);
854     else
855         ec = INVALID_ACCESS_ERR;
856 }
857
858 #if ENABLE(SPEECH_SYNTHESIS)
859 void Internals::enableMockSpeechSynthesizer()
860 {
861     Document* document = contextDocument();
862     if (!document || !document->domWindow())
863         return;
864     SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(document->domWindow());
865     if (!synthesis)
866         return;
867     
868     synthesis->setPlatformSynthesizer(PlatformSpeechSynthesizerMock::create(synthesis));
869 }
870 #endif
871     
872 void Internals::setEnableMockPagePopup(bool enabled, ExceptionCode& ec)
873 {
874 #if ENABLE(PAGE_POPUP)
875     Document* document = contextDocument();
876     if (!document || !document->page() || !document->page()->chrome())
877         return;
878     Page* page = document->page();
879     if (!enabled) {
880         page->chrome()->client()->resetPagePopupDriver();
881         return;
882     }
883     if (!s_pagePopupDriver)
884         s_pagePopupDriver = MockPagePopupDriver::create(page->mainFrame()).leakPtr();
885     page->chrome()->client()->setPagePopupDriver(s_pagePopupDriver);
886 #else
887     UNUSED_PARAM(enabled);
888     UNUSED_PARAM(ec);
889 #endif
890 }
891
892 #if ENABLE(PAGE_POPUP)
893 PassRefPtr<PagePopupController> Internals::pagePopupController()
894 {
895     return s_pagePopupDriver ? s_pagePopupDriver->pagePopupController() : 0;
896 }
897 #endif
898
899 PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
900 {
901     Document* document = contextDocument();
902     if (!document || !document->frame() || !document->frame()->selection()) {
903         ec = INVALID_ACCESS_ERR;
904         return ClientRect::create();
905     }
906
907     return ClientRect::create(document->frame()->selection()->absoluteCaretBounds());
908 }
909
910 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
911 {
912     if (!element) {
913         ec = INVALID_ACCESS_ERR;
914         return ClientRect::create();
915     }
916
917     element->document()->updateLayoutIgnorePendingStylesheets();
918     RenderObject* renderer = element->renderer();
919     if (!renderer)
920         return ClientRect::create();
921     return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
922 }
923
924 PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(Document* document, ExceptionCode& ec)
925 {
926 #if ENABLE(INSPECTOR)
927     if (!document || !document->page() || !document->page()->inspectorController()) {
928         ec = INVALID_ACCESS_ERR;
929         return ClientRectList::create();
930     }
931
932     Highlight highlight;
933     document->page()->inspectorController()->getHighlight(&highlight);
934     return ClientRectList::create(highlight.quads);
935 #else
936     UNUSED_PARAM(document);
937     UNUSED_PARAM(ec);
938     return ClientRectList::create();
939 #endif
940 }
941
942 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
943 {
944     if (!node) {
945         ec = INVALID_ACCESS_ERR;
946         return 0;
947     }
948
949     DocumentMarker::MarkerTypes markerTypes = 0;
950     if (!markerTypesFrom(markerType, markerTypes)) {
951         ec = SYNTAX_ERR;
952         return 0;
953     }
954
955     return node->document()->markers()->markersFor(node, markerTypes).size();
956 }
957
958 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
959 {
960     if (!node) {
961         ec = INVALID_ACCESS_ERR;
962         return 0;
963     }
964
965     DocumentMarker::MarkerTypes markerTypes = 0;
966     if (!markerTypesFrom(markerType, markerTypes)) {
967         ec = SYNTAX_ERR;
968         return 0;
969     }
970
971     Vector<DocumentMarker*> markers = node->document()->markers()->markersFor(node, markerTypes);
972     if (markers.size() <= index)
973         return 0;
974     return markers[index];
975 }
976
977 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
978 {
979     DocumentMarker* marker = markerAt(node, markerType, index, ec);
980     if (!marker)
981         return 0;
982     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
983 }
984
985 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
986 {
987     DocumentMarker* marker = markerAt(node, markerType, index, ec);
988     if (!marker)
989         return String();
990     return marker->description();
991 }
992
993 void Internals::addTextMatchMarker(const Range* range, bool isActive)
994 {
995     range->ownerDocument()->updateLayoutIgnorePendingStylesheets();
996     range->ownerDocument()->markers()->addTextMatchMarker(range, isActive);
997 }
998
999 void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionCode& ec)
1000 {
1001     if (!document || !document->view()) {
1002         ec = INVALID_ACCESS_ERR;
1003         return;
1004     }
1005
1006     FrameView* frameView = document->view();
1007     bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
1008     bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
1009
1010     frameView->setConstrainsScrollingToContentEdge(false);
1011     frameView->setScrollbarsSuppressed(false);
1012     frameView->setScrollOffsetFromInternals(IntPoint(x, y));
1013     frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
1014     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
1015 }
1016
1017 void Internals::setPagination(Document* document, const String& mode, int gap, int pageLength, ExceptionCode& ec)
1018 {
1019     if (!document || !document->page()) {
1020         ec = INVALID_ACCESS_ERR;
1021         return;
1022     }
1023     Page* page = document->page();
1024
1025     Pagination pagination;
1026     if (mode == "Unpaginated")
1027         pagination.mode = Pagination::Unpaginated;
1028     else if (mode == "LeftToRightPaginated")
1029         pagination.mode = Pagination::LeftToRightPaginated;
1030     else if (mode == "RightToLeftPaginated")
1031         pagination.mode = Pagination::RightToLeftPaginated;
1032     else if (mode == "TopToBottomPaginated")
1033         pagination.mode = Pagination::TopToBottomPaginated;
1034     else if (mode == "BottomToTopPaginated")
1035         pagination.mode = Pagination::BottomToTopPaginated;
1036     else {
1037         ec = SYNTAX_ERR;
1038         return;
1039     }
1040
1041     pagination.gap = gap;
1042     pagination.pageLength = pageLength;
1043     page->setPagination(pagination);
1044 }
1045
1046 String Internals::configurationForViewport(Document* document, float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
1047 {
1048     if (!document || !document->page()) {
1049         ec = INVALID_ACCESS_ERR;
1050         return String();
1051     }
1052     Page* page = document->page();
1053
1054     const int defaultLayoutWidthForNonMobilePages = 980;
1055
1056     ViewportArguments arguments = page->viewportArguments();
1057     ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
1058     restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
1059     restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
1060
1061     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");
1062 }
1063
1064 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
1065 {
1066     if (!textField) {
1067         ec = INVALID_ACCESS_ERR;
1068         return false;
1069     }
1070
1071     if (HTMLInputElement* inputElement = textField->toInputElement())
1072         return inputElement->lastChangeWasUserEdit();
1073
1074     // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
1075     if (textField->tagName() == "TEXTAREA")
1076         return static_cast<HTMLTextAreaElement*>(textField)->lastChangeWasUserEdit();
1077
1078     ec = INVALID_NODE_TYPE_ERR;
1079     return false;
1080 }
1081
1082 bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
1083 {
1084     if (!element) {
1085         ec = INVALID_ACCESS_ERR;
1086         return false;
1087     }
1088
1089     if (HTMLInputElement* inputElement = element->toInputElement())
1090         return inputElement->shouldAutocomplete();
1091
1092     ec = INVALID_NODE_TYPE_ERR;
1093     return false;
1094 }
1095
1096 String Internals::suggestedValue(Element* element, ExceptionCode& ec)
1097 {
1098     if (!element) {
1099         ec = INVALID_ACCESS_ERR;
1100         return String();
1101     }
1102
1103     HTMLInputElement* inputElement = element->toInputElement();
1104     if (!inputElement) {
1105         ec = INVALID_NODE_TYPE_ERR;
1106         return String();
1107     }
1108
1109     return inputElement->suggestedValue();
1110 }
1111
1112 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
1113 {
1114     if (!element) {
1115         ec = INVALID_ACCESS_ERR;
1116         return;
1117     }
1118
1119     HTMLInputElement* inputElement = element->toInputElement();
1120     if (!inputElement) {
1121         ec = INVALID_NODE_TYPE_ERR;
1122         return;
1123     }
1124
1125     inputElement->setSuggestedValue(value);
1126 }
1127
1128 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
1129 {
1130     if (!element) {
1131         ec = INVALID_ACCESS_ERR;
1132         return;
1133     }
1134
1135     HTMLInputElement* inputElement = element->toInputElement();
1136     if (!inputElement) {
1137         ec = INVALID_NODE_TYPE_ERR;
1138         return;
1139     }
1140
1141     inputElement->setEditingValue(value);
1142 }
1143
1144 void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
1145 {
1146     HTMLInputElement* inputElement = element->toInputElement();
1147     if (!inputElement) {
1148         ec = INVALID_ACCESS_ERR;
1149         return;
1150     }
1151     inputElement->setAutofilled(enabled);
1152 }
1153
1154 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
1155 {
1156     if (!element || !element->document() || !element->document()->view()) {
1157         ec = INVALID_ACCESS_ERR;
1158         return;
1159     }
1160     FrameView* frameView = element->document()->view();
1161     frameView->scrollElementToRect(element, IntRect(x, y, w, h));
1162 }
1163
1164 void Internals::paintControlTints(Document* document, ExceptionCode& ec)
1165 {
1166     if (!document || !document->view()) {
1167         ec = INVALID_ACCESS_ERR;
1168         return;
1169     }
1170
1171     FrameView* frameView = document->view();
1172     frameView->paintControlTints();
1173 }
1174
1175 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
1176 {
1177     if (!scope) {
1178         ec = INVALID_ACCESS_ERR;
1179         return 0;
1180     }
1181
1182     return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
1183 }
1184
1185 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1186 {
1187     if (!scope || !range) {
1188         ec = INVALID_ACCESS_ERR;
1189         return 0;
1190     }
1191
1192     size_t location = 0;
1193     size_t unusedLength = 0;
1194     TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
1195     return location;
1196 }
1197
1198 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1199 {
1200     if (!scope || !range) {
1201         ec = INVALID_ACCESS_ERR;
1202         return 0;
1203     }
1204
1205     size_t unusedLocation = 0;
1206     size_t length = 0;
1207     TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
1208     return length;
1209 }
1210
1211 String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
1212 {
1213     if (!range) {
1214         ec = INVALID_ACCESS_ERR;
1215         return String();
1216     }
1217
1218     return range->text();
1219 }
1220
1221 void Internals::setDelegatesScrolling(bool enabled, Document* document, ExceptionCode& ec)
1222 {
1223     // Delegate scrolling is valid only on mainframe's view.
1224     if (!document || !document->view() || !document->page() || document->page()->mainFrame() != document->frame()) {
1225         ec = INVALID_ACCESS_ERR;
1226         return;
1227     }
1228
1229     document->view()->setDelegatesScrolling(enabled);
1230 }
1231
1232 #if ENABLE(TOUCH_ADJUSTMENT)
1233 PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
1234 {
1235     if (!document || !document->frame()) {
1236         ec = INVALID_ACCESS_ERR;
1237         return 0;
1238     }
1239
1240     IntSize radius(width / 2, height / 2);
1241     IntPoint point(x + radius.width(), y + radius.height());
1242
1243     Node* targetNode;
1244     IntPoint adjustedPoint;
1245
1246     bool foundNode = document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1247     if (foundNode)
1248         return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
1249
1250     return 0;
1251 }
1252
1253 Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
1254 {
1255     if (!document || !document->frame()) {
1256         ec = INVALID_ACCESS_ERR;
1257         return 0;
1258     }
1259
1260     IntSize radius(width / 2, height / 2);
1261     IntPoint point(x + radius.width(), y + radius.height());
1262
1263     Node* targetNode;
1264     IntPoint adjustedPoint;
1265     document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1266     return targetNode;
1267 }
1268
1269 PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
1270 {
1271     if (!document || !document->frame()) {
1272         ec = INVALID_ACCESS_ERR;
1273         return 0;
1274     }
1275
1276     IntSize radius(width / 2, height / 2);
1277     IntPoint point(x + radius.width(), y + radius.height());
1278
1279     Node* targetNode = 0;
1280     IntPoint adjustedPoint;
1281
1282     bool foundNode = document->frame()->eventHandler()->bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1283     if (foundNode)
1284         return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
1285
1286     return WebKitPoint::create(x, y);
1287 }
1288
1289 Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
1290 {
1291     if (!document || !document->frame()) {
1292         ec = INVALID_ACCESS_ERR;
1293         return 0;
1294     }
1295
1296     IntSize radius(width / 2, height / 2);
1297     IntPoint point(x + radius.width(), y + radius.height());
1298
1299     Node* targetNode = 0;
1300     IntPoint adjustedPoint;
1301     document->frame()->eventHandler()->bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1302     return targetNode;
1303 }
1304
1305 PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
1306 {
1307     if (!document || !document->frame()) {
1308         ec = INVALID_ACCESS_ERR;
1309         return 0;
1310     }
1311
1312     IntSize radius(width / 2, height / 2);
1313     IntPoint point(x + radius.width(), y + radius.height());
1314
1315     Node* targetNode;
1316     IntRect zoomableArea;
1317     bool foundNode = document->frame()->eventHandler()->bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode);
1318     if (foundNode)
1319         return ClientRect::create(zoomableArea);
1320
1321     return 0;
1322 }
1323 #endif
1324
1325
1326 int Internals::lastSpellCheckRequestSequence(Document* document, ExceptionCode& ec)
1327 {
1328     SpellChecker* checker = spellchecker(document);
1329
1330     if (!checker) {
1331         ec = INVALID_ACCESS_ERR;
1332         return -1;
1333     }
1334
1335     return checker->lastRequestSequence();
1336 }
1337
1338 int Internals::lastSpellCheckProcessedSequence(Document* document, ExceptionCode& ec)
1339 {
1340     SpellChecker* checker = spellchecker(document);
1341
1342     if (!checker) {
1343         ec = INVALID_ACCESS_ERR;
1344         return -1;
1345     }
1346
1347     return checker->lastProcessedSequence();
1348 }
1349
1350 Vector<String> Internals::userPreferredLanguages() const
1351 {
1352     return WebCore::userPreferredLanguages();
1353 }
1354
1355 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
1356 {
1357     WebCore::overrideUserPreferredLanguages(languages);
1358 }
1359
1360 unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionCode& ec)
1361 {
1362     if (!document) {
1363         ec = INVALID_ACCESS_ERR;
1364         return 0;
1365     }
1366
1367     return document->wheelEventHandlerCount();
1368 }
1369
1370 unsigned Internals::touchEventHandlerCount(Document* document, ExceptionCode& ec)
1371 {
1372     if (!document) {
1373         ec = INVALID_ACCESS_ERR;
1374         return 0;
1375     }
1376
1377     const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
1378     if (!touchHandlers)
1379         return 0;
1380
1381     unsigned count = 0;
1382     for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
1383         count += iter->value;
1384     return count;
1385 }
1386
1387 #if ENABLE(TOUCH_EVENT_TRACKING)
1388 PassRefPtr<ClientRectList> Internals::touchEventTargetClientRects(Document* document, ExceptionCode& ec)
1389 {
1390     if (!document || !document->view() || !document->page()) {
1391         ec = INVALID_ACCESS_ERR;
1392         return 0;
1393     }
1394     if (!document->page()->scrollingCoordinator())
1395         return ClientRectList::create();
1396
1397     document->updateLayoutIgnorePendingStylesheets();
1398
1399     Vector<IntRect> absoluteRects;
1400     document->page()->scrollingCoordinator()->computeAbsoluteTouchEventTargetRects(document, absoluteRects);
1401     Vector<FloatQuad> absoluteQuads(absoluteRects.size());
1402
1403     for (size_t i = 0; i < absoluteRects.size(); ++i)
1404         absoluteQuads[i] = FloatQuad(absoluteRects[i]);
1405
1406     return ClientRectList::create(absoluteQuads);
1407 }
1408 #endif
1409
1410 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int x, int y, unsigned topPadding, unsigned rightPadding,
1411     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
1412 {
1413     if (!document || !document->frame() || !document->frame()->view()) {
1414         ec = INVALID_ACCESS_ERR;
1415         return 0;
1416     }
1417
1418     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
1419     if (ignoreClipping)
1420         hitType |= HitTestRequest::IgnoreClipping;
1421     if (!allowShadowContent)
1422         hitType |= HitTestRequest::DisallowShadowContent;
1423     if (allowChildFrameContent)
1424         hitType |= HitTestRequest::AllowChildFrameContent;
1425
1426     return document->nodesFromRect(x, y, topPadding, rightPadding, bottomPadding, leftPadding, hitType);
1427 }
1428
1429 void Internals::emitInspectorDidBeginFrame()
1430 {
1431 #if ENABLE(INSPECTOR)
1432     InspectorController* inspectorController = contextDocument()->frame()->page()->inspectorController();
1433     inspectorController->didBeginFrame();
1434 #endif
1435 }
1436
1437 void Internals::emitInspectorDidCancelFrame()
1438 {
1439 #if ENABLE(INSPECTOR)
1440     InspectorController* inspectorController = contextDocument()->frame()->page()->inspectorController();
1441     inspectorController->didCancelFrame();
1442 #endif
1443 }
1444
1445 void Internals::setBatteryStatus(Document* document, const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
1446 {
1447     if (!document || !document->page()) {
1448         ec = INVALID_ACCESS_ERR;
1449         return;
1450     }
1451
1452 #if ENABLE(BATTERY_STATUS)
1453     BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
1454 #else
1455     UNUSED_PARAM(eventType);
1456     UNUSED_PARAM(charging);
1457     UNUSED_PARAM(chargingTime);
1458     UNUSED_PARAM(dischargingTime);
1459     UNUSED_PARAM(level);
1460 #endif
1461 }
1462
1463 void Internals::setNetworkInformation(Document* document, const String& eventType, double bandwidth, bool metered, ExceptionCode& ec)
1464 {
1465     if (!document || !document->page()) {
1466         ec = INVALID_ACCESS_ERR;
1467         return;
1468     }
1469
1470 #if ENABLE(NETWORK_INFO)
1471     NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered));
1472 #else
1473     UNUSED_PARAM(eventType);
1474     UNUSED_PARAM(bandwidth);
1475     UNUSED_PARAM(metered);
1476 #endif
1477 }
1478
1479 void Internals::setDeviceProximity(Document* document, const String& eventType, double value, double min, double max, ExceptionCode& ec)
1480 {
1481     if (!document || !document->page()) {
1482         ec = INVALID_ACCESS_ERR;
1483         return;
1484     }
1485
1486 #if ENABLE(PROXIMITY_EVENTS)
1487     DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
1488 #else
1489     UNUSED_PARAM(eventType);
1490     UNUSED_PARAM(value);
1491     UNUSED_PARAM(min);
1492     UNUSED_PARAM(max);
1493 #endif
1494 }
1495
1496 bool Internals::hasSpellingMarker(Document* document, int from, int length, ExceptionCode&)
1497 {
1498     if (!document || !document->frame())
1499         return 0;
1500
1501     return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1502 }
1503     
1504 bool Internals::hasAutocorrectedMarker(Document* document, int from, int length, ExceptionCode&)
1505 {
1506     if (!document || !document->frame())
1507         return 0;
1508     
1509     return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
1510 }
1511
1512 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
1513 {
1514     if (!contextDocument() || !contextDocument()->frame() || !contextDocument()->frame()->editor())
1515         return;
1516
1517     if (enabled != contextDocument()->frame()->editor()->isContinuousSpellCheckingEnabled())
1518         contextDocument()->frame()->editor()->toggleContinuousSpellChecking();
1519 }
1520
1521 bool Internals::isOverwriteModeEnabled(Document* document, ExceptionCode&)
1522 {
1523     if (!document || !document->frame())
1524         return 0;
1525
1526     return document->frame()->editor()->isOverwriteModeEnabled();
1527 }
1528
1529 void Internals::toggleOverwriteModeEnabled(Document* document, ExceptionCode&)
1530 {
1531     if (!document || !document->frame())
1532         return;
1533
1534     document->frame()->editor()->toggleOverwriteModeEnabled();
1535 }
1536
1537 #if ENABLE(INSPECTOR)
1538 unsigned Internals::numberOfLiveNodes() const
1539 {
1540     return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
1541 }
1542
1543 unsigned Internals::numberOfLiveDocuments() const
1544 {
1545     return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
1546 }
1547
1548 Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const
1549 {
1550     InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
1551     if (!instrumentingAgents)
1552         return Vector<String>();
1553     InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent();
1554     if (!consoleAgent)
1555         return Vector<String>();
1556     Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
1557     Vector<String> result(counts.size());
1558     for (size_t i = 0; i < counts.size(); i++)
1559         result[i] = String::number(counts[i]);
1560     return result;
1561 }
1562
1563 PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
1564 {
1565     Page* page = contextDocument()->frame()->page();
1566     ASSERT(page);
1567
1568     DOMWindow* window = page->mainFrame()->document()->domWindow();
1569     ASSERT(window);
1570
1571     m_frontendWindow = window->open(url, "", "", window, window);
1572     ASSERT(m_frontendWindow);
1573
1574     Page* frontendPage = m_frontendWindow->document()->page();
1575     ASSERT(frontendPage);
1576
1577     OwnPtr<InspectorFrontendClientDummy> frontendClient = adoptPtr(new InspectorFrontendClientDummy(page->inspectorController(), frontendPage));
1578
1579     frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient.release());
1580
1581     m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
1582
1583     page->inspectorController()->connectFrontend(m_frontendChannel.get());
1584
1585     return m_frontendWindow;
1586 }
1587
1588 void Internals::closeDummyInspectorFrontend()
1589 {
1590     Page* page = contextDocument()->frame()->page();
1591     ASSERT(page);
1592     ASSERT(m_frontendWindow);
1593
1594     page->inspectorController()->disconnectFrontend();
1595
1596     m_frontendChannel.release();
1597
1598     m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
1599     m_frontendWindow.release();
1600 }
1601
1602 void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec)
1603 {
1604     Page* page = contextDocument()->frame()->page();
1605     if (!page || !page->inspectorController()) {
1606         ec = INVALID_ACCESS_ERR;
1607         return;
1608     }
1609     page->inspectorController()->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
1610 }
1611
1612 void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
1613 {
1614     Page* page = contextDocument()->frame()->page();
1615     if (!page || !page->inspectorController()) {
1616         ec = INVALID_ACCESS_ERR;
1617         return;
1618     }
1619
1620     page->inspectorController()->setProfilerEnabled(enabled);
1621 }
1622 #endif // ENABLE(INSPECTOR)
1623
1624 bool Internals::hasGrammarMarker(Document* document, int from, int length, ExceptionCode&)
1625 {
1626     if (!document || !document->frame())
1627         return 0;
1628
1629     return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1630 }
1631
1632 unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionCode&)
1633 {
1634     unsigned count = 0;
1635     Frame* frame = document->frame();
1636     if (frame->view()->scrollableAreas())
1637         count += frame->view()->scrollableAreas()->size();
1638
1639     for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
1640         if (child->view() && child->view()->scrollableAreas())
1641             count += child->view()->scrollableAreas()->size();
1642     }
1643
1644     return count;
1645 }
1646     
1647 bool Internals::isPageBoxVisible(Document* document, int pageNumber, ExceptionCode& ec)
1648 {
1649     if (!document) {
1650         ec = INVALID_ACCESS_ERR;
1651         return false;
1652     }
1653
1654     return document->isPageBoxVisible(pageNumber);
1655 }
1656
1657 String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
1658 {
1659     return layerTreeAsText(document, 0, ec);
1660 }
1661
1662 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
1663 {
1664     if (!document || !document->frame()) {
1665         ec = INVALID_ACCESS_ERR;
1666         return String();
1667     }
1668
1669     LayerTreeFlags layerTreeFlags = 0;
1670     if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
1671         layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
1672     if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
1673         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
1674     if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
1675         layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
1676     if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
1677         layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
1678
1679     return document->frame()->layerTreeAsText(layerTreeFlags);
1680 }
1681
1682 String Internals::repaintRectsAsText(Document* document, ExceptionCode& ec) const
1683 {
1684     if (!document || !document->frame()) {
1685         ec = INVALID_ACCESS_ERR;
1686         return String();
1687     }
1688
1689     return document->frame()->trackedRepaintRectsAsText();
1690 }
1691
1692 String Internals::scrollingStateTreeAsText(Document* document, ExceptionCode& ec) const
1693 {
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->scrollingStateTreeAsText();
1704 }
1705
1706 String Internals::mainThreadScrollingReasons(Document* document, ExceptionCode& ec) const
1707 {
1708     if (!document || !document->frame()) {
1709         ec = INVALID_ACCESS_ERR;
1710         return String();
1711     }
1712
1713     Page* page = document->page();
1714     if (!page)
1715         return String();
1716
1717     return page->mainThreadScrollingReasonsAsText();
1718 }
1719
1720 PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(Document* document, ExceptionCode& ec) const
1721 {
1722     if (!document || !document->frame()) {
1723         ec = INVALID_ACCESS_ERR;
1724         return 0;
1725     }
1726
1727     Page* page = document->page();
1728     if (!page)
1729         return 0;
1730
1731     return page->nonFastScrollableRects(document->frame());
1732 }
1733
1734 void Internals::garbageCollectDocumentResources(Document* document, ExceptionCode& ec) const
1735 {
1736     if (!document) {
1737         ec = INVALID_ACCESS_ERR;
1738         return;
1739     }
1740
1741     CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
1742     if (!cachedResourceLoader)
1743         return;
1744     cachedResourceLoader->garbageCollectDocumentResources();
1745 }
1746
1747 void Internals::allowRoundingHacks() const
1748 {
1749     TextRun::setAllowsRoundingHacks(true);
1750 }
1751
1752 void Internals::insertAuthorCSS(Document* document, const String& css) const
1753 {
1754     RefPtr<StyleSheetContents> parsedSheet = StyleSheetContents::create(document);
1755     parsedSheet->setIsUserStyleSheet(false);
1756     parsedSheet->parseString(css);
1757     document->styleSheetCollection()->addAuthorSheet(parsedSheet);
1758 }
1759
1760 void Internals::insertUserCSS(Document* document, const String& css) const
1761 {
1762     RefPtr<StyleSheetContents> parsedSheet = StyleSheetContents::create(document);
1763     parsedSheet->setIsUserStyleSheet(true);
1764     parsedSheet->parseString(css);
1765     document->styleSheetCollection()->addUserSheet(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(Document* document) const
1797 {
1798     return iconURLs(document, Favicon);
1799 }
1800
1801 Vector<String> Internals::allIconURLs(Document* document) const
1802 {
1803     return iconURLs(document, 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(Document* document, float height)
1846 {
1847     if (!document || !document->view())
1848         return;
1849 #if USE(ACCELERATED_COMPOSITING)
1850     FrameView* frameView = document->view();
1851     frameView->setHeaderHeight(height);
1852 #endif
1853 }
1854
1855 void Internals::setFooterHeight(Document* document, float height)
1856 {
1857     if (!document || !document->view())
1858         return;
1859 #if USE(ACCELERATED_COMPOSITING)
1860     FrameView* frameView = document->view();
1861     frameView->setFooterHeight(height);
1862 #endif
1863 }
1864
1865 #if ENABLE(FULLSCREEN_API)
1866 void Internals::webkitWillEnterFullScreenForElement(Document* document, Element* element)
1867 {
1868     if (!document)
1869         return;
1870     document->webkitWillEnterFullScreenForElement(element);
1871 }
1872
1873 void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element)
1874 {
1875     if (!document)
1876         return;
1877     document->webkitDidEnterFullScreenForElement(element);
1878 }
1879
1880 void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element)
1881 {
1882     if (!document)
1883         return;
1884     document->webkitWillExitFullScreenForElement(element);
1885 }
1886
1887 void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element)
1888 {
1889     if (!document)
1890         return;
1891     document->webkitDidExitFullScreenForElement(element);
1892 }
1893 #endif
1894
1895 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
1896 {
1897     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1898 }
1899
1900 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
1901 {
1902     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
1903 }
1904
1905 PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
1906 {
1907     return MallocStatistics::create();
1908 }
1909
1910 PassRefPtr<TypeConversions> Internals::typeConversions() const
1911 {
1912     return TypeConversions::create();
1913 }
1914
1915 Vector<String> Internals::getReferencedFilePaths() const
1916 {
1917     frame()->loader()->history()->saveDocumentAndScrollState();
1918     return FormController::getReferencedFilePaths(frame()->loader()->history()->currentItem()->documentState());
1919 }
1920
1921 void Internals::startTrackingRepaints(Document* document, ExceptionCode& ec)
1922 {
1923     if (!document || !document->view()) {
1924         ec = INVALID_ACCESS_ERR;
1925         return;
1926     }
1927
1928     FrameView* frameView = document->view();
1929     frameView->setTracksRepaints(true);
1930 }
1931
1932 void Internals::stopTrackingRepaints(Document* document, ExceptionCode& ec)
1933 {
1934     if (!document || !document->view()) {
1935         ec = INVALID_ACCESS_ERR;
1936         return;
1937     }
1938
1939     FrameView* frameView = document->view();
1940     frameView->setTracksRepaints(false);
1941 }
1942
1943 #if USE(LAZY_NATIVE_CURSOR)
1944 static const char* cursorTypeToString(Cursor::Type cursorType)
1945 {
1946     switch (cursorType) {
1947     case Cursor::Pointer: return "Pointer";
1948     case Cursor::Cross: return "Cross";
1949     case Cursor::Hand: return "Hand";
1950     case Cursor::IBeam: return "IBeam";
1951     case Cursor::Wait: return "Wait";
1952     case Cursor::Help: return "Help";
1953     case Cursor::EastResize: return "EastResize";
1954     case Cursor::NorthResize: return "NorthResize";
1955     case Cursor::NorthEastResize: return "NorthEastResize";
1956     case Cursor::NorthWestResize: return "NorthWestResize";
1957     case Cursor::SouthResize: return "SouthResize";
1958     case Cursor::SouthEastResize: return "SouthEastResize";
1959     case Cursor::SouthWestResize: return "SouthWestResize";
1960     case Cursor::WestResize: return "WestResize";
1961     case Cursor::NorthSouthResize: return "NorthSouthResize";
1962     case Cursor::EastWestResize: return "EastWestResize";
1963     case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
1964     case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
1965     case Cursor::ColumnResize: return "ColumnResize";
1966     case Cursor::RowResize: return "RowResize";
1967     case Cursor::MiddlePanning: return "MiddlePanning";
1968     case Cursor::EastPanning: return "EastPanning";
1969     case Cursor::NorthPanning: return "NorthPanning";
1970     case Cursor::NorthEastPanning: return "NorthEastPanning";
1971     case Cursor::NorthWestPanning: return "NorthWestPanning";
1972     case Cursor::SouthPanning: return "SouthPanning";
1973     case Cursor::SouthEastPanning: return "SouthEastPanning";
1974     case Cursor::SouthWestPanning: return "SouthWestPanning";
1975     case Cursor::WestPanning: return "WestPanning";
1976     case Cursor::Move: return "Move";
1977     case Cursor::VerticalText: return "VerticalText";
1978     case Cursor::Cell: return "Cell";
1979     case Cursor::ContextMenu: return "ContextMenu";
1980     case Cursor::Alias: return "Alias";
1981     case Cursor::Progress: return "Progress";
1982     case Cursor::NoDrop: return "NoDrop";
1983     case Cursor::Copy: return "Copy";
1984     case Cursor::None: return "None";
1985     case Cursor::NotAllowed: return "NotAllowed";
1986     case Cursor::ZoomIn: return "ZoomIn";
1987     case Cursor::ZoomOut: return "ZoomOut";
1988     case Cursor::Grab: return "Grab";
1989     case Cursor::Grabbing: return "Grabbing";
1990     case Cursor::Custom: return "Custom";
1991     }
1992
1993     ASSERT_NOT_REACHED();
1994     return "UNKNOWN";
1995 }
1996 #endif
1997
1998 String Internals::getCurrentCursorInfo(Document* document, ExceptionCode& ec)
1999 {
2000     if (!document || !document->frame()) {
2001         ec = INVALID_ACCESS_ERR;
2002         return String();
2003     }
2004
2005     Cursor cursor = document->frame()->eventHandler()->currentMouseCursor();
2006
2007 #if USE(LAZY_NATIVE_CURSOR)
2008     StringBuilder result;
2009     result.append("type=");
2010     result.append(cursorTypeToString(cursor.type()));
2011     result.append(" hotSpot=");
2012     result.appendNumber(cursor.hotSpot().x());
2013     result.append(",");
2014     result.appendNumber(cursor.hotSpot().y());
2015     if (cursor.image()) {
2016         IntSize size = cursor.image()->size();
2017         result.append(" image=");
2018         result.appendNumber(size.width());
2019         result.append("x");
2020         result.appendNumber(size.height());
2021     }
2022 #if ENABLE(MOUSE_CURSOR_SCALE)
2023     if (cursor.imageScaleFactor() != 1) {
2024         result.append(" scale=");
2025         NumberToStringBuffer buffer;
2026         result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
2027     }
2028 #endif
2029     return result.toString();
2030 #else
2031     return "FAIL: Cursor details not available on this platform.";
2032 #endif
2033 }
2034
2035 PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
2036 {
2037     Vector<uint8_t> bytes = value->data();
2038     return ArrayBuffer::create(bytes.data(), bytes.size());
2039 }
2040
2041 PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
2042 {
2043     Vector<uint8_t> bytes;
2044     bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
2045     return SerializedScriptValue::adopt(bytes);
2046 }
2047
2048 void Internals::setUsesOverlayScrollbars(bool enabled)
2049 {
2050     WebCore::Settings::setUsesOverlayScrollbars(enabled);
2051 }
2052
2053 void Internals::forceReload(bool endToEnd)
2054 {
2055     frame()->loader()->reload(endToEnd);
2056 }
2057
2058 #if ENABLE(ENCRYPTED_MEDIA_V2)
2059 void Internals::initializeMockCDM()
2060 {
2061     CDM::registerCDMFactory(MockCDM::create, MockCDM::supportsKeySytem);
2062 }
2063 #endif
2064
2065 String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
2066 {
2067     if (!element) {
2068         ec = INVALID_ACCESS_ERR;
2069         return String();
2070     }
2071     return WebCore::markerTextForListItem(element);
2072 }
2073
2074 String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
2075 {
2076     if (!element) {
2077         ec = INVALID_ACCESS_ERR;
2078         return String();
2079     }
2080     return element->imageSourceURL();
2081 }
2082
2083 #if ENABLE(VIDEO)
2084 void Internals::simulateAudioInterruption(Node* node)
2085 {
2086 #if USE(GSTREAMER)
2087     HTMLMediaElement* element = toMediaElement(node);
2088     element->player()->simulateAudioInterruption();
2089 #else
2090     UNUSED_PARAM(node);
2091 #endif
2092 }
2093 #endif
2094
2095 bool Internals::isSelectPopupVisible(Node* node)
2096 {
2097     if (!isHTMLSelectElement(node))
2098         return false;
2099
2100     HTMLSelectElement* select = toHTMLSelectElement(node);
2101
2102     RenderObject* renderer = select->renderer();
2103     if (!renderer->isMenuList())
2104         return false;
2105
2106     RenderMenuList* menuList = toRenderMenuList(renderer);
2107     return menuList->popupIsVisible();
2108 }
2109
2110 }