More scrollOffset/scrollPosition disambiguation, in RenderLayer
[WebKit-https.git] / Source / WebCore / bindings / objc / DOMHTML.mm
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3  * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 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 INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #import "config.h"
28
29 #import "DOMDocumentFragmentInternal.h"
30 #import "DOMExtensions.h"
31 #import "DOMHTMLCollectionInternal.h"
32 #import "DOMHTMLDocumentInternal.h"
33 #import "DOMHTMLInputElementInternal.h"
34 #import "DOMHTMLSelectElementInternal.h"
35 #import "DOMHTMLTextAreaElementInternal.h"
36 #import "DOMNodeInternal.h"
37 #import "DOMPrivate.h"
38 #import "DocumentFragment.h"
39 #import "FrameView.h"
40 #import "HTMLCollection.h"
41 #import "HTMLDocument.h"
42 #import "HTMLInputElement.h"
43 #import "HTMLParserIdioms.h"
44 #import "HTMLSelectElement.h"
45 #import "HTMLTextAreaElement.h"
46 #import "Page.h"
47 #import "Range.h"
48 #import "RenderTextControl.h"
49 #import "Settings.h"
50 #import "markup.h"
51
52 #if PLATFORM(IOS)
53 #import "Autocapitalize.h"
54 #import "DOMHTMLElementInternal.h"
55 #import "HTMLTextFormControlElement.h"
56 #import "JSMainThreadExecState.h"
57 #import "RenderLayer.h"
58 #import "WAKWindow.h"
59 #import "WebCoreThreadMessage.h"
60 #endif
61
62 #if PLATFORM(IOS)
63
64 using namespace WebCore;
65
66 @implementation DOMHTMLElement (DOMHTMLElementExtensions)
67
68 - (int)scrollXOffset
69 {
70     RenderObject *renderer = core(self)->renderer();
71     if (!renderer)
72         return 0;
73
74     if (!is<RenderBlockFlow>(*renderer))
75         renderer = renderer->containingBlock();
76
77     if (!is<RenderBox>(*renderer) || !renderer->hasOverflowClip())
78         return 0;
79
80     return downcast<RenderBox>(*renderer).layer()->scrollOffset().x();
81 }
82
83 - (int)scrollYOffset
84 {
85     RenderObject* renderer = core(self)->renderer();
86     if (!renderer)
87         return 0;
88
89     if (!is<RenderBlockFlow>(*renderer))
90         renderer = renderer->containingBlock();
91     if (!is<RenderBox>(*renderer) || !renderer->hasOverflowClip())
92         return 0;
93
94     return downcast<RenderBox>(*renderer).layer()->scrollOffset().y();
95 }
96
97 - (void)setScrollXOffset:(int)x scrollYOffset:(int)y
98 {
99     [self setScrollXOffset:x scrollYOffset:y adjustForIOSCaret:NO];
100 }
101
102 - (void)setScrollXOffset:(int)x scrollYOffset:(int)y adjustForIOSCaret:(BOOL)adjustForIOSCaret
103 {
104     RenderObject* renderer = core(self)->renderer();
105     if (!renderer)
106         return;
107
108     if (!is<RenderBlockFlow>(*renderer))
109         renderer = renderer->containingBlock();
110     if (!renderer->hasOverflowClip() || !is<RenderBox>(*renderer))
111         return;
112
113     RenderLayer* layer = downcast<RenderBox>(*renderer).layer();
114     if (adjustForIOSCaret)
115         layer->setAdjustForIOSCaretWhenScrolling(true);
116     layer->scrollToOffset(ScrollOffset(x, y));
117     if (adjustForIOSCaret)
118         layer->setAdjustForIOSCaretWhenScrolling(false);
119 }
120
121 - (void)absolutePosition:(int *)x :(int *)y :(int *)w :(int *)h
122 {
123     RenderBox *renderer = core(self)->renderBox();
124     if (renderer) {
125         if (w)
126             *w = renderer->width();
127         if (h)
128             *h = renderer->width();
129         if (x && y) {
130             FloatPoint floatPoint(*x, *y);
131             renderer->localToAbsolute(floatPoint);
132             IntPoint point = roundedIntPoint(floatPoint);
133             *x = point.x();
134             *y = point.y();
135         }
136     }
137 }
138
139 @end
140
141 #endif // PLATFORM(IOS)
142
143 //------------------------------------------------------------------------------------------
144 // DOMHTMLDocument
145
146 @implementation DOMHTMLDocument (DOMHTMLDocumentExtensions)
147
148 - (DOMDocumentFragment *)createDocumentFragmentWithMarkupString:(NSString *)markupString baseURL:(NSURL *)baseURL
149 {
150     return kit(createFragmentFromMarkup(*core(self), markupString, [baseURL absoluteString]).ptr());
151 }
152
153 - (DOMDocumentFragment *)createDocumentFragmentWithText:(NSString *)text
154 {
155     // FIXME: Since this is not a contextual fragment, it won't handle whitespace properly.
156     return kit(createFragmentFromText(core(self)->createRange(), text).ptr());
157 }
158
159 @end
160
161 @implementation DOMHTMLDocument (WebPrivate)
162
163 - (DOMDocumentFragment *)_createDocumentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString
164 {
165     NSURL *baseURL = core(self)->completeURL(WebCore::stripLeadingAndTrailingHTMLSpaces(baseURLString));
166     return [self createDocumentFragmentWithMarkupString:markupString baseURL:baseURL];
167 }
168
169 - (DOMDocumentFragment *)_createDocumentFragmentWithText:(NSString *)text
170 {
171     return [self createDocumentFragmentWithText:text];
172 }
173
174 @end
175
176 @implementation DOMHTMLInputElement (FormAutoFillTransition)
177
178 - (BOOL)_isTextField
179 {
180     return core(self)->isTextField();
181 }
182
183 #if PLATFORM(IOS)
184 - (BOOL)_isAutofilled
185 {
186     return core(self)->isAutoFilled();
187 }
188
189 - (void)_setAutofilled:(BOOL)filled
190 {
191     // This notifies the input element that the content has been autofilled
192     // This allows WebKit to obey the -webkit-autofill pseudo style, which
193     // changes the background color.
194     core(self)->setAutoFilled(filled);
195 }
196 #endif // PLATFORM(IOS)
197
198 @end
199
200 @implementation DOMHTMLSelectElement (FormAutoFillTransition)
201
202 - (void)_activateItemAtIndex:(int)index
203 {
204     // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590>
205     if (WebCore::HTMLSelectElement* select = core(self))
206         select->optionSelectedByUser(index, true);
207 }
208
209 - (void)_activateItemAtIndex:(int)index allowMultipleSelection:(BOOL)allowMultipleSelection
210 {
211     // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590>
212     // If this is a <select multiple> the allowMultipleSelection flag will allow setting multiple
213     // selections without clearing the other selections.
214     if (WebCore::HTMLSelectElement* select = core(self))
215         select->optionSelectedByUser(index, true, allowMultipleSelection);
216 }
217
218 @end
219
220 #if PLATFORM(IOS)
221
222 @implementation DOMHTMLInputElement (FormPromptAdditions)
223
224 - (BOOL)_isEdited
225 {
226     return core(self)->lastChangeWasUserEdit();
227 }
228
229 @end
230
231 @implementation DOMHTMLTextAreaElement (FormPromptAdditions)
232
233 - (BOOL)_isEdited
234 {
235     return core(self)->lastChangeWasUserEdit();
236 }
237
238 @end
239
240 @implementation DOMHTMLInputElement (AutocapitalizeAdditions)
241
242 - (WebAutocapitalizeType)_autocapitalizeType
243 {
244     WebCore::HTMLInputElement* inputElement = core(self);
245     return static_cast<WebAutocapitalizeType>(inputElement->autocapitalizeType());
246 }
247
248 @end
249
250 @implementation DOMHTMLTextAreaElement (AutocapitalizeAdditions)
251
252 - (WebAutocapitalizeType)_autocapitalizeType
253 {
254     WebCore::HTMLTextAreaElement* textareaElement = core(self);
255     return static_cast<WebAutocapitalizeType>(textareaElement->autocapitalizeType());
256 }
257
258 @end
259
260 @implementation DOMHTMLInputElement (WebInputChangeEventAdditions)
261
262 - (void)setValueWithChangeEvent:(NSString *)newValue
263 {
264     WebCore::JSMainThreadNullState state;
265     core(self)->setValue(newValue, DispatchInputAndChangeEvent);
266 }
267
268 - (void)setValueAsNumberWithChangeEvent:(double)newValueAsNumber
269 {
270     WebCore::JSMainThreadNullState state;
271     WebCore::ExceptionCode ec = 0;
272     core(self)->setValueAsNumber(newValueAsNumber, ec, DispatchInputAndChangeEvent);
273 }
274
275 @end
276 #endif
277
278 Class kitClass(WebCore::HTMLCollection* collection)
279 {
280     if (collection->type() == WebCore::SelectOptions)
281         return [DOMHTMLOptionsCollection class];
282     return [DOMHTMLCollection class];
283 }