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