FLEXShortcutsFactory+Defaults.m 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. //
  2. // FLEXShortcutsFactory+Defaults.m
  3. // FLEX
  4. //
  5. // Created by Tanner Bennett on 8/29/19.
  6. // Copyright © 2020 FLEX Team. All rights reserved.
  7. //
  8. #import "FLEXShortcutsFactory+Defaults.h"
  9. #import "FLEXShortcut.h"
  10. #import "FLEXRuntimeUtility.h"
  11. #import "NSObject+FLEX_Reflection.h"
  12. #pragma mark - UIApplication
  13. @implementation FLEXShortcutsFactory (UIApplication)
  14. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  15. // sharedApplication class property possibly not added
  16. // as a literal class property until iOS 10
  17. FLEXRuntimeUtilityTryAddObjectProperty(
  18. 2, sharedApplication, UIApplication.flex_metaclass, UIApplication, PropertyKey(ReadOnly)
  19. );
  20. self.append.classProperties(@[@"sharedApplication"]).forClass(UIApplication.flex_metaclass);
  21. self.append.properties(@[
  22. @"delegate", @"keyWindow", @"windows"
  23. ]).forClass(UIApplication.class);
  24. if (@available(iOS 13, *)) {
  25. self.append.properties(@[
  26. @"connectedScenes", @"openSessions", @"supportsMultipleScenes"
  27. ]).forClass(UIApplication.class);
  28. }
  29. }
  30. @end
  31. #pragma mark - Views
  32. @implementation FLEXShortcutsFactory (Views)
  33. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  34. // A quirk of UIView and some other classes: a lot of the `@property`s are
  35. // not actually properties from the perspective of the runtime.
  36. //
  37. // We add these properties to the class at runtime if they haven't been added yet.
  38. // This way, we can use our property editor to access and change them.
  39. // The property attributes match the declared attributes in their headers.
  40. // UIView, public
  41. Class UIView_ = UIView.class;
  42. FLEXRuntimeUtilityTryAddNonatomicProperty(2, frame, UIView_, CGRect);
  43. FLEXRuntimeUtilityTryAddNonatomicProperty(2, alpha, UIView_, CGFloat);
  44. FLEXRuntimeUtilityTryAddNonatomicProperty(2, clipsToBounds, UIView_, BOOL);
  45. FLEXRuntimeUtilityTryAddNonatomicProperty(2, opaque, UIView_, BOOL, PropertyKeyGetter(isOpaque));
  46. FLEXRuntimeUtilityTryAddNonatomicProperty(2, hidden, UIView_, BOOL, PropertyKeyGetter(isHidden));
  47. FLEXRuntimeUtilityTryAddObjectProperty(2, backgroundColor, UIView_, UIColor, PropertyKey(Copy));
  48. FLEXRuntimeUtilityTryAddObjectProperty(6, constraints, UIView_, NSArray, PropertyKey(ReadOnly));
  49. FLEXRuntimeUtilityTryAddObjectProperty(2, subviews, UIView_, NSArray, PropertyKey(ReadOnly));
  50. FLEXRuntimeUtilityTryAddObjectProperty(2, superview, UIView_, UIView, PropertyKey(ReadOnly));
  51. // UIButton, private
  52. FLEXRuntimeUtilityTryAddObjectProperty(2, font, UIButton.class, UIFont, PropertyKey(ReadOnly));
  53. // Only available since iOS 3.2, but we never supported iOS 3, so who cares
  54. NSArray *ivars = @[@"_gestureRecognizers"];
  55. NSArray *methods = @[@"sizeToFit", @"setNeedsLayout", @"removeFromSuperview"];
  56. // UIView
  57. self.append.ivars(ivars).methods(methods).properties(@[
  58. @"frame", @"bounds", @"center", @"transform",
  59. @"backgroundColor", @"alpha", @"opaque", @"hidden",
  60. @"clipsToBounds", @"userInteractionEnabled", @"layer",
  61. @"superview", @"subviews"
  62. ]).forClass(UIView.class);
  63. // UILabel
  64. self.append.ivars(ivars).methods(methods).properties(@[
  65. @"text", @"attributedText", @"font", @"frame",
  66. @"textColor", @"textAlignment", @"numberOfLines",
  67. @"lineBreakMode", @"enabled", @"backgroundColor",
  68. @"alpha", @"hidden", @"preferredMaxLayoutWidth",
  69. @"superview", @"subviews"
  70. ]).forClass(UILabel.class);
  71. // UIWindow
  72. self.append.ivars(ivars).properties(@[
  73. @"rootViewController", @"windowLevel", @"keyWindow",
  74. @"frame", @"bounds", @"center", @"transform",
  75. @"backgroundColor", @"alpha", @"opaque", @"hidden",
  76. @"clipsToBounds", @"userInteractionEnabled", @"layer",
  77. @"subviews"
  78. ]).forClass(UIWindow.class);
  79. if (@available(iOS 13, *)) {
  80. self.append.properties(@[@"windowScene"]).forClass(UIWindow.class);
  81. }
  82. ivars = @[@"_targetActions", @"_gestureRecognizers"];
  83. // Property was added in iOS 10 but we want it on iOS 9 too
  84. FLEXRuntimeUtilityTryAddObjectProperty(9, allTargets, UIControl.class, NSArray, PropertyKey(ReadOnly));
  85. // UIControl
  86. self.append.ivars(ivars).methods(methods).properties(@[
  87. @"enabled", @"allTargets", @"frame",
  88. @"backgroundColor", @"hidden", @"clipsToBounds",
  89. @"userInteractionEnabled", @"superview", @"subviews"
  90. ]).forClass(UIControl.class);
  91. // UIButton
  92. self.append.ivars(ivars).properties(@[
  93. @"titleLabel", @"font", @"imageView", @"tintColor",
  94. @"currentTitle", @"currentImage", @"enabled", @"frame",
  95. @"superview", @"subviews"
  96. ]).forClass(UIButton.class);
  97. // UIImageView
  98. self.append.properties(@[
  99. @"image", @"animationImages", @"frame", @"bounds", @"center",
  100. @"transform", @"alpha", @"hidden", @"clipsToBounds",
  101. @"userInteractionEnabled", @"layer", @"superview", @"subviews",
  102. ]).forClass(UIImageView.class);
  103. }
  104. @end
  105. #pragma mark - View Controllers
  106. @implementation FLEXShortcutsFactory (ViewControllers)
  107. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  108. // toolbarItems is not really a property, make it one
  109. FLEXRuntimeUtilityTryAddObjectProperty(3, toolbarItems, UIViewController.class, NSArray);
  110. // UIViewController
  111. self.append
  112. .properties(@[
  113. @"viewIfLoaded", @"title", @"navigationItem", @"toolbarItems", @"tabBarItem",
  114. @"childViewControllers", @"navigationController", @"tabBarController", @"splitViewController",
  115. @"parentViewController", @"presentedViewController", @"presentingViewController",
  116. ]).methods(@[@"view"]).forClass(UIViewController.class);
  117. }
  118. @end
  119. #pragma mark - UIImage
  120. @implementation FLEXShortcutsFactory (UIImage)
  121. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  122. self.append.methods(@[
  123. @"CGImage", @"CIImage"
  124. ]).properties(@[
  125. @"scale", @"size", @"capInsets",
  126. @"alignmentRectInsets", @"duration", @"images"
  127. ]).forClass(UIImage.class);
  128. if (@available(iOS 13, *)) {
  129. self.append.properties(@[@"symbolImage"]).forClass(UIImage.class);
  130. }
  131. }
  132. @end
  133. #pragma mark - NSBundle
  134. @implementation FLEXShortcutsFactory (NSBundle)
  135. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  136. self.append.properties(@[
  137. @"bundleIdentifier", @"principalClass",
  138. @"infoDictionary", @"bundlePath",
  139. @"executablePath", @"loaded"
  140. ]).forClass(NSBundle.class);
  141. }
  142. @end
  143. #pragma mark - Classes
  144. @implementation FLEXShortcutsFactory (Classes)
  145. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  146. self.append.classMethods(@[@"new", @"alloc"]).forClass(NSObject.flex_metaclass);
  147. }
  148. @end
  149. #pragma mark - Activities
  150. @implementation FLEXShortcutsFactory (Activities)
  151. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  152. #if !TARGET_OS_TV
  153. // Property was added in iOS 10 but we want it on iOS 9 too
  154. FLEXRuntimeUtilityTryAddNonatomicProperty(9, item, UIActivityItemProvider.class, id, PropertyKey(ReadOnly));
  155. self.append.properties(@[
  156. @"item", @"placeholderItem", @"activityType"
  157. ]).forClass(UIActivityItemProvider.class);
  158. self.append.properties(@[
  159. @"activityItems", @"applicationActivities", @"excludedActivityTypes", @"completionHandler"
  160. ]).forClass(UIActivityViewController.class);
  161. #endif
  162. }
  163. @end
  164. #pragma mark - Blocks
  165. @implementation FLEXShortcutsFactory (Blocks)
  166. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  167. self.append.methods(@[@"invoke"]).forClass(NSClassFromString(@"NSBlock"));
  168. }
  169. @end
  170. #pragma mark - Foundation
  171. @implementation FLEXShortcutsFactory (Foundation)
  172. + (void)load { FLEX_EXIT_IF_NO_CTORS()
  173. self.append.properties(@[
  174. @"configuration", @"delegate", @"delegateQueue", @"sessionDescription",
  175. ]).methods(@[
  176. @"dataTaskWithURL:", @"finishTasksAndInvalidate", @"invalidateAndCancel",
  177. ]).forClass(NSURLSession.class);
  178. self.append.methods(@[
  179. @"cachedResponseForRequest:", @"storeCachedResponse:forRequest:",
  180. @"storeCachedResponse:forDataTask:", @"removeCachedResponseForRequest:",
  181. @"removeCachedResponseForDataTask:", @"removeCachedResponsesSinceDate:",
  182. @"removeAllCachedResponses",
  183. ]).forClass(NSURLCache.class);
  184. self.append.methods(@[
  185. @"postNotification:", @"postNotificationName:object:userInfo:",
  186. @"addObserver:selector:name:object:", @"removeObserver:",
  187. @"removeObserver:name:object:",
  188. ]).forClass(NSNotificationCenter.class);
  189. // NSTimeZone class properties aren't real properties
  190. FLEXRuntimeUtilityTryAddObjectProperty(2, localTimeZone, NSTimeZone.flex_metaclass, NSTimeZone);
  191. FLEXRuntimeUtilityTryAddObjectProperty(2, systemTimeZone, NSTimeZone.flex_metaclass, NSTimeZone);
  192. FLEXRuntimeUtilityTryAddObjectProperty(2, defaultTimeZone, NSTimeZone.flex_metaclass, NSTimeZone);
  193. FLEXRuntimeUtilityTryAddObjectProperty(2, knownTimeZoneNames, NSTimeZone.flex_metaclass, NSArray);
  194. FLEXRuntimeUtilityTryAddObjectProperty(2, abbreviationDictionary, NSTimeZone.flex_metaclass, NSDictionary);
  195. self.append.classMethods(@[
  196. @"timeZoneWithName:", @"timeZoneWithAbbreviation:", @"timeZoneForSecondsFromGMT:", @"", @"", @"",
  197. ]).forClass(NSTimeZone.flex_metaclass);
  198. self.append.classProperties(@[
  199. @"defaultTimeZone", @"systemTimeZone", @"localTimeZone"
  200. ]).forClass(NSTimeZone.class);
  201. }
  202. @end