Simplify hitTestResultAtPoint and nodesFromRect APIs
[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 "ClientRect.h"
32 #include "ClientRectList.h"
33 #include "ComposedShadowTreeWalker.h"
34 #include "DOMStringList.h"
35 #include "Document.h"
36 #include "DocumentMarker.h"
37 #include "DocumentMarkerController.h"
38 #include "Element.h"
39 #include "ElementShadow.h"
40 #include "ExceptionCode.h"
41 #include "FormController.h"
42 #include "Frame.h"
43 #include "FrameView.h"
44 #include "HTMLContentElement.h"
45 #include "HTMLInputElement.h"
46 #include "HTMLNames.h"
47 #include "HTMLTextAreaElement.h"
48 #include "HistoryItem.h"
49 #include "InspectorConsoleAgent.h"
50 #include "InspectorController.h"
51 #include "InspectorCounters.h"
52 #include "InspectorInstrumentation.h"
53 #include "InspectorOverlay.h"
54 #include "InstrumentingAgents.h"
55 #include "InternalSettings.h"
56 #include "IntRect.h"
57 #include "Language.h"
58 #include "MallocStatistics.h"
59 #include "NodeRenderingContext.h"
60 #include "Page.h"
61 #include "PrintContext.h"
62 #include "Range.h"
63 #include "RenderObject.h"
64 #include "RenderTreeAsText.h"
65 #include "RuntimeEnabledFeatures.h"
66 #include "SchemeRegistry.h"
67 #include "Settings.h"
68 #include "ShadowRoot.h"
69 #include "SpellChecker.h"
70 #include "TextIterator.h"
71 #include "TreeScope.h"
72 #include "ViewportArguments.h"
73
74 #if ENABLE(INPUT_TYPE_COLOR)
75 #include "ColorChooser.h"
76 #endif
77
78 #if ENABLE(BATTERY_STATUS)
79 #include "BatteryController.h"
80 #endif
81
82 #if ENABLE(NETWORK_INFO)
83 #include "NetworkInfo.h"
84 #include "NetworkInfoController.h"
85 #endif
86
87 #if ENABLE(PAGE_POPUP)
88 #include "PagePopupController.h"
89 #endif
90
91 #if ENABLE(TOUCH_ADJUSTMENT)
92 #include "EventHandler.h"
93 #include "WebKitPoint.h"
94 #endif
95
96 #if PLATFORM(CHROMIUM)
97 #include "FilterOperation.h"
98 #include "FilterOperations.h"
99 #include "GraphicsLayer.h"
100 #include "GraphicsLayerChromium.h"
101 #include "RenderLayerBacking.h"
102 #endif
103
104 namespace WebCore {
105
106 using namespace HTMLNames;
107
108 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
109 {
110     if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
111         result = DocumentMarker::AllMarkers();
112     else if (equalIgnoringCase(markerType, "Spelling"))
113         result =  DocumentMarker::Spelling;
114     else if (equalIgnoringCase(markerType, "Grammar"))
115         result =  DocumentMarker::Grammar;
116     else if (equalIgnoringCase(markerType, "TextMatch"))
117         result =  DocumentMarker::TextMatch;
118     else if (equalIgnoringCase(markerType, "Replacement"))
119         result =  DocumentMarker::Replacement;
120     else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
121         result =  DocumentMarker::CorrectionIndicator;
122     else if (equalIgnoringCase(markerType, "RejectedCorrection"))
123         result =  DocumentMarker::RejectedCorrection;
124     else if (equalIgnoringCase(markerType, "Autocorrected"))
125         result =  DocumentMarker::Autocorrected;
126     else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
127         result =  DocumentMarker::SpellCheckingExemption;
128     else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
129         result =  DocumentMarker::DeletedAutocorrection;
130     else if (equalIgnoringCase(markerType, "DictationAlternatives"))
131         result =  DocumentMarker::DictationAlternatives;
132     else
133         return false;
134
135     return true;
136 }
137
138 static SpellChecker* spellchecker(Document* document)
139 {
140     if (!document || !document->frame() || !document->frame()->editor())
141         return 0;
142
143     return document->frame()->editor()->spellChecker();
144 }
145
146 const char* Internals::internalsId = "internals";
147
148 PassRefPtr<Internals> Internals::create(Document* document)
149 {
150     return adoptRef(new Internals(document));
151 }
152
153 Internals::~Internals()
154 {
155 }
156
157 Internals::Internals(Document* document)
158     : ContextDestructionObserver(document)
159 {
160 }
161
162 Document* Internals::contextDocument() const
163 {
164     return static_cast<Document*>(scriptExecutionContext());
165 }
166
167 Frame* Internals::frame() const
168 {
169     if (!contextDocument())
170         return 0;
171     return contextDocument()->frame();
172 }
173
174 InternalSettings* Internals::settings() const
175 {
176     Document* document = contextDocument();
177     if (!document)
178         return 0;
179     Page* page = document->page();
180     if (!page)
181         return 0;
182     return InternalSettings::from(page);
183 }
184
185 String Internals::address(Node* node)
186 {
187     char buf[32];
188     sprintf(buf, "%p", node);
189
190     return String(buf);
191 }
192
193 bool Internals::isPreloaded(Document* document, const String& url)
194 {
195     if (!document)
196         return false;
197
198     return document->cachedResourceLoader()->isPreloaded(url);
199 }
200
201 PassRefPtr<Element> Internals::createContentElement(Document* document, ExceptionCode& ec)
202 {
203     if (!document) {
204         ec = INVALID_ACCESS_ERR;
205         return 0;
206     }
207
208     return HTMLContentElement::create(document);
209 }
210
211 Element* Internals::getElementByIdInShadowRoot(Node* shadowRoot, const String& id, ExceptionCode& ec)
212 {
213     if (!shadowRoot || !shadowRoot->isShadowRoot()) {
214         ec = INVALID_ACCESS_ERR;
215         return 0;
216     }
217     return toShadowRoot(shadowRoot)->getElementById(id);
218 }
219
220 bool Internals::isValidContentSelect(Element* insertionPoint, ExceptionCode& ec)
221 {
222     if (!insertionPoint || !isInsertionPoint(insertionPoint)) {
223         ec = INVALID_ACCESS_ERR;
224         return false;
225     }
226
227     return toInsertionPoint(insertionPoint)->isSelectValid();
228 }
229
230 Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
231 {
232     if (!node) {
233         ec = INVALID_ACCESS_ERR;
234         return 0;
235     }
236
237     return node->treeScope()->rootNode();
238 }
239
240 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
241 {
242     if (!node) {
243         ec = INVALID_ACCESS_ERR;
244         return 0;
245     }
246     const TreeScope* parentTreeScope = node->treeScope()->parentTreeScope();
247     return parentTreeScope ? parentTreeScope->rootNode() : 0;
248 }
249
250 bool Internals::attached(Node* node, ExceptionCode& ec)
251 {
252     if (!node) {
253         ec = INVALID_ACCESS_ERR;
254         return false;
255     }
256
257     return node->attached();
258 }
259
260 Node* Internals::nextSiblingByWalker(Node* node, ExceptionCode& ec)
261 {
262     if (!node) {
263         ec = INVALID_ACCESS_ERR;
264         return 0;
265     }
266     ComposedShadowTreeWalker walker(node);
267     walker.nextSibling();
268     return walker.get();
269 }
270
271 Node* Internals::firstChildByWalker(Node* node, ExceptionCode& ec)
272 {
273     if (!node) {
274         ec = INVALID_ACCESS_ERR;
275         return 0;
276     }
277     ComposedShadowTreeWalker walker(node);
278     walker.firstChild();
279     return walker.get();
280 }
281
282 Node* Internals::lastChildByWalker(Node* node, ExceptionCode& ec)
283 {
284     if (!node) {
285         ec = INVALID_ACCESS_ERR;
286         return 0;
287     }
288     ComposedShadowTreeWalker walker(node);
289     walker.lastChild();
290     return walker.get();
291 }
292
293 Node* Internals::nextNodeByWalker(Node* node, ExceptionCode& ec)
294 {
295     if (!node) {
296         ec = INVALID_ACCESS_ERR;
297         return 0;
298     }
299     ComposedShadowTreeWalker walker(node);
300     walker.next();
301     return walker.get();
302 }
303
304 Node* Internals::previousNodeByWalker(Node* node, ExceptionCode& ec)
305 {
306     if (!node) {
307         ec = INVALID_ACCESS_ERR;
308         return 0;
309     }
310     ComposedShadowTreeWalker walker(node);
311     walker.previous();
312     return walker.get();
313 }
314
315 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
316 {
317     if (!element) {
318         ec = INVALID_ACCESS_ERR;
319         return String();
320     }
321
322     String representation = externalRepresentation(element);
323     if (representation.isEmpty()) {
324         ec = INVALID_ACCESS_ERR;
325         return String();
326     }
327
328     return representation;
329 }
330
331 size_t Internals::numberOfScopedHTMLStyleChildren(const Node* scope, ExceptionCode& ec) const
332 {
333     if (scope && (scope->isElementNode() || scope->isShadowRoot()))
334 #if ENABLE(STYLE_SCOPED)
335         return scope->numberOfScopedHTMLStyleChildren();
336 #else
337         return 0;
338 #endif
339
340     ec = INVALID_ACCESS_ERR;
341     return 0;
342 }
343
344 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
345 {
346     if (!host) {
347         ec = INVALID_ACCESS_ERR;
348         return 0;
349     }
350
351     if (ElementShadow* shadow = host->shadow())
352         return shadow->youngestShadowRoot();
353
354     return ShadowRoot::create(host, ec).get();
355 }
356
357 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::shadowRoot(Element* host, ExceptionCode& ec)
358 {
359     // FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot().
360     // https://bugs.webkit.org/show_bug.cgi?id=78465
361     return youngestShadowRoot(host, ec);
362 }
363
364 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::youngestShadowRoot(Element* host, ExceptionCode& ec)
365 {
366     if (!host) {
367         ec = INVALID_ACCESS_ERR;
368         return 0;
369     }
370
371     if (ElementShadow* shadow = host->shadow())
372         return shadow->youngestShadowRoot();
373     return 0;
374 }
375
376 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::oldestShadowRoot(Element* host, ExceptionCode& ec)
377 {
378     if (!host) {
379         ec = INVALID_ACCESS_ERR;
380         return 0;
381     }
382
383     if (ElementShadow* shadow = host->shadow())
384         return shadow->oldestShadowRoot();
385     return 0;
386 }
387
388 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::youngerShadowRoot(Node* shadow, ExceptionCode& ec)
389 {
390     if (!shadow || !shadow->isShadowRoot()) {
391         ec = INVALID_ACCESS_ERR;
392         return 0;
393     }
394
395     return toShadowRoot(shadow)->youngerShadowRoot();
396 }
397
398 Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::olderShadowRoot(Node* shadow, ExceptionCode& ec)
399 {
400     if (!shadow || !shadow->isShadowRoot()) {
401         ec = INVALID_ACCESS_ERR;
402         return 0;
403     }
404
405     return toShadowRoot(shadow)->olderShadowRoot();
406 }
407
408 Element* Internals::includerFor(Node* node, ExceptionCode& ec)
409 {
410     if (!node) {
411         ec = INVALID_ACCESS_ERR;
412         return 0;
413     }
414
415     return NodeRenderingContext(node).insertionPoint();
416 }
417
418 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
419 {
420     if (!element) {
421         ec = INVALID_ACCESS_ERR;
422         return String();
423     }
424
425     return element->shadowPseudoId().string();
426 }
427
428 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
429 {
430     if (!element) {
431         ec = INVALID_ACCESS_ERR;
432         return;
433     }
434
435     return element->setShadowPseudoId(id, ec);
436 }
437
438 String Internals::visiblePlaceholder(Element* element)
439 {
440     HTMLTextFormControlElement* textControl = toTextFormControl(element);
441     if (textControl && textControl->placeholderShouldBeVisible())
442         return textControl->placeholderElement()->textContent();
443     return String();
444 }
445
446 #if ENABLE(INPUT_TYPE_COLOR)
447 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
448 {
449     if (!element->hasTagName(inputTag))
450         return;
451     HTMLInputElement* inputElement = element->toInputElement();
452     if (!inputElement)
453         return;
454     inputElement->selectColorInColorChooser(Color(colorValue));
455 }
456 #endif
457
458 PassRefPtr<DOMStringList> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
459 {
460     HistoryItem* mainItem = frame()->loader()->history()->previousItem();
461     if (!mainItem) {
462         ec = INVALID_ACCESS_ERR;
463         return 0;
464     }
465     String uniqueName = frame()->tree()->uniqueName();
466     if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
467         ec = INVALID_ACCESS_ERR;
468         return 0;
469     }
470     const Vector<String>& state = mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
471     RefPtr<DOMStringList> stringList = DOMStringList::create();
472     for (unsigned i = 0; i < state.size(); ++i)
473         stringList->append(state[i]);
474     return stringList.release();
475 }
476
477 void Internals::setFormControlStateOfPreviousHistoryItem(PassRefPtr<DOMStringList> state, ExceptionCode& ec)
478 {
479     HistoryItem* mainItem = frame()->loader()->history()->previousItem();
480     if (!state || !mainItem) {
481         ec = INVALID_ACCESS_ERR;
482         return;
483     }
484     String uniqueName = frame()->tree()->uniqueName();
485     if (mainItem->target() == uniqueName)
486         mainItem->setDocumentState(*state.get());
487     else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
488         subItem->setDocumentState(*state.get());
489     else
490         ec = INVALID_ACCESS_ERR;
491 }
492
493 #if ENABLE(PAGE_POPUP)
494 PassRefPtr<PagePopupController> Internals::pagePopupController()
495 {
496     InternalSettings* settings = this->settings();
497     if (!settings)
498         return 0;
499     return settings->pagePopupController();
500 }
501 #endif
502
503 PassRefPtr<ClientRect> Internals::absoluteCaretBounds(Document* document, ExceptionCode& ec)
504 {
505     if (!document || !document->frame() || !document->frame()->selection()) {
506         ec = INVALID_ACCESS_ERR;
507         return ClientRect::create();
508     }
509
510     return ClientRect::create(document->frame()->selection()->absoluteCaretBounds());
511 }
512
513 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
514 {
515     if (!element) {
516         ec = INVALID_ACCESS_ERR;
517         return ClientRect::create();
518     }
519
520     element->document()->updateLayoutIgnorePendingStylesheets();
521     RenderObject* renderer = element->renderer();
522     if (!renderer)
523         return ClientRect::create();
524     return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
525 }
526
527 PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(Document* document, ExceptionCode& ec)
528 {
529 #if ENABLE(INSPECTOR)
530     if (!document || !document->page() || !document->page()->inspectorController()) {
531         ec = INVALID_ACCESS_ERR;
532         return ClientRectList::create();
533     }
534
535     Highlight highlight;
536     document->page()->inspectorController()->getHighlight(&highlight);
537     return ClientRectList::create(highlight.quads);
538 #else
539     UNUSED_PARAM(document);
540     UNUSED_PARAM(ec);
541     return ClientRectList::create();
542 #endif
543 }
544
545 #if PLATFORM(CHROMIUM)
546 void Internals::setBackgroundBlurOnNode(Node* node, int blurLength, ExceptionCode& ec)
547 {
548     if (!node) {
549         ec = INVALID_ACCESS_ERR;
550         return;
551     }
552
553     RenderObject* renderObject = node->renderer();
554     if (!renderObject) {
555         ec = INVALID_NODE_TYPE_ERR;
556         return;
557     }
558
559     RenderLayer* renderLayer = renderObject->enclosingLayer();
560     if (!renderLayer || !renderLayer->isComposited()) {
561         ec = INVALID_STATE_ERR;
562         return;
563     }
564
565     GraphicsLayer* graphicsLayer = renderLayer->backing()->graphicsLayer();
566     if (!graphicsLayer) {
567         ec = INVALID_NODE_TYPE_ERR;
568         return;
569     }
570
571     FilterOperations filters;
572     filters.operations().append(BlurFilterOperation::create(Length(blurLength, Fixed), FilterOperation::BLUR));
573     static_cast<GraphicsLayerChromium*>(graphicsLayer)->setBackgroundFilters(filters);
574 }
575 #else
576 void Internals::setBackgroundBlurOnNode(Node*, int, ExceptionCode&)
577 {
578 }
579 #endif
580
581 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
582 {
583     if (!node) {
584         ec = INVALID_ACCESS_ERR;
585         return 0;
586     }
587
588     DocumentMarker::MarkerTypes markerTypes = 0;
589     if (!markerTypesFrom(markerType, markerTypes)) {
590         ec = SYNTAX_ERR;
591         return 0;
592     }
593
594     return node->document()->markers()->markersFor(node, markerTypes).size();
595 }
596
597 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
598 {
599     if (!node) {
600         ec = INVALID_ACCESS_ERR;
601         return 0;
602     }
603
604     DocumentMarker::MarkerTypes markerTypes = 0;
605     if (!markerTypesFrom(markerType, markerTypes)) {
606         ec = SYNTAX_ERR;
607         return 0;
608     }
609
610     Vector<DocumentMarker*> markers = node->document()->markers()->markersFor(node, markerTypes);
611     if (markers.size() <= index)
612         return 0;
613     return markers[index];
614 }
615
616 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
617 {
618     DocumentMarker* marker = markerAt(node, markerType, index, ec);
619     if (!marker)
620         return 0;
621     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
622 }
623
624 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
625 {
626     DocumentMarker* marker = markerAt(node, markerType, index, ec);
627     if (!marker)
628         return String();
629     return marker->description();
630 }
631
632 void Internals::addTextMatchMarker(const Range* range, bool isActive)
633 {
634     range->ownerDocument()->updateLayoutIgnorePendingStylesheets();
635     range->ownerDocument()->markers()->addTextMatchMarker(range, isActive);
636 }
637
638 void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionCode& ec)
639 {
640     if (!document || !document->view()) {
641         ec = INVALID_ACCESS_ERR;
642         return;
643     }
644
645     FrameView* frameView = document->view();
646     bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
647     bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
648
649     frameView->setConstrainsScrollingToContentEdge(false);
650     frameView->setScrollbarsSuppressed(false);
651     frameView->setScrollOffsetFromInternals(IntPoint(x, y));
652     frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
653     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
654 }
655
656 void Internals::setPagination(Document*, const String& mode, int gap, int pageLength, ExceptionCode& ec)
657 {
658     settings()->setPagination(mode, gap, pageLength, ec);
659 }
660
661 String Internals::configurationForViewport(Document*, float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
662 {
663     return settings()->configurationForViewport(devicePixelRatio, deviceWidth, deviceHeight, availableWidth, availableHeight, ec);
664 }
665
666 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
667 {
668     if (!textField) {
669         ec = INVALID_ACCESS_ERR;
670         return false;
671     }
672
673     if (HTMLInputElement* inputElement = textField->toInputElement())
674         return inputElement->lastChangeWasUserEdit();
675
676     // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
677     if (textField->tagName() == "TEXTAREA")
678         return static_cast<HTMLTextAreaElement*>(textField)->lastChangeWasUserEdit();
679
680     ec = INVALID_NODE_TYPE_ERR;
681     return false;
682 }
683
684 String Internals::suggestedValue(Element* element, ExceptionCode& ec)
685 {
686     if (!element) {
687         ec = INVALID_ACCESS_ERR;
688         return String();
689     }
690
691     HTMLInputElement* inputElement = element->toInputElement();
692     if (!inputElement) {
693         ec = INVALID_NODE_TYPE_ERR;
694         return String();
695     }
696
697     return inputElement->suggestedValue();
698 }
699
700 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
701 {
702     if (!element) {
703         ec = INVALID_ACCESS_ERR;
704         return;
705     }
706
707     HTMLInputElement* inputElement = element->toInputElement();
708     if (!inputElement) {
709         ec = INVALID_NODE_TYPE_ERR;
710         return;
711     }
712
713     inputElement->setSuggestedValue(value);
714 }
715
716 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
717 {
718     if (!element) {
719         ec = INVALID_ACCESS_ERR;
720         return;
721     }
722
723     HTMLInputElement* inputElement = element->toInputElement();
724     if (!inputElement) {
725         ec = INVALID_NODE_TYPE_ERR;
726         return;
727     }
728
729     inputElement->setEditingValue(value);
730 }
731
732 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
733 {
734     if (!element || !element->document() || !element->document()->view()) {
735         ec = INVALID_ACCESS_ERR;
736         return;
737     }
738     FrameView* frameView = element->document()->view();
739     frameView->scrollElementToRect(element, IntRect(x, y, w, h));
740 }
741
742 void Internals::paintControlTints(Document* document, ExceptionCode& ec)
743 {
744     if (!document || !document->view()) {
745         ec = INVALID_ACCESS_ERR;
746         return;
747     }
748
749     FrameView* frameView = document->view();
750     frameView->paintControlTints();
751 }
752
753 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
754 {
755     if (!scope) {
756         ec = INVALID_ACCESS_ERR;
757         return 0;
758     }
759
760     return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
761 }
762
763 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
764 {
765     if (!scope || !range) {
766         ec = INVALID_ACCESS_ERR;
767         return 0;
768     }
769
770     size_t location = 0;
771     size_t unusedLength = 0;
772     TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
773     return location;
774 }
775
776 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
777 {
778     if (!scope || !range) {
779         ec = INVALID_ACCESS_ERR;
780         return 0;
781     }
782
783     size_t unusedLocation = 0;
784     size_t length = 0;
785     TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
786     return length;
787 }
788
789 String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
790 {
791     if (!range) {
792         ec = INVALID_ACCESS_ERR;
793         return String();
794     }
795
796     return range->text();
797 }
798
799 void Internals::setDelegatesScrolling(bool enabled, Document* document, ExceptionCode& ec)
800 {
801     // Delegate scrolling is valid only on mainframe's view.
802     if (!document || !document->view() || !document->page() || document->page()->mainFrame() != document->frame()) {
803         ec = INVALID_ACCESS_ERR;
804         return;
805     }
806
807     document->view()->setDelegatesScrolling(enabled);
808 }
809
810 #if ENABLE(TOUCH_ADJUSTMENT)
811 PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
812 {
813     if (!document || !document->frame()) {
814         ec = INVALID_ACCESS_ERR;
815         return 0;
816     }
817
818     IntSize radius(width / 2, height / 2);
819     IntPoint point(x + radius.width(), y + radius.height());
820
821     Node* targetNode;
822     IntPoint adjustedPoint;
823
824     bool foundNode = document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
825     if (foundNode)
826         return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
827
828     return 0;
829 }
830
831 Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
832 {
833     if (!document || !document->frame()) {
834         ec = INVALID_ACCESS_ERR;
835         return 0;
836     }
837
838     IntSize radius(width / 2, height / 2);
839     IntPoint point(x + radius.width(), y + radius.height());
840
841     Node* targetNode;
842     IntPoint adjustedPoint;
843     document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
844     return targetNode;
845 }
846
847 PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
848 {
849     if (!document || !document->frame()) {
850         ec = INVALID_ACCESS_ERR;
851         return 0;
852     }
853
854     IntSize radius(width / 2, height / 2);
855     IntPoint point(x + radius.width(), y + radius.height());
856
857     Node* targetNode = 0;
858     IntPoint adjustedPoint;
859
860     bool foundNode = document->frame()->eventHandler()->bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
861     if (foundNode)
862         return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
863
864     return WebKitPoint::create(x, y);
865 }
866
867 Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
868 {
869     if (!document || !document->frame()) {
870         ec = INVALID_ACCESS_ERR;
871         return 0;
872     }
873
874     IntSize radius(width / 2, height / 2);
875     IntPoint point(x + radius.width(), y + radius.height());
876
877     Node* targetNode = 0;
878     IntPoint adjustedPoint;
879     document->frame()->eventHandler()->bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
880     return targetNode;
881 }
882
883 PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionCode& ec)
884 {
885     if (!document || !document->frame()) {
886         ec = INVALID_ACCESS_ERR;
887         return 0;
888     }
889
890     IntSize radius(width / 2, height / 2);
891     IntPoint point(x + radius.width(), y + radius.height());
892
893     Node* targetNode;
894     IntRect zoomableArea;
895     bool foundNode = document->frame()->eventHandler()->bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode);
896     if (foundNode)
897         return ClientRect::create(zoomableArea);
898
899     return 0;
900 }
901 #endif
902
903
904 int Internals::lastSpellCheckRequestSequence(Document* document, ExceptionCode& ec)
905 {
906     SpellChecker* checker = spellchecker(document);
907
908     if (!checker) {
909         ec = INVALID_ACCESS_ERR;
910         return -1;
911     }
912
913     return checker->lastRequestSequence();
914 }
915
916 int Internals::lastSpellCheckProcessedSequence(Document* document, ExceptionCode& ec)
917 {
918     SpellChecker* checker = spellchecker(document);
919
920     if (!checker) {
921         ec = INVALID_ACCESS_ERR;
922         return -1;
923     }
924
925     return checker->lastProcessedSequence();
926 }
927
928 Vector<String> Internals::userPreferredLanguages() const
929 {
930     return settings()->userPreferredLanguages();
931 }
932
933 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
934 {
935     settings()->setUserPreferredLanguages(languages);
936 }
937
938 void Internals::setShouldDisplayTrackKind(Document*, const String& kind, bool enabled, ExceptionCode& ec)
939 {
940     settings()->setShouldDisplayTrackKind(kind, enabled, ec);
941 }
942
943 bool Internals::shouldDisplayTrackKind(Document*, const String& kind, ExceptionCode& ec)
944 {
945     return settings()->shouldDisplayTrackKind(kind, ec);
946 }
947
948 unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionCode& ec)
949 {
950     if (!document) {
951         ec = INVALID_ACCESS_ERR;
952         return 0;
953     }
954
955     return document->wheelEventHandlerCount();
956 }
957
958 unsigned Internals::touchEventHandlerCount(Document* document, ExceptionCode& ec)
959 {
960     if (!document) {
961         ec = INVALID_ACCESS_ERR;
962         return 0;
963     }
964
965     return document->touchEventHandlerCount();
966 }
967
968 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int x, int y, unsigned topPadding, unsigned rightPadding,
969     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
970 {
971     if (!document || !document->frame() || !document->frame()->view()) {
972         ec = INVALID_ACCESS_ERR;
973         return 0;
974     }
975     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
976     if (ignoreClipping)
977         hitType |= HitTestRequest::IgnoreClipping;
978     if (allowShadowContent)
979         hitType |= HitTestRequest::AllowShadowContent;
980     if (allowChildFrameContent)
981         hitType |= HitTestRequest::AllowChildFrameContent;
982
983     return document->nodesFromRect(x, y, topPadding, rightPadding, bottomPadding, leftPadding, hitType);
984 }
985
986 void Internals::emitInspectorDidBeginFrame()
987 {
988     InspectorInstrumentation::didBeginFrame(contextDocument()->frame()->page());
989 }
990
991 void Internals::emitInspectorDidCancelFrame()
992 {
993     InspectorInstrumentation::didCancelFrame(contextDocument()->frame()->page());
994 }
995
996 void Internals::setBatteryStatus(Document* document, const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
997 {
998     if (!document || !document->page()) {
999         ec = INVALID_ACCESS_ERR;
1000         return;
1001     }
1002
1003 #if ENABLE(BATTERY_STATUS)
1004     BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
1005 #else
1006     UNUSED_PARAM(eventType);
1007     UNUSED_PARAM(charging);
1008     UNUSED_PARAM(chargingTime);
1009     UNUSED_PARAM(dischargingTime);
1010     UNUSED_PARAM(level);
1011 #endif
1012 }
1013
1014 void Internals::setNetworkInformation(Document* document, const String& eventType, double bandwidth, bool metered, ExceptionCode& ec)
1015 {
1016     if (!document || !document->page()) {
1017         ec = INVALID_ACCESS_ERR;
1018         return;
1019     }
1020
1021 #if ENABLE(NETWORK_INFO)
1022     NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered));
1023 #else
1024     UNUSED_PARAM(eventType);
1025     UNUSED_PARAM(bandwidth);
1026     UNUSED_PARAM(metered);
1027 #endif
1028 }
1029
1030 bool Internals::hasSpellingMarker(Document* document, int from, int length, ExceptionCode&)
1031 {
1032     if (!document || !document->frame())
1033         return 0;
1034
1035     return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1036 }
1037     
1038 bool Internals::hasAutocorrectedMarker(Document* document, int from, int length, ExceptionCode&)
1039 {
1040     if (!document || !document->frame())
1041         return 0;
1042     
1043     return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
1044 }
1045
1046 #if ENABLE(INSPECTOR)
1047 unsigned Internals::numberOfLiveNodes() const
1048 {
1049     return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
1050 }
1051
1052 unsigned Internals::numberOfLiveDocuments() const
1053 {
1054     return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
1055 }
1056
1057 Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const
1058 {
1059     InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
1060     if (!instrumentingAgents)
1061         return Vector<String>();
1062     InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent();
1063     if (!consoleAgent)
1064         return Vector<String>();
1065     Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
1066     Vector<String> result(counts.size());
1067     for (size_t i = 0; i < counts.size(); i++)
1068         result[i] = String::number(counts[i]);
1069     return result;
1070 }
1071 #endif // ENABLE(INSPECTOR)
1072
1073 bool Internals::hasGrammarMarker(Document* document, int from, int length, ExceptionCode&)
1074 {
1075     if (!document || !document->frame())
1076         return 0;
1077
1078     return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1079 }
1080
1081 unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionCode&)
1082 {
1083     unsigned count = 0;
1084     Frame* frame = document->frame();
1085     if (frame->view()->scrollableAreas())
1086         count += frame->view()->scrollableAreas()->size();
1087
1088     for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
1089         if (child->view() && child->view()->scrollableAreas())
1090             count += child->view()->scrollableAreas()->size();
1091     }
1092
1093     return count;
1094 }
1095     
1096 bool Internals::isPageBoxVisible(Document* document, int pageNumber, ExceptionCode& ec)
1097 {
1098     if (!document) {
1099         ec = INVALID_ACCESS_ERR;
1100         return false;
1101     }
1102
1103     return document->isPageBoxVisible(pageNumber);
1104 }
1105
1106 void Internals::suspendAnimations(Document* document, ExceptionCode& ec) const
1107 {
1108     if (!document || !document->frame()) {
1109         ec = INVALID_ACCESS_ERR;
1110         return;
1111     }
1112
1113     AnimationController* controller = document->frame()->animation();
1114     if (!controller)
1115         return;
1116
1117     controller->suspendAnimations();
1118 }
1119
1120 void Internals::resumeAnimations(Document* document, ExceptionCode& ec) const
1121 {
1122     if (!document || !document->frame()) {
1123         ec = INVALID_ACCESS_ERR;
1124         return;
1125     }
1126
1127     AnimationController* controller = document->frame()->animation();
1128     if (!controller)
1129         return;
1130
1131     controller->resumeAnimations();
1132 }
1133
1134 void Internals::garbageCollectDocumentResources(Document* document, ExceptionCode& ec) const
1135 {
1136     if (!document) {
1137         ec = INVALID_ACCESS_ERR;
1138         return;
1139     }
1140
1141     CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
1142     if (!cachedResourceLoader)
1143         return;
1144     cachedResourceLoader->garbageCollectDocumentResources();
1145 }
1146
1147 void Internals::allowRoundingHacks() const
1148 {
1149     settings()->allowRoundingHacks();
1150 }
1151
1152 String Internals::counterValue(Element* element)
1153 {
1154     if (!element)
1155         return String();
1156
1157     return counterValueForElement(element);
1158 }
1159
1160 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
1161 {
1162     if (!element)
1163         return 0;
1164
1165     return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
1166 }
1167
1168 PassRefPtr<DOMStringList> Internals::iconURLs(Document* document) const
1169 {
1170     Vector<IconURL> iconURLs = document->iconURLs();
1171     RefPtr<DOMStringList> stringList = DOMStringList::create();
1172
1173     Vector<IconURL>::const_iterator iter(iconURLs.begin());
1174     for (; iter != iconURLs.end(); ++iter)
1175         stringList->append(iter->m_iconURL.string());
1176
1177     return stringList.release();
1178 }
1179
1180 int Internals::numberOfPages(float pageWidth, float pageHeight)
1181 {
1182     if (!frame())
1183         return -1;
1184
1185     return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
1186 }
1187
1188 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
1189 {
1190     if (!frame()) {
1191         ec = INVALID_ACCESS_ERR;
1192         return String();
1193     }
1194
1195     return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
1196 }
1197
1198 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
1199 {
1200     if (!frame()) {
1201         ec = INVALID_ACCESS_ERR;
1202         return String();
1203     }
1204
1205     return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
1206 }
1207
1208 #if ENABLE(FULLSCREEN_API)
1209 void Internals::webkitWillEnterFullScreenForElement(Document* document, Element* element)
1210 {
1211     if (!document)
1212         return;
1213     document->webkitWillEnterFullScreenForElement(element);
1214 }
1215
1216 void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element)
1217 {
1218     if (!document)
1219         return;
1220     document->webkitDidEnterFullScreenForElement(element);
1221 }
1222
1223 void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element)
1224 {
1225     if (!document)
1226         return;
1227     document->webkitWillExitFullScreenForElement(element);
1228 }
1229
1230 void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element)
1231 {
1232     if (!document)
1233         return;
1234     document->webkitDidExitFullScreenForElement(element);
1235 }
1236 #endif
1237
1238 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
1239 {
1240     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1241 }
1242
1243 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
1244 {
1245     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
1246 }
1247
1248 PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
1249 {
1250     return MallocStatistics::create();
1251 }
1252
1253 PassRefPtr<DOMStringList> Internals::getReferencedFilePaths() const
1254 {
1255     RefPtr<DOMStringList> stringList = DOMStringList::create();
1256     frame()->loader()->history()->saveDocumentAndScrollState();
1257     const Vector<String>& filePaths = FormController::getReferencedFilePaths(frame()->loader()->history()->currentItem()->documentState());
1258     for (size_t i = 0; i < filePaths.size(); ++i)
1259         stringList->append(filePaths[i]);
1260     return stringList.release();
1261 }
1262
1263 }