diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index 4a2f8fffa..5935fef13 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -638,6 +638,20 @@ HTMLInputElement::InitDatePicker()
nsresult rv = datePicker->Init(win, EmptyString()); // title NYI
NS_ENSURE_SUCCESS(rv, rv);
rv = datePicker->SetDefaultDate(initialValue);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (HasAttr(kNameSpaceID_None, nsGkAtoms::min)) {
+ nsAutoString minStr;
+ GetAttr(kNameSpaceID_None, nsGkAtoms::min, minStr);
+ rv = datePicker->SetMinDate(minStr);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ if (HasAttr(kNameSpaceID_None, nsGkAtoms::max)) {
+ nsAutoString maxStr;
+ GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxStr);
+ rv = datePicker->SetMaxDate(maxStr);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
nsCOMPtr callback =
new nsDatePickerShownCallback(this, datePicker);
@@ -2279,10 +2293,12 @@ HTMLInputElement::MozSetFileNameArray(const char16_t** aFileNames, uint32_t aLen
bool
HTMLInputElement::MozIsTextField(bool aExcludePassword)
{
+/*
// TODO: temporary until bug 773205 is fixed.
if (IsExperimentalMobileType(mType)) {
return false;
}
+*/
return IsSingleLineTextControl(aExcludePassword);
}
@@ -4824,8 +4840,8 @@ HTMLInputElement::ParseAttribute(int32_t aNamespaceID,
bool success = aResult.ParseEnumValue(aValue, kInputTypeTable, false);
if (success) {
newType = aResult.GetEnumValue();
- if ((IsExperimentalMobileType(newType) &&
- !Preferences::GetBool("dom.experimental_forms", false)) ||
+ if (/* (IsExperimentalMobileType(newType) &&
+ !Preferences::GetBool("dom.experimental_forms", false)) || */
(newType == NS_FORM_INPUT_DATE &&
!Preferences::GetBool("tenfourfox.dom.forms.date", false)) ||
(newType == NS_FORM_INPUT_TIME &&
@@ -6328,10 +6344,12 @@ HTMLInputElement::PlaceholderApplies() const
bool
HTMLInputElement::DoesPatternApply() const
{
+/*
// TODO: temporary until bug 773205 is fixed.
if (IsExperimentalMobileType(mType)) {
return false;
}
+*/
return IsSingleLineTextControl(false);
}
diff --git a/widget/cocoa/nsDatePicker.h b/widget/cocoa/nsDatePicker.h
index 8ddd6733e..b975e672c 100644
--- a/widget/cocoa/nsDatePicker.h
+++ b/widget/cocoa/nsDatePicker.h
@@ -41,7 +41,9 @@ protected:
bool mHasDefault;
nsString mDefault;
nsString mMinDate;
+ bool mHasMin;
nsString mMaxDate;
+ bool mHasMax;
};
#endif // nsDatePicker_h_
diff --git a/widget/cocoa/nsDatePicker.mm b/widget/cocoa/nsDatePicker.mm
index 9c0a3be34..db644b4b5 100644
--- a/widget/cocoa/nsDatePicker.mm
+++ b/widget/cocoa/nsDatePicker.mm
@@ -28,37 +28,76 @@
- (id)buildAlertStyle:(int)fp8 title:(id)fp12 message:(id)fp16 first:(id)fp20 second:(id)fp24 third:(id)fp28 oldStyle:(BOOL)fp32 args:(char *)fp36;
@end
-////// NSPopUpDatePicker
+@class NSDoubleDatePicker; // forward declaration
+
+@interface NSDoubleDateDelegate : NSObject {
+ NSDoubleDatePicker *_parentAlert;
+ NSDatePicker *_source;
+}
+
+- (void)datePickerCell:(NSDatePickerCell *)aDatePickerCell
+ validateProposedDateValue:(NSDate **)proposedDateValue
+ timeInterval:(NSTimeInterval *)proposedTimeInterval;
+- (void)setParentAlert:(NSDoubleDatePicker *)parentAlert
+ withSource:(NSDatePicker *)source;
+@end
+
+@implementation NSDoubleDateDelegate
+- (void)datePickerCell:(NSDatePickerCell *)aDatePickerCell
+ validateProposedDateValue:(NSDate **)proposedDateValue
+ timeInterval:(NSTimeInterval *)proposedTimeInterval
+{
+ //NSLog(@"validate");
+ [_parentAlert onSwitchControl:_source newDate:proposedDateValue];
+}
+
+- (void)setParentAlert:(NSDoubleDatePicker *)parentAlert
+ withSource:(NSDatePicker *)source
+{
+ _parentAlert = parentAlert;
+ _source = source;
+}
+@end
+
+////// NSDoubleDatePicker
////// based on NSAlertCheckbox, http://cocoadev.github.io/NSAlertCheckbox/
-@interface NSPopUpDatePicker : NSAlert {
- NSDatePicker *_picker;
+@interface NSDoubleDatePicker : NSAlert {
+ NSDatePicker *_pickertop;
+ NSDatePicker *_pickerbottom;
+ NSDoubleDateDelegate *_topdelegate;
+ NSDoubleDateDelegate *_bottomdelegate;
}
- (void)dealloc;
-- (NSPopUpDatePicker *)datePicker:(NSString *)message
+- (NSDoubleDatePicker *)datePicker:(NSString *)message
defaultButton:(NSString *)defaultButton
alternateButton:(NSString *)alternateButton
otherButton:(NSString *)otherButton
informativeTextWithFormat:(NSString *)format;
+- (void)onSwitchControl:(NSDatePicker *)which newDate:(NSDate **)newDate;
- (NSDate *)date;
- (void)setDate:(NSDate *)date;
@end
-@interface NSPopUpDatePicker(Private)
-- (void)_ensureDatePicker;
-- (void)_addDatePickerToAlert;
+@interface NSDoubleDatePicker(Private)
+- (void)_ensureDatePickers;
+- (void)_addDatePickersToAlert;
@end
-@implementation NSPopUpDatePicker
+@implementation NSDoubleDatePicker
- (void)dealloc
{
- [_picker release];
+//NSLog(@"dealloc");
+ [_pickertop release];
+ [_pickerbottom release];
+ [_topdelegate release];
+ [_bottomdelegate release];
[super dealloc];
}
-- (NSPopUpDatePicker *)datePicker:(NSString *)message
+- (NSDoubleDatePicker *)datePicker:(NSString *)message
defaultButton:(NSString *)defaultButton
alternateButton:(NSString *)alternateButton
otherButton:(NSString *)otherButton
@@ -69,7 +108,7 @@
alternateButton:alternateButton
otherButton:otherButton
informativeTextWithFormat:format];
- return (NSPopUpDatePicker *)alert;
+ return (NSDoubleDatePicker *)alert;
}
- (id)buildAlertStyle:(int)fp8
@@ -87,7 +126,7 @@
second:fp24
third:fp28
oldStyle:fp32];
- [self _addDatePickerToAlert];
+ [self _addDatePickersToAlert];
return rv;
}
@@ -108,46 +147,92 @@
third:fp28
oldStyle:fp32
args:fp36];
- [self _addDatePickerToAlert];
+ [self _addDatePickersToAlert];
return rv;
}
+- (void)onSwitchControl:(NSDatePicker *)which newDate:(NSDate **)newDate
+{
+ // Halt the delegate on the one we're setting first.
+ if (which == _pickertop) {
+ //NSLog(@"control event: top");
+ [_pickerbottom setDelegate:nil];
+ [_pickerbottom setDateValue:*newDate];
+ [_pickerbottom setDelegate:_bottomdelegate];
+ } else if (which == _pickerbottom) {
+ //NSLog(@"control event: bottom");
+ [_pickertop setDelegate:nil];
+ [_pickertop setDateValue:*newDate];
+ [_pickertop setDelegate:_topdelegate];
+ } else
+ NSLog(@"wtf");
+}
+
- (NSDate *)date
{
- [self _ensureDatePicker];
- return [_picker dateValue];
+ [self _ensureDatePickers];
+ return [_pickertop dateValue];
}
- (void)setDate:(NSDate *)date
{
- [self _ensureDatePicker];
- [_picker setDateValue:date];
+ [self _ensureDatePickers];
+ [_pickertop setDateValue:date];
+ [_pickerbottom setDateValue:date];
+}
+
+- (void)setMinDate:(NSDate *)date
+{
+ [self _ensureDatePickers];
+ [_pickertop setMinDate:date];
+ [_pickerbottom setMinDate:date];
+}
+
+- (void)setMaxDate:(NSDate *)date
+{
+ [self _ensureDatePickers];
+ [_pickertop setMaxDate:date];
+ [_pickerbottom setMaxDate:date];
}
@end
-@implementation NSPopUpDatePicker(Private)
-- (void)_ensureDatePicker
+@implementation NSDoubleDatePicker(Private)
+- (void)_ensureDatePickers
{
- if (!_picker) {
- _picker = [[NSDatePicker alloc] initWithFrame:NSMakeRect(10,10,295,154)];
- [_picker setDatePickerStyle:NSClockAndCalendarDatePickerStyle];
- [_picker setDatePickerElements:NSYearMonthDayDatePickerElementFlag];
+ if (!_pickertop) {
+// NSLog(@"picker init");
+ _pickertop = [[NSDatePicker alloc] initWithFrame:NSMakeRect(10,10,295,154)];
+ [_pickertop setDatePickerStyle:NSClockAndCalendarDatePickerStyle];
+ [_pickertop setDatePickerElements:NSYearMonthDayDatePickerElementFlag];
+
+ _topdelegate = [[NSDoubleDateDelegate alloc] init];
+ [_topdelegate setParentAlert:self withSource:_pickertop];
+ [_pickertop setDelegate:_topdelegate];
+
+ _pickerbottom = [[NSDatePicker alloc] initWithFrame:NSMakeRect(10,10,295,154)];
+ [_pickerbottom setDatePickerStyle:NSTextFieldAndStepperDatePickerStyle];
+ [_pickerbottom setDatePickerElements:NSYearMonthDayDatePickerElementFlag];
+
+ _bottomdelegate = [[NSDoubleDateDelegate alloc] init];
+ [_bottomdelegate setParentAlert:self withSource:_pickerbottom];
+ [_pickerbottom setDelegate:_bottomdelegate];
}
}
-- (void)_addDatePickerToAlert
+
+- (void)_addDatePickersToAlert
{
NSWindow *window = [self window];
NSView *content = [window contentView];
float padding = 14.0f;
-
+
NSArray *subviews = [content subviews];
NSEnumerator *en = [subviews objectEnumerator];
NSView *subview = nil;
NSTextField *messageText = nil;
int count = 0;
-
- [self _ensureDatePicker];
-
+
+ [self _ensureDatePickers];
+
// Find the main text field.
while (subview = [en nextObject]) {
if ([subview isKindOfClass:[NSTextField class]]) {
@@ -156,24 +241,35 @@
}
}
if (messageText) {
- [content addSubview:_picker];
- [_picker sizeToFit];
-
+ [content addSubview:_pickertop];
+ [_pickertop sizeToFit];
+ [content addSubview:_pickerbottom];
+ [_pickerbottom sizeToFit];
+
// Expand the alert window.
NSRect windowFrame = [window frame];
- NSRect pickerFrame = [_picker frame];
-
- windowFrame.size.height += pickerFrame.size.height + padding;
+ NSRect topPickerFrame = [_pickertop frame];
+ NSRect bottomPickerFrame = [_pickerbottom frame];
+
+ windowFrame.size.height += topPickerFrame.size.height + padding +
+ bottomPickerFrame.size.height + padding;
[window setFrame:windowFrame display:YES];
-
- // Insert the picker below the main text field.
- pickerFrame.origin.y = [messageText frame].origin.y -
- pickerFrame.size.height - padding;
- pickerFrame.origin.x = [messageText frame].origin.x;
-
- [_picker setFrame:pickerFrame];
+
+ // Insert the pickers below the main text field.
+ topPickerFrame.origin.y = [messageText frame].origin.y -
+ bottomPickerFrame.size.height - padding -
+ topPickerFrame.size.height - padding;
+ topPickerFrame.origin.x = [messageText frame].origin.x;
+
+ bottomPickerFrame.origin.y = topPickerFrame.origin.y +
+ topPickerFrame.size.height + padding;
+ bottomPickerFrame.origin.x = topPickerFrame.origin.x;
+
+ [_pickertop setFrame:topPickerFrame];
+ [_pickerbottom setFrame:bottomPickerFrame];
+ //NSLog(@"Picker installed");
} else
- fprintf(stderr, "Could not insinuate modal NSDatePicker.\n");
+ NSLog(@"Couldn't find message text, did not add pickers");
}
@end
@@ -215,37 +311,46 @@ int16_t
nsDatePicker::GetDate()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
- int16_t retVal = returnCancel;
-
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setFormatterBehavior:NSDateFormatterBehavior10_4];
[formatter setDateFormat:@"yyyy-MM-dd"];
- NSPopUpDatePicker *alert = [NSPopUpDatePicker
- alertWithMessageText:@"One"
- defaultButton:@"OK"
- alternateButton:@"Cancel"
- otherButton:nil
- informativeTextWithFormat:@"Blah blah"];
+ NSDoubleDatePicker *alert = [NSDoubleDatePicker
+ alertWithMessageText:@" "// XXX: localize this eventually
+ defaultButton:nil // "OK"
+ alternateButton:nil // "Cancel"
+ otherButton:nil // nothin'
+ informativeTextWithFormat:@""];
if (mHasDefault) {
NSDate *newDate = [formatter dateFromString:nsCocoaUtils::ToNSString(mDefault)];
- [alert setDate:newDate];
+ if (newDate)
+ [alert setDate:newDate];
} else
[alert setDate:[NSDate date]];
+ if (mHasMin) {
+ NSDate *newDate = [formatter dateFromString:nsCocoaUtils::ToNSString(mMinDate)];
+ if (newDate)
+ [alert setMinDate:newDate];
+ }
+ if (mHasMax) {
+ NSDate *newDate = [formatter dateFromString:nsCocoaUtils::ToNSString(mMaxDate)];
+ if (newDate)
+ [alert setMaxDate:newDate];
+ }
nsCocoaUtils::PrepareForNativeAppModalDialog();
- int result = [alert runModal]; //[NSApp runModalForWindow:pwin];
+ int result = [alert runModal];
nsCocoaUtils::CleanUpAfterNativeAppModalDialog();
- if (result == NSFileHandlingPanelCancelButton)
- return retVal;
+ if (result == NSAlertAlternateReturn) // cancel
+ return returnCancel;
nsCocoaUtils::GetStringForNSString([formatter stringFromDate:[alert date]],
mDate);
- return retVal;
+ return returnOK;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(returnCancel);
}
-// XXX Not used
+// XXX Not used currently, needs localization
// Sets the dialog title to whatever it should be. If it fails, eh,
// the OS will provide a sensible default.
void
@@ -272,6 +377,7 @@ NS_IMETHODIMP nsDatePicker::GetDefaultDate(nsAString& aString)
NS_IMETHODIMP nsDatePicker::SetMinDate(const nsAString& aString)
{
+ mHasMin = true;
mMinDate = aString;
return NS_OK;
}
@@ -283,6 +389,7 @@ NS_IMETHODIMP nsDatePicker::GetMinDate(nsAString& aString)
NS_IMETHODIMP nsDatePicker::SetMaxDate(const nsAString& aString)
{
+ mHasMax = true;
mMaxDate = aString;
return NS_OK;
}