WebCore:
authorsullivan <sullivan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jul 2005 21:16:56 +0000 (21:16 +0000)
committersullivan <sullivan@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 29 Jul 2005 21:16:56 +0000 (21:16 +0000)
        Reviewed by Dave Hyatt.

        Test cases added: none, this only affects Safari forms autofill

        - WebCore part of <rdar://problem/4187404> Redo form SPI so that it doesn't rely on NSViews

        * khtml/html/html_formimpl.cpp:
        added a FIXME about a bug I ran into while doing this autofill stuff

        * kwq/DOMHTML.mm:
        (viewForElement):
        Moved this function here (was in WebCoreBridge), and simplified it a little. This will go
        away when we have non-NSView ways of implementing all the methods below.
        (-[DOMHTMLInputElement _displayedValue]):
        moved here from Safari
        (-[DOMHTMLInputElement _setDisplayedValue:]):
        ditto
        (-[DOMHTMLInputElement _rectOnScreen]):
        ditto
        (-[DOMHTMLInputElement _replaceCharactersInRange:withString:selectingFromIndex:]):
        ditto
        (-[DOMHTMLInputElement _selectedRange]):
        ditto
        (-[DOMHTMLInputElement _setBackgroundColor:]):
        ditto
        (-[DOMHTMLSelectElement _activateItemAtIndex:]):
        ditto
        (-[DOMHTMLSelectElement _optionLabels]):
        ditto

        * kwq/DOMPrivate.h:
        moved DOMHTMLInputElement and DOMHTMLSelectElement categories here from Safari

        * kwq/WebCoreBridge.h:
        * kwq/WebCoreBridge.mm:
        removed viewForElement:, which had been added as a temporary measure while I did this conversion.

WebKit:

        Reviewed by Dave Hyatt.

        - WebKit part of <rdar://problem/4187404> Redo form SPI so that it doesn't rely on NSViews

        Much of 4187404 was addressed in earlier checkins. This checkin completes the task.

        * WebView.subproj/WebHTMLRepresentation.h:
        * WebView.subproj/WebHTMLRepresentation.m:
        removed viewForElement:, which was the only remaining NSView-related SPI that Safari autofill was
        still using. I added viewForElement a week ago as a transitional measure, so removing it won't
        affect any other clients.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@9950 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog-2005-08-23
WebCore/khtml/html/html_formimpl.cpp
WebCore/kwq/DOMHTML.mm
WebCore/kwq/DOMPrivate.h
WebCore/kwq/WebCoreBridge.h
WebCore/kwq/WebCoreBridge.mm
WebKit/ChangeLog
WebKit/WebView.subproj/WebHTMLRepresentation.h
WebKit/WebView.subproj/WebHTMLRepresentation.m

index 90e2734..ffbcfea 100644 (file)
@@ -1,3 +1,42 @@
+2005-07-29  John Sullivan  <sullivan@apple.com>
+
+        Reviewed by Dave Hyatt.
+
+        Test cases added: none, this only affects Safari forms autofill
+
+        - WebCore part of <rdar://problem/4187404> Redo form SPI so that it doesn't rely on NSViews
+
+        * khtml/html/html_formimpl.cpp:
+        added a FIXME about a bug I ran into while doing this autofill stuff
+        
+        * kwq/DOMHTML.mm:
+        (viewForElement):
+        Moved this function here (was in WebCoreBridge), and simplified it a little. This will go
+        away when we have non-NSView ways of implementing all the methods below.
+        (-[DOMHTMLInputElement _displayedValue]):
+        moved here from Safari
+        (-[DOMHTMLInputElement _setDisplayedValue:]):
+        ditto
+        (-[DOMHTMLInputElement _rectOnScreen]):
+        ditto
+        (-[DOMHTMLInputElement _replaceCharactersInRange:withString:selectingFromIndex:]):
+        ditto
+        (-[DOMHTMLInputElement _selectedRange]):
+        ditto
+        (-[DOMHTMLInputElement _setBackgroundColor:]):
+        ditto
+        (-[DOMHTMLSelectElement _activateItemAtIndex:]):
+        ditto
+        (-[DOMHTMLSelectElement _optionLabels]):
+        ditto
+
+        * kwq/DOMPrivate.h:
+        moved DOMHTMLInputElement and DOMHTMLSelectElement categories here from Safari
+        
+        * kwq/WebCoreBridge.h:
+        * kwq/WebCoreBridge.mm:
+        removed viewForElement:, which had been added as a temporary measure while I did this conversion.
+
 2005-07-29  Eric Seidel  <eseidel@apple.com>
 
         Reviewed by sullivan.
