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