mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 13:07:02 +00:00
205 lines
5.8 KiB
Plaintext
205 lines
5.8 KiB
Plaintext
/*
|
|
* CPPlatformString.j
|
|
* AppKit
|
|
*
|
|
* Created by Francisco Tolmasky.
|
|
* Copyright 2010, 280 North, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
var DOMFixedWidthSpanElement = nil,
|
|
DOMFlexibleWidthSpanElement = nil,
|
|
DOMMetricsDivElement = nil,
|
|
DOMMetricsImgElement = nil,
|
|
DefaultFont = nil;
|
|
|
|
@implementation CPPlatformString : CPBasePlatformString
|
|
{
|
|
}
|
|
|
|
+ (void)initialize
|
|
{
|
|
if (self !== [CPPlatformString class])
|
|
return;
|
|
|
|
DefaultFont = [CPFont systemFontOfSize:CPFontCurrentSystemSize];
|
|
}
|
|
|
|
+ (void)bootstrap
|
|
{
|
|
[self createDOMElements];
|
|
}
|
|
|
|
+ (void)createDOMElements
|
|
{
|
|
var style,
|
|
bodyElement = [CPPlatform mainBodyElement];
|
|
|
|
DOMFlexibleWidthSpanElement = document.createElement("span");
|
|
DOMFlexibleWidthSpanElement.className = "cpdontremove";
|
|
style = DOMFlexibleWidthSpanElement.style;
|
|
style.position = "absolute";
|
|
style.left = "-100000px";
|
|
style.zIndex = -10000;
|
|
style.visibility = "visible";
|
|
style.padding = "0px";
|
|
style.margin = "0px";
|
|
style.whiteSpace = "pre";
|
|
|
|
DOMFixedWidthSpanElement = document.createElement("span");
|
|
DOMFixedWidthSpanElement.className = "cpdontremove";
|
|
style = DOMFixedWidthSpanElement.style;
|
|
style.display = "block";
|
|
style.position = "absolute";
|
|
style.left = "-100000px";
|
|
style.zIndex = -10000;
|
|
style.visibility = "visible";
|
|
style.padding = "0px";
|
|
style.margin = "0px";
|
|
style.width = "1px";
|
|
style.wordWrap = "break-word";
|
|
|
|
try
|
|
{
|
|
style.whiteSpace = "pre";
|
|
style.whiteSpace = "-o-pre-wrap";
|
|
style.whiteSpace = "-pre-wrap";
|
|
style.whiteSpace = "-moz-pre-wrap";
|
|
style.whiteSpace = "pre-wrap";
|
|
}
|
|
catch(e)
|
|
{
|
|
//some versions of IE throw exceptions for unsupported properties.
|
|
style.whiteSpace = "pre";
|
|
}
|
|
|
|
bodyElement.appendChild(DOMFlexibleWidthSpanElement);
|
|
bodyElement.appendChild(DOMFixedWidthSpanElement);
|
|
}
|
|
|
|
+ (void)createDOMMetricsElements
|
|
{
|
|
var style,
|
|
bodyElement = [CPPlatform mainBodyElement];
|
|
|
|
DOMMetricsDivElement = document.createElement("div");
|
|
DOMMetricsDivElement.className = "cpdontremove";
|
|
style = DOMMetricsDivElement.style;
|
|
style.position = "absolute";
|
|
style.left = "-100000px";
|
|
style.zIndex = -10000;
|
|
style.width = "100000px";
|
|
style.whiteSpace = "nowrap";
|
|
style.lineHeight = "1em";
|
|
style.padding = "0px";
|
|
style.margin = "0px";
|
|
DOMMetricsDivElement.innerHTML = "x";
|
|
|
|
bodyElement.appendChild(DOMMetricsDivElement);
|
|
|
|
var imgPath = [[CPBundle bundleForClass:[CPView class]] pathForResource:@"empty.png"];
|
|
|
|
DOMMetricsImgElement = document.createElement("img");
|
|
DOMMetricsImgElement.className = "cpdontremove";
|
|
DOMMetricsImgElement.setAttribute("src", imgPath);
|
|
DOMMetricsImgElement.setAttribute("width", "1");
|
|
DOMMetricsImgElement.setAttribute("height", "1");
|
|
DOMMetricsImgElement.setAttribute("alt", "");
|
|
style = DOMMetricsImgElement.style;
|
|
style.zIndex = -10000;
|
|
style.visibility = "visible";
|
|
style.padding = "0px";
|
|
style.margin = "0px";
|
|
style.border = "none";
|
|
style.verticalAlign = "baseline";
|
|
|
|
DOMMetricsDivElement.appendChild(DOMMetricsImgElement);
|
|
}
|
|
|
|
+ (int)charPositionOfString:(CPString)aString withFont:(CPFont)aFont forPoint:(CGPoint)aPoint
|
|
{
|
|
if (!aString)
|
|
return 0;
|
|
|
|
var position = 0,
|
|
stringLength = aString.length,
|
|
currentString = "";
|
|
|
|
for (var i = 0; i < stringLength; i++)
|
|
{
|
|
var lastChar = aString[i];
|
|
|
|
currentString += lastChar;
|
|
|
|
var sizeOfString = [self sizeOfString:currentString withFont:aFont forWidth:nil].width,
|
|
sizeLastChar = [self sizeOfString:lastChar withFont:aFont forWidth:nil].width;
|
|
|
|
if (sizeOfString - sizeLastChar / 2 < aPoint.x)
|
|
position++;
|
|
else
|
|
break;
|
|
}
|
|
|
|
return position;
|
|
}
|
|
|
|
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
|
|
{
|
|
if (!DOMFixedWidthSpanElement)
|
|
[self createDOMElements];
|
|
|
|
var span;
|
|
|
|
if (!aWidth)
|
|
span = DOMFlexibleWidthSpanElement;
|
|
else
|
|
{
|
|
span = DOMFixedWidthSpanElement;
|
|
span.style.width = ROUND(aWidth) + "px";
|
|
}
|
|
|
|
var effectiveFontCSSString = [(aFont || DefaultFont) cssString];
|
|
if (span.style.font !== effectiveFontCSSString)
|
|
span.style.font = effectiveFontCSSString;
|
|
|
|
if (CPFeatureIsCompatible(CPJavaScriptInnerTextFeature))
|
|
span.innerText = aString;
|
|
else if (CPFeatureIsCompatible(CPJavaScriptTextContentFeature))
|
|
span.textContent = aString;
|
|
|
|
return CGSizeMake(span.clientWidth + 1, span.clientHeight);
|
|
}
|
|
|
|
+ (CPDictionary)metricsOfFont:(CPFont)aFont
|
|
{
|
|
if (!DOMMetricsDivElement)
|
|
[self createDOMMetricsElements];
|
|
|
|
DOMMetricsDivElement.style.font = [(aFont || DefaultFont) cssString];
|
|
|
|
var lineHeight = DOMMetricsDivElement.offsetHeight,
|
|
baseline = DOMMetricsImgElement.offsetTop + DOMMetricsImgElement.offsetHeight,
|
|
descender = baseline - lineHeight;
|
|
|
|
return @{
|
|
@"ascender": baseline,
|
|
@"descender": descender,
|
|
@"lineHeight": lineHeight,
|
|
};
|
|
}
|
|
|
|
@end
|