Node.appendChild(null) / replaceChild(null, null) / removeChild(null) / insertBefore...
[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()->scrollXOffset();
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()->scrollYOffset();
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(IntSize(x, y));
117     if (adjustForIOSCaret)
118         layer->setAdjustForIOSCaretWhenScrolling(false);
119 }
120
121 - (void)absolutePosition:(int *)x :(int *)y :(int *)w :(int *)h {
122     RenderBox *renderer = core(self)->renderBox();
123     if (renderer) {
124         if (w)
125             *w = renderer->width();
126         if (h)
127             *h = renderer->width();
128         if (x && y) {
129             FloatPoint floatPoint(*x, *y);
130             renderer->localToAbsolute(floatPoint);
131             IntPoint point = roundedIntPoint(floatPoint);
132             *x = point.x();
133             *y = point.y();
134         }
135     }
136 }
137
138 @end
139
140 #endif // PLATFORM(IOS)
141
142 //------------------------------------------------------------------------------------------
143 // DOMHTMLDocument
144
145 @implementation DOMHTMLDocument (DOMHTMLDocumentExtensions)
146
147 - (DOMDocumentFragment *)createDocumentFragmentWithMarkupString:(NSString *)markupString baseURL:(NSURL *)baseURL
148 {
149     return kit(createFragmentFromMarkup(*core(self), markupString, [baseURL absoluteString]).ptr());
150 }
151
152 - (DOMDocumentFragment *)createDocumentFragmentWithText:(NSString *)text
153 {
154     // FIXME: Since this is not a contextual fragment, it won't handle whitespace properly.
155     return kit(createFragmentFromText(core(self)->createRange(), text).ptr());
156 }
157
158 @end
159
160 @implementation DOMHTMLDocument (WebPrivate)
161
162 - (DOMDocumentFragment *)_createDocumentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString
163 {
164     NSURL *baseURL = core(self)->completeURL(WebCore::stripLeadingAndTrailingHTMLSpaces(baseURLString));
165     return [self createDocumentFragmentWithMarkupString:markupString baseURL:baseURL];
166 }
167
168 - (DOMDocumentFragment *)_createDocumentFragmentWithText:(NSString *)text
169 {
170     return [self createDocumentFragmentWithText:text];
171 }
172
173 @end
174
175 @implementation DOMHTMLInputElement (FormAutoFillTransition)
176
177 - (BOOL)_isTextField
178 {
179     return core(self)->isTextField();
180 }
181
182 #if PLATFORM(IOS)
183 - (BOOL)_isAutofilled
184 {
185     return core(self)->isAutoFilled();
186 }
187
188 - (void)_setAutofilled:(BOOL)filled
189 {
190     // This notifies the input element that the content has been autofilled
191     // This allows WebKit to obey the -webkit-autofill pseudo style, which
192     // changes the background color.
193     core(self)->setAutoFilled(filled);
194 }
195 #endif // PLATFORM(IOS)
196
197 @end
198
199 @implementation DOMHTMLSelectElement (FormAutoFillTransition)
200
201 - (void)_activateItemAtIndex:(int)index
202 {
203     // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590>
204     if (WebCore::HTMLSelectElement* select = core(self))
205         select->optionSelectedByUser(index, true);
206 }
207
208 - (void)_activateItemAtIndex:(int)index allowMultipleSelection:(BOOL)allowMultipleSelection
209 {
210     // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590>
211     // If this is a <select multiple> the allowMultipleSelection flag will allow setting multiple
212     // selections without clearing the other selections.
213     if (WebCore::HTMLSelectElement* select = core(self))
214         select->optionSelectedByUser(index, true, allowMultipleSelection);
215 }
216
217 @end
218
219 #if PLATFORM(IOS)
220
221 @implementation DOMHTMLInputElement (FormPromptAdditions)
222
223 - (BOOL)_isEdited
224 {
225     return core(self)->lastChangeWasUserEdit();
226 }
227
228 @end
229
230 @implementation DOMHTMLTextAreaElement (FormPromptAdditions)
231
232 - (BOOL)_isEdited
233 {
234     return core(self)->lastChangeWasUserEdit();
235 }
236
237 @end
238
239 @implementation DOMHTMLInputElement (AutocapitalizeAdditions)
240
241 - (WebAutocapitalizeType)_autocapitalizeType
242 {
243     WebCore::HTMLInputElement* inputElement = core(self);
244     return static_cast<WebAutocapitalizeType>(inputElement->autocapitalizeType());
245 }
246
247 @end
248
249 @implementation DOMHTMLTextAreaElement (AutocapitalizeAdditions)
250
251 - (WebAutocapitalizeType)_autocapitalizeType
252 {
253     WebCore::HTMLTextAreaElement* textareaElement = core(self);
254     return static_cast<WebAutocapitalizeType>(textareaElement->autocapitalizeType());
255 }
256
257 @end
258
259 @implementation DOMHTMLInputElement (WebInputChangeEventAdditions)
260
261 - (void)setValueWithChangeEvent:(NSString *)newValue
262 {
263     WebCore::JSMainThreadNullState state;
264     core(self)->setValue(newValue, DispatchInputAndChangeEvent);
265 }
266
267 - (void)setValueAsNumberWithChangeEvent:(double)newValueAsNumber
268 {
269     WebCore::JSMainThreadNullState state;
270     WebCore::ExceptionCode ec = 0;
271     core(self)->setValueAsNumber(newValueAsNumber, ec, DispatchInputAndChangeEvent);
272 }
273
274 @end
275 #endif
276
277 Class kitClass(WebCore::HTMLCollection* collection)
278 {
279     if (collection->type() == WebCore::SelectOptions)
280         return [DOMHTMLOptionsCollection class];
281     return [DOMHTMLCollection class];
282 }