FLEXShortcutsFactory+Defaults.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //
  2. // FLEXShortcutsFactory+Defaults.m
  3. // FLEX
  4. //
  5. // Created by Tanner Bennett on 8/29/19.
  6. // Copyright © 2019 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXShortcutsFactory+Defaults.h"
  9. #import "FLEXShortcut.h"
  10. #import "FLEXRuntimeUtility.h"
  11. #import "NSObject+Reflection.h"
  12. #pragma mark - Views
  13. @implementation FLEXShortcutsFactory (Views)
  14. + (void)load { FLEX_EXIT_IF_TESTING()
  15. // A quirk of UIView and some other classes: a lot of the `@property`s are
  16. // not actually properties from the perspective of the runtime.
  17. //
  18. // We add these properties to the class at runtime if they haven't been added yet.
  19. // This way, we can use our property editor to access and change them.
  20. // The property attributes match the declared attributes in their headers.
  21. // UIView, public
  22. Class UIView_ = UIView.class;
  23. FLEXRuntimeUtilityTryAddNonatomicProperty(2, frame, UIView_, CGRect);
  24. FLEXRuntimeUtilityTryAddNonatomicProperty(2, alpha, UIView_, CGFloat);
  25. FLEXRuntimeUtilityTryAddNonatomicProperty(2, clipsToBounds, UIView_, BOOL);
  26. FLEXRuntimeUtilityTryAddNonatomicProperty(2, opaque, UIView_, BOOL, PropertyKeyGetter(isOpaque));
  27. FLEXRuntimeUtilityTryAddNonatomicProperty(2, hidden, UIView_, BOOL, PropertyKeyGetter(isHidden));
  28. FLEXRuntimeUtilityTryAddObjectProperty(2, backgroundColor, UIView_, UIColor, PropertyKey(Copy));
  29. FLEXRuntimeUtilityTryAddObjectProperty(6, constraints, UIView_, NSArray, PropertyKey(ReadOnly));
  30. FLEXRuntimeUtilityTryAddObjectProperty(2, subviews, UIView_, NSArray, PropertyKey(ReadOnly));
  31. FLEXRuntimeUtilityTryAddObjectProperty(2, superview, UIView_, UIView, PropertyKey(ReadOnly));
  32. // UIButton, private
  33. FLEXRuntimeUtilityTryAddObjectProperty(2, font, UIButton.class, UIFont, PropertyKey(ReadOnly));
  34. // Only available since iOS 3.2, but we never supported iOS 3, so who cares
  35. NSArray *ivars = @[@"_gestureRecognizers"];
  36. NSArray *methods = @[@"sizeToFit", @"setNeedsLayout", @"removeFromSuperview"];
  37. // UIView
  38. self.append.ivars(ivars).methods(methods).properties(@[
  39. @"frame", @"bounds", @"center", @"transform",
  40. @"backgroundColor", @"alpha", @"opaque", @"hidden",
  41. @"clipsToBounds", @"userInteractionEnabled", @"layer",
  42. @"superview", @"subviews"
  43. ]).forClass(UIView.class);
  44. // UILabel
  45. self.append.ivars(ivars).methods(methods).properties(@[
  46. @"text", @"attributedText", @"font", @"frame",
  47. @"textColor", @"textAlignment", @"numberOfLines",
  48. @"lineBreakMode", @"enabled", @"backgroundColor",
  49. @"alpha", @"hidden", @"preferredMaxLayoutWidth",
  50. @"superview", @"subviews"
  51. ]).forClass(UILabel.class);
  52. // UIWindow
  53. self.append.ivars(ivars).properties(@[
  54. @"rootViewController", @"windowLevel", @"keyWindow",
  55. @"frame", @"bounds", @"center", @"transform",
  56. @"backgroundColor", @"alpha", @"opaque", @"hidden",
  57. @"clipsToBounds", @"userInteractionEnabled", @"layer",
  58. @"subviews"
  59. ]).forClass(UIWindow.class);
  60. if (@available(iOS 13, *)) {
  61. self.append.properties(@[@"windowScene"]).forClass(UIWindow.class);
  62. }
  63. ivars = @[@"_targetActions", @"_gestureRecognizers"];
  64. // UIControl
  65. self.append.ivars(ivars).methods(methods).properties(@[
  66. @"enabled", @"allTargets", @"frame",
  67. @"backgroundColor", @"hidden", @"clipsToBounds",
  68. @"userInteractionEnabled", @"superview", @"subviews"
  69. ]).forClass(UIControl.class);
  70. // UIButton
  71. self.append.ivars(ivars).properties(@[
  72. @"titleLabel", @"font", @"imageView", @"tintColor",
  73. @"currentTitle", @"currentImage", @"enabled", @"frame",
  74. @"superview", @"subviews"
  75. ]).forClass(UIButton.class);
  76. }
  77. @end
  78. #pragma mark - View Controllers
  79. @implementation FLEXShortcutsFactory (ViewControllers)
  80. + (void)load { FLEX_EXIT_IF_TESTING()
  81. // toolbarItems is not really a property, make it one
  82. FLEXRuntimeUtilityTryAddObjectProperty(3, toolbarItems, UIViewController.class, NSArray);
  83. // UIViewController
  84. self.append
  85. .properties(@[
  86. @"viewIfLoaded", @"title", @"navigationItem", @"toolbarItems", @"tabBarItem",
  87. @"childViewControllers", @"navigationController", @"tabBarController", @"splitViewController",
  88. @"parentViewController", @"presentedViewController", @"presentingViewController",
  89. ]).methods(@[@"view"]).forClass(UIViewController.class);
  90. }
  91. @end
  92. #pragma mark - UIImage
  93. @implementation FLEXShortcutsFactory (UIImage)
  94. + (void)load { FLEX_EXIT_IF_TESTING()
  95. self.append.methods(@[
  96. @"CGImage", @"CIImage"
  97. ]).properties(@[
  98. @"scale", @"size", @"capInsets",
  99. @"alignmentRectInsets", @"duration", @"images"
  100. ]).forClass(UIImage.class);
  101. if (@available(iOS 13, *)) {
  102. self.append.properties(@[@"symbolImage"]);
  103. }
  104. }
  105. @end
  106. #pragma mark - NSBundle
  107. @implementation FLEXShortcutsFactory (NSBundle)
  108. + (void)load { FLEX_EXIT_IF_TESTING()
  109. self.append.properties(@[
  110. @"bundleIdentifier", @"principalClass",
  111. @"infoDictionary", @"bundlePath",
  112. @"executablePath", @"loaded"
  113. ]).forClass(NSBundle.class);
  114. }
  115. @end
  116. #pragma mark - Classes
  117. @implementation FLEXShortcutsFactory (Classes)
  118. + (void)load { FLEX_EXIT_IF_TESTING()
  119. self.append.methods(@[@"new", @"alloc"]).forClass(objc_getMetaClass("NSObject"));
  120. }
  121. @end
  122. #pragma mark - Activities
  123. @implementation FLEXShortcutsFactory (Activities)
  124. + (void)load { FLEX_EXIT_IF_TESTING()
  125. self.append.properties(@[
  126. @"item", @"placeholderItem", @"activityType"
  127. ]).forClass(UIActivityItemProvider.class);
  128. self.append.properties(@[
  129. @"activityItems", @"applicationActivities", @"excludedActivityTypes", @"completionHandler"
  130. ]).forClass(UIActivityViewController.class);
  131. }
  132. @end
  133. #pragma mark - Activities
  134. @implementation FLEXShortcutsFactory (Blocks)
  135. + (void)load { FLEX_EXIT_IF_TESTING()
  136. self.append.methods(@[@"invoke"]).forClass(NSClassFromString(@"NSBlock"));
  137. }
  138. @end