Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

1.3.0-pre: add bookmarking capability

  • Loading branch information...
commit 1725ad8d1c2c3e3cffeacb2db62962101bcee0ec 1 parent 62baa39
@mtigas mtigas authored
Showing with 980 additions and 114 deletions.
  1. +16 −2 CHANGES.txt
  2. +60 −3 OnionBrowser/OnionBrowser.xcodeproj/project.pbxproj
  3. +7 −0 OnionBrowser/OnionBrowser/AppDelegate.h
  4. +73 −3 OnionBrowser/OnionBrowser/AppDelegate.m
  5. +19 −0 OnionBrowser/OnionBrowser/Bookmark.h
  6. +18 −0 OnionBrowser/OnionBrowser/Bookmark.m
  7. +21 −0 OnionBrowser/OnionBrowser/BookmarkEditViewController.h
  8. +185 −0 OnionBrowser/OnionBrowser/BookmarkEditViewController.m
  9. +33 −0 OnionBrowser/OnionBrowser/BookmarkTableViewController.h
  10. +265 −0 OnionBrowser/OnionBrowser/BookmarkTableViewController.m
  11. +8 −0 OnionBrowser/OnionBrowser/Bookmarks.xcdatamodeld/.xccurrentversion
  12. +11 −0 OnionBrowser/OnionBrowser/Bookmarks.xcdatamodeld/Bookmarks 2.xcdatamodel/contents
  13. +10 −0 OnionBrowser/OnionBrowser/Bookmarks.xcdatamodeld/Bookmarks.xcdatamodel/contents
  14. +2 −2 OnionBrowser/OnionBrowser/OnionBrowser-Info.plist
  15. +1 −0  OnionBrowser/OnionBrowser/OnionBrowser-Prefix.pch
  16. +5 −1 OnionBrowser/OnionBrowser/WebViewController.h
  17. +207 −75 OnionBrowser/OnionBrowser/WebViewController.m
  18. +27 −3 OnionBrowser/ProxyURLProtocol.m
  19. +4 −6 OnionBrowser/TorController.m
  20. +1 −1  OnionBrowser/about.html
  21. +5 −16 OnionBrowser/startup.html
  22. +1 −1  README.markdown
  23. +1 −1  README.txt
