mirror of
				https://github.com/SoPat712/YTLitePlus.git
				synced 2025-10-31 04:44:14 -04:00 
			
		
		
		
	added files via upload
This commit is contained in:
		
							
								
								
									
										250
									
								
								Tweaks/FLEX/GlobalStateExplorers/FLEXObjectListViewController.m
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								Tweaks/FLEX/GlobalStateExplorers/FLEXObjectListViewController.m
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| // | ||||
| //  FLEXObjectListViewController.m | ||||
| //  Flipboard | ||||
| // | ||||
| //  Created by Ryan Olson on 5/28/14. | ||||
| //  Copyright (c) 2020 FLEX Team. All rights reserved. | ||||
| // | ||||
|  | ||||
| #import "FLEXObjectListViewController.h" | ||||
| #import "FLEXObjectExplorerFactory.h" | ||||
| #import "FLEXObjectExplorerViewController.h" | ||||
| #import "FLEXMutableListSection.h" | ||||
| #import "FLEXRuntimeUtility.h" | ||||
| #import "FLEXUtility.h" | ||||
| #import "FLEXHeapEnumerator.h" | ||||
| #import "FLEXObjectRef.h" | ||||
| #import "NSString+FLEX.h" | ||||
| #import "NSObject+FLEX_Reflection.h" | ||||
| #import "FLEXTableViewCell.h" | ||||
| #import <malloc/malloc.h> | ||||
|  | ||||
|  | ||||
| typedef NS_ENUM(NSUInteger, FLEXObjectReferenceSection) { | ||||
|     FLEXObjectReferenceSectionMain, | ||||
|     FLEXObjectReferenceSectionAutoLayout, | ||||
|     FLEXObjectReferenceSectionKVO, | ||||
|     FLEXObjectReferenceSectionFLEX, | ||||
|      | ||||
|     FLEXObjectReferenceSectionCount | ||||
| }; | ||||
|  | ||||
| @interface FLEXObjectListViewController () | ||||
|  | ||||
| @property (nonatomic, readonly, class) NSArray<NSPredicate *> *defaultPredicates; | ||||
| @property (nonatomic, readonly, class) NSArray<NSString *> *defaultSectionTitles; | ||||
|  | ||||
|  | ||||
| @property (nonatomic, copy) NSArray<FLEXMutableListSection *> *sections; | ||||
| @property (nonatomic, copy) NSArray<FLEXMutableListSection *> *allSections; | ||||
|  | ||||
| @property (nonatomic, readonly, nullable) NSArray<FLEXObjectRef *> *references; | ||||
| @property (nonatomic, readonly) NSArray<NSPredicate *> *predicates; | ||||
| @property (nonatomic, readonly) NSArray<NSString *> *sectionTitles; | ||||
|  | ||||
| @end | ||||
|  | ||||
| @implementation FLEXObjectListViewController | ||||
| @dynamic sections, allSections; | ||||
|  | ||||
| #pragma mark - Reference Grouping | ||||
|  | ||||
| + (NSPredicate *)defaultPredicateForSection:(NSInteger)section { | ||||
|     // These are the types of references that we typically don't care about. | ||||
|     // We want this list of "object-ivar pairs" split into two sections. | ||||
|     BOOL(^isKVORelated)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { | ||||
|         NSString *row = ref.reference; | ||||
|         return [row isEqualToString:@"__NSObserver object"] || | ||||
|                [row isEqualToString:@"_CFXNotificationObjcObserverRegistration _object"]; | ||||
|     }; | ||||
|  | ||||
|     /// These are common AutoLayout related references we also rarely care about. | ||||
|     BOOL(^isConstraintRelated)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { | ||||
|         static NSSet *ignored = nil; | ||||
|         static dispatch_once_t onceToken; | ||||
|         dispatch_once(&onceToken, ^{ | ||||
|             ignored = [NSSet setWithArray:@[ | ||||
|                 @"NSLayoutConstraint _container", | ||||
|                 @"NSContentSizeLayoutConstraint _container", | ||||
|                 @"NSAutoresizingMaskLayoutConstraint _container", | ||||
|                 @"MASViewConstraint _installedView", | ||||
|                 @"MASLayoutConstraint _container", | ||||
|                 @"MASViewAttribute _view" | ||||
|             ]]; | ||||
|         }); | ||||
|  | ||||
|         NSString *row = ref.reference; | ||||
|         return ([row hasPrefix:@"NSLayout"] && [row hasSuffix:@" _referenceItem"]) || | ||||
|                ([row hasPrefix:@"NSIS"] && [row hasSuffix:@" _delegate"])  || | ||||
|                ([row hasPrefix:@"_NSAutoresizingMask"] && [row hasSuffix:@" _referenceItem"]) || | ||||
|                [ignored containsObject:row]; | ||||
|     }; | ||||
|      | ||||
|     /// These are FLEX classes and usually you aren't looking for FLEX references inside FLEX itself | ||||
|     BOOL(^isFLEXClass)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { | ||||
|         return [ref.reference hasPrefix:@"FLEX"]; | ||||
|     }; | ||||
|  | ||||
|     BOOL(^isEssential)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { | ||||
|         return !( | ||||
|             isKVORelated(ref, bindings) || | ||||
|             isConstraintRelated(ref, bindings) || | ||||
|             isFLEXClass(ref, bindings) | ||||
|         ); | ||||
|     }; | ||||
|  | ||||
|     switch (section) { | ||||
|         case FLEXObjectReferenceSectionMain: | ||||
|             return [NSPredicate predicateWithBlock:isEssential]; | ||||
|         case FLEXObjectReferenceSectionAutoLayout: | ||||
|             return [NSPredicate predicateWithBlock:isConstraintRelated]; | ||||
|         case FLEXObjectReferenceSectionKVO: | ||||
|             return [NSPredicate predicateWithBlock:isKVORelated]; | ||||
|         case FLEXObjectReferenceSectionFLEX: | ||||
|             return [NSPredicate predicateWithBlock:isFLEXClass]; | ||||
|  | ||||
|         default: return nil; | ||||
|     } | ||||
| } | ||||
|  | ||||
| + (NSArray<NSPredicate *> *)defaultPredicates { | ||||
|     return [NSArray flex_forEachUpTo:FLEXObjectReferenceSectionCount map:^id(NSUInteger i) { | ||||
|         return [self defaultPredicateForSection:i]; | ||||
|     }]; | ||||
| } | ||||
|  | ||||
| + (NSArray<NSString *> *)defaultSectionTitles { | ||||
|     return @[ | ||||
|         @"", @"AutoLayout", @"Key-Value Observing", @"FLEX" | ||||
|     ]; | ||||
| } | ||||
|  | ||||
|  | ||||
| #pragma mark - Initialization | ||||
|  | ||||
| - (id)initWithReferences:(nullable NSArray<FLEXObjectRef *> *)references { | ||||
|     return [self initWithReferences:references predicates:nil sectionTitles:nil]; | ||||
| } | ||||
|  | ||||
| - (id)initWithReferences:(NSArray<FLEXObjectRef *> *)references | ||||
|               predicates:(NSArray<NSPredicate *> *)predicates | ||||
|            sectionTitles:(NSArray<NSString *> *)sectionTitles { | ||||
|     NSParameterAssert(predicates.count == sectionTitles.count); | ||||
|  | ||||
|     self = [super initWithStyle:UITableViewStylePlain]; | ||||
|     if (self) { | ||||
|         _references = references; | ||||
|         _predicates = predicates; | ||||
|         _sectionTitles = sectionTitles; | ||||
|     } | ||||
|  | ||||
|     return self; | ||||
| } | ||||
|  | ||||
| + (UIViewController *)instancesOfClassWithName:(NSString *)className retained:(BOOL)retain { | ||||
|     NSArray<FLEXObjectRef *> *references = [FLEXHeapEnumerator | ||||
|         instancesOfClassWithName:className retained:retain | ||||
|     ]; | ||||
|      | ||||
|     if (references.count == 1) { | ||||
|         return [FLEXObjectExplorerFactory | ||||
|             explorerViewControllerForObject:references.firstObject.object | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     FLEXObjectListViewController *controller = [[self alloc] initWithReferences:references]; | ||||
|     controller.title = [NSString stringWithFormat:@"%@ (%@)", className, @(references.count)]; | ||||
|     return controller; | ||||
| } | ||||
|  | ||||
| + (instancetype)subclassesOfClassWithName:(NSString *)className { | ||||
|     NSArray<FLEXObjectRef *> *references = [FLEXHeapEnumerator subclassesOfClassWithName:className]; | ||||
|     FLEXObjectListViewController *controller = [[self alloc] initWithReferences:references]; | ||||
|     controller.title = [NSString stringWithFormat:@"Subclasses of %@ (%@)", | ||||
|         className, @(references.count) | ||||
|     ]; | ||||
|  | ||||
|     return controller; | ||||
| } | ||||
|  | ||||
| + (instancetype)objectsWithReferencesToObject:(id)object retained:(BOOL)retain { | ||||
|     static Class SwiftObjectClass = nil; | ||||
|     static dispatch_once_t onceToken; | ||||
|     dispatch_once(&onceToken, ^{ | ||||
|         SwiftObjectClass = NSClassFromString(@"SwiftObject"); | ||||
|         if (!SwiftObjectClass) { | ||||
|             SwiftObjectClass = NSClassFromString(@"Swift._SwiftObject"); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     NSArray<FLEXObjectRef *> *instances = [FLEXHeapEnumerator | ||||
|         objectsWithReferencesToObject:object retained:retain | ||||
|     ]; | ||||
|  | ||||
|     FLEXObjectListViewController *viewController = [[self alloc] | ||||
|         initWithReferences:instances | ||||
|         predicates:self.defaultPredicates | ||||
|         sectionTitles:self.defaultSectionTitles | ||||
|     ]; | ||||
|     viewController.title = [NSString stringWithFormat:@"Referencing %@ %p", | ||||
|         [FLEXRuntimeUtility safeClassNameForObject:object], object | ||||
|     ]; | ||||
|     return viewController; | ||||
| } | ||||
|  | ||||
|  | ||||
| #pragma mark - Overrides | ||||
|  | ||||
| - (void)viewDidLoad { | ||||
|     [super viewDidLoad]; | ||||
|  | ||||
|     self.showsSearchBar = YES; | ||||
| } | ||||
|  | ||||
| - (NSArray<FLEXMutableListSection *> *)makeSections { | ||||
|     if (self.predicates.count) { | ||||
|         return [self buildSections:self.sectionTitles predicates:self.predicates]; | ||||
|     } else { | ||||
|         return @[[self makeSection:self.references title:nil]]; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| #pragma mark - Private | ||||
|  | ||||
| - (NSArray *)buildSections:(NSArray<NSString *> *)titles predicates:(NSArray<NSPredicate *> *)predicates { | ||||
|     NSParameterAssert(titles.count == predicates.count); | ||||
|     NSParameterAssert(titles); NSParameterAssert(predicates); | ||||
|  | ||||
|     return [NSArray flex_forEachUpTo:titles.count map:^id(NSUInteger i) { | ||||
|         NSArray *rows = [self.references filteredArrayUsingPredicate:predicates[i]]; | ||||
|         return [self makeSection:rows title:titles[i]]; | ||||
|     }]; | ||||
| } | ||||
|  | ||||
| - (FLEXMutableListSection *)makeSection:(NSArray *)rows title:(NSString *)title { | ||||
|     FLEXMutableListSection *section = [FLEXMutableListSection list:rows | ||||
|         cellConfiguration:^(FLEXTableViewCell *cell, FLEXObjectRef *ref, NSInteger row) { | ||||
|             cell.textLabel.text = ref.reference; | ||||
|             cell.detailTextLabel.text = ref.summary; | ||||
|             cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; | ||||
|         } filterMatcher:^BOOL(NSString *filterText, FLEXObjectRef *ref) { | ||||
|             if (ref.summary && [ref.summary localizedCaseInsensitiveContainsString:filterText]) { | ||||
|                 return YES; | ||||
|             } | ||||
|  | ||||
|             return [ref.reference localizedCaseInsensitiveContainsString:filterText]; | ||||
|         } | ||||
|     ]; | ||||
|  | ||||
|     section.selectionHandler = ^(UIViewController *host, FLEXObjectRef *ref) { | ||||
|         [host.navigationController pushViewController:[ | ||||
|             FLEXObjectExplorerFactory explorerViewControllerForObject:ref.object | ||||
|         ] animated:YES]; | ||||
|     }; | ||||
|  | ||||
|     section.customTitle = title; | ||||
|     return section; | ||||
| } | ||||
|  | ||||
| @end | ||||
		Reference in New Issue
	
	Block a user
	 Balackburn
					Balackburn