]> git.saurik.com Git - cydia.git/blobdiff - Cydia.mm
Numerous style changes to support ratings integration.
[cydia.git] / Cydia.mm
index 7ec9c259a4776019806c7a971cbac36ac0228206..0f52d2886038ed2a1866c1d635339b4b15b42b55 100644 (file)
--- a/Cydia.mm
+++ b/Cydia.mm
 // XXX: remove
 #import <MessageUI/MailComposeController.h>
 
-#import <WebCore/WebScriptObject.h>
-//#include <WebCore/DOMHTML.h>
+#include <WebKit/DOMCSSPrimitiveValue.h>
+#include <WebKit/DOMCSSStyleDeclaration.h>
+#include <WebKit/DOMDocument.h>
+#include <WebKit/DOMHTMLBodyElement.h>
+#include <WebKit/DOMNodeList.h>
+#include <WebKit/DOMRGBColor.h>
 
 #include <WebKit/WebFrame.h>
 #include <WebKit/WebPolicyDelegate.h>
-#include <WebKit/WebView.h>
+#include <WebKit/WebScriptObject.h>
 
+#import <WebKit/WebView.h>
 #import <WebKit/WebView-WebPrivate.h>
 
 #include <sstream>
@@ -166,6 +171,10 @@ class _H {
 
 #define _pooled _H<NSAutoreleasePool> _pool([[NSAutoreleasePool alloc] init], true);
 
+void NSLogPoint(const char *fix, const CGPoint &point) {
+    NSLog(@"%s(%g,%g)", fix, point.x, point.y);
+}
+
 void NSLogRect(const char *fix, const CGRect &rect) {
     NSLog(@"%s(%g,%g)+(%g,%g)", fix, rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
 }
@@ -258,9 +267,9 @@ extern NSString * const kCAFilterNearest;
 #define lprintf(args...) fprintf(stderr, args)
 
 #define ForRelease 0
-#define ForSaurik 1 && !ForRelease
+#define ForSaurik (1 && !ForRelease)
 #define RecycleWebViews 0
-#define AlwaysReload 1 && !ForRelease
+#define AlwaysReload (1 && !ForRelease)
 
 /* Radix Sort {{{ */
 @interface NSMutableArray (Radix)
@@ -341,6 +350,34 @@ extern NSString * const kCAFilterNearest;
 @end
 /* }}} */
 
+/* Apple Bug Fixes {{{ */
+@implementation UIWebDocumentView (Cydia)
+
+- (void) _setScrollerOffset:(CGPoint)offset {
+    UIScroller *scroller([self _scroller]);
+
+    CGSize size([scroller contentSize]);
+    CGSize bounds([scroller bounds].size);
+
+    CGPoint max;
+    max.x = size.width - bounds.width;
+    max.y = size.height - bounds.height;
+
+    // wtf Apple?!
+    if (max.x < 0)
+        max.x = 0;
+    if (max.y < 0)
+        max.y = 0;
+
+    offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x;
+    offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y;
+
+    [scroller setOffset:offset];
+}
+
+@end
+/* }}} */
+
 typedef enum {
     kUIControlEventMouseDown = 1 << 0,
     kUIControlEventMouseMovedInside = 1 << 2, // mouse moved inside control target
@@ -350,6 +387,19 @@ typedef enum {
     kUIControlAllEvents = (kUIControlEventMouseDown | kUIControlEventMouseMovedInside | kUIControlEventMouseMovedOutside | kUIControlEventMouseUpInside | kUIControlEventMouseUpOutside)
 } UIControlEventMasks;
 
+NSUInteger DOMNodeList$countByEnumeratingWithState$objects$count$(DOMNodeList *self, SEL sel, NSFastEnumerationState *state, id *objects, NSUInteger count) {
+    size_t length([self length] - state->state);
+    if (length <= 0)
+        return 0;
+    else if (length > count)
+        length = count;
+    for (size_t i(0); i != length; ++i)
+        objects[i] = [self item:state->state++];
+    state->itemsPtr = objects;
+    state->mutationsPtr = (unsigned long *) self;
+    return length;
+}
+
 @interface NSString (UIKit)
 - (NSString *) stringByAddingPercentEscapes;
 - (NSString *) stringByReplacingCharacter:(unsigned short)arg0 withCharacter:(unsigned short)arg1;
@@ -600,6 +650,7 @@ bool reload_;
 
 static NSDictionary *SectionMap_;
 static NSMutableDictionary *Metadata_;
+static NSMutableDictionary *Indices_;
 static _transient NSMutableDictionary *Settings_;
 static _transient NSString *Role_;
 static _transient NSMutableDictionary *Packages_;
@@ -1193,6 +1244,7 @@ class Progress :
 
 - (Source *) source;
 - (NSString *) role;
+- (NSString *) rating;
 
 - (BOOL) matches:(NSString *)text;
 
@@ -1255,7 +1307,7 @@ class Progress :
 }
 
 + (NSArray *) _attributeKeys {
-    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"maintainer", @"name", @"purposes", @"section", @"size", @"source", @"sponsor", @"tagline", @"warnings", nil];
+    return [NSArray arrayWithObjects:@"applications", @"author", @"depiction", @"description", @"essential", @"homepage", @"icon", @"id", @"installed", @"latest", @"maintainer", @"name", @"purposes", @"rating", @"section", @"size", @"source", @"sponsor", @"tagline", @"warnings", nil];
 }
 
 - (NSArray *) attributeKeys {
@@ -1759,6 +1811,13 @@ class Progress :
     return role_;
 }
 
+- (NSString *) rating {
+    if (NSString *pattern = [Indices_ objectForKey:@"Rating"])
+        return [pattern stringByReplacingOccurrencesOfString:@"%@" withString:[id_ stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
+    else
+        return nil;
+}
+
 - (BOOL) matches:(NSString *)text {
     if (text == nil)
         return NO;
@@ -2667,9 +2726,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context = [sheet context];
+    NSString *context([sheet context]);
 
-    if ([context isEqualToString:@"remove"])
+    if ([context isEqualToString:@"remove"]) {
         switch (button) {
             case 1:
                 [self cancel];
@@ -2682,10 +2741,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             default:
                 _assert(false);
         }
-    else if ([context isEqualToString:@"unable"])
-        [self cancel];
 
-    [sheet dismiss];
+        [sheet dismiss];
+    } else if ([context isEqualToString:@"unable"]) {
+        [self cancel];
+        [sheet dismiss];
+    } else
+        [super alertSheet:sheet buttonClicked:button];
 }
 
 - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
@@ -3027,7 +3089,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context = [sheet context];
+    NSString *context([sheet context]);
+
     if ([context isEqualToString:@"conffile"]) {
         FILE *input = [database_ input];
 
@@ -3043,9 +3106,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             default:
                 _assert(false);
         }
-    }
 
-    [sheet dismiss];
+        [sheet dismiss];
+    }
 }
 
 - (void) closeButtonPushed {
@@ -3793,18 +3856,22 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    int count = [buttons_ count];
-    _assert(count != 0);
-    _assert(button <= count + 1);
+    NSString *context([sheet context]);
 
-    if (count != button - 1)
-        [self _clickButtonWithName:[buttons_ objectAtIndex:(button - 1)]];
+    if ([context isEqualToString:@"modify"]) {
+        int count = [buttons_ count];
+        _assert(count != 0);
+        _assert(button <= count + 1);
 
-    [sheet dismiss];
+        if (count != button - 1)
+            [self _clickButtonWithName:[buttons_ objectAtIndex:(button - 1)]];
+
+        [sheet dismiss];
+    } else
+        [super alertSheet:sheet buttonClicked:button];
 }
 
 - (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
-    [[frame windowObject] evaluateWebScript:@"document.base.target = '_top'"];
     return [super webView:sender didFinishLoadForFrame:frame];
 }
 
