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