X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/1cedb821fd6cdd85a56cca535e840a144d97590c..680eb1352b50571cdc347e295cf6189b13cc53c5:/Cydia.mm diff --git a/Cydia.mm b/Cydia.mm index ddfe6aa4..0f52d288 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -52,13 +52,18 @@ // XXX: remove #import -#import -//#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include +#import #import #include @@ -262,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 0 && !ForRelease +#define AlwaysReload (1 && !ForRelease) /* Radix Sort {{{ */ @interface NSMutableArray (Radix) @@ -382,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; @@ -632,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_; @@ -1225,6 +1244,7 @@ class Progress : - (Source *) source; - (NSString *) role; +- (NSString *) rating; - (BOOL) matches:(NSString *)text; @@ -1287,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 { @@ -1791,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; @@ -3845,7 +3872,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } - (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - [[frame windowObject] evaluateWebScript:@"document.base.target = '_top'"]; return [super webView:sender didFinishLoadForFrame:frame]; } @@ -4462,7 +4488,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } [sheet dismiss]; - } + } else if ([context isEqualToString:@"trivial"]) + [sheet dismiss]; + else if ([context isEqualToString:@"urlerror"]) + [sheet dismiss]; } - (id) initWithBook:(RVBook *)book database:(Database *)database { @@ -4538,9 +4567,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [sheet addTextFieldWithValue:@"http://" label:@""]; UITextInputTraits *traits = [[sheet textField] textInputTraits]; - [traits setAutocapitalizationType:0]; + [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; + [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; [traits setKeyboardType:UIKeyboardTypeURL]; - [traits setAutocorrectionType:1]; + // XXX: UIReturnKeyDone + [traits setReturnKeyType:UIReturnKeyNext]; [sheet popupAlertAnimated:YES]; } @@ -4772,6 +4803,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { /* }}} */ /* Browser Implementation {{{ */ @implementation BrowserView +#include "internals.h" - (void) dealloc { if (challenge_ != nil) @@ -4810,6 +4842,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [scroller_ setDelegate:nil]; + [background_ release]; [scroller_ release]; [urls_ release]; [indicator_ release]; @@ -4895,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)listener { +- (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener { if (NSURL *url = [request URL]) { + NSLog(@"win:%@:%@", url, [action description]); if (![self getSpecial:url]) { NSString *scheme([[url scheme] lowercaseString]); if ([scheme isEqualToString:@"mailto"]) @@ -4931,6 +4978,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [listener use]; return; } + else NSLog(@"nav:%@:%@", url, [action description]); const NSArray *capability(reinterpret_cast(GSSystemGetCapability(kGSDisplayIdentifiersCapability))); @@ -4993,7 +5041,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { - (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { NSString *context([sheet context]); - if ([context isEqualToString:@"challenge"]) { + if ([context isEqualToString:@"alert"]) + [sheet dismiss]; + else if ([context isEqualToString:@"challenge"]) { id sender([challenge_ sender]); switch (button) { @@ -5044,14 +5094,20 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { UITextField *username([sheet textFieldAtIndex:0]); { UITextInputTraits *traits([username textInputTraits]); - [traits setAutocapitalizationType:0]; - [traits setAutocorrectionType:1]; + [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; + [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; + [traits setKeyboardType:UIKeyboardTypeASCIICapable]; + [traits setReturnKeyType:UIReturnKeyNext]; } UITextField *password([sheet textFieldAtIndex:1]); { UITextInputTraits *traits([password textInputTraits]); - [traits setAutocapitalizationType:0]; - [traits setAutocorrectionType:1]; + [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; + [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; + [traits setKeyboardType:UIKeyboardTypeASCIICapable]; + // XXX: UIReturnKeyDone + [traits setReturnKeyType:UIReturnKeyNext]; + [traits setSecureTextEntry:YES]; } [sheet popupAlertAnimated:YES]; @@ -5150,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 *bodies = [document getElementsByTagName:@"body"]) + for (DOMHTMLBodyElement *body in bodies) { + DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]); + + bool colored(false); + + if (DOMCSSPrimitiveValue *color = static_cast([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([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]; } @@ -5179,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_]; @@ -5211,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)]; @@ -5269,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; } @@ -5625,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]; @@ -6264,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}}; @@ -7410,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) { @@ -7487,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 {