├── .gitignore ├── .gitmodules ├── DEBIAN └── control ├── MobileSubstrateStubs.framework ├── Headers │ ├── MobileSubstrateStubs.h │ └── substrate.h ├── Info.plist └── MobileSubstrateStubs ├── ObjectiveC Tweak ├── Hooks │ ├── Hooks.m │ ├── TWEView.h │ └── classCreate.m ├── Info.plist ├── MONPluginSafariInlineVideos.h ├── MONPluginSafariInlineVideos.m └── Tweak.h ├── Readme.md ├── Safari Inline Videos.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── build.rb ├── hookTarget ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── hookTargetTests ├── Info.plist └── hookTargetTests.m └── screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | xcuserdata/ 3 | compile/ 4 | build/ 5 | DerivedData/ 6 | *.xccheckout 7 | release/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Monolith"] 2 | path = Monolith 3 | url = https://github.com/johncoates/Monolith.git 4 | -------------------------------------------------------------------------------- /DEBIAN/control: -------------------------------------------------------------------------------- 1 | Package: com.monolith.safariInlineVideos 2 | Name: Safari Inline Videos 3 | Depends: com.johncoates.monolith (>= 0.3), mobilesubstrate, firmware (>> 8.0) 4 | Version: 1.0 5 | Architecture: iphoneos-arm 6 | Description: Display HTML 5 videos inline. 7 | Maintainer: John Coates 8 | Author: John Coates 9 | Section: Tweaks 10 | -------------------------------------------------------------------------------- /MobileSubstrateStubs.framework/Headers/MobileSubstrateStubs.h: -------------------------------------------------------------------------------- 1 | // 2 | // MobileSubstrateStubs.h 3 | // MobileSubstrateStubs 4 | // 5 | // Created by John Coates on 6/3/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for MobileSubstrateStubs. 12 | FOUNDATION_EXPORT double MobileSubstrateStubsVersionNumber; 13 | 14 | //! Project version string for MobileSubstrateStubs. 15 | FOUNDATION_EXPORT const unsigned char MobileSubstrateStubsVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | #import "substrate.h" 19 | 20 | -------------------------------------------------------------------------------- /MobileSubstrateStubs.framework/Headers/substrate.h: -------------------------------------------------------------------------------- 1 | #ifndef _SUBSTRATE 2 | 3 | #define _SUBSTRATE 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | #include 9 | #ifdef __cplusplus 10 | } 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #ifdef __cplusplus 18 | #define _default(x) = x 19 | extern "C" { 20 | #else 21 | #define _default(x) 22 | #endif 23 | typedef const void *MSImageRef; 24 | void MSHookFunction(void *symbol, void *replace, void **result); 25 | void *MSFindSymbol(const void *image, const char *name); 26 | MSImageRef MSGetImageByName(const char *file); 27 | 28 | #ifdef __APPLE__ 29 | #ifdef __arm__ 30 | IMP MSHookMessage(Class _class, SEL sel, IMP imp, const char *prefix _default(NULL)); 31 | #endif 32 | void MSHookMessageEx(Class _class, SEL sel, IMP imp, IMP *result); 33 | 34 | 35 | #endif 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #ifdef __cplusplus 41 | template 42 | static inline void MSHookFunction(Type_ *symbol, Type_ *replace) { 43 | return MSHookFunction(symbol, replace, reinterpret_cast(NULL)); 44 | } 45 | 46 | template 47 | static inline void MSHookSymbol(Type_ *&value, const char *name, void *handle) { 48 | value = reinterpret_cast(dlsym(handle, name)); 49 | } 50 | 51 | template 52 | static inline Type_ &MSHookIvar(id self, const char *name) { 53 | Ivar ivar(class_getInstanceVariable(object_getClass(self), name)); 54 | void *pointer(ivar == NULL ? NULL : reinterpret_cast(self) + ivar_getOffset(ivar)); 55 | return *reinterpret_cast(pointer); 56 | } 57 | #endif 58 | 59 | 60 | #endif -------------------------------------------------------------------------------- /MobileSubstrateStubs.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoatesOSS/SafariInlineVideos/ce80ab61d4411a403806e8388f29c4081b2b9805/MobileSubstrateStubs.framework/Info.plist -------------------------------------------------------------------------------- /MobileSubstrateStubs.framework/MobileSubstrateStubs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoatesOSS/SafariInlineVideos/ce80ab61d4411a403806e8388f29c4081b2b9805/MobileSubstrateStubs.framework/MobileSubstrateStubs -------------------------------------------------------------------------------- /ObjectiveC Tweak/Hooks/Hooks.m: -------------------------------------------------------------------------------- 1 | // 2 | // Hooks 3 | // Safari Inline Videos 4 | // 5 | // Created by John Coates on 4/28/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | /* 14 | These hooks are all jumbled in here, probably not the best example! 15 | 16 | */ 17 | 18 | @interface SIV_UIWebView : MONHook 19 | 20 | @end 21 | @implementation SIV_UIWebView 22 | 23 | + (NSString *)targetClass { 24 | return @"UIWebView"; 25 | } 26 | 27 | - (BOOL)allowsInlineMediaPlayback_hook:(MONCallHandler *)call { 28 | return YES; 29 | } 30 | 31 | @end 32 | 33 | @interface SIV_UIWebBrowserView : MONHook 34 | 35 | @end 36 | @implementation SIV_UIWebBrowserView 37 | 38 | + (NSString *)targetClass { 39 | return @"UIWebBrowserView"; 40 | } 41 | 42 | - (BOOL)allowsInlineMediaPlayback_hook:(MONCallHandler *)call { 43 | return YES; 44 | } 45 | 46 | @end 47 | 48 | 49 | @interface SIV_UIWebViewSettings : MONHook 50 | 51 | @end 52 | @implementation SIV_UIWebViewSettings 53 | 54 | + (NSString *)targetClass { 55 | return @"_UIWebViewSettings"; 56 | } 57 | 58 | - (BOOL)allowsInlineMediaPlayback_hook:(MONCallHandler *)call { 59 | return YES; 60 | } 61 | 62 | @end 63 | 64 | 65 | @interface SIV_WKWebViewConfiguration : MONHook 66 | 67 | @end 68 | @implementation SIV_WKWebViewConfiguration 69 | 70 | + (NSString *)targetClass { 71 | return @"WKWebViewConfiguration"; 72 | } 73 | 74 | - (BOOL)allowsInlineMediaPlayback_hook:(MONCallHandler *)call { 75 | return YES; 76 | } 77 | 78 | @end 79 | 80 | 81 | @interface SIV_FigPluginView : MONHook 82 | @end 83 | 84 | @implementation SIV_FigPluginView 85 | 86 | + (NSString *)targetClass { 87 | return @"FigPluginView"; 88 | } 89 | - (void)willBeginPlayback_hook:(MONCallHandler *)call { 90 | [self mediaElementAttributeChanged:@"webkit-playsinline" value:@(TRUE)]; 91 | [call callOriginalMethod]; 92 | } 93 | 94 | // stub 95 | -(void)mediaElementAttributeChanged:(id)changed value:(id)value { 96 | } 97 | 98 | @end 99 | 100 | 101 | @interface SIV_DOMElement : MONHook { 102 | 103 | } 104 | @end 105 | 106 | static int (*original_getAttribute)(void *instance, int *string, int * unknown); 107 | static int getAttribute(void *instance, int *string, int * unknown); 108 | 109 | @implementation SIV_DOMElement 110 | 111 | + (NSString *)targetClass { 112 | return @"DOMElement"; 113 | } 114 | 115 | - (id)firstElementChild_hook:(MONCallHandler *)call { 116 | // This is a bit hacky 117 | // I'm hooking a random WebCore class to get notified of WebCore's load through +(void)installedHooks 118 | return [call callOriginalMethod]; 119 | } 120 | 121 | + (void)installedHooks { 122 | // We need to use Substrate for this as Monolith doesn't support 123 | // hooking C++ methods 124 | void *func; 125 | func = MSFindSymbol(NULL, "__ZNK7WebCore7Element12getAttributeERKNS_13QualifiedNameE"); 126 | if (func) { 127 | MSHookFunction((int *)func, (int*)getAttribute, (void**)&original_getAttribute); 128 | } 129 | } 130 | 131 | @end 132 | 133 | @interface DOMElement : NSObject 134 | - (NSString *)nodeName; 135 | - (void)setAttribute:(id)attribute value:(id)value; 136 | 137 | @end 138 | 139 | #import 140 | #import 141 | #import 142 | #include 143 | 144 | int offsetForInstanceVariable(void *object, NSString *instanceVariableName) { 145 | Class class = object_getClass((__bridge id)object); 146 | 147 | while (class && class != [NSObject class]) { 148 | unsigned count, i; 149 | Ivar* firstIvar = class_copyIvarList(class, &count); 150 | 151 | const char *instanceVariableNameCString = instanceVariableName.UTF8String; 152 | 153 | for (i = 0; i < count; i++) { 154 | Ivar* ivar = firstIvar + i; 155 | const char *nameCString = ivar_getName(*ivar); 156 | 157 | if (strcmp(instanceVariableNameCString, nameCString) == 0) { 158 | return (int)ivar_getOffset(*ivar); 159 | } 160 | } 161 | 162 | free(firstIvar); 163 | 164 | class = class_getSuperclass(class); 165 | } 166 | 167 | NSLog(@"couldn't find %@ in %@", instanceVariableName, NSStringFromClass(class)); 168 | 169 | return -1; 170 | } 171 | 172 | 173 | id const createClassInstance(Class const class); 174 | 175 | static int getAttribute(void *instance, int *string, int * unknown) { 176 | int ret = original_getAttribute(instance, string, unknown); 177 | 178 | 179 | static DOMElement *testElement; 180 | static CFMutableSetRef checked; 181 | if (!testElement) { 182 | testElement = createClassInstance([DOMElement class]); 183 | checked = CFSetCreateMutable(NULL, 0, NULL); 184 | } 185 | 186 | if (CFSetContainsValue(checked, instance)){ 187 | return ret; 188 | } 189 | 190 | static int internalOffset = -2; 191 | if (internalOffset == -2) { 192 | internalOffset = offsetForInstanceVariable((__bridge void *)testElement, @"_internal"); 193 | } 194 | 195 | if (internalOffset != -2 && internalOffset != -1) { 196 | void *internalAddress = (__bridge void *)testElement; 197 | internalAddress += internalOffset; 198 | memcpy(internalAddress, &instance, sizeof(instance)); 199 | 200 | if ([[testElement nodeName].lowercaseString isEqualToString:@"video"]) { 201 | [testElement setAttribute:@"webkit-playsinline" value:@"webkit-playsinclassline"]; 202 | } 203 | } 204 | 205 | CFSetAddValue(checked, instance); 206 | 207 | return ret; 208 | } 209 | 210 | 211 | -------------------------------------------------------------------------------- /ObjectiveC Tweak/Hooks/TWEView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TWEView.h 3 | // ObjectiveC Tweak 4 | // 5 | // Created by John Coates on 4/28/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface TWEView : MNOHook 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ObjectiveC Tweak/Hooks/classCreate.m: -------------------------------------------------------------------------------- 1 | // 2 | // classCreate.m 3 | // ObjectiveC Tweak 4 | // 5 | // Created by John Coates on 6/5/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #include 12 | 13 | id createClassInstance(Class const class) { 14 | id instance = class_createInstance(class, 0); 15 | [instance retain]; 16 | return instance; 17 | } -------------------------------------------------------------------------------- /ObjectiveC Tweak/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.johncoates.monolith.templates.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ObjectiveC Tweak/MONPluginSafariInlineVideos.h: -------------------------------------------------------------------------------- 1 | // 2 | // MONPluginSafariInlineVideos.h 3 | // Safari Inline Videos 4 | // 5 | // Created by John Coates on 6/6/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MONPluginSafariInlineVideos : MONPlugin 12 | 13 | + (NSString *)name; 14 | 15 | + (BOOL)shouldLoadIntoProcess:(MONProcess *)process; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /ObjectiveC Tweak/MONPluginSafariInlineVideos.m: -------------------------------------------------------------------------------- 1 | // 2 | // MONPluginSafariInlineVideos.m 3 | // Safari Inline Videos 4 | // 5 | // Created by John Coates on 6/6/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MONPluginSafariInlineVideos.h" 11 | 12 | @implementation MONPluginSafariInlineVideos 13 | 14 | + (NSString *)name { 15 | return @"Safari Inline Videos"; 16 | } 17 | 18 | + (BOOL)shouldLoadIntoProcess:(MONProcess *)process { 19 | if (!process.bundleIdentifier) { 20 | return FALSE; 21 | } 22 | 23 | NSArray *validBundles = @[@"com.apple.WebKit.WebContent", @"com.apple.mobilesafari"]; 24 | 25 | return [validBundles containsObject:process.bundleIdentifier]; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /ObjectiveC Tweak/Tweak.h: -------------------------------------------------------------------------------- 1 | // 2 | // Tweak.h 3 | // ObjectiveC Tweak 4 | // 5 | // Created by John Coates on 4/28/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## Safari Inline Videos 2 | This tweak was requested on [/r/jailbreak](http://www.reddit.com/r/jailbreak/comments/385zdu/taking_tweak_requests_for_immediate_developing/crskg0v) by Liamrc 3 | 4 | ## Features 5 | Safari now plays HTML5 videos inline, instead of full screen. Try it out at [http://i.imgur.com/OZz4qTS.gifv](http://i.imgur.com/OZz4qTS.gifv) 6 | 7 | Adds webkit-playsinline to video HTML tags as necessary. 8 | 9 | Note: Uses Monolith framework, which is currently in beta. 10 | 11 | ## Download 12 | Get it on my [Delta Repo](http://getdelta.co/) 13 | 14 | ## Screenshot 15 | 16 | ![Screenshot](https://raw.githubusercontent.com/johncoates/SafariInlineVideos/master/screenshot.png) -------------------------------------------------------------------------------- /Safari Inline Videos.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8E45A2141B21E5780027109E /* WebCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E45A2131B21E5780027109E /* WebCore.framework */; }; 11 | 8E45A2171B21E7EF0027109E /* classCreate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E45A2151B21E7DA0027109E /* classCreate.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 12 | 8E45A2181B21EB400027109E /* classCreate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E45A2151B21E7DA0027109E /* classCreate.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 13 | 8E45A2191B21EB760027109E /* WebCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E45A2131B21E5780027109E /* WebCore.framework */; }; 14 | 8E63FD451AF038A500B2E569 /* Tweak.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E63FD441AF038A500B2E569 /* Tweak.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 8E63FD611AF0394C00B2E569 /* Hooks.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E63FD5F1AF0394C00B2E569 /* Hooks.m */; }; 16 | 8EBEA2421B22CBF700B5E090 /* MONPluginSafariInlineVideos.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EBEA2401B22CBF600B5E090 /* MONPluginSafariInlineVideos.h */; }; 17 | 8EBEA2431B22CBF700B5E090 /* MONPluginSafariInlineVideos.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EBEA2411B22CBF600B5E090 /* MONPluginSafariInlineVideos.m */; }; 18 | 8EDCBFB51B21C8BA006C58DE /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EDCBFB41B21C8BA006C58DE /* WebKit.framework */; }; 19 | 8EDCBFBA1B21D40B006C58DE /* MobileSubstrateStubs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EDCBFB91B21D40B006C58DE /* MobileSubstrateStubs.framework */; }; 20 | 8EDCBFBB1B21D585006C58DE /* MobileSubstrateStubs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EDCBFB91B21D40B006C58DE /* MobileSubstrateStubs.framework */; }; 21 | 8EF9C5B11B1D66D40027000C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF9C5B01B1D66D40027000C /* main.m */; }; 22 | 8EF9C5B41B1D66D40027000C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF9C5B31B1D66D40027000C /* AppDelegate.m */; }; 23 | 8EF9C5B71B1D66D40027000C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EF9C5B61B1D66D40027000C /* ViewController.m */; }; 24 | 8EF9C5BA1B1D66D40027000C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8EF9C5B81B1D66D40027000C /* Main.storyboard */; }; 25 | 8EF9C5BC1B1D66D40027000C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8EF9C5BB1B1D66D40027000C /* Images.xcassets */; }; 26 | 8EF9C5BF1B1D66D40027000C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8EF9C5BD1B1D66D40027000C /* LaunchScreen.xib */; }; 27 | 8EF9C5D41B1D6AF50027000C /* Monolith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD725CD1B1D07CC0032E880 /* Monolith.framework */; }; 28 | 8EF9C5D51B1D6AF50027000C /* Monolith.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FAD725CD1B1D07CC0032E880 /* Monolith.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 29 | 8EF9C5D71B1D77790027000C /* Hooks.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E63FD5F1AF0394C00B2E569 /* Hooks.m */; }; 30 | FAD725CE1B1D07CC0032E880 /* Monolith.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAD725CD1B1D07CC0032E880 /* Monolith.framework */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXCopyFilesBuildPhase section */ 34 | 8EF9C5D61B1D6AF50027000C /* Embed Frameworks */ = { 35 | isa = PBXCopyFilesBuildPhase; 36 | buildActionMask = 2147483647; 37 | dstPath = ""; 38 | dstSubfolderSpec = 10; 39 | files = ( 40 | 8EF9C5D51B1D6AF50027000C /* Monolith.framework in Embed Frameworks */, 41 | ); 42 | name = "Embed Frameworks"; 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXCopyFilesBuildPhase section */ 46 | 47 | /* Begin PBXFileReference section */ 48 | 8E45A2131B21E5780027109E /* WebCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebCore.framework; path = System/Library/PrivateFrameworks/WebCore.framework; sourceTree = SDKROOT; }; 49 | 8E45A2151B21E7DA0027109E /* classCreate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = classCreate.m; sourceTree = ""; }; 50 | 8E63FD3F1AF038A500B2E569 /* Tweak.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Tweak.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 8E63FD431AF038A500B2E569 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 8E63FD441AF038A500B2E569 /* Tweak.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Tweak.h; sourceTree = ""; }; 53 | 8E63FD5F1AF0394C00B2E569 /* Hooks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Hooks.m; sourceTree = ""; }; 54 | 8EBEA2401B22CBF600B5E090 /* MONPluginSafariInlineVideos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MONPluginSafariInlineVideos.h; sourceTree = ""; }; 55 | 8EBEA2411B22CBF600B5E090 /* MONPluginSafariInlineVideos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MONPluginSafariInlineVideos.m; sourceTree = ""; }; 56 | 8EDCBFB41B21C8BA006C58DE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; 57 | 8EDCBFB91B21D40B006C58DE /* MobileSubstrateStubs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MobileSubstrateStubs.framework; sourceTree = ""; }; 58 | 8EF9C5AC1B1D66D40027000C /* hookTarget.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = hookTarget.app; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 8EF9C5AF1B1D66D40027000C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 60 | 8EF9C5B01B1D66D40027000C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 61 | 8EF9C5B21B1D66D40027000C /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 62 | 8EF9C5B31B1D66D40027000C /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 63 | 8EF9C5B51B1D66D40027000C /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 64 | 8EF9C5B61B1D66D40027000C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 65 | 8EF9C5B91B1D66D40027000C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 66 | 8EF9C5BB1B1D66D40027000C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 67 | 8EF9C5BE1B1D66D40027000C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 68 | 8EF9C5C91B1D66D50027000C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | 8EF9C5CA1B1D66D50027000C /* hookTargetTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = hookTargetTests.m; sourceTree = ""; }; 70 | FAD725CD1B1D07CC0032E880 /* Monolith.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Monolith.framework; path = Monolith/Monolith.framework; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 8E63FD3B1AF038A500B2E569 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | 8EDCBFBA1B21D40B006C58DE /* MobileSubstrateStubs.framework in Frameworks */, 79 | 8E45A2191B21EB760027109E /* WebCore.framework in Frameworks */, 80 | FAD725CE1B1D07CC0032E880 /* Monolith.framework in Frameworks */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | 8EF9C5A91B1D66D40027000C /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | 8EDCBFB51B21C8BA006C58DE /* WebKit.framework in Frameworks */, 89 | 8E45A2141B21E5780027109E /* WebCore.framework in Frameworks */, 90 | 8EDCBFBB1B21D585006C58DE /* MobileSubstrateStubs.framework in Frameworks */, 91 | 8EF9C5D41B1D6AF50027000C /* Monolith.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXFrameworksBuildPhase section */ 96 | 97 | /* Begin PBXGroup section */ 98 | 8E2823FF1B22C6B3006FADB4 /* Frameworks */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 8E45A2131B21E5780027109E /* WebCore.framework */, 102 | 8EDCBFB91B21D40B006C58DE /* MobileSubstrateStubs.framework */, 103 | 8EDCBFB41B21C8BA006C58DE /* WebKit.framework */, 104 | FAD725CD1B1D07CC0032E880 /* Monolith.framework */, 105 | ); 106 | name = Frameworks; 107 | sourceTree = ""; 108 | }; 109 | 8E63FD351AF038A500B2E569 = { 110 | isa = PBXGroup; 111 | children = ( 112 | 8E2823FF1B22C6B3006FADB4 /* Frameworks */, 113 | 8E63FD411AF038A500B2E569 /* ObjectiveC Tweak */, 114 | 8EF9C5AD1B1D66D40027000C /* hookTarget */, 115 | 8EF9C5C71B1D66D50027000C /* hookTargetTests */, 116 | 8E63FD401AF038A500B2E569 /* Products */, 117 | ); 118 | sourceTree = ""; 119 | }; 120 | 8E63FD401AF038A500B2E569 /* Products */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 8E63FD3F1AF038A500B2E569 /* Tweak.framework */, 124 | 8EF9C5AC1B1D66D40027000C /* hookTarget.app */, 125 | ); 126 | name = Products; 127 | sourceTree = ""; 128 | }; 129 | 8E63FD411AF038A500B2E569 /* ObjectiveC Tweak */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 8E63FD5D1AF0392B00B2E569 /* Hooks */, 133 | 8EBEA2401B22CBF600B5E090 /* MONPluginSafariInlineVideos.h */, 134 | 8EBEA2411B22CBF600B5E090 /* MONPluginSafariInlineVideos.m */, 135 | 8E63FD441AF038A500B2E569 /* Tweak.h */, 136 | 8E63FD421AF038A500B2E569 /* Supporting Files */, 137 | ); 138 | path = "ObjectiveC Tweak"; 139 | sourceTree = ""; 140 | }; 141 | 8E63FD421AF038A500B2E569 /* Supporting Files */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 8E63FD431AF038A500B2E569 /* Info.plist */, 145 | ); 146 | name = "Supporting Files"; 147 | sourceTree = ""; 148 | }; 149 | 8E63FD5D1AF0392B00B2E569 /* Hooks */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 8E63FD5F1AF0394C00B2E569 /* Hooks.m */, 153 | 8E45A2151B21E7DA0027109E /* classCreate.m */, 154 | ); 155 | path = Hooks; 156 | sourceTree = ""; 157 | }; 158 | 8EF9C5AD1B1D66D40027000C /* hookTarget */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 8EF9C5B21B1D66D40027000C /* AppDelegate.h */, 162 | 8EF9C5B31B1D66D40027000C /* AppDelegate.m */, 163 | 8EF9C5B51B1D66D40027000C /* ViewController.h */, 164 | 8EF9C5B61B1D66D40027000C /* ViewController.m */, 165 | 8EF9C5B81B1D66D40027000C /* Main.storyboard */, 166 | 8EF9C5BB1B1D66D40027000C /* Images.xcassets */, 167 | 8EF9C5BD1B1D66D40027000C /* LaunchScreen.xib */, 168 | 8EF9C5AE1B1D66D40027000C /* Supporting Files */, 169 | ); 170 | path = hookTarget; 171 | sourceTree = ""; 172 | }; 173 | 8EF9C5AE1B1D66D40027000C /* Supporting Files */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 8EF9C5AF1B1D66D40027000C /* Info.plist */, 177 | 8EF9C5B01B1D66D40027000C /* main.m */, 178 | ); 179 | name = "Supporting Files"; 180 | sourceTree = ""; 181 | }; 182 | 8EF9C5C71B1D66D50027000C /* hookTargetTests */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 8EF9C5CA1B1D66D50027000C /* hookTargetTests.m */, 186 | 8EF9C5C81B1D66D50027000C /* Supporting Files */, 187 | ); 188 | path = hookTargetTests; 189 | sourceTree = ""; 190 | }; 191 | 8EF9C5C81B1D66D50027000C /* Supporting Files */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 8EF9C5C91B1D66D50027000C /* Info.plist */, 195 | ); 196 | name = "Supporting Files"; 197 | sourceTree = ""; 198 | }; 199 | /* End PBXGroup section */ 200 | 201 | /* Begin PBXHeadersBuildPhase section */ 202 | 8E63FD3C1AF038A500B2E569 /* Headers */ = { 203 | isa = PBXHeadersBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | 8E63FD451AF038A500B2E569 /* Tweak.h in Headers */, 207 | 8EBEA2421B22CBF700B5E090 /* MONPluginSafariInlineVideos.h in Headers */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | /* End PBXHeadersBuildPhase section */ 212 | 213 | /* Begin PBXLegacyTarget section */ 214 | FAD725CF1B1D08230032E880 /* Install Tweak */ = { 215 | isa = PBXLegacyTarget; 216 | buildArgumentsString = ./build.rb; 217 | buildConfigurationList = FAD725D01B1D08230032E880 /* Build configuration list for PBXLegacyTarget "Install Tweak" */; 218 | buildPhases = ( 219 | ); 220 | buildToolPath = /usr/bin/ruby; 221 | buildWorkingDirectory = ./; 222 | dependencies = ( 223 | ); 224 | name = "Install Tweak"; 225 | passBuildSettingsInEnvironment = 1; 226 | productName = "Install Tweak"; 227 | }; 228 | /* End PBXLegacyTarget section */ 229 | 230 | /* Begin PBXNativeTarget section */ 231 | 8E63FD3E1AF038A500B2E569 /* Tweak */ = { 232 | isa = PBXNativeTarget; 233 | buildConfigurationList = 8E63FD551AF038A600B2E569 /* Build configuration list for PBXNativeTarget "Tweak" */; 234 | buildPhases = ( 235 | 8E63FD3A1AF038A500B2E569 /* Sources */, 236 | 8E63FD3B1AF038A500B2E569 /* Frameworks */, 237 | 8E63FD3C1AF038A500B2E569 /* Headers */, 238 | 8E63FD3D1AF038A500B2E569 /* Resources */, 239 | ); 240 | buildRules = ( 241 | ); 242 | dependencies = ( 243 | ); 244 | name = Tweak; 245 | productName = "ObjectiveC Tweak"; 246 | productReference = 8E63FD3F1AF038A500B2E569 /* Tweak.framework */; 247 | productType = "com.apple.product-type.framework"; 248 | }; 249 | 8EF9C5AB1B1D66D40027000C /* hookTarget */ = { 250 | isa = PBXNativeTarget; 251 | buildConfigurationList = 8EF9C5D01B1D66D50027000C /* Build configuration list for PBXNativeTarget "hookTarget" */; 252 | buildPhases = ( 253 | 8EF9C5A81B1D66D40027000C /* Sources */, 254 | 8EF9C5A91B1D66D40027000C /* Frameworks */, 255 | 8EF9C5AA1B1D66D40027000C /* Resources */, 256 | 8EF9C5D61B1D6AF50027000C /* Embed Frameworks */, 257 | ); 258 | buildRules = ( 259 | ); 260 | dependencies = ( 261 | ); 262 | name = hookTarget; 263 | productName = hookTarget; 264 | productReference = 8EF9C5AC1B1D66D40027000C /* hookTarget.app */; 265 | productType = "com.apple.product-type.application"; 266 | }; 267 | /* End PBXNativeTarget section */ 268 | 269 | /* Begin PBXProject section */ 270 | 8E63FD361AF038A500B2E569 /* Project object */ = { 271 | isa = PBXProject; 272 | attributes = { 273 | LastUpgradeCheck = 0630; 274 | ORGANIZATIONNAME = "John Coates"; 275 | TargetAttributes = { 276 | 8E63FD3E1AF038A500B2E569 = { 277 | CreatedOnToolsVersion = 6.3.1; 278 | }; 279 | 8EF9C5AB1B1D66D40027000C = { 280 | CreatedOnToolsVersion = 6.3.1; 281 | }; 282 | FAD725CF1B1D08230032E880 = { 283 | CreatedOnToolsVersion = 6.3; 284 | }; 285 | }; 286 | }; 287 | buildConfigurationList = 8E63FD391AF038A500B2E569 /* Build configuration list for PBXProject "Safari Inline Videos" */; 288 | compatibilityVersion = "Xcode 3.2"; 289 | developmentRegion = English; 290 | hasScannedForEncodings = 0; 291 | knownRegions = ( 292 | en, 293 | Base, 294 | ); 295 | mainGroup = 8E63FD351AF038A500B2E569; 296 | productRefGroup = 8E63FD401AF038A500B2E569 /* Products */; 297 | projectDirPath = ""; 298 | projectRoot = ""; 299 | targets = ( 300 | 8E63FD3E1AF038A500B2E569 /* Tweak */, 301 | FAD725CF1B1D08230032E880 /* Install Tweak */, 302 | 8EF9C5AB1B1D66D40027000C /* hookTarget */, 303 | ); 304 | }; 305 | /* End PBXProject section */ 306 | 307 | /* Begin PBXResourcesBuildPhase section */ 308 | 8E63FD3D1AF038A500B2E569 /* Resources */ = { 309 | isa = PBXResourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | }; 315 | 8EF9C5AA1B1D66D40027000C /* Resources */ = { 316 | isa = PBXResourcesBuildPhase; 317 | buildActionMask = 2147483647; 318 | files = ( 319 | 8EF9C5BA1B1D66D40027000C /* Main.storyboard in Resources */, 320 | 8EF9C5BF1B1D66D40027000C /* LaunchScreen.xib in Resources */, 321 | 8EF9C5BC1B1D66D40027000C /* Images.xcassets in Resources */, 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | }; 325 | /* End PBXResourcesBuildPhase section */ 326 | 327 | /* Begin PBXSourcesBuildPhase section */ 328 | 8E63FD3A1AF038A500B2E569 /* Sources */ = { 329 | isa = PBXSourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | 8E45A2181B21EB400027109E /* classCreate.m in Sources */, 333 | 8E63FD611AF0394C00B2E569 /* Hooks.m in Sources */, 334 | 8EBEA2431B22CBF700B5E090 /* MONPluginSafariInlineVideos.m in Sources */, 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | 8EF9C5A81B1D66D40027000C /* Sources */ = { 339 | isa = PBXSourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | 8EF9C5B71B1D66D40027000C /* ViewController.m in Sources */, 343 | 8EF9C5B41B1D66D40027000C /* AppDelegate.m in Sources */, 344 | 8E45A2171B21E7EF0027109E /* classCreate.m in Sources */, 345 | 8EF9C5D71B1D77790027000C /* Hooks.m in Sources */, 346 | 8EF9C5B11B1D66D40027000C /* main.m in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | /* End PBXSourcesBuildPhase section */ 351 | 352 | /* Begin PBXVariantGroup section */ 353 | 8EF9C5B81B1D66D40027000C /* Main.storyboard */ = { 354 | isa = PBXVariantGroup; 355 | children = ( 356 | 8EF9C5B91B1D66D40027000C /* Base */, 357 | ); 358 | name = Main.storyboard; 359 | sourceTree = ""; 360 | }; 361 | 8EF9C5BD1B1D66D40027000C /* LaunchScreen.xib */ = { 362 | isa = PBXVariantGroup; 363 | children = ( 364 | 8EF9C5BE1B1D66D40027000C /* Base */, 365 | ); 366 | name = LaunchScreen.xib; 367 | sourceTree = ""; 368 | }; 369 | /* End PBXVariantGroup section */ 370 | 371 | /* Begin XCBuildConfiguration section */ 372 | 8E63FD531AF038A600B2E569 /* Debug */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ALWAYS_SEARCH_USER_PATHS = NO; 376 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 377 | CLANG_CXX_LIBRARY = "libc++"; 378 | CLANG_ENABLE_MODULES = YES; 379 | CLANG_ENABLE_OBJC_ARC = YES; 380 | CLANG_WARN_BOOL_CONVERSION = YES; 381 | CLANG_WARN_CONSTANT_CONVERSION = YES; 382 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 383 | CLANG_WARN_EMPTY_BODY = YES; 384 | CLANG_WARN_ENUM_CONVERSION = YES; 385 | CLANG_WARN_INT_CONVERSION = YES; 386 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 387 | CLANG_WARN_UNREACHABLE_CODE = YES; 388 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 389 | CODE_SIGNING_REQUIRED = NO; 390 | COPY_PHASE_STRIP = NO; 391 | CURRENT_PROJECT_VERSION = 1; 392 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 393 | ENABLE_STRICT_OBJC_MSGSEND = YES; 394 | FRAMEWORK_SEARCH_PATHS = ../../; 395 | GCC_C_LANGUAGE_STANDARD = gnu99; 396 | GCC_DYNAMIC_NO_PIC = NO; 397 | GCC_NO_COMMON_BLOCKS = YES; 398 | GCC_OPTIMIZATION_LEVEL = 0; 399 | GCC_PREPROCESSOR_DEFINITIONS = ( 400 | "DEBUG=1", 401 | "$(inherited)", 402 | ); 403 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 404 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 405 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 406 | GCC_WARN_UNDECLARED_SELECTOR = YES; 407 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 408 | GCC_WARN_UNUSED_FUNCTION = YES; 409 | GCC_WARN_UNUSED_VARIABLE = YES; 410 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 411 | MTL_ENABLE_DEBUG_INFO = YES; 412 | ONLY_ACTIVE_ARCH = YES; 413 | SDKROOT = iphoneos; 414 | TARGETED_DEVICE_FAMILY = "1,2"; 415 | VERSIONING_SYSTEM = "apple-generic"; 416 | VERSION_INFO_PREFIX = ""; 417 | }; 418 | name = Debug; 419 | }; 420 | 8E63FD541AF038A600B2E569 /* Release */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | ALWAYS_SEARCH_USER_PATHS = NO; 424 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 425 | CLANG_CXX_LIBRARY = "libc++"; 426 | CLANG_ENABLE_MODULES = YES; 427 | CLANG_ENABLE_OBJC_ARC = YES; 428 | CLANG_WARN_BOOL_CONVERSION = YES; 429 | CLANG_WARN_CONSTANT_CONVERSION = YES; 430 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 431 | CLANG_WARN_EMPTY_BODY = YES; 432 | CLANG_WARN_ENUM_CONVERSION = YES; 433 | CLANG_WARN_INT_CONVERSION = YES; 434 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 435 | CLANG_WARN_UNREACHABLE_CODE = YES; 436 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 437 | CODE_SIGNING_REQUIRED = NO; 438 | COPY_PHASE_STRIP = NO; 439 | CURRENT_PROJECT_VERSION = 1; 440 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 441 | ENABLE_NS_ASSERTIONS = NO; 442 | ENABLE_STRICT_OBJC_MSGSEND = YES; 443 | FRAMEWORK_SEARCH_PATHS = ../../; 444 | GCC_C_LANGUAGE_STANDARD = gnu99; 445 | GCC_NO_COMMON_BLOCKS = YES; 446 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 447 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 448 | GCC_WARN_UNDECLARED_SELECTOR = YES; 449 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 450 | GCC_WARN_UNUSED_FUNCTION = YES; 451 | GCC_WARN_UNUSED_VARIABLE = YES; 452 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 453 | MTL_ENABLE_DEBUG_INFO = NO; 454 | SDKROOT = iphoneos; 455 | TARGETED_DEVICE_FAMILY = "1,2"; 456 | VALIDATE_PRODUCT = YES; 457 | VERSIONING_SYSTEM = "apple-generic"; 458 | VERSION_INFO_PREFIX = ""; 459 | }; 460 | name = Release; 461 | }; 462 | 8E63FD561AF038A600B2E569 /* Debug */ = { 463 | isa = XCBuildConfiguration; 464 | buildSettings = { 465 | DEFINES_MODULE = YES; 466 | DYLIB_COMPATIBILITY_VERSION = 1; 467 | DYLIB_CURRENT_VERSION = 1; 468 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 469 | FRAMEWORK_SEARCH_PATHS = ( 470 | "$(inherited)", 471 | "$(PROJECT_DIR)", 472 | "$(SDKROOT)/System/Library/PrivateFrameworks", 473 | ); 474 | INFOPLIST_FILE = "ObjectiveC Tweak/Info.plist"; 475 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 476 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 477 | PRODUCT_NAME = "$(TARGET_NAME)"; 478 | SKIP_INSTALL = YES; 479 | }; 480 | name = Debug; 481 | }; 482 | 8E63FD571AF038A600B2E569 /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | DEFINES_MODULE = YES; 486 | DYLIB_COMPATIBILITY_VERSION = 1; 487 | DYLIB_CURRENT_VERSION = 1; 488 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 489 | FRAMEWORK_SEARCH_PATHS = ( 490 | "$(inherited)", 491 | "$(PROJECT_DIR)", 492 | "$(SDKROOT)/System/Library/PrivateFrameworks", 493 | ); 494 | INFOPLIST_FILE = "ObjectiveC Tweak/Info.plist"; 495 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 496 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SKIP_INSTALL = YES; 499 | }; 500 | name = Release; 501 | }; 502 | 8EF9C5CC1B1D66D50027000C /* Debug */ = { 503 | isa = XCBuildConfiguration; 504 | buildSettings = { 505 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 506 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 507 | ENTITLEMENTS_REQUIRED = NO; 508 | FRAMEWORK_SEARCH_PATHS = ( 509 | "$(inherited)", 510 | "$(PROJECT_DIR)", 511 | "$(SDKROOT)/System/Library/PrivateFrameworks", 512 | ); 513 | GCC_PREPROCESSOR_DEFINITIONS = ( 514 | "DEBUG=1", 515 | "$(inherited)", 516 | ); 517 | INFOPLIST_FILE = hookTarget/Info.plist; 518 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 519 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 520 | PRODUCT_NAME = "$(TARGET_NAME)"; 521 | }; 522 | name = Debug; 523 | }; 524 | 8EF9C5CD1B1D66D50027000C /* Release */ = { 525 | isa = XCBuildConfiguration; 526 | buildSettings = { 527 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 528 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 529 | ENTITLEMENTS_REQUIRED = NO; 530 | FRAMEWORK_SEARCH_PATHS = ( 531 | "$(inherited)", 532 | "$(PROJECT_DIR)", 533 | "$(SDKROOT)/System/Library/PrivateFrameworks", 534 | ); 535 | INFOPLIST_FILE = hookTarget/Info.plist; 536 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 537 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 538 | ONLY_ACTIVE_ARCH = YES; 539 | PRODUCT_NAME = "$(TARGET_NAME)"; 540 | }; 541 | name = Release; 542 | }; 543 | FAD725D11B1D08230032E880 /* Debug */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | DEBUGGING_SYMBOLS = YES; 547 | DEBUG_INFORMATION_FORMAT = dwarf; 548 | GCC_GENERATE_DEBUGGING_SYMBOLS = YES; 549 | GCC_OPTIMIZATION_LEVEL = 0; 550 | GCC_PREPROCESSOR_DEFINITIONS = ( 551 | "DEBUG=1", 552 | "$(inherited)", 553 | ); 554 | MACOSX_DEPLOYMENT_TARGET = 10.10; 555 | OTHER_CFLAGS = ""; 556 | OTHER_LDFLAGS = ""; 557 | PRODUCT_NAME = "$(TARGET_NAME)"; 558 | SDKROOT = macosx; 559 | }; 560 | name = Debug; 561 | }; 562 | FAD725D21B1D08230032E880 /* Release */ = { 563 | isa = XCBuildConfiguration; 564 | buildSettings = { 565 | MACOSX_DEPLOYMENT_TARGET = 10.10; 566 | OTHER_CFLAGS = ""; 567 | OTHER_LDFLAGS = ""; 568 | PRODUCT_NAME = "$(TARGET_NAME)"; 569 | SDKROOT = macosx; 570 | }; 571 | name = Release; 572 | }; 573 | /* End XCBuildConfiguration section */ 574 | 575 | /* Begin XCConfigurationList section */ 576 | 8E63FD391AF038A500B2E569 /* Build configuration list for PBXProject "Safari Inline Videos" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | 8E63FD531AF038A600B2E569 /* Debug */, 580 | 8E63FD541AF038A600B2E569 /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | defaultConfigurationName = Release; 584 | }; 585 | 8E63FD551AF038A600B2E569 /* Build configuration list for PBXNativeTarget "Tweak" */ = { 586 | isa = XCConfigurationList; 587 | buildConfigurations = ( 588 | 8E63FD561AF038A600B2E569 /* Debug */, 589 | 8E63FD571AF038A600B2E569 /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | 8EF9C5D01B1D66D50027000C /* Build configuration list for PBXNativeTarget "hookTarget" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | 8EF9C5CC1B1D66D50027000C /* Debug */, 598 | 8EF9C5CD1B1D66D50027000C /* Release */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | FAD725D01B1D08230032E880 /* Build configuration list for PBXLegacyTarget "Install Tweak" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | FAD725D11B1D08230032E880 /* Debug */, 607 | FAD725D21B1D08230032E880 /* Release */, 608 | ); 609 | defaultConfigurationIsVisible = 0; 610 | defaultConfigurationName = Release; 611 | }; 612 | /* End XCConfigurationList section */ 613 | }; 614 | rootObject = 8E63FD361AF038A500B2E569 /* Project object */; 615 | } 616 | -------------------------------------------------------------------------------- /Safari Inline Videos.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /build.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/ruby 2 | 3 | # configure with your device's IP 4 | # make sure you can SSH in without a password 5 | # use this tutorial: http://www.priyaontech.com/2012/01/ssh-into-your-jailbroken-idevice-without-a-password/ 6 | deviceIP = "192.168.1.153" 7 | tweakName = "Safari Inline Videos" 8 | 9 | require 'fileutils' 10 | 11 | # check for dpkg-deb 12 | # add path to homebrew directory 13 | # in case our enviroment variables aren't set correctly 14 | ENV['PATH'] = ENV['PATH'] ? ENV['PATH'] + ':/usr/local/bin/' : "/usr/local/bin/" 15 | 16 | # taken from http://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby 17 | def which(cmd) 18 | exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] 19 | ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| 20 | exts.each { |ext| 21 | exe = File.join(path, "#{cmd}#{ext}") 22 | return exe if File.executable?(exe) && !File.directory?(exe) 23 | } 24 | end 25 | return nil 26 | end 27 | 28 | # taken from http://stackoverflow.com/questions/1939333/how-to-make-a-ruby-string-safe-for-a-filesystem 29 | def sanitizeFilename(filename) 30 | # Split the name when finding a period which is preceded by some 31 | # character, and is followed by some character other than a period, 32 | # if there is no following period that is followed by something 33 | # other than a period (yeah, confusing, I know) 34 | fn = filename.split /(?<=.)\.(?=[^.])(?!.*\.[^.])/m 35 | 36 | # We now have one or two parts (depending on whether we could find 37 | # a suitable period). For each of these parts, replace any unwanted 38 | # sequence of characters with an underscore 39 | fn.map! { |s| s.gsub /[^a-z0-9\-]+/i, '_' } 40 | 41 | # Finally, join the parts with a period and return the result 42 | return fn.join '.' 43 | end 44 | 45 | # install dpkg as necessary 46 | 47 | if which("dpkg-deb") == nil 48 | puts "dpkg not detected, install? y/n" 49 | response = gets.chomp 50 | 51 | if response[0] == "y" 52 | if which("brew") == nil 53 | puts "installing prerequisite: homebrew package manager" 54 | system "ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\"" 55 | end 56 | 57 | puts "installing dpkg with homebrew" 58 | system "brew install dpkg" 59 | 60 | elsif response[0] == "n" 61 | puts "install refused: cannot continue with build" 62 | exit; 63 | else 64 | puts "Expected y or n, received: "+response 65 | puts "cannot continue with build" 66 | end 67 | end 68 | 69 | Dir.chdir(File.dirname(__FILE__)) do 70 | # build project 71 | target = "Tweak" 72 | system "xcodebuild", "-target", target, "-configuration", "Release", "build", "CONFIGURATION_BUILD_DIR=release/product", "OBJROOT=release/build" 73 | 74 | Dir.chdir("./release") do 75 | # clear folder 76 | if File.exists?('./_') == true 77 | FileUtils.rm_r("./_") 78 | end 79 | 80 | FileUtils.mkdir_p("./_/Library/Monolith/Plugins/") 81 | 82 | # make tweak name filesystem safe 83 | tweakNameFilesystem = sanitizeFilename(tweakName) 84 | 85 | FileUtils.copy_file(src="./product/Tweak.framework/Tweak", dst="./_/Library/Monolith/Plugins/#{tweakNameFilesystem}.dylib") 86 | 87 | # copy over control file 88 | FileUtils.mkdir_p("./_/DEBIAN/") 89 | FileUtils.copy_file(src="../DEBIAN/control", dst="./_/DEBIAN/control") 90 | 91 | # remove .DS_Store files 92 | system "find ./_/ -name '*.DS_Store' -type f -delete" 93 | 94 | filename = "#{tweakNameFilesystem}.deb" 95 | system "dpkg-deb", "-b", "-Zgzip", "_", filename 96 | 97 | # transfer deb 98 | system "scp -P 22 #{filename} root@#{deviceIP}:#{filename}" 99 | 100 | # install deb 101 | system "ssh -p 22 root@#{deviceIP} \"dpkg -i #{filename}\"" 102 | 103 | # kill the app we're testing 104 | system "ssh -p 22 root@#{deviceIP} \"killall MobileSafari\"" 105 | 106 | end 107 | end -------------------------------------------------------------------------------- /hookTarget/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // hookTarget 4 | // 5 | // Created by John Coates on 6/1/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /hookTarget/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // hookTarget 4 | // 5 | // Created by John Coates on 6/1/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /hookTarget/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /hookTarget/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /hookTarget/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /hookTarget/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.johncoates.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /hookTarget/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // hookTarget 4 | // 5 | // Created by John Coates on 6/1/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /hookTarget/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // hookTarget 4 | // 5 | // Created by John Coates on 6/1/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import 11 | @interface MONOperative : NSObject 12 | + (BOOL)logAllMethodsForClass:(Class)class; 13 | + (BOOL)logAllMethodsForImage:(NSString *)imageName; 14 | @end 15 | 16 | @interface ViewController () 17 | 18 | @end 19 | 20 | @implementation ViewController 21 | 22 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 23 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 24 | 25 | if (self) { 26 | } 27 | 28 | return self; 29 | } 30 | 31 | - (void)viewDidLoad { 32 | [UIView setAnimationsEnabled:FALSE]; 33 | 34 | [super viewDidLoad]; 35 | 36 | // WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame]; 37 | UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame]; 38 | [self.view addSubview:webView]; 39 | 40 | [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://i.imgur.com/OZz4qTS.gifv"]]]; 41 | 42 | } 43 | 44 | - (void)didReceiveMemoryWarning { 45 | [super didReceiveMemoryWarning]; 46 | // Dispose of any resources that can be recreated. 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /hookTarget/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // hookTarget 4 | // 5 | // Created by John Coates on 6/1/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /hookTargetTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.johncoates.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /hookTargetTests/hookTargetTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // hookTargetTests.m 3 | // hookTargetTests 4 | // 5 | // Created by John Coates on 6/1/15. 6 | // Copyright (c) 2015 John Coates. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface hookTargetTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation hookTargetTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JohnCoatesOSS/SafariInlineVideos/ce80ab61d4411a403806e8388f29c4081b2b9805/screenshot.png --------------------------------------------------------------------------------