@@ -3833,7 +3900,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             buttons:buttons
             defaultButtonIndex:2
             delegate:self
-            context:@"manage"
+            context:@"modify"
         ] autorelease]];
     }
 }
@@ -4388,8 +4455,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context = [sheet context];
-    if ([context isEqualToString:@"source"])
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"source"]) {
         switch (button) {
             case 1: {
                 NSString *href = [[sheet textField] text];
@@ -4419,7 +4487,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 _assert(false);
         }
 
-    [sheet dismiss];
+        [sheet dismiss];
+    } else if ([context isEqualToString:@"trivial"])
+        [sheet dismiss];
+    else if ([context isEqualToString:@"urlerror"])
+        [sheet dismiss];
 }
 
 - (id) initWithBook:(RVBook *)book database:(Database *)database {
@@ -4490,12 +4562,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         context:@"source"
     ] autorelease];
 
+    [sheet setNumberOfRows:1];
+
     [sheet addTextFieldWithValue:@"http://" label:@""];
 
     UITextInputTraits *traits = [[sheet textField] textInputTraits];
-    [traits setAutocapitalizationType:0];
-    [traits setKeyboardType:3];
-    [traits setAutocorrectionType:1];
+    [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
+    [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
+    [traits setKeyboardType:UIKeyboardTypeURL];
+    // XXX: UIReturnKeyDone
+    [traits setReturnKeyType:UIReturnKeyNext];
 
     [sheet popupAlertAnimated:YES];
 }
@@ -4611,7 +4687,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 @implementation HomeView
 
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    [sheet dismiss];
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"about"])
+        [sheet dismiss];
+    else
+        [super alertSheet:sheet buttonClicked:button];
 }
 
 - (void) _leftButtonClicked {
@@ -4667,9 +4748,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return @"Settings";
 }
 
