From 831bbef9e11d0e8ce663b11d2b67d11b9e4a60ea Mon Sep 17 00:00:00 2001 From: Ross Boucher Date: Mon, 13 Apr 2009 14:33:27 -0700 Subject: [PATCH] First take of new CPSecureTextField. Known issues in IE. --- AppKit/CPSecureTextField.j | 95 ++------------------------------------ AppKit/CPTextField.j | 55 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 94 deletions(-) diff --git a/AppKit/CPSecureTextField.j b/AppKit/CPSecureTextField.j index d53c3402e..cca7e0da1 100644 --- a/AppKit/CPSecureTextField.j +++ b/AppKit/CPSecureTextField.j @@ -2,102 +2,13 @@ #include "Platform/Platform.h" - -var TOP_PADDING = 4.0, - BOTTOM_PADDING = 3.0; - HORIZONTAL_PADDING = 3.0; - -var CPSecureTextFieldDOMInputElement = nil; - @implementation CPSecureTextField : CPTextField { } -#if PLATFORM(DOM) -+ (DOMElement)_inputElement +- (BOOL)isSecure { - if (!CPSecureTextFieldDOMInputElement) - { - CPSecureTextFieldDOMInputElement = document.createElement("input"); - CPSecureTextFieldDOMInputElement.type = "password"; - CPSecureTextFieldDOMInputElement.style.position = "absolute"; - CPSecureTextFieldDOMInputElement.style.top = "0px"; - CPSecureTextFieldDOMInputElement.style.left = "0px"; - CPSecureTextFieldDOMInputElement.style.width = "100%" - CPSecureTextFieldDOMInputElement.style.height = "100%"; - CPSecureTextFieldDOMInputElement.style.border = "0px"; - CPSecureTextFieldDOMInputElement.style.padding = "0px"; - CPSecureTextFieldDOMInputElement.style.whiteSpace = "pre"; - CPSecureTextFieldDOMInputElement.style.background = "transparent"; - CPSecureTextFieldDOMInputElement.style.outline = "none"; - CPSecureTextFieldDOMInputElement.style.paddingLeft = HORIZONTAL_PADDING + "px"; - CPSecureTextFieldDOMInputElement.style.paddingTop = TOP_PADDING - 2.0 + "px"; - CPSecureTextFieldDOMInputElement.style.margin = "0px"; - } - - return CPSecureTextFieldDOMInputElement; -} -#endif - -- (id)initWithFrame:(CGRect)aFrame -{ - self = [super initWithFrame:aFrame]; - - if (self) - { -#if PLATFORM(DOM) - _DOMElement.removeChild(_DOMTextElement); - - _DOMTextElement = document.createElement("input"); - _DOMTextElement.type = "password"; - _DOMTextElement.style.position = "absolute"; - _DOMTextElement.style.top = TOP_PADDING + "px"; - _DOMTextElement.style.left = HORIZONTAL_PADDING + "px"; - _DOMTextElement.style.width = MAX(0.0, CGRectGetWidth(aFrame) - 2.0 * HORIZONTAL_PADDING) + "px"; - _DOMTextElement.style.height = MAX(0.0, CGRectGetHeight(aFrame) - TOP_PADDING - BOTTOM_PADDING) + "px"; - _DOMTextElement.style.whiteSpace = "pre"; - _DOMTextElement.style.cursor = "default"; - _DOMTextElement.style.zIndex = 100; - _DOMTextElement.style.border = "0"; - _DOMTextElement.style.font = _DOMElement.style.font; - _DOMTextElement.style.padding = "0px"; - _DOMTextElement.style.margin = "0px"; - - _DOMElement.appendChild(_DOMTextElement); -#endif - } - - return self; + return YES; } -- (void)setFont:(CPFont)aFont -{ - [super setFont:aFont]; - -#if PLATFORM(DOM) - if (_DOMTextElement) - _DOMTextElement.style.font = _DOMElement.style.font; -#endif -} - -- (CPString)stringValue -{ - // All of this needs to be better. -#if PLATFORM(DOM) - if ([[self window] firstResponder] == self) - return [[self class] _inputElement].value; -#endif - - return _DOMTextElement.value; -} - -- (void)setStringValue:(CPString)aStringValue -{ - _value = aStringValue; - -#if PLATFORM(DOM) - _DOMTextElement.value = _value; -#endif -} - -@end \ No newline at end of file +@end diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 6d1ffc8d1..b79159bbc 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -78,6 +78,8 @@ CPTextFieldRoundedBezel = 1; var CPTextFieldDOMInputElement = nil; #endif +var CPSecureTextFieldCharacter = "\u2022"; + @implementation CPString (CPTextFieldAdditions) /*! @@ -100,6 +102,7 @@ CPTextFieldStatePlaceholder = 1 << 13; { BOOL _isEditable; BOOL _isSelectable; + BOOL _isSecure; BOOL _drawsBackground; @@ -143,6 +146,12 @@ CPTextFieldStatePlaceholder = 1 << 13; } #endif ++ (void)initialize +{ + if (CPBrowserIsEngine(CPGeckoBrowserEngine)) + CPSecureTextFieldCharacter = "*"; +} + - (id)initWithFrame:(CGRect)aFrame { self = [super initWithFrame:aFrame]; @@ -195,6 +204,23 @@ CPTextFieldStatePlaceholder = 1 << 13; return _isSelectable; } +/*! + Sets whether the field's text is secure. + @param aFlag YES makes the text secure +*/ +- (void)setSecure:(BOOL)aFlag +{ + _isSecure = aFlag; +} + +/*! + Returns YES if the field's text is secure (password entry). +*/ +- (BOOL)isSecure +{ + return _isSecure; +} + // Setting the Bezel Style /*! Sets whether the textfield will have a bezeled border. @@ -346,6 +372,11 @@ CPTextFieldStatePlaceholder = 1 << 13; element.style.font = [[self currentValueForThemedAttributeName:@"font"] cssString]; element.style.zIndex = 1000; + if ([self isSecure]) + element.type = "password"; + else + element.type = "text"; + var contentRect = [self contentRectForBounds:[self bounds]]; element.style.top = _CGRectGetMinY(contentRect) + "px"; @@ -682,10 +713,17 @@ CPTextFieldStatePlaceholder = 1 << 13; { [contentView setHidden:_controlState & CPControlStateEditing]; + var string = ""; + if (_controlState & CPTextFieldStatePlaceholder) - [contentView setText:[self placeholderString]]; + string = [self placeholderString]; else - [contentView setText:[self stringValue]]; + string = [self stringValue]; + + if ([self isSecure]) + string = secureStringForString(string); + + [contentView setText:string]; [contentView setTextColor:[self currentValueForThemedAttributeName:@"text-color"]]; [contentView setFont:[self currentValueForThemedAttributeName:@"font"]]; @@ -699,6 +737,18 @@ CPTextFieldStatePlaceholder = 1 << 13; @end +var secureStringForString = function(aString) +{ + var secureString = "", + length = aString.length; + + while (length--) + secureString += CPSecureTextFieldCharacter; + + return secureString; +} + + var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey", CPTextFieldIsSelectableKey = "CPTextFieldIsSelectableKey", CPTextFieldIsBorderedKey = "CPTextFieldIsBorderedKey", @@ -754,3 +804,4 @@ var CPTextFieldIsEditableKey = "CPTextFieldIsEditableKey", } @end +