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