View
18 CHANGES.txt
@@ -1,6 +1,20 @@
Onion Browser Version History (since 1.2.2)
-===== 1.2.6 =====
+===== 1.3.0 - In Development =====
+ TBD - Build/submit date
+ TBD - App Store accept date
+
+* Bookmarking ability. Moved most of the "quick links" from startup
+ page into default bookmarks.
+
+* Major changes to underlying Tor wrapper code. May solve issues
+ related to connection dying after the app has been open for some
+ time and if the app was open while the device went into idle sleep.
+ (Issue #2, Issue #3)
+
+* Update tor to 0.2.3.21-rc (Sep 05, 2012).
+
+===== 1.2.6 - In Review =====
Sep 05, 2012 - Build/submit date
TBD - App Store accept date
@@ -20,7 +34,7 @@ Sep 05, 2012 - Build/submit date
* Updated libevent to 2.0.20-stable (Aug 23, 2012)
-===== 1.2.5 =====
+===== 1.2.5 - In App Store =====
Aug 23, 2012 - Build/submit date
Aug 30, 2012 - App Store accept date
View
63 OnionBrowser/OnionBrowser.xcodeproj/project.pbxproj
@@ -11,8 +11,12 @@
6924C28C155262E2004BE7F9 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6924C28A155262E2004BE7F9 /* SettingsViewController.m */; };
6924C28D155262E2004BE7F9 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6924C28B155262E2004BE7F9 /* SettingsViewController.xib */; };
6924C29015526343004BE7F9 /* SettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6924C28F15526343004BE7F9 /* SettingsTableViewController.m */; };
+ 692B338815FAD31D00A23DD5 /* Bookmark.m in Sources */ = {isa = PBXBuildFile; fileRef = 692B338715FAD31D00A23DD5 /* Bookmark.m */; };
+ 692B338C15FAF2E500A23DD5 /* BookmarkEditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 692B338B15FAF2E400A23DD5 /* BookmarkEditViewController.m */; };
692B86AF153CD4CB000806A9 /* NSData+Conversion.m in Sources */ = {isa = PBXBuildFile; fileRef = 692B86AE153CD4CB000806A9 /* NSData+Conversion.m */; };
6940BD1F15F84C0C00FE74CB /* TorController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6940BD1E15F84C0C00FE74CB /* TorController.m */; };
+ 6940BD2315F86B5C00FE74CB /* Bookmarks.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 6940BD2115F86B5C00FE74CB /* Bookmarks.xcdatamodeld */; };
+ 6940BD2515F8761900FE74CB /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6940BD2415F8761900FE74CB /* CoreData.framework */; };
694F34F1152ECFF20002BCBC /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 694F34E9152ECFF20002BCBC /* Icon.png */; };
694F34F2152ECFF20002BCBC /* Icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 694F34EA152ECFF20002BCBC /* Icon-72.png */; };
694F34F3152ECFF20002BCBC /* Icon-72@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 694F34EB152ECFF20002BCBC /* Icon-72@2x.png */; };
@@ -21,6 +25,7 @@
694F34F6152ECFF20002BCBC /* Icon-Small-50@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 694F34EE152ECFF20002BCBC /* Icon-Small-50@2x.png */; };
694F34F7152ECFF20002BCBC /* Icon-Small@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 694F34EF152ECFF20002BCBC /* Icon-Small@2x.png */; };
694F34F8152ECFF20002BCBC /* Icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 694F34F0152ECFF20002BCBC /* Icon@2x.png */; };
+ 6963E61615FAB2EC00310E8D /* BookmarkTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6963E61515FAB2EC00310E8D /* BookmarkTableViewController.m */; };
696C33AE1530D0D400990E69 /* startup.html in Resources */ = {isa = PBXBuildFile; fileRef = 696C33AD1530D0D400990E69 /* startup.html */; };
696EBD7814F7877900B81BC9 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696EBD7714F7877900B81BC9 /* UIKit.framework */; };
696EBD7A14F7877900B81BC9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 696EBD7914F7877900B81BC9 /* Foundation.framework */; };
@@ -69,10 +74,17 @@
6924C28B155262E2004BE7F9 /* SettingsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsViewController.xib; sourceTree = "<group>"; };
6924C28E15526343004BE7F9 /* SettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsTableViewController.h; sourceTree = "<group>"; };
6924C28F15526343004BE7F9 /* SettingsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsTableViewController.m; sourceTree = "<group>"; };
+ 692B338615FAD31D00A23DD5 /* Bookmark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bookmark.h; sourceTree = "<group>"; };
+ 692B338715FAD31D00A23DD5 /* Bookmark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Bookmark.m; sourceTree = "<group>"; };
+ 692B338915FAD4B600A23DD5 /* Bookmarks 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Bookmarks 2.xcdatamodel"; sourceTree = "<group>"; };
+ 692B338A15FAF2E400A23DD5 /* BookmarkEditViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BookmarkEditViewController.h; sourceTree = "<group>"; };
+ 692B338B15FAF2E400A23DD5 /* BookmarkEditViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BookmarkEditViewController.m; sourceTree = "<group>"; };
692B86AD153CD4CB000806A9 /* NSData+Conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Conversion.h"; sourceTree = "<group>"; };
692B86AE153CD4CB000806A9 /* NSData+Conversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Conversion.m"; sourceTree = "<group>"; };
6940BD1D15F84C0C00FE74CB /* TorController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TorController.h; sourceTree = "<group>"; };
6940BD1E15F84C0C00FE74CB /* TorController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TorController.m; sourceTree = "<group>"; };
+ 6940BD2215F86B5C00FE74CB /* Bookmarks.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Bookmarks.xcdatamodel; sourceTree = "<group>"; };
+ 6940BD2415F8761900FE74CB /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
694F34E9152ECFF20002BCBC /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = icon/Icon.png; sourceTree = "<group>"; };
694F34EA152ECFF20002BCBC /* Icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72.png"; path = "icon/Icon-72.png"; sourceTree = "<group>"; };
694F34EB152ECFF20002BCBC /* Icon-72@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-72@2x.png"; path = "icon/Icon-72@2x.png"; sourceTree = "<group>"; };
@@ -81,6 +93,8 @@
694F34EE152ECFF20002BCBC /* Icon-Small-50@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small-50@2x.png"; path = "icon/Icon-Small-50@2x.png"; sourceTree = "<group>"; };
694F34EF152ECFF20002BCBC /* Icon-Small@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-Small@2x.png"; path = "icon/Icon-Small@2x.png"; sourceTree = "<group>"; };
694F34F0152ECFF20002BCBC /* Icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon@2x.png"; path = "icon/Icon@2x.png"; sourceTree = "<group>"; };
+ 6963E61415FAB2EC00310E8D /* BookmarkTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BookmarkTableViewController.h; sourceTree = "<group>"; };
+ 6963E61515FAB2EC00310E8D /* BookmarkTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BookmarkTableViewController.m; sourceTree = "<group>"; };
696C33AD1530D0D400990E69 /* startup.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = startup.html; sourceTree = "<group>"; };
696EBD7314F7877900B81BC9 /* OnionBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OnionBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; };
696EBD7714F7877900B81BC9 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
@@ -135,6 +149,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 6940BD2515F8761900FE74CB /* CoreData.framework in Frameworks */,
699CCEBD14FA1939004A2F56 /* libxml2.dylib in Frameworks */,
697ABCD814FA043300E1678C /* MobileCoreServices.framework in Frameworks */,
697ABCD614FA042C00E1678C /* SystemConfiguration.framework in Frameworks */,
@@ -160,7 +175,16 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 6924C27515525F3B004BE7F9 /* Settings View */ = {
+ 6924C27515525F3B004BE7F9 /* Settings */ = {
+ isa = PBXGroup;
+ children = (
+ 69A82A7D15F97553009B31F1 /* Bookmarks */,
+ 6940BD3115F87FC100FE74CB /* SettingsView */,
+ );
+ name = Settings;
+ sourceTree = "<group>";
+ };
+ 6940BD3115F87FC100FE74CB /* SettingsView */ = {
isa = PBXGroup;
children = (
6924C289155262E2004BE7F9 /* SettingsViewController.h */,
@@ -169,12 +193,13 @@
6924C28E15526343004BE7F9 /* SettingsTableViewController.h */,
6924C28F15526343004BE7F9 /* SettingsTableViewController.m */,
);
- name = "Settings View";
+ name = SettingsView;
sourceTree = "<group>";
};
696EBD6814F7877900B81BC9 = {
isa = PBXGroup;
children = (
+ 6940BD2415F8761900FE74CB /* CoreData.framework */,
696F9EB114F8DD5300BC5FDC /* ThirdParty */,
69BB0A4C14F8D31800E7E909 /* Tor */,
696EBD7D14F7877900B81BC9 /* OnionBrowser */,
@@ -220,7 +245,7 @@
69C6F6A414FACC3000894495 /* ProxyURLProtocol.m */,
69F3C5F714FC8739008274C3 /* CKHTTPConnection.h */,
69F3C5F814FC8739008274C3 /* CKHTTPConnection.m */,
- 6924C27515525F3B004BE7F9 /* Settings View */,
+ 6924C27515525F3B004BE7F9 /* Settings */,
);
path = OnionBrowser;
sourceTree = "<group>";
@@ -290,6 +315,20 @@
name = External;
sourceTree = "<group>";
};
+ 69A82A7D15F97553009B31F1 /* Bookmarks */ = {
+ isa = PBXGroup;
+ children = (
+ 6940BD2115F86B5C00FE74CB /* Bookmarks.xcdatamodeld */,
+ 6963E61415FAB2EC00310E8D /* BookmarkTableViewController.h */,
+ 6963E61515FAB2EC00310E8D /* BookmarkTableViewController.m */,
+ 692B338615FAD31D00A23DD5 /* Bookmark.h */,
+ 692B338715FAD31D00A23DD5 /* Bookmark.m */,
+ 692B338A15FAF2E400A23DD5 /* BookmarkEditViewController.h */,
+ 692B338B15FAF2E400A23DD5 /* BookmarkEditViewController.m */,
+ );
+ name = Bookmarks;
+ sourceTree = "<group>";
+ };
69BB0A4C14F8D31800E7E909 /* Tor */ = {
isa = PBXGroup;
children = (
@@ -397,6 +436,10 @@
6924C28C155262E2004BE7F9 /* SettingsViewController.m in Sources */,
6924C29015526343004BE7F9 /* SettingsTableViewController.m in Sources */,
6940BD1F15F84C0C00FE74CB /* TorController.m in Sources */,
+ 6940BD2315F86B5C00FE74CB /* Bookmarks.xcdatamodeld in Sources */,
+ 6963E61615FAB2EC00310E8D /* BookmarkTableViewController.m in Sources */,
+ 692B338815FAD31D00A23DD5 /* Bookmark.m in Sources */,
+ 692B338C15FAF2E500A23DD5 /* BookmarkEditViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -545,6 +588,20 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
+
+/* Begin XCVersionGroup section */
+ 6940BD2115F86B5C00FE74CB /* Bookmarks.xcdatamodeld */ = {
+ isa = XCVersionGroup;
+ children = (
+ 692B338915FAD4B600A23DD5 /* Bookmarks 2.xcdatamodel */,
+ 6940BD2215F86B5C00FE74CB /* Bookmarks.xcdatamodel */,
+ );
+ currentVersion = 692B338915FAD4B600A23DD5 /* Bookmarks 2.xcdatamodel */;
+ path = Bookmarks.xcdatamodeld;
+ sourceTree = "<group>";
+ versionGroupType = wrapper.xcdatamodel;
+ };
+/* End XCVersionGroup section */
};
rootObject = 696EBD6A14F7877900B81BC9 /* Project object */;
}
View
7 OnionBrowser/OnionBrowser/AppDelegate.h
@@ -23,6 +23,10 @@
@property (strong, nonatomic) UIWindow *window;
+@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
+@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
+@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
+
@property (nonatomic) WebViewController *appWebView;
@property (nonatomic) Byte spoofUserAgent;
@@ -31,4 +35,7 @@
@property (nonatomic) NSMutableArray *sslWhitelistedDomains; // for self-signed
+@property (nonatomic) Boolean doPrepopulateBookmarks;
+- (NSURL *)applicationDocumentsDirectory;
+
@end
View
76 OnionBrowser/OnionBrowser/AppDelegate.m
@@ -7,6 +7,7 @@
#import "AppDelegate.h"
#include <Openssl/sha.h>
+#include "Bookmark.h"
@implementation AppDelegate
@@ -17,11 +18,20 @@ @implementation AppDelegate
sslWhitelistedDomains,
appWebView,
tor = _tor,
- window = _window
+ window = _window,
+ managedObjectContext = __managedObjectContext,
+ managedObjectModel = __managedObjectModel,
+ persistentStoreCoordinator = __persistentStoreCoordinator,
+ doPrepopulateBookmarks
;
-- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-{
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Detect
+ NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Bookmarks.sqlite"];
+ NSLog(@"%@", [storeURL absoluteString]);
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ doPrepopulateBookmarks = (![fileManager fileExistsAtPath:[storeURL path]]);
+
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
appWebView = [[WebViewController alloc] init];
@@ -52,6 +62,66 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
return YES;
}
+#pragma mark - Core Data stack
+
+// Returns the managed object context for the application.
+// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
+- (NSManagedObjectContext *)managedObjectContext
+{
+ if (__managedObjectContext != nil) {
+ return __managedObjectContext;
+ }
+
+ NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
+ if (coordinator != nil) {
+ __managedObjectContext = [[NSManagedObjectContext alloc] init];
+ [__managedObjectContext setPersistentStoreCoordinator:coordinator];
+ }
+ return __managedObjectContext;
+}
+
+// Returns the managed object model for the application.
+// If the model doesn't already exist, it is created from the application's model.
+- (NSManagedObjectModel *)managedObjectModel
+{
+ if (__managedObjectModel != nil) {
+ return __managedObjectModel;
+ }
+ NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Bookmarks" withExtension:@"momd"];
+ __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
+ return __managedObjectModel;
+}
+
+// Returns the persistent store coordinator for the application.
+// If the coordinator doesn't already exist, it is created and the application's store added to it.
+- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
+{
+ if (__persistentStoreCoordinator != nil) {
+ return __persistentStoreCoordinator;
+ }
+
+ NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Bookmarks.sqlite"];
+
+ NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
+ [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
+
+ NSError *error = nil;
+ __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
+ if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
+ NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
+ abort();
+ }
+
+ return __persistentStoreCoordinator;
+}
+
+- (NSURL *)applicationDocumentsDirectory {
+ return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
+}
+
+
+
#pragma mark -
#pragma mark App lifecycle
View
19 OnionBrowser/OnionBrowser/Bookmark.h
@@ -0,0 +1,19 @@
+//
+// Bookmark.h
+// OnionBrowser
+//
+// Created by Mike Tigas on 9/7/12.
+//
+//
+
+#import <Foundation/Foundation.h>
+#import <CoreData/CoreData.h>
+
+
+@interface Bookmark : NSManagedObject
+
+@property (nonatomic, retain) NSString * title;
+@property (nonatomic, retain) NSString * url;
+@property (nonatomic) int16_t order;
+
+@end
View
18 OnionBrowser/OnionBrowser/Bookmark.m
@@ -0,0 +1,18 @@
+//
+// Bookmark.m
+// OnionBrowser
+//
+// Created by Mike Tigas on 9/7/12.
+//
+//
+
+#import "Bookmark.h"
+
+
+@implementation Bookmark
+
+@dynamic title;
+@dynamic url;
+@dynamic order;
+
+@end
View
21 OnionBrowser/OnionBrowser/BookmarkEditViewController.h
@@ -0,0 +1,21 @@
+//
+// BookmarkEditViewController.h
+// OnionBrowser
+//
+// Created by Mike Tigas on 9/7/12.
+//
+//
+
+#import <UIKit/UIKit.h>
+#import "Bookmark.h"
+
+@interface BookmarkEditViewController : UITableViewController <UITextFieldDelegate> {
+ Bookmark *bookmark;
+}
+
+-(id)initWithBookmark:(Bookmark*)bookmarkToEdit;
+@property (nonatomic, retain) Bookmark *bookmark;
+
+
+-(void)saveAndGoBack;
+@end
View
185 OnionBrowser/OnionBrowser/BookmarkEditViewController.m
@@ -0,0 +1,185 @@
+//
+// BookmarkEditViewController.m
+// OnionBrowser
+//
+// Created by Mike Tigas on 9/7/12.
+//
+//
+
+#import "BookmarkEditViewController.h"
+#import "BookmarkTableViewController.h"
+
+@interface BookmarkEditViewController ()
+
+@end
+
+@implementation BookmarkEditViewController
+@synthesize bookmark;
+
+- (id)initWithStyle:(UITableViewStyle)style
+{
+ self = [super initWithStyle:style];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (id)initWithBookmark:(Bookmark *)bookmarkToEdit {
+ self = [super initWithStyle:UITableViewStyleGrouped];
+ if (self) {
+ self.bookmark = bookmarkToEdit;
+ }
+ return self;
+}
+
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ // Uncomment the following line to preserve selection between presentations.
+ // self.clearsSelectionOnViewWillAppear = NO;
+
+ // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
+ // self.navigationItem.rightBarButtonItem = self.editButtonItem;
+}
+
+- (void)viewDidUnload
+{
+ [super viewDidUnload];
+ // Release any retained subviews of the main view.
+ // e.g. self.myOutlet = nil;
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return (IS_IPAD) || (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 3;
+}
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
+ if(section == 0)
+ return @"Bookmark Title";
+ else if (section == 1)
+ return @"Bookmark URL";
+ else
+ return nil;
+}
+
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+ return 1;
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ static NSString *CellIdentifier = @"Cell";
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
+ }
+
+ if ((indexPath.section == 0)||(indexPath.section == 1)) {
+ cell.selectionStyle = UITableViewCellSelectionStyleNone;
+
+ CGRect textFrame;
+ if (IS_IPAD) {
+ textFrame = CGRectMake(50, 10,
+ cell.contentView.frame.size.width-100, cell.contentView.frame.size.height-20);
+ } else {
+ textFrame = CGRectMake(20, 10,
+ cell.contentView.frame.size.width-40, cell.contentView.frame.size.height-20);
+ }
+ UITextField *editField = [[UITextField alloc]
+ initWithFrame:textFrame];
+ editField.adjustsFontSizeToFitWidth = YES;
+ editField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
+
+ /*
+ editField.textColor = [UIColor blackColor];
+ editField.backgroundColor = [UIColor whiteColor];
+ */
+ editField.textAlignment = UITextAlignmentLeft;
+ editField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
+ [editField setEnabled: YES];
+ editField.delegate = self;
+
+ if (indexPath.section == 0) {
+ editField.autocorrectionType = UITextAutocorrectionTypeYes;
+ editField.autocapitalizationType = UITextAutocapitalizationTypeWords;
+ editField.text = bookmark.title;
+ editField.returnKeyType = UIReturnKeyNext;
+ editField.tag = 100;
+ } else {
+ editField.autocorrectionType = UITextAutocorrectionTypeNo;
+ editField.autocapitalizationType = UITextAutocapitalizationTypeNone;
+ editField.text = bookmark.url;
+ editField.returnKeyType = UIReturnKeyDone;
+ editField.tag = 101;
+ }
+
+ [cell addSubview:editField];
+
+ } else {
+ cell.selectionStyle = UITableViewCellSelectionStyleBlue;
+
+ cell.textLabel.textAlignment = UITextAlignmentCenter;
+ cell.textLabel.text = @"Done";
+ }
+
+ return cell;
+}
+
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+ if (textField.tag == 100)
+ [[self.view viewWithTag:101] becomeFirstResponder];
+ else if (textField.tag == 101) {
+ [self saveAndGoBack];
+ }
+ return YES;
+}
+
+// Override to support conditional editing of the table view.
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+ return NO;
+}
+
+#pragma mark - Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if ((indexPath.section == 0)||(indexPath.section == 1)) {
+ } else {
+ [self saveAndGoBack];
+ }
+}
+
+-(void)saveAndGoBack {
+ NSUInteger titlePathInt[2] = {0,0};
+ NSIndexPath* titlePath = [[NSIndexPath alloc] initWithIndexes:titlePathInt length:2];
+ UITableViewCell *titleCell = [self.tableView cellForRowAtIndexPath:titlePath];
+ UITextField *titleEditField = (UITextField*)[titleCell viewWithTag:100];
+ bookmark.title = titleEditField.text;
+
+ NSUInteger urlPathInt[2] = {1,0};
+ NSIndexPath* urlPath = [[NSIndexPath alloc] initWithIndexes:urlPathInt length:2];
+ UITableViewCell *urlCell = [self.tableView cellForRowAtIndexPath:urlPath];
+ UITextField *urlEditField = (UITextField*)[urlCell viewWithTag:101];
+ bookmark.url = urlEditField.text;
+
+ BookmarkTableViewController *tableVC = (BookmarkTableViewController*)self.parentViewController;
+
+ NSError *error = nil;
+ if (![tableVC.managedObjectContext save:&error]) {
+ NSLog(@"Error updating bookmark order: %@", error);
+ }
+ [tableVC reload];
+ [self dismissModalViewControllerAnimated:YES];
+}
+@end
View
33 OnionBrowser/OnionBrowser/BookmarkTableViewController.h
@@ -0,0 +1,33 @@
+//
+// BookmarkListViewController.h
+// OnionBrowser
+//
+// Created by Mike Tigas on 9/7/12.
+//
+//
+
+#import <UIKit/UIKit.h>
+
+@interface BookmarkTableViewController : UITableViewController {
+ NSMutableArray *bookmarksArray;
+ NSManagedObjectContext *managedObjectContext;
+ UIBarButtonItem *addButton;
+}
+
+@property (nonatomic, retain) NSMutableArray *bookmarksArray;
+@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
+@property (nonatomic, retain) UIBarButtonItem *editButton;
+@property (nonatomic, retain) UIBarButtonItem *addButton;
+@property (nonatomic, retain) UIBarButtonItem *backButton;
+@property (nonatomic, retain) UIBarButtonItem *editDoneButton;
+
+@property (readonly, nonatomic) NSArray *presetBookmarks;
+
+- (void)saveBookmarkOrder;
+
+- (void)reload;
+- (void)addBookmark;
+- (void)startEditing;
+- (void)stopEditing;
+- (void)goBack;
+@end
View
265 OnionBrowser/OnionBrowser/BookmarkTableViewController.m
@@ -0,0 +1,265 @@
+//
+// BookmarkListViewController.m
+// OnionBrowser
+//
+// Created by Mike Tigas on 9/7/12.
+//
+//
+
+#import "BookmarkTableViewController.h"
+#import "Bookmark.h"
+#import "BookmarkEditViewController.h"
+#import "AppDelegate.h"
+
+@interface BookmarkTableViewController ()
+
+@end
+
+@implementation BookmarkTableViewController
+@synthesize bookmarksArray;
+@synthesize managedObjectContext;
+@synthesize addButton;
+@synthesize editButton;
+@synthesize backButton;
+@synthesize editDoneButton;
+@synthesize presetBookmarks = _presetBookmarks;
+
+- (id)initWithStyle:(UITableViewStyle)style
+{
+ self = [super initWithStyle:style];
+ if (self) {
+ // Custom initialization
+ }
+ return self;
+}
+
+- (NSArray *)presetBookmarks {
+ if (_presetBookmarks == nil) {
+ _presetBookmarks = [NSArray arrayWithObjects:
+ [NSArray arrayWithObjects:@"Main Site", @"http://onionbrowser.com/", nil],
+ [NSArray arrayWithObjects:@"Source Code Site", @"https://github.com/mtigas/iOS-OnionBrowser/", nil],
+ [NSArray arrayWithObjects:@"Version History", @"https://raw.github.com/mtigas/iOS-OnionBrowser/master/CHANGES.txt", nil],
+ [NSArray arrayWithObjects:@"Mike Tigas, App Developer", @"http://mike.tig.as/", nil],
+ nil];
+ }
+ return _presetBookmarks;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+ [self.tableView setAllowsSelectionDuringEditing:YES];
+
+ self.title = @"Bookmarks";
+
+ self.navigationItem.leftBarButtonItem = self.editButtonItem;
+
+ addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
+ target:self action:@selector(addBookmark)];
+ editButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
+ target:self action:@selector(startEditing)];
+ editDoneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
+ target:self action:@selector(stopEditing)];
+ backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleDone target:self action:@selector(goBack)];
+ self.navigationItem.leftBarButtonItem = editButton;
+ self.navigationItem.rightBarButtonItem = backButton;
+ [self reload];
+}
+- (void)viewDidAppear:(BOOL)animated {
+ [super viewDidAppear:animated];
+ [self reload];
+}
+-(void)reload {
+ NSFetchRequest *request = [[NSFetchRequest alloc] init];
+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Bookmark" inManagedObjectContext:managedObjectContext];
+ [request setEntity:entity];
+ NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"order" ascending:YES];
+ NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
+ [request setSortDescriptors:sortDescriptors];
+
+ NSError *error = nil;
+ NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
+ if (mutableFetchResults == nil) {
+ // Handle the error.
+ }
+ [self setBookmarksArray:mutableFetchResults];
+ [self.tableView reloadData];
+}
+
+- (void)viewDidUnload
+{
+ [super viewDidUnload];
+ self.bookmarksArray = nil;
+ self.addButton = nil;
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
+ return (IS_IPAD) || (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
+}
+
+#pragma mark - Table view data source
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return 2;
+}
+
+- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
+ if (section == 1)
+ return @"Onion Browser Links";
+ else
+ return nil;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+ if (section == 0)
+ return [bookmarksArray count];
+ else
+ return [[self presetBookmarks] count];
+}
+
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (indexPath.section == 0)
+ return YES;
+ else
+ return NO;
+}
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+ static NSString *CellIdentifier = @"Cell";
+
+ // Dequeue or create a new cell.
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ if (cell == nil) {
+ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
+ [cell setEditingAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
+ }
+
+ if (indexPath.section == 0) {
+ Bookmark *bookmark = (Bookmark *)[bookmarksArray objectAtIndex:indexPath.row];
+ cell.textLabel.text = bookmark.title;
+ cell.detailTextLabel.text = bookmark.url;
+ return cell;
+ } else {
+ NSArray *item = [[self presetBookmarks] objectAtIndex:indexPath.row];
+ cell.textLabel.text = [item objectAtIndex:0];
+ cell.detailTextLabel.text = [item objectAtIndex:1];
+ return cell;
+ }
+}
+
+- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
+
+ // Delete the managed object at the given index path.
+ NSManagedObject *bookmarkToDelete = [bookmarksArray objectAtIndex:indexPath.row];
+ [managedObjectContext deleteObject:bookmarkToDelete];
+
+ // Update the array and table view.
+ [bookmarksArray removeObjectAtIndex:indexPath.row];
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
+ // Commit the change.
+ NSError *error = nil;
+ if (![managedObjectContext save:&error]) {
+ // Handle the error.
+ }
+ [self saveBookmarkOrder];
+ }
+}
+
+- (void)saveBookmarkOrder {
+ int16_t i = 0;
+ for (Bookmark *bookmark in bookmarksArray) {
+ [bookmark setOrder:i];
+ i++;
+ }
+ NSError *error = nil;
+ if (![managedObjectContext save:&error]) {
+ NSLog(@"Error updating bookmark order: %@", error);
+ }
+}
+
+
+// Override to support rearranging the table view.
+- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
+
+}
+
+#pragma mark - Table view delegate
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+ if (tableView.isEditing) {
+ if (indexPath.section == 0) {
+ // Open an editing pane
+ Bookmark *bookmark = (Bookmark *)[bookmarksArray objectAtIndex:indexPath.row];
+ BookmarkEditViewController *editController = [[BookmarkEditViewController alloc] initWithBookmark:bookmark];
+ [self presentModalViewController:editController animated:YES];
+ } else {
+
+ }
+ } else {
+ NSURL *url;
+ NSString *urlString;
+ if (indexPath.section == 0) {
+ Bookmark *bookmark = (Bookmark *)[bookmarksArray objectAtIndex:indexPath.row];
+ urlString = bookmark.url;
+ } else {
+ NSArray *item = [[self presetBookmarks] objectAtIndex:indexPath.row];
+ urlString = [item objectAtIndex:1];
+ }
+ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
+ url = [NSURL URLWithString:urlString];
+ [appDelegate.appWebView loadURL:url];
+ [appDelegate.appWebView.addressField setText:urlString];
+ [self goBack];
+ }
+}
+
+- (void)addBookmark {
+ Bookmark *bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:managedObjectContext];
+
+ [bookmark setTitle:@"Title"];
+ [bookmark setUrl:@"http://example.com/"];
+
+ int16_t order = [bookmarksArray count];
+ [bookmark setOrder:order];
+
+ NSError *error = nil;
+ if (![managedObjectContext save:&error]) {
+ NSLog(@"Error adding bookmark: %@", error);
+ }
+ [bookmarksArray addObject:bookmark];
+ [self saveBookmarkOrder];
+
+ BookmarkEditViewController *editController = [[BookmarkEditViewController alloc] initWithBookmark:bookmark];
+ [self presentModalViewController:editController animated:YES];
+ /*
+ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:order inSection:0];
+ [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
+ withRowAnimation:UITableViewRowAnimationFade];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:order inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
+ */
+}
+
+- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
+ if (editing) {
+ self.navigationItem.leftBarButtonItem = editDoneButton;
+ self.navigationItem.rightBarButtonItem = addButton;
+ } else {
+ [self saveBookmarkOrder];
+ self.navigationItem.leftBarButtonItem = editButton;
+ self.navigationItem.rightBarButtonItem = backButton;
+ }
+ [super setEditing:editing animated:animated];
+}
+
+- (void)startEditing {
+ [self setEditing:YES];
+}
+- (void)stopEditing {
+ [self setEditing:NO];
+}
+- (void)goBack {
+ [self dismissModalViewControllerAnimated:YES];
+}
+
+@end
View
8 OnionBrowser/OnionBrowser/Bookmarks.xcdatamodeld/.xccurrentversion
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>_XCCurrentVersionName</key>
+ <string>Bookmarks 2.xcdatamodel</string>
+</dict>
+</plist>
View
11 OnionBrowser/OnionBrowser/Bookmarks.xcdatamodeld/Bookmarks 2.xcdatamodel/contents
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1487" systemVersion="11E53" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
+ <entity name="Bookmark" representedClassName="Bookmark" syncable="YES">
+ <attribute name="order" optional="YES" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
+ <attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
+ <attribute name="url" optional="YES" attributeType="String" syncable="YES"/>
+ </entity>
+ <elements>
+ <element name="Bookmark" positionX="0" positionY="0" width="128" height="75"/>
+ </elements>
+</model>
View
10 OnionBrowser/OnionBrowser/Bookmarks.xcdatamodeld/Bookmarks.xcdatamodel/contents
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1487" systemVersion="11E53" minimumToolsVersion="Xcode 4.3" macOSVersion="Automatic" iOSVersion="Automatic">
+ <entity name="Bookmark" representedClassName="Bookmark" syncable="YES">
+ <attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
+ <attribute name="url" optional="YES" attributeType="String" syncable="YES"/>
+ </entity>
+ <elements>
+ <element name="Bookmark" positionX="0" positionY="0" width="128" height="75"/>
+ </elements>
+</model>
View
4 OnionBrowser/OnionBrowser/OnionBrowser-Info.plist
@@ -28,11 +28,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>1.2.6</string>
+ <string>1.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>20120905.2</string>
+ <string>20120907.1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIPrerenderedIcon</key>
View
1  OnionBrowser/OnionBrowser/OnionBrowser-Prefix.pch
@@ -11,6 +11,7 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
+ #import <CoreData/CoreData.h>
#endif
/** String: Identifier **/
View
6 OnionBrowser/OnionBrowser/WebViewController.h
@@ -18,12 +18,13 @@
@property (nonatomic) UIBarButtonItem* toolButton;
@property (nonatomic) UIActionSheet* optionsMenu;
@property (nonatomic) UIBarButtonItem* bookmarkButton;
-@property (nonatomic) UIActionSheet* bookmarkMenu;
@property (nonatomic) UIBarButtonItem* stopRefreshButton;
@property (nonatomic) UILabel* pageTitleLabel;
@property (nonatomic) UITextField* addressField;
@property (nonatomic) NSString *currentURL;
+@property (nonatomic, retain) UINavigationController *bookmarkNavController;
+
@property (nonatomic) NSString *torStatus;
- (void)loadURL: (NSURL *)navigationURL;
@@ -36,6 +37,9 @@
- (void)reload;
- (void)stopLoading;
+- (void)prePopulateBookmarks;
+- (void)showBookmarks;
+- (void)addCurrentAsBookmark;
- (void)updateButtons;
- (void)updateTitle:(UIWebView*)aWebView;
- (void)updateAddress:(NSURLRequest*)request;
View
282 OnionBrowser/OnionBrowser/WebViewController.m
@@ -8,7 +8,9 @@
#import "WebViewController.h"
#import "AppDelegate.h"
+#import "BookmarkTableViewController.h"
#import "SettingsViewController.h"
+#import "Bookmark.h"
static const CGFloat kNavBarHeight = 52.0f;
static const CGFloat kToolBarHeight = 44.0f;
@@ -39,7 +41,6 @@ @implementation WebViewController
toolButton = _toolButton,
optionsMenu = _optionsMenu,
bookmarkButton = _bookmarkButton,
- bookmarkMenu = _bookmarkMenu,
stopRefreshButton = _stopRefreshButton,
pageTitleLabel = _pageTitleLabel,
addressField = _addressField,
@@ -94,7 +95,7 @@ - (void)renderTorStatus: (NSString *)statusLine {
if (summary_loc2.location != NSNotFound)
summary_str = [summary_str substringToIndex:summary_loc2.location];
- NSString *status = [NSString stringWithFormat:@"Connecting… This may take a minute.\n\nIf this takes longer than 60 seconds, please close and re-open the app to retry connection initialization.\n\nIf this problem persists, please visit the following web page in another browser:\nhttp://onionbrowser.com/help/\n\n%@%%\n%@",
+ NSString *status = [NSString stringWithFormat:@"Connecting… This may take a minute.\n\nIf this takes longer than 60 seconds, please close and re-open the app to try connecting from scratch.\n\nIf this problem persists, please visit the following web page in another browser:\nhttp://onionbrowser.com/help/\n\n%@%%\n%@",
progress_str,
summary_str];
loadingStatus.text = status;
@@ -120,6 +121,7 @@ -(void)loadURL: (NSURL *)navigationURL {
_addressField.enabled = YES;
_toolButton.enabled = YES;
_stopRefreshButton.enabled = YES;
+ _bookmarkButton.enabled = YES;
[self updateButtons];
}
@@ -185,8 +187,8 @@ - (void)viewDidLoad {
action:@selector(openOptionsMenu)];
_bookmarkButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks
- target:nil
- action:nil];
+ target:self
+ action:@selector(showBookmarks)];
_stopRefreshButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
@@ -213,13 +215,13 @@ - (void)viewDidLoad {
[self.view addSubview:_toolbar];
// (/toolbar)
- // Set up "action sheet" (options menu)
+ // Set up actionsheets (options menu, bookmarks menu)
_optionsMenu = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:@"Close"
destructiveButtonTitle:@"New Identity"
- otherButtonTitles:@"Browser Settings", @"Open Home Page", @"About Onion Browser", nil];
- // (/actionsheet)
+ otherButtonTitles:@"Bookmark Current Page", @"Browser Settings", @"Open Start Page", @"About Onion Browser", nil];
+ // (/actionsheets)
// Set up navbar
@@ -285,6 +287,66 @@ - (void)viewDidLoad {
loadingStatus.textAlignment = UITextAlignmentLeft;
loadingStatus.text = @"Connecting...\n\n\n\n\n";
[self.view addSubview:loadingStatus];
+
+ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
+ if (appDelegate.doPrepopulateBookmarks){
+ [self prePopulateBookmarks];
+ }
+}
+
+-(void) prePopulateBookmarks {
+ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
+
+ NSManagedObjectContext *context = [appDelegate managedObjectContext];
+
+ NSUInteger i = 0;
+
+ Bookmark *bookmark;
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"The Tor Project (.onion)"];
+ [bookmark setUrl:@"http://idnxcnkne4qt76tg.onion/"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"Tor Project News (HTTPS)"];
+ [bookmark setUrl:@"https://blog.torproject.org/"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"The Cleaned Hidden Wiki (.onion)"];
+ [bookmark setUrl:@"http://3suaolltfj2xjksb.onion/hiddenwiki/index.php/Main_Page"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"The Tor Library (.onion)"];
+ [bookmark setUrl:@"http://am4wuhz3zifexz5u.onion/"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"Reddit /r/onions"];
+ [bookmark setUrl:@"http://www.reddit.com/r/onions"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"Reddit /r/netsec"];
+ [bookmark setUrl:@"http://www.reddit.com/r/netsec"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"Tor Mail (.onion)"];
+ [bookmark setUrl:@"http://jhiwjjlqpyawmpjx.onion/"];
+ [bookmark setOrder:i++];
+
+ bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:context];
+ [bookmark setTitle:@"RedditTor (.onion)"];
+ [bookmark setUrl:@"http://gmyzy5exjw4pimvf.onion/"];
+ [bookmark setOrder:i++];
+
+ NSError *error = nil;
+ if (![context save:&error]) {
+ NSLog(@"Error adding bookmarks: %@", error);
+ }
}
@@ -482,67 +544,68 @@ - (void)openOptionsMenu {
[_optionsMenu showFromToolbar:_toolbar];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
- if (buttonIndex == 0) {
- ////////////////////////////////////////////////////////
- // New Identity
- ////////////////////////////////////////////////////////
- AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
- [appDelegate.tor requestNewTorIdentity];
-
- NSHTTPCookie *cookie;
- NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- for (cookie in [storage cookies]) {
- [storage deleteCookie:cookie];
+ if (actionSheet == _optionsMenu) {
+ if (buttonIndex == 0) {
+ ////////////////////////////////////////////////////////
+ // New Identity
+ ////////////////////////////////////////////////////////
+ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
+ [appDelegate.tor requestNewTorIdentity];
+
+ NSHTTPCookie *cookie;
+ NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+ for (cookie in [storage cookies]) {
+ [storage deleteCookie:cookie];
+ }
+ [[NSURLCache sharedURLCache] removeAllCachedResponses];
+
+ // Initialize a new UIWebView (to clear the history of the previous one)
+ UIWebView *newWebView = [[UIWebView alloc] initWithFrame:_myWebView.frame];
+ newWebView.backgroundColor = [UIColor whiteColor];
+ newWebView.scalesPageToFit = YES;
+ newWebView.contentScaleFactor = 3;
+ newWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
+ newWebView.delegate = self;
+ [_myWebView removeFromSuperview];
+ _myWebView = newWebView;
+ [self.view addSubview: _myWebView];
+
+ // Reset forward/back buttons.
+ [self updateButtons];
+
+ // Reset the address field
+ _addressField.text = @"";
+
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
+ message:@"Requesting a new IP address from Tor. Cache, cookies, and browser history cleared.\n\nDue to an iOS limitation, visisted links will still get the ':visited' CSS highlight state. iOS is resistant to script-based access to this information, but if you are still concerned about leaking history, please force-quit this app and re-launch. Please visit http://yu8.in/M5 for more detailed information."
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:nil];
+ [alert show];
+ } else if (buttonIndex == 1) {
+ ////////////////////////////////////////////////////////
+ // Add To Bookmarks
+ ////////////////////////////////////////////////////////
+ [self addCurrentAsBookmark];
+ } else if (buttonIndex == 2) {
+ ////////////////////////////////////////////////////////
+ // Settings Menu
+ ////////////////////////////////////////////////////////
+ SettingsViewController *settingsController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil];
+ [self presentModalViewController:settingsController animated:YES];
}
- [[NSURLCache sharedURLCache] removeAllCachedResponses];
- // Initialize a new UIWebView (to clear the history of the previous one)
- UIWebView *newWebView = [[UIWebView alloc] initWithFrame:_myWebView.frame];
- newWebView.backgroundColor = [UIColor whiteColor];
- newWebView.scalesPageToFit = YES;
- newWebView.contentScaleFactor = 3;
- newWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
- newWebView.delegate = self;
- [_myWebView removeFromSuperview];
- _myWebView = newWebView;
- [self.view addSubview: _myWebView];
-
- // Reset forward/back buttons.
- [self updateButtons];
-
- // Reset the address field
- _addressField.text = @"";
-
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
- message:@"Requesting a new IP address from Tor. Cache, cookies, and browser history cleared.\n\nDue to an iOS limitation, visisted links will still get the ':visited' CSS highlight state. iOS is resistant to script-based access to this information, but if you are still concerned about leaking history, please force-quit this app and re-launch. Please visit http://yu8.in/M5 for more detailed information."
- delegate:nil
- cancelButtonTitle:@"OK"
- otherButtonTitles:nil];
- [alert show];
- } else if (buttonIndex == 1) {
- ////////////////////////////////////////////////////////
- // Settings Menu
- ////////////////////////////////////////////////////////
- SettingsViewController *settingsController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil];
- [self presentModalViewController:settingsController animated:YES];
- }
-
- if ((buttonIndex == 0) || (buttonIndex == 2)) {
- ////////////////////////////////////////////////////////
- // New Identity OR Return To Home
- ////////////////////////////////////////////////////////
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
- resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
- [self loadURL:[NSURL URLWithString: [NSString stringWithFormat:@"file:/%@//startup.html",resourcePath]]];
- } else if (buttonIndex == 3) {
- ////////////////////////////////////////////////////////
- // About Page
- ////////////////////////////////////////////////////////
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
- resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
- [self loadURL:[NSURL URLWithString: [NSString stringWithFormat:@"file:/%@//about.html",resourcePath]]];
+ if ((buttonIndex == 0) || (buttonIndex == 3)) {
+ ////////////////////////////////////////////////////////
+ // New Identity OR Return To Home
+ ////////////////////////////////////////////////////////
+ [self loadURL:[NSURL URLWithString:@"onionbrowser:start"]];
+ } else if (buttonIndex == 4) {
+ ////////////////////////////////////////////////////////
+ // About Page
+ ////////////////////////////////////////////////////////
+ [self loadURL:[NSURL URLWithString:@"onionbrowser:about"]];
+ }
}
}
@@ -564,9 +627,7 @@ - (void)goBack {
- (void)stopLoading {
[_myWebView stopLoading];
[self updateTitle:_myWebView];
- if ([_currentURL rangeOfString:@"file:"].location == 0) {
- _addressField.text = @"";
- } else if (!_addressField.isEditing) {
+ if (!_addressField.isEditing) {
_addressField.text = _currentURL;
}
[self updateButtons];
@@ -618,14 +679,26 @@ - (void)updateTitle:(UIWebView*)aWebView
_pageTitleLabel.text = pageTitle;
}
-- (void)updateAddress:(NSURLRequest*)request
-{
+- (void)updateAddress:(NSURLRequest*)request {
NSURL* url = [request mainDocumentURL];
- NSString* absoluteString = [url absoluteString];
+ NSString* absoluteString;
- if ([absoluteString rangeOfString:@"file:"].location == 0) {
- _addressField.text = @"";
- } else if (![absoluteString isEqualToString:_currentURL]){
+ if ((url != nil) && [[url scheme] isEqualToString:@"file"]) {
+ // Faked local URLs
+ if ([[url absoluteString] rangeOfString:@"startup.html"].location != NSNotFound) {
+ absoluteString = @"onionbrowser:start";
+ }
+ else if ([[url absoluteString] rangeOfString:@"about.html"].location != NSNotFound) {
+ absoluteString = @"onionbrowser:about";
+ } else {
+ absoluteString = @"";
+ }
+ } else {
+ // Regular ol' web URL.
+ absoluteString = [url absoluteString];
+ }
+
+ if (![absoluteString isEqualToString:_currentURL]){
_currentURL = absoluteString;
if (!_addressField.isEditing) {
_addressField.text = absoluteString;
@@ -645,4 +718,63 @@ - (void)loadAddress:(id)sender event:(UIEvent *)event {
[self loadURL:url];
}
+- (void) addCurrentAsBookmark {
+ if ((_currentURL != nil) && ![_currentURL isEqualToString:@""]) {
+ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
+ NSFetchRequest *request = [[NSFetchRequest alloc] init];
+ NSEntityDescription *entity = [NSEntityDescription entityForName:@"Bookmark" inManagedObjectContext:appDelegate.managedObjectContext];
+ [request setEntity:entity];
+
+ NSError *error = nil;
+ NSUInteger numBookmarks = [appDelegate.managedObjectContext countForFetchRequest:request error:&error];
+ if (error) {
+ // error state?
+ }
+ Bookmark *bookmark = (Bookmark *)[NSEntityDescription insertNewObjectForEntityForName:@"Bookmark" inManagedObjectContext:appDelegate.managedObjectContext];
+
+ NSString *pageTitle = [_myWebView stringByEvaluatingJavaScriptFromString:@"document.title"];
+ [bookmark setTitle:pageTitle];
+ [bookmark setUrl:_currentURL];
+ [bookmark setOrder:numBookmarks];
+
+ NSError *saveError = nil;
+ if (![appDelegate.managedObjectContext save:&saveError]) {
+ NSLog(@"Error saving bookmark: %@", saveError);
+ }
+
+ UIAlertView* alertView = [[UIAlertView alloc]
+ initWithTitle:@"Add Bookmark"
+ message:[NSString stringWithFormat:@"Added '%@' %@ to bookmarks.",
+ pageTitle, _currentURL]
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:nil];
+ alertView.delegate = self;
+ [alertView show];
+ } else {
+ UIAlertView* alertView = [[UIAlertView alloc]
+ initWithTitle:@"Add Bookmark"
+ message:@"Can't bookmark a (local) page with no URL."
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:nil];
+ alertView.delegate = self;
+ [alertView show];
+ }
+}
+
+-(void)showBookmarks {
+ BookmarkTableViewController *bookmarksVC = [[BookmarkTableViewController alloc] initWithStyle:UITableViewStylePlain];
+ UINavigationController *bookmarkNavController = [[UINavigationController alloc]
+ initWithRootViewController:bookmarksVC];
+
+ AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
+
+ NSManagedObjectContext *context = [appDelegate managedObjectContext];
+
+ bookmarksVC.managedObjectContext = context;
+
+ [self presentModalViewController:bookmarkNavController animated:YES];
+}
+
@end
View
30 OnionBrowser/ProxyURLProtocol.m
@@ -68,7 +68,12 @@ - (void)appendData:(NSData *)newData {
// Class methods
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
- if ( !([[[request URL] scheme] isEqualToString:@"file"] || [[[request URL] scheme] isEqualToString:@"data"]) ) {
+ if ( !([[[request URL] scheme] isEqualToString:@"file"] ||
+ [[[request URL] scheme] isEqualToString:@"data"] ||
+ [[[request URL] scheme] isEqualToString:@"itms"] ||
+ [[[request URL] scheme] isEqualToString:@"itms-apps"]
+ )
+ ) {
// Previously we checked if it matched "http" or "https". Apparently
// UIWebView can attempt to make FTP connections for HTML page resources (i.e.
// a <link> tag for a CSS file with an FTP scheme.). So we whitelist
@@ -86,8 +91,27 @@ + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
- (void)startLoading {
- CKHTTPConnection *con = [CKHTTPConnection connectionWithRequest:[self request] delegate:self];
- [self setConnection:con];
+ if ([[[[self request] URL] scheme] isEqualToString:@"onionbrowser"]) {
+ /*
+ This is either "onionbrowser:start" or "onionbrowser:about".
+ */
+ NSURL *url;
+ NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
+ resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
+ resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
+ if ([[[[self request] URL] absoluteString] rangeOfString:@"about"].location != NSNotFound) {
+ url = [NSURL URLWithString: [NSString stringWithFormat:@"file:/%@/about.html",resourcePath]];
+ } else {
+ url = [NSURL URLWithString: [NSString stringWithFormat:@"file:/%@/startup.html",resourcePath]];
+ }
+ NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:url];
+ [newRequest setAllHTTPHeaderFields:[[self request] allHTTPHeaderFields]];
+ NSURLConnection *con = [NSURLConnection connectionWithRequest:newRequest delegate:self];
+ [self setConnection:(CKHTTPConnection *)con]; // lie.
+ } else {
+ CKHTTPConnection *con = [CKHTTPConnection connectionWithRequest:[self request] delegate:self];
+ [self setConnection:con];
+ }
}
-(void)stopLoading {
View
10 OnionBrowser/TorController.m
@@ -13,7 +13,7 @@
@implementation TorController
-#define STATUS_CHECK_TIMEOUT 1.0f
+#define STATUS_CHECK_TIMEOUT 3.0f
@synthesize
didFirstConnect,
@@ -182,7 +182,8 @@ - (void)checkTorStatusTimeout {
//
// Fail: Restart Tor? (Maybe HUP?)
NSLog(@"[tor] checkTor timed out, attempting to restart tor");
- [self startTor];
+ //[self startTor];
+ [self hupTor];
}
@@ -247,10 +248,7 @@ - (void)netsocket:(ULINetSocket*)inNetSocket dataAvailable:(unsigned)inAmount {
if ([msgIn rangeOfString:@"BOOTSTRAP PROGRESS=100"].location != NSNotFound) {
// This is our first go-around (haven't loaded page into webView yet)
// but we are now at 100%, so go ahead.
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@"/" withString:@"//"];
- resourcePath = [resourcePath stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
- [wvc loadURL:[NSURL URLWithString: [NSString stringWithFormat:@"file:/%@//startup.html",resourcePath]]];
+ [wvc loadURL:[NSURL URLWithString:@"onionbrowser:start"]];
didFirstConnect = YES;
// See "checkTor call in middle of app" a little bit below.
View
2  OnionBrowser/about.html
@@ -8,7 +8,7 @@
Support: <a href="http://onionbrowser.com/help/">http://onionbrowser.com/help/</a></p>
<p>&copy; 2012 Mike Tigas (<a href="http://mike.tig.as/">http://mike.tig.as/</a>)</p>
<ul>
- <li><b>OnionBrowser</b>: 1.2.6 (20120905.2)</li>
+ <li><b>OnionBrowser</b>: 1.3.0 (20120907.1)</li>
<li><b>Tor</b>: 0.2.3.21-rc (Sep 05 2012)</li>
<li><b>libevent</b>: 2.0.20-stable (Aug 23 2012)</li>
<li><b>OpenSSL</b>: 1.0.1c (May 10 2012)</li>
View
21 OnionBrowser/startup.html
@@ -7,7 +7,7 @@
<p>Now connected. Please note that web browsing
through the anonymization network will be significantly slower than
through a non-tunneled browser connection.
-<p><b>Helpful Links:</b><br>(.onion unless otherwise noted)</p>
+<p><b>Helpful Links:</b></p>
<ul>
<!-- This is my default search engine here, because page responses tend to be
less than 30KB including all resources. Helpful for limited bandwidth
@@ -26,19 +26,6 @@
<li><a href="https://check.torproject.org/">Am I Using Tor? / What is my IP? (Regular HTTPS)</a></li>
<li><a href="http://ifconfig.me/">ifconfig.me IP/User-Agent Check (Regular HTTP)</a></li>
</ul>
-<ul>
- <li><a href="http://7jguhsfwruviatqe.onion/index.php/Main_Page">The Hidden Wiki</a></li>
- <li><a href="http://am4wuhz3zifexz5u.onion/">The Tor Library</a></li>
- <li><a href="http://xycpusearchon2mc.onion/">DeepSearch</a></li>
- <li><a href="http://xfq5l5p4g3eyrct7.onion/">Onion Image Uploader</a></li>
- <li><a href="http://4eiruntyxxbgfv7o.onion/imgzapr/">ImgZapr</a></li>
- <li><a href="http://4eiruntyxxbgfv7o.onion/paste/">qPasteBin</a></li>
- <li><a href="http://jhiwjjlqpyawmpjx.onion/">TorMail</a></li>
- <li><a href="http://utovvyhaflle76gh.onion/sTORage/">sTORage</a></li>
- <li><a href="http://k6gsb4ibatcico35.onion/">RedditTor</a>
- <li><a href="https://pay.reddit.com/r/onions">Reddit /r/onions (Regular HTTPS)</a></li>
-</ul>
-
<hr />
<p>Disclaimer: Using Onion Browser does not inherently guarantee security or privacy.</p>
<p>Caveats:</p>
@@ -47,8 +34,10 @@
API cannot be disabled.</li>
</ul>
<p>Technical details of caveats, usage tips, &amp; latest app information can always be found at <a href="http://v3.mike.tig.as/onionbrowser/#caveats">onionbrowser.com (regular HTTP)</a>.</p>
-<hr />
-<p><a href="about.html">About / Help / License</a></p>
+ <hr />
+<p>Enjoy Onion Browser? <a href="itms-apps://itunes.apple.com/us/app/onion-browser/id519296448">Review it in the App Store</a> and let others know about it.</p>
+<p>Having issues? <a href="http://v3.mike.tig.as/onionbrowser/help/">Click here</a>.</p>
+<p><a href="onionbrowser:about">About / License</a></p>
</body></html>
View
2  README.markdown
@@ -24,7 +24,7 @@ and App Store links.
#### Technical notes
-* **OnionBrowser**: 1.2.6 (20120905.2)
+* **OnionBrowser**: 1.3.0 (20120907.1)
* **Tor**: 0.2.3.21-rc (Sep 05 2012)
* **libevent**: 2.0.20-stable (Aug 23 2012)
* **OpenSSL**: 1.0.1c (May 10 2012)
View
2  README.txt
@@ -17,7 +17,7 @@ the Tor network (https://www.torproject.org/). See the official site
## Technical notes
-* OnionBrowser: 1.2.6 (20120905.2)
+* OnionBrowser: 1.3.0 (20120907.1)
* Tor: 0.2.3.21-rc (Sep 05 2012)
* libevent: 2.0.20-stable (Aug 23 2012)
* OpenSSL: 1.0.1c (May 10 2012)
Please sign in to comment.
Something went wrong with that request. Please try again.