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