+#if !AlwaysReload
 - (NSString *) _rightButtonTitle {
     return nil;
 }
+#endif
 
 @end
 /* }}} */
@@ -4720,8 +4803,12 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 /* }}} */
 /* Browser Implementation {{{ */
 @implementation BrowserView
+#include "internals.h"
 
 - (void) dealloc {
+    if (challenge_ != nil)
+        [challenge_ release];
+
     WebView *webview = [webview_ webView];
     [webview setFrameLoadDelegate:nil];
     [webview setResourceLoadDelegate:nil];
@@ -4755,6 +4842,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
     [scroller_ setDelegate:nil];
 
+    [background_ release];
     [scroller_ release];
     [urls_ release];
     [indicator_ release];
@@ -4840,12 +4928,26 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return true;
 }
 
+- (void) webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
+    UIActionSheet *sheet = [[[UIActionSheet alloc]
+        initWithTitle:@"JavaScript Alert"
+        buttons:[NSArray arrayWithObjects:@"OK", nil]
+        defaultButtonIndex:0
+        delegate:self
+        context:@"alert"
+    ] autorelease];
+
+    [sheet setBodyText:message];
+    [sheet popupAlertAnimated:YES];
+}
+
 - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame {
     [window setValue:delegate_ forKey:@"cydia"];
 }
 
