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