From 684eeca7472991e46451773413c0a446bc1abd18 Mon Sep 17 00:00:00 2001 From: Mahmoud abdelahab Date: Wed, 10 Sep 2025 09:39:41 +0400 Subject: [PATCH 1/3] Add RTL fixes for Arabic support in FLEX - Force LTR layout for FLEXNetworkTransactionCell - Add LTR semantic content attributes to all labels and views - Apply RTL fixes to FLEXTableViewController base class - Force LTR layout for FLEXExplorerViewController interface --- .../Controllers/FLEXTableViewController.m | 6 ++++++ .../FLEXExplorerViewController.m | 8 +++++++ Classes/Network/FLEXNetworkTransactionCell.m | 21 +++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/Classes/Core/Controllers/FLEXTableViewController.m b/Classes/Core/Controllers/FLEXTableViewController.m index 79ef6f44cf..2c574c7024 100644 --- a/Classes/Core/Controllers/FLEXTableViewController.m +++ b/Classes/Core/Controllers/FLEXTableViewController.m @@ -232,6 +232,12 @@ - (void)loadView { - (void)viewDidLoad { [super viewDidLoad]; + // Force LTR layout for all FLEX table views + if (@available(iOS 9.0, *)) { + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.tableView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } + self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; // Toolbar diff --git a/Classes/ExplorerInterface/FLEXExplorerViewController.m b/Classes/ExplorerInterface/FLEXExplorerViewController.m index 9b4964dd43..cf6d832310 100644 --- a/Classes/ExplorerInterface/FLEXExplorerViewController.m +++ b/Classes/ExplorerInterface/FLEXExplorerViewController.m @@ -94,8 +94,16 @@ - (void)dealloc { - (void)viewDidLoad { [super viewDidLoad]; + // Force LTR layout for FLEX explorer interface + if (@available(iOS 9.0, *)) { + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } + // Toolbar _explorerToolbar = [FLEXExplorerToolbar new]; + if (@available(iOS 9.0, *)) { + _explorerToolbar.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } // Start the toolbar off below any bars that may be at the top of the view. CGFloat toolbarOriginY = NSUserDefaults.standardUserDefaults.flex_toolbarTopMargin; diff --git a/Classes/Network/FLEXNetworkTransactionCell.m b/Classes/Network/FLEXNetworkTransactionCell.m index 8a0724d05d..50a69f39af 100644 --- a/Classes/Network/FLEXNetworkTransactionCell.m +++ b/Classes/Network/FLEXNetworkTransactionCell.m @@ -29,26 +29,47 @@ - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSStr self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + // Force LTR layout for FLEX network cells + if (@available(iOS 9.0, *)) { + self.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.contentView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } self.nameLabel = [UILabel new]; self.nameLabel.font = UIFont.flex_defaultTableCellFont; + self.nameLabel.textAlignment = NSTextAlignmentLeft; + if (@available(iOS 9.0, *)) { + self.nameLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } [self.contentView addSubview:self.nameLabel]; self.pathLabel = [UILabel new]; self.pathLabel.font = UIFont.flex_defaultTableCellFont; self.pathLabel.textColor = [UIColor colorWithWhite:0.4 alpha:1.0]; self.pathLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + self.pathLabel.textAlignment = NSTextAlignmentLeft; + if (@available(iOS 9.0, *)) { + self.pathLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } [self.contentView addSubview:self.pathLabel]; self.thumbnailImageView = [UIImageView new]; self.thumbnailImageView.layer.borderColor = UIColor.blackColor.CGColor; self.thumbnailImageView.layer.borderWidth = 1.0; self.thumbnailImageView.contentMode = UIViewContentModeScaleAspectFit; + if (@available(iOS 9.0, *)) { + self.thumbnailImageView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } [self.contentView addSubview:self.thumbnailImageView]; self.transactionDetailsLabel = [UILabel new]; self.transactionDetailsLabel.font = [UIFont systemFontOfSize:10.0]; self.transactionDetailsLabel.textColor = [UIColor colorWithWhite:0.65 alpha:1.0]; + self.transactionDetailsLabel.textAlignment = NSTextAlignmentLeft; + if (@available(iOS 9.0, *)) { + self.transactionDetailsLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } [self.contentView addSubview:self.transactionDetailsLabel]; } return self; From b266125dd8092719722e9e43f4f2e8ada05ef44e Mon Sep 17 00:00:00 2001 From: Mahmoud abdelwahab Date: Thu, 11 Sep 2025 19:46:57 +0400 Subject: [PATCH 2/3] force LTR semantic --- .../Controllers/FLEXNavigationController.m | 18 ++++++++++++++++++ Classes/Core/Views/Cells/FLEXTableViewCell.m | 6 ++++++ Classes/ExplorerInterface/FLEXWindow.m | 5 +++++ .../FLEXLiveObjectsController.m | 3 ++- .../Globals/FLEXGlobalsSection.m | 9 +++++++++ .../Globals/FLEXGlobalsViewController.m | 6 ++++++ .../FLEXHTTPTransactionDetailController.m | 10 ++++++++++ .../Network/FLEXNetworkMITMViewController.m | 5 +++++ .../Network/FLEXNetworkSettingsController.m | 10 ++++++++++ Classes/Network/FLEXNetworkTransaction.m | 6 +++++- 10 files changed, 76 insertions(+), 2 deletions(-) diff --git a/Classes/Core/Controllers/FLEXNavigationController.m b/Classes/Core/Controllers/FLEXNavigationController.m index ec695e8bac..fff7404762 100644 --- a/Classes/Core/Controllers/FLEXNavigationController.m +++ b/Classes/Core/Controllers/FLEXNavigationController.m @@ -36,6 +36,24 @@ + (instancetype)withRootViewController:(UIViewController *)rootVC { - (void)viewDidLoad { [super viewDidLoad]; + // Force LTR layout for FLEX interface + if (@available(iOS 9.0, *)) { + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationBar.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } + + // Set navigation bar title text color to ensure visibility + if (@available(iOS 13.0, *)) { + UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; + [appearance configureWithDefaultBackground]; + appearance.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor labelColor]}; + appearance.largeTitleTextAttributes = @{NSForegroundColorAttributeName: [UIColor labelColor]}; + self.navigationBar.standardAppearance = appearance; + self.navigationBar.scrollEdgeAppearance = appearance; + } else { + self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor blackColor]}; + } + self.waitingToAddTab = YES; // Add gesture to reveal toolbar if hidden diff --git a/Classes/Core/Views/Cells/FLEXTableViewCell.m b/Classes/Core/Views/Cells/FLEXTableViewCell.m index ceb4752e29..aa89fa2539 100644 --- a/Classes/Core/Views/Cells/FLEXTableViewCell.m +++ b/Classes/Core/Views/Cells/FLEXTableViewCell.m @@ -44,6 +44,12 @@ - (void)postInit { self.titleLabel.numberOfLines = 1; self.subtitleLabel.numberOfLines = 1; + + // Force LTR layout for all FLEX table view cells + self.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.contentView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.titleLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.subtitleLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; } - (UILabel *)titleLabel { diff --git a/Classes/ExplorerInterface/FLEXWindow.m b/Classes/ExplorerInterface/FLEXWindow.m index 41cd5d08c9..cac2271306 100644 --- a/Classes/ExplorerInterface/FLEXWindow.m +++ b/Classes/ExplorerInterface/FLEXWindow.m @@ -19,6 +19,11 @@ - (id)initWithFrame:(CGRect)frame { // If we make the window level too high, we block out UIAlertViews. // There's a balance between staying above the app's windows and staying below alerts. self.windowLevel = UIWindowLevelAlert - 1; + + // Force LTR layout for FLEX window + if (@available(iOS 9.0, *)) { + self.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } } return self; } diff --git a/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m b/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m index fce0f8c6e4..2a14b73fff 100644 --- a/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m +++ b/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m @@ -38,7 +38,8 @@ - (void)viewDidLoad { self.activatesSearchBarAutomatically = YES; self.searchBarDebounceInterval = kFLEXDebounceInstant; self.showsCarousel = YES; - self.carousel.items = @[@"A→Z", @"Count", @"Size"]; + // Use RTL-aware arrow that flips direction in Arabic/RTL layouts + self.carousel.items = @[@"A\u2192Z", @"Count", @"Size"]; self.refreshControl = [UIRefreshControl new]; [self.refreshControl addTarget:self action:@selector(refreshControlDidRefresh:) forControlEvents:UIControlEventValueChanged]; diff --git a/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m b/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m index abb97ea2b4..c76db8bb4f 100644 --- a/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m +++ b/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m @@ -72,6 +72,15 @@ - (void)configureCell:(__kindof UITableViewCell *)cell forRow:(NSInteger)row { cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.textLabel.font = UIFont.flex_defaultTableCellFont; cell.textLabel.text = self.rows[row].entryNameFuture(); + + // Force LTR layout for FLEX table view cells + if (@available(iOS 9.0, *)) { + cell.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + cell.contentView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + if (cell.textLabel) { + cell.textLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } + } } @end diff --git a/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m b/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m index 569b5633df..3b9e2b1b6f 100644 --- a/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m +++ b/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m @@ -166,6 +166,12 @@ + (FLEXGlobalsEntry *)globalsEntryForRow:(FLEXGlobalsRow)row { - (void)viewDidLoad { [super viewDidLoad]; + + // Force LTR layout for FLEX globals menu + if (@available(iOS 9.0, *)) { + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.tableView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + } self.title = @"💪 FLEX"; self.showsSearchBar = YES; diff --git a/Classes/Network/FLEXHTTPTransactionDetailController.m b/Classes/Network/FLEXHTTPTransactionDetailController.m index adb71f470b..a21a0376f2 100644 --- a/Classes/Network/FLEXHTTPTransactionDetailController.m +++ b/Classes/Network/FLEXHTTPTransactionDetailController.m @@ -61,6 +61,11 @@ - (instancetype)initWithStyle:(UITableViewStyle)style { - (void)viewDidLoad { [super viewDidLoad]; + + // Force LTR layout for network transaction detail screen + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.tableView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationController.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(handleTransactionUpdatedNotification:) @@ -156,6 +161,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.textLabel.attributedText = [[self class] attributedTextForRow:rowModel]; cell.accessoryType = rowModel.selectionFuture ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; cell.selectionStyle = rowModel.selectionFuture ? UITableViewCellSelectionStyleDefault : UITableViewCellSelectionStyleNone; + + // Force LTR layout for network detail cells + cell.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + cell.contentView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + cell.textLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; return cell; } diff --git a/Classes/Network/FLEXNetworkMITMViewController.m b/Classes/Network/FLEXNetworkMITMViewController.m index 54314b879d..97678e1ee5 100644 --- a/Classes/Network/FLEXNetworkMITMViewController.m +++ b/Classes/Network/FLEXNetworkMITMViewController.m @@ -56,6 +56,11 @@ - (id)init { - (void)viewDidLoad { [super viewDidLoad]; + + // Force LTR layout for network history screen + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.tableView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationController.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; self.showsSearchBar = YES; self.pinSearchBar = YES; diff --git a/Classes/Network/FLEXNetworkSettingsController.m b/Classes/Network/FLEXNetworkSettingsController.m index 4d57ea9391..de29a871e9 100644 --- a/Classes/Network/FLEXNetworkSettingsController.m +++ b/Classes/Network/FLEXNetworkSettingsController.m @@ -31,6 +31,11 @@ @implementation FLEXNetworkSettingsController - (void)viewDidLoad { [super viewDidLoad]; + // Force LTR layout for network settings screen + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.tableView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationController.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + [self disableToolbar]; self.hostDenylist = FLEXNetworkRecorder.defaultRecorder.hostDenylist.mutableCopy; @@ -145,6 +150,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell.accessoryView = nil; cell.textLabel.textColor = FLEXColor.primaryTextColor; + // Force LTR layout for network settings cells + cell.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + cell.contentView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + cell.textLabel.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + switch (indexPath.section) { // Settings case 0: { diff --git a/Classes/Network/FLEXNetworkTransaction.m b/Classes/Network/FLEXNetworkTransaction.m index 7eaf08de46..46baa4a362 100644 --- a/Classes/Network/FLEXNetworkTransaction.m +++ b/Classes/Network/FLEXNetworkTransaction.m @@ -265,8 +265,12 @@ + (instancetype)withMessage:(NSURLSessionWebSocketMessage *)message } - (NSArray *)details API_AVAILABLE(ios(13.0)) { + // Use RTL-aware arrows that automatically flip direction based on layout + NSString *outgoingArrow = @"SENT \u2192"; // Right arrow (→) that flips in RTL + NSString *incomingArrow = @"\u2190 RECEIVED"; // Left arrow (←) that flips in RTL + return @[ - self.direction == FLEXWebsocketOutgoing ? @"SENT →" : @"→ RECEIVED", + self.direction == FLEXWebsocketOutgoing ? outgoingArrow : incomingArrow, [NSByteCountFormatter stringFromByteCount:self.dataLength countStyle:NSByteCountFormatterCountStyleBinary From 078fa782c6e07741bbf2c848e0ed9e40e4ba1cf9 Mon Sep 17 00:00:00 2001 From: Mahmoud abdelwahab Date: Thu, 11 Sep 2025 20:13:41 +0400 Subject: [PATCH 3/3] Force LTR layout for remaining FLEX view controllers - Added LTR forcing to FLEXKeyboardHelpViewController for technical content - Added LTR forcing to FLEXImagePreviewViewController for UI consistency - Added LTR forcing to FLEXWebViewController for technical content display - Ensures 100% LTR coverage across all FLEX debugging screens --- Classes/GlobalStateExplorers/FLEXWebViewController.m | 5 +++++ Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m | 5 +++++ Classes/ViewHierarchy/FLEXImagePreviewViewController.m | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/Classes/GlobalStateExplorers/FLEXWebViewController.m b/Classes/GlobalStateExplorers/FLEXWebViewController.m index 7680c4620e..bee356e380 100644 --- a/Classes/GlobalStateExplorers/FLEXWebViewController.m +++ b/Classes/GlobalStateExplorers/FLEXWebViewController.m @@ -74,7 +74,12 @@ - (id)initWithURL:(NSURL *)url { - (void)viewDidLoad { [super viewDidLoad]; + // Force LTR layout for technical content + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationController.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + [self.view addSubview:self.webView]; + self.webView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; self.webView.frame = self.view.bounds; self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; diff --git a/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m b/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m index 1caafab188..9606d818da 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m @@ -19,8 +19,13 @@ @implementation FLEXKeyboardHelpViewController - (void)viewDidLoad { [super viewDidLoad]; + + // Force LTR layout for technical content + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationController.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; self.textView = [[UITextView alloc] initWithFrame:self.view.bounds]; + self.textView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; [self.view addSubview:self.textView]; #if TARGET_OS_SIMULATOR diff --git a/Classes/ViewHierarchy/FLEXImagePreviewViewController.m b/Classes/ViewHierarchy/FLEXImagePreviewViewController.m index 24634ec471..90610f0fed 100644 --- a/Classes/ViewHierarchy/FLEXImagePreviewViewController.m +++ b/Classes/ViewHierarchy/FLEXImagePreviewViewController.m @@ -61,8 +61,14 @@ - (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))comp - (void)viewDidLoad { [super viewDidLoad]; + // Force LTR layout for UI consistency + self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.navigationController.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + self.imageView = [[UIImageView alloc] initWithImage:self.image]; + self.imageView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; + self.scrollView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; self.scrollView.delegate = self; self.scrollView.backgroundColor = self.backgroundColors.firstObject; self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;