-- (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)dictionary request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id<WebPolicyDecisionListener>)listener {
+- (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id<WebPolicyDecisionListener>)listener {
     if (NSURL *url = [request URL]) {
+        NSLog(@"win:%@:%@", url, [action description]);
         if (![self getSpecial:url]) {
             NSString *scheme([[url scheme] lowercaseString]);
             if ([scheme isEqualToString:@"mailto"])
@@ -4876,6 +4978,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [listener use];
         return;
     }
+    else NSLog(@"nav:%@:%@", url, [action description]);
 
     const NSArray *capability(reinterpret_cast<const NSArray *>(GSSystemGetCapability(kGSDisplayIdentifiersCapability)));
 
@@ -4935,7 +5038,82 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     [book_ pushPage:self];
 }
 
-- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource {
+- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"alert"])
+        [sheet dismiss];
+    else if ([context isEqualToString:@"challenge"]) {
+        id<NSURLAuthenticationChallengeSender> sender([challenge_ sender]);
+
+        switch (button) {
+            case 1: {
+                NSString *username([[sheet textFieldAtIndex:0] text]);
+                NSString *password([[sheet textFieldAtIndex:1] text]);
+
+                NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]);
+
+                [sender useCredential:credential forAuthenticationChallenge:challenge_];
+            } break;
+
+            case 2:
+                [sender cancelAuthenticationChallenge:challenge_];
+            break;
+
+            default:
+                _assert(false);
+        }
+
+        [challenge_ release];
+        challenge_ = nil;
+
+        [sheet dismiss];
+    }
+}
+
+- (void) webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)source {
+    challenge_ = [challenge retain];
+
+    NSURLProtectionSpace *space([challenge protectionSpace]);
+    NSString *realm([space realm]);
+    if (realm == nil)
+        realm = @"";
+
+    UIActionSheet *sheet = [[[UIActionSheet alloc]
+        initWithTitle:realm
+        buttons:[NSArray arrayWithObjects:@"Login", @"Cancel", nil]
+        defaultButtonIndex:0
+        delegate:self
+        context:@"challenge"
+    ] autorelease];
+
+    [sheet setNumberOfRows:1];
+
+    [sheet addTextFieldWithValue:@"" label:@"username"];
+    [sheet addTextFieldWithValue:@"" label:@"password"];
+
+    UITextField *username([sheet textFieldAtIndex:0]); {
+        UITextInputTraits *traits([username textInputTraits]);
+        [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
+        [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
+        [traits setKeyboardType:UIKeyboardTypeASCIICapable];
+        [traits setReturnKeyType:UIReturnKeyNext];
+    }
+
+    UITextField *password([sheet textFieldAtIndex:1]); {
+        UITextInputTraits *traits([password textInputTraits]);
+        [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
+        [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
+        [traits setKeyboardType:UIKeyboardTypeASCIICapable];
+        // XXX: UIReturnKeyDone
+        [traits setReturnKeyType:UIReturnKeyNext];
+        [traits setSecureTextEntry:YES];
+    }
+
+    [sheet popupAlertAnimated:YES];
+}
+
+- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source {
     NSURL *url = [request URL];
     if ([self getSpecial:url])
         return nil;
@@ -5028,9 +5206,53 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
     return [webview_ webView:sender didReceiveDocTypeForFrame:frame];
 }
 
+- (void) _clearBackground {
+    [background_ setBackgroundColor:[UIColor pinStripeColor]];
+    [background_ setImage:[UIImage applicationImageNamed:@"pinstripe.png"]];
+    [scroller_ setShowBackgroundShadow:NO];
+}
+
 - (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
-    if ([frame parentFrame] == nil)
+    if ([frame parentFrame] == nil) {
         [self _finishLoading];
+
+        [self _clearBackground];
+
+        if (DOMDocument *document = [frame DOMDocument])
+            if (DOMNodeList<NSFastEnumeration> *bodies = [document getElementsByTagName:@"body"])
+                for (DOMHTMLBodyElement *body in bodies) {
+                    DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]);
+
+                    bool colored(false);
+
+                    if (DOMCSSPrimitiveValue *color = static_cast<DOMCSSPrimitiveValue *>([style getPropertyCSSValue:@"background-color"])) {
+                        DOMRGBColor *rgb([color getRGBColorValue]);
+
+                        float alpha([[rgb alpha] getFloatValue:DOM_CSS_NUMBER]);
+                        if (alpha != 0) {
+                            colored = true;
+
+                            [background_ setBackgroundColor:[UIColor
+                                colorWithRed:([[rgb red] getFloatValue:DOM_CSS_NUMBER] / 255)
+                                green:([[rgb green] getFloatValue:DOM_CSS_NUMBER] / 255)
+                                blue:([[rgb blue] getFloatValue:DOM_CSS_NUMBER] / 255)
+                                alpha:alpha
+                            ]];
+                        }
+                    }
+
+                    if (DOMCSSPrimitiveValue *image = static_cast<DOMCSSPrimitiveValue *>([style getPropertyCSSValue:@"background-image"])) {
+                        NSString *src([image getStringValue]);
+                        if ([src isEqualToString:@"none"])
+                            goto none;
+                        NSLog(@"img:%@", [image getStringValue]);
+                    } else none: if (colored)
+                        [background_ setImage:nil];
+
+                    break;
+                }
+    }
+
     return [webview_ webView:sender didFinishLoadForFrame:frame];
 }
 
@@ -5057,9 +5279,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         struct CGRect bounds = [self bounds];
 
-        UIImageView *pinstripe = [[[UIImageView alloc] initWithFrame:bounds] autorelease];
-        [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]];
-        [self addSubview:pinstripe];
+        background_ = [[UIImageView alloc] initWithFrame:bounds];
+        [self _clearBackground];
+        [self addSubview:background_];
 
         scroller_ = [[UIScroller alloc] initWithFrame:bounds];
         [self addSubview:scroller_];
@@ -5089,6 +5311,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 #endif
             webview_ = [[UIWebDocumentView alloc] initWithFrame:webrect];
             webview = [webview_ webView];
+            [webview_ setDrawsBackground:NO];
 
             [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)];
 
@@ -5110,8 +5333,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [webview_ setZoomsFocusedFormControl:YES];
             [webview_ setContentsPosition:7];
             [webview_ setEnabledGestures:0xa];
-            [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x4];
-            [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x7];
+            [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeIsZoomRubberBandEnabled];
+            [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeUpdatesScroller];
 
             [webview_ setSmoothsFonts:YES];
 
