Fixed: refactoring of CPTextView

This commit is contained in:
Alexandre Wilhelm
2016-03-06 21:48:42 -08:00
parent c85355986b
commit be129d243b
8 changed files with 118 additions and 74 deletions
+4 -1
View File
@@ -105,7 +105,7 @@ var _availableTraits= [@"Normal", @"Italic", @"Bold", @"Bold Italic"],
glyphRange = [_layoutManager glyphRangeForTextContainer:_textContainer],
usedRect = [_layoutManager usedRectForTextContainer:_textContainer],
bounds = [self bounds],
pos = CPMakePoint((bounds.size.width - usedRect.size.width) / 2.0, (bounds.size.height - usedRect.size.height) / 2.0);
pos = CGPointMake((bounds.size.width - usedRect.size.width) / 2.0, (bounds.size.height - usedRect.size.height) / 2.0);
CGContextSaveGState(ctx);
CGContextSetFillColor(ctx, [CPColor whiteColor]);
@@ -226,12 +226,15 @@ var _availableTraits= [@"Normal", @"Italic", @"Bold", @"Bold Italic"],
upperView = [[CPView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(contentBounds), CGRectGetHeight(contentBounds) - (kBorderSpacing + kToolbarHeight + kInnerSpacing))];
[contentView addSubview:_toolbarView];
_fontBrowser = [[CPBrowser alloc] initWithFrame:CGRectMake(10, 35, 150, 350)];
_traitBrowser = [[CPBrowser alloc] initWithFrame:CGRectMake(155, 35, 150, 350)];
_sizeBrowser = [[CPBrowser alloc] initWithFrame:CGRectMake(300, 35, 140, 350)];
[self _setupBrowser:_fontBrowser];
[self _setupBrowser:_traitBrowser];
[self _setupBrowser:_sizeBrowser];
[[CPNotificationCenter defaultCenter] addObserver:self
selector:@selector(textViewDidChangeSelection:)
name:CPTextViewDidChangeSelectionNotification
+8 -3
View File
@@ -31,6 +31,7 @@
@import "CPTextContainer.j"
@import "CGContext.j"
@import "CPTypesetter.j"
@import "CPFont.j"
@global _MakeRangeFromAbs
@@ -127,6 +128,7 @@ _oncontextmenuhandler = function () { return false; };
{
return [_textStorage length];
}
- (int)numberOfCharacters
{
return [_textStorage length];
@@ -176,7 +178,7 @@ _oncontextmenuhandler = function () { return false; };
if (fragment._textContainer === container)
{
var frames = [fragment glyphFrames],
l = frames? frames.length : 0;
l = frames ? frames.length : 0;
for (var j = 0; j < l; j++)
{
@@ -289,9 +291,11 @@ _oncontextmenuhandler = function () { return false; };
// document.title=startIndex;
[_typesetter layoutGlyphsInLayoutManager:self startingAtGlyphIndex:startIndex maxNumberOfLineFragments:-1 nextGlyphIndex:nil];
#if PLATFORM(DOM)
[self _cleanUpDOM];
#endif
_isValidatingLayoutAndGlyphs = NO;
}
@@ -431,6 +435,7 @@ _oncontextmenuhandler = function () { return false; };
- (void)textStorage:(CPTextStorage)textStorage edited:(unsigned)mask range:(CPRange)charRange changeInLength:(int)delta invalidatedRange:(CPRange)invalidatedRange
{
var actualRange = CPMakeRange(CPNotFound,0);
[self invalidateLayoutForCharacterRange: invalidatedRange isSoft:NO actualCharacterRange:actualRange];
[self invalidateDisplayForGlyphRange: actualRange];
}
@@ -734,7 +739,7 @@ _oncontextmenuhandler = function () { return false; };
var lineFragment = _objectWithLocationInRange(_lineFragments, glyphRange.location);
if (lineFragment)
[lineFragment setAdvancements: someAdvancements];
[lineFragment setAdvancements:someAdvancements];
}
- (void)setLocation:(CGPoint)aPoint forStartOfGlyphRange:(CPRange)glyphRange
@@ -1198,7 +1203,7 @@ var _objectsInRange = function(aList, aRange)
for (var i = 0; i < count; i++)
_glyphsFrames[i].origin.y += (height - _fragmentRect.size.height);
_fragmentRect.size.height=height;
_fragmentRect.size.height = height;
}
- (CPString)description
+1 -1
View File
@@ -123,7 +123,7 @@ CPLineMovesUp = 4;
{
var oldSize = _size;
_size = someSize;
_size = CGSizeMakeCopy(someSize);
if (oldSize.width != _size.width)
{
+12 -10
View File
@@ -23,7 +23,9 @@
@import <Foundation/CPNotificationCenter.j>
@import <Foundation/CPAttributedString.j>
@import "CPText.j"
@import "CPFont.j"
@class CPLayoutManager;
@@ -119,20 +121,20 @@ var CPTextStorageDelegate_textStorageWillProcessEditing_ = 1 << 1,
- (void)addLayoutManager:(CPLayoutManager)aManager
{
if (![_layoutManagers containsObject:aManager])
{
[aManager setTextStorage:self];
[_layoutManagers addObject:aManager];
}
if ([_layoutManagers containsObject:aManager])
return
[aManager setTextStorage:self];
[_layoutManagers addObject:aManager];
}
- (void)removeLayoutManager:(CPLayoutManager)aManager
{
if ([_layoutManagers containsObject:aManager])
{
[aManager setTextStorage:nil];
[_layoutManagers removeObject:aManager];
}
if (![_layoutManagers containsObject:aManager])
return
[aManager setTextStorage:nil];
[_layoutManagers removeObject:aManager];
}
- (void)invalidateAttributesInRange:(CPRange)aRange
+73 -39
View File
@@ -64,7 +64,7 @@ _MidRange = function(a1)
function _isWhitespaceCharacter(chr)
{
return (chr === '\n' || chr === '\r' || chr === ' ' || chr === '\t');
return (chr === '\n' || chr === '\r' || chr === ' ' || chr === '\t');
}
_characterTripletFromStringAtIndex = function(string, index)
@@ -267,24 +267,26 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)copy:(id)sender
{
[_CPNativeInputManager setLastCopyWasNative:[sender isKindOfClass:[_CPNativeInputManager class]]];
_copySelectionGranularity = _previousSelectionGranularity;
[super copy:sender];
[_CPNativeInputManager setLastCopyWasNative:[sender isKindOfClass:[_CPNativeInputManager class]]];
_copySelectionGranularity = _previousSelectionGranularity;
[super copy:sender];
if (![self isRichText])
return;
var selectedRange = [self selectedRange],
pasteboard = [CPPasteboard generalPasteboard],
stringForPasting = [_textStorage attributedSubstringFromRange:CPMakeRangeCopy(selectedRange)];
stringForPasting = [_textStorage attributedSubstringFromRange:CPMakeRangeCopy(selectedRange)];
// put rich representation on the pasteboad only if we have multliple attributes selected
if (stringForPasting._rangeEntries.length > 1)
{
var richData = [_CPRTFProducer produceRTF:stringForPasting documentAttributes:@{}];
// [pasteboard declareTypes:[CPStringPboardType, CPRichStringPboardType] owner:nil]; // this does currently do not work due to limitations in cappuccino
[pasteboard setString:richData forType:CPStringPboardType]; // crude hack to make rich pasting possible in chrome and firefox: put rtf on the plain pasteboard
}
// put rich representation on the pasteboad only if we have multliple attributes selected
if (stringForPasting._rangeEntries.length > 1)
{
// [pasteboard declareTypes:[CPStringPboardType, CPRichStringPboardType] owner:nil]; // this does currently do not work due to limitations in cappuccino
var richData = [_CPRTFProducer produceRTF:stringForPasting documentAttributes:@{}];
// crude hack to make rich pasting possible in chrome and firefox: put rtf on the plain pasteboard
[pasteboard setString:richData forType:CPStringPboardType];
}
}
- (void)paste:(id)sender
@@ -739,18 +741,22 @@ var kDelegateRespondsTo_textShouldBeginEditing
// interface to the _CPNativeInputManager
- (void)_activateNativeInputElement:(DOMElemet)aNativeField
{
var attributes=[[self typingAttributes] copy];
[attributes setObject:[CPColor colorWithRed:1 green:1 blue:1 alpha:0] forKey:CPForegroundColorAttributeName]; // make it invisible
var attributes = [[self typingAttributes] copy];
// make it invisible
[attributes setObject:[CPColor colorWithRed:1 green:1 blue:1 alpha:0] forKey:CPForegroundColorAttributeName];
// FIXME: this hack to provide the visual space for the inputmanager should at least bypass the undomanager
var placeholderString = [[CPAttributedString alloc] initWithString:aNativeField.innerHTML attributes:attributes];
[self insertText:placeholderString]; // FIXME: this hack to provide the visual space for the inputmanager should at least bypass the undomanager
[self insertText:placeholderString];
var caretOrigin = [_layoutManager boundingRectForGlyphRange:CPMakeRange(MAX(0, _selectionRange.location - 1), 1) inTextContainer:_textContainer].origin;
caretOrigin.y += [_layoutManager _characterOffsetAtLocation:MAX(0, _selectionRange.location - 1)];
caretOrigin.x += 2; // two pixel offset to the LHS character
#if PLATFORM(DOM)
aNativeField.style.left = caretOrigin.x+"px";
aNativeField.style.top = caretOrigin.y+"px";
aNativeField.style.left = caretOrigin.x + "px";
aNativeField.style.top = caretOrigin.y + "px";
aNativeField.style.font = [[_typingAttributes objectForKey:CPFontAttributeName] cssString];
aNativeField.style.color = [[_typingAttributes objectForKey:CPForegroundColorAttributeName] cssString];
#endif
@@ -982,7 +988,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
// <!> FIXME: find a better way for getting the coordinates of the next line
point.y += 2 + rectSource.size.height;
var dindex= point.y >= CPRectGetMaxY(rectEnd) ? nglyphs : [_layoutManager glyphIndexForPoint:point inTextContainer:_textContainer fractionOfDistanceThroughGlyph:fraction],
var dindex = point.y >= CGRectGetMaxY(rectEnd) ? nglyphs : [_layoutManager glyphIndexForPoint:point inTextContainer:_textContainer fractionOfDistanceThroughGlyph:fraction],
oldStickyLoc = _stickyXLocation;
if (fraction[0] > 0.5)
@@ -1861,20 +1867,21 @@ var kDelegateRespondsTo_textShouldBeginEditing
- (void)updateInsertionPointStateAndRestartTimer:(BOOL)flag
{
var caretRect,
nglyphs= [_layoutManager numberOfCharacters];
numberOfGlyphs= [_layoutManager numberOfCharacters];
if (_selectionRange.length)
[_caret setVisibility:NO];
if (_selectionRange.location >= nglyphs) // cursor is "behind" the last chacacter
if (_selectionRange.location >= numberOfGlyphs) // cursor is "behind" the last chacacter
{
caretRect = [_layoutManager boundingRectForGlyphRange:CPMakeRange(MAX(0,_selectionRange.location - 1), 1) inTextContainer:_textContainer];
if (!nglyphs)
if (!numberOfGlyphs)
{
var f = [_typingAttributes objectForKey:CPFontAttributeName];
caretRect.size.height = [f size];
caretRect.origin.y = ([f ascender] - [f descender]) * 0.5;
var font = [_typingAttributes objectForKey:CPFontAttributeName];
caretRect.size.height = [font size];
caretRect.origin.y = ([font ascender] - [font descender]) * 0.5;
}
caretRect.origin.x += caretRect.size.width;
@@ -1886,9 +1893,11 @@ var kDelegateRespondsTo_textShouldBeginEditing
}
}
else
{
caretRect = [_layoutManager boundingRectForGlyphRange:CPMakeRange(_selectionRange.location, 1) inTextContainer:_textContainer];
}
var loc = (_selectionRange.location === nglyphs && nglyphs > 0) ? _selectionRange.location - 1 : _selectionRange.location,
var loc = (_selectionRange.location === numberOfGlyphs && numberOfGlyphs > 0) ? _selectionRange.location - 1 : _selectionRange.location,
caretOffset = [_layoutManager _characterOffsetAtLocation:loc],
oldYPosition = CGRectGetMaxY(caretRect),
caretDescend = [_layoutManager _descentAtLocation:loc];
@@ -1899,11 +1908,14 @@ var kDelegateRespondsTo_textShouldBeginEditing
caretRect.size.height = oldYPosition - caretRect.origin.y;
}
if (caretDescend < 0)
{
caretRect.size.height -= caretDescend;
}
caretRect.origin.x += _textContainerOrigin.x;
caretRect.origin.y += _textContainerOrigin.y;
caretRect.size.width = 1;
[_caret setRect:caretRect];
if (flag)
@@ -2154,6 +2166,7 @@ var CPTextViewAllowsUndoKey = @"CPTextViewAllowsUndoKey",
- (void)setVisibility:(BOOL)visibilityFlag stop:(BOOL)stopFlag
{
#if PLATFORM(DOM)
_caretDOM.style.visibility = visibilityFlag ? "visible" : "hidden";
#endif
@@ -2161,6 +2174,7 @@ var CPTextViewAllowsUndoKey = @"CPTextViewAllowsUndoKey",
if (! visibilityFlag && stopFlag)
[self stopBlinking];
}
- (void)setVisibility:(BOOL)visibilityFlag
{
[self setVisibility:visibilityFlag stop:YES];
@@ -2229,6 +2243,7 @@ var _CPCopyPlaceholder = '-';
+ (void)cancelCurrentNativeInputSession
{
#if PLATFORM(DOM)
if (_CPNativeInputField.innerHTML.length > 2)
_CPNativeInputField.innerHTML = '';
@@ -2263,7 +2278,7 @@ var _CPCopyPlaceholder = '-';
#if PLATFORM(DOM)
_CPNativeInputField = document.createElement("div");
_CPNativeInputField.contentEditable = YES;
_CPNativeInputField.style.width="64px";
_CPNativeInputField.style.width = "64px";
_CPNativeInputField.style.zIndex = 10000;
_CPNativeInputField.style.position = "absolute";
_CPNativeInputField.style.visibility = "visible";
@@ -2275,6 +2290,7 @@ var _CPCopyPlaceholder = '-';
_CPNativeInputField.addEventListener("keyup", function(e)
{
_CPNativeInputFieldKeyUpCalled = YES;
// filter out the shift-up, cursor keys and friends used to access the deadkeys
// fixme: e.which is depreciated(?) -> find a better way to identify the modifier-keyups
if (e.which < 27 || e.which == 91 || e.which == 93) // include apple command keys
@@ -2292,18 +2308,22 @@ var _CPCopyPlaceholder = '-';
var charCode = _CPNativeInputField.innerHTML.charCodeAt(0);
if (charCode == 229 || charCode == 197) // å and Å need to be filtered out in keyDown: due to chrome inserting 229 on a deadkey
// å and Å need to be filtered out in keyDown: due to chrome inserting 229 on a deadkey
if (charCode == 229 || charCode == 197)
{
[currentFirstResponder insertText:_CPNativeInputField.innerHTML];
_CPNativeInputField.innerHTML = '';
return;
}
if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyPressedCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder && _CPNativeInputField.innerHTML.length < 3 && _CPNativeInputFieldLastValue !== _CPNativeInputField.innerHTML) // chrome-trigger: keypressed is omitted for deadkeys and cursor keys
// chrome-trigger: keypressed is omitted for deadkeys and cursor keys
if (!_CPNativeInputFieldActive && _CPNativeInputFieldKeyPressedCalled == NO && _CPNativeInputField.innerHTML.length && _CPNativeInputField.innerHTML != _CPCopyPlaceholder && _CPNativeInputField.innerHTML.length < 3 && _CPNativeInputFieldLastValue !== _CPNativeInputField.innerHTML)
{
_CPNativeInputFieldActive = YES;
[currentFirstResponder _activateNativeInputElement:_CPNativeInputField];
} else
}
else
{
if (_CPNativeInputFieldActive)
[self _endInputSessionWithString:_CPNativeInputField.innerHTML];
@@ -2335,6 +2355,7 @@ var _CPCopyPlaceholder = '-';
else if (!_CPNativeInputFieldActive)
[self hideInputElement];
}, 200);
return false;
}, true); // capture mode
@@ -2343,6 +2364,7 @@ var _CPCopyPlaceholder = '-';
_CPNativeInputFieldKeyUpCalled = YES;
_CPNativeInputFieldKeyPressedCalled = YES;
return false;
}, true); // capture mode
if (CPBrowserIsEngine(CPGeckoBrowserEngine))
@@ -2360,8 +2382,10 @@ var _CPCopyPlaceholder = '-';
setTimeout(function(){ // prevent dom-flickering
[currentFirstResponder paste:self];
}, 20);
return false;
}
_CPNativeInputField.oncopy = function(e)
{
var pasteboard = [CPPasteboard generalPasteboard],
@@ -2369,30 +2393,35 @@ var _CPCopyPlaceholder = '-';
currentFirstResponder = [[CPApp keyWindow] firstResponder];
[currentFirstResponder copy:self];
// dataForPasting = [pasteboard dataForType:CPRichStringPboardType],
// dataForPasting = [pasteboard dataForType:CPRichStringPboardType],
stringForPasting = [pasteboard stringForType:CPStringPboardType];
e.clipboardData.setData('text/plain', stringForPasting);
// e.clipboardData.setData('application/rtf', stringForPasting); // does not seem to work
return false;
// e.clipboardData.setData('application/rtf', stringForPasting); // does not seem to work
return false;
}
_CPNativeInputField.oncut = function(e)
{
var pasteboard = [CPPasteboard generalPasteboard],
string,
currentFirstResponder = [[CPApp keyWindow] firstResponder];
setTimeout(function(){ // prevent dom-flickering
// prevent dom-flickering
setTimeout(function(){
[currentFirstResponder cut:self];
}, 20);
[currentFirstResponder copy:self]; // this is necessary because cut will only execute in the future
// dataForPasting = [pasteboard dataForType:CPRichStringPboardType],
// this is necessary because cut will only execute in the future
[currentFirstResponder copy:self];
//dataForPasting = [pasteboard dataForType:CPRichStringPboardType],
stringForPasting = [pasteboard stringForType:CPStringPboardType];
e.clipboardData.setData('text/plain', stringForPasting);
// e.clipboardData.setData('application/rtf', stringForPasting); // does not seem to work
//e.clipboardData.setData('application/rtf', stringForPasting); // does not seem to work
return false;
}
}
@@ -2425,10 +2454,12 @@ var _CPCopyPlaceholder = '-';
currentFirstResponder._DOMElement.appendChild(_CPNativeInputField);
_CPNativeInputField.focus();
#endif
}
+ (void)focusForClipboardOfTextView:(CPTextView)textview
{
#if PLATFORM(DOM)
if (!_CPNativeInputFieldActive && _CPNativeInputField.innerHTML.length == 0)
_CPNativeInputField.innerHTML = _CPCopyPlaceholder; // make sure we have a selection to allow the native pasteboard work in safari
@@ -2453,14 +2484,17 @@ var _CPCopyPlaceholder = '-';
selection.addRange(range);
}
#endif
}
+ (void)hideInputElement
{
#if PLATFORM(DOM)
_CPNativeInputField.style.top="-10000px";
_CPNativeInputField.style.left="-10000px";
_CPNativeInputField.style.top = "-10000px";
_CPNativeInputField.style.left = "-10000px";
#endif
}
@end
+13 -13
View File
@@ -26,8 +26,10 @@
*/
@import <Foundation/CPObject.j>
@import "CPParagraphStyle.j"
@import "CPTextStorage.j"
@import "CPFont.j"
@global _isNewlineCharacter
@@ -46,9 +48,8 @@ CPTypesetterLineBreakAction = 1 << 3;
CPTypesetterParagraphBreakAction = 1 << 4;
CPTypesetterContainerBreakAction = 1 << 5;
var _sharedSimpleTypesetter;
var CPSystemTypesetterFactory;
var CPSystemTypesetterFactory,
_sharedSimpleTypesetter;
@implementation CPTypesetter : CPObject
@@ -196,7 +197,7 @@ var CPSystemTypesetterFactory;
break;
}
[_layoutManager setLocation:CPMakePoint(myX, _lineBase) forStartOfGlyphRange:lineRange];
[_layoutManager setLocation:CGPointMake(myX, _lineBase) forStartOfGlyphRange:lineRange];
[_layoutManager _setAdvancements:advancements forGlyphRange:lineRange];
if (!sameLine) //fix the _lineFragments when fontsizes differ
@@ -292,10 +293,8 @@ var CPSystemTypesetterFactory;
lineRange.length++;
measuringRange.length++;
var currentChar = theString[glyphIndex];
var rangeWidth = [theString.substr(measuringRange.location, measuringRange.length) sizeWithFont:_currentFont inWidth:NULL].width + currentAnchor;
var currentChar = theString[glyphIndex],
rangeWidth = [theString.substr(measuringRange.location, measuringRange.length) sizeWithFont:_currentFont inWidth:NULL].width + currentAnchor;
switch (currentChar) // faster than sending actionForControlCharacterAtIndex: called for each char.
{
@@ -323,7 +322,8 @@ var CPSystemTypesetterFactory;
}
var advancement = CPMakeSize(rangeWidth - prevRangeWidth, ascent);
advancement.descent=descent;
advancement.descent = descent;
advancements.push(advancement);
prevRangeWidth = _lineWidth = rangeWidth;
@@ -332,10 +332,10 @@ var CPSystemTypesetterFactory;
{
if (wrapWidth)
{
lineRange = wrapRange;
_lineWidth = wrapWidth;
_lineHeight = wrapRange._height;
_lineBase = wrapRange._base;
lineRange = wrapRange;
_lineWidth = wrapWidth;
_lineHeight = wrapRange._height;
_lineBase = wrapRange._base;
}
isNewline = YES;
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14F6a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment version="1050" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="9532"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@@ -33,19 +33,19 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="textColor" red="1" green="0.30493083910000002" blue="0.37424202039999999" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="446" height="318"/>
<size key="minSize" width="431" height="318"/>
<size key="maxSize" width="463" height="10000000"/>
<attributedString key="textStorage">
<fragment content="Je suis un CPTextView">
<attributes>
<color key="NSColor" red="1" green="0.30493083910000002" blue="0.37424202039999999" alpha="1" colorSpace="calibratedRGB"/>
<font key="NSFont" metaFont="smallSystem"/>
<font key="NSFont" size="16" name="Arial-Black"/>
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural"/>
</attributes>
</fragment>
</attributedString>
<color key="insertionPointColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<size key="minSize" width="446" height="318"/>
<size key="minSize" width="431" height="318"/>
<size key="maxSize" width="463" height="10000000"/>
<connections>
<outlet property="delegate" destination="450" id="TUv-WJ-Fxj"/>
@@ -59,7 +59,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="HzS-T1-0kM">
<rect key="frame" x="223" y="1" width="16" height="133"/>
<rect key="frame" x="432" y="1" width="15" height="318"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>