index 50e0bca..91bd6ef 100644 (file)
@@ -2937,6 +2937,8 @@ int HTMLSelectElementImpl::listToOptionIndex(int listIndex) const
     return optionIndex;
 }
 
+// FIXME 4197997: this method is used by the public API -[DOMHTMLSelectElement options], but always returns
+// an empty list.
 HTMLOptionsCollectionImpl *HTMLSelectElementImpl::options()
 {
     if (!m_options) {
index c89ce90..6f0f652 100644 (file)
@@ -3989,3 +3989,140 @@ using DOM::NodeImpl;
 }
 
 @end
+
+// These #imports and "usings" are used only by viewForElement and should be deleted 
+// when that function goes away.
+#import "render_object.h"
+#import "render_replaced.h"
+using khtml::RenderObject;
+using khtml::RenderWidget;
+
+// This function is used only by the two FormAutoFillTransition categories, and will go away
+// as soon as possible.
+static NSView *viewForElement(DOMElement *element)
+{
+    RenderObject *renderer = [element _elementImpl]->renderer();
+    if (renderer && renderer->isWidget()) {
+        QWidget *widget = static_cast<const RenderWidget *>(renderer)->widget();
+        if (widget) {
+            widget->populate();
+            return widget->getView();
+        }
+    }
+    return nil;
+}
+
+@implementation DOMHTMLInputElement(FormAutoFillTransition)
+
+- (NSString *)_displayedValue
+{
+    // Seems like we could just call [_element value] here but doing so messes up autofill (when you type in
+    // a form and it autocompletes, the autocompleted part of the text isn't left selected; instead the insertion
+    // point appears between what you typed and the autocompleted part of the text). I think the DOM element's
+    // stored value isn't updated until the text in the field is committed when losing focus or perhaps on Enter.
+    // Maybe when we switch over to not using NSTextField here then [_element value] will be good enough and
+    // we can get rid of this method.
+    return [(NSTextField *)viewForElement(self) stringValue];
+}
+
+- (void)_setDisplayedValue:(NSString *)newValue
+{
+    // This method is used by autofill and needs to work even when the field is currently being edited.
+    NSTextField *field = (NSTextField *)viewForElement(self);
+    NSText *fieldEditor = [field currentEditor];
+    if (fieldEditor != nil) {
+        [fieldEditor setString:newValue];
+        [(NSTextView *)fieldEditor didChangeText];
+    } else {
+        // Not currently being edited, so we can set the string the simple way. Note that we still can't
+        // just use [self setValue:] here because it would break background-color-setting in the current
+        // autofill code. When we've adopted a new way to set the background color to indicate autofilled
+        // fields, then this case at least can probably change to [self setValue:].
+        [field setStringValue:newValue];
+    }
+}
+
+- (NSRect)_rectOnScreen
+{
+    // Returns bounding rect of text field, in screen coordinates.
+    // FIXME: need a way to determine bounding rect for DOMElements before we can convert this code to
+    // not use views. Hyatt says we need to add offsetLeft/offsetTop/width/height to DOMExtensions, but
+    // then callers would need to walk up the offsetParent chain to determine real coordinates. So we
+    // probably need to (also?) add some call(s) to get the absolute origin.
+    NSTextField *field = (NSTextField *)viewForElement(self);
+    ASSERT(field != nil);
+    NSRect result = [field bounds];
+    if ([field isFlipped]) {
+        result.origin.y += result.size.height;
+    }
+    result.origin = [field convertPoint:result.origin toView:nil];
+    result.origin = [[field window] convertBaseToScreen:result.origin];
+    return result;
+}
+
+- (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index
+{
+    NSText *fieldEditor = [(NSTextField *)viewForElement(self) currentEditor];
+    [fieldEditor replaceCharactersInRange:targetRange withString:replacementString];
+    
+    NSRange selectRange;
+    selectRange.location = index;
+    selectRange.length = [[self _displayedValue] length] - selectRange.location;
+    [fieldEditor setSelectedRange:selectRange];
+    
+    [(NSTextView *)fieldEditor didChangeText];
+}
+
+- (NSRange)_selectedRange
+{    
+    NSText *editor = [(NSTextField *)viewForElement(self) currentEditor];
+    if (editor == nil) {
+        return NSMakeRange(NSNotFound, 0);
+    }
+    
+    return [editor selectedRange];
+}    
+
+- (void)_setBackgroundColor:(NSColor *)color
+{
+    // We currently have no DOM-aware way of setting the background color of a text field.
+    // Safari autofill uses this method, which is fragile because there's no guarantee that
+    // the color set here won't be clobbered by other WebCore code. However, it works OK for
+    // Safari autofill's purposes right now. When we switch over to using DOMElements for
+    // form controls, we'll probably need a CSS pseudoclass to make this work.
+    [(NSTextField *)viewForElement(self) setBackgroundColor:color];
+}
+
+@end
+
+@implementation DOMHTMLSelectElement(FormAutoFillTransition)
+
+- (void)_activateItemAtIndex:(int)index
+{
+    NSPopUpButton *popUp = (NSPopUpButton *)viewForElement(self);
+    [popUp selectItemAtIndex:index];
+    // Must do this to simulate same side effect as if user made the choice
+    [NSApp sendAction:[popUp action] to:[popUp target] from:popUp];
+}
+
+- (NSArray *)_optionLabels
+{    
+    // FIXME 4197997: This code should work, and when it does we can eliminate this method entirely
+    // and just have the only current caller (in Safari autofill code) embed this code directly.
+    // But at the moment -[DOMHTMLSelectElement options] always returns an empty collection.
+#if 0
+    DOMHTMLOptionsCollection *options = [self options];
+    NSMutableArray *optionLabels = [NSMutableArray array];
+    int itemCount = [options length];
+    int itemIndex;
+    for (itemIndex = 0; itemIndex < itemCount; ++itemIndex) {
+        [optionLabels addObject:[(DOMHTMLOptionElement *)[options item:itemIndex] label]];
+    }
+    return optionLabels;
+#endif
+    
+    // Due to the DOM API brokenness, for now we have to get the titles from the view
+    return [(NSPopUpButton *)viewForElement(self) itemTitles];
+}
+
+@end
index 0ea391d..26c1863 100644 (file)
 - (DOMDocumentFragment *)_createDocumentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString;
 - (DOMDocumentFragment *)_createDocumentFragmentWithText:(NSString *)text;
 @end
+
+// All the methods in this category are used by Safari forms autofill and should not be used for any other purpose.
+// They are stopgap measures until we finish transitioning form controls to not use NSView. Each one should become
+// replaceable by public DOM API, and when that happens Safari will switch to implementations using that public API,
+// and these will be deleted.
+@interface DOMHTMLInputElement(FormsAutoFillTransition)
+- (NSString *)_displayedValue; // the string currently displayed in the field, even when the field is being edited
+- (void)_setDisplayedValue:(NSString *)newValue; // set the value displayed, even when the field is being edited
+- (NSRect)_rectOnScreen; // bounding box of the text field, in screen coordinates
+- (void)_replaceCharactersInRange:(NSRange)targetRange withString:(NSString *)replacementString selectingFromIndex:(int)index;
+- (NSRange)_selectedRange;
+- (void)_setBackgroundColor:(NSColor *)color;
+@end
+
+// All the methods in this category are used by Safari forms autofill and should not be used for any other purpose.
+// They are stopgap measures until we finish transitioning form controls to not use NSView. Each one should become
+// replaceable by public DOM API, and when that happens Safari will switch to implementations using that public API,
+// and these will be deleted.
+@interface DOMHTMLSelectElement(FormsAutoFillTransition)
+- (void)_activateItemAtIndex:(int)index;
+- (NSArray *)_optionLabels;
+@end
+
index 51aa002..eb06854 100644 (file)
@@ -285,7 +285,6 @@ typedef enum
 
 - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form;
 - (DOMElement *)elementForView:(NSView *)view;
-- (NSView *)viewForElement:(DOMElement *)view; // introduced temporarily to ease transition to view-free form SPI
 - (BOOL)elementDoesAutoComplete:(DOMElement *)element;
 - (BOOL)elementIsPassword:(DOMElement *)element;
 - (DOMElement *)formForElement:(DOMElement *)element;
index c4b749c..9299a67 100644 (file)
@@ -895,24 +895,6 @@ static BOOL nowPrinting(WebCoreBridge *self)
     return nil;
 }
 
-static NSView *viewForElement(ElementImpl *elementImpl)
-{
-    RenderObject *renderer = elementImpl->renderer();
-    if (renderer && renderer->isWidget()) {
-        QWidget *widget = static_cast<const RenderWidget *>(renderer)->widget();
-        if (widget) {
-            widget->populate();
-            return widget->getView();
-        }
-    }
-    return nil;
-}
-
-- (NSView *)viewForElement:(DOMElement *)element
-{
-    return viewForElement([element _elementImpl]);
-}
-
 static HTMLInputElementImpl *inputElementFromDOMElement(DOMElement *element)
 {
     NodeImpl *node = [element _nodeImpl];
index 42bf038..34330c5 100644 (file)
@@ -1,5 +1,19 @@
 2005-07-29  John Sullivan  <sullivan@apple.com>
 
+        Reviewed by Dave Hyatt.
+        
+        - WebKit part of <rdar://problem/4187404> Redo form SPI so that it doesn't rely on NSViews
+        
+        Much of 4187404 was addressed in earlier checkins. This checkin completes the task.
+
+        * WebView.subproj/WebHTMLRepresentation.h:
+        * WebView.subproj/WebHTMLRepresentation.m:
+        removed viewForElement:, which was the only remaining NSView-related SPI that Safari autofill was
+        still using. I added viewForElement a week ago as a transitional measure, so removing it won't
+        affect any other clients.
+
+2005-07-29  John Sullivan  <sullivan@apple.com>
+
         Reviewed by Chris Blumenberg.
 
         * WebView.subproj/WebFrameView.m:
index 4963a3a..7a51740 100644 (file)
@@ -51,7 +51,6 @@
 - (NSAttributedString *)attributedStringFrom:(DOMNode *)startNode startOffset:(int)startOffset to:(DOMNode *)endNode endOffset:(int)endOffset;
 
 - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form;
-- (NSView *)viewForElement:(DOMElement *)element; // introduced temporarily to ease transition to view-free form SPI
 - (BOOL)elementDoesAutoComplete:(DOMElement *)element;
 - (BOOL)elementIsPassword:(DOMElement *)element;
 - (DOMElement *)formForElement:(DOMElement *)element;
index d0bcc6d..78de2e7 100644 (file)
     return [_private->bridge elementWithName:name inForm:form];
 }
 
-- (NSView *)viewForElement:(DOMElement *)element
-{
-    return [_private->bridge viewForElement:element];
-}
-
 - (BOOL)elementDoesAutoComplete:(DOMElement *)element
 {
     return [_private->bridge elementDoesAutoComplete:element];