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