diff --git a/AppKit/CPCompatibility.j b/AppKit/CPCompatibility.j index 1b05ed895..d2a8b0279 100644 --- a/AppKit/CPCompatibility.j +++ b/AppKit/CPCompatibility.j @@ -67,6 +67,12 @@ CPHTML5DragAndDropSourceYOffBy1 = 1 << 26; CPSOPDisabledFromFileURLs = 1 << 27; +// element.style.font can be set for an element not in the DOM. +CPInputSetFontOutsideOfDOM = 1 << 28; + +// Input elements have 1 px of extra padding on the left regardless of padding setting. +CPInput1PxLeftPadding = 1 << 29; + var USER_AGENT = "", PLATFORM_ENGINE = CPUnknownBrowserEngine, PLATFORM_FEATURES = 0; @@ -74,6 +80,7 @@ var USER_AGENT = "", // default these features to true PLATFORM_FEATURES |= CPInputTypeCanBeChangedFeature; +PLATFORM_FEATURES |= CPInputSetFontOutsideOfDOM; if (typeof window !== "undefined" && typeof window.navigator !== "undefined") USER_AGENT = window.navigator.userAgent; @@ -99,6 +106,9 @@ else if (typeof window !== "undefined" && window.attachEvent) // Must follow Ope PLATFORM_FEATURES |= CPOpacityRequiresFilterFeature; PLATFORM_FEATURES &= ~CPInputTypeCanBeChangedFeature; + + // Tested in Internet Explore 8 and 9. + PLATFORM_FEATURES &= ~CPInputSetFontOutsideOfDOM; } // WebKit @@ -135,6 +145,10 @@ else if (USER_AGENT.indexOf("AppleWebKit/") != -1) if (majorVersion < 532 || (majorVersion === 532 && minorVersion < 6)) PLATFORM_FEATURES |= CPHTML5DragAndDropSourceYOffBy1; + // This is supposedly fixed in webkit r123603. Seems to work in Chrome 21 but not Safari 6.0. + if (majorVersion < 537) + PLATFORM_FEATURES |= CPInput1PxLeftPadding; + if (USER_AGENT.indexOf("Chrome") === CPNotFound) PLATFORM_FEATURES |= CPSOPDisabledFromFileURLs; } @@ -160,6 +174,9 @@ else if (USER_AGENT.indexOf("Gecko") !== -1) // Must follow KHTML check. if (version < 3.0) PLATFORM_FEATURES |= CPJavaScriptMouseWheelValues_8_15; + + // Some day this might be fixed and should be version prefixed. No known fixed version yet. + PLATFORM_FEATURES |= CPInput1PxLeftPadding; } // Feature Specific Checks diff --git a/AppKit/CPTextField.j b/AppKit/CPTextField.j index 8fb8cab56..8c0360197 100644 --- a/AppKit/CPTextField.j +++ b/AppKit/CPTextField.j @@ -509,7 +509,8 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); element.value = _stringValue; element.style.color = [[self currentValueForThemeAttribute:@"text-color"] cssString]; - element.style.font = [font cssString]; + if (CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM)) + element.style.font = [font cssString]; element.style.zIndex = 1000; switch ([self alignment]) @@ -544,12 +545,22 @@ CPTextFieldStatePlaceholder = CPThemeState("placeholder"); } element.style.top = topPoint; - element.style.left = (_CGRectGetMinX(contentRect) - 1) + "px"; // -1 because input element seems to have 1px left inset + var left = _CGRectGetMinX(contentRect); + // If the browser has a built in left padding, compensate for it. We need the input text to be exactly on top of the original text. + if (CPFeatureIsCompatible(CPInput1PxLeftPadding)) + left -= 1; + element.style.left = left + "px"; element.style.width = _CGRectGetWidth(contentRect) + "px"; - element.style.height = lineHeight + "px"; + element.style.height = ROUND(lineHeight) + "px"; + element.style.lineHeight = ROUND(lineHeight) + "px"; + element.style.verticalAlign = @"top"; _DOMElement.appendChild(element); + // The font change above doesn't work for some browsers if the element isn't already .appendChild'ed. + if (!CPFeatureIsCompatible(CPInputSetFontOutsideOfDOM)) + element.style.font = [font cssString]; + window.setTimeout(function() { element.focus(); diff --git a/AppKit/Platform/DOM/CPPlatformString.j b/AppKit/Platform/DOM/CPPlatformString.j index 34929ad7b..0f6e7731d 100644 --- a/AppKit/Platform/DOM/CPPlatformString.j +++ b/AppKit/Platform/DOM/CPPlatformString.j @@ -135,8 +135,8 @@ var DOMFixedWidthSpanElement = nil, style.border = "none"; style.verticalAlign = "baseline"; - bodyElement.appendChild(DOMMetricsTextSpanElement); - bodyElement.appendChild(DOMMetricsImgElement); + DOMMetricsDivElement.appendChild(DOMMetricsTextSpanElement); + DOMMetricsDivElement.appendChild(DOMMetricsImgElement); } + (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth diff --git a/AppKit/_CPImageAndTextView.j b/AppKit/_CPImageAndTextView.j index 4a33f2201..c12661d1e 100644 --- a/AppKit/_CPImageAndTextView.j +++ b/AppKit/_CPImageAndTextView.j @@ -432,13 +432,15 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0, { _DOMTextShadowElement = document.createElement("div"); - var shadowStyle = _DOMTextShadowElement.style; + var shadowStyle = _DOMTextShadowElement.style, + font = (_font || [CPFont systemFontOfSize:CPFontCurrentSystemSize]); - shadowStyle.font = [(_font || [CPFont systemFontOfSize:CPFontCurrentSystemSize]) cssString]; + shadowStyle.font = [font cssString]; shadowStyle.position = "absolute"; shadowStyle.whiteSpace = textStyle.whiteSpace; shadowStyle.wordWrap = textStyle.wordWrap; shadowStyle.color = [_textShadowColor cssString]; + shadowStyle.lineHeight = [font defaultLineHeightForFont] + "px"; shadowStyle.zIndex = 150; shadowStyle.textOverflow = textStyle.textOverflow; @@ -484,11 +486,16 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0, if (_flags & _CPImageAndTextViewFontChangedFlag) { - var fontStyle = [(_font || [CPFont systemFontOfSize:CPFontCurrentSystemSize]) cssString]; + var font = (_font || [CPFont systemFontOfSize:CPFontCurrentSystemSize]), + fontStyle = [font cssString]; textStyle.font = fontStyle; + textStyle.lineHeight = [font defaultLineHeightForFont] + "px"; if (shadowStyle) + { shadowStyle.font = fontStyle; + shadowStyle.lineHeight = [font defaultLineHeightForFont] + "px"; + } } // Update the line break mode if necessary. @@ -713,6 +720,7 @@ var _CPimageAndTextViewFrameSizeChangedFlag = 1 << 0, textStyle.left = ROUND(textRectX) + "px"; textStyle.width = MAX(CEIL(textRectWidth), 0) + "px"; textStyle.height = MAX(CEIL(textRectHeight), 0) + "px"; + textStyle.verticalAlign = @"top"; if (shadowStyle) { diff --git a/Tests/Manual/CPTextField/AppController.j b/Tests/Manual/CPTextField/AppController.j index ccef231bd..11911d466 100644 --- a/Tests/Manual/CPTextField/AppController.j +++ b/Tests/Manual/CPTextField/AppController.j @@ -52,6 +52,28 @@ [contentView addSubview:shadowLabel]; [contentView addSubview:championOfLightLabel]; + var jumpLabel = [CPTextField labelWithTitle:@"The text of these text fields should not move when a field becomes the first responder."]; + + [jumpLabel sizeToFit]; + [jumpLabel setFrameOrigin:CGPointMake(15, 150)]; + [contentView addSubview:jumpLabel]; + + var y = CGRectGetMaxY([jumpLabel frame]) + 10; + + for (var i = 0; i < 5; i++) + { + var size = 10 + 3 * i, + textField = [CPTextField textFieldWithStringValue:@"Size " + size placeholder:@"Size " + size width:200]; + + [textField setFont:[CPFont systemFontOfSize:size]]; + [textField sizeToFit]; + [textField setFrameOrigin:CGPointMake(15, y)]; + + y = CGRectGetMaxY([textField frame]) + 6; + + [contentView addSubview:textField]; + } + [theWindow orderFront:self]; aWindow = [[CPWindow alloc] initWithContentRect:CGRectMake(150, 300, 400, 150) styleMask:CPTitledWindowMask | CPClosableWindowMask | CPDocModalWindowMask];