1 /* 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2006 Samuel Weinig <sam.weinig (at) 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 COMPUTER, 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 COMPUTER, 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 //------------------------------------------------------------------------------------------ 53 // DOMHTMLDocument 54 55 @implementation DOMHTMLDocument (DOMHTMLDocumentExtensions) 56 57 - (DOMDocumentFragment *)createDocumentFragmentWithMarkupString:(NSString *)markupString baseURL:(NSURL *)baseURL 58 { 59 return kit(createFragmentFromMarkup(core(self), markupString, [baseURL absoluteString]).get()); 60 } 61 62 - (DOMDocumentFragment *)createDocumentFragmentWithText:(NSString *)text 63 { 64 // FIXME: Since this is not a contextual fragment, it won't handle whitespace properly. 65 return kit(createFragmentFromText(core(self)->createRange().get(), text).get()); 66 } 67 68 @end 69 70 @implementation DOMHTMLDocument (WebPrivate) 71 72 - (DOMDocumentFragment *)_createDocumentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString 73 { 74 NSURL *baseURL = core(self)->completeURL(WebCore::stripLeadingAndTrailingHTMLSpaces(baseURLString)); 75 return [self createDocumentFragmentWithMarkupString:markupString baseURL:baseURL]; 76 } 77 78 - (DOMDocumentFragment *)_createDocumentFragmentWithText:(NSString *)text 79 { 80 return [self createDocumentFragmentWithText:text]; 81 } 82 83 @end 84 85 #ifdef BUILDING_ON_TIGER 86 @implementation DOMHTMLDocument (DOMHTMLDocumentOverrides) 87 88 - (DOMNode *)firstChild 89 { 90 WebCore::HTMLDocument* coreHTMLDocument = core(self); 91 if (!coreHTMLDocument->page() || !coreHTMLDocument->page()->settings()->needsTigerMailQuirks()) 92 return kit(coreHTMLDocument->firstChild()); 93 94 WebCore::Node* child = coreHTMLDocument->firstChild(); 95 while (child && child->nodeType() == WebCore::Node::DOCUMENT_TYPE_NODE) 96 child = child->nextSibling(); 97 98 return kit(child); 99 } 100 101 @end 102 #endif 103 104 @implementation DOMHTMLInputElement (FormAutoFillTransition) 105 106 - (BOOL)_isTextField 107 { 108 return core(self)->isTextField(); 109 } 110 111 - (NSRect)_rectOnScreen 112 { 113 // Returns bounding rect of text field, in screen coordinates. 114 NSRect result = [self boundingBox]; 115 if (!core(self)->document()->view()) 116 return result; 117 118 NSView* view = core(self)->document()->view()->documentView(); 119 result = [view convertRect:result toView:nil]; 120 result.origin = [[view window] convertBaseToScreen:result.origin]; 121 return result; 122 } 123 124 - (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index 125 { 126 WebCore::HTMLInputElement* inputElement = core(self); 127 if (inputElement) { 128 WTF::String newValue = inputElement->value(); 129 newValue.replace(targetRange.location, targetRange.length, replacementString); 130 inputElement->setValue(newValue); 131 inputElement->setSelectionRange(index, newValue.length()); 132 } 133 } 134 135 - (NSRange)_selectedRange 136 { 137 WebCore::HTMLInputElement* inputElement = core(self); 138 if (inputElement) { 139 int start = inputElement->selectionStart(); 140 int end = inputElement->selectionEnd(); 141 return NSMakeRange(start, end - start); 142 } 143 return NSMakeRange(NSNotFound, 0); 144 } 145 146 - (BOOL)_isAutofilled 147 { 148 return core(self)->isAutofilled(); 149 } 150 151 - (void)_setAutofilled:(BOOL)filled 152 { 153 // This notifies the input element that the content has been autofilled 154 // This allows WebKit to obey the -webkit-autofill pseudo style, which 155 // changes the background color. 156 core(self)->setAutofilled(filled); 157 } 158 159 @end 160 161 @implementation DOMHTMLSelectElement (FormAutoFillTransition) 162 163 - (void)_activateItemAtIndex:(int)index 164 { 165 // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590> 166 if (WebCore::HTMLSelectElement* select = core(self)) 167 select->setSelectedIndexByUser(index, true, true); 168 } 169 170 - (void)_activateItemAtIndex:(int)index allowMultipleSelection:(BOOL)allowMultipleSelection 171 { 172 // Use the setSelectedIndexByUser function so a change event will be fired. <rdar://problem/6760590> 173 // If this is a <select multiple> the allowMultipleSelection flag will allow setting multiple 174 // selections without clearing the other selections. 175 if (WebCore::HTMLSelectElement* select = core(self)) 176 select->setSelectedIndexByUser(index, true, true, allowMultipleSelection); 177 } 178 179 @end 180 181 @implementation DOMHTMLInputElement (FormPromptAdditions) 182 183 - (BOOL)_isEdited 184 { 185 return core(self)->lastChangeWasUserEdit(); 186 } 187 188 @end 189 190 @implementation DOMHTMLTextAreaElement (FormPromptAdditions) 191 192 - (BOOL)_isEdited 193 { 194 return core(self)->lastChangeWasUserEdit(); 195 } 196 197 @end 198 199 Class kitClass(WebCore::HTMLCollection* collection) 200 { 201 if (collection->type() == WebCore::SelectOptions) 202 return [DOMHTMLOptionsCollection class]; 203 return [DOMHTMLCollection class]; 204 } 205