@@ -5147,8 +5370,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         urls_ = [[NSMutableArray alloc] initWithCapacity:16];
 
         [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
+        [background_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
         [scroller_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
-        [pinstripe setAutoresizingMask:UIViewAutoresizingFlexibleHeight];
     } return self;
 }
 
@@ -5503,6 +5726,22 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         NSData *data(UIImagePNGRepresentation(icon));
 
+        NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]);
+        [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
+        [client URLProtocol:self didLoadData:data];
+        [client URLProtocolDidFinishLoading:self];
+    } else if ([command isEqualToString:@"source-icon"]) {
+        if (path == nil)
+            goto fail;
+        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+        NSString *source(Simplify(path));
+
+        UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sources/%@.png", App_, source]]);
+        if (icon == nil)
+            icon = [UIImage applicationImageNamed:@"unknown.png"];
+
+        NSData *data(UIImagePNGRepresentation(icon));
+
         NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]);
         [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
         [client URLProtocol:self didLoadData:data];
@@ -6142,10 +6381,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 
         [field_ setPaddingTop:5];
 
-        UITextInputTraits *traits = [field_ textInputTraits];
-        [traits setAutocapitalizationType:0];
-        [traits setAutocorrectionType:1];
-        [traits setReturnKeyType:6];
+        UITextInputTraits *traits([field_ textInputTraits]);
+        [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone];
+        [traits setAutocorrectionType:UITextAutocorrectionTypeNo];
+        [traits setReturnKeyType:UIReturnKeySearch];
 
         CGRect accrect = {{0, 6}, {6 + cnfrect.size.width + 6 + area.size.width + 6, area.size.height}};
 
@@ -6933,8 +7172,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
 }
 
 - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button {
-    NSString *context = [sheet context];
-    if ([context isEqualToString:@"fixhalf"])
+    NSString *context([sheet context]);
+
+    if ([context isEqualToString:@"fixhalf"]) {
         switch (button) {
             case 1:
                 @synchronized (self) {
@@ -6962,7 +7202,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             default:
                 _assert(false);
         }
-    else if ([context isEqualToString:@"role"]) {
+
+        [sheet dismiss];
+    } else if ([context isEqualToString:@"role"]) {
         switch (button) {
             case 1: Role_ = @"User"; break;
             case 2: Role_ = @"Hacker"; break;
@@ -6987,7 +7229,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
             [self updateData];
         else
             [self finish];
-    } else if ([context isEqualToString:@"upgrade"])
+
+        [sheet dismiss];
+    } else if ([context isEqualToString:@"upgrade"]) {
         switch (button) {
             case 1:
                 @synchronized (self) {
@@ -7013,7 +7257,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
                 _assert(false);
         }
 
-    [sheet dismiss];
+        [sheet dismiss];
+    }
 }
 
 - (void) reorganize { _pooled
@@ -7166,7 +7411,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) {
         [self setIdleTimerDisabled:YES];
 
         hud_ = [self addProgressHUD];
-        [hud_ setText:@"Reorganizing\n\nWill Automatically\nRestart When Done"];
+        [hud_ setText:@"Reorganizing\n\nWill Automatically\nClose When Done"];
 
         [self setStatusBarShowsProgress:YES];
 
@@ -7282,6 +7527,8 @@ id Dealloc_(id self, SEL selector) {
 }*/
 
 int main(int argc, char *argv[]) { _pooled
+    class_addMethod(objc_getClass("DOMNodeList"), @selector(countByEnumeratingWithState:objects:count:), (IMP) &DOMNodeList$countByEnumeratingWithState$objects$count$, "I20@0:4^{NSFastEnumerationState}8^@12I16");
+
     bool substrate(false);
 
     if (argc != 0) {
@@ -7320,7 +7567,7 @@ int main(int argc, char *argv[]) { _pooled
     setuid(0);
     setgid(0);
 
-#if 0 /* XXX: this costs 1.4s of startup performance */
+#if 1 /* XXX: this costs 1.4s of startup performance */
     if (unlink("/var/cache/apt/pkgcache.bin") == -1)
         _assert(errno == ENOENT);
     if (unlink("/var/cache/apt/srcpkgcache.bin") == -1)
@@ -7359,6 +7606,9 @@ int main(int argc, char *argv[]) { _pooled
     /*AddPreferences(@"/Applications/Preferences.app/Settings-iPhone.plist");
     AddPreferences(@"/Applications/Preferences.app/Settings-iPod.plist");*/
 
+    if ((Indices_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/indices.plist"]) == NULL)
+        Indices_ = [[NSMutableDictionary alloc] init];
+
     if ((Metadata_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"]) == NULL)
         Metadata_ = [[NSMutableDictionary alloc] initWithCapacity:2];
     else {