REGRESSION(r94274): FormManagerTest.PreviewForm and FillFormNonEmptyField fail on...
[WebKit-https.git] / Source / WebCore / testing / Internals.cpp
1 /*
2  * Copyright (C) 2011 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 "CachedResourceLoader.h"
30 #include "ClientRect.h"
31 #include "Document.h"
32 #include "DocumentMarkerController.h"
33 #include "Element.h"
34 #include "ExceptionCode.h"
35 #include "HTMLInputElement.h"
36 #include "HTMLNames.h"
37 #include "HTMLTextAreaElement.h"
38 #include "InspectorController.h"
39 #include "MemoryCache.h"
40 #include "NodeRenderingContext.h"
41 #include "Page.h"
42 #include "Range.h"
43 #include "RenderObject.h"
44 #include "RenderTreeAsText.h"
45 #include "Settings.h"
46 #include "ShadowContentElement.h"
47 #include "ShadowRoot.h"
48
49 #if ENABLE(INPUT_COLOR)
50 #include "ColorChooser.h"
51 #endif
52
53 namespace WebCore {
54
55 const char* Internals::internalsId = "internals";
56
57 PassRefPtr<Internals> Internals::create()
58 {
59     return adoptRef(new Internals);
60 }
61
62 Internals::~Internals()
63 {
64 }
65
66 Internals::Internals()
67     : passwordEchoDurationInSecondsBackedUp(false)
68     , passwordEchoEnabledBackedUp(false)
69 {
70 }
71
72 bool Internals::isPreloaded(Document* document, const String& url)
73 {
74     if (!document)
75         return false;
76
77     return document->cachedResourceLoader()->isPreloaded(url);
78 }
79
80 PassRefPtr<Element> Internals::createShadowContentElement(Document* document, ExceptionCode& ec)
81 {
82     if (!document) {
83         ec = INVALID_ACCESS_ERR;
84         return 0;
85     }
86
87     return ShadowContentElement::create(document);
88 }
89
90 Element* Internals::getElementByIdInShadowRoot(Node* shadowRoot, const String& id, ExceptionCode& ec)
91 {
92     if (!shadowRoot || !shadowRoot->isShadowRoot()) {
93         ec = INVALID_ACCESS_ERR;
94         return 0;
95     }
96     return toShadowRoot(shadowRoot)->getElementById(id);
97 }
98
99 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
100 {
101     if (!element) {
102         ec = INVALID_ACCESS_ERR;
103         return String();
104     }
105
106     String representation = externalRepresentation(element);
107     if (representation.isEmpty()) {
108         ec = INVALID_ACCESS_ERR;
109         return String();
110     }
111
112     return representation;
113 }
114
115 Node* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
116 {
117     if (!host) {
118         ec = INVALID_ACCESS_ERR;
119         return 0;
120     }
121
122     return host->ensureShadowRoot();
123 }
124
125 Node* Internals::shadowRoot(Element* host, ExceptionCode& ec)
126 {
127     if (!host) {
128         ec = INVALID_ACCESS_ERR;
129         return 0;
130     }
131
132     return host->shadowRoot();
133 }
134
135 void Internals::removeShadowRoot(Element* host, ExceptionCode& ec)
136 {
137     if (!host) {
138         ec = INVALID_ACCESS_ERR;
139         return;
140     }
141
142     host->removeShadowRoot();
143 }
144
145 Element* Internals::includerFor(Node* node, ExceptionCode& ec)
146 {
147     if (!node) {
148         ec = INVALID_ACCESS_ERR;
149         return 0;
150     }
151
152     return NodeRenderingContext(node).includer();
153 }
154
155 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
156 {
157     if (!element) {
158         ec = INVALID_ACCESS_ERR;
159         return String();
160     }
161
162     return element->shadowPseudoId().string();
163 }
164
165 void Internals::disableMemoryCache(bool disabled)
166 {
167     WebCore::memoryCache()->setDisabled(disabled);
168 }
169
170 #if ENABLE(INPUT_COLOR)
171 bool Internals::connectColorChooserClient(Element* element)
172 {
173     if (!element->hasTagName(HTMLNames::inputTag))
174         return false;
175     HTMLInputElement* inputElement = element->toInputElement();
176     if (!inputElement)
177         return false;
178     return inputElement->connectToColorChooser();
179 }
180
181 void Internals::selectColorInColorChooser(const String& colorValue)
182 {
183     ColorChooser::chooser()->colorSelected(Color(colorValue));
184 }
185 #endif
186
187 #if ENABLE(INSPECTOR)
188 void Internals::setInspectorResourcesDataSizeLimits(Document* document, int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec)
189 {
190     if (!document || !document->page() || !document->page()->inspectorController()) {
191         ec = INVALID_ACCESS_ERR;
192         return;
193     }
194     document->page()->inspectorController()->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
195 }
196 #endif
197
198 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
199 {
200     if (!element) {
201         ec = INVALID_ACCESS_ERR;
202         return ClientRect::create();
203     }
204
205     element->document()->updateLayoutIgnorePendingStylesheets();
206     RenderObject* renderer = element->renderer();
207     if (!renderer)
208         return ClientRect::create();
209     return ClientRect::create(renderer->absoluteBoundingBoxRect());
210 }
211
212 unsigned Internals::markerCountForNode(Node* node, ExceptionCode& ec)
213 {
214     if (!node) {
215         ec = INVALID_ACCESS_ERR;
216         return 0;
217     }
218
219     return node->document()->markers()->markersFor(node).size();
220 }
221
222 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, unsigned index, ExceptionCode& ec)
223 {
224     if (!node) {
225         ec = INVALID_ACCESS_ERR;
226         return 0;
227     }
228     
229     Vector<DocumentMarker*> markers = node->document()->markers()->markersFor(node);
230     if (markers.size() <= index)
231         return 0;
232     return Range::create(node->document(), node, markers[index]->startOffset(), node, markers[index]->endOffset());
233 }
234
235 void Internals::setForceCompositingMode(Document* document, bool enabled, ExceptionCode& ec)
236 {
237     if (!document || !document->settings()) {
238         ec = INVALID_ACCESS_ERR;
239         return;
240     }
241
242     document->settings()->setForceCompositingMode(enabled);
243 }
244
245 void Internals::setPasswordEchoEnabled(Document* document, bool enabled, ExceptionCode& ec)
246 {
247     if (!document || !document->settings()) {
248         ec = INVALID_ACCESS_ERR;
249         return;
250     }
251
252     if (!passwordEchoEnabledBackedUp) {
253         passwordEchoEnabledBackup = document->settings()->passwordEchoEnabled();
254         passwordEchoEnabledBackedUp = true;
255     }
256     document->settings()->setPasswordEchoEnabled(enabled);
257 }
258
259 void Internals::setPasswordEchoDurationInSeconds(Document* document, double durationInSeconds, ExceptionCode& ec)
260 {
261     if (!document || !document->settings()) {
262         ec = INVALID_ACCESS_ERR;
263         return;
264     }
265
266     if (!passwordEchoDurationInSecondsBackedUp) {
267         passwordEchoDurationInSecondsBackup = document->settings()->passwordEchoDurationInSeconds();
268         passwordEchoDurationInSecondsBackedUp = true;
269     }
270     document->settings()->setPasswordEchoDurationInSeconds(durationInSeconds);
271 }
272
273 void Internals::reset(Document* document)
274 {
275     if (!document || !document->settings())
276         return;
277
278     if (passwordEchoDurationInSecondsBackedUp) {
279         document->settings()->setPasswordEchoDurationInSeconds(passwordEchoDurationInSecondsBackup);
280         passwordEchoDurationInSecondsBackedUp = false;
281     }
282
283     if (passwordEchoEnabledBackedUp) {
284         document->settings()->setPasswordEchoEnabled(passwordEchoEnabledBackup);
285         passwordEchoEnabledBackedUp = false;
286     }
287 }
288
289 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
290 {
291     if (!textField) {
292         ec = INVALID_ACCESS_ERR;
293         return false;
294     }
295
296     if (textField->hasTagName(HTMLNames::inputTag))
297         return static_cast<HTMLInputElement*>(textField)->lastChangeWasUserEdit();
298
299     if (textField->hasTagName(HTMLNames::textareaTag))
300         return static_cast<HTMLTextAreaElement*>(textField)->lastChangeWasUserEdit();
301
302     ec = INVALID_NODE_TYPE_ERR;
303     return false;
304 }
305
306 String Internals::suggestedValue(Element* inputElement, ExceptionCode& ec)
307 {
308     if (!inputElement) {
309         ec = INVALID_ACCESS_ERR;
310         return String();
311     }
312
313     if (!inputElement->hasTagName(HTMLNames::inputTag)) {
314         ec = INVALID_NODE_TYPE_ERR;
315         return String();
316     }
317
318     return static_cast<HTMLInputElement*>(inputElement)->suggestedValue();
319 }
320
321 void Internals::setSuggestedValue(Element* inputElement, const String& value, ExceptionCode& ec)
322 {
323     if (!inputElement) {
324         ec = INVALID_ACCESS_ERR;
325         return;
326     }
327
328     if (!inputElement->hasTagName(HTMLNames::inputTag)) {
329         ec = INVALID_NODE_TYPE_ERR;
330         return;
331     }
332
333     static_cast<HTMLInputElement*>(inputElement)->setSuggestedValue(value);
334 }
335
336 }