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