<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[165116] trunk/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/165116">165116</a></dd>
<dt>Author</dt> <dd>enrica@apple.com</dd>
<dt>Date</dt> <dd>2014-03-05 11:48:32 -0800 (Wed, 05 Mar 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS WebKit2] support multi-select and select with groups for iPhone.
https://bugs.webkit.org/show_bug.cgi?id=129344
&lt;rdar://problem/16206928&gt;

Reviewed by Simon Fraser.

This is the remaining work on select element support on iOS.
This adds multi-select and select with group support with UI
for iPhone that uses UIPickerView.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView resignFirstResponder]):
(-[WKContentView inputAccessoryView]): Removed incorrect early return.
(-[WKContentView _stopAssistingNode]):
* UIProcess/ios/forms/WKFormSelectControl.h:
* UIProcess/ios/forms/WKFormSelectControl.mm:
(adjustedFontSize): Moved here to make it available to both picker and
popover based implementations.
(-[WKFormSelectControl initWithView:]):
* UIProcess/ios/forms/WKFormSelectPicker.mm:
(-[WKOptionPickerCell _isSelectable]):
(-[WKOptionPickerCell initCommon]):
(-[WKOptionPickerCell initWithOptionItem:]):
(-[WKOptionGroupPickerCell initWithOptionItem:]):
(-[WKOptionGroupPickerCell labelWidthForBounds:]):
(-[WKOptionGroupPickerCell layoutSubviews]):
(-[WKMultipleSelectPicker initWithView:]):
(-[WKMultipleSelectPicker dealloc]):
(-[WKMultipleSelectPicker controlView]):
(-[WKMultipleSelectPicker controlBeginEditing]):
(-[WKMultipleSelectPicker controlEndEditing]):
(-[WKMultipleSelectPicker layoutSubviews]):
(-[WKMultipleSelectPicker pickerView:viewForRow:forComponent:reusingView:]):
(-[WKMultipleSelectPicker numberOfComponentsInPickerView:]):
(-[WKMultipleSelectPicker pickerView:numberOfRowsInComponent:]):
(-[WKMultipleSelectPicker findItemIndexAt:]):
(-[WKMultipleSelectPicker pickerView:row:column:checked:]):
(-[WKSelectSinglePicker initWithView:]):
(-[WKSelectSinglePicker controlEndEditing]):
* UIProcess/ios/forms/WKFormSelectPopover.mm:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosformsWKFormSelectControlh">trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosformsWKFormSelectControlmm">trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosformsWKFormSelectPickermm">trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPicker.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosformsWKFormSelectPopovermm">trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPopover.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (165115 => 165116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-03-05 18:59:58 UTC (rev 165115)
+++ trunk/Source/WebKit2/ChangeLog        2014-03-05 19:48:32 UTC (rev 165116)
</span><span class="lines">@@ -1,3 +1,46 @@
</span><ins>+2014-03-05  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+        [iOS WebKit2] support multi-select and select with groups for iPhone.
+        https://bugs.webkit.org/show_bug.cgi?id=129344
+        &lt;rdar://problem/16206928&gt;
+
+        Reviewed by Simon Fraser.
+
+        This is the remaining work on select element support on iOS.
+        This adds multi-select and select with group support with UI
+        for iPhone that uses UIPickerView.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView resignFirstResponder]):
+        (-[WKContentView inputAccessoryView]): Removed incorrect early return.
+        (-[WKContentView _stopAssistingNode]):
+        * UIProcess/ios/forms/WKFormSelectControl.h:
+        * UIProcess/ios/forms/WKFormSelectControl.mm:
+        (adjustedFontSize): Moved here to make it available to both picker and
+        popover based implementations.
+        (-[WKFormSelectControl initWithView:]):
+        * UIProcess/ios/forms/WKFormSelectPicker.mm:
+        (-[WKOptionPickerCell _isSelectable]):
+        (-[WKOptionPickerCell initCommon]):
+        (-[WKOptionPickerCell initWithOptionItem:]):
+        (-[WKOptionGroupPickerCell initWithOptionItem:]):
+        (-[WKOptionGroupPickerCell labelWidthForBounds:]):
+        (-[WKOptionGroupPickerCell layoutSubviews]):
+        (-[WKMultipleSelectPicker initWithView:]):
+        (-[WKMultipleSelectPicker dealloc]):
+        (-[WKMultipleSelectPicker controlView]):
+        (-[WKMultipleSelectPicker controlBeginEditing]):
+        (-[WKMultipleSelectPicker controlEndEditing]):
+        (-[WKMultipleSelectPicker layoutSubviews]):
+        (-[WKMultipleSelectPicker pickerView:viewForRow:forComponent:reusingView:]):
+        (-[WKMultipleSelectPicker numberOfComponentsInPickerView:]):
+        (-[WKMultipleSelectPicker pickerView:numberOfRowsInComponent:]):
+        (-[WKMultipleSelectPicker findItemIndexAt:]):
+        (-[WKMultipleSelectPicker pickerView:row:column:checked:]):
+        (-[WKSelectSinglePicker initWithView:]):
+        (-[WKSelectSinglePicker controlEndEditing]):
+        * UIProcess/ios/forms/WKFormSelectPopover.mm:
+
</ins><span class="cx"> 2014-03-03  Martin Robinson  &lt;mrobinson@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK][CMake] Generate documentation for the DOM bindings
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (165115 => 165116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-03-05 18:59:58 UTC (rev 165115)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-03-05 19:48:32 UTC (rev 165116)
</span><span class="lines">@@ -229,6 +229,8 @@
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Maybe we should call resignFirstResponder on the superclass
</span><span class="cx">     // and do nothing if the return value is NO.
</span><ins>+    // We need to complete the editing operation before we blur the element.
+    [_inputPeripheral endEditing];
</ins><span class="cx">     _page-&gt;blurAssistedNode();
</span><span class="cx">     [self _cancelInteraction];
</span><span class="cx">     [_webSelectionAssistant resignedFirstResponder];
</span><span class="lines">@@ -741,9 +743,6 @@
</span><span class="cx"> 
</span><span class="cx"> - (UIView *)inputAccessoryView
</span><span class="cx"> {
</span><del>-    if (!_isEditable)
-        return nil;
-    
</del><span class="cx">     if (!_formAccessoryView) {
</span><span class="cx">         _formAccessoryView = adoptNS([[UIWebFormAccessory alloc] init]);
</span><span class="cx">         [_formAccessoryView setDelegate:self];
</span><span class="lines">@@ -1883,7 +1882,6 @@
</span><span class="cx"> - (void)_stopAssistingNode
</span><span class="cx"> {
</span><span class="cx">     _isEditable = NO;
</span><del>-    [_inputPeripheral endEditing];
</del><span class="cx">     _assistedNodeInformation.elementType = WKTypeNone;
</span><span class="cx">     _inputPeripheral = nil;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosformsWKFormSelectControlh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.h (165115 => 165116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.h        2014-03-05 18:59:58 UTC (rev 165115)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.h        2014-03-05 19:48:32 UTC (rev 165116)
</span><span class="lines">@@ -25,11 +25,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx"> 
</span><ins>+#import &quot;AssistedNodeInformation.h&quot;
</ins><span class="cx"> #import &quot;WKFormPeripheral.h&quot;
</span><span class="cx"> #import &quot;WKFormPopover.h&quot;
</span><span class="cx"> #import &lt;UIKit/UIPickerView.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIPickerView_Private.h&gt;
</span><span class="cx"> 
</span><ins>+CGFloat adjustedFontSize(CGFloat textWidth, UIFont *font, CGFloat initialFontSize, const Vector&lt;WebKit::WKOptionItem&gt;&amp; items);
+
</ins><span class="cx"> @class WKContentView;
</span><span class="cx"> 
</span><span class="cx"> @interface WKFormSelectControl : NSObject&lt;WKFormPeripheral&gt;
</span><span class="lines">@@ -45,5 +48,9 @@
</span><span class="cx"> - (instancetype)initWithView:(WKContentView *)view;
</span><span class="cx"> @end
</span><span class="cx"> 
</span><ins>+@interface WKMultipleSelectPicker : UIPickerView &lt;WKFormControl, UIPickerViewDataSource, UIPickerViewDelegate&gt;
+- (instancetype)initWithView:(WKContentView *)view;
+@end
+
</ins><span class="cx"> #endif // PLATFORM(IOS)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosformsWKFormSelectControlmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.mm (165115 => 165116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.mm        2014-03-05 18:59:58 UTC (rev 165115)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectControl.mm        2014-03-05 19:48:32 UTC (rev 165116)
</span><span class="lines">@@ -44,6 +44,25 @@
</span><span class="cx"> 
</span><span class="cx"> using namespace WebKit;
</span><span class="cx"> 
</span><ins>+static const CGFloat minimumOptionFontSize = 12;
+
+CGFloat adjustedFontSize(CGFloat textWidth, UIFont *font, CGFloat initialFontSize, const Vector&lt;WKOptionItem&gt;&amp; items)
+{
+    CGFloat adjustedSize = initialFontSize;
+    for (size_t i = 0; i &lt; items.size(); ++i) {
+        const WKOptionItem&amp; item = items[i];
+        if (item.text.isEmpty())
+            continue;
+
+        CGFloat actualFontSize = initialFontSize;
+        [(NSString *)item.text _legacy_sizeWithFont:font minFontSize:minimumOptionFontSize actualFontSize:&amp;actualFontSize forWidth:textWidth lineBreakMode:NSLineBreakByWordWrapping];
+
+        if (actualFontSize &gt; 0 &amp;&amp; actualFontSize &lt; adjustedSize)
+            adjustedSize = actualFontSize;
+    }
+    return adjustedSize;
+}
+
</ins><span class="cx"> @implementation WKFormSelectControl {
</span><span class="cx">     RetainPtr&lt;id&lt;WKFormControl&gt;&gt; _control;
</span><span class="cx"> }
</span><span class="lines">@@ -63,10 +82,11 @@
</span><span class="cx"> 
</span><span class="cx">     if (UICurrentUserInterfaceIdiomIsPad())
</span><span class="cx">         _control = adoptNS([[WKSelectPopover alloc] initWithView:view hasGroups:hasGroups]);
</span><del>-    else if (!view.assistedNodeInformation.isMultiSelect &amp;&amp; !hasGroups)
</del><ins>+    else if (view.assistedNodeInformation.isMultiSelect || hasGroups)
+        _control = adoptNS([[WKMultipleSelectPicker alloc] initWithView:view]);
+    else
</ins><span class="cx">         _control = adoptNS([[WKSelectSinglePicker alloc] initWithView:view]);
</span><span class="cx">         
</span><del>-    // FIXME: Add support for iPhone UI with multiselect and or groups.
</del><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosformsWKFormSelectPickermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPicker.mm (165115 => 165116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPicker.mm        2014-03-05 18:59:58 UTC (rev 165115)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPicker.mm        2014-03-05 19:48:32 UTC (rev 165116)
</span><span class="lines">@@ -36,12 +36,269 @@
</span><span class="cx"> #import &lt;UIKit/UIApplication_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIDevice_Private.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIKeyboard_Private.h&gt;
</span><ins>+#import &lt;UIKit/UIPickerContentView_Private.h&gt;
</ins><span class="cx"> #import &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> 
</span><span class="cx"> using namespace WebKit;
</span><span class="cx"> 
</span><span class="cx"> static const float DisabledOptionAlpha = 0.3;
</span><span class="cx"> 
</span><ins>+@interface UIPickerView (UIPickerViewInternal)
+- (BOOL)allowsMultipleSelection;
+- (void)setAllowsMultipleSelection:(BOOL)aFlag;
+- (UITableView*)tableViewForColumn:(NSInteger)column;
+@end
+
+@interface WKOptionPickerCell : UIPickerContentView {
+    BOOL _disabled;
+}
+
+@property(nonatomic) BOOL disabled;
+
+- (instancetype)initWithOptionItem:(const WKOptionItem&amp;)item;
+
+@end
+
+@implementation WKOptionPickerCell
+
+- (BOOL)_isSelectable
+{
+    return !self.disabled;
+}
+
+- (instancetype)init
+{
+    if (!(self = [super initWithFrame:CGRectZero]))
+        return nil;
+    [[self titleLabel] setLineBreakMode:NSLineBreakByTruncatingMiddle];
+    return self;
+}
+
+- (instancetype)initWithOptionItem:(const WKOptionItem&amp;)item
+{
+    if (!(self = [self init]))
+        return nil;
+
+    NSMutableString *trimmedText = [[item.text mutableCopy] autorelease];
+    CFStringTrimWhitespace((CFMutableStringRef)trimmedText);
+
+    [[self titleLabel] setText:trimmedText];
+    [self setChecked:item.isSelected];
+    [self setDisabled:item.disabled];
+    if (_disabled)
+        [[self titleLabel] setTextColor:[UIColor colorWithWhite:0.0 alpha:DisabledOptionAlpha]];
+
+    return self;
+}
+
+@end
+
+
+@interface WKOptionGroupPickerCell : WKOptionPickerCell
+- (instancetype)initWithOptionItem:(const WKOptionItem&amp;)item;
+@end
+
+@implementation WKOptionGroupPickerCell
+
+- (instancetype)initWithOptionItem:(const WKOptionItem&amp;)item
+{
+    if (!(self = [self init]))
+        return nil;
+
+    NSMutableString *trimmedText = [[item.text mutableCopy] autorelease];
+    CFStringTrimWhitespace((CFMutableStringRef)trimmedText);
+
+    [[self titleLabel] setText:trimmedText];
+    [self setChecked:NO];
+    [[self titleLabel] setTextColor:[UIColor colorWithWhite:0.0 alpha:0.5]];
+    [self setDisabled:YES];
+
+    return self;
+}
+
+- (CGFloat)labelWidthForBounds:(CGRect)bounds
+{
+    return CGRectGetWidth(bounds) - [UIPickerContentView _checkmarkOffset];
+}
+
+- (void)layoutSubviews
+{
+    if (!self.titleLabel)
+        return;
+
+    CGRect bounds = self.bounds;
+    self.titleLabel.frame = CGRectMake([UIPickerContentView _checkmarkOffset], 0, CGRectGetMaxX(bounds) - [UIPickerContentView _checkmarkOffset], CGRectGetHeight(bounds));
+}
+
+@end
+
+
+@implementation WKMultipleSelectPicker {
+    WKContentView *_view;
+    NSTextAlignment _textAlignment;
+    NSUInteger _singleSelectionIndex;
+    bool _allowsMultipleSelection;
+    CGFloat _layoutWidth;
+    CGFloat _fontSize;
+    CGFloat _maximumTextWidth;
+}
+
+- (instancetype)initWithView:(WKContentView *)view
+{
+    if (!(self = [super initWithFrame:CGRectZero]))
+        return nil;
+
+    _view = view;
+    _allowsMultipleSelection = _view.assistedNodeInformation.isMultiSelect;
+    _singleSelectionIndex = NSNotFound;
+    [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
+    [self setDataSource:self];
+    [self setDelegate:self];
+    [self _setUsesCheckedSelection:YES];
+
+    [self _setMagnifierEnabled:NO];
+
+    UITextWritingDirection writingDirection = UITextWritingDirectionLeftToRight;
+    // FIXME: retrieve from WebProcess writing direction.
+    _textAlignment = (writingDirection == UITextWritingDirectionLeftToRight) ? NSTextAlignmentLeft : NSTextAlignmentRight;
+
+    [self setAllowsMultipleSelection:_allowsMultipleSelection];
+    [self setSize:[UIKeyboard defaultSizeForInterfaceOrientation:[UIApp interfaceOrientation]]];
+    [self reloadAllComponents];
+
+    const Vector&lt;WKOptionItem&gt;&amp; selectOptions = [_view assistedNodeSelectOptions];
+    int currentIndex = 0;
+    for (size_t i = 0; i &lt; selectOptions.size(); ++i) {
+        const WKOptionItem&amp; item = selectOptions[i];
+        if (item.isGroup)
+            continue;
+
+        if (!_allowsMultipleSelection &amp;&amp; item.isSelected)
+            _singleSelectionIndex = currentIndex;
+
+        currentIndex++;
+    }
+
+    if (_singleSelectionIndex != NSNotFound)
+        [self selectRow:_singleSelectionIndex inComponent:0 animated:NO];
+    
+    return self;
+}
+
+- (void)dealloc
+{
+    [self setDataSource:nil];
+    [self setDelegate:nil];
+
+    [super dealloc];
+}
+
+- (UIView *)controlView
+{
+    return self;
+}
+
+- (void)controlBeginEditing
+{
+}
+
+- (void)controlEndEditing
+{
+}
+
+- (void)layoutSubviews
+{
+    [super layoutSubviews];
+    if (_singleSelectionIndex != NSNotFound) {
+        [self selectRow:_singleSelectionIndex inComponent:0 animated:NO];
+    }
+
+    // Make sure all rows are sized properly after a rotation.
+    if (_layoutWidth != self.frame.size.width) {
+        [self reloadAllComponents];
+        _layoutWidth = self.frame.size.width;
+    }
+}
+
+- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)rowIndex forComponent:(NSInteger)columnIndex reusingView:(UIView *)view
+{
+    const WKOptionItem&amp; item = [_view assistedNodeSelectOptions][rowIndex];
+    UIPickerContentView* pickerItem = item.isGroup ? [[[WKOptionGroupPickerCell alloc] initWithOptionItem:item] autorelease] : [[[WKOptionPickerCell alloc] initWithOptionItem:item] autorelease];
+
+    // The cell starts out with a null frame. We need to set its frame now so we can find the right font size.
+    UITableView *table = [pickerView tableViewForColumn:0];
+    CGRect frame = [table rectForRowAtIndexPath:[NSIndexPath indexPathForRow:rowIndex inSection:0]];
+    pickerItem.frame = frame;
+
+    UILabel *titleTextLabel = pickerItem.titleLabel;
+    float width = [pickerItem labelWidthForBounds:CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame))];
+    ASSERT(width &gt; 0);
+
+    // Assume all cells have the same available text width.
+    UIFont *font = titleTextLabel.font;
+    if (width != _maximumTextWidth || _fontSize == 0) {
+        _maximumTextWidth = width;
+        _fontSize = adjustedFontSize(_maximumTextWidth, font, titleTextLabel.font.pointSize, [_view assistedNodeSelectOptions]);
+    }
+
+    [titleTextLabel setFont:[font fontWithSize:_fontSize]];
+    [titleTextLabel setLineBreakMode:NSLineBreakByWordWrapping];
+    [titleTextLabel setNumberOfLines:2];
+    [titleTextLabel setTextAlignment:_textAlignment];
+
+    return pickerItem;
+}
+
+- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)aPickerView
+{
+    return 1;
+}
+
+- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)columnIndex
+{
+    return [_view assistedNodeSelectOptions].size();
+}
+
+- (NSInteger)findItemIndexAt:(int)rowIndex
+{
+    ASSERT(rowIndex &gt;= 0 &amp;&amp; (size_t)rowIndex &lt; [_view assistedNodeSelectOptions].size());
+    NSInteger itemIndex = 0;
+    for (int i = 0; i &lt; rowIndex; ++i) {
+        if ([_view assistedNodeSelectOptions][i].isGroup)
+            continue;
+        itemIndex++;
+    }
+
+    ASSERT(itemIndex &gt;= 0);
+    return itemIndex;
+}
+
+- (void)pickerView:(UIPickerView *)pickerView row:(int)rowIndex column:(int)columnIndex checked:(BOOL)isChecked
+{
+    if ((size_t)rowIndex &gt;= [_view assistedNodeSelectOptions].size())
+        return;
+
+    WKOptionItem&amp; item = [_view assistedNodeSelectOptions][rowIndex];
+
+    if ([self allowsMultipleSelection]) {
+        [_view page]-&gt;setAssistedNodeSelectedIndex([self findItemIndexAt:rowIndex], isChecked);
+        item.isSelected = isChecked;
+    } else {
+        // Single selection.
+        item.isSelected = NO;
+        _singleSelectionIndex = rowIndex;
+
+        // This private delegate often gets called for multiple rows in the picker,
+        // so we only activate and set as selected the checked item in single selection.
+        if (isChecked) {
+            [_view page]-&gt;setAssistedNodeSelectedIndex([self findItemIndexAt:rowIndex], isChecked);
+            item.isSelected = YES;
+        }
+    }
+}
+
+@end
+
</ins><span class="cx"> @implementation WKSelectSinglePicker {
</span><span class="cx">     WKContentView *_view;
</span><span class="cx">     NSInteger _selectedIndex;
</span><span class="lines">@@ -53,15 +310,14 @@
</span><span class="cx">         return nil;
</span><span class="cx"> 
</span><span class="cx">     _view = view;
</span><del>-    self.delegate = self;
-    self.dataSource = self;
-    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
</del><ins>+    [self setDelegate:self];
+    [self setDataSource:self];
+    [self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
</ins><span class="cx"> 
</span><span class="cx">     _selectedIndex = NSNotFound;
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; [view assistedNodeSelectOptions].size(); ++i) {
</span><del>-        const WKOptionItem item = [_view assistedNodeSelectOptions][i];
-        if (item.isSelected) {
</del><ins>+        if ([_view assistedNodeSelectOptions][i].isSelected) {
</ins><span class="cx">             _selectedIndex = i;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -77,8 +333,8 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)dealloc
</span><span class="cx"> {
</span><del>-    self.delegate = nil;
-    self.dataSource = nil;
</del><ins>+    [self setDelegate:nil];
+     [self setDataSource:nil];
</ins><span class="cx"> 
</span><span class="cx">     [super dealloc];
</span><span class="cx"> }
</span><span class="lines">@@ -98,7 +354,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (_selectedIndex &lt; (NSInteger)[_view assistedNodeSelectOptions].size()) {
</span><del>-        [_view assistedNodeSelectOptions][_selectedIndex].isSelected = false;
</del><ins>+        [_view assistedNodeSelectOptions][_selectedIndex].isSelected = true;
</ins><span class="cx">         [_view page]-&gt;setAssistedNodeSelectedIndex(_selectedIndex);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -108,33 +364,6 @@
</span><span class="cx">     return 1;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static NSString *stringByTrimmingWhitespaceAndNewlines(NSString *string)
-{
-    NSRange r = NSMakeRange(0, [string length]);
-
-    if (!r.length)
-        return string;
-
-    NSUInteger originalLength = r.length;
-
-    // First strip all white space off the end of the range
-    while (r.length &gt; 0 &amp;&amp; CFUniCharIsMemberOf([string characterAtIndex: r.length - 1], kCFUniCharWhitespaceAndNewlineCharacterSet))
-        r.length -= 1;
-
-    // Then, trim any whitespace from the start of the range.
-    while (r.length &gt; 0 &amp;&amp; CFUniCharIsMemberOf([string characterAtIndex: r.location], kCFUniCharWhitespaceAndNewlineCharacterSet)) {
-        r.location += 1;
-        r.length -= 1;
-    }
-
-    // If we changed the length of the string from what it originally was, return a new string with just those
-    // characters.  Otherwise just return.
-    if (originalLength != r.length)
-        return [string substringWithRange:r];
-
-    return string;
-}
-
</del><span class="cx"> - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)columnIndex
</span><span class="cx"> {
</span><span class="cx">     return _view.assistedNodeInformation.selectOptions.size();
</span><span class="lines">@@ -146,11 +375,12 @@
</span><span class="cx">         return nil;
</span><span class="cx"> 
</span><span class="cx">     const WKOptionItem&amp; option = [_view assistedNodeSelectOptions][row];
</span><del>-    NSString *text = stringByTrimmingWhitespaceAndNewlines(option.text);
</del><ins>+    NSMutableString *trimmedText = [[option.text mutableCopy] autorelease];
+    CFStringTrimWhitespace((CFMutableStringRef)trimmedText);
</ins><span class="cx"> 
</span><del>-    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];
</del><ins>+    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:trimmedText];
</ins><span class="cx">     if (option.disabled)
</span><del>-        [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithWhite:0.0 alpha:DisabledOptionAlpha] range:NSMakeRange(0, [text length])];
</del><ins>+        [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithWhite:0.0 alpha:DisabledOptionAlpha] range:NSMakeRange(0, [trimmedText length])];
</ins><span class="cx"> 
</span><span class="cx">     return [attributedString autorelease];
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosformsWKFormSelectPopovermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPopover.mm (165115 => 165116)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPopover.mm        2014-03-05 18:59:58 UTC (rev 165115)
+++ trunk/Source/WebKit2/UIProcess/ios/forms/WKFormSelectPopover.mm        2014-03-05 19:48:32 UTC (rev 165116)
</span><span class="lines">@@ -48,7 +48,6 @@
</span><span class="cx"> using namespace WebKit;
</span><span class="cx"> 
</span><span class="cx"> static NSString* WKPopoverTableViewCellReuseIdentifier  = @&quot;WKPopoverTableViewCellReuseIdentifier&quot;;
</span><del>-static const CGFloat minimumOptionFontSize = 12;
</del><span class="cx"> 
</span><span class="cx"> @interface UITableViewCell (Internal)
</span><span class="cx"> - (CGRect)textRectForContentRect:(CGRect)contentRect;
</span><span class="lines">@@ -82,23 +81,6 @@
</span><span class="cx">     return [NSString stringWithFormat:@&quot;%C%@%C&quot;, directionalFormattingCharacter, string, popDirectionalFormatting];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static CGFloat adjustedFontSize(CGFloat textWidth, UIFont *font, CGFloat initialFontSize, const Vector&lt;WKOptionItem&gt;&amp; items)
-{
-    CGFloat adjustedSize = initialFontSize;
-    for (size_t i = 0; i &lt; items.size(); ++i) {
-        const WKOptionItem&amp; item = items[i];
-        if (item.text.isEmpty())
-            continue;
-        
-        CGFloat actualFontSize = initialFontSize;
-        [(NSString *)item.text _legacy_sizeWithFont:font minFontSize:minimumOptionFontSize actualFontSize:&amp;actualFontSize forWidth:textWidth lineBreakMode:NSLineBreakByWordWrapping];
-        
-        if (actualFontSize &gt; 0 &amp;&amp; actualFontSize &lt; adjustedSize)
-            adjustedSize = actualFontSize;
-    }
-    return adjustedSize;
-}
-
</del><span class="cx"> @class WKSelectPopover;
</span><span class="cx"> 
</span><span class="cx"> @interface WKSelectTableViewController : UITableViewController &lt;UIKeyInput&gt;
</span></span></pre>
</div>
</div>

</body>
</html>