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