X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/de3b1ab45842f7265fae101aae296d1a2d9b7ae6..4ef0751af2a5cae1b09491205224a97e819d8a7a:/Cydia.mm?ds=sidebyside diff --git a/Cydia.mm b/Cydia.mm index be88a41f..ac9df53a 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -52,15 +52,6 @@ // XXX: remove #import -#import -//#include - -#include -#include -#include - -#import - #include #include @@ -102,6 +93,8 @@ extern "C" { #import "BrowserView.h" #import "ResetView.h" + +#import "substrate.h" /* }}} */ //#define _finline __attribute__((force_inline)) @@ -116,6 +109,14 @@ bool _itv; exit(0); \ } while (false) +static uint64_t profile_; + +#define _timestamp ({ \ + struct timeval tv; \ + gettimeofday(&tv, NULL); \ + tv.tv_sec * 1000000 + tv.tv_usec; \ +}) + /* Objective-C Handle<> {{{ */ template class _H { @@ -158,11 +159,18 @@ class _H { #define _pooled _H _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); } -static const NSStringCompareOptions CompareOptions_ = NSCaseInsensitiveSearch | NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch | NSForcedOrderingSearch; +/* NSForcedOrderingSearch doesn't work on the iPhone */ +static const NSStringCompareOptions BaseCompareOptions_ = NSNumericSearch | NSDiacriticInsensitiveSearch | NSWidthInsensitiveSearch; +static const NSStringCompareOptions ForcedCompareOptions_ = BaseCompareOptions_; +static const NSStringCompareOptions LaxCompareOptions_ = BaseCompareOptions_ | NSCaseInsensitiveSearch; /* iPhoneOS 2.0 Compatibility {{{ */ #ifdef __OBJC2__ @@ -250,9 +258,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) @@ -333,6 +341,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 @@ -342,6 +378,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; @@ -355,10 +404,7 @@ typedef enum { @implementation NSString (Cydia) + (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length { - char data[length + 1]; - memcpy(data, bytes, length); - data[length] = '\0'; - return [NSString stringWithUTF8String:data]; + return [[[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding] autorelease]; } - (NSComparisonResult) compareByPath:(NSString *)other { @@ -551,6 +597,7 @@ static const float KeyboardTime_ = 0.3f; #define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist" #define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb" +#define NotifyConfig_ "/etc/notify.conf" static CGColor Blue_; static CGColor Blueish_; @@ -595,6 +642,7 @@ bool reload_; static NSDictionary *SectionMap_; static NSMutableDictionary *Metadata_; +static NSMutableDictionary *Indices_; static _transient NSMutableDictionary *Settings_; static _transient NSString *Role_; static _transient NSMutableDictionary *Packages_; @@ -719,6 +767,7 @@ bool isSectionVisible(NSString *section) { - (RVPage *) pageForURL:(NSURL *)url hasTag:(int *)tag; - (RVPage *) pageForPackage:(NSString *)name; - (void) openMailToURL:(NSURL *)url; +- (void) clearFirstResponder; @end /* }}} */ @@ -1018,7 +1067,7 @@ class Progress : return NSOrderedDescending; } - return [lhs compare:rhs options:CompareOptions_]; + return [lhs compare:rhs options:LaxCompareOptions_]; } - (NSDictionary *) record { @@ -1111,35 +1160,6 @@ class Progress : @end /* }}} */ /* Package Class {{{ */ -NSString *Scour(const char *field, const char *begin, const char *end) { - size_t i(0), l(strlen(field)); - - for (;;) { - const char *name = begin + i; - const char *colon = name + l; - const char *value = colon + 1; - - if ( - value < end && - *colon == ':' && - strncasecmp(name, field, l) == 0 - ) { - while (value != end && value[0] == ' ') - ++value; - const char *line = std::find(value, end, '\n'); - while (line != value && line[-1] == ' ') - --line; - - return [NSString stringWithUTF8Bytes:value length:(line - value)]; - } else { - begin = std::find(begin, end, '\n'); - if (begin == end) - return nil; - ++begin; - } - } -} - @interface Package : NSObject { pkgCache::PkgIterator iterator_; _transient Database *database_; @@ -1217,6 +1237,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { - (Source *) source; - (NSString *) role; +- (NSString *) rating; - (BOOL) matches:(NSString *)text; @@ -1279,7 +1300,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { } + (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 { @@ -1318,32 +1339,77 @@ NSString *Scour(const char *field, const char *begin, const char *end) { const char *begin, *end; parser->GetRec(begin, end); - name_ = Scour("name", begin, end); + NSString *website(nil); + NSString *sponsor(nil); + NSString *author(nil); + NSString *tag(nil); + + struct { + const char *name_; + NSString **value_; + } names[] = { + {"name", &name_}, + {"icon", &icon_}, + {"depiction", &depiction_}, + {"homepage", &homepage_}, + {"website", &website}, + {"sponsor", &sponsor}, + {"author", &author}, + {"tag", &tag}, + }; + + while (begin != end) + if (*begin == '\n') { + ++begin; + continue; + } else if (isblank(*begin)) next: { + begin = static_cast(memchr(begin + 1, '\n', end - begin - 1)); + if (begin == NULL) + break; + } else if (const char *colon = static_cast(memchr(begin, ':', end - begin))) { + const char *name(begin); + size_t size(colon - begin); + + begin = static_cast(memchr(begin, '\n', end - begin)); + + { + const char *stop(begin == NULL ? end : begin); + while (stop[-1] == '\r') + --stop; + while (++colon != stop && isblank(*colon)); + + for (size_t i(0); i != sizeof(names) / sizeof(names[0]); ++i) + if (strncasecmp(names[i].name_, name, size) == 0) { + NSString *value([NSString stringWithUTF8Bytes:colon length:(stop - colon)]); + *names[i].value_ = value; + break; + } + } + + if (begin == NULL) + break; + ++begin; + } else goto next; + if (name_ != nil) name_ = [name_ retain]; tagline_ = [[NSString stringWithUTF8String:parser->ShortDesc().c_str()] retain]; - icon_ = Scour("icon", begin, end); if (icon_ != nil) icon_ = [icon_ retain]; - depiction_ = Scour("depiction", begin, end); if (depiction_ != nil) depiction_ = [depiction_ retain]; - homepage_ = Scour("homepage", begin, end); if (homepage_ == nil) - homepage_ = Scour("website", begin, end); + homepage_ = website; if ([homepage_ isEqualToString:depiction_]) homepage_ = nil; if (homepage_ != nil) homepage_ = [homepage_ retain]; - NSString *sponsor = Scour("sponsor", begin, end); if (sponsor != nil) sponsor_ = [[Address addressWithString:sponsor] retain]; - NSString *author = Scour("author", begin, end); if (author != nil) author_ = [[Address addressWithString:author] retain]; - NSString *tags = Scour("tag", begin, end); - if (tags != nil) - tags_ = [[tags componentsSeparatedByString:@", "] retain]; + if (tag != nil) + tags_ = [[tag componentsSeparatedByString:@", "] retain]; } if (tags_ != nil) @@ -1738,6 +1804,13 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return role_; } +- (NSString *) rating { + if (NSString *rating = [Indices_ objectForKey:@"Rating"]) + return [rating stringByReplacingOccurrencesOfString:@"@P" withString:[id_ stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; + else + return nil; +} + - (BOOL) matches:(NSString *)text { if (text == nil) return NO; @@ -1810,7 +1883,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return NSOrderedDescending; } - return [lhs compare:rhs options:CompareOptions_]; + return [lhs compare:rhs options:LaxCompareOptions_]; } - (NSComparisonResult) compareBySection:(Package *)package { @@ -1822,9 +1895,8 @@ NSString *Scour(const char *field, const char *begin, const char *end) { else if (lhs != NULL && rhs == NULL) return NSOrderedDescending; else if (lhs != NULL && rhs != NULL) { - NSComparisonResult result = [lhs compare:rhs options:CompareOptions_]; - if (result != NSOrderedSame) - return result; + NSComparisonResult result([lhs compare:rhs options:LaxCompareOptions_]); + return result != NSOrderedSame ? result : [lhs compare:rhs options:ForcedCompareOptions_]; } return NSOrderedSame; @@ -1944,7 +2016,7 @@ NSString *Scour(const char *field, const char *begin, const char *end) { return NSOrderedDescending; } - return [lhs compare:rhs options:CompareOptions_]; + return [lhs compare:rhs options:LaxCompareOptions_]; } - (Section *) initWithName:(NSString *)name { @@ -2301,6 +2373,7 @@ static NSArray *Finishes_; [packages_ removeAllObjects]; _trace(); + profile_ = 0; for (pkgCache::PkgIterator iterator = cache_->PkgBegin(); !iterator.end(); ++iterator) if (Package *package = [Package packageWithIterator:iterator database:self]) [packages_ addObject:package]; @@ -2645,9 +2718,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]; @@ -2660,10 +2733,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 { @@ -2774,7 +2850,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Cancel"; } -- (NSString *) _rightButtonTitle { +- (id) _rightButtonTitle { return issues_ == nil ? @"Confirm" : nil; } @@ -2853,6 +2929,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { id delegate_; BOOL running_; SHA1SumValue springlist_; + SHA1SumValue notifyconf_; SHA1SumValue sandplate_; size_t received_; NSTimeInterval last_; @@ -3005,7 +3082,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]; @@ -3021,9 +3099,9 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { default: _assert(false); } - } - [sheet dismiss]; + [sheet dismiss]; + } } - (void) closeButtonPushed { @@ -3071,6 +3149,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Finish_ = 4; } + if (Finish_ < 4) { + FileFd file(NotifyConfig_, FileFd::ReadOnly); + MMap mmap(file, MMap::ReadOnly); + SHA1Summation sha1; + sha1.Add(reinterpret_cast(mmap.Data()), mmap.Size()); + if (!(notifyconf_ == sha1.Result())) + Finish_ = 4; + } + if (Finish_ < 3) { FileFd file(SpringBoard_, FileFd::ReadOnly); MMap mmap(file, MMap::ReadOnly); @@ -3113,9 +3200,11 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { NSString *plist = [path stringByAppendingPathComponent:@"Info.plist"]; if (NSMutableDictionary *info = [[NSMutableDictionary alloc] initWithContentsOfFile:plist]) { [info autorelease]; - [info setObject:path forKey:@"Path"]; - [info setObject:@"System" forKey:@"ApplicationType"]; - [system addInfoDictionary:info]; + if ([info objectForKey:@"CFBundleIdentifier"] != nil) { + [info setObject:path forKey:@"Path"]; + [info setObject:@"System" forKey:@"ApplicationType"]; + [system addInfoDictionary:info]; + } } } } else goto error; @@ -3169,6 +3258,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { sandplate_ = sha1.Result(); } + { + FileFd file(NotifyConfig_, FileFd::ReadOnly); + MMap mmap(file, MMap::ReadOnly); + SHA1Summation sha1; + sha1.Add(reinterpret_cast(mmap.Data()), mmap.Size()); + notifyconf_ = sha1.Result(); + } + { FileFd file(SpringBoard_, FileFd::ReadOnly); MMap mmap(file, MMap::ReadOnly); @@ -3769,18 +3866,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]; } @@ -3809,13 +3910,13 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { buttons:buttons defaultButtonIndex:2 delegate:self - context:@"manage" + context:@"modify" ] autorelease]]; } } #endif -- (NSString *) _rightButtonTitle { +- (id) _rightButtonTitle { int count = [buttons_ count]; return count == 0 ? nil : count != 1 ? @"Modify" : [buttons_ objectAtIndex:0]; } @@ -3862,6 +3963,10 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { } } +- (bool) _loading { + return false; +} + - (void) reloadData { [self setPackage:[database_ packageWithName:name_]]; [self reloadButtons]; @@ -4364,8 +4469,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]; @@ -4395,7 +4501,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 { @@ -4466,12 +4576,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]; } @@ -4491,7 +4605,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [[list_ table] isRowDeletionEnabled] ? @"Add" : nil; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return [[list_ table] isRowDeletionEnabled] ? @"Done" : @"Edit"; } @@ -4562,7 +4676,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Packages"; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return Role_ != nil && [Role_ isEqualToString:@"Developer"] ? nil : expert_ ? @"Expert" : @"Simple"; } @@ -4587,7 +4701,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 { @@ -4643,20 +4762,18 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Settings"; } -- (NSString *) _rightButtonTitle { +#if !AlwaysReload +- (id) _rightButtonTitle { return nil; } +#endif -@end -/* }}} */ +- (bool) _loading { + return false; +} -@interface WebView (Cydia) -- (void) setScriptDebugDelegate:(id)delegate; -- (void) _setFormDelegate:(id)delegate; -- (void) _setUIKitDelegate:(id)delegate; -- (void) setWebMailDelegate:(id)delegate; -- (void) _setLayoutInterval:(float)interval; @end +/* }}} */ /* Indirect Delegate {{{ */ @interface IndirectDelegate : NSProxy { @@ -4694,481 +4811,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Browser Implementation {{{ */ -@implementation BrowserView - -- (void) dealloc { - WebView *webview = [webview_ webView]; - [webview setFrameLoadDelegate:nil]; - [webview setResourceLoadDelegate:nil]; - [webview setUIDelegate:nil]; - [webview setScriptDebugDelegate:nil]; - [webview setPolicyDelegate:nil]; - - [webview setDownloadDelegate:nil]; - - [webview _setFormDelegate:nil]; - [webview _setUIKitDelegate:nil]; - [webview setWebMailDelegate:nil]; - [webview setEditingDelegate:nil]; - - [webview_ setDelegate:nil]; - [webview_ setGestureDelegate:nil]; - - //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - [webview close]; - -#if RecycleWebViews - [webview_ removeFromSuperview]; - [Documents_ addObject:[webview_ autorelease]]; -#else - [webview_ release]; -#endif - - [indirect_ setDelegate:nil]; - [indirect_ release]; - - [scroller_ setDelegate:nil]; - - [scroller_ release]; - [urls_ release]; - [indicator_ release]; - if (title_ != nil) - [title_ release]; - [super dealloc]; -} - -- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - [self loadRequest:[NSURLRequest - requestWithURL:url - cachePolicy:policy - timeoutInterval:30.0 - ]]; -} - -- (void) loadURL:(NSURL *)url { - [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; -} - -- (NSURLRequest *) _addHeadersToRequest:(NSURLRequest *)request { - NSMutableURLRequest *copy = [request mutableCopy]; - - if (Machine_ != NULL) - [copy addValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; - if (UniqueID_ != nil) - [copy addValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; - - if (Role_ != nil) - [copy addValue:Role_ forHTTPHeaderField:@"X-Role"]; - - return copy; -} - -- (void) loadRequest:(NSURLRequest *)request { - pushed_ = true; - [webview_ loadRequest:request]; -} - -- (void) reloadURL { - if ([urls_ count] == 0) - return; - NSURL *url = [[[urls_ lastObject] retain] autorelease]; - [urls_ removeLastObject]; - [self loadURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData]; -} - -- (WebView *) webView { - return [webview_ webView]; -} - -- (void) view:(UIView *)sender didSetFrame:(CGRect)frame { - [scroller_ setContentSize:frame.size]; -} - -- (void) view:(UIView *)sender didSetFrame:(CGRect)frame oldFrame:(CGRect)old { - [self view:sender didSetFrame:frame]; -} - -- (void) pushPage:(RVPage *)page { - [self setBackButtonTitle:title_]; - [page setDelegate:delegate_]; - [book_ pushPage:page]; -} - -- (BOOL) getSpecial:(NSURL *)url { - NSString *href([url absoluteString]); - NSString *scheme([[url scheme] lowercaseString]); - - RVPage *page = nil; - - if ([href hasPrefix:@"apptapp://package/"]) - page = [delegate_ pageForPackage:[href substringFromIndex:18]]; - else if ([scheme isEqualToString:@"cydia"]) { - page = [delegate_ pageForURL:url hasTag:NULL]; - if (page == nil) - return false; - } else if (![scheme isEqualToString:@"apptapp"]) - return false; - - if (page != nil) - [self pushPage:page]; - return true; -} - -- (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 { - if (NSURL *url = [request URL]) { - if (![self getSpecial:url]) { - NSString *scheme([[url scheme] lowercaseString]); - if ([scheme isEqualToString:@"mailto"]) - [delegate_ openMailToURL:url]; - else goto use; - } - - [listener ignore]; - } else use: - [listener use]; -} - -- (void) webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - if ([WebView canShowMIMEType:type]) - [listener use]; - else { - // XXX: handle more mime types! - [listener ignore]; - if (frame == [webView mainFrame]) - [UIApp openURL:[request URL]]; - } -} - -- (void) webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - NSURL *url([request URL]); - - if (url == nil) use: { - [listener use]; - return; - } - - const NSArray *capability(reinterpret_cast(GSSystemGetCapability(kGSDisplayIdentifiersCapability))); - - if ( - [capability containsObject:@"com.apple.Maps"] && [url mapsURL] || - [capability containsObject:@"com.apple.youtube"] && [url youTubeURL] - ) { - open: - [UIApp openURL:url]; - ignore: - [listener ignore]; - return; - } - - int store(_not(int)); - if (NSURL *itms = [url itmsURL:&store]) { - NSLog(@"itms#%@#%u#%@", url, store, itms); - if ( - store == 1 && [capability containsObject:@"com.apple.MobileStore"] || - store == 2 && [capability containsObject:@"com.apple.AppStore"] - ) { - url = itms; - goto open; - } - } - - NSString *scheme([[url scheme] lowercaseString]); - - if ([scheme isEqualToString:@"tel"]) { - // XXX: intelligence - goto open; - } - - if ([scheme isEqualToString:@"mailto"]) { - [delegate_ openMailToURL:url]; - goto ignore; - } - - if ([self getSpecial:url]) - goto ignore; - else if ([WebView _canHandleRequest:request]) - goto use; - else if ([url isSpringboardHandledURL]) - goto open; - else - goto use; -} - -- (void) webView:(WebView *)sender setStatusText:(NSString *)text { - //lprintf("Status:%s\n", [text UTF8String]); -} - -- (void) _pushPage { - if (pushed_) - return; - pushed_ = true; - [book_ pushPage:self]; -} - -- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource { - NSURL *url = [request URL]; - if ([self getSpecial:url]) - return nil; - [self _pushPage]; - return [self _addHeadersToRequest:request]; -} - -- (WebView *) _createWebViewWithRequest:(NSURLRequest *)request pushed:(BOOL)pushed { - [self setBackButtonTitle:title_]; - - BrowserView *browser = [[[BrowserView alloc] initWithBook:book_] autorelease]; - [browser setDelegate:delegate_]; - - if (pushed) { - [browser loadRequest:[self _addHeadersToRequest:request]]; - [book_ pushPage:browser]; - } - - return [browser webView]; -} - -- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { - return [self _createWebViewWithRequest:request pushed:(request != nil)]; -} - -- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features { - return [self _createWebViewWithRequest:request pushed:YES]; -} - -- (void) webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - title_ = [title retain]; - [book_ reloadTitleForPage:self]; -} - -- (void) webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - reloading_ = false; - loading_ = true; - [indicator_ startAnimation]; - [self reloadButtons]; - - if (title_ != nil) { - [title_ release]; - title_ = nil; - } - - [book_ reloadTitleForPage:self]; - - WebView *webview = [webview_ webView]; - NSString *href = [webview mainFrameURL]; - [urls_ addObject:[NSURL URLWithString:href]]; - - [scroller_ scrollPointVisibleAtTopLeft:CGPointZero]; - - CGRect webrect = [scroller_ bounds]; - webrect.size.height = 0; - [webview_ setFrame:webrect]; -} - -- (void) _finishLoading { - if (!reloading_) { - loading_ = false; - [indicator_ stopAnimation]; - [self reloadButtons]; - } -} - -- (BOOL) webView:(WebView *)sender shouldScrollToPoint:(struct CGPoint)point forFrame:(WebFrame *)frame { - return [webview_ webView:sender shouldScrollToPoint:point forFrame:frame]; -} - -- (void) webView:(WebView *)sender didReceiveViewportArguments:(id)arguments forFrame:(WebFrame *)frame { - return [webview_ webView:sender didReceiveViewportArguments:arguments forFrame:frame]; -} - -- (void) webView:(WebView *)sender needsScrollNotifications:(id)notifications forFrame:(WebFrame *)frame { - return [webview_ webView:sender needsScrollNotifications:notifications forFrame:frame]; -} - -- (void) webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { - return [webview_ webView:sender didCommitLoadForFrame:frame]; -} - -- (void) webView:(WebView *)sender didReceiveDocTypeForFrame:(WebFrame *)frame { - return [webview_ webView:sender didReceiveDocTypeForFrame:frame]; -} - -- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] == nil) - [self _finishLoading]; - return [webview_ webView:sender didFinishLoadForFrame:frame]; -} - -- (void) webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - [self _finishLoading]; - - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", - [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString], - [[error localizedDescription] stringByAddingPercentEscapes] - ]]]; -} - -- (void) webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary { -#if ForSaurik - lprintf("Console:%s\n", [[dictionary description] UTF8String]); -#endif -} - -- (id) initWithBook:(RVBook *)book { - if ((self = [super initWithBook:book]) != nil) { - loading_ = false; - - struct CGRect bounds = [self bounds]; - - UIImageView *pinstripe = [[[UIImageView alloc] initWithFrame:bounds] autorelease]; - [pinstripe setImage:[UIImage applicationImageNamed:@"pinstripe.png"]]; - [self addSubview:pinstripe]; - - scroller_ = [[UIScroller alloc] initWithFrame:bounds]; - [self addSubview:scroller_]; - - [scroller_ setScrollingEnabled:YES]; - [scroller_ setAdjustForContentSizeChange:YES]; - [scroller_ setClipsSubviews:YES]; - [scroller_ setAllowsRubberBanding:YES]; - [scroller_ setScrollDecelerationFactor:0.99]; - [scroller_ setDelegate:self]; - - CGRect webrect = [scroller_ bounds]; - webrect.size.height = 0; - - WebView *webview; - -#if RecycleWebViews - webview_ = [Documents_ lastObject]; - if (webview_ != nil) { - webview_ = [webview_ retain]; - webview = [webview_ webView]; - [Documents_ removeLastObject]; - [webview_ setFrame:webrect]; - } else { -#else - if (true) { -#endif - webview_ = [[UIWebDocumentView alloc] initWithFrame:webrect]; - webview = [webview_ webView]; - - [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)]; - - [webview_ setAllowsMessaging:YES]; - - [webview_ setTilingEnabled:YES]; - [webview_ setDrawsGrid:NO]; - [webview_ setLogsTilingChanges:NO]; - [webview_ setTileMinificationFilter:kCAFilterNearest]; - [webview_ setDetectsPhoneNumbers:NO]; - [webview_ setAutoresizes:YES]; - [webview_ setViewportSize:CGSizeMake(980, -1) forDocumentTypes:0x10]; - [webview_ setViewportSize:CGSizeMake(320, -1) forDocumentTypes:0x2]; - [webview_ setViewportSize:CGSizeMake(320, -1) forDocumentTypes:0x8]; - - [webview_ _setDocumentType:0x4]; - - [webview_ setZoomsFocusedFormControl:YES]; - [webview_ setContentsPosition:7]; - [webview_ setEnabledGestures:0xa]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x4]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:0x7]; - - [webview_ setSmoothsFonts:YES]; - - [webview _setUsesLoaderCache:YES]; - [webview setGroupName:@"Cydia"]; - //[webview _setLayoutInterval:0.5]; - } - - [webview_ setDelegate:self]; - [webview_ setGestureDelegate:self]; - [scroller_ addSubview:webview_]; - - //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - CGSize indsize = [UIProgressIndicator defaultSizeForStyle:UIProgressIndicatorStyleMediumWhite]; - indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectMake(281, 12, indsize.width, indsize.height)]; - [indicator_ setStyle:UIProgressIndicatorStyleMediumWhite]; - - Package *package([[Database sharedInstance] packageWithName:@"cydia"]); - NSString *application = package == nil ? @"Cydia" : [NSString - stringWithFormat:@"Cydia/%@", - [package installed] - ]; [webview setApplicationNameForUserAgent:application]; - - indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; - - [webview setFrameLoadDelegate:self]; - [webview setResourceLoadDelegate:indirect_]; - [webview setUIDelegate:self]; - [webview setScriptDebugDelegate:self]; - [webview setPolicyDelegate:self]; - - urls_ = [[NSMutableArray alloc] initWithCapacity:16]; - - [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - [scroller_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - [pinstripe setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - } return self; -} - -- (void) didFinishGesturesInView:(UIView *)view forEvent:(id)event { - [webview_ redrawScaledDocument]; -} - -- (void) _rightButtonClicked { - reloading_ = true; - [self reloadURL]; -} - -- (NSString *) _rightButtonTitle { - return @"Reload"; -} - -- (NSString *) rightButtonTitle { - return loading_ ? @"" : [self _rightButtonTitle]; -} - -- (NSString *) title { - return title_ == nil ? @"Loading" : title_; -} - -- (NSString *) backButtonTitle { - return @"Browser"; -} - -- (void) setPageActive:(BOOL)active { - if (!active) - [indicator_ removeFromSuperview]; - else - [[book_ navigationBar] addSubview:indicator_]; -} - -- (void) resetViewAnimated:(BOOL)animated { -} - -- (void) setPushed:(bool)pushed { - pushed_ = pushed; -} - -@end -/* }}} */ +#include /* Cydia Book {{{ */ @interface CYBook : RVBook < @@ -5446,6 +5090,16 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return request; } +- (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request { + id client([self client]); + 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]; +} + - (void) startLoading { id client([self client]); NSURLRequest *request([self request]); @@ -5474,31 +5128,32 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Package *package([database packageWithName:path]); if (package == nil) goto fail; - UIImage *icon([package icon]); - - 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]; + [self _returnPNGWithImage:icon forRequest:request]; + } 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"]; + [self _returnPNGWithImage:icon forRequest:request]; + } else if ([command isEqualToString:@"uikit-image"]) { + if (path == nil) + goto fail; + path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + UIImage *icon(_UIImageWithName(path)); + [self _returnPNGWithImage:icon forRequest:request]; } else if ([command isEqualToString:@"section-icon"]) { if (path == nil) goto fail; path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *section(Simplify(path)); - UIImage *icon([UIImage imageAtPath:[NSString stringWithFormat:@"%@/Sections/%@.png", App_, section]]); 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]; - [client URLProtocolDidFinishLoading:self]; + [self _returnPNGWithImage:icon forRequest:request]; } else fail: { [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; } @@ -5717,7 +5372,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return @"Sections"; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return [sections_ count] == 0 ? nil : editing_ ? @"Done" : @"Edit"; } @@ -5925,7 +5580,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { return [(CYBook *)book_ updating] ? nil : @"Refresh"; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return upgrades_ == 0 ? nil : [NSString stringWithFormat:@"Upgrade (%u)", upgrades_]; } @@ -6118,10 +5773,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}}; @@ -6885,7 +6540,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { CGSize keysize = [UIKeyboard defaultSize]; CGRect keyrect = {{0, [overlay_ bounds].size.height}, keysize}; keyboard_ = [[UIKeyboard alloc] initWithFrame:keyrect]; - [[UIKeyboardImpl sharedInstance] setSoundsEnabled:(Sounds_Keyboard_ ? YES : NO)]; + //[[UIKeyboardImpl sharedInstance] setSoundsEnabled:(Sounds_Keyboard_ ? YES : NO)]; [overlay_ addSubview:keyboard_]; if (!bootstrap_) @@ -6909,8 +6564,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) { @@ -6938,7 +6594,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; @@ -6963,7 +6621,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) { @@ -6989,7 +6649,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { _assert(false); } - [sheet dismiss]; + [sheet dismiss]; + } } - (void) reorganize { _pooled @@ -7024,10 +6685,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { #if 0 [[[MailToView alloc] initWithView:underlay_ delegate:self url:url] autorelease]; #else - [UIApp openURL:url]; + [UIApp openURL:url];// asPanel:YES]; #endif } +- (void) clearFirstResponder { + if (id responder = [window_ firstResponder]) + [responder resignFirstResponder]; +} + - (RVPage *) pageForPackage:(NSString *)name { if (Package *package = [database_ packageWithName:name]) { PackageView *view = [[[PackageView alloc] initWithBook:book_ database:database_] autorelease]; @@ -7142,7 +6808,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]; @@ -7155,22 +6821,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { [self finish]; } -/* Web Scripting {{{ */ -+ (NSString *) webScriptNameForSelector:(SEL)selector { - if (selector == @selector(supports:)) - return @"supports"; - return nil; -} - -+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { - return selector != @selector(supports:); -} - -- (BOOL) supports:(NSString *)feature { - return [feature isEqualToString:@"window.open"]; -} -/* }}} */ - - (void) showKeyboard:(BOOL)show { CGSize keysize = [UIKeyboard defaultSize]; CGRect keydown = {{0, [overlay_ bounds].size.height}, keysize}; @@ -7258,6 +6908,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) { @@ -7335,6 +6987,13 @@ 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];*/ + + Indices_ = [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"http://"/*"cache.saurik.com/"*/"cydia.saurik.com/server/rating/@P", @"Rating", + nil]; + if ((Metadata_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"]) == NULL) Metadata_ = [[NSMutableDictionary alloc] initWithCapacity:2]; else {